diff --git a/CHANGELOG.md b/CHANGELOG.md index a88ba3aca0..f15a8c2bea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +## Unreleased + +### General +- + +### Client +- Fix: RSSティッカーウィジェットが正しく動作しない問題を修正 + +### Server +- + + ## 2025.8.0 ### Note diff --git a/package.json b/package.json index e4cec6aea6..328397e710 100644 --- a/package.json +++ b/package.json @@ -67,6 +67,7 @@ }, "devDependencies": { "@misskey-dev/eslint-plugin": "2.1.0", + "@types/js-yaml": "4.0.9", "@types/node": "22.17.2", "@typescript-eslint/eslint-plugin": "8.40.0", "@typescript-eslint/parser": "8.40.0", diff --git a/packages/backend/src/core/RoleService.ts b/packages/backend/src/core/RoleService.ts index 3df7ee69ee..7dc07ef4dd 100644 --- a/packages/backend/src/core/RoleService.ts +++ b/packages/backend/src/core/RoleService.ts @@ -31,6 +31,7 @@ import { FanoutTimelineService } from '@/core/FanoutTimelineService.js'; import { NotificationService } from '@/core/NotificationService.js'; import type { OnApplicationShutdown, OnModuleInit } from '@nestjs/common'; +// misskey-js の rolePolicies と同期すべし export type RolePolicies = { gtlAvailable: boolean; ltlAvailable: boolean; diff --git a/packages/backend/src/models/Notification.ts b/packages/backend/src/models/Notification.ts index 5764a307b0..0b4eeb3455 100644 --- a/packages/backend/src/models/Notification.ts +++ b/packages/backend/src/models/Notification.ts @@ -10,6 +10,7 @@ import { MiAccessToken } from './AccessToken.js'; import { MiRole } from './Role.js'; import { MiDriveFile } from './DriveFile.js'; +// misskey-js の notificationTypes と同期すべし export type MiNotification = { type: 'note'; id: string; diff --git a/packages/frontend-shared/js/const.ts b/packages/frontend-shared/js/const.ts index b2d83fff8b..c8c437afe9 100644 --- a/packages/frontend-shared/js/const.ts +++ b/packages/frontend-shared/js/const.ts @@ -54,68 +54,6 @@ https://github.com/sindresorhus/file-type/blob/main/core.js https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Containers */ -export const notificationTypes = [ - 'note', - 'follow', - 'mention', - 'reply', - 'renote', - 'quote', - 'reaction', - 'pollEnded', - 'receiveFollowRequest', - 'followRequestAccepted', - 'roleAssigned', - 'chatRoomInvitationReceived', - 'achievementEarned', - 'exportCompleted', - 'login', - 'createToken', - 'test', - 'app', -] as const; -export const obsoleteNotificationTypes = ['pollVote', 'groupInvited'] as const; - -export const ROLE_POLICIES = [ - 'gtlAvailable', - 'ltlAvailable', - 'canPublicNote', - 'mentionLimit', - 'canInvite', - 'inviteLimit', - 'inviteLimitCycle', - 'inviteExpirationTime', - 'canManageCustomEmojis', - 'canManageAvatarDecorations', - 'canSearchNotes', - 'canSearchUsers', - 'canUseTranslator', - 'canHideAds', - 'driveCapacityMb', - 'maxFileSizeMb', - 'alwaysMarkNsfw', - 'canUpdateBioMedia', - 'pinLimit', - 'antennaLimit', - 'wordMuteLimit', - 'webhookLimit', - 'clipLimit', - 'noteEachClipsLimit', - 'userListLimit', - 'userEachUserListsLimit', - 'rateLimitFactor', - 'avatarDecorationLimit', - 'canImportAntennas', - 'canImportBlocking', - 'canImportFollowing', - 'canImportMuting', - 'canImportUserLists', - 'chatAvailability', - 'uploadableFileTypes', - 'noteDraftLimit', - 'watermarkAvailable', -] as const; - export const MFM_TAGS = ['tada', 'jelly', 'twitch', 'shake', 'spin', 'jump', 'bounce', 'flip', 'x2', 'x3', 'x4', 'scale', 'position', 'fg', 'bg', 'border', 'font', 'blur', 'rainbow', 'sparkle', 'rotate', 'ruby', 'unixtime']; export const MFM_PARAMS: Record = { tada: ['speed=', 'delay='], diff --git a/packages/frontend/.storybook/fakes.ts b/packages/frontend/.storybook/fakes.ts index 91ef41eedf..ed29c63471 100644 --- a/packages/frontend/.storybook/fakes.ts +++ b/packages/frontend/.storybook/fakes.ts @@ -127,7 +127,7 @@ export function galleryPost(isSensitive = false) { } } -export function file(isSensitive = false) { +export function file(isSensitive = false): entities.DriveFile { return { id: 'somefileid', createdAt: '2016-12-28T22:49:51.000Z', @@ -207,6 +207,7 @@ export function federationInstance(): entities.FederationInstance { isSuspended: false, suspensionState: 'none', isBlocked: false, + isMediaSilenced: false, softwareName: 'misskey', softwareVersion: '2024.5.0', openRegistrations: false, @@ -311,6 +312,8 @@ export function userDetailed(id = 'someuserid', username = 'miskist', host: enti alsoKnownAs: null, notify: 'none', memo: null, + canChat: true, + chatScope: 'everyone', }; } @@ -378,6 +381,7 @@ export function role(params: { asBadge: params.asBadge ?? true, canEditMembersByModerator: params.canEditMembersByModerator ?? false, usersCount: params.usersCount ?? 10, + preserveAssignmentOnMoveAccount: false, condFormula: { id: '', type: 'or', diff --git a/packages/frontend/src/aiscript/api.ts b/packages/frontend/src/aiscript/api.ts index a876e94ee8..0549ab76a0 100644 --- a/packages/frontend/src/aiscript/api.ts +++ b/packages/frontend/src/aiscript/api.ts @@ -86,7 +86,7 @@ export function createAiScriptEnv(opts: { storageKey: string, token?: string }) throw new errors.AiScriptRuntimeError('expected param'); } utils.assertObject(param); - return misskeyApi(ep.value, utils.valToJs(param) as object, actualToken).then(res => { + return misskeyApi(ep.value as keyof Misskey.Endpoints, utils.valToJs(param) as object, actualToken).then(res => { return utils.jsToVal(res); }, err => { return values.ERROR('request_failed', utils.jsToVal(err)); diff --git a/packages/frontend/src/components/MkAuthConfirm.vue b/packages/frontend/src/components/MkAuthConfirm.vue index b3331d742b..8744b50926 100644 --- a/packages/frontend/src/components/MkAuthConfirm.vue +++ b/packages/frontend/src/components/MkAuthConfirm.vue @@ -167,9 +167,13 @@ async function init() { for (const user of usersRes) { if (users.value.has(user.id)) continue; + const account = accounts.find(a => a.id === user.id); + + if (!account || account.token == null) continue; + users.value.set(user.id, { ...user, - token: accounts.find(a => a.id === user.id)!.token, + token: account.token, }); } } diff --git a/packages/frontend/src/components/MkAutocomplete.vue b/packages/frontend/src/components/MkAutocomplete.vue index e5b9533cd7..cf5d95e11b 100644 --- a/packages/frontend/src/components/MkAutocomplete.vue +++ b/packages/frontend/src/components/MkAutocomplete.vue @@ -25,7 +25,7 @@ SPDX-License-Identifier: AGPL-3.0-only - + ({{ emoji.aliasOf }}) @@ -36,7 +36,7 @@ SPDX-License-Identifier: AGPL-3.0-only
    -
  1. +
  2. {{ param }}
