refactor(frontend): menuのdividerをnullで表現するのをやめる

This commit is contained in:
syuilo 2023-12-12 10:26:37 +09:00
parent ebdb443180
commit b691126bff
17 changed files with 44 additions and 45 deletions

View file

@ -616,7 +616,7 @@ function getMenu() {
type: 'switch', type: 'switch',
text: i18n.ts.keepOriginalUploading, text: i18n.ts.keepOriginalUploading,
ref: keepOriginal, ref: keepOriginal,
}, null, { }, { type: 'divider' }, {
text: i18n.ts.addFile, text: i18n.ts.addFile,
type: 'label', type: 'label',
}, { }, {
@ -627,7 +627,7 @@ function getMenu() {
text: i18n.ts.fromUrl, text: i18n.ts.fromUrl,
icon: 'ti ti-link', icon: 'ti ti-link',
action: () => { urlUpload(); }, action: () => { urlUpload(); },
}, null, { }, { type: 'divider' }, {
text: folder.value ? folder.value.name : i18n.ts.drive, text: folder.value ? folder.value.name : i18n.ts.drive,
type: 'label', type: 'label',
}, folder.value ? { }, folder.value ? {

View file

@ -13,7 +13,7 @@ SPDX-License-Identifier: AGPL-3.0-only
@contextmenu.self="e => e.preventDefault()" @contextmenu.self="e => e.preventDefault()"
> >
<template v-for="(item, i) in items2"> <template v-for="(item, i) in items2">
<div v-if="item === null" role="separator" :class="$style.divider"></div> <div v-if="item.type === 'divider'" role="separator" :class="$style.divider"></div>
<span v-else-if="item.type === 'label'" role="menuitem" :class="[$style.label, $style.item]"> <span v-else-if="item.type === 'label'" role="menuitem" :class="[$style.label, $style.item]">
<span>{{ item.text }}</span> <span>{{ item.text }}</span>
</span> </span>

View file

@ -464,7 +464,7 @@ function showRenoteMenu(viaKeyboard = false): void {
pleaseLogin(); pleaseLogin();
os.popupMenu([ os.popupMenu([
getCopyNoteLinkMenu(note.value, i18n.ts.copyLinkRenote), getCopyNoteLinkMenu(note.value, i18n.ts.copyLinkRenote),
null, { type: 'divider' },
getUnrenote(), getUnrenote(),
], renoteTime.value, { ], renoteTime.value, {
viaKeyboard: viaKeyboard, viaKeyboard: viaKeyboard,
@ -472,7 +472,7 @@ function showRenoteMenu(viaKeyboard = false): void {
} else { } else {
os.popupMenu([ os.popupMenu([
getCopyNoteLinkMenu(note.value, i18n.ts.copyLinkRenote), getCopyNoteLinkMenu(note.value, i18n.ts.copyLinkRenote),
null, { type: 'divider' },
getAbuseNoteMenu(note.value, i18n.ts.reportAbuseRenote), getAbuseNoteMenu(note.value, i18n.ts.reportAbuseRenote),
$i.isModerator || $i.isAdmin ? getUnrenote() : undefined, $i.isModerator || $i.isAdmin ? getUnrenote() : undefined,
], renoteTime.value, { ], renoteTime.value, {

View file

@ -13,7 +13,7 @@ SPDX-License-Identifier: AGPL-3.0-only
import { ref, shallowRef } from 'vue'; import { ref, shallowRef } from 'vue';
import MkModal from './MkModal.vue'; import MkModal from './MkModal.vue';
import MkMenu from './MkMenu.vue'; import MkMenu from './MkMenu.vue';
import { MenuItem } from '@/types/menu'; import { MenuItem } from '@/types/menu.js';
defineProps<{ defineProps<{
items: MenuItem[]; items: MenuItem[];

View file

@ -103,7 +103,7 @@ function showMenu(ev) {
action: () => { action: () => {
os.pageWindow('/about-misskey'); os.pageWindow('/about-misskey');
}, },
}, null, (instance.impressumUrl) ? { }, { type: 'divider' }, (instance.impressumUrl) ? {
text: i18n.ts.impressum, text: i18n.ts.impressum,
icon: 'ti ti-file-invoice', icon: 'ti ti-file-invoice',
action: () => { action: () => {
@ -121,7 +121,7 @@ function showMenu(ev) {
action: () => { action: () => {
window.open(instance.privacyPolicyUrl, '_blank', 'noopener'); window.open(instance.privacyPolicyUrl, '_blank', 'noopener');
}, },
} : undefined, (!instance.impressumUrl && !instance.tosUrl && !instance.privacyPolicyUrl) ? undefined : null, { } : undefined, (!instance.impressumUrl && !instance.tosUrl && !instance.privacyPolicyUrl) ? undefined : { type: 'divider' }, {
text: i18n.ts.help, text: i18n.ts.help,
icon: 'ti ti-help-circle', icon: 'ti ti-help-circle',
action: () => { action: () => {

View file

@ -546,7 +546,7 @@ export async function openEmojiPicker(src?: HTMLElement, opts, initialTextarea:
}); });
} }
export function popupMenu(items: MenuItem[] | Ref<MenuItem[]>, src?: HTMLElement, options?: { export function popupMenu(items: MenuItem[] | Ref<MenuItem[]>, src?: HTMLElement | null, options?: {
align?: string; align?: string;
width?: number; width?: number;
viaKeyboard?: boolean; viaKeyboard?: boolean;

View file

@ -60,7 +60,7 @@ function setFilter(ev) {
action: () => { action: () => {
includeTypes.value = null; includeTypes.value = null;
}, },
}, null, ...typeItems] : typeItems; }, { type: 'divider' }, ...typeItems] : typeItems;
os.popupMenu(items, ev.currentTarget ?? ev.target); os.popupMenu(items, ev.currentTarget ?? ev.target);
} }

View file

@ -406,7 +406,7 @@ function menu(ev: MouseEvent, profileId: string) {
icon: 'ti ti-download', icon: 'ti ti-download',
href: URL.createObjectURL(new Blob([JSON.stringify(profiles.value[profileId], null, 2)], { type: 'application/json' })), href: URL.createObjectURL(new Blob([JSON.stringify(profiles.value[profileId], null, 2)], { type: 'application/json' })),
download: `${profiles.value[profileId].name}.json`, download: `${profiles.value[profileId].name}.json`,
}, null, { }, { type: 'divider' }, {
text: ts.rename, text: ts.rename,
icon: 'ti ti-forms', icon: 'ti ti-forms',
action: () => rename(profileId), action: () => rename(profileId),
@ -414,7 +414,7 @@ function menu(ev: MouseEvent, profileId: string) {
text: ts._preferencesBackups.save, text: ts._preferencesBackups.save,
icon: 'ti ti-device-floppy', icon: 'ti ti-device-floppy',
action: () => save(profileId), action: () => save(profileId),
}, null, { }, { type: 'divider' }, {
text: ts.delete, text: ts.delete,
icon: 'ti ti-trash', icon: 'ti ti-trash',
action: () => deleteProfile(profileId), action: () => deleteProfile(profileId),

View file

@ -232,7 +232,7 @@ const age = computed(() => {
return calcAge(props.user.birthday); return calcAge(props.user.birthday);
}); });
function menu(ev) { function menu(ev: MouseEvent) {
const { menu, cleanup } = getUserMenu(user.value, router); const { menu, cleanup } = getUserMenu(user.value, router);
os.popupMenu(menu, ev.currentTarget ?? ev.target).finally(cleanup); os.popupMenu(menu, ev.currentTarget ?? ev.target).finally(cleanup);
} }

View file

@ -82,7 +82,7 @@ export function getDriveFileMenu(file: Misskey.entities.DriveFile, folder?: Miss
to: `/my/drive/file/${file.id}`, to: `/my/drive/file/${file.id}`,
text: i18n.ts._fileViewer.title, text: i18n.ts._fileViewer.title,
icon: 'ti ti-info-circle', icon: 'ti ti-info-circle',
}, null, { }, { type: 'divider' }, {
text: i18n.ts.rename, text: i18n.ts.rename,
icon: 'ti ti-forms', icon: 'ti ti-forms',
action: () => rename(file), action: () => rename(file),
@ -101,7 +101,7 @@ export function getDriveFileMenu(file: Misskey.entities.DriveFile, folder?: Miss
aspectRatio: NaN, aspectRatio: NaN,
uploadFolder: folder ? folder.id : folder, uploadFolder: folder ? folder.id : folder,
}), }),
}] : [], null, { }] : [], { type: 'divider' }, {
text: i18n.ts.createNoteFromTheFile, text: i18n.ts.createNoteFromTheFile,
icon: 'ti ti-pencil', icon: 'ti ti-pencil',
action: () => os.post({ action: () => os.post({
@ -118,7 +118,7 @@ export function getDriveFileMenu(file: Misskey.entities.DriveFile, folder?: Miss
text: i18n.ts.download, text: i18n.ts.download,
icon: 'ti ti-download', icon: 'ti ti-download',
download: file.name, download: file.name,
}, null, { }, { type: 'divider' }, {
text: i18n.ts.delete, text: i18n.ts.delete,
icon: 'ti ti-trash', icon: 'ti ti-trash',
danger: true, danger: true,
@ -126,7 +126,7 @@ export function getDriveFileMenu(file: Misskey.entities.DriveFile, folder?: Miss
}]; }];
if (defaultStore.state.devMode) { if (defaultStore.state.devMode) {
menu = menu.concat([null, { menu = menu.concat([{ type: 'divider' }, {
icon: 'ti ti-id', icon: 'ti ti-id',
text: i18n.ts.copyFileId, text: i18n.ts.copyFileId,
action: () => { action: () => {

View file

@ -61,7 +61,7 @@ export async function getNoteClipMenu(props: {
}, },
); );
}, },
})), null, { })), { type: 'divider' }, {
icon: 'ti ti-plus', icon: 'ti ti-plus',
text: i18n.ts.createNew, text: i18n.ts.createNew,
action: async () => { action: async () => {
@ -94,7 +94,7 @@ export async function getNoteClipMenu(props: {
}]; }];
} }
export function getAbuseNoteMenu(note: misskey.entities.Note, text: string): MenuItem { export function getAbuseNoteMenu(note: Misskey.entities.Note, text: string): MenuItem {
return { return {
icon: 'ti ti-exclamation-circle', icon: 'ti ti-exclamation-circle',
text, text,
@ -108,7 +108,7 @@ export function getAbuseNoteMenu(note: misskey.entities.Note, text: string): Men
}; };
} }
export function getCopyNoteLinkMenu(note: misskey.entities.Note, text: string): MenuItem { export function getCopyNoteLinkMenu(note: Misskey.entities.Note, text: string): MenuItem {
return { return {
icon: 'ti ti-link', icon: 'ti ti-link',
text, text,
@ -264,7 +264,7 @@ export function getNoteMenu(props: {
text: i18n.ts.unclip, text: i18n.ts.unclip,
danger: true, danger: true,
action: unclip, action: unclip,
}, null] : [] }, { type: 'divider' }] : []
), { ), {
icon: 'ti ti-info-circle', icon: 'ti ti-info-circle',
text: i18n.ts.details, text: i18n.ts.details,
@ -291,7 +291,7 @@ export function getNoteMenu(props: {
text: i18n.ts.translate, text: i18n.ts.translate,
action: translate, action: translate,
} : undefined, } : undefined,
null, { type: 'divider' },
statePromise.then(state => state.isFavorited ? { statePromise.then(state => state.isFavorited ? {
icon: 'ti ti-star-off', icon: 'ti ti-star-off',
text: i18n.ts.unfavorite, text: i18n.ts.unfavorite,
@ -338,7 +338,7 @@ export function getNoteMenu(props: {
}, },
/* /*
...($i.isModerator || $i.isAdmin ? [ ...($i.isModerator || $i.isAdmin ? [
null, { type: 'divider' },
{ {
icon: 'ti ti-speakerphone', icon: 'ti ti-speakerphone',
text: i18n.ts.promote, text: i18n.ts.promote,
@ -347,13 +347,13 @@ export function getNoteMenu(props: {
: [] : []
),*/ ),*/
...(appearNote.userId !== $i.id ? [ ...(appearNote.userId !== $i.id ? [
null, { type: 'divider' },
appearNote.userId !== $i.id ? getAbuseNoteMenu(appearNote, i18n.ts.reportAbuse) : undefined, appearNote.userId !== $i.id ? getAbuseNoteMenu(appearNote, i18n.ts.reportAbuse) : undefined,
] ]
: [] : []
), ),
...(appearNote.userId === $i.id || $i.isModerator || $i.isAdmin ? [ ...(appearNote.userId === $i.id || $i.isModerator || $i.isAdmin ? [
null, { type: 'divider' },
appearNote.userId === $i.id ? { appearNote.userId === $i.id ? {
icon: 'ti ti-edit', icon: 'ti ti-edit',
text: i18n.ts.deleteAndEdit, text: i18n.ts.deleteAndEdit,
@ -528,10 +528,9 @@ export function getRenoteMenu(props: {
}]); }]);
} }
// nullを挟むことで区切り線を出せる
const renoteItems = [ const renoteItems = [
...normalRenoteItems, ...normalRenoteItems,
...(channelRenoteItems.length > 0 && normalRenoteItems.length > 0) ? [null] : [], ...(channelRenoteItems.length > 0 && normalRenoteItems.length > 0) ? [{ type: 'divider' }] : [],
...channelRenoteItems, ...channelRenoteItems,
]; ];

View file

@ -183,7 +183,7 @@ export function getUserMenu(user: Misskey.entities.UserDetailed, router: Router
const canonical = user.host === null ? `@${user.username}` : `@${user.username}@${user.host}`; const canonical = user.host === null ? `@${user.username}` : `@${user.username}@${user.host}`;
os.post({ specified: user, initialText: `${canonical} ` }); os.post({ specified: user, initialText: `${canonical} ` });
}, },
}, null, { }, { type: 'divider' }, {
icon: 'ti ti-pencil', icon: 'ti ti-pencil',
text: i18n.ts.editMemo, text: i18n.ts.editMemo,
action: () => { action: () => {
@ -307,7 +307,7 @@ export function getUserMenu(user: Misskey.entities.UserDetailed, router: Router
}]); }]);
//} //}
menu = menu.concat([null, { menu = menu.concat([{ type: 'divider' }, {
icon: user.isMuted ? 'ti ti-eye' : 'ti ti-eye-off', icon: user.isMuted ? 'ti ti-eye' : 'ti ti-eye-off',
text: user.isMuted ? i18n.ts.unmute : i18n.ts.mute, text: user.isMuted ? i18n.ts.unmute : i18n.ts.mute,
action: toggleMute, action: toggleMute,
@ -329,7 +329,7 @@ export function getUserMenu(user: Misskey.entities.UserDetailed, router: Router
}]); }]);
} }
menu = menu.concat([null, { menu = menu.concat([{ type: 'divider' }, {
icon: 'ti ti-exclamation-circle', icon: 'ti ti-exclamation-circle',
text: i18n.ts.reportAbuse, text: i18n.ts.reportAbuse,
action: reportAbuse, action: reportAbuse,
@ -337,7 +337,7 @@ export function getUserMenu(user: Misskey.entities.UserDetailed, router: Router
} }
if (user.host !== null) { if (user.host !== null) {
menu = menu.concat([null, { menu = menu.concat([{ type: 'divider' }, {
icon: 'ti ti-refresh', icon: 'ti ti-refresh',
text: i18n.ts.updateRemoteUser, text: i18n.ts.updateRemoteUser,
action: userInfoUpdate, action: userInfoUpdate,
@ -345,7 +345,7 @@ export function getUserMenu(user: Misskey.entities.UserDetailed, router: Router
} }
if (defaultStore.state.devMode) { if (defaultStore.state.devMode) {
menu = menu.concat([null, { menu = menu.concat([{ type: 'divider' }, {
icon: 'ti ti-id', icon: 'ti ti-id',
text: i18n.ts.copyUserId, text: i18n.ts.copyUserId,
action: () => { action: () => {
@ -355,7 +355,7 @@ export function getUserMenu(user: Misskey.entities.UserDetailed, router: Router
} }
if ($i && meId === user.id) { if ($i && meId === user.id) {
menu = menu.concat([null, { menu = menu.concat([{ type: 'divider' }, {
icon: 'ti ti-pencil', icon: 'ti ti-pencil',
text: i18n.ts.editProfile, text: i18n.ts.editProfile,
action: () => { action: () => {
@ -365,7 +365,7 @@ export function getUserMenu(user: Misskey.entities.UserDetailed, router: Router
} }
if (userActions.length > 0) { if (userActions.length > 0) {
menu = menu.concat([null, ...userActions.map(action => ({ menu = menu.concat([{ type: 'divider' }, ...userActions.map(action => ({
icon: 'ti ti-plug', icon: 'ti ti-plug',
text: action.title, text: action.title,
action: () => { action: () => {

View file

@ -8,7 +8,7 @@ import { Ref } from 'vue';
export type MenuAction = (ev: MouseEvent) => void; export type MenuAction = (ev: MouseEvent) => void;
export type MenuDivider = null; export type MenuDivider = { type: 'divider' };
export type MenuNull = undefined; export type MenuNull = undefined;
export type MenuLabel = { type: 'label', text: string }; export type MenuLabel = { type: 'label', text: string };
export type MenuLink = { type: 'link', to: string, text: string, icon?: string, indicate?: boolean, avatar?: Misskey.entities.User }; export type MenuLink = { type: 'link', to: string, text: string, icon?: string, indicate?: boolean, avatar?: Misskey.entities.User };

View file

@ -64,7 +64,7 @@ export function openInstanceMenu(ev: MouseEvent) {
text: i18n.ts.charts, text: i18n.ts.charts,
icon: 'ti ti-chart-line', icon: 'ti ti-chart-line',
to: '/about#charts', to: '/about#charts',
}, null, { }, { type: 'divider' }, {
type: 'link', type: 'link',
text: i18n.ts.ads, text: i18n.ts.ads,
icon: 'ti ti-ad', icon: 'ti ti-ad',
@ -79,7 +79,7 @@ export function openInstanceMenu(ev: MouseEvent) {
text: i18n.ts.tools, text: i18n.ts.tools,
icon: 'ti ti-tool', icon: 'ti ti-tool',
children: toolsMenuItems(), children: toolsMenuItems(),
}, null, (instance.impressumUrl) ? { }, { type: 'divider' }, (instance.impressumUrl) ? {
text: i18n.ts.impressum, text: i18n.ts.impressum,
icon: 'ti ti-file-invoice', icon: 'ti ti-file-invoice',
action: () => { action: () => {
@ -97,7 +97,7 @@ export function openInstanceMenu(ev: MouseEvent) {
action: () => { action: () => {
window.open(instance.privacyPolicyUrl, '_blank', 'noopener'); window.open(instance.privacyPolicyUrl, '_blank', 'noopener');
}, },
} : undefined, (!instance.impressumUrl && !instance.tosUrl && !instance.privacyPolicyUrl) ? undefined : null, { } : undefined, (!instance.impressumUrl && !instance.tosUrl && !instance.privacyPolicyUrl) ? undefined : { type: 'divider' }, {
text: i18n.ts.help, text: i18n.ts.help,
icon: 'ti ti-help-circle', icon: 'ti ti-help-circle',
action: () => { action: () => {

View file

@ -236,7 +236,7 @@ function changeProfile(ev: MouseEvent) {
deckStore.set('profile', k); deckStore.set('profile', k);
unisonReload(); unisonReload();
}, },
}))), null, { }))), { type: 'divider' }, {
text: i18n.ts._deck.newProfile, text: i18n.ts._deck.newProfile,
icon: 'ti ti-plus', icon: 'ti ti-plus',
action: async () => { action: async () => {

View file

@ -104,7 +104,7 @@ function toggleActive() {
} }
function getMenu() { function getMenu() {
let items = [{ let items: MenuItem[] = [{
icon: 'ti ti-settings', icon: 'ti ti-settings',
text: i18n.ts._deck.configureColumn, text: i18n.ts._deck.configureColumn,
action: async () => { action: async () => {
@ -170,7 +170,7 @@ function getMenu() {
action: () => { action: () => {
popRightColumn(props.column.id); popRightColumn(props.column.id);
}, },
} : undefined, null, { } : undefined, { type: 'divider' }, {
icon: 'ti ti-trash', icon: 'ti ti-trash',
text: i18n.ts.remove, text: i18n.ts.remove,
danger: true, danger: true,
@ -180,7 +180,7 @@ function getMenu() {
}]; }];
if (props.menu) { if (props.menu) {
items.unshift(null); items.unshift({ type: 'divider' });
items = props.menu.concat(items); items = props.menu.concat(items);
} }

View file

@ -130,7 +130,7 @@ const choose = async (ev) => {
text: i18n.ts._timelines.global, text: i18n.ts._timelines.global,
icon: 'ti ti-whirl', icon: 'ti ti-whirl',
action: () => { setSrc('global'); }, action: () => { setSrc('global'); },
}, antennaItems.length > 0 ? null : undefined, ...antennaItems, listItems.length > 0 ? null : undefined, ...listItems], ev.currentTarget ?? ev.target).then(() => { }, antennaItems.length > 0 ? { type: 'divider' } : undefined, ...antennaItems, listItems.length > 0 ? { type: 'divider' } : undefined, ...listItems], ev.currentTarget ?? ev.target).then(() => {
menuOpened.value = false; menuOpened.value = false;
}); });
}; };