diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index cec462955..031692795 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -1239,6 +1239,7 @@ admin/views/instance.vue: disable-global-timeline: "グローバルタイムラインを無効にする" disabling-timelines-info: "これらのタイムラインを無効にしても、管理者およびモデレーターは引き続き利用できます。" enable-emoji-reaction: "リアクションに絵文字を使えるようにする" + use-star-for-reaction-fallback: "不明なリアクションのフォールバックに star を使う" invite: "招待" save: "保存" saved: "保存しました" diff --git a/src/client/app/admin/views/instance.vue b/src/client/app/admin/views/instance.vue index ab337f187..2d2a07784 100644 --- a/src/client/app/admin/views/instance.vue +++ b/src/client/app/admin/views/instance.vue @@ -26,6 +26,7 @@ {{ $t('disable-global-timeline') }} {{ $t('disabling-timelines-info') }} {{ $t('enable-emoji-reaction') }} + {{ $t('use-star-for-reaction-fallback') }}
{{ $t('drive-config') }}
@@ -157,6 +158,7 @@ export default Vue.extend({ disableLocalTimeline: false, disableGlobalTimeline: false, enableEmojiReaction: true, + useStarForReactionFallback: false, mascotImageUrl: null, bannerUrl: null, errorImageUrl: null, @@ -209,6 +211,7 @@ export default Vue.extend({ this.disableLocalTimeline = meta.disableLocalTimeline; this.disableGlobalTimeline = meta.disableGlobalTimeline; this.enableEmojiReaction = meta.enableEmojiReaction; + this.useStarForReactionFallback = meta.useStarForReactionFallback; this.mascotImageUrl = meta.mascotImageUrl; this.bannerUrl = meta.bannerUrl; this.errorImageUrl = meta.errorImageUrl; @@ -271,6 +274,7 @@ export default Vue.extend({ disableLocalTimeline: this.disableLocalTimeline, disableGlobalTimeline: this.disableGlobalTimeline, enableEmojiReaction: this.enableEmojiReaction, + useStarForReactionFallback: this.useStarForReactionFallback, mascotImageUrl: this.mascotImageUrl, bannerUrl: this.bannerUrl, errorImageUrl: this.errorImageUrl, diff --git a/src/client/app/common/views/components/reaction-icon.vue b/src/client/app/common/views/components/reaction-icon.vue index 199166950..022d57dc4 100644 --- a/src/client/app/common/views/components/reaction-icon.vue +++ b/src/client/app/common/views/components/reaction-icon.vue @@ -31,6 +31,7 @@ export default Vue.extend({ case 'confused': return '😥'; case 'rip': return '😇'; case 'pudding': return (this.$store.getters.isSignedIn && this.$store.state.settings.iLikeSushi) ? '🍣' : '🍮'; + case 'star': return '⭐'; default: return this.reaction; } }, diff --git a/src/misc/get-reaction-emoji.ts b/src/misc/get-reaction-emoji.ts index 9d6956c4a..c2e0b9858 100644 --- a/src/misc/get-reaction-emoji.ts +++ b/src/misc/get-reaction-emoji.ts @@ -10,6 +10,7 @@ export default function(reaction: string): string { case 'confused': return '😥'; case 'rip': return '😇'; case 'pudding': return '🍮'; - default: return ''; + case 'star': return '⭐'; + default: return reaction; } } diff --git a/src/misc/reaction-lib.ts b/src/misc/reaction-lib.ts index c81e35b37..a27fb883b 100644 --- a/src/misc/reaction-lib.ts +++ b/src/misc/reaction-lib.ts @@ -1,5 +1,6 @@ import Emoji from '../models/emoji'; import { emojiRegex } from './emoji-regex'; +import fetchMeta from './fetch-meta'; const basic10: Record = { '👍': 'like', @@ -15,7 +16,8 @@ const basic10: Record = { }; export async function getFallbackReaction(): Promise { - return 'like'; + const meta = await fetchMeta(); + return meta.useStarForReactionFallback ? 'star' : 'like'; } export async function toDbReaction(reaction: string, enableEmoji = true): Promise { diff --git a/src/models/meta.ts b/src/models/meta.ts index bea4714bf..5ca0f0123 100644 --- a/src/models/meta.ts +++ b/src/models/meta.ts @@ -195,6 +195,7 @@ export type IMeta = { disableLocalTimeline?: boolean; disableGlobalTimeline?: boolean; enableEmojiReaction?: boolean; + useStarForReactionFallback?: boolean; hidedTags?: string[]; mascotImageUrl?: string; bannerUrl?: string; diff --git a/src/models/note-reaction.ts b/src/models/note-reaction.ts index 1152161ea..dc741614a 100644 --- a/src/models/note-reaction.ts +++ b/src/models/note-reaction.ts @@ -20,19 +20,6 @@ export interface INoteReaction { reaction: string; } -export const validateReaction = $.str.or([ - 'like', - 'love', - 'laugh', - 'hmm', - 'surprise', - 'congrats', - 'angry', - 'confused', - 'rip', - 'pudding' -]); - /** * Pack a reaction for API response */ diff --git a/src/server/api/endpoints/admin/update-meta.ts b/src/server/api/endpoints/admin/update-meta.ts index 9afe90295..f8f7cb5d9 100644 --- a/src/server/api/endpoints/admin/update-meta.ts +++ b/src/server/api/endpoints/admin/update-meta.ts @@ -48,6 +48,13 @@ export const meta = { } }, + useStarForReactionFallback: { + validator: $.optional.nullable.bool, + desc: { + 'ja-JP': '不明なリアクションのフォールバックに star リアクションを使うか' + } + }, + hidedTags: { validator: $.optional.nullable.arr($.str), desc: { @@ -362,6 +369,10 @@ export default define(meta, async (ps) => { set.enableEmojiReaction = ps.enableEmojiReaction; } + if (typeof ps.useStarForReactionFallback === 'boolean') { + set.useStarForReactionFallback = ps.useStarForReactionFallback; + } + if (Array.isArray(ps.hidedTags)) { set.hidedTags = ps.hidedTags; } diff --git a/src/server/api/endpoints/meta.ts b/src/server/api/endpoints/meta.ts index 1759a3c2f..7b04f5089 100644 --- a/src/server/api/endpoints/meta.ts +++ b/src/server/api/endpoints/meta.ts @@ -152,6 +152,7 @@ export default define(meta, async (ps, me) => { } if (me && (me.isAdmin || me.isModerator)) { + response.useStarForReactionFallback = instance.useStarForReactionFallback; response.hidedTags = instance.hidedTags; response.recaptchaSecretKey = instance.recaptchaSecretKey; response.proxyAccount = instance.proxyAccount; diff --git a/src/server/api/openapi/schemas.ts b/src/server/api/openapi/schemas.ts index 7b9dc35f2..70a0d6faf 100644 --- a/src/server/api/openapi/schemas.ts +++ b/src/server/api/openapi/schemas.ts @@ -392,7 +392,8 @@ export const schemas = { 'angry', 'confused', 'rip', - 'pudding' + 'pudding', + 'star' ], description: 'The reaction type.' },