diff --git a/src/client/components/deck/column.vue b/src/client/components/deck/column.vue index 9a744e2d6b..5c131e49ec 100644 --- a/src/client/components/deck/column.vue +++ b/src/client/components/deck/column.vue @@ -207,7 +207,7 @@ export default defineComponent({ }, showMenu() { - this.$root.menu({ + this.$store.dispatch('showMenu', { items: this.getMenu(), source: this.$refs.menu, }); diff --git a/src/client/components/drive.file.vue b/src/client/components/drive.file.vue index bbe7310064..86e0035b27 100644 --- a/src/client/components/drive.file.vue +++ b/src/client/components/drive.file.vue @@ -82,7 +82,7 @@ export default defineComponent({ if (this.selectMode) { this.$emit('chosen', this.file); } else { - this.$root.menu({ + this.$store.dispatch('showMenu', { items: [{ text: this.$t('rename'), icon: faICursor, diff --git a/src/client/components/menu.vue b/src/client/components/menu.vue index b68f50190a..b0c4618d29 100644 --- a/src/client/components/menu.vue +++ b/src/client/components/menu.vue @@ -1,6 +1,6 @@ diff --git a/src/client/components/note.vue b/src/client/components/note.vue index 05ef5d6f9b..e2a2dc2eb1 100644 --- a/src/client/components/note.vue +++ b/src/client/components/note.vue @@ -452,7 +452,7 @@ export default defineComponent({ renote(viaKeyboard = false) { pleaseLogin(this.$root); this.blur(); - this.$root.menu({ + this.$store.dispatch('showMenu', { items: [{ text: this.$t('renote'), icon: faRetweet, @@ -685,7 +685,7 @@ export default defineComponent({ }))]); } - this.$root.menu({ + this.$store.dispatch('showMenu', { items: menu, source: this.$refs.menuButton, viaKeyboard @@ -694,7 +694,7 @@ export default defineComponent({ showRenoteMenu(viaKeyboard = false) { if (!this.isMyRenote) return; - this.$root.menu({ + this.$store.dispatch('showMenu', { items: [{ text: this.$t('unrenote'), icon: faTrashAlt, diff --git a/src/client/components/popup.vue b/src/client/components/popup.vue index 825f9987cd..505f24aea9 100644 --- a/src/client/components/popup.vue +++ b/src/client/components/popup.vue @@ -1,3 +1,5 @@ +// popupはmodalと統合 + @@ -18,6 +20,7 @@ export default defineComponent({ DefaultUI, DeckUI, XDialog: defineAsyncComponent(() => import('./components/dialog.vue')), + XMenu: defineAsyncComponent(() => import('./components/menu.vue')), XPostFormDialog: defineAsyncComponent(() => import('./components/post-form-dialog.vue')), }, @@ -51,6 +54,12 @@ export default defineComponent({ // what: ダイアログが複数ある場合は、一番最後に追加されたダイアログを表示する // why: ダイアログが一度に複数表示されるとユーザビリティが悪いため。 return this.$store.state.dialogs[this.$store.state.dialogs.length - 1]; + }, + + menu() { + if (this.$store.state.menus.length === 0) return null; + + return this.$store.state.menus[this.$store.state.menus.length - 1]; } }, diff --git a/src/client/scripts/select-file.ts b/src/client/scripts/select-file.ts index 9e6f3e3fc1..a89aaddbf3 100644 --- a/src/client/scripts/select-file.ts +++ b/src/client/scripts/select-file.ts @@ -65,7 +65,7 @@ export function selectFile(component: any, src: any, label: string | null, multi }; - component.$root.menu({ + component.$store.dispatch('showMenu', { items: [label ? { text: label, type: 'label' diff --git a/src/client/store.ts b/src/client/store.ts index b703baf3ae..3a99a24365 100644 --- a/src/client/store.ts +++ b/src/client/store.ts @@ -115,6 +115,7 @@ export const store = createStore({ text: string; result: any; }[], + menus: [], postForm: null, fullView: false, @@ -277,6 +278,10 @@ export const store = createStore({ state.dialogs = state.dialogs.filter(d => d.id !== dialogId); }, + addMenu(state, menu) { + state.menus.push(menu); + }, + setPostForm(state, postForm) { if (state.postForm != null && postForm != null) return; state.postForm = postForm; @@ -392,6 +397,21 @@ export const store = createStore({ }); }, + showMenu(ctx, opts) { + return new Promise((res, rej) => { + const menu = reactive({ + ...opts, + result: null, + id: Math.random().toString() // TODO: uuidとか使う + }); + ctx.commit('addMenu', menu); + const unwatch = watch(() => menu.result, result => { + unwatch(); + res(result); + }); + }); + }, + api(ctx, { endpoint, data, token }) { if (++ctx.state.pendingApiRequestsCount === 1) { // TODO: spinnerの表示はstoreでやらない diff --git a/src/client/widgets/timeline.vue b/src/client/widgets/timeline.vue index bd0b7ba0c9..b82c4fd849 100644 --- a/src/client/widgets/timeline.vue +++ b/src/client/widgets/timeline.vue @@ -88,7 +88,7 @@ export default defineComponent({ this.setSrc('list'); } })); - this.$root.menu({ + this.$store.dispatch('showMenu', { items: [{ text: this.$t('_timelines.home'), icon: faHome,