Skip to content

Commit 7e6e1e6

Browse files
committed
Frontend: Update code examples in src/common/README.md photoprism#5145 photoprism#5307 photoprism#5313
Signed-off-by: Michael Mayer <[email protected]>
1 parent efb720c commit 7e6e1e6

File tree

7 files changed

+28
-12
lines changed

7 files changed

+28
-12
lines changed

AGENTS.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# PhotoPrism® Repository Guidelines
22

3-
**Last Updated:** November 11, 2025
3+
**Last Updated:** November 12, 2025
44

55
## Purpose
66

@@ -224,6 +224,8 @@ Note: Across our public documentation, official images, and in production, the c
224224

225225
- Dialogs must follow the shared focus pattern documented in `frontend/src/common/README.md`.
226226
- Always expose `ref="dialog"` on `<v-dialog>` overlays, call `$view.enter/leave` in `@after-enter` / `@after-leave`, and avoid positive `tabindex` values.
227+
- Persistent dialogs (those with the `persistent` prop) must handle Escape via `@keydown.esc.exact` so Vuetify’s default rejection animation is suppressed; keep other shortcuts on `@keyup` so inner inputs can cancel them first.
228+
- Global shortcuts run through `onShortCut(ev)` in `common/view.js`; it only forwards Escape and `ctrl`/`meta` combinations, so do not rely on it for arbitrary keys.
227229
- When a dialog opens nested menus (for example, combobox suggestion lists), ensure they work with the global trap; see the README for troubleshooting tips.
228230

229231
## Safety & Data

frontend/CODEMAP.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
PhotoPrism — Frontend CODEMAP
22

3-
**Last Updated:** October 13, 2025
3+
**Last Updated:** November 12, 2025
44

55
Purpose
66
- Help agents and contributors navigate the Vue 3 + Vuetify 3 app quickly and make safe changes.
@@ -107,6 +107,10 @@ Common How‑Tos
107107
- Compute `key` from route + filter params and cap eager loads with `Rest.restoreCap(Model.batchSize())` (defaults to 10× the batch size).
108108
- Check `$view.wasBackwardNavigation()` when deciding whether to reuse stored state; `src/app.js` wires the router guards that keep the history direction in sync so no globals like `window.backwardsNavigationDetected` are needed.
109109

110+
- Handle dialog shortcuts
111+
- Persistent dialogs (`persistent` prop) must listen for Escape on `@keydown.esc.exact` to override Vuetify’s rejection animation; keep Enter and other actions on `@keyup` so child inputs can intercept them first.
112+
- Global shortcuts go through `onShortCut(ev)` in `common/view.js`. It only forwards Escape and `ctrl`/`meta` combinations, so do not depend on it for plain character keys.
113+
110114
Conventions & Safety
111115
- Avoid `v-html`; use `v-sanitize` or `$util.sanitizeHtml()` (build enforces this)
112116
- Keep big components lazy if needed; split views logically under `src/page`

frontend/src/common/README.md

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,12 @@ Vuetify dialogs are teleported to the overlay container, so consistent refs and
6464

6565
```vue
6666
<v-card-actions class="action-buttons">
67-
<v-btn variant="flat" color="button" class="action-cancel" @click.stop="close">
67+
<v-btn variant="flat" color="button"
68+
class="action-cancel" @click.stop="close">
6869
{{ $gettext(`Cancel`) }}
6970
</v-btn>
70-
<v-btn variant="flat" color="highlight" class="action-confirm" @click.stop="confirm">
71+
<v-btn variant="flat" color="highlight"
72+
class="action-confirm" @click.stop="confirm">
7173
{{ $gettext(`Delete`) }}
7274
</v-btn>
7375
</v-card-actions>
@@ -124,7 +126,8 @@ Both snippets allow focused inputs to veto shortcuts by calling `event.stopPropa
124126
`common/view.js` registers a single `keydown` listener that forwards shortcut keys to the active component:
125127

126128
```js
127-
// onKeyDown forwards global shortcuts (Escape, Ctrl/⌘ combos) to the active component when supported.
129+
// onKeyDown forwards global shortcuts (Escape, Ctrl/⌘ combos)
130+
// to the active component when supported.
128131
onKeyDown(ev) {
129132
if (!this.current || !ev || !(ev instanceof KeyboardEvent) || !ev.code) {
130133
return;
@@ -162,13 +165,15 @@ onKeyDown(ev) {
162165
<v-card ref="content" tabindex="-1">
163166
<v-card-title class="d-flex justify-start align-center ga-3">
164167
<v-icon icon="mdi-delete-outline" size="54" color="primary"></v-icon>
165-
<p class="text-subtitle-1">{{ $gettext(`Are you sure you want to permanently delete this file?`) }}</p>
168+
<p class="text-subtitle-1">{{ $gettext(`Are you sure?`) }}</p>
166169
</v-card-title>
167170
<v-card-actions class="action-buttons mt-1">
168-
<v-btn variant="flat" color="button" class="action-cancel" @click.stop="close">
171+
<v-btn variant="flat" color="button"
172+
class="action-cancel" @click.stop="close">
169173
{{ $gettext(`Cancel`) }}
170174
</v-btn>
171-
<v-btn color="highlight" variant="flat" class="action-confirm" @click.stop="confirm">
175+
<v-btn color="highlight" variant="flat"
176+
class="action-confirm" @click.stop="confirm">
172177
{{ $gettext(`Delete`) }}
173178
</v-btn>
174179
</v-card-actions>

frontend/src/component/lightbox.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
@keydown.space.exact="onKeyDown"
1818
@keydown.left.exact="onKeyDown"
1919
@keydown.right.exact="onKeyDown"
20-
@keydown.esc.stop="close"
20+
@keydown.esc.exact.stop="close"
2121
@click.capture="captureDialogClick"
2222
@pointerdown.capture="captureDialogPointerDown"
2323
>

frontend/src/component/location/dialog.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
scrim
99
scrollable
1010
class="p-location-dialog"
11-
@keydown.esc="close"
11+
@keydown.esc.exact="close"
1212
@after-enter="afterEnter"
1313
@after-leave="afterLeave"
1414
>

frontend/src/component/photo/edit/dialog.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
@after-leave="afterLeave"
1313
@keydown.left.exact="onKeyLeft"
1414
@keydown.right.exact="onKeyRight"
15-
@keydown.esc.stop="onClose"
15+
@keydown.esc.exact.stop="onClose"
1616
>
1717
<v-card ref="content" tabindex="-1" :tile="$vuetify.display.smAndDown">
1818
<v-toolbar flat color="navigation" :density="$vuetify.display.smAndDown ? 'compact' : 'comfortable'">

frontend/src/page/library/errors.vue

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,12 @@
111111
@close="dialog.delete = false"
112112
@confirm="onConfirmDelete"
113113
></p-confirm-dialog>
114-
<v-dialog :model-value="details.visible" max-width="550" class="p-dialog">
114+
<v-dialog
115+
:model-value="details.visible"
116+
max-width="550"
117+
class="p-dialog"
118+
@keydown.esc.exact="details.visible = false"
119+
>
115120
<v-card>
116121
<v-card-title class="d-flex justify-start align-center ga-3">
117122
<v-icon v-if="details.err.Level === 'error'" icon="mdi-alert-circle-outline" color="error"></v-icon>

0 commit comments

Comments
 (0)