summaryrefslogtreecommitdiff
path: root/src/client/components/note.vue
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/components/note.vue')
-rw-r--r--src/client/components/note.vue32
1 files changed, 32 insertions, 0 deletions
diff --git a/src/client/components/note.vue b/src/client/components/note.vue
index 873b96030a..38b529dd91 100644
--- a/src/client/components/note.vue
+++ b/src/client/components/note.vue
@@ -51,6 +51,13 @@
<MkA class="reply" v-if="appearNote.replyId" :to="`/notes/${appearNote.replyId}`"><i class="fas fa-reply"></i></MkA>
<Mfm v-if="appearNote.text" :text="appearNote.text" :author="appearNote.user" :i="$i" :custom-emojis="appearNote.emojis"/>
<a class="rp" v-if="appearNote.renote != null">RN:</a>
+ <div class="translation" v-if="translating || translation">
+ <MkLoading v-if="translating" mini/>
+ <div class="translated" v-else>
+ <b>{{ $t('translatedFrom', { x: translation.sourceLang }) }}:</b>
+ {{ translation.text }}
+ </div>
+ </div>
</div>
<div class="files" v-if="appearNote.files.length > 0">
<XMediaList :media-list="appearNote.files"/>
@@ -164,6 +171,8 @@ export default defineComponent({
collapsed: false,
isDeleted: false,
muted: false,
+ translation: null,
+ translating: false,
};
},
@@ -594,6 +603,11 @@ export default defineComponent({
text: this.$ts.share,
action: this.share
},
+ this.$instance.translatorAvailable ? {
+ icon: 'fas fa-language',
+ text: this.$ts.translate,
+ action: this.translate
+ } : undefined,
null,
statePromise.then(state => state.isFavorited ? {
icon: 'fas fa-star',
@@ -827,6 +841,17 @@ export default defineComponent({
});
},
+ async translate() {
+ if (this.translation != null) return;
+ this.translating = true;
+ const res = await os.api('notes/translate', {
+ noteId: this.appearNote.id,
+ targetLang: localStorage.getItem('lang') || navigator.language,
+ });
+ this.translating = false;
+ this.translation = res;
+ },
+
focus() {
this.$el.focus();
},
@@ -1053,6 +1078,13 @@ export default defineComponent({
font-style: oblique;
color: var(--renote);
}
+
+ > .translation {
+ border: solid 0.5px var(--divider);
+ border-radius: var(--radius);
+ padding: 12px;
+ margin-top: 8px;
+ }
}
> .url-preview {