diff options
Diffstat (limited to 'packages/frontend/src/scripts/get-user-menu.ts')
| -rw-r--r-- | packages/frontend/src/scripts/get-user-menu.ts | 115 |
1 files changed, 83 insertions, 32 deletions
diff --git a/packages/frontend/src/scripts/get-user-menu.ts b/packages/frontend/src/scripts/get-user-menu.ts index 1c93d58b44..128cbafb15 100644 --- a/packages/frontend/src/scripts/get-user-menu.ts +++ b/packages/frontend/src/scripts/get-user-menu.ts @@ -1,19 +1,26 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + import { toUnicode } from 'punycode'; -import { defineAsyncComponent } from 'vue'; -import * as misskey from 'misskey-js'; -import { i18n } from '@/i18n'; -import copyToClipboard from '@/scripts/copy-to-clipboard'; -import { host, url } from '@/config'; -import * as os from '@/os'; -import { defaultStore, userActions } from '@/store'; -import { $i, iAmModerator } from '@/account'; -import { mainRouter } from '@/router'; -import { Router } from '@/nirax'; -import { antennasCache, rolesCache, userListsCache } from '@/cache'; +import { defineAsyncComponent, ref, watch } from 'vue'; +import * as Misskey from 'misskey-js'; +import { i18n } from '@/i18n.js'; +import copyToClipboard from '@/scripts/copy-to-clipboard.js'; +import { host, url } from '@/config.js'; +import * as os from '@/os.js'; +import { defaultStore, userActions } from '@/store.js'; +import { $i, iAmModerator } from '@/account.js'; +import { mainRouter } from '@/router.js'; +import { Router } from '@/nirax.js'; +import { antennasCache, rolesCache, userListsCache } from '@/cache.js'; -export function getUserMenu(user: misskey.entities.UserDetailed, router: Router = mainRouter) { +export function getUserMenu(user: Misskey.entities.UserDetailed, router: Router = mainRouter) { const meId = $i ? $i.id : null; + const cleanups = [] as (() => void)[]; + async function toggleMute() { if (user.isMuted) { os.apiWithDialog('mute/delete', { @@ -73,6 +80,15 @@ export function getUserMenu(user: misskey.entities.UserDetailed, router: Router }); } + async function toggleNotify() { + os.apiWithDialog('following/update', { + userId: user.id, + notify: user.notify === 'normal' ? 'none' : 'normal', + }).then(() => { + user.notify = user.notify === 'normal' ? 'none' : 'normal'; + }); + } + function reportAbuse() { os.popup(defineAsyncComponent(() => import('@/components/MkAbuseReportWindow.vue')), { user: user, @@ -126,13 +142,13 @@ export function getUserMenu(user: misskey.entities.UserDetailed, router: Router action: () => { copyToClipboard(`@${user.username}@${user.host ?? host}`); }, - }, { - icon: 'ti ti-info-circle', - text: i18n.ts.info, + }, ...(iAmModerator ? [{ + icon: 'ti ti-user-exclamation', + text: i18n.ts.moderation, action: () => { - router.push(`/user-info/${user.id}`); + router.push(`/admin/user/${user.id}`); }, - }, { + }] : []), { icon: 'ti ti-rss', text: i18n.ts.copyRSS, action: () => { @@ -149,7 +165,8 @@ export function getUserMenu(user: misskey.entities.UserDetailed, router: Router icon: 'ti ti-mail', text: i18n.ts.sendMessage, action: () => { - os.post({ specified: user, initialText: `@${user.username} ` }); + const canonical = user.host === null ? `@${user.username}` : `@${user.username}@${user.host}`; + os.post({ specified: user, initialText: `${canonical} ` }); }, }, null, { icon: 'ti ti-pencil', @@ -162,25 +179,40 @@ export function getUserMenu(user: misskey.entities.UserDetailed, router: Router icon: 'ti ti-list', text: i18n.ts.addToList, children: async () => { - const lists = await userListsCache.fetch(() => os.api('users/lists/list')); + const lists = await userListsCache.fetch(); + return lists.map(list => { + const isListed = ref(list.userIds.includes(user.id)); + cleanups.push(watch(isListed, () => { + if (isListed.value) { + os.apiWithDialog('users/lists/push', { + listId: list.id, + userId: user.id, + }).then(() => { + list.userIds.push(user.id); + }); + } else { + os.apiWithDialog('users/lists/pull', { + listId: list.id, + userId: user.id, + }).then(() => { + list.userIds.splice(list.userIds.indexOf(user.id), 1); + }); + } + })); - return lists.map(list => ({ - text: list.name, - action: async () => { - await os.apiWithDialog('users/lists/push', { - listId: list.id, - userId: user.id, - }); - userListsCache.delete(); - }, - })); + return { + type: 'switch', + text: list.name, + ref: isListed, + }; + }); }, }, { type: 'parent', icon: 'ti ti-antenna', text: i18n.ts.addToAntenna, children: async () => { - const antennas = await antennasCache.fetch(() => os.api('antennas/list')); + const antennas = await antennasCache.fetch(); const canonical = user.host === null ? `@${user.username}` : `@${user.username}@${toUnicode(user.host)}`; return antennas.filter((a) => a.src === 'users').map(antenna => ({ text: antenna.name, @@ -211,7 +243,7 @@ export function getUserMenu(user: misskey.entities.UserDetailed, router: Router icon: 'ti ti-badges', text: i18n.ts.roles, children: async () => { - const roles = await rolesCache.fetch(() => os.api('admin/roles/list')); + const roles = await rolesCache.fetch(); return roles.filter(r => r.target === 'manual').map(r => ({ text: r.name, @@ -247,6 +279,15 @@ export function getUserMenu(user: misskey.entities.UserDetailed, router: Router }]); } + // フォローしたとしても user.isFollowing はリアルタイム更新されないので不便なため + //if (user.isFollowing) { + menu = menu.concat([{ + icon: user.notify === 'none' ? 'ti ti-bell' : 'ti ti-bell-off', + text: user.notify === 'none' ? i18n.ts.notifyNotes : i18n.ts.unnotifyNotes, + action: toggleNotify, + }]); + //} + menu = menu.concat([null, { icon: user.isMuted ? 'ti ti-eye' : 'ti ti-eye-off', text: user.isMuted ? i18n.ts.unmute : i18n.ts.mute, @@ -306,5 +347,15 @@ export function getUserMenu(user: misskey.entities.UserDetailed, router: Router }))]); } - return menu; + const cleanup = () => { + if (_DEV_) console.log('user menu cleanup', cleanups); + for (const cl of cleanups) { + cl(); + } + }; + + return { + menu, + cleanup, + }; } |