diff --git a/locales/en-US.yml b/locales/en-US.yml index 7b275c990c..8aad5b2921 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -121,6 +121,7 @@ inChannelQuote: "Channel-only Quote" renoteToChannel: "Renote to channel" renoteToOtherChannel: "Renote to other channel" pinnedNote: "Pinned note" +pinnedOnly: "Pinned" pinned: "Pin to profile" you: "You" clickToShow: "Click to show" @@ -1268,7 +1269,8 @@ alwaysConfirmFollow: "Always confirm when following" inquiry: "Contact" tryAgain: "Please try again later" confirmWhenRevealingSensitiveMedia: "Confirm when revealing sensitive media" -sensitiveMediaRevealConfirm: "This might be a sensitive media. Are you sure to reveal?" +sensitiveMediaRevealConfirm: "This media might be sensitive. Are you sure you want to reveal it?" +warnExternalUrl: "Show warning when opening external URLs" createdLists: "Created lists" createdAntennas: "Created antennas" fromX: "From {x}" diff --git a/locales/index.d.ts b/locales/index.d.ts index 6b6879cac5..82dfce0d1a 100644 --- a/locales/index.d.ts +++ b/locales/index.d.ts @@ -502,6 +502,10 @@ export interface Locale extends ILocale { * ピン留めされたノート */ "pinnedNote": string; + /** + * Pinned + */ + "pinnedOnly": string; /** * ピン留め */ @@ -5103,6 +5107,10 @@ export interface Locale extends ILocale { * This media might be sensitive. Are you sure you want to reveal it? */ "sensitiveMediaRevealConfirm": string; + /** + * 外部URLを開く際に警告を表示する + */ + "warnExternalUrl": string; /** * 作成したリスト */ diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 678bc7e66b..437586c070 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -121,6 +121,7 @@ inChannelQuote: "チャンネル内引用" renoteToChannel: "チャンネルにリノート" renoteToOtherChannel: "他のチャンネルにリノート" pinnedNote: "ピン留めされたノート" +pinnedOnly: "Pinned" pinned: "ピン留め" you: "あなた" clickToShow: "クリックして表示" @@ -1271,6 +1272,7 @@ inquiry: "お問い合わせ" tryAgain: "もう一度お試しください。" confirmWhenRevealingSensitiveMedia: "センシティブなメディアを表示するとき確認する" sensitiveMediaRevealConfirm: "センシティブなメディアです。表示しますか?" +warnExternalUrl: "外部URLを開く際に警告を表示する" createdLists: "作成したリスト" createdAntennas: "作成したアンテナ" fromX: "{x}から" diff --git a/packages/backend/src/queue/QueueProcessorService.ts b/packages/backend/src/queue/QueueProcessorService.ts index 6841f6ec28..eaeb6d58df 100644 --- a/packages/backend/src/queue/QueueProcessorService.ts +++ b/packages/backend/src/queue/QueueProcessorService.ts @@ -128,20 +128,30 @@ export class QueueProcessorService implements OnApplicationShutdown { ) { this.logger = this.queueLoggerService.logger; - function renderError(e: Error): any { - if (e) { // 何故かeがundefinedで来ることがある - return { - stack: e.stack, - message: e.message, - name: e.name, - }; - } else { - return { - stack: '?', - message: '?', - name: '?', - }; + function renderError(e?: Error) { + // 何故かeがundefinedで来ることがある + if (!e) return '?'; + + if (e instanceof Bull.UnrecoverableError || e.name === 'AbortError') { + return `${e.name}: ${e.message}`; } + + return { + stack: e.stack, + message: e.message, + name: e.name, + }; + } + + function renderJob(job?: Bull.Job) { + if (!job) return '?'; + + return { + name: job.name || undefined, + info: getJobInfo(job), + failedReason: job.failedReason || undefined, + data: job.data, + }; } //#region system @@ -176,15 +186,15 @@ export class QueueProcessorService implements OnApplicationShutdown { .on('active', (job) => logger.debug(`active id=${job.id}`)) .on('completed', (job, result) => logger.debug(`completed(${result}) id=${job.id}`)) .on('failed', (job, err: Error) => { - logger.error(`failed(${err.stack}) id=${job ? job.id : '-'}`, { job, e: renderError(err) }); + logger.error(`failed(${err.name}: ${err.message}) id=${job?.id ?? '?'}`, { job: renderJob(job), e: renderError(err) }); if (config.sentryForBackend) { - Sentry.captureMessage(`Queue: System: ${job?.name ?? '?'}: ${err.message}`, { + Sentry.captureMessage(`Queue: System: ${job?.name ?? '?'}: ${err.name}: ${err.message}`, { level: 'error', extra: { job, err }, }); } }) - .on('error', (err: Error) => logger.error(`error ${err.stack}`, { e: renderError(err) })) + .on('error', (err: Error) => logger.error(`error ${err.name}: ${err.message}`, { e: renderError(err) })) .on('stalled', (jobId) => logger.warn(`stalled id=${jobId}`)); } //#endregion @@ -241,15 +251,15 @@ export class QueueProcessorService implements OnApplicationShutdown { .on('active', (job) => logger.debug(`active id=${job.id}`)) .on('completed', (job, result) => logger.debug(`completed(${result}) id=${job.id}`)) .on('failed', (job, err) => { - logger.error(`failed(${err.stack}) id=${job ? job.id : '-'}`, { job, e: renderError(err) }); + logger.error(`failed(${err.name}: ${err.message}) id=${job?.id ?? '?'}`, { job: renderJob(job), e: renderError(err) }); if (config.sentryForBackend) { - Sentry.captureMessage(`Queue: DB: ${job?.name ?? '?'}: ${err.message}`, { + Sentry.captureMessage(`Queue: DB: ${job?.name ?? '?'}: ${err.name}: ${err.message}`, { level: 'error', extra: { job, err }, }); } }) - .on('error', (err: Error) => logger.error(`error ${err.stack}`, { e: renderError(err) })) + .on('error', (err: Error) => logger.error(`error ${err.name}: ${err.message}`, { e: renderError(err) })) .on('stalled', (jobId) => logger.warn(`stalled id=${jobId}`)); } //#endregion @@ -281,15 +291,15 @@ export class QueueProcessorService implements OnApplicationShutdown { .on('active', (job) => logger.debug(`active ${getJobInfo(job, true)} to=${job.data.to}`)) .on('completed', (job, result) => logger.debug(`completed(${result}) ${getJobInfo(job, true)} to=${job.data.to}`)) .on('failed', (job, err) => { - logger.error(`failed(${err.stack}) ${getJobInfo(job)} to=${job ? job.data.to : '-'}`); + logger.error(`failed(${err.name}: ${err.message}) ${getJobInfo(job)} to=${job ? job.data.to : '-'}`); if (config.sentryForBackend) { - Sentry.captureMessage(`Queue: Deliver: ${err.message}`, { + Sentry.captureMessage(`Queue: Deliver: ${err.name}: ${err.message}`, { level: 'error', extra: { job, err }, }); } }) - .on('error', (err: Error) => logger.error(`error ${err.stack}`, { e: renderError(err) })) + .on('error', (err: Error) => logger.error(`error ${err.name}: ${err.message}`, { e: renderError(err) })) .on('stalled', (jobId) => logger.warn(`stalled id=${jobId}`)); } //#endregion @@ -321,15 +331,15 @@ export class QueueProcessorService implements OnApplicationShutdown { .on('active', (job) => logger.debug(`active ${getJobInfo(job, true)}`)) .on('completed', (job, result) => logger.debug(`completed(${result}) ${getJobInfo(job, true)}`)) .on('failed', (job, err) => { - logger.error(`failed(${err.stack}) ${getJobInfo(job)} activity=${job ? (job.data.activity ? job.data.activity.id : 'none') : '-'}`, { job, e: renderError(err) }); + logger.error(`failed(${err.name}: ${err.message}) ${getJobInfo(job)} activity=${job ? (job.data.activity ? job.data.activity.id : 'none') : '-'}`, { job: renderJob(job), e: renderError(err) }); if (config.sentryForBackend) { - Sentry.captureMessage(`Queue: Inbox: ${err.message}`, { + Sentry.captureMessage(`Queue: Inbox: ${err.name}: ${err.message}`, { level: 'error', extra: { job, err }, }); } }) - .on('error', (err: Error) => logger.error(`error ${err.stack}`, { e: renderError(err) })) + .on('error', (err: Error) => logger.error(`error ${err.name}: ${err.message}`, { e: renderError(err) })) .on('stalled', (jobId) => logger.warn(`stalled id=${jobId}`)); } //#endregion @@ -361,15 +371,15 @@ export class QueueProcessorService implements OnApplicationShutdown { .on('active', (job) => logger.debug(`active ${getJobInfo(job, true)} to=${job.data.to}`)) .on('completed', (job, result) => logger.debug(`completed(${result}) ${getJobInfo(job, true)} to=${job.data.to}`)) .on('failed', (job, err) => { - logger.error(`failed(${err.stack}) ${getJobInfo(job)} to=${job ? job.data.to : '-'}`); + logger.error(`failed(${err.name}: ${err.message}) ${getJobInfo(job)} to=${job ? job.data.to : '-'}`); if (config.sentryForBackend) { - Sentry.captureMessage(`Queue: UserWebhookDeliver: ${err.message}`, { + Sentry.captureMessage(`Queue: UserWebhookDeliver: ${err.name}: ${err.message}`, { level: 'error', extra: { job, err }, }); } }) - .on('error', (err: Error) => logger.error(`error ${err.stack}`, { e: renderError(err) })) + .on('error', (err: Error) => logger.error(`error ${err.name}: ${err.message}`, { e: renderError(err) })) .on('stalled', (jobId) => logger.warn(`stalled id=${jobId}`)); } //#endregion @@ -401,15 +411,15 @@ export class QueueProcessorService implements OnApplicationShutdown { .on('active', (job) => logger.debug(`active ${getJobInfo(job, true)} to=${job.data.to}`)) .on('completed', (job, result) => logger.debug(`completed(${result}) ${getJobInfo(job, true)} to=${job.data.to}`)) .on('failed', (job, err) => { - logger.error(`failed(${err.stack}) ${getJobInfo(job)} to=${job ? job.data.to : '-'}`); + logger.error(`failed(${err.name}: ${err.message}) ${getJobInfo(job)} to=${job ? job.data.to : '-'}`); if (config.sentryForBackend) { - Sentry.captureMessage(`Queue: SystemWebhookDeliver: ${err.message}`, { + Sentry.captureMessage(`Queue: SystemWebhookDeliver: ${err.name}: ${err.message}`, { level: 'error', extra: { job, err }, }); } }) - .on('error', (err: Error) => logger.error(`error ${err.stack}`, { e: renderError(err) })) + .on('error', (err: Error) => logger.error(`error ${err.name}: ${err.message}`, { e: renderError(err) })) .on('stalled', (jobId) => logger.warn(`stalled id=${jobId}`)); } //#endregion @@ -448,15 +458,15 @@ export class QueueProcessorService implements OnApplicationShutdown { .on('active', (job) => logger.debug(`active id=${job.id}`)) .on('completed', (job, result) => logger.debug(`completed(${result}) id=${job.id}`)) .on('failed', (job, err) => { - logger.error(`failed(${err.stack}) id=${job ? job.id : '-'}`, { job, e: renderError(err) }); + logger.error(`failed(${err.name}: ${err.message}) id=${job?.id ?? '?'}`, { job: renderJob(job), e: renderError(err) }); if (config.sentryForBackend) { - Sentry.captureMessage(`Queue: Relationship: ${job?.name ?? '?'}: ${err.message}`, { + Sentry.captureMessage(`Queue: Relationship: ${job?.name ?? '?'}: ${err.name}: ${err.message}`, { level: 'error', extra: { job, err }, }); } }) - .on('error', (err: Error) => logger.error(`error ${err.stack}`, { e: renderError(err) })) + .on('error', (err: Error) => logger.error(`error ${err.name}: ${err.message}`, { e: renderError(err) })) .on('stalled', (jobId) => logger.warn(`stalled id=${jobId}`)); } //#endregion @@ -489,15 +499,15 @@ export class QueueProcessorService implements OnApplicationShutdown { .on('active', (job) => logger.debug(`active id=${job.id}`)) .on('completed', (job, result) => logger.debug(`completed(${result}) id=${job.id}`)) .on('failed', (job, err) => { - logger.error(`failed(${err.stack}) id=${job ? job.id : '-'}`, { job, e: renderError(err) }); + logger.error(`failed(${err.name}: ${err.message}) id=${job?.id ?? '?'}`, { job: renderJob(job), e: renderError(err) }); if (config.sentryForBackend) { - Sentry.captureMessage(`Queue: ObjectStorage: ${job?.name ?? '?'}: ${err.message}`, { + Sentry.captureMessage(`Queue: ObjectStorage: ${job?.name ?? '?'}: ${err.name}: ${err.message}`, { level: 'error', extra: { job, err }, }); } }) - .on('error', (err: Error) => logger.error(`error ${err.stack}`, { e: renderError(err) })) + .on('error', (err: Error) => logger.error(`error ${err.name}: ${err.message}`, { e: renderError(err) })) .on('stalled', (jobId) => logger.warn(`stalled id=${jobId}`)); } //#endregion diff --git a/packages/frontend/src/components/MkEmojiPicker.vue b/packages/frontend/src/components/MkEmojiPicker.vue index 7ef6efa939..949ed4db91 100644 --- a/packages/frontend/src/components/MkEmojiPicker.vue +++ b/packages/frontend/src/components/MkEmojiPicker.vue @@ -233,7 +233,7 @@ watch(q, () => { // 名前にキーワードが含まれている for (const emoji of emojis) { - if (keywords.every(keyword => emoji.name.includes(keyword))) { + if (keywords.every(keyword => emoji.name.toLowerCase().includes(keyword))) { matches.add(emoji); if (matches.size >= max) break; } @@ -242,7 +242,7 @@ watch(q, () => { // 名前またはエイリアスにキーワードが含まれている for (const emoji of emojis) { - if (keywords.every(keyword => emoji.name.includes(keyword) || emoji.aliases.some(alias => alias.includes(keyword)))) { + if (keywords.every(keyword => emoji.name.toLowerCase().includes(keyword) || emoji.aliases.some(alias => alias.toLowerCase().includes(keyword)))) { matches.add(emoji); if (matches.size >= max) break; } @@ -254,7 +254,7 @@ watch(q, () => { if (matches.size >= max) return matches; for (const emoji of emojis) { - if (emoji.aliases.some(alias => alias === newQ)) { + if (emoji.aliases.some(alias => alias.toLowerCase() === newQ)) { matches.add(emoji); if (matches.size >= max) break; } @@ -262,7 +262,7 @@ watch(q, () => { if (matches.size >= max) return matches; for (const emoji of emojis) { - if (emoji.name.startsWith(newQ)) { + if (emoji.name.toLowerCase().startsWith(newQ)) { matches.add(emoji); if (matches.size >= max) break; } @@ -270,7 +270,7 @@ watch(q, () => { if (matches.size >= max) return matches; for (const emoji of emojis) { - if (emoji.aliases.some(alias => alias.startsWith(newQ))) { + if (emoji.aliases.some(alias => alias.toLowerCase().startsWith(newQ))) { matches.add(emoji); if (matches.size >= max) break; } @@ -278,7 +278,7 @@ watch(q, () => { if (matches.size >= max) return matches; for (const emoji of emojis) { - if (emoji.name.includes(newQ)) { + if (emoji.name.toLowerCase().includes(newQ)) { matches.add(emoji); if (matches.size >= max) break; } @@ -286,7 +286,7 @@ watch(q, () => { if (matches.size >= max) return matches; for (const emoji of emojis) { - if (emoji.aliases.some(alias => alias.includes(newQ))) { + if (emoji.aliases.some(alias => alias.toLowerCase().includes(newQ))) { matches.add(emoji); if (matches.size >= max) break; } diff --git a/packages/frontend/src/pages/settings/general.vue b/packages/frontend/src/pages/settings/general.vue index 9b6cbc51ca..dbf174c458 100644 --- a/packages/frontend/src/pages/settings/general.vue +++ b/packages/frontend/src/pages/settings/general.vue @@ -238,11 +238,11 @@ SPDX-License-Identifier: AGPL-3.0-only {{ i18n.ts.enableInfiniteScroll }} {{ i18n.ts.keepScreenOn }} {{ i18n.ts.clickToOpen }} - {{ i18n.ts.showBots }} {{ i18n.ts.disableStreamingTimeline }} {{ i18n.ts.enableHorizontalSwipe }} {{ i18n.ts.alwaysConfirmFollow }} {{ i18n.ts.confirmWhenRevealingSensitiveMedia }} + {{ i18n.ts.warnExternalUrl }} @@ -380,14 +380,6 @@ const limitWidthOfReaction = computed(defaultStore.makeGetterSetter('limitWidthO const collapseRenotes = computed(defaultStore.makeGetterSetter('collapseRenotes')); const collapseNotesRepliedTo = computed(defaultStore.makeGetterSetter('collapseNotesRepliedTo')); const clickToOpen = computed(defaultStore.makeGetterSetter('clickToOpen')); -// copied from src/pages/timeline.vue -const showBots = computed({ - get: () => defaultStore.reactiveState.tl.value.filter.withBots, - set: (newValue) => { - const out = deepMerge({ filter: { withBots: newValue } }, defaultStore.state.tl); - defaultStore.set('tl', out); - }, -}); const collapseFiles = computed(defaultStore.makeGetterSetter('collapseFiles')); const autoloadConversation = computed(defaultStore.makeGetterSetter('autoloadConversation')); const reduceAnimation = computed(defaultStore.makeGetterSetter('animation', v => !v, v => !v)); @@ -440,6 +432,7 @@ const useNativeUIForVideoAudioPlayer = computed(defaultStore.makeGetterSetter('u const alwaysConfirmFollow = computed(defaultStore.makeGetterSetter('alwaysConfirmFollow')); const confirmWhenRevealingSensitiveMedia = computed(defaultStore.makeGetterSetter('confirmWhenRevealingSensitiveMedia')); const contextMenu = computed(defaultStore.makeGetterSetter('contextMenu')); +const warnExternalUrl = computed(defaultStore.makeGetterSetter('warnExternalUrl')); watch(lang, () => { miLocalStorage.setItem('lang', lang.value as string); @@ -501,6 +494,7 @@ watch([ alwaysConfirmFollow, confirmWhenRevealingSensitiveMedia, contextMenu, + warnExternalUrl, ], async () => { await reloadAsk({ reason: i18n.ts.reloadToApplySetting, unison: true }); }); diff --git a/packages/frontend/src/pages/timeline.vue b/packages/frontend/src/pages/timeline.vue index 24a99f4c1c..60974da971 100644 --- a/packages/frontend/src/pages/timeline.vue +++ b/packages/frontend/src/pages/timeline.vue @@ -17,7 +17,7 @@ SPDX-License-Identifier: AGPL-3.0-only
{ type: 'switch', text: i18n.ts.showRenotes, ref: withRenotes, + }, { + type: 'switch', + text: i18n.ts.showBots, + ref: withBots, }); if (isBasicTimeline(src.value) && hasWithReplies(src.value)) { diff --git a/packages/frontend/src/pages/user/home.vue b/packages/frontend/src/pages/user/home.vue index a403dc9e34..50b3bf3451 100644 --- a/packages/frontend/src/pages/user/home.vue +++ b/packages/frontend/src/pages/user/home.vue @@ -130,10 +130,7 @@ SPDX-License-Identifier: AGPL-3.0-only
-
- -
- {{ i18n.ts.userPagePinTip }} + {{ i18n.ts.userPagePinTip }}