Выпущен 0.1.3: UX convenience pack, unwrap/admin polish и cache-bust статики.
Добавлены Share/QR PNG, zip all, size meter, PWA-manifest, системная тема и haptic на copy; улучшены success/unwrap и статистика админки (EN/RU).
This commit is contained in:
@@ -140,5 +140,5 @@
|
||||
</section>
|
||||
{% endblock %}
|
||||
{% block admin_scripts %}
|
||||
<script src="/static/js/admin-audit.js"></script>
|
||||
<script src="{{ static_url('js/admin-audit.js') }}"></script>
|
||||
{% endblock %}
|
||||
|
||||
@@ -7,15 +7,17 @@
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500&family=Outfit:wght@400;500;600;700&display=swap" rel="stylesheet" />
|
||||
<link rel="stylesheet" href="/static/css/app.css" />
|
||||
<link rel="icon" href="/static/favicon.svg" type="image/svg+xml" />
|
||||
<link rel="icon" href="/static/favicon.ico" sizes="any" />
|
||||
<link rel="apple-touch-icon" href="/static/apple-touch-icon.png" />
|
||||
<link rel="stylesheet" href="{{ static_url('css/app.css') }}" />
|
||||
<link rel="icon" href="{{ static_url('favicon.svg') }}" type="image/svg+xml" />
|
||||
<link rel="icon" href="{{ static_url('favicon.ico') }}" sizes="any" />
|
||||
<link rel="apple-touch-icon" href="{{ static_url('apple-touch-icon.png') }}" />
|
||||
<link rel="manifest" href="{{ static_url('manifest.webmanifest') }}" />
|
||||
<meta name="theme-color" content="#0b1020" />
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css" crossorigin="anonymous" referrerpolicy="no-referrer" />
|
||||
</head>
|
||||
<body class="admin-body">
|
||||
<div class="bg-grid" aria-hidden="true"></div>
|
||||
<header class="admin-top">
|
||||
<header class="admin-top" id="admin-top">
|
||||
<a class="brand" href="/admin">
|
||||
<span class="brand-mark" aria-hidden="true">
|
||||
<i class="fa-solid fa-shield-halved"></i>
|
||||
@@ -25,35 +27,46 @@
|
||||
<span class="brand-tagline" data-i18n="admin.brand.tagline">Admin console</span>
|
||||
</span>
|
||||
</a>
|
||||
<div class="admin-top-right">
|
||||
<nav class="admin-nav" aria-label="Admin">
|
||||
<a href="/admin/stats" class="admin-nav-link {% if active == 'stats' %}active{% endif %}">
|
||||
<i class="fa-solid fa-chart-simple" aria-hidden="true"></i>
|
||||
<span data-i18n="admin.nav.stats">Stats</span>
|
||||
</a>
|
||||
<a href="/admin/settings" class="admin-nav-link {% if active == 'settings' %}active{% endif %}">
|
||||
<i class="fa-solid fa-sliders" aria-hidden="true"></i>
|
||||
<span data-i18n="admin.nav.settings">Settings</span>
|
||||
</a>
|
||||
<a href="/admin/audit" class="admin-nav-link {% if active == 'audit' %}active{% endif %}">
|
||||
<i class="fa-solid fa-list" aria-hidden="true"></i>
|
||||
<span data-i18n="admin.nav.audit">Audit</span>
|
||||
</a>
|
||||
<a href="/admin/danger" class="admin-nav-link admin-nav-danger {% if active == 'danger' %}active{% endif %}">
|
||||
<i class="fa-solid fa-triangle-exclamation" aria-hidden="true"></i>
|
||||
<span data-i18n="admin.nav.danger">Danger</span>
|
||||
</a>
|
||||
<a href="/" class="admin-nav-link" target="_blank" rel="noopener noreferrer">
|
||||
<i class="fa-solid fa-arrow-up-right-from-square" aria-hidden="true"></i>
|
||||
<span data-i18n="admin.nav.site">Site</span>
|
||||
</a>
|
||||
<form method="post" action="/admin/logout" class="inline">
|
||||
<button class="admin-nav-link admin-nav-logout" type="submit">
|
||||
<i class="fa-solid fa-right-from-bracket" aria-hidden="true"></i>
|
||||
<span data-i18n="admin.nav.logout">Logout</span>
|
||||
</button>
|
||||
</form>
|
||||
</nav>
|
||||
<nav class="admin-nav" id="admin-nav" aria-label="Admin">
|
||||
<a href="/admin/stats" class="admin-nav-link {% if active == 'stats' %}active{% endif %}">
|
||||
<i class="fa-solid fa-chart-simple" aria-hidden="true"></i>
|
||||
<span data-i18n="admin.nav.stats">Stats</span>
|
||||
</a>
|
||||
<a href="/admin/settings" class="admin-nav-link {% if active == 'settings' %}active{% endif %}">
|
||||
<i class="fa-solid fa-sliders" aria-hidden="true"></i>
|
||||
<span data-i18n="admin.nav.settings">Settings</span>
|
||||
</a>
|
||||
<a href="/admin/audit" class="admin-nav-link {% if active == 'audit' %}active{% endif %}">
|
||||
<i class="fa-solid fa-list" aria-hidden="true"></i>
|
||||
<span data-i18n="admin.nav.audit">Audit</span>
|
||||
</a>
|
||||
<a href="/admin/danger" class="admin-nav-link admin-nav-danger {% if active == 'danger' %}active{% endif %}">
|
||||
<i class="fa-solid fa-triangle-exclamation" aria-hidden="true"></i>
|
||||
<span data-i18n="admin.nav.danger">Danger</span>
|
||||
</a>
|
||||
<a href="/" class="admin-nav-link" target="_blank" rel="noopener noreferrer">
|
||||
<i class="fa-solid fa-arrow-up-right-from-square" aria-hidden="true"></i>
|
||||
<span data-i18n="admin.nav.site">Site</span>
|
||||
</a>
|
||||
<form method="post" action="/admin/logout" class="inline admin-nav-logout-form">
|
||||
<button class="admin-nav-link admin-nav-logout" type="submit">
|
||||
<i class="fa-solid fa-right-from-bracket" aria-hidden="true"></i>
|
||||
<span data-i18n="admin.nav.logout">Logout</span>
|
||||
</button>
|
||||
</form>
|
||||
</nav>
|
||||
<div class="admin-top-tools">
|
||||
<button
|
||||
type="button"
|
||||
class="icon-btn admin-nav-toggle"
|
||||
id="admin-nav-toggle"
|
||||
aria-controls="admin-nav"
|
||||
aria-expanded="false"
|
||||
title="Menu"
|
||||
aria-label="Menu"
|
||||
>
|
||||
<i class="fa-solid fa-bars" aria-hidden="true"></i>
|
||||
</button>
|
||||
<div class="top-actions">
|
||||
<button type="button" class="icon-btn" id="lang-toggle" title="Language" aria-label="Language">
|
||||
<span id="lang-label">RU</span>
|
||||
@@ -69,9 +82,10 @@
|
||||
<h1 data-i18n="{% if active == 'stats' %}admin.stats.title{% elif active == 'audit' %}admin.audit.title{% elif active == 'danger' %}admin.danger.title{% else %}admin.settings.title{% endif %}">{{ title }}</h1>
|
||||
{% block admin_content %}{% endblock %}
|
||||
</main>
|
||||
<script src="/static/js/i18n.js"></script>
|
||||
<script src="/static/js/theme.js"></script>
|
||||
<script src="/static/js/modal.js"></script>
|
||||
<script src="{{ static_url('js/i18n.js') }}"></script>
|
||||
<script src="{{ static_url('js/theme.js') }}"></script>
|
||||
<script src="{{ static_url('js/modal.js') }}"></script>
|
||||
<script src="{{ static_url('js/admin-nav.js') }}"></script>
|
||||
{% block admin_scripts %}{% endblock %}
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -7,10 +7,12 @@
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500&family=Outfit:wght@400;500;600;700&display=swap" rel="stylesheet" />
|
||||
<link rel="stylesheet" href="/static/css/app.css" />
|
||||
<link rel="icon" href="/static/favicon.svg" type="image/svg+xml" />
|
||||
<link rel="icon" href="/static/favicon.ico" sizes="any" />
|
||||
<link rel="apple-touch-icon" href="/static/apple-touch-icon.png" />
|
||||
<link rel="stylesheet" href="{{ static_url('css/app.css') }}" />
|
||||
<link rel="icon" href="{{ static_url('favicon.svg') }}" type="image/svg+xml" />
|
||||
<link rel="icon" href="{{ static_url('favicon.ico') }}" sizes="any" />
|
||||
<link rel="apple-touch-icon" href="{{ static_url('apple-touch-icon.png') }}" />
|
||||
<link rel="manifest" href="{{ static_url('manifest.webmanifest') }}" />
|
||||
<meta name="theme-color" content="#0b1020" />
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css" crossorigin="anonymous" referrerpolicy="no-referrer" />
|
||||
</head>
|
||||
<body class="admin-body">
|
||||
@@ -47,7 +49,7 @@
|
||||
<button class="btn primary" type="submit" data-i18n="admin.login.submit">Sign in</button>
|
||||
</form>
|
||||
</main>
|
||||
<script src="/static/js/i18n.js"></script>
|
||||
<script src="/static/js/theme.js"></script>
|
||||
<script src="{{ static_url('js/i18n.js') }}"></script>
|
||||
<script src="{{ static_url('js/theme.js') }}"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -150,5 +150,5 @@
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<script src="/static/js/admin-tabs.js"></script>
|
||||
<script src="{{ static_url('js/admin-tabs.js') }}"></script>
|
||||
{% endblock %}
|
||||
|
||||
@@ -28,18 +28,29 @@
|
||||
<article class="stat-card">
|
||||
<div class="stat-card-head">
|
||||
<i class="fa-solid fa-lock-open" aria-hidden="true"></i>
|
||||
<h2 data-i18n="admin.stats.unwrappedTitle">Unwrapped (all time)</h2>
|
||||
<h2 data-i18n="admin.stats.unwrappedTitle">Successful unwraps</h2>
|
||||
</div>
|
||||
<p class="stat-value">{{ stats.wraps_consumed }}</p>
|
||||
<p class="stat-value">{{ stats.unwraps_success }}</p>
|
||||
<p class="stat-sub">
|
||||
<span data-i18n="admin.stats.auditOk">audit ok</span>
|
||||
<span class="stat-num">{{ stats.audit_unwraps_ok }}</span>
|
||||
<span data-i18n="admin.stats.dbConsumed">DB consumed</span>
|
||||
<span class="stat-num">{{ stats.wraps_consumed }}</span>
|
||||
·
|
||||
<span data-i18n="admin.stats.last24h">24h</span>
|
||||
<span class="stat-num">{{ stats.consumed_24h }}</span>
|
||||
</p>
|
||||
</article>
|
||||
|
||||
<article class="stat-card">
|
||||
<div class="stat-card-head">
|
||||
<i class="fa-solid fa-shield-halved" aria-hidden="true"></i>
|
||||
<h2 data-i18n="admin.stats.passwordBurnsTitle">Burned by password</h2>
|
||||
</div>
|
||||
<p class="stat-value">{{ stats.password_burns }}</p>
|
||||
<p class="stat-sub" data-i18n="admin.stats.passwordBurnsHint">
|
||||
Destroyed after too many wrong passwords
|
||||
</p>
|
||||
</article>
|
||||
|
||||
<article class="stat-card">
|
||||
<div class="stat-card-head">
|
||||
<i class="fa-solid fa-hourglass-half" aria-hidden="true"></i>
|
||||
@@ -93,13 +104,13 @@
|
||||
<td data-i18n="admin.stats.status.consumed">consumed</td>
|
||||
<td class="mono">{{ stats.wraps_consumed }}</td>
|
||||
<td class="mono">{{ stats.size_consumed_human }}</td>
|
||||
<td class="mono">—</td>
|
||||
<td class="mono">{{ stats.items_consumed }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td data-i18n="admin.stats.status.expired">expired</td>
|
||||
<td class="mono">{{ stats.wraps_expired }}</td>
|
||||
<td class="mono">—</td>
|
||||
<td class="mono">—</td>
|
||||
<td class="mono">{{ stats.size_expired_human }}</td>
|
||||
<td class="mono">{{ stats.items_expired }}</td>
|
||||
</tr>
|
||||
<tr class="stats-total-row">
|
||||
<td data-i18n="admin.stats.total">Total</td>
|
||||
@@ -142,6 +153,64 @@
|
||||
</ul>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div class="stats-sections">
|
||||
<section class="stats-section">
|
||||
<h3 data-i18n="admin.stats.failReasonsSection">Unwrap fail reasons (all time)</h3>
|
||||
<div class="stats-table-wrap">
|
||||
<table class="stats-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-i18n="admin.stats.col.reason">Reason</th>
|
||||
<th data-i18n="admin.stats.col.count">Count</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% if stats.unwrap_fail_reasons %}
|
||||
{% for row in stats.unwrap_fail_reasons %}
|
||||
<tr>
|
||||
<td class="mono">{{ row.reason }}</td>
|
||||
<td class="mono">{{ row.count }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<tr>
|
||||
<td colspan="2" class="hint" data-i18n="admin.stats.noFailReasons">No failed unwraps yet.</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="stats-section">
|
||||
<h3 data-i18n="admin.stats.failReasons24hSection">Unwrap fail reasons (24h)</h3>
|
||||
<div class="stats-table-wrap">
|
||||
<table class="stats-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-i18n="admin.stats.col.reason">Reason</th>
|
||||
<th data-i18n="admin.stats.col.count">Count</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% if stats.unwrap_fail_reasons_24h %}
|
||||
{% for row in stats.unwrap_fail_reasons_24h %}
|
||||
<tr>
|
||||
<td class="mono">{{ row.reason }}</td>
|
||||
<td class="mono">{{ row.count }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<tr>
|
||||
<td colspan="2" class="hint" data-i18n="admin.stats.noFailReasons">No failed unwraps yet.</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</section>
|
||||
{% endblock %}
|
||||
{% block admin_scripts %}
|
||||
|
||||
+11
-9
@@ -7,10 +7,12 @@
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&family=Outfit:wght@400;500;600;700&display=swap" rel="stylesheet" />
|
||||
<link rel="stylesheet" href="/static/css/app.css" />
|
||||
<link rel="icon" href="/static/favicon.svg" type="image/svg+xml" />
|
||||
<link rel="icon" href="/static/favicon.ico" sizes="any" />
|
||||
<link rel="apple-touch-icon" href="/static/apple-touch-icon.png" />
|
||||
<link rel="stylesheet" href="{{ static_url('css/app.css') }}" />
|
||||
<link rel="icon" href="{{ static_url('favicon.svg') }}" type="image/svg+xml" />
|
||||
<link rel="icon" href="{{ static_url('favicon.ico') }}" sizes="any" />
|
||||
<link rel="apple-touch-icon" href="{{ static_url('apple-touch-icon.png') }}" />
|
||||
<link rel="manifest" href="{{ static_url('manifest.webmanifest') }}" />
|
||||
<meta name="theme-color" content="#0b1020" />
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css" crossorigin="anonymous" referrerpolicy="no-referrer" />
|
||||
<link id="hljs-theme-dark" rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/styles/github-dark.min.css" />
|
||||
<link id="hljs-theme-light" rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/styles/github.min.css" disabled />
|
||||
@@ -71,11 +73,11 @@
|
||||
</div>
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/highlight.min.js" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||
<script src="/static/js/i18n.js"></script>
|
||||
<script src="/static/js/theme.js"></script>
|
||||
<script src="/static/js/ui.js"></script>
|
||||
<script src="/static/js/about.js"></script>
|
||||
<script src="/static/js/highlight-ui.js"></script>
|
||||
<script src="{{ static_url('js/i18n.js') }}"></script>
|
||||
<script src="{{ static_url('js/theme.js') }}"></script>
|
||||
<script src="{{ static_url('js/ui.js') }}"></script>
|
||||
<script src="{{ static_url('js/about.js') }}"></script>
|
||||
<script src="{{ static_url('js/highlight-ui.js') }}"></script>
|
||||
{% block scripts %}{% endblock %}
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+56
-12
@@ -24,6 +24,7 @@
|
||||
<input id="file-input" type="file" multiple hidden />
|
||||
</div>
|
||||
<ul id="file-list" class="file-list"></ul>
|
||||
<p id="size-meter" class="size-meter hint" aria-live="polite"></p>
|
||||
|
||||
<div class="grid-2">
|
||||
<div class="field">
|
||||
@@ -64,17 +65,59 @@
|
||||
<span data-i18n="create.successWarnHint">After opening, ciphertext is deleted on the server.</span>
|
||||
</span>
|
||||
</div>
|
||||
<label data-i18n="create.shareLink">Share link</label>
|
||||
<div class="copy-row">
|
||||
<input id="share-link" readonly />
|
||||
<button type="button" class="btn" id="copy-link" data-i18n="common.copy">Copy</button>
|
||||
|
||||
<ul class="success-checklist" id="success-checklist">
|
||||
<li data-i18n="create.checkLink">Copy the share link</li>
|
||||
<li id="check-password-item" class="hidden" data-i18n="create.checkPassword">Send the password in a separate message</li>
|
||||
<li data-i18n="create.checkExpires">Note the expiry time</li>
|
||||
</ul>
|
||||
<p class="hint success-trust" data-i18n="create.trustKey">
|
||||
The encryption key lives only in the link #fragment — the server never sees it.
|
||||
</p>
|
||||
|
||||
<div class="success-layout">
|
||||
<div class="success-main">
|
||||
<div id="success-password-block" class="success-password-block hidden">
|
||||
<div class="success-password-badge" role="status">
|
||||
<i class="fa-solid fa-lock" aria-hidden="true"></i>
|
||||
<span data-i18n="create.passwordProtected">Password protected</span>
|
||||
</div>
|
||||
<label for="share-password" data-i18n="create.sharePassword">Password</label>
|
||||
<div class="copy-row">
|
||||
<input id="share-password" class="mono" readonly autocomplete="off" />
|
||||
<button type="button" class="btn" id="copy-password" data-i18n="common.copy">Copy</button>
|
||||
</div>
|
||||
<p class="hint success-password-hint" data-i18n="create.passwordSeparateHint">
|
||||
Do not send the password in the same chat as the link.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<label for="share-link" data-i18n="create.shareLink">Share link</label>
|
||||
<div class="copy-row">
|
||||
<input id="share-link" readonly />
|
||||
<button type="button" class="btn" id="copy-link" data-i18n="common.copy">Copy</button>
|
||||
</div>
|
||||
|
||||
<label for="share-token" data-i18n="create.token">Wrapped token</label>
|
||||
<div class="copy-row">
|
||||
<input id="share-token" class="mono" readonly />
|
||||
<button type="button" class="btn" id="copy-token" data-i18n="common.copy">Copy</button>
|
||||
</div>
|
||||
|
||||
<div class="success-actions">
|
||||
<button type="button" class="btn hidden" id="share-native" data-i18n="create.share">Share</button>
|
||||
<button type="button" class="btn" id="download-qr" data-i18n="create.downloadQr">Download QR</button>
|
||||
</div>
|
||||
|
||||
<p class="expires-meta" id="expires-meta"></p>
|
||||
</div>
|
||||
|
||||
<div class="success-qr" aria-label="QR code">
|
||||
<div id="share-qr" class="share-qr"></div>
|
||||
<p class="hint success-qr-hint" data-i18n="create.qrHint">Scan to open the share link</p>
|
||||
</div>
|
||||
</div>
|
||||
<label data-i18n="create.token">Wrapped token</label>
|
||||
<div class="copy-row">
|
||||
<input id="share-token" class="mono" readonly />
|
||||
<button type="button" class="btn" id="copy-token" data-i18n="common.copy">Copy</button>
|
||||
</div>
|
||||
<p class="expires-meta" id="expires-meta"></p>
|
||||
|
||||
<button type="button" class="btn ghost" id="create-another" data-i18n="create.another">Create another</button>
|
||||
</div>
|
||||
</section>
|
||||
@@ -92,6 +135,7 @@
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% block scripts %}
|
||||
<script src="/static/js/crypto.js"></script>
|
||||
<script src="/static/js/create.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/qrcodejs/1.0.0/qrcode.min.js" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||
<script src="{{ static_url('js/crypto.js') }}"></script>
|
||||
<script src="{{ static_url('js/create.js') }}"></script>
|
||||
{% endblock %}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
<section class="hero-panel unwrap-panel">
|
||||
<div class="panel-head">
|
||||
<div class="panel-head" id="unwrap-head">
|
||||
<p class="eyebrow" data-i18n="unwrap.eyebrow">Unwrap</p>
|
||||
<h1 data-i18n="unwrap.title">Reveal once</h1>
|
||||
<p class="lede" data-i18n="unwrap.lede">Paste a wrapped token or open a share link. Ciphertext is fetched once and deleted from the server.</p>
|
||||
@@ -32,6 +32,15 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="unwrap-state" class="unwrap-state hidden" role="status">
|
||||
<div class="unwrap-state-icon" aria-hidden="true">
|
||||
<i class="fa-solid fa-link-slash" id="unwrap-state-fa"></i>
|
||||
</div>
|
||||
<h2 id="unwrap-state-title"></h2>
|
||||
<p class="lede" id="unwrap-state-hint"></p>
|
||||
<a class="btn primary" href="/" data-i18n="unwrap.createOwn">Create your own wrap</a>
|
||||
</div>
|
||||
|
||||
<div id="result-panel" class="result-panel hidden">
|
||||
<div class="success-callout" role="status">
|
||||
<span class="success-callout-icon" aria-hidden="true">
|
||||
@@ -42,11 +51,26 @@
|
||||
<span data-i18n="unwrap.destroyedHint">Preview lives only in this browser session.</span>
|
||||
</span>
|
||||
</div>
|
||||
<p class="hint success-trust" data-i18n="unwrap.trustKey">
|
||||
The key was only in the link #fragment and was never sent to the server.
|
||||
</p>
|
||||
<div class="result-actions">
|
||||
<button type="button" class="btn hidden" id="download-all" data-i18n="unwrap.downloadAll">Download all</button>
|
||||
</div>
|
||||
<div id="items" class="items"></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div id="image-lightbox" class="image-lightbox hidden" role="dialog" aria-modal="true" aria-label="Image preview">
|
||||
<button type="button" class="image-lightbox-close" id="lightbox-close" aria-label="Close">
|
||||
<i class="fa-solid fa-xmark" aria-hidden="true"></i>
|
||||
</button>
|
||||
<img id="lightbox-img" alt="" />
|
||||
<p class="image-lightbox-caption" id="lightbox-caption"></p>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% block scripts %}
|
||||
<script src="/static/js/crypto.js"></script>
|
||||
<script src="/static/js/unwrap.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||
<script src="{{ static_url('js/crypto.js') }}"></script>
|
||||
<script src="{{ static_url('js/unwrap.js') }}"></script>
|
||||
{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user