forked from AkkomaGang/akkoma-fe
add translation options
This commit is contained in:
parent
6e31816c7d
commit
c23964b7a8
10 changed files with 98 additions and 64 deletions
|
@ -250,6 +250,7 @@ const getNodeInfo = async ({ store }) => {
|
|||
store.dispatch('setInstanceOption', { name: 'pollsAvailable', value: features.includes('polls') })
|
||||
store.dispatch('setInstanceOption', { name: 'pollLimits', value: metadata.pollLimits })
|
||||
store.dispatch('setInstanceOption', { name: 'mailerEnabled', value: metadata.mailerEnabled })
|
||||
store.dispatch('setInstanceOption', { name: 'translationEnabled', value: features.includes('akkoma:machine_translation') })
|
||||
|
||||
const uploadLimits = metadata.uploadLimits
|
||||
store.dispatch('setInstanceOption', { name: 'uploadlimit', value: parseInt(uploadLimits.general) })
|
||||
|
|
|
@ -57,6 +57,12 @@ const ExtraButtons = {
|
|||
hideDeleteStatusConfirmDialog () {
|
||||
this.showingDeleteDialog = false
|
||||
},
|
||||
|
||||
translateStatus () {
|
||||
this.$store.dispatch('translateStatus', { id: this.status.id, language: this.$store.state.instance.interfaceLanguage })
|
||||
.then(() => this.$emit('onSuccess'))
|
||||
.catch(err => this.$emit('onError', err.error.error))
|
||||
},
|
||||
pinStatus () {
|
||||
this.$store.dispatch('pinStatus', this.status.id)
|
||||
.then(() => this.$emit('onSuccess'))
|
||||
|
@ -112,6 +118,9 @@ const ExtraButtons = {
|
|||
canMute () {
|
||||
return !!this.currentUser
|
||||
},
|
||||
canTranslate () {
|
||||
return this.$store.state.instance.translationEnabled === true
|
||||
},
|
||||
statusLink () {
|
||||
if (this.status.is_local) {
|
||||
return `${this.$store.state.instance.server}${this.$router.resolve({ name: 'conversation', params: { id: this.status.id } }).href}`
|
||||
|
|
|
@ -127,6 +127,17 @@
|
|||
icon="quote-left"
|
||||
/><span>{{ $t("tool_tip.quote") }}</span>
|
||||
</button>
|
||||
<button
|
||||
v-if="canTranslate"
|
||||
class="button-default dropdown-item dropdown-item-icon"
|
||||
@click.prevent="translateStatus"
|
||||
@click="close"
|
||||
>
|
||||
<FAIcon
|
||||
fixed-width
|
||||
icon="globe"
|
||||
/><span>{{ $t("status.translate") }}</span>
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot:trigger>
|
||||
|
|
|
@ -4,6 +4,12 @@
|
|||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.translation {
|
||||
border: 1px solid var(--accent, $fallback--link);
|
||||
border-radius: var(--panelRadius, $fallback--panelRadius);
|
||||
margin-top: 1em;
|
||||
padding: 0.5em;
|
||||
}
|
||||
.emoji {
|
||||
--_still_image-label-scale: 0.5;
|
||||
--emoji-size: 38px;
|
||||
|
|
|
@ -56,6 +56,23 @@
|
|||
:attentions="status.attentions"
|
||||
@parseReady="onParseReady"
|
||||
/>
|
||||
<div
|
||||
v-if="status.translation"
|
||||
class="translation"
|
||||
>
|
||||
<h4>{{ $t('status.translated_from', { language: status.translation.detected_language }) }}</h4>
|
||||
<RichContent
|
||||
:class="{ '-single-line': singleLine }"
|
||||
class="text media-body"
|
||||
:html="status.translation.text"
|
||||
:emoji="status.emojis"
|
||||
:handle-links="true"
|
||||
:mfm="renderMisskeyMarkdown && (status.media_type === 'text/x.misskeymarkdown')"
|
||||
:greentext="mergedConfig.greentext"
|
||||
:attentions="status.attentions"
|
||||
@parseReady="onParseReady"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
v-show="hideSubjectStatus"
|
||||
|
|
|
@ -813,6 +813,8 @@
|
|||
"pinned": "Pinned",
|
||||
"bookmark": "Bookmark",
|
||||
"unbookmark": "Unbookmark",
|
||||
"translate": "Translate",
|
||||
"translated_from": "Translated from {language}",
|
||||
"delete_confirm": "Do you really want to delete this status?",
|
||||
"reply_to": "Reply to",
|
||||
"delete_confirm_title": "Confirm deletion",
|
||||
|
|
|
@ -561,69 +561,39 @@
|
|||
"mention_link_display_full": "名前とドメイン、例: {'@'}foo{'@'}example.org",
|
||||
"fun": "お楽しみ",
|
||||
"virtual_scrolling": "タイムラインの描画を最適化する",
|
||||
"type_domains_to_mute": "ミュートしたいドメインを検索",
|
||||
"useStreamingApiWarning": "(実験中で、投稿を取りこぼすかもしれないので、おすすめしません)",
|
||||
"useStreamingApi": "投稿と通知を、すぐに受け取る",
|
||||
"user_mutes": "ユーザー",
|
||||
"reset_background_confirm": "本当にバックグラウンドを初期化しますか?",
|
||||
"reset_banner_confirm": "本当にバナーを初期化しますか?",
|
||||
"reset_avatar_confirm": "本当にアバターを初期化しますか?",
|
||||
"hide_wallpaper": "インスタンスのバックグラウンドを隠す",
|
||||
"reset_profile_background": "プロフィールのバックグラウンドを初期化",
|
||||
"reset_profile_banner": "プロフィールのバナーを初期化",
|
||||
"reset_avatar": "アバターを初期化",
|
||||
"notification_visibility_emoji_reactions": "リアクション",
|
||||
"notification_visibility_moves": "ユーザーの引っ越し",
|
||||
"new_email": "新しいメールアドレス",
|
||||
"post_look_feel": "投稿の見た目",
|
||||
"mention_links": "メンションリンク",
|
||||
"profile_fields": {
|
||||
"value": "内容",
|
||||
"name": "ラベル",
|
||||
"add_field": "枠を追加",
|
||||
"label": "プロフィール補足情報"
|
||||
"word_filter": "単語フィルタ"
|
||||
},
|
||||
"accent": "アクセント",
|
||||
"mutes_imported": "ミュートをインポートしました!少し時間がかかるかもしれません。",
|
||||
"emoji_reactions_on_timeline": "絵文字リアクションをタイムラインに表示",
|
||||
"domain_mutes": "ドメイン",
|
||||
"mutes_and_blocks": "ミュートとブロック",
|
||||
"chatMessageRadius": "チャットメッセージ",
|
||||
"change_email_error": "メールアドレスを変えることが、できなかったかもしれません。",
|
||||
"changed_email": "メールアドレスが、変わりました!",
|
||||
"change_email": "メールアドレスを変える",
|
||||
"bot": "これは bot アカウントです",
|
||||
"mute_export_button": "ミュートをCSVファイルにエクスポートする",
|
||||
"import_mutes_from_a_csv_file": "CSVファイルからミュートをインポートする",
|
||||
"mute_import_error": "ミュートのインポートに失敗しました",
|
||||
"mute_import": "ミュートのインポート",
|
||||
"mute_export": "ミュートのエクスポート",
|
||||
"allow_following_move": "フォロー中のアカウントが引っ越したとき、自動フォローを許可する",
|
||||
"setting_changed": "規定の設定と異なっています",
|
||||
"greentext": "引用を緑色で表示",
|
||||
"sensitive_by_default": "はじめから投稿をセンシティブとして設定",
|
||||
"sensitive_if_subject": "ステータスにサブジェクトをついたらNSFWにする",
|
||||
"render_mfm": "Misskey Markdownを表示",
|
||||
"more_settings": "その他の設定",
|
||||
"reply_visibility_self_short": "自分宛のリプライを見る",
|
||||
"reply_visibility_following_short": "フォローしている人に宛てられたリプライを見る",
|
||||
"hide_all_muted_posts": "ミュートした投稿を隠す",
|
||||
"hide_media_previews": "メディアのプレビューを隠す",
|
||||
"word_filter": "単語フィルタ",
|
||||
"file_export_import": {
|
||||
"errors": {
|
||||
"invalid_file": "これはPleromaの設定をバックアップしたファイルではありません。",
|
||||
"file_slightly_new": "ファイルのマイナーバージョンが異なり、一部の設定が読み込まれないことがあります"
|
||||
},
|
||||
"restore_settings": "設定をファイルから復元する",
|
||||
"backup_settings_theme": "テーマを含む設定をファイルにバックアップする",
|
||||
"backup_settings": "設定をファイルにバックアップする",
|
||||
"backup_restore": "設定をバックアップ"
|
||||
},
|
||||
"save": "変更を保存",
|
||||
"hide_shoutbox": "Shoutboxを表示しない",
|
||||
"always_show_post_button": "投稿ボタンを常に表示",
|
||||
"right_sidebar": "サイドバーを右に表示"
|
||||
"status": {
|
||||
"bookmark": "ブックマーク",
|
||||
"copy_link": "リンクをコピー",
|
||||
"delete": "ステータスを削除",
|
||||
"delete_confirm": "本当にこのステータスを削除してもよろしいですか?",
|
||||
"expand": "広げる",
|
||||
"external_source": "外部ソース",
|
||||
"favorites": "お気に入り",
|
||||
"hide_content": "隠す",
|
||||
"hide_full_subject": "隠す",
|
||||
"mentions": "メンション",
|
||||
"mute_conversation": "スレッドをミュート",
|
||||
"nsfw": "閲覧注意",
|
||||
"pin": "プロフィールにピン留め",
|
||||
"pinned": "ピン留め",
|
||||
"plus_more": "ほか{number}件",
|
||||
"repeats": "リピート",
|
||||
"replies_list": "返信:",
|
||||
"reply_to": "返信",
|
||||
"show_content": "見る",
|
||||
"show_full_subject": "全部見る",
|
||||
"status_deleted": "この投稿は削除されました",
|
||||
"status_unavailable": "利用できません",
|
||||
"thread_muted": "ミュートされたスレッド",
|
||||
"thread_muted_and_words": "以下の単語を含むため:",
|
||||
"translate": "翻訳",
|
||||
"translated_from": "{language}から翻訳されました",
|
||||
"unbookmark": "ブックマーク解除",
|
||||
"unmute_conversation": "スレッドのミュートを解除",
|
||||
"unpin": "プロフィールのピン留めを外す",
|
||||
"you": "(あなた)"
|
||||
},
|
||||
"time": {
|
||||
"now": "たった今",
|
||||
|
|
|
@ -186,6 +186,7 @@ const config = {
|
|||
case 'interfaceLanguage':
|
||||
messages.setLanguage(this.getters.i18n, value)
|
||||
Cookies.set(BACKEND_LANGUAGE_COOKIE_NAME, localeService.internalToBackendLocale(value))
|
||||
dispatch('setInstanceOption', { name: 'interfaceLanguage', value })
|
||||
break
|
||||
case 'thirdColumnMode':
|
||||
dispatch('setLayoutWidth', undefined)
|
||||
|
|
|
@ -425,6 +425,10 @@ export const mutations = {
|
|||
state.conversationsObject[newStatus.statusnet_conversation_id].forEach(status => { status.thread_muted = newStatus.thread_muted })
|
||||
}
|
||||
},
|
||||
setTranslatedStatus (state, { id, translation }) {
|
||||
const newStatus = state.allStatusesObject[id]
|
||||
newStatus.translation = translation
|
||||
},
|
||||
setRetweeted (state, { status, value }) {
|
||||
const newStatus = state.allStatusesObject[status.id]
|
||||
|
||||
|
@ -637,6 +641,10 @@ const statuses = {
|
|||
rootState.api.backendInteractor.unpinOwnStatus({ id: statusId })
|
||||
.then((status) => dispatch('addNewStatuses', { statuses: [status] }))
|
||||
},
|
||||
translateStatus ({ rootState, commit }, { id, translation, language }) {
|
||||
return rootState.api.backendInteractor.translateStatus({ id: id, translation, language })
|
||||
.then((translation) => commit('setTranslatedStatus', { id, translation }))
|
||||
},
|
||||
muteConversation ({ rootState, commit }, statusId) {
|
||||
return rootState.api.backendInteractor.muteConversation({ id: statusId })
|
||||
.then((status) => commit('setMutedStatus', status))
|
||||
|
|
|
@ -31,6 +31,7 @@ const MASTODON_LOGIN_URL = '/api/v1/accounts/verify_credentials'
|
|||
const MASTODON_REGISTRATION_URL = '/api/v1/accounts'
|
||||
const MASTODON_USER_FAVORITES_TIMELINE_URL = '/api/v1/favourites'
|
||||
const MASTODON_USER_NOTIFICATIONS_URL = '/api/v1/notifications'
|
||||
const AKKOMA_TRANSLATE_URL = (id, lang) => `/api/v1/statuses/${id}/translations/${lang}`
|
||||
const MASTODON_DISMISS_NOTIFICATION_URL = id => `/api/v1/notifications/${id}/dismiss`
|
||||
const MASTODON_FAVORITE_URL = id => `/api/v1/statuses/${id}/favourite`
|
||||
const MASTODON_UNFAVORITE_URL = id => `/api/v1/statuses/${id}/unfavourite`
|
||||
|
@ -738,6 +739,13 @@ const unretweet = ({ id, credentials }) => {
|
|||
.then((data) => parseStatus(data))
|
||||
}
|
||||
|
||||
const translateStatus = ({ id, credentials, language }) => {
|
||||
return promisedRequest({ url: AKKOMA_TRANSLATE_URL(id, language), method: 'GET', credentials })
|
||||
.then((data) => {
|
||||
return data
|
||||
})
|
||||
}
|
||||
|
||||
const bookmarkStatus = ({ id, credentials }) => {
|
||||
return promisedRequest({
|
||||
url: MASTODON_BOOKMARK_STATUS_URL(id),
|
||||
|
@ -1576,7 +1584,8 @@ const apiService = {
|
|||
postAnnouncement,
|
||||
editAnnouncement,
|
||||
deleteAnnouncement,
|
||||
adminFetchAnnouncements
|
||||
adminFetchAnnouncements,
|
||||
translateStatus
|
||||
}
|
||||
|
||||
export default apiService
|
||||
|
|
Loading…
Reference in a new issue