feat: chunked file save + export progress spinner + password-reveal + avatar size

Large file save (fixes black screen on big attachment download / export)
- Bridge.saveFile streams anything over ~1MB base64 in chunks through the
  cmd:// channel instead of stuffing the whole payload in one URL — a
  multi-MB base64 URL blew past WebView2's ~2MB navigation cap and blanked
  the document (black screen). Small payloads keep the single-shot path.
- Chunks are sent sequentially (each acked via Bridge.onFileChunkAck
  before the next) so repeated location.href assignments don't coalesce.
- Delphi accumulates chunks per reqId in a TStringBuilder
  (FFileSaveChunks), commits on file/save-commit, and shares the
  decode+dialog+write logic with the single-shot path via SaveDecodedFile.
- Chunk size 1MB → far fewer round-trips (a 20MB export dropped from ~67
  to ~27 hops).

Busy overlay + progress
- Global spinner overlay (showBusy/updateBusy/hideBusy). doExport shows it
  immediately on click — BEFORE the entry-decrypt + attachment-fetch loop
  that is the real cost — with a 0ms yield so it paints before the thread
  blocks (was appearing 3-5s late). Phases: "Reading vault… N/total" →
  "Encrypting export…" → "Preparing file… N%" (real chunk progress).
  Attachment download shows the same for files > 512KB.
- Spinner ring used an undefined --bg-elev-3 (invalid border → invisible);
  switched to --border. Fixed a second stale --bg-elev-3 use on the
  settings-search clear button hover.

Password reveal
- promptDialog gets an eye toggle in password mode, so every encrypted
  prompt (export, import, backup password, recovery code, sync password)
  can show/hide the typed value.

Avatar
- Top-right chip avatar enlarged 22px → 30px with the chip padding
  rebalanced.

Rebuild: BuildAssets + F9 (UMainForm.pas changed for the chunk handlers).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
r-zakarya
2026-07-03 16:56:47 +01:00
parent 3f8ecde571
commit c5fe26ce94
5 changed files with 279 additions and 76 deletions
+14 -1
View File
@@ -1130,8 +1130,13 @@
<p id="confirmMessage" style="margin:0 0 12px;color:var(--text-dim);font-size:13px;line-height:1.5">
Are you sure?
</p>
<label class="field is-hidden" id="confirmInputField">
<label class="field is-hidden" id="confirmInputField" style="position:relative">
<input id="confirmInput" type="text" autocomplete="off">
<button type="button" id="confirmInputEye" class="icon-btn icon-btn-sm"
title="Show / hide"
style="display:none;position:absolute;right:4px;top:50%;transform:translateY(-50%)">
<svg><use href="#i-eye"/></svg>
</button>
</label>
</form>
<footer class="modal-footer">
@@ -1143,6 +1148,14 @@
</div>
</div>
<!-- Global busy overlay: spinner + text for long operations (export…). -->
<div id="busyOverlay" class="busy-overlay is-hidden">
<div class="busy-box">
<div class="busy-spinner"></div>
<div class="busy-text" id="busyText">Working…</div>
</div>
</div>
<!-- ============================================================ -->
<!-- AUTOFILL PICKER — shown when multiple entries match hotkey -->
<!-- ============================================================ -->