diff --git a/README.md b/README.md index 6840503243..2407bee3f0 100644 --- a/README.md +++ b/README.md @@ -7,9 +7,6 @@ --- - - find an instance - create an instance diff --git a/locales/en-US.yml b/locales/en-US.yml index c20ecbefbc..03a5a91e84 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -2432,6 +2432,7 @@ _notification: roleAssigned: "Role given" achievementEarned: "Achievement unlocked" app: "Notifications from linked apps" + edited: "Edits" _actions: followBack: "followed you back" reply: "Reply" diff --git a/locales/index.d.ts b/locales/index.d.ts index 2d07667cf6..7020bc2159 100644 --- a/locales/index.d.ts +++ b/locales/index.d.ts @@ -9435,6 +9435,10 @@ export interface Locale extends ILocale { * 連携アプリからの通知 */ "app": string; + /** + * 編集済み + */ + "edited": string; }; "_actions": { /** diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index ee43ccd58b..8f3bb4f48c 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -2490,6 +2490,7 @@ _notification: roleAssigned: "ロールが付与された" achievementEarned: "実績の獲得" app: "連携アプリからの通知" + edited: "編集済み" _actions: followBack: "フォローバック" diff --git a/packages/backend/package.json b/packages/backend/package.json index b05dc10c11..8e8d76bf23 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -112,6 +112,7 @@ "content-disposition": "0.5.4", "date-fns": "2.30.0", "deep-email-validator": "0.1.21", + "fast-xml-parser": "^4.4.0", "fastify": "4.26.2", "fastify-multer": "^2.0.3", "fastify-raw-body": "4.3.0", diff --git a/packages/backend/src/core/WebfingerService.ts b/packages/backend/src/core/WebfingerService.ts index 374536a741..cbbac52cdb 100644 --- a/packages/backend/src/core/WebfingerService.ts +++ b/packages/backend/src/core/WebfingerService.ts @@ -5,7 +5,7 @@ import { URL } from 'node:url'; import { Injectable } from '@nestjs/common'; -import { query as urlQuery } from '@/misc/prelude/url.js'; +import { XMLParser } from 'fast-xml-parser'; import { HttpRequestService } from '@/core/HttpRequestService.js'; import { bindThis } from '@/decorators.js'; @@ -22,6 +22,8 @@ export type IWebFinger = { const urlRegex = /^https?:\/\//; const mRegex = /^([^@]+)@(.*)/; +const defaultProtocol = process.env.MISSKEY_WEBFINGER_USE_HTTP?.toLowerCase() === 'true' ? 'http' : 'https'; + @Injectable() export class WebfingerService { constructor( @@ -31,25 +33,76 @@ export class WebfingerService { @bindThis public async webfinger(query: string): Promise { - const url = this.genUrl(query); + const hostMetaUrl = this.queryToHostMetaUrl(query); + const template = await this.fetchWebFingerTemplateFromHostMeta(hostMetaUrl) ?? this.queryToWebFingerTemplate(query); + const url = this.genUrl(query, template); return await this.httpRequestService.getJson(url, 'application/jrd+json, application/json'); } @bindThis - private genUrl(query: string): string { + private genUrl(query: string, template: string): string { + if (template.indexOf('{uri}') < 0) throw new Error(`Invalid webFingerUrl: ${template}`); + + if (query.match(urlRegex)) { + return template.replace('{uri}', encodeURIComponent(query)); + } + + const m = query.match(mRegex); + if (m) { + return template.replace('{uri}', encodeURIComponent(`acct:${query}`)); + } + + throw new Error(`Invalid query (${query})`); + } + + @bindThis + private queryToWebFingerTemplate(query: string): string { if (query.match(urlRegex)) { const u = new URL(query); - return `${u.protocol}//${u.hostname}/.well-known/webfinger?` + urlQuery({ resource: query }); + return `${u.protocol}//${u.hostname}/.well-known/webfinger?resource={uri}`; } const m = query.match(mRegex); if (m) { const hostname = m[2]; - const useHttp = process.env.MISSKEY_WEBFINGER_USE_HTTP && process.env.MISSKEY_WEBFINGER_USE_HTTP.toLowerCase() === 'true'; - return `http${useHttp ? '' : 's'}://${hostname}/.well-known/webfinger?${urlQuery({ resource: `acct:${query}` })}`; + return `${defaultProtocol}//${hostname}/.well-known/webfinger?resource={uri}`; } throw new Error(`Invalid query (${query})`); } + + @bindThis + private queryToHostMetaUrl(query: string): string { + if (query.match(urlRegex)) { + const u = new URL(query); + return `${u.protocol}//${u.hostname}/.well-known/host-meta`; + } + + const m = query.match(mRegex); + if (m) { + const hostname = m[2]; + return `${defaultProtocol}://${hostname}/.well-known/host-meta`; + } + + throw new Error(`Invalid query (${query})`); + } + + @bindThis + private async fetchWebFingerTemplateFromHostMeta(url: string): Promise { + try { + const res = await this.httpRequestService.getHtml(url, 'application/xrd+xml'); + const options = { + ignoreAttributes: false, + isArray: (_name: string, jpath: string) => jpath === 'XRD.Link', + }; + const parser = new XMLParser(options); + const hostMeta = parser.parse(res); + const template = (hostMeta['XRD']['Link'] as Array).filter(p => p['@_rel'] === 'lrdd')[0]['@_template']; + return template.indexOf('{uri}') < 0 ? null : template; + } catch (err) { + console.error(`error while request host-meta for ${url}`); + return null; + } + } } diff --git a/packages/backend/src/server/api/endpoints/blocking/create.ts b/packages/backend/src/server/api/endpoints/blocking/create.ts index 5066215749..fd6c164449 100644 --- a/packages/backend/src/server/api/endpoints/blocking/create.ts +++ b/packages/backend/src/server/api/endpoints/blocking/create.ts @@ -6,9 +6,10 @@ import ms from 'ms'; import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; -import type { UsersRepository, BlockingsRepository } from '@/models/_.js'; +import type { UsersRepository, BlockingsRepository, MutingsRepository } from '@/models/_.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { UserBlockingService } from '@/core/UserBlockingService.js'; +import { UserMutingService } from '@/core/UserMutingService.js'; import { DI } from '@/di-symbols.js'; import { GetterService } from '@/server/api/GetterService.js'; import { ApiError } from '../../error.js'; @@ -69,9 +70,13 @@ export default class extends Endpoint { // eslint- @Inject(DI.blockingsRepository) private blockingsRepository: BlockingsRepository, + @Inject(DI.mutingsRepository) + private mutingsRepository: MutingsRepository, + private userEntityService: UserEntityService, private getterService: GetterService, private userBlockingService: UserBlockingService, + private userMutingService: UserMutingService, ) { super(meta, paramDef, async (ps, me) => { const blocker = await this.usersRepository.findOneByOrFail({ id: me.id }); @@ -99,7 +104,19 @@ export default class extends Endpoint { // eslint- throw new ApiError(meta.errors.alreadyBlocking); } - await this.userBlockingService.block(blocker, blockee); + await Promise.all([ + this.userBlockingService.block(blocker, blockee), + this.mutingsRepository.exists({ + where: { + muterId: blocker.id, + muteeId: blockee.id, + }, + }).then(exists => { + if (!exists) { + this.userMutingService.mute(blocker, blockee, null); + } + }), + ]); return await this.userEntityService.pack(blockee.id, blocker, { schema: 'UserDetailedNotMe', diff --git a/packages/backend/src/server/api/endpoints/blocking/delete.ts b/packages/backend/src/server/api/endpoints/blocking/delete.ts index cebb307338..a4cd1b1cde 100644 --- a/packages/backend/src/server/api/endpoints/blocking/delete.ts +++ b/packages/backend/src/server/api/endpoints/blocking/delete.ts @@ -6,9 +6,10 @@ import ms from 'ms'; import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; -import type { UsersRepository, BlockingsRepository } from '@/models/_.js'; +import type { UsersRepository, BlockingsRepository, MutingsRepository } from '@/models/_.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { UserBlockingService } from '@/core/UserBlockingService.js'; +import { UserMutingService } from '@/core/UserMutingService.js'; import { DI } from '@/di-symbols.js'; import { GetterService } from '@/server/api/GetterService.js'; import { ApiError } from '../../error.js'; @@ -69,9 +70,13 @@ export default class extends Endpoint { // eslint- @Inject(DI.blockingsRepository) private blockingsRepository: BlockingsRepository, + @Inject(DI.mutingsRepository) + private mutingsRepository: MutingsRepository, + private userEntityService: UserEntityService, private getterService: GetterService, private userBlockingService: UserBlockingService, + private userMutingService: UserMutingService, ) { super(meta, paramDef, async (ps, me) => { const blocker = await this.usersRepository.findOneByOrFail({ id: me.id }); @@ -100,7 +105,17 @@ export default class extends Endpoint { // eslint- } // Delete blocking - await this.userBlockingService.unblock(blocker, blockee); + await Promise.all([ + this.userBlockingService.unblock(blocker, blockee), + this.mutingsRepository.findOneBy({ + muterId: blocker.id, + muteeId: blockee.id, + }).then(exists => { + if (exists) { + this.userMutingService.unmute([exists]); + } + }), + ]); return await this.userEntityService.pack(blockee.id, blocker, { schema: 'UserDetailedNotMe', diff --git a/packages/backend/src/server/web/UrlPreviewService.ts b/packages/backend/src/server/web/UrlPreviewService.ts index 8f8f08a305..96038d9c1e 100644 --- a/packages/backend/src/server/web/UrlPreviewService.ts +++ b/packages/backend/src/server/web/UrlPreviewService.ts @@ -17,20 +17,33 @@ import { bindThis } from '@/decorators.js'; import { ApiError } from '@/server/api/error.js'; import { MiMeta } from '@/models/Meta.js'; import type { FastifyRequest, FastifyReply } from 'fastify'; +import * as Redis from 'ioredis'; +import { RedisKVCache } from '@/misc/cache.js'; @Injectable() export class UrlPreviewService { private logger: Logger; + private previewCache: RedisKVCache; constructor( @Inject(DI.config) private config: Config, + @Inject(DI.redis) + private redisClient: Redis.Redis, + private metaService: MetaService, private httpRequestService: HttpRequestService, private loggerService: LoggerService, ) { this.logger = this.loggerService.getLogger('url-preview'); + this.previewCache = new RedisKVCache(this.redisClient, 'summaly', { + lifetime: 1000 * 86400, + memoryCacheLifetime: 1000 * 10 * 60, + fetcher: (key: string) => { throw new Error('the UrlPreview cache should never fetch'); }, + toRedisConverter: (value) => JSON.stringify(value), + fromRedisConverter: (value) => JSON.parse(value), + }); } @bindThis @@ -75,9 +88,19 @@ export class UrlPreviewService { }; } + const key = `${url}@${lang}`; + const cached = await this.previewCache.get(key); + if (cached !== undefined) { + this.logger.info(`Returning cache preview of ${key}`); + // Cache 7days + reply.header('Cache-Control', 'max-age=604800, immutable'); + + return cached; + } + this.logger.info(meta.urlPreviewSummaryProxyUrl - ? `(Proxy) Getting preview of ${url}@${lang} ...` - : `Getting preview of ${url}@${lang} ...`); + ? `(Proxy) Getting preview of ${key} ...` + : `Getting preview of ${key} ...`); try { const summary = meta.urlPreviewSummaryProxyUrl @@ -97,6 +120,8 @@ export class UrlPreviewService { summary.icon = this.wrap(summary.icon); summary.thumbnail = this.wrap(summary.thumbnail); + this.previewCache.set(key, summary); + // Cache 7days reply.header('Cache-Control', 'max-age=604800, immutable'); diff --git a/packages/frontend/lib/rollup-plugin-unwind-css-module-class-name.test.ts b/packages/frontend/lib/rollup-plugin-unwind-css-module-class-name.test.ts index 948cc8b2c9..5d8cf05fff 100644 --- a/packages/frontend/lib/rollup-plugin-unwind-css-module-class-name.test.ts +++ b/packages/frontend/lib/rollup-plugin-unwind-css-module-class-name.test.ts @@ -63,7 +63,7 @@ import { M as MkContainer } from './MkContainer-!~{03M}~.js'; import { b as defineComponent, a as ref, e as onMounted, z as resolveComponent, g as openBlock, h as createBlock, i as withCtx, K as createTextVNode, E as toDisplayString, u as unref, l as createBaseVNode, q as normalizeClass, B as createCommentVNode, k as createElementBlock, F as Fragment, C as renderList, A as createVNode } from './vue-!~{002}~.js'; import './photoswipe-!~{003}~.js'; -const _hoisted_1 = /* @__PURE__ */ createBaseVNode("i", { class: "ph-image-square ph-bold ph-lg" }, null, -1); +const _hoisted_1 = /* @__PURE__ */ createBaseVNode("i", { class: "ti ti-photo" }, null, -1); const _sfc_main = /* @__PURE__ */ defineComponent({ __name: "index.photos", props: { @@ -178,7 +178,7 @@ import {M as MkContainer} from './MkContainer-!~{03M}~.js'; import {b as defineComponent, a as ref, e as onMounted, z as resolveComponent, g as openBlock, h as createBlock, i as withCtx, K as createTextVNode, E as toDisplayString, u as unref, l as createBaseVNode, q as normalizeClass, B as createCommentVNode, k as createElementBlock, F as Fragment, C as renderList, A as createVNode} from './vue-!~{002}~.js'; import './photoswipe-!~{003}~.js'; const _hoisted_1 = createBaseVNode("i", { - class: "ph-image-square ph-bold ph-lg" + class: "ti ti-photo" }, null, -1); const index_photos = defineComponent({ __name: "index.photos", @@ -345,7 +345,7 @@ const _sfc_main = defineComponent({ class: $style["date-1"] }, [ h("i", { - class: \`ph-caret-up ph-bold ph-lg \${$style["date-1-icon"]}\` + class: \`ti ti-chevron-up \${$style["date-1-icon"]}\` }), getDateText(item.createdAt) ]), @@ -354,7 +354,7 @@ const _sfc_main = defineComponent({ }, [ getDateText(props.items[i + 1].createdAt), h("i", { - class: \`ph-caret-down ph-bold ph-lg \${$style["date-2-icon"]}\` + class: \`ti ti-chevron-down \${$style["date-2-icon"]}\` }) ]) ])); @@ -511,11 +511,11 @@ const _sfc_main = defineComponent({ }, [h("span", { class: $style["date-1"] }, [h("i", { - class: \`ph-caret-up ph-bold ph-lg \${$style["date-1-icon"]}\` + class: \`ti ti-chevron-up \${$style["date-1-icon"]}\` }), getDateText(item.createdAt)]), h("span", { class: $style["date-2"] }, [getDateText(props.items[i + 1].createdAt), h("i", { - class: \`ph-caret-down ph-bold ph-lg \${$style["date-2-icon"]}\` + class: \`ti ti-chevron-down \${$style["date-2-icon"]}\` })])])); return [el, separator]; } else { diff --git a/packages/frontend/src/account.ts b/packages/frontend/src/account.ts index 90cc2e51c9..5a67c4e777 100644 --- a/packages/frontend/src/account.ts +++ b/packages/frontend/src/account.ts @@ -293,7 +293,7 @@ export async function openAccountMenu(opts: { avatar: $i, }, { type: 'divider' as const }, ...(opts.includeCurrentAccount ? [createItem($i)] : []), ...accountItemPromises, { type: 'parent' as const, - icon: 'ph-plus ph-bold ph-lg', + icon: 'ti ti-plus', text: i18n.ts.addAccount, children: [{ text: i18n.ts.existingAccount, @@ -304,7 +304,7 @@ export async function openAccountMenu(opts: { }], }, { type: 'link' as const, - icon: 'ph-users ph-bold ph-lg', + icon: 'ti ti-users', text: i18n.ts.manageAccounts, to: '/settings/accounts', }, { diff --git a/packages/frontend/src/components/MkAbuseReportWindow.vue b/packages/frontend/src/components/MkAbuseReportWindow.vue index f228df85a6..b09c7bb3fb 100644 --- a/packages/frontend/src/components/MkAbuseReportWindow.vue +++ b/packages/frontend/src/components/MkAbuseReportWindow.vue @@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only diff --git a/packages/frontend/src/pages/settings/accounts.vue b/packages/frontend/src/pages/settings/accounts.vue index f5effbd68b..1182346de9 100644 --- a/packages/frontend/src/pages/settings/accounts.vue +++ b/packages/frontend/src/pages/settings/accounts.vue @@ -8,8 +8,8 @@ SPDX-License-Identifier: AGPL-3.0-only
- {{ i18n.ts.addAccount }} - {{ i18n.ts.reloadAccountsList }} + {{ i18n.ts.addAccount }} + {{ i18n.ts.reloadAccountsList }}
@@ -48,11 +48,11 @@ const init = async () => { function menu(account, ev) { os.popupMenu([{ text: i18n.ts.switch, - icon: 'ph-arrows-left-right ph-bold ph-lg', + icon: 'ti ti-switch-horizontal', action: () => switchAccount(account), }, { text: i18n.ts.logout, - icon: 'ph-trash ph-bold ph-lg', + icon: 'ti ti-trash', danger: true, action: () => removeAccount(account), }], ev.currentTarget ?? ev.target); @@ -108,7 +108,7 @@ const headerTabs = computed(() => []); definePageMetadata(() => ({ title: i18n.ts.accounts, - icon: 'ph-users ph-bold ph-lg', + icon: 'ti ti-users', })); diff --git a/packages/frontend/src/pages/settings/api.vue b/packages/frontend/src/pages/settings/api.vue index f8f340d602..d9596b4e45 100644 --- a/packages/frontend/src/pages/settings/api.vue +++ b/packages/frontend/src/pages/settings/api.vue @@ -47,6 +47,6 @@ const headerTabs = computed(() => []); definePageMetadata(() => ({ title: 'API', - icon: 'ph-webhooks-logo ph-bold ph-lg', + icon: 'ti ti-api', })); diff --git a/packages/frontend/src/pages/settings/apps.vue b/packages/frontend/src/pages/settings/apps.vue index abdb5d1cdd..c58ea5d378 100644 --- a/packages/frontend/src/pages/settings/apps.vue +++ b/packages/frontend/src/pages/settings/apps.vue @@ -34,7 +34,7 @@ SPDX-License-Identifier: AGPL-3.0-only
- +
@@ -77,7 +77,7 @@ const headerTabs = computed(() => []); definePageMetadata(() => ({ title: i18n.ts.installedApps, - icon: 'ph-plug ph-bold ph-lg', + icon: 'ti ti-plug', })); diff --git a/packages/frontend/src/pages/settings/avatar-decoration.decoration.vue b/packages/frontend/src/pages/settings/avatar-decoration.decoration.vue index 1b731ff624..0767fa7864 100644 --- a/packages/frontend/src/pages/settings/avatar-decoration.decoration.vue +++ b/packages/frontend/src/pages/settings/avatar-decoration.decoration.vue @@ -10,7 +10,7 @@ SPDX-License-Identifier: AGPL-3.0-only >
{{ decoration.name }}
- + diff --git a/packages/frontend/src/pages/settings/avatar-decoration.dialog.vue b/packages/frontend/src/pages/settings/avatar-decoration.dialog.vue index 327e0ef723..ce1d4e48d8 100644 --- a/packages/frontend/src/pages/settings/avatar-decoration.dialog.vue +++ b/packages/frontend/src/pages/settings/avatar-decoration.dialog.vue @@ -36,9 +36,9 @@ SPDX-License-Identifier: AGPL-3.0-only
- {{ i18n.ts.update }} - {{ i18n.ts.detach }} - {{ i18n.ts.attach }} + {{ i18n.ts.update }} + {{ i18n.ts.detach }} + {{ i18n.ts.attach }}
diff --git a/packages/frontend/src/pages/settings/avatar-decoration.vue b/packages/frontend/src/pages/settings/avatar-decoration.vue index a60d7209cf..3cc911c014 100644 --- a/packages/frontend/src/pages/settings/avatar-decoration.vue +++ b/packages/frontend/src/pages/settings/avatar-decoration.vue @@ -130,7 +130,7 @@ const headerTabs = computed(() => []); definePageMetadata(() => ({ title: i18n.ts.avatarDecorations, - icon: 'ph-sparkle ph-bold ph-lg', + icon: 'ti ti-sparkles', })); diff --git a/packages/frontend/src/pages/settings/custom-css.vue b/packages/frontend/src/pages/settings/custom-css.vue index 59733e896f..cf05e75acc 100644 --- a/packages/frontend/src/pages/settings/custom-css.vue +++ b/packages/frontend/src/pages/settings/custom-css.vue @@ -47,6 +47,6 @@ const headerTabs = computed(() => []); definePageMetadata(() => ({ title: i18n.ts.customCss, - icon: 'ph-code ph-bold ph-lg', + icon: 'ti ti-code', })); diff --git a/packages/frontend/src/pages/settings/deck.vue b/packages/frontend/src/pages/settings/deck.vue index 81ae9bc2f7..e574ec7dc0 100644 --- a/packages/frontend/src/pages/settings/deck.vue +++ b/packages/frontend/src/pages/settings/deck.vue @@ -38,6 +38,6 @@ const headerTabs = computed(() => []); definePageMetadata(() => ({ title: i18n.ts.deck, - icon: 'ph-text-columns ph-bold ph-lg', + icon: 'ti ti-columns', })); diff --git a/packages/frontend/src/pages/settings/drive-cleaner.vue b/packages/frontend/src/pages/settings/drive-cleaner.vue index fef12fee06..0b0b932f46 100644 --- a/packages/frontend/src/pages/settings/drive-cleaner.vue +++ b/packages/frontend/src/pages/settings/drive-cleaner.vue @@ -119,7 +119,7 @@ function onContextMenu(ev: MouseEvent, file): void { definePageMetadata(() => ({ title: i18n.ts.drivecleaner, - icon: 'ph-trash ph-bold ph-lg', + icon: 'ti ti-trash', })); diff --git a/packages/frontend/src/pages/settings/drive.vue b/packages/frontend/src/pages/settings/drive.vue index 06de4163b6..bcaa048de2 100644 --- a/packages/frontend/src/pages/settings/drive.vue +++ b/packages/frontend/src/pages/settings/drive.vue @@ -35,7 +35,7 @@ SPDX-License-Identifier: AGPL-3.0-only {{ i18n.ts.uploadFolder }} - + {{ i18n.ts.drivecleaner }} @@ -144,7 +144,7 @@ const headerTabs = computed(() => []); definePageMetadata(() => ({ title: i18n.ts.drive, - icon: 'ph-cloud ph-bold ph-lg', + icon: 'ti ti-cloud', })); diff --git a/packages/frontend/src/pages/settings/email.vue b/packages/frontend/src/pages/settings/email.vue index 938abb0651..f226647569 100644 --- a/packages/frontend/src/pages/settings/email.vue +++ b/packages/frontend/src/pages/settings/email.vue @@ -8,9 +8,9 @@ SPDX-License-Identifier: AGPL-3.0-only - + - + @@ -115,6 +115,6 @@ const headerTabs = computed(() => []); definePageMetadata(() => ({ title: i18n.ts.email, - icon: 'ph-envelope ph-bold ph-lg', + icon: 'ti ti-mail', })); diff --git a/packages/frontend/src/pages/settings/emoji-picker.vue b/packages/frontend/src/pages/settings/emoji-picker.vue index e9936ca5f2..1df723c850 100644 --- a/packages/frontend/src/pages/settings/emoji-picker.vue +++ b/packages/frontend/src/pages/settings/emoji-picker.vue @@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only @@ -38,15 +38,15 @@ SPDX-License-Identifier: AGPL-3.0-only
- {{ i18n.ts.preview }} - {{ i18n.ts.default }} - {{ i18n.ts.overwriteFromPinnedEmojis }} + {{ i18n.ts.preview }} + {{ i18n.ts.default }} + {{ i18n.ts.overwriteFromPinnedEmojis }}
- + @@ -69,7 +69,7 @@ SPDX-License-Identifier: AGPL-3.0-only @@ -78,9 +78,9 @@ SPDX-License-Identifier: AGPL-3.0-only
- {{ i18n.ts.preview }} - {{ i18n.ts.default }} - {{ i18n.ts.overwriteFromPinnedEmojisForReaction }} + {{ i18n.ts.preview }} + {{ i18n.ts.default }} + {{ i18n.ts.overwriteFromPinnedEmojisForReaction }}
@@ -278,7 +278,7 @@ watch(pinnedEmojis, () => { definePageMetadata(() => ({ title: i18n.ts.emojiPicker, - icon: 'ph-smiley ph-bold ph-lg', + icon: 'ti ti-mood-happy', })); diff --git a/packages/frontend/src/pages/settings/general.vue b/packages/frontend/src/pages/settings/general.vue index eef69f694a..b48308b96f 100644 --- a/packages/frontend/src/pages/settings/general.vue +++ b/packages/frontend/src/pages/settings/general.vue @@ -27,9 +27,9 @@ SPDX-License-Identifier: AGPL-3.0-only - - - + + + @@ -40,7 +40,7 @@ SPDX-License-Identifier: AGPL-3.0-only {{ i18n.ts.add }} - {{ i18n.ts.remove }} + {{ i18n.ts.remove }} @@ -157,16 +157,16 @@ SPDX-License-Identifier: AGPL-3.0-only - - - - + + + + - - + + {{ i18n.ts._notification.checkNotificationBehavior }} @@ -303,13 +303,13 @@ SPDX-License-Identifier: AGPL-3.0-only
{{ i18n.ts.deck }} - {{ i18n.ts.customCss }} + {{ i18n.ts.customCss }} @@ -615,7 +615,7 @@ const headerTabs = computed(() => []); definePageMetadata(() => ({ title: i18n.ts.general, - icon: 'ph-faders ph-bold ph-lg', + icon: 'ti ti-adjustments', })); const useCustomSearchEngine = computed(() => !Object.keys(searchEngineMap).includes(searchEngine.value)); diff --git a/packages/frontend/src/pages/settings/import-export.vue b/packages/frontend/src/pages/settings/import-export.vue index 87bde70fc2..9c02b604c0 100644 --- a/packages/frontend/src/pages/settings/import-export.vue +++ b/packages/frontend/src/pages/settings/import-export.vue @@ -6,12 +6,12 @@ SPDX-License-Identifier: AGPL-3.0-only diff --git a/packages/frontend/src/pages/settings/navbar.vue b/packages/frontend/src/pages/settings/navbar.vue index ae5f081e1c..7f8460e316 100644 --- a/packages/frontend/src/pages/settings/navbar.vue +++ b/packages/frontend/src/pages/settings/navbar.vue @@ -21,18 +21,18 @@ SPDX-License-Identifier: AGPL-3.0-only v-if="element.type === '-' || navbarItemDef[element.type]" :class="$style.item" > - + {{ navbarItemDef[element.type]?.title ?? i18n.ts.divider }} - +
- {{ i18n.ts.addItem }} - {{ i18n.ts.default }} - {{ i18n.ts.save }} + {{ i18n.ts.addItem }} + {{ i18n.ts.default }} + {{ i18n.ts.save }}
@@ -120,7 +120,7 @@ const headerTabs = computed(() => []); definePageMetadata(() => ({ title: i18n.ts.navbar, - icon: 'ph-list ph-bold ph-lg', + icon: 'ti ti-list', })); diff --git a/packages/frontend/src/pages/settings/notifications.notification-config.vue b/packages/frontend/src/pages/settings/notifications.notification-config.vue index 8d78ce7031..1a945aa3ad 100644 --- a/packages/frontend/src/pages/settings/notifications.notification-config.vue +++ b/packages/frontend/src/pages/settings/notifications.notification-config.vue @@ -21,7 +21,7 @@ SPDX-License-Identifier: AGPL-3.0-only
- {{ i18n.ts.save }} + {{ i18n.ts.save }}
diff --git a/packages/frontend/src/pages/settings/notifications.vue b/packages/frontend/src/pages/settings/notifications.vue index 36fe7df03e..a861f6ee0d 100644 --- a/packages/frontend/src/pages/settings/notifications.vue +++ b/packages/frontend/src/pages/settings/notifications.vue @@ -133,6 +133,6 @@ const headerTabs = computed(() => []); definePageMetadata(() => ({ title: i18n.ts.notifications, - icon: 'ph-bell ph-bold ph-lg', + icon: 'ti ti-bell', })); diff --git a/packages/frontend/src/pages/settings/other.vue b/packages/frontend/src/pages/settings/other.vue index 683e5f0e30..86bbae431d 100644 --- a/packages/frontend/src/pages/settings/other.vue +++ b/packages/frontend/src/pages/settings/other.vue @@ -18,7 +18,7 @@ SPDX-License-Identifier: AGPL-3.0-only
- +
@@ -46,7 +46,7 @@ SPDX-License-Identifier: AGPL-3.0-only - +
@@ -58,7 +58,7 @@ SPDX-License-Identifier: AGPL-3.0-only - +
@@ -69,7 +69,7 @@ SPDX-License-Identifier: AGPL-3.0-only - +
@@ -82,7 +82,7 @@ SPDX-License-Identifier: AGPL-3.0-only - {{ i18n.ts.registry }} + {{ i18n.ts.registry }} @@ -189,6 +189,6 @@ const headerTabs = computed(() => []); definePageMetadata(() => ({ title: i18n.ts.other, - icon: 'ph-dots-three ph-bold ph-lg', + icon: 'ti ti-dots', })); diff --git a/packages/frontend/src/pages/settings/plugin.install.vue b/packages/frontend/src/pages/settings/plugin.install.vue index f3dd862bd1..3ab26e80d9 100644 --- a/packages/frontend/src/pages/settings/plugin.install.vue +++ b/packages/frontend/src/pages/settings/plugin.install.vue @@ -12,7 +12,7 @@ SPDX-License-Identifier: AGPL-3.0-only
- {{ i18n.ts.install }} + {{ i18n.ts.install }}
@@ -55,6 +55,6 @@ const headerTabs = computed(() => []); definePageMetadata(() => ({ title: i18n.ts._plugin.install, - icon: 'ph-download ph-bold ph-lg', + icon: 'ti ti-download', })); diff --git a/packages/frontend/src/pages/settings/plugin.vue b/packages/frontend/src/pages/settings/plugin.vue index 349015dd28..9804454e66 100644 --- a/packages/frontend/src/pages/settings/plugin.vue +++ b/packages/frontend/src/pages/settings/plugin.vue @@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only @@ -96,6 +96,6 @@ const headerTabs = computed(() => []); definePageMetadata(() => ({ title: i18n.ts.sounds, - icon: 'ph-music-notes ph-bold ph-lg', + icon: 'ti ti-music', })); diff --git a/packages/frontend/src/pages/settings/statusbar.vue b/packages/frontend/src/pages/settings/statusbar.vue index fa924d13f0..1ae3de7994 100644 --- a/packages/frontend/src/pages/settings/statusbar.vue +++ b/packages/frontend/src/pages/settings/statusbar.vue @@ -52,6 +52,6 @@ const headerTabs = computed(() => []); definePageMetadata(() => ({ title: i18n.ts.statusbar, - icon: 'ph-list ph-bold ph-lg', + icon: 'ti ti-list', })); diff --git a/packages/frontend/src/pages/settings/theme.install.vue b/packages/frontend/src/pages/settings/theme.install.vue index 01ae5286b7..4f05d3784c 100644 --- a/packages/frontend/src/pages/settings/theme.install.vue +++ b/packages/frontend/src/pages/settings/theme.install.vue @@ -10,8 +10,8 @@ SPDX-License-Identifier: AGPL-3.0-only
- {{ i18n.ts.preview }} - {{ i18n.ts.install }} + {{ i18n.ts.preview }} + {{ i18n.ts.install }}
@@ -61,6 +61,6 @@ const headerTabs = computed(() => []); definePageMetadata(() => ({ title: i18n.ts._theme.install, - icon: 'ph-download ph-bold ph-lg', + icon: 'ti ti-download', })); diff --git a/packages/frontend/src/pages/settings/theme.manage.vue b/packages/frontend/src/pages/settings/theme.manage.vue index 43d76951c0..8a94d7388b 100644 --- a/packages/frontend/src/pages/settings/theme.manage.vue +++ b/packages/frontend/src/pages/settings/theme.manage.vue @@ -25,7 +25,7 @@ SPDX-License-Identifier: AGPL-3.0-only - {{ i18n.ts.uninstall }} + {{ i18n.ts.uninstall }}
@@ -78,6 +78,6 @@ const headerTabs = computed(() => []); definePageMetadata(() => ({ title: i18n.ts._theme.manage, - icon: 'ph-wrench ph-bold ph-lg', + icon: 'ti ti-tool', })); diff --git a/packages/frontend/src/pages/settings/theme.vue b/packages/frontend/src/pages/settings/theme.vue index 9b493f5ffe..eaa9b5b97e 100644 --- a/packages/frontend/src/pages/settings/theme.vue +++ b/packages/frontend/src/pages/settings/theme.vue @@ -34,7 +34,7 @@ SPDX-License-Identifier: AGPL-3.0-only
- + @@ -45,7 +45,7 @@ SPDX-License-Identifier: AGPL-3.0-only - + @@ -58,10 +58,10 @@ SPDX-License-Identifier: AGPL-3.0-only
- {{ i18n.ts._theme.manage }} - {{ i18n.ts._theme.explore }} - {{ i18n.ts._theme.install }} - {{ i18n.ts._theme.make }} + {{ i18n.ts._theme.manage }} + {{ i18n.ts._theme.explore }} + {{ i18n.ts._theme.install }} + {{ i18n.ts._theme.make }}
@@ -179,7 +179,7 @@ const headerTabs = computed(() => []); definePageMetadata(() => ({ title: i18n.ts.theme, - icon: 'ph-palette ph-bold ph-lg', + icon: 'ti ti-palette', })); diff --git a/packages/frontend/src/pages/settings/webhook.edit.vue b/packages/frontend/src/pages/settings/webhook.edit.vue index 99326c8671..e9fb1e471e 100644 --- a/packages/frontend/src/pages/settings/webhook.edit.vue +++ b/packages/frontend/src/pages/settings/webhook.edit.vue @@ -14,7 +14,7 @@ SPDX-License-Identifier: AGPL-3.0-only - + @@ -35,8 +35,8 @@ SPDX-License-Identifier: AGPL-3.0-only {{ i18n.ts._webhookSettings.active }}
- {{ i18n.ts.save }} - {{ i18n.ts.delete }} + {{ i18n.ts.save }} + {{ i18n.ts.delete }}
@@ -116,6 +116,6 @@ const headerTabs = computed(() => []); definePageMetadata(() => ({ title: 'Edit webhook', - icon: 'ph-webhooks-logo ph-bold ph-lg', + icon: 'ti ti-webhook', })); diff --git a/packages/frontend/src/pages/settings/webhook.new.vue b/packages/frontend/src/pages/settings/webhook.new.vue index 299386338a..5bf85e48f4 100644 --- a/packages/frontend/src/pages/settings/webhook.new.vue +++ b/packages/frontend/src/pages/settings/webhook.new.vue @@ -14,7 +14,7 @@ SPDX-License-Identifier: AGPL-3.0-only - + @@ -33,7 +33,7 @@ SPDX-License-Identifier: AGPL-3.0-only
- {{ i18n.ts.create }} + {{ i18n.ts.create }}
@@ -84,6 +84,6 @@ const headerTabs = computed(() => []); definePageMetadata(() => ({ title: 'Create new webhook', - icon: 'ph-webhooks-logo ph-bold ph-lg', + icon: 'ti ti-webhook', })); diff --git a/packages/frontend/src/pages/settings/webhook.vue b/packages/frontend/src/pages/settings/webhook.vue index 3717abb13e..0d11b00c97 100644 --- a/packages/frontend/src/pages/settings/webhook.vue +++ b/packages/frontend/src/pages/settings/webhook.vue @@ -15,10 +15,10 @@ SPDX-License-Identifier: AGPL-3.0-only
{{ webhook.name || webhook.url }}