From 872ea8adb0b7a77e0caa62b408f5d1d5e92064b3 Mon Sep 17 00:00:00 2001 From: Lhcfl Date: Wed, 20 Mar 2024 01:08:14 +0800 Subject: [PATCH] feat: Automatically detect and warn to correct the language of post --- locales/en-US.yml | 2 ++ locales/zh-CN.yml | 2 ++ packages/client/src/components/MkPostForm.vue | 31 +++++++++++++++++++ packages/client/src/i18n.ts | 2 +- .../client/src/pages/settings/general.vue | 6 ++++ .../pages/settings/preferences-backups.vue | 1 + packages/client/src/store.ts | 4 +++ 7 files changed, 47 insertions(+), 1 deletion(-) diff --git a/locales/en-US.yml b/locales/en-US.yml index f5b597e3c9..7a7d911e27 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -2227,3 +2227,5 @@ moreUrlsDescription: "Enter the pages you want to pin to the help menu in the lo left corner using this notation:\n\"Display name\": https://example.com/" messagingUnencryptedInfo: "Chats on Firefish are not end-to-end encrypted. Don't share any sensitive infomation over Firefish." +autocorrectNoteLanguage: Automatically detect and warn to correct the language of your post. +incorrectLanguageWarning: "It looks like your post is in {detected}, but the language you selected is {current}.\nWould you like to post in {detected} instead?" diff --git a/locales/zh-CN.yml b/locales/zh-CN.yml index 085fbeb435..23ad51206c 100644 --- a/locales/zh-CN.yml +++ b/locales/zh-CN.yml @@ -2056,3 +2056,5 @@ searchRangeDescription: "如果您要过滤时间段,请按以下格式输入 messagingUnencryptedInfo: "Firefish 上的聊天没有经过端到端加密,请不要在聊天中分享您的敏感信息。" noAltTextWarning: 有些附件没有描述。您是否忘记写描述了? showNoAltTextWarning: 当您尝试发布没有描述的帖子附件时显示警告 +autocorrectNoteLanguage: 自动检测和弹窗纠正您所使用的帖子语言 +incorrectLanguageWarning: "看上去您帖子使用的语言是{detected},但您选择的语言是{current}。\n要改为以{detected}发帖吗?" diff --git a/packages/client/src/components/MkPostForm.vue b/packages/client/src/components/MkPostForm.vue index d3f0a1ee7e..0d0710bb3e 100644 --- a/packages/client/src/components/MkPostForm.vue +++ b/packages/client/src/components/MkPostForm.vue @@ -1020,6 +1020,37 @@ function deleteDraft() { } async function post() { + // For text that is too short, the false positive rate may be too high, so we don't show alarm. + if (defaultStore.state.autocorrectNoteLanguage && text.value.length > 10) { + const detectedLanguage: string = detectLanguage(text.value) ?? ""; + + const currentLanguageName : string | undefined | false = + language.value && + langmap[language.value]?.nativeName + const detectedLanguageName : string | undefined | false = + detectedLanguage !== "" && + detectedLanguage !== language.value && + langmap[detectedLanguage]?.nativeName; + + if (currentLanguageName && detectedLanguageName) { + // "canceled" means "post with detected language". + const { canceled } = await os.confirm({ + type: "warning", + text: i18n.t("incorrectLanguageWarning", { + detected: `${detectedLanguageName}`, + current: `${currentLanguageName}`, + }), + okText: i18n.ts.no, + cancelText: i18n.ts.yes, + isPlaintext: true, + }); + + if (canceled) { + language.value = detectedLanguage; + } + } + } + if ( defaultStore.state.showNoAltTextWarning && files.value.some((f) => f.comment == null || f.comment.length === 0) diff --git a/packages/client/src/i18n.ts b/packages/client/src/i18n.ts index 1b3fdc855d..6d352ba03e 100644 --- a/packages/client/src/i18n.ts +++ b/packages/client/src/i18n.ts @@ -22,7 +22,7 @@ class I18n> { if (args) { for (const [k, v] of Object.entries(args)) { - str = str.replace(`{${k}}`, v.toString()); + str = str.replaceAll(`{${k}}`, v.toString()); } } return str; diff --git a/packages/client/src/pages/settings/general.vue b/packages/client/src/pages/settings/general.vue index 2a7190bd6d..15e1172169 100644 --- a/packages/client/src/pages/settings/general.vue +++ b/packages/client/src/pages/settings/general.vue @@ -124,6 +124,9 @@ {{ i18n.ts.showNoAltTextWarning }} + {{ + i18n.ts.autocorrectNoteLanguage + }} @@ -530,6 +533,9 @@ const pullToRefreshThreshold = computed( const showNoAltTextWarning = computed( defaultStore.makeGetterSetter("showNoAltTextWarning"), ); +const autocorrectNoteLanguage = computed( + defaultStore.makeGetterSetter("autocorrectNoteLanguage"), +); // This feature (along with injectPromo) is currently disabled // function onChangeInjectFeaturedNote(v) { diff --git a/packages/client/src/pages/settings/preferences-backups.vue b/packages/client/src/pages/settings/preferences-backups.vue index 41e7dc0ad1..cd55895b48 100644 --- a/packages/client/src/pages/settings/preferences-backups.vue +++ b/packages/client/src/pages/settings/preferences-backups.vue @@ -125,6 +125,7 @@ const defaultStoreSaveKeys: (keyof (typeof defaultStore)["state"])[] = [ "enablePullToRefresh", "pullToRefreshThreshold", "showNoAltTextWarning", + "autocorrectNoteLanguage", ]; const coldDeviceStorageSaveKeys: (keyof typeof ColdDeviceStorage.default)[] = [ "lightTheme", diff --git a/packages/client/src/store.ts b/packages/client/src/store.ts index 6e7e4b8570..877ebc3e10 100644 --- a/packages/client/src/store.ts +++ b/packages/client/src/store.ts @@ -432,6 +432,10 @@ export const defaultStore = markRaw( where: "account", default: true, }, + autocorrectNoteLanguage: { + where: "account", + default: true, + } }), );