fix(editor): ignore Esc while a blocking operation owns the screen
The discard-confirm opened underneath the busy overlay, which sits at z-index 200 - blurred and half-clickable. Worse than the display: it let the user arbitrate closing the editor while a sync or a rotation was writing to the same entry.
This commit is contained in:
@@ -162,6 +162,12 @@ plus bas.
|
|||||||
- **ACTION** : `A` ouverte + dirty → lancer une action longue (export, sync) → cliquer sur le toast ou sur le spinner
|
- **ACTION** : `A` ouverte + dirty → lancer une action longue (export, sync) → cliquer sur le toast ou sur le spinner
|
||||||
- **ATTENDU** : l'éditeur ne se ferme pas, pas de discard.
|
- **ATTENDU** : l'éditeur ne se ferme pas, pas de discard.
|
||||||
|
|
||||||
|
### B15 · Esc pendant une opération bloquante
|
||||||
|
- **ACTION** : `A` ouverte + dirty → lancer *Sync now* (ou un export, une rotation de mot de passe maître) → presser `Esc` pendant que l'overlay « Encrypting… » est affiché.
|
||||||
|
- **ATTENDU** : rien ne se passe. Pas de modale « Discard unsaved changes? ». Elle redevient possible une fois l'overlay parti.
|
||||||
|
- **Historique** : la modale s'ouvrait bel et bien, mais **sous** l'overlay (`z-index 200`) — visible en flou, à demi cliquable. Deux problèmes en un : l'affichage, et surtout le fait d'arbitrer une fermeture d'éditeur pendant qu'une opération écrit sur la même entrée. Garde `isBusy()` posé dans la chaîne Esc de l'éditeur, avec les autres priorités (palette, Settings, modales).
|
||||||
|
- **Non-régression** : le clic extérieur ne ferme déjà pas l'éditeur pendant l'attente — `#busyOverlay` est dans la liste blanche, et il couvre l'écran de toute façon.
|
||||||
|
|
||||||
### B14 · dialogues natifs ouverts par un clic programmatique
|
### B14 · dialogues natifs ouverts par un clic programmatique
|
||||||
- **ACTION** : `A` ouverte + **dirty** → (a) Settings → *Import vault* ; (b) télécharger une pièce jointe (fallback web) ; (c) *Upload icon* ; (d) joindre un fichier.
|
- **ACTION** : `A` ouverte + **dirty** → (a) Settings → *Import vault* ; (b) télécharger une pièce jointe (fallback web) ; (c) *Upload icon* ; (d) joindre un fichier.
|
||||||
- **ATTENDU** : **seul** le dialogue natif s'ouvre. Pas de « Discard unsaved changes? » par-dessus, l'éditeur reste ouvert et modifié.
|
- **ATTENDU** : **seul** le dialogue natif s'ouvre. Pas de « Discard unsaved changes? » par-dessus, l'éditeur reste ouvert et modifié.
|
||||||
|
|||||||
@@ -5971,6 +5971,13 @@ function updateBusy(text) {
|
|||||||
function hideBusy() {
|
function hideBusy() {
|
||||||
const o = $('#busyOverlay'); if (o) o.classList.add('is-hidden');
|
const o = $('#busyOverlay'); if (o) o.classList.add('is-hidden');
|
||||||
}
|
}
|
||||||
|
// True while a blocking operation owns the screen. Anything that would open a
|
||||||
|
// dialog has to check this: the overlay is above every modal, so a dialog
|
||||||
|
// raised now is invisible under it.
|
||||||
|
function isBusy() {
|
||||||
|
const o = $('#busyOverlay');
|
||||||
|
return !!o && !o.classList.contains('is-hidden');
|
||||||
|
}
|
||||||
|
|
||||||
function closeConfirm(value) {
|
function closeConfirm(value) {
|
||||||
$('#confirmModal').classList.add('is-hidden');
|
$('#confirmModal').classList.add('is-hidden');
|
||||||
@@ -7378,6 +7385,11 @@ async function init() {
|
|||||||
if (e.key !== 'Escape') return;
|
if (e.key !== 'Escape') return;
|
||||||
if (!$('#slideover').classList.contains('is-open')) return;
|
if (!$('#slideover').classList.contains('is-open')) return;
|
||||||
if (document.querySelector('.modal:not(.is-hidden)')) return;
|
if (document.querySelector('.modal:not(.is-hidden)')) return;
|
||||||
|
// A long operation is running (sync, export, rotation…). The busy
|
||||||
|
// overlay sits above everything at z-index 200, so a discard-confirm
|
||||||
|
// opened now would render blurred underneath it — and answering it
|
||||||
|
// would race whatever the operation is doing to the same entry.
|
||||||
|
if (isBusy()) return;
|
||||||
// Command palette is .cmd-palette, not .modal — it sits on top of
|
// Command palette is .cmd-palette, not .modal — it sits on top of
|
||||||
// the editor, so its Esc must close IT (bubble handler), not pop
|
// the editor, so its Esc must close IT (bubble handler), not pop
|
||||||
// the editor's discard-confirm underneath.
|
// the editor's discard-confirm underneath.
|
||||||
|
|||||||
Reference in New Issue
Block a user