From 22fd3afd160d27c9ab43fcc8d1270db455403f8e Mon Sep 17 00:00:00 2001 From: Sean King Date: Thu, 30 Mar 2023 15:30:03 -0600 Subject: [PATCH 001/405] Change selenium server path to use require instead of hardcoding it --- test/e2e/nightwatch.conf.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/e2e/nightwatch.conf.js b/test/e2e/nightwatch.conf.js index 4041c698..fdd2fda2 100644 --- a/test/e2e/nightwatch.conf.js +++ b/test/e2e/nightwatch.conf.js @@ -9,7 +9,7 @@ module.exports = { selenium: { start_process: true, - server_path: 'node_modules/selenium-server/lib/runner/selenium-server-standalone-2.53.1.jar', + server_path: require('selenium-server').path, host: '127.0.0.1', port: 4444, cli_args: { From 8e64b1791bca4b34ec1988dda3fea99eb1715c1f Mon Sep 17 00:00:00 2001 From: Sean King Date: Thu, 30 Mar 2023 15:30:30 -0600 Subject: [PATCH 002/405] Add selenium server logs path to gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 4df5ec83..0d5befd2 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ selenium-debug.log .idea/ config/local.json static/emoji.json +logs/ From 829ab46fdcebceac78a00151361ce1755455c643 Mon Sep 17 00:00:00 2001 From: Pleroma Renovate Bot Date: Wed, 12 Apr 2023 09:11:09 +0000 Subject: [PATCH 003/405] Update dependency @ungap/event-target to v0.2.4 --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index db45f210..d832517c 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ "@babel/preset-env": "7.21.4", "@babel/register": "7.21.0", "@intlify/vue-i18n-loader": "5.0.1", - "@ungap/event-target": "0.2.3", + "@ungap/event-target": "0.2.4", "@vue/babel-helper-vue-jsx-merge-props": "1.4.0", "@vue/babel-plugin-jsx": "1.1.1", "@vue/compiler-sfc": "3.2.45", diff --git a/yarn.lock b/yarn.lock index 4b407fd5..52f9d2ae 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2152,10 +2152,10 @@ dependencies: "@types/node" "*" -"@ungap/event-target@0.2.3": - version "0.2.3" - resolved "https://registry.yarnpkg.com/@ungap/event-target/-/event-target-0.2.3.tgz#be682c681126dca2371c4e1a1721f8e8bb400905" - integrity sha512-7Bz0qdvxNGV9n0f+xcMKU7wsEfK6PNzo8IdAcOiBgMNyCuU0Mk9dv0Hbd/Kgr+MFFfn4xLHFbuOt820egT5qEA== +"@ungap/event-target@0.2.4": + version "0.2.4" + resolved "https://registry.yarnpkg.com/@ungap/event-target/-/event-target-0.2.4.tgz#8b083a62ee665228bac08013fa516a3488528bb8" + integrity sha512-u9Fd3k2qfMtn+0dxbCn/y0pzQ9Ucw6lWR984CrHcbxc+WzcMkJE4VjWHWSb9At40MjwMyHCkJNXroS55Osshhw== "@ungap/promise-all-settled@1.1.2": version "1.1.2" From e1ef3811624717559b2b3ed02eaadd71ab93a872 Mon Sep 17 00:00:00 2001 From: Pleroma Renovate Bot Date: Wed, 3 May 2023 09:07:55 +0000 Subject: [PATCH 004/405] Update dependency js-cookie to v3.0.5 --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 169dd609..3daae1eb 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "click-outside-vue3": "4.0.1", "cropperjs": "1.5.13", "escape-html": "1.0.3", - "js-cookie": "3.0.1", + "js-cookie": "3.0.5", "localforage": "1.10.0", "parse-link-header": "2.0.0", "phoenix": "1.6.2", diff --git a/yarn.lock b/yarn.lock index 1ccc9b05..4bef251f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5661,10 +5661,10 @@ js-beautify@1.14.6: glob "^8.0.3" nopt "^6.0.0" -js-cookie@3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/js-cookie/-/js-cookie-3.0.1.tgz#9e39b4c6c2f56563708d7d31f6f5f21873a92414" - integrity sha512-+0rgsUXZu4ncpPxRL+lNEptWMOWl9etvPHc/koSRp6MPwpRYAhmk0dUG00J4bxVV3r9uUzfo24wW0knS07SKSw== +js-cookie@3.0.5: + version "3.0.5" + resolved "https://registry.yarnpkg.com/js-cookie/-/js-cookie-3.0.5.tgz#0b7e2fd0c01552c58ba86e0841f94dc2557dcdbc" + integrity sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw== js-sdsl@^4.1.4: version "4.1.5" From 0d6a9e8a647be860b10506aecaafb4ff0f10150f Mon Sep 17 00:00:00 2001 From: tusooa Date: Sun, 13 Aug 2023 23:57:34 -0400 Subject: [PATCH 005/405] Display extra notifications on notifications column --- .../extra_notifications.js | 9 ++++ .../extra_notifications.vue | 42 +++++++++++++++++++ src/components/notifications/notifications.js | 7 +++- .../notifications/notifications.vue | 7 ++++ src/i18n/en.json | 4 +- 5 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 src/components/extra_notifications/extra_notifications.js create mode 100644 src/components/extra_notifications/extra_notifications.vue diff --git a/src/components/extra_notifications/extra_notifications.js b/src/components/extra_notifications/extra_notifications.js new file mode 100644 index 00000000..0bf904ba --- /dev/null +++ b/src/components/extra_notifications/extra_notifications.js @@ -0,0 +1,9 @@ +import { mapGetters } from 'vuex' + +const ExtraNotifications = { + computed: { + ...mapGetters(['unreadChatCount', 'unreadAnnouncementCount']) + } +} + +export default ExtraNotifications diff --git a/src/components/extra_notifications/extra_notifications.vue b/src/components/extra_notifications/extra_notifications.vue new file mode 100644 index 00000000..11eeb937 --- /dev/null +++ b/src/components/extra_notifications/extra_notifications.vue @@ -0,0 +1,42 @@ + + + + + diff --git a/src/components/settings_modal/settings_modal_admin_content.js b/src/components/settings_modal/settings_modal_admin_content.js index f94721ec..ce835bf2 100644 --- a/src/components/settings_modal/settings_modal_admin_content.js +++ b/src/components/settings_modal/settings_modal_admin_content.js @@ -3,6 +3,7 @@ import TabSwitcher from 'src/components/tab_switcher/tab_switcher.jsx' import InstanceTab from './admin_tabs/instance_tab.vue' import LimitsTab from './admin_tabs/limits_tab.vue' import FrontendsTab from './admin_tabs/frontends_tab.vue' +import EmojiTab from './admin_tabs/emoji_tab.vue' import { library } from '@fortawesome/fontawesome-svg-core' import { @@ -33,7 +34,8 @@ const SettingsModalAdminContent = { InstanceTab, LimitsTab, - FrontendsTab + FrontendsTab, + EmojiTab }, computed: { user () { diff --git a/src/components/settings_modal/settings_modal_admin_content.vue b/src/components/settings_modal/settings_modal_admin_content.vue index a7a2ac9a..ba2d0a30 100644 --- a/src/components/settings_modal/settings_modal_admin_content.vue +++ b/src/components/settings_modal/settings_modal_admin_content.vue @@ -60,6 +60,14 @@ > + +
+ +
diff --git a/src/i18n/en.json b/src/i18n/en.json index f4c9de18..09ba7025 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -877,7 +877,8 @@ "nodb": "No DB Config", "instance": "Instance", "limits": "Limits", - "frontends": "Front-ends" + "frontends": "Front-ends", + "emoji": "Emoji" }, "nodb": { "heading": "Database config is disabled", @@ -931,6 +932,10 @@ "failure_installing_frontend": "Failed to install frontend {version}: {reason}", "success_installing_frontend": "Frontend {version} successfully installed" }, + "emoji": { + "reload": "Reload emoji", + "importFS": "Import emoji from filesystem" + }, "temp_overrides": { ":pleroma": { ":instance": { diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js index bde2e163..4d8fdae2 100644 --- a/src/services/api/api.service.js +++ b/src/services/api/api.service.js @@ -114,6 +114,15 @@ const PLEROMA_ADMIN_DESCRIPTIONS_URL = '/api/pleroma/admin/config/descriptions' const PLEROMA_ADMIN_FRONTENDS_URL = '/api/pleroma/admin/frontends' const PLEROMA_ADMIN_FRONTENDS_INSTALL_URL = '/api/pleroma/admin/frontends/install' +const PLEROMA_EMOJI_RELOAD_URL = '/api/pleroma/admin/reload_emoji' +const PLEROMA_EMOJI_IMPORT_FS_URL = '/api/pleroma/emoji/packs/import' +const PLEROMA_EMOJI_PACKS_URL = (page, pageSize) => `/api/pleroma/emoji/packs?page=${page}&page_size=${pageSize}` +const PLEROMA_EMOJI_PACK_URL = (name) => `/api/pleroma/emoji/pack?name=${name}` +const PLEROMA_EMOJI_PACKS_DL_REMOTE_URL = '/api/pleroma/emoji/packs/download' +const PLEROMA_EMOJI_PACKS_LS_REMOTE_URL = + (url, page, pageSize) => `/api/pleroma/emoji/packs/remote?url=${url}&page=${page}&page_size=${pageSize}` +const PLEROMA_EMOJI_UPDATE_FILE_URL = (name) => `/api/pleroma/emoji/packs/files?name=${name}` + const oldfetch = window.fetch const fetch = (url, options) => { @@ -1787,6 +1796,92 @@ const fetchScrobbles = ({ accountId, limit = 1 }) => { }) } +const deleteEmojiPack = ({ name }) => { + return fetch(PLEROMA_EMOJI_PACK_URL(name), { method: 'DELETE' }) +} + +const reloadEmoji = () => { + return fetch(PLEROMA_EMOJI_RELOAD_URL, { method: 'POST' }) +} + +const importEmojiFromFS = () => { + return fetch(PLEROMA_EMOJI_IMPORT_FS_URL) +} + +const createEmojiPack = ({ name }) => { + return fetch(PLEROMA_EMOJI_PACK_URL(name), { method: 'PUT' }) +} + +const listEmojiPacks = () => { + return fetch(PLEROMA_EMOJI_PACKS_URL(1, 25)) +} + +const listRemoteEmojiPacks = ({ instance }) => { + return fetch( + PLEROMA_EMOJI_PACKS_LS_REMOTE_URL, + { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ instance_address: instance }) + } + ) +} + +const downloadRemoteEmojiPack = ({ instance, packName, as }) => { + if (as.trim() === '') { + as = null + } + + return fetch( + PLEROMA_EMOJI_PACKS_DL_REMOTE_URL, + { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + instance_address: instance, pack_name: packName, as + }) + } + ) +} + +const saveEmojiPackMetadata = ({ name, newData }) => { + return fetch( + PLEROMA_EMOJI_PACK_URL(name), + { + method: 'PATCH', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ name, new_data: newData }) + } + ) +} + +const addNewEmojiFile = ({ packName, file, shortcode, filename }) => { + const data = new FormData() + if (filename.trim() !== '') { data.set('filename', filename) } + if (shortcode.trim() !== '') { data.set('shortcode', shortcode) } + data.set('file', file) + + return fetch( + PLEROMA_EMOJI_UPDATE_FILE_URL(packName), + { method: 'POST', data } + ) +} + +const updateEmojiFile = ({ packName, shortcode, newShortcode, newFilename, force }) => { + return fetch( + PLEROMA_EMOJI_UPDATE_FILE_URL(packName), + { + method: 'PATCH', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ shortcode, new_shortcode: newShortcode, new_filename: newFilename, force }) + } + ) +} + +const deleteEmojiFile = ({ packName, shortcode }) => { + return fetch(`${PLEROMA_EMOJI_UPDATE_FILE_URL(packName)}&shortcode=${shortcode}`, { method: 'DELETE' }) +} + const apiService = { verifyCredentials, fetchTimeline, @@ -1906,7 +2001,18 @@ const apiService = { fetchInstanceConfigDescriptions, fetchAvailableFrontends, pushInstanceDBConfig, - installFrontend + installFrontend, + importEmojiFromFS, + reloadEmoji, + listEmojiPacks, + createEmojiPack, + deleteEmojiPack, + saveEmojiPackMetadata, + addNewEmojiFile, + updateEmojiFile, + deleteEmojiFile, + listRemoteEmojiPacks, + downloadRemoteEmojiPack } export default apiService From bfdad56b0d4b4f8ed89295661ff8abba22dca7f0 Mon Sep 17 00:00:00 2001 From: Ekaterina Vaartis Date: Thu, 21 Dec 2023 00:48:14 +0300 Subject: [PATCH 109/405] Make the frontend config work somewhat even without DB config --- .../settings_modal/admin_tabs/frontends_tab.js | 10 +++++++--- .../settings_modal/admin_tabs/frontends_tab.vue | 14 +++++++++----- src/components/settings_modal/helpers/setting.js | 3 ++- src/i18n/en.json | 1 + 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/components/settings_modal/admin_tabs/frontends_tab.js b/src/components/settings_modal/admin_tabs/frontends_tab.js index 8163af59..f57310ee 100644 --- a/src/components/settings_modal/admin_tabs/frontends_tab.js +++ b/src/components/settings_modal/admin_tabs/frontends_tab.js @@ -55,9 +55,13 @@ const FrontendsTab = { return fe.refs.includes(frontend.ref) }, getSuggestedRef (frontend) { - const defaultFe = this.adminDraft[':pleroma'][':frontends'][':primary'] - if (defaultFe?.name === frontend.name && this.canInstall(defaultFe)) { - return defaultFe.ref + if (this.adminDraft) { + const defaultFe = this.adminDraft[':pleroma'][':frontends'][':primary'] + if (defaultFe?.name === frontend.name && this.canInstall(defaultFe)) { + return defaultFe.ref + } else { + return frontend.refs[0] + } } else { return frontend.refs[0] } diff --git a/src/components/settings_modal/admin_tabs/frontends_tab.vue b/src/components/settings_modal/admin_tabs/frontends_tab.vue index dd4c9790..097877bc 100644 --- a/src/components/settings_modal/admin_tabs/frontends_tab.vue +++ b/src/components/settings_modal/admin_tabs/frontends_tab.vue @@ -6,7 +6,7 @@

{{ $t('admin_dash.tabs.frontends') }}

{{ $t('admin_dash.frontend.wip_notice') }}

-
    +
    • {{ $t('admin_dash.frontend.default_frontend') }}

      {{ $t('admin_dash.frontend.default_frontend_tip') }}

      @@ -23,6 +23,10 @@
+
+ {{ $t('admin_dash.frontend.default_frontend_unavail') }} +
+

{{ $t('admin_dash.frontend.available_frontends') }}

@@ -33,9 +37,9 @@ > {{ frontend.name }} {{ ' ' }} - + @@ -134,7 +138,7 @@ class="button button-default btn" type="button" :disabled=" - adminDraft[':pleroma'][':frontends'][':primary']?.name === frontend.name && + !adminDraft || adminDraft[':pleroma'][':frontends'][':primary']?.name === frontend.name && adminDraft[':pleroma'][':frontends'][':primary']?.ref === frontend.refs[0] " @click="setDefault(frontend)" diff --git a/src/components/settings_modal/helpers/setting.js b/src/components/settings_modal/helpers/setting.js index b3add346..abf9cfdf 100644 --- a/src/components/settings_modal/helpers/setting.js +++ b/src/components/settings_modal/helpers/setting.js @@ -195,7 +195,8 @@ export default { } }, canHardReset () { - return this.realSource === 'admin' && this.$store.state.adminSettings.modifiedPaths.has(this.canonPath.join(' -> ')) + return this.realSource === 'admin' && this.$store.state.adminSettings.modifiedPaths && + this.$store.state.adminSettings.modifiedPaths.has(this.canonPath.join(' -> ')) }, matchesExpertLevel () { return (this.expert || 0) <= this.$store.state.config.expertLevel > 0 diff --git a/src/i18n/en.json b/src/i18n/en.json index 09ba7025..62316a3f 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -928,6 +928,7 @@ "wip_notice": "Please note that this section is a WIP and lacks certain features as backend implementation of front-end management is incomplete.", "default_frontend": "Default front-end", "default_frontend_tip": "Default front-end will be shown to all users. Currently there's no way to for a user to select personal front-end. If you switch away from PleromaFE you'll most likely have to use old and buggy AdminFE to do instance configuration until we replace it.", + "default_frontend_unavail": "Default frontend settings are not available, as this requires configuration in the database", "available_frontends": "Available for install", "failure_installing_frontend": "Failed to install frontend {version}: {reason}", "success_installing_frontend": "Frontend {version} successfully installed" From 9b0fb0f7982fa8f8bba3ddd517ad5c796f65cc30 Mon Sep 17 00:00:00 2001 From: SyoBoN Date: Wed, 20 Dec 2023 03:25:05 +0000 Subject: [PATCH 110/405] Translated using Weblate (Japanese (ja_PEDANTIC)) Currently translated at 95.3% (1036 of 1086 strings) Translation: Pleroma/Pleroma-FE Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/ja_PEDANTIC/ --- src/i18n/ja_pedantic.json | 805 ++++++++++++++++++++++++++++---------- 1 file changed, 602 insertions(+), 203 deletions(-) diff --git a/src/i18n/ja_pedantic.json b/src/i18n/ja_pedantic.json index fddf24db..5d04fb6e 100644 --- a/src/i18n/ja_pedantic.json +++ b/src/i18n/ja_pedantic.json @@ -4,36 +4,37 @@ }, "exporter": { "export": "エクスポート", - "processing": "処理中です。処理が完了すると、ファイルをダウンロードするよう指示があります" + "processing": "処理中です。処理が完了すると、ファイルのダウンロードが開始します" }, "features_panel": { "chat": "チャット", "gopher": "Gopher", - "media_proxy": "メディアプロクシ", + "media_proxy": "メディアプロキシ", "scope_options": "公開範囲選択", - "text_limit": "文字の数", + "text_limit": "文字数制限", "title": "有効な機能", "who_to_follow": "おすすめユーザー", "upload_limit": "ファイルサイズの上限", - "pleroma_chat_messages": "Pleroma チャット" + "pleroma_chat_messages": "Pleroma チャット", + "shout": "Shoutbox" }, "finder": { - "error_fetching_user": "ユーザー検索がエラーになりました", + "error_fetching_user": "ユーザーの取得に失敗しました", "find_user": "ユーザーを探す" }, "general": { "apply": "適用", "submit": "送信", - "more": "続き", - "generic_error": "エラーになりました", - "optional": "省略可", + "more": "もっと", + "generic_error": "エラーが発生しました", + "optional": "任意", "show_more": "もっと見る", "show_less": "たたむ", "cancel": "キャンセル", "disable": "無効", "enable": "有効", "confirm": "確認", - "verify": "検査", + "verify": "検証", "peek": "隠す", "close": "閉じる", "dismiss": "無視", @@ -46,7 +47,20 @@ }, "flash_security": "Flashコンテンツが任意の命令を実行させることにより、コンピューターが危険にさらされることがあります。", "flash_fail": "Flashコンテンツの読み込みに失敗しました。コンソールで詳細を確認できます。", - "flash_content": "(試験的機能)クリックしてFlashコンテンツを再生します。" + "flash_content": "(試験的機能) クリックしてFlashコンテンツを再生します。", + "yes": "はい", + "no": "いいえ", + "scroll_to_top": "最上部へスクロール", + "unpin": "ピン留めを外す", + "pin": "ピン留めする", + "scope_in_timeline": { + "direct": "ダイレクト", + "private": "フォロワー限定", + "public": "パブリック", + "unlisted": "アンリステッド" + }, + "generic_error_message": "エラーが発生しました: {0}", + "never_show_again": "二度と表示しない" }, "image_cropper": { "crop_picture": "画像を切り抜く", @@ -57,7 +71,7 @@ "importer": { "submit": "送信", "success": "正常にインポートされました。", - "error": "このファイルをインポートするとき、エラーが発生しました。" + "error": "ファイルのインポート中にエラーが発生しました。" }, "login": { "login": "ログイン", @@ -69,30 +83,36 @@ "username": "ユーザー名", "hint": "会話に加わるには、ログインしてください", "authentication_code": "認証コード", - "enter_recovery_code": "リカバリーコードを入力してください", - "enter_two_factor_code": "2段階認証コードを入力してください", + "enter_recovery_code": "リカバリーコードを入力", + "enter_two_factor_code": "2段階認証コードを入力", "recovery_code": "リカバリーコード", "heading": { "totp": "2段階認証", - "recovery": "2段階リカバリー" - } + "recovery": "2段階認証リカバリー" + }, + "logout_confirm": "本当にログアウトしますか?", + "logout_confirm_accept_button": "ログアウト", + "logout_confirm_cancel_button": "ログアウトしない", + "logout_confirm_title": "ログアウトの確認" }, "media_modal": { - "previous": "前", - "next": "次" + "previous": "前へ", + "next": "次へ", + "hide": "メディアビューアを閉じる", + "counter": "{current} / {total}" }, "nav": { "about": "このインスタンスについて", "back": "戻る", "chat": "ローカルチャット", "friend_requests": "フォローリクエスト", - "mentions": "通知", - "interactions": "インタラクション", + "mentions": "メンション", + "interactions": "通知", "dms": "ダイレクトメッセージ", "public_tl": "公開タイムライン", "timeline": "タイムライン", "twkn": "すべてのネットワーク", - "user_search": "ユーザーを探す", + "user_search": "ユーザー検索", "search": "検索", "who_to_follow": "おすすめユーザー", "preferences": "設定", @@ -100,21 +120,35 @@ "bookmarks": "ブックマーク", "timelines": "タイムライン", "chats": "チャット", - "home_timeline": "ホームタイムライン" + "home_timeline": "ホームタイムライン", + "mobile_notifications_mark_as_seen": "すべて既読にする", + "search_close": "検索バーを閉じる", + "lists": "リスト", + "edit_nav_mobile": "ナビゲーションバーを編集", + "edit_pinned": "ピン留めを編集", + "edit_finish": "完了", + "mobile_notifications": "通知を開く (未読あり)", + "mobile_notifications_close": "通知を閉じる", + "announcements": "お知らせ" }, "notifications": { "broken_favorite": "ステータスが見つかりません。探しています…", - "favorited_you": "あなたのステータスがお気に入りされました", + "favorited_you": "ステータスがお気に入りされました", "followed_you": "フォローされました", - "load_older": "古い通知をみる", + "load_older": "古い通知を読み込む", "notifications": "通知", "read": "読んだ!", - "repeated_you": "あなたのステータスがリピートされました", + "repeated_you": "ステータスがリピートされました", "no_more_notifications": "通知はありません", "reacted_with": "{0} でリアクションしました", "migrated_to": "インスタンスを引っ越しました", - "follow_request": "あなたをフォローしたいです", - "error": "通知の取得に失敗しました: {0}" + "follow_request": "あなたをフォローしたがっています", + "error": "通知の取得に失敗しました: {0}", + "poll_ended": "投票結果が確定しました", + "configuration_tip_dismiss": "二度と表示しない", + "unread_announcements": "未読のお知らせが{num}件あります | 未読のお知らせが{num}件あります", + "unread_chats": "未読のチャットが{num}件あります | 未読のチャットが{num}件あります", + "unread_follow_requests": "フォローリクエストが{num}件来ています | フォローリクエストが{num}件来ています" }, "polls": { "add_poll": "投票を追加", @@ -128,20 +162,20 @@ "expiry": "投票期間", "expires_in": "投票は {0} で終了します", "expired": "投票は {0} 前に終了しました", - "not_enough_options": "相異なる選択肢が不足しています", + "not_enough_options": "選択肢が少なすぎます", "votes_count": "{count} 票 | {count} 票", - "people_voted_count": "{count} 人投票 | {count} 人投票" + "people_voted_count": "{count}人が投票しました | {count}人が投票しました" }, "emoji": { "stickers": "ステッカー", "emoji": "絵文字", - "keep_open": "ピッカーを開いたままにする", + "keep_open": "絵文字ピッカーを開いたままにする", "search_emoji": "絵文字を検索", "add_emoji": "絵文字を挿入", "custom": "カスタム絵文字", "unicode": "Unicode絵文字", "load_all": "全 {emojiAmount} 絵文字を読み込む", - "load_all_hint": "最初の {saneAmount} 絵文字を読み込みました、全て読み込むと重くなる可能性があります。" + "load_all_hint": "最初の {saneAmount} 件の絵文字を読み込みました。すべて読み込むとパフォーマンスに影響を与える可能性があります。" }, "stickers": { "add_sticker": "ステッカーを追加" @@ -149,30 +183,32 @@ "interactions": { "favs_repeats": "リピートとお気に入り", "follows": "新しいフォロワー", - "load_older": "古いインタラクションを見る", - "moves": "ユーザーの引っ越し" + "load_older": "古い通知を読み込む", + "moves": "ユーザーの引っ越し", + "emoji_reactions": "絵文字リアクション", + "reports": "通報" }, "post_status": { "new_status": "投稿する", - "account_not_locked_warning": "あなたのアカウントは {0} ではありません。あなたをフォローすれば、誰でも、フォロワー限定のステータスを読むことができます。", - "account_not_locked_warning_link": "ロックされたアカウント", - "attachments_sensitive": "ファイルをNSFWにする", + "account_not_locked_warning": "あなたのアカウントは {0} ではありません。あなたをフォローすれば、誰でもフォロワー限定のステータスを読むことができます。", + "account_not_locked_warning_link": "鍵アカウント", + "attachments_sensitive": "ファイルを閲覧注意に設定する", "content_type": { "text/plain": "プレーンテキスト", "text/html": "HTML", "text/markdown": "Markdown", "text/bbcode": "BBCode" }, - "content_warning": "説明 (省略可)", + "content_warning": "注釈 (任意)", "default": "羽田空港に着きました。", - "direct_warning_to_all": "この投稿は、メンションされたすべてのユーザーが、見ることができます。", - "direct_warning_to_first_only": "この投稿は、メッセージの冒頭でメンションされたユーザーだけが、見ることができます。", + "direct_warning_to_all": "この投稿は、メンションされたすべてのユーザーが閲覧できます。", + "direct_warning_to_first_only": "この投稿は、メッセージの冒頭でメンションされたユーザーだけが閲覧できます。", "direct_warning": "このステータスは、メンションされたユーザーだけが、読むことができます。", "posting": "投稿", "scope_notice": { - "public": "この投稿は、誰でも見ることができます", - "private": "この投稿は、あなたのフォロワーだけが、見ることができます", - "unlisted": "この投稿は、パブリックタイムラインと、接続しているすべてのネットワークには、表示されません" + "public": "この投稿は誰でも閲覧できます", + "private": "この投稿はフォロワーのみ閲覧できます", + "unlisted": "この投稿は、公開タイムラインとすべてのネットワークには表示されません" }, "scope": { "direct": "ダイレクト: メンションされたユーザーのみに届きます", @@ -180,22 +216,29 @@ "public": "パブリック: 公開タイムラインに届きます", "unlisted": "アンリステッド: 公開タイムラインに届きません" }, - "media_description_error": "メディアのアップロードに失敗しました。もう一度お試しください", + "media_description_error": "メディアのアップデートに失敗しました。もう一度お試しください", "empty_status_error": "投稿内容を入力してください", "preview_empty": "何もありません", "preview": "プレビュー", "media_description": "メディアの説明", - "post": "投稿" + "post": "投稿", + "edit_status": "ステータスを編集", + "reply_option": "このステータスに返信する", + "quote_option": "このステータスを引用する", + "edit_remote_warning": "他のインスタンスは投稿の編集に対応していないかもしれません。その場合、編集した内容は伝わりません。", + "edit_unsupported_warning": "Pleromaは、メンションと投票の編集に対応していません。", + "scope_notice_dismiss": "このメッセージを閉じる", + "content_type_selection": "投稿形式" }, "registration": { "bio": "プロフィール", - "email": "Eメール", - "fullname": "スクリーンネーム", + "email": "メールアドレス", + "fullname": "表示名", "password_confirm": "パスワードの確認", "registration": "登録", - "token": "招待トークン", + "token": "招待コード", "captcha": "CAPTCHA", - "new_captcha": "文字が読めないときは、画像をクリックすると、新しい画像になります", + "new_captcha": "文字が読めない場合、画像をクリックすると新しい画像が表示されます", "username_placeholder": "例: lain", "fullname_placeholder": "例: 岩倉玲音", "bio_placeholder": "例:\nこんにちは。私は玲音。\n私はアニメのキャラクターで、日本の郊外に住んでいます。私をWiredで見たことがあるかもしれません。", @@ -205,11 +248,18 @@ "email_required": "必須", "password_required": "必須", "password_confirmation_required": "必須", - "password_confirmation_match": "パスワードが違います" + "password_confirmation_match": "パスワードが一致しません", + "birthday_required": "必須", + "birthday_min_age": "{date} 以降のユーザーは登録できません" }, - "reason_placeholder": "このインスタンスは、新規登録を手動で受け付けています。\n登録したい理由を、インスタンスの管理者に教えてください。", - "reason": "登録するための目的", - "register": "登録" + "reason_placeholder": "このインスタンスは、新規登録を手動で承認しています。\n登録したい理由をインスタンスの管理者に教えてください。", + "reason": "登録を希望する理由", + "register": "登録", + "email_language": "このサーバーからのメールをどの言語で受け取りますか?", + "bio_optional": "プロフィール (任意)", + "email_optional": "メールアドレス (任意)", + "birthday": "誕生日:", + "birthday_optional": "誕生日 (任意):" }, "selectable_list": { "select_all": "すべて選択" @@ -228,39 +278,39 @@ "warning_of_generate_new_codes": "新しいリカバリーコードを生成すると、古いコードは使用できなくなります。", "recovery_codes": "リカバリーコード。", "waiting_a_recovery_codes": "バックアップコードを受信しています…", - "recovery_codes_warning": "コードを紙に書くか、安全な場所に保存してください。そうでなければ、あなたはコードを再び見ることはできません。もし2段階認証アプリのアクセスを喪失し、なおかつ、リカバリーコードもないならば、あなたは自分のアカウントから閉め出されます。", + "recovery_codes_warning": "リカバリーコードをどこか安全な場所に書き留めてください。このコードは二度と表示されません。二段階認証アプリへのアクセスを失い、リカバリーコードも紛失した場合、二度とアカウントにログインできなくなります。", "authentication_methods": "認証方法", "scan": { "title": "スキャン", - "desc": "あなたの2段階認証アプリを使って、このQRコードをスキャンするか、テキストキーを入力してください:", + "desc": "二段階認証アプリでQRコードを読み取るか、テキストキーを入力してください:", "secret_code": "キー" }, "verify": { - "desc": "2段階認証を有効にするには、あなたの2段階認証アプリのコードを入力してください:" + "desc": "2段階認証を有効にするには、2段階認証アプリに表示されたコードを入力してください:" } }, "attachmentRadius": "ファイル", "attachments": "ファイル", - "avatar": "アバター", - "avatarAltRadius": "通知のアバター", - "avatarRadius": "アバター", + "avatar": "アイコン", + "avatarAltRadius": "通知内のアイコン", + "avatarRadius": "アイコン", "background": "バックグラウンド", "bio": "プロフィール", "block_export": "ブロックのエクスポート", "block_export_button": "ブロックをCSVファイルにエクスポートする", "block_import": "ブロックのインポート", "block_import_error": "ブロックのインポートに失敗しました", - "blocks_imported": "ブロックをインポートしました! 実際に処理されるまでに、しばらく時間がかかります。", + "blocks_imported": "ブロックがインポートされました。処理には時間がかかる場合があります。", "blocks_tab": "ブロック", "btnRadius": "ボタン", "cBlue": "返信とフォロー", "cGreen": "リピート", "cOrange": "お気に入り", "cRed": "キャンセル", - "change_password": "パスワードを変える", - "change_password_error": "パスワードを変えることが、できなかったかもしれません。", - "changed_password": "パスワードが、変わりました!", - "collapse_subject": "説明のある投稿をたたむ", + "change_password": "パスワードを変更", + "change_password_error": "パスワードの変更中にエラーが発生しました。", + "changed_password": "パスワードが変更されました!", + "collapse_subject": "注釈のついた投稿をたたむ", "composing": "投稿", "confirm_new_password": "新しいパスワードの確認", "current_avatar": "現在のアバター", @@ -268,52 +318,52 @@ "current_profile_banner": "現在のプロフィールバナー", "data_import_export_tab": "インポートとエクスポート", "default_vis": "デフォルトの公開範囲", - "delete_account": "アカウントを消す", - "delete_account_description": "あなたのデータが消えて、アカウントが使えなくなります。", - "delete_account_error": "アカウントを消すことが、できなかったかもしれません。インスタンスの管理者に、連絡してください。", - "delete_account_instructions": "本当にアカウントを消してもいいなら、パスワードを入力してください。", + "delete_account": "アカウントの削除", + "delete_account_description": "アカウントのデータを永久的に削除し、アカウントを無効化します。", + "delete_account_error": "アカウントの削除中にエラーが発生しました。継続して発生する場合、管理者に問い合せてください。", + "delete_account_instructions": "アカウント削除の確認のため、パスワードを入力してください。", "discoverable": "検索などのサービスでこのアカウントを見つけることを許可する", - "avatar_size_instruction": "アバターの大きさは、150×150ピクセルか、それよりも大きくするといいです。", - "pad_emoji": "ピッカーから絵文字を挿入するとき、絵文字の両側にスペースを入れる", - "export_theme": "保存", + "avatar_size_instruction": "アイコン画像のサイズは150x150以上を推奨します。", + "pad_emoji": "絵文字ピッカーから絵文字を挿入するとき、絵文字の前後に空白を挿入する", + "export_theme": "ファイルにテーマを出力", "filtering": "フィルタリング", - "filtering_explanation": "これらの言葉を含むすべてのものがミュートされます。1行に1つの言葉を書いてください", + "filtering_explanation": "以下の単語を含むステータスはミュートされます。(1行に1単語)", "follow_export": "フォローのエクスポート", "follow_export_button": "エクスポート", "follow_export_processing": "お待ちください。まもなくファイルをダウンロードできます。", "follow_import": "フォローのインポート", - "follow_import_error": "フォローのインポートがエラーになりました", - "follows_imported": "フォローがインポートされました! 少し時間がかかるかもしれません。", + "follow_import_error": "フォローのインポートに失敗しました", + "follows_imported": "フォローがインポートされました。処理には時間がかかる場合があります。", "foreground": "フォアグラウンド", "general": "全般", - "hide_attachments_in_convo": "スレッドのファイルを隠す", - "hide_attachments_in_tl": "タイムラインのファイルを隠す", - "hide_muted_posts": "ミュートしているユーザーの投稿を隠す", - "max_thumbnails": "投稿に含まれるサムネイルの最大数", - "hide_isp": "インスタンス固有パネルを隠す", + "hide_attachments_in_convo": "スレッド内のファイルを表示しない", + "hide_attachments_in_tl": "タイムラインのファイルを表示しない", + "hide_muted_posts": "ミュートしているユーザーの投稿を表示しない", + "max_thumbnails": "投稿に表示するサムネイルの最大数 (空にすると無制限)", + "hide_isp": "インスタンス固有パネルを表示しない", "preload_images": "画像を先読みする", - "use_one_click_nsfw": "NSFWなファイルを1クリックで開く", - "hide_post_stats": "投稿の統計を隠す (例: お気に入りの数)", - "hide_user_stats": "ユーザーの統計を隠す (例: フォロワーの数)", - "hide_filtered_statuses": "フィルターされた投稿を隠す", + "use_one_click_nsfw": "閲覧注意なファイルを1クリックで開く", + "hide_post_stats": "投稿の統計を表示しない (例: お気に入りの数)", + "hide_user_stats": "ユーザーの統計を表示しない (例: フォロワーの数)", + "hide_filtered_statuses": "フィルタリングされた投稿を表示しない", "import_blocks_from_a_csv_file": "CSVファイルからブロックをインポートする", "import_followers_from_a_csv_file": "CSVファイルからフォローをインポートする", - "import_theme": "ロード", - "inputRadius": "インプットフィールド", + "import_theme": "ファイルからテーマを読み込む", + "inputRadius": "入力欄", "checkboxRadius": "チェックボックス", "instance_default": "(デフォルト: {value})", "instance_default_simple": "(デフォルト)", "interface": "インターフェース", "interfaceLanguage": "インターフェースの言語", - "invalid_theme_imported": "このファイルはPleromaのテーマではありません。テーマは変更されませんでした。", - "limited_availability": "あなたのブラウザではできません", + "invalid_theme_imported": "非対応の形式のテーマファイルです。テーマは変更されませんでした。", + "limited_availability": "非対応のブラウザです", "links": "リンク", - "lock_account_description": "あなたが認めた人だけ、あなたのアカウントをフォローできる", - "loop_video": "ビデオを繰り返す", - "loop_video_silent_only": "音のないビデオだけ繰り返す", + "lock_account_description": "フォローを承認制にする", + "loop_video": "動画をループ再生する", + "loop_video_silent_only": "音声のない動画のみループ再生する", "mutes_tab": "ミュート", - "play_videos_in_modal": "ビデオをメディアビューアーで見る", - "use_contain_fit": "画像のサムネイルを、切り抜かない", + "play_videos_in_modal": "動画をメディアビューアで再生する", + "use_contain_fit": "画像のサムネイルを切り抜かない", "name": "名前", "name_bio": "名前とプロフィール", "new_password": "新しいパスワード", @@ -322,55 +372,55 @@ "notification_visibility_likes": "お気に入り", "notification_visibility_mentions": "メンション", "notification_visibility_repeats": "リピート", - "no_rich_text_description": "リッチテキストを使わない", - "no_blocks": "ブロックはありません", - "no_mutes": "ミュートはありません", - "hide_follows_description": "フォローしている人を見せない", - "hide_followers_description": "フォロワーを見せない", - "hide_follows_count_description": "フォローしている人の数を見せない", - "hide_followers_count_description": "フォロワーの数を見せない", - "show_admin_badge": "\"管理者\"のバッジを見せる", - "show_moderator_badge": "\"モデレーター\"のバッジを見せる", - "nsfw_clickthrough": "NSFWなファイルを隠す", + "no_rich_text_description": "投稿のテキスト装飾を無効化する", + "no_blocks": "ブロックしたユーザーはいません", + "no_mutes": "ミュートしたユーザーはいません", + "hide_follows_description": "フォロー欄を非公開にする", + "hide_followers_description": "フォロワー欄を非公開にする", + "hide_follows_count_description": "フォロー数を非公開にする", + "hide_followers_count_description": "フォロワー数を非公開にする", + "show_admin_badge": "プロフィールに「管理者」バッジを表示する", + "show_moderator_badge": "プロフィールに「モデレーター」バッジを表示する", + "nsfw_clickthrough": "閲覧注意なファイルを隠す", "oauth_tokens": "OAuthトークン", "token": "トークン", "refresh_token": "トークンを更新", - "valid_until": "まで有効", + "valid_until": "有効期限", "revoke_token": "取り消す", "panelRadius": "パネル", - "pause_on_unfocused": "タブにフォーカスがないときストリーミングを止める", + "pause_on_unfocused": "タブにフォーカスがないとき、タイムラインの自動更新を止める", "presets": "プリセット", "profile_background": "プロフィールの背景", "profile_banner": "プロフィールのバナー", "profile_tab": "プロフィール", - "radii_help": "インターフェースの丸さを設定する", - "replies_in_timeline": "タイムラインのリプライ", - "reply_visibility_all": "すべてのリプライを見る", - "reply_visibility_following": "私に宛てられたリプライと、フォローしている人からのリプライを見る", - "reply_visibility_self": "私に宛てられたリプライを見る", - "autohide_floating_post_button": "新しい投稿ボタンを自動的に隠す (モバイル)", + "radii_help": "インターフェースの角丸を設定する (ピクセル単位)", + "replies_in_timeline": "タイムライン上の返信", + "reply_visibility_all": "すべての返信を表示", + "reply_visibility_following": "自分、もしくはフォローしているユーザー宛ての返信のみを表示", + "reply_visibility_self": "自分に宛てられた返信のみを表示", + "autohide_floating_post_button": "投稿ボタンを自動的に隠す (モバイル)", "saving_err": "設定を保存できませんでした", "saving_ok": "設定を保存しました", "search_user_to_block": "ブロックしたいユーザーを検索", "search_user_to_mute": "ミュートしたいユーザーを検索", "security_tab": "セキュリティ", - "scope_copy": "返信するとき、公開範囲をコピーする (DMの公開範囲は、常にコピーされます)", - "minimal_scopes_mode": "公開範囲選択オプションを最小にする", - "set_new_avatar": "新しいアバターを設定する", - "set_new_profile_background": "新しいプロフィールのバックグラウンドを設定する", - "set_new_profile_banner": "新しいプロフィールバナーを設定する", + "scope_copy": "返信の公開範囲を返信先に合わせる", + "minimal_scopes_mode": "公開範囲選択オプションを最小化する", + "set_new_avatar": "アイコンを設定する", + "set_new_profile_background": "プロフィールの背景を設定する", + "set_new_profile_banner": "プロフィールのバナーを設定する", "settings": "設定", - "subject_input_always_show": "サブジェクトフィールドをいつでも表示する", - "subject_line_behavior": "返信するときサブジェクトをコピーする", - "subject_line_email": "メール風: \"re: サブジェクト\"", - "subject_line_mastodon": "マストドン風: そのままコピー", + "subject_input_always_show": "注釈欄をいつでも表示する", + "subject_line_behavior": "返信するとき、返信先の注釈をコピーする", + "subject_line_email": "メール風: \"re: 注釈\"", + "subject_line_mastodon": "Mastodon風: そのままコピー", "subject_line_noop": "コピーしない", - "post_status_content_type": "投稿のコンテントタイプ", - "stop_gifs": "カーソルを重ねたとき、GIFを動かす", - "streaming": "上までスクロールしたとき、自動的にストリーミングする", + "post_status_content_type": "デフォルトの投稿形式", + "stop_gifs": "GIFを自動再生しない", + "streaming": "上までスクロールしたとき、自動でタイムラインを更新する", "text": "文字", "theme": "テーマ", - "theme_help": "カラーテーマをカスタマイズできます。", + "theme_help": "カラーコード(#rrggbb)を使用してカラーテーマをカスタマイズできます。", "theme_help_v2_1": "チェックボックスをONにすると、コンポーネントごとに、色と透明度をオーバーライドできます。「すべてクリア」ボタンを押すと、すべてのオーバーライドをやめます。", "theme_help_v2_2": "バックグラウンドとテキストのコントラストを表すアイコンがあります。マウスをホバーすると、詳しい説明が出ます。透明な色を使っているときは、最悪の場合のコントラストが示されます。", "tooltipRadius": "ツールチップとアラート", @@ -381,9 +431,9 @@ "true": "はい" }, "notifications": "通知", - "notification_mutes": "特定のユーザーからの通知を止めるには、ミュートしてください。", - "notification_blocks": "ブロックしているユーザーからの通知は、すべて止まります。", - "enable_web_push_notifications": "ウェブプッシュ通知を許可する", + "notification_mutes": "特定のユーザーからの通知を止めるには、ミュートを使用してください。", + "notification_blocks": "ユーザーをブロックすると、そのユーザーからの通知はすべて停止されます。", + "enable_web_push_notifications": "プッシュ通知を有効にする", "style": { "switcher": { "keep_color": "色を残す", @@ -398,12 +448,12 @@ "help": { "snapshot_missing": "テーマのスナップショットがありません。思っていた見た目と違うかもしれません。", "migration_snapshot_ok": "念のために、テーマのスナップショットが読み込まれました。テーマのデータを読み込むことができます。", - "fe_downgraded": "フロントエンドが前のバージョンに戻りました。", - "fe_upgraded": "フロントエンドと一緒に、テーマエンジンが新しくなりました。", - "older_version_imported": "古いフロントエンドで作られたファイルをインポートしました。", - "future_version_imported": "新しいフロントエンドで作られたファイルをインポートしました。", - "v2_imported": "古いフロントエンドのためのファイルをインポートしました。設定した通りにならないかもしれません。", - "upgraded_from_v2": "フロントエンドが新しくなったので、今までの見た目と少し違うかもしれません。", + "fe_downgraded": "PleromaFEが前のバージョンに戻りました。", + "fe_upgraded": "PleromaFEのテーマエンジンが更新されました。", + "older_version_imported": "古いバージョンで作成されたファイルをインポートしました。", + "future_version_imported": "新しいバージョンで作成されたファイルをインポートしました。", + "v2_imported": "古いバージョンで作成されたファイルをインポートしました。設定した通りにならないかもしれません。", + "upgraded_from_v2": "PleromaFEが更新されました。テーマの表示が以前と異なる場合があります。", "snapshot_source_mismatch": "フロントエンドがロールバックと更新を繰り返したため、バージョンが競合しています。", "migration_napshot_gone": "スナップショットがありません、覚えているものと見た目が違うかもしれません。", "snapshot_present": "テーマのスナップショットが読み込まれました。設定は上書きされました。代わりとして実データを読み込むことができます。" @@ -432,7 +482,7 @@ "common_colors": { "_tab_label": "共通", "main": "共通の色", - "foreground_hint": "「詳細」タブで、もっと細かく設定できます", + "foreground_hint": "「詳細」タブで、より細かく設定できます", "rgbo": "アイコンとアクセントとバッジ" }, "advanced_colors": { @@ -445,7 +495,7 @@ "top_bar": "トップバー", "borders": "境界", "buttons": "ボタン", - "inputs": "インプットフィールド", + "inputs": "入力欄", "faint_text": "薄いテキスト", "alert_neutral": "それ以外", "chat": { @@ -498,7 +548,7 @@ "buttonHover": "ボタン (ホバー)", "buttonPressed": "ボタン (押されているとき)", "buttonPressedHover": "ボタン (ホバー、かつ、押されているとき)", - "input": "インプットフィールド" + "input": "入力欄" }, "hintV3": "影の場合は、 {0} 表記を使って他の色スロットを使うこともできます。" }, @@ -507,7 +557,7 @@ "help": "「カスタム」を選んだときは、システムにあるフォントの名前を、正しく入力してください。", "components": { "interface": "インターフェース", - "input": "インプットフィールド", + "input": "入力欄", "post": "投稿", "postCode": "等幅 (投稿がリッチテキストであるとき)" }, @@ -536,7 +586,7 @@ "backend_version": "バックエンドのバージョン", "frontend_version": "フロントエンドのバージョン" }, - "notification_setting_hide_notification_contents": "送った人と内容を、プッシュ通知に表示しない", + "notification_setting_hide_notification_contents": "送った人と通知の内容をプッシュ通知に表示しない", "notification_setting_privacy": "プライバシー", "notification_setting_block_from_strangers": "フォローしていないユーザーからの通知を拒否する", "notification_setting_filters": "フィルター", @@ -544,53 +594,55 @@ "virtual_scrolling": "タイムラインの描画を最適化する", "type_domains_to_mute": "ミュートしたいドメインを検索", "useStreamingApiWarning": "(実験中で、投稿を取りこぼすかもしれないので、おすすめしません)", - "useStreamingApi": "投稿と通知を、すぐに受け取る", + "useStreamingApi": "投稿と通知をリアルタイムで受信する", "user_mutes": "ユーザー", - "reset_background_confirm": "本当にバックグラウンドを初期化しますか?", - "reset_banner_confirm": "本当にバナーを初期化しますか?", - "reset_avatar_confirm": "本当にアバターを初期化しますか?", - "hide_wallpaper": "インスタンスのバックグラウンドを隠す", - "reset_profile_background": "プロフィールのバックグラウンドを初期化", - "reset_profile_banner": "プロフィールのバナーを初期化", - "reset_avatar": "アバターを初期化", + "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": "新しいメールアドレス", "profile_fields": { "value": "内容", "name": "ラベル", - "add_field": "枠を追加", - "label": "プロフィール補足情報" + "add_field": "入力欄を追加", + "label": "追加情報" }, "accent": "アクセント", - "mutes_imported": "ミュートをインポートしました!少し時間がかかるかもしれません。", + "mutes_imported": "ミュートがインポートされました。処理には時間がかかる場合があります。", "emoji_reactions_on_timeline": "絵文字リアクションをタイムラインに表示", "domain_mutes": "ドメイン", "mutes_and_blocks": "ミュートとブロック", "chatMessageRadius": "チャットメッセージ", - "change_email_error": "メールアドレスを変えることが、できなかったかもしれません。", - "changed_email": "メールアドレスが、変わりました!", - "change_email": "メールアドレスを変える", + "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": "はじめから投稿をセンシティブとして設定", + "allow_following_move": "フォローしているアカウントが引っ越したとき、引っ越し先を自動でフォローする", + "setting_changed": "デフォルトから変更された設定", + "greentext": ">記号から始まる行を「リピート」の色で表示 (Meme Arrows)", + "sensitive_by_default": "デフォルトで投稿を閲覧注意として設定", "more_settings": "その他の設定", - "reply_visibility_self_short": "自分宛のリプライを見る", - "reply_visibility_following_short": "フォローしている人に宛てられたリプライを見る", - "hide_all_muted_posts": "ミュートした投稿を隠す", - "hide_media_previews": "メディアのプレビューを隠す", + "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": "ファイルのマイナーバージョンが異なり、一部の設定が読み込まれないことがあります" + "invalid_file": "非対応の形式の設定ファイルです。設定は変更されませんでした。", + "file_slightly_new": "設定ファイルのバージョンが異なります。一部の設定は読み込まれないかもしれません", + "file_too_new": "互換性エラー: PleromaFEが古すぎます。設定ファイルのバージョン{fileMajor}はこのPleromaFE (バージョン{feMajor})と互換性がありません", + "file_too_old": "互換性エラー: 設定ファイルが古すぎます。設定ファイルのバージョン{fileMajor}はこのPleromaFE (バージョン{feMajor})と互換性がありません" }, "restore_settings": "設定をファイルから復元する", "backup_settings_theme": "テーマを含む設定をファイルにバックアップする", @@ -600,7 +652,121 @@ "save": "変更を保存", "hide_shoutbox": "Shoutboxを表示しない", "always_show_post_button": "投稿ボタンを常に表示", - "right_sidebar": "サイドバーを右に表示" + "right_sidebar": "サイドバーを右に表示", + "email_language": "このサーバーから受け取るメールの言語", + "confirm_dialogs": "以下のとき確認ダイアログを表示する:", + "confirm_dialogs_repeat": "ステータスをリピートするとき", + "confirm_dialogs_unfollow": "ユーザーのフォローを解除するとき", + "confirm_dialogs_block": "ユーザーをブロックするとき", + "confirm_dialogs_mute": "ユーザーをミュートするとき", + "confirm_dialogs_delete": "投稿を削除するとき", + "confirm_dialogs_logout": "ログアウトするとき", + "confirm_dialogs_deny_follow": "フォローリクエストを却下するとき", + "confirm_dialogs_remove_follower": "フォロワーを解除するとき", + "move_account_target": "引っ越し先のアカウント (例: {example})", + "move_account_error": "引っ越し中にエラーが発生しました: {error}", + "autocomplete_select_first": "オートコンプリートで最初の結果を自動的に選択する", + "hide_bot_indication": "bot アカウントであることを示すマークを表示しない", + "navbar_column_stretch": "ナビゲーションバーの幅を画面幅に合わせる", + "notification_visibility_follow_requests": "フォローリクエスト", + "notification_visibility_reports": "通報", + "notification_extra_chats": "未読のチャットを表示する", + "hide_favorites_description": "お気に入り欄を非公開にする (通知は送信されます)", + "conversation_display_tree": "ツリー形式", + "max_depth_in_thread": "デフォルトで表示するスレッドの深さ", + "mention_link_display": "メンションリンクを", + "mention_link_display_short": "常に短く表示する (例: {'@'}hoge)", + "mention_link_use_tooltip": "メンションリンクをクリックした時ユーザーカードを表示する", + "mention_link_show_avatar": "メンションリンクの横にユーザーのアイコンを表示する", + "mention_link_display_full_for_remote": "リモートのユーザーのみすべて表示する (例: {'@'}hoge{'@'}example.org)", + "mention_link_display_full": "常にすべて表示する (例: {'@'}hoge{'@'}example.org)", + "notification_setting_filters_chrome_push": "Chromeなどのブラウザでは、種類に応じた通知の無効化がプッシュ通知に反映されない場合があります", + "hard_reset_value_tooltip": "データベースから設定値を削除し、デフォルト値に戻します", + "disable_sticky_headers": "カラムヘッダーを画面上部に固定しない", + "column_sizes_notifs": "通知カラム", + "conversation_other_replies_button": "「その他の返信」ボタンの位置", + "use_websockets": "Websocketを利用してリアルタイムで更新を行う", + "mention_link_fade_domain": "メンションのドメイン部分を薄く表示する (例: {'@'}foo{'@'}example.org の {'@'}example.org の部分)", + "mention_link_show_avatar_quick": "メンションの横にユーザーアイコンを表示する", + "mention_link_bolden_you": "自分宛てのメンションを強調表示する", + "user_popover_avatar_action": "ユーザーカード内のユーザーアイコンをクリックした際の挙動", + "user_popover_avatar_overlay": "ユーザーカードをユーザーアイコンに被せて表示する", + "show_yous": "自分宛てのメンションの横に「(あなた)」を表示", + "preview": "プレビュー", + "url": "URL", + "conversation_display": "スレッドの表示形式", + "column_sizes": "カラム幅", + "third_column_mode_none": "表示しない", + "column_sizes_content": "コンテンツ", + "third_column_mode_notifications": "通知カラムにする", + "third_column_mode_postform": "投稿フォームとナビゲーションにする", + "conversation_display_linear_quick": "時系列表示", + "conversation_display_linear": "時系列形式", + "conversation_display_tree_quick": "ツリー表示", + "user_popover_avatar_action_open": "プロフィールを表示する", + "account_backup": "アカウントのバックアップ", + "wordfilter": "ワードフィルター", + "column_sizes_sidebar": "サイドバー", + "emoji_reactions_scale": "絵文字リアクションの表示倍率", + "hide_wordfiltered_statuses": "ワードフィルターによってフィルタリングされたステータスを表示しない", + "hide_muted_threads": "ミュートしたスレッドを表示しない", + "notification_visibility_polls": "投票結果の確定", + "user_popover_avatar_action_zoom": "アイコンを拡大する", + "post_look_feel": "投稿の表示形式", + "mention_links": "メンションのリンク", + "setting_server_side": "この設定はサーバー側に保存され、すべてのセッションとクライアントに影響します", + "word_filter_and_more": "ワードフィルターとその他の設定", + "notification_extra_announcements": "未読のお知らせを表示する", + "notification_extra_follow_requests": "新着のフォローリクエストを表示する", + "show_scrollbars": "サイドカラムにスクロールバーを表示する", + "third_column_mode": "十分に幅があるとき、三つ目のカラムを", + "columns": "カラム", + "commit_value": "保存", + "commit_value_tooltip": "値は保存されていません。反映するにはこのボタンを押してください", + "remove_backup": "削除", + "add_backup": "新規バックアップを作成", + "account_backup_description": "アカウント情報と投稿のアーカイブをダウンロードできます。開発段階の機能であり、現状、ダウンロードしたデータをインポートすることはできません。", + "mute_bot_posts": "bot アカウントの投稿をミュートする", + "auto_update": "自動でタイムラインを更新する", + "enable_web_push_always_show_tip": "この設定は、Chromeなどのブラウザで「このサイトはバックグラウンドで更新されました」という通知が表示されることを防止します。その他のブラウザでこの設定を有効化すると、通知が二重で表示されることがあります。", + "backup_failed": "バックアップに失敗しました。", + "confirm_dialogs_approve_follow": "フォローリクエストを承認するとき", + "moved_account": "アカウントの引っ越しが完了しました。", + "reset_value": "リセット", + "reset_value_tooltip": "編集中の値を破棄します", + "hard_reset_value": "デフォルトに戻す", + "conversation_other_replies_button_below": "投稿の下", + "conversation_other_replies_button_inside": "投稿の中", + "add_language": "代替言語を追加", + "remove_language": "削除", + "account_alias_table_head": "エイリアス", + "account_alias": "アカウントエイリアス", + "list_aliases_error": "エイリアスの取得中にエラーが発生しました: {error}", + "hide_list_aliases_error_action": "閉じる", + "remove_alias": "削除", + "new_alias_target": "エイリアスを追加 (例: {example})", + "added_alias": "エイリアスが追加されました。", + "add_alias_error": "エイリアスの追加中にエラーが発生しました: {error}", + "move_account": "アカウントの引っ越し", + "move_account_notes": "アカウントを引っ越すためには、まず引っ越し先のアカウントにこのアカウントへのエイリアスを追加する必要があります。", + "birthday": { + "label": "誕生日", + "show_birthday": "誕生日を公開する" + }, + "account_privacy": "プライバシー", + "posts": "投稿", + "user_profiles": "ユーザープロフィール", + "primary_language": "第一言語:", + "fallback_language": "代替言語 {index}:", + "expert_mode": "高度な設定を表示", + "account_backup_table_head": "バックアップ", + "download_backup": "ダウンロード", + "backup_not_ready": "まだ準備中です。", + "backup_running": "処理中…{number}件のデータが処理されました。 | 処理中… {number}件のデータが処理されました。", + "list_backups_error": "バックアップ一覧の取得に失敗しました: {error}", + "added_backup": "バックアップがキューに追加されました。", + "add_backup_error": "バックアップの追加に失敗しました: {error}", + "user_popover_avatar_action_close": "ユーザーカードを閉じる" }, "time": { "day": "{0}日", @@ -622,7 +788,7 @@ "month_short": "{0}ヶ月前", "months_short": "{0}ヶ月前", "now": "たった今", - "now_short": "たった今", + "now_short": "今", "second": "{0}秒", "seconds": "{0}秒", "second_short": "{0}秒", @@ -634,23 +800,41 @@ "year": "{0}年", "years": "{0}年", "year_short": "{0}年", - "years_short": "{0}年" + "years_short": "{0}年", + "unit": { + "seconds_short": "{0}秒", + "weeks": "{0} 週間 | {0} 週間", + "weeks_short": "{0}週", + "years": "{0} 年 | {0} 年", + "years_short": "{0}年", + "days": "{0} 日 | {0} 日", + "hours": "{0} 時間 | {0} 時間", + "hours_short": "{0}時間", + "minutes": "{0} 分 | {0} 分", + "minutes_short": "{0}分", + "months": "{0} ヶ月 | {0} ヶ月", + "months_short": "{0}ヶ月", + "seconds": "{0} 秒 | {0} 秒", + "days_short": "{0}日" + } }, "timeline": { "collapse": "たたむ", "conversation": "スレッド", "error_fetching": "読み込みがエラーになりました", - "load_older": "古いステータス", - "no_retweet_hint": "投稿を「フォロワーのみ」または「ダイレクト」にすると、リピートできなくなります", + "load_older": "古いステータスを読み込む", + "no_retweet_hint": "公開範囲が「フォロワーのみ」または「ダイレクト」の投稿はリピートできません", "repeated": "リピート", "show_new": "読み込み", "up_to_date": "最新", "no_more_statuses": "これで終わりです", "no_statuses": "ステータスはありません", "reload": "再読み込み", - "error": "タイムラインの読み込みに失敗しました: {0}", + "error": "タイムラインの読み込み中にエラーが発生しました: {0}", "socket_reconnected": "リアルタイム接続が確立されました", - "socket_broke": "コード{0}によりリアルタイム接続が切断されました" + "socket_broke": "リアルタイム接続が切断されました: コード{0}", + "quick_view_settings": "表示の簡易設定", + "quick_filter_settings": "フィルターの簡易設定" }, "status": { "favorites": "お気に入り", @@ -659,8 +843,8 @@ "pin": "プロフィールにピン留め", "unpin": "プロフィールのピン留めを外す", "pinned": "ピン留め", - "delete_confirm": "本当にこのステータスを削除してもよろしいですか?", - "reply_to": "返信", + "delete_confirm": "本当にこの削除しますか?", + "reply_to": "返信先:", "replies_list": "返信:", "mute_conversation": "スレッドをミュート", "unmute_conversation": "スレッドのミュートを解除", @@ -679,19 +863,52 @@ "unbookmark": "ブックマーク解除", "bookmark": "ブックマーク", "mentions": "メンション", - "you": "(あなた)", - "plus_more": "ほか{number}件" + "you": "(あなた)", + "plus_more": "ほか{number}件", + "delete_confirm_title": "削除の確認", + "ancestor_follow": "このステータスについた{numReplies}件の返信をすべて表示 | このステータスについた{numReplies}件の返信をすべて表示", + "invisible_quote": "引用先のステータスが存在しません: {link}", + "ancestor_follow_with_icon": "{icon} {text}", + "show_all_conversation_with_icon": "{icon} {text}", + "delete_error": "ステータスの削除中にエラーが発生しました: {0}", + "delete_confirm_accept_button": "削除する", + "delete_confirm_cancel_button": "削除しない", + "collapse_attachments": "ファイルをたたむ", + "show_all_attachments": "すべてのファイルを表示", + "hide_attachment": "ファイルを隠す", + "reaction_count_label": "{num}人がリアクションしました | {num}人がリアクションしました", + "repeat_confirm_accept_button": "リピートする", + "repeat_confirm_cancel_button": "リピートしない", + "repeat_confirm": "本当にリピートしますか?", + "edit": "ステータスを編集", + "edited_at": "(最終編集: {time})", + "repeat_confirm_title": "リピートの確認", + "many_attachments": "この投稿には{number}件のファイルが添付されています", + "remove_attachment": "ファイルを削除", + "attachment_stop_flash": "Flashプレーヤーを停止", + "move_up": "ファイルを左へ移動", + "move_down": "ファイルを右へ移動", + "thread_follow": "このスレッドの残りを表示 (全部で{numStatus}件の投稿があります) | このスレッドの残りを表示 (全部で{numStatus}件の投稿があります)", + "thread_follow_with_icon": "{icon} {text}", + "hide_quote": "引用先を隠す", + "display_quote": "引用先を表示", + "show_only_conversation_under_this": "このステータスへの返信のみを表示", + "show_all_conversation": "スレッドの全体を表示 ({numStatus}件のステータス) | スレッドの全体を表示 ({numStatus}件のステータス)", + "replies_list_with_others": "返信 (+{numReplies}人): | 返信 (+{numReplies}人):", + "more_actions": "その他のアクション", + "thread_show_full": "このスレッドをすべて表示 (全部で{depth}層、{numStatus}件の投稿があります) | このスレッドを全て表示 (全部で{depth}層、{numStatus}件の投稿があります)", + "thread_show_full_with_icon": "{icon} {text}" }, "user_card": { - "approve": "受け入れ", + "approve": "承認", "block": "ブロック", "blocked": "ブロックしています!", - "deny": "お断り", + "deny": "拒否", "favorites": "お気に入り", "follow": "フォロー", - "follow_sent": "リクエストを送りました!", + "follow_sent": "リクエストを送信しました!", "follow_progress": "リクエストしています…", - "follow_unfollow": "フォローをやめる", + "follow_unfollow": "フォロー解除", "followees": "フォロー", "followers": "フォロワー", "following": "フォローしています!", @@ -700,7 +917,7 @@ "media": "メディア", "mention": "メンション", "mute": "ミュート", - "muted": "ミュートしています", + "muted": "ミュート済み", "per_day": "/日", "remote_follow": "リモートフォロー", "report": "通報", @@ -722,14 +939,15 @@ "activate_account": "アカウントをアクティブにする", "deactivate_account": "アカウントをアクティブでなくする", "delete_account": "アカウントを削除", - "force_nsfw": "すべての投稿をNSFWにする", - "strip_media": "投稿からメディアを除去する", - "force_unlisted": "投稿を未収載にする", - "sandbox": "投稿をフォロワーのみにする", - "disable_remote_subscription": "他のインスタンスからフォローされないようにする", - "disable_any_subscription": "フォローされないようにする", - "quarantine": "他のインスタンスからの投稿を止める", - "delete_user": "ユーザーを削除" + "force_nsfw": "すべての投稿を閲覧注意にする", + "strip_media": "すべての投稿からメディアを除去する", + "force_unlisted": "すべての投稿をアンリステッドにする", + "sandbox": "すべての投稿をフォロワー限定にする", + "disable_remote_subscription": "他のインスタンスからフォローできないようにする", + "disable_any_subscription": "フォローできないようにする", + "quarantine": "投稿を連合しないようにする", + "delete_user": "ユーザーを削除", + "delete_user_data_and_deactivate_confirmation": "このアカウントのデータを永久に削除し、アカウントを無効化します。本当によろしいですね?" }, "roles": { "moderator": "モデレーター", @@ -746,21 +964,53 @@ "side": "端に線を付ける", "disabled": "強調しない" }, - "edit_profile": "プロフィールを編集" + "edit_profile": "プロフィールを編集", + "deny_confirm_accept_button": "拒否する", + "note_blank": "(なし)", + "edit_note_cancel": "キャンセル", + "remove_follower_confirm_cancel_button": "解除しない", + "block_confirm_title": "ブロックの確認", + "block_confirm": "本当に{user}をブロックしますか?", + "birthday": "誕生日: {birthday}", + "edit_note": "メモを編集", + "edit_note_apply": "適用", + "note": "メモ", + "remove_follower_confirm": "本当に{user}からのフォローを解除しますか?", + "follow_cancel": "リクエストを取り消す", + "approve_confirm_title": "承認の確認", + "remove_follower": "フォロワーを解除", + "remove_follower_confirm_title": "フォロワー解除の確認", + "approve_confirm_accept_button": "承認する", + "deny_confirm": "本当に{user}からのフォローリクエストを拒否しますか?", + "deny_confirm_cancel_button": "拒否しない", + "mute_confirm_cancel_button": "ミュートしない", + "approve_confirm_cancel_button": "承認しない", + "approve_confirm": "本当に{user}からのフォローリクエストを承認しますか?", + "unfollow_confirm_title": "フォロー解除の確認", + "unfollow_confirm_cancel_button": "解除しない", + "mute_confirm_accept_button": "ミュートする", + "mute_confirm": "本当に{user}をミュートしますか?", + "block_confirm_accept_button": "ブロックする", + "block_confirm_cancel_button": "ブロックしない", + "deny_confirm_title": "拒否の確認", + "unfollow_confirm": "本当に{user}のフォローを解除しますか?", + "unfollow_confirm_accept_button": "解除する", + "remove_follower_confirm_accept_button": "解除する", + "mute_confirm_title": "ミュートの確認" }, "user_profile": { "timeline_title": "ユーザータイムライン", - "profile_does_not_exist": "申し訳ない。このプロフィールは存在しません。", - "profile_loading_error": "申し訳ない。プロフィールの読み込みがエラーになりました。" + "profile_does_not_exist": "このプロフィールは存在しません。", + "profile_loading_error": "プロフィールの読み込み中にエラーが発生しました。" }, "user_reporting": { - "title": "通報する: {0}", + "title": "{0}を通報する", "add_comment_description": "この通報は、あなたのインスタンスのモデレーターに送られます。このアカウントを通報する理由を説明することができます:", "additional_comments": "追加のコメント", - "forward_description": "このアカウントは他のサーバーに置かれています。この通報のコピーをリモートのサーバーに送りますか?", - "forward_to": "転送する: {0}", + "forward_description": "これは他のインスタンスのアカウントです。この通報のコピーをリモートのインスタンスに送りますか?", + "forward_to": "{0}に転送する", "submit": "送信", - "generic_error": "あなたのリクエストを処理しようとしましたが、エラーになりました。" + "generic_error": "リクエストの処理中にエラーが発生しました。" }, "who_to_follow": { "more": "詳細", @@ -774,15 +1024,15 @@ "user_settings": "ユーザー設定", "bookmark": "ブックマーク", "reject_follow_request": "フォローリクエストを拒否", - "accept_follow_request": "フォローリクエストを許可", + "accept_follow_request": "フォローリクエストを承認", "add_reaction": "リアクションを追加" }, "upload": { "error": { "base": "アップロードに失敗しました。", - "file_too_big": "ファイルが大きすぎます [{filesize} {filesizeunit} / {allowedsize} {allowedsizeunit}]", - "default": "しばらくしてから試してください", - "message": "アップロードに失敗: {0}" + "file_too_big": "ファイルが大きすぎます [{filesize}{filesizeunit} / {allowedsize}{allowedsizeunit}]", + "default": "時間を置いて再試行してください", + "message": "アップロードに失敗しました: {0}" }, "file_size_units": { "B": "B", @@ -793,11 +1043,12 @@ } }, "search": { - "people": "人々", + "people": "ユーザー", "hashtags": "ハッシュタグ", "person_talking": "{count} 人が話しています", "people_talking": "{count} 人が話しています", - "no_results": "見つかりませんでした" + "no_results": "見つかりませんでした", + "load_more": "さらに読み込む" }, "password_reset": { "forgot_password": "パスワードを忘れましたか?", @@ -820,20 +1071,22 @@ "media_nsfw": "メディアを閲覧注意に設定", "media_removal_desc": "このインスタンスでは、以下のインスタンスからの投稿に対して、メディアを除去します:", "media_removal": "メディア除去", - "ftl_removal": "「既知のネットワーク」タイムラインから除外", - "ftl_removal_desc": "このインスタンスでは、以下のインスタンスを「既知のネットワーク」タイムラインから除外します:", + "ftl_removal": "「すべてのネットワーク」タイムラインから除外", + "ftl_removal_desc": "このインスタンスでは、以下のインスタンスを「すべてのネットワーク」タイムラインから除外します:", "quarantine_desc": "このインスタンスでは、以下のインスタンスに対して公開投稿のみを送信します:", "quarantine": "検疫", "reject_desc": "このインスタンスでは、以下のインスタンスからのメッセージを受け付けません:", "accept_desc": "このインスタンスでは、以下のインスタンスからのメッセージのみを受け付けます:", "accept": "許可", "simple_policies": "インスタンス固有のポリシー", - "reject": "拒否" + "reject": "拒否", + "instance": "インスタンス", + "reason": "理由" }, "mrf_policies": "有効なMRFポリシー", "keyword": { "replace": "置き換え", - "ftl_removal": "「接続しているすべてのネットワーク」タイムラインから除外", + "ftl_removal": "「すべてのネットワーク」タイムラインから除外", "keyword_policies": "キーワードポリシー", "is_replaced_by": "→", "reject": "拒否" @@ -847,8 +1100,8 @@ "file_type": { "file": "ファイル", "image": "画像", - "video": "ビデオ", - "audio": "オーディオ" + "video": "動画", + "audio": "音声" }, "remote_user_resolver": { "error": "見つかりませんでした。", @@ -865,7 +1118,7 @@ "empty_chat_list_placeholder": "チャットはありません。新規チャットのボタンを押して始めましょう!", "error_sending_message": "メッセージの送信に失敗しました。", "error_loading_chat": "チャットの読み込みに失敗しました。", - "delete_confirm": "このメッセージを本当に消してもいいですか?", + "delete_confirm": "本当にこのメッセージを削除しますか?", "more": "もっと見る", "empty_message_error": "メッセージを入力して下さい", "new": "新規チャット", @@ -879,5 +1132,151 @@ "unmute": "ミュート解除", "mute_progress": "ミュート中…", "mute": "ミュート" + }, + "admin_dash": { + "window_title": "管理者設定", + "nodb": { + "text": "{property}が{value}に設定されるよう、設定ファイルを編集する必要があります。詳しくは{documentation}を確認してください。", + "documentation": "ドキュメント", + "text2": "ほとんどの設定項目は利用できません。", + "heading": "データベースへの設定の保存は無効化されています" + }, + "captcha": { + "native": "ネイティブ", + "kocaptcha": "KoCaptcha" + }, + "instance": { + "restrict": { + "header": "匿名ユーザーへのアクセス制限", + "profiles": "ユーザープロフィールへのアクセス", + "timelines": "タイムラインへのアクセス", + "activities": "ステータスへのアクセス", + "description": "この設定は特定のAPIへのアクセスを制御します。デフォルトでは、インスタンスの公開設定を反映します。一部の設定は、変更すると予期しない動作を引き起こすことがあります(例: ユーザープロフィールへのアクセスを禁止すると、投稿にユーザーの情報が表示されなくなります)。" + }, + "instance": "インスタンス情報", + "registrations": "ユーザー登録", + "access": "インスタンスへのアクセス", + "captcha_header": "CAPTCHA", + "kocaptcha": "KoCaptchaの設定" + }, + "frontend": { + "available_frontends": "インストール可能なフロントエンド", + "success_installing_frontend": "{version} は正常にインストールされました", + "failure_installing_frontend": "{version} のインストールに失敗しました: {reason}", + "repository": "リポジトリのURL", + "versions": "利用可能なバージョン", + "build_url": "ダウンロードURL", + "reinstall": "再インストール", + "install": "インストール", + "install_version": "バージョン {version} をインストール", + "is_default": "(デフォルト)", + "is_default_custom": "(デフォルト、バージョン: {version})", + "default_frontend": "デフォルトのフロントエンド", + "more_install_options": "その他のインストールオプション", + "wip_notice": "このセクションは開発段階です。バックエンド側の実装が未完成であるため、一部の機能は欠けています。", + "set_default": "デフォルトに設定", + "set_default_version": "バージョン {version} をデフォルトに設定", + "default_frontend_tip": "デフォルトのフロントエンドはすべてのユーザーに表示されます。現時点で、ユーザーがフロントエンドを選択する方法はありません。デフォルトのフロントエンドをPleromaFE以外に設定した場合、インスタンスの設定を変更するには古いAdminFEを使用する必要があります。" + }, + "temp_overrides": { + ":pleroma": { + ":instance": { + ":public": { + "label": "インスタンスを公開する", + "description": "この設定を無効化すると、すべてのAPIの使用にログインが必要になります。これにより、匿名ユーザーは公開タイムラインとすべてのネットワークにアクセスできなくなります。" + }, + ":background_image": { + "description": "(主にPleromaFEで使用される)背景画像", + "label": "背景画像" + }, + ":limit_to_local_content": { + "description": "他インスタンスの情報の検索を、未ログインのユーザー(デフォルト)もしくはすべてのユーザーに対して制限します", + "label": "検索をローカルのみに制限する" + }, + ":description_limit": { + "description": "ファイルの説明欄に対する文字数制限", + "label": "制限" + } + } + } + }, + "wip_notice": "この管理者用設定画面は試験段階であり、未完成です。{adminFeLink}。", + "reset_all": "すべてリセット", + "commit_all": "すべて保存", + "old_ui_link": "これまでの管理者画面にはここからアクセスできます", + "tabs": { + "limits": "制限", + "instance": "インスタンス", + "frontends": "フロントエンド" + }, + "limits": { + "arbitrary_limits": "変更可能な制限", + "posts": "投稿の制限", + "uploads": "ファイルの制限", + "profile_fields": "追加情報欄の制限", + "user_uploads": "プロフィール画像の制限", + "users": "ユーザープロフィールの設定" + } + }, + "lists": { + "search": "ユーザーを検索", + "update_title": "リスト名を保存", + "really_delete": "本当に削除しますか?", + "error": "リストの処理中にエラーが発生しました: {0}", + "lists": "リスト", + "new": "新規リスト", + "save": "変更を保存", + "delete": "リストを削除", + "editing_list": "{listTitle}の編集", + "creating_list": "新規リストの作成", + "create": "作成", + "title": "リスト名", + "following_only": "フォローしているユーザーのみ表示", + "manage_lists": "リストの管理", + "manage_members": "メンバーの管理", + "add_members": "ユーザーの追加", + "remove_from_list": "リストから削除", + "add_to_list": "リストに追加", + "is_in_list": "追加済み" + }, + "update": { + "update_bugs": "何か問題を見つけたら{pleromaGitlab}にて報告してください。開発中のバージョンにて念入りに確認はしましたが、様々なものが変更されているため、我々が見逃したものがあるかもしれません。バグの報告や、Pleroma/PleromaFEを改善するための提案やフィードバックは大歓迎です。", + "update_changelog_here": "変更履歴", + "update_changelog": "全ての変更点は{theFullChangelog}を参照してください。", + "big_update_content": "久しぶりのリリースですので、今までと異なるところがあるかもしれません。", + "update_bugs_gitlab": "Pleroma GitLab", + "big_update_title": "" + }, + "report": { + "reported_statuses": "通報されたステータス:", + "notes": "メモ:", + "state": "状態:", + "state_open": "未解決", + "reporter": "通報者:", + "state_resolved": "解決済み", + "reported_user": "被通報者:", + "state_closed": "問題なし" + }, + "unicode_domain_indicator": { + "tooltip": "このドメインには非ASCII文字が含まれています。" + }, + "announcements": { + "page_header": "お知らせ", + "title": "お知らせ", + "mark_as_read_action": "既読にする", + "post_form_header": "お知らせを投稿", + "post_placeholder": "お知らせの内容を入力してください…", + "post_action": "投稿", + "post_error": "エラー: {error}", + "close_error": "閉じる", + "delete_action": "削除", + "submit_edit_action": "完了", + "cancel_edit_action": "キャンセル", + "published_time_display": "{time} に公開", + "start_time_display": "{time}から開始", + "end_time_display": "{time}に終了", + "edit_action": "編集", + "start_time_prompt": "開始日時: ", + "end_time_prompt": "終了日時: " } } From b8a036ee64471b4337e642c5d2f50f5c8a3a8f8d Mon Sep 17 00:00:00 2001 From: SyoBoN Date: Sat, 23 Dec 2023 04:50:20 +0000 Subject: [PATCH 111/405] Translated using Weblate (Japanese (ja_PEDANTIC)) Currently translated at 96.5% (1048 of 1086 strings) Translation: Pleroma/Pleroma-FE Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/ja_PEDANTIC/ --- src/i18n/ja_pedantic.json | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/src/i18n/ja_pedantic.json b/src/i18n/ja_pedantic.json index 5d04fb6e..63ae7865 100644 --- a/src/i18n/ja_pedantic.json +++ b/src/i18n/ja_pedantic.json @@ -175,7 +175,8 @@ "custom": "カスタム絵文字", "unicode": "Unicode絵文字", "load_all": "全 {emojiAmount} 絵文字を読み込む", - "load_all_hint": "最初の {saneAmount} 件の絵文字を読み込みました。すべて読み込むとパフォーマンスに影響を与える可能性があります。" + "load_all_hint": "最初の {saneAmount} 件の絵文字を読み込みました。すべて読み込むとパフォーマンスに影響を与える可能性があります。", + "unpacked": "パック外の絵文字" }, "stickers": { "add_sticker": "ステッカーを追加" @@ -766,7 +767,9 @@ "list_backups_error": "バックアップ一覧の取得に失敗しました: {error}", "added_backup": "バックアップがキューに追加されました。", "add_backup_error": "バックアップの追加に失敗しました: {error}", - "user_popover_avatar_action_close": "ユーザーカードを閉じる" + "user_popover_avatar_action_close": "ユーザーカードを閉じる", + "tree_advanced": "高度なナビゲーションボタンを表示する", + "tree_fade_ancestors": "スレッド上で祖先にあたるステータスを薄いテキストで表示する" }, "time": { "day": "{0}日", @@ -897,7 +900,13 @@ "replies_list_with_others": "返信 (+{numReplies}人): | 返信 (+{numReplies}人):", "more_actions": "その他のアクション", "thread_show_full": "このスレッドをすべて表示 (全部で{depth}層、{numStatus}件の投稿があります) | このスレッドを全て表示 (全部で{depth}層、{numStatus}件の投稿があります)", - "thread_show_full_with_icon": "{icon} {text}" + "thread_show_full_with_icon": "{icon} {text}", + "show_attachment_in_modal": "メディアビューアで開く", + "show_attachment_description": "メディアの説明文をポップアップで表示 (全文を読むにはメディアを開いてください)", + "thread_hide": "このスレッドをたたむ", + "thread_show": "このスレッドを開く", + "open_gallery": "メディアビューアで開く", + "status_history": "編集履歴" }, "user_card": { "approve": "承認", @@ -937,7 +946,7 @@ "grant_moderator": "モデレーター権限を付与", "revoke_moderator": "モデレーター権限を解除", "activate_account": "アカウントをアクティブにする", - "deactivate_account": "アカウントをアクティブでなくする", + "deactivate_account": "アカウントを無効化する", "delete_account": "アカウントを削除", "force_nsfw": "すべての投稿を閲覧注意にする", "strip_media": "すべての投稿からメディアを除去する", @@ -996,7 +1005,8 @@ "unfollow_confirm": "本当に{user}のフォローを解除しますか?", "unfollow_confirm_accept_button": "解除する", "remove_follower_confirm_accept_button": "解除する", - "mute_confirm_title": "ミュートの確認" + "mute_confirm_title": "ミュートの確認", + "deactivated": "無効化済み" }, "user_profile": { "timeline_title": "ユーザータイムライン", @@ -1048,7 +1058,8 @@ "person_talking": "{count} 人が話しています", "people_talking": "{count} 人が話しています", "no_results": "見つかりませんでした", - "load_more": "さらに読み込む" + "load_more": "さらに読み込む", + "no_more_results": "結果は以上です" }, "password_reset": { "forgot_password": "パスワードを忘れましたか?", @@ -1234,7 +1245,7 @@ "following_only": "フォローしているユーザーのみ表示", "manage_lists": "リストの管理", "manage_members": "メンバーの管理", - "add_members": "ユーザーの追加", + "add_members": "メンバーの追加", "remove_from_list": "リストから削除", "add_to_list": "リストに追加", "is_in_list": "追加済み" @@ -1277,6 +1288,7 @@ "end_time_display": "{time}に終了", "edit_action": "編集", "start_time_prompt": "開始日時: ", - "end_time_prompt": "終了日時: " + "end_time_prompt": "終了日時: ", + "all_day_prompt": "終日" } } From 0110fd86c2f166de5be8d675ffa34ab815463b2d Mon Sep 17 00:00:00 2001 From: tusooa Date: Wed, 27 Dec 2023 22:30:19 -0500 Subject: [PATCH 112/405] Allow user to mark account as group --- src/boot/after_store.js | 1 + src/components/settings_modal/tabs/profile_tab.js | 10 ++++++++-- .../settings_modal/tabs/profile_tab.vue | 15 ++++++++++++--- src/i18n/en.json | 5 ++++- src/modules/instance.js | 1 + .../entity_normalizer.service.js | 1 + 6 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/boot/after_store.js b/src/boot/after_store.js index 84fea954..7039f85a 100644 --- a/src/boot/after_store.js +++ b/src/boot/after_store.js @@ -261,6 +261,7 @@ const getNodeInfo = async ({ store }) => { store.dispatch('setInstanceOption', { name: 'pollLimits', value: metadata.pollLimits }) store.dispatch('setInstanceOption', { name: 'mailerEnabled', value: metadata.mailerEnabled }) store.dispatch('setInstanceOption', { name: 'quotingAvailable', value: features.includes('quote_posting') }) + store.dispatch('setInstanceOption', { name: 'groupActorAvailable', value: features.includes('pleroma:group_actors') }) const uploadLimits = metadata.uploadLimits store.dispatch('setInstanceOption', { name: 'uploadlimit', value: parseInt(uploadLimits.general) }) diff --git a/src/components/settings_modal/tabs/profile_tab.js b/src/components/settings_modal/tabs/profile_tab.js index eeacad48..3cb3ae45 100644 --- a/src/components/settings_modal/tabs/profile_tab.js +++ b/src/components/settings_modal/tabs/profile_tab.js @@ -9,6 +9,7 @@ import suggestor from 'src/components/emoji_input/suggestor.js' import Autosuggest from 'src/components/autosuggest/autosuggest.vue' import Checkbox from 'src/components/checkbox/checkbox.vue' import InterfaceLanguageSwitcher from 'src/components/interface_language_switcher/interface_language_switcher.vue' +import Select from 'src/components/select/select.vue' import BooleanSetting from '../helpers/boolean_setting.vue' import SharedComputedObject from '../helpers/shared_computed_object.js' import localeService from 'src/services/locale/locale.service.js' @@ -39,6 +40,7 @@ const ProfileTab = { showRole: this.$store.state.users.currentUser.show_role, role: this.$store.state.users.currentUser.role, bot: this.$store.state.users.currentUser.bot, + actorType: this.$store.state.users.currentUser.actor_type, pickAvatarBtnVisible: true, bannerUploading: false, backgroundUploading: false, @@ -57,7 +59,8 @@ const ProfileTab = { ProgressButton, Checkbox, BooleanSetting, - InterfaceLanguageSwitcher + InterfaceLanguageSwitcher, + Select }, computed: { user () { @@ -116,6 +119,9 @@ const ProfileTab = { bannerImgSrc () { const src = this.$store.state.users.currentUser.cover_photo return (!src) ? this.defaultBanner : src + }, + availableActorTypes () { + return this.$store.state.instance.groupActorAvailable ? ['Person', 'Service', 'Group'] : ['Person', 'Service'] } }, methods: { @@ -127,7 +133,7 @@ const ProfileTab = { /* eslint-disable camelcase */ display_name: this.newName, fields_attributes: this.newFields.filter(el => el != null), - bot: this.bot, + actor_type: this.actorType, show_role: this.showRole, birthday: this.newBirthday || '', show_birthday: this.showBirthday diff --git a/src/components/settings_modal/tabs/profile_tab.vue b/src/components/settings_modal/tabs/profile_tab.vue index 1cc850cb..e6dc5987 100644 --- a/src/components/settings_modal/tabs/profile_tab.vue +++ b/src/components/settings_modal/tabs/profile_tab.vue @@ -109,9 +109,18 @@

- - {{ $t('settings.bot') }} - +

{ output.show_role = data.source.pleroma.show_role output.discoverable = data.source.pleroma.discoverable output.show_birthday = data.pleroma.show_birthday + output.actor_type = data.source.pleroma.actor_type } } From 4777bec85fd5488c5c50d5452efe26a51f90f53e Mon Sep 17 00:00:00 2001 From: tusooa Date: Wed, 27 Dec 2023 22:36:13 -0500 Subject: [PATCH 113/405] Add a description on what groups do --- src/components/settings_modal/tabs/profile_tab.js | 5 ++++- src/components/settings_modal/tabs/profile_tab.vue | 5 +++++ src/i18n/en.json | 1 + 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/components/settings_modal/tabs/profile_tab.js b/src/components/settings_modal/tabs/profile_tab.js index 3cb3ae45..dee17450 100644 --- a/src/components/settings_modal/tabs/profile_tab.js +++ b/src/components/settings_modal/tabs/profile_tab.js @@ -120,8 +120,11 @@ const ProfileTab = { const src = this.$store.state.users.currentUser.cover_photo return (!src) ? this.defaultBanner : src }, + groupActorAvailable () { + return this.$store.state.instance.groupActorAvailable + }, availableActorTypes () { - return this.$store.state.instance.groupActorAvailable ? ['Person', 'Service', 'Group'] : ['Person', 'Service'] + return this.groupActorAvailable ? ['Person', 'Service', 'Group'] : ['Person', 'Service'] } }, methods: { diff --git a/src/components/settings_modal/tabs/profile_tab.vue b/src/components/settings_modal/tabs/profile_tab.vue index e6dc5987..de5219a7 100644 --- a/src/components/settings_modal/tabs/profile_tab.vue +++ b/src/components/settings_modal/tabs/profile_tab.vue @@ -122,6 +122,11 @@

+
+ + {{ $t('settings.actor_type_description') }} + +

Date: Wed, 27 Dec 2023 22:40:07 -0500 Subject: [PATCH 114/405] Make user card group-aware --- src/components/user_card/user_card.vue | 8 +++++++- src/i18n/en.json | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue index 2de14063..2c76a220 100644 --- a/src/components/user_card/user_card.vue +++ b/src/components/user_card/user_card.vue @@ -124,11 +124,17 @@ {{ $t(`general.role.${visibleRole}`) }} {{ $t('user_card.bot') }} + + {{ $t('user_card.group') }} + Date: Wed, 27 Dec 2023 22:54:44 -0500 Subject: [PATCH 115/405] Implement indicator for groups --- src/components/settings_modal/tabs/filtering_tab.vue | 2 +- src/components/status/status.js | 10 ++-------- src/components/status/status.vue | 6 +++--- src/components/user_avatar/user_avatar.js | 8 +++++--- src/components/user_avatar/user_avatar.vue | 11 ++++++++--- src/i18n/en.json | 2 +- 6 files changed, 20 insertions(+), 19 deletions(-) diff --git a/src/components/settings_modal/tabs/filtering_tab.vue b/src/components/settings_modal/tabs/filtering_tab.vue index 89fdef1a..9e82fcfd 100644 --- a/src/components/settings_modal/tabs/filtering_tab.vue +++ b/src/components/settings_modal/tabs/filtering_tab.vue @@ -51,7 +51,7 @@

  • - {{ $t('settings.hide_bot_indication') }} + {{ $t('settings.hide_actor_type_indication') }}
  • @@ -133,7 +133,7 @@ >
    diff --git a/src/components/user_avatar/user_avatar.js b/src/components/user_avatar/user_avatar.js index 33d9a258..ffd81f87 100644 --- a/src/components/user_avatar/user_avatar.js +++ b/src/components/user_avatar/user_avatar.js @@ -3,11 +3,13 @@ import StillImage from '../still-image/still-image.vue' import { library } from '@fortawesome/fontawesome-svg-core' import { - faRobot + faRobot, + faPeopleGroup } from '@fortawesome/free-solid-svg-icons' library.add( - faRobot + faRobot, + faPeopleGroup ) const UserAvatar = { @@ -15,7 +17,7 @@ const UserAvatar = { 'user', 'betterShadow', 'compact', - 'bot' + 'showActorTypeIndicator' ], data () { return { diff --git a/src/components/user_avatar/user_avatar.vue b/src/components/user_avatar/user_avatar.vue index 91c17611..3cbccec3 100644 --- a/src/components/user_avatar/user_avatar.vue +++ b/src/components/user_avatar/user_avatar.vue @@ -18,9 +18,14 @@ :class="{ '-compact': compact }" /> + @@ -79,7 +84,7 @@ height: 100%; } - .bot-indicator { + .actor-type-indicator { position: absolute; bottom: 0; right: 0; diff --git a/src/i18n/en.json b/src/i18n/en.json index bb93f26f..71098822 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -499,7 +499,7 @@ "hide_media_previews": "Hide media previews", "hide_muted_posts": "Hide posts of muted users", "mute_bot_posts": "Mute bot posts", - "hide_bot_indication": "Hide bot indication in posts", + "hide_actor_type_indication": "Hide actor type (bots, groups, etc.) indication in posts", "hide_scrobbles": "Hide scrobbles", "hide_all_muted_posts": "Hide muted posts", "max_thumbnails": "Maximum amount of thumbnails per post (empty = no limit)", From a709127a3c9b20d9d6cca6d9d4f00754a4726428 Mon Sep 17 00:00:00 2001 From: tusooa Date: Wed, 27 Dec 2023 22:55:58 -0500 Subject: [PATCH 116/405] Use actor type to determine whether a user is a bot --- src/components/status/status.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/status/status.js b/src/components/status/status.js index 458c8554..8f22b708 100644 --- a/src/components/status/status.js +++ b/src/components/status/status.js @@ -233,7 +233,7 @@ const Status = { return muteWordHits(this.status, this.muteWords) }, botStatus () { - return this.status.user.bot + return this.status.user.actor_type === 'Service' }, showActorTypeIndicator () { return !this.hideBotIndication From 16f326216a7e3b560bd33b58f6f6cf44fb81ad54 Mon Sep 17 00:00:00 2001 From: tusooa Date: Wed, 27 Dec 2023 22:56:47 -0500 Subject: [PATCH 117/405] Add changelog for group actors --- changelog.d/group-actor.add | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/group-actor.add diff --git a/changelog.d/group-actor.add b/changelog.d/group-actor.add new file mode 100644 index 00000000..7b62676a --- /dev/null +++ b/changelog.d/group-actor.add @@ -0,0 +1 @@ +Support group actors From 6f452d672fe740035cf1d29d03bcda0d39438753 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?marcin=20miko=C5=82ajczak?= Date: Thu, 28 Dec 2023 10:43:06 +0100 Subject: [PATCH 118/405] Display public favorites on user profiles MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: marcin mikołajczak --- changelog.d/public-favorites.add | 1 + src/components/user_profile/user_profile.js | 5 +++++ src/components/user_profile/user_profile.vue | 3 ++- src/services/api/api.service.js | 6 ++++++ src/services/entity_normalizer/entity_normalizer.service.js | 1 + 5 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 changelog.d/public-favorites.add diff --git a/changelog.d/public-favorites.add b/changelog.d/public-favorites.add new file mode 100644 index 00000000..183fcc85 --- /dev/null +++ b/changelog.d/public-favorites.add @@ -0,0 +1 @@ +Display public favorites on user profiles \ No newline at end of file diff --git a/src/components/user_profile/user_profile.js b/src/components/user_profile/user_profile.js index acb612ed..751bfd5a 100644 --- a/src/components/user_profile/user_profile.js +++ b/src/components/user_profile/user_profile.js @@ -80,6 +80,9 @@ const UserProfile = { followersTabVisible () { return this.isUs || !this.user.hide_followers }, + favoritesTabVisible () { + return this.isUs || !this.user.hide_favorites + }, formattedBirthday () { const browserLocale = localeService.internalToBrowserLocale(this.$i18n.locale) return this.user.birthday && new Date(Date.parse(this.user.birthday)).toLocaleDateString(browserLocale, { timeZone: 'UTC', day: 'numeric', month: 'long', year: 'numeric' }) @@ -103,6 +106,8 @@ const UserProfile = { startFetchingTimeline('user', userId) startFetchingTimeline('media', userId) if (this.isUs) { + startFetchingTimeline('favorites') + } else if (!this.user.hide_favorites) { startFetchingTimeline('favorites', userId) } // Fetch all pinned statuses immediately diff --git a/src/components/user_profile/user_profile.vue b/src/components/user_profile/user_profile.vue index c63a303c..d0618dbb 100644 --- a/src/components/user_profile/user_profile.vue +++ b/src/components/user_profile/user_profile.vue @@ -109,7 +109,7 @@ :footer-slipgate="footerRef" /> diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js index bde2e163..19de07f7 100644 --- a/src/services/api/api.service.js +++ b/src/services/api/api.service.js @@ -108,6 +108,7 @@ const PLEROMA_POST_ANNOUNCEMENT_URL = '/api/v1/pleroma/admin/announcements' const PLEROMA_EDIT_ANNOUNCEMENT_URL = id => `/api/v1/pleroma/admin/announcements/${id}` const PLEROMA_DELETE_ANNOUNCEMENT_URL = id => `/api/v1/pleroma/admin/announcements/${id}` const PLEROMA_SCROBBLES_URL = id => `/api/v1/pleroma/accounts/${id}/scrobbles` +const PLEROMA_USER_FAVORITES_TIMELINE_URL = id => `/api/v1/pleroma/accounts/${id}/favourites` const PLEROMA_ADMIN_CONFIG_URL = '/api/pleroma/admin/config' const PLEROMA_ADMIN_DESCRIPTIONS_URL = '/api/pleroma/admin/config/descriptions' @@ -690,6 +691,7 @@ const fetchTimeline = ({ media: MASTODON_USER_TIMELINE_URL, list: MASTODON_LIST_TIMELINE_URL, favorites: MASTODON_USER_FAVORITES_TIMELINE_URL, + publicFavorites: PLEROMA_USER_FAVORITES_TIMELINE_URL, tag: MASTODON_TAG_TIMELINE_URL, bookmarks: MASTODON_BOOKMARK_TIMELINE_URL } @@ -698,6 +700,10 @@ const fetchTimeline = ({ let url = timelineUrls[timeline] + if (timeline === 'favorites' && userId) { + url = timelineUrls.publicFavorites(userId) + } + if (timeline === 'user' || timeline === 'media') { url = url(userId) } diff --git a/src/services/entity_normalizer/entity_normalizer.service.js b/src/services/entity_normalizer/entity_normalizer.service.js index 85da5223..97b5beb5 100644 --- a/src/services/entity_normalizer/entity_normalizer.service.js +++ b/src/services/entity_normalizer/entity_normalizer.service.js @@ -107,6 +107,7 @@ export const parseUser = (data) => { output.allow_following_move = data.pleroma.allow_following_move + output.hide_favorites = data.pleroma.hide_favorites output.hide_follows = data.pleroma.hide_follows output.hide_followers = data.pleroma.hide_followers output.hide_follows_count = data.pleroma.hide_follows_count From f177e0fe2474de9319b47eab6ffe4c5520c1edc7 Mon Sep 17 00:00:00 2001 From: nixe neko Date: Wed, 27 Dec 2023 14:37:07 +0000 Subject: [PATCH 119/405] Translated using Weblate (Japanese (ja_EASY)) Currently translated at 91.8% (997 of 1086 strings) Translation: Pleroma/Pleroma-FE Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/ja_EASY/ --- src/i18n/ja_easy.json | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/i18n/ja_easy.json b/src/i18n/ja_easy.json index 21b27d12..c5ed3b6c 100644 --- a/src/i18n/ja_easy.json +++ b/src/i18n/ja_easy.json @@ -163,7 +163,8 @@ "search_close": "けんさくバーをとじる", "edit_nav_mobile": "ナビゲーションバーのせっていをかえる", "mobile_sidebar": "モバイルのサイドバーをきりかえる", - "edit_finish": "へんしゅうをおわりにする" + "edit_finish": "へんしゅうをおわりにする", + "mobile_notifications_mark_as_seen": "ぜんぶ みたことにする" }, "notifications": { "broken_favorite": "ステータスがみつかりません。さがしています…", @@ -179,7 +180,13 @@ "migrated_to": "インスタンスを、ひっこしました", "reacted_with": "{0} でリアクションしました", "poll_ended": "とうひょうが、おわりました", - "submitted_report": "つうほうしました" + "submitted_report": "つうほうしました", + "unread_announcements": "まだ よんでいない おしらせが {num}こ あります", + "configuration_tip_settings": "せってい", + "configuration_tip_dismiss": "つぎは ひょうじしない", + "unread_chats": "よんでいない チャットが {num}こ あります", + "unread_follow_requests": "フォローリクエストが {num}こ あります", + "configuration_tip": "ここに ひょうじする ものを {theSettings}で へんこうできます。 {dismiss}" }, "polls": { "add_poll": "とうひょうをはじめる", @@ -218,7 +225,8 @@ "symbols": "きごう", "travel-and-places": "りょこう・ばしょ" }, - "regional_indicator": "ばしょをしめすきごう {letter}" + "regional_indicator": "ばしょをしめすきごう {letter}", + "unpacked": "アンパックされた えもじ" }, "stickers": { "add_sticker": "ステッカーをふやす" @@ -269,7 +277,9 @@ "preview": "プレビュー", "preview_empty": "なにもありません", "empty_status_error": "とうこうないようを、にゅうりょくしてください", - "scope_notice_dismiss": "このつうちをとじる" + "scope_notice_dismiss": "このつうちをとじる", + "reply_option": "この ステータスに へんしんする", + "quote_option": "この ステータスを いんようする" }, "registration": { "bio": "プロフィール", @@ -324,7 +334,7 @@ "warning_of_generate_new_codes": "あたらしいリカバリーコードをつくったら、ふるいコードはつかえなくなります。", "recovery_codes": "リカバリーコード。", "waiting_a_recovery_codes": "バックアップコードをうけとっています…", - "recovery_codes_warning": "コードをかきうつすか、ひとにみられないところにセーブしてください。そうでなければ、あなたはこのコードをふたたびみることはできません。もしあなたが、2FAアプリのアクセスをうしなって、なおかつ、リカバリーコードもおもいだせないならば、あなたはあなたのアカウントから、しめだされます。", + "recovery_codes_warning": "コードを かきうつすか、 ほかのひとが みれないところに ほぞんしてください。 そうしないと、 あなたは このコードを にどと みることができません。 もし あなたが 2FAアプリに アクセスできなくなり、 リカバリーコードも おもいだせないなら、 あなたは あなたの アカウントに はいれなくなります。", "authentication_methods": "にんしょうメソッド", "scan": { "title": "スキャン", @@ -697,9 +707,9 @@ "import_mutes_from_a_csv_file": "CSVファイルからミュートをインポートする", "reset_avatar": "アバターをリセットする", "remove_language": "とりのぞく", - "primary_language": "いちばんわかることば:", + "primary_language": "さいしょに つかう ことば:", "add_language": "よびとしてつかうことばを、ついかする", - "fallback_language": "よびとしてつかうことば {index}:", + "fallback_language": "よびとして つかう ことば {index}:", "lists_navigation": "ナビゲーションにリストをひょうじする", "account_alias": "アカウントのエイリアス", "mention_link_display_full": "いつも、ながいなまえをひょうじする (れい: {'@'}hoge{'@'}example.org)", @@ -797,7 +807,11 @@ "virtual_scrolling": "タイムラインのレンダリングをよくする", "use_at_icon": "{'@'} きごうを、もじのかわりに、アイコンでひょうじする", "mention_link_display_short": "いつも、みじかいなまえにする (れい: {'@'}hoge)", - "mention_link_display": "メンションのリンクをひょうじするけいしき" + "mention_link_display": "メンションのリンクをひょうじするけいしき", + "url": "URL", + "preview": "プレビュー", + "emoji_reactions_scale": "リアクションを なんばいの おおきさで ひょうじするか", + "autocomplete_select_first": "じどうほかんが あれば、 さいしょの ものを じどうで えらぶ" }, "time": { "day": "{0}日", From 3c4eaaab2c2cab1ad00ac3b4688d6c30c1ad173e Mon Sep 17 00:00:00 2001 From: Xnuk Shuman Date: Fri, 29 Dec 2023 04:08:17 +0000 Subject: [PATCH 120/405] Translated using Weblate (Korean) Currently translated at 97.6% (1061 of 1086 strings) Translation: Pleroma/Pleroma-FE Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/ko/ --- src/i18n/ko.json | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/i18n/ko.json b/src/i18n/ko.json index 69d898ba..003878db 100644 --- a/src/i18n/ko.json +++ b/src/i18n/ko.json @@ -109,7 +109,8 @@ "mobile_notifications_close": "알림 닫기", "mobile_sidebar": "모바일 사이드바 토글", "announcements": "공지사항", - "search_close": "검색 바 닫기" + "search_close": "검색 바 닫기", + "mobile_notifications_mark_as_seen": "모두 읽음으로 표시" }, "notifications": { "broken_favorite": "알 수 없는 게시물입니다, 검색합니다…", @@ -125,7 +126,13 @@ "error": "알림 불러오기 실패: {0}", "follow_request": "팔로우 요청", "submitted_report": "신고 내용을 전송함", - "poll_ended": "투표가 끝남" + "poll_ended": "투표가 끝남", + "unread_follow_requests": "{num}개의 새 팔로우 요청 | {num}개의 새 팔로우 요청", + "configuration_tip": "{theSettings}에서 어떻게 보이는지 바꿀 수 있습니다. {dismiss}", + "configuration_tip_settings": "설정", + "configuration_tip_dismiss": "다시 보지 않기", + "unread_announcements": "{num}개의 읽지 않은 공지사항 | {num}개의 읽지 않은 공지사항", + "unread_chats": "{num}개의 읽지 않은 채팅 | {num}개의 읽지 않은 채팅" }, "post_status": { "new_status": "새 게시물 게시", @@ -165,7 +172,9 @@ "post": "게시", "direct_warning_to_first_only": "맨 앞에 멘션한 사용자들에게만 보여집니다.", "content_type_selection": "게시물 형태", - "scope_notice_dismiss": "알림 닫기" + "scope_notice_dismiss": "알림 닫기", + "reply_option": "이 게시물에 답글", + "quote_option": "이 게시물을 인용" }, "registration": { "bio": "소개", From f3cdcaa172d0e17642eb634a91982c4286352734 Mon Sep 17 00:00:00 2001 From: SyoBoN Date: Sat, 30 Dec 2023 12:43:35 +0000 Subject: [PATCH 121/405] Translated using Weblate (Japanese (ja_PEDANTIC)) Currently translated at 96.5% (1049 of 1086 strings) Translation: Pleroma/Pleroma-FE Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/ja_PEDANTIC/ --- src/i18n/ja_pedantic.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i18n/ja_pedantic.json b/src/i18n/ja_pedantic.json index 63ae7865..0b20ffff 100644 --- a/src/i18n/ja_pedantic.json +++ b/src/i18n/ja_pedantic.json @@ -60,7 +60,8 @@ "unlisted": "アンリステッド" }, "generic_error_message": "エラーが発生しました: {0}", - "never_show_again": "二度と表示しない" + "never_show_again": "二度と表示しない", + "undo": "取り消す" }, "image_cropper": { "crop_picture": "画像を切り抜く", From 6c4c8fe51f0e2c4ce55f5915a2bc5434aef5e5e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?marcin=20miko=C5=82ajczak?= Date: Thu, 4 Jan 2024 22:46:04 +0100 Subject: [PATCH 122/405] Display quotes count on posts and add quotes list page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: marcin mikołajczak --- changelog.d/quotes-count.add | 1 + src/boot/routes.js | 2 ++ .../quotes_timeline/quotes_timeline.js | 26 +++++++++++++++++++ .../quotes_timeline/quotes_timeline.vue | 10 +++++++ src/components/status/status.scss | 1 + src/components/status/status.vue | 13 ++++++++++ src/components/timeline/timeline.js | 3 +++ src/components/timeline_menu/timeline_menu.js | 3 ++- src/i18n/en.json | 4 ++- src/modules/api.js | 5 ++-- src/services/api/api.service.js | 9 ++++++- .../backend_interactor_service.js | 4 +-- .../entity_normalizer.service.js | 1 + .../timeline_fetcher.service.js | 8 +++--- 14 files changed, 80 insertions(+), 10 deletions(-) create mode 100644 changelog.d/quotes-count.add create mode 100644 src/components/quotes_timeline/quotes_timeline.js create mode 100644 src/components/quotes_timeline/quotes_timeline.vue diff --git a/changelog.d/quotes-count.add b/changelog.d/quotes-count.add new file mode 100644 index 00000000..86779b96 --- /dev/null +++ b/changelog.d/quotes-count.add @@ -0,0 +1 @@ +Display quotes count on posts and add quotes list page \ No newline at end of file diff --git a/src/boot/routes.js b/src/boot/routes.js index 2dc900e7..31e3dbb0 100644 --- a/src/boot/routes.js +++ b/src/boot/routes.js @@ -25,6 +25,7 @@ import ListsTimeline from 'components/lists_timeline/lists_timeline.vue' import ListsEdit from 'components/lists_edit/lists_edit.vue' import NavPanel from 'src/components/nav_panel/nav_panel.vue' import AnnouncementsPage from 'components/announcements_page/announcements_page.vue' +import QuotesTimeline from '../components/quotes_timeline/quotes_timeline.vue' export default (store) => { const validateAuthenticatedRoute = (to, from, next) => { @@ -51,6 +52,7 @@ export default (store) => { { name: 'tag-timeline', path: '/tag/:tag', component: TagTimeline }, { name: 'bookmarks', path: '/bookmarks', component: BookmarkTimeline }, { name: 'conversation', path: '/notice/:id', component: ConversationPage, meta: { dontScroll: true } }, + { name: 'quotes', path: '/notice/:id/quotes', component: QuotesTimeline }, { name: 'remote-user-profile-acct', path: '/remote-users/:_(@)?:username([^/@]+)@:hostname([^/@]+)', diff --git a/src/components/quotes_timeline/quotes_timeline.js b/src/components/quotes_timeline/quotes_timeline.js new file mode 100644 index 00000000..a5f42da5 --- /dev/null +++ b/src/components/quotes_timeline/quotes_timeline.js @@ -0,0 +1,26 @@ +import Timeline from '../timeline/timeline.vue' + +const QuotesTimeline = { + created () { + this.$store.commit('clearTimeline', { timeline: 'quotes' }) + this.$store.dispatch('startFetchingTimeline', { timeline: 'quotes', statusId: this.statusId }) + }, + components: { + Timeline + }, + computed: { + statusId () { return this.$route.params.id }, + timeline () { return this.$store.state.statuses.timelines.quotes } + }, + watch: { + statusId () { + this.$store.commit('clearTimeline', { timeline: 'quotes' }) + this.$store.dispatch('startFetchingTimeline', { timeline: 'quotes', statusId: this.statusId }) + } + }, + unmounted () { + this.$store.dispatch('stopFetchingTimeline', 'quotes') + } +} + +export default QuotesTimeline diff --git a/src/components/quotes_timeline/quotes_timeline.vue b/src/components/quotes_timeline/quotes_timeline.vue new file mode 100644 index 00000000..835abd12 --- /dev/null +++ b/src/components/quotes_timeline/quotes_timeline.vue @@ -0,0 +1,10 @@ + + + diff --git a/src/components/status/status.scss b/src/components/status/status.scss index 760c6ac1..54c4b4ff 100644 --- a/src/components/status/status.scss +++ b/src/components/status/status.scss @@ -398,6 +398,7 @@ font-weight: bolder; font-size: 1.1em; line-height: 1em; + color: var(--selectedPostText, $fallback--text); } &:hover .stat-title { diff --git a/src/components/status/status.vue b/src/components/status/status.vue index fa9d6f0b..11dc1e2e 100644 --- a/src/components/status/status.vue +++ b/src/components/status/status.vue @@ -506,6 +506,19 @@
    + +
    + {{ $t('status.quotes') }} +
    + {{ statusFromGlobalRepository.quotes_count }} +
    +
    +
    diff --git a/src/components/timeline/timeline.js b/src/components/timeline/timeline.js index 1050b87a..6cb9d1f1 100644 --- a/src/components/timeline/timeline.js +++ b/src/components/timeline/timeline.js @@ -25,6 +25,7 @@ const Timeline = { 'title', 'userId', 'listId', + 'statusId', 'tag', 'embedded', 'count', @@ -121,6 +122,7 @@ const Timeline = { showImmediately, userId: this.userId, listId: this.listId, + statusId: this.statusId, tag: this.tag }) }, @@ -183,6 +185,7 @@ const Timeline = { showImmediately: true, userId: this.userId, listId: this.listId, + statusId: this.statusId, tag: this.tag }).then(({ statuses }) => { if (statuses && statuses.length === 0) { diff --git a/src/components/timeline_menu/timeline_menu.js b/src/components/timeline_menu/timeline_menu.js index 5a2a86c2..c4586b32 100644 --- a/src/components/timeline_menu/timeline_menu.js +++ b/src/components/timeline_menu/timeline_menu.js @@ -19,7 +19,8 @@ export const timelineNames = () => { bookmarks: 'nav.bookmarks', dms: 'nav.dms', 'public-timeline': 'nav.public_tl', - 'public-external-timeline': 'nav.twkn' + 'public-external-timeline': 'nav.twkn', + quotes: 'nav.quotes' } } diff --git a/src/i18n/en.json b/src/i18n/en.json index f4c9de18..96b84c90 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -190,7 +190,8 @@ "mobile_notifications": "Open notifications (there are unread ones)", "mobile_notifications_close": "Close notifications", "mobile_notifications_mark_as_seen": "Mark all as seen", - "announcements": "Announcements" + "announcements": "Announcements", + "quotes": "Quotes" }, "notifications": { "broken_favorite": "Unknown status, searching for it…", @@ -996,6 +997,7 @@ "status": { "favorites": "Favorites", "repeats": "Repeats", + "quotes": "Quotes", "repeat_confirm": "Do you really want to repeat this status?", "repeat_confirm_title": "Repeat confirmation", "repeat_confirm_accept_button": "Repeat", diff --git a/src/modules/api.js b/src/modules/api.js index fee584e8..3dbead5b 100644 --- a/src/modules/api.js +++ b/src/modules/api.js @@ -202,12 +202,13 @@ const api = { timeline = 'friends', tag = false, userId = false, - listId = false + listId = false, + statusId = false }) { if (store.state.fetchers[timeline]) return const fetcher = store.state.backendInteractor.startFetchingTimeline({ - timeline, store, userId, listId, tag + timeline, store, userId, listId, statusId, tag }) store.commit('addFetcher', { fetcherName: timeline, fetcher }) }, diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js index bde2e163..004698e7 100644 --- a/src/services/api/api.service.js +++ b/src/services/api/api.service.js @@ -108,6 +108,7 @@ const PLEROMA_POST_ANNOUNCEMENT_URL = '/api/v1/pleroma/admin/announcements' const PLEROMA_EDIT_ANNOUNCEMENT_URL = id => `/api/v1/pleroma/admin/announcements/${id}` const PLEROMA_DELETE_ANNOUNCEMENT_URL = id => `/api/v1/pleroma/admin/announcements/${id}` const PLEROMA_SCROBBLES_URL = id => `/api/v1/pleroma/accounts/${id}/scrobbles` +const PLEROMA_STATUS_QUOTES_URL = id => `/api/v1/pleroma/statuses/${id}/quotes` const PLEROMA_ADMIN_CONFIG_URL = '/api/pleroma/admin/config' const PLEROMA_ADMIN_DESCRIPTIONS_URL = '/api/pleroma/admin/config/descriptions' @@ -675,6 +676,7 @@ const fetchTimeline = ({ until = false, userId = false, listId = false, + statusId = false, tag = false, withMuted = false, replyVisibility = 'all', @@ -691,7 +693,8 @@ const fetchTimeline = ({ list: MASTODON_LIST_TIMELINE_URL, favorites: MASTODON_USER_FAVORITES_TIMELINE_URL, tag: MASTODON_TAG_TIMELINE_URL, - bookmarks: MASTODON_BOOKMARK_TIMELINE_URL + bookmarks: MASTODON_BOOKMARK_TIMELINE_URL, + quotes: PLEROMA_STATUS_QUOTES_URL } const isNotifications = timeline === 'notifications' const params = [] @@ -706,6 +709,10 @@ const fetchTimeline = ({ url = url(listId) } + if (timeline === 'quotes') { + url = url(statusId) + } + if (minId) { params.push(['min_id', minId]) } diff --git a/src/services/backend_interactor_service/backend_interactor_service.js b/src/services/backend_interactor_service/backend_interactor_service.js index 62ee8549..8ceb897d 100644 --- a/src/services/backend_interactor_service/backend_interactor_service.js +++ b/src/services/backend_interactor_service/backend_interactor_service.js @@ -5,8 +5,8 @@ import followRequestFetcher from '../../services/follow_request_fetcher/follow_r import listsFetcher from '../../services/lists_fetcher/lists_fetcher.service.js' const backendInteractorService = credentials => ({ - startFetchingTimeline ({ timeline, store, userId = false, listId = false, tag }) { - return timelineFetcher.startFetching({ timeline, store, credentials, userId, listId, tag }) + startFetchingTimeline ({ timeline, store, userId = false, listId = false, statusId = false, tag }) { + return timelineFetcher.startFetching({ timeline, store, credentials, userId, listId, statusId, tag }) }, fetchTimeline (args) { diff --git a/src/services/entity_normalizer/entity_normalizer.service.js b/src/services/entity_normalizer/entity_normalizer.service.js index 85da5223..4d671c5d 100644 --- a/src/services/entity_normalizer/entity_normalizer.service.js +++ b/src/services/entity_normalizer/entity_normalizer.service.js @@ -329,6 +329,7 @@ export const parseStatus = (data) => { output.quote_id = pleroma.quote_id ? pleroma.quote_id : (output.quote ? output.quote.id : undefined) output.quote_url = pleroma.quote_url output.quote_visible = pleroma.quote_visible + output.quotes_count = pleroma.quotes_count } else { output.text = data.content output.summary = data.spoiler_text diff --git a/src/services/timeline_fetcher/timeline_fetcher.service.js b/src/services/timeline_fetcher/timeline_fetcher.service.js index 8501907e..2fed14bc 100644 --- a/src/services/timeline_fetcher/timeline_fetcher.service.js +++ b/src/services/timeline_fetcher/timeline_fetcher.service.js @@ -24,6 +24,7 @@ const fetchAndUpdate = ({ showImmediately = false, userId = false, listId = false, + statusId = false, tag = false, until, since @@ -47,6 +48,7 @@ const fetchAndUpdate = ({ args.userId = userId args.listId = listId + args.statusId = statusId args.tag = tag args.withMuted = !hideMutedPosts if (loggedIn && ['friends', 'public', 'publicAndExternal'].includes(timeline)) { @@ -78,15 +80,15 @@ const fetchAndUpdate = ({ }) } -const startFetching = ({ timeline = 'friends', credentials, store, userId = false, listId = false, tag = false }) => { +const startFetching = ({ timeline = 'friends', credentials, store, userId = false, listId = false, statusId = false, tag = false }) => { const rootState = store.rootState || store.state const timelineData = rootState.statuses.timelines[camelCase(timeline)] const showImmediately = timelineData.visibleStatuses.length === 0 timelineData.userId = userId timelineData.listId = listId - fetchAndUpdate({ timeline, credentials, store, showImmediately, userId, listId, tag }) + fetchAndUpdate({ timeline, credentials, store, showImmediately, userId, listId, statusId, tag }) const boundFetchAndUpdate = () => - fetchAndUpdate({ timeline, credentials, store, userId, listId, tag }) + fetchAndUpdate({ timeline, credentials, store, userId, listId, statusId, tag }) return promiseInterval(boundFetchAndUpdate, 10000) } const timelineFetcher = { From 091532d577ae9a23f7a43f681bfd344f040c7738 Mon Sep 17 00:00:00 2001 From: Ekaterina Vaartis Date: Sun, 7 Jan 2024 02:45:49 +0300 Subject: [PATCH 123/405] Editing emojis in popover, pack creation/deletion Also fixed some API calls since they weren't working apparently --- .../settings_modal/admin_tabs/emoji_tab.js | 117 ++++++++-- .../settings_modal/admin_tabs/emoji_tab.scss | 22 ++ .../settings_modal/admin_tabs/emoji_tab.vue | 206 ++++++++++++------ .../settings_modal_admin_content.vue | 2 +- src/services/api/api.service.js | 14 +- 5 files changed, 272 insertions(+), 89 deletions(-) diff --git a/src/components/settings_modal/admin_tabs/emoji_tab.js b/src/components/settings_modal/admin_tabs/emoji_tab.js index f9d3b24e..874d1c3b 100644 --- a/src/components/settings_modal/admin_tabs/emoji_tab.js +++ b/src/components/settings_modal/admin_tabs/emoji_tab.js @@ -1,20 +1,46 @@ +import { clone } from 'lodash' import TabSwitcher from 'src/components/tab_switcher/tab_switcher.jsx' import StringSetting from '../helpers/string_setting.vue' import Checkbox from 'components/checkbox/checkbox.vue' import StillImage from 'components/still-image/still-image.vue' +import Select from 'components/select/select.vue' +import Popover from 'components/popover/popover.vue' +import ConfirmModal from 'components/confirm_modal/confirm_modal.vue' +import ModifiedIndicator from '../helpers/modified_indicator.vue' const EmojiTab = { components: { TabSwitcher, StringSetting, Checkbox, - StillImage + StillImage, + Select, + Popover, + ConfirmModal, + ModifiedIndicator }, data () { return { knownPacks: { }, - editedParts: { } + editedParts: { }, + editedMetadata: { }, + packName: '', + newPackName: '', + deleteModalVisible: false + } + }, + + computed: { + pack () { + return this.packName !== '' ? this.knownPacks[this.packName] : undefined + }, + packMeta () { + if (this.editedMetadata[this.packName] === undefined) { + this.editedMetadata[this.packName] = clone(this.knownPacks[this.packName].pack) + } + + return this.editedMetadata[this.packName] } }, @@ -25,37 +51,90 @@ const EmojiTab = { importFromFS () { this.$store.state.api.backendInteractor.importEmojiFromFS() }, - emojiAddr (packName, name) { - return `${this.$store.state.instance.server}/emoji/${encodeURIComponent(packName)}/${name}` + emojiAddr (name) { + return `${this.$store.state.instance.server}/emoji/${encodeURIComponent(this.packName)}/${name}` }, - editEmoji (packName, shortcode) { - if (this.editedParts[packName] === undefined) { this.editedParts[packName] = {} } - this.editedParts[packName][shortcode] = { - shortcode, file: this.knownPacks[packName].files[shortcode] + createEmojiPack () { + this.$store.state.api.backendInteractor.createEmojiPack( + { name: this.newPackName } + ).then(resp => resp.json()).then(resp => { + if (resp === 'ok') { + return this.refreshPackList() + } else { + return Promise.reject(resp) + } + }).then(done => { + this.$refs.createPackPopover.hidePopover() + + this.packName = this.newPackName + this.newPackName = '' + }) + }, + deleteEmojiPack () { + this.$store.state.api.backendInteractor.deleteEmojiPack( + { name: this.packName } + ).then(resp => resp.json()).then(resp => { + if (resp === 'ok') { + return this.refreshPackList() + } else { + return Promise.reject(resp) + } + }).then(done => { + delete this.editedMetadata[this.packName] + delete this.editedParts[this.packName] + + this.deleteModalVisible = false + this.packName = '' + }) + }, + + metaEdited (prop) { + return this.pack && this.packMeta[prop] !== this.pack.pack[prop] + }, + savePackMetadata () { + this.$store.state.api.backendInteractor.saveEmojiPackMetadata({ name: this.packName, newData: this.packMeta }).then( + resp => resp.json() + ).then(resp => { + // Update actual pack data + this.pack.pack = resp + // Delete edited pack data, should auto-update itself + delete this.editedMetadata[this.packName] + }) + }, + + editEmoji (shortcode) { + if (this.editedParts[this.packName] === undefined) { this.editedParts[this.packName] = {} } + + if (this.editedParts[this.packName][shortcode] === undefined) { + this.editedParts[this.packName][shortcode] = { + shortcode, file: this.knownPacks[this.packName].files[shortcode] + } } }, - saveEditedEmoji (packName, shortcode) { - const edited = this.editedParts[packName][shortcode] + saveEditedEmoji (shortcode) { + const edited = this.editedParts[this.packName][shortcode] this.$store.state.api.backendInteractor.updateEmojiFile( - { packName, shortcode, newShortcode: edited.shortcode, newFilename: edited.file, force: false } + { packName: this.packName, shortcode, newShortcode: edited.shortcode, newFilename: edited.file, force: false } ).then(resp => resp.ok ? resp.json() : resp.text().then(respText => Promise.reject(respText)) ).then(resp => { - this.knownPacks[packName].files = resp - delete this.editedParts[packName][shortcode] + this.knownPacks[this.packName].files = resp + delete this.editedParts[this.packName][shortcode] }) + }, + refreshPackList () { + return this.$store.state.api.backendInteractor.listEmojiPacks() + .then(data => data.json()) + .then(packData => { + this.knownPacks = packData.packs + }) } }, mounted () { - this.$store.state.api.backendInteractor.listEmojiPacks() - .then(data => data.json()) - .then(packData => { - this.knownPacks = packData.packs - console.log(this.knownPacks) - }) + this.refreshPackList() } } diff --git a/src/components/settings_modal/admin_tabs/emoji_tab.scss b/src/components/settings_modal/admin_tabs/emoji_tab.scss index 397580af..89bf2f7f 100644 --- a/src/components/settings_modal/admin_tabs/emoji_tab.scss +++ b/src/components/settings_modal/admin_tabs/emoji_tab.scss @@ -1,3 +1,5 @@ +@import "src/variables"; + .emoji-tab { .btn-group .btn { margin-left: 0.5em; @@ -21,4 +23,24 @@ width: 32px; height: 32px; } + + .emoji-unsaved { + box-shadow: 2px 3px 5px var(--cBlue, $fallback--cBlue); + } + + .emoji-list { + display: flex; + flex-wrap: wrap; + gap: 1em 1em; + } +} + +.emoji-tab-edit-popover { + padding-left: 0.5em; + padding-right: 0.5em; + padding-bottom: 0.5em; +} + +.emoji-tab-popover-button { + margin-left: 0.5em; } diff --git a/src/components/settings_modal/admin_tabs/emoji_tab.vue b/src/components/settings_modal/admin_tabs/emoji_tab.vue index 699e4afe..534f881a 100644 --- a/src/components/settings_modal/admin_tabs/emoji_tab.vue +++ b/src/components/settings_modal/admin_tabs/emoji_tab.vue @@ -6,84 +6,166 @@

    {{ $t('admin_dash.tabs.emoji') }}

    - - - - +
      +
    • + + +
    • - -
      -
      -
        -
      • -
        Description
        -