[auth] HTML export fixes (#4449)

This commit is contained in:
Neeraj Gupta 2024-12-20 15:45:45 +05:30 committed by GitHub
commit 65e1745aa0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 139 additions and 111 deletions

View File

@ -458,7 +458,6 @@
"pinnedCodeMessage": "{code} has been pinned", "pinnedCodeMessage": "{code} has been pinned",
"unpinnedCodeMessage": "{code} has been unpinned", "unpinnedCodeMessage": "{code} has been unpinned",
"pinned": "Pinned", "pinned": "Pinned",
"tags": "Tags", "tags": "Tags",
"createNewTag": "Create New Tag", "createNewTag": "Create New Tag",
"tag": "Tag", "tag": "Tag",
@ -502,5 +501,6 @@
"deduplicateCodes": "Deduplicate codes", "deduplicateCodes": "Deduplicate codes",
"deselectAll": "Deselect all", "deselectAll": "Deselect all",
"selectAll": "Select all", "selectAll": "Select all",
"deleteDuplicates": "Delete duplicates" "deleteDuplicates": "Delete duplicates",
"plainHTML": "Plain HTML"
} }

View File

@ -39,9 +39,9 @@ Future<void> handleExportClick(BuildContext context) async {
isInAlert: true, isInAlert: true,
buttonAction: ButtonAction.second, buttonAction: ButtonAction.second,
), ),
const ButtonWidget( ButtonWidget(
buttonType: ButtonType.secondary, buttonType: ButtonType.secondary,
labelText: "HTML", labelText: context.l10n.plainHTML,
buttonSize: ButtonSize.large, buttonSize: ButtonSize.large,
isInAlert: true, isInAlert: true,
buttonAction: ButtonAction.third, buttonAction: ButtonAction.third,

View File

@ -33,29 +33,29 @@ Future<String> generateQRImageBase64(String data) async {
return base64Encode(pngBytes); return base64Encode(pngBytes);
} }
Future<String> generateOTPEntryHtml( Future<String> generateOTPEntryHtml(Code code, BuildContext context) async {
Code code,
BuildContext context,
) async {
final qrBase64 = await generateQRImageBase64(code.rawData); final qrBase64 = await generateQRImageBase64(code.rawData);
String notes = code.display.note; String notes = code.display.note;
if (notes.isNotEmpty) { if (notes.isNotEmpty) {
notes = '<p>Note: <b>$notes</b></p>'; notes = '<p class="group">Note: <b>$notes</b></p>';
} }
return ''' return '''
<div class="otp-entry"> <table class="otp-entry">
<div> <tr>
<p><b>${code.issuer}</b> </p> <td>
<p><b>${code.account}</b></p> <p><b>${code.issuer}</b></p>
<br /> <p><b>${code.account}</b></p>
<p>Type: <b>${code.type.name}</b></p> <p class="group">Type: <b>${code.type.name}</b></p>
<p>Algorithm: <b>${code.algorithm.name}</b></p> <p>Algorithm: <b>${code.algorithm.name}</b></p>
<p>Digits: <b>${code.digits}</b></p> <p>Digits: <b>${code.digits}</b></p>
<p>Recovery Code: <b>${code.secret}</b></p> <p>Recovery Code: <b>${code.secret}</b></p>
$notes $notes
</div> </td>
<img src="data:image/png;base64,$qrBase64" alt="QR Code"> <td class="otp-qr">
</div> <img src="data:image/png;base64,$qrBase64" alt="QR Code">
</td>
</tr>
</table>
<br/> <br/>
<hr class="red-separator" /> <hr class="red-separator" />
<br/> <br/>
@ -80,116 +80,144 @@ Future<String> generateHtml(BuildContext context) async {
<meta content="text/html; charset=utf-8" /> <meta content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
<style> <style>
body { body {
background-color: #f0f1f3; background-color: #f0f1f3;
font-family: "Helvetica Neue", "Segoe UI", Helvetica, sans-serif; font-family: "Helvetica Neue", "Segoe UI", Helvetica, sans-serif;
font-size: 16px; font-size: 16px;
line-height: 27px; line-height: 27px;
margin: 0; margin: 0;
color: #444; color: #444;
} }
pre { pre {
background: #f4f4f4f4; background: #f4f4f4f4;
padding: 2px; padding: 2px;
} }
table { table {
width: 100%; width: 100%;
border: 1px solid #ddd; }
}
table td { table td {
border-color: #ddd; border-color: #ddd;
padding: 5px; padding: 5px;
} }
.wrap { .wrap {
background-color: #fff; background-color: #fff;
padding: 30px; padding: 30px;
max-width: 600px; max-width: 600px;
margin: 0 auto; margin: 0 auto;
border-radius: 5px; border-radius: 5px;
} }
.button { .button {
background: #0055d4; background: #0055d4;
border-radius: 3px; border-radius: 3px;
text-decoration: none !important; text-decoration: none !important;
color: #fff !important; color: #fff !important;
font-weight: bold; font-weight: bold;
padding: 10px 30px; padding: 10px 30px;
display: inline-block; display: inline-block;
} }
.button:hover { .button:hover {
background: #111; background: #111;
} }
.footer { .footer {
text-align: center; text-align: center;
font-size: 12px; font-size: 12px;
color: #888; color: #888;
} }
.footer a { .footer a {
color: #888; color: #888;
margin-right: 5px; margin-right: 5px;
} }
.gutter { .gutter {
padding: 30px; padding: 30px;
} }
img { img {
max-width: 100%; max-width: 100%;
height: auto; height: auto;
} }
a { a {
color: #0055d4; color: #0055d4;
} }
a:hover { a:hover {
color: #111; color: #111;
} }
@media screen and (max-width: 700px) {
.wrap {
max-width: auto;
}
.gutter {
padding: 10px;
}
}
.footer-icons {
padding: 4px !important;
width: 24px !important;
}
@media screen and (max-width: 700px) {
.otp-entry { .otp-entry {
display: flex; display: block;
align-items: center;
justify-content: space-between;
} }
.otp-entry div { .otp-entry td {
flex: 1; display: block;
width: 100%;
} }
.otp-entry p { .otp-qr img {
margin: 2px 0; margin-top: 10px;
} }
}
hr.red-separator { .footer-icons {
border: none; padding: 4px !important;
height: 1px; width: 24px !important;
background-color: rgb(173, 0, 255); }
}
</style> .otp-entry {
width: 100%;
table-layout: fixed;
border-collapse: collapse;
}
.otp-entry td {
padding: 20px;
margin: 0px;
vertical-align: middle;
}
.otp-entry td:first-child {
width: 70%;
word-wrap: break-word;
overflow-wrap: break-word;
}
.otp-qr img {
max-width: 200px;
height: auto;
display: block;
margin: 0 auto;
}
.otp-entry td.otp-qr {
width: 30%;
text-align: center;
vertical-align: middle;
}
.otp-entry p {
margin: 2px 0;
}
.otp-entry p.group {
margin-top: 15px;
}
hr.red-separator {
border: none;
height: 1px;
background-color: rgb(173, 0, 255);
}
</style>
</head> </head>
<body> <body>
<h1 style="text-align: center;">Ente Auth</h1> <h1 style="text-align: center;">Ente Auth</h1>