This commit is contained in:
syuilo 2020-09-06 00:20:06 +09:00
parent e441ee9d8a
commit 4d68baca0d
17 changed files with 117 additions and 27 deletions

View File

@ -207,7 +207,7 @@ export default defineComponent({
},
showMenu() {
this.$root.menu({
this.$store.dispatch('showMenu', {
items: this.getMenu(),
source: this.$refs.menu,
});

View File

@ -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,

View File

@ -1,6 +1,6 @@
<template>
<x-popup :source="source" :no-center="noCenter" :fixed="fixed" :width="width" ref="popup" @closed="() => { $emit('closed'); destroyDom(); }" v-hotkey.global="keymap">
<div class="rrevdjwt" :class="{ left: align === 'left' }" ref="items">
<x-modal :source="source" :no-center="noCenter" ref="popup" @click="" @closed="$store.commit('removeMenu', id)" :showing="showing">
<div class="rrevdjwt" :class="{ left: align === 'left' }" ref="items" :style="{ width: width + 'px' }">
<template v-for="(item, i) in items.filter(item => item !== undefined)">
<div v-if="item === null" class="divider" :key="i"></div>
<span v-else-if="item.type === 'label'" class="label item" :key="i">
@ -29,18 +29,18 @@
</button>
</template>
</div>
</x-popup>
</x-modal>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { faCircle } from '@fortawesome/free-solid-svg-icons';
import XPopup from './popup.vue';
import XModal from './modal.vue';
import { focusPrev, focusNext } from '../scripts/focus';
export default defineComponent({
components: {
XPopup
XModal
},
props: {
source: {
@ -58,10 +58,6 @@ export default defineComponent({
type: Boolean,
required: false
},
fixed: {
type: Boolean,
required: false
},
width: {
type: Number,
required: false

View File

@ -14,6 +14,8 @@
<script lang="ts">
import { defineComponent } from 'vue';
// memo: popup.vuefixedsource辿
export default defineComponent({
emits: ['click', 'esc', 'closed'],
props: {
@ -26,6 +28,9 @@ export default defineComponent({
required: false,
default: true,
},
sourceEl: {
required: false,
}
},
computed: {
keymap(): any {
@ -34,6 +39,64 @@ export default defineComponent({
};
},
},
mounted() {
this.$nextTick(() => {
const popover = this.$refs.content as any;
const rect = this.source.getBoundingClientRect();
const width = popover.offsetWidth;
const height = popover.offsetHeight;
let left;
let top;
if (this.$root.isMobile && !this.noCenter) {
const x = rect.left + (this.fixed ? 0 : window.pageXOffset) + (this.source.offsetWidth / 2);
const y = rect.top + (this.fixed ? 0 : window.pageYOffset) + (this.source.offsetHeight / 2);
left = (x - (width / 2));
top = (y - (height / 2));
popover.style.transformOrigin = 'center';
} else {
const x = rect.left + (this.fixed ? 0 : window.pageXOffset) + (this.source.offsetWidth / 2);
const y = rect.top + (this.fixed ? 0 : window.pageYOffset) + this.source.offsetHeight;
left = (x - (width / 2));
top = y;
}
if (this.fixed) {
if (left + width > window.innerWidth) {
left = window.innerWidth - width;
popover.style.transformOrigin = 'center';
}
if (top + height > window.innerHeight) {
top = window.innerHeight - height;
popover.style.transformOrigin = 'center';
}
} else {
if (left + width - window.pageXOffset > window.innerWidth) {
left = window.innerWidth - width + window.pageXOffset;
popover.style.transformOrigin = 'center';
}
if (top + height - window.pageYOffset > window.innerHeight) {
top = window.innerHeight - height + window.pageYOffset;
popover.style.transformOrigin = 'center';
}
}
if (top < 0) {
top = 0;
}
if (left < 0) {
left = 0;
}
popover.style.left = left + 'px';
popover.style.top = top + 'px';
});
},
});
</script>

View File

@ -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,

View File

@ -1,3 +1,5 @@
// popupmodal
<template>
<div class="mk-popup" v-hotkey.global="keymap">
<transition :name="$store.state.device.animation ? 'bg-fade' : ''" appear>

View File

@ -80,7 +80,7 @@ export default defineComponent({
},
showFileMenu(file, ev: MouseEvent) {
if (this.menu) return;
this.menu = this.$root.menu({
this.menu = this.$store.dispatch('showMenu', {
items: [{
text: this.$t('renameFile'),
icon: faICursor,

View File

@ -346,7 +346,7 @@ export default defineComponent({
},
chooseFileFrom(ev) {
this.$root.menu({
this.$store.dispatch('showMenu', {
items: [{
type: 'label',
text: this.$t('attachFile'),
@ -612,7 +612,7 @@ export default defineComponent({
},
showActions(ev) {
this.$root.menu({
this.$store.dispatch('showMenu', {
items: this.$store.state.postFormActions.map(action => ({
text: action.title,
action: () => {

View File

@ -149,7 +149,7 @@ export default defineComponent({
action: () => { this.switchAccount(account); }
}));
this.$root.menu({
this.$store.dispatch('showMenu', {
items: [...[{
type: 'link',
text: this.$t('profile'),
@ -164,7 +164,7 @@ export default defineComponent({
icon: faPlus,
text: this.$t('addAcount'),
action: () => {
this.$root.menu({
this.$store.dispatch('showMenu', {
items: [{
text: this.$t('existingAcount'),
action: () => { this.addAcount(); },
@ -187,7 +187,7 @@ export default defineComponent({
},
oepnInstanceMenu(ev) {
this.$root.menu({
this.$store.dispatch('showMenu', {
items: [{
type: 'link',
text: this.$t('dashboard'),
@ -250,7 +250,7 @@ export default defineComponent({
action: def.action,
indicate: def.indicated,
}));
this.$root.menu({
this.$store.dispatch('showMenu', {
items: [...items, null, {
type: 'link',
text: this.$t('help'),

View File

@ -39,7 +39,7 @@ export default defineComponent({
methods: {
menu(ev) {
this.menuOpened = true;
this.$root.menu({
this.$store.dispatch('showMenu', {
items: [{
text: this.$t('addFile'),
type: 'label'

View File

@ -171,7 +171,7 @@ export default defineComponent({
this.$router.push(`/channels/${channel.id}`);
}
}));
this.$root.menu({
this.$store.dispatch('showMenu', {
items: [{
text: this.$t('_timelines.home'),
icon: faHome,

View File

@ -115,7 +115,7 @@ export default defineComponent({
},
start(ev) {
this.$root.menu({
this.$store.dispatch('showMenu', {
items: [{
text: this.$t('messagingWithUser'),
icon: faUser,

View File

@ -255,7 +255,7 @@ export default defineComponent({
showTypeMenu(e: MouseEvent) {
return new Promise<ThemeValue>((resolve) => {
this.$root.menu({
this.$store.dispatch('showMenu', {
items: [{
text: this.$t('_theme.defaultValue'),
action: () => resolve(null),

View File

@ -4,6 +4,8 @@
<XPostFormDialog v-if="$store.state.postForm" v-bind="$store.state.postForm"/>
<XMenu v-if="menu" v-bind="menu" :key="menu.id"/>
<XDialog v-if="dialog" v-bind="dialog" :key="dialog.id"/>
</template>
@ -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];
}
},

View File

@ -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'

View File

@ -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でやらない

View File

@ -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,