From 2c4ba4723f7ce936a1eadd056416f0d676d1860e Mon Sep 17 00:00:00 2001 From: atsuchan <83960488+atsu1125@users.noreply.github.com> Date: Sun, 4 Feb 2024 20:44:35 +0900 Subject: [PATCH 01/40] =?UTF-8?q?fix(backend):=20=E3=83=A1=E3=83=BC?= =?UTF-8?q?=E3=83=AB=E9=85=8D=E4=BF=A1=E6=A9=9F=E8=83=BD=E3=81=8C=E7=84=A1?= =?UTF-8?q?=E5=8A=B9=E3=81=AA=E3=82=89=E3=81=B0=E3=83=A1=E3=83=BC=E3=83=AB?= =?UTF-8?q?=E3=82=92=E9=80=81=E3=82=8B=E3=81=93=E3=81=A8=E3=81=AE=E3=81=AA?= =?UTF-8?q?=E3=81=84=E3=82=88=E3=81=86=E3=81=AB=20(#13152)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Do not send email if email delivery is disabled --- packages/backend/src/core/EmailService.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/backend/src/core/EmailService.ts b/packages/backend/src/core/EmailService.ts index 8daee148eb..89722965c1 100644 --- a/packages/backend/src/core/EmailService.ts +++ b/packages/backend/src/core/EmailService.ts @@ -40,6 +40,8 @@ export class EmailService { public async sendEmail(to: string, subject: string, html: string, text: string) { const meta = await this.metaService.fetch(true); + if (!meta.enableEmail) return; + const iconUrl = `${this.config.url}/static-assets/mi-white.png`; const emailSettingUrl = `${this.config.url}/settings/email`; -- GitLab From bafef1f8b45b5117c4418f68160ea288135571c3 Mon Sep 17 00:00:00 2001 From: Gianni Ceccarelli <dakkar@thenautilus.net> Date: Sun, 4 Feb 2024 11:46:28 +0000 Subject: [PATCH 02/40] ignore `instance.actor` when checking if there are local users (#13146) * ignore `instance.actor` when checking if there are local users We've seen this happen a few times: * there was some AP software at $some_domain * it gets replaced by Misskey * before the first user can be created, an AP activity comes in * Misskey resolves the activity * to do this, it creates the `instance.actor` to sign its request * now there *is* a local user, so the `meta` endpoint returns `requireSetup:false` * the admin is very confused This commit factors out the check, and doesn't count the `instance.actor` as a real user. * autogen bits --- packages/backend/src/core/InstanceActorService.ts | 10 +++++++++- packages/backend/src/core/SignupService.ts | 4 +++- .../src/server/api/endpoints/admin/accounts/create.ts | 8 ++++---- packages/backend/src/server/api/endpoints/meta.ts | 11 ++++------- packages/misskey-js/src/autogen/apiClientJSDoc.ts | 2 +- packages/misskey-js/src/autogen/endpoint.ts | 2 +- packages/misskey-js/src/autogen/entities.ts | 2 +- packages/misskey-js/src/autogen/models.ts | 2 +- packages/misskey-js/src/autogen/types.ts | 2 +- 9 files changed, 25 insertions(+), 18 deletions(-) diff --git a/packages/backend/src/core/InstanceActorService.ts b/packages/backend/src/core/InstanceActorService.ts index b40fd46291..7ce8dc96a1 100644 --- a/packages/backend/src/core/InstanceActorService.ts +++ b/packages/backend/src/core/InstanceActorService.ts @@ -4,7 +4,7 @@ */ import { Inject, Injectable } from '@nestjs/common'; -import { IsNull } from 'typeorm'; +import { IsNull, Not } from 'typeorm'; import type { MiLocalUser } from '@/models/User.js'; import type { UsersRepository } from '@/models/_.js'; import { MemorySingleCache } from '@/misc/cache.js'; @@ -27,6 +27,14 @@ export class InstanceActorService { this.cache = new MemorySingleCache<MiLocalUser>(Infinity); } + @bindThis + public async realLocalUsersPresent(): Promise<boolean> { + return await this.usersRepository.existsBy({ + host: IsNull(), + username: Not(ACTOR_USERNAME), + }); + } + @bindThis public async getInstanceActor(): Promise<MiLocalUser> { const cached = this.cache.get(); diff --git a/packages/backend/src/core/SignupService.ts b/packages/backend/src/core/SignupService.ts index b9e3ded46f..81c2b241eb 100644 --- a/packages/backend/src/core/SignupService.ts +++ b/packages/backend/src/core/SignupService.ts @@ -16,6 +16,7 @@ import { MiUserKeypair } from '@/models/UserKeypair.js'; import { MiUsedUsername } from '@/models/UsedUsername.js'; import generateUserToken from '@/misc/generate-native-user-token.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; +import { InstanceActorService } from '@/core/InstanceActorService.js'; import { bindThis } from '@/decorators.js'; import UsersChart from '@/core/chart/charts/users.js'; import { UtilityService } from '@/core/UtilityService.js'; @@ -37,6 +38,7 @@ export class SignupService { private userEntityService: UserEntityService, private idService: IdService, private metaService: MetaService, + private instanceActorService: InstanceActorService, private usersChart: UsersChart, ) { } @@ -81,7 +83,7 @@ export class SignupService { throw new Error('USED_USERNAME'); } - const isTheFirstUser = (await this.usersRepository.countBy({ host: IsNull() })) === 0; + const isTheFirstUser = !await this.instanceActorService.realLocalUsersPresent(); if (!opts.ignorePreservedUsernames && !isTheFirstUser) { const instance = await this.metaService.fetch(true); diff --git a/packages/backend/src/server/api/endpoints/admin/accounts/create.ts b/packages/backend/src/server/api/endpoints/admin/accounts/create.ts index b18a7e0e41..14fd69a1a2 100644 --- a/packages/backend/src/server/api/endpoints/admin/accounts/create.ts +++ b/packages/backend/src/server/api/endpoints/admin/accounts/create.ts @@ -9,6 +9,7 @@ import { Endpoint } from '@/server/api/endpoint-base.js'; import type { UsersRepository } from '@/models/_.js'; import { SignupService } from '@/core/SignupService.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; +import { InstanceActorService } from '@/core/InstanceActorService.js'; import { localUsernameSchema, passwordSchema } from '@/models/User.js'; import { DI } from '@/di-symbols.js'; import { Packed } from '@/misc/json-schema.js'; @@ -46,13 +47,12 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- private userEntityService: UserEntityService, private signupService: SignupService, + private instanceActorService: InstanceActorService, ) { super(meta, paramDef, async (ps, _me, token) => { const me = _me ? await this.usersRepository.findOneByOrFail({ id: _me.id }) : null; - const noUsers = (await this.usersRepository.countBy({ - host: IsNull(), - })) === 0; - if ((!noUsers && !me?.isRoot) || token !== null) throw new Error('access denied'); + const realUsers = await this.instanceActorService.realLocalUsersPresent(); + if ((realUsers && !me?.isRoot) || token !== null) throw new Error('access denied'); const { account, secret } = await this.signupService.signup({ username: ps.username, diff --git a/packages/backend/src/server/api/endpoints/meta.ts b/packages/backend/src/server/api/endpoints/meta.ts index e1d3473482..c6489f67ac 100644 --- a/packages/backend/src/server/api/endpoints/meta.ts +++ b/packages/backend/src/server/api/endpoints/meta.ts @@ -6,11 +6,12 @@ import { IsNull, LessThanOrEqual, MoreThan, Brackets } from 'typeorm'; import { Inject, Injectable } from '@nestjs/common'; import JSON5 from 'json5'; -import type { AdsRepository, UsersRepository } from '@/models/_.js'; +import type { AdsRepository } from '@/models/_.js'; import { MAX_NOTE_TEXT_LENGTH } from '@/const.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { MetaService } from '@/core/MetaService.js'; +import { InstanceActorService } from '@/core/InstanceActorService.js'; import type { Config } from '@/config.js'; import { DI } from '@/di-symbols.js'; import { DEFAULT_POLICIES } from '@/core/RoleService.js'; @@ -326,14 +327,12 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- @Inject(DI.config) private config: Config, - @Inject(DI.usersRepository) - private usersRepository: UsersRepository, - @Inject(DI.adsRepository) private adsRepository: AdsRepository, private userEntityService: UserEntityService, private metaService: MetaService, + private instanceActorService: InstanceActorService, ) { super(meta, paramDef, async (ps, me) => { const instance = await this.metaService.fetch(true); @@ -412,9 +411,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- ...(ps.detail ? { cacheRemoteFiles: instance.cacheRemoteFiles, cacheRemoteSensitiveFiles: instance.cacheRemoteSensitiveFiles, - requireSetup: (await this.usersRepository.countBy({ - host: IsNull(), - })) === 0, + requireSetup: !await this.instanceActorService.realLocalUsersPresent(), } : {}), }; diff --git a/packages/misskey-js/src/autogen/apiClientJSDoc.ts b/packages/misskey-js/src/autogen/apiClientJSDoc.ts index 0f1223d1f8..121e349b85 100644 --- a/packages/misskey-js/src/autogen/apiClientJSDoc.ts +++ b/packages/misskey-js/src/autogen/apiClientJSDoc.ts @@ -1,6 +1,6 @@ /* * version: 2024.2.0-beta.8 - * generatedAt: 2024-01-31T01:46:47.964Z + * generatedAt: 2024-02-02T14:18:15.716Z */ import type { SwitchCaseResponseType } from '../api.js'; diff --git a/packages/misskey-js/src/autogen/endpoint.ts b/packages/misskey-js/src/autogen/endpoint.ts index d319fe7978..f7b6f52fde 100644 --- a/packages/misskey-js/src/autogen/endpoint.ts +++ b/packages/misskey-js/src/autogen/endpoint.ts @@ -1,6 +1,6 @@ /* * version: 2024.2.0-beta.8 - * generatedAt: 2024-01-31T01:46:47.962Z + * generatedAt: 2024-02-02T14:18:15.712Z */ import type { diff --git a/packages/misskey-js/src/autogen/entities.ts b/packages/misskey-js/src/autogen/entities.ts index ea2ca3948a..b971d8bda7 100644 --- a/packages/misskey-js/src/autogen/entities.ts +++ b/packages/misskey-js/src/autogen/entities.ts @@ -1,6 +1,6 @@ /* * version: 2024.2.0-beta.8 - * generatedAt: 2024-01-31T01:46:47.961Z + * generatedAt: 2024-02-02T14:18:15.709Z */ import { operations } from './types.js'; diff --git a/packages/misskey-js/src/autogen/models.ts b/packages/misskey-js/src/autogen/models.ts index 8ab5eeac9f..719f7923de 100644 --- a/packages/misskey-js/src/autogen/models.ts +++ b/packages/misskey-js/src/autogen/models.ts @@ -1,6 +1,6 @@ /* * version: 2024.2.0-beta.8 - * generatedAt: 2024-01-31T01:46:47.959Z + * generatedAt: 2024-02-02T14:18:15.708Z */ import { components } from './types.js'; diff --git a/packages/misskey-js/src/autogen/types.ts b/packages/misskey-js/src/autogen/types.ts index 1731b57003..0a78be1dfd 100644 --- a/packages/misskey-js/src/autogen/types.ts +++ b/packages/misskey-js/src/autogen/types.ts @@ -3,7 +3,7 @@ /* * version: 2024.2.0-beta.8 - * generatedAt: 2024-01-31T01:46:47.878Z + * generatedAt: 2024-02-02T14:18:15.529Z */ /** -- GitLab From dabf1867fd5619d82b860482ffaf7908a4b9f0df Mon Sep 17 00:00:00 2001 From: Gianni Ceccarelli <dakkar@thenautilus.net> Date: Sun, 4 Feb 2024 12:03:49 +0000 Subject: [PATCH 03/40] keep cached avatar&banner when refresh fails to get new values (#13145) * keep cached avatar&banner when refresh fails to get new values when the remote explicitly tells us a user image is gone, we remove our cached value, but if we fail to get the image, we keep whatever value we already have this should minimise the problem of avatars randomly disappearing * autogen bits * pnpm run build-misskey-js-with-types --------- Co-authored-by: tamaina <tamaina@hotmail.co.jp> --- .../activitypub/models/ApPersonService.ts | 35 ++++++++++++++----- .../misskey-js/src/autogen/apiClientJSDoc.ts | 2 +- packages/misskey-js/src/autogen/endpoint.ts | 2 +- packages/misskey-js/src/autogen/entities.ts | 2 +- packages/misskey-js/src/autogen/models.ts | 2 +- packages/misskey-js/src/autogen/types.ts | 2 +- 6 files changed, 31 insertions(+), 14 deletions(-) diff --git a/packages/backend/src/core/activitypub/models/ApPersonService.ts b/packages/backend/src/core/activitypub/models/ApPersonService.ts index bf38d5fd60..aec34aeb54 100644 --- a/packages/backend/src/core/activitypub/models/ApPersonService.ts +++ b/packages/backend/src/core/activitypub/models/ApPersonService.ts @@ -225,20 +225,37 @@ export class ApPersonService implements OnModuleInit { return null; } - private async resolveAvatarAndBanner(user: MiRemoteUser, icon: any, image: any): Promise<Pick<MiRemoteUser, 'avatarId' | 'bannerId' | 'avatarUrl' | 'bannerUrl' | 'avatarBlurhash' | 'bannerBlurhash'>> { + private async resolveAvatarAndBanner(user: MiRemoteUser, icon: any, image: any): Promise<Partial<Pick<MiRemoteUser, 'avatarId' | 'bannerId' | 'avatarUrl' | 'bannerUrl' | 'avatarBlurhash' | 'bannerBlurhash'>>> { + if (user == null) throw new Error('failed to create user: user is null'); + const [avatar, banner] = await Promise.all([icon, image].map(img => { - if (img == null) return null; - if (user == null) throw new Error('failed to create user: user is null'); + // if we have an explicitly missing image, return an + // explicitly-null set of values + if ((img == null) || (typeof img === 'object' && img.url == null)) { + return { id: null, url: null, blurhash: null }; + } + return this.apImageService.resolveImage(user, img).catch(() => null); })); + /* + we don't want to return nulls on errors! if the database fields + are already null, nothing changes; if the database has old + values, we should keep those. The exception is if the remote has + actually removed the images: in that case, the block above + returns the special {id:null}&c value, and we return those + */ return { - avatarId: avatar?.id ?? null, - bannerId: banner?.id ?? null, - avatarUrl: avatar ? this.driveFileEntityService.getPublicUrl(avatar, 'avatar') : null, - bannerUrl: banner ? this.driveFileEntityService.getPublicUrl(banner) : null, - avatarBlurhash: avatar?.blurhash ?? null, - bannerBlurhash: banner?.blurhash ?? null, + ...( avatar ? { + avatarId: avatar.id, + avatarUrl: avatar.url ? this.driveFileEntityService.getPublicUrl(avatar, 'avatar') : null, + avatarBlurhash: avatar.blurhash, + } : {}), + ...( banner ? { + bannerId: banner.id, + bannerUrl: banner.url ? this.driveFileEntityService.getPublicUrl(banner) : null, + bannerBlurhash: banner.blurhash, + } : {}), }; } diff --git a/packages/misskey-js/src/autogen/apiClientJSDoc.ts b/packages/misskey-js/src/autogen/apiClientJSDoc.ts index 121e349b85..7c727d2878 100644 --- a/packages/misskey-js/src/autogen/apiClientJSDoc.ts +++ b/packages/misskey-js/src/autogen/apiClientJSDoc.ts @@ -1,6 +1,6 @@ /* * version: 2024.2.0-beta.8 - * generatedAt: 2024-02-02T14:18:15.716Z + * generatedAt: 2024-02-04T11:51:13.598Z */ import type { SwitchCaseResponseType } from '../api.js'; diff --git a/packages/misskey-js/src/autogen/endpoint.ts b/packages/misskey-js/src/autogen/endpoint.ts index f7b6f52fde..cf9f96b526 100644 --- a/packages/misskey-js/src/autogen/endpoint.ts +++ b/packages/misskey-js/src/autogen/endpoint.ts @@ -1,6 +1,6 @@ /* * version: 2024.2.0-beta.8 - * generatedAt: 2024-02-02T14:18:15.712Z + * generatedAt: 2024-02-04T11:51:13.595Z */ import type { diff --git a/packages/misskey-js/src/autogen/entities.ts b/packages/misskey-js/src/autogen/entities.ts index b971d8bda7..2930f2cb7f 100644 --- a/packages/misskey-js/src/autogen/entities.ts +++ b/packages/misskey-js/src/autogen/entities.ts @@ -1,6 +1,6 @@ /* * version: 2024.2.0-beta.8 - * generatedAt: 2024-02-02T14:18:15.709Z + * generatedAt: 2024-02-04T11:51:13.593Z */ import { operations } from './types.js'; diff --git a/packages/misskey-js/src/autogen/models.ts b/packages/misskey-js/src/autogen/models.ts index 719f7923de..f01beaa706 100644 --- a/packages/misskey-js/src/autogen/models.ts +++ b/packages/misskey-js/src/autogen/models.ts @@ -1,6 +1,6 @@ /* * version: 2024.2.0-beta.8 - * generatedAt: 2024-02-02T14:18:15.708Z + * generatedAt: 2024-02-04T11:51:13.592Z */ import { components } from './types.js'; diff --git a/packages/misskey-js/src/autogen/types.ts b/packages/misskey-js/src/autogen/types.ts index 0a78be1dfd..77a493fe2e 100644 --- a/packages/misskey-js/src/autogen/types.ts +++ b/packages/misskey-js/src/autogen/types.ts @@ -3,7 +3,7 @@ /* * version: 2024.2.0-beta.8 - * generatedAt: 2024-02-02T14:18:15.529Z + * generatedAt: 2024-02-04T11:51:13.473Z */ /** -- GitLab From 03351cec0ccdba39b36619a401c6af8b65ea0295 Mon Sep 17 00:00:00 2001 From: syuilo <Syuilotan@yahoo.co.jp> Date: Mon, 5 Feb 2024 11:03:12 +0900 Subject: [PATCH 04/40] update patrons --- packages/frontend/src/pages/about-misskey.vue | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/frontend/src/pages/about-misskey.vue b/packages/frontend/src/pages/about-misskey.vue index f8eced8d72..acaae9f1d7 100644 --- a/packages/frontend/src/pages/about-misskey.vue +++ b/packages/frontend/src/pages/about-misskey.vue @@ -214,6 +214,12 @@ const patronsWithIcon = [{ }, { name: 'taichan', icon: 'https://assets.misskey-hub.net/patrons/f981ab0159fb4e2c998e05f7263e1cd9.png', +}, { + name: '猫å‰ã‚ˆã‚ŠãŠ', + icon: 'https://assets.misskey-hub.net/patrons/a11518b3b34b4536a4bdd7178ba76a7b.png', +}, { + name: 'æœ‰æ –ã‹ãšã¿', + icon: 'https://assets.misskey-hub.net/patrons/9240e8e0ba294a8884143e99ac7ed6a0.png', }]; const patrons = [ -- GitLab From c5ac2ae163c2035a1dc92eaee478ded261a89d9c Mon Sep 17 00:00:00 2001 From: syuilo <Syuilotan@yahoo.co.jp> Date: Mon, 5 Feb 2024 11:03:55 +0900 Subject: [PATCH 05/40] New Crowdin updates (#13156) * New translations ja-jp.yml (Italian) * New translations ja-jp.yml (Italian) * New translations ja-jp.yml (Korean) * New translations ja-jp.yml (Korean (Gyeongsang)) * New translations ja-jp.yml (Korean (Gyeongsang)) * New translations ja-jp.yml (Korean) * New translations ja-jp.yml (Catalan) * New translations ja-jp.yml (Catalan) * New translations ja-jp.yml (Catalan) * New translations ja-jp.yml (Catalan) * New translations ja-jp.yml (Catalan) --- locales/ca-ES.yml | 191 ++++++++++++++++++++++++++++++++++++++++++++++ locales/it-IT.yml | 60 ++++++++++++++- locales/ko-GS.yml | 72 ++++++++++++++++- locales/ko-KR.yml | 8 +- 4 files changed, 324 insertions(+), 7 deletions(-) diff --git a/locales/ca-ES.yml b/locales/ca-ES.yml index 9b1806a2cf..6c0d212ad2 100644 --- a/locales/ca-ES.yml +++ b/locales/ca-ES.yml @@ -1157,6 +1157,12 @@ edited: "Editat" notificationRecieveConfig: "Parà metres de notificacions" mutualFollow: "Seguidor mutu" fileAttachedOnly: "Només notes amb adjunts" +showRepliesToOthersInTimeline: "Mostrar les respostes a altres a la lÃnia de temps" +hideRepliesToOthersInTimeline: "Amagar les respostes a altres a la lÃnia de temps" +showRepliesToOthersInTimelineAll: "Mostrar les respostes a altres a usuaris que segueixes a la lÃnia de temps" +hideRepliesToOthersInTimelineAll: "Ocultar les teves respostes a tots els usuaris que segueixes a la lÃnia de temps" +confirmShowRepliesAll: "Aquesta opció no té marxa enrere. Vols mostrar les teves respostes a tots els que segueixes a la teva lÃnia de temps?" +confirmHideRepliesAll: "Aquesta opció no té marxa enrere. Vols ocultar les teves respostes a tots els usuaris que segueixes a la lÃnia de temps?" externalServices: "Serveis externs" impressum: "Impressum" impressumUrl: "Adreça URL impressum" @@ -1187,7 +1193,25 @@ seasonalScreenEffect: "Efectes de pantalla segons les estacions" decorate: "Decorar" addMfmFunction: "Afegeix funcions MFM" enableQuickAddMfmFunction: "Activar accés rà pid per afegir funcions MFM" +bubbleGame: "Bubble Game" +sfx: "Efectes de so" +soundWillBePlayed: "Es reproduiran efectes de so" +showReplay: "Veure reproducció" +replay: "Reproduir" +replaying: "Reproduint" +ranking: "Classificació" lastNDays: "Últims {n} dies" +backToTitle: "Torna al tÃtol" +hemisphere: "Geolocalització" +withSensitive: "Incloure notes amb fitxers sensibles" +userSaysSomethingSensitive: "La publicació de {name} conte material sensible" +enableHorizontalSwipe: "Lliscar per canviar de pestanya" +_bubbleGame: + howToPlay: "Com es juga" + _howToPlay: + section1: "Ajusta la posició i deixa caure l'objecte dintre la caixa." + section2: "Quan dos objectes del mateix tipus es toquen, canviaran en un objecte diferent i guanyares punts." + section3: "El joc s'acabarà quan els objectes sobresurtin de la caixa. Intenta aconseguir la puntuació més gran possible fusionant objectes mentre impedeixes que sobresurtin de la caixa!" _announcement: forExistingUsers: "Anunci per usuaris registrats" forExistingUsersDescription: "Aquest avÃs només es mostrarà als usuaris existents fins al moment de la publicació. Si no també es mostrarà als usuaris que es registrin després de la publicació." @@ -1209,8 +1233,32 @@ _initialAccountSetting: privacySetting: "Configuració de seguretat" theseSettingsCanEditLater: "Aquests ajustos es poden canviar més tard." youCanEditMoreSettingsInSettingsPageLater: "A més d'això, es poden fer diferents configuracions a través de la pà gina de configuració. Assegureu-vos de comprovar-ho més tard." + followUsers: "Prova de seguir usuaris que t'interessin per construir la teva lÃnia de temps." + pushNotificationDescription: "Activant les notificacions emergents et permetrà rebre notificacions de {name} directament al teu dispositiu." + initialAccountSettingCompleted: "Configuració del perfil completada!" + haveFun: "Disfruta {name}!" + youCanContinueTutorial: "Pots continuar amb un tutorial per aprendre a Fer servir {name} (MissKey) o tu pots estalviar i començar a fer-lo servir ja." + startTutorial: "Començar el tutorial" + skipAreYouSure: "Et vols saltar la configuració del perfil?" + laterAreYouSure: "Vols continuar la configuració del perfil més tard?" _initialTutorial: + launchTutorial: "Començar tutorial" + title: "Tutorial" + wellDone: "Ben fet!" + skipAreYouSure: "Sortir del tutorial?" + _landing: + title: "Benvingut al tutorial" + description: "Aquà aprendrà s el bà sic per poder fer servir Misskey i les seves caracterÃstiques." + _note: + title: "Què és una Nota?" + description: "Les publicacions a Misskey es diuen 'Notes'. Les Notes s'ordenen cronològicament a la lÃnia de temps i s'actualitzen de forma automà tica." + reply: "Fes clic en aquest botó per contestar a un missatge. També és possible contestar a una contestació, continuant la conversació en forma de fil." + renote: "Pots compartir una Nota a la teva pròpia lÃnia de temps. Inclús pots citar-les amb els teus comentaris." + reaction: "Pots afegir reaccions a les Notes. Entrarem més en detall a la pròxima pà gina." + menu: "Pots veure els detalls de les Notes, copiar enllaços i fer diferents accions." _reaction: + title: "Què són les Reaccions?" + description: "Es poden reaccionar a les Notes amb diferents emoticones. Les reaccions et permeten expressar matisos que hi són més enllà d'un simple m'agrada." letsTryReacting: "Es poden afegir reaccions fent clic al botó '+'. Prova reaccionant a aquesta nota!" reactToContinue: "Afegeix una reacció per continuar." reactNotification: "Rebrà s notificacions en temps real quan un usuari reaccioni a les teves notes." @@ -1272,9 +1320,75 @@ _serverSettings: shortName: "Nom curt" shortNameDescription: "Una abreviatura del nom de la instà ncia que es poguà mostrar en cas que el nom oficial sigui massa llarg" fanoutTimelineDescription: "Quan es troba activat millora bastant el rendiment quan es recuperen les lÃnies de temps i redueix la carrega de la base de dades. Com a contrapunt, l'ús de memòria de Redis es veurà incrementada. Considera d'estabilitat aquesta opció en cas de tenir un servidor amb poca memòria o si tens problemes de inestabilitat." + fanoutTimelineDbFallback: "Carregar de la base de dades" + fanoutTimelineDbFallbackDescription: "Quan s'activa, la lÃnia de temps fa servir la base de dades per consultes adicionals si la lÃnia de temps no es troba a la memòria cau. Si és desactiva la cà rrega del servidor és veure reduïda, però també és reduirà el nombre de lÃnies de temps que és poden obtenir." +_accountMigration: + moveFrom: "Migrar un altre compte a aquest" + moveFromSub: "Crear un à lies per un altre compte" + moveFromLabel: "Compte original #{n}" + moveFromDescription: "Has de crear un à lies del compte que vols migrar en aquest compte.\nFes servir aquest format per posar el compte que vols migrar: @nomusuari@servidor.exemple.com\nPer esborrar l'à lies deixa el camp en blanc (no és recomanable de fer)" + moveTo: "Migrar aquest compte a un altre" + moveToLabel: "Compte al qual es vol migrar:" + moveCannotBeUndone: "Les migracions dels comptes no es poden desfer." + moveAccountDescription: "Això migrarà la teva compte a un altre diferent.\n ・Els seguidors d'aquest compte és passaran al compte nou de forma automà tica\n ・Es deixaran de seguir a tots els usuaris que es segueixen actualment en aquest compte\n ・No es poden crear notes noves, etc. en aquest compte\n\nSi bé la migració de seguidors es automà tica, has de preparar alguns pasos manualment per migrar la llista d'usuaris que segueixes. Per fer això has d'exportar els seguidors que després importaraes al compte nou mitjançant el menú de configuració. El mateix procediment s'ha de seguir per less teves llistes i els teus usuaris silenciats i bloquejats.\n\n(Aquesta explicació s'aplica a Misskey v13.12.0 i posteriors. Altres aplicacions, com Mastodon, poden funcionar diferent.)" + moveAccountHowTo: "Per fer la migració, primer has de crear un à lies per aquest compte al compte al qual vols migrar.\nDesprés de crear l'à lies, introdueix el compte al qual vols migrar amb el format següent: @nomusuari@servidor.exemple.com" + startMigration: "Migrar" + migrationConfirm: "Vols migrar aquest compte a {account}? Una vegada comenci la migració no es podrà parar O fer marxa enrere i no podrà s tornar a fer servir aquest compte mai més." + movedAndCannotBeUndone: "Aquest compte ha migrat.\nLes migracions no es poden desfer." + postMigrationNote: "Aquest compte deixarà de seguir tots els comptes que segueix 24 hores després de germinar la migració.\nEl nombre de seguidors i seguits passarà a ser de zero. Per evitar que els teus seguidors no puguin veure les publicacions marcades com a només seguidors continuaren seguint aquest compte." + movedTo: "Nou compte:" _achievements: + earnedAt: "Desbloquejat el" _types: + _notes1: + title: "AquÃ, configurant el meu msky" + description: "Publica la teva primera Nota" + flavor: "Passa-t'ho bé fent servir Miskey!" + _notes10: + title: "Algunes notes" + description: "Publica 10 notes" + _notes100: + title: "Un piló de notes" + description: "Publica 100 notes" + _notes500: + title: "Cobert de notes" + description: "Publica 500 notes" + _notes1000: + title: "Un piló de notes" + description: "1 000 notes publicades" + _notes5000: + title: "Desbordament de notes" + description: "5 000 notes publicades" + _notes10000: + title: "Supernota" + description: "10 000 notes publicades" + _notes20000: + title: "Necessito... Més... Notes!" + description: "20 000 notes publicades" + _notes30000: + title: "Notes notes notes!" + description: "30 000 notes publicades" + _notes40000: + title: "Fà brica de notes" + description: "40 000 notes publicades" + _notes50000: + title: "Planeta de notes" + description: "50 000 notes publicades" + _notes60000: + title: "Quà sar de notes" + description: "60 000 notes publicades" + _notes70000: + title: "Forat negre de notes" + description: "70 000 notes publicades" + _notes80000: + title: "Galà xia de notes" + description: "80 000 notes publicades" + _notes90000: + title: "Univers de notes" + description: "90 000 notes publicades" _notes100000: + title: "ALL YOUR NOTE ARE BELONG TO US" + description: "100 000 notes publicades" flavor: "Segur que tens moltes coses a dir?" _login3: title: "Principiant I" @@ -1347,13 +1461,90 @@ _achievements: description: "És la primera vegada que et segueixo" _following10: title: "Segueix-me... Segueix-me..." + description: "Seguir 10 usuaris" + _following50: + title: "Molts amics" + description: "Seguir 50 comptes" + _following100: + title: "100 amics" + description: "Segueixes 100 comptes" + _following300: + title: "Sobrecà rrega d'amics" + description: "Segueixes 300 comptes" + _followers1: + title: "Primer seguidor" + description: "1 seguidor guanyat" + _followers10: + title: "Segueix-me!" + description: "10 seguidors guanyats" + _followers50: + title: "Venen en manada" + description: "50 seguidors guanyats" + _followers100: + title: "Popular" + description: "100 seguidors guanyats" + _followers300: + title: "Si us plau, d'un en un!" + description: "300 seguidors guanyats" + _followers500: + title: "Torre de rà dio" + description: "500 seguidors guanyats" + _followers1000: + title: "Influenciador" + description: "1 000 seguidors guanyats" + _collectAchievements30: + title: "Col·leccionista d'èxits " + description: "Desbloqueja 30 assoliments" + _viewAchievements3min: + title: "M'agraden els èxits " + description: "Mira la teva llista d'assoliments durant més de 3 minuts" + _iLoveMisskey: + title: "Estimo Misskey" + description: "Publica \"I ⤠#Misskey\"" + flavor: "L'equip de desenvolupament de Misskey agraeix el vostre suport!" + _foundTreasure: + title: "A la Recerca del Tresor" + description: "Has trobat el tresor amagat" + _client30min: + title: "Parem una estona" + description: "Mantingues obert Misskey per 30 minuts" + _client60min: + title: "A totes amb Misskey" + description: "Mantingues Misskey obert per 60 minuts" + _noteDeletedWithin1min: + title: "No et preocupis" + description: "Esborra una nota al minut de publicar-la" + _postedAtLateNight: + title: "Nocturn" + description: "Publica una nota a altes hores de la nit " + flavor: "És hora d'anar a dormir." _open3windows: title: "Multi finestres" description: "I va obrir més de tres finestres" _driveFolderCircularReference: title: "Consulteu la secció de bucle" _role: + permission: "Permisos de rol" + descriptionOfPermission: "Els <b>Moderadors</b> poden fer operacions bà siques de moderació.\nEls <b>Administradors</b> poden canviar tots els ajustos del servidor." assignTarget: "Assignar " + descriptionOfAssignTarget: "<b>Manual</b> per canviar manualment qui és part d'aquest rol i qui no.\n<b>Condicional</b> per afegir o eliminar de manera automà tica els usuaris d'aquest rol basat en una determinada condició." + manual: "Manual" + manualRoles: "Rols manuals" + conditional: "Condicional" + conditionalRoles: "Rols condicionals" + condition: "Condició" + isConditionalRole: "Aquest és un rol condicional" + isPublic: "Rol públic" + descriptionOfIsPublic: "Aquest rol es mostrarà al perfil dels usuaris al que se'ls assigni." + options: "Opcions" + policies: "PolÃtiques" + baseRole: "Plantilla de rols" + useBaseValue: "Fer servir els valors de la plantilla de rols" + chooseRoleToAssign: "Selecciona els rols a assignar" + iconUrl: "URL de la icona " + asBadge: "Mostrar com a insÃgnia " + descriptionOfAsBadge: "La icona d'aquest rol es mostrarà al costat dels noms d'usuaris que tinguin assignats aquest rol." + isExplorable: "Fer el rol explorable" priority: "Prioritat" _priority: low: "Baixa" diff --git a/locales/it-IT.yml b/locales/it-IT.yml index 5678ab7e34..fdddf24360 100644 --- a/locales/it-IT.yml +++ b/locales/it-IT.yml @@ -102,7 +102,7 @@ defaultNoteVisibility: "Privacy predefinita delle note" follow: "Segui" followRequest: "Richiesta di follow" followRequests: "Richieste di follow" -unfollow: "Interrompi following" +unfollow: "Smetti di seguire" followRequestPending: "Richiesta in approvazione" enterEmoji: "Inserisci emoji" renote: "Rinota" @@ -380,9 +380,11 @@ hcaptcha: "hCaptcha" enableHcaptcha: "Abilita hCaptcha" hcaptchaSiteKey: "Chiave del sito" hcaptchaSecretKey: "Chiave segreta" +mcaptcha: "mCaptcha" enableMcaptcha: "Abilita hCaptcha" mcaptchaSiteKey: "Chiave del sito" mcaptchaSecretKey: "Chiave segreta" +mcaptchaInstanceUrl: "URL della istanza mCaptcha" recaptcha: "reCAPTCHA" enableRecaptcha: "Abilita reCAPTCHA" recaptchaSiteKey: "Chiave del sito" @@ -630,6 +632,7 @@ medium: "Medio" small: "Piccolo" generateAccessToken: "Genera token di accesso" permission: "Autorizzazioni " +adminPermission: "Privilegi amministrativi" enableAll: "Abilita tutto" disableAll: "Disabilita tutto" tokenRequested: "Autorizza accesso al profilo" @@ -673,6 +676,7 @@ useGlobalSettingDesc: "Quando attiva, verranno utilizzate le impostazioni notifi other: "Ulteriori" regenerateLoginToken: "Genera di nuovo un token di connessione" regenerateLoginTokenDescription: "Genera un nuovo token di autenticazione. Solitamente questa operazione non è necessaria: quando si genera un nuovo token, tutti i dispositivi vanno disconnessi." +theKeywordWhenSearchingForCustomEmoji: "Questa sarà la parola chiave durante la ricerca di emoji personalizzate" setMultipleBySeparatingWithSpace: "È possibile creare multiple voci separate da spazi." fileIdOrUrl: "ID o URL del file" behavior: "Comportamento" @@ -869,7 +873,7 @@ pubSub: "Publish/Subscribe del profilo" lastCommunication: "La comunicazione più recente" resolved: "Risolto" unresolved: "Non risolto" -breakFollow: "Interrompi follow" +breakFollow: "Impedire di seguirmi" breakFollowConfirm: "Vuoi davvero che questo profilo smetta di seguirti?" itsOn: "Abilitato" itsOff: "Disabilitato" @@ -885,6 +889,8 @@ makeReactionsPublicDescription: "La lista delle reazioni che avete fatto è a di classic: "Classico" muteThread: "Silenzia conversazione" unmuteThread: "Riattiva la conversazione" +followingVisibility: "Visibilità dei profili seguiti" +followersVisibility: "Visibilità dei profili che ti seguono" continueThread: "Altre conversazioni" deleteAccountConfirm: "Così verrà eliminato il profilo. Vuoi procedere?" incorrectPassword: "La password è errata." @@ -1053,6 +1059,8 @@ limitWidthOfReaction: "Limita la larghezza delle reazioni e ridimensionale" noteIdOrUrl: "ID della Nota o URL" video: "Video" videos: "Video" +audio: "Audio" +audioFiles: "Audio" dataSaver: "Risparmia dati" accountMigration: "Migrazione del profilo" accountMoved: "Questo profilo ha migrato altrove:" @@ -1183,7 +1191,27 @@ remainingN: "Rimangono: {n}" overwriteContentConfirm: "Vuoi davvero sostituire l'attuale contenuto?" seasonalScreenEffect: "Schermate in base alla stagione" decorate: "Decora" +addMfmFunction: "Aggiungi decorazioni" +enableQuickAddMfmFunction: "Attiva il selettore di funzioni MFM" +bubbleGame: "Bubble Game" +sfx: "Effetti sonori" +soundWillBePlayed: "Verrà riprodotto il suono" +showReplay: "Vedi i replay" +replay: "Replay" +replaying: "Replay in corso" +ranking: "Classifica" lastNDays: "Ultimi {n} giorni" +backToTitle: "Torna al titolo" +hemisphere: "Geolocalizzazione" +withSensitive: "Mostra le Note con allegati espliciti" +userSaysSomethingSensitive: "Note da {name} con allegati espliciti" +enableHorizontalSwipe: "Trascina per invertire i tab" +_bubbleGame: + howToPlay: "Come giocare" + _howToPlay: + section1: "Regola la posizione e rilascia l'oggetto nella casella." + section2: "Ottieni un punteggio, quando due oggetti dello stesso tipo si toccano e si trasformano in un oggetto diverso." + section3: "Se gli oggetti traboccano dalla scatola, il gioco finisce. Cerca di ottenere un punteggio elevato fondendo gli oggetti, evitando che escano dalla scatola!" _announcement: forExistingUsers: "Solo ai profili attuali" forExistingUsersDescription: "L'annuncio sarà visibile solo ai profili esistenti in questo momento. Se disabilitato, sarà visibile anche ai profili che verranno creati dopo la pubblicazione di questo annuncio." @@ -1554,6 +1582,13 @@ _achievements: _tutorialCompleted: title: "Attestato di partecipazione al corso per principianti di Misskey" description: "Ha completato il tutorial" + _bubbleGameExplodingHead: + title: "🤯" + description: "Estrai l'oggetto più grande dal Bubble Game" + _bubbleGameDoubleExplodingHead: + title: "Doppio 🤯" + description: "Due oggetti più grossi contemporaneamente nel Bubble Game" + flavor: "Ha le dimensioni di una bento-box 🤯 🤯" _role: new: "Nuovo ruolo" edit: "Modifica ruolo" @@ -1644,6 +1679,7 @@ _emailUnavailable: disposable: "Indirizzo email non utilizzabile" mx: "Server email non corretto" smtp: "Il server email non risponde" + banned: "Non puoi registrarti con questo indirizzo email" _ffVisibility: public: "Pubblica" followers: "Mostra solo ai follower" @@ -1935,6 +1971,26 @@ _permissions: "write:flash": "Modifica Play" "read:flash-likes": "Visualizza lista di Play piaciuti" "write:flash-likes": "Modifica lista di Play piaciuti" + "read:admin:abuse-user-reports": "Mostra i report dai profili utente" + "write:admin:delete-account": "Elimina l'account utente" + "write:admin:delete-all-files-of-a-user": "Elimina i file dell'account utente" + "read:admin:index-stats": "Visualizza informazioni sugli indici del database" + "read:admin:table-stats": "Visualizza informazioni sulle tabelle del database" + "read:admin:user-ips": "Visualizza indirizzi IP degli account" + "read:admin:meta": "Visualizza i metadati dell'istanza" + "write:admin:reset-password": "Ripristina la password dell'account utente" + "write:admin:resolve-abuse-user-report": "Risolvere le segnalazioni dagli account utente" + "write:admin:send-email": "Spedire email" + "read:admin:server-info": "Vedere le informazioni sul server" + "read:admin:show-moderation-log": "Vedere lo storico di moderazione" + "read:admin:show-user": "Vedere le informazioni private degli account utente" + "read:admin:show-users": "Vedere le informazioni private degli account utente" + "write:admin:suspend-user": "Sospendere i profili" + "write:admin:unset-user-avatar": "Rimuovere la foto profilo dai profili" + "write:admin:unset-user-banner": "Rimuovere l'immagine testata dai profili" + "write:admin:unsuspend-user": "Togliere la sospensione ai profili" + "write:admin:meta": "Modificare i metadati dell'istanza" + "write:admin:user-note": "Scrivere annotazioni di moderazione" _auth: shareAccessTitle: "Permessi dell'applicazione" shareAccess: "Vuoi autorizzare {name} ad accedere al tuo profilo?" diff --git a/locales/ko-GS.yml b/locales/ko-GS.yml index 29bfe5394d..b1702114be 100644 --- a/locales/ko-GS.yml +++ b/locales/ko-GS.yml @@ -40,7 +40,7 @@ favorites: "질겨찾기" unfavorite: "질겨찾기서 á„‹á…¥á‡ì• 기" favorited: "ì§ˆê²¨ì°¾ê¸°ì— ë‹´ì•—ì‹ë‹ˆë‹¤." alreadyFavorited: "벌시로 ì§ˆê²¨ì°¾ê¸°ì— ë‹´ê¸° 잇ì‹ë‹ˆë‹¤." -cantFavorite: "ì§ˆê²¨ì°¾ê¸°ì— ëª¬ 담았ì‹ë‹ˆë‹¤." +cantFavorite: "ì§ˆê²¨ì°¾ê¸°ì— ëª¬ ë‹´ì•—ì‹ë‹ˆë‹¤." pin: "í”„ë¡œí•„ì— ë¶™ì´ê¸°" unpin: "프로필서 ë 기" copyContent: "ë‚´ìš© 복사하기" @@ -124,6 +124,7 @@ reactions: "반엉" reactionSettingDescription2: "꺼시서 ë‘ê³ , 누질ë¼ì„œ ë‰ìºê³ , ‘+’럴 누질ë¼ì„œ 옇ì‹ë‹ˆë‹¤." rememberNoteVisibility: "공개 범위럴 기억하기" attachCancel: "붙임 빼기" +deleteFile: "íŒŒì¼ ë‰ìºê¸°" markAsSensitive: "수ᇚ힘 ì„¤ì •" unmarkAsSensitive: "수ᇚ힘 무루기" enterFileName: "íŒŒì¼ ì´ëŸ¼ 서기" @@ -463,6 +464,8 @@ onlyOneFileCanBeAttached: "메시지엔 íŒŒì¼ í•˜ë‚˜ê¹Œì œë°–ì— ëª¬ ë„£ì‹ë‹ˆ invitations: "초대하기" invitationCode: "초대장" checking: "í•™ì¸í•˜ê³ 잇ì‹ë‹ˆë‹¤" +tooShort: "억수로 짜립니다" +tooLong: "억수로 집니다" passwordMatched: "맞ì‹ë‹ˆë‹¤" passwordNotMatched: "안 맞ì‹ë‹ˆë‹¤" signinFailed: "ë¡œê·¸ì¸ ëª¬ í–ˆì‹ë‹ˆë‹¤. ê³ ì´ë¦„ì´ëž‘ 비밀번호 ì œëŒ€ë¡œ ì¼ëŠ”ê°€ 확ì¸í•´ 주ì´ì†Œ." @@ -571,7 +574,11 @@ userSilenced: "ìš” ê²Œì •ì€... 수ᇚ혀 있ì‹ë‹ˆë‹¤." relays: "ë¦´ë ˆì´" addRelay: "ë¦´ë ˆì´ ì˜‡ê¸°" addedRelays: "ì˜‡ì€ ë¦´ë ˆì´" +deletedNote: "ë‰ìº” 걸" enableInfiniteScroll: "알아서 ë” ë³´ê¸°" +useCw: "ë‚´ìš© 수ᇚ후기" +description: "설멩" +describeFile: "캡션 옇기" author: "ë§¨ë˜ ì‚¬ëžŒ" manage: "간리" emailServer: "ì „ìžìš°íŽœ 서버" @@ -600,6 +607,7 @@ renotesCount: "리노트한 수" renotedCount: "ë¦¬ë…¸íŠ¸ë´ ìˆ˜" followingCount: "팔로우 수" followersCount: "팔로워 수" +noteFavoritesCount: "질겨찾기한 노트 수" clips: "í´ë¦½ 맨걸기" clearCache: "ìºì‹œ 비우기" unlikeConfirm: "좋네예럴 무룹니꺼?" @@ -608,6 +616,7 @@ user: "사용ìž" administration: "간리" on: "í‚´" off: "껌" +hide: "수ᇚ후기" clickToFinishEmailVerification: "[{ok}]럴 누질ë¼ì„œ ì „ìžìš°íŽœ ì •ë©©ì–¼ 껕내ì´ì†Œ." searchByGoogle: "찾기" tenMinutes: "ì‹ ë¶„" @@ -626,9 +635,11 @@ role: "ì˜‰í• " noRole: "ì˜‰í• ì´ ì—†ì‹ë‹ˆë‹¤" thisPostMayBeAnnoyingCancel: "ì•„ì´ì˜ˆ" likeOnly: "좋네예마" +myClips: "ë‚´ í´ë¦½" icon: "아바타" replies: "답하기" renotes: "리노트" +attach: "옇기" _initialAccountSetting: startTutorial: "길ë¼ìž¡ì´ 하기" _initialTutorial: @@ -641,9 +652,52 @@ _initialTutorial: title: "길ë¼ìž¡ì´ê°€ 껕낫ì‹ë‹ˆë‹¤!🎉" _achievements: _types: + _notes1: + description: "첫 노트럴 섯어예" + _notes10: + description: "노트럴 10번 섰어예" + _notes100: + description: "노트럴 100번 섰어예" + _notes500: + description: "노트럴 500번 섰어예" + _notes1000: + description: "노트럴 1,000번 섰어예" + _notes5000: + description: "노트럴 5,000번 섰어예" + _notes10000: + description: "노트럴 10,000번 섰어예" + _notes20000: + description: "노트럴 20,000번 섰어예" + _notes30000: + description: "노트럴 30,000번 섰어예" + _notes40000: + description: "노트럴 40,000번 섰어예" + _notes50000: + description: "노트럴 50,000번 섰어예" + _notes60000: + description: "노트럴 60,000번 섰어예" + _notes70000: + description: "노트럴 70,000번 섰어예" + _notes80000: + description: "노트럴 80,000번 섰어예" + _notes90000: + description: "노트럴 90,000번 섰어예" + _notes100000: + description: "노트럴 100,000번 섰어예" + _noteClipped1: + description: "첫 노트럴 í´ë¦½í–‡ì–´ì˜ˆ" + _noteFavorited1: + description: "첫 노트럴 ì§ˆê²¨ì°¾ê¸°ì— ë‹´ì•—ì–´ì˜ˆ" + _myNoteFavorited1: + description: "다런 ì‚¬ëžŒì´ ë‚´ 노트럴 ì§ˆê²¨ì°¾ê¸°ì— ë‹´ì•—ì‹ë‹ˆë‹¤" + _iLoveMisskey: + description: "“I ⤠#Misskeyâ€ëŸ´ 섰어예" + _postedAt0min0sec: + description: "0분 0ì´ˆì— ë…¸íŠ¸ë¥¼ 섰어예" _tutorialCompleted: description: "길ë¼ìž¡ì´ëŸ´ 껕냇ì‹ë‹ˆë‹¤" _gallery: + my: "ë‚´ 걸" liked: "좋네예한 걸" like: "좋네예!" unlike: "좋네예 무루기" @@ -654,7 +708,12 @@ _serverDisconnectedBehavior: reload: "알아서 새로곤침" _channel: removeBanner: "배너 ë‰ìºê¸°" + usersCount: "{n}명 참여" + notesCount: "노트 {n}ê°œ" +_menuDisplay: + hide: "수ᇚ후기" _theme: + description: "설멩" keys: mention: "멘션" _sfx: @@ -663,6 +722,9 @@ _sfx: _2fa: step3Title: "í•™ì¸ ê¸°í˜¸ëŸ´ 서기" renewTOTPCancel: "뎃어예" +_permissions: + "read:favorites": "질겨찾기 보기" + "write:favorites": "질겨찾기 곤치기" _widgets: profile: "프로필" instanceInfo: "서버 ì •ë³´" @@ -674,7 +736,10 @@ _widgets: _userList: chooseList: "리스트 개리기" _cw: + hide: "수ᇚ후기" show: "ë” ë³¼ëž˜ì˜ˆ" + chars: "ê±¸ìž {count}ê°œ" + files: "íŒŒì¼ {count}ê°œ" _visibility: home: "ëœë¨¸ë¦¬" followers: "팔로워" @@ -682,6 +747,7 @@ _profile: name: "ì´ëŸ¼" username: "ì‚¬ìš©ìž ì´ëŸ¼" _exportOrImport: + favoritedNotes: "질겨찾기한 노트" clips: "í´ë¦½ 맨걸기" followingList: "팔로잉" muteList: "수ᇚ후기" @@ -692,16 +758,20 @@ _charts: _timelines: home: "ëœë¨¸ë¦¬" _play: + my: "ë‚´ í”Œë ˆì´" script: "스í¬ë¦½íŠ¸" + summary: "설멩" _pages: like: "좋네예" unlike: "좋네예 무루기" + my: "ë‚´ 페ì´ì§€" blocks: image: "ì´ë¯¸ì§€" _note: id: "노트 ì•„ì´ë””" _notification: youWereFollowed: "새 팔로워가 잇ì‹ë‹ˆë‹¤" + newNote: "새 걸" _types: follow: "팔로잉" mention: "멘션" diff --git a/locales/ko-KR.yml b/locales/ko-KR.yml index 718d04caae..2a59ab9a23 100644 --- a/locales/ko-KR.yml +++ b/locales/ko-KR.yml @@ -279,7 +279,7 @@ uploadFromUrl: "URL 업로드" uploadFromUrlDescription: "ì—…ë¡œë“œí•˜ë ¤ëŠ” 파ì¼ì˜ URL" uploadFromUrlRequested: "업로드를 ìš”ì²í–ˆìŠµë‹ˆë‹¤" uploadFromUrlMayTakeTime: "업로드가 완료ë 때까지 ì‹œê°„ì´ ì†Œìš”ë 수 있습니다." -explore: "발견하기" +explore: "둘러보기" messageRead: "ì½ìŒ" noMoreHistory: "ì´ê²ƒë³´ë‹¤ ê³¼ê±°ì˜ ê¸°ë¡ì´ 없습니다" startMessaging: "대화 시작하기" @@ -1022,7 +1022,7 @@ internalServerError: "내부 서버 오류" internalServerErrorDescription: "내부 서버ì—ì„œ 예기치 ì•Šì€ ì˜¤ë¥˜ê°€ ë°œìƒí–ˆìŠµë‹ˆë‹¤." copyErrorInfo: "오류 ì •ë³´ 복사" joinThisServer: "ì´ ì„œë²„ì— ê°€ìž…" -exploreOtherServers: "다른 서버 둘러보기" +exploreOtherServers: "다른 서버 찾기" letsLookAtTimeline: "타임ë¼ì¸ 구경하기" disableFederationConfirm: "ì •ë§ë¡œ ì—°í•©ì„ ë„ì‹œê² ìŠµë‹ˆê¹Œ?" disableFederationConfirmWarn: "ì—°í•©ì„ ë„ë”ë¼ë„ ê²Œì‹œë¬¼ì´ ë¹„ê³µê°œë¡œ ì „í™˜ë˜ëŠ” ê²ƒì€ ì•„ë‹™ë‹ˆë‹¤. ëŒ€ë¶€ë¶„ì˜ ê²½ìš° ì—°í•©ì„ ë¹„í™œì„±í™”í• í•„ìš”ê°€ 없습니다." @@ -1797,7 +1797,7 @@ _instanceMute: title: "ì§€ì •í•œ ì„œë²„ì˜ ë…¸íŠ¸ë¥¼ 숨ê¹ë‹ˆë‹¤." heading: "ë®¤íŠ¸í• ì„œë²„" _theme: - explore: "테마 찾아보기" + explore: "테마 둘러보기" install: "테마 설치" manage: "테마 관리" code: "테마 코드" @@ -2022,7 +2022,7 @@ _permissions: "write:report-abuse": "위반 ë‚´ìš© ì‹ ê³ í•˜ê¸°" _auth: shareAccessTitle: "어플리케ì´ì…˜ì˜ ì ‘ê·¼ 허가" - shareAccess: "\"{name}\" ì´ ê³„ì •ì— ì ‘ê·¼í•˜ëŠ” ê²ƒì„ í—ˆìš©í•˜ì‹œê² ìŠµë‹ˆê¹Œ?" + shareAccess: "‘{name}’ì—ì„œ ê³„ì •ì— ì ‘ê·¼í•˜ëŠ” ê²ƒì„ í—ˆìš©í•˜ì‹œê² ìŠµë‹ˆê¹Œ?" shareAccessAsk: "ì´ ì• í”Œë¦¬ì¼€ì´ì…˜ì´ ê³„ì •ì— ì ‘ê·¼í•˜ëŠ” ê²ƒì„ í—ˆìš©í•˜ì‹œê² ìŠµë‹ˆê¹Œ?" permission: "{name}ì—ì„œ ë‹¤ìŒ ê¶Œí•œì„ ìš”ì²í•˜ì˜€ìŠµë‹ˆë‹¤" permissionAsk: "ì´ ì•±ì€ ë‹¤ìŒì˜ ê¶Œí•œì„ ìš”ì²í•©ë‹ˆë‹¤" -- GitLab From ddfc3b8a6a398f005ccb186654572b37f5e232a5 Mon Sep 17 00:00:00 2001 From: taichan <40626578+tai-cha@users.noreply.github.com> Date: Mon, 5 Feb 2024 15:01:31 +0900 Subject: [PATCH 06/40] =?UTF-8?q?Fix(frontend):=20=E3=82=AF=E3=83=AD?= =?UTF-8?q?=E3=83=83=E3=83=97=E5=BE=8C=E3=81=AE=E8=A7=A3=E5=83=8F=E5=BA=A6?= =?UTF-8?q?=E3=81=8C=E7=95=B0=E6=A7=98=E3=81=AB=E4=BD=8E=E3=81=8F=E3=81=AA?= =?UTF-8?q?=E3=82=8B=E5=95=8F=E9=A1=8C=E3=81=AE=E4=BF=AE=E6=AD=A3&?= =?UTF-8?q?=E3=82=AF=E3=83=AD=E3=83=83=E3=83=97=E3=81=AB=E5=A4=B1=E6=95=97?= =?UTF-8?q?=E3=81=99=E3=82=8B=E5=95=8F=E9=A1=8C&=E3=82=B3=E3=83=A1?= =?UTF-8?q?=E3=83=B3=E3=83=88=E3=81=ABnull=E3=81=A8=E3=81=84=E3=81=86?= =?UTF-8?q?=E6=96=87=E5=AD=97=E5=88=97=E3=81=8C=E5=85=A5=E3=82=8B=E5=95=8F?= =?UTF-8?q?=E9=A1=8C=E3=81=AE=E4=BF=AE=E6=AD=A3=20(#13162)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix(frontend): Fix resolution of cropped image (misskey-dev#11489) * CHANGELOG * Fix(frontend): クãƒãƒƒãƒ—ã®éš›ã€folderIdãŒnullã ã¨æ–‡å—列ã®nullãŒé€ã‚‰ã‚Œæ¤œç´¢ã§ããªã„å•é¡Œ * Fix: ã‚ャプションãŒå˜åœ¨ã—ãªã„ã¨ãã«ã‚¯ãƒãƒƒãƒ—ã™ã‚‹ã¨'null'ãŒã‚ャプションã«å…¥ã£ã¦ã—ã¾ã†å•é¡Œ (misskey-dev#11813) * Update CHANGELOG --- CHANGELOG.md | 3 +++ .../frontend/src/components/MkCropperDialog.vue | 17 ++++++++++++----- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f6cf2071b..c089aae279 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -62,6 +62,9 @@ - Enhance: ページé·ç§»æ™‚ã«Playerã‚’é–‰ã˜ã‚‹ã‚ˆã†ã« - Fix: iOSã§å¤§ããªç”»åƒã‚’変æ›ã—ã¦ã‚¢ãƒƒãƒ—ãƒãƒ¼ãƒ‰ã§ããªã„å•é¡Œã‚’ä¿®æ£ - Fix: 「アニメーション画åƒã‚’å†ç”Ÿã—ãªã„ã€ã‚‚ã—ãã¯ã€Œãƒ‡ãƒ¼ã‚¿ã‚»ãƒ¼ãƒãƒ¼ï¼ˆã‚¢ã‚¤ã‚³ãƒ³ï¼‰ã€ã‚’有効ã«ã—ã¦ã„ã¦ã‚‚ã€ã‚¢ã‚¤ã‚³ãƒ³ãƒ‡ã‚³ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ã®ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ãŒåœæ¢ã•ã‚Œãªã„å•é¡Œã‚’ä¿®æ£ +- Fix: ç”»åƒã‚’クãƒãƒƒãƒ—ã™ã‚‹ã¨ã‚¯ãƒãƒƒãƒ—後ã®è§£åƒåº¦ãŒç•°æ§˜ã«ä½Žããªã‚‹å•é¡Œã®ä¿®æ£ +- Fix: ç”»åƒã‚’クãƒãƒƒãƒ—時ã€æ£å¸¸ã«å®Œäº†ã§ããªã„å•é¡Œã®ä¿®æ£ +- Fix: ã‚ャプションãŒç©ºã®ç”»åƒã‚’クãƒãƒƒãƒ—ã™ã‚‹ã¨ã‚ャプションã«nullã¨ã„ã†æ–‡å—列ãŒå…¥ã£ã¦ã—ã¾ã†å•é¡Œã®ä¿®æ£ ### Server - Enhance: 連åˆå…ˆã®ãƒ¬ãƒ¼ãƒˆãƒªãƒŸãƒƒãƒˆã«å¼•ã£ã‹ã‹ã£ãŸéš›ã«ãƒªãƒˆãƒ©ã‚¤ã™ã‚‹ã‚ˆã†ã«ãªã‚Šã¾ã—㟠diff --git a/packages/frontend/src/components/MkCropperDialog.vue b/packages/frontend/src/components/MkCropperDialog.vue index 0a1ddd3171..745453646c 100644 --- a/packages/frontend/src/components/MkCropperDialog.vue +++ b/packages/frontend/src/components/MkCropperDialog.vue @@ -63,18 +63,25 @@ const loading = ref(true); const ok = async () => { const promise = new Promise<Misskey.entities.DriveFile>(async (res) => { - const croppedCanvas = await cropper?.getCropperSelection()?.$toCanvas(); + const croppedImage = await cropper?.getCropperImage(); + const croppedSection = await cropper?.getCropperSelection(); + + // 拡大率を計算ã—ã€(ã»ã¼)å…ƒã®å¤§ãã•ã«æˆ»ã™ + const zoomedRate = croppedImage.getBoundingClientRect().width / croppedImage.clientWidth; + const widthToRender = croppedSection.getBoundingClientRect().width / zoomedRate; + + const croppedCanvas = await croppedSection?.$toCanvas({ width: widthToRender }); croppedCanvas?.toBlob(blob => { if (!blob) return; const formData = new FormData(); formData.append('file', blob); formData.append('name', `cropped_${props.file.name}`); formData.append('isSensitive', props.file.isSensitive ? 'true' : 'false'); - formData.append('comment', props.file.comment ?? 'null'); + if (props.file.comment) { formData.append('comment', props.file.comment);} formData.append('i', $i!.token); - if (props.uploadFolder || props.uploadFolder === null) { - formData.append('folderId', props.uploadFolder ?? 'null'); - } else if (defaultStore.state.uploadFolder) { + if (props.uploadFolder) { + formData.append('folderId', props.uploadFolder); + } else if (props.uploadFolder !== null && defaultStore.state.uploadFolder) { formData.append('folderId', defaultStore.state.uploadFolder); } -- GitLab From 0df069494e70eafa7217b79d133bb248865baa85 Mon Sep 17 00:00:00 2001 From: zyoshoka <107108195+zyoshoka@users.noreply.github.com> Date: Mon, 5 Feb 2024 15:02:30 +0900 Subject: [PATCH 07/40] =?UTF-8?q?refactor(frontend):=20`os.popup()`?= =?UTF-8?q?=E3=81=AE`events`=E3=81=AE=E5=9E=8B=E3=83=81=E3=82=A7=E3=83=83?= =?UTF-8?q?=E3=82=AF=E3=82=92=E6=9C=89=E5=8A=B9=E5=8C=96=20(#13165)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/os.ts | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/packages/frontend/src/os.ts b/packages/frontend/src/os.ts index 7cce77cdf7..010fdbb6d8 100644 --- a/packages/frontend/src/os.ts +++ b/packages/frontend/src/os.ts @@ -128,9 +128,10 @@ export function promiseDialog<T extends Promise<any>>( let popupIdCount = 0; export const popups = ref([]) as Ref<{ - id: any; - component: any; + id: number; + component: Component; props: Record<string, any>; + events: Record<string, any>; }[]>; const zIndexes = { @@ -144,7 +145,18 @@ export function claimZIndex(priority: keyof typeof zIndexes = 'low'): number { return zIndexes[priority]; } -export async function popup<T extends Component>(component: T, props: ComponentProps<T>, events = {}, disposeEvent?: string) { +// InstanceType<typeof Component>['$emit'] ã ã¨ã‚¤ãƒ³ã‚¿ãƒ¼ã‚»ã‚¯ã‚·ãƒ§ãƒ³åž‹ãŒè¿”ã£ã¦ã㦠+// 使ã„物ã«ãªã‚‰ãªã„ã®ã§ã€ä»£ã‚ã‚Šã« ['$props'] ã‹ã‚‰è‰²ã€…çœãã“ã¨ã§ emit ã®åž‹ã‚’生æˆã™ã‚‹ +// FIXME: 何故㋠*.ts ファイルã‹ã‚‰ã ã¨åž‹ãŒã†ã¾ãå–ã‚Œãªã„?ã“ã¨ãŒã‚ã‚‹ã®ã‚’ãªã‚“ã¨ã‹ã—ãŸã„ +type ComponentEmit<T> = T extends new () => { $props: infer Props } + ? EmitsExtractor<Props> + : never; + +type EmitsExtractor<T> = { + [K in keyof T as K extends `onVnode${string}` ? never : K extends `on${infer E}` ? Uncapitalize<E> : K extends string ? never : K]: T[K]; +}; + +export async function popup<T extends Component>(component: T, props: ComponentProps<T>, events: ComponentEmit<T> = {} as ComponentEmit<T>, disposeEvent?: keyof ComponentEmit<T>) { markRaw(component); const id = ++popupIdCount; -- GitLab From 2f54a530623122f4fa962f7fd8b7de396f30c704 Mon Sep 17 00:00:00 2001 From: syuilo <Syuilotan@yahoo.co.jp> Date: Mon, 5 Feb 2024 21:08:05 +0900 Subject: [PATCH 08/40] 2024.2.0-beta.10 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index aff28ca7e2..bd4529f159 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "misskey", - "version": "2024.2.0-beta.9", + "version": "2024.2.0-beta.10", "codename": "nasubi", "repository": { "type": "git", -- GitLab From 16eccad49271b81282cdbd482d29e7a8bb048f4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=8B=E3=81=A3=E3=81=93=E3=81=8B=E3=82=8A?= <67428053+kakkokari-gtyih@users.noreply.github.com> Date: Tue, 6 Feb 2024 15:03:07 +0900 Subject: [PATCH 09/40] =?UTF-8?q?enhance(frontend):=20=E3=82=B7=E3=83=B3?= =?UTF-8?q?=E3=82=BF=E3=83=83=E3=82=AF=E3=82=B9=E3=83=8F=E3=82=A4=E3=83=A9?= =?UTF-8?q?=E3=82=A4=E3=83=88=E3=81=AB=E3=83=86=E3=83=BC=E3=83=9E=E3=82=92?= =?UTF-8?q?=E9=81=A9=E7=94=A8=E3=81=A7=E3=81=8D=E3=82=8B=E3=82=88=E3=81=86?= =?UTF-8?q?=E3=81=AB=20(#13175)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * enhance(frontend): シンタックスãƒã‚¤ãƒ©ã‚¤ãƒˆã«ãƒ†ãƒ¼ãƒžã‚’é©ç”¨ã§ãるよã†ã« * Update Changelog * ã“ã£ã¡ã‚‚ * テーマã®å€¤ãŒãƒ‡ã‚£ãƒ¼ãƒ—マージã•ã‚Œã‚‹ã‚ˆã†ã« * 常ã«ãƒ†ãƒ¼ãƒžè¨å®šã«æº–ã˜ã‚‹ã‚ˆã†ã« * テーマ更新時ã«æ–°ã—ã„shikiテーマをèªã¿è¾¼ã‚€ã‚ˆã†ã« --- CHANGELOG.md | 1 + .../frontend/src/components/MkCode.core.vue | 56 +++++++++++++-- packages/frontend/src/components/MkCode.vue | 8 +-- .../frontend/src/components/MkCodeEditor.vue | 5 +- .../frontend/src/components/MkCodeInline.vue | 3 +- packages/frontend/src/components/MkSelect.vue | 7 +- .../frontend/src/pages/settings/theme.vue | 15 +++- packages/frontend/src/pizzax.ts | 23 +------ packages/frontend/src/router/main.ts | 4 ++ packages/frontend/src/scripts/clone.ts | 4 +- .../frontend/src/scripts/code-highlighter.ts | 68 ++++++++++++++++++- packages/frontend/src/scripts/merge.ts | 31 +++++++++ packages/frontend/src/scripts/theme.ts | 10 ++- packages/frontend/src/store.ts | 1 + packages/frontend/src/themes/_dark.json5 | 4 ++ packages/frontend/src/themes/_light.json5 | 4 ++ 16 files changed, 202 insertions(+), 42 deletions(-) create mode 100644 packages/frontend/src/scripts/merge.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index c089aae279..c39a447c59 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -49,6 +49,7 @@ - Enhance: MFMã®å±žæ€§ã§ã‚ªãƒ¼ãƒˆã‚³ãƒ³ãƒ—リートãŒä½¿ç”¨ã§ãるよã†ã« #12735 - Enhance: 絵文å—編集ダイアãƒã‚°ã‚’モーダルã§ã¯ãªãウィンドウã§è¡¨ç¤ºã™ã‚‹ã‚ˆã†ã« - Enhance: リモートã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã¯ãƒ¡ãƒ‹ãƒ¥ãƒ¼ã‹ã‚‰ç›´æŽ¥ãƒªãƒ¢ãƒ¼ãƒˆã§è¡¨ç¤ºã§ãるよã†ã« +- Enhance: コードã®ã‚·ãƒ³ã‚¿ãƒƒã‚¯ã‚¹ãƒã‚¤ãƒ©ã‚¤ãƒˆã«ãƒ†ãƒ¼ãƒžã‚’é©ç”¨ã§ãるよã†ã« - Fix: ãƒã‚¤ãƒ†ã‚£ãƒ–モードã®çµµæ–‡å—ãŒãƒ¢ãƒŽã‚¯ãƒã«ãªã‚‰ãªã„よã†ã« - Fix: v2023.12.0ã§è¿½åŠ ã•ã‚ŒãŸã€Œãƒ¢ãƒ‡ãƒ¬ãƒ¼ã‚¿ãƒ¼ãŒãƒ¦ãƒ¼ã‚¶ãƒ¼ã®ã‚¢ã‚¤ã‚³ãƒ³ã‚‚ã—ãã¯ãƒãƒŠãƒ¼ç”»åƒã‚’未è¨å®šçŠ¶æ…‹ã«ã§ãる機能ã€ãŒç®¡ç†ç”»é¢ä¸Šã§æ£ã—ã表示ã•ã‚Œã¦ã„ãªã„å•é¡Œã‚’ä¿®æ£ - Fix: AiScriptã®`readline`関数ãŒä¸æ£ãªå€¤ã‚’è¿”ã™ã“ã¨ãŒã‚ã‚‹å•é¡Œã®v2023.12.0時点ã§ã®ä¿®æ£ãŒPlay以外ã«é©ç”¨ã•ã‚Œã¦ã„ãªã„ã®ã‚’ä¿®æ£ diff --git a/packages/frontend/src/components/MkCode.core.vue b/packages/frontend/src/components/MkCode.core.vue index c655ff416e..68c50c4c69 100644 --- a/packages/frontend/src/components/MkCode.core.vue +++ b/packages/frontend/src/components/MkCode.core.vue @@ -5,14 +5,15 @@ SPDX-License-Identifier: AGPL-3.0-only <!-- eslint-disable vue/no-v-html --> <template> -<div :class="[$style.codeBlockRoot, { [$style.codeEditor]: codeEditor }]" v-html="html"></div> +<div :class="[$style.codeBlockRoot, { [$style.codeEditor]: codeEditor }, (darkMode ? $style.dark : $style.light)]" v-html="html"></div> </template> <script lang="ts" setup> import { ref, computed, watch } from 'vue'; import { bundledLanguagesInfo } from 'shiki'; import type { BuiltinLanguage } from 'shiki'; -import { getHighlighter } from '@/scripts/code-highlighter.js'; +import { getHighlighter, getTheme } from '@/scripts/code-highlighter.js'; +import { defaultStore } from '@/store.js'; const props = defineProps<{ code: string; @@ -21,11 +22,23 @@ const props = defineProps<{ }>(); const highlighter = await getHighlighter(); - +const darkMode = defaultStore.reactiveState.darkMode; const codeLang = ref<BuiltinLanguage | 'aiscript'>('js'); + +const [lightThemeName, darkThemeName] = await Promise.all([ + getTheme('light', true), + getTheme('dark', true), +]); + const html = computed(() => highlighter.codeToHtml(props.code, { lang: codeLang.value, - theme: 'dark-plus', + themes: { + fallback: 'dark-plus', + light: lightThemeName, + dark: darkThemeName, + }, + defaultColor: false, + cssVariablePrefix: '--shiki-', })); async function fetchLanguage(to: string): Promise<void> { @@ -64,6 +77,15 @@ watch(() => props.lang, (to) => { margin: .5em 0; overflow: auto; border-radius: 8px; + border: 1px solid var(--divider); + + color: var(--shiki-fallback); + background-color: var(--shiki-fallback-bg); + + & span { + color: var(--shiki-fallback); + background-color: var(--shiki-fallback-bg); + } & pre, & code { @@ -71,6 +93,26 @@ watch(() => props.lang, (to) => { } } +.light.codeBlockRoot :global(.shiki) { + color: var(--shiki-light); + background-color: var(--shiki-light-bg); + + & span { + color: var(--shiki-light); + background-color: var(--shiki-light-bg); + } +} + +.dark.codeBlockRoot :global(.shiki) { + color: var(--shiki-dark); + background-color: var(--shiki-dark-bg); + + & span { + color: var(--shiki-dark); + background-color: var(--shiki-dark-bg); + } +} + .codeBlockRoot.codeEditor { min-width: 100%; height: 100%; @@ -79,6 +121,7 @@ watch(() => props.lang, (to) => { padding: 12px; margin: 0; border-radius: 6px; + border: none; min-height: 130px; pointer-events: none; min-width: calc(100% - 24px); @@ -90,6 +133,11 @@ watch(() => props.lang, (to) => { text-rendering: inherit; text-transform: inherit; white-space: pre; + + & span { + display: inline-block; + min-height: 1em; + } } } </style> diff --git a/packages/frontend/src/components/MkCode.vue b/packages/frontend/src/components/MkCode.vue index 251e6ade00..6c14738937 100644 --- a/packages/frontend/src/components/MkCode.vue +++ b/packages/frontend/src/components/MkCode.vue @@ -53,7 +53,6 @@ function copy() { } .codeBlockCopyButton { - color: #D4D4D4; position: absolute; top: 8px; right: 8px; @@ -67,8 +66,7 @@ function copy() { .codeBlockFallbackRoot { display: block; overflow-wrap: anywhere; - color: #D4D4D4; - background: #1E1E1E; + background: var(--bg); padding: 1em; margin: .5em 0; overflow: auto; @@ -93,8 +91,8 @@ function copy() { border-radius: 8px; padding: 24px; margin-top: 4px; - color: #D4D4D4; - background: #1E1E1E; + color: var(--fg); + background: var(--bg); } .codePlaceholderContainer { diff --git a/packages/frontend/src/components/MkCodeEditor.vue b/packages/frontend/src/components/MkCodeEditor.vue index c8c3deb610..3cf8234e72 100644 --- a/packages/frontend/src/components/MkCodeEditor.vue +++ b/packages/frontend/src/components/MkCodeEditor.vue @@ -196,10 +196,11 @@ watch(v, newValue => { resize: none; text-align: left; color: transparent; - caret-color: rgb(225, 228, 232); + caret-color: var(--fg); background-color: transparent; border: 0; border-radius: 6px; + box-sizing: border-box; outline: 0; min-width: calc(100% - 24px); height: 100%; @@ -210,6 +211,6 @@ watch(v, newValue => { } .textarea::selection { - color: #fff; + color: var(--bg); } </style> diff --git a/packages/frontend/src/components/MkCodeInline.vue b/packages/frontend/src/components/MkCodeInline.vue index 5340c1fd5f..6a9d97ab5a 100644 --- a/packages/frontend/src/components/MkCodeInline.vue +++ b/packages/frontend/src/components/MkCodeInline.vue @@ -18,8 +18,7 @@ const props = defineProps<{ display: inline-block; font-family: Consolas, Monaco, Andale Mono, Ubuntu Mono, monospace; overflow-wrap: anywhere; - color: #D4D4D4; - background: #1E1E1E; + background: var(--bg); padding: .1em; border-radius: .3em; } diff --git a/packages/frontend/src/components/MkSelect.vue b/packages/frontend/src/components/MkSelect.vue index 8dd2b9129d..3e8ff99387 100644 --- a/packages/frontend/src/components/MkSelect.vue +++ b/packages/frontend/src/components/MkSelect.vue @@ -27,7 +27,7 @@ SPDX-License-Identifier: AGPL-3.0-only </div> <div :class="$style.caption"><slot name="caption"></slot></div> - <MkButton v-if="manualSave && changed" primary @click="updated"><i class="ti ti-device-floppy"></i> {{ i18n.ts.save }}</MkButton> + <MkButton v-if="manualSave && changed" primary :class="$style.save" @click="updated"><i class="ti ti-device-floppy"></i> {{ i18n.ts.save }}</MkButton> </div> </template> @@ -138,6 +138,7 @@ function show() { active: computed(() => v.value === option.props?.value), action: () => { v.value = option.props?.value; + changed.value = true; emit('changeByUser', v.value); }, }); @@ -288,6 +289,10 @@ function show() { padding-left: 6px; } +.save { + margin: 8px 0 0 0; +} + .chevron { transition: transform 0.1s ease-out; } diff --git a/packages/frontend/src/pages/settings/theme.vue b/packages/frontend/src/pages/settings/theme.vue index dedac10270..1d6fec5290 100644 --- a/packages/frontend/src/pages/settings/theme.vue +++ b/packages/frontend/src/pages/settings/theme.vue @@ -88,6 +88,18 @@ import { uniqueBy } from '@/scripts/array.js'; import { fetchThemes, getThemes } from '@/theme-store.js'; import { definePageMetadata } from '@/scripts/page-metadata.js'; import { miLocalStorage } from '@/local-storage.js'; +import { unisonReload } from '@/scripts/unison-reload.js'; +import * as os from '@/os.js'; + +async function reloadAsk() { + const { canceled } = await os.confirm({ + type: 'info', + text: i18n.ts.reloadToApplySetting, + }); + if (canceled) return; + + unisonReload(); +} const installedThemes = ref(getThemes()); const builtinThemes = getBuiltinThemesRef(); @@ -124,6 +136,7 @@ const lightThemeId = computed({ } }, }); + const darkMode = computed(defaultStore.makeGetterSetter('darkMode')); const syncDeviceDarkMode = computed(ColdDeviceStorage.makeGetterSetter('syncDeviceDarkMode')); const wallpaper = ref(miLocalStorage.getItem('wallpaper')); @@ -141,7 +154,7 @@ watch(wallpaper, () => { } else { miLocalStorage.setItem('wallpaper', wallpaper.value); } - location.reload(); + reloadAsk(); }); onActivated(() => { diff --git a/packages/frontend/src/pizzax.ts b/packages/frontend/src/pizzax.ts index 68c36ca1b4..043b6efd73 100644 --- a/packages/frontend/src/pizzax.ts +++ b/packages/frontend/src/pizzax.ts @@ -13,6 +13,7 @@ import { get, set } from '@/scripts/idb-proxy.js'; import { defaultStore } from '@/store.js'; import { useStream } from '@/stream.js'; import { deepClone } from '@/scripts/clone.js'; +import { deepMerge } from '@/scripts/merge.js'; type StateDef = Record<string, { where: 'account' | 'device' | 'deviceAccount'; @@ -84,29 +85,9 @@ export class Storage<T extends StateDef> { return typeof value === 'object' && value !== null && !Array.isArray(value); } - /** - * valueã«ãªã„ã‚ーをdefã‹ã‚‰ã‚‚らã†ï¼ˆå†å¸°çš„)\ - * nullã¯ãã®ã¾ã¾ã€undefinedã¯defã®å€¤ - **/ - private mergeObject<X>(value: X, def: X): X { - if (this.isPureObject(value) && this.isPureObject(def)) { - const result = structuredClone(value) as X; - for (const [k, v] of Object.entries(def) as [keyof X, X[keyof X]][]) { - if (!Object.prototype.hasOwnProperty.call(value, k) || value[k] === undefined) { - result[k] = v; - } else if (this.isPureObject(v) && this.isPureObject(result[k])) { - const child = structuredClone(result[k]) as X[keyof X] & Record<string | number | symbol, unknown>; - result[k] = this.mergeObject<typeof v>(child, v); - } - } - return result; - } - return value; - } - private mergeState<X>(value: X, def: X): X { if (this.isPureObject(value) && this.isPureObject(def)) { - const merged = this.mergeObject(value, def); + const merged = deepMerge(value, def); if (_DEV_) console.log('Merging state. Incoming: ', value, ' Default: ', def, ' Result: ', merged); diff --git a/packages/frontend/src/router/main.ts b/packages/frontend/src/router/main.ts index 5adb3f606f..c6a520e913 100644 --- a/packages/frontend/src/router/main.ts +++ b/packages/frontend/src/router/main.ts @@ -80,6 +80,10 @@ class MainRouterProxy implements IRouter { return this.supplier().resolve(path); } + init(): void { + this.supplier().init(); + } + eventNames(): Array<EventEmitter.EventNames<RouterEvent>> { return this.supplier().eventNames(); } diff --git a/packages/frontend/src/scripts/clone.ts b/packages/frontend/src/scripts/clone.ts index ac38faefaa..6d3a1c8c79 100644 --- a/packages/frontend/src/scripts/clone.ts +++ b/packages/frontend/src/scripts/clone.ts @@ -8,13 +8,13 @@ // ã‚ã¨ã€Vue Refã‚’IndexedDBã«ä¿å˜ã—よã†ã¨ã—ã¦structredCloneを使ã£ãŸã‚‰ã‚¨ãƒ©ãƒ¼ã«ãªã£ãŸ // https://github.com/misskey-dev/misskey/pull/8098#issuecomment-1114144045 -type Cloneable = string | number | boolean | null | undefined | { [key: string]: Cloneable } | Cloneable[]; +export type Cloneable = string | number | boolean | null | undefined | { [key: string]: Cloneable } | { [key: number]: Cloneable } | { [key: symbol]: Cloneable } | Cloneable[]; export function deepClone<T extends Cloneable>(x: T): T { if (typeof x === 'object') { if (x === null) return x; if (Array.isArray(x)) return x.map(deepClone) as T; - const obj = {} as Record<string, Cloneable>; + const obj = {} as Record<string | number | symbol, Cloneable>; for (const [k, v] of Object.entries(x)) { obj[k] = v === undefined ? undefined : deepClone(v); } diff --git a/packages/frontend/src/scripts/code-highlighter.ts b/packages/frontend/src/scripts/code-highlighter.ts index bc05ec94d5..b11dfed41a 100644 --- a/packages/frontend/src/scripts/code-highlighter.ts +++ b/packages/frontend/src/scripts/code-highlighter.ts @@ -1,9 +1,51 @@ +import { bundledThemesInfo } from 'shiki'; import { getHighlighterCore, loadWasm } from 'shiki/core'; import darkPlus from 'shiki/themes/dark-plus.mjs'; -import type { Highlighter, LanguageRegistration } from 'shiki'; +import { unique } from './array.js'; +import { deepClone } from './clone.js'; +import { deepMerge } from './merge.js'; +import type { Highlighter, LanguageRegistration, ThemeRegistration, ThemeRegistrationRaw } from 'shiki'; +import { ColdDeviceStorage } from '@/store.js'; +import lightTheme from '@/themes/_light.json5'; +import darkTheme from '@/themes/_dark.json5'; let _highlighter: Highlighter | null = null; +export async function getTheme(mode: 'light' | 'dark', getName: true): Promise<string>; +export async function getTheme(mode: 'light' | 'dark', getName?: false): Promise<ThemeRegistration | ThemeRegistrationRaw>; +export async function getTheme(mode: 'light' | 'dark', getName = false): Promise<ThemeRegistration | ThemeRegistrationRaw | string | null> { + const theme = deepClone(ColdDeviceStorage.get(mode === 'light' ? 'lightTheme' : 'darkTheme')); + + if (theme.base) { + const base = [lightTheme, darkTheme].find(x => x.id === theme.base); + if (base && base.codeHighlighter) theme.codeHighlighter = Object.assign({}, base.codeHighlighter, theme.codeHighlighter); + } + + if (theme.codeHighlighter) { + let _res: ThemeRegistration = {}; + if (theme.codeHighlighter.base === '_none_') { + _res = deepClone(theme.codeHighlighter.overrides); + } else { + const base = await bundledThemesInfo.find(t => t.id === theme.codeHighlighter!.base)?.import() ?? darkPlus; + _res = deepMerge(theme.codeHighlighter.overrides ?? {}, 'default' in base ? base.default : base); + } + if (_res.name == null) { + _res.name = theme.id; + } + _res.type = mode; + + if (getName) { + return _res.name; + } + return _res; + } + + if (getName) { + return 'dark-plus'; + } + return darkPlus; +} + export async function getHighlighter(): Promise<Highlighter> { if (!_highlighter) { return await initHighlighter(); @@ -13,11 +55,17 @@ export async function getHighlighter(): Promise<Highlighter> { export async function initHighlighter() { const aiScriptGrammar = await import('aiscript-vscode/aiscript/syntaxes/aiscript.tmLanguage.json'); - + await loadWasm(import('shiki/onig.wasm?init')); + // テーマã®é‡è¤‡ã‚’消㙠+ const themes = unique([ + darkPlus, + ...(await Promise.all([getTheme('light'), getTheme('dark')])), + ]); + const highlighter = await getHighlighterCore({ - themes: [darkPlus], + themes, langs: [ import('shiki/langs/javascript.mjs'), { @@ -27,6 +75,20 @@ export async function initHighlighter() { ], }); + ColdDeviceStorage.watch('lightTheme', async () => { + const newTheme = await getTheme('light'); + if (newTheme.name && !highlighter.getLoadedThemes().includes(newTheme.name)) { + highlighter.loadTheme(newTheme); + } + }); + + ColdDeviceStorage.watch('darkTheme', async () => { + const newTheme = await getTheme('dark'); + if (newTheme.name && !highlighter.getLoadedThemes().includes(newTheme.name)) { + highlighter.loadTheme(newTheme); + } + }); + _highlighter = highlighter; return highlighter; diff --git a/packages/frontend/src/scripts/merge.ts b/packages/frontend/src/scripts/merge.ts new file mode 100644 index 0000000000..60097051fa --- /dev/null +++ b/packages/frontend/src/scripts/merge.ts @@ -0,0 +1,31 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { deepClone } from './clone.js'; +import type { Cloneable } from './clone.js'; + +function isPureObject(value: unknown): value is Record<string | number | symbol, unknown> { + return typeof value === 'object' && value !== null && !Array.isArray(value); +} + +/** + * valueã«ãªã„ã‚ーをdefã‹ã‚‰ã‚‚らã†ï¼ˆå†å¸°çš„)\ + * nullã¯ãã®ã¾ã¾ã€undefinedã¯defã®å€¤ + **/ +export function deepMerge<X extends Record<string | number | symbol, unknown>>(value: X, def: X): X { + if (isPureObject(value) && isPureObject(def)) { + const result = deepClone(value as Cloneable) as X; + for (const [k, v] of Object.entries(def) as [keyof X, X[keyof X]][]) { + if (!Object.prototype.hasOwnProperty.call(value, k) || value[k] === undefined) { + result[k] = v; + } else if (isPureObject(v) && isPureObject(result[k])) { + const child = deepClone(result[k] as Cloneable) as X[keyof X] & Record<string | number | symbol, unknown>; + result[k] = deepMerge<typeof v>(child, v); + } + } + return result; + } + return value; +} diff --git a/packages/frontend/src/scripts/theme.ts b/packages/frontend/src/scripts/theme.ts index 21ef85fe7a..d3bd9ba4bc 100644 --- a/packages/frontend/src/scripts/theme.ts +++ b/packages/frontend/src/scripts/theme.ts @@ -6,6 +6,7 @@ import { ref } from 'vue'; import tinycolor from 'tinycolor2'; import { deepClone } from './clone.js'; +import type { BuiltinTheme } from 'shiki'; import { globalEvents } from '@/events.js'; import lightTheme from '@/themes/_light.json5'; import darkTheme from '@/themes/_dark.json5'; @@ -18,6 +19,13 @@ export type Theme = { desc?: string; base?: 'dark' | 'light'; props: Record<string, string>; + codeHighlighter?: { + base: BuiltinTheme; + overrides?: Record<string, any>; + } | { + base: '_none_'; + overrides: Record<string, any>; + }; }; export const themeProps = Object.keys(lightTheme.props).filter(key => !key.startsWith('X')); @@ -53,7 +61,7 @@ export const getBuiltinThemesRef = () => { return builtinThemes; }; -let timeout = null; +let timeout: number | null = null; export function applyTheme(theme: Theme, persist = true) { if (timeout) window.clearTimeout(timeout); diff --git a/packages/frontend/src/store.ts b/packages/frontend/src/store.ts index afc35bb825..641a506679 100644 --- a/packages/frontend/src/store.ts +++ b/packages/frontend/src/store.ts @@ -7,6 +7,7 @@ import { markRaw, ref } from 'vue'; import * as Misskey from 'misskey-js'; import { miLocalStorage } from './local-storage.js'; import type { SoundType } from '@/scripts/sound.js'; +import type { BuiltinTheme as ShikiBuiltinTheme } from 'shiki'; import { Storage } from '@/pizzax.js'; import { hemisphere } from '@/scripts/intl-const.js'; diff --git a/packages/frontend/src/themes/_dark.json5 b/packages/frontend/src/themes/_dark.json5 index 3f5822977a..c82a956868 100644 --- a/packages/frontend/src/themes/_dark.json5 +++ b/packages/frontend/src/themes/_dark.json5 @@ -94,4 +94,8 @@ X16: ':alpha<0.7<@panel', X17: ':alpha<0.8<@bg', }, + + codeHighlighter: { + base: 'one-dark-pro', + }, } diff --git a/packages/frontend/src/themes/_light.json5 b/packages/frontend/src/themes/_light.json5 index 6ebfcaafeb..63bc030916 100644 --- a/packages/frontend/src/themes/_light.json5 +++ b/packages/frontend/src/themes/_light.json5 @@ -94,4 +94,8 @@ X16: ':alpha<0.7<@panel', X17: ':alpha<0.8<@bg', }, + + codeHighlighter: { + base: 'catppuccin-latte', + }, } -- GitLab From edb39a089d6652eb5b0212069f3050823c4c07e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=8B=E3=81=A3=E3=81=93=E3=81=8B=E3=82=8A?= <67428053+kakkokari-gtyih@users.noreply.github.com> Date: Tue, 6 Feb 2024 16:26:03 +0900 Subject: [PATCH 10/40] =?UTF-8?q?enhance(frontend):=20KeepAlive=E3=81=AE?= =?UTF-8?q?=E3=83=9A=E3=83=BC=E3=82=B8=E3=82=AD=E3=83=A3=E3=83=83=E3=82=B7?= =?UTF-8?q?=E3=83=A5=E3=82=92=E5=89=8A=E9=99=A4=E3=81=A7=E3=81=8D=E3=82=8B?= =?UTF-8?q?=E3=82=88=E3=81=86=E3=81=AB=20(#13180)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * enhance(frontend): 内部ã®ãƒšãƒ¼ã‚¸ã‚ャッシュを削除ã§ãるよã†ã« * Update Changelog --- CHANGELOG.md | 1 + .../src/components/global/RouterView.vue | 42 ++++++++++++++++--- packages/frontend/src/events.ts | 8 +++- .../frontend/src/pages/settings/profile.vue | 5 +++ 4 files changed, 49 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c39a447c59..0fc99cf5b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -66,6 +66,7 @@ - Fix: ç”»åƒã‚’クãƒãƒƒãƒ—ã™ã‚‹ã¨ã‚¯ãƒãƒƒãƒ—後ã®è§£åƒåº¦ãŒç•°æ§˜ã«ä½Žããªã‚‹å•é¡Œã®ä¿®æ£ - Fix: ç”»åƒã‚’クãƒãƒƒãƒ—時ã€æ£å¸¸ã«å®Œäº†ã§ããªã„å•é¡Œã®ä¿®æ£ - Fix: ã‚ャプションãŒç©ºã®ç”»åƒã‚’クãƒãƒƒãƒ—ã™ã‚‹ã¨ã‚ャプションã«nullã¨ã„ã†æ–‡å—列ãŒå…¥ã£ã¦ã—ã¾ã†å•é¡Œã®ä¿®æ£ +- Fix: プãƒãƒ•ã‚£ãƒ¼ãƒ«ã‚’編集ã—ã¦ã‚‚リãƒãƒ¼ãƒ‰ã™ã‚‹ã¾ã§åæ˜ ã•ã‚Œãªã„å•é¡Œã‚’ä¿®æ£ ### Server - Enhance: 連åˆå…ˆã®ãƒ¬ãƒ¼ãƒˆãƒªãƒŸãƒƒãƒˆã«å¼•ã£ã‹ã‹ã£ãŸéš›ã«ãƒªãƒˆãƒ©ã‚¤ã™ã‚‹ã‚ˆã†ã«ãªã‚Šã¾ã—㟠diff --git a/packages/frontend/src/components/global/RouterView.vue b/packages/frontend/src/components/global/RouterView.vue index dc7474835d..aeb87e659b 100644 --- a/packages/frontend/src/components/global/RouterView.vue +++ b/packages/frontend/src/components/global/RouterView.vue @@ -4,7 +4,10 @@ SPDX-License-Identifier: AGPL-3.0-only --> <template> -<KeepAlive :max="defaultStore.state.numberOfPageCache"> +<KeepAlive + :max="defaultStore.state.numberOfPageCache" + :exclude="pageCacheController" +> <Suspense :timeout="0"> <component :is="currentPageComponent" :key="key" v-bind="Object.fromEntries(currentPageProps)"/> @@ -16,9 +19,11 @@ SPDX-License-Identifier: AGPL-3.0-only </template> <script lang="ts" setup> -import { inject, onBeforeUnmount, provide, ref, shallowRef } from 'vue'; -import { IRouter, Resolved } from '@/nirax.js'; +import { inject, onBeforeUnmount, provide, ref, shallowRef, computed, nextTick } from 'vue'; +import { IRouter, Resolved, RouteDef } from '@/nirax.js'; import { defaultStore } from '@/store.js'; +import { globalEvents } from '@/events.js'; +import MkLoadingPage from '@/pages/_loading_.vue'; const props = defineProps<{ router?: IRouter; @@ -46,20 +51,47 @@ function resolveNested(current: Resolved, d = 0): Resolved | null { } const current = resolveNested(router.current)!; -const currentPageComponent = shallowRef(current.route.component); +const currentPageComponent = shallowRef('component' in current.route ? current.route.component : MkLoadingPage); const currentPageProps = ref(current.props); const key = ref(current.route.path + JSON.stringify(Object.fromEntries(current.props))); function onChange({ resolved, key: newKey }) { const current = resolveNested(resolved); - if (current == null) return; + if (current == null || 'redirect' in current.route) return; currentPageComponent.value = current.route.component; currentPageProps.value = current.props; key.value = current.route.path + JSON.stringify(Object.fromEntries(current.props)); + + nextTick(() => { + // ページé·ç§»å®Œäº†å¾Œã«å†ã³ã‚ャッシュを有効化 + if (clearCacheRequested.value) { + clearCacheRequested.value = false; + } + }); } router.addListener('change', onChange); +// #region ã‚ャッシュ制御 + +/** + * ã‚ャッシュクリアãŒæœ‰åŠ¹ã«ãªã£ãŸã‚‰ã€å…¨ã‚ャッシュをクリアã™ã‚‹ + * + * keepAliveå´ã«watcherãŒã‚ã‚‹ã®ã§ã™ã消ãˆã‚‹ã¨ã¯ãŠã‚‚ã†ã‘ã©ã€å¿µã®ãŸã‚ページé·ç§»å®Œäº†ã¾ã§ã¯ã‚ャッシュを無効化ã—ã¦ãŠã。 + * ã‚ャッシュ有効時å‘ã‘ã«excludeを使ã„ãŸã„å ´åˆã¯ã€pageCacheControllerã«ä¸¦åˆ—ã«çªã£è¾¼ã‚€ã®ã§ã¯ãªãã€ä¸‹ã«è¿½è¨˜ã™ã‚‹ã“㨠+ */ +const pageCacheController = computed(() => clearCacheRequested.value ? /.*/ : undefined); +const clearCacheRequested = ref(false); + +globalEvents.on('requestClearPageCache', () => { + if (_DEV_) console.log('clear page cache requested'); + if (!clearCacheRequested.value) { + clearCacheRequested.value = true; + } +}); + +// #endregion + onBeforeUnmount(() => { router.removeListener('change', onChange); }); diff --git a/packages/frontend/src/events.ts b/packages/frontend/src/events.ts index 90d5f6eede..46faec8d3e 100644 --- a/packages/frontend/src/events.ts +++ b/packages/frontend/src/events.ts @@ -4,6 +4,10 @@ */ import { EventEmitter } from 'eventemitter3'; +import * as Misskey from 'misskey-js'; -// TODO: 型付㑠-export const globalEvents = new EventEmitter(); +export const globalEvents = new EventEmitter<{ + themeChanged: () => void; + clientNotification: (notification: Misskey.entities.Notification) => void; + requestClearPageCache: () => void; +}>(); diff --git a/packages/frontend/src/pages/settings/profile.vue b/packages/frontend/src/pages/settings/profile.vue index 3e707041eb..aba7d0574a 100644 --- a/packages/frontend/src/pages/settings/profile.vue +++ b/packages/frontend/src/pages/settings/profile.vue @@ -125,6 +125,7 @@ import { langmap } from '@/scripts/langmap.js'; import { definePageMetadata } from '@/scripts/page-metadata.js'; import { claimAchievement } from '@/scripts/achievements.js'; import { defaultStore } from '@/store.js'; +import { globalEvents } from '@/events.js'; import MkInfo from '@/components/MkInfo.vue'; import MkTextarea from '@/components/MkTextarea.vue'; @@ -173,6 +174,7 @@ function saveFields() { os.apiWithDialog('i/update', { fields: fields.value.filter(field => field.name !== '' && field.value !== '').map(field => ({ name: field.name, value: field.value })), }); + globalEvents.emit('requestClearPageCache'); } function save() { @@ -191,6 +193,7 @@ function save() { isBot: !!profile.isBot, isCat: !!profile.isCat, }); + globalEvents.emit('requestClearPageCache'); claimAchievement('profileFilled'); if (profile.name === 'syuilo' || profile.name === 'ã—ã‚…ã„ã‚') { claimAchievement('setNameToSyuilo'); @@ -222,6 +225,7 @@ function changeAvatar(ev) { }); $i.avatarId = i.avatarId; $i.avatarUrl = i.avatarUrl; + globalEvents.emit('requestClearPageCache'); claimAchievement('profileFilled'); }); } @@ -248,6 +252,7 @@ function changeBanner(ev) { }); $i.bannerId = i.bannerId; $i.bannerUrl = i.bannerUrl; + globalEvents.emit('requestClearPageCache'); }); } -- GitLab From 74245df3829622a3cc0c880ea710b5c1c4f5c584 Mon Sep 17 00:00:00 2001 From: 1Step621 <86859447+1STEP621@users.noreply.github.com> Date: Tue, 6 Feb 2024 16:45:21 +0900 Subject: [PATCH 11/40] =?UTF-8?q?Enhance(frontend):=20=E3=83=95=E3=83=AD?= =?UTF-8?q?=E3=83=B3=E3=83=88=E5=81=B4=E3=81=A7=E3=82=82=E3=83=AA=E3=82=A2?= =?UTF-8?q?=E3=82=AF=E3=82=B7=E3=83=A7=E3=83=B3=E6=A8=A9=E9=99=90=E3=81=AE?= =?UTF-8?q?=E3=83=81=E3=82=A7=E3=83=83=E3=82=AF=E3=82=92=E3=81=99=E3=82=8B?= =?UTF-8?q?=E3=82=88=E3=81=86=E3=81=AB=20(#13134)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * フãƒãƒ³ãƒˆå´ã§ã‚‚リアクション権é™ã®ãƒã‚§ãƒƒã‚¯ã‚’ã™ã‚‹ã‚ˆã†ã« * update CHANGELOG.md * lint fixes * remove unrelated diffs * deny -> reject denyã¯ã€Œ(信用ã—ãªã„ã“ã¨ã‚’ç†ç”±ã«)æ‹’å¦ã™ã‚‹ã€ã¨ã„ã†æ„味らã—ã„ * allow -> accept * EmojiSimpleã«localOnlyã‚’å«ã‚るよã†ã« * リアクション権é™ã®ãªã„絵文å—ã¯æ‰“ã¦ãªã„よã†ã«(ダイアãƒã‚°ã‚’出ã™ã®ã§ã¯ãªã) * regenerate type definitions * lint fix * remove unused locales * remove unnecessary async --- CHANGELOG.md | 4 ++++ .../src/core/entities/EmojiEntityService.ts | 1 + .../backend/src/models/json-schema/emoji.ts | 4 ++++ .../frontend/src/components/MkEmojiPicker.vue | 4 +++- .../src/components/MkEmojiPickerDialog.vue | 3 +++ .../src/components/MkEmojiPickerWindow.vue | 4 +++- packages/frontend/src/components/MkNote.vue | 2 +- .../frontend/src/components/MkNoteDetailed.vue | 2 +- .../components/MkReactionsViewer.reaction.vue | 18 +++++++++++++----- .../src/pages/settings/emoji-picker.vue | 2 +- .../src/scripts/check-reaction-permissions.ts | 8 ++++++++ .../frontend/src/scripts/reaction-picker.ts | 6 +++++- .../misskey-js/src/autogen/apiClientJSDoc.ts | 2 +- packages/misskey-js/src/autogen/endpoint.ts | 2 +- packages/misskey-js/src/autogen/entities.ts | 2 +- packages/misskey-js/src/autogen/models.ts | 2 +- packages/misskey-js/src/autogen/types.ts | 3 ++- 17 files changed, 53 insertions(+), 16 deletions(-) create mode 100644 packages/frontend/src/scripts/check-reaction-permissions.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 0fc99cf5b8..17c06a90e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -50,6 +50,10 @@ - Enhance: 絵文å—編集ダイアãƒã‚°ã‚’モーダルã§ã¯ãªãウィンドウã§è¡¨ç¤ºã™ã‚‹ã‚ˆã†ã« - Enhance: リモートã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã¯ãƒ¡ãƒ‹ãƒ¥ãƒ¼ã‹ã‚‰ç›´æŽ¥ãƒªãƒ¢ãƒ¼ãƒˆã§è¡¨ç¤ºã§ãるよã†ã« - Enhance: コードã®ã‚·ãƒ³ã‚¿ãƒƒã‚¯ã‚¹ãƒã‚¤ãƒ©ã‚¤ãƒˆã«ãƒ†ãƒ¼ãƒžã‚’é©ç”¨ã§ãるよã†ã« +- Enhance: リアクション権é™ãŒãªã„å ´åˆã€ãƒãƒ¼ãƒˆã«ãƒ•ã‚©ãƒ¼ãƒ«ãƒãƒƒã‚¯ã™ã‚‹ã®ã§ã¯ãªãã€æ¨©é™ãŒãªã„ã“ã¨ã‚’ダイアãƒã‚°ã§è¡¨ç¤ºã™ã‚‹ã‚ˆã†ã« + - リモートã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã«ãƒãƒ¼ã‚«ãƒ«ã®ã¿ã®ã‚«ã‚¹ã‚¿ãƒ 絵文å—をリアクションã—よã†ã¨ã—ãŸå ´åˆ + - センシティブãªãƒªã‚¢ã‚¯ã‚·ãƒ§ãƒ³ã‚’èªã‚ã¦ã„ãªã„ユーザーã«ã‚»ãƒ³ã‚·ãƒ†ã‚£ãƒ–ãªã‚«ã‚¹ã‚¿ãƒ 絵文å—をリアクションã—よã†ã¨ã—ãŸå ´åˆ + - ãƒãƒ¼ãƒ«ãŒå¿…è¦ãªçµµæ–‡å—をリアクションã—よã†ã¨ã—ãŸå ´åˆ - Fix: ãƒã‚¤ãƒ†ã‚£ãƒ–モードã®çµµæ–‡å—ãŒãƒ¢ãƒŽã‚¯ãƒã«ãªã‚‰ãªã„よã†ã« - Fix: v2023.12.0ã§è¿½åŠ ã•ã‚ŒãŸã€Œãƒ¢ãƒ‡ãƒ¬ãƒ¼ã‚¿ãƒ¼ãŒãƒ¦ãƒ¼ã‚¶ãƒ¼ã®ã‚¢ã‚¤ã‚³ãƒ³ã‚‚ã—ãã¯ãƒãƒŠãƒ¼ç”»åƒã‚’未è¨å®šçŠ¶æ…‹ã«ã§ãる機能ã€ãŒç®¡ç†ç”»é¢ä¸Šã§æ£ã—ã表示ã•ã‚Œã¦ã„ãªã„å•é¡Œã‚’ä¿®æ£ - Fix: AiScriptã®`readline`関数ãŒä¸æ£ãªå€¤ã‚’è¿”ã™ã“ã¨ãŒã‚ã‚‹å•é¡Œã®v2023.12.0時点ã§ã®ä¿®æ£ãŒPlay以外ã«é©ç”¨ã•ã‚Œã¦ã„ãªã„ã®ã‚’ä¿®æ£ diff --git a/packages/backend/src/core/entities/EmojiEntityService.ts b/packages/backend/src/core/entities/EmojiEntityService.ts index 5b97cfad5e..655c4c5ada 100644 --- a/packages/backend/src/core/entities/EmojiEntityService.ts +++ b/packages/backend/src/core/entities/EmojiEntityService.ts @@ -31,6 +31,7 @@ export class EmojiEntityService { category: emoji.category, // || emoji.originalUrl ã—ã¦ã‚‹ã®ã¯å¾Œæ–¹äº’æ›æ€§ã®ãŸã‚(publicUrlã¯stringãªã®ã§??ã¯ã ã‚) url: emoji.publicUrl || emoji.originalUrl, + localOnly: emoji.localOnly ? true : undefined, isSensitive: emoji.isSensitive ? true : undefined, roleIdsThatCanBeUsedThisEmojiAsReaction: emoji.roleIdsThatCanBeUsedThisEmojiAsReaction.length > 0 ? emoji.roleIdsThatCanBeUsedThisEmojiAsReaction : undefined, }; diff --git a/packages/backend/src/models/json-schema/emoji.ts b/packages/backend/src/models/json-schema/emoji.ts index 99a58f8773..954eb98d57 100644 --- a/packages/backend/src/models/json-schema/emoji.ts +++ b/packages/backend/src/models/json-schema/emoji.ts @@ -27,6 +27,10 @@ export const packedEmojiSimpleSchema = { type: 'string', optional: false, nullable: false, }, + localOnly: { + type: 'boolean', + optional: true, nullable: false, + }, isSensitive: { type: 'boolean', optional: true, nullable: false, diff --git a/packages/frontend/src/components/MkEmojiPicker.vue b/packages/frontend/src/components/MkEmojiPicker.vue index 58160cdf5b..f5ab7a2e29 100644 --- a/packages/frontend/src/components/MkEmojiPicker.vue +++ b/packages/frontend/src/components/MkEmojiPicker.vue @@ -118,6 +118,7 @@ import { i18n } from '@/i18n.js'; import { defaultStore } from '@/store.js'; import { customEmojiCategories, customEmojis, customEmojisMap } from '@/custom-emojis.js'; import { $i } from '@/account.js'; +import { checkReactionPermissions } from '@/scripts/check-reaction-permissions.js'; const props = withDefaults(defineProps<{ showPinned?: boolean; @@ -126,6 +127,7 @@ const props = withDefaults(defineProps<{ asDrawer?: boolean; asWindow?: boolean; asReactionPicker?: boolean; // 今ã¯ä½¿ã‚ã‚Œã¦ãªã„ãŒå°†æ¥çš„ã«ä½¿ã„ãㆠ+ targetNote?: Misskey.entities.Note; }>(), { showPinned: true, }); @@ -340,7 +342,7 @@ watch(q, () => { }); function filterAvailable(emoji: Misskey.entities.EmojiSimple): boolean { - return ((emoji.roleIdsThatCanBeUsedThisEmojiAsReaction == null || emoji.roleIdsThatCanBeUsedThisEmojiAsReaction.length === 0) || ($i && $i.roles.some(r => emoji.roleIdsThatCanBeUsedThisEmojiAsReaction?.includes(r.id)))) ?? false; + return !props.targetNote || checkReactionPermissions($i!, props.targetNote, emoji); } function focus() { diff --git a/packages/frontend/src/components/MkEmojiPickerDialog.vue b/packages/frontend/src/components/MkEmojiPickerDialog.vue index 6660dcf1ed..444e8a4cec 100644 --- a/packages/frontend/src/components/MkEmojiPickerDialog.vue +++ b/packages/frontend/src/components/MkEmojiPickerDialog.vue @@ -24,6 +24,7 @@ SPDX-License-Identifier: AGPL-3.0-only :showPinned="showPinned" :pinnedEmojis="pinnedEmojis" :asReactionPicker="asReactionPicker" + :targetNote="targetNote" :asDrawer="type === 'drawer'" :max-height="maxHeight" @chosen="chosen" @@ -32,6 +33,7 @@ SPDX-License-Identifier: AGPL-3.0-only </template> <script lang="ts" setup> +import * as Misskey from 'misskey-js'; import { shallowRef } from 'vue'; import MkModal from '@/components/MkModal.vue'; import MkEmojiPicker from '@/components/MkEmojiPicker.vue'; @@ -43,6 +45,7 @@ const props = withDefaults(defineProps<{ showPinned?: boolean; pinnedEmojis?: string[], asReactionPicker?: boolean; + targetNote?: Misskey.entities.Note; choseAndClose?: boolean; }>(), { manualShowing: null, diff --git a/packages/frontend/src/components/MkEmojiPickerWindow.vue b/packages/frontend/src/components/MkEmojiPickerWindow.vue index 1a2c55e785..2a6828f242 100644 --- a/packages/frontend/src/components/MkEmojiPickerWindow.vue +++ b/packages/frontend/src/components/MkEmojiPickerWindow.vue @@ -13,12 +13,13 @@ SPDX-License-Identifier: AGPL-3.0-only :front="true" @closed="emit('closed')" > - <MkEmojiPicker :showPinned="showPinned" :asReactionPicker="asReactionPicker" asWindow :class="$style.picker" @chosen="chosen"/> + <MkEmojiPicker :showPinned="showPinned" :asReactionPicker="asReactionPicker" :targetNote="targetNote" asWindow :class="$style.picker" @chosen="chosen"/> </MkWindow> </template> <script lang="ts" setup> import { } from 'vue'; +import * as Misskey from 'misskey-js'; import MkWindow from '@/components/MkWindow.vue'; import MkEmojiPicker from '@/components/MkEmojiPicker.vue'; @@ -26,6 +27,7 @@ withDefaults(defineProps<{ src?: HTMLElement; showPinned?: boolean; asReactionPicker?: boolean; + targetNote?: Misskey.entities.Note }>(), { showPinned: true, }); diff --git a/packages/frontend/src/components/MkNote.vue b/packages/frontend/src/components/MkNote.vue index 735ec86564..27e8bc45b7 100644 --- a/packages/frontend/src/components/MkNote.vue +++ b/packages/frontend/src/components/MkNote.vue @@ -385,7 +385,7 @@ function react(viaKeyboard = false): void { } } else { blur(); - reactionPicker.show(reactButton.value ?? null, reaction => { + reactionPicker.show(reactButton.value ?? null, note.value, reaction => { sound.playMisskeySfx('reaction'); if (props.mock) { diff --git a/packages/frontend/src/components/MkNoteDetailed.vue b/packages/frontend/src/components/MkNoteDetailed.vue index dd956b21ad..a53dd90d27 100644 --- a/packages/frontend/src/components/MkNoteDetailed.vue +++ b/packages/frontend/src/components/MkNoteDetailed.vue @@ -385,7 +385,7 @@ function react(viaKeyboard = false): void { } } else { blur(); - reactionPicker.show(reactButton.value ?? null, reaction => { + reactionPicker.show(reactButton.value ?? null, note.value, reaction => { sound.playMisskeySfx('reaction'); misskeyApi('notes/reactions/create', { diff --git a/packages/frontend/src/components/MkReactionsViewer.reaction.vue b/packages/frontend/src/components/MkReactionsViewer.reaction.vue index ffbf62a45c..67b448ccb7 100644 --- a/packages/frontend/src/components/MkReactionsViewer.reaction.vue +++ b/packages/frontend/src/components/MkReactionsViewer.reaction.vue @@ -32,6 +32,8 @@ import { claimAchievement } from '@/scripts/achievements.js'; import { defaultStore } from '@/store.js'; import { i18n } from '@/i18n.js'; import * as sound from '@/scripts/sound.js'; +import { checkReactionPermissions } from '@/scripts/check-reaction-permissions.js'; +import { customEmojis } from '@/custom-emojis.js'; const props = defineProps<{ reaction: string; @@ -48,13 +50,19 @@ const emit = defineEmits<{ const buttonEl = shallowRef<HTMLElement>(); -const canToggle = computed(() => !props.reaction.match(/@\w/) && $i); +const isCustomEmoji = computed(() => props.reaction.includes(':')); +const emoji = computed(() => isCustomEmoji.value ? customEmojis.value.find(emoji => emoji.name === props.reaction.replace(/:/g, '').replace(/@\./, '')) : null); + +const canToggle = computed(() => { + return !props.reaction.match(/@\w/) && $i + && (emoji.value && checkReactionPermissions($i, props.note, emoji.value)) + || !isCustomEmoji.value; +}); +const canGetInfo = computed(() => !props.reaction.match(/@\w/) && props.reaction.includes(':')); async function toggleReaction() { if (!canToggle.value) return; - // TODO: ãã®çµµæ–‡å—を使ã†æ¨©é™ãŒã‚ã‚‹ã‹ã©ã†ã‹ç¢ºèª - const oldReaction = props.note.myReaction; if (oldReaction) { const confirm = await os.confirm({ @@ -101,8 +109,8 @@ async function toggleReaction() { } async function menu(ev) { - if (!canToggle.value) return; - if (!props.reaction.includes(':')) return; + if (!canGetInfo.value) return; + os.popupMenu([{ text: i18n.ts.info, icon: 'ti ti-info-circle', diff --git a/packages/frontend/src/pages/settings/emoji-picker.vue b/packages/frontend/src/pages/settings/emoji-picker.vue index 61f3332122..1215af35cf 100644 --- a/packages/frontend/src/pages/settings/emoji-picker.vue +++ b/packages/frontend/src/pages/settings/emoji-picker.vue @@ -157,7 +157,7 @@ const chooseEmoji = (ev: MouseEvent) => pickEmoji(pinnedEmojis, ev); const setDefaultEmoji = () => setDefault(pinnedEmojis); function previewReaction(ev: MouseEvent) { - reactionPicker.show(getHTMLElement(ev)); + reactionPicker.show(getHTMLElement(ev), null); } function previewEmoji(ev: MouseEvent) { diff --git a/packages/frontend/src/scripts/check-reaction-permissions.ts b/packages/frontend/src/scripts/check-reaction-permissions.ts new file mode 100644 index 0000000000..c9d2a5bfc6 --- /dev/null +++ b/packages/frontend/src/scripts/check-reaction-permissions.ts @@ -0,0 +1,8 @@ +import * as Misskey from 'misskey-js'; + +export function checkReactionPermissions(me: Misskey.entities.MeDetailed, note: Misskey.entities.Note, emoji: Misskey.entities.EmojiSimple): boolean { + const roleIdsThatCanBeUsedThisEmojiAsReaction = emoji.roleIdsThatCanBeUsedThisEmojiAsReaction ?? []; + return !(emoji.localOnly && note.user.host !== me.host) + && !(emoji.isSensitive && (note.reactionAcceptance === 'nonSensitiveOnly' || note.reactionAcceptance === 'nonSensitiveOnlyForLocalLikeOnlyForRemote')) + && (roleIdsThatCanBeUsedThisEmojiAsReaction.length === 0 || me.roles.some(role => roleIdsThatCanBeUsedThisEmojiAsReaction.includes(role.id))); +} diff --git a/packages/frontend/src/scripts/reaction-picker.ts b/packages/frontend/src/scripts/reaction-picker.ts index a13351b536..193ac838a2 100644 --- a/packages/frontend/src/scripts/reaction-picker.ts +++ b/packages/frontend/src/scripts/reaction-picker.ts @@ -3,6 +3,7 @@ * SPDX-License-Identifier: AGPL-3.0-only */ +import * as Misskey from 'misskey-js'; import { defineAsyncComponent, Ref, ref } from 'vue'; import { popup } from '@/os.js'; import { defaultStore } from '@/store.js'; @@ -10,6 +11,7 @@ import { defaultStore } from '@/store.js'; class ReactionPicker { private src: Ref<HTMLElement | null> = ref(null); private manualShowing = ref(false); + private targetNote: Ref<Misskey.entities.Note | null> = ref(null); private onChosen?: (reaction: string) => void; private onClosed?: () => void; @@ -23,6 +25,7 @@ class ReactionPicker { src: this.src, pinnedEmojis: reactionsRef, asReactionPicker: true, + targetNote: this.targetNote, manualShowing: this.manualShowing, }, { done: reaction => { @@ -38,8 +41,9 @@ class ReactionPicker { }); } - public show(src: HTMLElement | null, onChosen?: ReactionPicker['onChosen'], onClosed?: ReactionPicker['onClosed']) { + public show(src: HTMLElement | null, targetNote: Misskey.entities.Note | null, onChosen?: ReactionPicker['onChosen'], onClosed?: ReactionPicker['onClosed']) { this.src.value = src; + this.targetNote.value = targetNote; this.manualShowing.value = true; this.onChosen = onChosen; this.onClosed = onClosed; diff --git a/packages/misskey-js/src/autogen/apiClientJSDoc.ts b/packages/misskey-js/src/autogen/apiClientJSDoc.ts index 7c727d2878..cb761493a2 100644 --- a/packages/misskey-js/src/autogen/apiClientJSDoc.ts +++ b/packages/misskey-js/src/autogen/apiClientJSDoc.ts @@ -1,6 +1,6 @@ /* * version: 2024.2.0-beta.8 - * generatedAt: 2024-02-04T11:51:13.598Z + * generatedAt: 2024-02-04T16:51:09.469Z */ import type { SwitchCaseResponseType } from '../api.js'; diff --git a/packages/misskey-js/src/autogen/endpoint.ts b/packages/misskey-js/src/autogen/endpoint.ts index cf9f96b526..10ec645a53 100644 --- a/packages/misskey-js/src/autogen/endpoint.ts +++ b/packages/misskey-js/src/autogen/endpoint.ts @@ -1,6 +1,6 @@ /* * version: 2024.2.0-beta.8 - * generatedAt: 2024-02-04T11:51:13.595Z + * generatedAt: 2024-02-04T16:51:09.467Z */ import type { diff --git a/packages/misskey-js/src/autogen/entities.ts b/packages/misskey-js/src/autogen/entities.ts index 2930f2cb7f..04b52e9fb6 100644 --- a/packages/misskey-js/src/autogen/entities.ts +++ b/packages/misskey-js/src/autogen/entities.ts @@ -1,6 +1,6 @@ /* * version: 2024.2.0-beta.8 - * generatedAt: 2024-02-04T11:51:13.593Z + * generatedAt: 2024-02-04T16:51:09.466Z */ import { operations } from './types.js'; diff --git a/packages/misskey-js/src/autogen/models.ts b/packages/misskey-js/src/autogen/models.ts index f01beaa706..ee14b22f74 100644 --- a/packages/misskey-js/src/autogen/models.ts +++ b/packages/misskey-js/src/autogen/models.ts @@ -1,6 +1,6 @@ /* * version: 2024.2.0-beta.8 - * generatedAt: 2024-02-04T11:51:13.592Z + * generatedAt: 2024-02-04T16:51:09.465Z */ import { components } from './types.js'; diff --git a/packages/misskey-js/src/autogen/types.ts b/packages/misskey-js/src/autogen/types.ts index 77a493fe2e..cce2dadcdb 100644 --- a/packages/misskey-js/src/autogen/types.ts +++ b/packages/misskey-js/src/autogen/types.ts @@ -3,7 +3,7 @@ /* * version: 2024.2.0-beta.8 - * generatedAt: 2024-02-04T11:51:13.473Z + * generatedAt: 2024-02-04T16:51:09.378Z */ /** @@ -4423,6 +4423,7 @@ export type components = { name: string; category: string | null; url: string; + localOnly?: boolean; isSensitive?: boolean; roleIdsThatCanBeUsedThisEmojiAsReaction?: string[]; }; -- GitLab From 4bf3974abdb41613d33bc2cb1a7f99a24c096b04 Mon Sep 17 00:00:00 2001 From: Soli <personal@str08.net> Date: Tue, 6 Feb 2024 16:47:17 +0900 Subject: [PATCH 12/40] =?UTF-8?q?fix(frontend):=20=E3=82=A8=E3=83=A9?= =?UTF-8?q?=E3=83=BC=E7=94=BB=E5=83=8FURL=E3=82=92=E8=A8=AD=E5=AE=9A?= =?UTF-8?q?=E3=81=97=E3=81=9F=E5=BE=8C=E8=A7=A3=E9=99=A4=E3=81=99=E3=82=8B?= =?UTF-8?q?=E3=81=A8=EF=BC=8C=E3=83=87=E3=83=95=E3=82=A9=E3=83=AB=E3=83=88?= =?UTF-8?q?=E3=81=AE=E7=94=BB=E5=83=8F=E3=81=8C=E8=A1=A8=E7=A4=BA=E3=81=95?= =?UTF-8?q?=E3=82=8C=E3=81=AA=E3=81=84=E5=95=8F=E9=A1=8C=E3=81=AE=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3=20(#13172)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: ã‹ã£ã“ã‹ã‚Š <67428053+kakkokari-gtyih@users.noreply.github.com> --- CHANGELOG.md | 1 + packages/frontend/src/pages/admin/branding.vue | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 17c06a90e9..98c565fe90 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -71,6 +71,7 @@ - Fix: ç”»åƒã‚’クãƒãƒƒãƒ—時ã€æ£å¸¸ã«å®Œäº†ã§ããªã„å•é¡Œã®ä¿®æ£ - Fix: ã‚ャプションãŒç©ºã®ç”»åƒã‚’クãƒãƒƒãƒ—ã™ã‚‹ã¨ã‚ャプションã«nullã¨ã„ã†æ–‡å—列ãŒå…¥ã£ã¦ã—ã¾ã†å•é¡Œã®ä¿®æ£ - Fix: プãƒãƒ•ã‚£ãƒ¼ãƒ«ã‚’編集ã—ã¦ã‚‚リãƒãƒ¼ãƒ‰ã™ã‚‹ã¾ã§åæ˜ ã•ã‚Œãªã„å•é¡Œã‚’ä¿®æ£ +- Fix: エラー画åƒURLã‚’è¨å®šã—ãŸå¾Œè§£é™¤ã™ã‚‹ã¨ï¼Œãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®ç”»åƒãŒè¡¨ç¤ºã•ã‚Œãªã„å•é¡Œã®ä¿®æ£ ### Server - Enhance: 連åˆå…ˆã®ãƒ¬ãƒ¼ãƒˆãƒªãƒŸãƒƒãƒˆã«å¼•ã£ã‹ã‹ã£ãŸéš›ã«ãƒªãƒˆãƒ©ã‚¤ã™ã‚‹ã‚ˆã†ã«ãªã‚Šã¾ã—㟠diff --git a/packages/frontend/src/pages/admin/branding.vue b/packages/frontend/src/pages/admin/branding.vue index dbbb3941d8..7f01b6021f 100644 --- a/packages/frontend/src/pages/admin/branding.vue +++ b/packages/frontend/src/pages/admin/branding.vue @@ -148,9 +148,9 @@ function save() { themeColor: themeColor.value === '' ? null : themeColor.value, defaultLightTheme: defaultLightTheme.value === '' ? null : defaultLightTheme.value, defaultDarkTheme: defaultDarkTheme.value === '' ? null : defaultDarkTheme.value, - infoImageUrl: infoImageUrl.value, - notFoundImageUrl: notFoundImageUrl.value, - serverErrorImageUrl: serverErrorImageUrl.value, + infoImageUrl: infoImageUrl.value === '' ? null : infoImageUrl.value, + notFoundImageUrl: notFoundImageUrl.value === '' ? null : notFoundImageUrl.value, + serverErrorImageUrl: serverErrorImageUrl.value === '' ? null : serverErrorImageUrl.value, manifestJsonOverride: manifestJsonOverride.value === '' ? '{}' : JSON.stringify(JSON5.parse(manifestJsonOverride.value)), }).then(() => { fetchInstance(); -- GitLab From 6829ecb50949249ec49b68d0d2071cb90e05ea7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=8B=E3=81=A3=E3=81=93=E3=81=8B=E3=82=8A?= <67428053+kakkokari-gtyih@users.noreply.github.com> Date: Tue, 6 Feb 2024 16:49:57 +0900 Subject: [PATCH 13/40] =?UTF-8?q?enhance(frontend):=20=E3=83=AA=E3=83=A2?= =?UTF-8?q?=E3=83=BC=E3=83=88=E3=81=B8=E3=81=AE=E5=BC=95=E7=94=A8=E3=83=AA?= =?UTF-8?q?=E3=83=8E=E3=83=BC=E3=83=88=E3=81=A8=E5=90=8C=E4=B8=80=E3=81=AE?= =?UTF-8?q?=E3=83=AA=E3=83=B3=E3=82=AF=E3=81=AB=E3=81=AF=E3=83=AA=E3=83=B3?= =?UTF-8?q?=E3=82=AF=E3=83=97=E3=83=AC=E3=83=93=E3=83=A5=E3=83=BC=E3=82=92?= =?UTF-8?q?=E8=A1=A8=E7=A4=BA=E3=81=97=E3=81=AA=E3=81=84=E3=82=88=E3=81=86?= =?UTF-8?q?=E3=81=AB=20(#13178)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * enhance(frontend): リモートã¸ã®å¼•ç”¨ãƒªãƒŽãƒ¼ãƒˆã¨åŒä¸€ã®ãƒªãƒ³ã‚¯ã«ã¯ãƒªãƒ³ã‚¯ãƒ—レビューを表示ã—ãªã„よã†ã« * Update Changelog --------- Co-authored-by: syuilo <Syuilotan@yahoo.co.jp> --- CHANGELOG.md | 1 + packages/frontend/src/components/MkNote.vue | 2 +- packages/frontend/src/components/MkNoteDetailed.vue | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 98c565fe90..1ba032b3f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -49,6 +49,7 @@ - Enhance: MFMã®å±žæ€§ã§ã‚ªãƒ¼ãƒˆã‚³ãƒ³ãƒ—リートãŒä½¿ç”¨ã§ãるよã†ã« #12735 - Enhance: 絵文å—編集ダイアãƒã‚°ã‚’モーダルã§ã¯ãªãウィンドウã§è¡¨ç¤ºã™ã‚‹ã‚ˆã†ã« - Enhance: リモートã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã¯ãƒ¡ãƒ‹ãƒ¥ãƒ¼ã‹ã‚‰ç›´æŽ¥ãƒªãƒ¢ãƒ¼ãƒˆã§è¡¨ç¤ºã§ãるよã†ã« +- Enhance: リモートã¸ã®å¼•ç”¨ãƒªãƒŽãƒ¼ãƒˆã¨åŒä¸€ã®ãƒªãƒ³ã‚¯ã«ã¯ãƒªãƒ³ã‚¯ãƒ—レビューを表示ã—ãªã„よã†ã« - Enhance: コードã®ã‚·ãƒ³ã‚¿ãƒƒã‚¯ã‚¹ãƒã‚¤ãƒ©ã‚¤ãƒˆã«ãƒ†ãƒ¼ãƒžã‚’é©ç”¨ã§ãるよã†ã« - Enhance: リアクション権é™ãŒãªã„å ´åˆã€ãƒãƒ¼ãƒˆã«ãƒ•ã‚©ãƒ¼ãƒ«ãƒãƒƒã‚¯ã™ã‚‹ã®ã§ã¯ãªãã€æ¨©é™ãŒãªã„ã“ã¨ã‚’ダイアãƒã‚°ã§è¡¨ç¤ºã™ã‚‹ã‚ˆã†ã« - リモートã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã«ãƒãƒ¼ã‚«ãƒ«ã®ã¿ã®ã‚«ã‚¹ã‚¿ãƒ 絵文å—をリアクションã—よã†ã¨ã—ãŸå ´åˆ diff --git a/packages/frontend/src/components/MkNote.vue b/packages/frontend/src/components/MkNote.vue index 27e8bc45b7..ac5abc3f66 100644 --- a/packages/frontend/src/components/MkNote.vue +++ b/packages/frontend/src/components/MkNote.vue @@ -253,7 +253,7 @@ const appearNote = computed(() => isRenote ? note.value.renote as Misskey.entiti const isMyRenote = $i && ($i.id === note.value.userId); const showContent = ref(false); const parsed = computed(() => appearNote.value.text ? mfm.parse(appearNote.value.text) : null); -const urls = computed(() => parsed.value ? extractUrlFromMfm(parsed.value) : null); +const urls = computed(() => parsed.value ? extractUrlFromMfm(parsed.value).filter((url) => appearNote.value.renote?.url !== url && appearNote.value.renote?.uri !== url) : null); const isLong = shouldCollapsed(appearNote.value, urls.value ?? []); const collapsed = ref(appearNote.value.cw == null && isLong); const isDeleted = ref(false); diff --git a/packages/frontend/src/components/MkNoteDetailed.vue b/packages/frontend/src/components/MkNoteDetailed.vue index a53dd90d27..89ab88ac36 100644 --- a/packages/frontend/src/components/MkNoteDetailed.vue +++ b/packages/frontend/src/components/MkNoteDetailed.vue @@ -277,7 +277,7 @@ const muted = ref($i ? checkWordMute(appearNote.value, $i, $i.mutedWords) : fals const translation = ref<Misskey.entities.NotesTranslateResponse | null>(null); const translating = ref(false); const parsed = appearNote.value.text ? mfm.parse(appearNote.value.text) : null; -const urls = parsed ? extractUrlFromMfm(parsed) : null; +const urls = parsed ? extractUrlFromMfm(parsed).filter((url) => appearNote.value.renote?.url !== url && appearNote.value.renote?.uri !== url) : null; const showTicker = (defaultStore.state.instanceTicker === 'always') || (defaultStore.state.instanceTicker === 'remote' && appearNote.value.user.instance); const conversation = ref<Misskey.entities.Note[]>([]); const replies = ref<Misskey.entities.Note[]>([]); -- GitLab From d6cb68b0910cfb53e469d5cf53714f71a1f06ba6 Mon Sep 17 00:00:00 2001 From: MeiMei <30769358+mei23@users.noreply.github.com> Date: Tue, 6 Feb 2024 16:51:14 +0900 Subject: [PATCH 14/40] =?UTF-8?q?AP=20Key=20=E3=81=AE=20JSON-LD=20?= =?UTF-8?q?=E8=A1=A8=E7=8F=BE=E3=82=92=E4=BF=AE=E6=AD=A3=20(#13170)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/backend/src/core/activitypub/ApRendererService.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/backend/src/core/activitypub/ApRendererService.ts b/packages/backend/src/core/activitypub/ApRendererService.ts index 1891c341e4..530e4a3c33 100644 --- a/packages/backend/src/core/activitypub/ApRendererService.ts +++ b/packages/backend/src/core/activitypub/ApRendererService.ts @@ -625,6 +625,7 @@ export class ApRendererService { 'https://www.w3.org/ns/activitystreams', 'https://w3id.org/security/v1', { + Key: 'sec:Key', // as non-standards manuallyApprovesFollowers: 'as:manuallyApprovesFollowers', sensitive: 'as:sensitive', -- GitLab From 653ca7e7089075909c0981c484aef8305a3bd79f Mon Sep 17 00:00:00 2001 From: 1Step621 <86859447+1STEP621@users.noreply.github.com> Date: Tue, 6 Feb 2024 16:55:21 +0900 Subject: [PATCH 15/40] =?UTF-8?q?CHANGELOG=E3=82=92=E4=BF=AE=E6=AD=A3=20(#?= =?UTF-8?q?13181)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ba032b3f9..63bf42c72f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -51,7 +51,7 @@ - Enhance: リモートã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã¯ãƒ¡ãƒ‹ãƒ¥ãƒ¼ã‹ã‚‰ç›´æŽ¥ãƒªãƒ¢ãƒ¼ãƒˆã§è¡¨ç¤ºã§ãるよã†ã« - Enhance: リモートã¸ã®å¼•ç”¨ãƒªãƒŽãƒ¼ãƒˆã¨åŒä¸€ã®ãƒªãƒ³ã‚¯ã«ã¯ãƒªãƒ³ã‚¯ãƒ—レビューを表示ã—ãªã„よã†ã« - Enhance: コードã®ã‚·ãƒ³ã‚¿ãƒƒã‚¯ã‚¹ãƒã‚¤ãƒ©ã‚¤ãƒˆã«ãƒ†ãƒ¼ãƒžã‚’é©ç”¨ã§ãるよã†ã« -- Enhance: リアクション権é™ãŒãªã„å ´åˆã€ãƒãƒ¼ãƒˆã«ãƒ•ã‚©ãƒ¼ãƒ«ãƒãƒƒã‚¯ã™ã‚‹ã®ã§ã¯ãªãã€æ¨©é™ãŒãªã„ã“ã¨ã‚’ダイアãƒã‚°ã§è¡¨ç¤ºã™ã‚‹ã‚ˆã†ã« +- Enhance: リアクション権é™ãŒãªã„å ´åˆã€ãƒãƒ¼ãƒˆã«ãƒ•ã‚©ãƒ¼ãƒ«ãƒãƒƒã‚¯ã™ã‚‹ã®ã§ã¯ãªãリアクションピッカーãªã©ã‹ã‚‰æ‰“ã¦ãªã„よã†ã« - リモートã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã«ãƒãƒ¼ã‚«ãƒ«ã®ã¿ã®ã‚«ã‚¹ã‚¿ãƒ 絵文å—をリアクションã—よã†ã¨ã—ãŸå ´åˆ - センシティブãªãƒªã‚¢ã‚¯ã‚·ãƒ§ãƒ³ã‚’èªã‚ã¦ã„ãªã„ユーザーã«ã‚»ãƒ³ã‚·ãƒ†ã‚£ãƒ–ãªã‚«ã‚¹ã‚¿ãƒ 絵文å—をリアクションã—よã†ã¨ã—ãŸå ´åˆ - ãƒãƒ¼ãƒ«ãŒå¿…è¦ãªçµµæ–‡å—をリアクションã—よã†ã¨ã—ãŸå ´åˆ -- GitLab From 93e711d8a9fe1dae4c1eaed7f509d643398f8cd8 Mon Sep 17 00:00:00 2001 From: Kisaragi <48310258+KisaragiEffective@users.noreply.github.com> Date: Tue, 6 Feb 2024 17:17:52 +0900 Subject: [PATCH 16/40] chore(frontend): reword possible typo (#13182) --- packages/frontend/src/pizzax.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/frontend/src/pizzax.ts b/packages/frontend/src/pizzax.ts index 043b6efd73..199addaefd 100644 --- a/packages/frontend/src/pizzax.ts +++ b/packages/frontend/src/pizzax.ts @@ -239,7 +239,7 @@ export class Storage<T extends StateDef> { /** * 特定ã®ã‚ーã®ã€ç°¡æ˜“çš„ãªgetter/setterを作りã¾ã™ - * 主ã«vueå ´ã§è¨å®šã‚³ãƒ³ãƒˆãƒãƒ¼ãƒ«ã®modelã¨ã—ã¦ä½¿ã†ç”¨ + * 主ã«vue上ã§è¨å®šã‚³ãƒ³ãƒˆãƒãƒ¼ãƒ«ã®modelã¨ã—ã¦ä½¿ã†ç”¨ */ public makeGetterSetter<K extends keyof T>(key: K, getter?: (v: T[K]) => unknown, setter?: (v: unknown) => T[K]): { get: () => T[K]['default']; -- GitLab From 500ea793b3ce6bc38ba6887d7446f91bba7dda9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=8B=E3=81=A3=E3=81=93=E3=81=8B=E3=82=8A?= <67428053+kakkokari-gtyih@users.noreply.github.com> Date: Tue, 6 Feb 2024 19:24:52 +0900 Subject: [PATCH 17/40] =?UTF-8?q?fix(bubble-game):=20=E5=85=B1=E6=9C=89?= =?UTF-8?q?=E7=94=A8=E7=94=BB=E5=83=8F=E3=81=AE=E3=82=B3=E3=83=A1=E3=83=B3?= =?UTF-8?q?=E3=83=88=E3=81=ABnull=E3=81=8C=E5=85=A5=E3=82=8B=E5=95=8F?= =?UTF-8?q?=E9=A1=8C=E3=82=92=E4=BF=AE=E6=AD=A3=20(#13183)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/components/MkLaunchPad.vue | 1 + packages/frontend/src/pages/drop-and-fusion.game.vue | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/frontend/src/components/MkLaunchPad.vue b/packages/frontend/src/components/MkLaunchPad.vue index 21a382f2f1..1ec1f36770 100644 --- a/packages/frontend/src/components/MkLaunchPad.vue +++ b/packages/frontend/src/components/MkLaunchPad.vue @@ -119,6 +119,7 @@ function close() { margin-top: 12px; font-size: 0.8em; line-height: 1.5em; + text-align: center; } > .indicatorWithValue { diff --git a/packages/frontend/src/pages/drop-and-fusion.game.vue b/packages/frontend/src/pages/drop-and-fusion.game.vue index 51819fafd0..2e1098a516 100644 --- a/packages/frontend/src/pages/drop-and-fusion.game.vue +++ b/packages/frontend/src/pages/drop-and-fusion.game.vue @@ -893,7 +893,6 @@ function getGameImageDriveFile() { formData.append('file', blob); formData.append('name', `bubble-game-${Date.now()}.png`); formData.append('isSensitive', 'false'); - formData.append('comment', 'null'); formData.append('i', $i.token); if (defaultStore.state.uploadFolder) { formData.append('folderId', defaultStore.state.uploadFolder); -- GitLab From c81b61eb2e4e3a16f0039ebfa9c174ee216ccafb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=8A=E3=81=95=E3=82=80=E3=81=AE=E3=81=B2=E3=81=A8?= <46447427+samunohito@users.noreply.github.com> Date: Tue, 6 Feb 2024 21:03:29 +0900 Subject: [PATCH 18/40] =?UTF-8?q?fix(misskey-js):=20=E8=87=AA=E5=8B=95?= =?UTF-8?q?=E7=94=9F=E6=88=90=E7=89=A9=E3=81=AE=E5=86=92=E9=A0=AD=E3=81=8B?= =?UTF-8?q?=E3=82=89=E3=83=90=E3=83=BC=E3=82=B8=E3=83=A7=E3=83=B3=E3=81=A8?= =?UTF-8?q?=E6=97=A5=E4=BB=98=E3=82=92=E5=89=8A=E9=99=A4=20(#13185)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../misskey-js/generator/src/generator.ts | 30 ------------------- .../misskey-js/src/autogen/apiClientJSDoc.ts | 5 ---- packages/misskey-js/src/autogen/endpoint.ts | 5 ---- packages/misskey-js/src/autogen/entities.ts | 5 ---- packages/misskey-js/src/autogen/models.ts | 5 ---- packages/misskey-js/src/autogen/types.ts | 5 ---- 6 files changed, 55 deletions(-) diff --git a/packages/misskey-js/generator/src/generator.ts b/packages/misskey-js/generator/src/generator.ts index 7e72359167..f091e599a9 100644 --- a/packages/misskey-js/generator/src/generator.ts +++ b/packages/misskey-js/generator/src/generator.ts @@ -4,22 +4,6 @@ import { toPascal } from 'ts-case-convert'; import OpenAPIParser from '@readme/openapi-parser'; import openapiTS from 'openapi-typescript'; -function generateVersionHeaderComment(openApiDocs: OpenAPIV3_1.Document): string { - const contents = { - version: openApiDocs.info.version, - generatedAt: new Date().toISOString(), - }; - - const lines: string[] = []; - lines.push('/*'); - for (const [key, value] of Object.entries(contents)) { - lines.push(` * ${key}: ${value}`); - } - lines.push(' */'); - - return lines.join('\n'); -} - async function generateBaseTypes( openApiDocs: OpenAPIV3_1.Document, openApiJsonPath: string, @@ -36,9 +20,6 @@ async function generateBaseTypes( } lines.push(''); - lines.push(generateVersionHeaderComment(openApiDocs)); - lines.push(''); - const generatedTypes = await openapiTS(openApiJsonPath, { exportType: true }); lines.push(generatedTypes); lines.push(''); @@ -59,8 +40,6 @@ async function generateSchemaEntities( const schemaNames = Object.keys(schemas); const typeAliasLines: string[] = []; - typeAliasLines.push(generateVersionHeaderComment(openApiDocs)); - typeAliasLines.push(''); typeAliasLines.push(`import { components } from '${toImportPath(typeFileName)}';`); typeAliasLines.push( ...schemaNames.map(it => `export type ${it} = components['schemas']['${it}'];`), @@ -119,9 +98,6 @@ async function generateEndpoints( const entitiesOutputLine: string[] = []; - entitiesOutputLine.push(generateVersionHeaderComment(openApiDocs)); - entitiesOutputLine.push(''); - entitiesOutputLine.push(`import { operations } from '${toImportPath(typeFileName)}';`); entitiesOutputLine.push(''); @@ -139,9 +115,6 @@ async function generateEndpoints( const endpointOutputLine: string[] = []; - endpointOutputLine.push(generateVersionHeaderComment(openApiDocs)); - endpointOutputLine.push(''); - endpointOutputLine.push('import type {'); endpointOutputLine.push( ...[emptyRequest, emptyResponse, ...entities].map(it => '\t' + it.generateName() + ','), @@ -187,9 +160,6 @@ async function generateApiClientJSDoc( const endpointOutputLine: string[] = []; - endpointOutputLine.push(generateVersionHeaderComment(openApiDocs)); - endpointOutputLine.push(''); - endpointOutputLine.push(`import type { SwitchCaseResponseType } from '${toImportPath(apiClientFileName)}';`); endpointOutputLine.push(`import type { Endpoints } from '${toImportPath(endpointsFileName)}';`); endpointOutputLine.push(''); diff --git a/packages/misskey-js/src/autogen/apiClientJSDoc.ts b/packages/misskey-js/src/autogen/apiClientJSDoc.ts index cb761493a2..d27413810c 100644 --- a/packages/misskey-js/src/autogen/apiClientJSDoc.ts +++ b/packages/misskey-js/src/autogen/apiClientJSDoc.ts @@ -1,8 +1,3 @@ -/* - * version: 2024.2.0-beta.8 - * generatedAt: 2024-02-04T16:51:09.469Z - */ - import type { SwitchCaseResponseType } from '../api.js'; import type { Endpoints } from './endpoint.js'; diff --git a/packages/misskey-js/src/autogen/endpoint.ts b/packages/misskey-js/src/autogen/endpoint.ts index 10ec645a53..7e5ca9b9ce 100644 --- a/packages/misskey-js/src/autogen/endpoint.ts +++ b/packages/misskey-js/src/autogen/endpoint.ts @@ -1,8 +1,3 @@ -/* - * version: 2024.2.0-beta.8 - * generatedAt: 2024-02-04T16:51:09.467Z - */ - import type { EmptyRequest, EmptyResponse, diff --git a/packages/misskey-js/src/autogen/entities.ts b/packages/misskey-js/src/autogen/entities.ts index 04b52e9fb6..9363ef7bcf 100644 --- a/packages/misskey-js/src/autogen/entities.ts +++ b/packages/misskey-js/src/autogen/entities.ts @@ -1,8 +1,3 @@ -/* - * version: 2024.2.0-beta.8 - * generatedAt: 2024-02-04T16:51:09.466Z - */ - import { operations } from './types.js'; export type EmptyRequest = Record<string, unknown> | undefined; diff --git a/packages/misskey-js/src/autogen/models.ts b/packages/misskey-js/src/autogen/models.ts index ee14b22f74..8d594e61bb 100644 --- a/packages/misskey-js/src/autogen/models.ts +++ b/packages/misskey-js/src/autogen/models.ts @@ -1,8 +1,3 @@ -/* - * version: 2024.2.0-beta.8 - * generatedAt: 2024-02-04T16:51:09.465Z - */ - import { components } from './types.js'; export type Error = components['schemas']['Error']; export type UserLite = components['schemas']['UserLite']; diff --git a/packages/misskey-js/src/autogen/types.ts b/packages/misskey-js/src/autogen/types.ts index cce2dadcdb..b7d65406cb 100644 --- a/packages/misskey-js/src/autogen/types.ts +++ b/packages/misskey-js/src/autogen/types.ts @@ -1,11 +1,6 @@ /* eslint @typescript-eslint/naming-convention: 0 */ /* eslint @typescript-eslint/no-explicit-any: 0 */ -/* - * version: 2024.2.0-beta.8 - * generatedAt: 2024-02-04T16:51:09.378Z - */ - /** * This file was auto-generated by openapi-typescript. * Do not make direct changes to the file. -- GitLab From 6a94a52131840728219cec1a91357970837ee85f Mon Sep 17 00:00:00 2001 From: Marie <marie@kaifa.ch> Date: Tue, 6 Feb 2024 21:23:37 +0100 Subject: [PATCH 19/40] merge: upstream --- CHANGELOG.md | 11 + locales/ca-ES.yml | 191 ++++++++++++++++++ locales/it-IT.yml | 60 +++++- locales/ko-GS.yml | 72 ++++++- locales/ko-KR.yml | 8 +- package.json | 2 +- packages/backend/src/core/EmailService.ts | 2 + .../backend/src/core/InstanceActorService.ts | 10 +- packages/backend/src/core/SignupService.ts | 4 +- .../src/core/activitypub/ApRendererService.ts | 1 + .../activitypub/models/ApPersonService.ts | 43 ++-- .../src/core/entities/EmojiEntityService.ts | 1 + .../backend/src/models/json-schema/emoji.ts | 4 + .../api/endpoints/admin/accounts/create.ts | 8 +- .../backend/src/server/api/endpoints/meta.ts | 11 +- .../frontend/src/components/MkCode.core.vue | 56 ++++- packages/frontend/src/components/MkCode.vue | 8 +- .../frontend/src/components/MkCodeEditor.vue | 5 +- .../frontend/src/components/MkCodeInline.vue | 3 +- .../src/components/MkCropperDialog.vue | 17 +- .../frontend/src/components/MkEmojiPicker.vue | 4 +- .../src/components/MkEmojiPickerDialog.vue | 3 + .../src/components/MkEmojiPickerWindow.vue | 4 +- .../frontend/src/components/MkLaunchPad.vue | 1 + packages/frontend/src/components/MkNote.vue | 6 +- .../src/components/MkNoteDetailed.vue | 6 +- .../frontend/src/components/MkPageWindow.vue | 2 +- .../components/MkReactionsViewer.reaction.vue | 18 +- packages/frontend/src/components/MkSelect.vue | 7 +- packages/frontend/src/components/SkNote.vue | 4 +- .../src/components/SkNoteDetailed.vue | 4 +- .../src/components/global/RouterView.vue | 42 +++- packages/frontend/src/events.ts | 8 +- packages/frontend/src/os.ts | 18 +- .../src/pages/admin/bot-protection.vue | 6 +- .../frontend/src/pages/admin/branding.vue | 6 +- .../frontend/src/pages/admin/security.vue | 6 +- .../src/pages/drop-and-fusion.game.vue | 1 - packages/frontend/src/pages/instance-info.vue | 2 +- packages/frontend/src/pages/reversi/index.vue | 16 +- .../src/pages/settings/emoji-picker.vue | 2 +- .../frontend/src/pages/settings/profile.vue | 12 +- .../frontend/src/pages/settings/theme.vue | 15 +- packages/frontend/src/pizzax.ts | 25 +-- packages/frontend/src/router/main.ts | 4 + .../src/scripts/check-reaction-permissions.ts | 8 + packages/frontend/src/scripts/clone.ts | 4 +- .../frontend/src/scripts/code-highlighter.ts | 68 ++++++- packages/frontend/src/scripts/merge.ts | 31 +++ .../frontend/src/scripts/reaction-picker.ts | 6 +- packages/frontend/src/scripts/theme.ts | 10 +- packages/frontend/src/store.ts | 1 + packages/frontend/src/themes/_dark.json5 | 4 + packages/frontend/src/themes/_light.json5 | 4 + .../misskey-js/generator/src/generator.ts | 30 --- .../misskey-js/src/autogen/apiClientJSDoc.ts | 5 - packages/misskey-js/src/autogen/endpoint.ts | 5 - packages/misskey-js/src/autogen/entities.ts | 5 - packages/misskey-js/src/autogen/models.ts | 5 - packages/misskey-js/src/autogen/types.ts | 6 +- 60 files changed, 741 insertions(+), 190 deletions(-) create mode 100644 packages/frontend/src/scripts/check-reaction-permissions.ts create mode 100644 packages/frontend/src/scripts/merge.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f6cf2071b..63bf42c72f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -49,6 +49,12 @@ - Enhance: MFMã®å±žæ€§ã§ã‚ªãƒ¼ãƒˆã‚³ãƒ³ãƒ—リートãŒä½¿ç”¨ã§ãるよã†ã« #12735 - Enhance: 絵文å—編集ダイアãƒã‚°ã‚’モーダルã§ã¯ãªãウィンドウã§è¡¨ç¤ºã™ã‚‹ã‚ˆã†ã« - Enhance: リモートã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã¯ãƒ¡ãƒ‹ãƒ¥ãƒ¼ã‹ã‚‰ç›´æŽ¥ãƒªãƒ¢ãƒ¼ãƒˆã§è¡¨ç¤ºã§ãるよã†ã« +- Enhance: リモートã¸ã®å¼•ç”¨ãƒªãƒŽãƒ¼ãƒˆã¨åŒä¸€ã®ãƒªãƒ³ã‚¯ã«ã¯ãƒªãƒ³ã‚¯ãƒ—レビューを表示ã—ãªã„よã†ã« +- Enhance: コードã®ã‚·ãƒ³ã‚¿ãƒƒã‚¯ã‚¹ãƒã‚¤ãƒ©ã‚¤ãƒˆã«ãƒ†ãƒ¼ãƒžã‚’é©ç”¨ã§ãるよã†ã« +- Enhance: リアクション権é™ãŒãªã„å ´åˆã€ãƒãƒ¼ãƒˆã«ãƒ•ã‚©ãƒ¼ãƒ«ãƒãƒƒã‚¯ã™ã‚‹ã®ã§ã¯ãªãリアクションピッカーãªã©ã‹ã‚‰æ‰“ã¦ãªã„よã†ã« + - リモートã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã«ãƒãƒ¼ã‚«ãƒ«ã®ã¿ã®ã‚«ã‚¹ã‚¿ãƒ 絵文å—をリアクションã—よã†ã¨ã—ãŸå ´åˆ + - センシティブãªãƒªã‚¢ã‚¯ã‚·ãƒ§ãƒ³ã‚’èªã‚ã¦ã„ãªã„ユーザーã«ã‚»ãƒ³ã‚·ãƒ†ã‚£ãƒ–ãªã‚«ã‚¹ã‚¿ãƒ 絵文å—をリアクションã—よã†ã¨ã—ãŸå ´åˆ + - ãƒãƒ¼ãƒ«ãŒå¿…è¦ãªçµµæ–‡å—をリアクションã—よã†ã¨ã—ãŸå ´åˆ - Fix: ãƒã‚¤ãƒ†ã‚£ãƒ–モードã®çµµæ–‡å—ãŒãƒ¢ãƒŽã‚¯ãƒã«ãªã‚‰ãªã„よã†ã« - Fix: v2023.12.0ã§è¿½åŠ ã•ã‚ŒãŸã€Œãƒ¢ãƒ‡ãƒ¬ãƒ¼ã‚¿ãƒ¼ãŒãƒ¦ãƒ¼ã‚¶ãƒ¼ã®ã‚¢ã‚¤ã‚³ãƒ³ã‚‚ã—ãã¯ãƒãƒŠãƒ¼ç”»åƒã‚’未è¨å®šçŠ¶æ…‹ã«ã§ãる機能ã€ãŒç®¡ç†ç”»é¢ä¸Šã§æ£ã—ã表示ã•ã‚Œã¦ã„ãªã„å•é¡Œã‚’ä¿®æ£ - Fix: AiScriptã®`readline`関数ãŒä¸æ£ãªå€¤ã‚’è¿”ã™ã“ã¨ãŒã‚ã‚‹å•é¡Œã®v2023.12.0時点ã§ã®ä¿®æ£ãŒPlay以外ã«é©ç”¨ã•ã‚Œã¦ã„ãªã„ã®ã‚’ä¿®æ£ @@ -62,6 +68,11 @@ - Enhance: ページé·ç§»æ™‚ã«Playerã‚’é–‰ã˜ã‚‹ã‚ˆã†ã« - Fix: iOSã§å¤§ããªç”»åƒã‚’変æ›ã—ã¦ã‚¢ãƒƒãƒ—ãƒãƒ¼ãƒ‰ã§ããªã„å•é¡Œã‚’ä¿®æ£ - Fix: 「アニメーション画åƒã‚’å†ç”Ÿã—ãªã„ã€ã‚‚ã—ãã¯ã€Œãƒ‡ãƒ¼ã‚¿ã‚»ãƒ¼ãƒãƒ¼ï¼ˆã‚¢ã‚¤ã‚³ãƒ³ï¼‰ã€ã‚’有効ã«ã—ã¦ã„ã¦ã‚‚ã€ã‚¢ã‚¤ã‚³ãƒ³ãƒ‡ã‚³ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ã®ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ãŒåœæ¢ã•ã‚Œãªã„å•é¡Œã‚’ä¿®æ£ +- Fix: ç”»åƒã‚’クãƒãƒƒãƒ—ã™ã‚‹ã¨ã‚¯ãƒãƒƒãƒ—後ã®è§£åƒåº¦ãŒç•°æ§˜ã«ä½Žããªã‚‹å•é¡Œã®ä¿®æ£ +- Fix: ç”»åƒã‚’クãƒãƒƒãƒ—時ã€æ£å¸¸ã«å®Œäº†ã§ããªã„å•é¡Œã®ä¿®æ£ +- Fix: ã‚ャプションãŒç©ºã®ç”»åƒã‚’クãƒãƒƒãƒ—ã™ã‚‹ã¨ã‚ャプションã«nullã¨ã„ã†æ–‡å—列ãŒå…¥ã£ã¦ã—ã¾ã†å•é¡Œã®ä¿®æ£ +- Fix: プãƒãƒ•ã‚£ãƒ¼ãƒ«ã‚’編集ã—ã¦ã‚‚リãƒãƒ¼ãƒ‰ã™ã‚‹ã¾ã§åæ˜ ã•ã‚Œãªã„å•é¡Œã‚’ä¿®æ£ +- Fix: エラー画åƒURLã‚’è¨å®šã—ãŸå¾Œè§£é™¤ã™ã‚‹ã¨ï¼Œãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®ç”»åƒãŒè¡¨ç¤ºã•ã‚Œãªã„å•é¡Œã®ä¿®æ£ ### Server - Enhance: 連åˆå…ˆã®ãƒ¬ãƒ¼ãƒˆãƒªãƒŸãƒƒãƒˆã«å¼•ã£ã‹ã‹ã£ãŸéš›ã«ãƒªãƒˆãƒ©ã‚¤ã™ã‚‹ã‚ˆã†ã«ãªã‚Šã¾ã—㟠diff --git a/locales/ca-ES.yml b/locales/ca-ES.yml index eeafcafed2..02e1d3e362 100644 --- a/locales/ca-ES.yml +++ b/locales/ca-ES.yml @@ -1157,6 +1157,12 @@ edited: "Editat" notificationRecieveConfig: "Parà metres de notificacions" mutualFollow: "Seguidor mutu" fileAttachedOnly: "Només notes amb adjunts" +showRepliesToOthersInTimeline: "Mostrar les respostes a altres a la lÃnia de temps" +hideRepliesToOthersInTimeline: "Amagar les respostes a altres a la lÃnia de temps" +showRepliesToOthersInTimelineAll: "Mostrar les respostes a altres a usuaris que segueixes a la lÃnia de temps" +hideRepliesToOthersInTimelineAll: "Ocultar les teves respostes a tots els usuaris que segueixes a la lÃnia de temps" +confirmShowRepliesAll: "Aquesta opció no té marxa enrere. Vols mostrar les teves respostes a tots els que segueixes a la teva lÃnia de temps?" +confirmHideRepliesAll: "Aquesta opció no té marxa enrere. Vols ocultar les teves respostes a tots els usuaris que segueixes a la lÃnia de temps?" externalServices: "Serveis externs" impressum: "Impressum" impressumUrl: "Adreça URL impressum" @@ -1187,7 +1193,25 @@ seasonalScreenEffect: "Efectes de pantalla segons les estacions" decorate: "Decorar" addMfmFunction: "Afegeix funcions MFM" enableQuickAddMfmFunction: "Activar accés rà pid per afegir funcions MFM" +bubbleGame: "Bubble Game" +sfx: "Efectes de so" +soundWillBePlayed: "Es reproduiran efectes de so" +showReplay: "Veure reproducció" +replay: "Reproduir" +replaying: "Reproduint" +ranking: "Classificació" lastNDays: "Últims {n} dies" +backToTitle: "Torna al tÃtol" +hemisphere: "Geolocalització" +withSensitive: "Incloure notes amb fitxers sensibles" +userSaysSomethingSensitive: "La publicació de {name} conte material sensible" +enableHorizontalSwipe: "Lliscar per canviar de pestanya" +_bubbleGame: + howToPlay: "Com es juga" + _howToPlay: + section1: "Ajusta la posició i deixa caure l'objecte dintre la caixa." + section2: "Quan dos objectes del mateix tipus es toquen, canviaran en un objecte diferent i guanyares punts." + section3: "El joc s'acabarà quan els objectes sobresurtin de la caixa. Intenta aconseguir la puntuació més gran possible fusionant objectes mentre impedeixes que sobresurtin de la caixa!" _announcement: forExistingUsers: "Anunci per usuaris registrats" forExistingUsersDescription: "Aquest avÃs només es mostrarà als usuaris existents fins al moment de la publicació. Si no també es mostrarà als usuaris que es registrin després de la publicació." @@ -1209,8 +1233,32 @@ _initialAccountSetting: privacySetting: "Configuració de seguretat" theseSettingsCanEditLater: "Aquests ajustos es poden canviar més tard." youCanEditMoreSettingsInSettingsPageLater: "A més d'això, es poden fer diferents configuracions a través de la pà gina de configuració. Assegureu-vos de comprovar-ho més tard." + followUsers: "Prova de seguir usuaris que t'interessin per construir la teva lÃnia de temps." + pushNotificationDescription: "Activant les notificacions emergents et permetrà rebre notificacions de {name} directament al teu dispositiu." + initialAccountSettingCompleted: "Configuració del perfil completada!" + haveFun: "Disfruta {name}!" + youCanContinueTutorial: "Pots continuar amb un tutorial per aprendre a Fer servir {name} (MissKey) o tu pots estalviar i començar a fer-lo servir ja." + startTutorial: "Començar el tutorial" + skipAreYouSure: "Et vols saltar la configuració del perfil?" + laterAreYouSure: "Vols continuar la configuració del perfil més tard?" _initialTutorial: + launchTutorial: "Començar tutorial" + title: "Tutorial" + wellDone: "Ben fet!" + skipAreYouSure: "Sortir del tutorial?" + _landing: + title: "Benvingut al tutorial" + description: "Aquà aprendrà s el bà sic per poder fer servir Misskey i les seves caracterÃstiques." + _note: + title: "Què és una Nota?" + description: "Les publicacions a Misskey es diuen 'Notes'. Les Notes s'ordenen cronològicament a la lÃnia de temps i s'actualitzen de forma automà tica." + reply: "Fes clic en aquest botó per contestar a un missatge. També és possible contestar a una contestació, continuant la conversació en forma de fil." + renote: "Pots compartir una Nota a la teva pròpia lÃnia de temps. Inclús pots citar-les amb els teus comentaris." + reaction: "Pots afegir reaccions a les Notes. Entrarem més en detall a la pròxima pà gina." + menu: "Pots veure els detalls de les Notes, copiar enllaços i fer diferents accions." _reaction: + title: "Què són les Reaccions?" + description: "Es poden reaccionar a les Notes amb diferents emoticones. Les reaccions et permeten expressar matisos que hi són més enllà d'un simple m'agrada." letsTryReacting: "Es poden afegir reaccions fent clic al botó '+'. Prova reaccionant a aquesta nota!" reactToContinue: "Afegeix una reacció per continuar." reactNotification: "Rebrà s notificacions en temps real quan un usuari reaccioni a les teves notes." @@ -1272,9 +1320,75 @@ _serverSettings: shortName: "Nom curt" shortNameDescription: "Una abreviatura del nom de la instà ncia que es poguà mostrar en cas que el nom oficial sigui massa llarg" fanoutTimelineDescription: "Quan es troba activat millora bastant el rendiment quan es recuperen les lÃnies de temps i redueix la carrega de la base de dades. Com a contrapunt, l'ús de memòria de Redis es veurà incrementada. Considera d'estabilitat aquesta opció en cas de tenir un servidor amb poca memòria o si tens problemes de inestabilitat." + fanoutTimelineDbFallback: "Carregar de la base de dades" + fanoutTimelineDbFallbackDescription: "Quan s'activa, la lÃnia de temps fa servir la base de dades per consultes adicionals si la lÃnia de temps no es troba a la memòria cau. Si és desactiva la cà rrega del servidor és veure reduïda, però també és reduirà el nombre de lÃnies de temps que és poden obtenir." +_accountMigration: + moveFrom: "Migrar un altre compte a aquest" + moveFromSub: "Crear un à lies per un altre compte" + moveFromLabel: "Compte original #{n}" + moveFromDescription: "Has de crear un à lies del compte que vols migrar en aquest compte.\nFes servir aquest format per posar el compte que vols migrar: @nomusuari@servidor.exemple.com\nPer esborrar l'à lies deixa el camp en blanc (no és recomanable de fer)" + moveTo: "Migrar aquest compte a un altre" + moveToLabel: "Compte al qual es vol migrar:" + moveCannotBeUndone: "Les migracions dels comptes no es poden desfer." + moveAccountDescription: "Això migrarà la teva compte a un altre diferent.\n ・Els seguidors d'aquest compte és passaran al compte nou de forma automà tica\n ・Es deixaran de seguir a tots els usuaris que es segueixen actualment en aquest compte\n ・No es poden crear notes noves, etc. en aquest compte\n\nSi bé la migració de seguidors es automà tica, has de preparar alguns pasos manualment per migrar la llista d'usuaris que segueixes. Per fer això has d'exportar els seguidors que després importaraes al compte nou mitjançant el menú de configuració. El mateix procediment s'ha de seguir per less teves llistes i els teus usuaris silenciats i bloquejats.\n\n(Aquesta explicació s'aplica a Misskey v13.12.0 i posteriors. Altres aplicacions, com Mastodon, poden funcionar diferent.)" + moveAccountHowTo: "Per fer la migració, primer has de crear un à lies per aquest compte al compte al qual vols migrar.\nDesprés de crear l'à lies, introdueix el compte al qual vols migrar amb el format següent: @nomusuari@servidor.exemple.com" + startMigration: "Migrar" + migrationConfirm: "Vols migrar aquest compte a {account}? Una vegada comenci la migració no es podrà parar O fer marxa enrere i no podrà s tornar a fer servir aquest compte mai més." + movedAndCannotBeUndone: "Aquest compte ha migrat.\nLes migracions no es poden desfer." + postMigrationNote: "Aquest compte deixarà de seguir tots els comptes que segueix 24 hores després de germinar la migració.\nEl nombre de seguidors i seguits passarà a ser de zero. Per evitar que els teus seguidors no puguin veure les publicacions marcades com a només seguidors continuaren seguint aquest compte." + movedTo: "Nou compte:" _achievements: + earnedAt: "Desbloquejat el" _types: + _notes1: + title: "AquÃ, configurant el meu msky" + description: "Publica la teva primera Nota" + flavor: "Passa-t'ho bé fent servir Miskey!" + _notes10: + title: "Algunes notes" + description: "Publica 10 notes" + _notes100: + title: "Un piló de notes" + description: "Publica 100 notes" + _notes500: + title: "Cobert de notes" + description: "Publica 500 notes" + _notes1000: + title: "Un piló de notes" + description: "1 000 notes publicades" + _notes5000: + title: "Desbordament de notes" + description: "5 000 notes publicades" + _notes10000: + title: "Supernota" + description: "10 000 notes publicades" + _notes20000: + title: "Necessito... Més... Notes!" + description: "20 000 notes publicades" + _notes30000: + title: "Notes notes notes!" + description: "30 000 notes publicades" + _notes40000: + title: "Fà brica de notes" + description: "40 000 notes publicades" + _notes50000: + title: "Planeta de notes" + description: "50 000 notes publicades" + _notes60000: + title: "Quà sar de notes" + description: "60 000 notes publicades" + _notes70000: + title: "Forat negre de notes" + description: "70 000 notes publicades" + _notes80000: + title: "Galà xia de notes" + description: "80 000 notes publicades" + _notes90000: + title: "Univers de notes" + description: "90 000 notes publicades" _notes100000: + title: "ALL YOUR NOTE ARE BELONG TO US" + description: "100 000 notes publicades" flavor: "Segur que tens moltes coses a dir?" _login3: title: "Principiant I" @@ -1347,13 +1461,90 @@ _achievements: description: "És la primera vegada que et segueixo" _following10: title: "Segueix-me... Segueix-me..." + description: "Seguir 10 usuaris" + _following50: + title: "Molts amics" + description: "Seguir 50 comptes" + _following100: + title: "100 amics" + description: "Segueixes 100 comptes" + _following300: + title: "Sobrecà rrega d'amics" + description: "Segueixes 300 comptes" + _followers1: + title: "Primer seguidor" + description: "1 seguidor guanyat" + _followers10: + title: "Segueix-me!" + description: "10 seguidors guanyats" + _followers50: + title: "Venen en manada" + description: "50 seguidors guanyats" + _followers100: + title: "Popular" + description: "100 seguidors guanyats" + _followers300: + title: "Si us plau, d'un en un!" + description: "300 seguidors guanyats" + _followers500: + title: "Torre de rà dio" + description: "500 seguidors guanyats" + _followers1000: + title: "Influenciador" + description: "1 000 seguidors guanyats" + _collectAchievements30: + title: "Col·leccionista d'èxits " + description: "Desbloqueja 30 assoliments" + _viewAchievements3min: + title: "M'agraden els èxits " + description: "Mira la teva llista d'assoliments durant més de 3 minuts" + _iLoveMisskey: + title: "Estimo Misskey" + description: "Publica \"I ⤠#Misskey\"" + flavor: "L'equip de desenvolupament de Misskey agraeix el vostre suport!" + _foundTreasure: + title: "A la Recerca del Tresor" + description: "Has trobat el tresor amagat" + _client30min: + title: "Parem una estona" + description: "Mantingues obert Misskey per 30 minuts" + _client60min: + title: "A totes amb Misskey" + description: "Mantingues Misskey obert per 60 minuts" + _noteDeletedWithin1min: + title: "No et preocupis" + description: "Esborra una nota al minut de publicar-la" + _postedAtLateNight: + title: "Nocturn" + description: "Publica una nota a altes hores de la nit " + flavor: "És hora d'anar a dormir." _open3windows: title: "Multi finestres" description: "I va obrir més de tres finestres" _driveFolderCircularReference: title: "Consulteu la secció de bucle" _role: + permission: "Permisos de rol" + descriptionOfPermission: "Els <b>Moderadors</b> poden fer operacions bà siques de moderació.\nEls <b>Administradors</b> poden canviar tots els ajustos del servidor." assignTarget: "Assignar " + descriptionOfAssignTarget: "<b>Manual</b> per canviar manualment qui és part d'aquest rol i qui no.\n<b>Condicional</b> per afegir o eliminar de manera automà tica els usuaris d'aquest rol basat en una determinada condició." + manual: "Manual" + manualRoles: "Rols manuals" + conditional: "Condicional" + conditionalRoles: "Rols condicionals" + condition: "Condició" + isConditionalRole: "Aquest és un rol condicional" + isPublic: "Rol públic" + descriptionOfIsPublic: "Aquest rol es mostrarà al perfil dels usuaris al que se'ls assigni." + options: "Opcions" + policies: "PolÃtiques" + baseRole: "Plantilla de rols" + useBaseValue: "Fer servir els valors de la plantilla de rols" + chooseRoleToAssign: "Selecciona els rols a assignar" + iconUrl: "URL de la icona " + asBadge: "Mostrar com a insÃgnia " + descriptionOfAsBadge: "La icona d'aquest rol es mostrarà al costat dels noms d'usuaris que tinguin assignats aquest rol." + isExplorable: "Fer el rol explorable" priority: "Prioritat" _priority: low: "Baixa" diff --git a/locales/it-IT.yml b/locales/it-IT.yml index 0c03337343..db98eaaa24 100644 --- a/locales/it-IT.yml +++ b/locales/it-IT.yml @@ -103,7 +103,7 @@ defaultNoteVisibility: "Privacy predefinita delle note" follow: "Segui" followRequest: "Richiesta di follow" followRequests: "Richieste di follow" -unfollow: "Interrompi following" +unfollow: "Smetti di seguire" followRequestPending: "Richiesta in approvazione" enterEmoji: "Inserisci emoji" renote: "Rinota" @@ -381,9 +381,11 @@ hcaptcha: "hCaptcha" enableHcaptcha: "Abilita hCaptcha" hcaptchaSiteKey: "Chiave del sito" hcaptchaSecretKey: "Chiave segreta" +mcaptcha: "mCaptcha" enableMcaptcha: "Abilita hCaptcha" mcaptchaSiteKey: "Chiave del sito" mcaptchaSecretKey: "Chiave segreta" +mcaptchaInstanceUrl: "URL della istanza mCaptcha" recaptcha: "reCAPTCHA" enableRecaptcha: "Abilita reCAPTCHA" recaptchaSiteKey: "Chiave del sito" @@ -631,6 +633,7 @@ medium: "Medio" small: "Piccolo" generateAccessToken: "Genera token di accesso" permission: "Autorizzazioni " +adminPermission: "Privilegi amministrativi" enableAll: "Abilita tutto" disableAll: "Disabilita tutto" tokenRequested: "Autorizza accesso al profilo" @@ -674,6 +677,7 @@ useGlobalSettingDesc: "Quando attiva, verranno utilizzate le impostazioni notifi other: "Ulteriori" regenerateLoginToken: "Genera di nuovo un token di connessione" regenerateLoginTokenDescription: "Genera un nuovo token di autenticazione. Solitamente questa operazione non è necessaria: quando si genera un nuovo token, tutti i dispositivi vanno disconnessi." +theKeywordWhenSearchingForCustomEmoji: "Questa sarà la parola chiave durante la ricerca di emoji personalizzate" setMultipleBySeparatingWithSpace: "È possibile creare multiple voci separate da spazi." fileIdOrUrl: "ID o URL del file" behavior: "Comportamento" @@ -872,7 +876,7 @@ pubSub: "Publish/Subscribe del profilo" lastCommunication: "La comunicazione più recente" resolved: "Risolto" unresolved: "Non risolto" -breakFollow: "Interrompi follow" +breakFollow: "Impedire di seguirmi" breakFollowConfirm: "Vuoi davvero che questo profilo smetta di seguirti?" itsOn: "Abilitato" itsOff: "Disabilitato" @@ -888,6 +892,8 @@ makeReactionsPublicDescription: "La lista delle reazioni che avete fatto è a di classic: "Classico" muteThread: "Silenzia conversazione" unmuteThread: "Riattiva la conversazione" +followingVisibility: "Visibilità dei profili seguiti" +followersVisibility: "Visibilità dei profili che ti seguono" continueThread: "Altre conversazioni" deleteAccountConfirm: "Così verrà eliminato il profilo. Vuoi procedere?" incorrectPassword: "La password è errata." @@ -1057,6 +1063,8 @@ limitWidthOfReaction: "Limita la larghezza delle reazioni e ridimensionale" noteIdOrUrl: "ID della Nota o URL" video: "Video" videos: "Video" +audio: "Audio" +audioFiles: "Audio" dataSaver: "Risparmia dati" accountMigration: "Migrazione del profilo" accountMoved: "Questo profilo ha migrato altrove:" @@ -1187,7 +1195,27 @@ remainingN: "Rimangono: {n}" overwriteContentConfirm: "Vuoi davvero sostituire l'attuale contenuto?" seasonalScreenEffect: "Schermate in base alla stagione" decorate: "Decora" +addMfmFunction: "Aggiungi decorazioni" +enableQuickAddMfmFunction: "Attiva il selettore di funzioni MFM" +bubbleGame: "Bubble Game" +sfx: "Effetti sonori" +soundWillBePlayed: "Verrà riprodotto il suono" +showReplay: "Vedi i replay" +replay: "Replay" +replaying: "Replay in corso" +ranking: "Classifica" lastNDays: "Ultimi {n} giorni" +backToTitle: "Torna al titolo" +hemisphere: "Geolocalizzazione" +withSensitive: "Mostra le Note con allegati espliciti" +userSaysSomethingSensitive: "Note da {name} con allegati espliciti" +enableHorizontalSwipe: "Trascina per invertire i tab" +_bubbleGame: + howToPlay: "Come giocare" + _howToPlay: + section1: "Regola la posizione e rilascia l'oggetto nella casella." + section2: "Ottieni un punteggio, quando due oggetti dello stesso tipo si toccano e si trasformano in un oggetto diverso." + section3: "Se gli oggetti traboccano dalla scatola, il gioco finisce. Cerca di ottenere un punteggio elevato fondendo gli oggetti, evitando che escano dalla scatola!" _announcement: forExistingUsers: "Solo ai profili attuali" forExistingUsersDescription: "L'annuncio sarà visibile solo ai profili esistenti in questo momento. Se disabilitato, sarà visibile anche ai profili che verranno creati dopo la pubblicazione di questo annuncio." @@ -1558,6 +1586,13 @@ _achievements: _tutorialCompleted: title: "Attestato di partecipazione al corso per principianti di Misskey" description: "Ha completato il tutorial" + _bubbleGameExplodingHead: + title: "🤯" + description: "Estrai l'oggetto più grande dal Bubble Game" + _bubbleGameDoubleExplodingHead: + title: "Doppio 🤯" + description: "Due oggetti più grossi contemporaneamente nel Bubble Game" + flavor: "Ha le dimensioni di una bento-box 🤯 🤯" _role: new: "Nuovo ruolo" edit: "Modifica ruolo" @@ -1648,6 +1683,7 @@ _emailUnavailable: disposable: "Indirizzo email non utilizzabile" mx: "Server email non corretto" smtp: "Il server email non risponde" + banned: "Non puoi registrarti con questo indirizzo email" _ffVisibility: public: "Pubblica" followers: "Mostra solo ai follower" @@ -1940,6 +1976,26 @@ _permissions: "write:flash": "Modifica Play" "read:flash-likes": "Visualizza lista di Play piaciuti" "write:flash-likes": "Modifica lista di Play piaciuti" + "read:admin:abuse-user-reports": "Mostra i report dai profili utente" + "write:admin:delete-account": "Elimina l'account utente" + "write:admin:delete-all-files-of-a-user": "Elimina i file dell'account utente" + "read:admin:index-stats": "Visualizza informazioni sugli indici del database" + "read:admin:table-stats": "Visualizza informazioni sulle tabelle del database" + "read:admin:user-ips": "Visualizza indirizzi IP degli account" + "read:admin:meta": "Visualizza i metadati dell'istanza" + "write:admin:reset-password": "Ripristina la password dell'account utente" + "write:admin:resolve-abuse-user-report": "Risolvere le segnalazioni dagli account utente" + "write:admin:send-email": "Spedire email" + "read:admin:server-info": "Vedere le informazioni sul server" + "read:admin:show-moderation-log": "Vedere lo storico di moderazione" + "read:admin:show-user": "Vedere le informazioni private degli account utente" + "read:admin:show-users": "Vedere le informazioni private degli account utente" + "write:admin:suspend-user": "Sospendere i profili" + "write:admin:unset-user-avatar": "Rimuovere la foto profilo dai profili" + "write:admin:unset-user-banner": "Rimuovere l'immagine testata dai profili" + "write:admin:unsuspend-user": "Togliere la sospensione ai profili" + "write:admin:meta": "Modificare i metadati dell'istanza" + "write:admin:user-note": "Scrivere annotazioni di moderazione" _auth: shareAccessTitle: "Permessi dell'applicazione" shareAccess: "Vuoi autorizzare {name} ad accedere al tuo profilo?" diff --git a/locales/ko-GS.yml b/locales/ko-GS.yml index 29bfe5394d..b1702114be 100644 --- a/locales/ko-GS.yml +++ b/locales/ko-GS.yml @@ -40,7 +40,7 @@ favorites: "질겨찾기" unfavorite: "질겨찾기서 á„‹á…¥á‡ì• 기" favorited: "ì§ˆê²¨ì°¾ê¸°ì— ë‹´ì•—ì‹ë‹ˆë‹¤." alreadyFavorited: "벌시로 ì§ˆê²¨ì°¾ê¸°ì— ë‹´ê¸° 잇ì‹ë‹ˆë‹¤." -cantFavorite: "ì§ˆê²¨ì°¾ê¸°ì— ëª¬ 담았ì‹ë‹ˆë‹¤." +cantFavorite: "ì§ˆê²¨ì°¾ê¸°ì— ëª¬ ë‹´ì•—ì‹ë‹ˆë‹¤." pin: "í”„ë¡œí•„ì— ë¶™ì´ê¸°" unpin: "프로필서 ë 기" copyContent: "ë‚´ìš© 복사하기" @@ -124,6 +124,7 @@ reactions: "반엉" reactionSettingDescription2: "꺼시서 ë‘ê³ , 누질ë¼ì„œ ë‰ìºê³ , ‘+’럴 누질ë¼ì„œ 옇ì‹ë‹ˆë‹¤." rememberNoteVisibility: "공개 범위럴 기억하기" attachCancel: "붙임 빼기" +deleteFile: "íŒŒì¼ ë‰ìºê¸°" markAsSensitive: "수ᇚ힘 ì„¤ì •" unmarkAsSensitive: "수ᇚ힘 무루기" enterFileName: "íŒŒì¼ ì´ëŸ¼ 서기" @@ -463,6 +464,8 @@ onlyOneFileCanBeAttached: "메시지엔 íŒŒì¼ í•˜ë‚˜ê¹Œì œë°–ì— ëª¬ ë„£ì‹ë‹ˆ invitations: "초대하기" invitationCode: "초대장" checking: "í•™ì¸í•˜ê³ 잇ì‹ë‹ˆë‹¤" +tooShort: "억수로 짜립니다" +tooLong: "억수로 집니다" passwordMatched: "맞ì‹ë‹ˆë‹¤" passwordNotMatched: "안 맞ì‹ë‹ˆë‹¤" signinFailed: "ë¡œê·¸ì¸ ëª¬ í–ˆì‹ë‹ˆë‹¤. ê³ ì´ë¦„ì´ëž‘ 비밀번호 ì œëŒ€ë¡œ ì¼ëŠ”ê°€ 확ì¸í•´ 주ì´ì†Œ." @@ -571,7 +574,11 @@ userSilenced: "ìš” ê²Œì •ì€... 수ᇚ혀 있ì‹ë‹ˆë‹¤." relays: "ë¦´ë ˆì´" addRelay: "ë¦´ë ˆì´ ì˜‡ê¸°" addedRelays: "ì˜‡ì€ ë¦´ë ˆì´" +deletedNote: "ë‰ìº” 걸" enableInfiniteScroll: "알아서 ë” ë³´ê¸°" +useCw: "ë‚´ìš© 수ᇚ후기" +description: "설멩" +describeFile: "캡션 옇기" author: "ë§¨ë˜ ì‚¬ëžŒ" manage: "간리" emailServer: "ì „ìžìš°íŽœ 서버" @@ -600,6 +607,7 @@ renotesCount: "리노트한 수" renotedCount: "ë¦¬ë…¸íŠ¸ë´ ìˆ˜" followingCount: "팔로우 수" followersCount: "팔로워 수" +noteFavoritesCount: "질겨찾기한 노트 수" clips: "í´ë¦½ 맨걸기" clearCache: "ìºì‹œ 비우기" unlikeConfirm: "좋네예럴 무룹니꺼?" @@ -608,6 +616,7 @@ user: "사용ìž" administration: "간리" on: "í‚´" off: "껌" +hide: "수ᇚ후기" clickToFinishEmailVerification: "[{ok}]럴 누질ë¼ì„œ ì „ìžìš°íŽœ ì •ë©©ì–¼ 껕내ì´ì†Œ." searchByGoogle: "찾기" tenMinutes: "ì‹ ë¶„" @@ -626,9 +635,11 @@ role: "ì˜‰í• " noRole: "ì˜‰í• ì´ ì—†ì‹ë‹ˆë‹¤" thisPostMayBeAnnoyingCancel: "ì•„ì´ì˜ˆ" likeOnly: "좋네예마" +myClips: "ë‚´ í´ë¦½" icon: "아바타" replies: "답하기" renotes: "리노트" +attach: "옇기" _initialAccountSetting: startTutorial: "길ë¼ìž¡ì´ 하기" _initialTutorial: @@ -641,9 +652,52 @@ _initialTutorial: title: "길ë¼ìž¡ì´ê°€ 껕낫ì‹ë‹ˆë‹¤!🎉" _achievements: _types: + _notes1: + description: "첫 노트럴 섯어예" + _notes10: + description: "노트럴 10번 섰어예" + _notes100: + description: "노트럴 100번 섰어예" + _notes500: + description: "노트럴 500번 섰어예" + _notes1000: + description: "노트럴 1,000번 섰어예" + _notes5000: + description: "노트럴 5,000번 섰어예" + _notes10000: + description: "노트럴 10,000번 섰어예" + _notes20000: + description: "노트럴 20,000번 섰어예" + _notes30000: + description: "노트럴 30,000번 섰어예" + _notes40000: + description: "노트럴 40,000번 섰어예" + _notes50000: + description: "노트럴 50,000번 섰어예" + _notes60000: + description: "노트럴 60,000번 섰어예" + _notes70000: + description: "노트럴 70,000번 섰어예" + _notes80000: + description: "노트럴 80,000번 섰어예" + _notes90000: + description: "노트럴 90,000번 섰어예" + _notes100000: + description: "노트럴 100,000번 섰어예" + _noteClipped1: + description: "첫 노트럴 í´ë¦½í–‡ì–´ì˜ˆ" + _noteFavorited1: + description: "첫 노트럴 ì§ˆê²¨ì°¾ê¸°ì— ë‹´ì•—ì–´ì˜ˆ" + _myNoteFavorited1: + description: "다런 ì‚¬ëžŒì´ ë‚´ 노트럴 ì§ˆê²¨ì°¾ê¸°ì— ë‹´ì•—ì‹ë‹ˆë‹¤" + _iLoveMisskey: + description: "“I ⤠#Misskeyâ€ëŸ´ 섰어예" + _postedAt0min0sec: + description: "0분 0ì´ˆì— ë…¸íŠ¸ë¥¼ 섰어예" _tutorialCompleted: description: "길ë¼ìž¡ì´ëŸ´ 껕냇ì‹ë‹ˆë‹¤" _gallery: + my: "ë‚´ 걸" liked: "좋네예한 걸" like: "좋네예!" unlike: "좋네예 무루기" @@ -654,7 +708,12 @@ _serverDisconnectedBehavior: reload: "알아서 새로곤침" _channel: removeBanner: "배너 ë‰ìºê¸°" + usersCount: "{n}명 참여" + notesCount: "노트 {n}ê°œ" +_menuDisplay: + hide: "수ᇚ후기" _theme: + description: "설멩" keys: mention: "멘션" _sfx: @@ -663,6 +722,9 @@ _sfx: _2fa: step3Title: "í•™ì¸ ê¸°í˜¸ëŸ´ 서기" renewTOTPCancel: "뎃어예" +_permissions: + "read:favorites": "질겨찾기 보기" + "write:favorites": "질겨찾기 곤치기" _widgets: profile: "프로필" instanceInfo: "서버 ì •ë³´" @@ -674,7 +736,10 @@ _widgets: _userList: chooseList: "리스트 개리기" _cw: + hide: "수ᇚ후기" show: "ë” ë³¼ëž˜ì˜ˆ" + chars: "ê±¸ìž {count}ê°œ" + files: "íŒŒì¼ {count}ê°œ" _visibility: home: "ëœë¨¸ë¦¬" followers: "팔로워" @@ -682,6 +747,7 @@ _profile: name: "ì´ëŸ¼" username: "ì‚¬ìš©ìž ì´ëŸ¼" _exportOrImport: + favoritedNotes: "질겨찾기한 노트" clips: "í´ë¦½ 맨걸기" followingList: "팔로잉" muteList: "수ᇚ후기" @@ -692,16 +758,20 @@ _charts: _timelines: home: "ëœë¨¸ë¦¬" _play: + my: "ë‚´ í”Œë ˆì´" script: "스í¬ë¦½íŠ¸" + summary: "설멩" _pages: like: "좋네예" unlike: "좋네예 무루기" + my: "ë‚´ 페ì´ì§€" blocks: image: "ì´ë¯¸ì§€" _note: id: "노트 ì•„ì´ë””" _notification: youWereFollowed: "새 팔로워가 잇ì‹ë‹ˆë‹¤" + newNote: "새 걸" _types: follow: "팔로잉" mention: "멘션" diff --git a/locales/ko-KR.yml b/locales/ko-KR.yml index 718d04caae..2a59ab9a23 100644 --- a/locales/ko-KR.yml +++ b/locales/ko-KR.yml @@ -279,7 +279,7 @@ uploadFromUrl: "URL 업로드" uploadFromUrlDescription: "ì—…ë¡œë“œí•˜ë ¤ëŠ” 파ì¼ì˜ URL" uploadFromUrlRequested: "업로드를 ìš”ì²í–ˆìŠµë‹ˆë‹¤" uploadFromUrlMayTakeTime: "업로드가 완료ë 때까지 ì‹œê°„ì´ ì†Œìš”ë 수 있습니다." -explore: "발견하기" +explore: "둘러보기" messageRead: "ì½ìŒ" noMoreHistory: "ì´ê²ƒë³´ë‹¤ ê³¼ê±°ì˜ ê¸°ë¡ì´ 없습니다" startMessaging: "대화 시작하기" @@ -1022,7 +1022,7 @@ internalServerError: "내부 서버 오류" internalServerErrorDescription: "내부 서버ì—ì„œ 예기치 ì•Šì€ ì˜¤ë¥˜ê°€ ë°œìƒí–ˆìŠµë‹ˆë‹¤." copyErrorInfo: "오류 ì •ë³´ 복사" joinThisServer: "ì´ ì„œë²„ì— ê°€ìž…" -exploreOtherServers: "다른 서버 둘러보기" +exploreOtherServers: "다른 서버 찾기" letsLookAtTimeline: "타임ë¼ì¸ 구경하기" disableFederationConfirm: "ì •ë§ë¡œ ì—°í•©ì„ ë„ì‹œê² ìŠµë‹ˆê¹Œ?" disableFederationConfirmWarn: "ì—°í•©ì„ ë„ë”ë¼ë„ ê²Œì‹œë¬¼ì´ ë¹„ê³µê°œë¡œ ì „í™˜ë˜ëŠ” ê²ƒì€ ì•„ë‹™ë‹ˆë‹¤. ëŒ€ë¶€ë¶„ì˜ ê²½ìš° ì—°í•©ì„ ë¹„í™œì„±í™”í• í•„ìš”ê°€ 없습니다." @@ -1797,7 +1797,7 @@ _instanceMute: title: "ì§€ì •í•œ ì„œë²„ì˜ ë…¸íŠ¸ë¥¼ 숨ê¹ë‹ˆë‹¤." heading: "ë®¤íŠ¸í• ì„œë²„" _theme: - explore: "테마 찾아보기" + explore: "테마 둘러보기" install: "테마 설치" manage: "테마 관리" code: "테마 코드" @@ -2022,7 +2022,7 @@ _permissions: "write:report-abuse": "위반 ë‚´ìš© ì‹ ê³ í•˜ê¸°" _auth: shareAccessTitle: "어플리케ì´ì…˜ì˜ ì ‘ê·¼ 허가" - shareAccess: "\"{name}\" ì´ ê³„ì •ì— ì ‘ê·¼í•˜ëŠ” ê²ƒì„ í—ˆìš©í•˜ì‹œê² ìŠµë‹ˆê¹Œ?" + shareAccess: "‘{name}’ì—ì„œ ê³„ì •ì— ì ‘ê·¼í•˜ëŠ” ê²ƒì„ í—ˆìš©í•˜ì‹œê² ìŠµë‹ˆê¹Œ?" shareAccessAsk: "ì´ ì• í”Œë¦¬ì¼€ì´ì…˜ì´ ê³„ì •ì— ì ‘ê·¼í•˜ëŠ” ê²ƒì„ í—ˆìš©í•˜ì‹œê² ìŠµë‹ˆê¹Œ?" permission: "{name}ì—ì„œ ë‹¤ìŒ ê¶Œí•œì„ ìš”ì²í•˜ì˜€ìŠµë‹ˆë‹¤" permissionAsk: "ì´ ì•±ì€ ë‹¤ìŒì˜ ê¶Œí•œì„ ìš”ì²í•©ë‹ˆë‹¤" diff --git a/package.json b/package.json index 7af66b8e37..171adc0da3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sharkey", - "version": "2024.2.0-beta.9", + "version": "2024.2.0-beta.10", "codename": "shonk", "repository": { "type": "git", diff --git a/packages/backend/src/core/EmailService.ts b/packages/backend/src/core/EmailService.ts index 8daee148eb..89722965c1 100644 --- a/packages/backend/src/core/EmailService.ts +++ b/packages/backend/src/core/EmailService.ts @@ -40,6 +40,8 @@ export class EmailService { public async sendEmail(to: string, subject: string, html: string, text: string) { const meta = await this.metaService.fetch(true); + if (!meta.enableEmail) return; + const iconUrl = `${this.config.url}/static-assets/mi-white.png`; const emailSettingUrl = `${this.config.url}/settings/email`; diff --git a/packages/backend/src/core/InstanceActorService.ts b/packages/backend/src/core/InstanceActorService.ts index b40fd46291..7ce8dc96a1 100644 --- a/packages/backend/src/core/InstanceActorService.ts +++ b/packages/backend/src/core/InstanceActorService.ts @@ -4,7 +4,7 @@ */ import { Inject, Injectable } from '@nestjs/common'; -import { IsNull } from 'typeorm'; +import { IsNull, Not } from 'typeorm'; import type { MiLocalUser } from '@/models/User.js'; import type { UsersRepository } from '@/models/_.js'; import { MemorySingleCache } from '@/misc/cache.js'; @@ -27,6 +27,14 @@ export class InstanceActorService { this.cache = new MemorySingleCache<MiLocalUser>(Infinity); } + @bindThis + public async realLocalUsersPresent(): Promise<boolean> { + return await this.usersRepository.existsBy({ + host: IsNull(), + username: Not(ACTOR_USERNAME), + }); + } + @bindThis public async getInstanceActor(): Promise<MiLocalUser> { const cached = this.cache.get(); diff --git a/packages/backend/src/core/SignupService.ts b/packages/backend/src/core/SignupService.ts index 32e3dee937..6b8c64488f 100644 --- a/packages/backend/src/core/SignupService.ts +++ b/packages/backend/src/core/SignupService.ts @@ -17,6 +17,7 @@ import { MiUserKeypair } from '@/models/UserKeypair.js'; import { MiUsedUsername } from '@/models/UsedUsername.js'; import generateUserToken from '@/misc/generate-native-user-token.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; +import { InstanceActorService } from '@/core/InstanceActorService.js'; import { bindThis } from '@/decorators.js'; import UsersChart from '@/core/chart/charts/users.js'; import { UtilityService } from '@/core/UtilityService.js'; @@ -38,6 +39,7 @@ export class SignupService { private userEntityService: UserEntityService, private idService: IdService, private metaService: MetaService, + private instanceActorService: InstanceActorService, private usersChart: UsersChart, ) { } @@ -84,7 +86,7 @@ export class SignupService { throw new Error('USED_USERNAME'); } - const isTheFirstUser = (await this.usersRepository.countBy({ host: IsNull() })) === 0; + const isTheFirstUser = !await this.instanceActorService.realLocalUsersPresent(); if (!opts.ignorePreservedUsernames && !isTheFirstUser) { const isPreserved = instance.preservedUsernames.map(x => x.toLowerCase()).includes(username.toLowerCase()); diff --git a/packages/backend/src/core/activitypub/ApRendererService.ts b/packages/backend/src/core/activitypub/ApRendererService.ts index 19899629c3..3f6ddd8027 100644 --- a/packages/backend/src/core/activitypub/ApRendererService.ts +++ b/packages/backend/src/core/activitypub/ApRendererService.ts @@ -796,6 +796,7 @@ export class ApRendererService { 'https://www.w3.org/ns/activitystreams', 'https://w3id.org/security/v1', { + Key: 'sec:Key', // as non-standards manuallyApprovesFollowers: 'as:manuallyApprovesFollowers', sensitive: 'as:sensitive', diff --git a/packages/backend/src/core/activitypub/models/ApPersonService.ts b/packages/backend/src/core/activitypub/models/ApPersonService.ts index 8507c6f949..a4d497a7ff 100644 --- a/packages/backend/src/core/activitypub/models/ApPersonService.ts +++ b/packages/backend/src/core/activitypub/models/ApPersonService.ts @@ -225,23 +225,42 @@ export class ApPersonService implements OnModuleInit { return null; } - private async resolveAvatarAndBanner(user: MiRemoteUser, icon: any, image: any, bgimg: any): Promise<Pick<MiRemoteUser, 'avatarId' | 'bannerId' | 'backgroundId' | 'avatarUrl' | 'bannerUrl' | 'backgroundUrl' | 'avatarBlurhash' | 'bannerBlurhash' | 'backgroundBlurhash'>> { + private async resolveAvatarAndBanner(user: MiRemoteUser, icon: any, image: any, bgimg: any): Promise<Partial<Pick<MiRemoteUser, 'avatarId' | 'bannerId' | 'backgroundId' | 'avatarUrl' | 'bannerUrl' | 'backgroundUrl' | 'avatarBlurhash' | 'bannerBlurhash' | 'backgroundBlurhash'>>> { + if (user == null) throw new Error('failed to create user: user is null'); + const [avatar, banner, background] = await Promise.all([icon, image, bgimg].map(img => { - if (img == null) return null; - if (user == null) throw new Error('failed to create user: user is null'); + // if we have an explicitly missing image, return an + // explicitly-null set of values + if ((img == null) || (typeof img === 'object' && img.url == null)) { + return { id: null, url: null, blurhash: null }; + } + return this.apImageService.resolveImage(user, img).catch(() => null); })); + /* + we don't want to return nulls on errors! if the database fields + are already null, nothing changes; if the database has old + values, we should keep those. The exception is if the remote has + actually removed the images: in that case, the block above + returns the special {id:null}&c value, and we return those + */ return { - avatarId: avatar?.id ?? null, - bannerId: banner?.id ?? null, - backgroundId: background?.id ?? null, - avatarUrl: avatar ? this.driveFileEntityService.getPublicUrl(avatar, 'avatar') : null, - bannerUrl: banner ? this.driveFileEntityService.getPublicUrl(banner) : null, - backgroundUrl: background ? this.driveFileEntityService.getPublicUrl(background) : null, - avatarBlurhash: avatar?.blurhash ?? null, - bannerBlurhash: banner?.blurhash ?? null, - backgroundBlurhash: background?.blurhash ?? null + ...( avatar ? { + avatarId: avatar.id, + avatarUrl: avatar.url ? this.driveFileEntityService.getPublicUrl(avatar, 'avatar') : null, + avatarBlurhash: avatar.blurhash, + } : {}), + ...( banner ? { + bannerId: banner.id, + bannerUrl: banner.url ? this.driveFileEntityService.getPublicUrl(banner) : null, + bannerBlurhash: banner.blurhash, + } : {}), + ...( background ? { + backgroundId: background.id, + backgroundUrl: background.url ? this.driveFileEntityService.getPublicUrl(background) : null, + backgroundBlurhash: background.blurhash, + } : {}), }; } diff --git a/packages/backend/src/core/entities/EmojiEntityService.ts b/packages/backend/src/core/entities/EmojiEntityService.ts index 5b97cfad5e..655c4c5ada 100644 --- a/packages/backend/src/core/entities/EmojiEntityService.ts +++ b/packages/backend/src/core/entities/EmojiEntityService.ts @@ -31,6 +31,7 @@ export class EmojiEntityService { category: emoji.category, // || emoji.originalUrl ã—ã¦ã‚‹ã®ã¯å¾Œæ–¹äº’æ›æ€§ã®ãŸã‚(publicUrlã¯stringãªã®ã§??ã¯ã ã‚) url: emoji.publicUrl || emoji.originalUrl, + localOnly: emoji.localOnly ? true : undefined, isSensitive: emoji.isSensitive ? true : undefined, roleIdsThatCanBeUsedThisEmojiAsReaction: emoji.roleIdsThatCanBeUsedThisEmojiAsReaction.length > 0 ? emoji.roleIdsThatCanBeUsedThisEmojiAsReaction : undefined, }; diff --git a/packages/backend/src/models/json-schema/emoji.ts b/packages/backend/src/models/json-schema/emoji.ts index 99a58f8773..954eb98d57 100644 --- a/packages/backend/src/models/json-schema/emoji.ts +++ b/packages/backend/src/models/json-schema/emoji.ts @@ -27,6 +27,10 @@ export const packedEmojiSimpleSchema = { type: 'string', optional: false, nullable: false, }, + localOnly: { + type: 'boolean', + optional: true, nullable: false, + }, isSensitive: { type: 'boolean', optional: true, nullable: false, diff --git a/packages/backend/src/server/api/endpoints/admin/accounts/create.ts b/packages/backend/src/server/api/endpoints/admin/accounts/create.ts index b18a7e0e41..14fd69a1a2 100644 --- a/packages/backend/src/server/api/endpoints/admin/accounts/create.ts +++ b/packages/backend/src/server/api/endpoints/admin/accounts/create.ts @@ -9,6 +9,7 @@ import { Endpoint } from '@/server/api/endpoint-base.js'; import type { UsersRepository } from '@/models/_.js'; import { SignupService } from '@/core/SignupService.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; +import { InstanceActorService } from '@/core/InstanceActorService.js'; import { localUsernameSchema, passwordSchema } from '@/models/User.js'; import { DI } from '@/di-symbols.js'; import { Packed } from '@/misc/json-schema.js'; @@ -46,13 +47,12 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- private userEntityService: UserEntityService, private signupService: SignupService, + private instanceActorService: InstanceActorService, ) { super(meta, paramDef, async (ps, _me, token) => { const me = _me ? await this.usersRepository.findOneByOrFail({ id: _me.id }) : null; - const noUsers = (await this.usersRepository.countBy({ - host: IsNull(), - })) === 0; - if ((!noUsers && !me?.isRoot) || token !== null) throw new Error('access denied'); + const realUsers = await this.instanceActorService.realLocalUsersPresent(); + if ((realUsers && !me?.isRoot) || token !== null) throw new Error('access denied'); const { account, secret } = await this.signupService.signup({ username: ps.username, diff --git a/packages/backend/src/server/api/endpoints/meta.ts b/packages/backend/src/server/api/endpoints/meta.ts index cb52bf6b51..6d553e5d79 100644 --- a/packages/backend/src/server/api/endpoints/meta.ts +++ b/packages/backend/src/server/api/endpoints/meta.ts @@ -6,10 +6,11 @@ import { IsNull, LessThanOrEqual, MoreThan, Brackets } from 'typeorm'; import { Inject, Injectable } from '@nestjs/common'; import JSON5 from 'json5'; -import type { AdsRepository, UsersRepository } from '@/models/_.js'; +import type { AdsRepository } from '@/models/_.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { MetaService } from '@/core/MetaService.js'; +import { InstanceActorService } from '@/core/InstanceActorService.js'; import type { Config } from '@/config.js'; import { DI } from '@/di-symbols.js'; import { DEFAULT_POLICIES } from '@/core/RoleService.js'; @@ -337,14 +338,12 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- @Inject(DI.config) private config: Config, - @Inject(DI.usersRepository) - private usersRepository: UsersRepository, - @Inject(DI.adsRepository) private adsRepository: AdsRepository, private userEntityService: UserEntityService, private metaService: MetaService, + private instanceActorService: InstanceActorService, ) { super(meta, paramDef, async (ps, me) => { const instance = await this.metaService.fetch(true); @@ -427,9 +426,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- ...(ps.detail ? { cacheRemoteFiles: instance.cacheRemoteFiles, cacheRemoteSensitiveFiles: instance.cacheRemoteSensitiveFiles, - requireSetup: (await this.usersRepository.countBy({ - host: IsNull(), - })) === 0, + requireSetup: !await this.instanceActorService.realLocalUsersPresent(), } : {}), }; diff --git a/packages/frontend/src/components/MkCode.core.vue b/packages/frontend/src/components/MkCode.core.vue index b06bb70e99..0da256866e 100644 --- a/packages/frontend/src/components/MkCode.core.vue +++ b/packages/frontend/src/components/MkCode.core.vue @@ -5,14 +5,15 @@ SPDX-License-Identifier: AGPL-3.0-only <!-- eslint-disable vue/no-v-html --> <template> -<div :class="[$style.codeBlockRoot, { [$style.codeEditor]: codeEditor }]" v-html="html"></div> +<div :class="[$style.codeBlockRoot, { [$style.codeEditor]: codeEditor }, (darkMode ? $style.dark : $style.light)]" v-html="html"></div> </template> <script lang="ts" setup> import { ref, computed, watch } from 'vue'; import { bundledLanguagesInfo } from 'shiki'; import type { BuiltinLanguage } from 'shiki'; -import { getHighlighter } from '@/scripts/code-highlighter.js'; +import { getHighlighter, getTheme } from '@/scripts/code-highlighter.js'; +import { defaultStore } from '@/store.js'; const props = defineProps<{ code: string; @@ -21,11 +22,23 @@ const props = defineProps<{ }>(); const highlighter = await getHighlighter(); - +const darkMode = defaultStore.reactiveState.darkMode; const codeLang = ref<BuiltinLanguage | 'aiscript'>('js'); + +const [lightThemeName, darkThemeName] = await Promise.all([ + getTheme('light', true), + getTheme('dark', true), +]); + const html = computed(() => highlighter.codeToHtml(props.code, { lang: codeLang.value, - theme: 'dark-plus', + themes: { + fallback: 'dark-plus', + light: lightThemeName, + dark: darkThemeName, + }, + defaultColor: false, + cssVariablePrefix: '--shiki-', })); async function fetchLanguage(to: string): Promise<void> { @@ -79,6 +92,15 @@ watch(() => props.lang, (to) => { margin: .5em 0; overflow: auto; border-radius: var(--radius-sm); + border: 1px solid var(--divider); + + color: var(--shiki-fallback); + background-color: var(--shiki-fallback-bg); + + & span { + color: var(--shiki-fallback); + background-color: var(--shiki-fallback-bg); + } & pre, & code { @@ -86,6 +108,26 @@ watch(() => props.lang, (to) => { } } +.light.codeBlockRoot :global(.shiki) { + color: var(--shiki-light); + background-color: var(--shiki-light-bg); + + & span { + color: var(--shiki-light); + background-color: var(--shiki-light-bg); + } +} + +.dark.codeBlockRoot :global(.shiki) { + color: var(--shiki-dark); + background-color: var(--shiki-dark-bg); + + & span { + color: var(--shiki-dark); + background-color: var(--shiki-dark-bg); + } +} + .codeBlockRoot.codeEditor { min-width: 100%; height: 100%; @@ -94,6 +136,7 @@ watch(() => props.lang, (to) => { padding: 12px; margin: 0; border-radius: var(--radius-sm); + border: none; min-height: 130px; pointer-events: none; min-width: calc(100% - 24px); @@ -105,6 +148,11 @@ watch(() => props.lang, (to) => { text-rendering: inherit; text-transform: inherit; white-space: pre; + + & span { + display: inline-block; + min-height: 1em; + } } } </style> diff --git a/packages/frontend/src/components/MkCode.vue b/packages/frontend/src/components/MkCode.vue index 05b5fe8da1..b34eb8aaf6 100644 --- a/packages/frontend/src/components/MkCode.vue +++ b/packages/frontend/src/components/MkCode.vue @@ -53,7 +53,6 @@ function copy() { } .codeBlockCopyButton { - color: #D4D4D4; position: absolute; top: 8px; right: 8px; @@ -67,8 +66,7 @@ function copy() { .codeBlockFallbackRoot { display: block; overflow-wrap: anywhere; - color: #D4D4D4; - background: #1E1E1E; + background: var(--bg); padding: 1em; margin: .5em 0; overflow: auto; @@ -93,8 +91,8 @@ function copy() { border-radius: var(--radius-sm); padding: 24px; margin-top: 4px; - color: #D4D4D4; - background: #1E1E1E; + color: var(--fg); + background: var(--bg); } .codePlaceholderContainer { diff --git a/packages/frontend/src/components/MkCodeEditor.vue b/packages/frontend/src/components/MkCodeEditor.vue index 7334fc4d0e..5ff6c801a5 100644 --- a/packages/frontend/src/components/MkCodeEditor.vue +++ b/packages/frontend/src/components/MkCodeEditor.vue @@ -196,10 +196,11 @@ watch(v, newValue => { resize: none; text-align: left; color: transparent; - caret-color: rgb(225, 228, 232); + caret-color: var(--fg); background-color: transparent; border: 0; border-radius: var(--radius-sm); + box-sizing: border-box; outline: 0; min-width: calc(100% - 24px); height: 100%; @@ -212,6 +213,6 @@ watch(v, newValue => { } .textarea::selection { - color: #fff; + color: var(--bg); } </style> diff --git a/packages/frontend/src/components/MkCodeInline.vue b/packages/frontend/src/components/MkCodeInline.vue index 5340c1fd5f..6a9d97ab5a 100644 --- a/packages/frontend/src/components/MkCodeInline.vue +++ b/packages/frontend/src/components/MkCodeInline.vue @@ -18,8 +18,7 @@ const props = defineProps<{ display: inline-block; font-family: Consolas, Monaco, Andale Mono, Ubuntu Mono, monospace; overflow-wrap: anywhere; - color: #D4D4D4; - background: #1E1E1E; + background: var(--bg); padding: .1em; border-radius: .3em; } diff --git a/packages/frontend/src/components/MkCropperDialog.vue b/packages/frontend/src/components/MkCropperDialog.vue index 0a1ddd3171..745453646c 100644 --- a/packages/frontend/src/components/MkCropperDialog.vue +++ b/packages/frontend/src/components/MkCropperDialog.vue @@ -63,18 +63,25 @@ const loading = ref(true); const ok = async () => { const promise = new Promise<Misskey.entities.DriveFile>(async (res) => { - const croppedCanvas = await cropper?.getCropperSelection()?.$toCanvas(); + const croppedImage = await cropper?.getCropperImage(); + const croppedSection = await cropper?.getCropperSelection(); + + // 拡大率を計算ã—ã€(ã»ã¼)å…ƒã®å¤§ãã•ã«æˆ»ã™ + const zoomedRate = croppedImage.getBoundingClientRect().width / croppedImage.clientWidth; + const widthToRender = croppedSection.getBoundingClientRect().width / zoomedRate; + + const croppedCanvas = await croppedSection?.$toCanvas({ width: widthToRender }); croppedCanvas?.toBlob(blob => { if (!blob) return; const formData = new FormData(); formData.append('file', blob); formData.append('name', `cropped_${props.file.name}`); formData.append('isSensitive', props.file.isSensitive ? 'true' : 'false'); - formData.append('comment', props.file.comment ?? 'null'); + if (props.file.comment) { formData.append('comment', props.file.comment);} formData.append('i', $i!.token); - if (props.uploadFolder || props.uploadFolder === null) { - formData.append('folderId', props.uploadFolder ?? 'null'); - } else if (defaultStore.state.uploadFolder) { + if (props.uploadFolder) { + formData.append('folderId', props.uploadFolder); + } else if (props.uploadFolder !== null && defaultStore.state.uploadFolder) { formData.append('folderId', defaultStore.state.uploadFolder); } diff --git a/packages/frontend/src/components/MkEmojiPicker.vue b/packages/frontend/src/components/MkEmojiPicker.vue index 1db03a5eb9..a4c5e07cd9 100644 --- a/packages/frontend/src/components/MkEmojiPicker.vue +++ b/packages/frontend/src/components/MkEmojiPicker.vue @@ -118,6 +118,7 @@ import { i18n } from '@/i18n.js'; import { defaultStore } from '@/store.js'; import { customEmojiCategories, customEmojis, customEmojisMap } from '@/custom-emojis.js'; import { $i } from '@/account.js'; +import { checkReactionPermissions } from '@/scripts/check-reaction-permissions.js'; const props = withDefaults(defineProps<{ showPinned?: boolean; @@ -126,6 +127,7 @@ const props = withDefaults(defineProps<{ asDrawer?: boolean; asWindow?: boolean; asReactionPicker?: boolean; // 今ã¯ä½¿ã‚ã‚Œã¦ãªã„ãŒå°†æ¥çš„ã«ä½¿ã„ãㆠ+ targetNote?: Misskey.entities.Note; }>(), { showPinned: true, }); @@ -340,7 +342,7 @@ watch(q, () => { }); function filterAvailable(emoji: Misskey.entities.EmojiSimple): boolean { - return ((emoji.roleIdsThatCanBeUsedThisEmojiAsReaction == null || emoji.roleIdsThatCanBeUsedThisEmojiAsReaction.length === 0) || ($i && $i.roles.some(r => emoji.roleIdsThatCanBeUsedThisEmojiAsReaction?.includes(r.id)))) ?? false; + return !props.targetNote || checkReactionPermissions($i!, props.targetNote, emoji); } function focus() { diff --git a/packages/frontend/src/components/MkEmojiPickerDialog.vue b/packages/frontend/src/components/MkEmojiPickerDialog.vue index 4068a79f08..1c0f9a5a33 100644 --- a/packages/frontend/src/components/MkEmojiPickerDialog.vue +++ b/packages/frontend/src/components/MkEmojiPickerDialog.vue @@ -24,6 +24,7 @@ SPDX-License-Identifier: AGPL-3.0-only :showPinned="showPinned" :pinnedEmojis="pinnedEmojis" :asReactionPicker="asReactionPicker" + :targetNote="targetNote" :asDrawer="type === 'drawer'" :max-height="maxHeight" @chosen="chosen" @@ -32,6 +33,7 @@ SPDX-License-Identifier: AGPL-3.0-only </template> <script lang="ts" setup> +import * as Misskey from 'misskey-js'; import { shallowRef } from 'vue'; import MkModal from '@/components/MkModal.vue'; import MkEmojiPicker from '@/components/MkEmojiPicker.vue'; @@ -43,6 +45,7 @@ const props = withDefaults(defineProps<{ showPinned?: boolean; pinnedEmojis?: string[], asReactionPicker?: boolean; + targetNote?: Misskey.entities.Note; choseAndClose?: boolean; }>(), { manualShowing: null, diff --git a/packages/frontend/src/components/MkEmojiPickerWindow.vue b/packages/frontend/src/components/MkEmojiPickerWindow.vue index 1a2c55e785..2a6828f242 100644 --- a/packages/frontend/src/components/MkEmojiPickerWindow.vue +++ b/packages/frontend/src/components/MkEmojiPickerWindow.vue @@ -13,12 +13,13 @@ SPDX-License-Identifier: AGPL-3.0-only :front="true" @closed="emit('closed')" > - <MkEmojiPicker :showPinned="showPinned" :asReactionPicker="asReactionPicker" asWindow :class="$style.picker" @chosen="chosen"/> + <MkEmojiPicker :showPinned="showPinned" :asReactionPicker="asReactionPicker" :targetNote="targetNote" asWindow :class="$style.picker" @chosen="chosen"/> </MkWindow> </template> <script lang="ts" setup> import { } from 'vue'; +import * as Misskey from 'misskey-js'; import MkWindow from '@/components/MkWindow.vue'; import MkEmojiPicker from '@/components/MkEmojiPicker.vue'; @@ -26,6 +27,7 @@ withDefaults(defineProps<{ src?: HTMLElement; showPinned?: boolean; asReactionPicker?: boolean; + targetNote?: Misskey.entities.Note }>(), { showPinned: true, }); diff --git a/packages/frontend/src/components/MkLaunchPad.vue b/packages/frontend/src/components/MkLaunchPad.vue index 79b2b91154..02bf987bde 100644 --- a/packages/frontend/src/components/MkLaunchPad.vue +++ b/packages/frontend/src/components/MkLaunchPad.vue @@ -119,6 +119,7 @@ function close() { margin-top: 12px; font-size: 0.8em; line-height: 1.5em; + text-align: center; } > .indicatorWithValue { diff --git a/packages/frontend/src/components/MkNote.vue b/packages/frontend/src/components/MkNote.vue index 0abad81d97..ff9bf3c395 100644 --- a/packages/frontend/src/components/MkNote.vue +++ b/packages/frontend/src/components/MkNote.vue @@ -285,13 +285,11 @@ const quoteButton = shallowRef<HTMLElement>(); const clipButton = shallowRef<HTMLElement>(); const likeButton = shallowRef<HTMLElement>(); const appearNote = computed(() => isRenote ? note.value.renote as Misskey.entities.Note : note.value); -const renoteUrl = appearNote.value.renote ? appearNote.value.renote.url : null; -const renoteUri = appearNote.value.renote ? appearNote.value.renote.uri : null; const isMyRenote = $i && ($i.id === note.value.userId); const showContent = ref(defaultStore.state.uncollapseCW); const parsed = computed(() => appearNote.value.text ? mfm.parse(appearNote.value.text) : null); -const urls = computed(() => parsed.value ? extractUrlFromMfm(parsed.value).filter(u => u !== renoteUrl && u !== renoteUri) : null); +const urls = computed(() => parsed.value ? extractUrlFromMfm(parsed.value).filter((url) => appearNote.value.renote?.url !== url && appearNote.value.renote?.uri !== url) : null); const isLong = shouldCollapsed(appearNote.value, urls.value ?? []); const collapsed = ref(defaultStore.state.expandLongNote && appearNote.value.cw == null && isLong ? false : appearNote.value.cw == null && isLong); const isDeleted = ref(false); @@ -624,7 +622,7 @@ function react(viaKeyboard = false): void { } } else { blur(); - reactionPicker.show(reactButton.value ?? null, reaction => { + reactionPicker.show(reactButton.value ?? null, note.value, reaction => { sound.playMisskeySfx('reaction'); if (props.mock) { diff --git a/packages/frontend/src/components/MkNoteDetailed.vue b/packages/frontend/src/components/MkNoteDetailed.vue index d31f77bbc2..a2e3a747d9 100644 --- a/packages/frontend/src/components/MkNoteDetailed.vue +++ b/packages/frontend/src/components/MkNoteDetailed.vue @@ -303,8 +303,6 @@ const quoteButton = shallowRef<HTMLElement>(); const clipButton = shallowRef<HTMLElement>(); const likeButton = shallowRef<HTMLElement>(); const appearNote = computed(() => isRenote ? note.value.renote as Misskey.entities.Note : note.value); -const renoteUrl = appearNote.value.renote ? appearNote.value.renote.url : null; -const renoteUri = appearNote.value.renote ? appearNote.value.renote.uri : null; const isMyRenote = $i && ($i.id === note.value.userId); const showContent = ref(defaultStore.state.uncollapseCW); const isDeleted = ref(false); @@ -313,7 +311,7 @@ const muted = ref($i ? checkWordMute(appearNote.value, $i, $i.mutedWords) : fals const translation = ref<Misskey.entities.NotesTranslateResponse | null>(null); const translating = ref(false); const parsed = appearNote.value.text ? mfm.parse(appearNote.value.text) : null; -const urls = parsed ? extractUrlFromMfm(parsed).filter(u => u !== renoteUrl && u !== renoteUri) : null; +const urls = parsed ? extractUrlFromMfm(parsed).filter((url) => appearNote.value.renote?.url !== url && appearNote.value.renote?.uri !== url) : null; const animated = computed(() => parsed ? checkAnimationFromMfm(parsed) : null); const allowAnim = ref(defaultStore.state.advancedMfm && defaultStore.state.animatedMfm ? true : false); const showTicker = (defaultStore.state.instanceTicker === 'always') || (defaultStore.state.instanceTicker === 'remote' && appearNote.value.user.instance); @@ -612,7 +610,7 @@ function react(viaKeyboard = false): void { } } else { blur(); - reactionPicker.show(reactButton.value ?? null, reaction => { + reactionPicker.show(reactButton.value ?? null, note.value, reaction => { sound.playMisskeySfx('reaction'); misskeyApi('notes/reactions/create', { diff --git a/packages/frontend/src/components/MkPageWindow.vue b/packages/frontend/src/components/MkPageWindow.vue index cb2db0b6a5..ee0963a9b5 100644 --- a/packages/frontend/src/components/MkPageWindow.vue +++ b/packages/frontend/src/components/MkPageWindow.vue @@ -76,7 +76,7 @@ const buttonsLeft = computed(() => { }); const buttonsRight = computed(() => { const buttons = [{ - icon: 'ph-arrow-clockwise ph-bold ph-lg', + icon: 'ph-arrows-clockwise ph-bold ph-lg', title: i18n.ts.reload, onClick: reload, }, { diff --git a/packages/frontend/src/components/MkReactionsViewer.reaction.vue b/packages/frontend/src/components/MkReactionsViewer.reaction.vue index e43841e5c9..356020a0de 100644 --- a/packages/frontend/src/components/MkReactionsViewer.reaction.vue +++ b/packages/frontend/src/components/MkReactionsViewer.reaction.vue @@ -32,6 +32,8 @@ import { claimAchievement } from '@/scripts/achievements.js'; import { defaultStore } from '@/store.js'; import { i18n } from '@/i18n.js'; import * as sound from '@/scripts/sound.js'; +import { checkReactionPermissions } from '@/scripts/check-reaction-permissions.js'; +import { customEmojis } from '@/custom-emojis.js'; const props = defineProps<{ reaction: string; @@ -48,13 +50,19 @@ const emit = defineEmits<{ const buttonEl = shallowRef<HTMLElement>(); -const canToggle = computed(() => !props.reaction.match(/@\w/) && $i); +const isCustomEmoji = computed(() => props.reaction.includes(':')); +const emoji = computed(() => isCustomEmoji.value ? customEmojis.value.find(emoji => emoji.name === props.reaction.replace(/:/g, '').replace(/@\./, '')) : null); + +const canToggle = computed(() => { + return !props.reaction.match(/@\w/) && $i + && (emoji.value && checkReactionPermissions($i, props.note, emoji.value)) + || !isCustomEmoji.value; +}); +const canGetInfo = computed(() => !props.reaction.match(/@\w/) && props.reaction.includes(':')); async function toggleReaction() { if (!canToggle.value) return; - // TODO: ãã®çµµæ–‡å—を使ã†æ¨©é™ãŒã‚ã‚‹ã‹ã©ã†ã‹ç¢ºèª - const oldReaction = props.note.myReaction; if (oldReaction) { const confirm = await os.confirm({ @@ -101,8 +109,8 @@ async function toggleReaction() { } async function menu(ev) { - if (!canToggle.value) return; - if (!props.reaction.includes(':')) return; + if (!canGetInfo.value) return; + os.popupMenu([{ text: i18n.ts.info, icon: 'ph-info ph-bold ph-lg', diff --git a/packages/frontend/src/components/MkSelect.vue b/packages/frontend/src/components/MkSelect.vue index 6ac8297c02..1ed6c0d822 100644 --- a/packages/frontend/src/components/MkSelect.vue +++ b/packages/frontend/src/components/MkSelect.vue @@ -27,7 +27,7 @@ SPDX-License-Identifier: AGPL-3.0-only </div> <div :class="$style.caption"><slot name="caption"></slot></div> - <MkButton v-if="manualSave && changed" primary @click="updated"><i class="ph-floppy-disk ph-bold ph-lg"></i> {{ i18n.ts.save }}</MkButton> + <MkButton v-if="manualSave && changed" primary :class="$style.save" @click="updated"><i class="ph-floppy-disk ph-bold ph-lg"></i> {{ i18n.ts.save }}</MkButton> </div> </template> @@ -138,6 +138,7 @@ function show() { active: computed(() => v.value === option.props?.value), action: () => { v.value = option.props?.value; + changed.value = true; emit('changeByUser', v.value); }, }); @@ -288,6 +289,10 @@ function show() { padding-left: 6px; } +.save { + margin: 8px 0 0 0; +} + .chevron { transition: transform 0.1s ease-out; } diff --git a/packages/frontend/src/components/SkNote.vue b/packages/frontend/src/components/SkNote.vue index 84bcd3886d..61d32d721e 100644 --- a/packages/frontend/src/components/SkNote.vue +++ b/packages/frontend/src/components/SkNote.vue @@ -286,13 +286,11 @@ const quoteButton = shallowRef<HTMLElement>(); const clipButton = shallowRef<HTMLElement>(); const likeButton = shallowRef<HTMLElement>(); const appearNote = computed(() => isRenote ? note.value.renote as Misskey.entities.Note : note.value); -const renoteUrl = appearNote.value.renote ? appearNote.value.renote.url : null; -const renoteUri = appearNote.value.renote ? appearNote.value.renote.uri : null; const isMyRenote = $i && ($i.id === note.value.userId); const showContent = ref(defaultStore.state.uncollapseCW); const parsed = computed(() => appearNote.value.text ? mfm.parse(appearNote.value.text) : null); -const urls = computed(() => parsed.value ? extractUrlFromMfm(parsed.value).filter(u => u !== renoteUrl && u !== renoteUri) : null); +const urls = computed(() => parsed.value ? extractUrlFromMfm(parsed.value).filter((url) => appearNote.value.renote?.url !== url && appearNote.value.renote?.uri !== url) : null); const isLong = shouldCollapsed(appearNote.value, urls.value ?? []); const collapsed = ref(defaultStore.state.expandLongNote && appearNote.value.cw == null && isLong ? false : appearNote.value.cw == null && isLong); const isDeleted = ref(false); diff --git a/packages/frontend/src/components/SkNoteDetailed.vue b/packages/frontend/src/components/SkNoteDetailed.vue index ca3ea09b2a..c1c20e5b29 100644 --- a/packages/frontend/src/components/SkNoteDetailed.vue +++ b/packages/frontend/src/components/SkNoteDetailed.vue @@ -312,8 +312,6 @@ const quoteButton = shallowRef<HTMLElement>(); const clipButton = shallowRef<HTMLElement>(); const likeButton = shallowRef<HTMLElement>(); const appearNote = computed(() => isRenote ? note.value.renote as Misskey.entities.Note : note.value); -const renoteUrl = appearNote.value.renote ? appearNote.value.renote.url : null; -const renoteUri = appearNote.value.renote ? appearNote.value.renote.uri : null; const isMyRenote = $i && ($i.id === note.value.userId); const showContent = ref(defaultStore.state.uncollapseCW); const isDeleted = ref(false); @@ -322,7 +320,7 @@ const muted = ref($i ? checkWordMute(appearNote.value, $i, $i.mutedWords) : fals const translation = ref<Misskey.entities.NotesTranslateResponse | null>(null); const translating = ref(false); const parsed = appearNote.value.text ? mfm.parse(appearNote.value.text) : null; -const urls = parsed ? extractUrlFromMfm(parsed).filter(u => u !== renoteUrl && u !== renoteUri) : null; +const urls = parsed ? extractUrlFromMfm(parsed).filter((url) => appearNote.value.renote?.url !== url && appearNote.value.renote?.uri !== url) : null; const animated = computed(() => parsed ? checkAnimationFromMfm(parsed) : null); const allowAnim = ref(defaultStore.state.advancedMfm && defaultStore.state.animatedMfm ? true : false); const showTicker = (defaultStore.state.instanceTicker === 'always') || (defaultStore.state.instanceTicker === 'remote' && appearNote.value.user.instance); diff --git a/packages/frontend/src/components/global/RouterView.vue b/packages/frontend/src/components/global/RouterView.vue index dc7474835d..aeb87e659b 100644 --- a/packages/frontend/src/components/global/RouterView.vue +++ b/packages/frontend/src/components/global/RouterView.vue @@ -4,7 +4,10 @@ SPDX-License-Identifier: AGPL-3.0-only --> <template> -<KeepAlive :max="defaultStore.state.numberOfPageCache"> +<KeepAlive + :max="defaultStore.state.numberOfPageCache" + :exclude="pageCacheController" +> <Suspense :timeout="0"> <component :is="currentPageComponent" :key="key" v-bind="Object.fromEntries(currentPageProps)"/> @@ -16,9 +19,11 @@ SPDX-License-Identifier: AGPL-3.0-only </template> <script lang="ts" setup> -import { inject, onBeforeUnmount, provide, ref, shallowRef } from 'vue'; -import { IRouter, Resolved } from '@/nirax.js'; +import { inject, onBeforeUnmount, provide, ref, shallowRef, computed, nextTick } from 'vue'; +import { IRouter, Resolved, RouteDef } from '@/nirax.js'; import { defaultStore } from '@/store.js'; +import { globalEvents } from '@/events.js'; +import MkLoadingPage from '@/pages/_loading_.vue'; const props = defineProps<{ router?: IRouter; @@ -46,20 +51,47 @@ function resolveNested(current: Resolved, d = 0): Resolved | null { } const current = resolveNested(router.current)!; -const currentPageComponent = shallowRef(current.route.component); +const currentPageComponent = shallowRef('component' in current.route ? current.route.component : MkLoadingPage); const currentPageProps = ref(current.props); const key = ref(current.route.path + JSON.stringify(Object.fromEntries(current.props))); function onChange({ resolved, key: newKey }) { const current = resolveNested(resolved); - if (current == null) return; + if (current == null || 'redirect' in current.route) return; currentPageComponent.value = current.route.component; currentPageProps.value = current.props; key.value = current.route.path + JSON.stringify(Object.fromEntries(current.props)); + + nextTick(() => { + // ページé·ç§»å®Œäº†å¾Œã«å†ã³ã‚ャッシュを有効化 + if (clearCacheRequested.value) { + clearCacheRequested.value = false; + } + }); } router.addListener('change', onChange); +// #region ã‚ャッシュ制御 + +/** + * ã‚ャッシュクリアãŒæœ‰åŠ¹ã«ãªã£ãŸã‚‰ã€å…¨ã‚ャッシュをクリアã™ã‚‹ + * + * keepAliveå´ã«watcherãŒã‚ã‚‹ã®ã§ã™ã消ãˆã‚‹ã¨ã¯ãŠã‚‚ã†ã‘ã©ã€å¿µã®ãŸã‚ページé·ç§»å®Œäº†ã¾ã§ã¯ã‚ャッシュを無効化ã—ã¦ãŠã。 + * ã‚ャッシュ有効時å‘ã‘ã«excludeを使ã„ãŸã„å ´åˆã¯ã€pageCacheControllerã«ä¸¦åˆ—ã«çªã£è¾¼ã‚€ã®ã§ã¯ãªãã€ä¸‹ã«è¿½è¨˜ã™ã‚‹ã“㨠+ */ +const pageCacheController = computed(() => clearCacheRequested.value ? /.*/ : undefined); +const clearCacheRequested = ref(false); + +globalEvents.on('requestClearPageCache', () => { + if (_DEV_) console.log('clear page cache requested'); + if (!clearCacheRequested.value) { + clearCacheRequested.value = true; + } +}); + +// #endregion + onBeforeUnmount(() => { router.removeListener('change', onChange); }); diff --git a/packages/frontend/src/events.ts b/packages/frontend/src/events.ts index 90d5f6eede..46faec8d3e 100644 --- a/packages/frontend/src/events.ts +++ b/packages/frontend/src/events.ts @@ -4,6 +4,10 @@ */ import { EventEmitter } from 'eventemitter3'; +import * as Misskey from 'misskey-js'; -// TODO: 型付㑠-export const globalEvents = new EventEmitter(); +export const globalEvents = new EventEmitter<{ + themeChanged: () => void; + clientNotification: (notification: Misskey.entities.Notification) => void; + requestClearPageCache: () => void; +}>(); diff --git a/packages/frontend/src/os.ts b/packages/frontend/src/os.ts index 7cce77cdf7..010fdbb6d8 100644 --- a/packages/frontend/src/os.ts +++ b/packages/frontend/src/os.ts @@ -128,9 +128,10 @@ export function promiseDialog<T extends Promise<any>>( let popupIdCount = 0; export const popups = ref([]) as Ref<{ - id: any; - component: any; + id: number; + component: Component; props: Record<string, any>; + events: Record<string, any>; }[]>; const zIndexes = { @@ -144,7 +145,18 @@ export function claimZIndex(priority: keyof typeof zIndexes = 'low'): number { return zIndexes[priority]; } -export async function popup<T extends Component>(component: T, props: ComponentProps<T>, events = {}, disposeEvent?: string) { +// InstanceType<typeof Component>['$emit'] ã ã¨ã‚¤ãƒ³ã‚¿ãƒ¼ã‚»ã‚¯ã‚·ãƒ§ãƒ³åž‹ãŒè¿”ã£ã¦ã㦠+// 使ã„物ã«ãªã‚‰ãªã„ã®ã§ã€ä»£ã‚ã‚Šã« ['$props'] ã‹ã‚‰è‰²ã€…çœãã“ã¨ã§ emit ã®åž‹ã‚’生æˆã™ã‚‹ +// FIXME: 何故㋠*.ts ファイルã‹ã‚‰ã ã¨åž‹ãŒã†ã¾ãå–ã‚Œãªã„?ã“ã¨ãŒã‚ã‚‹ã®ã‚’ãªã‚“ã¨ã‹ã—ãŸã„ +type ComponentEmit<T> = T extends new () => { $props: infer Props } + ? EmitsExtractor<Props> + : never; + +type EmitsExtractor<T> = { + [K in keyof T as K extends `onVnode${string}` ? never : K extends `on${infer E}` ? Uncapitalize<E> : K extends string ? never : K]: T[K]; +}; + +export async function popup<T extends Component>(component: T, props: ComponentProps<T>, events: ComponentEmit<T> = {} as ComponentEmit<T>, disposeEvent?: keyof ComponentEmit<T>) { markRaw(component); const id = ++popupIdCount; diff --git a/packages/frontend/src/pages/admin/bot-protection.vue b/packages/frontend/src/pages/admin/bot-protection.vue index 080a81767b..b39c825152 100644 --- a/packages/frontend/src/pages/admin/bot-protection.vue +++ b/packages/frontend/src/pages/admin/bot-protection.vue @@ -31,15 +31,15 @@ SPDX-License-Identifier: AGPL-3.0-only </template> <template v-else-if="provider === 'mcaptcha'"> <MkInput v-model="mcaptchaSiteKey"> - <template #prefix><i class="ti ti-key"></i></template> + <template #prefix><i class="ph-key ph-bold ph-lg"></i></template> <template #label>{{ i18n.ts.mcaptchaSiteKey }}</template> </MkInput> <MkInput v-model="mcaptchaSecretKey"> - <template #prefix><i class="ti ti-key"></i></template> + <template #prefix><i class="ph-key ph-bold ph-lg"></i></template> <template #label>{{ i18n.ts.mcaptchaSecretKey }}</template> </MkInput> <MkInput v-model="mcaptchaInstanceUrl"> - <template #prefix><i class="ti ti-link"></i></template> + <template #prefix><i class="ph-globe-simple ph-bold ph-lg"></i></template> <template #label>{{ i18n.ts.mcaptchaInstanceUrl }}</template> </MkInput> <FormSlot v-if="mcaptchaSiteKey && mcaptchaInstanceUrl"> diff --git a/packages/frontend/src/pages/admin/branding.vue b/packages/frontend/src/pages/admin/branding.vue index 4238589f18..d0fce6407b 100644 --- a/packages/frontend/src/pages/admin/branding.vue +++ b/packages/frontend/src/pages/admin/branding.vue @@ -158,9 +158,9 @@ function save() { themeColor: themeColor.value === '' ? null : themeColor.value, defaultLightTheme: defaultLightTheme.value === '' ? null : defaultLightTheme.value, defaultDarkTheme: defaultDarkTheme.value === '' ? null : defaultDarkTheme.value, - infoImageUrl: infoImageUrl.value, - notFoundImageUrl: notFoundImageUrl.value, - serverErrorImageUrl: serverErrorImageUrl.value, + infoImageUrl: infoImageUrl.value === '' ? null : infoImageUrl.value, + notFoundImageUrl: notFoundImageUrl.value === '' ? null : notFoundImageUrl.value, + serverErrorImageUrl: serverErrorImageUrl.value === '' ? null : serverErrorImageUrl.value, manifestJsonOverride: manifestJsonOverride.value === '' ? '{}' : JSON.stringify(JSON5.parse(manifestJsonOverride.value)), }).then(() => { fetchInstance(); diff --git a/packages/frontend/src/pages/admin/security.vue b/packages/frontend/src/pages/admin/security.vue index 7190dd436d..b1083636db 100644 --- a/packages/frontend/src/pages/admin/security.vue +++ b/packages/frontend/src/pages/admin/security.vue @@ -42,14 +42,14 @@ SPDX-License-Identifier: AGPL-3.0-only <template #label>Use TrueMail API</template> </MkSwitch> <MkInput v-model="truemailInstance"> - <template #prefix><i class="ti ti-key"></i></template> + <template #prefix><i class="ph-key ph-bold ph-lg"></i></template> <template #label>TrueMail API Instance</template> </MkInput> <MkInput v-model="truemailAuthKey"> - <template #prefix><i class="ti ti-key"></i></template> + <template #prefix><i class="ph-key ph-bold ph-lg"></i></template> <template #label>TrueMail API Auth Key</template> </MkInput> - <MkButton primary @click="save"><i class="ti ti-device-floppy"></i> {{ i18n.ts.save }}</MkButton> + <MkButton primary @click="save"><i class="ph-floppy-disk ph-bold ph-lg"></i> {{ i18n.ts.save }}</MkButton> </div> </MkFolder> diff --git a/packages/frontend/src/pages/drop-and-fusion.game.vue b/packages/frontend/src/pages/drop-and-fusion.game.vue index 6d805862e2..513b656097 100644 --- a/packages/frontend/src/pages/drop-and-fusion.game.vue +++ b/packages/frontend/src/pages/drop-and-fusion.game.vue @@ -893,7 +893,6 @@ function getGameImageDriveFile() { formData.append('file', blob); formData.append('name', `bubble-game-${Date.now()}.png`); formData.append('isSensitive', 'false'); - formData.append('comment', 'null'); formData.append('i', $i.token); if (defaultStore.state.uploadFolder) { formData.append('folderId', defaultStore.state.uploadFolder); diff --git a/packages/frontend/src/pages/instance-info.vue b/packages/frontend/src/pages/instance-info.vue index 4a4953bbc2..e8b29e9ba3 100644 --- a/packages/frontend/src/pages/instance-info.vue +++ b/packages/frontend/src/pages/instance-info.vue @@ -39,7 +39,7 @@ SPDX-License-Identifier: AGPL-3.0-only <MkSwitch v-model="isBlocked" :disabled="!meta || !instance" @update:modelValue="toggleBlock">{{ i18n.ts.blockThisInstance }}</MkSwitch> <MkSwitch v-model="isSilenced" :disabled="!meta || !instance" @update:modelValue="toggleSilenced">{{ i18n.ts.silenceThisInstance }}</MkSwitch> <MkSwitch v-model="isNSFW" :disabled="!instance" @update:modelValue="toggleNSFW">Mark as NSFW</MkSwitch> - <MkButton @click="refreshMetadata"><i class="ti ti-refresh"></i> Refresh metadata</MkButton> + <MkButton @click="refreshMetadata"><i class="ph-arrows-clockwise ph-bold ph-lg"></i> Refresh metadata</MkButton> </div> </FormSection> diff --git a/packages/frontend/src/pages/reversi/index.vue b/packages/frontend/src/pages/reversi/index.vue index fb812589b4..634a950391 100644 --- a/packages/frontend/src/pages/reversi/index.vue +++ b/packages/frontend/src/pages/reversi/index.vue @@ -36,13 +36,13 @@ SPDX-License-Identifier: AGPL-3.0-only <div :class="$style.gamePreviews"> <MkA v-for="g in items" :key="g.id" v-panel :class="[$style.gamePreview, !g.isStarted && !g.isEnded && $style.gamePreviewWaiting, g.isStarted && !g.isEnded && $style.gamePreviewActive]" tabindex="-1" :to="`/reversi/g/${g.id}`"> <div :class="$style.gamePreviewPlayers"> - <span v-if="g.winnerId === g.user1Id" style="margin-right: 0.75em; color: var(--accent); font-weight: bold;"><i class="ti ti-trophy"></i></span> - <span v-if="g.winnerId === g.user2Id" style="margin-right: 0.75em; visibility: hidden;"><i class="ti ti-x"></i></span> + <span v-if="g.winnerId === g.user1Id" style="margin-right: 0.75em; color: var(--accent); font-weight: bold;"><i class="ph-trophy ph-bold ph-lg"></i></span> + <span v-if="g.winnerId === g.user2Id" style="margin-right: 0.75em; visibility: hidden;"><i class="ph-x ph-bold ph-lg"></i></span> <MkAvatar :class="$style.gamePreviewPlayersAvatar" :user="g.user1"/> <span style="margin: 0 1em;">vs</span> <MkAvatar :class="$style.gamePreviewPlayersAvatar" :user="g.user2"/> - <span v-if="g.winnerId === g.user1Id" style="margin-left: 0.75em; visibility: hidden;"><i class="ti ti-x"></i></span> - <span v-if="g.winnerId === g.user2Id" style="margin-left: 0.75em; color: var(--accent); font-weight: bold;"><i class="ti ti-trophy"></i></span> + <span v-if="g.winnerId === g.user1Id" style="margin-left: 0.75em; visibility: hidden;"><i class="ph-x ph-bold ph-lg"></i></span> + <span v-if="g.winnerId === g.user2Id" style="margin-left: 0.75em; color: var(--accent); font-weight: bold;"><i class="ph-trophy ph-bold ph-lg"></i></span> </div> <div :class="$style.gamePreviewFooter"> <span v-if="g.isStarted && !g.isEnded" :class="$style.gamePreviewStatusActive">{{ i18n.ts._reversi.playing }}</span> @@ -63,13 +63,13 @@ SPDX-License-Identifier: AGPL-3.0-only <div :class="$style.gamePreviews"> <MkA v-for="g in items" :key="g.id" v-panel :class="[$style.gamePreview, !g.isStarted && !g.isEnded && $style.gamePreviewWaiting, g.isStarted && !g.isEnded && $style.gamePreviewActive]" tabindex="-1" :to="`/reversi/g/${g.id}`"> <div :class="$style.gamePreviewPlayers"> - <span v-if="g.winnerId === g.user1Id" style="margin-right: 0.75em; color: var(--accent); font-weight: bold;"><i class="ti ti-trophy"></i></span> - <span v-if="g.winnerId === g.user2Id" style="margin-right: 0.75em; visibility: hidden;"><i class="ti ti-x"></i></span> + <span v-if="g.winnerId === g.user1Id" style="margin-right: 0.75em; color: var(--accent); font-weight: bold;"><i class="ph-trophy ph-bold ph-lg"></i></span> + <span v-if="g.winnerId === g.user2Id" style="margin-right: 0.75em; visibility: hidden;"><i class="ph-x ph-bold ph-lg"></i></span> <MkAvatar :class="$style.gamePreviewPlayersAvatar" :user="g.user1"/> <span style="margin: 0 1em;">vs</span> <MkAvatar :class="$style.gamePreviewPlayersAvatar" :user="g.user2"/> - <span v-if="g.winnerId === g.user1Id" style="margin-left: 0.75em; visibility: hidden;"><i class="ti ti-x"></i></span> - <span v-if="g.winnerId === g.user2Id" style="margin-left: 0.75em; color: var(--accent); font-weight: bold;"><i class="ti ti-trophy"></i></span> + <span v-if="g.winnerId === g.user1Id" style="margin-left: 0.75em; visibility: hidden;"><i class="ph-x ph-bold ph-lg"></i></span> + <span v-if="g.winnerId === g.user2Id" style="margin-left: 0.75em; color: var(--accent); font-weight: bold;"><i class="ph-trophy ph-bold ph-lg"></i></span> </div> <div :class="$style.gamePreviewFooter"> <span v-if="g.isStarted && !g.isEnded" :class="$style.gamePreviewStatusActive">{{ i18n.ts._reversi.playing }}</span> diff --git a/packages/frontend/src/pages/settings/emoji-picker.vue b/packages/frontend/src/pages/settings/emoji-picker.vue index 40bb823ac6..383841d02f 100644 --- a/packages/frontend/src/pages/settings/emoji-picker.vue +++ b/packages/frontend/src/pages/settings/emoji-picker.vue @@ -172,7 +172,7 @@ const chooseEmoji = (ev: MouseEvent) => pickEmoji(pinnedEmojis, ev); const setDefaultEmoji = () => setDefault(pinnedEmojis); function previewReaction(ev: MouseEvent) { - reactionPicker.show(getHTMLElement(ev)); + reactionPicker.show(getHTMLElement(ev), null); } function previewEmoji(ev: MouseEvent) { diff --git a/packages/frontend/src/pages/settings/profile.vue b/packages/frontend/src/pages/settings/profile.vue index abf929e30b..37fca4f8ae 100644 --- a/packages/frontend/src/pages/settings/profile.vue +++ b/packages/frontend/src/pages/settings/profile.vue @@ -132,6 +132,7 @@ import { langmap } from '@/scripts/langmap.js'; import { definePageMetadata } from '@/scripts/page-metadata.js'; import { claimAchievement } from '@/scripts/achievements.js'; import { defaultStore } from '@/store.js'; +import { globalEvents } from '@/events.js'; import MkInfo from '@/components/MkInfo.vue'; import MkTextarea from '@/components/MkTextarea.vue'; @@ -158,7 +159,7 @@ const profile = reactive({ lang: $i.lang, isBot: $i.isBot ?? false, isCat: $i.isCat ?? false, - speakAsCat: $i.speakAsCat, + speakAsCat: $i.speakAsCat ?? false, }); watch(() => profile, () => { @@ -190,6 +191,7 @@ function saveFields() { os.apiWithDialog('i/update', { fields: fields.value.filter(field => field.name !== '' && field.value !== '').map(field => ({ name: field.name, value: field.value })), }); + globalEvents.emit('requestClearPageCache'); } function save() { @@ -217,6 +219,7 @@ function save() { isCat: !!profile.isCat, speakAsCat: !!profile.speakAsCat, }); + globalEvents.emit('requestClearPageCache'); claimAchievement('profileFilled'); if (profile.name === 'syuilo' || profile.name === 'ã—ã‚…ã„ã‚') { claimAchievement('setNameToSyuilo'); @@ -248,6 +251,7 @@ function changeAvatar(ev) { }); $i.avatarId = i.avatarId; $i.avatarUrl = i.avatarUrl; + globalEvents.emit('requestClearPageCache'); claimAchievement('profileFilled'); }); } @@ -278,6 +282,7 @@ function changeBanner(ev) { }); $i.bannerId = i.bannerId; $i.bannerUrl = i.bannerUrl; + globalEvents.emit('requestClearPageCache'); }); }, }, { @@ -288,6 +293,7 @@ function changeBanner(ev) { }); $i.bannerId = i.bannerId; $i.bannerUrl = i.bannerUrl; + globalEvents.emit('requestClearPageCache'); }, }], ev.currentTarget ?? ev.target); } else { @@ -312,6 +318,7 @@ function changeBanner(ev) { }); $i.bannerId = i.bannerId; $i.bannerUrl = i.bannerUrl; + globalEvents.emit('requestClearPageCache'); }); } } @@ -342,6 +349,7 @@ function changeBackground(ev) { }); $i.backgroundId = i.backgroundId; $i.backgroundUrl = i.backgroundUrl; + globalEvents.emit('requestClearPageCache'); }); }, }, { @@ -352,6 +360,7 @@ function changeBackground(ev) { }); $i.backgroundId = i.backgroundId; $i.backgroundUrl = i.backgroundUrl; + globalEvents.emit('requestClearPageCache'); }, }], ev.currentTarget ?? ev.target); } else { @@ -376,6 +385,7 @@ function changeBackground(ev) { }); $i.backgroundId = i.backgroundId; $i.backgroundUrl = i.backgroundUrl; + globalEvents.emit('requestClearPageCache'); }); } } diff --git a/packages/frontend/src/pages/settings/theme.vue b/packages/frontend/src/pages/settings/theme.vue index cb9c714441..f01ebc1377 100644 --- a/packages/frontend/src/pages/settings/theme.vue +++ b/packages/frontend/src/pages/settings/theme.vue @@ -88,6 +88,18 @@ import { uniqueBy } from '@/scripts/array.js'; import { fetchThemes, getThemes } from '@/theme-store.js'; import { definePageMetadata } from '@/scripts/page-metadata.js'; import { miLocalStorage } from '@/local-storage.js'; +import { unisonReload } from '@/scripts/unison-reload.js'; +import * as os from '@/os.js'; + +async function reloadAsk() { + const { canceled } = await os.confirm({ + type: 'info', + text: i18n.ts.reloadToApplySetting, + }); + if (canceled) return; + + unisonReload(); +} const installedThemes = ref(getThemes()); const builtinThemes = getBuiltinThemesRef(); @@ -124,6 +136,7 @@ const lightThemeId = computed({ } }, }); + const darkMode = computed(defaultStore.makeGetterSetter('darkMode')); const syncDeviceDarkMode = computed(ColdDeviceStorage.makeGetterSetter('syncDeviceDarkMode')); const wallpaper = ref(miLocalStorage.getItem('wallpaper')); @@ -141,7 +154,7 @@ watch(wallpaper, () => { } else { miLocalStorage.setItem('wallpaper', wallpaper.value); } - location.reload(); + reloadAsk(); }); onActivated(() => { diff --git a/packages/frontend/src/pizzax.ts b/packages/frontend/src/pizzax.ts index 68c36ca1b4..199addaefd 100644 --- a/packages/frontend/src/pizzax.ts +++ b/packages/frontend/src/pizzax.ts @@ -13,6 +13,7 @@ import { get, set } from '@/scripts/idb-proxy.js'; import { defaultStore } from '@/store.js'; import { useStream } from '@/stream.js'; import { deepClone } from '@/scripts/clone.js'; +import { deepMerge } from '@/scripts/merge.js'; type StateDef = Record<string, { where: 'account' | 'device' | 'deviceAccount'; @@ -84,29 +85,9 @@ export class Storage<T extends StateDef> { return typeof value === 'object' && value !== null && !Array.isArray(value); } - /** - * valueã«ãªã„ã‚ーをdefã‹ã‚‰ã‚‚らã†ï¼ˆå†å¸°çš„)\ - * nullã¯ãã®ã¾ã¾ã€undefinedã¯defã®å€¤ - **/ - private mergeObject<X>(value: X, def: X): X { - if (this.isPureObject(value) && this.isPureObject(def)) { - const result = structuredClone(value) as X; - for (const [k, v] of Object.entries(def) as [keyof X, X[keyof X]][]) { - if (!Object.prototype.hasOwnProperty.call(value, k) || value[k] === undefined) { - result[k] = v; - } else if (this.isPureObject(v) && this.isPureObject(result[k])) { - const child = structuredClone(result[k]) as X[keyof X] & Record<string | number | symbol, unknown>; - result[k] = this.mergeObject<typeof v>(child, v); - } - } - return result; - } - return value; - } - private mergeState<X>(value: X, def: X): X { if (this.isPureObject(value) && this.isPureObject(def)) { - const merged = this.mergeObject(value, def); + const merged = deepMerge(value, def); if (_DEV_) console.log('Merging state. Incoming: ', value, ' Default: ', def, ' Result: ', merged); @@ -258,7 +239,7 @@ export class Storage<T extends StateDef> { /** * 特定ã®ã‚ーã®ã€ç°¡æ˜“çš„ãªgetter/setterを作りã¾ã™ - * 主ã«vueå ´ã§è¨å®šã‚³ãƒ³ãƒˆãƒãƒ¼ãƒ«ã®modelã¨ã—ã¦ä½¿ã†ç”¨ + * 主ã«vue上ã§è¨å®šã‚³ãƒ³ãƒˆãƒãƒ¼ãƒ«ã®modelã¨ã—ã¦ä½¿ã†ç”¨ */ public makeGetterSetter<K extends keyof T>(key: K, getter?: (v: T[K]) => unknown, setter?: (v: unknown) => T[K]): { get: () => T[K]['default']; diff --git a/packages/frontend/src/router/main.ts b/packages/frontend/src/router/main.ts index 5adb3f606f..c6a520e913 100644 --- a/packages/frontend/src/router/main.ts +++ b/packages/frontend/src/router/main.ts @@ -80,6 +80,10 @@ class MainRouterProxy implements IRouter { return this.supplier().resolve(path); } + init(): void { + this.supplier().init(); + } + eventNames(): Array<EventEmitter.EventNames<RouterEvent>> { return this.supplier().eventNames(); } diff --git a/packages/frontend/src/scripts/check-reaction-permissions.ts b/packages/frontend/src/scripts/check-reaction-permissions.ts new file mode 100644 index 0000000000..c9d2a5bfc6 --- /dev/null +++ b/packages/frontend/src/scripts/check-reaction-permissions.ts @@ -0,0 +1,8 @@ +import * as Misskey from 'misskey-js'; + +export function checkReactionPermissions(me: Misskey.entities.MeDetailed, note: Misskey.entities.Note, emoji: Misskey.entities.EmojiSimple): boolean { + const roleIdsThatCanBeUsedThisEmojiAsReaction = emoji.roleIdsThatCanBeUsedThisEmojiAsReaction ?? []; + return !(emoji.localOnly && note.user.host !== me.host) + && !(emoji.isSensitive && (note.reactionAcceptance === 'nonSensitiveOnly' || note.reactionAcceptance === 'nonSensitiveOnlyForLocalLikeOnlyForRemote')) + && (roleIdsThatCanBeUsedThisEmojiAsReaction.length === 0 || me.roles.some(role => roleIdsThatCanBeUsedThisEmojiAsReaction.includes(role.id))); +} diff --git a/packages/frontend/src/scripts/clone.ts b/packages/frontend/src/scripts/clone.ts index ac38faefaa..6d3a1c8c79 100644 --- a/packages/frontend/src/scripts/clone.ts +++ b/packages/frontend/src/scripts/clone.ts @@ -8,13 +8,13 @@ // ã‚ã¨ã€Vue Refã‚’IndexedDBã«ä¿å˜ã—よã†ã¨ã—ã¦structredCloneを使ã£ãŸã‚‰ã‚¨ãƒ©ãƒ¼ã«ãªã£ãŸ // https://github.com/misskey-dev/misskey/pull/8098#issuecomment-1114144045 -type Cloneable = string | number | boolean | null | undefined | { [key: string]: Cloneable } | Cloneable[]; +export type Cloneable = string | number | boolean | null | undefined | { [key: string]: Cloneable } | { [key: number]: Cloneable } | { [key: symbol]: Cloneable } | Cloneable[]; export function deepClone<T extends Cloneable>(x: T): T { if (typeof x === 'object') { if (x === null) return x; if (Array.isArray(x)) return x.map(deepClone) as T; - const obj = {} as Record<string, Cloneable>; + const obj = {} as Record<string | number | symbol, Cloneable>; for (const [k, v] of Object.entries(x)) { obj[k] = v === undefined ? undefined : deepClone(v); } diff --git a/packages/frontend/src/scripts/code-highlighter.ts b/packages/frontend/src/scripts/code-highlighter.ts index bc05ec94d5..b11dfed41a 100644 --- a/packages/frontend/src/scripts/code-highlighter.ts +++ b/packages/frontend/src/scripts/code-highlighter.ts @@ -1,9 +1,51 @@ +import { bundledThemesInfo } from 'shiki'; import { getHighlighterCore, loadWasm } from 'shiki/core'; import darkPlus from 'shiki/themes/dark-plus.mjs'; -import type { Highlighter, LanguageRegistration } from 'shiki'; +import { unique } from './array.js'; +import { deepClone } from './clone.js'; +import { deepMerge } from './merge.js'; +import type { Highlighter, LanguageRegistration, ThemeRegistration, ThemeRegistrationRaw } from 'shiki'; +import { ColdDeviceStorage } from '@/store.js'; +import lightTheme from '@/themes/_light.json5'; +import darkTheme from '@/themes/_dark.json5'; let _highlighter: Highlighter | null = null; +export async function getTheme(mode: 'light' | 'dark', getName: true): Promise<string>; +export async function getTheme(mode: 'light' | 'dark', getName?: false): Promise<ThemeRegistration | ThemeRegistrationRaw>; +export async function getTheme(mode: 'light' | 'dark', getName = false): Promise<ThemeRegistration | ThemeRegistrationRaw | string | null> { + const theme = deepClone(ColdDeviceStorage.get(mode === 'light' ? 'lightTheme' : 'darkTheme')); + + if (theme.base) { + const base = [lightTheme, darkTheme].find(x => x.id === theme.base); + if (base && base.codeHighlighter) theme.codeHighlighter = Object.assign({}, base.codeHighlighter, theme.codeHighlighter); + } + + if (theme.codeHighlighter) { + let _res: ThemeRegistration = {}; + if (theme.codeHighlighter.base === '_none_') { + _res = deepClone(theme.codeHighlighter.overrides); + } else { + const base = await bundledThemesInfo.find(t => t.id === theme.codeHighlighter!.base)?.import() ?? darkPlus; + _res = deepMerge(theme.codeHighlighter.overrides ?? {}, 'default' in base ? base.default : base); + } + if (_res.name == null) { + _res.name = theme.id; + } + _res.type = mode; + + if (getName) { + return _res.name; + } + return _res; + } + + if (getName) { + return 'dark-plus'; + } + return darkPlus; +} + export async function getHighlighter(): Promise<Highlighter> { if (!_highlighter) { return await initHighlighter(); @@ -13,11 +55,17 @@ export async function getHighlighter(): Promise<Highlighter> { export async function initHighlighter() { const aiScriptGrammar = await import('aiscript-vscode/aiscript/syntaxes/aiscript.tmLanguage.json'); - + await loadWasm(import('shiki/onig.wasm?init')); + // テーマã®é‡è¤‡ã‚’消㙠+ const themes = unique([ + darkPlus, + ...(await Promise.all([getTheme('light'), getTheme('dark')])), + ]); + const highlighter = await getHighlighterCore({ - themes: [darkPlus], + themes, langs: [ import('shiki/langs/javascript.mjs'), { @@ -27,6 +75,20 @@ export async function initHighlighter() { ], }); + ColdDeviceStorage.watch('lightTheme', async () => { + const newTheme = await getTheme('light'); + if (newTheme.name && !highlighter.getLoadedThemes().includes(newTheme.name)) { + highlighter.loadTheme(newTheme); + } + }); + + ColdDeviceStorage.watch('darkTheme', async () => { + const newTheme = await getTheme('dark'); + if (newTheme.name && !highlighter.getLoadedThemes().includes(newTheme.name)) { + highlighter.loadTheme(newTheme); + } + }); + _highlighter = highlighter; return highlighter; diff --git a/packages/frontend/src/scripts/merge.ts b/packages/frontend/src/scripts/merge.ts new file mode 100644 index 0000000000..60097051fa --- /dev/null +++ b/packages/frontend/src/scripts/merge.ts @@ -0,0 +1,31 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { deepClone } from './clone.js'; +import type { Cloneable } from './clone.js'; + +function isPureObject(value: unknown): value is Record<string | number | symbol, unknown> { + return typeof value === 'object' && value !== null && !Array.isArray(value); +} + +/** + * valueã«ãªã„ã‚ーをdefã‹ã‚‰ã‚‚らã†ï¼ˆå†å¸°çš„)\ + * nullã¯ãã®ã¾ã¾ã€undefinedã¯defã®å€¤ + **/ +export function deepMerge<X extends Record<string | number | symbol, unknown>>(value: X, def: X): X { + if (isPureObject(value) && isPureObject(def)) { + const result = deepClone(value as Cloneable) as X; + for (const [k, v] of Object.entries(def) as [keyof X, X[keyof X]][]) { + if (!Object.prototype.hasOwnProperty.call(value, k) || value[k] === undefined) { + result[k] = v; + } else if (isPureObject(v) && isPureObject(result[k])) { + const child = deepClone(result[k] as Cloneable) as X[keyof X] & Record<string | number | symbol, unknown>; + result[k] = deepMerge<typeof v>(child, v); + } + } + return result; + } + return value; +} diff --git a/packages/frontend/src/scripts/reaction-picker.ts b/packages/frontend/src/scripts/reaction-picker.ts index a13351b536..193ac838a2 100644 --- a/packages/frontend/src/scripts/reaction-picker.ts +++ b/packages/frontend/src/scripts/reaction-picker.ts @@ -3,6 +3,7 @@ * SPDX-License-Identifier: AGPL-3.0-only */ +import * as Misskey from 'misskey-js'; import { defineAsyncComponent, Ref, ref } from 'vue'; import { popup } from '@/os.js'; import { defaultStore } from '@/store.js'; @@ -10,6 +11,7 @@ import { defaultStore } from '@/store.js'; class ReactionPicker { private src: Ref<HTMLElement | null> = ref(null); private manualShowing = ref(false); + private targetNote: Ref<Misskey.entities.Note | null> = ref(null); private onChosen?: (reaction: string) => void; private onClosed?: () => void; @@ -23,6 +25,7 @@ class ReactionPicker { src: this.src, pinnedEmojis: reactionsRef, asReactionPicker: true, + targetNote: this.targetNote, manualShowing: this.manualShowing, }, { done: reaction => { @@ -38,8 +41,9 @@ class ReactionPicker { }); } - public show(src: HTMLElement | null, onChosen?: ReactionPicker['onChosen'], onClosed?: ReactionPicker['onClosed']) { + public show(src: HTMLElement | null, targetNote: Misskey.entities.Note | null, onChosen?: ReactionPicker['onChosen'], onClosed?: ReactionPicker['onClosed']) { this.src.value = src; + this.targetNote.value = targetNote; this.manualShowing.value = true; this.onChosen = onChosen; this.onClosed = onClosed; diff --git a/packages/frontend/src/scripts/theme.ts b/packages/frontend/src/scripts/theme.ts index a174f51756..05ccd3dc38 100644 --- a/packages/frontend/src/scripts/theme.ts +++ b/packages/frontend/src/scripts/theme.ts @@ -6,6 +6,7 @@ import { ref } from 'vue'; import tinycolor from 'tinycolor2'; import { deepClone } from './clone.js'; +import type { BuiltinTheme } from 'shiki'; import { globalEvents } from '@/events.js'; import lightTheme from '@/themes/_light.json5'; import darkTheme from '@/themes/_dark.json5'; @@ -18,6 +19,13 @@ export type Theme = { desc?: string; base?: 'dark' | 'light'; props: Record<string, string>; + codeHighlighter?: { + base: BuiltinTheme; + overrides?: Record<string, any>; + } | { + base: '_none_'; + overrides: Record<string, any>; + }; }; export const themeProps = Object.keys(lightTheme.props).filter(key => !key.startsWith('X')); @@ -57,7 +65,7 @@ export const getBuiltinThemesRef = () => { const themeFontFaceName = 'sharkey-theme-font-face'; -let timeout = null; +let timeout: number | null = null; export function applyTheme(theme: Theme, persist = true) { if (timeout) window.clearTimeout(timeout); diff --git a/packages/frontend/src/store.ts b/packages/frontend/src/store.ts index 4dad6ce406..d695caa95f 100644 --- a/packages/frontend/src/store.ts +++ b/packages/frontend/src/store.ts @@ -7,6 +7,7 @@ import { markRaw, ref } from 'vue'; import * as Misskey from 'misskey-js'; import { miLocalStorage } from './local-storage.js'; import type { SoundType } from '@/scripts/sound.js'; +import type { BuiltinTheme as ShikiBuiltinTheme } from 'shiki'; import { Storage } from '@/pizzax.js'; import { hemisphere } from '@/scripts/intl-const.js'; diff --git a/packages/frontend/src/themes/_dark.json5 b/packages/frontend/src/themes/_dark.json5 index 8544572718..7b70aa1e09 100644 --- a/packages/frontend/src/themes/_dark.json5 +++ b/packages/frontend/src/themes/_dark.json5 @@ -95,4 +95,8 @@ X16: ':alpha<0.7<@panel', X17: ':alpha<0.8<@bg', }, + + codeHighlighter: { + base: 'one-dark-pro', + }, } diff --git a/packages/frontend/src/themes/_light.json5 b/packages/frontend/src/themes/_light.json5 index 2f3783310f..d797aec734 100644 --- a/packages/frontend/src/themes/_light.json5 +++ b/packages/frontend/src/themes/_light.json5 @@ -95,4 +95,8 @@ X16: ':alpha<0.7<@panel', X17: ':alpha<0.8<@bg', }, + + codeHighlighter: { + base: 'catppuccin-latte', + }, } diff --git a/packages/misskey-js/generator/src/generator.ts b/packages/misskey-js/generator/src/generator.ts index 7e72359167..f091e599a9 100644 --- a/packages/misskey-js/generator/src/generator.ts +++ b/packages/misskey-js/generator/src/generator.ts @@ -4,22 +4,6 @@ import { toPascal } from 'ts-case-convert'; import OpenAPIParser from '@readme/openapi-parser'; import openapiTS from 'openapi-typescript'; -function generateVersionHeaderComment(openApiDocs: OpenAPIV3_1.Document): string { - const contents = { - version: openApiDocs.info.version, - generatedAt: new Date().toISOString(), - }; - - const lines: string[] = []; - lines.push('/*'); - for (const [key, value] of Object.entries(contents)) { - lines.push(` * ${key}: ${value}`); - } - lines.push(' */'); - - return lines.join('\n'); -} - async function generateBaseTypes( openApiDocs: OpenAPIV3_1.Document, openApiJsonPath: string, @@ -36,9 +20,6 @@ async function generateBaseTypes( } lines.push(''); - lines.push(generateVersionHeaderComment(openApiDocs)); - lines.push(''); - const generatedTypes = await openapiTS(openApiJsonPath, { exportType: true }); lines.push(generatedTypes); lines.push(''); @@ -59,8 +40,6 @@ async function generateSchemaEntities( const schemaNames = Object.keys(schemas); const typeAliasLines: string[] = []; - typeAliasLines.push(generateVersionHeaderComment(openApiDocs)); - typeAliasLines.push(''); typeAliasLines.push(`import { components } from '${toImportPath(typeFileName)}';`); typeAliasLines.push( ...schemaNames.map(it => `export type ${it} = components['schemas']['${it}'];`), @@ -119,9 +98,6 @@ async function generateEndpoints( const entitiesOutputLine: string[] = []; - entitiesOutputLine.push(generateVersionHeaderComment(openApiDocs)); - entitiesOutputLine.push(''); - entitiesOutputLine.push(`import { operations } from '${toImportPath(typeFileName)}';`); entitiesOutputLine.push(''); @@ -139,9 +115,6 @@ async function generateEndpoints( const endpointOutputLine: string[] = []; - endpointOutputLine.push(generateVersionHeaderComment(openApiDocs)); - endpointOutputLine.push(''); - endpointOutputLine.push('import type {'); endpointOutputLine.push( ...[emptyRequest, emptyResponse, ...entities].map(it => '\t' + it.generateName() + ','), @@ -187,9 +160,6 @@ async function generateApiClientJSDoc( const endpointOutputLine: string[] = []; - endpointOutputLine.push(generateVersionHeaderComment(openApiDocs)); - endpointOutputLine.push(''); - endpointOutputLine.push(`import type { SwitchCaseResponseType } from '${toImportPath(apiClientFileName)}';`); endpointOutputLine.push(`import type { Endpoints } from '${toImportPath(endpointsFileName)}';`); endpointOutputLine.push(''); diff --git a/packages/misskey-js/src/autogen/apiClientJSDoc.ts b/packages/misskey-js/src/autogen/apiClientJSDoc.ts index 205fba69a7..2d9d78228e 100644 --- a/packages/misskey-js/src/autogen/apiClientJSDoc.ts +++ b/packages/misskey-js/src/autogen/apiClientJSDoc.ts @@ -1,8 +1,3 @@ -/* - * version: 2024.2.0-beta2 - * generatedAt: 2024-02-03T19:17:05.681Z - */ - import type { SwitchCaseResponseType } from '../api.js'; import type { Endpoints } from './endpoint.js'; diff --git a/packages/misskey-js/src/autogen/endpoint.ts b/packages/misskey-js/src/autogen/endpoint.ts index 28fc82c609..3f95d3cf4b 100644 --- a/packages/misskey-js/src/autogen/endpoint.ts +++ b/packages/misskey-js/src/autogen/endpoint.ts @@ -1,8 +1,3 @@ -/* - * version: 2024.2.0-beta2 - * generatedAt: 2024-02-03T19:17:05.679Z - */ - import type { EmptyRequest, EmptyResponse, diff --git a/packages/misskey-js/src/autogen/entities.ts b/packages/misskey-js/src/autogen/entities.ts index 17471a27f0..3e96fcc61c 100644 --- a/packages/misskey-js/src/autogen/entities.ts +++ b/packages/misskey-js/src/autogen/entities.ts @@ -1,8 +1,3 @@ -/* - * version: 2024.2.0-beta2 - * generatedAt: 2024-02-03T19:17:05.678Z - */ - import { operations } from './types.js'; export type EmptyRequest = Record<string, unknown> | undefined; diff --git a/packages/misskey-js/src/autogen/models.ts b/packages/misskey-js/src/autogen/models.ts index 5d87df588c..8d594e61bb 100644 --- a/packages/misskey-js/src/autogen/models.ts +++ b/packages/misskey-js/src/autogen/models.ts @@ -1,8 +1,3 @@ -/* - * version: 2024.2.0-beta2 - * generatedAt: 2024-02-03T19:17:05.676Z - */ - import { components } from './types.js'; export type Error = components['schemas']['Error']; export type UserLite = components['schemas']['UserLite']; diff --git a/packages/misskey-js/src/autogen/types.ts b/packages/misskey-js/src/autogen/types.ts index 54765e86f2..08a2bd7412 100644 --- a/packages/misskey-js/src/autogen/types.ts +++ b/packages/misskey-js/src/autogen/types.ts @@ -1,11 +1,6 @@ /* eslint @typescript-eslint/naming-convention: 0 */ /* eslint @typescript-eslint/no-explicit-any: 0 */ -/* - * version: 2024.2.0-beta2 - * generatedAt: 2024-02-03T19:17:05.578Z - */ - /** * This file was auto-generated by openapi-typescript. * Do not make direct changes to the file. @@ -4556,6 +4551,7 @@ export type components = { name: string; category: string | null; url: string; + localOnly?: boolean; isSensitive?: boolean; roleIdsThatCanBeUsedThisEmojiAsReaction?: string[]; }; -- GitLab From 1fa347390a7cb65ca71446c812d3a92d117fd970 Mon Sep 17 00:00:00 2001 From: Marie <marie@kaifa.ch> Date: Tue, 6 Feb 2024 21:27:42 +0100 Subject: [PATCH 20/40] fix: add missing diff between SkNote* and MkNote* --- packages/frontend/src/components/SkNote.vue | 2 +- packages/frontend/src/components/SkNoteDetailed.vue | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/frontend/src/components/SkNote.vue b/packages/frontend/src/components/SkNote.vue index 61d32d721e..dc74c4928d 100644 --- a/packages/frontend/src/components/SkNote.vue +++ b/packages/frontend/src/components/SkNote.vue @@ -623,7 +623,7 @@ function react(viaKeyboard = false): void { } } else { blur(); - reactionPicker.show(reactButton.value ?? null, reaction => { + reactionPicker.show(reactButton.value ?? null, note.value, reaction => { sound.playMisskeySfx('reaction'); if (props.mock) { diff --git a/packages/frontend/src/components/SkNoteDetailed.vue b/packages/frontend/src/components/SkNoteDetailed.vue index c1c20e5b29..ef17a2e8a6 100644 --- a/packages/frontend/src/components/SkNoteDetailed.vue +++ b/packages/frontend/src/components/SkNoteDetailed.vue @@ -619,7 +619,7 @@ function react(viaKeyboard = false): void { } } else { blur(); - reactionPicker.show(reactButton.value ?? null, reaction => { + reactionPicker.show(reactButton.value ?? null, note.value, reaction => { sound.playMisskeySfx('reaction'); misskeyApi('notes/reactions/create', { -- GitLab From e89d7602403718c9ec5412db14e1288857d6c9a5 Mon Sep 17 00:00:00 2001 From: MeiMei <30769358+mei23@users.noreply.github.com> Date: Wed, 7 Feb 2024 19:57:59 +0900 Subject: [PATCH 21/40] =?UTF-8?q?Enhance:=20=E9=80=A3=E5=90=88=E5=90=91?= =?UTF-8?q?=E3=81=91=E3=81=AE=E3=83=8E=E3=83=BC=E3=83=88=E9=85=8D=E4=BF=A1?= =?UTF-8?q?=E3=82=92=E8=BB=BD=E9=87=8F=E5=8C=96=20(#13192)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * AP HTML表ç¾ã‚’シンプル㫠* a * CHANGELOG * リンク --- CHANGELOG.md | 1 + packages/backend/src/core/MfmService.ts | 4 ++ .../src/core/activitypub/ApMfmService.ts | 19 ++++++-- .../src/core/activitypub/ApRendererService.ts | 23 +++++----- packages/backend/test/unit/ApMfmService.ts | 44 +++++++++++++++++++ packages/backend/test/unit/MfmService.ts | 6 +++ 6 files changed, 81 insertions(+), 16 deletions(-) create mode 100644 packages/backend/test/unit/ApMfmService.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 63bf42c72f..cb4a17d95b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -87,6 +87,7 @@ - Fix: properly handle cc followers - Fix: ジョブã«é–¢ã™ã‚‹è¨å®šã®åå‰ã‚’ä¿®æ£ relashionshipJobPerSec -> relationshipJobPerSec - Fix: コントãƒãƒ¼ãƒ«ãƒ‘ãƒãƒ«->モデレーション->「誰ã§ã‚‚æ–°è¦ç™»éŒ²ã§ãるよã†ã«ã™ã‚‹ã€ã®åˆæœŸå€¤ã‚’ONã‹ã‚‰OFFã«å¤‰æ›´ #13122 +- Enhance: 連åˆå‘ã‘ã®ãƒŽãƒ¼ãƒˆé…信を軽é‡åŒ– #13192 ### Service Worker - Enhance: オフライン表示ã®ãƒ‡ã‚¶ã‚¤ãƒ³ã‚’改善・多言語対応 diff --git a/packages/backend/src/core/MfmService.ts b/packages/backend/src/core/MfmService.ts index e74c62e1a8..b2d8382bf6 100644 --- a/packages/backend/src/core/MfmService.ts +++ b/packages/backend/src/core/MfmService.ts @@ -419,6 +419,10 @@ export class MfmService { }, text: (node) => { + if (!node.props.text.match(/[\r\n]/)) { + return doc.createTextNode(node.props.text); + } + const el = doc.createElement('span'); const nodes = node.props.text.split(/\r\n|\r|\n/).map(x => doc.createTextNode(x)); diff --git a/packages/backend/src/core/activitypub/ApMfmService.ts b/packages/backend/src/core/activitypub/ApMfmService.ts index 60868627a2..737c34f3c5 100644 --- a/packages/backend/src/core/activitypub/ApMfmService.ts +++ b/packages/backend/src/core/activitypub/ApMfmService.ts @@ -25,8 +25,21 @@ export class ApMfmService { } @bindThis - public getNoteHtml(note: MiNote): string | null { - if (!note.text) return ''; - return this.mfmService.toHtml(mfm.parse(note.text), JSON.parse(note.mentionedRemoteUsers)); + public getNoteHtml(note: MiNote, apAppend?: string) { + let noMisskeyContent = false; + const srcMfm = (note.text ?? '') + (apAppend ?? ''); + + const parsed = mfm.parse(srcMfm); + + if (!apAppend && parsed?.every(n => ['text', 'unicodeEmoji', 'emojiCode', 'mention', 'hashtag', 'url'].includes(n.type))) { + noMisskeyContent = true; + } + + const content = this.mfmService.toHtml(parsed, JSON.parse(note.mentionedRemoteUsers)); + + return { + content, + noMisskeyContent, + }; } } diff --git a/packages/backend/src/core/activitypub/ApRendererService.ts b/packages/backend/src/core/activitypub/ApRendererService.ts index 530e4a3c33..211f4f4a44 100644 --- a/packages/backend/src/core/activitypub/ApRendererService.ts +++ b/packages/backend/src/core/activitypub/ApRendererService.ts @@ -389,17 +389,15 @@ export class ApRendererService { poll = await this.pollsRepository.findOneBy({ noteId: note.id }); } - let apText = text; + let apAppend = ''; if (quote) { - apText += `\n\nRE: ${quote}`; + apAppend += `\n\nRE: ${quote}`; } const summary = note.cw === '' ? String.fromCharCode(0x200B) : note.cw; - const content = this.apMfmService.getNoteHtml(Object.assign({}, note, { - text: apText, - })); + const { content, noMisskeyContent } = this.apMfmService.getNoteHtml(note, apAppend); const emojis = await this.getEmojis(note.emojis); const apemojis = emojis.filter(emoji => !emoji.localOnly).map(emoji => this.renderEmoji(emoji)); @@ -412,9 +410,6 @@ export class ApRendererService { const asPoll = poll ? { type: 'Question', - content: this.apMfmService.getNoteHtml(Object.assign({}, note, { - text: text, - })), [poll.expiresAt && poll.expiresAt < new Date() ? 'closed' : 'endTime']: poll.expiresAt, [poll.multiple ? 'anyOf' : 'oneOf']: poll.choices.map((text, i) => ({ type: 'Note', @@ -432,11 +427,13 @@ export class ApRendererService { attributedTo, summary: summary ?? undefined, content: content ?? undefined, - _misskey_content: text, - source: { - content: text, - mediaType: 'text/x.misskeymarkdown', - }, + ...(noMisskeyContent ? {} : { + _misskey_content: text, + source: { + content: text, + mediaType: 'text/x.misskeymarkdown', + }, + }), _misskey_quote: quote, quoteUrl: quote, published: this.idService.parse(note.id).date.toISOString(), diff --git a/packages/backend/test/unit/ApMfmService.ts b/packages/backend/test/unit/ApMfmService.ts new file mode 100644 index 0000000000..2b79041c86 --- /dev/null +++ b/packages/backend/test/unit/ApMfmService.ts @@ -0,0 +1,44 @@ +import * as assert from 'assert'; +import { Test } from '@nestjs/testing'; + +import { CoreModule } from '@/core/CoreModule.js'; +import { ApMfmService } from '@/core/activitypub/ApMfmService.js'; +import { GlobalModule } from '@/GlobalModule.js'; +import { MiNote } from '@/models/Note.js'; + +describe('ApMfmService', () => { + let apMfmService: ApMfmService; + + beforeAll(async () => { + const app = await Test.createTestingModule({ + imports: [GlobalModule, CoreModule], + }).compile(); + apMfmService = app.get<ApMfmService>(ApMfmService); + }); + + describe('getNoteHtml', () => { + test('Do not provide _misskey_content for simple text', () => { + const note: MiNote = { + text: 'テã‚スト #ã‚¿ã‚° @mention 🊠:emoji: https://example.com', + mentionedRemoteUsers: '[]', + } as any; + + const { content, noMisskeyContent } = apMfmService.getNoteHtml(note); + + assert.equal(noMisskeyContent, true, 'noMisskeyContent'); + assert.equal(content, '<p>テã‚スト <a href="http://misskey.local/tags/ã‚¿ã‚°" rel="tag">#ã‚¿ã‚°</a> <a href="http://misskey.local/@mention" class="u-url mention">@mention</a> 🊠​:emoji:​ <a href="https://example.com">https://example.com</a></p>', 'content'); + }); + + test('Provide _misskey_content for MFM', () => { + const note: MiNote = { + text: '$[tada foo]', + mentionedRemoteUsers: '[]', + } as any; + + const { content, noMisskeyContent } = apMfmService.getNoteHtml(note); + + assert.equal(noMisskeyContent, false, 'noMisskeyContent'); + assert.equal(content, '<p><i>foo</i></p>', 'content'); + }); + }); +}); diff --git a/packages/backend/test/unit/MfmService.ts b/packages/backend/test/unit/MfmService.ts index bb8e6981d5..c3827b20d2 100644 --- a/packages/backend/test/unit/MfmService.ts +++ b/packages/backend/test/unit/MfmService.ts @@ -33,6 +33,12 @@ describe('MfmService', () => { const output = '<p><span>foo<br>bar<br>baz</span></p>'; assert.equal(mfmService.toHtml(mfm.parse(input)), output); }); + + test('Do not generate unnecessary span', () => { + const input = 'foo $[tada bar]'; + const output = '<p>foo <i>bar</i></p>'; + assert.equal(mfmService.toHtml(mfm.parse(input)), output); + }); }); describe('fromHtml', () => { -- GitLab From 56d7f5862683b2136976608c5f4fa21dfc6748e2 Mon Sep 17 00:00:00 2001 From: 1Step621 <86859447+1STEP621@users.noreply.github.com> Date: Wed, 7 Feb 2024 19:58:21 +0900 Subject: [PATCH 22/40] =?UTF-8?q?Fix(frontend):=20MkCodeEditor=E3=81=A7?= =?UTF-8?q?=E8=A1=8C=E3=81=8C=E3=81=9A=E3=82=8C=E3=81=A6=E3=81=84=E3=81=8F?= =?UTF-8?q?=E3=81=AE=E3=82=92=E4=BF=AE=E6=AD=A3=20(#13188)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * MkCodeEditorã§è¡ŒãŒãšã‚Œã¦ã„ãã®ã‚’ä¿®æ£ * update CHANGELOG.md --- CHANGELOG.md | 1 + packages/frontend/src/components/MkCode.core.vue | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cb4a17d95b..652c7ea7c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -73,6 +73,7 @@ - Fix: ã‚ャプションãŒç©ºã®ç”»åƒã‚’クãƒãƒƒãƒ—ã™ã‚‹ã¨ã‚ャプションã«nullã¨ã„ã†æ–‡å—列ãŒå…¥ã£ã¦ã—ã¾ã†å•é¡Œã®ä¿®æ£ - Fix: プãƒãƒ•ã‚£ãƒ¼ãƒ«ã‚’編集ã—ã¦ã‚‚リãƒãƒ¼ãƒ‰ã™ã‚‹ã¾ã§åæ˜ ã•ã‚Œãªã„å•é¡Œã‚’ä¿®æ£ - Fix: エラー画åƒURLã‚’è¨å®šã—ãŸå¾Œè§£é™¤ã™ã‚‹ã¨ï¼Œãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®ç”»åƒãŒè¡¨ç¤ºã•ã‚Œãªã„å•é¡Œã®ä¿®æ£ +- Fix: MkCodeEditorã§è¡ŒãŒãšã‚Œã¦ã„ã£ã¦ã—ã¾ã†å•é¡Œã®ä¿®æ£ ### Server - Enhance: 連åˆå…ˆã®ãƒ¬ãƒ¼ãƒˆãƒªãƒŸãƒƒãƒˆã«å¼•ã£ã‹ã‹ã£ãŸéš›ã«ãƒªãƒˆãƒ©ã‚¤ã™ã‚‹ã‚ˆã†ã«ãªã‚Šã¾ã—㟠diff --git a/packages/frontend/src/components/MkCode.core.vue b/packages/frontend/src/components/MkCode.core.vue index 68c50c4c69..02a0ea475e 100644 --- a/packages/frontend/src/components/MkCode.core.vue +++ b/packages/frontend/src/components/MkCode.core.vue @@ -78,6 +78,7 @@ watch(() => props.lang, (to) => { overflow: auto; border-radius: 8px; border: 1px solid var(--divider); + font-family: Consolas, Monaco, Andale Mono, Ubuntu Mono, monospace; color: var(--shiki-fallback); background-color: var(--shiki-fallback-bg); -- GitLab From 313ce821926efc0e01fd815c7582d8bb30f7e935 Mon Sep 17 00:00:00 2001 From: MeiMei <30769358+mei23@users.noreply.github.com> Date: Wed, 7 Feb 2024 19:59:06 +0900 Subject: [PATCH 23/40] =?UTF-8?q?=E6=AD=A3=E3=81=97=E3=81=84=202024.2.0-be?= =?UTF-8?q?ta.10=20=E6=94=B9=E7=89=88=E6=89=8B=E9=A0=86=EF=BC=9F=20(#13173?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * æ£ã—ã„ 2024.2.0-beta.10 æ”¹ç‰ˆæ‰‹é †ï¼Ÿ * run build-misskey-js-with-types --- packages/misskey-js/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/misskey-js/package.json b/packages/misskey-js/package.json index 03952c7ac1..0c4dd52d14 100644 --- a/packages/misskey-js/package.json +++ b/packages/misskey-js/package.json @@ -1,7 +1,7 @@ { "type": "module", "name": "misskey-js", - "version": "2024.2.0-beta.8", + "version": "2024.2.0-beta.10", "description": "Misskey SDK for JavaScript", "types": "./built/dts/index.d.ts", "exports": { -- GitLab From 155896a851f2a1060454ff614b5fecde4a8dd016 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=8B=E3=81=A3=E3=81=93=E3=81=8B=E3=82=8A?= <67428053+kakkokari-gtyih@users.noreply.github.com> Date: Wed, 7 Feb 2024 20:02:29 +0900 Subject: [PATCH 24/40] =?UTF-8?q?enhance(frontend/HorizontalSwipe):=20?= =?UTF-8?q?=E6=93=8D=E4=BD=9C=E6=80=A7=E3=81=AE=E6=94=B9=E5=96=84=20(#1303?= =?UTF-8?q?8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update swipe thresholds and touch-action * スワイプä¸ã«PullToRefreshãŒåå¿œã—ãªã„よã†ã« * 横スワイプã«é–¢ä¸Žã™ã‚‹å¯èƒ½æ€§ã®ã‚ã‚‹è¦ç´ ãŒã‚ã‚‹å ´åˆã¯ã‚¹ãƒ¯ã‚¤ãƒ—を発ç«ã—ãªã„よã†ã« * update threshold * isSwipingを外部化 * rename --------- Co-authored-by: syuilo <Syuilotan@yahoo.co.jp> --- .../src/components/MkHorizontalSwipe.vue | 34 ++++++++++++++++--- .../src/components/MkPullToRefresh.vue | 7 +++- packages/frontend/src/scripts/touch.ts | 4 +++ 3 files changed, 39 insertions(+), 6 deletions(-) diff --git a/packages/frontend/src/components/MkHorizontalSwipe.vue b/packages/frontend/src/components/MkHorizontalSwipe.vue index 67d32c505a..bf7d43fd43 100644 --- a/packages/frontend/src/components/MkHorizontalSwipe.vue +++ b/packages/frontend/src/components/MkHorizontalSwipe.vue @@ -25,11 +25,11 @@ SPDX-License-Identifier: AGPL-3.0-only </Transition> </div> </template> - <script lang="ts" setup> import { ref, shallowRef, computed, nextTick, watch } from 'vue'; import type { Tab } from '@/components/global/MkPageHeader.tabs.vue'; import { defaultStore } from '@/store.js'; +import { isHorizontalSwipeSwiping as isSwiping } from '@/scripts/touch.js'; const rootEl = shallowRef<HTMLDivElement>(); @@ -49,16 +49,16 @@ const shouldAnimate = computed(() => defaultStore.reactiveState.enableHorizontal // â–¼ ã—ãã„値 â–¼ // // スワイプã¨åˆ¤å®šã•ã‚Œã‚‹æœ€å°ã®è·é›¢ -const MIN_SWIPE_DISTANCE = 50; +const MIN_SWIPE_DISTANCE = 20; // スワイプ時ã®å‹•ä½œã‚’発ç«ã™ã‚‹æœ€å°ã®è·é›¢ -const SWIPE_DISTANCE_THRESHOLD = 125; +const SWIPE_DISTANCE_THRESHOLD = 70; // スワイプをä¸æ–ã™ã‚‹Yæ–¹å‘ã®ç§»å‹•è·é›¢ const SWIPE_ABORT_Y_THRESHOLD = 75; // スワイプã§ãる最大ã®è·é›¢ -const MAX_SWIPE_DISTANCE = 150; +const MAX_SWIPE_DISTANCE = 120; // â–² ã—ãã„値 â–² // @@ -68,7 +68,6 @@ let startScreenY: number | null = null; const currentTabIndex = computed(() => props.tabs.findIndex(tab => tab.key === tabModel.value)); const pullDistance = ref(0); -const isSwiping = ref(false); const isSwipingForClass = ref(false); let swipeAborted = false; @@ -77,6 +76,8 @@ function touchStart(event: TouchEvent) { if (event.touches.length !== 1) return; + if (hasSomethingToDoWithXSwipe(event.target as HTMLElement)) return; + startScreenX = event.touches[0].screenX; startScreenY = event.touches[0].screenY; } @@ -90,6 +91,8 @@ function touchMove(event: TouchEvent) { if (swipeAborted) return; + if (hasSomethingToDoWithXSwipe(event.target as HTMLElement)) return; + let distanceX = event.touches[0].screenX - startScreenX; let distanceY = event.touches[0].screenY - startScreenY; @@ -139,6 +142,8 @@ function touchEnd(event: TouchEvent) { if (!isSwiping.value) return; + if (hasSomethingToDoWithXSwipe(event.target as HTMLElement)) return; + const distance = event.changedTouches[0].screenX - startScreenX; if (Math.abs(distance) > SWIPE_DISTANCE_THRESHOLD) { @@ -162,6 +167,24 @@ function touchEnd(event: TouchEvent) { }, 400); } +/** 横スワイプã«é–¢ä¸Žã™ã‚‹å¯èƒ½æ€§ã®ã‚ã‚‹è¦ç´ を調ã¹ã‚‹ */ +function hasSomethingToDoWithXSwipe(el: HTMLElement) { + if (['INPUT', 'TEXTAREA'].includes(el.tagName)) return true; + if (el.isContentEditable) return true; + if (el.scrollWidth > el.clientWidth) return true; + + const style = window.getComputedStyle(el); + if (['absolute', 'fixed', 'sticky'].includes(style.position)) return true; + if (['scroll', 'auto'].includes(style.overflowX)) return true; + if (style.touchAction === 'pan-x') return true; + + if (el.parentElement && el.parentElement !== rootEl.value) { + return hasSomethingToDoWithXSwipe(el.parentElement); + } else { + return false; + } +} + const transitionName = ref<'swipeAnimationLeft' | 'swipeAnimationRight' | undefined>(undefined); watch(tabModel, (newTab, oldTab) => { @@ -182,6 +205,7 @@ watch(tabModel, (newTab, oldTab) => { <style lang="scss" module> .transitionRoot { + touch-action: pan-y pinch-zoom; display: grid; grid-template-columns: 100%; overflow: clip; diff --git a/packages/frontend/src/components/MkPullToRefresh.vue b/packages/frontend/src/components/MkPullToRefresh.vue index 54ef117d77..e730d63afe 100644 --- a/packages/frontend/src/components/MkPullToRefresh.vue +++ b/packages/frontend/src/components/MkPullToRefresh.vue @@ -26,6 +26,7 @@ SPDX-License-Identifier: AGPL-3.0-only import { onMounted, onUnmounted, ref, shallowRef } from 'vue'; import { i18n } from '@/i18n.js'; import { getScrollContainer } from '@/scripts/scroll.js'; +import { isHorizontalSwipeSwiping } from '@/scripts/touch.js'; const SCROLL_STOP = 10; const MAX_PULL_DISTANCE = Infinity; @@ -129,7 +130,7 @@ function moveEnd() { function moving(event: TouchEvent | PointerEvent) { if (!isPullStart.value || isRefreshing.value || disabled) return; - if ((scrollEl?.scrollTop ?? 0) > (supportPointerDesktop ? SCROLL_STOP : SCROLL_STOP + pullDistance.value)) { + if ((scrollEl?.scrollTop ?? 0) > (supportPointerDesktop ? SCROLL_STOP : SCROLL_STOP + pullDistance.value) || isHorizontalSwipeSwiping.value) { pullDistance.value = 0; isPullEnd.value = false; moveEnd(); @@ -148,6 +149,10 @@ function moving(event: TouchEvent | PointerEvent) { if (event.cancelable) event.preventDefault(); } + if (pullDistance.value > SCROLL_STOP) { + event.stopPropagation(); + } + isPullEnd.value = pullDistance.value >= FIRE_THRESHOLD; } diff --git a/packages/frontend/src/scripts/touch.ts b/packages/frontend/src/scripts/touch.ts index 05f379e4aa..4fd7d500c4 100644 --- a/packages/frontend/src/scripts/touch.ts +++ b/packages/frontend/src/scripts/touch.ts @@ -3,6 +3,7 @@ * SPDX-License-Identifier: AGPL-3.0-only */ +import { ref } from 'vue'; import { deviceKind } from '@/scripts/device-kind.js'; const isTouchSupported = 'maxTouchPoints' in navigator && navigator.maxTouchPoints > 0; @@ -16,3 +17,6 @@ if (isTouchSupported && !isTouchUsing) { isTouchUsing = true; }, { passive: true }); } + +/** (MkHorizontalSwipe) 横スワイプä¸ã‹ï¼Ÿ */ +export const isHorizontalSwipeSwiping = ref(false); -- GitLab From 52bf808d8981a72693580d111f38d371f4bdf740 Mon Sep 17 00:00:00 2001 From: syuilo <Syuilotan@yahoo.co.jp> Date: Wed, 7 Feb 2024 20:52:23 +0900 Subject: [PATCH 25/40] typo --- packages/frontend/src/pages/about-misskey.vue | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/frontend/src/pages/about-misskey.vue b/packages/frontend/src/pages/about-misskey.vue index acaae9f1d7..5c00f94cc2 100644 --- a/packages/frontend/src/pages/about-misskey.vue +++ b/packages/frontend/src/pages/about-misskey.vue @@ -213,13 +213,13 @@ const patronsWithIcon = [{ icon: 'https://assets.misskey-hub.net/patrons/302dce2898dd457ba03c3f7dc037900b.jpg', }, { name: 'taichan', - icon: 'https://assets.misskey-hub.net/patrons/f981ab0159fb4e2c998e05f7263e1cd9.png', + icon: 'https://assets.misskey-hub.net/patrons/f981ab0159fb4e2c998e05f7263e1cd9.jpg', }, { name: '猫å‰ã‚ˆã‚ŠãŠ', - icon: 'https://assets.misskey-hub.net/patrons/a11518b3b34b4536a4bdd7178ba76a7b.png', + icon: 'https://assets.misskey-hub.net/patrons/a11518b3b34b4536a4bdd7178ba76a7b.jpg', }, { name: 'æœ‰æ –ã‹ãšã¿', - icon: 'https://assets.misskey-hub.net/patrons/9240e8e0ba294a8884143e99ac7ed6a0.png', + icon: 'https://assets.misskey-hub.net/patrons/9240e8e0ba294a8884143e99ac7ed6a0.jpg', }]; const patrons = [ -- GitLab From 82c34f7f45888d07f153c7ea0f313f0a231fc26c Mon Sep 17 00:00:00 2001 From: MeiMei <30769358+mei23@users.noreply.github.com> Date: Thu, 8 Feb 2024 13:16:22 +0900 Subject: [PATCH 26/40] =?UTF-8?q?Fix:=20Summaly=20proxy=E5=88=A9=E7=94=A8?= =?UTF-8?q?=E6=99=82=E3=81=AB=E3=83=97=E3=83=AC=E3=82=A4=E3=83=A4=E3=83=BC?= =?UTF-8?q?=E3=81=8C=E5=8B=95=E4=BD=9C=E3=81=97=E3=81=AA=E3=81=84=E3=81=93?= =?UTF-8?q?=E3=81=A8=E3=81=8C=E3=81=82=E3=82=8B=E3=81=AE=E3=82=92=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3=20(#13196)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix: Summaly proxy利用時ã«ãƒ—レイヤーãŒå‹•ä½œã—ãªã„ã“ã¨ãŒã‚ã‚‹ã®ã‚’ä¿®æ£ * CHANGELOG --- CHANGELOG.md | 1 + .../frontend/src/components/MkUrlPreview.vue | 2 +- packages/frontend/test/url-preview.test.ts | 28 +++++++++++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 652c7ea7c5..a32c557c94 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -74,6 +74,7 @@ - Fix: プãƒãƒ•ã‚£ãƒ¼ãƒ«ã‚’編集ã—ã¦ã‚‚リãƒãƒ¼ãƒ‰ã™ã‚‹ã¾ã§åæ˜ ã•ã‚Œãªã„å•é¡Œã‚’ä¿®æ£ - Fix: エラー画åƒURLã‚’è¨å®šã—ãŸå¾Œè§£é™¤ã™ã‚‹ã¨ï¼Œãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®ç”»åƒãŒè¡¨ç¤ºã•ã‚Œãªã„å•é¡Œã®ä¿®æ£ - Fix: MkCodeEditorã§è¡ŒãŒãšã‚Œã¦ã„ã£ã¦ã—ã¾ã†å•é¡Œã®ä¿®æ£ +- Fix: Summaly proxy利用時ã«ãƒ—レイヤーãŒå‹•ä½œã—ãªã„ã“ã¨ãŒã‚ã‚‹ã®ã‚’ä¿®æ£ #13196 ### Server - Enhance: 連åˆå…ˆã®ãƒ¬ãƒ¼ãƒˆãƒªãƒŸãƒƒãƒˆã«å¼•ã£ã‹ã‹ã£ãŸéš›ã«ãƒªãƒˆãƒ©ã‚¤ã™ã‚‹ã‚ˆã†ã«ãªã‚Šã¾ã—㟠diff --git a/packages/frontend/src/components/MkUrlPreview.vue b/packages/frontend/src/components/MkUrlPreview.vue index 2dcb5f226d..eb5e90ea9d 100644 --- a/packages/frontend/src/components/MkUrlPreview.vue +++ b/packages/frontend/src/components/MkUrlPreview.vue @@ -13,7 +13,7 @@ SPDX-License-Identifier: AGPL-3.0-only v-if="player.url.startsWith('http://') || player.url.startsWith('https://')" sandbox="allow-popups allow-scripts allow-storage-access-by-user-activation allow-same-origin" scrolling="no" - :allow="player.allow.join(';')" + :allow="player.allow == null ? 'autoplay;encrypted-media;fullscreen' : player.allow.filter(x => ['autoplay', 'clipboard-write', 'fullscreen', 'encrypted-media', 'picture-in-picture', 'web-share'].includes(x)).join(';')" :class="$style.playerIframe" :src="player.url + (player.url.match(/\?/) ? '&autoplay=1&auto_play=1' : '?autoplay=1&auto_play=1')" :style="{ border: 0 }" diff --git a/packages/frontend/test/url-preview.test.ts b/packages/frontend/test/url-preview.test.ts index 6cf8317c07..b7587754c6 100644 --- a/packages/frontend/test/url-preview.test.ts +++ b/packages/frontend/test/url-preview.test.ts @@ -116,6 +116,34 @@ describe('MkUrlPreview', () => { assert.strictEqual(iframe?.allow, 'fullscreen;web-share'); }); + test('A Summaly proxy response without allow falls back to the default', async () => { + const iframe = await renderAndOpenPreview({ + url: 'https://example.local', + player: { + url: 'https://example.local/player', + width: null, + height: null, + allow: undefined as any, + }, + }); + assert.exists(iframe, 'iframe should exist'); + assert.strictEqual(iframe?.allow, 'autoplay;encrypted-media;fullscreen'); + }); + + test('Filtering the allow list from the Summaly proxy', async () => { + const iframe = await renderAndOpenPreview({ + url: 'https://example.local', + player: { + url: 'https://example.local/player', + width: null, + height: null, + allow: ['autoplay', 'camera', 'fullscreen'], + }, + }); + assert.exists(iframe, 'iframe should exist'); + assert.strictEqual(iframe?.allow, 'autoplay;fullscreen'); + }); + test('Having a player width should keep the fixed aspect ratio', async () => { const iframe = await renderAndOpenPreview({ url: 'https://example.local', -- GitLab From 5299d17060d72f1a81edffccedff2f1c78a9c520 Mon Sep 17 00:00:00 2001 From: zyoshoka <107108195+zyoshoka@users.noreply.github.com> Date: Thu, 8 Feb 2024 13:28:49 +0900 Subject: [PATCH 27/40] test(frontend): migrate MSW in Storybook to v2 (#13195) --- CONTRIBUTING.md | 9 +- packages/frontend/.storybook/mocks.ts | 32 +++-- packages/frontend/package.json | 4 +- .../components/MkAbuseReport.stories.impl.ts | 8 +- .../MkAbuseReportWindow.stories.impl.ts | 8 +- .../components/MkAchievements.stories.impl.ts | 10 +- .../components/MkAutocomplete.stories.impl.ts | 14 +- .../src/components/MkAvatars.stories.impl.ts | 8 +- .../components/MkInviteCode.stories.impl.ts | 6 +- .../MkUserSetupDialog.Follow.stories.impl.ts | 14 +- .../MkUserSetupDialog.stories.impl.ts | 14 +- .../components/global/MkUrl.stories.impl.ts | 8 +- .../src/pages/user/home.stories.impl.ts | 24 ++-- pnpm-lock.yaml | 124 ++++++++---------- 14 files changed, 140 insertions(+), 143 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7f6c1f4f82..ac0a1ba3c1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -286,18 +286,17 @@ export const argTypes = { min: 1, max: 4, }, + }, }; ``` Also, you can use msw to mock API requests in the storybook. Creating a `MyComponent.stories.msw.ts` file to define the mock handlers. ```ts -import { rest } from 'msw'; +import { HttpResponse, http } from 'msw'; export const handlers = [ - rest.post('/api/notes/timeline', (req, res, ctx) => { - return res( - ctx.json([]), - ); + http.post('/api/notes/timeline', ({ request }) => { + return HttpResponse.json([]); }), ]; ``` diff --git a/packages/frontend/.storybook/mocks.ts b/packages/frontend/.storybook/mocks.ts index 80e5157c5a..f0feff9f78 100644 --- a/packages/frontend/.storybook/mocks.ts +++ b/packages/frontend/.storybook/mocks.ts @@ -3,7 +3,7 @@ * SPDX-License-Identifier: AGPL-3.0-only */ -import { type SharedOptions, rest } from 'msw'; +import { type SharedOptions, http, HttpResponse } from 'msw'; export const onUnhandledRequest = ((req, print) => { if (req.url.hostname !== 'localhost' || /^\/(?:client-assets\/|fluent-emojis?\/|iframe.html$|node_modules\/|src\/|sb-|static-assets\/|vite\/)/.test(req.url.pathname)) { @@ -13,19 +13,31 @@ export const onUnhandledRequest = ((req, print) => { }) satisfies SharedOptions['onUnhandledRequest']; export const commonHandlers = [ - rest.get('/fluent-emoji/:codepoints.png', async (req, res, ctx) => { - const { codepoints } = req.params; + http.get('/fluent-emoji/:codepoints.png', async ({ params }) => { + const { codepoints } = params; const value = await fetch(`https://raw.githubusercontent.com/misskey-dev/emojis/main/dist/${codepoints}.png`).then((response) => response.blob()); - return res(ctx.set('Content-Type', 'image/png'), ctx.body(value)); + return new HttpResponse(value, { + headers: { + 'Content-Type': 'image/png', + }, + }); }), - rest.get('/fluent-emojis/:codepoints.png', async (req, res, ctx) => { - const { codepoints } = req.params; + http.get('/fluent-emojis/:codepoints.png', async ({ params }) => { + const { codepoints } = params; const value = await fetch(`https://raw.githubusercontent.com/misskey-dev/emojis/main/dist/${codepoints}.png`).then((response) => response.blob()); - return res(ctx.set('Content-Type', 'image/png'), ctx.body(value)); + return new HttpResponse(value, { + headers: { + 'Content-Type': 'image/png', + }, + }); }), - rest.get('/twemoji/:codepoints.svg', async (req, res, ctx) => { - const { codepoints } = req.params; + http.get('/twemoji/:codepoints.svg', async ({ params }) => { + const { codepoints } = params; const value = await fetch(`https://unpkg.com/@discordapp/twemoji@15.0.2/dist/svg/${codepoints}.svg`).then((response) => response.blob()); - return res(ctx.set('Content-Type', 'image/svg+xml'), ctx.body(value)); + return new HttpResponse(value, { + headers: { + 'Content-Type': 'image/svg+xml', + }, + }); }), ]; diff --git a/packages/frontend/package.json b/packages/frontend/package.json index d614f75886..9e88c6c036 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -122,8 +122,8 @@ "happy-dom": "10.0.3", "intersection-observer": "0.12.2", "micromatch": "4.0.5", - "msw": "2.1.2", - "msw-storybook-addon": "1.10.0", + "msw": "2.1.7", + "msw-storybook-addon": "2.0.0-beta.1", "nodemon": "3.0.3", "prettier": "3.2.4", "react": "18.2.0", diff --git a/packages/frontend/src/components/MkAbuseReport.stories.impl.ts b/packages/frontend/src/components/MkAbuseReport.stories.impl.ts index 77e7c84d5c..dc2697f25c 100644 --- a/packages/frontend/src/components/MkAbuseReport.stories.impl.ts +++ b/packages/frontend/src/components/MkAbuseReport.stories.impl.ts @@ -6,7 +6,7 @@ /* eslint-disable @typescript-eslint/explicit-function-return-type */ import { action } from '@storybook/addon-actions'; import { StoryObj } from '@storybook/vue3'; -import { rest } from 'msw'; +import { HttpResponse, http } from 'msw'; import { abuseUserReport } from '../../.storybook/fakes.js'; import { commonHandlers } from '../../.storybook/mocks.js'; import MkAbuseReport from './MkAbuseReport.vue'; @@ -44,9 +44,9 @@ export const Default = { msw: { handlers: [ ...commonHandlers, - rest.post('/api/admin/resolve-abuse-user-report', async (req, res, ctx) => { - action('POST /api/admin/resolve-abuse-user-report')(await req.json()); - return res(ctx.json({})); + http.post('/api/admin/resolve-abuse-user-report', async ({ request }) => { + action('POST /api/admin/resolve-abuse-user-report')(await request.json()); + return HttpResponse.json({}); }), ], }, diff --git a/packages/frontend/src/components/MkAbuseReportWindow.stories.impl.ts b/packages/frontend/src/components/MkAbuseReportWindow.stories.impl.ts index dc842b3d1b..771452cb5f 100644 --- a/packages/frontend/src/components/MkAbuseReportWindow.stories.impl.ts +++ b/packages/frontend/src/components/MkAbuseReportWindow.stories.impl.ts @@ -6,7 +6,7 @@ /* eslint-disable @typescript-eslint/explicit-function-return-type */ import { action } from '@storybook/addon-actions'; import { StoryObj } from '@storybook/vue3'; -import { rest } from 'msw'; +import { HttpResponse, http } from 'msw'; import { userDetailed } from '../../.storybook/fakes.js'; import { commonHandlers } from '../../.storybook/mocks.js'; import MkAbuseReportWindow from './MkAbuseReportWindow.vue'; @@ -44,9 +44,9 @@ export const Default = { msw: { handlers: [ ...commonHandlers, - rest.post('/api/users/report-abuse', async (req, res, ctx) => { - action('POST /api/users/report-abuse')(await req.json()); - return res(ctx.json({})); + http.post('/api/users/report-abuse', async ({ request }) => { + action('POST /api/users/report-abuse')(await request.json()); + return HttpResponse.json({}); }), ], }, diff --git a/packages/frontend/src/components/MkAchievements.stories.impl.ts b/packages/frontend/src/components/MkAchievements.stories.impl.ts index 6d972467b1..81e9529de2 100644 --- a/packages/frontend/src/components/MkAchievements.stories.impl.ts +++ b/packages/frontend/src/components/MkAchievements.stories.impl.ts @@ -5,7 +5,7 @@ /* eslint-disable @typescript-eslint/explicit-function-return-type */ import { StoryObj } from '@storybook/vue3'; -import { rest } from 'msw'; +import { HttpResponse, http } from 'msw'; import { userDetailed } from '../../.storybook/fakes.js'; import { commonHandlers } from '../../.storybook/mocks.js'; import MkAchievements from './MkAchievements.vue'; @@ -39,8 +39,8 @@ export const Empty = { msw: { handlers: [ ...commonHandlers, - rest.post('/api/users/achievements', (req, res, ctx) => { - return res(ctx.json([])); + http.post('/api/users/achievements', () => { + return HttpResponse.json([]); }), ], }, @@ -52,8 +52,8 @@ export const All = { msw: { handlers: [ ...commonHandlers, - rest.post('/api/users/achievements', (req, res, ctx) => { - return res(ctx.json(ACHIEVEMENT_TYPES.map((name) => ({ name, unlockedAt: 0 })))); + http.post('/api/users/achievements', () => { + return HttpResponse.json(ACHIEVEMENT_TYPES.map((name) => ({ name, unlockedAt: 0 }))); }), ], }, diff --git a/packages/frontend/src/components/MkAutocomplete.stories.impl.ts b/packages/frontend/src/components/MkAutocomplete.stories.impl.ts index 969519386f..3ca8c5b864 100644 --- a/packages/frontend/src/components/MkAutocomplete.stories.impl.ts +++ b/packages/frontend/src/components/MkAutocomplete.stories.impl.ts @@ -8,7 +8,7 @@ import { action } from '@storybook/addon-actions'; import { expect } from '@storybook/jest'; import { userEvent, waitFor, within } from '@storybook/testing-library'; import { StoryObj } from '@storybook/vue3'; -import { rest } from 'msw'; +import { HttpResponse, http } from 'msw'; import { userDetailed } from '../../.storybook/fakes.js'; import { commonHandlers } from '../../.storybook/mocks.js'; import MkAutocomplete from './MkAutocomplete.vue'; @@ -99,11 +99,11 @@ export const User = { msw: { handlers: [ ...commonHandlers, - rest.post('/api/users/search-by-username-and-host', (req, res, ctx) => { - return res(ctx.json([ + http.post('/api/users/search-by-username-and-host', () => { + return HttpResponse.json([ userDetailed('44', 'mizuki', 'misskey-hub.net', 'Mizuki'), userDetailed('49', 'momoko', 'misskey-hub.net', 'Momoko'), - ])); + ]); }), ], }, @@ -132,12 +132,12 @@ export const Hashtag = { msw: { handlers: [ ...commonHandlers, - rest.post('/api/hashtags/search', (req, res, ctx) => { - return res(ctx.json([ + http.post('/api/hashtags/search', () => { + return HttpResponse.json([ '気象è¦å ±æ³¨æ„å ±', '気象è¦å ±', 'æ°—è±¡æƒ…å ±', - ])); + ]); }), ], }, diff --git a/packages/frontend/src/components/MkAvatars.stories.impl.ts b/packages/frontend/src/components/MkAvatars.stories.impl.ts index d41b64695f..a9b4540ca9 100644 --- a/packages/frontend/src/components/MkAvatars.stories.impl.ts +++ b/packages/frontend/src/components/MkAvatars.stories.impl.ts @@ -5,7 +5,7 @@ /* eslint-disable @typescript-eslint/explicit-function-return-type */ import { StoryObj } from '@storybook/vue3'; -import { rest } from 'msw'; +import { HttpResponse, http } from 'msw'; import { userDetailed } from '../../.storybook/fakes.js'; import { commonHandlers } from '../../.storybook/mocks.js'; import MkAvatars from './MkAvatars.vue'; @@ -38,12 +38,12 @@ export const Default = { msw: { handlers: [ ...commonHandlers, - rest.post('/api/users/show', (req, res, ctx) => { - return res(ctx.json([ + http.post('/api/users/show', () => { + return HttpResponse.json([ userDetailed('17'), userDetailed('20'), userDetailed('18'), - ])); + ]); }), ], }, diff --git a/packages/frontend/src/components/MkInviteCode.stories.impl.ts b/packages/frontend/src/components/MkInviteCode.stories.impl.ts index 2ea32dd3b6..2abe1a8770 100644 --- a/packages/frontend/src/components/MkInviteCode.stories.impl.ts +++ b/packages/frontend/src/components/MkInviteCode.stories.impl.ts @@ -5,7 +5,7 @@ /* eslint-disable @typescript-eslint/explicit-function-return-type */ import { StoryObj } from '@storybook/vue3'; -import { rest } from 'msw'; +import { HttpResponse, http } from 'msw'; import { userDetailed, inviteCode } from '../../.storybook/fakes.js'; import { commonHandlers } from '../../.storybook/mocks.js'; import MkInviteCode from './MkInviteCode.vue'; @@ -39,8 +39,8 @@ export const Default = { msw: { handlers: [ ...commonHandlers, - rest.post('/api/users/show', (req, res, ctx) => { - return res(ctx.json(userDetailed(req.params.userId as string))); + http.post('/api/users/show', ({ params }) => { + return HttpResponse.json(userDetailed(params.userId as string)); }), ], }, diff --git a/packages/frontend/src/components/MkUserSetupDialog.Follow.stories.impl.ts b/packages/frontend/src/components/MkUserSetupDialog.Follow.stories.impl.ts index 45c7da40ce..c1b380bd1b 100644 --- a/packages/frontend/src/components/MkUserSetupDialog.Follow.stories.impl.ts +++ b/packages/frontend/src/components/MkUserSetupDialog.Follow.stories.impl.ts @@ -5,7 +5,7 @@ /* eslint-disable @typescript-eslint/explicit-function-return-type */ import { StoryObj } from '@storybook/vue3'; -import { rest } from 'msw'; +import { HttpResponse, http } from 'msw'; import { commonHandlers } from '../../.storybook/mocks.js'; import { userDetailed } from '../../.storybook/fakes.js'; import MkUserSetupDialog_Follow from './MkUserSetupDialog.Follow.vue'; @@ -38,17 +38,17 @@ export const Default = { msw: { handlers: [ ...commonHandlers, - rest.post('/api/users', (req, res, ctx) => { - return res(ctx.json([ + http.post('/api/users', () => { + return HttpResponse.json([ userDetailed('44'), userDetailed('49'), - ])); + ]); }), - rest.post('/api/pinned-users', (req, res, ctx) => { - return res(ctx.json([ + http.post('/api/pinned-users', () => { + return HttpResponse.json([ userDetailed('44'), userDetailed('49'), - ])); + ]); }), ], }, diff --git a/packages/frontend/src/components/MkUserSetupDialog.stories.impl.ts b/packages/frontend/src/components/MkUserSetupDialog.stories.impl.ts index 5182db12b2..7177d256e1 100644 --- a/packages/frontend/src/components/MkUserSetupDialog.stories.impl.ts +++ b/packages/frontend/src/components/MkUserSetupDialog.stories.impl.ts @@ -5,7 +5,7 @@ /* eslint-disable @typescript-eslint/explicit-function-return-type */ import { StoryObj } from '@storybook/vue3'; -import { rest } from 'msw'; +import { HttpResponse, http } from 'msw'; import { commonHandlers } from '../../.storybook/mocks.js'; import { userDetailed } from '../../.storybook/fakes.js'; import MkUserSetupDialog from './MkUserSetupDialog.vue'; @@ -38,17 +38,17 @@ export const Default = { msw: { handlers: [ ...commonHandlers, - rest.post('/api/users', (req, res, ctx) => { - return res(ctx.json([ + http.post('/api/users', () => { + return HttpResponse.json([ userDetailed('44'), userDetailed('49'), - ])); + ]); }), - rest.post('/api/pinned-users', (req, res, ctx) => { - return res(ctx.json([ + http.post('/api/pinned-users', () => { + return HttpResponse.json([ userDetailed('44'), userDetailed('49'), - ])); + ]); }), ], }, diff --git a/packages/frontend/src/components/global/MkUrl.stories.impl.ts b/packages/frontend/src/components/global/MkUrl.stories.impl.ts index b35b6114fd..d053069087 100644 --- a/packages/frontend/src/components/global/MkUrl.stories.impl.ts +++ b/packages/frontend/src/components/global/MkUrl.stories.impl.ts @@ -7,7 +7,7 @@ import { expect } from '@storybook/jest'; import { userEvent, waitFor, within } from '@storybook/testing-library'; import { StoryObj } from '@storybook/vue3'; -import { rest } from 'msw'; +import { HttpResponse, http } from 'msw'; import { commonHandlers } from '../../../.storybook/mocks.js'; import MkUrl from './MkUrl.vue'; export const Default = { @@ -59,8 +59,8 @@ export const Default = { msw: { handlers: [ ...commonHandlers, - rest.get('/url', (req, res, ctx) => { - return res(ctx.json({ + http.get('/url', () => { + return HttpResponse.json({ title: 'Misskey Hub', icon: 'https://misskey-hub.net/favicon.ico', description: 'Misskeyã¯ã‚ªãƒ¼ãƒ—ンソースã®åˆ†æ•£åž‹ã‚½ãƒ¼ã‚·ãƒ£ãƒ«ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚ングプラットフォームã§ã™ã€‚', @@ -74,7 +74,7 @@ export const Default = { sitename: 'misskey-hub.net', sensitive: false, url: 'https://misskey-hub.net/', - })); + }); }), ], }, diff --git a/packages/frontend/src/pages/user/home.stories.impl.ts b/packages/frontend/src/pages/user/home.stories.impl.ts index a2ef5d50d1..1e67d96c71 100644 --- a/packages/frontend/src/pages/user/home.stories.impl.ts +++ b/packages/frontend/src/pages/user/home.stories.impl.ts @@ -5,7 +5,7 @@ /* eslint-disable @typescript-eslint/explicit-function-return-type */ import { StoryObj } from '@storybook/vue3'; -import { rest } from 'msw'; +import { HttpResponse, http } from 'msw'; import { userDetailed } from '../../../.storybook/fakes.js'; import { commonHandlers } from '../../../.storybook/mocks.js'; import home_ from './home.vue'; @@ -39,12 +39,13 @@ export const Default = { msw: { handlers: [ ...commonHandlers, - rest.post('/api/users/notes', (req, res, ctx) => { - return res(ctx.json([])); + http.post('/api/users/notes', () => { + return HttpResponse.json([]); }), - rest.get('/api/charts/user/notes', (req, res, ctx) => { - const length = Math.max(Math.min(parseInt(req.url.searchParams.get('limit') ?? '30', 10), 1), 300); - return res(ctx.json({ + http.get('/api/charts/user/notes', ({ request }) => { + const url = new URL(request.url); + const length = Math.max(Math.min(parseInt(url.searchParams.get('limit') ?? '30', 10), 1), 300); + return HttpResponse.json({ total: Array.from({ length }, () => 0), inc: Array.from({ length }, () => 0), dec: Array.from({ length }, () => 0), @@ -54,11 +55,12 @@ export const Default = { renote: Array.from({ length }, () => 0), withFile: Array.from({ length }, () => 0), }, - })); + }); }), - rest.get('/api/charts/user/pv', (req, res, ctx) => { - const length = Math.max(Math.min(parseInt(req.url.searchParams.get('limit') ?? '30', 10), 1), 300); - return res(ctx.json({ + http.get('/api/charts/user/pv', ({ request }) => { + const url = new URL(request.url); + const length = Math.max(Math.min(parseInt(url.searchParams.get('limit') ?? '30', 10), 1), 300); + return HttpResponse.json({ upv: { user: Array.from({ length }, () => 0), visitor: Array.from({ length }, () => 0), @@ -67,7 +69,7 @@ export const Default = { user: Array.from({ length }, () => 0), visitor: Array.from({ length }, () => 0), }, - })); + }); }), ], }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0561e8b01e..291ec305c7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -978,11 +978,11 @@ importers: specifier: 4.0.5 version: 4.0.5 msw: - specifier: 2.1.2 - version: 2.1.2(typescript@5.3.3) + specifier: 2.1.7 + version: 2.1.7(typescript@5.3.3) msw-storybook-addon: - specifier: 1.10.0 - version: 1.10.0(msw@2.1.2) + specifier: 2.0.0-beta.1 + version: 2.0.0-beta.1(msw@2.1.7) nodemon: specifier: 3.0.3 version: 3.0.3 @@ -1909,7 +1909,7 @@ packages: '@babel/traverse': 7.22.11 '@babel/types': 7.22.17 convert-source-map: 1.9.0 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 @@ -1932,7 +1932,7 @@ packages: '@babel/traverse': 7.23.5 '@babel/types': 7.23.5 convert-source-map: 2.0.0 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 @@ -2034,7 +2034,7 @@ packages: '@babel/core': 7.23.5 '@babel/helper-compilation-targets': 7.22.15 '@babel/helper-plugin-utils': 7.22.5 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) lodash.debounce: 4.0.8 resolve: 1.22.8 transitivePeerDependencies: @@ -3433,7 +3433,7 @@ packages: '@babel/helper-split-export-declaration': 7.22.6 '@babel/parser': 7.23.5 '@babel/types': 7.22.17 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) globals: 11.12.0 transitivePeerDependencies: - supports-color @@ -3451,7 +3451,7 @@ packages: '@babel/helper-split-export-declaration': 7.22.6 '@babel/parser': 7.23.6 '@babel/types': 7.23.5 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) globals: 11.12.0 transitivePeerDependencies: - supports-color @@ -3521,12 +3521,6 @@ packages: cookie: 0.5.0 dev: true - /@bundled-es-modules/js-levenshtein@2.0.1: - resolution: {integrity: sha512-DERMS3yfbAljKsQc0U2wcqGKUWpdFjwqWuoMugEJlqBnKO180/n+4SR/J8MRDt1AN48X1ovgoD9KrdVXcaa3Rg==} - dependencies: - js-levenshtein: 1.1.6 - dev: true - /@bundled-es-modules/statuses@1.0.1: resolution: {integrity: sha512-yn7BklA5acgcBr+7w064fGV+SGIFySjCKpqjcWgBAIfrAkY+4GQTJJHQMeT3V/sgz23VTEVV8TtOmkvJAhFVfg==} dependencies: @@ -4158,7 +4152,7 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: ajv: 6.12.6 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) espree: 9.6.1 globals: 13.19.0 ignore: 5.2.4 @@ -4175,7 +4169,7 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: ajv: 6.12.6 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) espree: 9.6.1 globals: 13.19.0 ignore: 5.2.4 @@ -4410,7 +4404,7 @@ packages: engines: {node: '>=10.10.0'} dependencies: '@humanwhocodes/object-schema': 2.0.1 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) minimatch: 3.1.2 transitivePeerDependencies: - supports-color @@ -4974,8 +4968,8 @@ packages: engines: {node: '>=18'} dev: true - /@mswjs/interceptors@0.25.14: - resolution: {integrity: sha512-2dnIxl+obqIqjoPXTFldhe6pcdOrqiz+GcLaQQ6hmL02OldAF7nIC+rUgTWm+iF6lvmyCVhFFqbgbapNhR8eag==} + /@mswjs/interceptors@0.25.16: + resolution: {integrity: sha512-8QC8JyKztvoGAdPgyZy49c9vSHHAZjHagwl4RY9E8carULk8ym3iTaiawrT1YoLF/qb449h48f71XDPgkUSOUg==} engines: {node: '>=18'} dependencies: '@open-draft/deferred-promise': 2.2.0 @@ -8207,10 +8201,6 @@ packages: pretty-format: 29.7.0 dev: true - /@types/js-levenshtein@1.1.3: - resolution: {integrity: sha512-jd+Q+sD20Qfu9e2aEXogiO3vpOC1PYJOUdyN9gvs4Qrvkg4wF43L5OhqrPeokdv8TL0/mXoYfpkcoGZMNN2pkQ==} - dev: true - /@types/js-yaml@4.0.9: resolution: {integrity: sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==} dev: true @@ -8593,7 +8583,7 @@ packages: '@typescript-eslint/type-utils': 6.11.0(eslint@8.53.0)(typescript@5.3.3) '@typescript-eslint/utils': 6.11.0(eslint@8.53.0)(typescript@5.3.3) '@typescript-eslint/visitor-keys': 6.11.0 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) eslint: 8.53.0 graphemer: 1.4.0 ignore: 5.2.4 @@ -8622,7 +8612,7 @@ packages: '@typescript-eslint/type-utils': 6.18.1(eslint@8.56.0)(typescript@5.3.3) '@typescript-eslint/utils': 6.18.1(eslint@8.56.0)(typescript@5.3.3) '@typescript-eslint/visitor-keys': 6.18.1 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) eslint: 8.56.0 graphemer: 1.4.0 ignore: 5.2.4 @@ -8648,7 +8638,7 @@ packages: '@typescript-eslint/types': 6.11.0 '@typescript-eslint/typescript-estree': 6.11.0(typescript@5.3.3) '@typescript-eslint/visitor-keys': 6.11.0 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) eslint: 8.53.0 typescript: 5.3.3 transitivePeerDependencies: @@ -8669,7 +8659,7 @@ packages: '@typescript-eslint/types': 6.18.1 '@typescript-eslint/typescript-estree': 6.18.1(typescript@5.3.3) '@typescript-eslint/visitor-keys': 6.18.1 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) eslint: 8.56.0 typescript: 5.3.3 transitivePeerDependencies: @@ -8704,7 +8694,7 @@ packages: dependencies: '@typescript-eslint/typescript-estree': 6.11.0(typescript@5.3.3) '@typescript-eslint/utils': 6.11.0(eslint@8.53.0)(typescript@5.3.3) - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) eslint: 8.53.0 ts-api-utils: 1.0.1(typescript@5.3.3) typescript: 5.3.3 @@ -8724,7 +8714,7 @@ packages: dependencies: '@typescript-eslint/typescript-estree': 6.18.1(typescript@5.3.3) '@typescript-eslint/utils': 6.18.1(eslint@8.56.0)(typescript@5.3.3) - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) eslint: 8.56.0 ts-api-utils: 1.0.1(typescript@5.3.3) typescript: 5.3.3 @@ -8753,7 +8743,7 @@ packages: dependencies: '@typescript-eslint/types': 6.11.0 '@typescript-eslint/visitor-keys': 6.11.0 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) globby: 11.1.0 is-glob: 4.0.3 semver: 7.5.4 @@ -8774,7 +8764,7 @@ packages: dependencies: '@typescript-eslint/types': 6.18.1 '@typescript-eslint/visitor-keys': 6.18.1 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) globby: 11.1.0 is-glob: 4.0.3 minimatch: 9.0.3 @@ -9215,7 +9205,7 @@ packages: engines: {node: '>= 6.0.0'} requiresBuild: true dependencies: - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) transitivePeerDependencies: - supports-color @@ -9223,7 +9213,7 @@ packages: resolution: {integrity: sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==} engines: {node: '>= 14'} dependencies: - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) transitivePeerDependencies: - supports-color dev: false @@ -9605,7 +9595,7 @@ packages: resolution: {integrity: sha512-TAlMYvOuwGyLK3PfBb5WKBXZmXz2fVCgv23d6zZFdle/q3gPjmxBaeuC0pY0Dzs5PWMSgfqqEZkrye19GlDTgw==} dependencies: archy: 1.0.0 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) fastq: 1.15.0 transitivePeerDependencies: - supports-color @@ -11057,6 +11047,7 @@ packages: dependencies: ms: 2.1.2 supports-color: 5.5.0 + dev: true /debug@4.3.4(supports-color@8.1.1): resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} @@ -11069,7 +11060,6 @@ packages: dependencies: ms: 2.1.2 supports-color: 8.1.1 - dev: true /decamelize-keys@1.1.1: resolution: {integrity: sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==} @@ -11286,7 +11276,7 @@ packages: hasBin: true dependencies: address: 1.2.2 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) transitivePeerDependencies: - supports-color dev: true @@ -11610,7 +11600,7 @@ packages: peerDependencies: esbuild: '>=0.12 <1' dependencies: - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) esbuild: 0.18.20 transitivePeerDependencies: - supports-color @@ -11919,7 +11909,7 @@ packages: ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.3 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) doctrine: 3.0.0 escape-string-regexp: 4.0.0 eslint-scope: 7.2.2 @@ -11966,7 +11956,7 @@ packages: ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.3 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) doctrine: 3.0.0 escape-string-regexp: 4.0.0 eslint-scope: 7.2.2 @@ -12597,7 +12587,7 @@ packages: debug: optional: true dependencies: - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) /for-each@0.3.3: resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} @@ -13153,6 +13143,7 @@ packages: /has-flag@3.0.0: resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} engines: {node: '>=4'} + dev: true /has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} @@ -13290,7 +13281,7 @@ packages: engines: {node: '>= 14'} dependencies: agent-base: 7.1.0 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) transitivePeerDependencies: - supports-color dev: false @@ -13350,7 +13341,7 @@ packages: engines: {node: '>= 6.0.0'} dependencies: agent-base: 5.1.1 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) transitivePeerDependencies: - supports-color dev: true @@ -13360,7 +13351,7 @@ packages: engines: {node: '>= 6'} dependencies: agent-base: 6.0.2 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) transitivePeerDependencies: - supports-color @@ -13369,7 +13360,7 @@ packages: engines: {node: '>= 14'} dependencies: agent-base: 7.1.0 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) transitivePeerDependencies: - supports-color dev: false @@ -13529,7 +13520,7 @@ packages: dependencies: '@ioredis/commands': 1.2.0 cluster-key-slot: 1.1.2 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) denque: 2.1.0 lodash.defaults: 4.2.0 lodash.isarguments: 3.1.0 @@ -13975,7 +13966,7 @@ packages: resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} engines: {node: '>=10'} dependencies: - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) istanbul-lib-coverage: 3.2.2 source-map: 0.6.1 transitivePeerDependencies: @@ -14532,11 +14523,6 @@ packages: nopt: 6.0.0 dev: true - /js-levenshtein@1.1.6: - resolution: {integrity: sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==} - engines: {node: '>=0.10.0'} - dev: true - /js-stringify@1.0.2: resolution: {integrity: sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g==} @@ -15485,17 +15471,17 @@ packages: msgpackr-extract: 3.0.2 dev: false - /msw-storybook-addon@1.10.0(msw@2.1.2): - resolution: {integrity: sha512-soCTMTf7DnLeaMnFHPrtVgbyeFTJALVvnDHpzzXpJad+HOzJgQdwU4EAzVfDs1q+X5cVEgxOdAhSMC7ljvnSXg==} + /msw-storybook-addon@2.0.0-beta.1(msw@2.1.7): + resolution: {integrity: sha512-DRyIAMK3waEfC+pKTyiIq68OZfiZ4WZGUVAn6J4YwCRpDdoCvLzzoC2spN0Jgegx4dEmJ7589ATnS14NxqeBig==} peerDependencies: - msw: '>=0.35.0 <2.0.0' + msw: ^2.0.0 dependencies: is-node-process: 1.2.0 - msw: 2.1.2(typescript@5.3.3) + msw: 2.1.7(typescript@5.3.3) dev: true - /msw@2.1.2(typescript@5.3.3): - resolution: {integrity: sha512-7OKbeZNFQTCPFe++o+zZHMkQRIUi4D/5N1dAD3lOlaV+2Wpv3Srp3VFrFeH+2ftZJbb4jAiC0caZoW1efr80KQ==} + /msw@2.1.7(typescript@5.3.3): + resolution: {integrity: sha512-yTIYqEMqDSrdbVMrfmqP6rTKQsnIbglTvVmAHDWwNegyXPXRcV+RjsaFEqubRS266gwWCDLm9YdOkWSKLdDvJQ==} engines: {node: '>=18'} hasBin: true requiresBuild: true @@ -15506,13 +15492,11 @@ packages: optional: true dependencies: '@bundled-es-modules/cookie': 2.0.0 - '@bundled-es-modules/js-levenshtein': 2.0.1 '@bundled-es-modules/statuses': 1.0.1 '@mswjs/cookies': 1.1.0 - '@mswjs/interceptors': 0.25.14 + '@mswjs/interceptors': 0.25.16 '@open-draft/until': 2.1.0 '@types/cookie': 0.6.0 - '@types/js-levenshtein': 1.1.3 '@types/statuses': 2.0.4 chalk: 4.1.2 chokidar: 3.5.3 @@ -15520,7 +15504,6 @@ packages: headers-polyfill: 4.0.2 inquirer: 8.2.5 is-node-process: 1.2.0 - js-levenshtein: 1.1.6 outvariant: 1.4.2 path-to-regexp: 6.2.1 strict-event-emitter: 0.5.1 @@ -17286,7 +17269,7 @@ packages: engines: {node: '>=8.16.0'} dependencies: '@types/mime-types': 2.1.4 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) extract-zip: 1.7.0 https-proxy-agent: 4.0.0 mime: 2.6.0 @@ -18287,7 +18270,7 @@ packages: dependencies: '@hapi/hoek': 10.0.1 '@hapi/wreck': 18.0.1 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) joi: 17.7.0 transitivePeerDependencies: - supports-color @@ -18487,7 +18470,7 @@ packages: engines: {node: '>= 14'} dependencies: agent-base: 7.1.0 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) socks: 2.7.1 transitivePeerDependencies: - supports-color @@ -18640,7 +18623,7 @@ packages: arg: 5.0.2 bluebird: 3.7.2 check-more-types: 2.24.0 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) execa: 5.1.1 lazy-ass: 1.6.0 ps-tree: 1.2.0 @@ -18898,6 +18881,7 @@ packages: engines: {node: '>=4'} dependencies: has-flag: 3.0.0 + dev: true /supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} @@ -19518,7 +19502,7 @@ packages: chalk: 4.1.2 cli-highlight: 2.1.11 dayjs: 1.11.10 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) dotenv: 16.0.3 glob: 10.3.10 ioredis: 5.3.2 @@ -19878,7 +19862,7 @@ packages: hasBin: true dependencies: cac: 6.7.14 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) mlly: 1.5.0 pathe: 1.1.2 picocolors: 1.0.0 @@ -19990,7 +19974,7 @@ packages: acorn-walk: 8.3.2 cac: 6.7.14 chai: 4.3.10 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) happy-dom: 10.0.3 local-pkg: 0.4.3 magic-string: 0.30.5 @@ -20064,7 +20048,7 @@ packages: peerDependencies: eslint: '>=6.0.0' dependencies: - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.4(supports-color@8.1.1) eslint: 8.56.0 eslint-scope: 7.2.2 eslint-visitor-keys: 3.4.3 -- GitLab From 90b633b5a629aa16444bfa12fdb4d57f92fc9f4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=8B=E3=81=A3=E3=81=93=E3=81=8B=E3=82=8A?= <67428053+kakkokari-gtyih@users.noreply.github.com> Date: Thu, 8 Feb 2024 14:15:56 +0900 Subject: [PATCH 28/40] fix(frontend) misskey-js type (#13202) --- packages/frontend/src/components/MkTimeline.vue | 9 ++++----- .../frontend/src/components/MkUserSetupDialog.Follow.vue | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/packages/frontend/src/components/MkTimeline.vue b/packages/frontend/src/components/MkTimeline.vue index 3c77878379..8b6d1bd8b6 100644 --- a/packages/frontend/src/components/MkTimeline.vue +++ b/packages/frontend/src/components/MkTimeline.vue @@ -18,8 +18,7 @@ SPDX-License-Identifier: AGPL-3.0-only <script lang="ts" setup> import { computed, watch, onUnmounted, provide, ref, shallowRef } from 'vue'; -import Misskey from 'misskey-js'; -import { Connection } from 'misskey-js/built/streaming.js'; +import * as Misskey from 'misskey-js'; import MkNotes from '@/components/MkNotes.vue'; import MkPullToRefresh from '@/components/MkPullToRefresh.vue'; import { useStream } from '@/stream.js'; @@ -87,8 +86,8 @@ function prepend(note) { } } -let connection: Connection; -let connection2: Connection; +let connection: Misskey.ChannelConnection | null = null; +let connection2: Misskey.ChannelConnection | null = null; let paginationQuery: Paging | null = null; const stream = useStream(); @@ -151,7 +150,7 @@ function connectChannel() { roleId: props.role, }); } - if (props.src !== 'directs' && props.src !== 'mentions') connection.on('note', prepend); + if (props.src !== 'directs' && props.src !== 'mentions') connection?.on('note', prepend); } function disconnectChannel() { diff --git a/packages/frontend/src/components/MkUserSetupDialog.Follow.vue b/packages/frontend/src/components/MkUserSetupDialog.Follow.vue index 46459df6a6..86a5c812bd 100644 --- a/packages/frontend/src/components/MkUserSetupDialog.Follow.vue +++ b/packages/frontend/src/components/MkUserSetupDialog.Follow.vue @@ -34,7 +34,7 @@ SPDX-License-Identifier: AGPL-3.0-only </template> <script lang="ts" setup> -import Misskey from 'misskey-js'; +import * as Misskey from 'misskey-js'; import { i18n } from '@/i18n.js'; import MkFolder from '@/components/MkFolder.vue'; import XUser from '@/components/MkUserSetupDialog.User.vue'; -- GitLab From 0f7918c51b990c1b307360e5ae5d2397df1e00e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=8B=E3=81=A3=E3=81=93=E3=81=8B=E3=82=8A?= <67428053+kakkokari-gtyih@users.noreply.github.com> Date: Thu, 8 Feb 2024 16:04:41 +0900 Subject: [PATCH 29/40] refactor(backend): exist -> exists (#13203) * refactor(backend): exist -> exists * fix --- packages/backend/src/core/CustomEmojiService.ts | 2 +- packages/backend/src/core/NoteCreateService.ts | 4 ++-- packages/backend/src/core/NoteReadService.ts | 4 ++-- packages/backend/src/core/SignupService.ts | 4 ++-- .../backend/src/core/UserFollowingService.ts | 10 +++++----- .../src/core/activitypub/ApInboxService.ts | 6 +++--- .../src/core/activitypub/ApRendererService.ts | 2 +- .../src/core/entities/ChannelEntityService.ts | 4 ++-- .../src/core/entities/ClipEntityService.ts | 2 +- .../src/core/entities/FlashEntityService.ts | 2 +- .../core/entities/GalleryPostEntityService.ts | 2 +- .../src/core/entities/NoteEntityService.ts | 2 +- .../src/core/entities/PageEntityService.ts | 2 +- .../src/core/entities/UserEntityService.ts | 16 ++++++++-------- .../backend/src/server/api/SignupApiService.ts | 4 ++-- .../server/api/endpoints/admin/promo/create.ts | 2 +- .../src/server/api/endpoints/auth/accept.ts | 2 +- .../src/server/api/endpoints/blocking/create.ts | 2 +- .../src/server/api/endpoints/blocking/delete.ts | 2 +- .../src/server/api/endpoints/clips/favorite.ts | 2 +- .../api/endpoints/drive/files/check-existence.ts | 2 +- .../src/server/api/endpoints/flash/like.ts | 2 +- .../src/server/api/endpoints/following/create.ts | 2 +- .../src/server/api/endpoints/following/delete.ts | 2 +- .../server/api/endpoints/gallery/posts/like.ts | 2 +- .../server/api/endpoints/i/import-antennas.ts | 2 +- .../src/server/api/endpoints/i/revoke-token.ts | 4 ++-- .../src/server/api/endpoints/mute/create.ts | 2 +- .../src/server/api/endpoints/notes/create.ts | 4 ++-- .../api/endpoints/notes/favorites/create.ts | 2 +- .../src/server/api/endpoints/pages/like.ts | 2 +- .../src/server/api/endpoints/promo/read.ts | 2 +- .../src/server/api/endpoints/users/followers.ts | 2 +- .../src/server/api/endpoints/users/following.ts | 2 +- .../endpoints/users/lists/create-from-public.ts | 6 +++--- .../server/api/endpoints/users/lists/favorite.ts | 4 ++-- .../src/server/api/endpoints/users/lists/push.ts | 4 ++-- .../src/server/api/endpoints/users/lists/show.ts | 2 +- .../api/endpoints/users/lists/unfavorite.ts | 2 +- .../src/server/api/stream/channels/user-list.ts | 2 +- 40 files changed, 64 insertions(+), 64 deletions(-) diff --git a/packages/backend/src/core/CustomEmojiService.ts b/packages/backend/src/core/CustomEmojiService.ts index 9a8267b466..f87136e20a 100644 --- a/packages/backend/src/core/CustomEmojiService.ts +++ b/packages/backend/src/core/CustomEmojiService.ts @@ -385,7 +385,7 @@ export class CustomEmojiService implements OnApplicationShutdown { */ @bindThis public checkDuplicate(name: string): Promise<boolean> { - return this.emojisRepository.exist({ where: { name, host: IsNull() } }); + return this.emojisRepository.exists({ where: { name, host: IsNull() } }); } @bindThis diff --git a/packages/backend/src/core/NoteCreateService.ts b/packages/backend/src/core/NoteCreateService.ts index 30f6d07118..f7e870831d 100644 --- a/packages/backend/src/core/NoteCreateService.ts +++ b/packages/backend/src/core/NoteCreateService.ts @@ -603,7 +603,7 @@ export class NoteCreateService implements OnApplicationShutdown { if (data.reply) { // 通知 if (data.reply.userHost === null) { - const isThreadMuted = await this.noteThreadMutingsRepository.exist({ + const isThreadMuted = await this.noteThreadMutingsRepository.exists({ where: { userId: data.reply.userId, threadId: data.reply.threadId ?? data.reply.id, @@ -741,7 +741,7 @@ export class NoteCreateService implements OnApplicationShutdown { @bindThis private async createMentionedEvents(mentionedUsers: MinimumUser[], note: MiNote, nm: NotificationManager) { for (const u of mentionedUsers.filter(u => this.userEntityService.isLocalUser(u))) { - const isThreadMuted = await this.noteThreadMutingsRepository.exist({ + const isThreadMuted = await this.noteThreadMutingsRepository.exists({ where: { userId: u.id, threadId: note.threadId ?? note.id, diff --git a/packages/backend/src/core/NoteReadService.ts b/packages/backend/src/core/NoteReadService.ts index c73cf76592..11791a4412 100644 --- a/packages/backend/src/core/NoteReadService.ts +++ b/packages/backend/src/core/NoteReadService.ts @@ -49,7 +49,7 @@ export class NoteReadService implements OnApplicationShutdown { //#endregion // スレッドミュート - const isThreadMuted = await this.noteThreadMutingsRepository.exist({ + const isThreadMuted = await this.noteThreadMutingsRepository.exists({ where: { userId: userId, threadId: note.threadId ?? note.id, @@ -70,7 +70,7 @@ export class NoteReadService implements OnApplicationShutdown { // 2秒経ã£ã¦ã‚‚æ—¢èªã«ãªã‚‰ãªã‹ã£ãŸã‚‰ã€Œæœªèªã®æŠ•ç¨¿ãŒã‚ã‚Šã¾ã™ã‚ˆã€ã‚¤ãƒ™ãƒ³ãƒˆã‚’発行ã™ã‚‹ setTimeout(2000, 'unread note', { signal: this.#shutdownController.signal }).then(async () => { - const exist = await this.noteUnreadsRepository.exist({ where: { id: unread.id } }); + const exist = await this.noteUnreadsRepository.exists({ where: { id: unread.id } }); if (!exist) return; diff --git a/packages/backend/src/core/SignupService.ts b/packages/backend/src/core/SignupService.ts index 81c2b241eb..0a119a90d5 100644 --- a/packages/backend/src/core/SignupService.ts +++ b/packages/backend/src/core/SignupService.ts @@ -74,12 +74,12 @@ export class SignupService { const secret = generateUserToken(); // Check username duplication - if (await this.usersRepository.exist({ where: { usernameLower: username.toLowerCase(), host: IsNull() } })) { + if (await this.usersRepository.exists({ where: { usernameLower: username.toLowerCase(), host: IsNull() } })) { throw new Error('DUPLICATED_USERNAME'); } // Check deleted username duplication - if (await this.usedUsernamesRepository.exist({ where: { username: username.toLowerCase() } })) { + if (await this.usedUsernamesRepository.exists({ where: { username: username.toLowerCase() } })) { throw new Error('USED_USERNAME'); } diff --git a/packages/backend/src/core/UserFollowingService.ts b/packages/backend/src/core/UserFollowingService.ts index 93e9fbbd70..e82a7e06f9 100644 --- a/packages/backend/src/core/UserFollowingService.ts +++ b/packages/backend/src/core/UserFollowingService.ts @@ -144,7 +144,7 @@ export class UserFollowingService implements OnModuleInit { let autoAccept = false; // éµã‚¢ã‚«ã‚¦ãƒ³ãƒˆã§ã‚ã£ã¦ã‚‚ã€æ—¢ã«ãƒ•ã‚©ãƒãƒ¼ã•ã‚Œã¦ã„ãŸå ´åˆã¯ã‚¹ãƒ«ãƒ¼ - const isFollowing = await this.followingsRepository.exist({ + const isFollowing = await this.followingsRepository.exists({ where: { followerId: follower.id, followeeId: followee.id, @@ -156,7 +156,7 @@ export class UserFollowingService implements OnModuleInit { // フォãƒãƒ¼ã—ã¦ã„るユーザーã¯è‡ªå‹•æ‰¿èªã‚ªãƒ—ション if (!autoAccept && (this.userEntityService.isLocalUser(followee) && followeeProfile.autoAcceptFollowed)) { - const isFollowed = await this.followingsRepository.exist({ + const isFollowed = await this.followingsRepository.exists({ where: { followerId: followee.id, followeeId: follower.id, @@ -170,7 +170,7 @@ export class UserFollowingService implements OnModuleInit { if (followee.isLocked && !autoAccept) { autoAccept = !!(await this.accountMoveService.validateAlsoKnownAs( follower, - (oldSrc, newSrc) => this.followingsRepository.exist({ + (oldSrc, newSrc) => this.followingsRepository.exists({ where: { followeeId: followee.id, followerId: newSrc.id, @@ -233,7 +233,7 @@ export class UserFollowingService implements OnModuleInit { this.cacheService.userFollowingsCache.refresh(follower.id); - const requestExist = await this.followRequestsRepository.exist({ + const requestExist = await this.followRequestsRepository.exists({ where: { followeeId: followee.id, followerId: follower.id, @@ -531,7 +531,7 @@ export class UserFollowingService implements OnModuleInit { } } - const requestExist = await this.followRequestsRepository.exist({ + const requestExist = await this.followRequestsRepository.exists({ where: { followeeId: followee.id, followerId: follower.id, diff --git a/packages/backend/src/core/activitypub/ApInboxService.ts b/packages/backend/src/core/activitypub/ApInboxService.ts index a0c63bdbf7..5e06f29946 100644 --- a/packages/backend/src/core/activitypub/ApInboxService.ts +++ b/packages/backend/src/core/activitypub/ApInboxService.ts @@ -629,7 +629,7 @@ export class ApInboxService { return 'skip: follower not found'; } - const isFollowing = await this.followingsRepository.exist({ + const isFollowing = await this.followingsRepository.exists({ where: { followerId: follower.id, followeeId: actor.id, @@ -686,14 +686,14 @@ export class ApInboxService { return 'skip: フォãƒãƒ¼è§£é™¤ã—よã†ã¨ã—ã¦ã„るユーザーã¯ãƒãƒ¼ã‚«ãƒ«ãƒ¦ãƒ¼ã‚¶ãƒ¼ã§ã¯ã‚ã‚Šã¾ã›ã‚“'; } - const requestExist = await this.followRequestsRepository.exist({ + const requestExist = await this.followRequestsRepository.exists({ where: { followerId: actor.id, followeeId: followee.id, }, }); - const isFollowing = await this.followingsRepository.exist({ + const isFollowing = await this.followingsRepository.exists({ where: { followerId: actor.id, followeeId: followee.id, diff --git a/packages/backend/src/core/activitypub/ApRendererService.ts b/packages/backend/src/core/activitypub/ApRendererService.ts index 211f4f4a44..87b603b905 100644 --- a/packages/backend/src/core/activitypub/ApRendererService.ts +++ b/packages/backend/src/core/activitypub/ApRendererService.ts @@ -325,7 +325,7 @@ export class ApRendererService { inReplyToNote = await this.notesRepository.findOneBy({ id: note.replyId }); if (inReplyToNote != null) { - const inReplyToUserExist = await this.usersRepository.exist({ where: { id: inReplyToNote.userId } }); + const inReplyToUserExist = await this.usersRepository.exists({ where: { id: inReplyToNote.userId } }); if (inReplyToUserExist) { if (inReplyToNote.uri) { diff --git a/packages/backend/src/core/entities/ChannelEntityService.ts b/packages/backend/src/core/entities/ChannelEntityService.ts index 305946b8a6..f358875f72 100644 --- a/packages/backend/src/core/entities/ChannelEntityService.ts +++ b/packages/backend/src/core/entities/ChannelEntityService.ts @@ -51,14 +51,14 @@ export class ChannelEntityService { const banner = channel.bannerId ? await this.driveFilesRepository.findOneBy({ id: channel.bannerId }) : null; - const isFollowing = meId ? await this.channelFollowingsRepository.exist({ + const isFollowing = meId ? await this.channelFollowingsRepository.exists({ where: { followerId: meId, followeeId: channel.id, }, }) : false; - const isFavorited = meId ? await this.channelFavoritesRepository.exist({ + const isFavorited = meId ? await this.channelFavoritesRepository.exists({ where: { userId: meId, channelId: channel.id, diff --git a/packages/backend/src/core/entities/ClipEntityService.ts b/packages/backend/src/core/entities/ClipEntityService.ts index 96422894fd..2133f80f1a 100644 --- a/packages/backend/src/core/entities/ClipEntityService.ts +++ b/packages/backend/src/core/entities/ClipEntityService.ts @@ -46,7 +46,7 @@ export class ClipEntityService { description: clip.description, isPublic: clip.isPublic, favoritedCount: await this.clipFavoritesRepository.countBy({ clipId: clip.id }), - isFavorited: meId ? await this.clipFavoritesRepository.exist({ where: { clipId: clip.id, userId: meId } }) : undefined, + isFavorited: meId ? await this.clipFavoritesRepository.exists({ where: { clipId: clip.id, userId: meId } }) : undefined, }); } diff --git a/packages/backend/src/core/entities/FlashEntityService.ts b/packages/backend/src/core/entities/FlashEntityService.ts index 70faa2b380..c1b9f9a791 100644 --- a/packages/backend/src/core/entities/FlashEntityService.ts +++ b/packages/backend/src/core/entities/FlashEntityService.ts @@ -47,7 +47,7 @@ export class FlashEntityService { summary: flash.summary, script: flash.script, likedCount: flash.likedCount, - isLiked: meId ? await this.flashLikesRepository.exist({ where: { flashId: flash.id, userId: meId } }) : undefined, + isLiked: meId ? await this.flashLikesRepository.exists({ where: { flashId: flash.id, userId: meId } }) : undefined, }); } diff --git a/packages/backend/src/core/entities/GalleryPostEntityService.ts b/packages/backend/src/core/entities/GalleryPostEntityService.ts index d7b960e0d9..2a615a9216 100644 --- a/packages/backend/src/core/entities/GalleryPostEntityService.ts +++ b/packages/backend/src/core/entities/GalleryPostEntityService.ts @@ -53,7 +53,7 @@ export class GalleryPostEntityService { tags: post.tags.length > 0 ? post.tags : undefined, isSensitive: post.isSensitive, likedCount: post.likedCount, - isLiked: meId ? await this.galleryLikesRepository.exist({ where: { postId: post.id, userId: meId } }) : undefined, + isLiked: meId ? await this.galleryLikesRepository.exists({ where: { postId: post.id, userId: meId } }) : undefined, }); } diff --git a/packages/backend/src/core/entities/NoteEntityService.ts b/packages/backend/src/core/entities/NoteEntityService.ts index a095a5daf7..6cf737a906 100644 --- a/packages/backend/src/core/entities/NoteEntityService.ts +++ b/packages/backend/src/core/entities/NoteEntityService.ts @@ -108,7 +108,7 @@ export class NoteEntityService implements OnModuleInit { hide = false; } else { // フォãƒãƒ¯ãƒ¼ã‹ã©ã†ã‹ - const isFollowing = await this.followingsRepository.exist({ + const isFollowing = await this.followingsRepository.exists({ where: { followeeId: packedNote.userId, followerId: meId, diff --git a/packages/backend/src/core/entities/PageEntityService.ts b/packages/backend/src/core/entities/PageEntityService.ts index bc26362aba..27c9011f6d 100644 --- a/packages/backend/src/core/entities/PageEntityService.ts +++ b/packages/backend/src/core/entities/PageEntityService.ts @@ -104,7 +104,7 @@ export class PageEntityService { eyeCatchingImage: page.eyeCatchingImageId ? await this.driveFileEntityService.pack(page.eyeCatchingImageId) : null, attachedFiles: this.driveFileEntityService.packMany((await Promise.all(attachedFiles)).filter((x): x is MiDriveFile => x != null)), likedCount: page.likedCount, - isLiked: meId ? await this.pageLikesRepository.exist({ where: { pageId: page.id, userId: meId } }) : undefined, + isLiked: meId ? await this.pageLikesRepository.exists({ where: { pageId: page.id, userId: meId } }) : undefined, }); } diff --git a/packages/backend/src/core/entities/UserEntityService.ts b/packages/backend/src/core/entities/UserEntityService.ts index 9d73dc607d..2496180ec1 100644 --- a/packages/backend/src/core/entities/UserEntityService.ts +++ b/packages/backend/src/core/entities/UserEntityService.ts @@ -152,43 +152,43 @@ export class UserEntityService implements OnModuleInit { followerId: me, followeeId: target, }), - this.followingsRepository.exist({ + this.followingsRepository.exists({ where: { followerId: target, followeeId: me, }, }), - this.followRequestsRepository.exist({ + this.followRequestsRepository.exists({ where: { followerId: me, followeeId: target, }, }), - this.followRequestsRepository.exist({ + this.followRequestsRepository.exists({ where: { followerId: target, followeeId: me, }, }), - this.blockingsRepository.exist({ + this.blockingsRepository.exists({ where: { blockerId: me, blockeeId: target, }, }), - this.blockingsRepository.exist({ + this.blockingsRepository.exists({ where: { blockerId: target, blockeeId: me, }, }), - this.mutingsRepository.exist({ + this.mutingsRepository.exists({ where: { muterId: me, muteeId: target, }, }), - this.renoteMutingsRepository.exist({ + this.renoteMutingsRepository.exists({ where: { muterId: me, muteeId: target, @@ -215,7 +215,7 @@ export class UserEntityService implements OnModuleInit { /* const myAntennas = (await this.antennaService.getAntennas()).filter(a => a.userId === userId); - const isUnread = (myAntennas.length > 0 ? await this.antennaNotesRepository.exist({ + const isUnread = (myAntennas.length > 0 ? await this.antennaNotesRepository.exists({ where: { antennaId: In(myAntennas.map(x => x.id)), read: false, diff --git a/packages/backend/src/server/api/SignupApiService.ts b/packages/backend/src/server/api/SignupApiService.ts index 95016cdba6..f025999c7a 100644 --- a/packages/backend/src/server/api/SignupApiService.ts +++ b/packages/backend/src/server/api/SignupApiService.ts @@ -163,12 +163,12 @@ export class SignupApiService { } if (instance.emailRequiredForSignup) { - if (await this.usersRepository.exist({ where: { usernameLower: username.toLowerCase(), host: IsNull() } })) { + if (await this.usersRepository.exists({ where: { usernameLower: username.toLowerCase(), host: IsNull() } })) { throw new FastifyReplyError(400, 'DUPLICATED_USERNAME'); } // Check deleted username duplication - if (await this.usedUsernamesRepository.exist({ where: { username: username.toLowerCase() } })) { + if (await this.usedUsernamesRepository.exists({ where: { username: username.toLowerCase() } })) { throw new FastifyReplyError(400, 'USED_USERNAME'); } diff --git a/packages/backend/src/server/api/endpoints/admin/promo/create.ts b/packages/backend/src/server/api/endpoints/admin/promo/create.ts index ab69dfba96..339b7a8aa4 100644 --- a/packages/backend/src/server/api/endpoints/admin/promo/create.ts +++ b/packages/backend/src/server/api/endpoints/admin/promo/create.ts @@ -55,7 +55,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- throw e; }); - const exist = await this.promoNotesRepository.exist({ where: { noteId: note.id } }); + const exist = await this.promoNotesRepository.exists({ where: { noteId: note.id } }); if (exist) { throw new ApiError(meta.errors.alreadyPromoted); diff --git a/packages/backend/src/server/api/endpoints/auth/accept.ts b/packages/backend/src/server/api/endpoints/auth/accept.ts index e0baeb3565..602c34b1e6 100644 --- a/packages/backend/src/server/api/endpoints/auth/accept.ts +++ b/packages/backend/src/server/api/endpoints/auth/accept.ts @@ -62,7 +62,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- const accessToken = secureRndstr(32); // Fetch exist access token - const exist = await this.accessTokensRepository.exist({ + const exist = await this.accessTokensRepository.exists({ where: { appId: session.appId, userId: me.id, diff --git a/packages/backend/src/server/api/endpoints/blocking/create.ts b/packages/backend/src/server/api/endpoints/blocking/create.ts index 1dc4563180..ea7d2076b0 100644 --- a/packages/backend/src/server/api/endpoints/blocking/create.ts +++ b/packages/backend/src/server/api/endpoints/blocking/create.ts @@ -88,7 +88,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- }); // Check if already blocking - const exist = await this.blockingsRepository.exist({ + const exist = await this.blockingsRepository.exists({ where: { blockerId: blocker.id, blockeeId: blockee.id, diff --git a/packages/backend/src/server/api/endpoints/blocking/delete.ts b/packages/backend/src/server/api/endpoints/blocking/delete.ts index a6e6bcb5b3..b0d66fd05c 100644 --- a/packages/backend/src/server/api/endpoints/blocking/delete.ts +++ b/packages/backend/src/server/api/endpoints/blocking/delete.ts @@ -88,7 +88,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- }); // Check not blocking - const exist = await this.blockingsRepository.exist({ + const exist = await this.blockingsRepository.exists({ where: { blockerId: blocker.id, blockeeId: blockee.id, diff --git a/packages/backend/src/server/api/endpoints/clips/favorite.ts b/packages/backend/src/server/api/endpoints/clips/favorite.ts index 015b2cfa85..b4c6a4940b 100644 --- a/packages/backend/src/server/api/endpoints/clips/favorite.ts +++ b/packages/backend/src/server/api/endpoints/clips/favorite.ts @@ -62,7 +62,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- throw new ApiError(meta.errors.noSuchClip); } - const exist = await this.clipFavoritesRepository.exist({ + const exist = await this.clipFavoritesRepository.exists({ where: { clipId: clip.id, userId: me.id, diff --git a/packages/backend/src/server/api/endpoints/drive/files/check-existence.ts b/packages/backend/src/server/api/endpoints/drive/files/check-existence.ts index 85e6312b6a..8c1f491f8d 100644 --- a/packages/backend/src/server/api/endpoints/drive/files/check-existence.ts +++ b/packages/backend/src/server/api/endpoints/drive/files/check-existence.ts @@ -38,7 +38,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- private driveFilesRepository: DriveFilesRepository, ) { super(meta, paramDef, async (ps, me) => { - const exist = await this.driveFilesRepository.exist({ + const exist = await this.driveFilesRepository.exists({ where: { md5: ps.md5, userId: me.id, diff --git a/packages/backend/src/server/api/endpoints/flash/like.ts b/packages/backend/src/server/api/endpoints/flash/like.ts index 1003249c0c..5878200828 100644 --- a/packages/backend/src/server/api/endpoints/flash/like.ts +++ b/packages/backend/src/server/api/endpoints/flash/like.ts @@ -70,7 +70,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- } // if already liked - const exist = await this.flashLikesRepository.exist({ + const exist = await this.flashLikesRepository.exists({ where: { flashId: flash.id, userId: me.id, diff --git a/packages/backend/src/server/api/endpoints/following/create.ts b/packages/backend/src/server/api/endpoints/following/create.ts index 9037944ef9..1d0691407d 100644 --- a/packages/backend/src/server/api/endpoints/following/create.ts +++ b/packages/backend/src/server/api/endpoints/following/create.ts @@ -101,7 +101,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- }); // Check if already following - const exist = await this.followingsRepository.exist({ + const exist = await this.followingsRepository.exists({ where: { followerId: follower.id, followeeId: followee.id, diff --git a/packages/backend/src/server/api/endpoints/following/delete.ts b/packages/backend/src/server/api/endpoints/following/delete.ts index f44692ba6d..f761968c90 100644 --- a/packages/backend/src/server/api/endpoints/following/delete.ts +++ b/packages/backend/src/server/api/endpoints/following/delete.ts @@ -85,7 +85,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- }); // Check not following - const exist = await this.followingsRepository.exist({ + const exist = await this.followingsRepository.exists({ where: { followerId: follower.id, followeeId: followee.id, diff --git a/packages/backend/src/server/api/endpoints/gallery/posts/like.ts b/packages/backend/src/server/api/endpoints/gallery/posts/like.ts index cc424261b4..576cff4e91 100644 --- a/packages/backend/src/server/api/endpoints/gallery/posts/like.ts +++ b/packages/backend/src/server/api/endpoints/gallery/posts/like.ts @@ -72,7 +72,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- } // if already liked - const exist = await this.galleryLikesRepository.exist({ + const exist = await this.galleryLikesRepository.exists({ where: { postId: post.id, userId: me.id, diff --git a/packages/backend/src/server/api/endpoints/i/import-antennas.ts b/packages/backend/src/server/api/endpoints/i/import-antennas.ts index 71db8710af..771f3395ce 100644 --- a/packages/backend/src/server/api/endpoints/i/import-antennas.ts +++ b/packages/backend/src/server/api/endpoints/i/import-antennas.ts @@ -71,7 +71,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { private downloadService: DownloadService, ) { super(meta, paramDef, async (ps, me) => { - const userExist = await this.usersRepository.exist({ where: { id: me.id } }); + const userExist = await this.usersRepository.exists({ where: { id: me.id } }); if (!userExist) throw new ApiError(meta.errors.noSuchUser); const file = await this.driveFilesRepository.findOneBy({ id: ps.fileId }); if (file === null) throw new ApiError(meta.errors.noSuchFile); diff --git a/packages/backend/src/server/api/endpoints/i/revoke-token.ts b/packages/backend/src/server/api/endpoints/i/revoke-token.ts index 98d866f867..545d16082c 100644 --- a/packages/backend/src/server/api/endpoints/i/revoke-token.ts +++ b/packages/backend/src/server/api/endpoints/i/revoke-token.ts @@ -34,7 +34,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- ) { super(meta, paramDef, async (ps, me) => { if (ps.tokenId) { - const tokenExist = await this.accessTokensRepository.exist({ where: { id: ps.tokenId } }); + const tokenExist = await this.accessTokensRepository.exists({ where: { id: ps.tokenId } }); if (tokenExist) { await this.accessTokensRepository.delete({ @@ -43,7 +43,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- }); } } else if (ps.token) { - const tokenExist = await this.accessTokensRepository.exist({ where: { token: ps.token } }); + const tokenExist = await this.accessTokensRepository.exists({ where: { token: ps.token } }); if (tokenExist) { await this.accessTokensRepository.delete({ diff --git a/packages/backend/src/server/api/endpoints/mute/create.ts b/packages/backend/src/server/api/endpoints/mute/create.ts index 49c2b5707d..1d931150e1 100644 --- a/packages/backend/src/server/api/endpoints/mute/create.ts +++ b/packages/backend/src/server/api/endpoints/mute/create.ts @@ -83,7 +83,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- }); // Check if already muting - const exist = await this.mutingsRepository.exist({ + const exist = await this.mutingsRepository.exists({ where: { muterId: muter.id, muteeId: mutee.id, diff --git a/packages/backend/src/server/api/endpoints/notes/create.ts b/packages/backend/src/server/api/endpoints/notes/create.ts index 29a0f7418c..787cda3834 100644 --- a/packages/backend/src/server/api/endpoints/notes/create.ts +++ b/packages/backend/src/server/api/endpoints/notes/create.ts @@ -260,7 +260,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- // Check blocking if (renote.userId !== me.id) { - const blockExist = await this.blockingsRepository.exist({ + const blockExist = await this.blockingsRepository.exists({ where: { blockerId: renote.userId, blockeeId: me.id, @@ -308,7 +308,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- // Check blocking if (reply.userId !== me.id) { - const blockExist = await this.blockingsRepository.exist({ + const blockExist = await this.blockingsRepository.exists({ where: { blockerId: reply.userId, blockeeId: me.id, diff --git a/packages/backend/src/server/api/endpoints/notes/favorites/create.ts b/packages/backend/src/server/api/endpoints/notes/favorites/create.ts index ed3dce7f35..bfa621aa38 100644 --- a/packages/backend/src/server/api/endpoints/notes/favorites/create.ts +++ b/packages/backend/src/server/api/endpoints/notes/favorites/create.ts @@ -67,7 +67,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- }); // if already favorited - const exist = await this.noteFavoritesRepository.exist({ + const exist = await this.noteFavoritesRepository.exists({ where: { noteId: note.id, userId: me.id, diff --git a/packages/backend/src/server/api/endpoints/pages/like.ts b/packages/backend/src/server/api/endpoints/pages/like.ts index 8c18982b50..bee60f080d 100644 --- a/packages/backend/src/server/api/endpoints/pages/like.ts +++ b/packages/backend/src/server/api/endpoints/pages/like.ts @@ -70,7 +70,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- } // if already liked - const exist = await this.pageLikesRepository.exist({ + const exist = await this.pageLikesRepository.exists({ where: { pageId: page.id, userId: me.id, diff --git a/packages/backend/src/server/api/endpoints/promo/read.ts b/packages/backend/src/server/api/endpoints/promo/read.ts index f427939a7a..4899408ddd 100644 --- a/packages/backend/src/server/api/endpoints/promo/read.ts +++ b/packages/backend/src/server/api/endpoints/promo/read.ts @@ -49,7 +49,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- throw err; }); - const exist = await this.promoReadsRepository.exist({ + const exist = await this.promoReadsRepository.exists({ where: { noteId: note.id, userId: me.id, diff --git a/packages/backend/src/server/api/endpoints/users/followers.ts b/packages/backend/src/server/api/endpoints/users/followers.ts index 5706e46b96..314a45ed61 100644 --- a/packages/backend/src/server/api/endpoints/users/followers.ts +++ b/packages/backend/src/server/api/endpoints/users/followers.ts @@ -101,7 +101,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- if (me == null) { throw new ApiError(meta.errors.forbidden); } else if (me.id !== user.id) { - const isFollowing = await this.followingsRepository.exist({ + const isFollowing = await this.followingsRepository.exists({ where: { followeeId: user.id, followerId: me.id, diff --git a/packages/backend/src/server/api/endpoints/users/following.ts b/packages/backend/src/server/api/endpoints/users/following.ts index 794fb04f10..86f55c5a12 100644 --- a/packages/backend/src/server/api/endpoints/users/following.ts +++ b/packages/backend/src/server/api/endpoints/users/following.ts @@ -109,7 +109,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- if (me == null) { throw new ApiError(meta.errors.forbidden); } else if (me.id !== user.id) { - const isFollowing = await this.followingsRepository.exist({ + const isFollowing = await this.followingsRepository.exists({ where: { followeeId: user.id, followerId: me.id, diff --git a/packages/backend/src/server/api/endpoints/users/lists/create-from-public.ts b/packages/backend/src/server/api/endpoints/users/lists/create-from-public.ts index fa2e3338b8..dd9b459a1f 100644 --- a/packages/backend/src/server/api/endpoints/users/lists/create-from-public.ts +++ b/packages/backend/src/server/api/endpoints/users/lists/create-from-public.ts @@ -90,7 +90,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- private roleService: RoleService, ) { super(meta, paramDef, async (ps, me) => { - const listExist = await this.userListsRepository.exist({ + const listExist = await this.userListsRepository.exists({ where: { id: ps.listId, isPublic: true, @@ -121,7 +121,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- }); if (currentUser.id !== me.id) { - const blockExist = await this.blockingsRepository.exist({ + const blockExist = await this.blockingsRepository.exists({ where: { blockerId: currentUser.id, blockeeId: me.id, @@ -132,7 +132,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- } } - const exist = await this.userListMembershipsRepository.exist({ + const exist = await this.userListMembershipsRepository.exists({ where: { userListId: userList.id, userId: currentUser.id, diff --git a/packages/backend/src/server/api/endpoints/users/lists/favorite.ts b/packages/backend/src/server/api/endpoints/users/lists/favorite.ts index 864cdc2ee0..e5b3a73b55 100644 --- a/packages/backend/src/server/api/endpoints/users/lists/favorite.ts +++ b/packages/backend/src/server/api/endpoints/users/lists/favorite.ts @@ -47,7 +47,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { private idService: IdService, ) { super(meta, paramDef, async (ps, me) => { - const userListExist = await this.userListsRepository.exist({ + const userListExist = await this.userListsRepository.exists({ where: { id: ps.listId, isPublic: true, @@ -58,7 +58,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { throw new ApiError(meta.errors.noSuchList); } - const exist = await this.userListFavoritesRepository.exist({ + const exist = await this.userListFavoritesRepository.exists({ where: { userId: me.id, userListId: ps.listId, diff --git a/packages/backend/src/server/api/endpoints/users/lists/push.ts b/packages/backend/src/server/api/endpoints/users/lists/push.ts index c4ceec575b..0984270943 100644 --- a/packages/backend/src/server/api/endpoints/users/lists/push.ts +++ b/packages/backend/src/server/api/endpoints/users/lists/push.ts @@ -104,7 +104,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- // Check blocking if (user.id !== me.id) { - const blockExist = await this.blockingsRepository.exist({ + const blockExist = await this.blockingsRepository.exists({ where: { blockerId: user.id, blockeeId: me.id, @@ -115,7 +115,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- } } - const exist = await this.userListMembershipsRepository.exist({ + const exist = await this.userListMembershipsRepository.exists({ where: { userListId: userList.id, userId: user.id, diff --git a/packages/backend/src/server/api/endpoints/users/lists/show.ts b/packages/backend/src/server/api/endpoints/users/lists/show.ts index df44870b04..10efbaafd8 100644 --- a/packages/backend/src/server/api/endpoints/users/lists/show.ts +++ b/packages/backend/src/server/api/endpoints/users/lists/show.ts @@ -74,7 +74,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { userListId: ps.listId, }); if (me !== null) { - additionalProperties.isLiked = await this.userListFavoritesRepository.exist({ + additionalProperties.isLiked = await this.userListFavoritesRepository.exists({ where: { userId: me.id, userListId: ps.listId, diff --git a/packages/backend/src/server/api/endpoints/users/lists/unfavorite.ts b/packages/backend/src/server/api/endpoints/users/lists/unfavorite.ts index d51d57343e..0935584cbc 100644 --- a/packages/backend/src/server/api/endpoints/users/lists/unfavorite.ts +++ b/packages/backend/src/server/api/endpoints/users/lists/unfavorite.ts @@ -45,7 +45,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { private userListFavoritesRepository: UserListFavoritesRepository, ) { super(meta, paramDef, async (ps, me) => { - const userListExist = await this.userListsRepository.exist({ + const userListExist = await this.userListsRepository.exists({ where: { id: ps.listId, isPublic: true, diff --git a/packages/backend/src/server/api/stream/channels/user-list.ts b/packages/backend/src/server/api/stream/channels/user-list.ts index e0245814c4..0434833df8 100644 --- a/packages/backend/src/server/api/stream/channels/user-list.ts +++ b/packages/backend/src/server/api/stream/channels/user-list.ts @@ -43,7 +43,7 @@ class UserListChannel extends Channel { this.withRenotes = params.withRenotes ?? true; // Check existence and owner - const listExist = await this.userListsRepository.exist({ + const listExist = await this.userListsRepository.exists({ where: { id: this.listId, userId: this.user!.id, -- GitLab From d40612ac522df8f67758daa0ad17eea7cb2d6da2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=8B=E3=81=A3=E3=81=93=E3=81=8B=E3=82=8A?= <67428053+kakkokari-gtyih@users.noreply.github.com> Date: Fri, 9 Feb 2024 00:08:33 +0900 Subject: [PATCH 30/40] =?UTF-8?q?fix(frontend):=20aiscript=E3=81=AE?= =?UTF-8?q?=E3=82=B3=E3=83=BC=E3=83=89=E3=83=96=E3=83=AD=E3=83=83=E3=82=AF?= =?UTF-8?q?=E3=81=A7=E3=81=AE=E3=83=8F=E3=82=A4=E3=83=A9=E3=82=A4=E3=83=88?= =?UTF-8?q?=E6=8C=87=E5=AE=9A=E3=82=92=E4=BF=AE=E6=AD=A3=20(#13208)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/package.json | 2 +- .../frontend/src/scripts/code-highlighter.ts | 9 +-- pnpm-lock.yaml | 62 +++++++++++++++++-- 3 files changed, 61 insertions(+), 12 deletions(-) diff --git a/packages/frontend/package.json b/packages/frontend/package.json index 9e88c6c036..d8ba08501e 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -29,7 +29,7 @@ "@twemoji/parser": "15.0.0", "@vitejs/plugin-vue": "5.0.3", "@vue/compiler-sfc": "3.4.15", - "aiscript-vscode": "github:aiscript-dev/aiscript-vscode#v0.0.6", + "aiscript-vscode": "github:aiscript-dev/aiscript-vscode#v0.1.2", "astring": "1.8.6", "broadcast-channel": "7.0.0", "buraha": "0.0.1", diff --git a/packages/frontend/src/scripts/code-highlighter.ts b/packages/frontend/src/scripts/code-highlighter.ts index b11dfed41a..2733897bab 100644 --- a/packages/frontend/src/scripts/code-highlighter.ts +++ b/packages/frontend/src/scripts/code-highlighter.ts @@ -20,7 +20,7 @@ export async function getTheme(mode: 'light' | 'dark', getName = false): Promise const base = [lightTheme, darkTheme].find(x => x.id === theme.base); if (base && base.codeHighlighter) theme.codeHighlighter = Object.assign({}, base.codeHighlighter, theme.codeHighlighter); } - + if (theme.codeHighlighter) { let _res: ThemeRegistration = {}; if (theme.codeHighlighter.base === '_none_') { @@ -55,7 +55,7 @@ export async function getHighlighter(): Promise<Highlighter> { export async function initHighlighter() { const aiScriptGrammar = await import('aiscript-vscode/aiscript/syntaxes/aiscript.tmLanguage.json'); - + await loadWasm(import('shiki/onig.wasm?init')); // テーマã®é‡è¤‡ã‚’消㙠@@ -68,10 +68,7 @@ export async function initHighlighter() { themes, langs: [ import('shiki/langs/javascript.mjs'), - { - aliases: ['is', 'ais'], - ...aiScriptGrammar.default, - } as unknown as LanguageRegistration, + aiScriptGrammar.default as unknown as LanguageRegistration, ], }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 291ec305c7..bdc9a48464 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -704,8 +704,8 @@ importers: specifier: 3.4.15 version: 3.4.15 aiscript-vscode: - specifier: github:aiscript-dev/aiscript-vscode#v0.0.6 - version: github.com/aiscript-dev/aiscript-vscode/b5a8aa0ad927831a0b867d1c183460a14e6c48cd + specifier: github:aiscript-dev/aiscript-vscode#v0.1.2 + version: github.com/aiscript-dev/aiscript-vscode/793211d40243c8775f6b85f015c221c82cbffb07 astring: specifier: 1.8.6 version: 1.8.6 @@ -20001,6 +20001,42 @@ packages: resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==} engines: {node: '>=0.10.0'} + /vscode-jsonrpc@8.2.0: + resolution: {integrity: sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==} + engines: {node: '>=14.0.0'} + dev: false + + /vscode-languageclient@9.0.1: + resolution: {integrity: sha512-JZiimVdvimEuHh5olxhxkht09m3JzUGwggb5eRUkzzJhZ2KjCN0nh55VfiED9oez9DyF8/fz1g1iBV3h+0Z2EA==} + engines: {vscode: ^1.82.0} + dependencies: + minimatch: 5.1.2 + semver: 7.5.4 + vscode-languageserver-protocol: 3.17.5 + dev: false + + /vscode-languageserver-protocol@3.17.5: + resolution: {integrity: sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==} + dependencies: + vscode-jsonrpc: 8.2.0 + vscode-languageserver-types: 3.17.5 + dev: false + + /vscode-languageserver-textdocument@1.0.11: + resolution: {integrity: sha512-X+8T3GoiwTVlJbicx/sIAF+yuJAqz8VvwJyoMVhwEMoEKE/fkDmrqUgDMyBECcM2A2frVZIUj5HI/ErRXCfOeA==} + dev: false + + /vscode-languageserver-types@3.17.5: + resolution: {integrity: sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==} + dev: false + + /vscode-languageserver@9.0.1: + resolution: {integrity: sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==} + hasBin: true + dependencies: + vscode-languageserver-protocol: 3.17.5 + dev: false + /vue-component-type-helpers@1.8.27: resolution: {integrity: sha512-0vOfAtI67UjeO1G6UiX5Kd76CqaQ67wrRZiOe7UAb9Jm6GzlUr/fC7CV90XfwapJRjpCMaZFhv1V0ajWRmE9Dg==} dev: true @@ -20560,11 +20596,27 @@ packages: readable-stream: 3.6.0 dev: false - github.com/aiscript-dev/aiscript-vscode/b5a8aa0ad927831a0b867d1c183460a14e6c48cd: - resolution: {tarball: https://codeload.github.com/aiscript-dev/aiscript-vscode/tar.gz/b5a8aa0ad927831a0b867d1c183460a14e6c48cd} + '@github.com/aiscript-dev/aiscript-languageserver/releases/download/0.1.5/aiscript-dev-aiscript-languageserver-0.1.5.tgz': + resolution: {tarball: https://github.com/aiscript-dev/aiscript-languageserver/releases/download/0.1.5/aiscript-dev-aiscript-languageserver-0.1.5.tgz} + name: '@aiscript-dev/aiscript-languageserver' + version: 0.1.5 + hasBin: true + dependencies: + seedrandom: 3.0.5 + stringz: 2.1.0 + uuid: 9.0.1 + vscode-languageserver: 9.0.1 + vscode-languageserver-textdocument: 1.0.11 + dev: false + + github.com/aiscript-dev/aiscript-vscode/793211d40243c8775f6b85f015c221c82cbffb07: + resolution: {tarball: https://codeload.github.com/aiscript-dev/aiscript-vscode/tar.gz/793211d40243c8775f6b85f015c221c82cbffb07} name: aiscript-vscode - version: 0.0.6 + version: 0.1.2 engines: {vscode: ^1.83.0} + dependencies: + '@aiscript-dev/aiscript-languageserver': '@github.com/aiscript-dev/aiscript-languageserver/releases/download/0.1.5/aiscript-dev-aiscript-languageserver-0.1.5.tgz' + vscode-languageclient: 9.0.1 dev: false github.com/misskey-dev/storybook-addon-misskey-theme/cf583db098365b2ccc81a82f63ca9c93bc32b640(@storybook/blocks@7.6.10)(@storybook/components@7.6.10)(@storybook/core-events@7.6.10)(@storybook/manager-api@7.6.10)(@storybook/preview-api@7.6.10)(@storybook/theming@7.6.10)(@storybook/types@7.6.10)(react-dom@18.2.0)(react@18.2.0): -- GitLab From c0cb76f0ec63dec3dd1d8381a3395c8c84d43a97 Mon Sep 17 00:00:00 2001 From: tamaina <tamaina@hotmail.co.jp> Date: Thu, 8 Feb 2024 17:24:51 +0000 Subject: [PATCH 31/40] chore: use vite@5.1.0 / pnpm@8.15.1 --- package.json | 2 +- packages/frontend/package.json | 2 +- pnpm-lock.yaml | 66 +++++++++++++++++++--------------- 3 files changed, 39 insertions(+), 31 deletions(-) diff --git a/package.json b/package.json index bd4529f159..1a38627361 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "type": "git", "url": "https://github.com/misskey-dev/misskey.git" }, - "packageManager": "pnpm@8.12.1", + "packageManager": "pnpm@8.15.1", "workspaces": [ "packages/frontend", "packages/backend", diff --git a/packages/frontend/package.json b/packages/frontend/package.json index d8ba08501e..5aaddde5ca 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -71,7 +71,7 @@ "typescript": "5.3.3", "uuid": "9.0.1", "v-code-diff": "1.7.2", - "vite": "5.0.12", + "vite": "5.1.0", "vue": "3.4.15", "vuedraggable": "next" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bdc9a48464..eb0c613e97 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -699,7 +699,7 @@ importers: version: 15.0.0 '@vitejs/plugin-vue': specifier: 5.0.3 - version: 5.0.3(vite@5.0.12)(vue@3.4.15) + version: 5.0.3(vite@5.1.0)(vue@3.4.15) '@vue/compiler-sfc': specifier: 3.4.15 version: 3.4.15 @@ -830,8 +830,8 @@ importers: specifier: 1.7.2 version: 1.7.2(vue@3.4.15) vite: - specifier: 5.0.12 - version: 5.0.12(@types/node@20.11.10)(sass@1.70.0)(terser@5.27.0) + specifier: 5.1.0 + version: 5.1.0(@types/node@20.11.10)(sass@1.70.0)(terser@5.27.0) vue: specifier: 3.4.15 version: 3.4.15(typescript@5.3.3) @@ -883,7 +883,7 @@ importers: version: 7.6.10(react-dom@18.2.0)(react@18.2.0)(typescript@5.3.3) '@storybook/react-vite': specifier: 7.6.10 - version: 7.6.10(react-dom@18.2.0)(react@18.2.0)(rollup@4.9.6)(typescript@5.3.3)(vite@5.0.12) + version: 7.6.10(react-dom@18.2.0)(react@18.2.0)(rollup@4.9.6)(typescript@5.3.3)(vite@5.1.0) '@storybook/testing-library': specifier: 0.2.2 version: 0.2.2 @@ -898,7 +898,7 @@ importers: version: 7.6.10(vue@3.4.15) '@storybook/vue3-vite': specifier: 7.6.10 - version: 7.6.10(typescript@5.3.3)(vite@5.0.12)(vue@3.4.15) + version: 7.6.10(typescript@5.3.3)(vite@5.1.0)(vue@3.4.15) '@testing-library/vue': specifier: 8.0.1 version: 8.0.1(@vue/compiler-sfc@3.4.15)(vue@3.4.15) @@ -4694,7 +4694,7 @@ packages: chalk: 4.1.2 dev: true - /@joshwooding/vite-plugin-react-docgen-typescript@0.3.0(typescript@5.3.3)(vite@5.0.12): + /@joshwooding/vite-plugin-react-docgen-typescript@0.3.0(typescript@5.3.3)(vite@5.1.0): resolution: {integrity: sha512-2D6y7fNvFmsLmRt6UCOFJPvFoPMJGT0Uh1Wg0RaigUp7kdQPs6yYn8Dmx6GZkOH/NW0yMTwRz/p0SRMMRo50vA==} peerDependencies: typescript: '>= 4.3.x' @@ -4708,7 +4708,7 @@ packages: magic-string: 0.27.0 react-docgen-typescript: 2.2.2(typescript@5.3.3) typescript: 5.3.3 - vite: 5.0.12(@types/node@20.11.10)(sass@1.70.0)(terser@5.27.0) + vite: 5.1.0(@types/node@20.11.10)(sass@1.70.0)(terser@5.27.0) dev: true /@jridgewell/gen-mapping@0.3.2: @@ -6740,7 +6740,7 @@ packages: - supports-color dev: true - /@storybook/builder-vite@7.6.10(typescript@5.3.3)(vite@5.0.12): + /@storybook/builder-vite@7.6.10(typescript@5.3.3)(vite@5.1.0): resolution: {integrity: sha512-qxe19axiNJVdIKj943e1ucAmADwU42fTGgMSdBzzrvfH3pSOmx2057aIxRzd8YtBRnj327eeqpgCHYIDTunMYQ==} peerDependencies: '@preact/preset-vite': '*' @@ -6772,7 +6772,7 @@ packages: magic-string: 0.30.5 rollup: 3.29.4 typescript: 5.3.3 - vite: 5.0.12(@types/node@20.11.10)(sass@1.70.0)(terser@5.27.0) + vite: 5.1.0(@types/node@20.11.10)(sass@1.70.0)(terser@5.27.0) transitivePeerDependencies: - encoding - supports-color @@ -7129,7 +7129,7 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: true - /@storybook/react-vite@7.6.10(react-dom@18.2.0)(react@18.2.0)(rollup@4.9.6)(typescript@5.3.3)(vite@5.0.12): + /@storybook/react-vite@7.6.10(react-dom@18.2.0)(react@18.2.0)(rollup@4.9.6)(typescript@5.3.3)(vite@5.1.0): resolution: {integrity: sha512-YE2+J1wy8nO+c6Nv/hBMu91Edew3K184L1KSnfoZV8vtq2074k1Me/8pfe0QNuq631AncpfCYNb37yBAXQ/80w==} engines: {node: '>=16'} peerDependencies: @@ -7137,16 +7137,16 @@ packages: react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 vite: ^3.0.0 || ^4.0.0 || ^5.0.0 dependencies: - '@joshwooding/vite-plugin-react-docgen-typescript': 0.3.0(typescript@5.3.3)(vite@5.0.12) + '@joshwooding/vite-plugin-react-docgen-typescript': 0.3.0(typescript@5.3.3)(vite@5.1.0) '@rollup/pluginutils': 5.1.0(rollup@4.9.6) - '@storybook/builder-vite': 7.6.10(typescript@5.3.3)(vite@5.0.12) + '@storybook/builder-vite': 7.6.10(typescript@5.3.3)(vite@5.1.0) '@storybook/react': 7.6.10(react-dom@18.2.0)(react@18.2.0)(typescript@5.3.3) - '@vitejs/plugin-react': 3.1.0(vite@5.0.12) + '@vitejs/plugin-react': 3.1.0(vite@5.1.0) magic-string: 0.30.5 react: 18.2.0 react-docgen: 7.0.1 react-dom: 18.2.0(react@18.2.0) - vite: 5.0.12(@types/node@20.11.10)(sass@1.70.0)(terser@5.27.0) + vite: 5.1.0(@types/node@20.11.10)(sass@1.70.0)(terser@5.27.0) transitivePeerDependencies: - '@preact/preset-vite' - encoding @@ -7261,18 +7261,18 @@ packages: file-system-cache: 2.3.0 dev: true - /@storybook/vue3-vite@7.6.10(typescript@5.3.3)(vite@5.0.12)(vue@3.4.15): + /@storybook/vue3-vite@7.6.10(typescript@5.3.3)(vite@5.1.0)(vue@3.4.15): resolution: {integrity: sha512-5f0Rh4PTVEeAI86ybihfN+rHGXXLNiRsoGKinpJSb7hkfsq/L7u3sVCXJwH/qsG+rUJlZyHs3kfa4/Kgyyi3Mg==} engines: {node: ^14.18 || >=16} peerDependencies: vite: ^3.0.0 || ^4.0.0 || ^5.0.0 dependencies: - '@storybook/builder-vite': 7.6.10(typescript@5.3.3)(vite@5.0.12) + '@storybook/builder-vite': 7.6.10(typescript@5.3.3)(vite@5.1.0) '@storybook/core-server': 7.6.10 '@storybook/vue3': 7.6.10(vue@3.4.15) - '@vitejs/plugin-vue': 4.5.2(vite@5.0.12)(vue@3.4.15) + '@vitejs/plugin-vue': 4.5.2(vite@5.1.0)(vue@3.4.15) magic-string: 0.30.5 - vite: 5.0.12(@types/node@20.11.10)(sass@1.70.0)(terser@5.27.0) + vite: 5.1.0(@types/node@20.11.10)(sass@1.70.0)(terser@5.27.0) vue-docgen-api: 4.64.1(vue@3.4.15) transitivePeerDependencies: - '@preact/preset-vite' @@ -8833,7 +8833,7 @@ packages: resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} dev: true - /@vitejs/plugin-react@3.1.0(vite@5.0.12): + /@vitejs/plugin-react@3.1.0(vite@5.1.0): resolution: {integrity: sha512-AfgcRL8ZBhAlc3BFdigClmTUMISmmzHn7sB2h9U1odvc5U/MjWXsAaz18b/WoppUTDBzxOJwo2VdClfUcItu9g==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: @@ -8844,30 +8844,30 @@ packages: '@babel/plugin-transform-react-jsx-source': 7.19.6(@babel/core@7.23.5) magic-string: 0.27.0 react-refresh: 0.14.0 - vite: 5.0.12(@types/node@20.11.10)(sass@1.70.0)(terser@5.27.0) + vite: 5.1.0(@types/node@20.11.10)(sass@1.70.0)(terser@5.27.0) transitivePeerDependencies: - supports-color dev: true - /@vitejs/plugin-vue@4.5.2(vite@5.0.12)(vue@3.4.15): + /@vitejs/plugin-vue@4.5.2(vite@5.1.0)(vue@3.4.15): resolution: {integrity: sha512-UGR3DlzLi/SaVBPX0cnSyE37vqxU3O6chn8l0HJNzQzDia6/Au2A4xKv+iIJW8w2daf80G7TYHhi1pAUjdZ0bQ==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: vite: ^4.0.0 || ^5.0.0 vue: ^3.2.25 dependencies: - vite: 5.0.12(@types/node@20.11.10)(sass@1.70.0)(terser@5.27.0) + vite: 5.1.0(@types/node@20.11.10)(sass@1.70.0)(terser@5.27.0) vue: 3.4.15(typescript@5.3.3) dev: true - /@vitejs/plugin-vue@5.0.3(vite@5.0.12)(vue@3.4.15): + /@vitejs/plugin-vue@5.0.3(vite@5.1.0)(vue@3.4.15): resolution: {integrity: sha512-b8S5dVS40rgHdDrw+DQi/xOM9ed+kSRZzfm1T74bMmBDCd8XO87NKlFYInzCtwvtWwXZvo1QxE2OSspTATWrbA==} engines: {node: ^18.0.0 || >=20.0.0} peerDependencies: vite: ^5.0.0 vue: ^3.2.25 dependencies: - vite: 5.0.12(@types/node@20.11.10)(sass@1.70.0)(terser@5.27.0) + vite: 5.1.0(@types/node@20.11.10)(sass@1.70.0)(terser@5.27.0) vue: 3.4.15(typescript@5.3.3) dev: false @@ -16910,6 +16910,14 @@ packages: picocolors: 1.0.0 source-map-js: 1.0.2 + /postcss@8.4.35: + resolution: {integrity: sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.7 + picocolors: 1.0.0 + source-map-js: 1.0.2 + /postgres-array@2.0.0: resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==} engines: {node: '>=4'} @@ -19866,7 +19874,7 @@ packages: mlly: 1.5.0 pathe: 1.1.2 picocolors: 1.0.0 - vite: 5.0.12(@types/node@20.11.10)(sass@1.70.0)(terser@5.27.0) + vite: 5.1.0(@types/node@20.11.10)(sass@1.70.0)(terser@5.27.0) transitivePeerDependencies: - '@types/node' - less @@ -19882,8 +19890,8 @@ packages: resolution: {integrity: sha512-p4D8CFVhZS412SyQX125qxyzOgIFouwOcvjZWk6bQbNPR1wtaEzFT6jZxAjf1dejlGqa6fqHcuCvQea6EWUkUA==} dev: true - /vite@5.0.12(@types/node@20.11.10)(sass@1.70.0)(terser@5.27.0): - resolution: {integrity: sha512-4hsnEkG3q0N4Tzf1+t6NdN9dg/L3BM+q8SWgbSPnJvrgH2kgdyzfVJwbR1ic69/4uMJJ/3dqDZZE5/WwqW8U1w==} + /vite@5.1.0(@types/node@20.11.10)(sass@1.70.0)(terser@5.27.0): + resolution: {integrity: sha512-STmSFzhY4ljuhz14bg9LkMTk3d98IO6DIArnTY6MeBwiD1Za2StcQtz7fzOUnRCqrHSD5+OS2reg4HOz1eoLnw==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: @@ -19912,7 +19920,7 @@ packages: dependencies: '@types/node': 20.11.10 esbuild: 0.19.11 - postcss: 8.4.33 + postcss: 8.4.35 rollup: 4.9.6 sass: 1.70.0 terser: 5.27.0 @@ -19984,7 +19992,7 @@ packages: strip-literal: 1.3.0 tinybench: 2.6.0 tinypool: 0.7.0 - vite: 5.0.12(@types/node@20.11.10)(sass@1.70.0)(terser@5.27.0) + vite: 5.1.0(@types/node@20.11.10)(sass@1.70.0)(terser@5.27.0) vite-node: 0.34.6(@types/node@20.11.10)(sass@1.70.0)(terser@5.27.0) why-is-node-running: 2.2.2 transitivePeerDependencies: -- GitLab From 614c9a0fc602586710e3f24bb26140bb49c2d54a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=8A=E3=81=95=E3=82=80=E3=81=AE=E3=81=B2=E3=81=A8?= <46447427+samunohito@users.noreply.github.com> Date: Fri, 9 Feb 2024 10:07:18 +0900 Subject: [PATCH 32/40] =?UTF-8?q?fix:=20=E7=89=B9=E5=AE=9A=E6=96=87?= =?UTF-8?q?=E5=AD=97=E5=88=97=E3=82=92=E5=90=AB=E3=82=80=E3=83=8E=E3=83=BC?= =?UTF-8?q?=E3=83=88=E3=82=92=E6=8A=95=E7=A8=BF=E3=81=A7=E3=81=8D=E3=81=AA?= =?UTF-8?q?=E3=81=84=E3=82=88=E3=81=86=E3=81=AB=E3=81=99=E3=82=8B=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E7=94=BB=E9=9D=A2=E7=94=A8=E8=A8=AD=E5=AE=9A=E9=A0=85?= =?UTF-8?q?=E7=9B=AE=E3=82=92=E8=BF=BD=E5=8A=A0=20(#13210)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: 特定文å—列をå«ã‚€ãƒŽãƒ¼ãƒˆã‚’投稿ã§ããªã„よã†ã«ã™ã‚‹ç®¡ç†ç”»é¢ç”¨è¨å®šé …ç›®ã‚’è¿½åŠ * Serviceã§ãƒã‚§ãƒƒã‚¯ã™ã‚‹ã‚ˆã†ã«å¤‰æ›´ --- CHANGELOG.md | 2 + locales/index.d.ts | 12 +++ locales/ja-JP.yml | 3 + .../1707429690000-prohibited-words.js | 16 ++++ packages/backend/src/core/HashtagService.ts | 2 +- .../backend/src/core/NoteCreateService.ts | 10 ++- packages/backend/src/core/UtilityService.ts | 6 +- packages/backend/src/models/Meta.ts | 5 ++ .../src/server/api/endpoints/admin/meta.ts | 8 ++ .../server/api/endpoints/admin/update-meta.ts | 8 ++ .../src/server/api/endpoints/notes/create.ts | 67 ++++++++++------- packages/backend/test/e2e/note.ts | 73 +++++++++++++++++++ .../frontend/src/pages/admin/moderation.vue | 8 ++ packages/misskey-js/src/autogen/types.ts | 2 + 14 files changed, 192 insertions(+), 30 deletions(-) create mode 100644 packages/backend/migration/1707429690000-prohibited-words.js diff --git a/CHANGELOG.md b/CHANGELOG.md index a32c557c94..1d788e1522 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,8 @@ - Fix: リモートユーザーã®ãƒªã‚¢ã‚¯ã‚·ãƒ§ãƒ³ä¸€è¦§ãŒã™ã¹ã¦è¦‹ãˆã¦ã—ã¾ã†ã®ã‚’ä¿®æ£ * ã™ã¹ã¦ã®ãƒªãƒ¢ãƒ¼ãƒˆãƒ¦ãƒ¼ã‚¶ãƒ¼ã®ãƒªã‚¢ã‚¯ã‚·ãƒ§ãƒ³ä¸€è¦§ã‚’見ãˆãªã„よã†ã«ã—ã¾ã™ - Enhance: モデレーターã¯ã™ã¹ã¦ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã®ãƒªã‚¢ã‚¯ã‚·ãƒ§ãƒ³ä¸€è¦§ã‚’見られるよã†ã« +- Fix: 特定ã®ã‚ーワードをå«ã‚€ãƒŽãƒ¼ãƒˆãŒæŠ•ç¨¿ã•ã‚ŒãŸéš›ã€ã‚¨ãƒ©ãƒ¼ã«å‡ºæ¥ã‚‹ã‚ˆã†ãªè¨å®šé …ç›®ã‚’è¿½åŠ #13207 + * デフォルトã¯ç©ºæ¬„ãªã®ã§é©ç”¨å‰ã¨åŒç‰ã®å‹•ä½œã«ãªã‚Šã¾ã™ ### Client - Feat: æ–°ã—ã„ã‚²ãƒ¼ãƒ ã‚’è¿½åŠ diff --git a/locales/index.d.ts b/locales/index.d.ts index f8c4971655..8f4c9d18e4 100644 --- a/locales/index.d.ts +++ b/locales/index.d.ts @@ -4180,6 +4180,18 @@ export interface Locale extends ILocale { * スペースã§åŒºåˆ‡ã‚‹ã¨AND指定ã«ãªã‚Šã€ã‚ーワードをスラッシュã§å›²ã‚€ã¨æ£è¦è¡¨ç¾ã«ãªã‚Šã¾ã™ã€‚ */ "sensitiveWordsDescription2": string; + /** + * ç¦æ¢ãƒ¯ãƒ¼ãƒ‰ + */ + "prohibitedWords": string; + /** + * è¨å®šã—ãŸãƒ¯ãƒ¼ãƒ‰ãŒå«ã¾ã‚Œã‚‹ãƒŽãƒ¼ãƒˆã‚’投稿ã—よã†ã¨ã—ãŸéš›ã€ã‚¨ãƒ©ãƒ¼ã¨ãªã‚‹ã‚ˆã†ã«ã—ã¾ã™ã€‚改行ã§åŒºåˆ‡ã£ã¦è¤‡æ•°è¨å®šã§ãã¾ã™ã€‚ + */ + "prohibitedWordsDescription": string; + /** + * スペースã§åŒºåˆ‡ã‚‹ã¨AND指定ã«ãªã‚Šã€ã‚ーワードをスラッシュã§å›²ã‚€ã¨æ£è¦è¡¨ç¾ã«ãªã‚Šã¾ã™ã€‚ + */ + "prohibitedWordsDescription2": string; /** * éžè¡¨ç¤ºãƒãƒƒã‚·ãƒ¥ã‚¿ã‚° */ diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index cf45c13f75..5348502425 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -1041,6 +1041,9 @@ resetPasswordConfirm: "パスワードリセットã—ã¾ã™ã‹ï¼Ÿ" sensitiveWords: "センシティブワード" sensitiveWordsDescription: "è¨å®šã—ãŸãƒ¯ãƒ¼ãƒ‰ãŒå«ã¾ã‚Œã‚‹ãƒŽãƒ¼ãƒˆã®å…¬é–‹ç¯„囲をホームã«ã—ã¾ã™ã€‚改行ã§åŒºåˆ‡ã£ã¦è¤‡æ•°è¨å®šã§ãã¾ã™ã€‚" sensitiveWordsDescription2: "スペースã§åŒºåˆ‡ã‚‹ã¨AND指定ã«ãªã‚Šã€ã‚ーワードをスラッシュã§å›²ã‚€ã¨æ£è¦è¡¨ç¾ã«ãªã‚Šã¾ã™ã€‚" +prohibitedWords: "ç¦æ¢ãƒ¯ãƒ¼ãƒ‰" +prohibitedWordsDescription: "è¨å®šã—ãŸãƒ¯ãƒ¼ãƒ‰ãŒå«ã¾ã‚Œã‚‹ãƒŽãƒ¼ãƒˆã‚’投稿ã—よã†ã¨ã—ãŸéš›ã€ã‚¨ãƒ©ãƒ¼ã¨ãªã‚‹ã‚ˆã†ã«ã—ã¾ã™ã€‚改行ã§åŒºåˆ‡ã£ã¦è¤‡æ•°è¨å®šã§ãã¾ã™ã€‚" +prohibitedWordsDescription2: "スペースã§åŒºåˆ‡ã‚‹ã¨AND指定ã«ãªã‚Šã€ã‚ーワードをスラッシュã§å›²ã‚€ã¨æ£è¦è¡¨ç¾ã«ãªã‚Šã¾ã™ã€‚" hiddenTags: "éžè¡¨ç¤ºãƒãƒƒã‚·ãƒ¥ã‚¿ã‚°" hiddenTagsDescription: "è¨å®šã—ãŸã‚¿ã‚°ã‚’トレンドã«è¡¨ç¤ºã•ã›ãªã„よã†ã«ã—ã¾ã™ã€‚改行ã§åŒºåˆ‡ã£ã¦è¤‡æ•°è¨å®šã§ãã¾ã™ã€‚" notesSearchNotAvailable: "ノート検索ã¯åˆ©ç”¨ã§ãã¾ã›ã‚“。" diff --git a/packages/backend/migration/1707429690000-prohibited-words.js b/packages/backend/migration/1707429690000-prohibited-words.js new file mode 100644 index 0000000000..2dd62d8ff8 --- /dev/null +++ b/packages/backend/migration/1707429690000-prohibited-words.js @@ -0,0 +1,16 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +export class prohibitedWords1707429690000 { + name = 'prohibitedWords1707429690000' + + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" ADD "prohibitedWords" character varying(1024) array NOT NULL DEFAULT '{}'`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "prohibitedWords"`); + } +} diff --git a/packages/backend/src/core/HashtagService.ts b/packages/backend/src/core/HashtagService.ts index 5a2417c9cd..712530108e 100644 --- a/packages/backend/src/core/HashtagService.ts +++ b/packages/backend/src/core/HashtagService.ts @@ -163,7 +163,7 @@ export class HashtagService { const instance = await this.metaService.fetch(); const hiddenTags = instance.hiddenTags.map(t => normalizeForSearch(t)); if (hiddenTags.includes(hashtag)) return; - if (this.utilityService.isSensitiveWordIncluded(hashtag, instance.sensitiveWords)) return; + if (this.utilityService.isKeyWordIncluded(hashtag, instance.sensitiveWords)) return; // YYYYMMDDHHmm (10分間隔) const now = new Date(); diff --git a/packages/backend/src/core/NoteCreateService.ts b/packages/backend/src/core/NoteCreateService.ts index f7e870831d..153a6406a9 100644 --- a/packages/backend/src/core/NoteCreateService.ts +++ b/packages/backend/src/core/NoteCreateService.ts @@ -151,6 +151,8 @@ type Option = { export class NoteCreateService implements OnApplicationShutdown { #shutdownController = new AbortController(); + public static ContainsProhibitedWordsError = class extends Error {}; + constructor( @Inject(DI.config) private config: Config, @@ -254,13 +256,19 @@ export class NoteCreateService implements OnApplicationShutdown { if (data.visibility === 'public' && data.channel == null) { const sensitiveWords = meta.sensitiveWords; - if (this.utilityService.isSensitiveWordIncluded(data.cw ?? data.text ?? '', sensitiveWords)) { + if (this.utilityService.isKeyWordIncluded(data.cw ?? data.text ?? '', sensitiveWords)) { data.visibility = 'home'; } else if ((await this.roleService.getUserPolicies(user.id)).canPublicNote === false) { data.visibility = 'home'; } } + if (!user.host) { + if (this.utilityService.isKeyWordIncluded(data.cw ?? data.text ?? '', meta.prohibitedWords)) { + throw new NoteCreateService.ContainsProhibitedWordsError(); + } + } + const inSilencedInstance = this.utilityService.isSilencedHost(meta.silencedHosts, user.host); if (data.visibility === 'public' && inSilencedInstance && user.host !== null) { diff --git a/packages/backend/src/core/UtilityService.ts b/packages/backend/src/core/UtilityService.ts index 5dec36c89e..15b98abe63 100644 --- a/packages/backend/src/core/UtilityService.ts +++ b/packages/backend/src/core/UtilityService.ts @@ -43,13 +43,13 @@ export class UtilityService { } @bindThis - public isSensitiveWordIncluded(text: string, sensitiveWords: string[]): boolean { - if (sensitiveWords.length === 0) return false; + public isKeyWordIncluded(text: string, keyWords: string[]): boolean { + if (keyWords.length === 0) return false; if (text === '') return false; const regexpregexp = /^\/(.+)\/(.*)$/; - const matched = sensitiveWords.some(filter => { + const matched = keyWords.some(filter => { // represents RegExp const regexp = filter.match(regexpregexp); // This should never happen due to input sanitisation. diff --git a/packages/backend/src/models/Meta.ts b/packages/backend/src/models/Meta.ts index 3265e85dd7..bcde2db0b7 100644 --- a/packages/backend/src/models/Meta.ts +++ b/packages/backend/src/models/Meta.ts @@ -76,6 +76,11 @@ export class MiMeta { }) public sensitiveWords: string[]; + @Column('varchar', { + length: 1024, array: true, default: '{}', + }) + public prohibitedWords: string[]; + @Column('varchar', { length: 1024, array: true, default: '{}', }) diff --git a/packages/backend/src/server/api/endpoints/admin/meta.ts b/packages/backend/src/server/api/endpoints/admin/meta.ts index 0627c5055c..2af9e7cd9a 100644 --- a/packages/backend/src/server/api/endpoints/admin/meta.ts +++ b/packages/backend/src/server/api/endpoints/admin/meta.ts @@ -156,6 +156,13 @@ export const meta = { type: 'string', }, }, + prohibitedWords: { + type: 'array', + optional: false, nullable: false, + items: { + type: 'string', + }, + }, bannedEmailDomains: { type: 'array', optional: true, nullable: false, @@ -515,6 +522,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- blockedHosts: instance.blockedHosts, silencedHosts: instance.silencedHosts, sensitiveWords: instance.sensitiveWords, + prohibitedWords: instance.prohibitedWords, preservedUsernames: instance.preservedUsernames, hcaptchaSecretKey: instance.hcaptchaSecretKey, mcaptchaSecretKey: instance.mcaptchaSecretKey, diff --git a/packages/backend/src/server/api/endpoints/admin/update-meta.ts b/packages/backend/src/server/api/endpoints/admin/update-meta.ts index d76d3dfeea..ce8c8a505d 100644 --- a/packages/backend/src/server/api/endpoints/admin/update-meta.ts +++ b/packages/backend/src/server/api/endpoints/admin/update-meta.ts @@ -41,6 +41,11 @@ export const paramDef = { type: 'string', }, }, + prohibitedWords: { + type: 'array', nullable: true, items: { + type: 'string', + }, + }, themeColor: { type: 'string', nullable: true, pattern: '^#[0-9a-fA-F]{6}$' }, mascotImageUrl: { type: 'string', nullable: true }, bannerUrl: { type: 'string', nullable: true }, @@ -177,6 +182,9 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- if (Array.isArray(ps.sensitiveWords)) { set.sensitiveWords = ps.sensitiveWords.filter(Boolean); } + if (Array.isArray(ps.prohibitedWords)) { + set.prohibitedWords = ps.prohibitedWords.filter(Boolean); + } if (Array.isArray(ps.silencedHosts)) { let lastValue = ''; set.silencedHosts = ps.silencedHosts.sort().filter((h) => { diff --git a/packages/backend/src/server/api/endpoints/notes/create.ts b/packages/backend/src/server/api/endpoints/notes/create.ts index 787cda3834..50969c71cc 100644 --- a/packages/backend/src/server/api/endpoints/notes/create.ts +++ b/packages/backend/src/server/api/endpoints/notes/create.ts @@ -17,6 +17,8 @@ import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; import { NoteCreateService } from '@/core/NoteCreateService.js'; import { DI } from '@/di-symbols.js'; import { isPureRenote } from '@/misc/is-pure-renote.js'; +import { MetaService } from '@/core/MetaService.js'; +import { UtilityService } from '@/core/UtilityService.js'; import { ApiError } from '../../error.js'; export const meta = { @@ -111,6 +113,12 @@ export const meta = { code: 'CANNOT_RENOTE_OUTSIDE_OF_CHANNEL', id: '33510210-8452-094c-6227-4a6c05d99f00', }, + + containsProhibitedWords: { + message: 'Cannot post because it contains prohibited words.', + code: 'CONTAINS_PROHIBITED_WORDS', + id: 'aa6e01d3-a85c-669d-758a-76aab43af334', + }, }, } as const; @@ -340,31 +348,40 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- } // æŠ•ç¨¿ã‚’ä½œæˆ - const note = await this.noteCreateService.create(me, { - createdAt: new Date(), - files: files, - poll: ps.poll ? { - choices: ps.poll.choices, - multiple: ps.poll.multiple ?? false, - expiresAt: ps.poll.expiresAt ? new Date(ps.poll.expiresAt) : null, - } : undefined, - text: ps.text ?? undefined, - reply, - renote, - cw: ps.cw, - localOnly: ps.localOnly, - reactionAcceptance: ps.reactionAcceptance, - visibility: ps.visibility, - visibleUsers, - channel, - apMentions: ps.noExtractMentions ? [] : undefined, - apHashtags: ps.noExtractHashtags ? [] : undefined, - apEmojis: ps.noExtractEmojis ? [] : undefined, - }); - - return { - createdNote: await this.noteEntityService.pack(note, me), - }; + try { + const note = await this.noteCreateService.create(me, { + createdAt: new Date(), + files: files, + poll: ps.poll ? { + choices: ps.poll.choices, + multiple: ps.poll.multiple ?? false, + expiresAt: ps.poll.expiresAt ? new Date(ps.poll.expiresAt) : null, + } : undefined, + text: ps.text ?? undefined, + reply, + renote, + cw: ps.cw, + localOnly: ps.localOnly, + reactionAcceptance: ps.reactionAcceptance, + visibility: ps.visibility, + visibleUsers, + channel, + apMentions: ps.noExtractMentions ? [] : undefined, + apHashtags: ps.noExtractHashtags ? [] : undefined, + apEmojis: ps.noExtractEmojis ? [] : undefined, + }); + + return { + createdNote: await this.noteEntityService.pack(note, me), + }; + } catch (e) { + // TODO: ä»–ã®Errorã‚‚ã“ã“ã§ã‚ャッãƒã—ã¦ã‚¨ãƒ©ãƒ¼ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’当ã¦ã‚‹ã‚ˆã†ã«ã—ãŸã„ + if (e instanceof NoteCreateService.ContainsProhibitedWordsError) { + throw new ApiError(meta.errors.containsProhibitedWords); + } + + throw e; + } }); } } diff --git a/packages/backend/test/e2e/note.ts b/packages/backend/test/e2e/note.ts index 0280b051f5..1bc8cb591c 100644 --- a/packages/backend/test/e2e/note.ts +++ b/packages/backend/test/e2e/note.ts @@ -16,12 +16,14 @@ describe('Note', () => { let alice: misskey.entities.SignupResponse; let bob: misskey.entities.SignupResponse; + let tom: misskey.entities.SignupResponse; beforeAll(async () => { const connection = await initTestDb(true); Notes = connection.getRepository(MiNote); alice = await signup({ username: 'alice' }); bob = await signup({ username: 'bob' }); + tom = await signup({ username: 'tom', host: 'example.com' }); }, 1000 * 60 * 2); test('投稿ã§ãã‚‹', async () => { @@ -607,6 +609,77 @@ describe('Note', () => { assert.strictEqual(note2.status, 200); assert.strictEqual(note2.body.createdNote.visibility, 'home'); }); + + test('ç¦æ¢ãƒ¯ãƒ¼ãƒ‰ã‚’å«ã‚€æŠ•ç¨¿ã¯ã‚¨ãƒ©ãƒ¼ã«ãªã‚‹ (å˜èªžæŒ‡å®š)', async () => { + const prohibited = await api('admin/update-meta', { + prohibitedWords: [ + 'test', + ], + }, alice); + + assert.strictEqual(prohibited.status, 204); + + await new Promise(x => setTimeout(x, 2)); + + const note1 = await api('/notes/create', { + text: 'hogetesthuge', + }, alice); + + assert.strictEqual(note1.status, 400); + assert.strictEqual(note1.body.error.code, 'CONTAINS_PROHIBITED_WORDS'); + }); + + test('ç¦æ¢ãƒ¯ãƒ¼ãƒ‰ã‚’å«ã‚€æŠ•ç¨¿ã¯ã‚¨ãƒ©ãƒ¼ã«ãªã‚‹ (æ£è¦è¡¨ç¾)', async () => { + const prohibited = await api('admin/update-meta', { + prohibitedWords: [ + '/Test/i', + ], + }, alice); + + assert.strictEqual(prohibited.status, 204); + + const note2 = await api('/notes/create', { + text: 'hogetesthuge', + }, alice); + + assert.strictEqual(note2.status, 400); + assert.strictEqual(note2.body.error.code, 'CONTAINS_PROHIBITED_WORDS'); + }); + + test('ç¦æ¢ãƒ¯ãƒ¼ãƒ‰ã‚’å«ã‚€æŠ•ç¨¿ã¯ã‚¨ãƒ©ãƒ¼ã«ãªã‚‹ (スペースアンド)', async () => { + const prohibited = await api('admin/update-meta', { + prohibitedWords: [ + 'Test hoge', + ], + }, alice); + + assert.strictEqual(prohibited.status, 204); + + const note2 = await api('/notes/create', { + text: 'hogeTesthuge', + }, alice); + + assert.strictEqual(note2.status, 400); + assert.strictEqual(note2.body.error.code, 'CONTAINS_PROHIBITED_WORDS'); + }); + + test('ç¦æ¢ãƒ¯ãƒ¼ãƒ‰ã‚’å«ã‚“ã§ã„ã¦ã‚‚リモートノートã¯ã‚¨ãƒ©ãƒ¼ã«ãªã‚‰ãªã„', async () => { + const prohibited = await api('admin/update-meta', { + prohibitedWords: [ + 'test', + ], + }, alice); + + assert.strictEqual(prohibited.status, 204); + + await new Promise(x => setTimeout(x, 2)); + + const note1 = await api('/notes/create', { + text: 'hogetesthuge', + }, tom); + + assert.strictEqual(note1.status, 200); + }); }); describe('notes/delete', () => { diff --git a/packages/frontend/src/pages/admin/moderation.vue b/packages/frontend/src/pages/admin/moderation.vue index 4915bee713..248b4c53ce 100644 --- a/packages/frontend/src/pages/admin/moderation.vue +++ b/packages/frontend/src/pages/admin/moderation.vue @@ -40,6 +40,11 @@ SPDX-License-Identifier: AGPL-3.0-only <template #caption>{{ i18n.ts.sensitiveWordsDescription }}<br>{{ i18n.ts.sensitiveWordsDescription2 }}</template> </MkTextarea> + <MkTextarea v-model="prohibitedWords"> + <template #label>{{ i18n.ts.prohibitedWords }}</template> + <template #caption>{{ i18n.ts.prohibitedWordsDescription }}<br>{{ i18n.ts.prohibitedWordsDescription2 }}</template> + </MkTextarea> + <MkTextarea v-model="hiddenTags"> <template #label>{{ i18n.ts.hiddenTags }}</template> <template #caption>{{ i18n.ts.hiddenTagsDescription }}</template> @@ -76,6 +81,7 @@ import FormLink from '@/components/form/link.vue'; const enableRegistration = ref<boolean>(false); const emailRequiredForSignup = ref<boolean>(false); const sensitiveWords = ref<string>(''); +const prohibitedWords = ref<string>(''); const hiddenTags = ref<string>(''); const preservedUsernames = ref<string>(''); const tosUrl = ref<string | null>(null); @@ -86,6 +92,7 @@ async function init() { enableRegistration.value = !meta.disableRegistration; emailRequiredForSignup.value = meta.emailRequiredForSignup; sensitiveWords.value = meta.sensitiveWords.join('\n'); + prohibitedWords.value = meta.prohibitedWords.join('\n'); hiddenTags.value = meta.hiddenTags.join('\n'); preservedUsernames.value = meta.preservedUsernames.join('\n'); tosUrl.value = meta.tosUrl; @@ -99,6 +106,7 @@ function save() { tosUrl: tosUrl.value, privacyPolicyUrl: privacyPolicyUrl.value, sensitiveWords: sensitiveWords.value.split('\n'), + prohibitedWords: prohibitedWords.value.split('\n'), hiddenTags: hiddenTags.value.split('\n'), preservedUsernames: preservedUsernames.value.split('\n'), }).then(() => { diff --git a/packages/misskey-js/src/autogen/types.ts b/packages/misskey-js/src/autogen/types.ts index b7d65406cb..94d6673ac5 100644 --- a/packages/misskey-js/src/autogen/types.ts +++ b/packages/misskey-js/src/autogen/types.ts @@ -4659,6 +4659,7 @@ export type operations = { hiddenTags: string[]; blockedHosts: string[]; sensitiveWords: string[]; + prohibitedWords: string[]; bannedEmailDomains?: string[]; preservedUsernames: string[]; hcaptchaSecretKey: string | null; @@ -8413,6 +8414,7 @@ export type operations = { hiddenTags?: string[] | null; blockedHosts?: string[] | null; sensitiveWords?: string[] | null; + prohibitedWords?: string[] | null; themeColor?: string | null; mascotImageUrl?: string | null; bannerUrl?: string | null; -- GitLab From c23c97d303d227f6a0e2b3c775189f90772c1dfa Mon Sep 17 00:00:00 2001 From: syuilo <Syuilotan@yahoo.co.jp> Date: Fri, 9 Feb 2024 16:25:58 +0900 Subject: [PATCH 33/40] =?UTF-8?q?perf(frontend):=20splash=20screen?= =?UTF-8?q?=E3=81=AEdom=E3=81=8C=E6=B6=88=E3=81=88=E3=81=AA=E3=81=84?= =?UTF-8?q?=E5=A0=B4=E5=90=88=E3=81=8C=E3=81=82=E3=82=8B=E3=81=AE=E3=82=92?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://github.com/misskey-dev/misskey/issues/10805 --- packages/frontend/src/boot/common.ts | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/packages/frontend/src/boot/common.ts b/packages/frontend/src/boot/common.ts index fd5a03a70d..295585af57 100644 --- a/packages/frontend/src/boot/common.ts +++ b/packages/frontend/src/boot/common.ts @@ -60,12 +60,6 @@ export async function common(createVue: () => App<Element>) { }); } - const splash = document.getElementById('splash'); - // 念ã®ãŸã‚nullãƒã‚§ãƒƒã‚¯(HTMLãŒå¤ã„å ´åˆãŒã‚ã‚‹ãŸã‚(ãã®ã†ã¡æ¶ˆã™)) - if (splash) splash.addEventListener('transitionend', () => { - splash.remove(); - }); - let isClientUpdated = false; //#region クライアントãŒæ›´æ–°ã•ã‚ŒãŸã‹ãƒã‚§ãƒƒã‚¯ @@ -289,5 +283,10 @@ function removeSplash() { if (splash) { splash.style.opacity = '0'; splash.style.pointerEvents = 'none'; + + // transitionendイベントãŒç™ºç«ã—ãªã„å ´åˆãŒã‚ã‚‹ãŸã‚ + window.setTimeout(() => { + splash.remove(); + }, 1000); } } -- GitLab From 37d83df075214df0c4933ce28546cc8a2a9b95a2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 9 Feb 2024 17:05:25 +0900 Subject: [PATCH 34/40] chore(deps): bump pnpm/action-setup from 2 to 3 (#13215) Bumps [pnpm/action-setup](https://github.com/pnpm/action-setup) from 2 to 3. - [Release notes](https://github.com/pnpm/action-setup/releases) - [Commits](https://github.com/pnpm/action-setup/compare/v2...v3) --- updated-dependencies: - dependency-name: pnpm/action-setup dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/check-misskey-js-autogen.yml | 2 +- .github/workflows/get-api-diff.yml | 2 +- .github/workflows/lint.yml | 6 +++--- .github/workflows/on-release-created.yml | 2 +- .github/workflows/test-backend.yml | 4 ++-- .github/workflows/test-frontend.yml | 4 ++-- .github/workflows/test-production.yml | 2 +- .github/workflows/validate-api-json.yml | 2 +- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/check-misskey-js-autogen.yml b/.github/workflows/check-misskey-js-autogen.yml index 545b215756..4aaa8a5798 100644 --- a/.github/workflows/check-misskey-js-autogen.yml +++ b/.github/workflows/check-misskey-js-autogen.yml @@ -25,7 +25,7 @@ jobs: ref: ${{ github.event.pull_request.head.sha }} - name: setup pnpm - uses: pnpm/action-setup@v2 + uses: pnpm/action-setup@v3 with: version: 8 diff --git a/.github/workflows/get-api-diff.yml b/.github/workflows/get-api-diff.yml index bf92e701b2..3f229c77a6 100644 --- a/.github/workflows/get-api-diff.yml +++ b/.github/workflows/get-api-diff.yml @@ -32,7 +32,7 @@ jobs: ref: ${{ matrix.ref }} submodules: true - name: Install pnpm - uses: pnpm/action-setup@v2 + uses: pnpm/action-setup@v3 with: version: 8 run_install: false diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 86fca995d2..5c36547323 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -27,7 +27,7 @@ jobs: with: fetch-depth: 0 submodules: true - - uses: pnpm/action-setup@v2 + - uses: pnpm/action-setup@v3 with: version: 8 run_install: false @@ -54,7 +54,7 @@ jobs: with: fetch-depth: 0 submodules: true - - uses: pnpm/action-setup@v2 + - uses: pnpm/action-setup@v3 with: version: 7 run_install: false @@ -80,7 +80,7 @@ jobs: with: fetch-depth: 0 submodules: true - - uses: pnpm/action-setup@v2 + - uses: pnpm/action-setup@v3 with: version: 7 run_install: false diff --git a/.github/workflows/on-release-created.yml b/.github/workflows/on-release-created.yml index 3cc0e5007b..d2508f1b77 100644 --- a/.github/workflows/on-release-created.yml +++ b/.github/workflows/on-release-created.yml @@ -24,7 +24,7 @@ jobs: with: submodules: true - name: Install pnpm - uses: pnpm/action-setup@v2 + uses: pnpm/action-setup@v3 with: version: 8 run_install: false diff --git a/.github/workflows/test-backend.yml b/.github/workflows/test-backend.yml index 199443fca8..7bc3ad9a8f 100644 --- a/.github/workflows/test-backend.yml +++ b/.github/workflows/test-backend.yml @@ -41,7 +41,7 @@ jobs: with: submodules: true - name: Install pnpm - uses: pnpm/action-setup@v2 + uses: pnpm/action-setup@v3 with: version: 8 run_install: false @@ -91,7 +91,7 @@ jobs: with: submodules: true - name: Install pnpm - uses: pnpm/action-setup@v2 + uses: pnpm/action-setup@v3 with: version: 8 run_install: false diff --git a/.github/workflows/test-frontend.yml b/.github/workflows/test-frontend.yml index caa3fceef5..8ede222e5d 100644 --- a/.github/workflows/test-frontend.yml +++ b/.github/workflows/test-frontend.yml @@ -33,7 +33,7 @@ jobs: with: submodules: true - name: Install pnpm - uses: pnpm/action-setup@v2 + uses: pnpm/action-setup@v3 with: version: 8 run_install: false @@ -91,7 +91,7 @@ jobs: #- uses: browser-actions/setup-firefox@latest # if: ${{ matrix.browser == 'firefox' }} - name: Install pnpm - uses: pnpm/action-setup@v2 + uses: pnpm/action-setup@v3 with: version: 7 run_install: false diff --git a/.github/workflows/test-production.yml b/.github/workflows/test-production.yml index 9e02c0d8f8..eac0a51c66 100644 --- a/.github/workflows/test-production.yml +++ b/.github/workflows/test-production.yml @@ -23,7 +23,7 @@ jobs: with: submodules: true - name: Install pnpm - uses: pnpm/action-setup@v2 + uses: pnpm/action-setup@v3 with: version: 8 run_install: false diff --git a/.github/workflows/validate-api-json.yml b/.github/workflows/validate-api-json.yml index 93c4cf4cd1..08044322c9 100644 --- a/.github/workflows/validate-api-json.yml +++ b/.github/workflows/validate-api-json.yml @@ -24,7 +24,7 @@ jobs: with: submodules: true - name: Install pnpm - uses: pnpm/action-setup@v2 + uses: pnpm/action-setup@v3 with: version: 8 run_install: false -- GitLab From b5b31bfd5be533b2b9041db8e2f83032e534b776 Mon Sep 17 00:00:00 2001 From: syuilo <Syuilotan@yahoo.co.jp> Date: Fri, 9 Feb 2024 17:05:37 +0900 Subject: [PATCH 35/40] New Crowdin updates (#13179) * New translations ja-jp.yml (Catalan) * New translations ja-jp.yml (English) * New translations ja-jp.yml (Catalan) * New translations ja-jp.yml (Catalan) * New translations ja-jp.yml (Catalan) * New translations ja-jp.yml (Catalan) * New translations ja-jp.yml (Catalan) * New translations ja-jp.yml (Catalan) * New translations ja-jp.yml (English) * New translations ja-jp.yml (Catalan) * New translations ja-jp.yml (Catalan) * New translations ja-jp.yml (Catalan) * New translations ja-jp.yml (German) * New translations ja-jp.yml (Korean) * New translations ja-jp.yml (Chinese Simplified) * New translations ja-jp.yml (Spanish) * New translations ja-jp.yml (Czech) * New translations ja-jp.yml (Italian) * New translations ja-jp.yml (Russian) * New translations ja-jp.yml (Chinese Traditional) * New translations ja-jp.yml (English) * New translations ja-jp.yml (Indonesian) * New translations ja-jp.yml (Thai) * New translations ja-jp.yml (Japanese, Kansai) * New translations ja-jp.yml (Catalan) --- locales/ca-ES.yml | 299 ++++++++++++++++++++++++++++++++++++++++++++++ locales/cs-CZ.yml | 1 + locales/de-DE.yml | 1 + locales/en-US.yml | 26 ++++ locales/es-ES.yml | 1 + locales/id-ID.yml | 1 + locales/it-IT.yml | 1 + locales/ja-KS.yml | 1 + locales/ko-KR.yml | 1 + locales/ru-RU.yml | 1 + locales/th-TH.yml | 1 + locales/zh-CN.yml | 1 + locales/zh-TW.yml | 1 + 13 files changed, 336 insertions(+) diff --git a/locales/ca-ES.yml b/locales/ca-ES.yml index 6c0d212ad2..fb43e2efff 100644 --- a/locales/ca-ES.yml +++ b/locales/ca-ES.yml @@ -1041,6 +1041,9 @@ resetPasswordConfirm: "Vols canviar la teva contrasenya?" sensitiveWords: "Paraules sensibles" sensitiveWordsDescription: "La visibilitat de totes les notes que continguin qualsevol de les paraules configurades seran, automà ticament, afegides a \"Inici\". Pots llistar diferents paraules separant les per lÃnies noves." sensitiveWordsDescription2: "Fent servir espais crearà expressions AND si l'expressió s'envolta amb barres inclinades es converteix en una expressió regular." +prohibitedWords: "Paraules prohibides" +prohibitedWordsDescription: "Quan intenteu publicar una Nota que conté una paraula prohibida, feu que es converteixi en un error. Es poden dividir i establir múltiples lÃnies." +prohibitedWordsDescription2: "Fent servir espais crearà expressions AND si l'expressió s'envolta amb barres inclinades es converteix en una expressió regular." hiddenTags: "Etiquetes ocultes" hiddenTagsDescription: "La visibilitat de totes les notes que continguin qualsevol de les paraules configurades seran, automà ticament, afegides a \"Inici\". Pots llistar diferents paraules separant les per lÃnies noves." notesSearchNotAvailable: "La cerca de notes no es troba disponible." @@ -1518,12 +1521,82 @@ _achievements: title: "Nocturn" description: "Publica una nota a altes hores de la nit " flavor: "És hora d'anar a dormir." + _postedAt0min0sec: + title: "Rellotge xerraire" + description: "Publica una nota a les 0:00" + flavor: "Tic tac, tic tac, tic tac, DING!" + _selfQuote: + title: "Autoreferència " + description: "Cita una nota teva" + _htl20npm: + title: "LÃnia de temps fluida" + description: "La teva lÃnia de temps va a més de 20npm (notes per minut)" + _viewInstanceChart: + title: "Analista " + description: "Mira els grà fics de la teva instà ncia " + _outputHelloWorldOnScratchpad: + title: "Hola, món!" + description: "Escriu \"hola, món\" al bloc de notes" _open3windows: title: "Multi finestres" description: "I va obrir més de tres finestres" _driveFolderCircularReference: title: "Consulteu la secció de bucle" + description: "Intenta crear carpetes recursives al Disc" + _reactWithoutRead: + title: "De veritat has llegit això?" + description: "Reaccions a una nota de més de 100 carà cters publicada fa menys de 3 segons " + _clickedClickHere: + title: "Fer clic" + description: "Has fet clic aquà " + _justPlainLucky: + title: "Ha sigut sort" + description: "Oportunitat de guanyar-lo amb una probabilitat d'un 0.005% cada 10 segons" + _setNameToSyuilo: + title: "soc millor" + description: "Posat \"siuylo\" com a nom" + _passedSinceAccountCreated1: + title: "Primer aniversari" + description: "Ja ha passat un any d'ençà que vas crear el teu compte" + _passedSinceAccountCreated2: + title: "Segon aniversari" + description: "Ja han passat dos anys d'ençà que vas crear el teu compte" + _passedSinceAccountCreated3: + title: "Tres anys" + description: "Ja han passat tres anys d'ençà que vas crear el teu compte" + _loggedInOnBirthday: + title: "Felicitats!" + description: "T'has identificat el dia del teu aniversari" + _loggedInOnNewYearsDay: + title: "Bon any nou!" + description: "T'has identificat el primer dia de l'any " + flavor: "A per un altre any memorable a la teva instà ncia " + _cookieClicked: + title: "Un joc en què fas clic a les galetes" + description: "Pica galetes" + flavor: "Espera, ets al lloc web correcte?" + _brainDiver: + title: "Busseja Ments" + description: "Publica un enllaç al Busseja Ments" + flavor: "Misskey-Misskey La-Tu-Ma" + _smashTestNotificationButton: + title: "Sobrecà rrega de proves" + description: "Envia moltes notificacions de prova en un perÃode de temps molt curt" + _tutorialCompleted: + title: "Diploma del Curs Elemental de Misskey" + description: "Has completat el tutorial" + _bubbleGameExplodingHead: + title: "🤯" + description: "L'objecte més gran del joc de la bombolla " + _bubbleGameDoubleExplodingHead: + title: "Doble 🤯" + description: "Dos dels objectes més grans del joc de la bombolla al mateix temps" + flavor: "Pots emplenar una carmanyola com aquesta 🤯🤯 una mica" _role: + new: "Nou rol" + edit: "Editar el rol" + name: "Nom del rol" + description: "Descripció del rol" permission: "Permisos de rol" descriptionOfPermission: "Els <b>Moderadors</b> poden fer operacions bà siques de moderació.\nEls <b>Administradors</b> poden canviar tots els ajustos del servidor." assignTarget: "Assignar " @@ -1545,35 +1618,259 @@ _role: asBadge: "Mostrar com a insÃgnia " descriptionOfAsBadge: "La icona d'aquest rol es mostrarà al costat dels noms d'usuaris que tinguin assignats aquest rol." isExplorable: "Fer el rol explorable" + descriptionOfIsExplorable: "La lÃnia de temps d'aquest rol i la llista d'usuaris seran públics si s'activa." + displayOrder: "Posició " + descriptionOfDisplayOrder: "Com més gran és el número, més dalt la seva posició a la interfÃcie." + canEditMembersByModerator: "Permetre que els moderadors editin la llista d'usuaris en aquest rol" + descriptionOfCanEditMembersByModerator: "Quan s'activa, els moderadors, aixà com els administradors, podran afegir i treure usuaris d'aquest rol. Si es troba desactivat, només els administradors poden assignar usuaris." priority: "Prioritat" _priority: low: "Baixa" middle: "Mitjà " high: "Alta" _options: + gtlAvailable: "Pot veure la lÃnia de temps global" + ltlAvailable: "Pot veure la lÃnia de temps local" + canPublicNote: "Pot enviar notes públiques" + canInvite: "Pot crear invitacions a la instà ncia " + inviteLimit: "LÃmit d'invitacions " + inviteLimitCycle: "Temps de refresc de les invitacions" + inviteExpirationTime: "Interval de caducitat de les invitacions" canManageCustomEmojis: "Gestiona els emojis personalitzats" canManageAvatarDecorations: "Gestiona les decoracions dels avatars " + driveCapacity: "Capacitat del disc" + alwaysMarkNsfw: "Marca sempre els fitxers com a sensibles" + pinMax: "Nombre mà xim de notes fixades" antennaMax: "Nombre mà xim d'antenes" + wordMuteMax: "Nombre mà xim de carà cters permesos a les paraules silenciades" + webhookMax: "Nombre mà xim de Webhooks" + clipMax: "Nombre mà xim de clips" + noteEachClipsMax: "Nombre mà xim de notes dintre d'un clip" + userListMax: "Nombre mà xim de llistes d'usuaris " + userEachUserListsMax: "Nombre mà xim d'usuaris dintre d'una llista d'usuaris " + rateLimitFactor: "Limitador" + descriptionOfRateLimitFactor: "LÃmits baixos són menys restrictius, lÃmits alts són més restrictius." + canHideAds: "Pot amagar els anuncis" + canSearchNotes: "Pot cercar notes" + canUseTranslator: "Pot fer servir el traductor" + avatarDecorationLimit: "Nombre mà xim de decoracions que es poden aplicar els avatars" + _condition: + isLocal: "Usuari local" + isRemote: "Usuari remot" + createdLessThan: "Han passat menys de X a passat des de la creació del compte" + createdMoreThan: "Han passat més de X des de la creació del compte" + followersLessThanOrEq: "Té menys de X seguidors" + followersMoreThanOrEq: "Té X o més seguidors" + followingLessThanOrEq: "Segueix X o menys comptes" + followingMoreThanOrEq: "Segueix a X o més comptes" + notesLessThanOrEq: "Les publicacions són menys o igual a " + notesMoreThanOrEq: "Les publicacions són més o igual a " + and: "AND condicional " + or: "OR condicional" + not: "NOT condicional" +_sensitiveMediaDetection: + description: "Redueix els esforços de moderació grà cies al reconeixement automà tic dels fitxers amb contingut sensible mitjançant Machine Learing. Això augmentarà la cà rrega del servidor." + sensitivity: "Sensibilitat de la detecció " + sensitivityDescription: "Reduint la sensibilitat provocarà menys falsos positius. D'altra banda incrementant-ho generarà més falsos negatius." + setSensitiveFlagAutomatically: "Marcar com a sensible" + setSensitiveFlagAutomaticallyDescription: "Els resultats de la detecció interna seran desats, inclòs si aquesta opció es troba desactivada." + analyzeVideos: "Activar anà lisis de vÃdeos " + analyzeVideosDescription: "Analitzar els vÃdeos a més de les imatges. Això incrementarà lleugerament la cà rrega del servidor." +_emailUnavailable: + used: "Aquest correu electrònic ja s'està fent servir" + format: "El format del correu electrònic és invà lid " + disposable: "No es poden fer servir adreces de correu electrònic d'un sol ús " + mx: "Aquest servidor de correu electrònic no és và lid " + smtp: "Aquest servidor de correu electrònic no respon" + banned: "No pots registrar-te amb aquesta adreça de correu electrònic " _ffVisibility: public: "Publicar" + followers: "Visible només per a seguidors " + private: "Privat" +_signup: + almostThere: "Ja quasi estem" + emailAddressInfo: "Si us plau, escriu la teva adreça de correu electrònic. No es farà pública." + emailSent: "S'ha enviat un correu de confirmació a ({email}). Si us plau, fes clic a l'enllaç per completar el registre." +_accountDelete: + accountDelete: "Eliminar el compte" + mayTakeTime: "Com l'eliminació d'un compte consumeix bastants recursos, pot trigar un temps perquè es completi l'esborrat, depenent si tens molt contingut i la quantitat de fitxer que hagis pujat." + sendEmail: "Una vegada hagi finalitzat l'esborrat del compte rebrà s un correu electrònic a l'adreça que tinguis registrada en aquest compte." + requestAccountDelete: "Demanar l'eliminació del compte" + started: "Ha començat l'esborrat del compte." + inProgress: "L'esborrat es troba en procés " _ad: back: "Tornar" + reduceFrequencyOfThisAd: "Mostrar menys aquest anunci" + hide: "No mostrar mai" + timezoneinfo: "El dia de la setmana ve determinat del fus horari del servidor." + adsSettings: "Configuració d'anuncis " + notesPerOneAd: "Interval d'emplaçament d'anuncis en temps real (Notes per anuncis)" + setZeroToDisable: "Ajusta aquest valor a 0 per deshabilitar l'actualització d'anuncis en temps real" + adsTooClose: "L'interval actual pot fer que l'experiència de l'usuari sigui dolenta perquè l'interval és molt baix." +_forgotPassword: + enterEmail: "Escriu l'adreça de correu electrònic amb la que et vas registrar. S'enviarà un correu electrònic amb un enllaç perquè puguis canviar-la." + ifNoEmail: "Si no vas fer servir una adreça de correu electrònic per registrar-te, si us plau posa't en contacte amb l'administrador." + contactAdmin: "Aquesta instà ncia no suporta registrar-se amb correu electrònic. Si us plau, contacta amb l'administrador del servidor." +_gallery: + my: "La meva Galeria " + liked: "Publicacions que t'han agradat" + like: "M'agrada " + unlike: "Ja no m'agrada" _email: _follow: title: "t'ha seguit" + _receiveFollowRequest: + title: "Has rebut una sol·licitud de seguiment" +_plugin: + install: "Instal·lar un afegit " + installWarn: "Si us plau, no instal·lis afegits que no siguin de confiança." + manage: "Gestionar els afegits" + viewSource: "Veure l'origen " +_preferencesBackups: + list: "Llista de còpies de seguretat" + saveNew: "Fer una còpia de seguretat nova" + loadFile: "Carregar des d'un fitxer" + apply: "Aplicar en aquest dispositiu" + save: "Desar els canvis" + inputName: "Escriu un nom per aquesta còpia de seguretat" + cannotSave: "No s'ha pogut desar" + nameAlreadyExists: "Ja existeix una còpia de seguretat anomenada \"{name}\". Escriu un nom diferent." + applyConfirm: "Vols aplicar la còpia de seguretat \"{name}\" a aquest dispositiu? La configuració actual del dispositiu serà esborrada." + saveConfirm: "Desar còpia de seguretat com {name}?" + deleteConfirm: "Esborrar la còpia de seguretat {name}?" + renameConfirm: "Vols canvia el nom de la còpia de seguretat de \"{old}\" a \"{new}\"?" + noBackups: "No hi ha còpies de seguretat. Pots fer una còpia de seguretat de la configuració d'aquest dispositiu al servidor fent servir \"Crear nova còpia de seguretat\"" + createdAt: "Creat el: {date} {time}" + updatedAt: "Actualitzat el: {date} {time}" + cannotLoad: "Hi ha hagut un error al carregar" + invalidFile: "Format del fitxer no và lid " +_registry: + scope: "Àmbit " + key: "Clau" + keys: "Claus" + domain: "Domini" + createKey: "Crear una clau" +_aboutMisskey: + about: "Misskey és un programa de codi obert desenvolupar per syuilo des de 2014" + contributors: "Col·laboradors principals" + allContributors: "Tots els col·laboradors " + source: "Codi font" + translation: "Tradueix Misskey" + donate: "Fes un donatiu a Misskey" + morePatrons: "També agraïm el suport d'altres col·laboradors que no surten en aquesta llista. Grà cies! 🥰" + patrons: "Patrocinadors" + projectMembers: "Membres del projecte" +_displayOfSensitiveMedia: + respect: "Ocultar imatges o vÃdeos marcats com a sensibles" + ignore: "Mostrar imatges o vÃdeos marcats com a sensibles" + force: "Ocultar totes les imatges o vÃdeos " +_instanceTicker: + none: "No mostrar mai" + remote: "Mostrar per usuaris remots" + always: "Mostrar sempre" +_serverDisconnectedBehavior: + reload: "Recarregar automà ticament " + dialog: "Mostrar finestres de confirmació " + quiet: "Mostrar un avÃs que no molesti" +_channel: + create: "Crear un canal" + edit: "Editar canal" + setBanner: "Estableix el bà ner " + removeBanner: "Eliminar el.bà ner" + featured: "Popular" + owned: "Propietat" + following: "Seguin" + usersCount: "{n} Participants" + notesCount: "{n} Notes" + nameAndDescription: "Nom i descripció " + nameOnly: "Nom només " + allowRenoteToExternal: "Permet la citació i l'impuls fora del canal" _instanceMute: instanceMuteDescription: "Silencia tots els impulsos dels servidors seleccionats, també els usuaris que responen a altres d'un servidor silenciat." _theme: description: "Descripció" keys: + navHoverFg: "Text barra lateral (en passar per sobre)" + navActive: "Text barra lateral (actiu)" + navIndicator: "Indicador barra lateral" + link: "Enllaç" + hashtag: "Etiqueta" mention: "Menció" + mentionMe: "Mencions (jo)" renote: "Renotar" + modalBg: "Fons del modal" divider: "Divisor" + scrollbarHandle: "Maneta de la barra de desplaçament" + scrollbarHandleHover: "Maneta de la barra de desplaçament (en passar-hi per sobre)" + dateLabelFg: "Text de l'etiqueta de la data" + infoBg: "Fons d'informació " + infoFg: "Text d'informació " + infoWarnBg: "Fons avÃs " + infoWarnFg: "Text avÃs " + toastBg: "Fons notificació " + toastFg: "Text notificació " + buttonBg: "Fons botó " + buttonHoverBg: "Fons botó (en passar-hi per sobre)" + inputBorder: "Contorn del cap d'introducció " + listItemHoverBg: "Fons dels elements d'una llista" + driveFolderBg: "Fons de la carpeta Disc" + wallpaperOverlay: "Superposició del fons de pantalla " + badge: "InsÃgnia " + messageBg: "Fons del xat" + accentDarken: "Accent (fosc)" + accentLighten: "Accent (clar)" + fgHighlighted: "Text ressaltat" _sfx: note: "Notes" + noteMy: "Nota (per mi)" notification: "Notificacions" antenna: "Antenes" + channel: "Notificacions dels canals" + reaction: "Quan se selecciona una reacció " +_soundSettings: + driveFile: "Fer servir un fitxer d'à udio del disc" + driveFileWarn: "Seleccionar un fitxer d'à udio del disc" + driveFileTypeWarn: "Fitxer no suportat " + driveFileTypeWarnDescription: "Seleccionar un fitxer d'à udio " + driveFileDurationWarn: "L'à udio és massa llarg" + driveFileDurationWarnDescription: "Els à udios molt llargs pot interrompre l'ús de Misskey. Vols continuar?" +_ago: + future: "Futur " + justNow: "Ara mateix" + secondsAgo: "Fa {n} segons" + minutesAgo: "Fa {n} minuts" + hoursAgo: "Fa {n} hores" + daysAgo: "Fa {n} dies" + weeksAgo: "Fa {n} setmanes" + monthsAgo: "Fa {n} mesos" + yearsAgo: "Fa {n} anys" + invalid: "Res" +_timeIn: + seconds: "En {n} segons" + minutes: "En {n} minuts" + hours: "En {n} hores" + days: "En {n} dies" + weeks: "En {n} setmanes" + months: "En {n} mesos" + years: "En {n} anys" +_time: + second: "Segon(s)" + minute: "Minut(s)" + hour: "Hor(a)(es)" + day: "Di(a)(es)" _2fa: + alreadyRegistered: "J has registrat un dispositiu d'autenticació de doble factor." + registerTOTP: "Registrar una aplicació autenticadora" + step1: "Primer instal·la una aplicació autenticadora (com {a} o {b}) al teu dispositiu." + step2: "Després escaneja el codi QR que es mostra en aquesta pantalla." + step2Click: "Fent clic en aquest codi QR et permetrà registrar l'autenticació de doble factor a la teva clau de seguretat o en l'aplicació d'autenticació del teu dispositiu." + step2Uri: "Escriu la següent URI si està s fent servir una aplicació d'escriptori " + step3Title: "Escriu un codi d'autenticació" + step3: "Escriu el codi d'autenticació (token) que es mostra a la teva aplicació per finalitzar la configuració." + setupCompleted: "Configuració terminada" + step4: "D'ara endavant quan accedeixis se't demanarà el token que has introduït." + securityKeyNotSupported: "El teu navegador no suporta claus de seguretat" + removeKeyConfirm: "Esborrar la còpia de seguretat {name}?" renewTOTPCancel: "No, grà cies" _antennaSources: all: "Totes les publicacions" @@ -1592,6 +1889,8 @@ _widgets: chooseList: "Tria una llista" _cw: show: "Carregar més" +_poll: + deadlineTime: "Hor(a)(es)" _visibility: home: "Inici" followers: "Seguidors" diff --git a/locales/cs-CZ.yml b/locales/cs-CZ.yml index 8620a1207c..7da9461af1 100644 --- a/locales/cs-CZ.yml +++ b/locales/cs-CZ.yml @@ -1005,6 +1005,7 @@ resetPasswordConfirm: "Opravdu chcete resetovat heslo?" sensitiveWords: "Citlivá slova" sensitiveWordsDescription: "Viditelnost vÅ¡ech poznámek obsahujÃcÃch nÄ›které z nakonfigurovaných slov bude automaticky nastavena na \"Domů\". Můžete jich uvést vÃce tak, že je oddÄ›lÃte pomocà řádků." sensitiveWordsDescription2: "Použità mezer vytvořà výrazy AND a obklopenà klÃÄových slov lomÃtky je zmÄ›nà na regulárnà výraz." +prohibitedWordsDescription2: "Použità mezer vytvořà výrazy AND a obklopenà klÃÄových slov lomÃtky je zmÄ›nà na regulárnà výraz." notesSearchNotAvailable: "Vyhledávánà poznámek je nedostupné." license: "Licence" unfavoriteConfirm: "Opravdu chcete odstranit z oblÃbených?" diff --git a/locales/de-DE.yml b/locales/de-DE.yml index a8f8903cf1..a4412395f6 100644 --- a/locales/de-DE.yml +++ b/locales/de-DE.yml @@ -1036,6 +1036,7 @@ resetPasswordConfirm: "Wirklich Passwort zurücksetzen?" sensitiveWords: "Sensible Wörter" sensitiveWordsDescription: "Die Notizsichtbarkeit aller Notizen, die diese Wörter enthalten, wird automatisch auf \"Startseite\" gesetzt. Durch Zeilenumbrüche können mehrere konfiguriert werden." sensitiveWordsDescription2: "Durch die Verwendung von Leerzeichen können AND-Verknüpfungen angegeben werden und durch das Umgeben von Schrägstrichen können reguläre Ausdrücke verwendet werden." +prohibitedWordsDescription2: "Durch die Verwendung von Leerzeichen können AND-Verknüpfungen angegeben werden und durch das Umgeben von Schrägstrichen können reguläre Ausdrücke verwendet werden." hiddenTags: "Ausgeblendete Hashtags" hiddenTagsDescription: "Die hier eingestellten Tags werden nicht mehr in den Trends angezeigt. Mit der Umschalttaste können mehrere ausgewählt werden." notesSearchNotAvailable: "Die Notizsuche ist nicht verfügbar." diff --git a/locales/en-US.yml b/locales/en-US.yml index 3a017b8044..f82ce21906 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -1041,6 +1041,7 @@ resetPasswordConfirm: "Really reset your password?" sensitiveWords: "Sensitive words" sensitiveWordsDescription: "The visibility of all notes containing any of the configured words will be set to \"Home\" automatically. You can list multiple by separating them via line breaks." sensitiveWordsDescription2: "Using spaces will create AND expressions and surrounding keywords with slashes will turn them into a regular expression." +prohibitedWordsDescription2: "Using spaces will create AND expressions and surrounding keywords with slashes will turn them into a regular expression." hiddenTags: "Hidden hashtags" hiddenTagsDescription: "Select tags which will not shown on trend list.\nMultiple tags could be registered by lines." notesSearchNotAvailable: "Note search is unavailable." @@ -1971,6 +1972,31 @@ _permissions: "write:flash": "Edit Plays" "read:flash-likes": "View list of liked Plays" "write:flash-likes": "Edit list of liked Plays" + "read:admin:abuse-user-reports": "View user reports" + "write:admin:delete-account": "Delete user account" + "write:admin:delete-all-files-of-a-user": "Delete all files of a user" + "read:admin:meta": "View instance metadata" + "write:admin:reset-password": "Reset user password" + "write:admin:send-email": "Send email" + "read:admin:server-info": "View server info" + "read:admin:show-moderation-log": "View moderation log" + "read:admin:show-user": "View private user info" + "read:admin:show-users": "View private user info" + "write:admin:suspend-user": "Suspend user" + "write:admin:unset-user-avatar": "Remove user avatar" + "write:admin:unset-user-banner": "Remove user banner" + "write:admin:unsuspend-user": "Unsuspend user" + "write:admin:meta": "Manage instance metadata" + "write:admin:user-note": "Manage moderation note" + "write:admin:roles": "Manage roles" + "read:admin:roles": "View roles" + "write:admin:relays": "Manage relays" + "read:admin:relays": "View relays" + "write:admin:invite-codes": "Manage invite codes" + "read:admin:invite-codes": "View invite codes" + "write:admin:announcements": "Manage announcements" + "read:admin:announcements": "View announcements" + "write:admin:avatar-decorations": "Manage avatar decorations" _auth: shareAccessTitle: "Granting application permissions" shareAccess: "Would you like to authorize \"{name}\" to access this account?" diff --git a/locales/es-ES.yml b/locales/es-ES.yml index d4c0d6c4ad..38cb0f6b21 100644 --- a/locales/es-ES.yml +++ b/locales/es-ES.yml @@ -1041,6 +1041,7 @@ resetPasswordConfirm: "¿Realmente quieres cambiar la contraseña?" sensitiveWords: "Palabras sensibles" sensitiveWordsDescription: "La visibilidad de todas las notas que contienen cualquiera de las palabras configuradas serán puestas en \"Inicio\" automáticamente. Puedes enumerás varias separándolas con saltos de lÃnea" sensitiveWordsDescription2: "Si se usan espacios se crearán expresiones AND y las palabras subsecuentes con barras inclinadas se convertirán en expresiones regulares." +prohibitedWordsDescription2: "Si se usan espacios se crearán expresiones AND y las palabras subsecuentes con barras inclinadas se convertirán en expresiones regulares." hiddenTags: "Hashtags ocultos" hiddenTagsDescription: "Selecciona las etiquetas que no se mostrarán en tendencias. Una etiqueta por lÃnea." notesSearchNotAvailable: "No se puede buscar una nota" diff --git a/locales/id-ID.yml b/locales/id-ID.yml index 44a0503883..b38e95596b 100644 --- a/locales/id-ID.yml +++ b/locales/id-ID.yml @@ -1038,6 +1038,7 @@ resetPasswordConfirm: "Yakin untuk mereset kata sandimu?" sensitiveWords: "Kata sensitif" sensitiveWordsDescription: "Visibilitas dari semua catatan mengandung kata yang telah diatur akan dijadikan \"Beranda\" secara otomatis. Kamu dapat mendaftarkan kata tersebut lebih dari satu dengan menuliskannya di baris baru." sensitiveWordsDescription2: "Menggunakan spasi akan membuat ekspresi AND dan kata kunci disekitarnya dengan garis miring akan mengubahnya menjadi ekspresi reguler." +prohibitedWordsDescription2: "Menggunakan spasi akan membuat ekspresi AND dan kata kunci disekitarnya dengan garis miring akan mengubahnya menjadi ekspresi reguler." hiddenTags: "Tagar tersembunyi" hiddenTagsDescription: "Pilih tanda yang mana akan tidak diperlihatkan dalam daftar tren.\nTanda lebih dari satu dapat didaftarkan dengan tiap baris." notesSearchNotAvailable: "Pencarian catatan tidak tersedia." diff --git a/locales/it-IT.yml b/locales/it-IT.yml index fdddf24360..5a7fc11a03 100644 --- a/locales/it-IT.yml +++ b/locales/it-IT.yml @@ -1041,6 +1041,7 @@ resetPasswordConfirm: "Vuoi davvero ripristinare la password?" sensitiveWords: "Parole esplicite" sensitiveWordsDescription: "Imposta automaticamente \"Home\" alla visibilità delle Note che contengono una qualsiasi parola tra queste configurate. Puoi separarle per riga." sensitiveWordsDescription2: "Gli spazi creano la relazione \"E\" tra parole (questo E quello). Racchiudere una parola nelle slash \"/\" la trasforma in Espressione Regolare." +prohibitedWordsDescription2: "Gli spazi creano la relazione \"E\" tra parole (questo E quello). Racchiudere una parola nelle slash \"/\" la trasforma in Espressione Regolare." hiddenTags: "Hashtag nascosti" hiddenTagsDescription: "Impedire la visualizzazione del tag impostato nei trend. Puoi impostare più valori, uno per riga." notesSearchNotAvailable: "Non è possibile cercare tra le Note." diff --git a/locales/ja-KS.yml b/locales/ja-KS.yml index 4a3a79743d..c676bf4fdb 100644 --- a/locales/ja-KS.yml +++ b/locales/ja-KS.yml @@ -1041,6 +1041,7 @@ resetPasswordConfirm: "パスワード作り直ã™ã‚“ã§ãˆãˆãªï¼Ÿ" sensitiveWords: "ã‘ã£ãŸã„ãªå˜èªž" sensitiveWordsDescription: "è¨å®šã—ãŸå˜èªžãŒå…¥ã£ã¨ã‚‹ãƒŽãƒ¼ãƒˆã®å…¬é–‹ç¯„囲をホームã«ã—ãŸã‚‹ã‚。改行ã§åŒºåˆ‡ã£ãŸã‚‰è¤‡æ•°è¨å®šã§ãã‚‹ã§ã€‚" sensitiveWordsDescription2: "スペースã§åŒºåˆ‡ã‚‹ã¨AND指定ã€ã‚ーワードをスラッシュã§å›²ã‚“ã らæ£è¦è¡¨ç¾ã‚„。" +prohibitedWordsDescription2: "スペースã§åŒºåˆ‡ã‚‹ã¨AND指定ã€ã‚ーワードをスラッシュã§å›²ã‚“ã らæ£è¦è¡¨ç¾ã‚„。" hiddenTags: "見ãˆã¦ã¸ã‚“ãƒãƒƒã‚·ãƒ¥ã‚¿ã‚°" hiddenTagsDescription: "è¨å®šã—ãŸã‚¿ã‚°ã‚’最近æµè¡Œã‚Šã®ã¨ã“ã«è¦‹ãˆã‚“よã†ã«ã™ã‚“ã§ã€‚複数è¨å®šã™ã‚‹ã¨ãã¯æ”¹è¡Œã§åŒºåˆ‡ã£ã¦ãªã€‚" notesSearchNotAvailable: "ãªã‚“ã‹ãƒŽãƒ¼ãƒˆæŽ¢ã›ã¸ã‚“。" diff --git a/locales/ko-KR.yml b/locales/ko-KR.yml index 2a59ab9a23..1231209b36 100644 --- a/locales/ko-KR.yml +++ b/locales/ko-KR.yml @@ -1041,6 +1041,7 @@ resetPasswordConfirm: "비밀번호를 ìž¬ì„¤ì •í•˜ì‹œê² ìŠµë‹ˆê¹Œ?" sensitiveWords: "민ê°í•œ 단어" sensitiveWordsDescription: "ì„¤ì •í•œ 단어가 í¬í•¨ëœ ë…¸íŠ¸ì˜ ê³µê°œ 범위를 '홈'으로 ê°•ì œí•©ë‹ˆë‹¤. 개행으로 구분하여 여러 개를 ì§€ì •í• ìˆ˜ 있습니다." sensitiveWordsDescription2: "공백으로 구분하면 AND ì§€ì •ì´ ë˜ë©°, 키워드를 슬래시로 둘러싸면 ì •ê·œ 표현ì‹ì´ ë©ë‹ˆë‹¤." +prohibitedWordsDescription2: "공백으로 구분하면 AND ì§€ì •ì´ ë˜ë©°, 키워드를 슬래시로 둘러싸면 ì •ê·œ 표현ì‹ì´ ë©ë‹ˆë‹¤." hiddenTags: "숨긴 해시태그" hiddenTagsDescription: "ì„¤ì •í•œ 태그를 íŠ¸ë Œë“œì— í‘œì‹œí•˜ì§€ ì•Šë„ë¡ í•©ë‹ˆë‹¤. 줄 바꿈으로 하나씩 ë‚˜ëˆ ì„œ ì„¤ì •í• ìˆ˜ 있습니다." notesSearchNotAvailable: "노트 ê²€ìƒ‰ì„ ì´ìš©í•˜ì‹¤ 수 없습니다." diff --git a/locales/ru-RU.yml b/locales/ru-RU.yml index 60682fe961..d014b7fc25 100644 --- a/locales/ru-RU.yml +++ b/locales/ru-RU.yml @@ -1015,6 +1015,7 @@ resetPasswordConfirm: "СброÑить пароль?" sensitiveWords: "ЧувÑтвительные Ñлова" sensitiveWordsDescription: "УÑтановите общедоÑтупный диапазон заметки, Ñодержащей заданное Ñлово, на домашний. Можно Ñделать неÑколько наÑтроек, разделив их переноÑами Ñтрок." sensitiveWordsDescription2: "Разделение пробелом Ñоздаёт Ñпецификацию AND, а разделение коÑой чертой Ñоздаёт регулÑрное выражение." +prohibitedWordsDescription2: "Разделение пробелом Ñоздаёт Ñпецификацию AND, а разделение коÑой чертой Ñоздаёт регулÑрное выражение." notesSearchNotAvailable: "ПоиÑк заметок недоÑтупен" license: "ЛицензиÑ" unfavoriteConfirm: "Удалить избранное?" diff --git a/locales/th-TH.yml b/locales/th-TH.yml index ed776e5ec7..90a3e93d64 100644 --- a/locales/th-TH.yml +++ b/locales/th-TH.yml @@ -1041,6 +1041,7 @@ resetPasswordConfirm: "รีเซ็ตรหัสผ่านขà¸à¸‡à¸„ุ sensitiveWords: "คำที่มีเนื้à¸à¸«à¸²à¸¥à¸°à¹€à¸à¸µà¸¢à¸”à¸à¹ˆà¸à¸™" sensitiveWordsDescription: "à¸à¸²à¸£à¹€à¸›à¸´à¸”เผยโน้ตทั้งหมดที่มีคำที่à¸à¸³à¸«à¸™à¸”ค่าไว้จะถูà¸à¸•à¸±à¹‰à¸‡à¸„่าเป็น \"หน้าà¹à¸£à¸\" โดยà¸à¸±à¸•à¹‚นมัติ คุณยังสามารถà¹à¸ªà¸”งหลายรายà¸à¸²à¸£à¹„ด้โดยà¹à¸¢à¸à¸£à¸²à¸¢à¸à¸²à¸£à¹‚ดยใช้ตัวà¹à¸šà¹ˆà¸‡à¸šà¸£à¸£à¸—ัดได้นะ" sensitiveWordsDescription2: "à¸à¸²à¸£à¹ƒà¸Šà¹‰à¸Šà¹ˆà¸à¸‡à¸§à¹ˆà¸²à¸‡à¸™à¸±à¹‰à¸™à¸à¸²à¸ˆà¸ˆà¸°à¸ªà¸£à¹‰à¸²à¸‡à¸™à¸´à¸žà¸ˆà¸™à¹Œ AND à¹à¸¥à¸°à¸„ำหลัà¸à¸—ี่มีเครื่à¸à¸‡à¸«à¸¡à¸²à¸¢à¸—ับล้à¸à¸¡à¸£à¸à¸šà¸ˆà¸°à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹€à¸›à¹‡à¸™à¸™à¸´à¸žà¸ˆà¸™à¹Œà¸—ั่วไปนะ" +prohibitedWordsDescription2: "à¸à¸²à¸£à¹ƒà¸Šà¹‰à¸Šà¹ˆà¸à¸‡à¸§à¹ˆà¸²à¸‡à¸™à¸±à¹‰à¸™à¸à¸²à¸ˆà¸ˆà¸°à¸ªà¸£à¹‰à¸²à¸‡à¸™à¸´à¸žà¸ˆà¸™à¹Œ AND à¹à¸¥à¸°à¸„ำหลัà¸à¸—ี่มีเครื่à¸à¸‡à¸«à¸¡à¸²à¸¢à¸—ับล้à¸à¸¡à¸£à¸à¸šà¸ˆà¸°à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹€à¸›à¹‡à¸™à¸™à¸´à¸žà¸ˆà¸™à¹Œà¸—ั่วไปนะ" hiddenTags: "à¹à¸®à¸Šà¹à¸—็à¸à¸—ี่ซ่à¸à¸™à¸à¸¢à¸¹à¹ˆ" hiddenTagsDescription: "เลืà¸à¸à¹à¸—็à¸à¸—ี่จะไม่à¹à¸ªà¸”งในรายà¸à¸²à¸£à¹€à¸—รนด์ สามารถลงทะเบียนหลายà¹à¸—็à¸à¹„ด้โดยขึ้นบรรทัดใหม่" notesSearchNotAvailable: "à¸à¸²à¸£à¸„้นหาโน้ตไม่พร้à¸à¸¡à¹ƒà¸Šà¹‰à¸‡à¸²à¸™" diff --git a/locales/zh-CN.yml b/locales/zh-CN.yml index 09c210011c..4a36e30db8 100644 --- a/locales/zh-CN.yml +++ b/locales/zh-CN.yml @@ -1041,6 +1041,7 @@ resetPasswordConfirm: "确定é‡ç½®å¯†ç ?" sensitiveWords: "æ•æ„Ÿè¯" sensitiveWordsDescription: "将包å«è®¾ç½®è¯çš„帖åçš„å¯è§èŒƒå›´è®¾ç½®ä¸ºé¦–页。å¯ä»¥é€šè¿‡ç”¨æ¢è¡Œç¬¦åˆ†éš”æ¥è®¾ç½®å¤šä¸ªã€‚" sensitiveWordsDescription2: "AND æ¡ä»¶ç”¨ç©ºæ ¼åˆ†éš”,æ£åˆ™è¡¨è¾¾å¼ç”¨æ–œçº¿åŒ…裹。" +prohibitedWordsDescription2: "AND æ¡ä»¶ç”¨ç©ºæ ¼åˆ†éš”,æ£åˆ™è¡¨è¾¾å¼ç”¨æ–œçº¿åŒ…裹。" hiddenTags: "éšè—æ ‡ç¾" hiddenTagsDescription: "è®¾å®šçš„æ ‡ç¾å°†ä¸ä¼šåœ¨æ—¶é—´çº¿ä¸Šæ˜¾ç¤ºã€‚å¯ä½¿ç”¨æ¢è¡Œæ¥è®¾ç½®å¤šä¸ªæ ‡ç¾ã€‚" notesSearchNotAvailable: "帖å检索ä¸å¯ç”¨" diff --git a/locales/zh-TW.yml b/locales/zh-TW.yml index 872a90bc6a..ed2bd1cf3a 100644 --- a/locales/zh-TW.yml +++ b/locales/zh-TW.yml @@ -1041,6 +1041,7 @@ resetPasswordConfirm: "é‡è¨å¯†ç¢¼ï¼Ÿ" sensitiveWords: "æ•æ„Ÿè©ž" sensitiveWordsDescription: "å°‡å«æœ‰è¨å®šè©žå½™çš„貼文å¯è¦‹æ€§è¨ç‚ºç™¼é€è‡³é¦–é 。å¯ä»¥ç”¨æ›è¡Œä¾†é€²è¡Œè¤‡æ•¸çš„è¨å®šã€‚" sensitiveWordsDescription2: "ç©ºæ ¼ä»£è¡¨ã€Œä»¥åŠã€ï¼ˆAND),斜線包åœé—œéµå—代表使用æ£è¦è¡¨é”å¼ã€‚" +prohibitedWordsDescription2: "ç©ºæ ¼ä»£è¡¨ã€Œä»¥åŠã€ï¼ˆAND),斜線包åœé—œéµå—代表使用æ£è¦è¡¨é”å¼ã€‚" hiddenTags: "éš±è—標籤" hiddenTagsDescription: "è¨å®šçš„標籤ä¸æœƒåœ¨è¶¨å‹¢ä¸é¡¯ç¤ºï¼Œæ›è¡Œå¯ä»¥è¨å®šå¤šå€‹æ¨™ç±¤ã€‚" notesSearchNotAvailable: "無法使用æœå°‹è²¼æ–‡åŠŸèƒ½ã€‚" -- GitLab From 7fc1d77893631f7bc792c7d6d5398aba65a331c9 Mon Sep 17 00:00:00 2001 From: syuilo <Syuilotan@yahoo.co.jp> Date: Fri, 9 Feb 2024 17:10:16 +0900 Subject: [PATCH 36/40] update deps --- packages/backend/package.json | 10 +- packages/frontend/package.json | 14 +- packages/misskey-js/package.json | 2 +- pnpm-lock.yaml | 464 ++++++++++++++++++------------- 4 files changed, 289 insertions(+), 201 deletions(-) diff --git a/packages/backend/package.json b/packages/backend/package.json index 31ca56be49..ee1bf676cb 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -85,7 +85,7 @@ "@nestjs/core": "10.2.10", "@nestjs/testing": "10.2.10", "@peertube/http-signature": "1.7.0", - "@simplewebauthn/server": "9.0.1", + "@simplewebauthn/server": "9.0.2", "@sinonjs/fake-timers": "11.2.2", "@smithy/node-http-handler": "2.1.10", "@swc/cli": "0.1.63", @@ -98,12 +98,12 @@ "bcryptjs": "2.4.3", "blurhash": "2.0.5", "body-parser": "1.20.2", - "bullmq": "5.1.5", + "bullmq": "5.1.9", "cacheable-lookup": "7.0.0", - "cbor": "9.0.1", + "cbor": "9.0.2", "chalk": "5.3.0", "chalk-template": "1.1.0", - "chokidar": "3.5.3", + "chokidar": "3.6.0", "cli-highlight": "2.1.11", "color-convert": "2.0.1", "content-disposition": "0.5.4", @@ -203,7 +203,7 @@ "@types/jsrsasign": "10.5.12", "@types/mime-types": "2.1.4", "@types/ms": "0.7.34", - "@types/node": "20.11.10", + "@types/node": "20.11.17", "@types/node-fetch": "3.0.3", "@types/nodemailer": "6.4.14", "@types/oauth": "0.9.4", diff --git a/packages/frontend/package.json b/packages/frontend/package.json index 5aaddde5ca..5a3a228f12 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -28,7 +28,7 @@ "@tabler/icons-webfont": "2.44.0", "@twemoji/parser": "15.0.0", "@vitejs/plugin-vue": "5.0.3", - "@vue/compiler-sfc": "3.4.15", + "@vue/compiler-sfc": "3.4.18", "aiscript-vscode": "github:aiscript-dev/aiscript-vscode#v0.1.2", "astring": "1.8.6", "broadcast-channel": "7.0.0", @@ -72,7 +72,7 @@ "uuid": "9.0.1", "v-code-diff": "1.7.2", "vite": "5.1.0", - "vue": "3.4.15", + "vue": "3.4.18", "vuedraggable": "next" }, "devDependencies": { @@ -96,12 +96,12 @@ "@storybook/types": "7.6.10", "@storybook/vue3": "7.6.10", "@storybook/vue3-vite": "7.6.10", - "@testing-library/vue": "8.0.1", + "@testing-library/vue": "8.0.2", "@types/escape-regexp": "0.0.3", "@types/estree": "1.0.5", "@types/matter-js": "0.19.6", "@types/micromatch": "4.0.6", - "@types/node": "20.11.10", + "@types/node": "20.11.17", "@types/punycode": "2.1.3", "@types/sanitize-html": "2.9.5", "@types/throttle-debounce": "5.0.2", @@ -111,10 +111,10 @@ "@typescript-eslint/eslint-plugin": "6.18.1", "@typescript-eslint/parser": "6.18.1", "@vitest/coverage-v8": "0.34.6", - "@vue/runtime-core": "3.4.15", + "@vue/runtime-core": "3.4.18", "acorn": "8.11.3", "cross-env": "7.0.3", - "cypress": "13.6.3", + "cypress": "13.6.4", "eslint": "8.56.0", "eslint-plugin-import": "2.29.1", "eslint-plugin-vue": "9.20.1", @@ -125,7 +125,7 @@ "msw": "2.1.7", "msw-storybook-addon": "2.0.0-beta.1", "nodemon": "3.0.3", - "prettier": "3.2.4", + "prettier": "3.2.5", "react": "18.2.0", "react-dom": "18.2.0", "start-server-and-test": "2.0.3", diff --git a/packages/misskey-js/package.json b/packages/misskey-js/package.json index 0c4dd52d14..bc3001fc05 100644 --- a/packages/misskey-js/package.json +++ b/packages/misskey-js/package.json @@ -39,7 +39,7 @@ "@misskey-dev/eslint-plugin": "1.0.0", "@swc/jest": "0.2.31", "@types/jest": "29.5.11", - "@types/node": "20.11.10", + "@types/node": "20.11.17", "@typescript-eslint/eslint-plugin": "6.18.1", "@typescript-eslint/parser": "6.18.1", "eslint": "8.56.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index eb0c613e97..640713067f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -120,8 +120,8 @@ importers: specifier: 1.7.0 version: 1.7.0 '@simplewebauthn/server': - specifier: 9.0.1 - version: 9.0.1 + specifier: 9.0.2 + version: 9.0.2 '@sinonjs/fake-timers': specifier: 11.2.2 version: 11.2.2 @@ -159,14 +159,14 @@ importers: specifier: 1.20.2 version: 1.20.2 bullmq: - specifier: 5.1.5 - version: 5.1.5 + specifier: 5.1.9 + version: 5.1.9 cacheable-lookup: specifier: 7.0.0 version: 7.0.0 cbor: - specifier: 9.0.1 - version: 9.0.1 + specifier: 9.0.2 + version: 9.0.2 chalk: specifier: 5.3.0 version: 5.3.0 @@ -557,8 +557,8 @@ importers: specifier: 0.7.34 version: 0.7.34 '@types/node': - specifier: 20.11.10 - version: 20.11.10 + specifier: 20.11.17 + version: 20.11.17 '@types/node-fetch': specifier: 3.0.3 version: 3.0.3 @@ -651,7 +651,7 @@ importers: version: 9.0.0 jest: specifier: 29.7.0 - version: 29.7.0(@types/node@20.11.10) + version: 29.7.0(@types/node@20.11.17) jest-mock: specifier: 29.7.0 version: 29.7.0 @@ -699,10 +699,10 @@ importers: version: 15.0.0 '@vitejs/plugin-vue': specifier: 5.0.3 - version: 5.0.3(vite@5.1.0)(vue@3.4.15) + version: 5.0.3(vite@5.1.0)(vue@3.4.18) '@vue/compiler-sfc': - specifier: 3.4.15 - version: 3.4.15 + specifier: 3.4.18 + version: 3.4.18 aiscript-vscode: specifier: github:aiscript-dev/aiscript-vscode#v0.1.2 version: github.com/aiscript-dev/aiscript-vscode/793211d40243c8775f6b85f015c221c82cbffb07 @@ -828,16 +828,16 @@ importers: version: 9.0.1 v-code-diff: specifier: 1.7.2 - version: 1.7.2(vue@3.4.15) + version: 1.7.2(vue@3.4.18) vite: specifier: 5.1.0 - version: 5.1.0(@types/node@20.11.10)(sass@1.70.0)(terser@5.27.0) + version: 5.1.0(@types/node@20.11.17)(sass@1.70.0)(terser@5.27.0) vue: - specifier: 3.4.15 - version: 3.4.15(typescript@5.3.3) + specifier: 3.4.18 + version: 3.4.18(typescript@5.3.3) vuedraggable: specifier: next - version: 4.1.0(vue@3.4.15) + version: 4.1.0(vue@3.4.18) devDependencies: '@misskey-dev/eslint-plugin': specifier: 1.0.0 @@ -895,13 +895,13 @@ importers: version: 7.6.10 '@storybook/vue3': specifier: 7.6.10 - version: 7.6.10(vue@3.4.15) + version: 7.6.10(vue@3.4.18) '@storybook/vue3-vite': specifier: 7.6.10 - version: 7.6.10(typescript@5.3.3)(vite@5.1.0)(vue@3.4.15) + version: 7.6.10(typescript@5.3.3)(vite@5.1.0)(vue@3.4.18) '@testing-library/vue': - specifier: 8.0.1 - version: 8.0.1(@vue/compiler-sfc@3.4.15)(vue@3.4.15) + specifier: 8.0.2 + version: 8.0.2(@vue/compiler-sfc@3.4.18)(vue@3.4.18) '@types/escape-regexp': specifier: 0.0.3 version: 0.0.3 @@ -915,8 +915,8 @@ importers: specifier: 4.0.6 version: 4.0.6 '@types/node': - specifier: 20.11.10 - version: 20.11.10 + specifier: 20.11.17 + version: 20.11.17 '@types/punycode': specifier: 2.1.3 version: 2.1.3 @@ -945,8 +945,8 @@ importers: specifier: 0.34.6 version: 0.34.6(vitest@0.34.6) '@vue/runtime-core': - specifier: 3.4.15 - version: 3.4.15 + specifier: 3.4.18 + version: 3.4.18 acorn: specifier: 8.11.3 version: 8.11.3 @@ -954,8 +954,8 @@ importers: specifier: 7.0.3 version: 7.0.3 cypress: - specifier: 13.6.3 - version: 13.6.3 + specifier: 13.6.4 + version: 13.6.4 eslint: specifier: 8.56.0 version: 8.56.0 @@ -987,8 +987,8 @@ importers: specifier: 3.0.3 version: 3.0.3 prettier: - specifier: 3.2.4 - version: 3.2.4 + specifier: 3.2.5 + version: 3.2.5 react: specifier: 18.2.0 version: 18.2.0 @@ -1086,7 +1086,7 @@ importers: devDependencies: '@microsoft/api-extractor': specifier: 7.39.1 - version: 7.39.1(@types/node@20.11.10) + version: 7.39.1(@types/node@20.11.17) '@misskey-dev/eslint-plugin': specifier: 1.0.0 version: 1.0.0(@typescript-eslint/eslint-plugin@6.18.1)(@typescript-eslint/parser@6.18.1)(eslint-plugin-import@2.29.1)(eslint@8.56.0) @@ -1097,8 +1097,8 @@ importers: specifier: 29.5.11 version: 29.5.11 '@types/node': - specifier: 20.11.10 - version: 20.11.10 + specifier: 20.11.17 + version: 20.11.17 '@typescript-eslint/eslint-plugin': specifier: 6.18.1 version: 6.18.1(@typescript-eslint/parser@6.18.1)(eslint@8.56.0)(typescript@5.3.3) @@ -1110,7 +1110,7 @@ importers: version: 8.56.0 jest: specifier: 29.7.0 - version: 29.7.0(@types/node@20.11.10) + version: 29.7.0(@types/node@20.11.17) jest-fetch-mock: specifier: 3.0.3 version: 3.0.3 @@ -2290,6 +2290,14 @@ packages: hasBin: true dependencies: '@babel/types': 7.23.5 + dev: true + + /@babel/parser@7.23.9: + resolution: {integrity: sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.23.5 /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.23.3(@babel/core@7.23.5): resolution: {integrity: sha512-iRkKcCqb7iGnq9+3G6rZ+Ciz5VywC4XNRHe57lKM+jOeYAoR0lVqdeeDRfh0tQcTfw/+vBhHn926FmQhLtlFLQ==} @@ -4460,7 +4468,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.6.3 - '@types/node': 20.11.10 + '@types/node': 20.11.17 chalk: 4.1.2 jest-message-util: 29.7.0 jest-util: 29.7.0 @@ -4481,14 +4489,14 @@ packages: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.11.10 + '@types/node': 20.11.17 ansi-escapes: 4.3.2 chalk: 4.1.2 ci-info: 3.7.1 exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@20.11.10) + jest-config: 29.7.0(@types/node@20.11.17) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -4523,7 +4531,7 @@ packages: dependencies: '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.11.10 + '@types/node': 20.11.17 jest-mock: 29.7.0 dev: true @@ -4550,7 +4558,7 @@ packages: dependencies: '@jest/types': 29.6.3 '@sinonjs/fake-timers': 10.3.0 - '@types/node': 20.11.10 + '@types/node': 20.11.17 jest-message-util: 29.7.0 jest-mock: 29.7.0 jest-util: 29.7.0 @@ -4583,7 +4591,7 @@ packages: '@jest/transform': 29.7.0 '@jest/types': 29.6.3 '@jridgewell/trace-mapping': 0.3.18 - '@types/node': 20.11.10 + '@types/node': 20.11.17 chalk: 4.1.2 collect-v8-coverage: 1.0.1 exit: 0.1.2 @@ -4677,7 +4685,7 @@ packages: dependencies: '@types/istanbul-lib-coverage': 2.0.4 '@types/istanbul-reports': 3.0.1 - '@types/node': 20.11.10 + '@types/node': 20.11.17 '@types/yargs': 16.0.5 chalk: 4.1.2 dev: true @@ -4689,7 +4697,7 @@ packages: '@jest/schemas': 29.6.3 '@types/istanbul-lib-coverage': 2.0.4 '@types/istanbul-reports': 3.0.1 - '@types/node': 20.11.10 + '@types/node': 20.11.17 '@types/yargs': 17.0.19 chalk: 4.1.2 dev: true @@ -4708,7 +4716,7 @@ packages: magic-string: 0.27.0 react-docgen-typescript: 2.2.2(typescript@5.3.3) typescript: 5.3.3 - vite: 5.1.0(@types/node@20.11.10)(sass@1.70.0)(terser@5.27.0) + vite: 5.1.0(@types/node@20.11.17)(sass@1.70.0)(terser@5.27.0) dev: true /@jridgewell/gen-mapping@0.3.2: @@ -4806,24 +4814,24 @@ packages: react: 18.2.0 dev: true - /@microsoft/api-extractor-model@7.28.4(@types/node@20.11.10): + /@microsoft/api-extractor-model@7.28.4(@types/node@20.11.17): resolution: {integrity: sha512-vucgyPmgHrJ/D4/xQywAmjTmSfxAx2/aDmD6TkIoLu51FdsAfuWRbijWA48AePy60OO+l+mmy9p2P/CEeBZqig==} dependencies: '@microsoft/tsdoc': 0.14.2 '@microsoft/tsdoc-config': 0.16.2 - '@rushstack/node-core-library': 3.63.0(@types/node@20.11.10) + '@rushstack/node-core-library': 3.63.0(@types/node@20.11.17) transitivePeerDependencies: - '@types/node' dev: true - /@microsoft/api-extractor@7.39.1(@types/node@20.11.10): + /@microsoft/api-extractor@7.39.1(@types/node@20.11.17): resolution: {integrity: sha512-V0HtCufWa8hZZvSmlEzQZfINcJkHAU/bmpyJQj6w+zpI87EkR8DuBOW6RWrO9c7mUYFZoDaNgUTyKo83ytv+QQ==} hasBin: true dependencies: - '@microsoft/api-extractor-model': 7.28.4(@types/node@20.11.10) + '@microsoft/api-extractor-model': 7.28.4(@types/node@20.11.17) '@microsoft/tsdoc': 0.14.2 '@microsoft/tsdoc-config': 0.16.2 - '@rushstack/node-core-library': 3.63.0(@types/node@20.11.10) + '@rushstack/node-core-library': 3.63.0(@types/node@20.11.17) '@rushstack/rig-package': 0.5.1 '@rushstack/ts-command-line': 4.17.1 colors: 1.2.5 @@ -5911,7 +5919,7 @@ packages: requiresBuild: true optional: true - /@rushstack/node-core-library@3.63.0(@types/node@20.11.10): + /@rushstack/node-core-library@3.63.0(@types/node@20.11.17): resolution: {integrity: sha512-Q7B3dVpBQF1v+mUfxNcNZh5uHVR8ntcnkN5GYjbBLrxUYHBGKbnCM+OdcN+hzCpFlLBH6Ob0dEHhZ0spQwf24A==} peerDependencies: '@types/node': '*' @@ -5919,7 +5927,7 @@ packages: '@types/node': optional: true dependencies: - '@types/node': 20.11.10 + '@types/node': 20.11.17 colors: 1.2.5 fs-extra: 7.0.1 import-lazy: 4.0.0 @@ -5963,8 +5971,8 @@ packages: resolution: {integrity: sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==} dev: true - /@simplewebauthn/server@9.0.1: - resolution: {integrity: sha512-XnilMoBygy2BOZjIHPxby+7ENx5ChN2wXfhd14mOgO/XitYMqdphTo/kwgxEI4/Je3lELK1h/eLDJqM2fIKS1w==} + /@simplewebauthn/server@9.0.2: + resolution: {integrity: sha512-aaWA+qVOU4byk5IDb/l+M1+7dmrAJhTb4ISJHucpsgRQcMMEes76tbGIqO2JQuA7N50tc/OBrnGKBjoKYG1kSw==} engines: {node: '>=16.0.0'} dependencies: '@hexagon/base64': 1.1.27 @@ -5973,15 +5981,15 @@ packages: '@peculiar/asn1-rsa': 2.3.8 '@peculiar/asn1-schema': 2.3.8 '@peculiar/asn1-x509': 2.3.8 - '@simplewebauthn/types': 9.0.0 + '@simplewebauthn/types': 9.0.1 cbor-x: 1.5.4 cross-fetch: 4.0.0 transitivePeerDependencies: - encoding dev: false - /@simplewebauthn/types@9.0.0: - resolution: {integrity: sha512-Lo6LLNQee66D//KueYy9AyX7oiQ7BBKJgdLzP3l0HJDrV4GRSzSAii8AtigBGOeNc8hOQsF/D8itItyuZX9djA==} + /@simplewebauthn/types@9.0.1: + resolution: {integrity: sha512-tGSRP1QvsAvsJmnOlRQyw/mvK9gnPtjEc5fg2+m8n+QUa+D7rvrKkOYyfpy42GTs90X3RDOnqJgfHt+qO67/+w==} dev: false /@simplewebauthn/typescript-types@8.3.4: @@ -6772,7 +6780,7 @@ packages: magic-string: 0.30.5 rollup: 3.29.4 typescript: 5.3.3 - vite: 5.1.0(@types/node@20.11.10)(sass@1.70.0)(terser@5.27.0) + vite: 5.1.0(@types/node@20.11.17)(sass@1.70.0)(terser@5.27.0) transitivePeerDependencies: - encoding - supports-color @@ -7146,7 +7154,7 @@ packages: react: 18.2.0 react-docgen: 7.0.1 react-dom: 18.2.0(react@18.2.0) - vite: 5.1.0(@types/node@20.11.10)(sass@1.70.0)(terser@5.27.0) + vite: 5.1.0(@types/node@20.11.17)(sass@1.70.0)(terser@5.27.0) transitivePeerDependencies: - '@preact/preset-vite' - encoding @@ -7261,7 +7269,7 @@ packages: file-system-cache: 2.3.0 dev: true - /@storybook/vue3-vite@7.6.10(typescript@5.3.3)(vite@5.1.0)(vue@3.4.15): + /@storybook/vue3-vite@7.6.10(typescript@5.3.3)(vite@5.1.0)(vue@3.4.18): resolution: {integrity: sha512-5f0Rh4PTVEeAI86ybihfN+rHGXXLNiRsoGKinpJSb7hkfsq/L7u3sVCXJwH/qsG+rUJlZyHs3kfa4/Kgyyi3Mg==} engines: {node: ^14.18 || >=16} peerDependencies: @@ -7269,11 +7277,11 @@ packages: dependencies: '@storybook/builder-vite': 7.6.10(typescript@5.3.3)(vite@5.1.0) '@storybook/core-server': 7.6.10 - '@storybook/vue3': 7.6.10(vue@3.4.15) - '@vitejs/plugin-vue': 4.5.2(vite@5.1.0)(vue@3.4.15) + '@storybook/vue3': 7.6.10(vue@3.4.18) + '@vitejs/plugin-vue': 4.5.2(vite@5.1.0)(vue@3.4.18) magic-string: 0.30.5 - vite: 5.1.0(@types/node@20.11.10)(sass@1.70.0)(terser@5.27.0) - vue-docgen-api: 4.64.1(vue@3.4.15) + vite: 5.1.0(@types/node@20.11.17)(sass@1.70.0)(terser@5.27.0) + vue-docgen-api: 4.64.1(vue@3.4.18) transitivePeerDependencies: - '@preact/preset-vite' - bufferutil @@ -7285,7 +7293,7 @@ packages: - vue dev: true - /@storybook/vue3@7.6.10(vue@3.4.15): + /@storybook/vue3@7.6.10(vue@3.4.18): resolution: {integrity: sha512-FeZ9zjuudQgCdKPs2K8sU6TgEyrMjKrCN3e8+XXX5CAMSwLDV8IfexaaMF0ehYW6Wp0dgCIm0cVNBV3u8vtRRw==} engines: {node: '>=16.0.0'} peerDependencies: @@ -7300,7 +7308,7 @@ packages: lodash: 4.17.21 ts-dedent: 2.2.0 type-fest: 2.19.0 - vue: 3.4.15(typescript@5.3.3) + vue: 3.4.18(typescript@5.3.3) vue-component-type-helpers: 1.8.27 transitivePeerDependencies: - encoding @@ -7870,8 +7878,8 @@ packages: resolution: {integrity: sha512-fB0R+fa3AUqbLHWyxXa2kGVtf1Fe1ZZFr0Zp6AIbIAzXb2mKbEXl+PCQNUOaq5lbTab5tfctfXRNsWXxa2f7Aw==} engines: {node: '>=14'} dependencies: - '@babel/code-frame': 7.22.13 - '@babel/runtime': 7.23.2 + '@babel/code-frame': 7.23.5 + '@babel/runtime': 7.23.4 '@types/aria-query': 5.0.1 aria-query: 5.1.3 chalk: 4.1.2 @@ -7919,18 +7927,21 @@ packages: '@testing-library/dom': 9.2.0 dev: true - /@testing-library/vue@8.0.1(@vue/compiler-sfc@3.4.15)(vue@3.4.15): - resolution: {integrity: sha512-l51ZEpjTQ6glq3wM+asQ1GbKJMGcxwgHEygETx0aCRN4TjFEGvMZy4YdWKs/y7bu4bmLrxcxhbEPP7iPSW/2OQ==} + /@testing-library/vue@8.0.2(@vue/compiler-sfc@3.4.18)(vue@3.4.18): + resolution: {integrity: sha512-A8wWX+qQn0o0izpQWnGCpwQt8wAdpsVP8vPP2h5Q/jcGhZ5yKXz9PPUqhQv+45LTFaWlyRf8bArTVaB/KFFd5A==} engines: {node: '>=14'} peerDependencies: '@vue/compiler-sfc': '>= 3' vue: '>= 3' + peerDependenciesMeta: + '@vue/compiler-sfc': + optional: true dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.23.4 '@testing-library/dom': 9.3.3 - '@vue/compiler-sfc': 3.4.15 - '@vue/test-utils': 2.4.1(vue@3.4.15) - vue: 3.4.15(typescript@5.3.3) + '@vue/compiler-sfc': 3.4.18 + '@vue/test-utils': 2.4.1(vue@3.4.18) + vue: 3.4.18(typescript@5.3.3) transitivePeerDependencies: - '@vue/server-renderer' dev: true @@ -7956,7 +7967,7 @@ packages: /@types/accepts@1.3.7: resolution: {integrity: sha512-Pay9fq2lM2wXPWbteBsRAGiWH2hig4ZE2asK+mm7kUzlxRTfL961rj89I6zV/E3PcIkDqyuBEcMxFT7rccugeQ==} dependencies: - '@types/node': 20.11.10 + '@types/node': 20.11.17 dev: true /@types/archiver@6.0.2: @@ -8010,7 +8021,7 @@ packages: resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==} dependencies: '@types/connect': 3.4.35 - '@types/node': 20.11.10 + '@types/node': 20.11.17 dev: true /@types/braces@3.0.1: @@ -8022,14 +8033,14 @@ packages: dependencies: '@types/http-cache-semantics': 4.0.1 '@types/keyv': 3.1.4 - '@types/node': 20.11.10 + '@types/node': 20.11.17 '@types/responselike': 1.0.0 dev: false /@types/cbor@6.0.0: resolution: {integrity: sha512-mGQ1lbYOwVti5Xlarn1bTeBZqgY0kstsdjnkoEovgohYKdBjGejHyNGXHdMBeqyQazIv32Jjp33+5pBEaSRy2w==} dependencies: - cbor: 9.0.1 + cbor: 9.0.2 dev: true /@types/chai-subset@1.3.5: @@ -8055,7 +8066,7 @@ packages: /@types/connect@3.4.35: resolution: {integrity: sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==} dependencies: - '@types/node': 20.11.10 + '@types/node': 20.11.17 dev: true /@types/content-disposition@0.5.8: @@ -8069,7 +8080,7 @@ packages: /@types/cross-spawn@6.0.2: resolution: {integrity: sha512-KuwNhp3eza+Rhu8IFI5HUXRP0LIhqH5cAjubUvGXXthh4YYBuP2ntwEX+Cz8GJoZUHlKo247wPWOfA9LYEq4cw==} dependencies: - '@types/node': 20.11.10 + '@types/node': 20.11.17 dev: true /@types/detect-port@1.3.2: @@ -8121,7 +8132,7 @@ packages: /@types/express-serve-static-core@4.17.33: resolution: {integrity: sha512-TPBqmR/HRYI3eC2E5hmiivIzv+bidAfXofM+sbonAGvyDhySGw9/PQZFt2BLOrjUUR++4eJVpx6KnLQK1Fk9tA==} dependencies: - '@types/node': 20.11.10 + '@types/node': 20.11.17 '@types/qs': 6.9.7 '@types/range-parser': 1.2.4 dev: true @@ -8142,20 +8153,20 @@ packages: /@types/fluent-ffmpeg@2.1.24: resolution: {integrity: sha512-g5oQO8Jgi2kFS3tTub7wLvfLztr1s8tdXmRd8PiL/hLMLzTIAyMR2sANkTggM/rdEDAg3d63nYRRVepwBiCw5A==} dependencies: - '@types/node': 20.11.10 + '@types/node': 20.11.17 dev: true /@types/glob@7.2.0: resolution: {integrity: sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==} dependencies: '@types/minimatch': 5.1.2 - '@types/node': 20.11.10 + '@types/node': 20.11.17 dev: true /@types/graceful-fs@4.1.6: resolution: {integrity: sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==} dependencies: - '@types/node': 20.11.10 + '@types/node': 20.11.17 dev: true /@types/http-cache-semantics@4.0.1: @@ -8168,7 +8179,7 @@ packages: /@types/http-link-header@1.0.5: resolution: {integrity: sha512-AxhIKR8UbyoqCTNp9rRepkktHuUOw3DjfOfDCaO9kwI8AYzjhxyrvZq4+mRw/2daD3hYDknrtSeV6SsPwmc71w==} dependencies: - '@types/node': 20.11.10 + '@types/node': 20.11.17 dev: true /@types/istanbul-lib-coverage@2.0.4: @@ -8208,7 +8219,7 @@ packages: /@types/jsdom@21.1.6: resolution: {integrity: sha512-/7kkMsC+/kMs7gAYmmBR9P0vGTnOoLhQhyhQJSlXGI5bzTHp6xdo0TtKWQAsz6pmSAeVqKSbqeyP6hytqr9FDw==} dependencies: - '@types/node': 20.11.10 + '@types/node': 20.11.17 '@types/tough-cookie': 4.0.2 parse5: 7.1.2 dev: true @@ -8232,7 +8243,7 @@ packages: /@types/keyv@3.1.4: resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} dependencies: - '@types/node': 20.11.10 + '@types/node': 20.11.17 dev: false /@types/lodash@4.14.191: @@ -8281,7 +8292,7 @@ packages: /@types/node-fetch@2.6.4: resolution: {integrity: sha512-1ZX9fcN4Rvkvgv4E6PAY5WXUFWFcRWxZa3EW83UjycOB9ljJCedb2CupIP4RZMEwF/M3eTcCihbBRgwtGbg5Rg==} dependencies: - '@types/node': 20.11.10 + '@types/node': 20.11.17 form-data: 3.0.1 /@types/node-fetch@3.0.3: @@ -8294,8 +8305,8 @@ packages: resolution: {integrity: sha512-2yrWpBk32tvV/JAd3HNHWuZn/VDN1P+72hWirHnvsvTGSqbANi+kSeuQR9yAHnbvaBvHDsoTdXV0Fe+iRtHLKA==} dev: true - /@types/node@20.11.10: - resolution: {integrity: sha512-rZEfe/hJSGYmdfX9tvcPMYeYPW2sNl50nsw4jZmRcaG0HIAb0WYEpsB05GOb53vjqpyE9GUhlDQ4jLSoB5q9kg==} + /@types/node@20.11.17: + resolution: {integrity: sha512-QmgQZGWu1Yw9TDyAP9ZzpFJKynYNeOvwMJmaxABfieQoVoiVOS6MN1WSpqpRcbeA5+RW82kraAVxCCJg+780Qw==} dependencies: undici-types: 5.26.5 @@ -8314,7 +8325,7 @@ packages: /@types/nodemailer@6.4.14: resolution: {integrity: sha512-fUWthHO9k9DSdPCSPRqcu6TWhYyxTBg382vlNIttSe9M7XfsT06y0f24KHXtbnijPGGRIcVvdKHTNikOI6qiHA==} dependencies: - '@types/node': 20.11.10 + '@types/node': 20.11.17 dev: true /@types/normalize-package-data@2.4.1: @@ -8331,13 +8342,13 @@ packages: resolution: {integrity: sha512-Ali0fUUn+zgr4Yy/pCTFbuiaiJpq7l7OQwFnxYVchNbNGIx0c4Wkcdje6WO89I91RAaYF+gVc1pOaizA4YKZmA==} dependencies: '@types/express': 4.17.17 - '@types/node': 20.11.10 + '@types/node': 20.11.17 dev: true /@types/oauth@0.9.4: resolution: {integrity: sha512-qk9orhti499fq5XxKCCEbd0OzdPZuancneyse3KtR+vgMiHRbh+mn8M4G6t64ob/Fg+GZGpa565MF/2dKWY32A==} dependencies: - '@types/node': 20.11.10 + '@types/node': 20.11.17 dev: true /@types/offscreencanvas@2019.3.0: @@ -8353,7 +8364,7 @@ packages: /@types/pg@8.11.0: resolution: {integrity: sha512-sDAlRiBNthGjNFfvt0k6mtotoVYVQ63pA8R4EMWka7crawSR60waVYR0HAgmPRs/e2YaeJTD/43OoZ3PFw80pw==} dependencies: - '@types/node': 20.11.10 + '@types/node': 20.11.17 pg-protocol: 1.6.0 pg-types: 4.0.1 dev: true @@ -8377,7 +8388,7 @@ packages: /@types/qrcode@1.5.5: resolution: {integrity: sha512-CdfBi/e3Qk+3Z/fXYShipBT13OJ2fDO2Q2w5CIP5anLTLIndQG9z6P1cnm+8zCWSpm5dnxMFd/uREtb0EXuQzg==} dependencies: - '@types/node': 20.11.10 + '@types/node': 20.11.17 dev: true /@types/qs@6.9.7: @@ -8407,7 +8418,7 @@ packages: /@types/readdir-glob@1.1.1: resolution: {integrity: sha512-ImM6TmoF8bgOwvehGviEj3tRdRBbQujr1N+0ypaln/GWjaerOB26jb93vsRHmdMtvVQZQebOlqt2HROark87mQ==} dependencies: - '@types/node': 20.11.10 + '@types/node': 20.11.17 dev: true /@types/rename@1.0.7: @@ -8421,7 +8432,7 @@ packages: /@types/responselike@1.0.0: resolution: {integrity: sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==} dependencies: - '@types/node': 20.11.10 + '@types/node': 20.11.17 dev: false /@types/sanitize-html@2.9.5: @@ -8451,7 +8462,7 @@ packages: resolution: {integrity: sha512-NUo5XNiAdULrJENtJXZZ3fHtfMolzZwczzBbnAeBbqBwG+LaG6YaJtuwzwGSQZ2wsCrxjEhNNjAkKigy3n8teQ==} dependencies: '@types/mime': 3.0.1 - '@types/node': 20.11.10 + '@types/node': 20.11.17 dev: true /@types/serviceworker@0.0.67: @@ -8522,13 +8533,13 @@ packages: /@types/vary@1.1.3: resolution: {integrity: sha512-XJT8/ZQCL7NUut9QDLf6l24JfAEl7bnNdgxfj50cHIpEPRJLHHDDFOAq6i+GsEmeFfH7NamhBE4c4Thtb2egWg==} dependencies: - '@types/node': 20.11.10 + '@types/node': 20.11.17 dev: true /@types/web-push@3.6.3: resolution: {integrity: sha512-v3oT4mMJsHeJ/rraliZ+7TbZtr5bQQuxcgD7C3/1q/zkAj29c8RE0F9lVZVu3hiQe5Z9fYcBreV7TLnfKR+4mg==} dependencies: - '@types/node': 20.11.10 + '@types/node': 20.11.17 dev: true /@types/webgl-ext@0.0.30: @@ -8539,7 +8550,7 @@ packages: /@types/ws@8.5.10: resolution: {integrity: sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==} dependencies: - '@types/node': 20.11.10 + '@types/node': 20.11.17 dev: true /@types/yargs-parser@21.0.0: @@ -8562,7 +8573,7 @@ packages: resolution: {integrity: sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==} requiresBuild: true dependencies: - '@types/node': 20.11.10 + '@types/node': 20.11.17 dev: true optional: true @@ -8844,31 +8855,31 @@ packages: '@babel/plugin-transform-react-jsx-source': 7.19.6(@babel/core@7.23.5) magic-string: 0.27.0 react-refresh: 0.14.0 - vite: 5.1.0(@types/node@20.11.10)(sass@1.70.0)(terser@5.27.0) + vite: 5.1.0(@types/node@20.11.17)(sass@1.70.0)(terser@5.27.0) transitivePeerDependencies: - supports-color dev: true - /@vitejs/plugin-vue@4.5.2(vite@5.1.0)(vue@3.4.15): + /@vitejs/plugin-vue@4.5.2(vite@5.1.0)(vue@3.4.18): resolution: {integrity: sha512-UGR3DlzLi/SaVBPX0cnSyE37vqxU3O6chn8l0HJNzQzDia6/Au2A4xKv+iIJW8w2daf80G7TYHhi1pAUjdZ0bQ==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: vite: ^4.0.0 || ^5.0.0 vue: ^3.2.25 dependencies: - vite: 5.1.0(@types/node@20.11.10)(sass@1.70.0)(terser@5.27.0) - vue: 3.4.15(typescript@5.3.3) + vite: 5.1.0(@types/node@20.11.17)(sass@1.70.0)(terser@5.27.0) + vue: 3.4.18(typescript@5.3.3) dev: true - /@vitejs/plugin-vue@5.0.3(vite@5.1.0)(vue@3.4.15): + /@vitejs/plugin-vue@5.0.3(vite@5.1.0)(vue@3.4.18): resolution: {integrity: sha512-b8S5dVS40rgHdDrw+DQi/xOM9ed+kSRZzfm1T74bMmBDCd8XO87NKlFYInzCtwvtWwXZvo1QxE2OSspTATWrbA==} engines: {node: ^18.0.0 || >=20.0.0} peerDependencies: vite: ^5.0.0 vue: ^3.2.25 dependencies: - vite: 5.1.0(@types/node@20.11.10)(sass@1.70.0)(terser@5.27.0) - vue: 3.4.15(typescript@5.3.3) + vite: 5.1.0(@types/node@20.11.17)(sass@1.70.0)(terser@5.27.0) + vue: 3.4.18(typescript@5.3.3) dev: false /@vitest/coverage-v8@0.34.6(vitest@0.34.6): @@ -8966,6 +8977,16 @@ packages: entities: 4.5.0 estree-walker: 2.0.2 source-map-js: 1.0.2 + dev: true + + /@vue/compiler-core@3.4.18: + resolution: {integrity: sha512-F7YK8lMK0iv6b9/Gdk15A67wM0KKZvxDxed0RR60C1z9tIJTKta+urs4j0RTN5XqHISzI3etN3mX0uHhjmoqjQ==} + dependencies: + '@babel/parser': 7.23.9 + '@vue/shared': 3.4.18 + entities: 4.5.0 + estree-walker: 2.0.2 + source-map-js: 1.0.2 /@vue/compiler-core@3.4.3: resolution: {integrity: sha512-u8jzgFg0EDtSrb/hG53Wwh1bAOQFtc1ZCegBpA/glyvTlgHl+tq13o1zvRfLbegYUw/E4mSTGOiCnAJ9SJ+lsg==} @@ -8989,25 +9010,32 @@ packages: dependencies: '@vue/compiler-core': 3.4.15 '@vue/shared': 3.4.15 + dev: true - /@vue/compiler-sfc@3.4.15: - resolution: {integrity: sha512-LCn5M6QpkpFsh3GQvs2mJUOAlBQcCco8D60Bcqmf3O3w5a+KWS5GvYbrrJBkgvL1BDnTp+e8q0lXCLgHhKguBA==} + /@vue/compiler-dom@3.4.18: + resolution: {integrity: sha512-24Eb8lcMfInefvQ6YlEVS18w5Q66f4+uXWVA+yb7praKbyjHRNuKVWGuinfSSjM0ZIiPi++QWukhkgznBaqpEA==} dependencies: - '@babel/parser': 7.23.6 - '@vue/compiler-core': 3.4.15 - '@vue/compiler-dom': 3.4.15 - '@vue/compiler-ssr': 3.4.15 - '@vue/shared': 3.4.15 + '@vue/compiler-core': 3.4.18 + '@vue/shared': 3.4.18 + + /@vue/compiler-sfc@3.4.18: + resolution: {integrity: sha512-rG5tqtnzwrVpMqAQ7FHtvHaV70G6LLfJIWLYZB/jZ9m/hrnZmIQh+H3ewnC5onwe/ibljm9+ZupxeElzqCkTAw==} + dependencies: + '@babel/parser': 7.23.9 + '@vue/compiler-core': 3.4.18 + '@vue/compiler-dom': 3.4.18 + '@vue/compiler-ssr': 3.4.18 + '@vue/shared': 3.4.18 estree-walker: 2.0.2 - magic-string: 0.30.5 + magic-string: 0.30.7 postcss: 8.4.33 source-map-js: 1.0.2 - /@vue/compiler-ssr@3.4.15: - resolution: {integrity: sha512-1jdeQyiGznr8gjFDadVmOJqZiLNSsMa5ZgqavkPZ8O2wjHv0tVuAEsw5hTdUoUW4232vpBbL/wJhzVW/JwY1Uw==} + /@vue/compiler-ssr@3.4.18: + resolution: {integrity: sha512-hSlv20oUhPxo2UYUacHgGaxtqP0tvFo6ixxxD6JlXIkwzwoZ9eKK6PFQN4hNK/R13JlNyldwWt/fqGBKgWJ6nQ==} dependencies: - '@vue/compiler-dom': 3.4.15 - '@vue/shared': 3.4.15 + '@vue/compiler-dom': 3.4.18 + '@vue/shared': 3.4.18 /@vue/language-core@1.8.27(typescript@5.3.3): resolution: {integrity: sha512-L8Kc27VdQserNaCUNiSFdDl9LWT24ly8Hpwf1ECy3aFb9m6bDhBGQYOujDm21N7EW3moKIOKEanQwe1q5BK+mA==} @@ -9029,32 +9057,32 @@ packages: vue-template-compiler: 2.7.14 dev: true - /@vue/reactivity@3.4.15: - resolution: {integrity: sha512-55yJh2bsff20K5O84MxSvXKPHHt17I2EomHznvFiJCAZpJTNW8IuLj1xZWMLELRhBK3kkFV/1ErZGHJfah7i7w==} + /@vue/reactivity@3.4.18: + resolution: {integrity: sha512-7uda2/I0jpLiRygprDo5Jxs2HJkOVXcOMlyVlY54yRLxoycBpwGJRwJT9EdGB4adnoqJDXVT2BilUAYwI7qvmg==} dependencies: - '@vue/shared': 3.4.15 + '@vue/shared': 3.4.18 - /@vue/runtime-core@3.4.15: - resolution: {integrity: sha512-6E3by5m6v1AkW0McCeAyhHTw+3y17YCOKG0U0HDKDscV4Hs0kgNT5G+GCHak16jKgcCDHpI9xe5NKb8sdLCLdw==} + /@vue/runtime-core@3.4.18: + resolution: {integrity: sha512-7mU9diCa+4e+8/wZ7Udw5pwTH10A11sZ1nldmHOUKJnzCwvZxfJqAtw31mIf4T5H2FsLCSBQT3xgioA9vIjyDQ==} dependencies: - '@vue/reactivity': 3.4.15 - '@vue/shared': 3.4.15 + '@vue/reactivity': 3.4.18 + '@vue/shared': 3.4.18 - /@vue/runtime-dom@3.4.15: - resolution: {integrity: sha512-EVW8D6vfFVq3V/yDKNPBFkZKGMFSvZrUQmx196o/v2tHKdwWdiZjYUBS+0Ez3+ohRyF8Njwy/6FH5gYJ75liUw==} + /@vue/runtime-dom@3.4.18: + resolution: {integrity: sha512-2y1Mkzcw1niSfG7z3Qx+2ir9Gb4hdTkZe5p/I8x1aTIKQE0vY0tPAEUPhZm5tx6183gG3D/KwHG728UR0sIufA==} dependencies: - '@vue/runtime-core': 3.4.15 - '@vue/shared': 3.4.15 + '@vue/runtime-core': 3.4.18 + '@vue/shared': 3.4.18 csstype: 3.1.3 - /@vue/server-renderer@3.4.15(vue@3.4.15): - resolution: {integrity: sha512-3HYzaidu9cHjrT+qGUuDhFYvF/j643bHC6uUN9BgM11DVy+pM6ATsG6uPBLnkwOgs7BpJABReLmpL3ZPAsUaqw==} + /@vue/server-renderer@3.4.18(vue@3.4.18): + resolution: {integrity: sha512-YJd1wa7mzUN3NRqLEsrwEYWyO+PUBSROIGlCc3J/cvn7Zu6CxhNLgXa8Z4zZ5ja5/nviYO79J1InoPeXgwBTZA==} peerDependencies: - vue: 3.4.15 + vue: 3.4.18 dependencies: - '@vue/compiler-ssr': 3.4.15 - '@vue/shared': 3.4.15 - vue: 3.4.15(typescript@5.3.3) + '@vue/compiler-ssr': 3.4.18 + '@vue/shared': 3.4.18 + vue: 3.4.18(typescript@5.3.3) /@vue/shared@3.3.12: resolution: {integrity: sha512-6p0Yin0pclvnER7BLNOQuod9Z+cxSYh8pSh7CzHnWNjAIP6zrTlCdHRvSCb1aYEx6i3Q3kvfuWU7nG16CgG1ag==} @@ -9062,12 +9090,16 @@ packages: /@vue/shared@3.4.15: resolution: {integrity: sha512-KzfPTxVaWfB+eGcGdbSf4CWdaXcGDqckoeXUh7SB3fZdEtzPCK2Vq9B/lRRL3yutax/LWITz+SwvgyOxz5V75g==} + dev: true + + /@vue/shared@3.4.18: + resolution: {integrity: sha512-CxouGFxxaW5r1WbrSmWwck3No58rApXgRSBxrqgnY1K+jk20F6DrXJkHdH9n4HVT+/B6G2CAn213Uq3npWiy8Q==} /@vue/shared@3.4.3: resolution: {integrity: sha512-rIwlkkP1n4uKrRzivAKPZIEkHiuwY5mmhMJ2nZKCBLz8lTUlE73rQh4n1OnnMurXt1vcUNyH4ZPfdh8QweTjpQ==} dev: true - /@vue/test-utils@2.4.1(vue@3.4.15): + /@vue/test-utils@2.4.1(vue@3.4.18): resolution: {integrity: sha512-VO8nragneNzUZUah6kOjiFmD/gwRjUauG9DROh6oaOeFwX1cZRUNHhdeogE8635cISigXFTtGLUQWx5KCb0xeg==} peerDependencies: '@vue/server-renderer': ^3.0.1 @@ -9077,7 +9109,7 @@ packages: optional: true dependencies: js-beautify: 1.14.9 - vue: 3.4.15(typescript@5.3.3) + vue: 3.4.18(typescript@5.3.3) vue-component-type-helpers: 1.8.4 dev: true @@ -10000,8 +10032,8 @@ packages: dependencies: node-gyp-build: 4.6.0 - /bullmq@5.1.5: - resolution: {integrity: sha512-Rc9QGHrj/wJ8RMENKa839o1pJmdicg7KBTfmVU8YqYuEK2JcMSJaKMg2XrAi7sdYSawgOJgC/kiW9fCGYEj6Yg==} + /bullmq@5.1.9: + resolution: {integrity: sha512-9MfcQxYyfkG8kxpIxRsRXWYlTRQ1o8xWqgdoFR5pLClVTjtMI8qeDO5basRQLZPfp/uiPtv+gpzJ3OTNrm2ZNg==} dependencies: cron-parser: 4.8.1 glob: 8.1.0 @@ -10179,8 +10211,8 @@ packages: cbor-extract: 2.1.1 dev: false - /cbor@9.0.1: - resolution: {integrity: sha512-/TQOWyamDxvVIv+DY9cOLNuABkoyz8K/F3QE56539pGVYohx0+MEA1f4lChFTX79dBTBS7R1PF6ovH7G+VtBfQ==} + /cbor@9.0.2: + resolution: {integrity: sha512-JPypkxsB10s9QOWwa6zwPzqE1Md3vqpPc+cai4sAecuCsRyAtAl/pMyhPlMbT/xtPnm2dznJZYRLui57qiRhaQ==} engines: {node: '>=16'} dependencies: nofilter: 3.1.0 @@ -10717,7 +10749,7 @@ packages: readable-stream: 3.6.0 dev: false - /create-jest@29.7.0(@types/node@20.11.10): + /create-jest@29.7.0(@types/node@20.11.17): resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true @@ -10726,7 +10758,7 @@ packages: chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@20.11.10) + jest-config: 29.7.0(@types/node@20.11.17) jest-util: 29.7.0 prompts: 2.4.2 transitivePeerDependencies: @@ -10979,6 +11011,56 @@ packages: yauzl: 2.10.0 dev: true + /cypress@13.6.4: + resolution: {integrity: sha512-pYJjCfDYB+hoOoZuhysbbYhEmNW7DEDsqn+ToCLwuVowxUXppIWRr7qk4TVRIU471ksfzyZcH+mkoF0CQUKnpw==} + engines: {node: ^16.0.0 || ^18.0.0 || >=20.0.0} + hasBin: true + requiresBuild: true + dependencies: + '@cypress/request': 3.0.0 + '@cypress/xvfb': 1.2.4(supports-color@8.1.1) + '@types/sinonjs__fake-timers': 8.1.1 + '@types/sizzle': 2.3.3 + arch: 2.2.0 + blob-util: 2.0.2 + bluebird: 3.7.2 + buffer: 5.7.1 + cachedir: 2.3.0 + chalk: 4.1.2 + check-more-types: 2.24.0 + cli-cursor: 3.1.0 + cli-table3: 0.6.3 + commander: 6.2.1 + common-tags: 1.8.2 + dayjs: 1.11.10 + debug: 4.3.4(supports-color@8.1.1) + enquirer: 2.3.6 + eventemitter2: 6.4.7 + execa: 4.1.0 + executable: 4.1.1 + extract-zip: 2.0.1(supports-color@8.1.1) + figures: 3.2.0 + fs-extra: 9.1.0 + getos: 3.2.1 + is-ci: 3.0.1 + is-installed-globally: 0.4.0 + lazy-ass: 1.6.0 + listr2: 3.14.0(enquirer@2.3.6) + lodash: 4.17.21 + log-symbols: 4.1.0 + minimist: 1.2.8 + ospath: 1.2.2 + pretty-bytes: 5.6.0 + process: 0.11.10 + proxy-from-env: 1.0.0 + request-progress: 3.0.0 + semver: 7.5.4 + supports-color: 8.1.1 + tmp: 0.2.1 + untildify: 4.0.0 + yauzl: 2.10.0 + dev: true + /dashdash@1.14.1: resolution: {integrity: sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==} engines: {node: '>=0.10'} @@ -14028,7 +14110,7 @@ packages: '@jest/expect': 29.7.0 '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.11.10 + '@types/node': 20.11.17 chalk: 4.1.2 co: 4.6.0 dedent: 1.3.0 @@ -14049,7 +14131,7 @@ packages: - supports-color dev: true - /jest-cli@29.7.0(@types/node@20.11.10): + /jest-cli@29.7.0(@types/node@20.11.17): resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true @@ -14063,10 +14145,10 @@ packages: '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 chalk: 4.1.2 - create-jest: 29.7.0(@types/node@20.11.10) + create-jest: 29.7.0(@types/node@20.11.17) exit: 0.1.2 import-local: 3.1.0 - jest-config: 29.7.0(@types/node@20.11.10) + jest-config: 29.7.0(@types/node@20.11.17) jest-util: 29.7.0 jest-validate: 29.7.0 yargs: 17.6.2 @@ -14077,7 +14159,7 @@ packages: - ts-node dev: true - /jest-config@29.7.0(@types/node@20.11.10): + /jest-config@29.7.0(@types/node@20.11.17): resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: @@ -14092,7 +14174,7 @@ packages: '@babel/core': 7.22.11 '@jest/test-sequencer': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.11.10 + '@types/node': 20.11.17 babel-jest: 29.7.0(@babel/core@7.22.11) chalk: 4.1.2 ci-info: 3.7.1 @@ -14172,7 +14254,7 @@ packages: '@jest/environment': 29.7.0 '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.11.10 + '@types/node': 20.11.17 jest-mock: 29.7.0 jest-util: 29.7.0 dev: true @@ -14202,7 +14284,7 @@ packages: dependencies: '@jest/types': 29.6.3 '@types/graceful-fs': 4.1.6 - '@types/node': 20.11.10 + '@types/node': 20.11.17 anymatch: 3.1.3 fb-watchman: 2.0.2 graceful-fs: 4.2.11 @@ -14263,7 +14345,7 @@ packages: engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: '@jest/types': 27.5.1 - '@types/node': 20.11.10 + '@types/node': 20.11.17 dev: true /jest-mock@29.7.0: @@ -14271,7 +14353,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.6.3 - '@types/node': 20.11.10 + '@types/node': 20.11.17 jest-util: 29.7.0 dev: true @@ -14326,7 +14408,7 @@ packages: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.11.10 + '@types/node': 20.11.17 chalk: 4.1.2 emittery: 0.13.1 graceful-fs: 4.2.11 @@ -14357,7 +14439,7 @@ packages: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.11.10 + '@types/node': 20.11.17 chalk: 4.1.2 cjs-module-lexer: 1.2.2 collect-v8-coverage: 1.0.1 @@ -14409,7 +14491,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.6.3 - '@types/node': 20.11.10 + '@types/node': 20.11.17 chalk: 4.1.2 ci-info: 3.7.1 graceful-fs: 4.2.11 @@ -14434,7 +14516,7 @@ packages: dependencies: '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.11.10 + '@types/node': 20.11.17 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.13.1 @@ -14453,13 +14535,13 @@ packages: resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@types/node': 20.11.10 + '@types/node': 20.11.17 jest-util: 29.7.0 merge-stream: 2.0.0 supports-color: 8.1.1 dev: true - /jest@29.7.0(@types/node@20.11.10): + /jest@29.7.0(@types/node@20.11.17): resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true @@ -14472,7 +14554,7 @@ packages: '@jest/core': 29.7.0 '@jest/types': 29.6.3 import-local: 3.1.0 - jest-cli: 29.7.0(@types/node@20.11.10) + jest-cli: 29.7.0(@types/node@20.11.17) transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -15040,6 +15122,12 @@ packages: dependencies: '@jridgewell/sourcemap-codec': 1.4.15 + /magic-string@0.30.7: + resolution: {integrity: sha512-8vBuFF/I/+OSLRmdf2wwFCJCz+nSn0m6DPvGH1fS/KiQoSaR+sETbov0eIk9KhEKy8CYqIkIAnbohxT/4H0kuA==} + engines: {node: '>=12'} + dependencies: + '@jridgewell/sourcemap-codec': 1.4.15 + /mailcheck@1.1.1: resolution: {integrity: sha512-3WjL8+ZDouZwKlyJBMp/4LeziLFXgleOdsYu87piGcMLqhBzCsy2QFdbtAwv757TFC/rtqd738fgJw1tFQCSgA==} dev: false @@ -16995,8 +17083,8 @@ packages: hasBin: true dev: true - /prettier@3.2.4: - resolution: {integrity: sha512-FWu1oLHKCrtpO1ypU6J0SbK2d9Ckwysq6bHj/uaCP26DxrPpppCLQRGVuqAxSTvhF00AcvDRyYrLNW7ocBhFFQ==} + /prettier@3.2.5: + resolution: {integrity: sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==} engines: {node: '>=14'} hasBin: true dev: true @@ -19805,7 +19893,7 @@ packages: resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} hasBin: true - /v-code-diff@1.7.2(vue@3.4.15): + /v-code-diff@1.7.2(vue@3.4.18): resolution: {integrity: sha512-y+q8ZHf8GfphYLhcZbjAKcId/h6vZujS71Ryq5u+dI6Jg4ZLTdLrBNVSzYpHywHSSFFfBMdilm6XvVryEaH4+A==} requiresBuild: true peerDependencies: @@ -19818,8 +19906,8 @@ packages: diff: 5.1.0 diff-match-patch: 1.0.5 highlight.js: 11.8.0 - vue: 3.4.15(typescript@5.3.3) - vue-demi: 0.13.11(vue@3.4.15) + vue: 3.4.18(typescript@5.3.3) + vue-demi: 0.13.11(vue@3.4.18) dev: false /v8-to-istanbul@9.1.0: @@ -19864,7 +19952,7 @@ packages: core-util-is: 1.0.2 extsprintf: 1.3.0 - /vite-node@0.34.6(@types/node@20.11.10)(sass@1.70.0)(terser@5.27.0): + /vite-node@0.34.6(@types/node@20.11.17)(sass@1.70.0)(terser@5.27.0): resolution: {integrity: sha512-nlBMJ9x6n7/Amaz6F3zJ97EBwR2FkzhBRxF5e+jE6LA3yi6Wtc2lyTij1OnDMIr34v5g/tVQtsVAzhT0jc5ygA==} engines: {node: '>=v14.18.0'} hasBin: true @@ -19874,7 +19962,7 @@ packages: mlly: 1.5.0 pathe: 1.1.2 picocolors: 1.0.0 - vite: 5.1.0(@types/node@20.11.10)(sass@1.70.0)(terser@5.27.0) + vite: 5.1.0(@types/node@20.11.17)(sass@1.70.0)(terser@5.27.0) transitivePeerDependencies: - '@types/node' - less @@ -19890,7 +19978,7 @@ packages: resolution: {integrity: sha512-p4D8CFVhZS412SyQX125qxyzOgIFouwOcvjZWk6bQbNPR1wtaEzFT6jZxAjf1dejlGqa6fqHcuCvQea6EWUkUA==} dev: true - /vite@5.1.0(@types/node@20.11.10)(sass@1.70.0)(terser@5.27.0): + /vite@5.1.0(@types/node@20.11.17)(sass@1.70.0)(terser@5.27.0): resolution: {integrity: sha512-STmSFzhY4ljuhz14bg9LkMTk3d98IO6DIArnTY6MeBwiD1Za2StcQtz7fzOUnRCqrHSD5+OS2reg4HOz1eoLnw==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true @@ -19918,7 +20006,7 @@ packages: terser: optional: true dependencies: - '@types/node': 20.11.10 + '@types/node': 20.11.17 esbuild: 0.19.11 postcss: 8.4.35 rollup: 4.9.6 @@ -19972,7 +20060,7 @@ packages: dependencies: '@types/chai': 4.3.11 '@types/chai-subset': 1.3.5 - '@types/node': 20.11.10 + '@types/node': 20.11.17 '@vitest/expect': 0.34.6 '@vitest/runner': 0.34.6 '@vitest/snapshot': 0.34.6 @@ -19992,8 +20080,8 @@ packages: strip-literal: 1.3.0 tinybench: 2.6.0 tinypool: 0.7.0 - vite: 5.1.0(@types/node@20.11.10)(sass@1.70.0)(terser@5.27.0) - vite-node: 0.34.6(@types/node@20.11.10)(sass@1.70.0)(terser@5.27.0) + vite: 5.1.0(@types/node@20.11.17)(sass@1.70.0)(terser@5.27.0) + vite-node: 0.34.6(@types/node@20.11.17)(sass@1.70.0)(terser@5.27.0) why-is-node-running: 2.2.2 transitivePeerDependencies: - less @@ -20053,7 +20141,7 @@ packages: resolution: {integrity: sha512-6bnLkn8O0JJyiFSIF0EfCogzeqNXpnjJ0vW/SZzNHfe6sPx30lTtTXlE5TFs2qhJlAtDFybStVNpL73cPe3OMQ==} dev: true - /vue-demi@0.13.11(vue@3.4.15): + /vue-demi@0.13.11(vue@3.4.18): resolution: {integrity: sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==} engines: {node: '>=12'} hasBin: true @@ -20065,23 +20153,23 @@ packages: '@vue/composition-api': optional: true dependencies: - vue: 3.4.15(typescript@5.3.3) + vue: 3.4.18(typescript@5.3.3) dev: false - /vue-docgen-api@4.64.1(vue@3.4.15): + /vue-docgen-api@4.64.1(vue@3.4.18): resolution: {integrity: sha512-jbOf7ByE3Zvtuk+429Jorl+eIeh2aB2Fx1GUo3xJd1aByJWE8KDlSEa6b11PB1ze8f0sRUBraRDinICCk0KY7g==} dependencies: '@babel/parser': 7.23.6 '@babel/types': 7.23.5 '@vue/compiler-dom': 3.4.15 - '@vue/compiler-sfc': 3.4.15 + '@vue/compiler-sfc': 3.4.18 ast-types: 0.14.2 hash-sum: 2.0.0 lru-cache: 8.0.4 pug: 3.0.2 recast: 0.22.0 ts-map: 1.0.3 - vue-inbrowser-compiler-independent-utils: 4.64.1(vue@3.4.15) + vue-inbrowser-compiler-independent-utils: 4.64.1(vue@3.4.18) transitivePeerDependencies: - vue dev: true @@ -20104,12 +20192,12 @@ packages: - supports-color dev: true - /vue-inbrowser-compiler-independent-utils@4.64.1(vue@3.4.15): + /vue-inbrowser-compiler-independent-utils@4.64.1(vue@3.4.18): resolution: {integrity: sha512-Hn32n07XZ8j9W8+fmOXPQL+i+W2e/8i6mkH4Ju3H6nR0+cfvmWM95GhczYi5B27+Y8JlCKgAo04IUiYce4mKAw==} peerDependencies: vue: '>=2' dependencies: - vue: 3.4.15(typescript@5.3.3) + vue: 3.4.18(typescript@5.3.3) dev: true /vue-template-compiler@2.7.14: @@ -20131,28 +20219,28 @@ packages: typescript: 5.3.3 dev: true - /vue@3.4.15(typescript@5.3.3): - resolution: {integrity: sha512-jC0GH4KkWLWJOEQjOpkqU1bQsBwf4R1rsFtw5GQJbjHVKWDzO6P0nWWBTmjp1xSemAioDFj1jdaK1qa3DnMQoQ==} + /vue@3.4.18(typescript@5.3.3): + resolution: {integrity: sha512-0zLRYamFRe0wF4q2L3O24KQzLyLpL64ye1RUToOgOxuWZsb/FhaNRdGmeozdtVYLz6tl94OXLaK7/WQIrVCw1A==} peerDependencies: typescript: '*' peerDependenciesMeta: typescript: optional: true dependencies: - '@vue/compiler-dom': 3.4.15 - '@vue/compiler-sfc': 3.4.15 - '@vue/runtime-dom': 3.4.15 - '@vue/server-renderer': 3.4.15(vue@3.4.15) - '@vue/shared': 3.4.15 + '@vue/compiler-dom': 3.4.18 + '@vue/compiler-sfc': 3.4.18 + '@vue/runtime-dom': 3.4.18 + '@vue/server-renderer': 3.4.18(vue@3.4.18) + '@vue/shared': 3.4.18 typescript: 5.3.3 - /vuedraggable@4.1.0(vue@3.4.15): + /vuedraggable@4.1.0(vue@3.4.18): resolution: {integrity: sha512-FU5HCWBmsf20GpP3eudURW3WdWTKIbEIQxh9/8GE806hydR9qZqRRxRE3RjqX7PkuLuMQG/A7n3cfj9rCEchww==} peerDependencies: vue: ^3.0.1 dependencies: sortablejs: 1.14.0 - vue: 3.4.15(typescript@5.3.3) + vue: 3.4.18(typescript@5.3.3) dev: false /w3c-xmlserializer@5.0.0: -- GitLab From 639f14f7132840bfdcdb687dfaffe47c17ee6ade Mon Sep 17 00:00:00 2001 From: syuilo <Syuilotan@yahoo.co.jp> Date: Fri, 9 Feb 2024 17:10:31 +0900 Subject: [PATCH 37/40] 2024.2.0-beta.11 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1a38627361..3619366519 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "misskey", - "version": "2024.2.0-beta.10", + "version": "2024.2.0-beta.11", "codename": "nasubi", "repository": { "type": "git", -- GitLab From 7a8cf274ca8a3a738f7bf7045ee7c97b22482d71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=8B=E3=81=A3=E3=81=93=E3=81=8B=E3=82=8A?= <67428053+kakkokari-gtyih@users.noreply.github.com> Date: Fri, 9 Feb 2024 18:08:08 +0900 Subject: [PATCH 38/40] fix misskey-js version --- packages/misskey-js/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/misskey-js/package.json b/packages/misskey-js/package.json index bc3001fc05..26b682f1c4 100644 --- a/packages/misskey-js/package.json +++ b/packages/misskey-js/package.json @@ -1,7 +1,7 @@ { "type": "module", "name": "misskey-js", - "version": "2024.2.0-beta.10", + "version": "2024.2.0-beta.11", "description": "Misskey SDK for JavaScript", "types": "./built/dts/index.d.ts", "exports": { -- GitLab From 48c1f94dc5ad6926bbf49d8d3b3a3e07878012b4 Mon Sep 17 00:00:00 2001 From: Marie <marie@kaifa.ch> Date: Fri, 9 Feb 2024 19:39:58 +0100 Subject: [PATCH 39/40] fix: downgrade vue --- packages/frontend/package.json | 8 +- pnpm-lock.yaml | 271 +++++++++++++++------------------ 2 files changed, 128 insertions(+), 151 deletions(-) diff --git a/packages/frontend/package.json b/packages/frontend/package.json index 22553dc687..f5c968ec3c 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -29,7 +29,7 @@ "@phosphor-icons/web": "^2.0.3", "@twemoji/parser": "15.0.0", "@vitejs/plugin-vue": "5.0.3", - "@vue/compiler-sfc": "3.4.18", + "@vue/compiler-sfc": "3.4.15", "aiscript-vscode": "github:aiscript-dev/aiscript-vscode#v0.1.2", "astring": "1.8.6", "broadcast-channel": "7.0.0", @@ -73,7 +73,7 @@ "uuid": "9.0.1", "v-code-diff": "1.7.2", "vite": "5.1.0", - "vue": "3.4.18", + "vue": "3.4.15", "vuedraggable": "next" }, "devDependencies": { @@ -97,7 +97,7 @@ "@storybook/types": "7.6.10", "@storybook/vue3": "7.6.10", "@storybook/vue3-vite": "7.6.10", - "@testing-library/vue": "8.0.2", + "@testing-library/vue": "8.0.1", "@types/escape-regexp": "0.0.3", "@types/estree": "1.0.5", "@types/matter-js": "0.19.6", @@ -112,7 +112,7 @@ "@typescript-eslint/eslint-plugin": "6.18.1", "@typescript-eslint/parser": "6.18.1", "@vitest/coverage-v8": "0.34.6", - "@vue/runtime-core": "3.4.18", + "@vue/runtime-core": "3.4.15", "acorn": "8.11.3", "cross-env": "7.0.3", "cypress": "13.6.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7f8bc28742..2c15690f93 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -707,10 +707,10 @@ importers: version: 15.0.0 '@vitejs/plugin-vue': specifier: 5.0.3 - version: 5.0.3(vite@5.1.0)(vue@3.4.18) + version: 5.0.3(vite@5.1.0)(vue@3.4.15) '@vue/compiler-sfc': - specifier: 3.4.18 - version: 3.4.18 + specifier: 3.4.15 + version: 3.4.15 aiscript-vscode: specifier: github:aiscript-dev/aiscript-vscode#v0.1.2 version: github.com/aiscript-dev/aiscript-vscode/793211d40243c8775f6b85f015c221c82cbffb07 @@ -836,16 +836,16 @@ importers: version: 9.0.1 v-code-diff: specifier: 1.7.2 - version: 1.7.2(vue@3.4.18) + version: 1.7.2(vue@3.4.15) vite: specifier: 5.1.0 version: 5.1.0(@types/node@20.11.17)(sass@1.70.0)(terser@5.27.0) vue: - specifier: 3.4.18 - version: 3.4.18(typescript@5.3.3) + specifier: 3.4.15 + version: 3.4.15(typescript@5.3.3) vuedraggable: specifier: next - version: 4.1.0(vue@3.4.18) + version: 4.1.0(vue@3.4.15) devDependencies: '@misskey-dev/eslint-plugin': specifier: 1.0.0 @@ -903,13 +903,13 @@ importers: version: 7.6.10 '@storybook/vue3': specifier: 7.6.10 - version: 7.6.10(vue@3.4.18) + version: 7.6.10(vue@3.4.15) '@storybook/vue3-vite': specifier: 7.6.10 - version: 7.6.10(typescript@5.3.3)(vite@5.1.0)(vue@3.4.18) + version: 7.6.10(typescript@5.3.3)(vite@5.1.0)(vue@3.4.15) '@testing-library/vue': - specifier: 8.0.2 - version: 8.0.2(@vue/compiler-sfc@3.4.18)(vue@3.4.18) + specifier: 8.0.1 + version: 8.0.1(@vue/compiler-sfc@3.4.15)(vue@3.4.15) '@types/escape-regexp': specifier: 0.0.3 version: 0.0.3 @@ -953,8 +953,8 @@ importers: specifier: 0.34.6 version: 0.34.6(vitest@0.34.6) '@vue/runtime-core': - specifier: 3.4.18 - version: 3.4.18 + specifier: 3.4.15 + version: 3.4.15 acorn: specifier: 8.11.3 version: 8.11.3 @@ -1993,7 +1993,7 @@ packages: '@babel/traverse': 7.23.4 '@babel/types': 7.23.4 convert-source-map: 2.0.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 @@ -2085,7 +2085,7 @@ packages: '@babel/core': 7.23.3 '@babel/helper-compilation-targets': 7.23.6 '@babel/helper-plugin-utils': 7.22.5 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) lodash.debounce: 4.0.8 resolve: 1.22.8 transitivePeerDependencies: @@ -3296,7 +3296,7 @@ packages: '@babel/helper-split-export-declaration': 7.22.6 '@babel/parser': 7.23.4 '@babel/types': 7.23.4 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) globals: 11.12.0 transitivePeerDependencies: - supports-color @@ -3998,7 +3998,7 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: ajv: 6.12.6 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) espree: 9.6.1 globals: 13.23.0 ignore: 5.3.0 @@ -4015,7 +4015,7 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: ajv: 6.12.6 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) espree: 9.6.1 globals: 13.23.0 ignore: 5.3.0 @@ -4256,7 +4256,7 @@ packages: engines: {node: '>=10.10.0'} dependencies: '@humanwhocodes/object-schema': 2.0.1 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) minimatch: 3.1.2 transitivePeerDependencies: - supports-color @@ -7095,7 +7095,7 @@ packages: file-system-cache: 2.3.0 dev: true - /@storybook/vue3-vite@7.6.10(typescript@5.3.3)(vite@5.1.0)(vue@3.4.18): + /@storybook/vue3-vite@7.6.10(typescript@5.3.3)(vite@5.1.0)(vue@3.4.15): resolution: {integrity: sha512-5f0Rh4PTVEeAI86ybihfN+rHGXXLNiRsoGKinpJSb7hkfsq/L7u3sVCXJwH/qsG+rUJlZyHs3kfa4/Kgyyi3Mg==} engines: {node: ^14.18 || >=16} peerDependencies: @@ -7103,11 +7103,11 @@ packages: dependencies: '@storybook/builder-vite': 7.6.10(typescript@5.3.3)(vite@5.1.0) '@storybook/core-server': 7.6.10 - '@storybook/vue3': 7.6.10(vue@3.4.18) - '@vitejs/plugin-vue': 4.5.2(vite@5.1.0)(vue@3.4.18) + '@storybook/vue3': 7.6.10(vue@3.4.15) + '@vitejs/plugin-vue': 4.5.2(vite@5.1.0)(vue@3.4.15) magic-string: 0.30.5 vite: 5.1.0(@types/node@20.11.17)(sass@1.70.0)(terser@5.27.0) - vue-docgen-api: 4.64.1(vue@3.4.18) + vue-docgen-api: 4.64.1(vue@3.4.15) transitivePeerDependencies: - '@preact/preset-vite' - bufferutil @@ -7119,7 +7119,7 @@ packages: - vue dev: true - /@storybook/vue3@7.6.10(vue@3.4.18): + /@storybook/vue3@7.6.10(vue@3.4.15): resolution: {integrity: sha512-FeZ9zjuudQgCdKPs2K8sU6TgEyrMjKrCN3e8+XXX5CAMSwLDV8IfexaaMF0ehYW6Wp0dgCIm0cVNBV3u8vtRRw==} engines: {node: '>=16.0.0'} peerDependencies: @@ -7134,7 +7134,7 @@ packages: lodash: 4.17.21 ts-dedent: 2.2.0 type-fest: 2.19.0 - vue: 3.4.18(typescript@5.3.3) + vue: 3.4.15(typescript@5.3.3) vue-component-type-helpers: 1.8.27 transitivePeerDependencies: - encoding @@ -7624,21 +7624,18 @@ packages: '@testing-library/dom': 9.2.0 dev: true - /@testing-library/vue@8.0.2(@vue/compiler-sfc@3.4.18)(vue@3.4.18): - resolution: {integrity: sha512-A8wWX+qQn0o0izpQWnGCpwQt8wAdpsVP8vPP2h5Q/jcGhZ5yKXz9PPUqhQv+45LTFaWlyRf8bArTVaB/KFFd5A==} + /@testing-library/vue@8.0.1(@vue/compiler-sfc@3.4.15)(vue@3.4.15): + resolution: {integrity: sha512-l51ZEpjTQ6glq3wM+asQ1GbKJMGcxwgHEygETx0aCRN4TjFEGvMZy4YdWKs/y7bu4bmLrxcxhbEPP7iPSW/2OQ==} engines: {node: '>=14'} peerDependencies: '@vue/compiler-sfc': '>= 3' vue: '>= 3' - peerDependenciesMeta: - '@vue/compiler-sfc': - optional: true dependencies: '@babel/runtime': 7.23.4 '@testing-library/dom': 9.3.3 - '@vue/compiler-sfc': 3.4.18 - '@vue/test-utils': 2.4.1(vue@3.4.18) - vue: 3.4.18(typescript@5.3.3) + '@vue/compiler-sfc': 3.4.15 + '@vue/test-utils': 2.4.1(vue@3.4.15) + vue: 3.4.15(typescript@5.3.3) transitivePeerDependencies: - '@vue/server-renderer' dev: true @@ -8315,7 +8312,7 @@ packages: '@typescript-eslint/type-utils': 6.11.0(eslint@8.53.0)(typescript@5.3.3) '@typescript-eslint/utils': 6.11.0(eslint@8.53.0)(typescript@5.3.3) '@typescript-eslint/visitor-keys': 6.11.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) eslint: 8.53.0 graphemer: 1.4.0 ignore: 5.3.0 @@ -8344,7 +8341,7 @@ packages: '@typescript-eslint/type-utils': 6.12.0(eslint@8.54.0)(typescript@5.1.6) '@typescript-eslint/utils': 6.12.0(eslint@8.54.0)(typescript@5.1.6) '@typescript-eslint/visitor-keys': 6.12.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) eslint: 8.54.0 graphemer: 1.4.0 ignore: 5.3.0 @@ -8373,7 +8370,7 @@ packages: '@typescript-eslint/type-utils': 6.18.1(eslint@8.56.0)(typescript@5.3.3) '@typescript-eslint/utils': 6.18.1(eslint@8.56.0)(typescript@5.3.3) '@typescript-eslint/visitor-keys': 6.18.1 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) eslint: 8.56.0 graphemer: 1.4.0 ignore: 5.3.0 @@ -8399,7 +8396,7 @@ packages: '@typescript-eslint/types': 6.11.0 '@typescript-eslint/typescript-estree': 6.11.0(typescript@5.3.3) '@typescript-eslint/visitor-keys': 6.11.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) eslint: 8.53.0 typescript: 5.3.3 transitivePeerDependencies: @@ -8420,7 +8417,7 @@ packages: '@typescript-eslint/types': 6.12.0 '@typescript-eslint/typescript-estree': 6.12.0(typescript@5.1.6) '@typescript-eslint/visitor-keys': 6.12.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) eslint: 8.54.0 typescript: 5.1.6 transitivePeerDependencies: @@ -8441,7 +8438,7 @@ packages: '@typescript-eslint/types': 6.18.1 '@typescript-eslint/typescript-estree': 6.18.1(typescript@5.3.3) '@typescript-eslint/visitor-keys': 6.18.1 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) eslint: 8.56.0 typescript: 5.3.3 transitivePeerDependencies: @@ -8484,7 +8481,7 @@ packages: dependencies: '@typescript-eslint/typescript-estree': 6.11.0(typescript@5.3.3) '@typescript-eslint/utils': 6.11.0(eslint@8.53.0)(typescript@5.3.3) - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) eslint: 8.53.0 ts-api-utils: 1.0.3(typescript@5.3.3) typescript: 5.3.3 @@ -8504,7 +8501,7 @@ packages: dependencies: '@typescript-eslint/typescript-estree': 6.12.0(typescript@5.1.6) '@typescript-eslint/utils': 6.12.0(eslint@8.54.0)(typescript@5.1.6) - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) eslint: 8.54.0 ts-api-utils: 1.0.3(typescript@5.1.6) typescript: 5.1.6 @@ -8524,7 +8521,7 @@ packages: dependencies: '@typescript-eslint/typescript-estree': 6.18.1(typescript@5.3.3) '@typescript-eslint/utils': 6.18.1(eslint@8.56.0)(typescript@5.3.3) - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) eslint: 8.56.0 ts-api-utils: 1.0.3(typescript@5.3.3) typescript: 5.3.3 @@ -8558,7 +8555,7 @@ packages: dependencies: '@typescript-eslint/types': 6.11.0 '@typescript-eslint/visitor-keys': 6.11.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) globby: 11.1.0 is-glob: 4.0.3 semver: 7.5.4 @@ -8579,7 +8576,7 @@ packages: dependencies: '@typescript-eslint/types': 6.12.0 '@typescript-eslint/visitor-keys': 6.12.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) globby: 11.1.0 is-glob: 4.0.3 semver: 7.5.4 @@ -8600,7 +8597,7 @@ packages: dependencies: '@typescript-eslint/types': 6.18.1 '@typescript-eslint/visitor-keys': 6.18.1 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) globby: 11.1.0 is-glob: 4.0.3 minimatch: 9.0.3 @@ -8712,7 +8709,7 @@ packages: - supports-color dev: true - /@vitejs/plugin-vue@4.5.2(vite@5.1.0)(vue@3.4.18): + /@vitejs/plugin-vue@4.5.2(vite@5.1.0)(vue@3.4.15): resolution: {integrity: sha512-UGR3DlzLi/SaVBPX0cnSyE37vqxU3O6chn8l0HJNzQzDia6/Au2A4xKv+iIJW8w2daf80G7TYHhi1pAUjdZ0bQ==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: @@ -8720,10 +8717,10 @@ packages: vue: ^3.2.25 dependencies: vite: 5.1.0(@types/node@20.11.17)(sass@1.70.0)(terser@5.27.0) - vue: 3.4.18(typescript@5.3.3) + vue: 3.4.15(typescript@5.3.3) dev: true - /@vitejs/plugin-vue@5.0.3(vite@5.1.0)(vue@3.4.18): + /@vitejs/plugin-vue@5.0.3(vite@5.1.0)(vue@3.4.15): resolution: {integrity: sha512-b8S5dVS40rgHdDrw+DQi/xOM9ed+kSRZzfm1T74bMmBDCd8XO87NKlFYInzCtwvtWwXZvo1QxE2OSspTATWrbA==} engines: {node: ^18.0.0 || >=20.0.0} peerDependencies: @@ -8731,7 +8728,7 @@ packages: vue: ^3.2.25 dependencies: vite: 5.1.0(@types/node@20.11.17)(sass@1.70.0)(terser@5.27.0) - vue: 3.4.18(typescript@5.3.3) + vue: 3.4.15(typescript@5.3.3) dev: false /@vitest/coverage-v8@0.34.6(vitest@0.34.6): @@ -8812,24 +8809,14 @@ packages: path-browserify: 1.0.1 dev: true - /@vue/compiler-core@3.3.12: - resolution: {integrity: sha512-qAtjyG3GBLG0chzp5xGCyRLLe6wFCHmjI82aGzwuGKyznNP+GJJMxjc0wOYWDB2YKfho7niJFdoFpo0CZZQg9w==} - dependencies: - '@babel/parser': 7.23.6 - '@vue/shared': 3.3.12 - estree-walker: 2.0.2 - source-map-js: 1.0.2 - dev: true - /@vue/compiler-core@3.4.15: resolution: {integrity: sha512-XcJQVOaxTKCnth1vCxEChteGuwG6wqnUHxAm1DO3gCz0+uXKaJNx8/digSz4dLALCy8n2lKq24jSUs8segoqIw==} dependencies: - '@babel/parser': 7.23.6 + '@babel/parser': 7.23.9 '@vue/shared': 3.4.15 entities: 4.5.0 estree-walker: 2.0.2 source-map-js: 1.0.2 - dev: true /@vue/compiler-core@3.4.18: resolution: {integrity: sha512-F7YK8lMK0iv6b9/Gdk15A67wM0KKZvxDxed0RR60C1z9tIJTKta+urs4j0RTN5XqHISzI3etN3mX0uHhjmoqjQ==} @@ -8839,6 +8826,7 @@ packages: entities: 4.5.0 estree-walker: 2.0.2 source-map-js: 1.0.2 + dev: true /@vue/compiler-core@3.4.3: resolution: {integrity: sha512-u8jzgFg0EDtSrb/hG53Wwh1bAOQFtc1ZCegBpA/glyvTlgHl+tq13o1zvRfLbegYUw/E4mSTGOiCnAJ9SJ+lsg==} @@ -8850,44 +8838,37 @@ packages: source-map-js: 1.0.2 dev: true - /@vue/compiler-dom@3.3.12: - resolution: {integrity: sha512-RdJU9oEYaoPKUdGXCy0l+i4clesdDeLmbvRlszoc9iagsnBnMmQtYfCPVQ5BHB6o7K4SCucDdJM2Dh3oXB0D6g==} - dependencies: - '@vue/compiler-core': 3.3.12 - '@vue/shared': 3.3.12 - dev: true - /@vue/compiler-dom@3.4.15: resolution: {integrity: sha512-wox0aasVV74zoXyblarOM3AZQz/Z+OunYcIHe1OsGclCHt8RsRm04DObjefaI82u6XDzv+qGWZ24tIsRAIi5MQ==} dependencies: '@vue/compiler-core': 3.4.15 '@vue/shared': 3.4.15 - dev: true /@vue/compiler-dom@3.4.18: resolution: {integrity: sha512-24Eb8lcMfInefvQ6YlEVS18w5Q66f4+uXWVA+yb7praKbyjHRNuKVWGuinfSSjM0ZIiPi++QWukhkgznBaqpEA==} dependencies: '@vue/compiler-core': 3.4.18 '@vue/shared': 3.4.18 + dev: true - /@vue/compiler-sfc@3.4.18: - resolution: {integrity: sha512-rG5tqtnzwrVpMqAQ7FHtvHaV70G6LLfJIWLYZB/jZ9m/hrnZmIQh+H3ewnC5onwe/ibljm9+ZupxeElzqCkTAw==} + /@vue/compiler-sfc@3.4.15: + resolution: {integrity: sha512-LCn5M6QpkpFsh3GQvs2mJUOAlBQcCco8D60Bcqmf3O3w5a+KWS5GvYbrrJBkgvL1BDnTp+e8q0lXCLgHhKguBA==} dependencies: '@babel/parser': 7.23.9 - '@vue/compiler-core': 3.4.18 - '@vue/compiler-dom': 3.4.18 - '@vue/compiler-ssr': 3.4.18 - '@vue/shared': 3.4.18 + '@vue/compiler-core': 3.4.15 + '@vue/compiler-dom': 3.4.15 + '@vue/compiler-ssr': 3.4.15 + '@vue/shared': 3.4.15 estree-walker: 2.0.2 magic-string: 0.30.7 postcss: 8.4.33 source-map-js: 1.0.2 - /@vue/compiler-ssr@3.4.18: - resolution: {integrity: sha512-hSlv20oUhPxo2UYUacHgGaxtqP0tvFo6ixxxD6JlXIkwzwoZ9eKK6PFQN4hNK/R13JlNyldwWt/fqGBKgWJ6nQ==} + /@vue/compiler-ssr@3.4.15: + resolution: {integrity: sha512-1jdeQyiGznr8gjFDadVmOJqZiLNSsMa5ZgqavkPZ8O2wjHv0tVuAEsw5hTdUoUW4232vpBbL/wJhzVW/JwY1Uw==} dependencies: - '@vue/compiler-dom': 3.4.18 - '@vue/shared': 3.4.18 + '@vue/compiler-dom': 3.4.15 + '@vue/shared': 3.4.15 /@vue/language-core@1.8.27(typescript@5.3.3): resolution: {integrity: sha512-L8Kc27VdQserNaCUNiSFdDl9LWT24ly8Hpwf1ECy3aFb9m6bDhBGQYOujDm21N7EW3moKIOKEanQwe1q5BK+mA==} @@ -8899,8 +8880,8 @@ packages: dependencies: '@volar/language-core': 1.11.1 '@volar/source-map': 1.11.1 - '@vue/compiler-dom': 3.3.12 - '@vue/shared': 3.3.12 + '@vue/compiler-dom': 3.4.18 + '@vue/shared': 3.4.18 computeds: 0.0.1 minimatch: 9.0.3 muggle-string: 0.3.1 @@ -8909,49 +8890,45 @@ packages: vue-template-compiler: 2.7.14 dev: true - /@vue/reactivity@3.4.18: - resolution: {integrity: sha512-7uda2/I0jpLiRygprDo5Jxs2HJkOVXcOMlyVlY54yRLxoycBpwGJRwJT9EdGB4adnoqJDXVT2BilUAYwI7qvmg==} + /@vue/reactivity@3.4.15: + resolution: {integrity: sha512-55yJh2bsff20K5O84MxSvXKPHHt17I2EomHznvFiJCAZpJTNW8IuLj1xZWMLELRhBK3kkFV/1ErZGHJfah7i7w==} dependencies: - '@vue/shared': 3.4.18 + '@vue/shared': 3.4.15 - /@vue/runtime-core@3.4.18: - resolution: {integrity: sha512-7mU9diCa+4e+8/wZ7Udw5pwTH10A11sZ1nldmHOUKJnzCwvZxfJqAtw31mIf4T5H2FsLCSBQT3xgioA9vIjyDQ==} + /@vue/runtime-core@3.4.15: + resolution: {integrity: sha512-6E3by5m6v1AkW0McCeAyhHTw+3y17YCOKG0U0HDKDscV4Hs0kgNT5G+GCHak16jKgcCDHpI9xe5NKb8sdLCLdw==} dependencies: - '@vue/reactivity': 3.4.18 - '@vue/shared': 3.4.18 + '@vue/reactivity': 3.4.15 + '@vue/shared': 3.4.15 - /@vue/runtime-dom@3.4.18: - resolution: {integrity: sha512-2y1Mkzcw1niSfG7z3Qx+2ir9Gb4hdTkZe5p/I8x1aTIKQE0vY0tPAEUPhZm5tx6183gG3D/KwHG728UR0sIufA==} + /@vue/runtime-dom@3.4.15: + resolution: {integrity: sha512-EVW8D6vfFVq3V/yDKNPBFkZKGMFSvZrUQmx196o/v2tHKdwWdiZjYUBS+0Ez3+ohRyF8Njwy/6FH5gYJ75liUw==} dependencies: - '@vue/runtime-core': 3.4.18 - '@vue/shared': 3.4.18 + '@vue/runtime-core': 3.4.15 + '@vue/shared': 3.4.15 csstype: 3.1.3 - /@vue/server-renderer@3.4.18(vue@3.4.18): - resolution: {integrity: sha512-YJd1wa7mzUN3NRqLEsrwEYWyO+PUBSROIGlCc3J/cvn7Zu6CxhNLgXa8Z4zZ5ja5/nviYO79J1InoPeXgwBTZA==} + /@vue/server-renderer@3.4.15(vue@3.4.15): + resolution: {integrity: sha512-3HYzaidu9cHjrT+qGUuDhFYvF/j643bHC6uUN9BgM11DVy+pM6ATsG6uPBLnkwOgs7BpJABReLmpL3ZPAsUaqw==} peerDependencies: - vue: 3.4.18 + vue: 3.4.15 dependencies: - '@vue/compiler-ssr': 3.4.18 - '@vue/shared': 3.4.18 - vue: 3.4.18(typescript@5.3.3) - - /@vue/shared@3.3.12: - resolution: {integrity: sha512-6p0Yin0pclvnER7BLNOQuod9Z+cxSYh8pSh7CzHnWNjAIP6zrTlCdHRvSCb1aYEx6i3Q3kvfuWU7nG16CgG1ag==} - dev: true + '@vue/compiler-ssr': 3.4.15 + '@vue/shared': 3.4.15 + vue: 3.4.15(typescript@5.3.3) /@vue/shared@3.4.15: resolution: {integrity: sha512-KzfPTxVaWfB+eGcGdbSf4CWdaXcGDqckoeXUh7SB3fZdEtzPCK2Vq9B/lRRL3yutax/LWITz+SwvgyOxz5V75g==} - dev: true /@vue/shared@3.4.18: resolution: {integrity: sha512-CxouGFxxaW5r1WbrSmWwck3No58rApXgRSBxrqgnY1K+jk20F6DrXJkHdH9n4HVT+/B6G2CAn213Uq3npWiy8Q==} + dev: true /@vue/shared@3.4.3: resolution: {integrity: sha512-rIwlkkP1n4uKrRzivAKPZIEkHiuwY5mmhMJ2nZKCBLz8lTUlE73rQh4n1OnnMurXt1vcUNyH4ZPfdh8QweTjpQ==} dev: true - /@vue/test-utils@2.4.1(vue@3.4.18): + /@vue/test-utils@2.4.1(vue@3.4.15): resolution: {integrity: sha512-VO8nragneNzUZUah6kOjiFmD/gwRjUauG9DROh6oaOeFwX1cZRUNHhdeogE8635cISigXFTtGLUQWx5KCb0xeg==} peerDependencies: '@vue/server-renderer': ^3.0.1 @@ -8961,7 +8938,7 @@ packages: optional: true dependencies: js-beautify: 1.14.9 - vue: 3.4.18(typescript@5.3.3) + vue: 3.4.15(typescript@5.3.3) vue-component-type-helpers: 1.8.4 dev: true @@ -9067,7 +9044,7 @@ packages: resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} engines: {node: '>= 6.0.0'} dependencies: - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) transitivePeerDependencies: - supports-color @@ -9075,7 +9052,7 @@ packages: resolution: {integrity: sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==} engines: {node: '>= 14'} dependencies: - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) transitivePeerDependencies: - supports-color dev: false @@ -9471,7 +9448,7 @@ packages: resolution: {integrity: sha512-TAlMYvOuwGyLK3PfBb5WKBXZmXz2fVCgv23d6zZFdle/q3gPjmxBaeuC0pY0Dzs5PWMSgfqqEZkrye19GlDTgw==} dependencies: archy: 1.0.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) fastq: 1.15.0 transitivePeerDependencies: - supports-color @@ -10985,7 +10962,6 @@ packages: dependencies: ms: 2.1.2 supports-color: 5.5.0 - dev: true /debug@4.3.4(supports-color@8.1.1): resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} @@ -10998,6 +10974,7 @@ packages: dependencies: ms: 2.1.2 supports-color: 8.1.1 + dev: true /decamelize-keys@1.1.1: resolution: {integrity: sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==} @@ -11210,7 +11187,7 @@ packages: hasBin: true dependencies: address: 1.2.2 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) transitivePeerDependencies: - supports-color dev: true @@ -11527,7 +11504,7 @@ packages: peerDependencies: esbuild: '>=0.12 <1' dependencies: - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) esbuild: 0.18.20 transitivePeerDependencies: - supports-color @@ -11843,7 +11820,7 @@ packages: ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.3 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) doctrine: 3.0.0 escape-string-regexp: 4.0.0 eslint-scope: 7.2.2 @@ -11890,7 +11867,7 @@ packages: ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.3 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) doctrine: 3.0.0 escape-string-regexp: 4.0.0 eslint-scope: 7.2.2 @@ -11937,7 +11914,7 @@ packages: ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.3 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) doctrine: 3.0.0 escape-string-regexp: 4.0.0 eslint-scope: 7.2.2 @@ -12589,7 +12566,7 @@ packages: debug: optional: true dependencies: - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) /for-each@0.3.3: resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} @@ -13238,7 +13215,7 @@ packages: engines: {node: '>= 14'} dependencies: agent-base: 7.1.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) transitivePeerDependencies: - supports-color dev: false @@ -13277,7 +13254,7 @@ packages: engines: {node: '>= 6.0.0'} dependencies: agent-base: 5.1.1 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) transitivePeerDependencies: - supports-color dev: true @@ -13287,7 +13264,7 @@ packages: engines: {node: '>= 6'} dependencies: agent-base: 6.0.2 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) transitivePeerDependencies: - supports-color @@ -13296,7 +13273,7 @@ packages: engines: {node: '>= 14'} dependencies: agent-base: 7.1.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) transitivePeerDependencies: - supports-color dev: false @@ -13456,7 +13433,7 @@ packages: dependencies: '@ioredis/commands': 1.2.0 cluster-key-slot: 1.1.2 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) denque: 2.1.0 lodash.defaults: 4.2.0 lodash.isarguments: 3.1.0 @@ -13880,7 +13857,7 @@ packages: resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} engines: {node: '>=10'} dependencies: - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) istanbul-lib-coverage: 3.2.2 source-map: 0.6.1 transitivePeerDependencies: @@ -17115,7 +17092,7 @@ packages: engines: {node: '>=8.16.0'} dependencies: '@types/mime-types': 2.1.4 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) extract-zip: 1.7.0 https-proxy-agent: 4.0.0 mime: 2.6.0 @@ -18084,7 +18061,7 @@ packages: dependencies: '@hapi/hoek': 10.0.1 '@hapi/wreck': 18.0.1 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) joi: 17.7.0 transitivePeerDependencies: - supports-color @@ -18284,7 +18261,7 @@ packages: engines: {node: '>= 14'} dependencies: agent-base: 7.1.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) socks: 2.7.1 transitivePeerDependencies: - supports-color @@ -18437,7 +18414,7 @@ packages: arg: 5.0.2 bluebird: 3.7.2 check-more-types: 2.24.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) execa: 5.1.1 lazy-ass: 1.6.0 ps-tree: 1.2.0 @@ -19342,7 +19319,7 @@ packages: chalk: 4.1.2 cli-highlight: 2.1.11 dayjs: 1.11.10 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) dotenv: 16.0.3 glob: 10.3.10 ioredis: 5.3.2 @@ -19626,7 +19603,7 @@ packages: resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} hasBin: true - /v-code-diff@1.7.2(vue@3.4.18): + /v-code-diff@1.7.2(vue@3.4.15): resolution: {integrity: sha512-y+q8ZHf8GfphYLhcZbjAKcId/h6vZujS71Ryq5u+dI6Jg4ZLTdLrBNVSzYpHywHSSFFfBMdilm6XvVryEaH4+A==} requiresBuild: true peerDependencies: @@ -19639,8 +19616,8 @@ packages: diff: 5.1.0 diff-match-patch: 1.0.5 highlight.js: 11.8.0 - vue: 3.4.18(typescript@5.3.3) - vue-demi: 0.13.11(vue@3.4.18) + vue: 3.4.15(typescript@5.3.3) + vue-demi: 0.13.11(vue@3.4.15) dev: false /v8-to-istanbul@9.2.0: @@ -19682,7 +19659,7 @@ packages: hasBin: true dependencies: cac: 6.7.14 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) mlly: 1.5.0 pathe: 1.1.2 picocolors: 1.0.0 @@ -19794,7 +19771,7 @@ packages: acorn-walk: 8.3.2 cac: 6.7.14 chai: 4.3.10 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) happy-dom: 10.0.3 local-pkg: 0.4.3 magic-string: 0.30.5 @@ -19873,7 +19850,7 @@ packages: resolution: {integrity: sha512-6bnLkn8O0JJyiFSIF0EfCogzeqNXpnjJ0vW/SZzNHfe6sPx30lTtTXlE5TFs2qhJlAtDFybStVNpL73cPe3OMQ==} dev: true - /vue-demi@0.13.11(vue@3.4.18): + /vue-demi@0.13.11(vue@3.4.15): resolution: {integrity: sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==} engines: {node: '>=12'} hasBin: true @@ -19885,23 +19862,23 @@ packages: '@vue/composition-api': optional: true dependencies: - vue: 3.4.18(typescript@5.3.3) + vue: 3.4.15(typescript@5.3.3) dev: false - /vue-docgen-api@4.64.1(vue@3.4.18): + /vue-docgen-api@4.64.1(vue@3.4.15): resolution: {integrity: sha512-jbOf7ByE3Zvtuk+429Jorl+eIeh2aB2Fx1GUo3xJd1aByJWE8KDlSEa6b11PB1ze8f0sRUBraRDinICCk0KY7g==} dependencies: '@babel/parser': 7.23.6 '@babel/types': 7.23.4 '@vue/compiler-dom': 3.4.15 - '@vue/compiler-sfc': 3.4.18 + '@vue/compiler-sfc': 3.4.15 ast-types: 0.14.2 hash-sum: 2.0.0 lru-cache: 8.0.4 pug: 3.0.2 recast: 0.22.0 ts-map: 1.0.3 - vue-inbrowser-compiler-independent-utils: 4.64.1(vue@3.4.18) + vue-inbrowser-compiler-independent-utils: 4.64.1(vue@3.4.15) transitivePeerDependencies: - vue dev: true @@ -19912,7 +19889,7 @@ packages: peerDependencies: eslint: '>=6.0.0' dependencies: - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4(supports-color@5.5.0) eslint: 8.56.0 eslint-scope: 7.2.2 eslint-visitor-keys: 3.4.3 @@ -19924,12 +19901,12 @@ packages: - supports-color dev: true - /vue-inbrowser-compiler-independent-utils@4.64.1(vue@3.4.18): + /vue-inbrowser-compiler-independent-utils@4.64.1(vue@3.4.15): resolution: {integrity: sha512-Hn32n07XZ8j9W8+fmOXPQL+i+W2e/8i6mkH4Ju3H6nR0+cfvmWM95GhczYi5B27+Y8JlCKgAo04IUiYce4mKAw==} peerDependencies: vue: '>=2' dependencies: - vue: 3.4.18(typescript@5.3.3) + vue: 3.4.15(typescript@5.3.3) dev: true /vue-template-compiler@2.7.14: @@ -19951,28 +19928,28 @@ packages: typescript: 5.3.3 dev: true - /vue@3.4.18(typescript@5.3.3): - resolution: {integrity: sha512-0zLRYamFRe0wF4q2L3O24KQzLyLpL64ye1RUToOgOxuWZsb/FhaNRdGmeozdtVYLz6tl94OXLaK7/WQIrVCw1A==} + /vue@3.4.15(typescript@5.3.3): + resolution: {integrity: sha512-jC0GH4KkWLWJOEQjOpkqU1bQsBwf4R1rsFtw5GQJbjHVKWDzO6P0nWWBTmjp1xSemAioDFj1jdaK1qa3DnMQoQ==} peerDependencies: typescript: '*' peerDependenciesMeta: typescript: optional: true dependencies: - '@vue/compiler-dom': 3.4.18 - '@vue/compiler-sfc': 3.4.18 - '@vue/runtime-dom': 3.4.18 - '@vue/server-renderer': 3.4.18(vue@3.4.18) - '@vue/shared': 3.4.18 + '@vue/compiler-dom': 3.4.15 + '@vue/compiler-sfc': 3.4.15 + '@vue/runtime-dom': 3.4.15 + '@vue/server-renderer': 3.4.15(vue@3.4.15) + '@vue/shared': 3.4.15 typescript: 5.3.3 - /vuedraggable@4.1.0(vue@3.4.18): + /vuedraggable@4.1.0(vue@3.4.15): resolution: {integrity: sha512-FU5HCWBmsf20GpP3eudURW3WdWTKIbEIQxh9/8GE806hydR9qZqRRxRE3RjqX7PkuLuMQG/A7n3cfj9rCEchww==} peerDependencies: vue: ^3.0.1 dependencies: sortablejs: 1.14.0 - vue: 3.4.18(typescript@5.3.3) + vue: 3.4.15(typescript@5.3.3) dev: false /w3c-xmlserializer@5.0.0: -- GitLab From 2e7df3297c13826c4c37f1c06bd87bc7cfba9e4c Mon Sep 17 00:00:00 2001 From: Marie <marie@kaifa.ch> Date: Fri, 9 Feb 2024 19:51:41 +0100 Subject: [PATCH 40/40] fix: diff between NoteCreateService and NoteEditService --- packages/backend/src/core/NoteCreateService.ts | 2 +- packages/backend/src/core/NoteEditService.ts | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/backend/src/core/NoteCreateService.ts b/packages/backend/src/core/NoteCreateService.ts index 34f3736446..0d032011b6 100644 --- a/packages/backend/src/core/NoteCreateService.ts +++ b/packages/backend/src/core/NoteCreateService.ts @@ -259,7 +259,7 @@ export class NoteCreateService implements OnApplicationShutdown { if (data.visibility === 'public' && data.channel == null) { const sensitiveWords = meta.sensitiveWords; - if (this.utilityService.isSensitiveWordIncluded(data.cw ?? data.text ?? '', sensitiveWords)) { + if (this.utilityService.isKeyWordIncluded(data.cw ?? data.text ?? '', sensitiveWords)) { data.visibility = 'home'; } else if ((await this.roleService.getUserPolicies(user.id)).canPublicNote === false) { data.visibility = 'home'; diff --git a/packages/backend/src/core/NoteEditService.ts b/packages/backend/src/core/NoteEditService.ts index a6f7edb05c..c0d17fc7ac 100644 --- a/packages/backend/src/core/NoteEditService.ts +++ b/packages/backend/src/core/NoteEditService.ts @@ -145,6 +145,8 @@ type Option = { export class NoteEditService implements OnApplicationShutdown { #shutdownController = new AbortController(); + public static ContainsProhibitedWordsError = class extends Error {}; + constructor( @Inject(DI.config) private config: Config, @@ -266,7 +268,7 @@ export class NoteEditService implements OnApplicationShutdown { if (data.visibility === 'public' && data.channel == null) { const sensitiveWords = meta.sensitiveWords; - if (this.utilityService.isSensitiveWordIncluded(data.cw ?? data.text ?? '', sensitiveWords)) { + if (this.utilityService.isKeyWordIncluded(data.cw ?? data.text ?? '', sensitiveWords)) { data.visibility = 'home'; } else if ((await this.roleService.getUserPolicies(user.id)).canPublicNote === false) { data.visibility = 'home'; -- GitLab