fixes: scratchpad, zen ESC, chat time, tooltip safety, collab sync race
- Scratchpad: card-scoped private notes in editor (toggle vs preview), smaller font, cleared via button, stored in cards.scratchpad - Zen mode: ESC exits zen before closing detail, Z toggles zen - Chat: always show absolute time (hh:mm, yesterday, or date+time) - Backspace/Delete also deletes focused card (not just selected) - Selected + focused cards use brand accent (not accent2) - Tooltip: guard against non-element targets - Collab sync: skip poll while editor is open, 2s push debounce - Rrule test: only check geburtstag tag, not title format Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
2169c1de1b
commit
7e2b130434
11 files changed
+92
-30
No files matched your search
+12
-5
@@ -214,7 +214,8 @@ const { board: gBoard } = guards;
|
||||
|
||||
// — Escape chain (highest priority first) —
|
||||
registerShortcut({ key: 'Escape', priority: 100, guard: () => !isDialogOpen() && !document.getElementById('quick-capture').classList.contains('hidden'), section: 'global', label: 'close quick capture', hidden: true, handler: () => { const qc = document.getElementById('quick-capture'); qc.classList.add('hidden'); document.getElementById('quick-capture-input').value = ''; } });
|
||||
registerShortcut({ key: 'Escape', priority: 90, guard: () => !isDialogOpen() && guards.isOpen('detail'), section: 'global', label: 'close detail', hidden: true, handler: () => { const escAction = localStorage.getItem('hyprcrd-esc-action') || 'close'; if (escAction === 'exitZen' && document.getElementById('detail')?.classList.contains('zen')) { document.getElementById('detail-zen')?.click(); return; } closeDetail(); } });
|
||||
registerShortcut({ key: 'Escape', priority: 90, guard: () => !isDialogOpen() && guards.isOpen('detail'), section: 'global', label: 'close detail', hidden: true, handler: () => { if (document.getElementById('detail')?.classList.contains('zen')) { document.getElementById('detail-zen')?.click(); return; } closeDetail(); } });
|
||||
registerShortcut({ key: 'z', guard: () => !isDialogOpen() && guards.isOpen('detail'), section: 'detail', keys: '<kbd>Z</kbd>', label: 'toggle zen mode', handler: () => document.getElementById('detail-zen')?.click() });
|
||||
registerShortcut({ key: 'Escape', priority: 80, guard: () => !isDialogOpen() && guards.isOpen('modal'), section: 'global', label: 'close editor', hidden: true, handler: () => closeModal() });
|
||||
registerShortcut({ key: 'Escape', priority: 70, guard: () => !isDialogOpen() && guards.isOpen('search'), section: 'global', label: 'close search', hidden: true, handler: () => closeSearch() });
|
||||
registerShortcut({ key: 'Escape', priority: 60, guard: () => !isDialogOpen() && guards.isOpen('tasks'), section: 'global', label: 'close tasks', hidden: true, handler: () => closeTasks() });
|
||||
@@ -316,17 +317,23 @@ registerShortcut({ key: 'Enter', guard: () => gBoard() && !!document.querySelect
|
||||
const focused = document.querySelector('#board .card-focused');
|
||||
if (focused) { window._openDetail(focused.dataset.id); clearCardFocus(); }
|
||||
}});
|
||||
// Delete selected cards
|
||||
registerShortcut({ match: (e) => (e.key === 'Delete' || e.key === 'Backspace') && !e.ctrlKey && gBoard() && getSelectedIds().length > 0, section: 'global', keys: '<kbd>Del</kbd>', label: 'delete selected', hidden: true, handler: async () => {
|
||||
const ids = getSelectedIds();
|
||||
// Delete selected or focused card
|
||||
registerShortcut({ match: (e) => (e.key === 'Delete' || e.key === 'Backspace') && !e.ctrlKey && gBoard() && (getSelectedIds().length > 0 || !!document.querySelector('#board .card-focused')), section: 'global', keys: '<kbd>⌫</kbd>', label: 'delete selected / focused', hidden: true, handler: async () => {
|
||||
let ids = getSelectedIds();
|
||||
if (!ids.length) {
|
||||
const focused = document.querySelector('#board .card-focused');
|
||||
if (focused) ids = [focused.dataset.id];
|
||||
}
|
||||
if (!ids.length) return;
|
||||
if (localStorage.getItem('hyprcrd-confirm-delete') !== '0') {
|
||||
const ok = await showDialog({ title: 'delete cards', message: `Delete ${ids.length} card${ids.length > 1 ? 's' : ''}?`, danger: true, okLabel: 'Delete' });
|
||||
if (!ok) return;
|
||||
}
|
||||
const { animateCardRemoval } = await import('./modules/board.js');
|
||||
const { animateCardRemoval, clearCardFocus } = await import('./modules/board.js');
|
||||
await animateCardRemoval(ids);
|
||||
for (const id of ids) await api(`api/cards/${id}`, { method: 'DELETE' });
|
||||
clearSelection();
|
||||
clearCardFocus();
|
||||
await window._reloadAll();
|
||||
}});
|
||||
|
||||
|
||||
Reference in new issue
Block a user