@@ -194,6 +194,11 @@ const mfmParams = ref([]); const select = ref(-1); const zIndex = os.claimZIndex('high'); +function completeMfmParam(param: string) { + if (props.type !== 'mfmParam') throw new Error('Invalid type'); + complete('mfmParam', props.q.params.toSpliced(-1, 1, param).join(',')); +} + function complete(type: T, value: CompleteInfo[T]['payload']) { emit('done', { type, value }); emit('closed'); diff --git a/packages/frontend/src/components/MkChartTooltip.vue b/packages/frontend/src/components/MkChartTooltip.vue index 51081ede23..b9d2c8219a 100644 --- a/packages/frontend/src/components/MkChartTooltip.vue +++ b/packages/frontend/src/components/MkChartTooltip.vue @@ -25,12 +25,12 @@ defineProps<{ showing: boolean; x: number; y: number; - title?: string; + title?: string | null; series?: { backgroundColor: string; borderColor: string; text: string; - }[]; + }[] | null; }>(); const emit = defineEmits<{ diff --git a/packages/frontend/src/components/MkCropperDialog.stories.impl.ts b/packages/frontend/src/components/MkCropperDialog.stories.impl.ts index bd6733f9a8..7ac3e2a2cd 100644 --- a/packages/frontend/src/components/MkCropperDialog.stories.impl.ts +++ b/packages/frontend/src/components/MkCropperDialog.stories.impl.ts @@ -38,7 +38,7 @@ export const Default = { }; }, args: { - file: file(), + imageFile: file(), aspectRatio: NaN, }, parameters: { diff --git a/packages/frontend/src/components/MkDrive.vue b/packages/frontend/src/components/MkDrive.vue index 9f1364aec4..19c98c3738 100644 --- a/packages/frontend/src/components/MkDrive.vue +++ b/packages/frontend/src/components/MkDrive.vue @@ -699,7 +699,7 @@ useGlobalEvent('driveFoldersDeleted', (folders) => { } }); -let connection: Misskey.ChannelConnection | null = null; +let connection: Misskey.IChannelConnection | null = null; onMounted(() => { if (store.s.realtimeMode) { diff --git a/packages/frontend/src/components/MkEmbedCodeGenDialog.vue b/packages/frontend/src/components/MkEmbedCodeGenDialog.vue index d18fe0ed0c..17823deb85 100644 --- a/packages/frontend/src/components/MkEmbedCodeGenDialog.vue +++ b/packages/frontend/src/components/MkEmbedCodeGenDialog.vue @@ -160,7 +160,7 @@ const embedPreviewUrl = computed(() => { const isEmbedWithScrollbar = computed(() => embedRouteWithScrollbar.includes(props.entity)); const header = ref(props.params?.header ?? true); -const maxHeight = ref(props.params?.maxHeight !== 0 ? props.params?.maxHeight ?? undefined : 500); +const maxHeight = ref(props.params?.maxHeight !== 0 ? props.params?.maxHeight ?? null : 500); const colorMode = ref<'light' | 'dark' | 'auto'>(props.params?.colorMode ?? 'auto'); const rounded = ref(props.params?.rounded ?? true); diff --git a/packages/frontend/src/components/MkFormDialog.vue b/packages/frontend/src/components/MkFormDialog.vue index 6ac4441cac..8d697499a5 100644 --- a/packages/frontend/src/components/MkFormDialog.vue +++ b/packages/frontend/src/components/MkFormDialog.vue @@ -41,11 +41,11 @@ SPDX-License-Identifier: AGPL-3.0-only - + - + @@ -77,7 +77,7 @@ import MkRange from './MkRange.vue'; import MkButton from './MkButton.vue'; import MkRadios from './MkRadios.vue'; import XFile from './MkFormDialog.file.vue'; -import type { Form } from '@/utility/form.js'; +import type { EnumItem, Form, RadioFormItem } from '@/utility/form.js'; import MkModalWindow from '@/components/MkModalWindow.vue'; import { i18n } from '@/i18n.js'; @@ -99,7 +99,11 @@ const dialog = useTemplateRef('dialog'); const values = reactive({}); for (const item in props.form) { - values[item] = props.form[item].default ?? null; + if ('default' in props.form[item]) { + values[item] = props.form[item].default ?? null; + } else { + values[item] = null; + } } function ok() { @@ -115,4 +119,20 @@ function cancel() { }); dialog.value?.close(); } + +function getEnumLabel(e: EnumItem) { + return typeof e === 'string' ? e : e.label; +} + +function getEnumValue(e: EnumItem) { + return typeof e === 'string' ? e : e.value; +} + +function getEnumKey(e: EnumItem) { + return typeof e === 'string' ? e : typeof e.value === 'string' ? e.value : JSON.stringify(e.value); +} + +function getRadioKey(e: RadioFormItem['options'][number]) { + return typeof e.value === 'string' ? e.value : JSON.stringify(e.value); +} diff --git a/packages/frontend/src/components/MkImageEffectorFxForm.vue b/packages/frontend/src/components/MkImageEffectorFxForm.vue index d7ab620132..e581b1f743 100644 --- a/packages/frontend/src/components/MkImageEffectorFxForm.vue +++ b/packages/frontend/src/components/MkImageEffectorFxForm.vue @@ -8,7 +8,8 @@ SPDX-License-Identifier: AGPL-3.0-only
+ v-model="params[k]" + > @@ -53,12 +54,12 @@ SPDX-License-Identifier: AGPL-3.0-only + + diff --git a/packages/frontend/src/components/MkServerSetupWizard.vue b/packages/frontend/src/components/MkServerSetupWizard.vue index 1d2dfed297..8e3b41e754 100644 --- a/packages/frontend/src/components/MkServerSetupWizard.vue +++ b/packages/frontend/src/components/MkServerSetupWizard.vue @@ -134,7 +134,7 @@ SPDX-License-Identifier: AGPL-3.0-only
{{ i18n.ts._serverSettings.entrancePageStyle }}:
-
{{ serverSettings.clientOptions.entrancePageStyle }}
+
{{ serverSettings.clientOptions?.entrancePageStyle }}
@@ -191,7 +191,6 @@ SPDX-License-Identifier: AGPL-3.0-only + + diff --git a/packages/frontend/src/pages/admin-file.vue b/packages/frontend/src/pages/admin-file.vue index 052829ffe2..608a77c06b 100644 --- a/packages/frontend/src/pages/admin-file.vue +++ b/packages/frontend/src/pages/admin-file.vue @@ -4,197 +4,37 @@ SPDX-License-Identifier: AGPL-3.0-only --> - - diff --git a/packages/frontend/src/pages/admin/branding.vue b/packages/frontend/src/pages/admin/branding.vue index f78a4f27bd..e5e0f087e1 100644 --- a/packages/frontend/src/pages/admin/branding.vue +++ b/packages/frontend/src/pages/admin/branding.vue @@ -152,6 +152,7 @@ SPDX-License-Identifier: AGPL-3.0-only import { ref, computed } from 'vue'; import JSON5 from 'json5'; import { host } from '@@/js/config.js'; +import type { ClientOptions } from '@/instance.js'; import MkInput from '@/components/MkInput.vue'; import MkTextarea from '@/components/MkTextarea.vue'; import * as os from '@/os.js'; @@ -166,9 +167,13 @@ import MkSwitch from '@/components/MkSwitch.vue'; const meta = await misskeyApi('admin/meta'); -const entrancePageStyle = ref(meta.clientOptions.entrancePageStyle ?? 'classic'); -const showTimelineForVisitor = ref(meta.clientOptions.showTimelineForVisitor ?? true); -const showActivitiesForVisitor = ref(meta.clientOptions.showActivitiesForVisitor ?? true); +// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition +const entrancePageStyle = ref(meta.clientOptions.entrancePageStyle ?? 'classic'); +// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition +const showTimelineForVisitor = ref(meta.clientOptions.showTimelineForVisitor ?? true); +// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition +const showActivitiesForVisitor = ref(meta.clientOptions.showActivitiesForVisitor ?? true); + const iconUrl = ref(meta.iconUrl); const app192IconUrl = ref(meta.app192IconUrl); const app512IconUrl = ref(meta.app512IconUrl); @@ -186,11 +191,11 @@ const manifestJsonOverride = ref(meta.manifestJsonOverride === '' ? '{}' : JSON. function save() { os.apiWithDialog('admin/update-meta', { - clientOptions: { + clientOptions: ({ entrancePageStyle: entrancePageStyle.value, showTimelineForVisitor: showTimelineForVisitor.value, showActivitiesForVisitor: showActivitiesForVisitor.value, - }, + } as ClientOptions) as any, iconUrl: iconUrl.value, app192IconUrl: app192IconUrl.value, app512IconUrl: app512IconUrl.value, diff --git a/packages/frontend/src/pages/admin/database.vue b/packages/frontend/src/pages/admin/database.vue index d51f43c098..f41967d3bd 100644 --- a/packages/frontend/src/pages/admin/database.vue +++ b/packages/frontend/src/pages/admin/database.vue @@ -6,19 +6,18 @@ SPDX-License-Identifier: AGPL-3.0-only + + diff --git a/packages/frontend/src/pages/gallery/edit.vue b/packages/frontend/src/pages/gallery/edit.vue index 3fd462e0b9..12d1a37390 100644 --- a/packages/frontend/src/pages/gallery/edit.vue +++ b/packages/frontend/src/pages/gallery/edit.vue @@ -4,162 +4,35 @@ SPDX-License-Identifier: AGPL-3.0-only --> - - diff --git a/packages/frontend/src/pages/notifications.vue b/packages/frontend/src/pages/notifications.vue index 71c957460c..5d308e6b29 100644 --- a/packages/frontend/src/pages/notifications.vue +++ b/packages/frontend/src/pages/notifications.vue @@ -21,7 +21,7 @@ SPDX-License-Identifier: AGPL-3.0-only