Skip to content

Commit c672b9a

Browse files
committed
fix: catch ctrl+f event to focus new search
-e Signed-off-by: Peter Ringelmann <peter.ringelmann@nextcloud.com>
1 parent e107c10 commit c672b9a

45 files changed

Lines changed: 365357 additions & 127 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

apps/settings/src/views/UserManagementNavigation.vue

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
<div class="account-management__search" role="search" :aria-label="t('settings', 'Search accounts and groups')">
2121
<NcInputField
22+
ref="searchField"
2223
v-model="searchInput"
2324
:label="t('settings', 'Search accounts and groups…')"
2425
:show-trailing-button="searchInput !== ''"
@@ -126,7 +127,7 @@
126127
import { mdiAccountOffOutline, mdiAccountOutline, mdiClose, mdiCogOutline, mdiHistory, mdiMagnify, mdiPlus, mdiShieldAccountOutline } from '@mdi/js'
127128
import { translate as t } from '@nextcloud/l10n'
128129
import debounce from 'debounce'
129-
import { computed, onBeforeUnmount, ref, watch } from 'vue'
130+
import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'
130131
import { useRoute } from 'vue-router/composables'
131132
import NcAppNavigation from '@nextcloud/vue/components/NcAppNavigation'
132133
import NcAppNavigationItem from '@nextcloud/vue/components/NcAppNavigationItem'
@@ -144,6 +145,7 @@ import { useStore } from '../store/index.js'
144145
const route = useRoute()
145146
const store = useStore()
146147
148+
const searchField = ref<InstanceType<typeof NcInputField>>()
147149
const searchInput = ref('')
148150
const commitSearch = debounce((query: string) => {
149151
store.commit('setSearchQuery', query)
@@ -156,6 +158,30 @@ function clearSearch() {
156158
}
157159
onBeforeUnmount(() => commitSearch.clear())
158160
161+
/**
162+
* Intercept Ctrl+F (Cmd+F on macOS) so it focuses the local search input
163+
* instead of opening the global unified search. We always stop propagation
164+
* to prevent the global handler from firing; preventDefault is skipped when
165+
* the field already has focus so a second Ctrl+F opens the browser's native
166+
* find-in-page dialog as an escape hatch.
167+
*
168+
* @param event - The keydown event
169+
*/
170+
function onKeyDown(event: KeyboardEvent) {
171+
if (!(event.ctrlKey || event.metaKey) || event.key !== 'f') {
172+
return
173+
}
174+
event.stopImmediatePropagation()
175+
const fieldEl = (searchField.value?.$el as HTMLElement | undefined) ?? null
176+
if (fieldEl?.contains(document.activeElement)) {
177+
return
178+
}
179+
event.preventDefault()
180+
searchField.value?.focus()
181+
}
182+
onMounted(() => window.addEventListener('keydown', onKeyDown, { capture: true }))
183+
onBeforeUnmount(() => window.removeEventListener('keydown', onKeyDown, { capture: true }))
184+
159185
/** State of the 'new-account' dialog */
160186
const isDialogOpen = ref(false)
161187

dist/comments-comments-app.mjs

Lines changed: 102 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,103 @@
1-
import{l as o}from"./activity-DdSAHrqw.chunk.mjs";import{a as m,t as s}from"./translation-DoG5ZELJ-DJHEP2RB.chunk.mjs";import{c as n}from"./pinia-BrO7AuLF.chunk.mjs";import{e as r}from"./preload-helper-DoJVKVMq.chunk.mjs";import{C as a}from"./FilesSidebarTab-7Od1VwNN.chunk.mjs";import"./index-Bp9-GhMo.chunk.mjs";import"./public-CvthP4YJ.chunk.mjs";import"./index-C1xmmKTZ-B9NwkrZ2.chunk.mjs";import"./NcDialog-nDc1gW50-CpnK8gUQ.chunk.mjs";import"./NcModal-kyWZ3UFC-BxKwwKAq.chunk.mjs";import"./mdi-BUoBIgaz.chunk.mjs";import"./NcIconSvgWrapper-De-2-ukl-CcvQeIAt.chunk.mjs";import"./Web-rJva_rmF.chunk.mjs";import"./TrashCanOutline-D66Xz3gd.chunk.mjs";import"./NcAvatar-ruClKRzS-C0OkDCcs.chunk.mjs";import"./index-CzqMHoWC.chunk.mjs";import"./util-Caafb9Jl.chunk.mjs";import"./colors-BfjxNgsx-Dyl_2CuU.chunk.mjs";import"./NcUserStatusIcon-JWiuiAXe-RsQTD2PO.chunk.mjs";import"./PencilOutline-BzoFsBsK.chunk.mjs";import"./NcDateTime.vue_vue_type_script_setup_true_lang-B4upiZjL-L27IwP9h.chunk.mjs";import"./NcEmptyContent-CDgWCt_m-MnlDvtO9.chunk.mjs";import"./CommentView-BP3FygMe.chunk.mjs";/* empty css */import"./NcUserBubble-BE6yD-R0-aMsD0K5b.chunk.mjs";import"./GetComments-DHvGzfol.chunk.mjs";import"./index-BDmvh1Np.chunk.mjs";class e{app;instance;constructor(t="files",i={}){const p=n();this.app=r(a,{...i.propsData??{},...i.props??{},resourceType:t}),this.app.mixin({data(){return{logger:o}},methods:{t:s,n:m}}),this.app.use(p),i.el&&(this.instance=this.app.mount(i.el))}$mount(t){this.instance&&this.app.unmount(),this.instance=this.app.mount(t)}$unmount(){this.app.unmount(),this.instance=void 0}update(t){this.instance&&this.instance.update(t)}}window.OCA&&!window.OCA.Comments&&Object.assign(window.OCA,{Comments:{}}),Object.assign(window.OCA.Comments,{View:e}),o.debug("OCA.Comments.View initialized");
1+
const appName = "nextcloud-ui";
2+
const appVersion = "1.0.0";
3+
import { l as logger } from "./activity-T1z5SEpQ.chunk.mjs";
4+
import { a as translatePlural, t as translate } from "./translation-DoG5ZELJ-BjhwdF87.chunk.mjs";
5+
import { c as createPinia } from "./pinia-QL4zg7IU.chunk.mjs";
6+
import { e as createApp } from "./Web-DZB3kNgd.chunk.mjs";
7+
import { C as CommentsApp } from "./FilesSidebarTab-EG-_zLyQ.chunk.mjs";
8+
import "./index-DzGPUIIw.chunk.mjs";
9+
import "./public-BOTv8zL5.chunk.mjs";
10+
import "./util-CV4gl569.chunk.mjs";
11+
import "./index-C1xmmKTZ-B1s4uv1T.chunk.mjs";
12+
import "./NcDialog-nDc1gW50-IgYjPKc0.chunk.mjs";
13+
import "./autolink-U5pBzLgI-Pp1RlhKi.chunk.mjs";
14+
import "./ArrowRight-Bqdh1jJN.chunk.mjs";
15+
import "./NcIconSvgWrapper-De-2-ukl-D4fii7IT.chunk.mjs";
16+
import "./PencilOutline-BpohmyA3.chunk.mjs";
17+
import "./mdi-DSkVotM5.chunk.mjs";
18+
import "./NcAvatar-ruClKRzS-DuS7YXf6.chunk.mjs";
19+
import "./index-BLBICdD3.chunk.mjs";
20+
import "./colors-BfjxNgsx-DyC4Rnj5.chunk.mjs";
21+
import "./NcUserStatusIcon-JWiuiAXe-BQbtMEov.chunk.mjs";
22+
import "./NcActionButton-BuRnYpJX-D8zeIhEM.chunk.mjs";
23+
import "./NcDateTime.vue_vue_type_script_setup_true_lang-B4upiZjL-CKWCeu2D.chunk.mjs";
24+
import "./NcEmptyContent-CDgWCt_m-CTXOS_Yk.chunk.mjs";
25+
import "./CommentView-UxeKj3LJ.chunk.mjs";
26+
/* empty css */
27+
import "./NcUserBubble-BE6yD-R0-4_fb61Nk.chunk.mjs";
28+
import "./GetComments-0XwtoPLA.chunk.mjs";
29+
import "./index-H1GawPmo.chunk.mjs";
30+
/*!
31+
* SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
32+
* SPDX-License-Identifier: AGPL-3.0-or-later
33+
*/
34+
class CommentInstance {
35+
app;
36+
instance;
37+
/**
38+
* Initialize a new Comments instance for the desired type
39+
*
40+
* @param resourceType - The comments endpoint type
41+
* @param options - The vue options (props, parent, el...)
42+
*/
43+
constructor(resourceType = "files", options = {}) {
44+
const pinia = createPinia();
45+
this.app = createApp(
46+
CommentsApp,
47+
{
48+
...options.propsData ?? {},
49+
...options.props ?? {},
50+
resourceType
51+
}
52+
);
53+
this.app.mixin({
54+
data() {
55+
return {
56+
logger
57+
};
58+
},
59+
methods: {
60+
t: translate,
61+
n: translatePlural
62+
}
63+
});
64+
this.app.use(pinia);
65+
if (options.el) {
66+
this.instance = this.app.mount(options.el);
67+
}
68+
}
69+
/**
70+
* Mount the Comments instance to a new element.
71+
*
72+
* @param el - The element to mount the instance on
73+
*/
74+
$mount(el) {
75+
if (this.instance) {
76+
this.app.unmount();
77+
}
78+
this.instance = this.app.mount(el);
79+
}
80+
/**
81+
* Unmount the Comments instance from the DOM and destroy it.
82+
*/
83+
$unmount() {
84+
this.app.unmount();
85+
this.instance = void 0;
86+
}
87+
/**
88+
* Update the current resource id.
89+
*
90+
* @param id - The new resource id to load the comments for
91+
*/
92+
update(id) {
93+
if (this.instance) {
94+
this.instance.update(id);
95+
}
96+
}
97+
}
98+
if (window.OCA && !window.OCA.Comments) {
99+
Object.assign(window.OCA, { Comments: {} });
100+
}
101+
Object.assign(window.OCA.Comments, { View: CommentInstance });
102+
logger.debug("OCA.Comments.View initialized");
2103
//# sourceMappingURL=comments-comments-app.mjs.map

0 commit comments

Comments
 (0)