feat(client): 返信も翻訳できるように
This commit is contained in:
parent
c4991b8ea6
commit
851d2a48a0
|
@ -67,6 +67,7 @@
|
||||||
- CherryPick 고유 기능 및 개선된 기능은 [CherryPick] 배지 추가
|
- CherryPick 고유 기능 및 개선된 기능은 [CherryPick] 배지 추가
|
||||||
- 네비게이션 메뉴 편집 페이지 UI 개선 ([shrimpia bf8c84d](https://github.com/shrimpia/misskey/commit/bf8c84d299bd06cb21e18a9fe68ff9abc11fd4a0))
|
- 네비게이션 메뉴 편집 페이지 UI 개선 ([shrimpia bf8c84d](https://github.com/shrimpia/misskey/commit/bf8c84d299bd06cb21e18a9fe68ff9abc11fd4a0))
|
||||||
- 「노트 본문에 번역 버튼 표시」를 선택 사항으로 설정
|
- 「노트 본문에 번역 버튼 표시」를 선택 사항으로 설정
|
||||||
|
- 답글도 번역할 수 있도록 개선
|
||||||
- Fix: (Friendly) 플로팅 메뉴를 길게 눌렀을 때 프로필 이미지를 드래그 할 수 있는 문제
|
- Fix: (Friendly) 플로팅 메뉴를 길게 눌렀을 때 프로필 이미지를 드래그 할 수 있는 문제
|
||||||
- Fix: (Friendly) 타임라인이 변경되었을 때 네비게이션 바의 인디케이터가 사라지지 않는 문제
|
- Fix: (Friendly) 타임라인이 변경되었을 때 네비게이션 바의 인디케이터가 사라지지 않는 문제
|
||||||
- Fix: (Friendly) 모바일에서 헤더가 사라졌을 때 프로필 아이콘의 높이가 잘못 설정되는 문제
|
- Fix: (Friendly) 모바일에서 헤더가 사라졌을 때 프로필 아이콘의 높이가 잘못 설정되는 문제
|
||||||
|
|
|
@ -6,6 +6,18 @@
|
||||||
<MkA v-if="note.replyId" :class="$style.reply" :to="`/notes/${note.replyId}`"><i class="ti ti-arrow-back-up"></i></MkA>
|
<MkA v-if="note.replyId" :class="$style.reply" :to="`/notes/${note.replyId}`"><i class="ti ti-arrow-back-up"></i></MkA>
|
||||||
<Mfm v-if="note.text" :text="note.text" :author="note.user" :i="$i" :emojiUrls="note.emojis"/>
|
<Mfm v-if="note.text" :text="note.text" :author="note.user" :i="$i" :emojiUrls="note.emojis"/>
|
||||||
<MkA v-if="note.renoteId" :class="$style.rp" :to="`/notes/${note.renoteId}`">RN: ...</MkA>
|
<MkA v-if="note.renoteId" :class="$style.rp" :to="`/notes/${note.renoteId}`">RN: ...</MkA>
|
||||||
|
<div style="padding-top: 5px; color: var(--accent);"><button v-if="defaultStore.state.showTranslateButtonInNote" ref="translateButton" class="_button" @mousedown="translate()">{{ i18n.ts.translateNote }}</button></div>
|
||||||
|
<div v-if="translating || translation" :class="$style.translation">
|
||||||
|
<MkLoading v-if="translating" mini/>
|
||||||
|
<div v-else>
|
||||||
|
<b>{{ i18n.t('translatedFrom', { x: translation.sourceLang }) }}:</b><hr style="margin: 10px 0;">
|
||||||
|
<Mfm :text="translation.text" :author="note.user" :i="$i" :emojiUrls="note.emojis"/>
|
||||||
|
<div v-if="translation.translator == 'ctav3'" style="margin-top: 10px; padding: 0 0 15px;">
|
||||||
|
<img v-if="!defaultStore.state.darkMode" src="/client-assets/color-short.svg" alt="" style="float: right;">
|
||||||
|
<img v-else src="/client-assets/white-short.svg" alt="" style="float: right;"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<details v-if="note.files.length > 0">
|
<details v-if="note.files.length > 0">
|
||||||
<summary>({{ i18n.t('withNFiles', { n: note.files.length }) }})</summary>
|
<summary>({{ i18n.t('withNFiles', { n: note.files.length }) }})</summary>
|
||||||
|
@ -23,12 +35,18 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { } from 'vue';
|
import { ref } from 'vue';
|
||||||
import * as misskey from 'cherrypick-js';
|
import * as misskey from 'cherrypick-js';
|
||||||
|
import * as os from '@/os';
|
||||||
import MkMediaList from '@/components/MkMediaList.vue';
|
import MkMediaList from '@/components/MkMediaList.vue';
|
||||||
import MkPoll from '@/components/MkPoll.vue';
|
import MkPoll from '@/components/MkPoll.vue';
|
||||||
import { i18n } from '@/i18n';
|
import { i18n } from '@/i18n';
|
||||||
import { $i } from '@/account';
|
import { $i } from '@/account';
|
||||||
|
import { defaultStore } from '@/store';
|
||||||
|
import { miLocalStorage } from '@/local-storage';
|
||||||
|
|
||||||
|
const translation = ref<any>(null);
|
||||||
|
const translating = ref(false);
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
note: misskey.entities.Note;
|
note: misskey.entities.Note;
|
||||||
|
@ -39,6 +57,17 @@ const collapsed = $ref(
|
||||||
(props.note.text.split('\n').length > 9) ||
|
(props.note.text.split('\n').length > 9) ||
|
||||||
(props.note.text.length > 500)
|
(props.note.text.length > 500)
|
||||||
));
|
));
|
||||||
|
|
||||||
|
async function translate(): Promise<void> {
|
||||||
|
if (translation.value != null) return;
|
||||||
|
translating.value = true;
|
||||||
|
const res = await os.api('notes/translate', {
|
||||||
|
noteId: props.note.id,
|
||||||
|
targetLang: miLocalStorage.getItem('lang') ?? navigator.language,
|
||||||
|
});
|
||||||
|
translating.value = false;
|
||||||
|
translation.value = res;
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" module>
|
<style lang="scss" module>
|
||||||
|
@ -87,4 +116,11 @@ const collapsed = $ref(
|
||||||
font-style: oblique;
|
font-style: oblique;
|
||||||
color: var(--renote);
|
color: var(--renote);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.translation {
|
||||||
|
border: solid 0.5px var(--divider);
|
||||||
|
border-radius: var(--radius);
|
||||||
|
padding: 12px;
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
Loading…
Reference in a new issue