fix(clipboard): copy toasts reflect the configured clear delay
The "clears in 30s" suffix was hardcoded in ~14 toasts. Single helper
clipClearSuffix() reads clipboardClearSeconds (''=Never); prefixes concatenated
to it. Cheatsheet text made generic "(auto-clears)".
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1106,6 +1106,13 @@ function toast(msg, type) {
|
|||||||
|
|
||||||
function $(sel, root) { return (root || document).querySelector(sel); }
|
function $(sel, root) { return (root || document).querySelector(sel); }
|
||||||
function $$(sel, root) { return Array.from((root || document).querySelectorAll(sel)); }
|
function $$(sel, root) { return Array.from((root || document).querySelectorAll(sel)); }
|
||||||
|
// Toast suffix for a just-copied secret, honouring the auto-clear setting.
|
||||||
|
// '' when the user disabled auto-clear (Never).
|
||||||
|
function clipClearSuffix() {
|
||||||
|
const s = state.clipboardClearSeconds;
|
||||||
|
return s > 0 ? ' · clears in ' + s + 's' : '';
|
||||||
|
}
|
||||||
|
|
||||||
function el(tag, props, ...kids) {
|
function el(tag, props, ...kids) {
|
||||||
const e = document.createElement(tag);
|
const e = document.createElement(tag);
|
||||||
if (props) for (const k in props) {
|
if (props) for (const k in props) {
|
||||||
@@ -4205,7 +4212,7 @@ function buildCustomFieldRow(field, idx, rerender) {
|
|||||||
if (!v) return;
|
if (!v) return;
|
||||||
if (Bridge.active) Bridge.copySecure(v, 30000);
|
if (Bridge.active) Bridge.copySecure(v, 30000);
|
||||||
else { try { navigator.clipboard.writeText(v); } catch (_) {} }
|
else { try { navigator.clipboard.writeText(v); } catch (_) {} }
|
||||||
toast('Copied · clears in 30s');
|
toast('Copied' + clipClearSuffix());
|
||||||
});
|
});
|
||||||
|
|
||||||
const delBtn = el('button', { class: 'icon-btn icon-btn-sm', type: 'button',
|
const delBtn = el('button', { class: 'icon-btn icon-btn-sm', type: 'button',
|
||||||
@@ -4366,10 +4373,10 @@ function soPasswordField(plain) {
|
|||||||
copy.appendChild(icon('i-copy'));
|
copy.appendChild(icon('i-copy'));
|
||||||
copy.addEventListener('click', () => {
|
copy.addEventListener('click', () => {
|
||||||
if (Bridge.copySecure(input.value, 30000)) {
|
if (Bridge.copySecure(input.value, 30000)) {
|
||||||
toast('Copied · clears in 30s');
|
toast('Copied' + clipClearSuffix());
|
||||||
} else {
|
} else {
|
||||||
navigator.clipboard.writeText(input.value).then(() => {
|
navigator.clipboard.writeText(input.value).then(() => {
|
||||||
toast('Copied · clears in 30s');
|
toast('Copied' + clipClearSuffix());
|
||||||
setTimeout(() => navigator.clipboard.writeText('').catch(()=>{}), 30000);
|
setTimeout(() => navigator.clipboard.writeText('').catch(()=>{}), 30000);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -4497,10 +4504,10 @@ function soTotpField(plainSecret) {
|
|||||||
try {
|
try {
|
||||||
const t = await generateTOTP(secret);
|
const t = await generateTOTP(secret);
|
||||||
if (Bridge.copySecure(t.code, 30000)) {
|
if (Bridge.copySecure(t.code, 30000)) {
|
||||||
toast('Code copied · clears in 30s');
|
toast('Code copied' + clipClearSuffix());
|
||||||
} else {
|
} else {
|
||||||
navigator.clipboard.writeText(t.code).then(() => {
|
navigator.clipboard.writeText(t.code).then(() => {
|
||||||
toast('Code copied · clears in 30s');
|
toast('Code copied' + clipClearSuffix());
|
||||||
setTimeout(() => navigator.clipboard.writeText('').catch(()=>{}), 30000);
|
setTimeout(() => navigator.clipboard.writeText('').catch(()=>{}), 30000);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -5418,9 +5425,9 @@ async function copyPassword(entry) {
|
|||||||
const p = await decryptPwd(entry.encrypted_password, entry.iv);
|
const p = await decryptPwd(entry.encrypted_password, entry.iv);
|
||||||
if (p === '[ERROR]') return toast('Cannot decrypt', 'error');
|
if (p === '[ERROR]') return toast('Cannot decrypt', 'error');
|
||||||
if (Bridge.copySecure(p, 30000)) {
|
if (Bridge.copySecure(p, 30000)) {
|
||||||
toast('Password copied · clears in 30s');
|
toast('Password copied' + clipClearSuffix());
|
||||||
} else {
|
} else {
|
||||||
navigator.clipboard.writeText(p).then(() => toast('Password copied · clears in 30s'));
|
navigator.clipboard.writeText(p).then(() => toast('Password copied' + clipClearSuffix()));
|
||||||
setTimeout(() => navigator.clipboard.writeText('').catch(()=>{}), 30000);
|
setTimeout(() => navigator.clipboard.writeText('').catch(()=>{}), 30000);
|
||||||
}
|
}
|
||||||
touchEntry(entry.id);
|
touchEntry(entry.id);
|
||||||
@@ -7334,10 +7341,10 @@ async function init() {
|
|||||||
$('#genCopy').addEventListener('click', () => {
|
$('#genCopy').addEventListener('click', () => {
|
||||||
if (!genCurrent) return;
|
if (!genCurrent) return;
|
||||||
if (Bridge.copySecure(genCurrent, 30000)) {
|
if (Bridge.copySecure(genCurrent, 30000)) {
|
||||||
toast('Copied · clears in 30s');
|
toast('Copied' + clipClearSuffix());
|
||||||
} else {
|
} else {
|
||||||
navigator.clipboard.writeText(genCurrent).then(() => {
|
navigator.clipboard.writeText(genCurrent).then(() => {
|
||||||
toast('Copied · clears in 30s');
|
toast('Copied' + clipClearSuffix());
|
||||||
setTimeout(() => navigator.clipboard.writeText('').catch(()=>{}), 30000);
|
setTimeout(() => navigator.clipboard.writeText('').catch(()=>{}), 30000);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -152,7 +152,7 @@ async function quickSearchPickEntry(entry, mode) {
|
|||||||
if (!u) { toast('No username on this entry', 'warning'); return; }
|
if (!u) { toast('No username on this entry', 'warning'); return; }
|
||||||
if (Bridge.active) Bridge.copySecure(u, 30000);
|
if (Bridge.active) Bridge.copySecure(u, 30000);
|
||||||
else { try { await navigator.clipboard.writeText(u); } catch (_) {} }
|
else { try { await navigator.clipboard.writeText(u); } catch (_) {} }
|
||||||
toast('Username copied · clears in 30s');
|
toast('Username copied' + clipClearSuffix());
|
||||||
} else {
|
} else {
|
||||||
const pwd = await decryptPwd(entry.encrypted_password, entry.iv);
|
const pwd = await decryptPwd(entry.encrypted_password, entry.iv);
|
||||||
if (pwd === '[ERROR]') { toast('Decryption error', 'error'); return; }
|
if (pwd === '[ERROR]') { toast('Decryption error', 'error'); return; }
|
||||||
@@ -202,7 +202,7 @@ const CHEATSHEET_GROUPS = [
|
|||||||
title: 'On each card',
|
title: 'On each card',
|
||||||
items: [
|
items: [
|
||||||
{ keys: [{ icon: 'i-globe' }], desc: 'Open the site in your default browser' },
|
{ keys: [{ icon: 'i-globe' }], desc: 'Open the site in your default browser' },
|
||||||
{ keys: [{ icon: 'i-copy' }], desc: 'Copy password to the secure clipboard (auto-clears in 30s)' },
|
{ keys: [{ icon: 'i-copy' }], desc: 'Copy password to the secure clipboard (auto-clears)' },
|
||||||
{ keys: ['Click card'], desc: 'Open the entry details / edit panel' },
|
{ keys: ['Click card'], desc: 'Open the entry details / edit panel' },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -306,7 +306,7 @@ async function openHistoryModal(entryId) {
|
|||||||
copy.addEventListener('click', () => {
|
copy.addEventListener('click', () => {
|
||||||
if (Bridge.active) Bridge.copySecure(plain, 30000);
|
if (Bridge.active) Bridge.copySecure(plain, 30000);
|
||||||
else { try { navigator.clipboard.writeText(plain); } catch (_) {} }
|
else { try { navigator.clipboard.writeText(plain); } catch (_) {} }
|
||||||
toast('Copied · clears in 30s');
|
toast('Copied' + clipClearSuffix());
|
||||||
});
|
});
|
||||||
preview.appendChild(copy);
|
preview.appendChild(copy);
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -733,10 +733,10 @@ async function doGenerateRecoveryKey() {
|
|||||||
// running embedded, navigator.clipboard with manual scrub
|
// running embedded, navigator.clipboard with manual scrub
|
||||||
// otherwise.
|
// otherwise.
|
||||||
if (Bridge.copySecure(code, 30000)) {
|
if (Bridge.copySecure(code, 30000)) {
|
||||||
toast('Recovery code copied · clears in 30s');
|
toast('Recovery code copied' + clipClearSuffix());
|
||||||
} else {
|
} else {
|
||||||
navigator.clipboard.writeText(code).then(() => {
|
navigator.clipboard.writeText(code).then(() => {
|
||||||
toast('Recovery code copied · clears in 30s');
|
toast('Recovery code copied' + clipClearSuffix());
|
||||||
setTimeout(() => navigator.clipboard.writeText('').catch(()=>{}), 30000);
|
setTimeout(() => navigator.clipboard.writeText('').catch(()=>{}), 30000);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user