This commit is contained in:
parent
225eabb19d
commit
615e25f4fa
|
@ -39,7 +39,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<MkSwitchButton :class="$style.switchButton" :checked="item.ref" :disabled="item.disabled" @toggle="switchItem(item)" />
|
<MkSwitchButton :class="$style.switchButton" :checked="item.ref" :disabled="item.disabled" @toggle="switchItem(item)" />
|
||||||
<span :class="$style.switchText">{{ item.text }}</span>
|
<span :class="$style.switchText">{{ item.text }}</span>
|
||||||
</button>
|
</button>
|
||||||
<div v-else-if="item.type === 'parent'" role="menuitem" :tabindex="i" :class="[$style.item, $style.parent, { [$style.childShowing]: childShowingItem === item }]" @mouseenter="showChildren(item, $event)" @click.stop="showChildren(item, $event)">
|
<div v-else-if="item.type === 'parent'" role="menuitem" :tabindex="i" :class="[$style.item, $style.parent, { [$style.childShowing]: childShowingItem === item }]" @mouseenter="isTouchUsing ? null : showChildren(item, $event)" @click="!isTouchUsing ? null : showChildren(item, $event)">
|
||||||
<i v-if="item.icon" class="ti-fw" :class="[$style.icon, item.icon]"></i>
|
<i v-if="item.icon" class="ti-fw" :class="[$style.icon, item.icon]"></i>
|
||||||
<span>{{ item.text }}</span>
|
<span>{{ item.text }}</span>
|
||||||
<span :class="$style.caret"><i class="ti ti-chevron-right ti-fw"></i></span>
|
<span :class="$style.caret"><i class="ti ti-chevron-right ti-fw"></i></span>
|
||||||
|
@ -68,8 +68,9 @@ import MkSwitchButton from '@/components/MkSwitch.button.vue';
|
||||||
import { MenuItem, InnerMenuItem, MenuPending, MenuAction, MenuSwitch, MenuParent } from '@/types/menu';
|
import { MenuItem, InnerMenuItem, MenuPending, MenuAction, MenuSwitch, MenuParent } from '@/types/menu';
|
||||||
import * as os from '@/os';
|
import * as os from '@/os';
|
||||||
import { i18n } from '@/i18n';
|
import { i18n } from '@/i18n';
|
||||||
|
import { isTouchUsing } from '@/scripts/touch';
|
||||||
|
|
||||||
const childrenCache = new WeakMap<MenuParent, MenuItem[]>();
|
const childrenCache = new WeakMap<MenuParent, Ref<(MenuItem | MenuPending)[]>>();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
@ -136,11 +137,6 @@ function childActioned() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const onGlobalMousedown = (event: MouseEvent) => {
|
const onGlobalMousedown = (event: MouseEvent) => {
|
||||||
console.log('globalmousedown', itemsEl);
|
|
||||||
if (!itemsEl || !document.body.contains(itemsEl)) {
|
|
||||||
document.removeEventListener('mousedown', onGlobalMousedown);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (childTarget && (event.target === childTarget || childTarget.contains(event.target))) return;
|
if (childTarget && (event.target === childTarget || childTarget.contains(event.target))) return;
|
||||||
if (child && child.checkHit(event)) return;
|
if (child && child.checkHit(event)) return;
|
||||||
closeChild();
|
closeChild();
|
||||||
|
@ -156,30 +152,29 @@ function onItemMouseLeave(item) {
|
||||||
if (childCloseTimer) window.clearTimeout(childCloseTimer);
|
if (childCloseTimer) window.clearTimeout(childCloseTimer);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function showChildren(item: MenuParent, ev: MouseEvent) {
|
function showChildren(item: MenuParent, ev: MouseEvent) {
|
||||||
console.log(ev);
|
|
||||||
if (props.asDrawer && childrenCache.has(item)) return;
|
if (props.asDrawer && childrenCache.has(item)) return;
|
||||||
const children: Ref<(MenuItem | MenuPending)[]> = ref([]);
|
|
||||||
if (!item.noCache && childrenCache.has(item)) {
|
const children = (() => {
|
||||||
children.value = childrenCache.get(item)!;
|
if (!item.noCache && childrenCache.has(item)) {
|
||||||
} else {
|
return childrenCache.get(item)!;
|
||||||
if (typeof item.children === 'function') {
|
|
||||||
children.value = [{
|
|
||||||
type: 'pending',
|
|
||||||
}];
|
|
||||||
Promise.resolve(item.children()).then(x => {
|
|
||||||
children.value = x;
|
|
||||||
childrenCache.set(item, x);
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
children.value = item.children;
|
if (typeof item.children === 'function') {
|
||||||
|
const result: Ref<(MenuItem | MenuPending)[]> = ref([{ type: 'pending' }]);
|
||||||
|
childrenCache.set(item, result);
|
||||||
|
Promise.resolve(item.children()).then(x => {
|
||||||
|
result.value = x;
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
} else {
|
||||||
|
return ref(item.children) as Ref<(MenuItem | MenuPending)[]>;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
})();
|
||||||
|
|
||||||
if (props.asDrawer) {
|
if (props.asDrawer) {
|
||||||
os.popupMenu(children as Ref<MenuItem[]>, ev.currentTarget ?? ev.target).finally(() => {
|
os.popupMenu(children as Ref<MenuItem[]>, ev.currentTarget ?? ev.target).finally(() => {
|
||||||
childrenCache.delete(item);
|
childrenCache.delete(item);
|
||||||
console.log('child drawer close');
|
|
||||||
emit('close');
|
emit('close');
|
||||||
});
|
});
|
||||||
emit('hide');
|
emit('hide');
|
||||||
|
|
|
@ -32,7 +32,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
})"
|
})"
|
||||||
:duration="transitionDuration" appear @afterLeave="afterLeave" @enter="emit('opening')" @afterEnter="onOpened"
|
:duration="transitionDuration" appear @afterLeave="afterLeave" @enter="emit('opening')" @afterEnter="onOpened"
|
||||||
>
|
>
|
||||||
<div v-show="manualShowing != null ? manualShowing : showing" v-hotkey.global="keymap" :class="[$style.root, { [$style.drawer]: type === 'drawer', [$style.dialog]: type === 'dialog', [$style.popup]: type === 'popup' }]" :style="{ zIndex, pointerEvents: (manualShowing != null ? manualShowing : showing) ? 'auto' : 'none', '--transformOrigin': transformOrigin }">
|
<div v-show="manualShowing != null ? (manuallyClosed ? false : manualShowing) : showing" v-hotkey.global="keymap" :class="[$style.root, { [$style.drawer]: type === 'drawer', [$style.dialog]: type === 'dialog', [$style.popup]: type === 'popup' }]" :style="{ zIndex, pointerEvents: (manualShowing != null ? manualShowing : showing) ? 'auto' : 'none', '--transformOrigin': transformOrigin }">
|
||||||
<div data-cy-bg :data-cy-transparent="isEnableBgTransparent" class="_modalBg" :class="[$style.bg, { [$style.bgTransparent]: isEnableBgTransparent }]" :style="{ zIndex }" @click="onBgClick" @mousedown.self="onBgClick" @contextmenu.prevent.stop="() => {}"></div>
|
<div data-cy-bg :data-cy-transparent="isEnableBgTransparent" class="_modalBg" :class="[$style.bg, { [$style.bgTransparent]: isEnableBgTransparent }]" :style="{ zIndex }" @click="onBgClick" @mousedown.self="onBgClick" @contextmenu.prevent.stop="() => {}"></div>
|
||||||
<div ref="content" :class="[$style.content, { [$style.fixed]: fixed }]" :style="{ zIndex }" @click.self="onBgClick">
|
<div ref="content" :class="[$style.content, { [$style.fixed]: fixed }]" :style="{ zIndex }" @click.self="onBgClick">
|
||||||
<slot :max-height="maxHeight" :type="type"></slot>
|
<slot :max-height="maxHeight" :type="type"></slot>
|
||||||
|
@ -150,18 +150,19 @@ function close(opts: { useSendAnimation?: boolean } = {}) {
|
||||||
showing = false;
|
showing = false;
|
||||||
manuallyClosed = true;
|
manuallyClosed = true;
|
||||||
emit('close');
|
emit('close');
|
||||||
|
if (props.manualShowing === false) {
|
||||||
|
afterLeave();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function afterLeave() {
|
function afterLeave() {
|
||||||
emit('hide');
|
emit('hide');
|
||||||
console.log('closed?', props.manualShowing, manuallyClosed);
|
|
||||||
if (props.manualShowing === null || manuallyClosed) {
|
if (props.manualShowing === null || manuallyClosed) {
|
||||||
emit('closed');
|
emit('closed');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onBgClick(e) {
|
function onBgClick(e) {
|
||||||
console.log(e, contentClicking);
|
|
||||||
if (contentClicking) return;
|
if (contentClicking) return;
|
||||||
emit('click');
|
emit('click');
|
||||||
}
|
}
|
||||||
|
@ -296,10 +297,8 @@ const onOpened = () => {
|
||||||
// モーダルコンテンツにマウスボタンが押され、コンテンツ外でマウスボタンが離されたときにモーダルバックグラウンドクリックと判定させないためにマウスイベントを監視しフラグ管理する
|
// モーダルコンテンツにマウスボタンが押され、コンテンツ外でマウスボタンが離されたときにモーダルバックグラウンドクリックと判定させないためにマウスイベントを監視しフラグ管理する
|
||||||
const el = content!.children[0];
|
const el = content!.children[0];
|
||||||
el.addEventListener('mousedown', ev => {
|
el.addEventListener('mousedown', ev => {
|
||||||
console.log('mousedown');
|
|
||||||
contentClicking = true;
|
contentClicking = true;
|
||||||
window.addEventListener('mouseup', ev => {
|
window.addEventListener('mouseup', ev => {
|
||||||
console.log('mouseup');
|
|
||||||
// click イベントより先に mouseup イベントが発生するかもしれないのでちょっと待つ
|
// click イベントより先に mouseup イベントが発生するかもしれないのでちょっと待つ
|
||||||
window.setTimeout(() => {
|
window.setTimeout(() => {
|
||||||
contentClicking = false;
|
contentClicking = false;
|
||||||
|
|
|
@ -28,35 +28,27 @@ const emit = defineEmits<{
|
||||||
(ev: 'closing'): void;
|
(ev: 'closing'): void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
console.log('popup menu modal setup', props.items);
|
|
||||||
|
|
||||||
let modal = $shallowRef<InstanceType<typeof MkModal>>();
|
let modal = $shallowRef<InstanceType<typeof MkModal>>();
|
||||||
const manualShowing = ref(true);
|
const manualShowing = ref(true);
|
||||||
|
|
||||||
function click() {
|
function click() {
|
||||||
console.log('popup menu modal click', props.items);
|
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
|
||||||
function onModalClose() {
|
function onModalClose() {
|
||||||
console.log('popup menu modal close', props.items);
|
|
||||||
emit('closing');
|
emit('closing');
|
||||||
}
|
}
|
||||||
|
|
||||||
function onMenuClose() {
|
function onMenuClose() {
|
||||||
console.log('popup menu menu click', props.items);
|
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
|
||||||
function closed() {
|
function closed() {
|
||||||
console.log('popup menu modal closed', props.items);
|
|
||||||
emit('closed');
|
emit('closed');
|
||||||
}
|
}
|
||||||
|
|
||||||
function close() {
|
function close() {
|
||||||
console.log('popup menu close', props.items);
|
|
||||||
if (!modal) return;
|
if (!modal) return;
|
||||||
manualShowing.value = false;
|
|
||||||
modal.close();
|
modal.close();
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -550,7 +550,6 @@ export function popupMenu(items: MenuItem[] | Ref<MenuItem[]>, src?: HTMLElement
|
||||||
viaKeyboard: options?.viaKeyboard,
|
viaKeyboard: options?.viaKeyboard,
|
||||||
}, {
|
}, {
|
||||||
closed: () => {
|
closed: () => {
|
||||||
console.log('closed detected');
|
|
||||||
resolve();
|
resolve();
|
||||||
dispose();
|
dispose();
|
||||||
},
|
},
|
||||||
|
|
|
@ -330,7 +330,7 @@ export function getUserMenu(user: misskey.entities.UserDetailed, router: Router
|
||||||
}
|
}
|
||||||
|
|
||||||
const cleanup = () => {
|
const cleanup = () => {
|
||||||
console.log('user menu cleanup', cleanups);
|
if (_DEV_) console.log('user menu cleanup', cleanups);
|
||||||
cleanups.forEach(cleanup => cleanup());
|
cleanups.forEach(cleanup => cleanup());
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue