refactor(client): Refine routing (#8846)
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
import * as Acct from 'misskey-js/built/acct';
|
||||
import { defineAsyncComponent } from 'vue';
|
||||
import { i18n } from '@/i18n';
|
||||
import copyToClipboard from '@/scripts/copy-to-clipboard';
|
||||
import { host } from '@/config';
|
||||
import * as Acct from 'misskey-js/built/acct';
|
||||
import * as os from '@/os';
|
||||
import { userActions } from '@/store';
|
||||
import { router } from '@/router';
|
||||
import { $i, iAmModerator } from '@/account';
|
||||
import { defineAsyncComponent } from 'vue';
|
||||
import { mainRouter } from '@/router';
|
||||
|
||||
export function getUserMenu(user) {
|
||||
const meId = $i ? $i.id : null;
|
||||
@@ -17,20 +17,20 @@ export function getUserMenu(user) {
|
||||
if (lists.length === 0) {
|
||||
os.alert({
|
||||
type: 'error',
|
||||
text: i18n.ts.youHaveNoLists
|
||||
text: i18n.ts.youHaveNoLists,
|
||||
});
|
||||
return;
|
||||
}
|
||||
const { canceled, result: listId } = await os.select({
|
||||
title: t,
|
||||
items: lists.map(list => ({
|
||||
value: list.id, text: list.name
|
||||
}))
|
||||
value: list.id, text: list.name,
|
||||
})),
|
||||
});
|
||||
if (canceled) return;
|
||||
os.apiWithDialog('users/lists/push', {
|
||||
listId: listId,
|
||||
userId: user.id
|
||||
userId: user.id,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -39,20 +39,20 @@ export function getUserMenu(user) {
|
||||
if (groups.length === 0) {
|
||||
os.alert({
|
||||
type: 'error',
|
||||
text: i18n.ts.youHaveNoGroups
|
||||
text: i18n.ts.youHaveNoGroups,
|
||||
});
|
||||
return;
|
||||
}
|
||||
const { canceled, result: groupId } = await os.select({
|
||||
title: i18n.ts.group,
|
||||
items: groups.map(group => ({
|
||||
value: group.id, text: group.name
|
||||
}))
|
||||
value: group.id, text: group.name,
|
||||
})),
|
||||
});
|
||||
if (canceled) return;
|
||||
os.apiWithDialog('users/groups/invite', {
|
||||
groupId: groupId,
|
||||
userId: user.id
|
||||
userId: user.id,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ export function getUserMenu(user) {
|
||||
if (!await getConfirmed(user.isBlocking ? i18n.ts.unblockConfirm : i18n.ts.blockConfirm)) return;
|
||||
|
||||
os.apiWithDialog(user.isBlocking ? 'blocking/delete' : 'blocking/create', {
|
||||
userId: user.id
|
||||
userId: user.id,
|
||||
}).then(() => {
|
||||
user.isBlocking = !user.isBlocking;
|
||||
});
|
||||
@@ -111,7 +111,7 @@ export function getUserMenu(user) {
|
||||
if (!await getConfirmed(i18n.t(user.isSilenced ? 'unsilenceConfirm' : 'silenceConfirm'))) return;
|
||||
|
||||
os.apiWithDialog(user.isSilenced ? 'admin/unsilence-user' : 'admin/silence-user', {
|
||||
userId: user.id
|
||||
userId: user.id,
|
||||
}).then(() => {
|
||||
user.isSilenced = !user.isSilenced;
|
||||
});
|
||||
@@ -121,7 +121,7 @@ export function getUserMenu(user) {
|
||||
if (!await getConfirmed(i18n.t(user.isSuspended ? 'unsuspendConfirm' : 'suspendConfirm'))) return;
|
||||
|
||||
os.apiWithDialog(user.isSuspended ? 'admin/unsuspend-user' : 'admin/suspend-user', {
|
||||
userId: user.id
|
||||
userId: user.id,
|
||||
}).then(() => {
|
||||
user.isSuspended = !user.isSuspended;
|
||||
});
|
||||
@@ -145,7 +145,7 @@ export function getUserMenu(user) {
|
||||
|
||||
async function invalidateFollow() {
|
||||
os.apiWithDialog('following/invalidate', {
|
||||
userId: user.id
|
||||
userId: user.id,
|
||||
}).then(() => {
|
||||
user.isFollowed = !user.isFollowed;
|
||||
});
|
||||
@@ -156,19 +156,19 @@ export function getUserMenu(user) {
|
||||
text: i18n.ts.copyUsername,
|
||||
action: () => {
|
||||
copyToClipboard(`@${user.username}@${user.host || host}`);
|
||||
}
|
||||
},
|
||||
}, {
|
||||
icon: 'fas fa-info-circle',
|
||||
text: i18n.ts.info,
|
||||
action: () => {
|
||||
os.pageWindow(`/user-info/${user.id}`);
|
||||
}
|
||||
},
|
||||
}, {
|
||||
icon: 'fas fa-envelope',
|
||||
text: i18n.ts.sendMessage,
|
||||
action: () => {
|
||||
os.post({ specified: user });
|
||||
}
|
||||
},
|
||||
}, meId !== user.id ? {
|
||||
type: 'link',
|
||||
icon: 'fas fa-comments',
|
||||
@@ -177,47 +177,47 @@ export function getUserMenu(user) {
|
||||
} : undefined, null, {
|
||||
icon: 'fas fa-list-ul',
|
||||
text: i18n.ts.addToList,
|
||||
action: pushList
|
||||
action: pushList,
|
||||
}, meId !== user.id ? {
|
||||
icon: 'fas fa-users',
|
||||
text: i18n.ts.inviteToGroup,
|
||||
action: inviteGroup
|
||||
action: inviteGroup,
|
||||
} : undefined] as any;
|
||||
|
||||
if ($i && meId !== user.id) {
|
||||
menu = menu.concat([null, {
|
||||
icon: user.isMuted ? 'fas fa-eye' : 'fas fa-eye-slash',
|
||||
text: user.isMuted ? i18n.ts.unmute : i18n.ts.mute,
|
||||
action: toggleMute
|
||||
action: toggleMute,
|
||||
}, {
|
||||
icon: 'fas fa-ban',
|
||||
text: user.isBlocking ? i18n.ts.unblock : i18n.ts.block,
|
||||
action: toggleBlock
|
||||
action: toggleBlock,
|
||||
}]);
|
||||
|
||||
if (user.isFollowed) {
|
||||
menu = menu.concat([{
|
||||
icon: 'fas fa-unlink',
|
||||
text: i18n.ts.breakFollow,
|
||||
action: invalidateFollow
|
||||
action: invalidateFollow,
|
||||
}]);
|
||||
}
|
||||
|
||||
menu = menu.concat([null, {
|
||||
icon: 'fas fa-exclamation-circle',
|
||||
text: i18n.ts.reportAbuse,
|
||||
action: reportAbuse
|
||||
action: reportAbuse,
|
||||
}]);
|
||||
|
||||
if (iAmModerator) {
|
||||
menu = menu.concat([null, {
|
||||
icon: 'fas fa-microphone-slash',
|
||||
text: user.isSilenced ? i18n.ts.unsilence : i18n.ts.silence,
|
||||
action: toggleSilence
|
||||
action: toggleSilence,
|
||||
}, {
|
||||
icon: 'fas fa-snowflake',
|
||||
text: user.isSuspended ? i18n.ts.unsuspend : i18n.ts.suspend,
|
||||
action: toggleSuspend
|
||||
action: toggleSuspend,
|
||||
}]);
|
||||
}
|
||||
}
|
||||
@@ -227,8 +227,8 @@ export function getUserMenu(user) {
|
||||
icon: 'fas fa-pencil-alt',
|
||||
text: i18n.ts.editProfile,
|
||||
action: () => {
|
||||
router.push('/settings/profile');
|
||||
}
|
||||
mainRouter.push('/settings/profile');
|
||||
},
|
||||
}]);
|
||||
}
|
||||
|
||||
@@ -238,7 +238,7 @@ export function getUserMenu(user) {
|
||||
text: action.title,
|
||||
action: () => {
|
||||
action.handler(user);
|
||||
}
|
||||
},
|
||||
}))]);
|
||||
}
|
||||
|
||||
|
@@ -1,34 +0,0 @@
|
||||
import { inject } from 'vue';
|
||||
import { router } from '@/router';
|
||||
import { defaultStore } from '@/store';
|
||||
|
||||
export type Navigate = (path: string, record?: boolean) => void;
|
||||
|
||||
export class MisskeyNavigator {
|
||||
public readonly navHook: Navigate | null = null;
|
||||
public readonly sideViewHook: Navigate | null = null;
|
||||
|
||||
// It should be constructed during vue creating in order for inject function to work
|
||||
constructor() {
|
||||
this.navHook = inject<Navigate | null>('navHook', null);
|
||||
this.sideViewHook = inject<Navigate | null>('sideViewHook', null);
|
||||
}
|
||||
|
||||
// Use this method instead of router.push()
|
||||
public push(path: string, record = true) {
|
||||
if (this.navHook) {
|
||||
this.navHook(path, record);
|
||||
} else {
|
||||
if (defaultStore.state.defaultSideView && this.sideViewHook && path !== '/') {
|
||||
return this.sideViewHook(path, record);
|
||||
}
|
||||
|
||||
if (router.currentRoute.value.path === path) {
|
||||
window.scroll({ top: 0, behavior: 'smooth' });
|
||||
} else {
|
||||
if (record) router.push(path);
|
||||
else router.replace(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
41
packages/client/src/scripts/page-metadata.ts
Normal file
41
packages/client/src/scripts/page-metadata.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import * as misskey from 'misskey-js';
|
||||
import { ComputedRef, inject, isRef, onActivated, onMounted, provide, ref, Ref } from 'vue';
|
||||
|
||||
export const setPageMetadata = Symbol('setPageMetadata');
|
||||
export const pageMetadataProvider = Symbol('pageMetadataProvider');
|
||||
|
||||
export type PageMetadata = {
|
||||
title: string;
|
||||
subtitle?: string;
|
||||
icon?: string | null;
|
||||
avatar?: misskey.entities.User | null;
|
||||
userName?: misskey.entities.User | null;
|
||||
bg?: string;
|
||||
};
|
||||
|
||||
export function definePageMetadata(metadata: PageMetadata | null | Ref<PageMetadata | null> | ComputedRef<PageMetadata | null>): void {
|
||||
const _metadata = isRef(metadata) ? metadata : ref(metadata);
|
||||
|
||||
provide(pageMetadataProvider, _metadata);
|
||||
|
||||
const set = inject(setPageMetadata) as any;
|
||||
if (set) {
|
||||
set(_metadata);
|
||||
|
||||
onMounted(() => {
|
||||
set(_metadata);
|
||||
});
|
||||
|
||||
onActivated(() => {
|
||||
set(_metadata);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function provideMetadataReceiver(callback: (info: ComputedRef<PageMetadata>) => void): void {
|
||||
provide(setPageMetadata, callback);
|
||||
}
|
||||
|
||||
export function injectPageMetadata(): PageMetadata | undefined {
|
||||
return inject(pageMetadataProvider);
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
import * as os from '@/os';
|
||||
import { i18n } from '@/i18n';
|
||||
import { router } from '@/router';
|
||||
import { mainRouter } from '@/router';
|
||||
|
||||
export async function search() {
|
||||
const { canceled, result: query } = await os.inputText({
|
||||
@@ -11,12 +11,12 @@ export async function search() {
|
||||
const q = query.trim();
|
||||
|
||||
if (q.startsWith('@') && !q.includes(' ')) {
|
||||
router.push(`/${q}`);
|
||||
mainRouter.push(`/${q}`);
|
||||
return;
|
||||
}
|
||||
|
||||
if (q.startsWith('#')) {
|
||||
router.push(`/tags/${encodeURIComponent(q.substr(1))}`);
|
||||
mainRouter.push(`/tags/${encodeURIComponent(q.substr(1))}`);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -36,14 +36,14 @@ export async function search() {
|
||||
//v.$root.$emit('warp', date);
|
||||
os.alert({
|
||||
icon: 'fas fa-history',
|
||||
iconOnly: true, autoClose: true
|
||||
iconOnly: true, autoClose: true,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (q.startsWith('https://')) {
|
||||
const promise = os.api('ap/show', {
|
||||
uri: q
|
||||
uri: q,
|
||||
});
|
||||
|
||||
os.promiseDialog(promise, null, null, i18n.ts.fetchingAsApObject);
|
||||
@@ -51,13 +51,13 @@ export async function search() {
|
||||
const res = await promise;
|
||||
|
||||
if (res.type === 'User') {
|
||||
router.push(`/@${res.object.username}@${res.object.host}`);
|
||||
mainRouter.push(`/@${res.object.username}@${res.object.host}`);
|
||||
} else if (res.type === 'Note') {
|
||||
router.push(`/notes/${res.object.id}`);
|
||||
mainRouter.push(`/notes/${res.object.id}`);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
router.push(`/search?q=${encodeURIComponent(q)}`);
|
||||
mainRouter.push(`/search?q=${encodeURIComponent(q)}`);
|
||||
}
|
||||
|
@@ -1,5 +1,4 @@
|
||||
import { inject, onUnmounted, Ref } from 'vue';
|
||||
import { onBeforeRouteLeave } from 'vue-router';
|
||||
import { i18n } from '@/i18n';
|
||||
import * as os from '@/os';
|
||||
|
||||
|
Reference in New Issue
Block a user