1
0
Fork 0
mirror of https://github.com/paricafe/misskey.git synced 2025-03-24 12:09:32 -05:00

add translate foreign language in MkNote

This commit is contained in:
fly_mc 2024-10-17 23:19:17 +08:00
parent 5d5cc0f9d7
commit e484545d5e
5 changed files with 56 additions and 0 deletions
packages

View file

@ -25,6 +25,13 @@ const externalPackages = [
: id;
},
},
{
name: 'tinyld',
match: /^tinyld$/,
path(): string {
return `https://cdn.jsdelivr.net/npm/tinyld@${packageInfo.dependencies.tinyld}/dist/tinyld.normal.node.mjs`
},
},
];
const hash = (str: string, seed = 0): number => {

View file

@ -67,6 +67,7 @@
"three": "0.169.0",
"throttle-debounce": "5.0.2",
"tinycolor2": "1.6.0",
"tinyld": "^1.3.4",
"tsc-alias": "1.8.10",
"tsconfig-paths": "4.2.0",
"typescript": "5.6.2",

View file

@ -80,6 +80,10 @@ SPDX-License-Identifier: AGPL-3.0-only
:enableEmojiMenu="true"
:enableEmojiMenuReaction="true"
/>
<div v-if="instance.translatorAvailable && $i && $i.policies.canUseTranslator && appearNote.text && isForeignLanguage" style="padding-top: 5px; color: var(--MI_THEME-accent);">
<button v-if="!(translating || translation)" ref="translateButton" class="_button" @click.stop="translate()">{{ i18n.ts.translate }}</button>
<button v-else class="_button" @click.stop="translation= null">{{ i18n.ts.close }}</button>
</div>
<div v-if="translating || translation" :class="$style.translation">
<MkLoading v-if="translating" mini/>
<div v-else-if="translation">
@ -215,6 +219,8 @@ import { isEnabledUrlPreview } from '@/instance.js';
import { type Keymap } from '@/scripts/hotkey.js';
import { focusPrev, focusNext } from '@/scripts/focus.js';
import { getAppearNote } from '@/scripts/get-appear-note.js';
import { miLocalStorage } from '@/local-storage.js';
import detectLanguage from '@/scripts/detect-language.js';
const props = withDefaults(defineProps<{
note: Misskey.entities.Note;
@ -572,6 +578,23 @@ async function clip(): Promise<void> {
os.popupMenu(await getNoteClipMenu({ note: note.value, isDeleted, currentClip: currentClip?.value }), clipButton.value).then(focus);
}
const isForeignLanguage: boolean = appearNote.value.text != null && (() => {
const targetLang = (miLocalStorage.getItem('lang') ?? navigator.language).slice(0, 2);
const postLang = detectLanguage(appearNote.value.text);
return postLang !== '' && postLang !== targetLang;
})();
async function translate(): Promise<void> {
if (props.translation.value != null) return;
props.translating.value = true;
const res = await misskeyApi('notes/translate', {
noteId: appearNote.id,
targetLang: miLocalStorage.getItem('lang') ?? navigator.language,
});
props.translating.value = false;
props.translation.value = res;
}
function showRenoteMenu(): void {
if (props.mock) {
return;

View file

@ -0,0 +1,18 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { detect } from 'tinyld';
import * as mfm from 'mfm-js';
export default function detectLanguage(text: string): string {
const nodes = mfm.parse(text);
const filtered = mfm.extract(nodes, (node) => {
return node.type === 'text' || node.type === 'quote';
});
const purified = mfm.toString(filtered);
if (detect(purified) === '') return 'en';
return detect(purified);
}

View file

@ -27,6 +27,13 @@ const externalPackages = [
: id;
},
},
{
name: 'tinyld',
match: /^tinyld$/,
path(): string {
return `https://cdn.jsdelivr.net/npm/tinyld@${packageInfo.dependencies.tinyld}/dist/tinyld.normal.node.mjs`
},
},
];
const hash = (str: string, seed = 0): number => {