@@ -75,17 +75,17 @@ SPDX-License-Identifier: AGPL-3.0-only
import { watch, ref, computed } from 'vue';
import { toUnicode } from 'punycode.js';
import tinycolor from 'tinycolor2';
-import { genId } from '@/utility/id.js';
import JSON5 from 'json5';
import lightTheme from '@@/themes/_light.json5';
import darkTheme from '@@/themes/_dark.json5';
import { host } from '@@/js/config.js';
import type { Theme } from '@/theme.js';
+import { genId } from '@/utility/id.js';
import MkButton from '@/components/MkButton.vue';
import MkCodeEditor from '@/components/MkCodeEditor.vue';
import MkTextarea from '@/components/MkTextarea.vue';
import MkFolder from '@/components/MkFolder.vue';
-import { $i } from '@/i.js';
+import { ensureSignin } from '@/i.js';
import { addTheme, applyTheme } from '@/theme.js';
import * as os from '@/os.js';
import { store } from '@/store.js';
@@ -94,6 +94,8 @@ import { useLeaveGuard } from '@/composables/use-leave-guard.js';
import { definePage } from '@/page.js';
import { prefer } from '@/preferences.js';
+const $i = ensureSignin();
+
const bgColors = [
{ color: '#f5f5f5', kind: 'light', forPreview: '#f5f5f5' },
{ color: '#f0eee9', kind: 'light', forPreview: '#f3e2b9' },
@@ -123,12 +125,15 @@ const fgColors = [
{ color: 'pink', forLight: '#84667d', forDark: '#e4d1e0', forPreview: '#b12390' },
];
-const theme = ref
>({
+const theme = ref({
+ id: genId(),
+ name: 'untitled',
+ author: `@${$i.username}@${toUnicode(host)}`,
base: 'light',
props: lightTheme.props,
});
const description = ref(null);
-const themeCode = ref(null);
+const themeCode = ref('');
const changed = ref(false);
useLeaveGuard(changed);
@@ -194,7 +199,6 @@ async function saveAs() {
theme.value.id = genId();
theme.value.name = name;
- theme.value.author = `@${$i.username}@${toUnicode(host)}`;
if (description.value) theme.value.desc = description.value;
await addTheme(theme.value);
applyTheme(theme.value);
diff --git a/packages/frontend/src/pages/user/activity.following.vue b/packages/frontend/src/pages/user/activity.following.vue
index f2a5ad8e75..2cd825f3dc 100644
--- a/packages/frontend/src/pages/user/activity.following.vue
+++ b/packages/frontend/src/pages/user/activity.following.vue
@@ -36,7 +36,7 @@ const props = defineProps<{
const chartEl = useTemplateRef('chartEl');
const legendEl = useTemplateRef('legendEl');
const now = new Date();
-let chartInstance: Chart = null;
+let chartInstance: Chart | null = null;
const chartLimit = 30;
const fetching = ref(true);
diff --git a/packages/frontend/src/pages/user/follow-list.vue b/packages/frontend/src/pages/user/follow-list.vue
index 6bb1360d42..c383b9b7bd 100644
--- a/packages/frontend/src/pages/user/follow-list.vue
+++ b/packages/frontend/src/pages/user/follow-list.vue
@@ -7,7 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only
diff --git a/packages/frontend/src/pages/user/home.vue b/packages/frontend/src/pages/user/home.vue
index ed3ae6a2aa..e10c44960a 100644
--- a/packages/frontend/src/pages/user/home.vue
+++ b/packages/frontend/src/pages/user/home.vue
@@ -25,8 +25,8 @@ SPDX-License-Identifier: AGPL-3.0-only
-
-
+
+
@@ -43,8 +43,8 @@ SPDX-License-Identifier: AGPL-3.0-only
-
-
+
+
@@ -228,7 +228,7 @@ const bannerEl = ref
(null);
const memoTextareaEl = ref(null);
const memoDraft = ref(props.user.memo);
const isEditingMemo = ref(false);
-const moderationNote = ref(props.user.moderationNote);
+const moderationNote = ref(props.user.moderationNote ?? '');
const editModerationNote = ref(false);
watch(moderationNote, async () => {
diff --git a/packages/frontend/src/pages/user/raw.vue b/packages/frontend/src/pages/user/raw.vue
index f0e675b913..145ef5dd92 100644
--- a/packages/frontend/src/pages/user/raw.vue
+++ b/packages/frontend/src/pages/user/raw.vue
@@ -48,7 +48,7 @@ import FormSection from '@/components/form/section.vue';
import MkObjectView from '@/components/MkObjectView.vue';
const props = defineProps<{
- user: Misskey.entities.User;
+ user: Misskey.entities.UserDetailed & { isModerator?: boolean; };
}>();
const moderator = computed(() => props.user.isModerator ?? false);
diff --git a/packages/frontend/src/utility/admin-lookup.ts b/packages/frontend/src/utility/admin-lookup.ts
index 7405e229fe..eccc88d8a9 100644
--- a/packages/frontend/src/utility/admin-lookup.ts
+++ b/packages/frontend/src/utility/admin-lookup.ts
@@ -12,7 +12,7 @@ export async function lookupUser() {
const { canceled, result } = await os.inputText({
title: i18n.ts.usernameOrUserId,
});
- if (canceled) return;
+ if (canceled || result == null) return;
const show = (user) => {
os.pageWindow(`/admin/user/${user.id}`);
@@ -46,7 +46,7 @@ export async function lookupUserByEmail() {
title: i18n.ts.emailAddress,
type: 'email',
});
- if (canceled) return;
+ if (canceled || result == null) return;
try {
const user = await os.apiWithDialog('admin/accounts/find-by-email', { email: result });
diff --git a/packages/frontend/src/utility/get-note-menu.ts b/packages/frontend/src/utility/get-note-menu.ts
index 11c87dc653..f7b56040cc 100644
--- a/packages/frontend/src/utility/get-note-menu.ts
+++ b/packages/frontend/src/utility/get-note-menu.ts
@@ -179,7 +179,7 @@ export function getNoteMenu(props: {
translating: Ref;
currentClip?: Misskey.entities.Clip;
}) {
- const appearNote = getAppearNote(props.note);
+ const appearNote = getAppearNote(props.note) ?? props.note;
const link = appearNote.url ?? appearNote.uri;
const cleanups = [] as (() => void)[];
@@ -554,7 +554,7 @@ export function getRenoteMenu(props: {
renoteButton: ShallowRef;
mock?: boolean;
}) {
- const appearNote = getAppearNote(props.note);
+ const appearNote = getAppearNote(props.note) ?? props.note;
const channelRenoteItems: MenuItem[] = [];
const normalRenoteItems: MenuItem[] = [];
From 120af977a9cb0af4744e590b36e829bfb140ae4a Mon Sep 17 00:00:00 2001
From: syuilo <4439005+syuilo@users.noreply.github.com>
Date: Tue, 26 Aug 2025 08:57:36 +0900
Subject: [PATCH 13/61] refactoe
---
packages/frontend/src/pages/lookup.vue | 17 +++++++----------
packages/frontend/src/pages/my-lists/index.vue | 6 +++---
packages/frontend/src/pages/my-lists/list.vue | 2 +-
packages/frontend/src/pages/notifications.vue | 4 ++--
packages/frontend/src/pages/settings/2fa.vue | 6 +++---
.../frontend/src/pages/settings/accounts.vue | 4 ++--
packages/frontend/src/pages/settings/apps.vue | 4 ++--
packages/frontend/src/pages/settings/email.vue | 2 +-
8 files changed, 21 insertions(+), 24 deletions(-)
diff --git a/packages/frontend/src/pages/lookup.vue b/packages/frontend/src/pages/lookup.vue
index d5ee0cdf97..8a1e952d85 100644
--- a/packages/frontend/src/pages/lookup.vue
+++ b/packages/frontend/src/pages/lookup.vue
@@ -29,7 +29,7 @@ import MkButton from '@/components/MkButton.vue';
const state = ref<'fetching' | 'done'>('fetching');
-function fetch() {
+function _fetch_() {
const params = new URL(window.location.href).searchParams;
// acctのほうはdeprecated
@@ -44,20 +44,18 @@ function fetch() {
if (uri.startsWith('https://')) {
promise = misskeyApi('ap/show', {
uri,
- });
-
- promise.then(res => {
+ }).then(res => {
if (res.type === 'User') {
mainRouter.replace('/@:acct/:page?', {
params: {
acct: res.host != null ? `${res.object.username}@${res.object.host}` : res.object.username,
- }
+ },
});
} else if (res.type === 'Note') {
mainRouter.replace('/notes/:noteId/:initialTab?', {
params: {
noteId: res.object.id,
- }
+ },
});
} else {
os.alert({
@@ -70,12 +68,11 @@ function fetch() {
if (uri.startsWith('acct:')) {
uri = uri.slice(5);
}
- promise = misskeyApi('users/show', Misskey.acct.parse(uri));
- promise.then(user => {
+ promise = misskeyApi('users/show', Misskey.acct.parse(uri)).then(user => {
mainRouter.replace('/@:acct/:page?', {
params: {
acct: user.host != null ? `${user.username}@${user.host}` : user.username,
- }
+ },
});
});
}
@@ -96,7 +93,7 @@ function goToMisskey(): void {
window.location.href = '/';
}
-fetch();
+_fetch_();
const headerActions = computed(() => []);
diff --git a/packages/frontend/src/pages/my-lists/index.vue b/packages/frontend/src/pages/my-lists/index.vue
index fb31cd542c..0933618f54 100644
--- a/packages/frontend/src/pages/my-lists/index.vue
+++ b/packages/frontend/src/pages/my-lists/index.vue
@@ -17,8 +17,8 @@ SPDX-License-Identifier: AGPL-3.0-only
- {{ list.name }} ({{ i18n.tsx.nUsers({ n: `${list.userIds.length}/${$i.policies['userEachUserListsLimit']}` }) }})
-
+ {{ list.name }} ({{ i18n.tsx.nUsers({ n: `${list.userIds!.length}/${$i.policies['userEachUserListsLimit']}` }) }})
+
@@ -50,7 +50,7 @@ async function create() {
const { canceled, result: name } = await os.inputText({
title: i18n.ts.enterListName,
});
- if (canceled) return;
+ if (canceled || name == null) return;
await os.apiWithDialog('users/lists/create', { name: name });
userListsCache.delete();
fetch();
diff --git a/packages/frontend/src/pages/my-lists/list.vue b/packages/frontend/src/pages/my-lists/list.vue
index 6b5a797023..eb8e26be3b 100644
--- a/packages/frontend/src/pages/my-lists/list.vue
+++ b/packages/frontend/src/pages/my-lists/list.vue
@@ -24,7 +24,7 @@ SPDX-License-Identifier: AGPL-3.0-only
{{ i18n.ts.members }}
- {{ i18n.tsx.nUsers({ n: `${list.userIds.length}/${$i.policies['userEachUserListsLimit']}` }) }}
+ {{ i18n.tsx.nUsers({ n: `${list.userIds!.length}/${$i.policies['userEachUserListsLimit']}` }) }}
{{ i18n.ts.addUser }}
diff --git a/packages/frontend/src/pages/notifications.vue b/packages/frontend/src/pages/notifications.vue
index a8c1fb654c..71c957460c 100644
--- a/packages/frontend/src/pages/notifications.vue
+++ b/packages/frontend/src/pages/notifications.vue
@@ -31,7 +31,7 @@ import { Paginator } from '@/utility/paginator.js';
const tab = ref('all');
const includeTypes = ref
(null);
-const excludeTypes = computed(() => includeTypes.value ? notificationTypes.filter(t => !includeTypes.value.includes(t)) : null);
+const excludeTypes = computed(() => includeTypes.value ? notificationTypes.filter(t => !includeTypes.value!.includes(t)) : null);
const mentionsPaginator = markRaw(new Paginator('notes/mentions', {
limit: 10,
@@ -71,7 +71,7 @@ const headerActions = computed(() => [tab.value === 'all' ? {
text: i18n.ts.markAllAsRead,
icon: 'ti ti-check',
handler: () => {
- os.apiWithDialog('notifications/mark-all-as-read');
+ os.apiWithDialog('notifications/mark-all-as-read', {});
},
} : undefined].filter(x => x !== undefined));
diff --git a/packages/frontend/src/pages/settings/2fa.vue b/packages/frontend/src/pages/settings/2fa.vue
index 1f98fab618..ca404b43c4 100644
--- a/packages/frontend/src/pages/settings/2fa.vue
+++ b/packages/frontend/src/pages/settings/2fa.vue
@@ -25,7 +25,7 @@ SPDX-License-Identifier: AGPL-3.0-only
-
+
{{ i18n.ts._2fa.renewTOTP }}
{{ i18n.ts._2fa.whyTOTPOnlyRenew }}
@@ -58,7 +58,7 @@ SPDX-License-Identifier: AGPL-3.0-only
{{ i18n.ts._2fa.registerSecurityKey }}
-
+
{{ key.name }}
@@ -72,7 +72,7 @@ SPDX-License-Identifier: AGPL-3.0-only
- updatePasswordLessLogin(v)">
+ updatePasswordLessLogin(v)">
{{ i18n.ts.passwordLessLogin }}
{{ i18n.ts.passwordLessLoginDescription }}
diff --git a/packages/frontend/src/pages/settings/accounts.vue b/packages/frontend/src/pages/settings/accounts.vue
index 2fd0a021da..26010e93eb 100644
--- a/packages/frontend/src/pages/settings/accounts.vue
+++ b/packages/frontend/src/pages/settings/accounts.vue
@@ -11,7 +11,7 @@ SPDX-License-Identifier: AGPL-3.0-only
-
+
@@ -36,7 +36,7 @@ function refreshAllAccounts() {
// TODO
}
-function menu(host: string, account: Misskey.entities.UserDetailed, ev: MouseEvent) {
+function showMenu(host: string, account: Misskey.entities.UserDetailed, ev: MouseEvent) {
let menu: MenuItem[];
menu = [{
diff --git a/packages/frontend/src/pages/settings/apps.vue b/packages/frontend/src/pages/settings/apps.vue
index 5f51a5e079..54e214241b 100644
--- a/packages/frontend/src/pages/settings/apps.vue
+++ b/packages/frontend/src/pages/settings/apps.vue
@@ -16,7 +16,7 @@ SPDX-License-Identifier: AGPL-3.0-only
{{ token.name }}
{{ token.description }}
-
+
{{ i18n.ts.delete }}
@@ -28,7 +28,7 @@ SPDX-License-Identifier: AGPL-3.0-only
{{ i18n.ts.installedDate }}
-
+
{{ i18n.ts.lastUsedDate }}
diff --git a/packages/frontend/src/pages/settings/email.vue b/packages/frontend/src/pages/settings/email.vue
index fb8f51041e..469a3c2f1c 100644
--- a/packages/frontend/src/pages/settings/email.vue
+++ b/packages/frontend/src/pages/settings/email.vue
@@ -74,7 +74,7 @@ import { instance } from '@/instance.js';
const $i = ensureSignin();
-const emailAddress = ref($i.email);
+const emailAddress = ref($i.email ?? '');
const onChangeReceiveAnnouncementEmail = (v) => {
misskeyApi('i/update', {
From 9e5c8d94bff0352bca3b15fd75a7c6ccaa1df2ff Mon Sep 17 00:00:00 2001
From: syuilo <4439005+syuilo@users.noreply.github.com>
Date: Tue, 26 Aug 2025 09:08:00 +0900
Subject: [PATCH 14/61] refactor
---
packages/frontend/src/components/MkAchievements.vue | 6 +++---
packages/frontend/src/components/MkAnimBg.vue | 2 ++
packages/frontend/src/pages/admin-file.vue | 4 ++--
packages/frontend/src/pages/announcement.vue | 6 +++---
packages/frontend/src/pages/drive.file.info.vue | 12 ++++++------
packages/frontend/src/pages/install-extensions.vue | 4 ++--
packages/frontend/src/pages/instance-info.vue | 4 ++--
packages/frontend/src/pages/my-antennas/index.vue | 6 +++---
packages/frontend/src/pages/my-lists/index.vue | 10 +++++-----
packages/frontend/src/pages/settings/index.vue | 6 +++++-
packages/frontend/src/pages/settings/profile.vue | 2 +-
.../frontend/src/pages/settings/theme.install.vue | 6 +++---
.../frontend/src/pages/settings/theme.manage.vue | 2 +-
packages/frontend/src/theme.ts | 1 +
14 files changed, 39 insertions(+), 32 deletions(-)
diff --git a/packages/frontend/src/components/MkAchievements.vue b/packages/frontend/src/components/MkAchievements.vue
index 70766634ce..3b7b59b4d3 100644
--- a/packages/frontend/src/components/MkAchievements.vue
+++ b/packages/frontend/src/components/MkAchievements.vue
@@ -71,7 +71,7 @@ const props = withDefaults(defineProps<{
const achievements = ref(null);
const lockedAchievements = computed(() => ACHIEVEMENT_TYPES.filter(x => !(achievements.value ?? []).some(a => a.name === x)));
-function fetch() {
+function _fetch_() {
misskeyApi('users/achievements', { userId: props.user.id }).then(res => {
achievements.value = [];
for (const t of ACHIEVEMENT_TYPES) {
@@ -84,11 +84,11 @@ function fetch() {
function clickHere() {
claimAchievement('clickedClickHere');
- fetch();
+ _fetch_();
}
onMounted(() => {
- fetch();
+ _fetch_();
});
diff --git a/packages/frontend/src/components/MkAnimBg.vue b/packages/frontend/src/components/MkAnimBg.vue
index 82606c9aa4..19a21f6e24 100644
--- a/packages/frontend/src/components/MkAnimBg.vue
+++ b/packages/frontend/src/components/MkAnimBg.vue
@@ -265,6 +265,8 @@ onUnmounted(() => {
if (handle) {
window.cancelAnimationFrame(handle);
}
+
+ // TODO: WebGLリソースの解放
});
diff --git a/packages/frontend/src/pages/admin-file.vue b/packages/frontend/src/pages/admin-file.vue
index 7a49ba542f..90b3ca81cf 100644
--- a/packages/frontend/src/pages/admin-file.vue
+++ b/packages/frontend/src/pages/admin-file.vue
@@ -111,13 +111,13 @@ const props = defineProps<{
fileId: string,
}>();
-async function fetch() {
+async function _fetch_() {
file.value = await misskeyApi('drive/files/show', { fileId: props.fileId });
info.value = await misskeyApi('admin/drive/show-file', { fileId: props.fileId });
isSensitive.value = file.value.isSensitive;
}
-fetch();
+_fetch_();
async function del() {
const { canceled } = await os.confirm({
diff --git a/packages/frontend/src/pages/announcement.vue b/packages/frontend/src/pages/announcement.vue
index f9b870eda1..0bcfd28f67 100644
--- a/packages/frontend/src/pages/announcement.vue
+++ b/packages/frontend/src/pages/announcement.vue
@@ -39,7 +39,7 @@ SPDX-License-Identifier: AGPL-3.0-only
{{ i18n.ts.gotIt }}