Compare commits

...

275 Commits

Author SHA1 Message Date
かっこかり 3d5481011a
Merge b5734a1662 into 7796fce779 2025-10-05 05:36:24 +00:00
かっこかり b5734a1662
Merge branch 'develop' into enh-14810 2025-10-05 14:36:21 +09:00
syuilo 7796fce779
New Crowdin updates (#16532)
* New translations ja-jp.yml (Chinese Traditional)

* New translations ja-jp.yml (Italian)

* New translations ja-jp.yml (Spanish)

* New translations ja-jp.yml (Italian)

* New translations ja-jp.yml (Turkish)

* New translations ja-jp.yml (Chinese Traditional)

* New translations ja-jp.yml (Catalan)

* New translations ja-jp.yml (German)

* New translations ja-jp.yml (Korean)

* New translations ja-jp.yml (Portuguese)

* New translations ja-jp.yml (Chinese Simplified)

* New translations ja-jp.yml (English)

* New translations ja-jp.yml (Vietnamese)

* New translations ja-jp.yml (Thai)

* New translations ja-jp.yml (Japanese, Kansai)

* New translations ja-jp.yml (Chinese Traditional)

* New translations ja-jp.yml (Chinese Simplified)

* New translations ja-jp.yml (Catalan)

* New translations ja-jp.yml (Spanish)

* New translations ja-jp.yml (Chinese Traditional)

* New translations ja-jp.yml (Korean)

* New translations ja-jp.yml (Spanish)

* New translations ja-jp.yml (Italian)

* New translations ja-jp.yml (Russian)

* New translations ja-jp.yml (Turkish)

* New translations ja-jp.yml (Chinese Traditional)

* New translations ja-jp.yml (Romanian)

* New translations ja-jp.yml (French)

* New translations ja-jp.yml (Arabic)

* New translations ja-jp.yml (Catalan)

* New translations ja-jp.yml (Czech)

* New translations ja-jp.yml (German)

* New translations ja-jp.yml (Korean)

* New translations ja-jp.yml (Portuguese)

* New translations ja-jp.yml (Chinese Simplified)

* New translations ja-jp.yml (English)

* New translations ja-jp.yml (Vietnamese)

* New translations ja-jp.yml (Indonesian)

* New translations ja-jp.yml (Thai)

* New translations ja-jp.yml (Japanese, Kansai)

* New translations ja-jp.yml (Chinese Traditional)

* New translations ja-jp.yml (Catalan)

* New translations ja-jp.yml (Chinese Simplified)

* New translations ja-jp.yml (Korean)

* New translations ja-jp.yml (Italian)

* New translations ja-jp.yml (Italian)

* New translations ja-jp.yml (Spanish)

* New translations ja-jp.yml (Italian)

* New translations ja-jp.yml (Russian)

* New translations ja-jp.yml (Turkish)

* New translations ja-jp.yml (Chinese Traditional)

* New translations ja-jp.yml (Romanian)

* New translations ja-jp.yml (French)

* New translations ja-jp.yml (Arabic)

* New translations ja-jp.yml (Catalan)

* New translations ja-jp.yml (Czech)

* New translations ja-jp.yml (German)

* New translations ja-jp.yml (Korean)

* New translations ja-jp.yml (Dutch)

* New translations ja-jp.yml (Norwegian)

* New translations ja-jp.yml (Polish)

* New translations ja-jp.yml (Portuguese)

* New translations ja-jp.yml (Slovak)

* New translations ja-jp.yml (Ukrainian)

* New translations ja-jp.yml (Chinese Simplified)

* New translations ja-jp.yml (English)

* New translations ja-jp.yml (Vietnamese)

* New translations ja-jp.yml (Indonesian)

* New translations ja-jp.yml (Bengali)

* New translations ja-jp.yml (Thai)

* New translations ja-jp.yml (Uzbek)

* New translations ja-jp.yml (Japanese, Kansai)

* New translations ja-jp.yml (Korean (Gyeongsang))

* New translations ja-jp.yml (Catalan)

* New translations ja-jp.yml (Chinese Simplified)

* New translations ja-jp.yml (English)

* New translations ja-jp.yml (Italian)

* New translations ja-jp.yml (Korean)

* New translations ja-jp.yml (Italian)

* New translations ja-jp.yml (Chinese Traditional)

* New translations ja-jp.yml (Catalan)

* New translations ja-jp.yml (Korean)

* New translations ja-jp.yml (Chinese Simplified)

* New translations ja-jp.yml (English)

* New translations ja-jp.yml (Catalan)

* New translations ja-jp.yml (Chinese Simplified)

* New translations ja-jp.yml (Chinese Traditional)

* New translations ja-jp.yml (Chinese Traditional)

* New translations ja-jp.yml (Spanish)

* New translations ja-jp.yml (Spanish)

* New translations ja-jp.yml (Korean)

* New translations ja-jp.yml (Japanese, Kansai)

* New translations ja-jp.yml (Korean)

* New translations ja-jp.yml (Chinese Simplified)

* New translations ja-jp.yml (Chinese Traditional)

* New translations ja-jp.yml (Catalan)

* New translations ja-jp.yml (Spanish)

* New translations ja-jp.yml (Chinese Traditional)

* New translations ja-jp.yml (Korean)

* New translations ja-jp.yml (Chinese Simplified)

* New translations ja-jp.yml (Chinese Traditional)

* New translations ja-jp.yml (Catalan)

* New translations ja-jp.yml (Chinese Simplified)

* New translations ja-jp.yml (Chinese Simplified)

* New translations ja-jp.yml (Chinese Simplified)

* New translations ja-jp.yml (Chinese Simplified)

* New translations ja-jp.yml (Chinese Simplified)

* New translations ja-jp.yml (Chinese Simplified)

* New translations ja-jp.yml (Chinese Simplified)

* New translations ja-jp.yml (English)

* New translations ja-jp.yml (English)

* New translations ja-jp.yml (Spanish)

* New translations ja-jp.yml (Chinese Simplified)

* New translations ja-jp.yml (Italian)

* New translations ja-jp.yml (Italian)

* New translations ja-jp.yml (Thai)

* New translations ja-jp.yml (Thai)

* New translations ja-jp.yml (Portuguese)

* New translations ja-jp.yml (Portuguese)

* New translations ja-jp.yml (Chinese Simplified)

* New translations ja-jp.yml (Chinese Simplified)

* New translations ja-jp.yml (Chinese Simplified)
2025-10-05 13:28:23 +09:00
renovate[bot] 3954837cfa
fix(deps): update [root] update dependencies [skip ci] (#16576)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-04 15:58:30 +09:00
renovate[bot] 7ea4cad12e
chore(deps): update [misskey-js] update dependencies [skip ci] (#16543)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-04 15:44:08 +09:00
github-actions[bot] d864e9a269 Bump version to 2025.10.0-beta.0 2025-10-04 06:40:01 +00:00
syuilo 4e0434c275
Update CHANGELOG with new features and enhancements 2025-10-04 15:38:05 +09:00
renovate[bot] e2f939080a
fix(deps): update [frontend] update dependencies [ci skip] (#16548)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-04 15:26:26 +09:00
renovate[bot] 6956f44d1f
chore(deps): update [github actions] update dependencies (#16545)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-04 15:18:21 +09:00
renovate[bot] a393d5a87e
fix(deps): update [backend] update dependencies (#16547)
* fix(deps): update [backend] update dependencies

* chore: update typeorm.patch

* fix: handle socket creation failure in HttpRequestServiceAgent

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: anatawa12 <anatawa12@icloud.com>
Co-authored-by: kakkokari-gtyih <67428053+kakkokari-gtyih@users.noreply.github.com>
2025-10-04 15:04:28 +09:00
syuilo 6c634de482
Bump version to 2025.10.0 in CHANGELOG
Updated version number and note for pnpm requirement.
2025-10-04 09:50:58 +09:00
syuilo fc02e0d34d chore(frontend): make enableFolderPageView false by default
see #16553
2025-10-04 08:54:49 +09:00
syuilo cb1a90ddad chore(frontend): improve usability 2025-10-04 08:53:19 +09:00
github-actions[bot] f0fb3a56a8 Bump version to 2025.10.0-alpha.0 2025-10-01 04:57:00 +00:00
かっこかり b8ae7edcec
fix(gh): add minimumReleaseAge settings to renovate [ci skip] 2025-09-28 18:28:37 +09:00
syuilo e24233c1c7 add ideas 2025-09-27 20:53:21 +09:00
syuilo 225154d76d enhance(frontend): improve zoomLines image effect 2025-09-27 18:46:26 +09:00
syuilo c5f9c0ce5c enhance(frontend): add pixelate mask effect 2025-09-26 18:27:53 +09:00
github-actions[bot] cce302ae4f Bump version to 2025.9.1-alpha.2 2025-09-26 06:44:58 +00:00
かっこかり e0d210e15b
fix(frontend): アクティビティウィジェットのグラフモードが動作しない問題を修正 (#16579)
* fix(frontend): アクティビティウィジェットのグラフモードが動作しない問題を修正

* 🎨

* Update Changelog

* fix
2025-09-26 15:36:50 +09:00
syuilo 0b7634b126 enhance(frontend): テーマをドラッグ&ドロップできるように 2025-09-26 15:36:25 +09:00
syuilo d1446d195a
feat: scheduled post (#16577)
* Update NoteDraft.ts

* Update NoteDraft.ts

* wip

* Update CHANGELOG.md

* wip

* Update PostScheduledNoteProcessorService.ts

* Update PostScheduledNoteProcessorService.ts

* Update Notification.ts

* wip

* Update NoteDraftService.ts

* Update NoteDraftService.ts

* Update NoteDraftService.ts

* wip

* Create 1758677617888-scheduled-post.js

* Update index.d.ts

* Update stats.ts

* wip

* wip

* wip

* wip

* wip

* Update MkNotification.vue

* wip

* wip

* wip

* Update NoteDraftService.ts

* Update NoteDraftService.ts

* wip

* wip

* Update NoteDraftEntityService.ts

* wip

* Update index.d.ts

* Update MkPostForm.vue

* wip

* wip

* wip

* Update NoteCreateService.ts

* wip

* wip

* wip

* Update NoteDraftEntityService.ts

* Update NoteCreateService.ts

* Update NoteDraftService.ts

* wip

* Update NoteDraftService.ts

* wip

* wip

* Update MkPostForm.vue

* wip

* Update MkPostForm.vue

* Update os.ts

* wip

* Update MkNoteDraftsDialog.vue
2025-09-26 15:29:52 +09:00
かっこかり 218070eb13
fix(frontend): ビルド成果物のファイル名にlocalesのhashを含めるように (#16580) 2025-09-24 17:01:48 +09:00
syuilo 0f8c068e84
feat(frontend): Video compression (#16574)
* wip

* Update CHANGELOG.md

* wip

* wip

* wip

* wip

* Update use-uploader.ts

* Update use-uploader.ts
2025-09-24 09:01:06 +09:00
github-actions[bot] 69d66b89f2 Bump version to 2025.9.1-alpha.1 2025-09-22 10:52:25 +00:00
饺子w (Yumechi) 211365de64
enhance(backend): 設定ファイルにFastifyOptions.trustProxyを追加 (#16567)
* enhance(backend): 設定ファイルにFastifyOptions.trustProxyを追加

Signed-off-by: eternal-flame-AD <yume@yumechi.jp>

* try harder

Signed-off-by: eternal-flame-AD <yume@yumechi.jp>

---------

Signed-off-by: eternal-flame-AD <yume@yumechi.jp>
2025-09-22 19:45:01 +09:00
syuilo 966127c63e enhance(frontend): 絵文字ピッカーのサイズをより大きくできるように 2025-09-22 19:43:31 +09:00
果物リン 54800971eb
プロフィールの「ユーザーのノートを検索」でローカルのユーザーを検索できないのを修正 (#16570)
* プロフィールの「ユーザーのノートを検索」でローカルのユーザーを検索できないのを修正

* fix lint
2025-09-22 19:21:01 +09:00
syuilo 13d5c6d2b2 refactor MkAnimBg 2025-09-22 19:00:47 +09:00
syuilo 2cff00eedd update pnpm 2025-09-22 18:27:39 +09:00
syuilo 3fc2261041 dev(pnpm): set minimumReleaseAge to 7days
to mitigate supply-chain attack
Resolve #16572
2025-09-22 18:23:43 +09:00
syuilo 18d66c0233 Update CHANGELOG.md 2025-09-20 14:21:51 +09:00
Copilot 2f52c20150
Implement professional-grade Gaussian-approximated blur effect with resolution independence and configurable quality for image effector system (#16571)
* Initial plan

* Implement blur effect for image effector system

Co-authored-by: syuilo <4439005+syuilo@users.noreply.github.com>

* Improve blur quality with configurable sample count

Co-authored-by: syuilo <4439005+syuilo@users.noreply.github.com>

* Revert to simpler blur implementation with configurable sample count

Co-authored-by: syuilo <4439005+syuilo@users.noreply.github.com>

* Fix blur size independence from sample count

Co-authored-by: syuilo <4439005+syuilo@users.noreply.github.com>

* Make blur radius resolution-independent

Co-authored-by: syuilo <4439005+syuilo@users.noreply.github.com>

* Update blur.ts

* Enhance blur quality with explicit diagonal sampling and fix parameter configuration

Co-authored-by: syuilo <4439005+syuilo@users.noreply.github.com>

* Implement Gaussian-approximated blur with distance-based weighting for superior quality

Co-authored-by: syuilo <4439005+syuilo@users.noreply.github.com>

* Revert "Implement Gaussian-approximated blur with distance-based weighting for superior quality"

This reverts commit c739e9f55b.

* Revert "Enhance blur quality with explicit diagonal sampling and fix parameter configuration"

This reverts commit ffbc6eeba7.

* wip

* tweak

* ellipse

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: syuilo <4439005+syuilo@users.noreply.github.com>
2025-09-20 14:19:35 +09:00
github-actions[bot] 9d70c9ad78 Bump version to 2025.9.1-alpha.0 2025-09-19 13:51:21 +00:00
tamaina 42b2aea533
feat(frontend): 自分のプロフィールページの二次元コード(QRコード)を表示し、他の人のコードを読み取りするページを追加 (#16456)
* wip (qr.show.vue)

* added to navbar

* qr.show.vue

* fix

* added to navbar

* fix size

* 🎨

* 🎨

* fix div warn

* fix

* use * 0.25

* fix??

* fix lint

* clean up

* ???

* ?

* fix

* 🎨

* 🎨

* refactor

* 🎨

* 🎨

* :ar:t

* 🎨

* iphone flip

* no lazy import

* 🎨

* 🎨

* 🎨

* ユーザー全部flipでいいや

* ✌️

* fix

* fix

* fix lint

* 🎨

* fix type

* fix: local user profile url cannot be resolved with ap/show

* fix: local user url with hostname could not be resolved

* chore: use common utility for checking self host

* wip

* 🎨

* 🎨

* fix imports

* fix

* fix

* fix

* 🎨

* fix...

* set spacer-w

* ✌️

* 全画面でQRを読むように

* fix

* 🎨

* modify navbar.ts

* start/stop on vue activation

* display raw content read from qr

* 端末のQRをスキャンするボタンを追加

* chore

* やっぱりmfmを先に表示する

* 🎨

* fix 18n

* QRの内容は/users/:userIdにする

* add spdx

* use cqh

* `defineProps` is a compiler macro and no longer needs to be imported.

* use MkUserName

* 🎨

* 🎨

* refactor

* clean up

* refactor

* 🎨

* Update qr.show.vue

* Misskeyロゴにdrop-shadowを追加

* clean up: do not use empty css

* fix os.select usage

* Update qr.vue

* Update qr.show.vue

* Update qr.show.vue

* Update get-user-menu.ts

* ✌️

* Update show.ts

* Update ja-JP.yml

* watermark

* Update CHANGELOG.md

* Update qr.read.vue

* Update qr.read.vue

* wip

* Update MkWatermarkEditorDialog.Layer.vue

---------

Co-authored-by: anatawa12 <anatawa12@icloud.com>
Co-authored-by: syuilo <4439005+syuilo@users.noreply.github.com>
2025-09-19 21:02:30 +09:00
syuilo 97adf6f2cc 🎨 2025-09-19 14:23:34 +09:00
tamaina 93ff209c51
enhance(frontend): bootでonunhandledrejectionでrenderErrorする場合、PromiseRejectionEvent.reasonを渡すように (#16563) 2025-09-18 19:35:23 +09:00
syuilo 5fe08d0bbb fix(frontend): iOSで、デバイスがダークモードだと初回読み込み時にエラーになる問題を修正
Fix #16562
2025-09-18 19:18:31 +09:00
syuilo 8c413d01e6
enhance(frontend): マスクエフェクト (#16556)
* wip

* wip

* Update MkImageEffectorDialog.vue

* Update MkImageEffectorDialog.vue

* Update MkImageEffectorDialog.vue

* Update MkImageEffectorDialog.vue

* Update MkImageEffectorDialog.vue

* Update fillSquare.ts

* Update CHANGELOG.md

* Update fillSquare.ts
2025-09-17 18:38:56 +09:00
syuilo b231da7c7c enhance(frontend): チャットの日本語名称をダイレクトメッセージに & ベータを外す 2025-09-16 16:24:10 +09:00
syuilo df3e44f62e enhance(backend): allow upload csv by default
Related #16541
2025-09-16 12:16:18 +09:00
かっこかり e504560477
fix: サーバー設定によりコンテンツの閲覧が制限されている場合のメッセージを区別するように (#16527) 2025-09-16 11:53:20 +09:00
syuilo bcb2073715 enhance(backend): 初期設定をスキップした場合の初期状態ポリシーでインポート系をオプトインに
Resolve #16540
2025-09-16 11:26:35 +09:00
syuilo 6a80c23a50
chore(frontend): enable enableFolderPageView by default 2025-09-15 14:33:32 +09:00
syuilo 2621f468ff enhance: 広告ごとにセンシティブフラグを設定できるように 2025-09-14 15:25:22 +09:00
かっこかり d4654dd7bd
refactor(frontend): os.select, MkSelectのitem指定をオブジェクトによる定義に統一し、型を狭める (#16475)
* refactor(frontend): MkSelectのitem指定をオブジェクトによる定義に統一

* fix

* spdx

* fix

* fix os.select

* fix lint

* add comment

* fix

* fix: os.select対応漏れを修正

* fix

* fix

* fix: MkSelectのmodelに対する型チェックを厳格化

* fix

* fix

* fix

* Update packages/frontend/src/components/MkEmbedCodeGenDialog.vue

Co-authored-by: syuilo <4439005+syuilo@users.noreply.github.com>

* fix

* fix types

* fix

* fix

* Update packages/frontend/src/pages/admin/roles.editor.vue

Co-authored-by: syuilo <4439005+syuilo@users.noreply.github.com>

* fix: MkSelectに直接配列を指定している場合に正常に型が解決されるように

---------

Co-authored-by: syuilo <4439005+syuilo@users.noreply.github.com>
2025-09-13 21:00:33 +09:00
renovate[bot] b7da6cad87
fix(deps): update dependency vite [security] (#16535)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-13 10:32:49 +09:00
かっこかり 5b4115e21a
refactor(frontend): フロントエンドの型エラー解消(途中まで) (#16539)
* fix(frontend): FormLinkをボタンとして使用した際にエラーが出る問題を修正

* refactor(frontend): フロントエンドの型エラー解消

* remove unused ts-expect-error

* migrate

* remove unrelated changes

* fix lint

* more type fixes
2025-09-13 08:33:14 +09:00
syuilo c174c5c144
Update CHANGELOG.md 2025-09-12 17:13:13 +09:00
かっこかり aebc3f781e
perf(frontend): 低精度な現在時刻を一か所で管理するように (#16479)
* perf(frontend): 低精度な現在時刻を一か所で管理するように

* lint

* fix

* remove unused imports

* fix

* Update Changelog

* [ci skip] typo

* enhance: カレンダーウィジェットの日付変更は時間通りに行うように

* [ci skip] fix
2025-09-12 17:12:50 +09:00
かっこかり f60b6291d7
chore(gh): add frontend-builder to renovate 2025-09-10 10:01:25 +09:00
taiy 7673874675
fix(eslint): add window prefix rules to frontend-embed & frontend-shared (#16531) 2025-09-10 09:22:12 +09:00
github-actions[bot] 6e3354f95d [skip ci] Update CHANGELOG.md (prepend template) 2025-09-08 12:29:30 +00:00
github-actions[bot] b9df928097 Release: 2025.9.0 2025-09-08 12:29:25 +00:00
github-actions[bot] 0754678144 Bump version to 2025.9.0-rc.0 2025-09-08 11:33:58 +00:00
tamaina a8cc51dc77
fix(frontend): Safari 26でモバイルUIが崩れる問題に対するhotfix (#16528) 2025-09-08 20:32:19 +09:00
github-actions[bot] 690edcef16 Bump version to 2025.9.0-beta.1 2025-09-08 11:21:12 +00:00
renovate[bot] 2ea784f345
fix(deps): update [backend] update dependencies (#16491)
* fix(deps): update [backend] update dependencies

* fix type error

* run pnpm dedupe

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: kakkokari-gtyih <67428053+kakkokari-gtyih@users.noreply.github.com>
2025-09-08 17:11:18 +09:00
renovate[bot] 20d257b562
chore(deps): update [misskey-js] update dependencies (#16489)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-08 16:14:23 +09:00
renovate[bot] c215415613
fix(deps): update [root] update dependencies (#16490)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-08 16:08:15 +09:00
github-actions[bot] 726c03d96a Bump version to 2025.9.0-beta.0 2025-09-08 06:32:15 +00:00
syuilo e65ddb546c
New Crowdin updates (#16526)
* New translations ja-jp.yml (Turkish)

* New translations ja-jp.yml (Russian)
2025-09-08 15:20:07 +09:00
renovate[bot] 85aea9077f
fix(deps): update [frontend] update dependencies (#16492)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-08 15:16:22 +09:00
syuilo f3fffce6a9 fix type 2025-09-08 14:57:53 +09:00
syuilo eb7db5a3aa Update MkSuspense.vue 2025-09-08 14:56:58 +09:00
syuilo e33eb26863 Update CHANGELOG.md 2025-09-07 19:41:40 +09:00
かっこかり 430310f306
fix(frontend): ctrlキーを押しながらリンクをクリックしても新しいタブで開かない問題を修正 (#16453)
* fix(frontend): ctrlキーを押しながらクリックしても新しいタブで開かない問題を修正

* Update Changelog

* fix: 制御キーの場合を個別ハンドリングするのではなくブラウザ既定の挙動に任せるように

* fix
2025-09-07 09:32:32 +09:00
syuilo 1e1eea521e chore(frontend): add force cloud backup button for debugging 2025-09-07 09:16:25 +09:00
syuilo 86ad771221
New Crowdin updates (#16525)
* New translations ja-jp.yml (Russian)

* New translations ja-jp.yml (Russian)
2025-09-07 09:01:12 +09:00
syuilo 057acf471e
New Crowdin updates (#16493)
* New translations ja-jp.yml (Catalan)

* New translations ja-jp.yml (Spanish)
2025-09-06 20:53:36 +09:00
github-actions[bot] 2bfe257879 Bump version to 2025.9.0-alpha.2 2025-09-06 08:54:34 +00:00
syuilo 6d75624aa8
Update CHANGELOG.md 2025-09-06 17:49:53 +09:00
tamaina 369f0ec88a
fix(backend): webpなどの画像に対してセンシティブなメディアの検出が適用されていなかった問題を修正 (#16523)
画像をnsfwjsにかける前にsharpで均一にするようにした
2025-09-06 17:48:53 +09:00
かっこかり 788c5660ba
enhance(frontend): フロントエンドのキャッシュクリア操作でブラウザの内部キャッシュも削除するように (#16522)
* enhance(frontend): フロントエンドのキャッシュクリア操作でブラウザの内部キャッシュも削除するように

* 削除するキャッシュを増やす

* Update Changelog

* fix: 何らかのエラーがあっても無視するように
2025-09-06 14:46:24 +09:00
github-actions[bot] 6cf1f86636 Bump version to 2025.9.0-alpha.1 2025-09-06 03:42:29 +00:00
syuilo 5b994b3e03 fix(frontend): プロファイルを復元後アカウントの切り替えができない問題を修正
Fix #16508
2025-09-06 12:41:27 +09:00
syuilo 7b2abb7577 enhance(frontend): クリップ/リスト/アンテナ/ロール追加系メニュー項目において、表示件数を拡張
#16510
2025-09-06 11:18:08 +09:00
github-actions[bot] b681788315 Bump version to 2025.9.0-alpha.0 2025-09-06 02:11:36 +00:00
syuilo 279af1d72f Update CHANGELOG.md 2025-09-06 11:10:41 +09:00
syuilo 9e188ca3fa Revert "refactor"
This reverts commit aa85d701b9.
2025-09-06 11:09:24 +09:00
syuilo de1b2223ff enhance(frontend): AiScriptAppウィジェットで構文エラーを検知してもダイアログではなくウィジェット内にエラーを表示するように 2025-09-05 19:44:11 +09:00
なっかあ 9b565728e7
fix #16494 (#16509) 2025-09-05 15:26:39 +09:00
饺子w (Yumechi) a92fd8856a
feat(backend): Send Clear-Site-Data header on /flush (#16517)
* feat(backend): Send Clear-Site-Data header on /flush

Signed-off-by: eternal-flame-AD <yume@yumechi.jp>

* simplify check on flush.pug

Signed-off-by: eternal-flame-AD <yume@yumechi.jp>

---------

Signed-off-by: eternal-flame-AD <yume@yumechi.jp>
2025-09-05 13:55:37 +09:00
takaion 047773341d
fix(frontend): エラー画像が横に引き伸ばされてしまう問題に対応 (#16502)
* fix(frontend): エラー画像が横に引き伸ばされてしまう問題に対応

Fix misskey-dev#15982

* Update CHANGELOG.md
2025-09-02 16:40:57 +09:00
yukineko 842670e100
fix(frontend): RSSティッカーウィジェットが正しく動作しない問題を修正 (#16498)
* fix: RSSティッカーウィジェットが正しく機能しない問題を修正

* chore: update CHANGELOG.md
2025-09-02 10:29:25 +09:00
anatawa12 ffc481a994
fix: 「自動でもっと見る」の設定ができない問題 (#16500) 2025-09-02 10:11:50 +09:00
syuilo 2ccf4f94cb refactor 2025-09-01 16:51:58 +09:00
syuilo 3566bc207f refactor 2025-09-01 16:36:15 +09:00
syuilo 4a0e968662 refactor 2025-09-01 16:23:05 +09:00
syuilo b1479ab1d8 Update misskey-js.api.md 2025-09-01 14:07:24 +09:00
syuilo 18a9ccf7af pnpm dedupe 2025-09-01 14:07:14 +09:00
syuilo 959e72b2b3 refactor 2025-09-01 14:02:14 +09:00
syuilo a3d78b2f08 refactor 2025-09-01 13:41:40 +09:00
syuilo 3c998e1f48 refactor 2025-09-01 12:59:53 +09:00
syuilo 782c9f9852 refactor 2025-09-01 12:33:44 +09:00
syuilo d27c740ab0 refactor 2025-09-01 12:31:27 +09:00
syuilo 08ecf7ca79 refactor 2025-09-01 10:19:14 +09:00
syuilo bdec4bf87a refactor 2025-09-01 10:16:33 +09:00
syuilo 7000095b44 refactor 2025-09-01 10:01:03 +09:00
syuilo 18e42cc83d refactoe 2025-09-01 09:53:38 +09:00
syuilo 11204eeb43 refactor 2025-09-01 09:50:36 +09:00
かっこかり c95092903a
refactor(frontend): フロントエンドの型エラー解消(途中まで) (#16477)
* refactor(frontend): フロントエンドの型エラー解消

* fix

---------

Co-authored-by: syuilo <4439005+syuilo@users.noreply.github.com>
2025-08-31 19:53:38 +09:00
github-actions[bot] 21b2b9e5f8 [skip ci] Update CHANGELOG.md (prepend template) 2025-08-31 08:42:45 +00:00
github-actions[bot] 665ec2c43c Release: 2025.8.0 2025-08-31 08:42:39 +00:00
syuilo 34bd840525 Update CHANGELOG.md 2025-08-31 15:56:07 +09:00
syuilo 3d1cbcf094 Update CHANGELOG.md 2025-08-31 15:29:22 +09:00
github-actions[bot] 5f5d88036f Bump version to 2025.8.0-rc.0 2025-08-31 01:32:06 +00:00
syuilo 24739cd040
New Crowdin updates (#16483)
* New translations ja-jp.yml (Spanish)

* New translations ja-jp.yml (Catalan)

* New translations ja-jp.yml (Italian)

* New translations ja-jp.yml (English)

* New translations ja-jp.yml (Chinese Simplified)

* New translations ja-jp.yml (Korean)

* New translations ja-jp.yml (Chinese Traditional)

* New translations ja-jp.yml (Italian)

* New translations ja-jp.yml (Italian)

* New translations ja-jp.yml (Italian)
2025-08-31 10:24:41 +09:00
syuilo b491432daa fix(frontend): タッチ操作時にマウスホバー時のユーザープレビューが開くことがある問題を修正
Fix #16464
2025-08-31 10:23:29 +09:00
syuilo ebe029458e enhance(frontend): アイコンのスクロール追従を無効化する際の適用範囲を強化
Resolve #16485
2025-08-31 10:18:48 +09:00
syuilo d127d82c5b Update CHANGELOG.md 2025-08-30 19:17:11 +09:00
syuilo aabda5a956 clean up 2025-08-30 19:15:52 +09:00
syuilo bd5b38c9d9 Update CHANGELOG.md 2025-08-30 19:12:53 +09:00
syuilo 647e03bf34 update locale 2025-08-30 19:10:19 +09:00
syuilo d16db7f311
New translations ja-jp.yml (English) (#16472) 2025-08-30 16:11:27 +09:00
github-actions[bot] ec4731dee4 Bump version to 2025.8.0-beta.6 2025-08-29 07:38:45 +00:00
syuilo 65a4d77a7f fix(backend): タイムラインAPIの withRenotes: false 時のレスポンスを修正 2025-08-29 16:03:03 +09:00
かっこかり 328301ffc2
fix(misskey-js): run api extractor (#16476) 2025-08-29 13:37:17 +09:00
syuilo def148d7a6 refactor 2025-08-28 20:02:28 +09:00
syuilo aa85d701b9 refactor 2025-08-28 19:53:10 +09:00
syuilo f0833cffe9 refactor 2025-08-28 19:47:58 +09:00
github-actions[bot] 9cd918f12b Bump version to 2025.8.0-beta.5 2025-08-28 05:33:23 +00:00
syuilo 195a80622b
New Crowdin updates (#16457)
* New translations ja-jp.yml (Spanish)

* New translations ja-jp.yml (Catalan)

* New translations ja-jp.yml (Italian)

* New translations ja-jp.yml (English)

* New translations ja-jp.yml (Chinese Simplified)

* New translations ja-jp.yml (Korean)

* New translations ja-jp.yml (Turkish)

* New translations ja-jp.yml (Chinese Traditional)

* New translations ja-jp.yml (Chinese Simplified)

* New translations ja-jp.yml (Catalan)

* New translations ja-jp.yml (Chinese Traditional)

* New translations ja-jp.yml (Chinese Simplified)

* New translations ja-jp.yml (Chinese Traditional)

* New translations ja-jp.yml (Catalan)

* New translations ja-jp.yml (Italian)

* New translations ja-jp.yml (Spanish)

* New translations ja-jp.yml (Italian)

* New translations ja-jp.yml (Korean)

* New translations ja-jp.yml (English)
2025-08-28 13:31:05 +09:00
syuilo 8b347e23e3 refactor 2025-08-28 13:30:52 +09:00
syuilo bca3602da2 refactor 2025-08-28 13:24:25 +09:00
syuilo cfd4d7c57b refactor 2025-08-28 13:20:11 +09:00
tamaina 084ccf5c9a
build-misskey-js-with-types (#16471)
* build-misskey-js-with-types

* build-misskey-js-with-types
2025-08-28 11:45:46 +09:00
syuilo fc1693f768 そもそもnullになることはあり得なかった 2025-08-28 11:39:54 +09:00
syuilo ff6f115976 refactor 2025-08-28 11:30:03 +09:00
syuilo 8c2b96ad37 lint 2025-08-28 11:16:40 +09:00
syuilo 3e24419981 refactor 2025-08-28 11:15:17 +09:00
tamaina 25c2007f59
build-misskey-js-with-types (#16470) 2025-08-28 10:39:39 +09:00
syuilo 2e4c4dd555 refactor 2025-08-28 08:59:13 +09:00
taiy 653cb116ea
fix(build): run build-misskey-js-with-types (#16468) 2025-08-27 19:11:05 +09:00
syuilo c9f363b215 fix i/apps schema 2025-08-27 17:21:24 +09:00
syuilo e72da587e4 型の漏れを修正 2025-08-27 17:05:29 +09:00
syuilo 439337a108 json schemaに誤りがあるのを修正 2025-08-27 17:01:02 +09:00
syuilo 5fef2332f4 refactor 2025-08-27 17:00:58 +09:00
syuilo 40a325cbe7 userのjson schemaに誤りがあるのを修正 2025-08-27 16:55:07 +09:00
syuilo 5eff31383f refactor 2025-08-27 16:52:58 +09:00
syuilo 575379a683 refactor 2025-08-27 16:48:32 +09:00
syuilo bf82b49633 refactor 2025-08-27 16:27:16 +09:00
syuilo 87d09f255d refactor 2025-08-27 15:59:39 +09:00
syuilo 98e07c3bd1 perf(frontend): use WeakMap 2025-08-27 12:41:24 +09:00
syuilo c5bb881438 refactor 2025-08-27 12:40:11 +09:00
syuilo ee96f77ef2 refactor 2025-08-27 12:09:19 +09:00
syuilo 55eb18f5a6
Update CHANGELOG.md 2025-08-27 10:29:45 +09:00
syuilo aa8daca914 chore(frontend): skip typecheck for auto-generated files 2025-08-27 10:23:41 +09:00
syuilo 3e9118af3d fix(frontend): lookupページでリモートURLを指定した際に正しく動作しない問題を修正 2025-08-27 10:15:11 +09:00
syuilo 25df56dfd0 refactor 2025-08-27 10:14:17 +09:00
syuilo 231ccae006 tweak locale 2025-08-27 09:57:33 +09:00
syuilo 2e0a34300a refactor 2025-08-27 09:46:31 +09:00
syuilo d2fd7460ed
Update CHANGELOG.md
#16465
2025-08-27 00:41:11 +09:00
syuilo 5e3d8fc9b8 refactor 2025-08-26 20:17:25 +09:00
syuilo b186c67767 refactor 2025-08-26 20:04:59 +09:00
syuilo ac7c60d102 refactor and fix 2025-08-26 19:06:15 +09:00
syuilo b9dbd58a1c refactor 2025-08-26 18:54:54 +09:00
syuilo 69bbac013a refactor 2025-08-26 17:31:36 +09:00
syuilo 203296b9cb chore(frontend): tweak MkServerSetupWizard 2025-08-26 15:02:12 +09:00
syuilo 689d70ffae refactor 2025-08-26 14:38:42 +09:00
syuilo d5475d1ff6 refactor 2025-08-26 14:22:53 +09:00
syuilo 05cc8047fa refactor 2025-08-26 13:58:57 +09:00
syuilo d6a1046361 refactor 2025-08-26 13:34:41 +09:00
syuilo eb9915baf8 refactor and fix 2025-08-26 10:56:09 +09:00
syuilo dbb6c71c5c refactor 2025-08-26 09:39:23 +09:00
syuilo 9e5c8d94bf refactor 2025-08-26 09:08:00 +09:00
syuilo 120af977a9 refactoe 2025-08-26 08:57:36 +09:00
syuilo 506c8a259b refactor 2025-08-26 08:50:34 +09:00
syuilo 0c8545ec1c
Update CHANGELOG.md 2025-08-26 07:44:26 +09:00
tamaina 7e7dc03796
fix(frontend): ap/showでローカルユーザーを解決した際@username@nullに飛ばされる問題を修正 (#16460) 2025-08-26 07:43:59 +09:00
syuilo a874def344 remove unused file 2025-08-25 20:32:07 +09:00
syuilo 44ac51f64f refactor: ReloadSuggest -> ReloadSuggestion 2025-08-25 20:31:22 +09:00
syuilo 3b65be8b91 clean up 2025-08-25 20:29:26 +09:00
syuilo 76beac41d2 refactor 2025-08-25 20:07:33 +09:00
syuilo 69cdc73f5a refactor 2025-08-25 19:55:42 +09:00
syuilo 1c966db324 refactor 2025-08-25 17:12:11 +09:00
syuilo 692284886b refactor 2025-08-25 17:04:49 +09:00
syuilo 0121d19645 refactor 2025-08-25 16:56:10 +09:00
syuilo bf8636e516 refactor 2025-08-25 16:56:05 +09:00
syuilo d336a1fb1c refactor 2025-08-25 13:51:52 +09:00
syuilo 7c761e7017 refactor 2025-08-25 13:48:09 +09:00
syuilo 7924daf7f8 refactor 2025-08-25 13:46:22 +09:00
syuilo 2b9706a68b refactor 2025-08-25 13:40:41 +09:00
syuilo f2d15f9240 refactor 2025-08-25 13:36:38 +09:00
syuilo caf6a3ab81 refactor 2025-08-25 13:34:17 +09:00
syuilo f4baa973bf refactor 2025-08-25 13:26:41 +09:00
syuilo 3741fa4b49 refactor 2025-08-25 13:25:05 +09:00
syuilo 27df7f643e fix typo
Fix #16452
2025-08-25 10:07:42 +09:00
syuilo 30987b6f1f
Update CHANGELOG.md 2025-08-25 10:05:15 +09:00
anatawa12 41b5677f01
fix: Pages will be deleted when eye-catching image is moved (#16455) 2025-08-25 10:04:35 +09:00
github-actions[bot] 47d83e8930 Bump version to 2025.8.0-beta.4 2025-08-24 09:29:08 +00:00
renovate[bot] 61ff1f313b
fix(deps): update [backend] update dependencies (#16450)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-24 18:27:14 +09:00
renovate[bot] 637ad3d479
chore(deps): update [misskey-js] update dependencies (#16448)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-24 16:05:06 +09:00
syuilo 2dd8c2a355
New Crowdin updates (#16442)
* New translations ja-jp.yml (Spanish)

* New translations ja-jp.yml (Turkish)

* New translations ja-jp.yml (English)

* New translations ja-jp.yml (Turkish)
2025-08-24 12:02:36 +09:00
renovate[bot] 857a87d4b6
chore(deps): update [github actions] update dependencies (#16447)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-24 11:53:23 +09:00
renovate[bot] 8b4cea5c86
fix(deps): update [root] update dependencies (#16449)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-24 11:53:10 +09:00
renovate[bot] 9f25d96ec3
fix(deps): update [frontend] update dependencies (#16387)
* fix(deps): update [frontend] update dependencies

* fix build error

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: kakkokari-gtyih <67428053+kakkokari-gtyih@users.noreply.github.com>
2025-08-24 09:13:04 +09:00
syuilo bd0730e5e8 fix(backend): 削除されたユーザーがチャットメッセージにリアクションしている場合`chat/history`などでエラーになる問題を修正
Fix #16445
2025-08-23 17:37:15 +09:00
syuilo 07ccb82691
Update CHANGELOG with recent feature and fix entries 2025-08-22 19:40:15 +09:00
github-actions[bot] 16030c6381 Bump version to 2025.8.0-beta.3 2025-08-22 10:39:14 +00:00
syuilo 1f6716d69b
New Crowdin updates (#16436)
* New translations ja-jp.yml (Spanish)

* New translations ja-jp.yml (Catalan)

* New translations ja-jp.yml (German)

* New translations ja-jp.yml (Italian)

* New translations ja-jp.yml (Russian)

* New translations ja-jp.yml (English)

* New translations ja-jp.yml (Japanese, Kansai)

* New translations ja-jp.yml (Chinese Simplified)

* New translations ja-jp.yml (French)

* New translations ja-jp.yml (Korean)

* New translations ja-jp.yml (Portuguese)

* New translations ja-jp.yml (Turkish)

* New translations ja-jp.yml (Chinese Traditional)

* New translations ja-jp.yml (Vietnamese)

* New translations ja-jp.yml (Indonesian)

* New translations ja-jp.yml (Thai)

* New translations ja-jp.yml (Catalan)

* New translations ja-jp.yml (Chinese Traditional)

* New translations ja-jp.yml (Italian)
2025-08-22 19:37:20 +09:00
かっこかり ade603ff7a
fix(frontend): ページネーションの進行方向を指定できるように (#16433)
* fix(frontend): ページネーションの進行方向を指定できるように

* Update Changelog

* fix lint

* fix: directionをMkPaginationに移動

* fix

* fix

* fix

---------

Co-authored-by: syuilo <4439005+syuilo@users.noreply.github.com>
2025-08-22 19:34:20 +09:00
かっこかり 4d215bde10
fix(frontend): follow-up of #16380 2025-08-22 19:31:27 +09:00
かっこかり 20d81696e1
fix(backend): fix test (#16441)
* fix(backend): fix test

* fix

* fix
2025-08-22 18:26:19 +09:00
syuilo 8cbbb80e3f fix(backend): `notes/mentions` で場合によっては並び順が正しく返されない問題を修正
Fix #16398
2025-08-21 19:10:16 +09:00
かっこかり 1eabb21d69
fix(backend): クリップ一覧APIをページネーションに対応させる (#16434)
* fix(backend): クリップ一覧APIをページネーションに対応させる

* Update Changelog
2025-08-21 19:02:21 +09:00
かっこかり 7f6ba2e501
enhance: verify-emailにフロントエンドUIを実装 (#16431)
* enhance: メールのverifyをAPIに変更

* enhance(frontend): メールのVerifyページを追加

* fix

* 🎨

* 🎨

* Update Changelog

* lint
2025-08-21 16:52:30 +09:00
github-actions[bot] 8c433d2706 Bump version to 2025.8.0-beta.2 2025-08-20 07:41:12 +00:00
syuilo 3a856b785d
New Crowdin updates (#16416)
* New translations ja-jp.yml (Chinese Simplified)

* New translations ja-jp.yml (Korean)

* New translations ja-jp.yml (Chinese Traditional)

* New translations ja-jp.yml (English)

* New translations ja-jp.yml (Catalan)

* New translations ja-jp.yml (Chinese Simplified)

* New translations ja-jp.yml (Chinese Traditional)

* New translations ja-jp.yml (Thai)

* New translations ja-jp.yml (Italian)

* New translations ja-jp.yml (Chinese Traditional)

* New translations ja-jp.yml (Korean)

* New translations ja-jp.yml (Chinese Simplified)

* New translations ja-jp.yml (Catalan)

* New translations ja-jp.yml (Italian)
2025-08-20 16:35:50 +09:00
syuilo b07bf838e3
サーバー管理コマンド (#15882)
* wip

* Update cli.ts

* Update cli.ts

* wip

* Update CHANGELOG.md

* Delete cli.mjs
2025-08-20 16:35:26 +09:00
syuilo bdfe709319 fix(frontend): 読み込み直後にプラグインによるノートの書き換えが行われない問題を修正
ブート時にプラグインがロードされるまで待機
Fix #16428
2025-08-20 15:57:20 +09:00
github-actions[bot] 4190c6cb8e Bump version to 2025.8.0-beta.1 2025-08-19 05:24:14 +00:00
renovate[bot] 44a2d531b3
fix(deps): update dependency tmp to v0.2.4 [security] (#16374)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-19 14:20:53 +09:00
syuilo a17271a5c4
Update CHANGELOG.md 2025-08-19 14:19:54 +09:00
syuilo 3980172243 feat: 非ログイン時に表示されるトップページのスタイルを選択できるように 2025-08-19 14:15:19 +09:00
syuilo 3b4879133c 🎨 2025-08-18 18:06:32 +09:00
syuilo a1232cbae3
Update CHANGELOG.md 2025-08-18 14:47:35 +09:00
github-actions[bot] ebb014da4c Bump version to 2025.8.0-beta.0 2025-08-18 05:41:44 +00:00
syuilo 7786761d76 chore(frontend): more haptic 2025-08-18 14:24:14 +09:00
Souma ff334fe9d7
enhance(frontend): Add an option to customize Lockdown duration (#16405)
* chore(locales): Add "setManually" and "_time.month"

Add Japanese locales to auto-generate other languages.

* feat(frontend): Add text fields to set lockdown duration manually

Choose from presets or set it manually.

* refactor(frontend): Make objects contains option's values and labels

When adding a new option, it needed to write two times.

* docs(changelog): Add a description about this change

Users can notice what's changed by this PR.

* refactor(frontend): Manage state by MkSelect

The functions only initialize the values.

* refactor(frontend): Make the custom input as writable computed

Clean up the MkInput components.

* chore(locales): Switch to "custom"

A single word is better than sentence on this situation.

* refactor(frontend): Insert the custom button to presets

Users don't need to click multiple times to use prests.
2025-08-18 14:11:48 +09:00
syuilo ba40cb750b Update about-misskey.vue 2025-08-18 10:59:31 +09:00
syuilo fcde6789ff feat(frontend): introduce haptic feedback as experimental feature
#16410
2025-08-18 10:49:27 +09:00
github-actions[bot] 14cc42e305 Bump version to 2025.8.0-alpha.13 2025-08-18 01:22:39 +00:00
syuilo e481205342 enhance(frontend): update aiscript to 1.1.0 2025-08-18 10:18:34 +09:00
anatawa12 fea9f27fd6
chore: preserve notes with local reactions (#16412) 2025-08-17 17:08:38 +09:00
github-actions[bot] 9ea7340da6 Bump version to 2025.8.0-alpha.12 2025-08-15 13:44:57 +00:00
anatawa12 60f7278aff
fix: Remote Note Cleaning will delete notes embedded in a page (#16408)
* feat: preserve number of pages referencing the note

* chore: delete pages on account delete

* fix: notes on the pages are removed by CleanRemoteNotes

* test: add the simplest test for page embedded notes

* fix: section block is not considered

* fix: section block is not considered in migration

* chore: remove comments from columns

* revert unnecessary change

* add pageCount to webhook test

* fix type error on backend
2025-08-15 22:39:55 +09:00
syuilo bae92a944d enhance(frontend): improve enableInfiniteScroll stability
Close #16318
2025-08-15 12:40:37 +09:00
syuilo 7d30768769 fix(frontend): Botプロテクションの設定の変更検知が正しくない問題を修正 2025-08-15 12:10:14 +09:00
github-actions[bot] e444942c4e Bump version to 2025.8.0-alpha.11 2025-08-14 08:02:14 +00:00
饺子w (Yumechi) 90b9609341
enhance: performance for CleanRemoteNotesProcessorService (#16404)
* enhance: performance for CleanRemoteNotesProcessorService

Signed-off-by: eternal-flame-AD <yume@yumechi.jp>

* suggestions

Signed-off-by: eternal-flame-AD <yume@yumechi.jp>

* docs

Signed-off-by: eternal-flame-AD <yume@yumechi.jp>

* change initial limit to 100

Signed-off-by: eternal-flame-AD <yume@yumechi.jp>

* robustness for transient race conditions

Signed-off-by: eternal-flame-AD <yume@yumechi.jp>

* handle cursors in postgres

Signed-off-by: eternal-flame-AD <yume@yumechi.jp>

* robustness: transient errors and timeout handling

Signed-off-by: eternal-flame-AD <yume@yumechi.jp>

* use '0' as initial cursor

Signed-off-by: eternal-flame-AD <yume@yumechi.jp>

---------

Signed-off-by: eternal-flame-AD <yume@yumechi.jp>
2025-08-14 16:54:28 +09:00
syuilo c25a922928 Merge branch 'develop' of https://github.com/misskey-dev/misskey into develop 2025-08-14 16:50:59 +09:00
syuilo d26169ea32 Update about-misskey.vue 2025-08-14 16:50:56 +09:00
github-actions[bot] 8839d8d679 Bump version to 2025.8.0-alpha.10 2025-08-13 02:01:57 +00:00
syuilo ad6af74eef
New Crowdin updates (#16394)
* New translations ja-jp.yml (Turkish)

* New translations ja-jp.yml (Turkish)

* New translations ja-jp.yml (Turkish)

* New translations ja-jp.yml (Turkish)

* New translations ja-jp.yml (Turkish)

* New translations ja-jp.yml (Turkish)

* New translations ja-jp.yml (Turkish)

* New translations ja-jp.yml (Chinese Simplified)
2025-08-13 10:59:40 +09:00
Sayamame-beans 7bb43329bb
fix(frontend): メンション補完のためのサジェストが正しく表示されない問題を修正 (#16401)
* fix(frontend): mention-syntax detection for autocomplete doesn't work properly

* docs(changelog): update changelog
2025-08-13 10:51:23 +09:00
syuilo 4c41930554
Update CHANGELOG.md 2025-08-11 15:54:18 +09:00
syuilo 295f42b986
New Crowdin updates (#16386)
* New translations ja-jp.yml (Spanish)

* New translations ja-jp.yml (Catalan)

* New translations ja-jp.yml (German)

* New translations ja-jp.yml (Italian)

* New translations ja-jp.yml (Russian)

* New translations ja-jp.yml (English)

* New translations ja-jp.yml (Japanese, Kansai)

* New translations ja-jp.yml (Chinese Simplified)

* New translations ja-jp.yml (Romanian)

* New translations ja-jp.yml (French)

* New translations ja-jp.yml (Arabic)

* New translations ja-jp.yml (Czech)

* New translations ja-jp.yml (Korean)

* New translations ja-jp.yml (Norwegian)

* New translations ja-jp.yml (Polish)

* New translations ja-jp.yml (Portuguese)

* New translations ja-jp.yml (Slovak)

* New translations ja-jp.yml (Swedish)

* New translations ja-jp.yml (Turkish)

* New translations ja-jp.yml (Ukrainian)

* New translations ja-jp.yml (Chinese Traditional)

* New translations ja-jp.yml (Vietnamese)

* New translations ja-jp.yml (Indonesian)

* New translations ja-jp.yml (Bengali)

* New translations ja-jp.yml (Thai)

* New translations ja-jp.yml (Uzbek)

* New translations ja-jp.yml (English)

* New translations ja-jp.yml (Korean)

* New translations ja-jp.yml (English)

* New translations ja-jp.yml (Chinese Traditional)

* New translations ja-jp.yml (Spanish)

* New translations ja-jp.yml (Catalan)

* New translations ja-jp.yml (Catalan)

* New translations ja-jp.yml (Turkish)

* New translations ja-jp.yml (Turkish)

* New translations ja-jp.yml (Turkish)

* New translations ja-jp.yml (Turkish)

* New translations ja-jp.yml (Thai)

* New translations ja-jp.yml (Turkish)

* New translations ja-jp.yml (Italian)
2025-08-11 12:25:59 +09:00
syuilo 299f9e3115 fix test 2025-08-11 12:09:25 +09:00
syuilo 1d8e183883 fix test 2025-08-11 12:01:32 +09:00
zyoshoka f242892382
fix(workflow): correct references to built image's ID (#16391) 2025-08-10 23:54:06 +09:00
syuilo ecc033f101 fix(backend): fix type errors caused by dependency update
https: //github.com/misskey-dev/misskey/pull/16308
Co-Authored-By: かっこかり <67428053+kakkokari-gtyih@users.noreply.github.com>
2025-08-09 17:41:01 +09:00
renovate[bot] 684dbfd626
fix(deps): update [backend] update dependencies (#16201)
* fix(deps): update [backend] update dependencies

* Update HttpRequestService.ts

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: syuilo <4439005+syuilo@users.noreply.github.com>
2025-08-09 17:00:59 +09:00
github-actions[bot] aa5c42997f Bump version to 2025.8.0-alpha.9 2025-08-09 07:45:10 +00:00
github-actions[bot] e7b666f567 Bump version to 2025.8.0-alpha.8 2025-08-09 06:04:17 +00:00
renovate[bot] 0f7c0ed053
chore(deps): update [misskey-js] update dependencies (#16346)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-09 14:48:02 +09:00
syuilo 1e92bb4a0a chore(backend): remove unused codes 2025-08-09 14:44:36 +09:00
かっこかり b5b7914073
enhance: ユーザー検索を制限できるように (#16380)
* enhance: ユーザー検索を制限できるように

* Update Changelog
2025-08-09 14:41:11 +09:00
syuilo 7595bff43b fix(backend): prevent run repeatable job immediately
Fix #16357
2025-08-09 14:37:09 +09:00
github-actions[bot] 72864fcbd0 Bump version to 2025.8.0-alpha.7 2025-08-09 05:27:57 +00:00
かっこかり 7b44271530
Update CHANGELOG.md 2025-08-09 11:55:09 +09:00
かっこかり ee5cf74c2c
Merge branch 'develop' into enh-14810 2025-08-09 11:54:50 +09:00
かっこかり 1dffa020cf
Update CHANGELOG.md 2025-06-14 15:02:45 +09:00
かっこかり ec967822bf
Merge branch 'develop' into enh-14810 2025-06-14 15:02:23 +09:00
kakkokari-gtyih 256579a70e fix lint 2025-04-29 17:10:18 +09:00
かっこかり ab8d58235d
Merge branch 'develop' into enh-14810 2025-04-29 17:08:50 +09:00
かっこかり 940f2a8fcf
Update CHANGELOG.md 2025-04-01 16:10:49 +09:00
かっこかり 32895eac43
Merge branch 'develop' into enh-14810 2025-04-01 16:10:24 +09:00
かっこかり 8e038de613
Merge branch 'develop' into enh-14810 2025-03-03 17:39:17 +09:00
かっこかり cd40bb4160
Merge branch 'develop' into enh-14810 2025-03-03 17:02:47 +09:00
かっこかり 6f90b916a4
Merge branch 'develop' into enh-14810 2025-02-28 18:43:24 +09:00
かっこかり 68561fb852
Merge branch 'develop' into enh-14810 2025-02-16 19:37:49 +09:00
かっこかり 66858cbb24
Merge branch 'develop' into enh-14810 2025-02-07 15:57:59 +09:00
かっこかり 9d32460e0b
Merge branch 'develop' into enh-14810 2025-02-05 19:09:31 +09:00
かっこかり ac1948ff2c
Merge branch 'develop' into enh-14810 2025-01-21 10:07:37 +09:00
かっこかり 4421b945bb
Merge branch 'develop' into enh-14810 2025-01-14 22:07:21 +09:00
かっこかり 76f7dd0672
Merge branch 'develop' into enh-14810 2025-01-08 20:02:01 +09:00
かっこかり 6c8369f12c
Merge branch 'develop' into enh-14810 2025-01-04 15:48:20 +09:00
かっこかり 9d8607b58f
Merge branch 'develop' into enh-14810 2025-01-04 15:31:26 +09:00
かっこかり f2d2b33c12
Merge branch 'develop' into enh-14810 2025-01-04 15:16:33 +09:00
かっこかり 24d7e78f5e
Merge branch 'develop' into enh-14810 2024-12-20 00:02:46 +09:00
かっこかり 517b283e05
Merge branch 'develop' into enh-14810 2024-12-10 10:37:29 +09:00
kakkokari-gtyih 4643eef71b tweak 2024-12-09 17:46:42 +09:00
kakkokari-gtyih def5a3dfae Update Changelog 2024-12-09 17:39:36 +09:00
kakkokari-gtyih 6df65d4bdd fix(frontend): デッキでダブルクリックするとウィンドウが2枚開く問題を修正 2024-12-09 17:39:04 +09:00
567 changed files with 14980 additions and 8452 deletions

View File

@ -105,6 +105,16 @@ port: 3000
# socket: /path/to/misskey.sock # socket: /path/to/misskey.sock
# chmodSocket: '777' # chmodSocket: '777'
# Proxy trust settings
#
# Changes how the server interpret the origin IP of the request.
#
# Any format supported by Fastify is accepted.
# Default: trust all proxies (i.e. trustProxy: true)
# See: https://fastify.dev/docs/latest/reference/server/#trustproxy
#
# trustProxy: 1
# ┌──────────────────────────┐ # ┌──────────────────────────┐
#───┘ PostgreSQL configuration └──────────────────────────────── #───┘ PostgreSQL configuration └────────────────────────────────

View File

@ -16,7 +16,7 @@ jobs:
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4.2.2 uses: actions/checkout@v4.3.0
- name: Setup pnpm - name: Setup pnpm
uses: pnpm/action-setup@v4.1.0 uses: pnpm/action-setup@v4.1.0

View File

@ -12,7 +12,7 @@ jobs:
steps: steps:
- name: Checkout head - name: Checkout head
uses: actions/checkout@v4.2.2 uses: actions/checkout@v4.3.0
- name: Setup Node.js - name: Setup Node.js
uses: actions/setup-node@v4.4.0 uses: actions/setup-node@v4.4.0
with: with:

View File

@ -18,7 +18,7 @@ jobs:
if: ${{ github.event.pull_request.mergeable == null || github.event.pull_request.mergeable == true }} if: ${{ github.event.pull_request.mergeable == null || github.event.pull_request.mergeable == true }}
steps: steps:
- name: checkout - name: checkout
uses: actions/checkout@v4.2.2 uses: actions/checkout@v4.3.0
with: with:
submodules: true submodules: true
persist-credentials: false persist-credentials: false
@ -66,7 +66,7 @@ jobs:
if: ${{ github.event.pull_request.mergeable == null || github.event.pull_request.mergeable == true }} if: ${{ github.event.pull_request.mergeable == null || github.event.pull_request.mergeable == true }}
steps: steps:
- name: checkout - name: checkout
uses: actions/checkout@v4.2.2 uses: actions/checkout@v4.3.0
with: with:
submodules: true submodules: true
persist-credentials: false persist-credentials: false

View File

@ -20,7 +20,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4.2.2 uses: actions/checkout@v4.3.0
- name: Check version - name: Check version
run: | run: |
if [ "$(jq -r '.version' package.json)" != "$(jq -r '.version' packages/misskey-js/package.json)" ]; then if [ "$(jq -r '.version' package.json)" != "$(jq -r '.version' packages/misskey-js/package.json)" ]; then

View File

@ -12,7 +12,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4.2.2 uses: actions/checkout@v4.3.0
- name: Check - name: Check
run: | run: |
counter=0 counter=0

View File

@ -10,7 +10,7 @@ jobs:
check_copyright_year: check_copyright_year:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4.2.2 - uses: actions/checkout@v4.3.0
- run: | - run: |
if [ "$(grep Copyright COPYING | sed -e 's/.*2014-\([0-9]*\) .*/\1/g')" -ne "$(date +%Y)" ]; then if [ "$(grep Copyright COPYING | sed -e 's/.*2014-\([0-9]*\) .*/\1/g')" -ne "$(date +%Y)" ]; then
echo "Please change copyright year!" echo "Please change copyright year!"

View File

@ -28,7 +28,7 @@ jobs:
wait_time: ${{ steps.get-wait-time.outputs.wait_time }} wait_time: ${{ steps.get-wait-time.outputs.wait_time }}
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4.2.2 uses: actions/checkout@v4.3.0
- name: Check allowed users - name: Check allowed users
id: check-allowed-users id: check-allowed-users

View File

@ -27,7 +27,7 @@ jobs:
platform=${{ matrix.platform }} platform=${{ matrix.platform }}
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
- name: Check out the repo - name: Check out the repo
uses: actions/checkout@v4.2.2 uses: actions/checkout@v4.3.0
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3 uses: docker/setup-buildx-action@v3
- name: Log in to Docker Hub - name: Log in to Docker Hub

View File

@ -32,7 +32,7 @@ jobs:
platform=${{ matrix.platform }} platform=${{ matrix.platform }}
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
- name: Check out the repo - name: Check out the repo
uses: actions/checkout@v4.2.2 uses: actions/checkout@v4.3.0
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3 uses: docker/setup-buildx-action@v3
- name: Docker meta - name: Docker meta

View File

@ -15,7 +15,7 @@ jobs:
DOCKER_CONTENT_TRUST: 1 DOCKER_CONTENT_TRUST: 1
DOCKLE_VERSION: 0.4.14 DOCKLE_VERSION: 0.4.14
steps: steps:
- uses: actions/checkout@v4.2.2 - uses: actions/checkout@v4.3.0
- name: Download and install dockle v${{ env.DOCKLE_VERSION }} - name: Download and install dockle v${{ env.DOCKLE_VERSION }}
run: | run: |
curl -L -o dockle.deb "https://github.com/goodwithtech/dockle/releases/download/v${DOCKLE_VERSION}/dockle_${DOCKLE_VERSION}_Linux-64bit.deb" curl -L -o dockle.deb "https://github.com/goodwithtech/dockle/releases/download/v${DOCKLE_VERSION}/dockle_${DOCKLE_VERSION}_Linux-64bit.deb"
@ -25,7 +25,7 @@ jobs:
cp ./compose_example.yml ./compose.yml cp ./compose_example.yml ./compose.yml
- run: | - run: |
docker compose up -d web docker compose up -d web
docker tag "$(docker compose images web | awk 'OFS=":" {print $4}' | tail -n +2)" misskey-web:latest docker tag "$(docker compose images --format json web | jq -r '.[] | .ID')" misskey-web:latest
- run: | - run: |
cmd="dockle --exit-code 1 misskey-web:latest ${image_name}" cmd="dockle --exit-code 1 misskey-web:latest ${image_name}"
echo "> ${cmd}" echo "> ${cmd}"

View File

@ -25,7 +25,7 @@ jobs:
ref: refs/pull/${{ github.event.number }}/merge ref: refs/pull/${{ github.event.number }}/merge
steps: steps:
- uses: actions/checkout@v4.2.2 - uses: actions/checkout@v4.3.0
with: with:
ref: ${{ matrix.ref }} ref: ${{ matrix.ref }}
submodules: true submodules: true

View File

@ -36,7 +36,7 @@ jobs:
pnpm_install: pnpm_install:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4.2.2 - uses: actions/checkout@v4.3.0
with: with:
fetch-depth: 0 fetch-depth: 0
submodules: true submodules: true
@ -69,7 +69,7 @@ jobs:
eslint-cache-version: v1 eslint-cache-version: v1
eslint-cache-path: ${{ github.workspace }}/node_modules/.cache/eslint-${{ matrix.workspace }} eslint-cache-path: ${{ github.workspace }}/node_modules/.cache/eslint-${{ matrix.workspace }}
steps: steps:
- uses: actions/checkout@v4.2.2 - uses: actions/checkout@v4.3.0
with: with:
fetch-depth: 0 fetch-depth: 0
submodules: true submodules: true
@ -81,7 +81,7 @@ jobs:
cache: 'pnpm' cache: 'pnpm'
- run: pnpm i --frozen-lockfile - run: pnpm i --frozen-lockfile
- name: Restore eslint cache - name: Restore eslint cache
uses: actions/cache@v4.2.3 uses: actions/cache@v4.3.0
with: with:
path: ${{ env.eslint-cache-path }} path: ${{ env.eslint-cache-path }}
key: eslint-${{ env.eslint-cache-version }}-${{ matrix.workspace }}-${{ hashFiles('**/pnpm-lock.yaml') }}-${{ github.ref_name }}-${{ github.sha }} key: eslint-${{ env.eslint-cache-version }}-${{ matrix.workspace }}-${{ hashFiles('**/pnpm-lock.yaml') }}-${{ github.ref_name }}-${{ github.sha }}
@ -99,7 +99,7 @@ jobs:
- sw - sw
- misskey-js - misskey-js
steps: steps:
- uses: actions/checkout@v4.2.2 - uses: actions/checkout@v4.3.0
with: with:
fetch-depth: 0 fetch-depth: 0
submodules: true submodules: true

View File

@ -14,7 +14,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
continue-on-error: true continue-on-error: true
steps: steps:
- uses: actions/checkout@v4.2.2 - uses: actions/checkout@v4.3.0
with: with:
fetch-depth: 0 fetch-depth: 0
submodules: true submodules: true

View File

@ -16,7 +16,7 @@ jobs:
id-token: write id-token: write
steps: steps:
- uses: actions/checkout@v4.2.2 - uses: actions/checkout@v4.3.0
with: with:
submodules: true submodules: true
- name: Setup pnpm - name: Setup pnpm

View File

@ -16,7 +16,7 @@ jobs:
# api-artifact # api-artifact
steps: steps:
- name: Download artifact - name: Download artifact
uses: actions/github-script@v7.0.1 uses: actions/github-script@v7.1.0
with: with:
script: | script: |
const fs = require('fs'); const fs = require('fs');

View File

@ -22,12 +22,12 @@ jobs:
NODE_OPTIONS: "--max_old_space_size=7168" NODE_OPTIONS: "--max_old_space_size=7168"
steps: steps:
- uses: actions/checkout@v4.2.2 - uses: actions/checkout@v4.3.0
if: github.event_name != 'pull_request_target' if: github.event_name != 'pull_request_target'
with: with:
fetch-depth: 0 fetch-depth: 0
submodules: true submodules: true
- uses: actions/checkout@v4.2.2 - uses: actions/checkout@v4.3.0
if: github.event_name == 'pull_request_target' if: github.event_name == 'pull_request_target'
with: with:
fetch-depth: 0 fetch-depth: 0
@ -90,7 +90,7 @@ jobs:
env: env:
CHROMATIC_PROJECT_TOKEN: ${{ secrets.CHROMATIC_PROJECT_TOKEN }} CHROMATIC_PROJECT_TOKEN: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
- name: Notify that Chromatic detects changes - name: Notify that Chromatic detects changes
uses: actions/github-script@v7.0.1 uses: actions/github-script@v7.1.0
if: github.event_name != 'pull_request_target' && steps.chromatic_push.outputs.success == 'false' if: github.event_name != 'pull_request_target' && steps.chromatic_push.outputs.success == 'false'
with: with:
github-token: ${{ secrets.GITHUB_TOKEN }} github-token: ${{ secrets.GITHUB_TOKEN }}

View File

@ -50,7 +50,7 @@ jobs:
- 56312:6379 - 56312:6379
steps: steps:
- uses: actions/checkout@v4.2.2 - uses: actions/checkout@v4.3.0
with: with:
submodules: true submodules: true
- name: Setup pnpm - name: Setup pnpm
@ -129,7 +129,7 @@ jobs:
- 56312:6379 - 56312:6379
steps: steps:
- uses: actions/checkout@v4.2.2 - uses: actions/checkout@v4.3.0
with: with:
submodules: true submodules: true
- name: Setup pnpm - name: Setup pnpm
@ -173,7 +173,7 @@ jobs:
POSTGRES_HOST_AUTH_METHOD: trust POSTGRES_HOST_AUTH_METHOD: trust
steps: steps:
- uses: actions/checkout@v4.2.2 - uses: actions/checkout@v4.3.0
with: with:
submodules: true submodules: true
- name: Setup pnpm - name: Setup pnpm

View File

@ -28,7 +28,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4.2.2 - uses: actions/checkout@v4.3.0
with: with:
submodules: true submodules: true
- name: Setup pnpm - name: Setup pnpm
@ -76,7 +76,7 @@ jobs:
- 56312:6379 - 56312:6379
steps: steps:
- uses: actions/checkout@v4.2.2 - uses: actions/checkout@v4.3.0
with: with:
submodules: true submodules: true
# https://github.com/cypress-io/cypress-docker-images/issues/150 # https://github.com/cypress-io/cypress-docker-images/issues/150

View File

@ -22,7 +22,7 @@ jobs:
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4.2.2 uses: actions/checkout@v4.3.0
- name: Setup pnpm - name: Setup pnpm
uses: pnpm/action-setup@v4.1.0 uses: pnpm/action-setup@v4.1.0

View File

@ -16,7 +16,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4.2.2 - uses: actions/checkout@v4.3.0
with: with:
submodules: true submodules: true
- name: Setup pnpm - name: Setup pnpm

View File

@ -17,7 +17,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4.2.2 - uses: actions/checkout@v4.3.0
with: with:
submodules: true submodules: true
- name: Setup pnpm - name: Setup pnpm

View File

@ -1,3 +1,48 @@
## 2025.10.0
### NOTE
- pnpm 10.16.0 が必要です
### General
- Feat: 予約投稿ができるようになりました
- デフォルトで作成可能数は1になっています。適宜ロールのポリシーで設定を行ってください。
- Enhance: 広告ごとにセンシティブフラグを設定できるようになりました
- Enhance: 依存関係の更新
- Enhance: 翻訳の更新
### Client
- Feat: アカウントのQRコードを表示・読み取りできるようになりました
- Feat: 動画を圧縮してアップロードできるようになりました
- Enhance: チャットの日本語名称がダイレクトメッセージに戻るとともに、ベータ版機能ではなくなりました
- Enhance: 画像編集にマスクエフェクト(塗りつぶし、ぼかし、モザイク)を追加
- Enhance: 画像編集の集中線エフェクトを強化
- Enhance: ウォーターマークにアカウントのQRコードを追加できるように
- Enhance: テーマをドラッグ&ドロップできるように
- Enhance: 絵文字ピッカーのサイズをより大きくできるように
- Enhance: 時刻計算のための基準値を一か所で管理するようにし、パフォーマンスを向上
- Fix: iOSで、デバイスがダークモードだと初回読み込み時にエラーになる問題を修正
- Fix: アクティビティウィジェットのグラフモードが動作しない問題を修正
- Fix: デッキでリンクをダブルクリックすると、ウィンドウが2枚開いてしまう問題を修正
### Server
- Enhance: ユーザーIPを確実に取得できるために設定ファイルにFastifyOptions.trustProxyを追加しました
## 2025.9.0
### Client
- Enhance: AiScriptAppウィジェットで構文エラーを検知してもダイアログではなくウィジェット内にエラーを表示するように
- Enhance: /flushページでサイトキャッシュをクリアできるようになりました
- Enhance: クリップ/リスト/アンテナ/ロール追加系メニュー項目において、表示件数を拡張
- Enhance: 「キャッシュを削除」ボタンでブラウザの内部キャッシュの削除も行えるように
- Enhance: CtrlキーCommandキーを押下しながらリンクをクリックすると新しいタブで開くように
- Fix: プッシュ通知を有効にできない問題を修正
- Fix: RSSティッカーウィジェットが正しく動作しない問題を修正
- Fix: プロファイルを復元後アカウントの切り替えができない問題を修正
- Fix: エラー画像が横に引き伸ばされてしまう問題に対応
### Server
- Fix: webpなどの画像に対してセンシティブなメディアの検出が適用されていなかった問題を修正
## 2025.8.0 ## 2025.8.0
### Note ### Note
@ -6,34 +51,48 @@
### General ### General
- ノートを削除した際、関連するノートが同時に削除されないようになりました - ノートを削除した際、関連するノートが同時に削除されないようになりました
- APIで、「replyIdが存在しているのにreplyがnull」や「renoteIdが存在しているのにrenoteがnull」であるという、今までにはなかったパターンが表れることになります - APIで、「replyIdが存在しているのにreplyがnull」や「renoteIdが存在しているのにrenoteがnull」であるという、今までにはなかったパターンが表れることになります
- 定期的に参照されていない古いリモートの投稿を削除する機能が実装されました(コントロールパネル→パフォーマンス→Remote Notes Cleaning) - 定期的に古いリモートの投稿を削除する機能が実装されました
- 既存のサーバーでは**デフォルトでオフ**、新規サーバーでは**デフォルトでオン**になります - コントロールパネル→パフォーマンス→Remote Notes Cleaning で有効化できます
- データベースの肥大化を防止することが可能です - データベースの肥大化を防止することが可能です
- 既存のサーバーで当機能を有効化した場合は、処理量が多くなるため、一時的にストレージ使用量が増加する可能性があります。 - 既存のサーバーで当機能を有効化した場合は、処理量が多くなるため、一時的にストレージ使用量が増加する可能性があります。
- 増加量を抑えるには、最大処理継続時間をデフォルトより短くしてください。 - 増加量を抑えるには、最大処理継続時間をデフォルトより短くしてください。
- データベースサイズへの効果が見られない場合はautovacuumが有効になっているか確認してください
- サーバーの初期設定が完了するまでは連合がオンにならないようになりました - サーバーの初期設定が完了するまでは連合がオンにならないようになりました
- 日本語における公開範囲名称の「ダイレクト」が「指名」に改称されました - 日本語における公開範囲名称の「ダイレクト」が「指名」に改称されました
- 実際の動作に即した名称になり、馴染みのない人でも理解しやすくなりました
- 他サービスにおける「ダイレクトメッセージ」に相当するMisskeyの機能は「チャット」ですが(過去のバージョンのMisskeyでも、当該機能は「チャット」ではなく「ダイレクトメッセージ」でした)、「ダイレクト投稿」という名称の機能が存在するとそちらがダイレクトメッセージ機能であるような誤解を生んでいました
- 今後、「チャット」の名称を「ダイレクトメッセージ」に戻す可能性があります
- mfm.jsをアップデートしました - mfm.jsをアップデートしました
- Enhance: Unicode 15.1 および 16.0 に収録されている絵文字に対応 - Enhance: Unicode 15.1 および 16.0 に収録されている絵文字に対応
- Enhance: acctに `.` が入っているユーザーのメンションに対応 - Enhance: acctに `.` が入っているユーザーのメンションに対応
- Fix: Unicode絵文字に隣接する異体字セレクタ`U+FE0F`)が絵文字として認識される問題を修正 - Fix: Unicode絵文字に隣接する異体字セレクタ`U+FE0F`)が絵文字として認識される問題を修正
- Enhance: ユーザー検索をロールポリシーで制限できるように
### Client ### Client
- Feat: AiScriptが1.0に更新されました - Feat: AiScriptが1.1.0に更新されました
- プラグインは1.0に対応したものが必要です - プラグインは1.xに対応したものが必要です
- Playはそのまま動作しますが、新規に作られるプリセットは1.0になります - Playはそのまま動作しますが、新規に作られるプリセットは1.xになります
- 以前のバージョンから無効化されていた note_view_interruptor が有効になりました - 以前のバージョンから無効化されていた note_view_interruptor が有効になりました
- ハンドラは同期的である必要があります
- Feat: セーフモード - Feat: セーフモード
- プラグイン・テーマ・カスタムCSSの使用でクライアントの起動に問題が発生した際に、これらを無効にして起動できます - プラグイン・テーマ・カスタムCSSの使用でクライアントの起動に問題が発生した際に、これらを無効にして起動できます
- 以下の方法でセーフモードを起動できます - 以下の方法でセーフモードを起動できます
- `g` キーを連打する - `g` キーを連打する
- URLに`?safemode=true`を付ける - URLに`?safemode=true`を付ける
- PWAのショートカットで Safemode を選択して起動する - PWAのショートカットで Safemode を選択して起動する
- Feat: 非ログイン時に表示されるトップページのスタイルを選択できるように
- コントロールパネル→ブランディング→エントランスページのスタイル
- Feat: ページのタブバーを下部に表示できるように - Feat: ページのタブバーを下部に表示できるように
- Enhance: コントロールパネルを検索できるように - Feat: (実験的)iOSでの触覚フィードバックを有効にできるように
- Feat: コントロールパネルを検索できるように
- Enhance: 「自動でもっと見る」オプションが有効になり、安定性が向上しました
- Enhance: トルコ語 (tr-TR) に対応 - Enhance: トルコ語 (tr-TR) に対応
- Enhance: 不必要な翻訳データを読み込まなくなり、パフォーマンスが向上しました - Enhance: 不必要な翻訳データを読み込まなくなり、パフォーマンスが向上しました
- Enhance: 画像エフェクトのパラメータ名の多言語対応 - Enhance: 画像エフェクトのパラメータ名の多言語対応
- Enhance: ートを非表示にする相対期間を1ヶ月単位で自由に指定できるように
- Enhance: メールアドレス確認画面のUIを改善
- Enhance: アイコンのスクロール追従を無効化する際の適用範囲を強化
- Enhance: レンダリングパフォーマンスの向上
- Enhance: 依存ソフトウェアの更新 - Enhance: 依存ソフトウェアの更新
- Fix: 投稿フォームでファイルのアップロードが中止または失敗した際のハンドリングを修正 - Fix: 投稿フォームでファイルのアップロードが中止または失敗した際のハンドリングを修正
- Fix: 一部の設定検索結果が存在しないパスになる問題を修正 - Fix: 一部の設定検索結果が存在しないパスになる問題を修正
@ -41,12 +100,29 @@
- Fix: テーマエディタが動作しない問題を修正 - Fix: テーマエディタが動作しない問題を修正
- Fix: チャンネルのハイライトページにノートが表示されない問題を修正 - Fix: チャンネルのハイライトページにノートが表示されない問題を修正
- Fix: カラムの名前が正しくリスト/チャンネルの名前にならない問題を修正 - Fix: カラムの名前が正しくリスト/チャンネルの名前にならない問題を修正
- Fix: 複数のメンションを1行に記述した場合に、サジェストが正しく表示されない問題を修正
- Fix: メンションとしての条件を満たしていても、特定の条件(`-`が含まれる場合など)で正しくサジェストされない問題を一部修正
- Fix: ユーザーの前後ノートを閲覧する機能が動作しない問題を修正
- Fix: 照会ダイアログでap/showでローカルユーザーを解決した際@username@nullに飛ばされる問題を修正
- Fix: アイコンのデコレーションを付ける際にデコレーションが表示されなくなる問題を修正
- Fix: タッチ操作時にマウスホバー時のユーザープレビューが開くことがある問題を修正
- Fix: 管理中アカウント一覧で正しい表示が行われない問題を修正
- Fix: lookupページでリモートURLを指定した際に正しく動作しない問題を修正
### Server ### Server
- Feat: サーバー管理コマンド
- `pnpm cli foo` の形式で実行可能です
- 現在以下のコマンドが利用可能です
- `reset-captcha` - CAPTCHA設定をリセットします
- Enhance: ノートの削除処理の効率化 - Enhance: ノートの削除処理の効率化
- Enhance: 全体的なパフォーマンスの向上 - Enhance: 全体的なパフォーマンスの向上
- Enhance: 依存ソフトウェアの更新 - Enhance: 依存ソフトウェアの更新
- Enhance: `clips/list` APIがページネーションに対応しました
- Fix: `notes/mentions` で場合によっては並び順が正しく返されない問題を修正
- Fix: SystemWebhook設定でsecretを空に出来ない問題を修正 - Fix: SystemWebhook設定でsecretを空に出来ない問題を修正
- Fix: 削除されたユーザーがチャットメッセージにリアクションしている場合`chat/history`などでエラーになる問題を修正
- Fix: Pageのアイキャッチ画像をドライブから消してもPageごと消えないように
- Fix: タイムラインAPIの withRenotes: false 時のレスポンスを修正
## 2025.7.0 ## 2025.7.0

View File

@ -4,8 +4,8 @@
*/ */
/* eslint-disable @typescript-eslint/explicit-function-return-type */ /* eslint-disable @typescript-eslint/explicit-function-return-type */
import { action } from '@storybook/addon-actions'; import { action } from 'storybook/actions';
import { StoryObj } from '@storybook/vue3'; import type { StoryObj } from '@storybook/vue3';
import { HttpResponse, http } from 'msw'; import { HttpResponse, http } from 'msw';
import { abuseUserReport } from '../packages/frontend/.storybook/fakes.js'; import { abuseUserReport } from '../packages/frontend/.storybook/fakes.js';
import { commonHandlers } from '../packages/frontend/.storybook/mocks.js'; import { commonHandlers } from '../packages/frontend/.storybook/mocks.js';

View File

@ -0,0 +1,232 @@
<!--
SPDX-FileCopyrightText: syuilo and misskey-project
SPDX-License-Identifier: AGPL-3.0-only
-->
<template>
<canvas ref="canvasEl" style="display: block; width: 100%; height: 100%; pointer-events: none;"></canvas>
</template>
<script lang="ts" setup>
import { onMounted, onUnmounted, useTemplateRef } from 'vue';
import isChromatic from 'chromatic/isChromatic';
import { initShaderProgram } from '@/utility/webgl.js';
const VERTEX_SHADER = `#version 300 es
in vec2 position;
out vec2 in_uv;
void main() {
in_uv = (position + 1.0) / 2.0;
gl_Position = vec4(position, 0.0, 1.0);
}
`;
const FRAGMENT_SHADER = `#version 300 es
precision mediump float;
const float PI = 3.141592653589793;
const float TWO_PI = 6.283185307179586;
const float HALF_PI = 1.5707963267948966;
in vec2 in_uv;
uniform vec2 in_resolution;
uniform float u_scale;
uniform float u_time;
uniform float u_seed;
uniform float u_angle;
uniform float u_radius;
uniform vec3 u_color;
uniform vec2 u_ripplePositions[16];
uniform float u_rippleRadiuses[16];
out vec4 out_color;
float getRipple(vec2 uv) {
float strength = 0.0;
float thickness = 0.05;
for (int i = 0; i < 16; i++) {
if (u_rippleRadiuses[i] <= 0.0) continue;
float d = distance(uv, u_ripplePositions[i]);
//
if (d < u_rippleRadiuses[i] + thickness && d > u_rippleRadiuses[i] - thickness) {
float gradate = abs(d - u_rippleRadiuses[i] + thickness) / thickness;
strength += (1.0 - u_rippleRadiuses[i]) * gradate;
}
//
if (d < u_rippleRadiuses[i] + thickness) {
strength += 0.25 * (1.0 - u_rippleRadiuses[i]);
}
}
return strength;
}
void main() {
float x_ratio = min(in_resolution.x / in_resolution.y, 1.0);
float y_ratio = min(in_resolution.y / in_resolution.x, 1.0);
float angle = -(u_angle * PI);
vec2 centeredUv = (in_uv - vec2(0.5, 0.5)) * vec2(x_ratio, y_ratio);
vec2 rotatedUV = vec2(
centeredUv.x * cos(angle) - centeredUv.y * sin(angle),
centeredUv.x * sin(angle) + centeredUv.y * cos(angle)
);
vec2 uv = rotatedUV;
float time = u_time * 0.00025;
float size = 1.0 / u_scale;
float size_half = size / 2.0;
float modX = mod(uv.x, size);
float modY = mod(uv.y, size);
vec2 pixelated_uv = vec2(
(size * (floor((uv.x - 0.5 - size) / size) + 0.5)),
(size * (floor((uv.y - 0.5 - size) / size) + 0.5))
) + vec2(0.5 + size, 0.5 + size);
float strength = getRipple(pixelated_uv);
float opacity = min(max(strength, 0.0), 1.0);
float threshold = ((u_radius / 2.0) / u_scale);
if (length(vec2(modX - size_half, modY - size_half)) < threshold) {
out_color = vec4(u_color.r, u_color.g, u_color.b, opacity);
//out_color = vec4(1.0);
return;
}
// debug
//float a = min(max(getRipple(uv), 0.0), 1.0);
//out_color = vec4(u_color.r, u_color.g, u_color.b, (opacity + a) / 2.0);
out_color = vec4(0.0, 0.0, 0.0, 0.0);
}
`;
const canvasEl = useTemplateRef('canvasEl');
const props = withDefaults(defineProps<{
scale?: number;
}>(), {
scale: 48,
});
let handle: ReturnType<typeof window['requestAnimationFrame']> | null = null;
onMounted(() => {
const canvas = canvasEl.value!;
let width = canvas.offsetWidth;
let height = canvas.offsetHeight;
canvas.width = width;
canvas.height = height;
const maybeGl = canvas.getContext('webgl2', { preserveDrawingBuffer: false, alpha: true, premultipliedAlpha: false, antialias: true });
if (maybeGl == null) return;
const gl = maybeGl;
const VERTICES = new Float32Array([-1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 1, -1]);
const vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, VERTICES, gl.STATIC_DRAW);
//gl.clearColor(0.0, 0.0, 0.0, 0.0);
//gl.clear(gl.COLOR_BUFFER_BIT);
const shaderProgram = initShaderProgram(gl, VERTEX_SHADER, FRAGMENT_SHADER);
gl.useProgram(shaderProgram);
const positionLocation = gl.getAttribLocation(shaderProgram, 'position');
gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(positionLocation);
const in_resolution = gl.getUniformLocation(shaderProgram, 'in_resolution');
gl.uniform2fv(in_resolution, [canvas.width, canvas.height]);
const u_time = gl.getUniformLocation(shaderProgram, 'u_time');
const u_seed = gl.getUniformLocation(shaderProgram, 'u_seed');
const u_scale = gl.getUniformLocation(shaderProgram, 'u_scale');
const u_angle = gl.getUniformLocation(shaderProgram, 'u_angle');
const u_radius = gl.getUniformLocation(shaderProgram, 'u_radius');
const u_color = gl.getUniformLocation(shaderProgram, 'u_color');
gl.uniform1f(u_seed, Math.random() * 1000);
gl.uniform1f(u_scale, props.scale);
gl.uniform1f(u_angle, 0.0);
gl.uniform1f(u_radius, 0.15);
gl.uniform3fv(u_color, [0.5, 1.0, 0]);
if (isChromatic()) {
gl.uniform1f(u_time, 0);
gl.drawArrays(gl.TRIANGLES, 0, 6);
} else {
let ripples = [] as { position: [number, number]; startTime: number; }[];
const LIFE_TIME = 1000 * 4;
function render(timeStamp: number) {
let sizeChanged = false;
if (Math.abs(height - canvas.offsetHeight) > 2) {
height = canvas.offsetHeight;
canvas.height = height;
sizeChanged = true;
}
if (Math.abs(width - canvas.offsetWidth) > 2) {
width = canvas.offsetWidth;
canvas.width = width;
sizeChanged = true;
}
if (sizeChanged && gl) {
gl.uniform2fv(in_resolution, [width, height]);
gl.viewport(0, 0, width, height);
}
gl.uniform1f(u_time, timeStamp);
if (Math.random() < 0.01 && ripples.length < 16) {
ripples.push({ position: [(Math.random() * 2) - 1, (Math.random() * 2) - 1], startTime: timeStamp });
}
for (let i = 0; i < 16; i++) {
const o = gl.getUniformLocation(shaderProgram, `u_ripplePositions[${i.toString()}]`);
const r = gl.getUniformLocation(shaderProgram, `u_rippleRadiuses[${i.toString()}]`);
const ripple = ripples[i];
if (ripple == null) {
gl.uniform2f(o, 0, 0);
gl.uniform1f(r, 0.0);
continue;
}
const delta = timeStamp - ripple.startTime;
gl.uniform2f(o, ripple.position[0], ripple.position[1]);
gl.uniform1f(r, delta / LIFE_TIME);
}
ripples = ripples.filter(r => (timeStamp - r.startTime) < LIFE_TIME);
if (ripples.length === 0) {
ripples.push({ position: [(Math.random() * 2) - 1, (Math.random() * 2) - 1], startTime: timeStamp });
}
gl.drawArrays(gl.TRIANGLES, 0, 6);
handle = window.requestAnimationFrame(render);
}
handle = window.requestAnimationFrame(render);
}
});
onUnmounted(() => {
if (handle) {
window.cancelAnimationFrame(handle);
}
// TODO: WebGL
});
</script>
<style lang="scss" module>
</style>

View File

@ -0,0 +1,190 @@
<!--
SPDX-FileCopyrightText: syuilo and misskey-project
SPDX-License-Identifier: AGPL-3.0-only
-->
<template>
<canvas ref="canvasEl" style="display: block; width: 100%; height: 100%; pointer-events: none;"></canvas>
</template>
<script lang="ts" setup>
import { onMounted, onUnmounted, useTemplateRef } from 'vue';
import isChromatic from 'chromatic/isChromatic';
import { GLSL_LIB_SNOISE, initShaderProgram } from '@/utility/webgl.js';
const VERTEX_SHADER = `#version 300 es
in vec2 position;
out vec2 in_uv;
void main() {
in_uv = (position + 1.0) / 2.0;
gl_Position = vec4(position, 0.0, 1.0);
}
`;
const FRAGMENT_SHADER = `#version 300 es
precision mediump float;
const float PI = 3.141592653589793;
const float TWO_PI = 6.283185307179586;
const float HALF_PI = 1.5707963267948966;
${GLSL_LIB_SNOISE}
in vec2 in_uv;
uniform vec2 in_resolution;
uniform float u_scale;
uniform float u_time;
uniform float u_seed;
uniform float u_angle;
uniform float u_radius;
uniform vec3 u_color;
out vec4 out_color;
void main() {
float x_ratio = min(in_resolution.x / in_resolution.y, 1.0);
float y_ratio = min(in_resolution.y / in_resolution.x, 1.0);
float size = 1.0 / u_scale;
float size_half = size / 2.0;
float angle = -(u_angle * PI);
vec2 centeredUv = (in_uv - vec2(0.5, 0.5)) * vec2(x_ratio, y_ratio);
vec2 rotatedUV = vec2(
centeredUv.x * cos(angle) - centeredUv.y * sin(angle),
centeredUv.x * sin(angle) + centeredUv.y * cos(angle)
);
vec2 uv = rotatedUV;
float modX = mod(uv.x, size);
float modY = mod(uv.y, size);
vec2 pixelated_uv = vec2(
(size * (floor((uv.x - 0.5 - size) / size) + 0.5)),
(size * (floor((uv.y - 0.5 - size) / size) + 0.5))
) + vec2(0.5 + size, 0.5 + size);
float time = u_time * 0.00025;
float noiseAScale = 1.0;
float noiseAX = (pixelated_uv.x + u_seed) * (u_scale / noiseAScale);
float noiseAY = (pixelated_uv.y + u_seed) * (u_scale / noiseAScale);
float noiseA = snoise(vec3(noiseAX, noiseAY, time * 2.0));
float noiseBScale = 32.0;
float noiseBX = (pixelated_uv.x + u_seed) * (u_scale / noiseBScale);
float noiseBY = (pixelated_uv.y + u_seed) * (u_scale / noiseBScale);
float noiseB = snoise(vec3(noiseBX, noiseBY, time));
float strength = 0.0;
strength += noiseA * 0.2;
strength += noiseB * 0.8;
float opacity = min(max(strength, 0.0), 1.0);
float threshold = ((u_radius / 2.0) / u_scale);
if (length(vec2(modX - size_half, modY - size_half)) < threshold) {
out_color = vec4(u_color.r, u_color.g, u_color.b, opacity);
return;
}
out_color = vec4(0.0, 0.0, 0.0, 0.0);
}
`;
const canvasEl = useTemplateRef('canvasEl');
const props = withDefaults(defineProps<{
scale?: number;
}>(), {
scale: 48,
});
let handle: ReturnType<typeof window['requestAnimationFrame']> | null = null;
onMounted(() => {
const canvas = canvasEl.value!;
let width = canvas.offsetWidth;
let height = canvas.offsetHeight;
canvas.width = width;
canvas.height = height;
const maybeGl = canvas.getContext('webgl2', { preserveDrawingBuffer: false, alpha: true, premultipliedAlpha: false, antialias: true });
if (maybeGl == null) return;
const gl = maybeGl;
const VERTICES = new Float32Array([-1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 1, -1]);
const vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, VERTICES, gl.STATIC_DRAW);
//gl.clearColor(0.0, 0.0, 0.0, 0.0);
//gl.clear(gl.COLOR_BUFFER_BIT);
const shaderProgram = initShaderProgram(gl, VERTEX_SHADER, FRAGMENT_SHADER);
gl.useProgram(shaderProgram);
const positionLocation = gl.getAttribLocation(shaderProgram, 'position');
gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(positionLocation);
const in_resolution = gl.getUniformLocation(shaderProgram, 'in_resolution');
gl.uniform2fv(in_resolution, [canvas.width, canvas.height]);
const u_time = gl.getUniformLocation(shaderProgram, 'u_time');
const u_seed = gl.getUniformLocation(shaderProgram, 'u_seed');
const u_scale = gl.getUniformLocation(shaderProgram, 'u_scale');
const u_angle = gl.getUniformLocation(shaderProgram, 'u_angle');
const u_radius = gl.getUniformLocation(shaderProgram, 'u_radius');
const u_color = gl.getUniformLocation(shaderProgram, 'u_color');
gl.uniform1f(u_seed, Math.random() * 1000);
gl.uniform1f(u_scale, props.scale);
gl.uniform1f(u_angle, 0.0);
gl.uniform1f(u_radius, 0.15);
gl.uniform3fv(u_color, [0.5, 1.0, 0]);
if (isChromatic()) {
gl.uniform1f(u_time, 0);
gl.drawArrays(gl.TRIANGLES, 0, 6);
} else {
function render(timeStamp: number) {
let sizeChanged = false;
if (Math.abs(height - canvas.offsetHeight) > 2) {
height = canvas.offsetHeight;
canvas.height = height;
sizeChanged = true;
}
if (Math.abs(width - canvas.offsetWidth) > 2) {
width = canvas.offsetWidth;
canvas.width = width;
sizeChanged = true;
}
if (sizeChanged && gl) {
gl.uniform2fv(in_resolution, [width, height]);
gl.viewport(0, 0, width, height);
}
gl.uniform1f(u_time, timeStamp);
gl.drawArrays(gl.TRIANGLES, 0, 6);
handle = window.requestAnimationFrame(render);
}
handle = window.requestAnimationFrame(render);
}
});
onUnmounted(() => {
if (handle) {
window.cancelAnimationFrame(handle);
}
// TODO: WebGL
});
</script>
<style lang="scss" module>
</style>

View File

@ -1599,3 +1599,13 @@ _watermarkEditor:
type: "نوع" type: "نوع"
image: "صور" image: "صور"
advanced: "متقدم" advanced: "متقدم"
_imageEffector:
_fxProps:
scale: "الحجم"
size: "الحجم"
offset: "الموضع"
color: "اللون"
opacity: "الشفافية"
_qr:
showTabTitle: "المظهر"
raw: "نص"

View File

@ -1357,3 +1357,13 @@ _watermarkEditor:
text: "লেখা" text: "লেখা"
image: "ছবি" image: "ছবি"
advanced: "উন্নত" advanced: "উন্নত"
_imageEffector:
_fxProps:
scale: "আকার"
size: "আকার"
color: "রং"
opacity: "অস্বচ্ছতা"
lightness: "উজ্জ্বল করুন"
_qr:
showTabTitle: "প্রদর্শন"
raw: "লেখা"

View File

@ -253,6 +253,7 @@ noteDeleteConfirm: "Segur que voleu eliminar aquesta publicació?"
pinLimitExceeded: "No podeu fixar més publicacions" pinLimitExceeded: "No podeu fixar més publicacions"
done: "Fet" done: "Fet"
processing: "S'està processant..." processing: "S'està processant..."
preprocessing: "Preparant"
preview: "Vista prèvia" preview: "Vista prèvia"
default: "Per defecte" default: "Per defecte"
defaultValueIs: "Per defecte: {value}" defaultValueIs: "Per defecte: {value}"
@ -1054,6 +1055,7 @@ permissionDeniedError: "Operació no permesa "
permissionDeniedErrorDescription: "Aquest compte no té suficients permisos per dur a terme aquesta acció " permissionDeniedErrorDescription: "Aquest compte no té suficients permisos per dur a terme aquesta acció "
preset: "Predefinit" preset: "Predefinit"
selectFromPresets: "Escull des dels predefinits" selectFromPresets: "Escull des dels predefinits"
custom: "Personalitzat"
achievements: "Assoliments" achievements: "Assoliments"
gotInvalidResponseError: "Resposta del servidor invàlida " gotInvalidResponseError: "Resposta del servidor invàlida "
gotInvalidResponseErrorDescription: "No es pot contactar amb el servidor o potser es troba fora de línia per manteniment. Provar-ho de nou més tard." gotInvalidResponseErrorDescription: "No es pot contactar amb el servidor o potser es troba fora de línia per manteniment. Provar-ho de nou més tard."
@ -1092,6 +1094,7 @@ prohibitedWordsDescription2: "Fent servir espais crearà expressions AND si l'ex
hiddenTags: "Etiquetes ocultes" hiddenTags: "Etiquetes ocultes"
hiddenTagsDescription: "La visibilitat de totes les notes que continguin qualsevol de les paraules configurades seran, automàticament, afegides a \"Inici\". Pots llistar diferents paraules separant les per línies noves." hiddenTagsDescription: "La visibilitat de totes les notes que continguin qualsevol de les paraules configurades seran, automàticament, afegides a \"Inici\". Pots llistar diferents paraules separant les per línies noves."
notesSearchNotAvailable: "La cerca de notes no es troba disponible." notesSearchNotAvailable: "La cerca de notes no es troba disponible."
usersSearchNotAvailable: "La cerca d'usuaris no està disponible."
license: "Llicència" license: "Llicència"
unfavoriteConfirm: "Esborrar dels favorits?" unfavoriteConfirm: "Esborrar dels favorits?"
myClips: "Els meus retalls" myClips: "Els meus retalls"
@ -1243,7 +1246,7 @@ releaseToRefresh: "Deixar anar per actualitzar"
refreshing: "Recarregant..." refreshing: "Recarregant..."
pullDownToRefresh: "Llisca cap a baix per recarregar" pullDownToRefresh: "Llisca cap a baix per recarregar"
useGroupedNotifications: "Mostrar les notificacions agrupades " useGroupedNotifications: "Mostrar les notificacions agrupades "
signupPendingError: "Hi ha hagut un problema verificant l'adreça de correu electrònic. L'enllaç pot haver caducat." emailVerificationFailedError: "Hem tingut un problema en verificar la teva adreça de correu electrònic. És probable que l'enllaç estigui caducat."
cwNotationRequired: "Si està activat \"Amagar contingut\" s'ha d'escriure una descripció " cwNotationRequired: "Si està activat \"Amagar contingut\" s'ha d'escriure una descripció "
doReaction: "Afegeix una reacció " doReaction: "Afegeix una reacció "
code: "Codi" code: "Codi"
@ -1314,6 +1317,7 @@ acknowledgeNotesAndEnable: "Activa'l després de comprendre els possibles perill
federationSpecified: "Aquest servidor treballa amb una federació de llistes blanques. No pot interactuar amb altres servidors que no siguin els especificats per l'administrador." federationSpecified: "Aquest servidor treballa amb una federació de llistes blanques. No pot interactuar amb altres servidors que no siguin els especificats per l'administrador."
federationDisabled: "La unió es troba deshabilitada en aquest servidor. No es pot interactuar amb usuaris d'altres servidors." federationDisabled: "La unió es troba deshabilitada en aquest servidor. No es pot interactuar amb usuaris d'altres servidors."
draft: "Esborrany " draft: "Esborrany "
draftsAndScheduledNotes: "Esborranys i publicacions programades"
confirmOnReact: "Confirmar en reaccionar" confirmOnReact: "Confirmar en reaccionar"
reactAreYouSure: "Vols reaccionar amb \"{emoji}\"?" reactAreYouSure: "Vols reaccionar amb \"{emoji}\"?"
markAsSensitiveConfirm: "Vols marcar aquest contingut com a sensible?" markAsSensitiveConfirm: "Vols marcar aquest contingut com a sensible?"
@ -1341,6 +1345,8 @@ postForm: "Formulari de publicació"
textCount: "Nombre de caràcters " textCount: "Nombre de caràcters "
information: "Informació" information: "Informació"
chat: "Xat" chat: "Xat"
directMessage: "Xateja amb aquest usuari"
directMessage_short: "Missatge"
migrateOldSettings: "Migrar la configuració anterior" migrateOldSettings: "Migrar la configuració anterior"
migrateOldSettings_description: "Normalment això es fa automàticament, però si la transició no es fa, el procés es pot iniciar manualment. S'esborrarà la configuració actual." migrateOldSettings_description: "Normalment això es fa automàticament, però si la transició no es fa, el procés es pot iniciar manualment. S'esborrarà la configuració actual."
compress: "Comprimir " compress: "Comprimir "
@ -1368,16 +1374,35 @@ redisplayAllTips: "Torna ha mostrat tots els trucs i consells"
hideAllTips: "Amagar tots els trucs i consells" hideAllTips: "Amagar tots els trucs i consells"
defaultImageCompressionLevel: "Nivell de comprensió de la imatge per defecte" defaultImageCompressionLevel: "Nivell de comprensió de la imatge per defecte"
defaultImageCompressionLevel_description: "Baixa, conserva la qualitat de la imatge però la mida de l'arxiu és més gran. <br>Alta, redueix la mida de l'arxiu però també la qualitat de la imatge." defaultImageCompressionLevel_description: "Baixa, conserva la qualitat de la imatge però la mida de l'arxiu és més gran. <br>Alta, redueix la mida de l'arxiu però també la qualitat de la imatge."
defaultCompressionLevel: "Nivell de compressió predeterminat"
defaultCompressionLevel_description: "Si el redueixes augmentaràs la qualitat de la imatge, però la mida de l'arxiu serà més gran. <br>Si augmentes l'opció redueixes la mida de l'arxiu i la qualitat de la imatge és pitjor."
inMinutes: "Minut(s)" inMinutes: "Minut(s)"
inDays: "Di(a)(es)" inDays: "Di(a)(es)"
safeModeEnabled: "Mode segur activat" safeModeEnabled: "Mode segur activat"
pluginsAreDisabledBecauseSafeMode: "Els afegits no estan activats perquè el mode segur està activat." pluginsAreDisabledBecauseSafeMode: "Els afegits no estan activats perquè el mode segur està activat."
customCssIsDisabledBecauseSafeMode: "El CSS personalitzat no s'aplica perquè el mode segur es troba activat." customCssIsDisabledBecauseSafeMode: "El CSS personalitzat no s'aplica perquè el mode segur es troba activat."
themeIsDefaultBecauseSafeMode: "El tema predeterminat es farà servir mentre el mode segur estigui activat. Una vegada es desactivi el mode segur es restablirà el tema escollit." themeIsDefaultBecauseSafeMode: "El tema predeterminat es farà servir mentre el mode segur estigui activat. Una vegada es desactivi el mode segur es restablirà el tema escollit."
thankYouForTestingBeta: "Gràcies per ajudar-nos a provar la versió beta!"
createUserSpecifiedNote: "Crear notes especificades per l'usuari "
schedulePost: "Programar una nota"
scheduleToPostOnX: "Programar una nota per {x}"
scheduledToPostOnX: "S'ha programat la nota per {x}"
schedule: "Programa"
scheduled: "Programat"
_compression:
_quality:
high: "Qualitat alta"
medium: "Qualitat mitjana"
low: "Qualitat baixa"
_size:
large: "Mida gran"
medium: "Mida mitjana"
small: "Mida petita"
_order: _order:
newest: "Més recent" newest: "Més recent"
oldest: "Antigues primer" oldest: "Antigues primer"
_chat: _chat:
messages: "Missatge"
noMessagesYet: "Encara no tens missatges " noMessagesYet: "Encara no tens missatges "
newMessage: "Missatge nou" newMessage: "Missatge nou"
individualChat: "Xat individual " individualChat: "Xat individual "
@ -1534,7 +1559,7 @@ _announcement:
needConfirmationToRead: "Es necessita confirmació de lectura de la notificació " needConfirmationToRead: "Es necessita confirmació de lectura de la notificació "
needConfirmationToReadDescription: "Si s'activa es mostrarà un diàleg per confirmar la lectura d'aquesta notificació. A més aquesta notificació serà exclosa de qualsevol funcionalitat com \"Marcar tot com a llegit\"." needConfirmationToReadDescription: "Si s'activa es mostrarà un diàleg per confirmar la lectura d'aquesta notificació. A més aquesta notificació serà exclosa de qualsevol funcionalitat com \"Marcar tot com a llegit\"."
end: "Final de la notificació " end: "Final de la notificació "
tooManyActiveAnnouncementDescription: "Tenir massa notificacions actives pot empitjorar l'experiència de l'usuari. Considera finalitzar els avisos que siguin antics." tooManyActiveAnnouncementDescription: "Tenir masses notificacions actives pot empitjorar l'experiència de l'usuari. Considera finalitzar els avisos que siguin antics."
readConfirmTitle: "Marcar com llegida?" readConfirmTitle: "Marcar com llegida?"
readConfirmText: "Això marcarà el contingut de \"{title}\" com llegit." readConfirmText: "Això marcarà el contingut de \"{title}\" com llegit."
shouldNotBeUsedToPresentPermanentInfo: "Ja que l'ús de notificacions pot impactar l'experiència dels nous usuaris, és recomanable fer servir les notificacions amb el flux d'informació en comptes de fer-les servir en un únic bloc." shouldNotBeUsedToPresentPermanentInfo: "Ja que l'ús de notificacions pot impactar l'experiència dels nous usuaris, és recomanable fer servir les notificacions amb el flux d'informació en comptes de fer-les servir en un únic bloc."
@ -1641,7 +1666,7 @@ _serverSettings:
reactionsBufferingDescription: "Quan s'activa aquesta opció millora bastant el rendiment en recuperar les línies de temps reduint la càrrega de la base. Com a contrapunt, augmentarà l'ús de memòria de Redís. Desactiva aquesta opció en cas de tenir un servidor amb poca memòria o si tens problemes d'inestabilitat." reactionsBufferingDescription: "Quan s'activa aquesta opció millora bastant el rendiment en recuperar les línies de temps reduint la càrrega de la base. Com a contrapunt, augmentarà l'ús de memòria de Redís. Desactiva aquesta opció en cas de tenir un servidor amb poca memòria o si tens problemes d'inestabilitat."
remoteNotesCleaning: "Neteja automàtica de notes remotes" remoteNotesCleaning: "Neteja automàtica de notes remotes"
remoteNotesCleaning_description: "Quan activis aquesta opció, periòdicament es netejaran les notes remotes que no es consultin, això evitarà que la base de dades se" remoteNotesCleaning_description: "Quan activis aquesta opció, periòdicament es netejaran les notes remotes que no es consultin, això evitarà que la base de dades se"
remoteNotesCleaningMaxProcessingDuration: "D'oració màxima del temps de funcionament del procés de neteja" remoteNotesCleaningMaxProcessingDuration: "Duració màxima del temps de funcionament del procés de neteja"
remoteNotesCleaningExpiryDaysForEachNotes: "Duració mínima de conservació de les notes" remoteNotesCleaningExpiryDaysForEachNotes: "Duració mínima de conservació de les notes"
inquiryUrl: "URL de consulta " inquiryUrl: "URL de consulta "
inquiryUrlDescription: "Escriu adreça URL per al formulari de consulta per al mantenidor del servidor o una pàgina web amb el contacte d'informació." inquiryUrlDescription: "Escriu adreça URL per al formulari de consulta per al mantenidor del servidor o una pàgina web amb el contacte d'informació."
@ -1663,6 +1688,9 @@ _serverSettings:
userGeneratedContentsVisibilityForVisitor_description2: "La publicació incondicional de tots els continguts del servidor a internet, incloent-hi els continguts remots rebuts pel servidor, comporta riscos. Això és extremadament important per els espectadors que desconeixen el caràcter descentralitzat dels continguts, ja que poden percebre erroneament els continguts remots com contingut generat per el propi servidor." userGeneratedContentsVisibilityForVisitor_description2: "La publicació incondicional de tots els continguts del servidor a internet, incloent-hi els continguts remots rebuts pel servidor, comporta riscos. Això és extremadament important per els espectadors que desconeixen el caràcter descentralitzat dels continguts, ja que poden percebre erroneament els continguts remots com contingut generat per el propi servidor."
restartServerSetupWizardConfirm_title: "Vols tornar a executar l'assistent de configuració inicial del servidor?" restartServerSetupWizardConfirm_title: "Vols tornar a executar l'assistent de configuració inicial del servidor?"
restartServerSetupWizardConfirm_text: "Algunes configuracions actuals seran restablertes." restartServerSetupWizardConfirm_text: "Algunes configuracions actuals seran restablertes."
entrancePageStyle: "Estil de la pàgina d'inici"
showTimelineForVisitor: "Mostrar la línia de temps"
showActivitiesForVisitor: "Mostrar activitat"
_userGeneratedContentsVisibilityForVisitor: _userGeneratedContentsVisibilityForVisitor:
all: "Tot obert al públic " all: "Tot obert al públic "
localOnly: "Només es publiquen els continguts locals, el contingut remot es manté privat" localOnly: "Només es publiquen els continguts locals, el contingut remot es manté privat"
@ -1999,6 +2027,7 @@ _role:
descriptionOfRateLimitFactor: "Límits baixos són menys restrictius, límits alts són més restrictius." descriptionOfRateLimitFactor: "Límits baixos són menys restrictius, límits alts són més restrictius."
canHideAds: "Pot amagar la publicitat" canHideAds: "Pot amagar la publicitat"
canSearchNotes: "Pot cercar notes" canSearchNotes: "Pot cercar notes"
canSearchUsers: "Pot cercar usuaris"
canUseTranslator: "Pot fer servir el traductor" canUseTranslator: "Pot fer servir el traductor"
avatarDecorationLimit: "Nombre màxim de decoracions que es poden aplicar els avatars" avatarDecorationLimit: "Nombre màxim de decoracions que es poden aplicar els avatars"
canImportAntennas: "Autoritza la importació d'antenes " canImportAntennas: "Autoritza la importació d'antenes "
@ -2011,6 +2040,7 @@ _role:
uploadableFileTypes_caption: "Especifica el tipus MIME. Es poden especificar diferents tipus MIME separats amb una nova línia, i es poden especificar comodins amb asteriscs (*). (Per exemple: image/*)" uploadableFileTypes_caption: "Especifica el tipus MIME. Es poden especificar diferents tipus MIME separats amb una nova línia, i es poden especificar comodins amb asteriscs (*). (Per exemple: image/*)"
uploadableFileTypes_caption2: "Pot que no sigui possible determinar el tipus MIME d'alguns arxius. Per permetre aquests tipus d'arxius afegeix {x} a les especificacions." uploadableFileTypes_caption2: "Pot que no sigui possible determinar el tipus MIME d'alguns arxius. Per permetre aquests tipus d'arxius afegeix {x} a les especificacions."
noteDraftLimit: "Nombre possible d'esborranys de notes al servidor" noteDraftLimit: "Nombre possible d'esborranys de notes al servidor"
scheduledNoteLimit: "Màxim nombre de notes programades que es poden crear simultàniament"
watermarkAvailable: "Pots fer servir la marca d'aigua" watermarkAvailable: "Pots fer servir la marca d'aigua"
_condition: _condition:
roleAssignedTo: "Assignat a rols manuals" roleAssignedTo: "Assignat a rols manuals"
@ -2069,7 +2099,7 @@ _ad:
timezoneinfo: "El dia de la setmana ve determinat del fus horari del servidor." timezoneinfo: "El dia de la setmana ve determinat del fus horari del servidor."
adsSettings: "Configurar la publicitat" adsSettings: "Configurar la publicitat"
notesPerOneAd: "Interval d'emplaçament publicitari en temps real (Notes per anuncis)" notesPerOneAd: "Interval d'emplaçament publicitari en temps real (Notes per anuncis)"
setZeroToDisable: "Ajusta aquest valor a 0 per deshabilitar l'actualització d'anuncis en temps real" setZeroToDisable: "Ajusta aquest valor a 0 per deshabilitar l'actualització de publicitat en temps real"
adsTooClose: "L'interval actual pot fer que l'experiència de l'usuari sigui dolenta perquè l'interval és molt baix." adsTooClose: "L'interval actual pot fer que l'experiència de l'usuari sigui dolenta perquè l'interval és molt baix."
_forgotPassword: _forgotPassword:
enterEmail: "Escriu l'adreça de correu electrònic amb la que et vas registrar. S'enviarà un correu electrònic amb un enllaç perquè puguis canviar-la." enterEmail: "Escriu l'adreça de correu electrònic amb la que et vas registrar. S'enviarà un correu electrònic amb un enllaç perquè puguis canviar-la."
@ -2271,6 +2301,7 @@ _time:
minute: "Minut(s)" minute: "Minut(s)"
hour: "Hor(a)(es)" hour: "Hor(a)(es)"
day: "Di(a)(es)" day: "Di(a)(es)"
month: "Mes(os)"
_2fa: _2fa:
alreadyRegistered: "J has registrat un dispositiu d'autenticació de doble factor." alreadyRegistered: "J has registrat un dispositiu d'autenticació de doble factor."
registerTOTP: "Registrar una aplicació autenticadora" registerTOTP: "Registrar una aplicació autenticadora"
@ -2445,7 +2476,7 @@ _widgets:
chooseList: "Tria una llista" chooseList: "Tria una llista"
clicker: "Clicker" clicker: "Clicker"
birthdayFollowings: "Usuaris que fan l'aniversari avui" birthdayFollowings: "Usuaris que fan l'aniversari avui"
chat: "Xat" chat: "Xateja amb aquest usuari"
_cw: _cw:
hide: "Amagar" hide: "Amagar"
show: "Carregar més" show: "Carregar més"
@ -2635,6 +2666,8 @@ _notification:
youReceivedFollowRequest: "Has rebut una petició de seguiment" youReceivedFollowRequest: "Has rebut una petició de seguiment"
yourFollowRequestAccepted: "La teva petició de seguiment ha sigut acceptada" yourFollowRequestAccepted: "La teva petició de seguiment ha sigut acceptada"
pollEnded: "Ja pots veure els resultats de l'enquesta " pollEnded: "Ja pots veure els resultats de l'enquesta "
scheduledNotePosted: "Una nota programada ha sigut publicada"
scheduledNotePostFailed: "Ha fallat la publicació d'una nota programada"
newNote: "Nota nova" newNote: "Nota nova"
unreadAntennaNote: "Antena {name}" unreadAntennaNote: "Antena {name}"
roleAssigned: "Rol assignat " roleAssigned: "Rol assignat "
@ -2714,7 +2747,7 @@ _deck:
mentions: "Mencions" mentions: "Mencions"
direct: "Publicacions directes" direct: "Publicacions directes"
roleTimeline: "Línia de temps dels rols" roleTimeline: "Línia de temps dels rols"
chat: "Xat" chat: "Xateja amb aquest usuari"
_dialog: _dialog:
charactersExceeded: "Has arribat al màxim de caràcters! Actualment és {current} de {max}" charactersExceeded: "Has arribat al màxim de caràcters! Actualment és {current} de {max}"
charactersBelow: "Ets per sota del mínim de caràcters! Actualment és {current} de {min}" charactersBelow: "Ets per sota del mínim de caràcters! Actualment és {current} de {min}"
@ -3160,14 +3193,16 @@ _watermarkEditor:
opacity: "Opacitat" opacity: "Opacitat"
scale: "Mida" scale: "Mida"
text: "Text" text: "Text"
qr: "Codi QR"
position: "Posició " position: "Posició "
margin: "Marge"
type: "Tipus" type: "Tipus"
image: "Imatges" image: "Imatges"
advanced: "Avançat" advanced: "Avançat"
angle: "Angle"
stripe: "Bandes" stripe: "Bandes"
stripeWidth: "Amplada de la banda" stripeWidth: "Amplada de la banda"
stripeFrequency: "Freqüència de la banda" stripeFrequency: "Freqüència de la banda"
angle: "Angle"
polkadot: "Lunars" polkadot: "Lunars"
checker: "Escacs" checker: "Escacs"
polkadotMainDotOpacity: "Opacitat del lunar principal" polkadotMainDotOpacity: "Opacitat del lunar principal"
@ -3175,16 +3210,20 @@ _watermarkEditor:
polkadotSubDotOpacity: "Opacitat del lunar secundari" polkadotSubDotOpacity: "Opacitat del lunar secundari"
polkadotSubDotRadius: "Mida del lunar secundari" polkadotSubDotRadius: "Mida del lunar secundari"
polkadotSubDotDivisions: "Nombre de punts secundaris" polkadotSubDotDivisions: "Nombre de punts secundaris"
leaveBlankToAccountUrl: "Si deixes aquest camp buit, es farà servir l'URL del teu compte"
_imageEffector: _imageEffector:
title: "Efecte" title: "Efecte"
addEffect: "Afegeix un efecte" addEffect: "Afegeix un efecte"
discardChangesConfirm: "Vols descartar els canvis i sortir?" discardChangesConfirm: "Vols descartar els canvis i sortir?"
nothingToConfigure: "No hi ha opcions de configuració disponibles"
_fxs: _fxs:
chromaticAberration: "Aberració cromàtica" chromaticAberration: "Aberració cromàtica"
glitch: "Glitch" glitch: "Glitch"
mirror: "Mirall" mirror: "Mirall"
invert: "Inversió cromàtica " invert: "Inversió cromàtica "
grayscale: "Monocrom " grayscale: "Monocrom "
blur: "Desenfocament"
pixelate: "Mosaic"
colorAdjust: "Correcció de color" colorAdjust: "Correcció de color"
colorClamp: "Compressió cromàtica " colorClamp: "Compressió cromàtica "
colorClampAdvanced: "Compressió de cromàtica avançada " colorClampAdvanced: "Compressió de cromàtica avançada "
@ -3196,6 +3235,43 @@ _imageEffector:
checker: "Escacs" checker: "Escacs"
blockNoise: "Bloqueig de soroll" blockNoise: "Bloqueig de soroll"
tearing: "Trencament d'imatge " tearing: "Trencament d'imatge "
fill: "Omplir"
_fxProps:
angle: "Angle"
scale: "Mida"
size: "Mida"
radius: "Radi"
samples: "Mida de la mostra"
offset: "Posició "
color: "Color"
opacity: "Opacitat"
normalize: "Normalitzar"
amount: "Quantitat"
lightness: "Brillantor"
contrast: "Contrast"
hue: "Tonalitat"
brightness: "Brillantor"
saturation: "Saturació"
max: "Màxim"
min: "Mínim"
direction: "Direcció "
phase: "Fase"
frequency: "Freqüència "
strength: "Intensitat"
glitchChannelShift: "Canvi de canal "
seed: "Llindar"
redComponent: "Component vermell"
greenComponent: "Component verd"
blueComponent: "Component blau"
threshold: "Llindar"
centerX: "Centre de X"
centerY: "Centre de Y"
zoomLinesSmoothing: "Suavitzat"
zoomLinesSmoothingDescription: "Els paràmetres de suavitzat i amplada de línia en augmentar no es poden fer servir junts."
zoomLinesThreshold: "Amplada de línia a l'augmentar "
zoomLinesMaskSize: "Diàmetre del centre"
zoomLinesBlack: "Obscurir"
circle: "Cercle"
drafts: "Esborrany " drafts: "Esborrany "
_drafts: _drafts:
select: "Seleccionar esborrany" select: "Seleccionar esborrany"
@ -3211,3 +3287,22 @@ _drafts:
restoreFromDraft: "Restaurar des dels esborranys" restoreFromDraft: "Restaurar des dels esborranys"
restore: "Restaurar esborrany" restore: "Restaurar esborrany"
listDrafts: "Llistat d'esborranys" listDrafts: "Llistat d'esborranys"
schedule: "Programació esborranys"
listScheduledNotes: "Llista de notes programades"
cancelSchedule: "Cancel·lar la programació"
qr: "Codi QR"
_qr:
showTabTitle: "Veure"
readTabTitle: "Escanejar "
shareTitle: "{name} {acct}"
shareText: "Segueix-me al Fediverse"
chooseCamera: "Seleccionar càmera "
cannotToggleFlash: "No es pot activar el flaix"
turnOnFlash: "Activar el flaix"
turnOffFlash: "Apagar el flaix"
startQr: "Reiniciar el lector de codis QR"
stopQr: "Parar el lector de codis QR"
noQrCodeFound: "No s'ha trobat cap codi QR"
scanFile: "Escanejar la imatge des del dispositiu"
raw: "Text"
mfm: "MFM"

View File

@ -2053,3 +2053,14 @@ _watermarkEditor:
type: "Typ" type: "Typ"
image: "Obrázky" image: "Obrázky"
advanced: "Pokročilé" advanced: "Pokročilé"
_imageEffector:
_fxProps:
scale: "Velikost"
size: "Velikost"
offset: "Pozice"
color: "Barva"
opacity: "Průhlednost"
lightness: "Zesvětlit"
_qr:
showTabTitle: "Zobrazit"
raw: "Text"

View File

@ -1243,7 +1243,6 @@ releaseToRefresh: "Zum Aktualisieren loslassen"
refreshing: "Wird aktualisiert..." refreshing: "Wird aktualisiert..."
pullDownToRefresh: "Zum Aktualisieren ziehen" pullDownToRefresh: "Zum Aktualisieren ziehen"
useGroupedNotifications: "Benachrichtigungen gruppieren" useGroupedNotifications: "Benachrichtigungen gruppieren"
signupPendingError: "Beim Überprüfen der Mailadresse ist etwas schiefgelaufen. Der Link könnte abgelaufen sein."
cwNotationRequired: "Ist \"Inhaltswarnung verwenden\" aktiviert, muss eine Beschreibung gegeben werden." cwNotationRequired: "Ist \"Inhaltswarnung verwenden\" aktiviert, muss eine Beschreibung gegeben werden."
doReaction: "Reagieren" doReaction: "Reagieren"
code: "Code" code: "Code"
@ -1341,6 +1340,7 @@ postForm: "Notizfenster"
textCount: "Zeichenanzahl" textCount: "Zeichenanzahl"
information: "Über" information: "Über"
chat: "Chat" chat: "Chat"
directMessage: "Mit dem Benutzer chatten"
migrateOldSettings: "Alte Client-Einstellungen migrieren" migrateOldSettings: "Alte Client-Einstellungen migrieren"
migrateOldSettings_description: "Dies sollte normalerweise automatisch geschehen, aber wenn die Migration aus irgendeinem Grund nicht erfolgreich war, kannst du den Migrationsprozess selbst manuell auslösen. Die aktuellen Konfigurationsinformationen werden dabei überschrieben." migrateOldSettings_description: "Dies sollte normalerweise automatisch geschehen, aber wenn die Migration aus irgendeinem Grund nicht erfolgreich war, kannst du den Migrationsprozess selbst manuell auslösen. Die aktuellen Konfigurationsinformationen werden dabei überschrieben."
compress: "Komprimieren" compress: "Komprimieren"
@ -2434,7 +2434,7 @@ _widgets:
chooseList: "Liste auswählen" chooseList: "Liste auswählen"
clicker: "Klickzähler" clicker: "Klickzähler"
birthdayFollowings: "Nutzer, die heute Geburtstag haben" birthdayFollowings: "Nutzer, die heute Geburtstag haben"
chat: "Chat" chat: "Mit dem Benutzer chatten"
_cw: _cw:
hide: "Inhalt verbergen" hide: "Inhalt verbergen"
show: "Inhalt anzeigen" show: "Inhalt anzeigen"
@ -2703,7 +2703,7 @@ _deck:
mentions: "Erwähnungen" mentions: "Erwähnungen"
direct: "Direktnachrichten" direct: "Direktnachrichten"
roleTimeline: "Rollenchronik" roleTimeline: "Rollenchronik"
chat: "Chat" chat: "Mit dem Benutzer chatten"
_dialog: _dialog:
charactersExceeded: "Maximallänge überschritten! Momentan {current} von {max}" charactersExceeded: "Maximallänge überschritten! Momentan {current} von {max}"
charactersBelow: "Minimallänge unterschritten! Momentan {current} von {min}" charactersBelow: "Minimallänge unterschritten! Momentan {current} von {min}"
@ -3147,10 +3147,10 @@ _watermarkEditor:
type: "Art" type: "Art"
image: "Bilder" image: "Bilder"
advanced: "Fortgeschritten" advanced: "Fortgeschritten"
angle: "Winkel"
stripe: "Streifen" stripe: "Streifen"
stripeWidth: "Linienbreite" stripeWidth: "Linienbreite"
stripeFrequency: "Linienanzahl" stripeFrequency: "Linienanzahl"
angle: "Winkel"
polkadot: "Punktmuster" polkadot: "Punktmuster"
polkadotMainDotOpacity: "Deckkraft des Hauptpunktes" polkadotMainDotOpacity: "Deckkraft des Hauptpunktes"
polkadotMainDotRadius: "Größe des Hauptpunktes" polkadotMainDotRadius: "Größe des Hauptpunktes"
@ -3173,6 +3173,14 @@ _imageEffector:
distort: "Verzerrung" distort: "Verzerrung"
stripe: "Streifen" stripe: "Streifen"
polkadot: "Punktmuster" polkadot: "Punktmuster"
_fxProps:
angle: "Winkel"
scale: "Größe"
size: "Größe"
offset: "Position"
color: "Farbe"
opacity: "Transparenz"
lightness: "Erhellen"
drafts: "Entwurf" drafts: "Entwurf"
_drafts: _drafts:
select: "Entwurf auswählen" select: "Entwurf auswählen"
@ -3187,3 +3195,6 @@ _drafts:
restoreFromDraft: "Aus Entwurf wiederherstellen" restoreFromDraft: "Aus Entwurf wiederherstellen"
restore: "Wiederherstellen" restore: "Wiederherstellen"
listDrafts: "Liste der Entwürfe" listDrafts: "Liste der Entwürfe"
_qr:
showTabTitle: "Anzeigeart"
raw: "Text"

View File

@ -253,6 +253,7 @@ noteDeleteConfirm: "Are you sure you want to delete this note?"
pinLimitExceeded: "You cannot pin any more notes" pinLimitExceeded: "You cannot pin any more notes"
done: "Done" done: "Done"
processing: "Processing..." processing: "Processing..."
preprocessing: "Preparing..."
preview: "Preview" preview: "Preview"
default: "Default" default: "Default"
defaultValueIs: "Default: {value}" defaultValueIs: "Default: {value}"
@ -1054,6 +1055,7 @@ permissionDeniedError: "Operation denied"
permissionDeniedErrorDescription: "This account does not have the permission to perform this action." permissionDeniedErrorDescription: "This account does not have the permission to perform this action."
preset: "Preset" preset: "Preset"
selectFromPresets: "Choose from presets" selectFromPresets: "Choose from presets"
custom: "Custom"
achievements: "Achievements" achievements: "Achievements"
gotInvalidResponseError: "Invalid server response" gotInvalidResponseError: "Invalid server response"
gotInvalidResponseErrorDescription: "The server may be unreachable or undergoing maintenance. Please try again later." gotInvalidResponseErrorDescription: "The server may be unreachable or undergoing maintenance. Please try again later."
@ -1092,6 +1094,7 @@ prohibitedWordsDescription2: "Using spaces will create AND expressions and surro
hiddenTags: "Hidden hashtags" hiddenTags: "Hidden hashtags"
hiddenTagsDescription: "Select tags which will not shown on trend list.\nMultiple tags could be registered by lines." hiddenTagsDescription: "Select tags which will not shown on trend list.\nMultiple tags could be registered by lines."
notesSearchNotAvailable: "Note search is unavailable." notesSearchNotAvailable: "Note search is unavailable."
usersSearchNotAvailable: "User search is not available."
license: "License" license: "License"
unfavoriteConfirm: "Really remove from favorites?" unfavoriteConfirm: "Really remove from favorites?"
myClips: "My clips" myClips: "My clips"
@ -1216,8 +1219,8 @@ showRepliesToOthersInTimeline: "Show replies to others in timeline"
hideRepliesToOthersInTimeline: "Hide replies to others from timeline" hideRepliesToOthersInTimeline: "Hide replies to others from timeline"
showRepliesToOthersInTimelineAll: "Show replies to others from everyone you follow in timeline" showRepliesToOthersInTimelineAll: "Show replies to others from everyone you follow in timeline"
hideRepliesToOthersInTimelineAll: "Hide replies to others from everyone you follow in timeline" hideRepliesToOthersInTimelineAll: "Hide replies to others from everyone you follow in timeline"
confirmShowRepliesAll: "This operation is irreversible. Would you really like to show replies to others from everyone you follow in your timeline?" confirmShowRepliesAll: "Are you sure you want to show replies from everyone you follow in your timeline? This action is irreversible."
confirmHideRepliesAll: "This operation is irreversible. Would you really like to hide replies to others from everyone you follow in your timeline?" confirmHideRepliesAll: "Are you sure you want to hide replies from everyone you follow in your timeline? This action is irreversible."
externalServices: "External Services" externalServices: "External Services"
sourceCode: "Source code" sourceCode: "Source code"
sourceCodeIsNotYetProvided: "Source code is not yet available. Contact the administrator to fix this problem." sourceCodeIsNotYetProvided: "Source code is not yet available. Contact the administrator to fix this problem."
@ -1243,7 +1246,7 @@ releaseToRefresh: "Release to refresh"
refreshing: "Refreshing..." refreshing: "Refreshing..."
pullDownToRefresh: "Pull down to refresh" pullDownToRefresh: "Pull down to refresh"
useGroupedNotifications: "Display grouped notifications" useGroupedNotifications: "Display grouped notifications"
signupPendingError: "There was a problem verifying the email address. The link may have expired." emailVerificationFailedError: "A problem occurred while verifying your email address. The link may have expired."
cwNotationRequired: "If \"Hide content\" is enabled, a description must be provided." cwNotationRequired: "If \"Hide content\" is enabled, a description must be provided."
doReaction: "Add reaction" doReaction: "Add reaction"
code: "Code" code: "Code"
@ -1314,6 +1317,7 @@ acknowledgeNotesAndEnable: "Turn on after understanding the precautions."
federationSpecified: "This server is operated in a whitelist federation. Interacting with servers other than those designated by the administrator is not allowed." federationSpecified: "This server is operated in a whitelist federation. Interacting with servers other than those designated by the administrator is not allowed."
federationDisabled: "Federation is disabled on this server. You cannot interact with users on other servers." federationDisabled: "Federation is disabled on this server. You cannot interact with users on other servers."
draft: "Drafts" draft: "Drafts"
draftsAndScheduledNotes: "Drafts and scheduled notes"
confirmOnReact: "Confirm when reacting" confirmOnReact: "Confirm when reacting"
reactAreYouSure: "Would you like to add a \"{emoji}\" reaction?" reactAreYouSure: "Would you like to add a \"{emoji}\" reaction?"
markAsSensitiveConfirm: "Do you want to set this media as sensitive?" markAsSensitiveConfirm: "Do you want to set this media as sensitive?"
@ -1341,6 +1345,8 @@ postForm: "Posting form"
textCount: "Character count" textCount: "Character count"
information: "About" information: "About"
chat: "Chat" chat: "Chat"
directMessage: "Chat with user"
directMessage_short: "Message"
migrateOldSettings: "Migrate old client settings" migrateOldSettings: "Migrate old client settings"
migrateOldSettings_description: "This should be done automatically but if for some reason the migration was not successful, you can trigger the migration process yourself manually. The current configuration information will be overwritten." migrateOldSettings_description: "This should be done automatically but if for some reason the migration was not successful, you can trigger the migration process yourself manually. The current configuration information will be overwritten."
compress: "Compress" compress: "Compress"
@ -1368,16 +1374,35 @@ redisplayAllTips: "Show all “Tips & Tricks” again"
hideAllTips: "Hide all \"Tips & Tricks\"" hideAllTips: "Hide all \"Tips & Tricks\""
defaultImageCompressionLevel: "Default image compression level" defaultImageCompressionLevel: "Default image compression level"
defaultImageCompressionLevel_description: "Lower level preserves image quality but increases file size.<br>Higher level reduce file size, but reduce image quality." defaultImageCompressionLevel_description: "Lower level preserves image quality but increases file size.<br>Higher level reduce file size, but reduce image quality."
defaultCompressionLevel: "Default compression level"
defaultCompressionLevel_description: "Lower compression preserves quality but increases file size.<br>Higher compression reduces file size but lowers quality."
inMinutes: "Minute(s)" inMinutes: "Minute(s)"
inDays: "Day(s)" inDays: "Day(s)"
safeModeEnabled: "Safe mode is enabled" safeModeEnabled: "Safe mode is enabled"
pluginsAreDisabledBecauseSafeMode: "All plugins are disabled because safe mode is enabled." pluginsAreDisabledBecauseSafeMode: "All plugins are disabled because safe mode is enabled."
customCssIsDisabledBecauseSafeMode: "Custom CSS is not applied because safe mode is enabled." customCssIsDisabledBecauseSafeMode: "Custom CSS is not applied because safe mode is enabled."
themeIsDefaultBecauseSafeMode: "While safe mode is active, the default theme is used. Disabling safe mode will revert these changes." themeIsDefaultBecauseSafeMode: "While safe mode is active, the default theme is used. Disabling safe mode will revert these changes."
thankYouForTestingBeta: "Thank you for helping us test the beta version!"
createUserSpecifiedNote: "Create a direct note"
schedulePost: "Schedule note"
scheduleToPostOnX: "Scheduled to note on {x}"
scheduledToPostOnX: "Note is scheduled for {x}"
schedule: "Schedule"
scheduled: "Scheduled"
_compression:
_quality:
high: "High quality"
medium: "Medium quality"
low: "Low quality"
_size:
large: "Large size"
medium: "Medium size"
small: "Small size"
_order: _order:
newest: "Newest First" newest: "Newest First"
oldest: "Oldest First" oldest: "Oldest First"
_chat: _chat:
messages: "Messages"
noMessagesYet: "No messages yet" noMessagesYet: "No messages yet"
newMessage: "New message" newMessage: "New message"
individualChat: "Private Chat" individualChat: "Private Chat"
@ -1465,6 +1490,7 @@ _settings:
contentsUpdateFrequency_description2: "When real-time mode is on, content is updated in real time regardless of this setting." contentsUpdateFrequency_description2: "When real-time mode is on, content is updated in real time regardless of this setting."
showUrlPreview: "Show URL preview" showUrlPreview: "Show URL preview"
showAvailableReactionsFirstInNote: "Show available reactions at the top." showAvailableReactionsFirstInNote: "Show available reactions at the top."
showPageTabBarBottom: "Show page tab bar at the bottom"
_chat: _chat:
showSenderName: "Show sender's name" showSenderName: "Show sender's name"
sendOnEnter: "Press Enter to send" sendOnEnter: "Press Enter to send"
@ -1662,6 +1688,9 @@ _serverSettings:
userGeneratedContentsVisibilityForVisitor_description2: "Unconditionally publishing all content on the server to the Internet, including remote content received by the server is risky. This is especially important for guests who are unaware of the distributed nature of the content, as they may mistakenly believe that even remote content is content created by users on the server." userGeneratedContentsVisibilityForVisitor_description2: "Unconditionally publishing all content on the server to the Internet, including remote content received by the server is risky. This is especially important for guests who are unaware of the distributed nature of the content, as they may mistakenly believe that even remote content is content created by users on the server."
restartServerSetupWizardConfirm_title: "Restart server setup wizard?" restartServerSetupWizardConfirm_title: "Restart server setup wizard?"
restartServerSetupWizardConfirm_text: "Some current settings will be reset." restartServerSetupWizardConfirm_text: "Some current settings will be reset."
entrancePageStyle: "Entrance page style"
showTimelineForVisitor: "Show timeline"
showActivitiesForVisitor: "Show activities"
_userGeneratedContentsVisibilityForVisitor: _userGeneratedContentsVisibilityForVisitor:
all: "Everything is public" all: "Everything is public"
localOnly: "Only local content is published, remote content is kept private" localOnly: "Only local content is published, remote content is kept private"
@ -1998,19 +2027,21 @@ _role:
descriptionOfRateLimitFactor: "Lower rate limits are less restrictive, higher ones more restrictive. " descriptionOfRateLimitFactor: "Lower rate limits are less restrictive, higher ones more restrictive. "
canHideAds: "Can hide ads" canHideAds: "Can hide ads"
canSearchNotes: "Usage of note search" canSearchNotes: "Usage of note search"
canSearchUsers: "User search"
canUseTranslator: "Translator usage" canUseTranslator: "Translator usage"
avatarDecorationLimit: "Maximum number of avatar decorations that can be applied" avatarDecorationLimit: "Maximum number of avatar decorations"
canImportAntennas: "Allow importing antennas" canImportAntennas: "Can import antennas"
canImportBlocking: "Allow importing blocking" canImportBlocking: "Can import blocking"
canImportFollowing: "Allow importing following" canImportFollowing: "Can import following"
canImportMuting: "Allow importing muting" canImportMuting: "Can import muting"
canImportUserLists: "Allow importing lists" canImportUserLists: "Can import lists"
chatAvailability: "Allow Chat" chatAvailability: "Chat"
uploadableFileTypes: "Uploadable file types" uploadableFileTypes: "Uploadable file types"
uploadableFileTypes_caption: "Specifies the allowed MIME/file types. Multiple MIME types can be specified by separating them with a new line, and wildcards can be specified with an asterisk (*). (e.g., image/*)" uploadableFileTypes_caption: "Specifies the allowed MIME/file types. Multiple MIME types can be specified by separating them with a new line, and wildcards can be specified with an asterisk (*). (e.g., image/*)"
uploadableFileTypes_caption2: "Some files types might fail to be detected. To allow such files, add {x} to the specification." uploadableFileTypes_caption2: "Some files types might fail to be detected. To allow such files, add {x} to the specification."
noteDraftLimit: "Number of possible drafts of server notes" noteDraftLimit: "Number of possible drafts of server notes"
watermarkAvailable: "Availability of watermark function" scheduledNoteLimit: "Maximum number of simultaneous scheduled notes"
watermarkAvailable: "Watermark function"
_condition: _condition:
roleAssignedTo: "Assigned to manual roles" roleAssignedTo: "Assigned to manual roles"
isLocal: "Local user" isLocal: "Local user"
@ -2270,6 +2301,7 @@ _time:
minute: "Minute(s)" minute: "Minute(s)"
hour: "Hour(s)" hour: "Hour(s)"
day: "Day(s)" day: "Day(s)"
month: "Month(s)"
_2fa: _2fa:
alreadyRegistered: "You have already registered a 2-factor authentication device." alreadyRegistered: "You have already registered a 2-factor authentication device."
registerTOTP: "Register authenticator app" registerTOTP: "Register authenticator app"
@ -2444,7 +2476,7 @@ _widgets:
chooseList: "Select a list" chooseList: "Select a list"
clicker: "Clicker" clicker: "Clicker"
birthdayFollowings: "Today's Birthdays" birthdayFollowings: "Today's Birthdays"
chat: "Chat" chat: "Chat with user"
_cw: _cw:
hide: "Hide" hide: "Hide"
show: "Show content" show: "Show content"
@ -2634,6 +2666,8 @@ _notification:
youReceivedFollowRequest: "You've received a follow request" youReceivedFollowRequest: "You've received a follow request"
yourFollowRequestAccepted: "Your follow request was accepted" yourFollowRequestAccepted: "Your follow request was accepted"
pollEnded: "Poll results have become available" pollEnded: "Poll results have become available"
scheduledNotePosted: "Scheduled note has been posted"
scheduledNotePostFailed: "Failed to post scheduled note"
newNote: "New note" newNote: "New note"
unreadAntennaNote: "Antenna {name}" unreadAntennaNote: "Antenna {name}"
roleAssigned: "Role given" roleAssigned: "Role given"
@ -2713,7 +2747,7 @@ _deck:
mentions: "Mentions" mentions: "Mentions"
direct: "Direct notes" direct: "Direct notes"
roleTimeline: "Role Timeline" roleTimeline: "Role Timeline"
chat: "Chat" chat: "Chat with user"
_dialog: _dialog:
charactersExceeded: "You've exceeded the maximum character limit! Currently at {current} of {max}." charactersExceeded: "You've exceeded the maximum character limit! Currently at {current} of {max}."
charactersBelow: "You're below the minimum character limit! Currently at {current} of {min}." charactersBelow: "You're below the minimum character limit! Currently at {current} of {min}."
@ -3159,14 +3193,16 @@ _watermarkEditor:
opacity: "Opacity" opacity: "Opacity"
scale: "Size" scale: "Size"
text: "Text" text: "Text"
qr: "QR Code"
position: "Position" position: "Position"
margin: "Margin"
type: "Type" type: "Type"
image: "Images" image: "Images"
advanced: "Advanced" advanced: "Advanced"
angle: "Angle"
stripe: "Stripes" stripe: "Stripes"
stripeWidth: "Line width" stripeWidth: "Line width"
stripeFrequency: "Lines count" stripeFrequency: "Lines count"
angle: "Angle"
polkadot: "Polkadot" polkadot: "Polkadot"
checker: "Checker" checker: "Checker"
polkadotMainDotOpacity: "Opacity of the main dot" polkadotMainDotOpacity: "Opacity of the main dot"
@ -3174,16 +3210,20 @@ _watermarkEditor:
polkadotSubDotOpacity: "Opacity of the secondary dot" polkadotSubDotOpacity: "Opacity of the secondary dot"
polkadotSubDotRadius: "Size of the secondary dot" polkadotSubDotRadius: "Size of the secondary dot"
polkadotSubDotDivisions: "Number of sub-dots." polkadotSubDotDivisions: "Number of sub-dots."
leaveBlankToAccountUrl: "Leave blank to use account URL"
_imageEffector: _imageEffector:
title: "Effects" title: "Effects"
addEffect: "Add Effects" addEffect: "Add Effects"
discardChangesConfirm: "Are you sure you want to leave? You have unsaved changes." discardChangesConfirm: "Are you sure you want to leave? You have unsaved changes."
nothingToConfigure: "No configurable options available"
_fxs: _fxs:
chromaticAberration: "Chromatic Aberration" chromaticAberration: "Chromatic Aberration"
glitch: "Glitch" glitch: "Glitch"
mirror: "Mirror" mirror: "Mirror"
invert: "Invert Colors" invert: "Invert Colors"
grayscale: "Grayscale" grayscale: "Grayscale"
blur: "Blur"
pixelate: "Pixelate"
colorAdjust: "Color Correction" colorAdjust: "Color Correction"
colorClamp: "Color Compression" colorClamp: "Color Compression"
colorClampAdvanced: "Color Compression (Advanced)" colorClampAdvanced: "Color Compression (Advanced)"
@ -3195,6 +3235,43 @@ _imageEffector:
checker: "Checker" checker: "Checker"
blockNoise: "Block Noise" blockNoise: "Block Noise"
tearing: "Tearing" tearing: "Tearing"
fill: "Fill"
_fxProps:
angle: "Angle"
scale: "Size"
size: "Size"
radius: "Radius"
samples: "Sample count"
offset: "Position"
color: "Color"
opacity: "Opacity"
normalize: "Normalize"
amount: "Amount"
lightness: "Lighten"
contrast: "Contrast"
hue: "Hue"
brightness: "Brightness"
saturation: "Saturation"
max: "Maximum"
min: "Minimum"
direction: "Direction"
phase: "Phase"
frequency: "Frequency"
strength: "Strength"
glitchChannelShift: "Channel shift"
seed: "Seed value"
redComponent: "Red component"
greenComponent: "Green component"
blueComponent: "Blue component"
threshold: "Threshold"
centerX: "Center X"
centerY: "Center Y"
zoomLinesSmoothing: "Smoothing"
zoomLinesSmoothingDescription: "Smoothing and zoom line width cannot be used together."
zoomLinesThreshold: "Zoom line width"
zoomLinesMaskSize: "Center diameter"
zoomLinesBlack: "Make black"
circle: "Circular"
drafts: "Drafts" drafts: "Drafts"
_drafts: _drafts:
select: "Select Draft" select: "Select Draft"
@ -3210,3 +3287,22 @@ _drafts:
restoreFromDraft: "Restore from Draft" restoreFromDraft: "Restore from Draft"
restore: "Restore" restore: "Restore"
listDrafts: "List of Drafts" listDrafts: "List of Drafts"
schedule: "Schedule note"
listScheduledNotes: "Scheduled notes list"
cancelSchedule: "Cancel schedule"
qr: "QR Code"
_qr:
showTabTitle: "Display"
readTabTitle: "Scan"
shareTitle: "{name} {acct}"
shareText: "Follow me on the Fediverse!"
chooseCamera: "Choose camera"
cannotToggleFlash: "Unable to toggle flashlight"
turnOnFlash: "Turn on flashlight"
turnOffFlash: "Turn off flashlight"
startQr: "Resume QR code reader"
stopQr: "Stop QR code reader"
noQrCodeFound: "No QR code found"
scanFile: "Scan image from device"
raw: "Text"
mfm: "MFM"

View File

@ -253,6 +253,7 @@ noteDeleteConfirm: "¿Quieres borrar esta nota?"
pinLimitExceeded: "Ya no se pueden fijar más notas" pinLimitExceeded: "Ya no se pueden fijar más notas"
done: "Terminado" done: "Terminado"
processing: "Procesando..." processing: "Procesando..."
preprocessing: "Preparando"
preview: "Vista previa" preview: "Vista previa"
default: "Predeterminado" default: "Predeterminado"
defaultValueIs: "Por defecto: {value}" defaultValueIs: "Por defecto: {value}"
@ -910,7 +911,7 @@ pubSub: "Cuentas Pub/Sub"
lastCommunication: "Última comunicación" lastCommunication: "Última comunicación"
resolved: "Resuelto" resolved: "Resuelto"
unresolved: "Sin resolver" unresolved: "Sin resolver"
breakFollow: "Dejar de seguir" breakFollow: "Eliminar seguidor"
breakFollowConfirm: "¿Quieres dejar de seguir?" breakFollowConfirm: "¿Quieres dejar de seguir?"
itsOn: "¡Está encendido!" itsOn: "¡Está encendido!"
itsOff: "¡Está apagado!" itsOff: "¡Está apagado!"
@ -1054,6 +1055,7 @@ permissionDeniedError: "Operación denegada"
permissionDeniedErrorDescription: "Esta cuenta no tiene permisos para hacer esa acción." permissionDeniedErrorDescription: "Esta cuenta no tiene permisos para hacer esa acción."
preset: "Predefinido" preset: "Predefinido"
selectFromPresets: "Escoger desde predefinidos" selectFromPresets: "Escoger desde predefinidos"
custom: "Personalizado"
achievements: "Logros" achievements: "Logros"
gotInvalidResponseError: "Respuesta del servidor inválida" gotInvalidResponseError: "Respuesta del servidor inválida"
gotInvalidResponseErrorDescription: "Puede que el servidor esté caído o en mantenimiento. Favor de intentar más tarde" gotInvalidResponseErrorDescription: "Puede que el servidor esté caído o en mantenimiento. Favor de intentar más tarde"
@ -1092,6 +1094,7 @@ prohibitedWordsDescription2: "Si se usan espacios se crearán expresiones AND y
hiddenTags: "Hashtags ocultos" hiddenTags: "Hashtags ocultos"
hiddenTagsDescription: "Selecciona las etiquetas que no se mostrarán en tendencias. Una etiqueta por línea." hiddenTagsDescription: "Selecciona las etiquetas que no se mostrarán en tendencias. Una etiqueta por línea."
notesSearchNotAvailable: "No se puede buscar una nota" notesSearchNotAvailable: "No se puede buscar una nota"
usersSearchNotAvailable: "La búsqueda de usuarios no está disponible."
license: "Licencia" license: "Licencia"
unfavoriteConfirm: "¿Desea quitar de favoritos?" unfavoriteConfirm: "¿Desea quitar de favoritos?"
myClips: "Mis clips" myClips: "Mis clips"
@ -1243,7 +1246,7 @@ releaseToRefresh: "Soltar para recargar"
refreshing: "Recargando..." refreshing: "Recargando..."
pullDownToRefresh: "Tira hacia abajo para recargar" pullDownToRefresh: "Tira hacia abajo para recargar"
useGroupedNotifications: "Mostrar notificaciones agrupadas" useGroupedNotifications: "Mostrar notificaciones agrupadas"
signupPendingError: "Ha habido un problema al verificar tu dirección de correo electrónico. Es posible que el enlace haya caducado." emailVerificationFailedError: "Se ha producido un error al confirmar tu dirección de correo electrónico. Es posible que el enlace haya caducado."
cwNotationRequired: "Si se ha activado \"ocultar contenido\", es necesario proporcionar una descripción." cwNotationRequired: "Si se ha activado \"ocultar contenido\", es necesario proporcionar una descripción."
doReaction: "Añadir reacción" doReaction: "Añadir reacción"
code: "Código" code: "Código"
@ -1314,6 +1317,7 @@ acknowledgeNotesAndEnable: "Activar después de comprender las precauciones"
federationSpecified: "Este servidor opera en una federación de listas blancas. No puede interactuar con otros servidores que no sean los especificados por el administrador." federationSpecified: "Este servidor opera en una federación de listas blancas. No puede interactuar con otros servidores que no sean los especificados por el administrador."
federationDisabled: "La federación está desactivada en este servidor. No puede interactuar con usuarios de otros servidores" federationDisabled: "La federación está desactivada en este servidor. No puede interactuar con usuarios de otros servidores"
draft: "Borrador" draft: "Borrador"
draftsAndScheduledNotes: "Borradores y notas programadas"
confirmOnReact: "Confirmar la reacción" confirmOnReact: "Confirmar la reacción"
reactAreYouSure: "¿Quieres añadir una reacción «{emoji}»?" reactAreYouSure: "¿Quieres añadir una reacción «{emoji}»?"
markAsSensitiveConfirm: "¿Desea establecer este medio multimedia(Imagen,vídeo...) como sensible?" markAsSensitiveConfirm: "¿Desea establecer este medio multimedia(Imagen,vídeo...) como sensible?"
@ -1341,6 +1345,8 @@ postForm: "Formulario"
textCount: "caracteres" textCount: "caracteres"
information: "Información" information: "Información"
chat: "Chat" chat: "Chat"
directMessage: "Chatear"
directMessage_short: "Mensaje"
migrateOldSettings: "Migrar la configuración anterior" migrateOldSettings: "Migrar la configuración anterior"
migrateOldSettings_description: "Esto debería hacerse automáticamente, pero si por alguna razón la migración no ha tenido éxito, puede activar usted mismo el proceso de migración manualmente. Se sobrescribirá la información de configuración actual." migrateOldSettings_description: "Esto debería hacerse automáticamente, pero si por alguna razón la migración no ha tenido éxito, puede activar usted mismo el proceso de migración manualmente. Se sobrescribirá la información de configuración actual."
compress: "Comprimir" compress: "Comprimir"
@ -1368,16 +1374,35 @@ redisplayAllTips: "Volver a mostrar todos \"Trucos y consejos\""
hideAllTips: "Ocultar todos los \"Trucos y consejos\"" hideAllTips: "Ocultar todos los \"Trucos y consejos\""
defaultImageCompressionLevel: "Nivel de compresión de la imagen por defecto" defaultImageCompressionLevel: "Nivel de compresión de la imagen por defecto"
defaultImageCompressionLevel_description: "Baja, conserva la calidad de la imagen pero la medida del archivo es más grande. <br>Alta, reduce la medida del archivo pero también la calidad de la imagen." defaultImageCompressionLevel_description: "Baja, conserva la calidad de la imagen pero la medida del archivo es más grande. <br>Alta, reduce la medida del archivo pero también la calidad de la imagen."
defaultCompressionLevel: "Nivel de compresión predeterminado"
defaultCompressionLevel_description: "Al reducir el ajuste se conserva la calidad, pero aumenta el tamaño del archivo.<br>Al aumentar el ajuste se reduce el tamaño del archivo, pero disminuye la calidad."
inMinutes: "Minutos" inMinutes: "Minutos"
inDays: "Días" inDays: "Días"
safeModeEnabled: "El modo seguro está activado" safeModeEnabled: "El modo seguro está activado"
pluginsAreDisabledBecauseSafeMode: "El modo seguro está activado, por lo que todos los plugins están desactivados." pluginsAreDisabledBecauseSafeMode: "El modo seguro está activado, por lo que todos los plugins están desactivados."
customCssIsDisabledBecauseSafeMode: "El modo seguro está activado, por lo que no se aplica el CSS personalizado." customCssIsDisabledBecauseSafeMode: "El modo seguro está activado, por lo que no se aplica el CSS personalizado."
themeIsDefaultBecauseSafeMode: "Mientras el modo seguro esté activado, se utilizará el tema predeterminado. Cuando se desactive el modo seguro, se volverá al tema original." themeIsDefaultBecauseSafeMode: "Mientras el modo seguro esté activado, se utilizará el tema predeterminado. Cuando se desactive el modo seguro, se volverá al tema original."
thankYouForTestingBeta: "¡Gracias por tu colaboración en la prueba de la versión beta!"
createUserSpecifiedNote: "Crear notas especificadas por el usuario"
schedulePost: "Programar una nota"
scheduleToPostOnX: "Programar una nota para {x}"
scheduledToPostOnX: "La nota está programada para {x}."
schedule: "Programado"
scheduled: "Programado"
_compression:
_quality:
high: "Calidad alta"
medium: "Calidad media"
low: "Calidad baja"
_size:
large: "Tamaño grande"
medium: "Tamaño mediano"
small: "Tamaño pequeño"
_order: _order:
newest: "Los más recientes primero" newest: "Los más recientes primero"
oldest: "Los más antiguos primero" oldest: "Los más antiguos primero"
_chat: _chat:
messages: "Mensaje"
noMessagesYet: "Aún no hay mensajes" noMessagesYet: "Aún no hay mensajes"
newMessage: "Mensajes nuevos" newMessage: "Mensajes nuevos"
individualChat: "Chat individual" individualChat: "Chat individual"
@ -1663,6 +1688,9 @@ _serverSettings:
userGeneratedContentsVisibilityForVisitor_description2: "Publicar incondicionalmente todo el contenido del servidor en Internet, incluido el contenido remoto recibido por el servidor, es arriesgado. Esto es especialmente importante para los invitados que desconocen la naturaleza distribuida del contenido, ya que pueden creer erróneamente que incluso el contenido remoto es contenido creado por usuarios en el servidor." userGeneratedContentsVisibilityForVisitor_description2: "Publicar incondicionalmente todo el contenido del servidor en Internet, incluido el contenido remoto recibido por el servidor, es arriesgado. Esto es especialmente importante para los invitados que desconocen la naturaleza distribuida del contenido, ya que pueden creer erróneamente que incluso el contenido remoto es contenido creado por usuarios en el servidor."
restartServerSetupWizardConfirm_title: "¿Reiniciar el asistente de configuración del servidor?" restartServerSetupWizardConfirm_title: "¿Reiniciar el asistente de configuración del servidor?"
restartServerSetupWizardConfirm_text: "Algunas configuraciones actuales se restablecerán" restartServerSetupWizardConfirm_text: "Algunas configuraciones actuales se restablecerán"
entrancePageStyle: "Estilo de la página de inicio"
showTimelineForVisitor: "Mostrar la línea de tiempo"
showActivitiesForVisitor: "Mostrar actividades"
_userGeneratedContentsVisibilityForVisitor: _userGeneratedContentsVisibilityForVisitor:
all: "Todo es público." all: "Todo es público."
localOnly: "Sólo se publica el contenido local, el remoto se mantiene privado" localOnly: "Sólo se publica el contenido local, el remoto se mantiene privado"
@ -1999,6 +2027,7 @@ _role:
descriptionOfRateLimitFactor: "Límites más bajos son menos restrictivos, más altos menos restrictivos" descriptionOfRateLimitFactor: "Límites más bajos son menos restrictivos, más altos menos restrictivos"
canHideAds: "Puede ocultar anuncios" canHideAds: "Puede ocultar anuncios"
canSearchNotes: "Uso de la búsqueda de notas" canSearchNotes: "Uso de la búsqueda de notas"
canSearchUsers: "Uso de la búsqueda de usuarios"
canUseTranslator: "Uso de traductor" canUseTranslator: "Uso de traductor"
avatarDecorationLimit: "Número máximo de decoraciones de avatar" avatarDecorationLimit: "Número máximo de decoraciones de avatar"
canImportAntennas: "Permitir la importación de antenas" canImportAntennas: "Permitir la importación de antenas"
@ -2011,6 +2040,7 @@ _role:
uploadableFileTypes_caption: "Especifica los tipos MIME/archivos permitidos. Se pueden especificar varios tipos MIME separándolos con una nueva línea, y se pueden especificar comodines con un asterisco (*). (por ejemplo, image/*)" uploadableFileTypes_caption: "Especifica los tipos MIME/archivos permitidos. Se pueden especificar varios tipos MIME separándolos con una nueva línea, y se pueden especificar comodines con un asterisco (*). (por ejemplo, image/*)"
uploadableFileTypes_caption2: "Es posible que no se detecten algunos tipos de archivos. Para permitir estos archivos, añade {x} a la especificación." uploadableFileTypes_caption2: "Es posible que no se detecten algunos tipos de archivos. Para permitir estos archivos, añade {x} a la especificación."
noteDraftLimit: "Número de posibles borradores de notas del servidor" noteDraftLimit: "Número de posibles borradores de notas del servidor"
scheduledNoteLimit: "Máximo número de notas programadas que se pueden crear simultáneamente."
watermarkAvailable: "Disponibilidad de la función de marca de agua" watermarkAvailable: "Disponibilidad de la función de marca de agua"
_condition: _condition:
roleAssignedTo: "Asignado a roles manuales" roleAssignedTo: "Asignado a roles manuales"
@ -2130,7 +2160,7 @@ _aboutMisskey:
_displayOfSensitiveMedia: _displayOfSensitiveMedia:
respect: "Esconder medios marcados como sensibles" respect: "Esconder medios marcados como sensibles"
ignore: "Mostrar medios marcados como sensibles" ignore: "Mostrar medios marcados como sensibles"
force: "Esconder todala multimedia" force: "Esconder toda la multimedia"
_instanceTicker: _instanceTicker:
none: "No mostrar" none: "No mostrar"
remote: "Mostrar a usuarios remotos" remote: "Mostrar a usuarios remotos"
@ -2271,6 +2301,7 @@ _time:
minute: "Minutos" minute: "Minutos"
hour: "Horas" hour: "Horas"
day: "Días" day: "Días"
month: "Mes(es)"
_2fa: _2fa:
alreadyRegistered: "Ya has completado la configuración." alreadyRegistered: "Ya has completado la configuración."
registerTOTP: "Registrar aplicación autenticadora" registerTOTP: "Registrar aplicación autenticadora"
@ -2445,7 +2476,7 @@ _widgets:
chooseList: "Seleccione una lista" chooseList: "Seleccione una lista"
clicker: "Cliqueador" clicker: "Cliqueador"
birthdayFollowings: "Hoy cumplen años" birthdayFollowings: "Hoy cumplen años"
chat: "Chat" chat: "Chatear"
_cw: _cw:
hide: "Ocultar" hide: "Ocultar"
show: "Ver más" show: "Ver más"
@ -2635,6 +2666,8 @@ _notification:
youReceivedFollowRequest: "Has mandado una solicitud de seguimiento" youReceivedFollowRequest: "Has mandado una solicitud de seguimiento"
yourFollowRequestAccepted: "Tu solicitud de seguimiento fue aceptada" yourFollowRequestAccepted: "Tu solicitud de seguimiento fue aceptada"
pollEnded: "Estan disponibles los resultados de la encuesta" pollEnded: "Estan disponibles los resultados de la encuesta"
scheduledNotePosted: "Una nota programada ha sido publicada"
scheduledNotePostFailed: "Ha fallado la publicación de una nota programada"
newNote: "Nueva nota" newNote: "Nueva nota"
unreadAntennaNote: "Antena {name}" unreadAntennaNote: "Antena {name}"
roleAssigned: "Rol asignado" roleAssigned: "Rol asignado"
@ -2714,7 +2747,7 @@ _deck:
mentions: "Menciones" mentions: "Menciones"
direct: "Notas directas" direct: "Notas directas"
roleTimeline: "Linea de tiempo del rol" roleTimeline: "Linea de tiempo del rol"
chat: "Chat" chat: "Chatear"
_dialog: _dialog:
charactersExceeded: "¡Has excedido el límite de caracteres! Actualmente {current} de {max}." charactersExceeded: "¡Has excedido el límite de caracteres! Actualmente {current} de {max}."
charactersBelow: "¡Estás por debajo del límite de caracteres! Actualmente {current} de {min}." charactersBelow: "¡Estás por debajo del límite de caracteres! Actualmente {current} de {min}."
@ -3160,14 +3193,16 @@ _watermarkEditor:
opacity: "Opacidad" opacity: "Opacidad"
scale: "Tamaño" scale: "Tamaño"
text: "Texto" text: "Texto"
qr: "Código QR"
position: "Posición" position: "Posición"
margin: "Margen"
type: "Tipo" type: "Tipo"
image: "Imágenes" image: "Imágenes"
advanced: "Avanzado" advanced: "Avanzado"
angle: "Ángulo"
stripe: "Rayas" stripe: "Rayas"
stripeWidth: "Anchura de línea" stripeWidth: "Anchura de línea"
stripeFrequency: "Número de líneas." stripeFrequency: "Número de líneas."
angle: "Ángulo"
polkadot: "Lunares" polkadot: "Lunares"
checker: "verificador" checker: "verificador"
polkadotMainDotOpacity: "Opacidad del círculo principal" polkadotMainDotOpacity: "Opacidad del círculo principal"
@ -3175,16 +3210,20 @@ _watermarkEditor:
polkadotSubDotOpacity: "Opacidad del círculo secundario" polkadotSubDotOpacity: "Opacidad del círculo secundario"
polkadotSubDotRadius: "Tamaño del círculo secundario." polkadotSubDotRadius: "Tamaño del círculo secundario."
polkadotSubDotDivisions: "Número de subpuntos." polkadotSubDotDivisions: "Número de subpuntos."
leaveBlankToAccountUrl: "Si dejas este campo en blanco, se utilizará la URL de tu cuenta."
_imageEffector: _imageEffector:
title: "Efecto" title: "Efecto"
addEffect: "Añadir Efecto" addEffect: "Añadir Efecto"
discardChangesConfirm: "¿Ignorar cambios y salir?" discardChangesConfirm: "¿Ignorar cambios y salir?"
nothingToConfigure: "No hay opciones configurables disponibles."
_fxs: _fxs:
chromaticAberration: "Aberración Cromática" chromaticAberration: "Aberración Cromática"
glitch: "Glitch" glitch: "Glitch"
mirror: "Espejo" mirror: "Espejo"
invert: "Invertir colores" invert: "Invertir colores"
grayscale: "Blanco y negro" grayscale: "Blanco y negro"
blur: "Difuminar"
pixelate: "Pixelar"
colorAdjust: "Corrección de Color" colorAdjust: "Corrección de Color"
colorClamp: "Compresión cromática" colorClamp: "Compresión cromática"
colorClampAdvanced: "Compresión cromática avanzada" colorClampAdvanced: "Compresión cromática avanzada"
@ -3196,6 +3235,43 @@ _imageEffector:
checker: "Corrector" checker: "Corrector"
blockNoise: "Bloquear Ruido" blockNoise: "Bloquear Ruido"
tearing: "Rasgado de Imagen (Tearing)" tearing: "Rasgado de Imagen (Tearing)"
fill: "Relleno de color"
_fxProps:
angle: "Ángulo"
scale: "Tamaño"
size: "Tamaño"
radius: "Radio"
samples: "Tamaño de muestra"
offset: "Posición"
color: "Color"
opacity: "Opacidad"
normalize: "Normalización"
amount: "Cantidad"
lightness: "Brillo"
contrast: "Contraste"
hue: "Tonalidad"
brightness: "Brillo"
saturation: "Saturación"
max: "Valor máximo"
min: "Valor mínimo"
direction: "Dirección"
phase: "Fase"
frequency: "Frecuencia"
strength: "Intensidad"
glitchChannelShift: "cambio de canal de imagen"
seed: "Valor de la semilla"
redComponent: "Componente rojo"
greenComponent: "Componente Verde"
blueComponent: "Componente Azul"
threshold: "Umbral"
centerX: "Centrar X"
centerY: "Centrar Y"
zoomLinesSmoothing: "Suavizado"
zoomLinesSmoothingDescription: "El suavizado y el ancho de línea de zoom no se pueden utilizar juntos."
zoomLinesThreshold: "Ancho de línea del zoom"
zoomLinesMaskSize: "Diámetro del centro"
zoomLinesBlack: "Hacer oscuro"
circle: "Círculo"
drafts: "Borrador" drafts: "Borrador"
_drafts: _drafts:
select: "Seleccionar borradores" select: "Seleccionar borradores"
@ -3211,3 +3287,22 @@ _drafts:
restoreFromDraft: "Restaurar desde los borradores" restoreFromDraft: "Restaurar desde los borradores"
restore: "Restaurar" restore: "Restaurar"
listDrafts: "Listar los borradores" listDrafts: "Listar los borradores"
schedule: "Programar Nota"
listScheduledNotes: "Lista de notas programadas"
cancelSchedule: "Cancelar programación"
qr: "Código QR"
_qr:
showTabTitle: "Apariencia"
readTabTitle: "Escanear"
shareTitle: "{name} {acct}"
shareText: "¡Sígueme en el Fediverso!"
chooseCamera: "Seleccione cámara"
cannotToggleFlash: "No se puede activar el flash"
turnOnFlash: "Encender el flash"
turnOffFlash: "Apagar el flash"
startQr: "Reiniciar el lector de códigos QR"
stopQr: "Detener el lector de códigos QR"
noQrCodeFound: "No se encontró el código QR"
scanFile: "Escanear imagen desde un dispositivo"
raw: "Texto"
mfm: "MFM"

View File

@ -1208,7 +1208,6 @@ releaseToRefresh: "Relâcher pour rafraîchir"
refreshing: "Rafraîchissement..." refreshing: "Rafraîchissement..."
pullDownToRefresh: "Tirer vers le bas pour rafraîchir" pullDownToRefresh: "Tirer vers le bas pour rafraîchir"
useGroupedNotifications: "Grouper les notifications" useGroupedNotifications: "Grouper les notifications"
signupPendingError: "Un problème est survenu lors de la vérification de votre adresse e-mail. Le lien a peut-être expiré."
cwNotationRequired: "Si « Masquer le contenu » est activé, une description doit être fournie." cwNotationRequired: "Si « Masquer le contenu » est activé, une description doit être fournie."
doReaction: "Réagir" doReaction: "Réagir"
code: "Code" code: "Code"
@ -2372,3 +2371,15 @@ _watermarkEditor:
image: "Images" image: "Images"
advanced: "Avancé" advanced: "Avancé"
angle: "Angle" angle: "Angle"
_imageEffector:
_fxProps:
angle: "Angle"
scale: "Taille"
size: "Taille"
offset: "Position"
color: "Couleur"
opacity: "Transparence"
lightness: "Clair"
_qr:
showTabTitle: "Affichage"
raw: "Texte"

View File

@ -1212,7 +1212,6 @@ releaseToRefresh: "Lepaskan untuk memuat ulang"
refreshing: "Sedang memuat ulang..." refreshing: "Sedang memuat ulang..."
pullDownToRefresh: "Tarik ke bawah untuk memuat ulang" pullDownToRefresh: "Tarik ke bawah untuk memuat ulang"
useGroupedNotifications: "Tampilkan notifikasi secara dikelompokkan" useGroupedNotifications: "Tampilkan notifikasi secara dikelompokkan"
signupPendingError: "Terdapat masalah ketika memverifikasi alamat surel. Tautan kemungkinan telah kedaluwarsa."
cwNotationRequired: "Jika \"Sembunyikan konten\" diaktifkan, deskripsi harus disediakan." cwNotationRequired: "Jika \"Sembunyikan konten\" diaktifkan, deskripsi harus disediakan."
doReaction: "Tambahkan reaksi" doReaction: "Tambahkan reaksi"
code: "Kode" code: "Kode"
@ -2627,3 +2626,15 @@ _watermarkEditor:
image: "Gambar" image: "Gambar"
advanced: "Tingkat lanjut" advanced: "Tingkat lanjut"
angle: "Sudut" angle: "Sudut"
_imageEffector:
_fxProps:
angle: "Sudut"
scale: "Ukuran"
size: "Ukuran"
offset: "Posisi"
color: "Warna"
opacity: "Opasitas"
lightness: "Menerangkan"
_qr:
showTabTitle: "Tampilkan"
raw: "Teks"

328
locales/index.d.ts vendored
View File

@ -1030,6 +1030,10 @@ export interface Locale extends ILocale {
* *
*/ */
"processing": string; "processing": string;
/**
*
*/
"preprocessing": string;
/** /**
* *
*/ */
@ -1227,7 +1231,7 @@ export interface Locale extends ILocale {
*/ */
"noMoreHistory": string; "noMoreHistory": string;
/** /**
* *
*/ */
"startChat": string; "startChat": string;
/** /**
@ -1927,7 +1931,7 @@ export interface Locale extends ILocale {
*/ */
"markAsReadAllUnreadNotes": string; "markAsReadAllUnreadNotes": string;
/** /**
* *
*/ */
"markAsReadAllTalkMessages": string; "markAsReadAllTalkMessages": string;
/** /**
@ -4234,6 +4238,10 @@ export interface Locale extends ILocale {
* *
*/ */
"selectFromPresets": string; "selectFromPresets": string;
/**
*
*/
"custom": string;
/** /**
* *
*/ */
@ -4386,6 +4394,10 @@ export interface Locale extends ILocale {
* *
*/ */
"notesSearchNotAvailable": string; "notesSearchNotAvailable": string;
/**
*
*/
"usersSearchNotAvailable": string;
/** /**
* *
*/ */
@ -4993,7 +5005,7 @@ export interface Locale extends ILocale {
/** /**
* *
*/ */
"signupPendingError": string; "emailVerificationFailedError": string;
/** /**
* *
*/ */
@ -5274,6 +5286,10 @@ export interface Locale extends ILocale {
* *
*/ */
"draft": string; "draft": string;
/**
* 稿
*/
"draftsAndScheduledNotes": string;
/** /**
* *
*/ */
@ -5382,6 +5398,14 @@ export interface Locale extends ILocale {
* *
*/ */
"chat": string; "chat": string;
/**
*
*/
"directMessage": string;
/**
*
*/
"directMessage_short": string;
/** /**
* *
*/ */
@ -5493,6 +5517,14 @@ export interface Locale extends ILocale {
* <br> * <br>
*/ */
"defaultImageCompressionLevel_description": string; "defaultImageCompressionLevel_description": string;
/**
*
*/
"defaultCompressionLevel": string;
/**
* <br>
*/
"defaultCompressionLevel_description": string;
/** /**
* *
*/ */
@ -5517,6 +5549,64 @@ export interface Locale extends ILocale {
* 使 * 使
*/ */
"themeIsDefaultBecauseSafeMode": string; "themeIsDefaultBecauseSafeMode": string;
/**
*
*/
"thankYouForTestingBeta": string;
/**
*
*/
"createUserSpecifiedNote": string;
/**
* 稿
*/
"schedulePost": string;
/**
* {x}稿
*/
"scheduleToPostOnX": ParameterizedString<"x">;
/**
* {x}稿
*/
"scheduledToPostOnX": ParameterizedString<"x">;
/**
*
*/
"schedule": string;
/**
*
*/
"scheduled": string;
"_compression": {
"_quality": {
/**
*
*/
"high": string;
/**
*
*/
"medium": string;
/**
*
*/
"low": string;
};
"_size": {
/**
*
*/
"large": string;
/**
*
*/
"medium": string;
/**
*
*/
"small": string;
};
};
"_order": { "_order": {
/** /**
* *
@ -5528,6 +5618,10 @@ export interface Locale extends ILocale {
"oldest": string; "oldest": string;
}; };
"_chat": { "_chat": {
/**
*
*/
"messages": string;
/** /**
* *
*/ */
@ -5537,36 +5631,36 @@ export interface Locale extends ILocale {
*/ */
"newMessage": string; "newMessage": string;
/** /**
* *
*/ */
"individualChat": string; "individualChat": string;
/** /**
* *
*/ */
"individualChat_description": string; "individualChat_description": string;
/** /**
* *
*/ */
"roomChat": string; "roomChat": string;
/** /**
* *
* *
*/ */
"roomChat_description": string; "roomChat_description": string;
/** /**
* *
*/ */
"createRoom": string; "createRoom": string;
/** /**
* *
*/ */
"inviteUserToChat": string; "inviteUserToChat": string;
/** /**
* *
*/ */
"yourRooms": string; "yourRooms": string;
/** /**
* *
*/ */
"joiningRooms": string; "joiningRooms": string;
/** /**
@ -5586,7 +5680,7 @@ export interface Locale extends ILocale {
*/ */
"noHistory": string; "noHistory": string;
/** /**
* *
*/ */
"noRooms": string; "noRooms": string;
/** /**
@ -5606,7 +5700,7 @@ export interface Locale extends ILocale {
*/ */
"ignore": string; "ignore": string;
/** /**
* 退 * 退
*/ */
"leave": string; "leave": string;
/** /**
@ -5630,35 +5724,35 @@ export interface Locale extends ILocale {
*/ */
"newline": string; "newline": string;
/** /**
* *
*/ */
"muteThisRoom": string; "muteThisRoom": string;
/** /**
* *
*/ */
"deleteRoom": string; "deleteRoom": string;
/** /**
* *
*/ */
"chatNotAvailableForThisAccountOrServer": string; "chatNotAvailableForThisAccountOrServer": string;
/** /**
* *
*/ */
"chatIsReadOnlyForThisAccountOrServer": string; "chatIsReadOnlyForThisAccountOrServer": string;
/** /**
* 使 * 使
*/ */
"chatNotAvailableInOtherAccount": string; "chatNotAvailableInOtherAccount": string;
/** /**
* *
*/ */
"cannotChatWithTheUser": string; "cannotChatWithTheUser": string;
/** /**
* 使 * 使
*/ */
"cannotChatWithTheUser_description": string; "cannotChatWithTheUser_description": string;
/** /**
* *
*/ */
"youAreNotAMemberOfThisRoomButInvited": string; "youAreNotAMemberOfThisRoomButInvited": string;
/** /**
@ -5666,31 +5760,31 @@ export interface Locale extends ILocale {
*/ */
"doYouAcceptInvitation": string; "doYouAcceptInvitation": string;
/** /**
* *
*/ */
"chatWithThisUser": string; "chatWithThisUser": string;
/** /**
* *
*/ */
"thisUserAllowsChatOnlyFromFollowers": string; "thisUserAllowsChatOnlyFromFollowers": string;
/** /**
* *
*/ */
"thisUserAllowsChatOnlyFromFollowing": string; "thisUserAllowsChatOnlyFromFollowing": string;
/** /**
* *
*/ */
"thisUserAllowsChatOnlyFromMutualFollowing": string; "thisUserAllowsChatOnlyFromMutualFollowing": string;
/** /**
* *
*/ */
"thisUserNotAllowedChatAnyone": string; "thisUserNotAllowedChatAnyone": string;
/** /**
* *
*/ */
"chatAllowedUsers": string; "chatAllowedUsers": string;
/** /**
* *
*/ */
"chatAllowedUsers_note": string; "chatAllowedUsers_note": string;
"_chatAllowedUsers": { "_chatAllowedUsers": {
@ -6519,7 +6613,7 @@ export interface Locale extends ILocale {
*/ */
"remoteNotesCleaning": string; "remoteNotesCleaning": string;
/** /**
* 稿 * 稿
*/ */
"remoteNotesCleaning_description": string; "remoteNotesCleaning_description": string;
/** /**
@ -6610,6 +6704,18 @@ export interface Locale extends ILocale {
* *
*/ */
"restartServerSetupWizardConfirm_text": string; "restartServerSetupWizardConfirm_text": string;
/**
*
*/
"entrancePageStyle": string;
/**
*
*/
"showTimelineForVisitor": string;
/**
*
*/
"showActivitiesForVisitor": string;
"_userGeneratedContentsVisibilityForVisitor": { "_userGeneratedContentsVisibilityForVisitor": {
/** /**
* *
@ -7799,6 +7905,10 @@ export interface Locale extends ILocale {
* *
*/ */
"canSearchNotes": string; "canSearchNotes": string;
/**
*
*/
"canSearchUsers": string;
/** /**
* *
*/ */
@ -7828,7 +7938,7 @@ export interface Locale extends ILocale {
*/ */
"canImportUserLists": string; "canImportUserLists": string;
/** /**
* *
*/ */
"chatAvailability": string; "chatAvailability": string;
/** /**
@ -7847,6 +7957,10 @@ export interface Locale extends ILocale {
* *
*/ */
"noteDraftLimit": string; "noteDraftLimit": string;
/**
* 稿
*/
"scheduledNoteLimit": string;
/** /**
* 使 * 使
*/ */
@ -8678,7 +8792,7 @@ export interface Locale extends ILocale {
*/ */
"badge": string; "badge": string;
/** /**
* *
*/ */
"messageBg": string; "messageBg": string;
/** /**
@ -8705,7 +8819,7 @@ export interface Locale extends ILocale {
*/ */
"reaction": string; "reaction": string;
/** /**
* *
*/ */
"chatMessage": string; "chatMessage": string;
}; };
@ -8828,6 +8942,10 @@ export interface Locale extends ILocale {
* *
*/ */
"day": string; "day": string;
/**
*
*/
"month": string;
}; };
"_2fa": { "_2fa": {
/** /**
@ -8985,11 +9103,11 @@ export interface Locale extends ILocale {
*/ */
"write:following": string; "write:following": string;
/** /**
* *
*/ */
"read:messaging": string; "read:messaging": string;
/** /**
* *
*/ */
"write:messaging": string; "write:messaging": string;
/** /**
@ -9281,11 +9399,11 @@ export interface Locale extends ILocale {
*/ */
"write:report-abuse": string; "write:report-abuse": string;
/** /**
* *
*/ */
"write:chat": string; "write:chat": string;
/** /**
* *
*/ */
"read:chat": string; "read:chat": string;
}; };
@ -9511,7 +9629,7 @@ export interface Locale extends ILocale {
*/ */
"birthdayFollowings": string; "birthdayFollowings": string;
/** /**
* *
*/ */
"chat": string; "chat": string;
}; };
@ -10238,6 +10356,14 @@ export interface Locale extends ILocale {
* *
*/ */
"pollEnded": string; "pollEnded": string;
/**
* 稿
*/
"scheduledNotePosted": string;
/**
* 稿
*/
"scheduledNotePostFailed": string;
/** /**
* 稿 * 稿
*/ */
@ -10251,7 +10377,7 @@ export interface Locale extends ILocale {
*/ */
"roleAssigned": string; "roleAssigned": string;
/** /**
* *
*/ */
"chatRoomInvitationReceived": string; "chatRoomInvitationReceived": string;
/** /**
@ -10364,7 +10490,7 @@ export interface Locale extends ILocale {
*/ */
"roleAssigned": string; "roleAssigned": string;
/** /**
* *
*/ */
"chatRoomInvitationReceived": string; "chatRoomInvitationReceived": string;
/** /**
@ -10546,7 +10672,7 @@ export interface Locale extends ILocale {
*/ */
"roleTimeline": string; "roleTimeline": string;
/** /**
* *
*/ */
"chat": string; "chat": string;
}; };
@ -10913,7 +11039,7 @@ export interface Locale extends ILocale {
*/ */
"deleteGalleryPost": string; "deleteGalleryPost": string;
/** /**
* *
*/ */
"deleteChatRoom": string; "deleteChatRoom": string;
/** /**
@ -12000,11 +12126,11 @@ export interface Locale extends ILocale {
*/ */
"youCanConfigureMoreFederationSettingsLater": string; "youCanConfigureMoreFederationSettingsLater": string;
/** /**
* *
*/ */
"remoteContentsCleaning": string; "remoteContentsCleaning": string;
/** /**
* *
*/ */
"remoteContentsCleaning_description": string; "remoteContentsCleaning_description": string;
/** /**
@ -12187,10 +12313,18 @@ export interface Locale extends ILocale {
* *
*/ */
"text": string; "text": string;
/**
*
*/
"qr": string;
/** /**
* *
*/ */
"position": string; "position": string;
/**
*
*/
"margin": string;
/** /**
* *
*/ */
@ -12247,6 +12381,10 @@ export interface Locale extends ILocale {
* *
*/ */
"polkadotSubDotDivisions": string; "polkadotSubDotDivisions": string;
/**
* URLになります
*/
"leaveBlankToAccountUrl": string;
}; };
"_imageEffector": { "_imageEffector": {
/** /**
@ -12286,6 +12424,14 @@ export interface Locale extends ILocale {
* *
*/ */
"grayscale": string; "grayscale": string;
/**
*
*/
"blur": string;
/**
*
*/
"pixelate": string;
/** /**
* 調 * 調
*/ */
@ -12330,6 +12476,10 @@ export interface Locale extends ILocale {
* *
*/ */
"tearing": string; "tearing": string;
/**
*
*/
"fill": string;
}; };
"_fxProps": { "_fxProps": {
/** /**
@ -12344,6 +12494,18 @@ export interface Locale extends ILocale {
* *
*/ */
"size": string; "size": string;
/**
*
*/
"radius": string;
/**
*
*/
"samples": string;
/**
*
*/
"offset": string;
/** /**
* *
*/ */
@ -12456,6 +12618,10 @@ export interface Locale extends ILocale {
* *
*/ */
"zoomLinesBlack": string; "zoomLinesBlack": string;
/**
*
*/
"circle": string;
}; };
}; };
/** /**
@ -12515,6 +12681,80 @@ export interface Locale extends ILocale {
* *
*/ */
"listDrafts": string; "listDrafts": string;
/**
* 稿
*/
"schedule": string;
/**
* 稿
*/
"listScheduledNotes": string;
/**
*
*/
"cancelSchedule": string;
};
/**
*
*/
"qr": string;
"_qr": {
/**
*
*/
"showTabTitle": string;
/**
*
*/
"readTabTitle": string;
/**
* {name} {acct}
*/
"shareTitle": ParameterizedString<"name" | "acct">;
/**
* Fediverseで私をフォローしてください
*/
"shareText": string;
/**
*
*/
"chooseCamera": string;
/**
*
*/
"cannotToggleFlash": string;
/**
*
*/
"turnOnFlash": string;
/**
*
*/
"turnOffFlash": string;
/**
*
*/
"startQr": string;
/**
*
*/
"stopQr": string;
/**
* QRコードが見つかりません
*/
"noQrCodeFound": string;
/**
*
*/
"scanFile": string;
/**
*
*/
"raw": string;
/**
* MFM
*/
"mfm": string;
}; };
} }
declare const locales: { declare const locales: {

View File

@ -139,7 +139,7 @@ overwriteFromPinnedEmojis: "Sovrascrivi con le impostazioni globali"
reactionSettingDescription2: "Trascina per riorganizzare, clicca per cancellare, usa il pulsante \"+\" per aggiungere." reactionSettingDescription2: "Trascina per riorganizzare, clicca per cancellare, usa il pulsante \"+\" per aggiungere."
rememberNoteVisibility: "Ricordare le impostazioni di visibilità delle note" rememberNoteVisibility: "Ricordare le impostazioni di visibilità delle note"
attachCancel: "Rimuovi allegato" attachCancel: "Rimuovi allegato"
deleteFile: "File da Drive eliminato" deleteFile: "Elimina un file dal Drive"
markAsSensitive: "Segna come esplicito" markAsSensitive: "Segna come esplicito"
unmarkAsSensitive: "Non segnare come esplicito " unmarkAsSensitive: "Non segnare come esplicito "
enterFileName: "Nome del file" enterFileName: "Nome del file"
@ -253,6 +253,7 @@ noteDeleteConfirm: "Vuoi davvero eliminare questa Nota?"
pinLimitExceeded: "Non puoi fissare altre note " pinLimitExceeded: "Non puoi fissare altre note "
done: "Fine" done: "Fine"
processing: "In elaborazione" processing: "In elaborazione"
preprocessing: "In preparazione"
preview: "Anteprima" preview: "Anteprima"
default: "Predefinito" default: "Predefinito"
defaultValueIs: "Predefinito: {value}" defaultValueIs: "Predefinito: {value}"
@ -577,7 +578,7 @@ showFixedPostForm: "Visualizzare la finestra di pubblicazione in cima alla timel
showFixedPostFormInChannel: "Per i canali, mostra il modulo di pubblicazione in cima alla timeline" showFixedPostFormInChannel: "Per i canali, mostra il modulo di pubblicazione in cima alla timeline"
withRepliesByDefaultForNewlyFollowed: "Quando segui nuovi profili, includi le risposte in TL come impostazione predefinita" withRepliesByDefaultForNewlyFollowed: "Quando segui nuovi profili, includi le risposte in TL come impostazione predefinita"
newNoteRecived: "Nuove Note da leggere" newNoteRecived: "Nuove Note da leggere"
newNote: "Nuova Nota" newNote: "Nuove Note"
sounds: "Impostazioni suoni" sounds: "Impostazioni suoni"
sound: "Suono" sound: "Suono"
notificationSoundSettings: "Preferenze di notifica" notificationSoundSettings: "Preferenze di notifica"
@ -1054,6 +1055,7 @@ permissionDeniedError: "Errore, attività non autorizzata"
permissionDeniedErrorDescription: "Non si dispone dell'autorizzazione per eseguire questa operazione." permissionDeniedErrorDescription: "Non si dispone dell'autorizzazione per eseguire questa operazione."
preset: "Preimpostato" preset: "Preimpostato"
selectFromPresets: "Seleziona preimpostato" selectFromPresets: "Seleziona preimpostato"
custom: "Personalizzato"
achievements: "Conquiste" achievements: "Conquiste"
gotInvalidResponseError: "Risposta del server non valida" gotInvalidResponseError: "Risposta del server non valida"
gotInvalidResponseErrorDescription: "Il server potrebbe essere irraggiungibile o in manutenzione. Riprova più tardi." gotInvalidResponseErrorDescription: "Il server potrebbe essere irraggiungibile o in manutenzione. Riprova più tardi."
@ -1092,6 +1094,7 @@ prohibitedWordsDescription2: "Gli spazi creano la relazione \"E\" tra parole (qu
hiddenTags: "Hashtag nascosti" hiddenTags: "Hashtag nascosti"
hiddenTagsDescription: "Impedire la visualizzazione del tag impostato nei trend. Puoi impostare più valori, uno per riga." hiddenTagsDescription: "Impedire la visualizzazione del tag impostato nei trend. Puoi impostare più valori, uno per riga."
notesSearchNotAvailable: "Non è possibile cercare tra le Note." notesSearchNotAvailable: "Non è possibile cercare tra le Note."
usersSearchNotAvailable: "La ricerca profili non è disponibile."
license: "Licenza" license: "Licenza"
unfavoriteConfirm: "Vuoi davvero rimuovere la preferenza?" unfavoriteConfirm: "Vuoi davvero rimuovere la preferenza?"
myClips: "Le mie Clip" myClips: "Le mie Clip"
@ -1243,7 +1246,7 @@ releaseToRefresh: "Rilascia per aggiornare"
refreshing: "Aggiornamento..." refreshing: "Aggiornamento..."
pullDownToRefresh: "Trascinare per aggiornare" pullDownToRefresh: "Trascinare per aggiornare"
useGroupedNotifications: "Mostra le notifiche raggruppate" useGroupedNotifications: "Mostra le notifiche raggruppate"
signupPendingError: "Si è verificato un problema durante la verifica del tuo indirizzo email. Potrebbe essere scaduto il collegamento temporaneo." emailVerificationFailedError: "La verifica dell'indirizzo e-mail non è andata a buon fine. Il link potrebbe essere scaduto."
cwNotationRequired: "Devi indicare perché il contenuto è indicato come esplicito." cwNotationRequired: "Devi indicare perché il contenuto è indicato come esplicito."
doReaction: "Reagisci" doReaction: "Reagisci"
code: "Codice" code: "Codice"
@ -1314,13 +1317,14 @@ acknowledgeNotesAndEnable: "Attivare dopo averne compreso il comportamento."
federationSpecified: "Questo server è federato solo con istanze specifiche del Fediverso. Puoi interagire solo con quelle scelte dall'amministrazione." federationSpecified: "Questo server è federato solo con istanze specifiche del Fediverso. Puoi interagire solo con quelle scelte dall'amministrazione."
federationDisabled: "Questo server ha la federazione disabilitata. Non puoi interagire con profili provenienti da altri server." federationDisabled: "Questo server ha la federazione disabilitata. Non puoi interagire con profili provenienti da altri server."
draft: "Bozza" draft: "Bozza"
draftsAndScheduledNotes: "Bozze e Note pianificate"
confirmOnReact: "Confermare le reazioni" confirmOnReact: "Confermare le reazioni"
reactAreYouSure: "Vuoi davvero reagire con {emoji} ?" reactAreYouSure: "Vuoi davvero reagire con {emoji} ?"
markAsSensitiveConfirm: "Vuoi davvero indicare questo contenuto multimediale come esplicito?" markAsSensitiveConfirm: "Vuoi davvero indicare questo contenuto multimediale come esplicito?"
unmarkAsSensitiveConfirm: "Vuoi davvero indicare come non esplicito il contenuto multimediale?" unmarkAsSensitiveConfirm: "Vuoi davvero indicare come non esplicito il contenuto multimediale?"
preferences: "Preferenze" preferences: "Preferenze"
accessibility: "Accessibilità" accessibility: "Accessibilità"
preferencesProfile: "Profilo preferenze" preferencesProfile: "Preferenze del profilo"
copyPreferenceId: "Copia ID preferenze" copyPreferenceId: "Copia ID preferenze"
resetToDefaultValue: "Ripristina a predefinito" resetToDefaultValue: "Ripristina a predefinito"
overrideByAccount: "Sovrascrivere col profilo" overrideByAccount: "Sovrascrivere col profilo"
@ -1341,6 +1345,8 @@ postForm: "Finestra di pubblicazione"
textCount: "Il numero di caratteri" textCount: "Il numero di caratteri"
information: "Informazioni" information: "Informazioni"
chat: "Chat" chat: "Chat"
directMessage: "Chatta con questa persona"
directMessage_short: "Messaggio"
migrateOldSettings: "Migrare le vecchie impostazioni" migrateOldSettings: "Migrare le vecchie impostazioni"
migrateOldSettings_description: "Di solito, viene fatto automaticamente. Se per qualche motivo non fossero migrate con successo, è possibile avviare il processo di migrazione manualmente, sovrascrivendo le configurazioni attuali." migrateOldSettings_description: "Di solito, viene fatto automaticamente. Se per qualche motivo non fossero migrate con successo, è possibile avviare il processo di migrazione manualmente, sovrascrivendo le configurazioni attuali."
compress: "Compressione" compress: "Compressione"
@ -1368,16 +1374,35 @@ redisplayAllTips: "Mostra tutti i suggerimenti"
hideAllTips: "Nascondi tutti i suggerimenti" hideAllTips: "Nascondi tutti i suggerimenti"
defaultImageCompressionLevel: "Livello predefinito di compressione immagini" defaultImageCompressionLevel: "Livello predefinito di compressione immagini"
defaultImageCompressionLevel_description: "La compressione diminuisce la qualità dell'immagine, poca compressione mantiene alta qualità delle immagini. Aumentandola, si riducono le dimensioni del file, a discapito della qualità dell'immagine." defaultImageCompressionLevel_description: "La compressione diminuisce la qualità dell'immagine, poca compressione mantiene alta qualità delle immagini. Aumentandola, si riducono le dimensioni del file, a discapito della qualità dell'immagine."
defaultCompressionLevel: "Compressione predefinita"
defaultCompressionLevel_description: "Diminuisci per mantenere la qualità aumentando le dimensioni del file.<br> Aumenta per ridurre le dimensioni del file e anche la qualità."
inMinutes: "min" inMinutes: "min"
inDays: "giorni" inDays: "giorni"
safeModeEnabled: "La modalità sicura è attiva" safeModeEnabled: "La modalità sicura è attiva"
pluginsAreDisabledBecauseSafeMode: "Tutti i plugin sono disattivati, poiché la modalità sicura è attiva." pluginsAreDisabledBecauseSafeMode: "Tutti i plugin sono disattivati, poiché la modalità sicura è attiva."
customCssIsDisabledBecauseSafeMode: "Il CSS personalizzato non è stato applicato, poiché la modalità sicura è attiva." customCssIsDisabledBecauseSafeMode: "Il CSS personalizzato non è stato applicato, poiché la modalità sicura è attiva."
themeIsDefaultBecauseSafeMode: "Quando la modalità sicura è attiva, viene utilizzato il tema predefinito. Quando la modalità sicura viene disattivata, il tema torna a essere quello precedente." themeIsDefaultBecauseSafeMode: "Quando la modalità sicura è attiva, viene utilizzato il tema predefinito. Quando la modalità sicura viene disattivata, il tema torna a essere quello precedente."
thankYouForTestingBeta: "Grazie per la tua collaborazione nella verifica delle versioni beta!"
createUserSpecifiedNote: "Creare Nota personalizzata"
schedulePost: "Pianificare la pubblicazione"
scheduleToPostOnX: "Pianificare la pubblicazione {x}"
scheduledToPostOnX: "Pubblicazione pianificata {x}"
schedule: "Pianificare"
scheduled: "Pianificata"
_compression:
_quality:
high: "Alta qualità"
medium: "Media qualità"
low: "Bassa qualità"
_size:
large: "Taglia grande"
medium: "Taglia media"
small: "Taglia piccola"
_order: _order:
newest: "Prima i più recenti" newest: "Prima i più recenti"
oldest: "Meno recenti prima" oldest: "Meno recenti prima"
_chat: _chat:
messages: "Messaggi"
noMessagesYet: "Ancora nessun messaggio" noMessagesYet: "Ancora nessun messaggio"
newMessage: "Nuovo messaggio" newMessage: "Nuovo messaggio"
individualChat: "Chat individuale" individualChat: "Chat individuale"
@ -1663,6 +1688,9 @@ _serverSettings:
userGeneratedContentsVisibilityForVisitor_description2: "Esistono dei rischi nell'esporre incondizionatamente su internet tutto il contenuto del tuo server, incluso il contenuto remoto ricevuto da altri server. In particolare, occorre prestare attenzione, perché le persone non consapevoli della federazione potrebbero erroneamente credere che il contenuto remoto sia stato invece creato all'interno del proprio server." userGeneratedContentsVisibilityForVisitor_description2: "Esistono dei rischi nell'esporre incondizionatamente su internet tutto il contenuto del tuo server, incluso il contenuto remoto ricevuto da altri server. In particolare, occorre prestare attenzione, perché le persone non consapevoli della federazione potrebbero erroneamente credere che il contenuto remoto sia stato invece creato all'interno del proprio server."
restartServerSetupWizardConfirm_title: "Vuoi ripetere la procedura guidata di configurazione iniziale del server?" restartServerSetupWizardConfirm_title: "Vuoi ripetere la procedura guidata di configurazione iniziale del server?"
restartServerSetupWizardConfirm_text: "Verranno ripristinate alcune tue impostazioni personalizzate." restartServerSetupWizardConfirm_text: "Verranno ripristinate alcune tue impostazioni personalizzate."
entrancePageStyle: "Stile della pagina di ingresso"
showTimelineForVisitor: "Mostra la Timeline a visitatori non autenticati"
showActivitiesForVisitor: "Mostrare la propria attività"
_userGeneratedContentsVisibilityForVisitor: _userGeneratedContentsVisibilityForVisitor:
all: "Tutto pubblico" all: "Tutto pubblico"
localOnly: "Pubblica solo contenuti locali, mantieni privati i contenuti remoti" localOnly: "Pubblica solo contenuti locali, mantieni privati i contenuti remoti"
@ -1999,6 +2027,7 @@ _role:
descriptionOfRateLimitFactor: "I rapporti più bassi sono meno restrittivi, quelli più alti lo sono di più." descriptionOfRateLimitFactor: "I rapporti più bassi sono meno restrittivi, quelli più alti lo sono di più."
canHideAds: "Nascondere i banner" canHideAds: "Nascondere i banner"
canSearchNotes: "Ricercare nelle Note" canSearchNotes: "Ricercare nelle Note"
canSearchUsers: "Può cercare profili"
canUseTranslator: "Tradurre le Note" canUseTranslator: "Tradurre le Note"
avatarDecorationLimit: "Numero massimo di decorazioni foto profilo installabili" avatarDecorationLimit: "Numero massimo di decorazioni foto profilo installabili"
canImportAntennas: "Può importare Antenne" canImportAntennas: "Può importare Antenne"
@ -2011,6 +2040,7 @@ _role:
uploadableFileTypes_caption: "Specifica il tipo MIME. Puoi specificare più valori separandoli andando a capo, oppure indicare caratteri jolly con un asterisco (*). Ad esempio: image/*" uploadableFileTypes_caption: "Specifica il tipo MIME. Puoi specificare più valori separandoli andando a capo, oppure indicare caratteri jolly con un asterisco (*). Ad esempio: image/*"
uploadableFileTypes_caption2: "A seconda del file, il tipo potrebbe non essere determinato. Se si desidera consentire tali file, aggiungere {x} alla specifica." uploadableFileTypes_caption2: "A seconda del file, il tipo potrebbe non essere determinato. Se si desidera consentire tali file, aggiungere {x} alla specifica."
noteDraftLimit: "Numero massimo di Note in bozza, lato server" noteDraftLimit: "Numero massimo di Note in bozza, lato server"
scheduledNoteLimit: "Quantità di Note pianificabili contemporaneamente"
watermarkAvailable: "Disponibilità della funzione filigrana" watermarkAvailable: "Disponibilità della funzione filigrana"
_condition: _condition:
roleAssignedTo: "Assegnato a ruoli manualmente" roleAssignedTo: "Assegnato a ruoli manualmente"
@ -2215,7 +2245,7 @@ _theme:
hashtag: "Hashtag" hashtag: "Hashtag"
mention: "Menzioni" mention: "Menzioni"
mentionMe: "Menzioni (di me)" mentionMe: "Menzioni (di me)"
renote: "Renota" renote: "Rinota"
modalBg: "Sfondo modale." modalBg: "Sfondo modale."
divider: "Interruzione di linea" divider: "Interruzione di linea"
scrollbarHandle: "Maniglie della barra di scorrimento" scrollbarHandle: "Maniglie della barra di scorrimento"
@ -2271,6 +2301,7 @@ _time:
minute: "min" minute: "min"
hour: "ore" hour: "ore"
day: "giorni" day: "giorni"
month: "Mese"
_2fa: _2fa:
alreadyRegistered: "La configurazione è stata già completata." alreadyRegistered: "La configurazione è stata già completata."
registerTOTP: "Registra una App di autenticazione a due fattori (2FA/MFA)" registerTOTP: "Registra una App di autenticazione a due fattori (2FA/MFA)"
@ -2445,7 +2476,7 @@ _widgets:
chooseList: "Seleziona una lista" chooseList: "Seleziona una lista"
clicker: "Cliccheria" clicker: "Cliccheria"
birthdayFollowings: "Compleanni del giorno" birthdayFollowings: "Compleanni del giorno"
chat: "Chat" chat: "Chatta con questa persona"
_cw: _cw:
hide: "Nascondere" hide: "Nascondere"
show: "Continua la lettura..." show: "Continua la lettura..."
@ -2635,6 +2666,8 @@ _notification:
youReceivedFollowRequest: "Hai ricevuto una richiesta di follow" youReceivedFollowRequest: "Hai ricevuto una richiesta di follow"
yourFollowRequestAccepted: "La tua richiesta di follow è stata accettata" yourFollowRequestAccepted: "La tua richiesta di follow è stata accettata"
pollEnded: "Risultati del sondaggio." pollEnded: "Risultati del sondaggio."
scheduledNotePosted: "Pubblicazione Nota pianificata"
scheduledNotePostFailed: "Impossibile pubblicare la Nota pianificata"
newNote: "Nuove Note" newNote: "Nuove Note"
unreadAntennaNote: "Antenna {name}" unreadAntennaNote: "Antenna {name}"
roleAssigned: "Ruolo assegnato" roleAssigned: "Ruolo assegnato"
@ -2655,7 +2688,7 @@ _notification:
createToken: "È stato creato un token di accesso" createToken: "È stato creato un token di accesso"
createTokenDescription: "In caso contrario, eliminare il token di accesso tramite ({text})." createTokenDescription: "In caso contrario, eliminare il token di accesso tramite ({text})."
_types: _types:
all: "Tutto" all: "Tutte"
note: "Nuove Note" note: "Nuove Note"
follow: "Follower" follow: "Follower"
mention: "Menzioni" mention: "Menzioni"
@ -2663,7 +2696,7 @@ _notification:
renote: "Rinota" renote: "Rinota"
quote: "Cita" quote: "Cita"
reaction: "Reazioni" reaction: "Reazioni"
pollEnded: "Sondaggio chiuso." pollEnded: "Sondaggio terminato"
receiveFollowRequest: "Richieste di follow in arrivo" receiveFollowRequest: "Richieste di follow in arrivo"
followRequestAccepted: "Richieste di follow accettate" followRequestAccepted: "Richieste di follow accettate"
roleAssigned: "Ruolo concesso" roleAssigned: "Ruolo concesso"
@ -2671,7 +2704,7 @@ _notification:
achievementEarned: "Risultato raggiunto" achievementEarned: "Risultato raggiunto"
exportCompleted: "Esportazione completata" exportCompleted: "Esportazione completata"
login: "Accessi" login: "Accessi"
createToken: "Creare un token di accesso" createToken: "Aggiunto un token di accesso"
test: "Notifiche di test" test: "Notifiche di test"
app: "Notifiche da applicazioni" app: "Notifiche da applicazioni"
_actions: _actions:
@ -2679,7 +2712,7 @@ _notification:
reply: "Rispondi" reply: "Rispondi"
renote: "Rinota" renote: "Rinota"
_deck: _deck:
alwaysShowMainColumn: "Mostra sempre la colonna principale" alwaysShowMainColumn: "Mostrare sempre la colonna Principale"
columnAlign: "Allineamento delle colonne" columnAlign: "Allineamento delle colonne"
columnGap: "Spessore del margine tra colonne" columnGap: "Spessore del margine tra colonne"
deckMenuPosition: "Posizione del menu Deck" deckMenuPosition: "Posizione del menu Deck"
@ -2696,8 +2729,8 @@ _deck:
profile: "Profilo" profile: "Profilo"
newProfile: "Nuovo profilo" newProfile: "Nuovo profilo"
deleteProfile: "Cancellare il profilo." deleteProfile: "Cancellare il profilo."
introduction: "Combinate le colonne per creare la vostra interfaccia!" introduction: "Crea la tua interfaccia combinando le colonne!"
introduction2: "È possibile aggiungere colonne in qualsiasi momento premendo + sulla destra dello schermo." introduction2: "Per aggiungere una colonna, cliccare il bottone + (più) visibile al margine dello schermo."
widgetsIntroduction: "Dal menu della colonna, selezionare \"Modifica i riquadri\" per aggiungere un un riquadro con funzionalità" widgetsIntroduction: "Dal menu della colonna, selezionare \"Modifica i riquadri\" per aggiungere un un riquadro con funzionalità"
useSimpleUiForNonRootPages: "Visualizza sotto pagine con interfaccia web semplice" useSimpleUiForNonRootPages: "Visualizza sotto pagine con interfaccia web semplice"
usedAsMinWidthWhenFlexible: "Se \"larghezza flessibile\" è abilitato, questa diventa la larghezza minima" usedAsMinWidthWhenFlexible: "Se \"larghezza flessibile\" è abilitato, questa diventa la larghezza minima"
@ -2714,7 +2747,7 @@ _deck:
mentions: "Menzioni" mentions: "Menzioni"
direct: "Note Dirette" direct: "Note Dirette"
roleTimeline: "Timeline Ruolo" roleTimeline: "Timeline Ruolo"
chat: "Chat" chat: "Chatta con questa persona"
_dialog: _dialog:
charactersExceeded: "Hai superato il limite di {max} caratteri! ({current})" charactersExceeded: "Hai superato il limite di {max} caratteri! ({current})"
charactersBelow: "Sei al di sotto del minimo di {min} caratteri! ({current})" charactersBelow: "Sei al di sotto del minimo di {min} caratteri! ({current})"
@ -2763,56 +2796,56 @@ _abuseReport:
notifiedWebhook: "Webhook da usare" notifiedWebhook: "Webhook da usare"
deleteConfirm: "Vuoi davvero rimuovere il destinatario della notifica?" deleteConfirm: "Vuoi davvero rimuovere il destinatario della notifica?"
_moderationLogTypes: _moderationLogTypes:
createRole: "Ruolo creato" createRole: "Crea un Ruolo"
deleteRole: "Ruolo eliminato" deleteRole: "Elimina un Ruolo"
updateRole: "Ruolo aggiornato" updateRole: "Modifica un ruolo"
assignRole: "Ruolo assegnato" assignRole: "Assegna un Ruolo"
unassignRole: "Ruolo disassegnato" unassignRole: "Toglie un Ruolo al Profilo"
suspend: "Sospensione" suspend: "Sospende"
unsuspend: "Sospensione rimossa" unsuspend: "Solleva la sospensione"
addCustomEmoji: "Emoji personalizzata aggiunta" addCustomEmoji: "Aggiunge Emoji personalizzata"
updateCustomEmoji: "Emoji personalizzata aggiornata" updateCustomEmoji: "Modifica Emoji personalizzata"
deleteCustomEmoji: "Emoji personalizzata eliminata" deleteCustomEmoji: "Elimina Emoji personalizzata"
updateServerSettings: "Impostazioni del server aggiornate" updateServerSettings: "Modifica le impostazioni del server"
updateUserNote: "Promemoria di moderazione aggiornato" updateUserNote: "Modifica un promemoria di moderazione"
deleteDriveFile: "File da Drive eliminato" deleteDriveFile: "Elimina un file dal Drive"
deleteNote: "Nota eliminata" deleteNote: "Elimina una Nota"
createGlobalAnnouncement: "Annuncio globale creato" createGlobalAnnouncement: "Crea un annuncio globale"
createUserAnnouncement: "Annuncio ai profili iscritti creato" createUserAnnouncement: "Crea un annuncio ai profili già iscritti"
updateGlobalAnnouncement: "Annuncio globale aggiornato" updateGlobalAnnouncement: "Modifica un annuncio globale"
updateUserAnnouncement: "Annuncio ai profili iscritti aggiornato" updateUserAnnouncement: "Modifica un annuncio ai profili già iscritti"
deleteGlobalAnnouncement: "Annuncio globale eliminato" deleteGlobalAnnouncement: "Elimina un annuncio globale"
deleteUserAnnouncement: "Annuncio ai profili iscritti eliminato" deleteUserAnnouncement: "Elimina un annuncio ai profili già iscritti"
resetPassword: "Password azzerata" resetPassword: "Azzera la password"
suspendRemoteInstance: "Istanza remota sospesa" suspendRemoteInstance: "Sospende una istanza remota"
unsuspendRemoteInstance: "Istanza remota riattivata" unsuspendRemoteInstance: "Riattiva una istanza remota"
updateRemoteInstanceNote: "Aggiornamento del promemoria di moderazione per il server remoto" updateRemoteInstanceNote: "Modifica il promemoria di moderazione per il server remoto"
markSensitiveDriveFile: "File nel Drive segnato come esplicito" markSensitiveDriveFile: "Aggiunge NSFW a un file nel Drive"
unmarkSensitiveDriveFile: "File nel Drive segnato come non esplicito" unmarkSensitiveDriveFile: "Toglie NSFW da un file nel Drive"
resolveAbuseReport: "Segnalazione risolta" resolveAbuseReport: "Risolve una segnalazione"
forwardAbuseReport: "Segnalazione inoltrata" forwardAbuseReport: "Inoltra una segnalazione"
updateAbuseReportNote: "Ha aggiornato la segnalazione" updateAbuseReportNote: "Modifica una segnalazione"
createInvitation: "Genera codice di invito" createInvitation: "Genera un codice di invito"
createAd: "Banner creato" createAd: "Aggiunge un Banner"
deleteAd: "Banner eliminato" deleteAd: "Elimina un Banner"
updateAd: "Banner aggiornato" updateAd: "Modifica un Banner"
createAvatarDecoration: "Creazione decorazione della foto profilo" createAvatarDecoration: "Crea una decorazione della foto profilo"
updateAvatarDecoration: "Aggiornamento decorazione foto profilo" updateAvatarDecoration: "Modifica una decorazione della foto profilo"
deleteAvatarDecoration: "Eliminazione decorazione della foto profilo" deleteAvatarDecoration: "Elimina una decorazione della foto profilo"
unsetUserAvatar: "Rimossa foto profilo" unsetUserAvatar: "Toglie una foto profilo"
unsetUserBanner: "Rimossa intestazione profilo" unsetUserBanner: "Toglie una immagine di intestazione profilo"
createSystemWebhook: "Crea un SystemWebhook" createSystemWebhook: "Aggiunge un System Webhook"
updateSystemWebhook: "Modifica SystemWebhook" updateSystemWebhook: "Modifica un System Webhook"
deleteSystemWebhook: "Elimina SystemWebhook" deleteSystemWebhook: "Elimina un System Webhook"
createAbuseReportNotificationRecipient: "Crea destinatario per le notifiche di segnalazioni" createAbuseReportNotificationRecipient: "Crea destinatario per le notifiche di segnalazioni"
updateAbuseReportNotificationRecipient: "Aggiorna destinatario notifiche di segnalazioni" updateAbuseReportNotificationRecipient: "Modifica un destinatario per le notifiche di segnalazioni"
deleteAbuseReportNotificationRecipient: "Elimina destinatario notifiche di segnalazioni" deleteAbuseReportNotificationRecipient: "Elimina un destinatario per le notifiche di segnalazioni"
deleteAccount: "Quando viene eliminato un profilo" deleteAccount: "Elimina un profilo"
deletePage: "Pagina eliminata" deletePage: "Elimina una Pagina"
deleteFlash: "Play eliminato" deleteFlash: "Elimina un Play"
deleteGalleryPost: "Eliminazione pubblicazione nella Galleria" deleteGalleryPost: "Elimina pubblicazione nella Galleria"
deleteChatRoom: "Elimina chat" deleteChatRoom: "Elimina una Chat"
updateProxyAccountDescription: "Aggiornata la descrizione del profilo proxy" updateProxyAccountDescription: "Aggiorna la descrizione del profilo proxy"
_fileViewer: _fileViewer:
title: "Dettagli del file" title: "Dettagli del file"
type: "Tipo di file" type: "Tipo di file"
@ -3160,14 +3193,16 @@ _watermarkEditor:
opacity: "Opacità" opacity: "Opacità"
scale: "Dimensioni" scale: "Dimensioni"
text: "Testo" text: "Testo"
qr: "QR Code"
position: "Posizione" position: "Posizione"
margin: "Margine"
type: "Tipo" type: "Tipo"
image: "Immagini" image: "Immagini"
advanced: "Avanzato" advanced: "Avanzato"
angle: "Angolo"
stripe: "Strisce" stripe: "Strisce"
stripeWidth: "Larghezza della linea" stripeWidth: "Larghezza della linea"
stripeFrequency: "Il numero di linee" stripeFrequency: "Il numero di linee"
angle: "Angolo"
polkadot: "A pallini" polkadot: "A pallini"
checker: "revisore" checker: "revisore"
polkadotMainDotOpacity: "Opacità del punto principale" polkadotMainDotOpacity: "Opacità del punto principale"
@ -3175,16 +3210,20 @@ _watermarkEditor:
polkadotSubDotOpacity: "Opacità del punto secondario" polkadotSubDotOpacity: "Opacità del punto secondario"
polkadotSubDotRadius: "Dimensione del punto secondario" polkadotSubDotRadius: "Dimensione del punto secondario"
polkadotSubDotDivisions: "Quantità di punti secondari" polkadotSubDotDivisions: "Quantità di punti secondari"
leaveBlankToAccountUrl: "Il valore vuoto indica la URL dell'account"
_imageEffector: _imageEffector:
title: "Effetto" title: "Effetto"
addEffect: "Aggiungi effetto" addEffect: "Aggiungi effetto"
discardChangesConfirm: "Scarta le modifiche ed esci?" discardChangesConfirm: "Scarta le modifiche ed esci?"
nothingToConfigure: "Nessuna impostazione configurabile."
_fxs: _fxs:
chromaticAberration: "Aberrazione cromatica" chromaticAberration: "Aberrazione cromatica"
glitch: "Glitch" glitch: "Glitch"
mirror: "Specchio" mirror: "Specchio"
invert: "Inversione colore" invert: "Inversione colore"
grayscale: "Bianco e nero" grayscale: "Bianco e nero"
blur: "Sfocatura"
pixelate: "Mosaico"
colorAdjust: "Correzione Colore" colorAdjust: "Correzione Colore"
colorClamp: "Compressione del colore" colorClamp: "Compressione del colore"
colorClampAdvanced: "Compressione del colore (avanzata)" colorClampAdvanced: "Compressione del colore (avanzata)"
@ -3196,7 +3235,44 @@ _imageEffector:
checker: "revisore" checker: "revisore"
blockNoise: "Attenua rumore" blockNoise: "Attenua rumore"
tearing: "Strappa immagine" tearing: "Strappa immagine"
drafts: "Bozza" fill: "Riempimento"
_fxProps:
angle: "Angolo"
scale: "Dimensioni"
size: "Dimensioni"
radius: "Raggio"
samples: "Quantità di campioni"
offset: "Posizione"
color: "Colore"
opacity: "Opacità"
normalize: "Normalizza"
amount: "Quantità"
lightness: "Chiaro"
contrast: "Contrasto"
hue: "Tinta"
brightness: "Luminosità"
saturation: "Saturazione"
max: "Valore massimo"
min: "Valore minimo"
direction: "Orientamento"
phase: "Fasare"
frequency: "Frequenza"
strength: "Forza"
glitchChannelShift: "Glitch cambio canale"
seed: "Seme"
redComponent: "Rosso composito"
greenComponent: "Verde composito"
blueComponent: "Blu composito"
threshold: "Soglia"
centerX: "Centro orizzontale"
centerY: "Centro verticale"
zoomLinesSmoothing: "Levigatura"
zoomLinesSmoothingDescription: "Non si possono usare insieme la levigatura e la larghezza della linea centrale."
zoomLinesThreshold: "Limite delle linee zoom"
zoomLinesMaskSize: "Ampiezza del diametro"
zoomLinesBlack: "Bande nere"
circle: "Circolare"
drafts: "Bozze"
_drafts: _drafts:
select: "Selezionare bozza" select: "Selezionare bozza"
cannotCreateDraftAnymore: "Hai superato il numero massimo di bozze ammissibili." cannotCreateDraftAnymore: "Hai superato il numero massimo di bozze ammissibili."
@ -3211,3 +3287,22 @@ _drafts:
restoreFromDraft: "Recuperare dalle bozze" restoreFromDraft: "Recuperare dalle bozze"
restore: "Ripristina" restore: "Ripristina"
listDrafts: "Elenco bozze" listDrafts: "Elenco bozze"
schedule: "Pianifica pubblicazione"
listScheduledNotes: "Elenca Note pianificate"
cancelSchedule: "Annulla pianificazione"
qr: "QR Code"
_qr:
showTabTitle: "Visualizza"
readTabTitle: "Leggere"
shareTitle: "{name} {acct}"
shareText: "Seguimi nel Fediverso!"
chooseCamera: "Seleziona fotocamera"
cannotToggleFlash: "Flash non controllabile"
turnOnFlash: "Accendi il flash"
turnOffFlash: "Spegni il flash"
startQr: "Inizia lettura QR Code"
stopQr: "Interrompi lettura QR Code"
noQrCodeFound: "Non trovo alcun QR Code"
scanFile: "Scansiona immagine nel dispositivo"
raw: "Testo"
mfm: "MFM"

View File

@ -253,6 +253,7 @@ noteDeleteConfirm: "このノートを削除しますか?"
pinLimitExceeded: "これ以上ピン留めできません" pinLimitExceeded: "これ以上ピン留めできません"
done: "完了" done: "完了"
processing: "処理中" processing: "処理中"
preprocessing: "準備中"
preview: "プレビュー" preview: "プレビュー"
default: "デフォルト" default: "デフォルト"
defaultValueIs: "デフォルト: {value}" defaultValueIs: "デフォルト: {value}"
@ -302,7 +303,7 @@ uploadNFiles: "{n}個のファイルをアップロード"
explore: "みつける" explore: "みつける"
messageRead: "既読" messageRead: "既読"
noMoreHistory: "これより過去の履歴はありません" noMoreHistory: "これより過去の履歴はありません"
startChat: "チャットを始める" startChat: "メッセージを送る"
nUsersRead: "{n}人が読みました" nUsersRead: "{n}人が読みました"
agreeTo: "{0}に同意" agreeTo: "{0}に同意"
agree: "同意する" agree: "同意する"
@ -477,7 +478,7 @@ notFoundDescription: "指定されたURLに該当するページはありませ
uploadFolder: "既定アップロード先" uploadFolder: "既定アップロード先"
markAsReadAllNotifications: "すべての通知を既読にする" markAsReadAllNotifications: "すべての通知を既読にする"
markAsReadAllUnreadNotes: "すべての投稿を既読にする" markAsReadAllUnreadNotes: "すべての投稿を既読にする"
markAsReadAllTalkMessages: "すべてのチャットを既読にする" markAsReadAllTalkMessages: "すべてのダイレクトメッセージを既読にする"
help: "ヘルプ" help: "ヘルプ"
inputMessageHere: "ここにメッセージを入力" inputMessageHere: "ここにメッセージを入力"
close: "閉じる" close: "閉じる"
@ -1054,6 +1055,7 @@ permissionDeniedError: "操作が拒否されました"
permissionDeniedErrorDescription: "このアカウントにはこの操作を行うための権限がありません。" permissionDeniedErrorDescription: "このアカウントにはこの操作を行うための権限がありません。"
preset: "プリセット" preset: "プリセット"
selectFromPresets: "プリセットから選択" selectFromPresets: "プリセットから選択"
custom: "カスタム"
achievements: "実績" achievements: "実績"
gotInvalidResponseError: "サーバーの応答が無効です" gotInvalidResponseError: "サーバーの応答が無効です"
gotInvalidResponseErrorDescription: "サーバーがダウンまたはメンテナンスしている可能性があります。しばらくしてから再度お試しください。" gotInvalidResponseErrorDescription: "サーバーがダウンまたはメンテナンスしている可能性があります。しばらくしてから再度お試しください。"
@ -1092,6 +1094,7 @@ prohibitedWordsDescription2: "スペースで区切るとAND指定になり、
hiddenTags: "非表示ハッシュタグ" hiddenTags: "非表示ハッシュタグ"
hiddenTagsDescription: "設定したタグをトレンドに表示させないようにします。改行で区切って複数設定できます。" hiddenTagsDescription: "設定したタグをトレンドに表示させないようにします。改行で区切って複数設定できます。"
notesSearchNotAvailable: "ノート検索は利用できません。" notesSearchNotAvailable: "ノート検索は利用できません。"
usersSearchNotAvailable: "ユーザー検索は利用できません。"
license: "ライセンス" license: "ライセンス"
unfavoriteConfirm: "お気に入り解除しますか?" unfavoriteConfirm: "お気に入り解除しますか?"
myClips: "自分のクリップ" myClips: "自分のクリップ"
@ -1243,7 +1246,7 @@ releaseToRefresh: "離してリロード"
refreshing: "リロード中" refreshing: "リロード中"
pullDownToRefresh: "引っ張ってリロード" pullDownToRefresh: "引っ張ってリロード"
useGroupedNotifications: "通知をグルーピング" useGroupedNotifications: "通知をグルーピング"
signupPendingError: "メールアドレスの確認中に問題が発生しました。リンクの有効期限が切れている可能性があります。" emailVerificationFailedError: "メールアドレスの確認中に問題が発生しました。リンクの有効期限が切れている可能性があります。"
cwNotationRequired: "「内容を隠す」がオンの場合は注釈の記述が必要です。" cwNotationRequired: "「内容を隠す」がオンの場合は注釈の記述が必要です。"
doReaction: "リアクションする" doReaction: "リアクションする"
code: "コード" code: "コード"
@ -1314,6 +1317,7 @@ acknowledgeNotesAndEnable: "注意事項を理解した上でオンにします
federationSpecified: "このサーバーはホワイトリスト連合で運用されています。管理者が指定したサーバー以外とやり取りすることはできません。" federationSpecified: "このサーバーはホワイトリスト連合で運用されています。管理者が指定したサーバー以外とやり取りすることはできません。"
federationDisabled: "このサーバーは連合が無効化されています。他のサーバーのユーザーとやり取りすることはできません。" federationDisabled: "このサーバーは連合が無効化されています。他のサーバーのユーザーとやり取りすることはできません。"
draft: "下書き" draft: "下書き"
draftsAndScheduledNotes: "下書きと予約投稿"
confirmOnReact: "リアクションする際に確認する" confirmOnReact: "リアクションする際に確認する"
reactAreYouSure: "\" {emoji} \" をリアクションしますか?" reactAreYouSure: "\" {emoji} \" をリアクションしますか?"
markAsSensitiveConfirm: "このメディアをセンシティブとして設定しますか?" markAsSensitiveConfirm: "このメディアをセンシティブとして設定しますか?"
@ -1341,6 +1345,8 @@ postForm: "投稿フォーム"
textCount: "文字数" textCount: "文字数"
information: "情報" information: "情報"
chat: "チャット" chat: "チャット"
directMessage: "ダイレクトメッセージ"
directMessage_short: "メッセージ"
migrateOldSettings: "旧設定情報を移行" migrateOldSettings: "旧設定情報を移行"
migrateOldSettings_description: "通常これは自動で行われていますが、何らかの理由により上手く移行されなかった場合は手動で移行処理をトリガーできます。現在の設定情報は上書きされます。" migrateOldSettings_description: "通常これは自動で行われていますが、何らかの理由により上手く移行されなかった場合は手動で移行処理をトリガーできます。現在の設定情報は上書きされます。"
compress: "圧縮" compress: "圧縮"
@ -1368,59 +1374,79 @@ redisplayAllTips: "全ての「ヒントとコツ」を再表示"
hideAllTips: "全ての「ヒントとコツ」を非表示" hideAllTips: "全ての「ヒントとコツ」を非表示"
defaultImageCompressionLevel: "デフォルトの画像圧縮度" defaultImageCompressionLevel: "デフォルトの画像圧縮度"
defaultImageCompressionLevel_description: "低くすると画質を保てますが、ファイルサイズは増加します。<br>高くするとファイルサイズを減らせますが、画質は低下します。" defaultImageCompressionLevel_description: "低くすると画質を保てますが、ファイルサイズは増加します。<br>高くするとファイルサイズを減らせますが、画質は低下します。"
defaultCompressionLevel: "デフォルトの圧縮度"
defaultCompressionLevel_description: "低くすると品質を保てますが、ファイルサイズは増加します。<br>高くするとファイルサイズを減らせますが、品質は低下します。"
inMinutes: "分" inMinutes: "分"
inDays: "日" inDays: "日"
safeModeEnabled: "セーフモードが有効です" safeModeEnabled: "セーフモードが有効です"
pluginsAreDisabledBecauseSafeMode: "セーフモードが有効なため、プラグインはすべて無効化されています。" pluginsAreDisabledBecauseSafeMode: "セーフモードが有効なため、プラグインはすべて無効化されています。"
customCssIsDisabledBecauseSafeMode: "セーフモードが有効なため、カスタムCSSは適用されていません。" customCssIsDisabledBecauseSafeMode: "セーフモードが有効なため、カスタムCSSは適用されていません。"
themeIsDefaultBecauseSafeMode: "セーフモードが有効な間はデフォルトのテーマが使用されます。セーフモードをオフにすると元に戻ります。" themeIsDefaultBecauseSafeMode: "セーフモードが有効な間はデフォルトのテーマが使用されます。セーフモードをオフにすると元に戻ります。"
thankYouForTestingBeta: "ベータ版の検証にご協力いただきありがとうございます!"
createUserSpecifiedNote: "ユーザー指定ノートを作成"
schedulePost: "投稿を予約"
scheduleToPostOnX: "{x}に投稿を予約します"
scheduledToPostOnX: "{x}に投稿が予約されています"
schedule: "予約"
scheduled: "予約"
_compression:
_quality:
high: "高品質"
medium: "中品質"
low: "低品質"
_size:
large: "サイズ大"
medium: "サイズ中"
small: "サイズ小"
_order: _order:
newest: "新しい順" newest: "新しい順"
oldest: "古い順" oldest: "古い順"
_chat: _chat:
messages: "メッセージ"
noMessagesYet: "まだメッセージはありません" noMessagesYet: "まだメッセージはありません"
newMessage: "新しいメッセージ" newMessage: "新しいメッセージ"
individualChat: "個人チャット" individualChat: "個"
individualChat_description: "特定ユーザーとの一対一のチャットができます。" individualChat_description: "特定ユーザーと個別にメッセージのやりとりができます。"
roomChat: "ルームチャット" roomChat: "グループ"
roomChat_description: "複数人でのチャットができます。\nまた、個人チャットを許可していないユーザーとでも、相手が受け入れればチャットができます。" roomChat_description: "複数人でメッセージのやりとりができます。\nまた、個別のメッセージを許可していないユーザーとでも、相手が受け入れればやりとりできます。"
createRoom: "ルームを作成" createRoom: "グループを作成"
inviteUserToChat: "ユーザーを招待してチャットを始めましょう" inviteUserToChat: "ユーザーを招待してメッセージを送信しましょう"
yourRooms: "作成したルーム" yourRooms: "作成したグループ"
joiningRooms: "参加中のルーム" joiningRooms: "参加中のグループ"
invitations: "招待" invitations: "招待"
noInvitations: "招待はありません" noInvitations: "招待はありません"
history: "履歴" history: "履歴"
noHistory: "履歴はありません" noHistory: "履歴はありません"
noRooms: "ルームはありません" noRooms: "グループはありません"
inviteUser: "ユーザーを招待" inviteUser: "ユーザーを招待"
sentInvitations: "送信した招待" sentInvitations: "送信した招待"
join: "参加" join: "参加"
ignore: "無視" ignore: "無視"
leave: "ルームから退出" leave: "グループから退出"
members: "メンバー" members: "メンバー"
searchMessages: "メッセージを検索" searchMessages: "メッセージを検索"
home: "ホーム" home: "ホーム"
send: "送信" send: "送信"
newline: "改行" newline: "改行"
muteThisRoom: "このルームをミュート" muteThisRoom: "このグループをミュート"
deleteRoom: "ルームを削除" deleteRoom: "グループを削除"
chatNotAvailableForThisAccountOrServer: "このサーバー、またはこのアカウントでチャットは有効化されていません。" chatNotAvailableForThisAccountOrServer: "このサーバー、またはこのアカウントでダイレクトメッセージは有効化されていません。"
chatIsReadOnlyForThisAccountOrServer: "このサーバー、またはこのアカウントでチャットは読み取り専用となっています。新たに書き込んだり、チャットルームを作成・参加したりすることはできません。" chatIsReadOnlyForThisAccountOrServer: "このサーバー、またはこのアカウントでダイレクトメッセージは読み取り専用となっています。新たに書き込んだり、グループを作成・参加したりすることはできません。"
chatNotAvailableInOtherAccount: "相手のアカウントでチャット機能が使えない状態になっています。" chatNotAvailableInOtherAccount: "相手のアカウントでダイレクトメッセージが使えない状態になっています。"
cannotChatWithTheUser: "このユーザーとのチャットを開始できません" cannotChatWithTheUser: "このユーザーとのダイレクトメッセージを開始できません"
cannotChatWithTheUser_description: "チャットが使えない状態になっているか、相手がチャットを開放していません。" cannotChatWithTheUser_description: "ダイレクトメッセージが使えない状態になっているか、相手がダイレクトメッセージを開放していません。"
youAreNotAMemberOfThisRoomButInvited: "あなたはこのルームの参加者ではありませんが、招待が届いています。参加するには、招待を承認してください。" youAreNotAMemberOfThisRoomButInvited: "あなたはこのグループの参加者ではありませんが、招待が届いています。参加するには、招待を承認してください。"
doYouAcceptInvitation: "招待を承認しますか?" doYouAcceptInvitation: "招待を承認しますか?"
chatWithThisUser: "チャットする" chatWithThisUser: "ダイレクトメッセージ"
thisUserAllowsChatOnlyFromFollowers: "このユーザーはフォロワーからのみチャットを受け付けています。" thisUserAllowsChatOnlyFromFollowers: "このユーザーはフォロワーからのみメッセージを受け付けています。"
thisUserAllowsChatOnlyFromFollowing: "このユーザーは、このユーザーがフォローしているユーザーからのみチャットを受け付けています。" thisUserAllowsChatOnlyFromFollowing: "このユーザーは、このユーザーがフォローしているユーザーからのみメッセージを受け付けています。"
thisUserAllowsChatOnlyFromMutualFollowing: "このユーザーは相互フォローのユーザーからのみチャットを受け付けています。" thisUserAllowsChatOnlyFromMutualFollowing: "このユーザーは相互フォローのユーザーからのみメッセージを受け付けています。"
thisUserNotAllowedChatAnyone: "このユーザーは誰からもチャットを受け付けていません。" thisUserNotAllowedChatAnyone: "このユーザーは誰からもメッセージを受け付けていません。"
chatAllowedUsers: "チャットを許可する相手" chatAllowedUsers: "メッセージを許可する相手"
chatAllowedUsers_note: "自分からチャットメッセージを送った相手とはこの設定に関わらずチャットが可能です。" chatAllowedUsers_note: "自分からメッセージを送った相手とはこの設定に関わらずメッセージの送受信が可能です。"
_chatAllowedUsers: _chatAllowedUsers:
everyone: "誰でも" everyone: "誰でも"
followers: "自分のフォロワーのみ" followers: "自分のフォロワーのみ"
@ -1657,7 +1683,7 @@ _serverSettings:
fanoutTimelineDbFallbackDescription: "有効にすると、タイムラインがキャッシュされていない場合にDBへ追加で問い合わせを行うフォールバック処理を行います。無効にすると、フォールバック処理を行わないことでさらにサーバーの負荷を軽減することができますが、タイムラインが取得できる範囲に制限が生じます。" fanoutTimelineDbFallbackDescription: "有効にすると、タイムラインがキャッシュされていない場合にDBへ追加で問い合わせを行うフォールバック処理を行います。無効にすると、フォールバック処理を行わないことでさらにサーバーの負荷を軽減することができますが、タイムラインが取得できる範囲に制限が生じます。"
reactionsBufferingDescription: "有効にすると、リアクション作成時のパフォーマンスが大幅に向上し、データベースへの負荷を軽減することが可能です。ただし、Redisのメモリ使用量は増加します。" reactionsBufferingDescription: "有効にすると、リアクション作成時のパフォーマンスが大幅に向上し、データベースへの負荷を軽減することが可能です。ただし、Redisのメモリ使用量は増加します。"
remoteNotesCleaning: "リモート投稿の自動クリーニング" remoteNotesCleaning: "リモート投稿の自動クリーニング"
remoteNotesCleaning_description: "有効にすると、参照されていない古いリモートの投稿を定期的にクリーンアップしてデータベースの肥大化を抑制します。" remoteNotesCleaning_description: "有効にすると、一定期間経過したリモートの投稿を定期的にクリーンアップしてデータベースの肥大化を抑制します。"
remoteNotesCleaningMaxProcessingDuration: "最大クリーニング処理継続時間" remoteNotesCleaningMaxProcessingDuration: "最大クリーニング処理継続時間"
remoteNotesCleaningExpiryDaysForEachNotes: "最低ノート保持日数" remoteNotesCleaningExpiryDaysForEachNotes: "最低ノート保持日数"
inquiryUrl: "問い合わせ先URL" inquiryUrl: "問い合わせ先URL"
@ -1680,6 +1706,9 @@ _serverSettings:
userGeneratedContentsVisibilityForVisitor_description2: "サーバーで受信したリモートのコンテンツを含め、サーバー内の全てのコンテンツを無条件でインターネットに公開することはリスクが伴います。特に、分散型の特性を知らない閲覧者にとっては、リモートのコンテンツであってもサーバー内で作成されたコンテンツであると誤って認識してしまう可能性があるため、注意が必要です。" userGeneratedContentsVisibilityForVisitor_description2: "サーバーで受信したリモートのコンテンツを含め、サーバー内の全てのコンテンツを無条件でインターネットに公開することはリスクが伴います。特に、分散型の特性を知らない閲覧者にとっては、リモートのコンテンツであってもサーバー内で作成されたコンテンツであると誤って認識してしまう可能性があるため、注意が必要です。"
restartServerSetupWizardConfirm_title: "サーバーの初期設定ウィザードをやり直しますか?" restartServerSetupWizardConfirm_title: "サーバーの初期設定ウィザードをやり直しますか?"
restartServerSetupWizardConfirm_text: "現在の一部の設定はリセットされます。" restartServerSetupWizardConfirm_text: "現在の一部の設定はリセットされます。"
entrancePageStyle: "エントランスページのスタイル"
showTimelineForVisitor: "タイムラインを表示する"
showActivitiesForVisitor: "アクティビティを表示する"
_userGeneratedContentsVisibilityForVisitor: _userGeneratedContentsVisibilityForVisitor:
all: "全て公開" all: "全て公開"
@ -2020,6 +2049,7 @@ _role:
descriptionOfRateLimitFactor: "小さいほど制限が緩和され、大きいほど制限が強化されます。" descriptionOfRateLimitFactor: "小さいほど制限が緩和され、大きいほど制限が強化されます。"
canHideAds: "広告の非表示" canHideAds: "広告の非表示"
canSearchNotes: "ノート検索の利用" canSearchNotes: "ノート検索の利用"
canSearchUsers: "ユーザー検索の利用"
canUseTranslator: "翻訳機能の利用" canUseTranslator: "翻訳機能の利用"
avatarDecorationLimit: "アイコンデコレーションの最大取付個数" avatarDecorationLimit: "アイコンデコレーションの最大取付個数"
canImportAntennas: "アンテナのインポートを許可" canImportAntennas: "アンテナのインポートを許可"
@ -2027,11 +2057,12 @@ _role:
canImportFollowing: "フォローのインポートを許可" canImportFollowing: "フォローのインポートを許可"
canImportMuting: "ミュートのインポートを許可" canImportMuting: "ミュートのインポートを許可"
canImportUserLists: "リストのインポートを許可" canImportUserLists: "リストのインポートを許可"
chatAvailability: "チャットを許可" chatAvailability: "ダイレクトメッセージを許可"
uploadableFileTypes: "アップロード可能なファイル種別" uploadableFileTypes: "アップロード可能なファイル種別"
uploadableFileTypes_caption: "MIMEタイプを指定します。改行で区切って複数指定できるほか、アスタリスク(*)でワイルドカード指定できます。(例: image/*)" uploadableFileTypes_caption: "MIMEタイプを指定します。改行で区切って複数指定できるほか、アスタリスク(*)でワイルドカード指定できます。(例: image/*)"
uploadableFileTypes_caption2: "ファイルによっては種別を判定できないことがあります。そのようなファイルを許可する場合は {x} を指定に追加してください。" uploadableFileTypes_caption2: "ファイルによっては種別を判定できないことがあります。そのようなファイルを許可する場合は {x} を指定に追加してください。"
noteDraftLimit: "サーバーサイドのノートの下書きの作成可能数" noteDraftLimit: "サーバーサイドのノートの下書きの作成可能数"
scheduledNoteLimit: "予約投稿の同時作成可能数"
watermarkAvailable: "ウォーターマーク機能の使用可否" watermarkAvailable: "ウォーターマーク機能の使用可否"
_condition: _condition:
roleAssignedTo: "マニュアルロールにアサイン済み" roleAssignedTo: "マニュアルロールにアサイン済み"
@ -2274,7 +2305,7 @@ _theme:
buttonHoverBg: "ボタンの背景 (ホバー)" buttonHoverBg: "ボタンの背景 (ホバー)"
inputBorder: "入力ボックスの縁取り" inputBorder: "入力ボックスの縁取り"
badge: "バッジ" badge: "バッジ"
messageBg: "チャットの背景" messageBg: "メッセージの背景"
fgHighlighted: "強調された文字" fgHighlighted: "強調された文字"
_sfx: _sfx:
@ -2282,7 +2313,7 @@ _sfx:
noteMy: "ノート(自分)" noteMy: "ノート(自分)"
notification: "通知" notification: "通知"
reaction: "リアクション選択時" reaction: "リアクション選択時"
chatMessage: "チャットのメッセージ" chatMessage: "ダイレクトメッセージ"
_soundSettings: _soundSettings:
driveFile: "ドライブの音声を使用" driveFile: "ドライブの音声を使用"
@ -2319,6 +2350,7 @@ _time:
minute: "分" minute: "分"
hour: "時間" hour: "時間"
day: "日" day: "日"
month: "ヶ月"
_2fa: _2fa:
alreadyRegistered: "既に設定は完了しています。" alreadyRegistered: "既に設定は完了しています。"
@ -2361,8 +2393,8 @@ _permissions:
"write:favorites": "お気に入りを操作する" "write:favorites": "お気に入りを操作する"
"read:following": "フォローの情報を見る" "read:following": "フォローの情報を見る"
"write:following": "フォロー・フォロー解除する" "write:following": "フォロー・フォロー解除する"
"read:messaging": "チャットを見る" "read:messaging": "ダイレクトメッセージを見る"
"write:messaging": "チャットを操作する" "write:messaging": "ダイレクトメッセージを操作する"
"read:mutes": "ミュートを見る" "read:mutes": "ミュートを見る"
"write:mutes": "ミュートを操作する" "write:mutes": "ミュートを操作する"
"write:notes": "ノートを作成・削除する" "write:notes": "ノートを作成・削除する"
@ -2435,8 +2467,8 @@ _permissions:
"read:clip-favorite": "クリップのいいねを見る" "read:clip-favorite": "クリップのいいねを見る"
"read:federation": "連合に関する情報を取得する" "read:federation": "連合に関する情報を取得する"
"write:report-abuse": "違反を報告する" "write:report-abuse": "違反を報告する"
"write:chat": "チャットを操作する" "write:chat": "ダイレクトメッセージを操作する"
"read:chat": "チャットを閲覧する" "read:chat": "ダイレクトメッセージを閲覧する"
_auth: _auth:
shareAccessTitle: "アプリへのアクセス許可" shareAccessTitle: "アプリへのアクセス許可"
@ -2499,7 +2531,7 @@ _widgets:
chooseList: "リストを選択" chooseList: "リストを選択"
clicker: "クリッカー" clicker: "クリッカー"
birthdayFollowings: "今日誕生日のユーザー" birthdayFollowings: "今日誕生日のユーザー"
chat: "チャット" chat: "ダイレクトメッセージ"
_cw: _cw:
hide: "隠す" hide: "隠す"
@ -2703,10 +2735,12 @@ _notification:
youReceivedFollowRequest: "フォローリクエストが来ました" youReceivedFollowRequest: "フォローリクエストが来ました"
yourFollowRequestAccepted: "フォローリクエストが承認されました" yourFollowRequestAccepted: "フォローリクエストが承認されました"
pollEnded: "アンケートの結果が出ました" pollEnded: "アンケートの結果が出ました"
scheduledNotePosted: "予約ノートが投稿されました"
scheduledNotePostFailed: "予約ノートの投稿に失敗しました"
newNote: "新しい投稿" newNote: "新しい投稿"
unreadAntennaNote: "アンテナ {name}" unreadAntennaNote: "アンテナ {name}"
roleAssigned: "ロールが付与されました" roleAssigned: "ロールが付与されました"
chatRoomInvitationReceived: "チャットルームへ招待されました" chatRoomInvitationReceived: "ダイレクトメッセージのグループへ招待されました"
emptyPushNotificationMessage: "プッシュ通知の更新をしました" emptyPushNotificationMessage: "プッシュ通知の更新をしました"
achievementEarned: "実績を獲得" achievementEarned: "実績を獲得"
testNotification: "通知テスト" testNotification: "通知テスト"
@ -2736,7 +2770,7 @@ _notification:
receiveFollowRequest: "フォロー申請を受け取った" receiveFollowRequest: "フォロー申請を受け取った"
followRequestAccepted: "フォローが受理された" followRequestAccepted: "フォローが受理された"
roleAssigned: "ロールが付与された" roleAssigned: "ロールが付与された"
chatRoomInvitationReceived: "チャットルームへ招待された" chatRoomInvitationReceived: "ダイレクトメッセージのグループへ招待された"
achievementEarned: "実績の獲得" achievementEarned: "実績の獲得"
exportCompleted: "エクスポートが完了した" exportCompleted: "エクスポートが完了した"
login: "ログイン" login: "ログイン"
@ -2786,7 +2820,7 @@ _deck:
mentions: "メンション" mentions: "メンション"
direct: "指名" direct: "指名"
roleTimeline: "ロールタイムライン" roleTimeline: "ロールタイムライン"
chat: "チャット" chat: "ダイレクトメッセージ"
_dialog: _dialog:
charactersExceeded: "最大文字数を超えています! 現在 {current} / 制限 {max}" charactersExceeded: "最大文字数を超えています! 現在 {current} / 制限 {max}"
@ -2889,7 +2923,7 @@ _moderationLogTypes:
deletePage: "ページを削除" deletePage: "ページを削除"
deleteFlash: "Playを削除" deleteFlash: "Playを削除"
deleteGalleryPost: "ギャラリーの投稿を削除" deleteGalleryPost: "ギャラリーの投稿を削除"
deleteChatRoom: "チャットルームを削除" deleteChatRoom: "ダイレクトメッセージのグループを削除"
updateProxyAccountDescription: "プロキシアカウントの説明を更新" updateProxyAccountDescription: "プロキシアカウントの説明を更新"
_fileViewer: _fileViewer:
@ -3208,8 +3242,8 @@ _serverSetupWizard:
doYouConnectToFediverse_description1: "分散型サーバーで構成されるネットワーク(Fediverse)に接続すると、他のサーバーと相互にコンテンツのやり取りが可能です。" doYouConnectToFediverse_description1: "分散型サーバーで構成されるネットワーク(Fediverse)に接続すると、他のサーバーと相互にコンテンツのやり取りが可能です。"
doYouConnectToFediverse_description2: "Fediverseと接続することは「連合」とも呼ばれます。" doYouConnectToFediverse_description2: "Fediverseと接続することは「連合」とも呼ばれます。"
youCanConfigureMoreFederationSettingsLater: "連合可能なサーバーの指定など、高度な設定も後ほど可能です。" youCanConfigureMoreFederationSettingsLater: "連合可能なサーバーの指定など、高度な設定も後ほど可能です。"
remoteContentsCleaning: "受信コンテンツの自動クリーニング" remoteContentsCleaning: "リモートコンテンツの自動クリーニング"
remoteContentsCleaning_description: "連合を行うと、継続して多くのコンテンツを受信します。自動クリーニングを有効にすると、参照されていない古くなったコンテンツを自動でサーバーから削除し、ストレージを節約できます。" remoteContentsCleaning_description: "連合を行うと、継続して多くのコンテンツを受信します。自動クリーニングを有効にすると、一定期間経過したリモートコンテンツを自動でサーバーから削除し、ストレージを節約できます。"
adminInfo: "管理者情報" adminInfo: "管理者情報"
adminInfo_description: "問い合わせを受け付けるために使用される管理者情報を設定します。" adminInfo_description: "問い合わせを受け付けるために使用される管理者情報を設定します。"
adminInfo_mustBeFilled: "オープンサーバー、または連合がオンの場合は必ず入力が必要です。" adminInfo_mustBeFilled: "オープンサーバー、または連合がオンの場合は必ず入力が必要です。"
@ -3263,7 +3297,9 @@ _watermarkEditor:
opacity: "不透明度" opacity: "不透明度"
scale: "サイズ" scale: "サイズ"
text: "テキスト" text: "テキスト"
qr: "二次元コード"
position: "位置" position: "位置"
margin: "マージン"
type: "タイプ" type: "タイプ"
image: "画像" image: "画像"
advanced: "高度" advanced: "高度"
@ -3278,6 +3314,7 @@ _watermarkEditor:
polkadotSubDotOpacity: "サブドットの不透明度" polkadotSubDotOpacity: "サブドットの不透明度"
polkadotSubDotRadius: "サブドットの大きさ" polkadotSubDotRadius: "サブドットの大きさ"
polkadotSubDotDivisions: "サブドットの数" polkadotSubDotDivisions: "サブドットの数"
leaveBlankToAccountUrl: "空欄にするとアカウントのURLになります"
_imageEffector: _imageEffector:
title: "エフェクト" title: "エフェクト"
@ -3291,6 +3328,8 @@ _imageEffector:
mirror: "ミラー" mirror: "ミラー"
invert: "色の反転" invert: "色の反転"
grayscale: "白黒" grayscale: "白黒"
blur: "ぼかし"
pixelate: "モザイク"
colorAdjust: "色調補正" colorAdjust: "色調補正"
colorClamp: "色の圧縮" colorClamp: "色の圧縮"
colorClampAdvanced: "色の圧縮(高度)" colorClampAdvanced: "色の圧縮(高度)"
@ -3302,11 +3341,15 @@ _imageEffector:
checker: "チェッカー" checker: "チェッカー"
blockNoise: "ブロックノイズ" blockNoise: "ブロックノイズ"
tearing: "ティアリング" tearing: "ティアリング"
fill: "塗りつぶし"
_fxProps: _fxProps:
angle: "角度" angle: "角度"
scale: "サイズ" scale: "サイズ"
size: "サイズ" size: "サイズ"
radius: "半径"
samples: "サンプル数"
offset: "位置"
color: "色" color: "色"
opacity: "不透明度" opacity: "不透明度"
normalize: "正規化" normalize: "正規化"
@ -3335,6 +3378,7 @@ _imageEffector:
zoomLinesThreshold: "集中線の幅" zoomLinesThreshold: "集中線の幅"
zoomLinesMaskSize: "中心径" zoomLinesMaskSize: "中心径"
zoomLinesBlack: "黒色にする" zoomLinesBlack: "黒色にする"
circle: "円形"
drafts: "下書き" drafts: "下書き"
_drafts: _drafts:
@ -3351,3 +3395,23 @@ _drafts:
restoreFromDraft: "下書きから復元" restoreFromDraft: "下書きから復元"
restore: "復元" restore: "復元"
listDrafts: "下書き一覧" listDrafts: "下書き一覧"
schedule: "投稿予約"
listScheduledNotes: "予約投稿一覧"
cancelSchedule: "予約解除"
qr: "二次元コード"
_qr:
showTabTitle: "表示"
readTabTitle: "読み取る"
shareTitle: "{name} {acct}"
shareText: "Fediverseで私をフォローしてください"
chooseCamera: "カメラを選択"
cannotToggleFlash: "ライト選択不可"
turnOnFlash: "ライトをオンにする"
turnOffFlash: "ライトをオフにする"
startQr: "コードリーダーを再開"
stopQr: "コードリーダーを停止"
noQrCodeFound: "QRコードが見つかりません"
scanFile: "端末の画像をスキャン"
raw: "テキスト"
mfm: "MFM"

View File

@ -1239,7 +1239,6 @@ releaseToRefresh: "離したらリロード"
refreshing: "リロードしとる" refreshing: "リロードしとる"
pullDownToRefresh: "引っ張ってリロードするで" pullDownToRefresh: "引っ張ってリロードするで"
useGroupedNotifications: "通知をグループ分けして出すで" useGroupedNotifications: "通知をグループ分けして出すで"
signupPendingError: "メアド確認してたらなんか変なことなったわ。リンクの期限切れてるかもしれん。"
cwNotationRequired: "「内容を隠す」んやったら注釈書かなアカンで。" cwNotationRequired: "「内容を隠す」んやったら注釈書かなアカンで。"
doReaction: "ツッコむで" doReaction: "ツッコむで"
code: "コード" code: "コード"
@ -1320,6 +1319,7 @@ preferenceSyncConflictChoiceMerge: "ガッチャンコしよか"
preferenceSyncConflictChoiceCancel: "同期の有効化はやめとくわ" preferenceSyncConflictChoiceCancel: "同期の有効化はやめとくわ"
postForm: "投稿フォーム" postForm: "投稿フォーム"
information: "情報" information: "情報"
directMessage: "チャットしよか"
migrateOldSettings: "旧設定情報をお引っ越し" migrateOldSettings: "旧設定情報をお引っ越し"
migrateOldSettings_description: "通常これは自動で行われるはずなんやけど、なんかの理由で上手く移行できへんかったときは手動で移行処理をポチっとできるで。今の設定情報は上書きされるで。" migrateOldSettings_description: "通常これは自動で行われるはずなんやけど、なんかの理由で上手く移行できへんかったときは手動で移行処理をポチっとできるで。今の設定情報は上書きされるで。"
settingsMigrating: "設定を移行しとるで。ちょっと待っとってな... (後で、設定→その他→旧設定情報を移行 で手動で移行することもできるで)" settingsMigrating: "設定を移行しとるで。ちょっと待っとってな... (後で、設定→その他→旧設定情報を移行 で手動で移行することもできるで)"
@ -1410,7 +1410,7 @@ _accountSettings:
makeNotesFollowersOnlyBefore: "昔のノートをフォロワーだけに見てもらう" makeNotesFollowersOnlyBefore: "昔のノートをフォロワーだけに見てもらう"
makeNotesFollowersOnlyBeforeDescription: "この機能が有効になってる間は、設定された日時より前、それか設定された時間が経ったノートがフォロワーのみ見れるようになるで。無効に戻すと、ノートの公開状態も戻るで。" makeNotesFollowersOnlyBeforeDescription: "この機能が有効になってる間は、設定された日時より前、それか設定された時間が経ったノートがフォロワーのみ見れるようになるで。無効に戻すと、ノートの公開状態も戻るで。"
makeNotesHiddenBefore: "昔のノートを見れんようにする" makeNotesHiddenBefore: "昔のノートを見れんようにする"
makeNotesHiddenBeforeDescription: "この機能が有効になってる間は、設定された日時より前、それか設定された時間が経ったノートがフォロワーのみ見れるようになるで。無効に戻すと、ノートの公開状態も戻るで。" makeNotesHiddenBeforeDescription: "この機能が有効になってる間は、設定された日時より前、それか設定された時間が経ったノートがあんただけ見れるようになるで。無効に戻すと、ノートの公開状態も戻るで。"
mayNotEffectForFederatedNotes: "リモートサーバーに連合されたノートには効果が及ばんかもしれん。" mayNotEffectForFederatedNotes: "リモートサーバーに連合されたノートには効果が及ばんかもしれん。"
mayNotEffectSomeSituations: "これらの制限は簡易的なものやで。リモートサーバーでの閲覧とかモデレーション時とか、一部のシチュエーションでは適用されへんかもしれん。" mayNotEffectSomeSituations: "これらの制限は簡易的なものやで。リモートサーバーでの閲覧とかモデレーション時とか、一部のシチュエーションでは適用されへんかもしれん。"
notesHavePassedSpecifiedPeriod: "決めた時間が経ったノート" notesHavePassedSpecifiedPeriod: "決めた時間が経ったノート"
@ -2136,6 +2136,7 @@ _sfx:
noteMy: "ノート(自分)" noteMy: "ノート(自分)"
notification: "通知" notification: "通知"
reaction: "ツッコミ選んどるとき" reaction: "ツッコミ選んどるとき"
chatMessage: "チャットしよか"
_soundSettings: _soundSettings:
driveFile: "ドライブん中の音使う" driveFile: "ドライブん中の音使う"
driveFileWarn: "ドライブん中のファイル選びや" driveFileWarn: "ドライブん中のファイル選びや"
@ -2341,6 +2342,7 @@ _widgets:
chooseList: "リストを選ぶ" chooseList: "リストを選ぶ"
clicker: "クリッカー" clicker: "クリッカー"
birthdayFollowings: "今日誕生日のツレ" birthdayFollowings: "今日誕生日のツレ"
chat: "チャットしよか"
_cw: _cw:
hide: "隠す" hide: "隠す"
show: "続き見して!" show: "続き見して!"
@ -2603,6 +2605,7 @@ _deck:
mentions: "あんた宛て" mentions: "あんた宛て"
direct: "ダイレクト" direct: "ダイレクト"
roleTimeline: "ロールタイムライン" roleTimeline: "ロールタイムライン"
chat: "チャットしよか"
_dialog: _dialog:
charactersExceeded: "最大の文字数を上回っとるで!今は {current} / 最大でも {max}" charactersExceeded: "最大の文字数を上回っとるで!今は {current} / 最大でも {max}"
charactersBelow: "最小の文字数を下回っとるで!今は {current} / 最低でも {min}" charactersBelow: "最小の文字数を下回っとるで!今は {current} / 最低でも {min}"
@ -3020,9 +3023,20 @@ _watermarkEditor:
angle: "角度" angle: "角度"
_imageEffector: _imageEffector:
discardChangesConfirm: "変更をせんで終わるか?" discardChangesConfirm: "変更をせんで終わるか?"
_fxProps:
angle: "角度"
scale: "大きさ"
size: "大きさ"
offset: "位置"
color: "色"
opacity: "不透明度"
lightness: "明るさ"
_drafts: _drafts:
cannotCreateDraftAnymore: "下書きはこれ以上は作れへんな。" cannotCreateDraftAnymore: "下書きはこれ以上は作れへんな。"
cannotCreateDraft: "この内容で下書きは作れへんな。" cannotCreateDraft: "この内容で下書きは作れへんな。"
delete: "下書きをほかす" delete: "下書きをほかす"
deleteAreYouSure: "下書きをほかしてもええか?" deleteAreYouSure: "下書きをほかしてもええか?"
noDrafts: "下書きはあらへん" noDrafts: "下書きはあらへん"
_qr:
showTabTitle: "表示"
raw: "テキスト"

View File

@ -852,3 +852,5 @@ _search:
searchScopeUser: "사용자 지정" searchScopeUser: "사용자 지정"
_watermarkEditor: _watermarkEditor:
image: "이미지" image: "이미지"
_qr:
showTabTitle: "보기"

View File

@ -253,6 +253,7 @@ noteDeleteConfirm: "이 노트를 삭제하시겠습니까?"
pinLimitExceeded: "더 이상 고정할 수 없습니다." pinLimitExceeded: "더 이상 고정할 수 없습니다."
done: "완료" done: "완료"
processing: "처리중" processing: "처리중"
preprocessing: "준비중"
preview: "미리보기" preview: "미리보기"
default: "기본값" default: "기본값"
defaultValueIs: "기본값: {value}" defaultValueIs: "기본값: {value}"
@ -1054,6 +1055,7 @@ permissionDeniedError: "작업이 거부되었습니다"
permissionDeniedErrorDescription: "이 작업을 수행할 권한이 없습니다." permissionDeniedErrorDescription: "이 작업을 수행할 권한이 없습니다."
preset: "프리셋" preset: "프리셋"
selectFromPresets: "프리셋에서 선택" selectFromPresets: "프리셋에서 선택"
custom: "커스텀"
achievements: "도전 과제" achievements: "도전 과제"
gotInvalidResponseError: "서버의 응답이 올바르지 않습니다" gotInvalidResponseError: "서버의 응답이 올바르지 않습니다"
gotInvalidResponseErrorDescription: " 서버가 다운되었거나 점검중일 가능성이 있습니다. 잠시후에 다시 시도해 주십시오." gotInvalidResponseErrorDescription: " 서버가 다운되었거나 점검중일 가능성이 있습니다. 잠시후에 다시 시도해 주십시오."
@ -1092,6 +1094,7 @@ prohibitedWordsDescription2: "공백으로 구분하면 AND 지정이 되며,
hiddenTags: "숨긴 해시태그" hiddenTags: "숨긴 해시태그"
hiddenTagsDescription: "설정한 태그를 트렌드에 표시하지 않도록 합니다. 줄 바꿈으로 하나씩 나눠서 설정할 수 있습니다." hiddenTagsDescription: "설정한 태그를 트렌드에 표시하지 않도록 합니다. 줄 바꿈으로 하나씩 나눠서 설정할 수 있습니다."
notesSearchNotAvailable: "노트 검색을 이용하실 수 없습니다." notesSearchNotAvailable: "노트 검색을 이용하실 수 없습니다."
usersSearchNotAvailable: "유저 검색을 이용하실 수 없습니다."
license: "라이선스" license: "라이선스"
unfavoriteConfirm: "즐겨찾기를 해제하시겠습니까?" unfavoriteConfirm: "즐겨찾기를 해제하시겠습니까?"
myClips: "내 클립" myClips: "내 클립"
@ -1243,7 +1246,7 @@ releaseToRefresh: "놓아서 새로고침"
refreshing: "새로고침 중" refreshing: "새로고침 중"
pullDownToRefresh: "아래로 내려서 새로고침" pullDownToRefresh: "아래로 내려서 새로고침"
useGroupedNotifications: "알림을 그룹화하고 표시" useGroupedNotifications: "알림을 그룹화하고 표시"
signupPendingError: "메일 주소 확인중에 문제가 발생했습니다. 링크의 유효기간이 지났을 가능성이 있습니다." emailVerificationFailedError: "메일 주소 확인에 실패했습니다. 확인에 필요한 URL의 유효기간이 지났을 가능성이 있습니다."
cwNotationRequired: "'내용을 숨기기'를 체크한 경우 주석을 써야 합니다." cwNotationRequired: "'내용을 숨기기'를 체크한 경우 주석을 써야 합니다."
doReaction: "리액션 추가" doReaction: "리액션 추가"
code: "문자열" code: "문자열"
@ -1314,6 +1317,7 @@ acknowledgeNotesAndEnable: "활성화 하기 전에 주의 사항을 확인했
federationSpecified: "이 서버는 화이트 리스트 제도로 운영 중 입니다. 정해진 리모트 서버가 아닌 경우 연합되지 않습니다." federationSpecified: "이 서버는 화이트 리스트 제도로 운영 중 입니다. 정해진 리모트 서버가 아닌 경우 연합되지 않습니다."
federationDisabled: "이 서버는 연합을 하지 않고 있습니다. 리모트 서버 유저와 통신을 할 수 없습니다." federationDisabled: "이 서버는 연합을 하지 않고 있습니다. 리모트 서버 유저와 통신을 할 수 없습니다."
draft: "초안" draft: "초안"
draftsAndScheduledNotes: "초안과 예약 게시물"
confirmOnReact: "리액션할 때 확인" confirmOnReact: "리액션할 때 확인"
reactAreYouSure: "\" {emoji} \"로 리액션하시겠습니까?" reactAreYouSure: "\" {emoji} \"로 리액션하시겠습니까?"
markAsSensitiveConfirm: "이 미디어를 민감한 미디어로 설정하시겠습니까?" markAsSensitiveConfirm: "이 미디어를 민감한 미디어로 설정하시겠습니까?"
@ -1341,6 +1345,8 @@ postForm: "글 입력란"
textCount: "문자 수" textCount: "문자 수"
information: "정보" information: "정보"
chat: "채팅" chat: "채팅"
directMessage: "채팅하기"
directMessage_short: "메시지"
migrateOldSettings: "기존 설정 정보를 이전" migrateOldSettings: "기존 설정 정보를 이전"
migrateOldSettings_description: "보통은 자동으로 이루어지지만, 어떤 이유로 인해 성공적으로 이전이 이루어지지 않는 경우 수동으로 이전을 실행할 수 있습니다. 현재 설정 정보는 덮어쓰게 됩니다." migrateOldSettings_description: "보통은 자동으로 이루어지지만, 어떤 이유로 인해 성공적으로 이전이 이루어지지 않는 경우 수동으로 이전을 실행할 수 있습니다. 현재 설정 정보는 덮어쓰게 됩니다."
compress: "압축" compress: "압축"
@ -1368,16 +1374,35 @@ redisplayAllTips: "모든 '팁과 유용한 정보'를 재표시"
hideAllTips: "모든 '팁과 유용한 정보'를 비표시" hideAllTips: "모든 '팁과 유용한 정보'를 비표시"
defaultImageCompressionLevel: "기본 이미지 압축 정도" defaultImageCompressionLevel: "기본 이미지 압축 정도"
defaultImageCompressionLevel_description: "낮추면 화질을 유지합니다만 파일 크기는 증가합니다. <br>높이면 파일 크기를 줄일 수 있습니다만 화질은 저하됩니다." defaultImageCompressionLevel_description: "낮추면 화질을 유지합니다만 파일 크기는 증가합니다. <br>높이면 파일 크기를 줄일 수 있습니다만 화질은 저하됩니다."
defaultCompressionLevel: "기본 압축 정도 "
defaultCompressionLevel_description: "낮추면 품질을 유지합니다만 파일 크기는 증가합니다. <br>높이면 파일 크기를 줄일 수 있습니다만 품질은 저하됩니다."
inMinutes: "분" inMinutes: "분"
inDays: "일" inDays: "일"
safeModeEnabled: "세이프 모드가 활성화돼있습니다" safeModeEnabled: "세이프 모드가 활성화돼있습니다"
pluginsAreDisabledBecauseSafeMode: "세이프 모드가 활성화돼있기에 플러그인은 전부 비활성화됩니다." pluginsAreDisabledBecauseSafeMode: "세이프 모드가 활성화돼있기에 플러그인은 전부 비활성화됩니다."
customCssIsDisabledBecauseSafeMode: "세이프 모드가 활성화돼있기에 커스텀 CSS는 적용되지 않습니다." customCssIsDisabledBecauseSafeMode: "세이프 모드가 활성화돼있기에 커스텀 CSS는 적용되지 않습니다."
themeIsDefaultBecauseSafeMode: "세이프 모드가 활성화돼있는 동안에는 기본 테마가 사용됩니다. 세이프 모드를 끄면 원래대로 돌아옵니다." themeIsDefaultBecauseSafeMode: "세이프 모드가 활성화돼있는 동안에는 기본 테마가 사용됩니다. 세이프 모드를 끄면 원래대로 돌아옵니다."
thankYouForTestingBeta: "베타 버전의 검증에 협력해 주셔서 감사합니다!"
createUserSpecifiedNote: "사용자 지정 노트를 작성"
schedulePost: "게시 예약"
scheduleToPostOnX: "{x}에 게시를 예약합니다."
scheduledToPostOnX: "{x}에 게시가 예약돼있습니다."
schedule: "예약"
scheduled: "예약"
_compression:
_quality:
high: "고품질"
medium: "중간 품질"
low: "저품질"
_size:
large: "대형"
medium: "중형"
small: "소형"
_order: _order:
newest: "최신 순" newest: "최신 순"
oldest: "오래된 순" oldest: "오래된 순"
_chat: _chat:
messages: "메시지"
noMessagesYet: "아직 메시지가 없습니다" noMessagesYet: "아직 메시지가 없습니다"
newMessage: "새로운 메시지" newMessage: "새로운 메시지"
individualChat: "개인 대화" individualChat: "개인 대화"
@ -1663,6 +1688,9 @@ _serverSettings:
userGeneratedContentsVisibilityForVisitor_description2: "서버에서 받은 리모트 콘텐츠를 포함해 서버 내의 모든 콘텐츠를 무조건 인터넷에 공개하는 것에는 위험이 따릅니다. 특히, 분산형 특성에 대해 모르는 열람자에게는 리모트 콘텐츠여도 서버 내에서 작성된 콘텐츠라고 잘못 인식할 수 있기에 주의가 필요합니다." userGeneratedContentsVisibilityForVisitor_description2: "서버에서 받은 리모트 콘텐츠를 포함해 서버 내의 모든 콘텐츠를 무조건 인터넷에 공개하는 것에는 위험이 따릅니다. 특히, 분산형 특성에 대해 모르는 열람자에게는 리모트 콘텐츠여도 서버 내에서 작성된 콘텐츠라고 잘못 인식할 수 있기에 주의가 필요합니다."
restartServerSetupWizardConfirm_title: "서버의 초기 설정 위자드를 재시도하시겠습니까?" restartServerSetupWizardConfirm_title: "서버의 초기 설정 위자드를 재시도하시겠습니까?"
restartServerSetupWizardConfirm_text: "현재 일부 설정은 리셋됩니다." restartServerSetupWizardConfirm_text: "현재 일부 설정은 리셋됩니다."
entrancePageStyle: "입구 페이지의 스타일"
showTimelineForVisitor: "타임라인 표시"
showActivitiesForVisitor: "액티비티 표시하기"
_userGeneratedContentsVisibilityForVisitor: _userGeneratedContentsVisibilityForVisitor:
all: "모두 공개" all: "모두 공개"
localOnly: "로컬 콘텐츠만 공개하고 리모트 콘텐츠는 비공개" localOnly: "로컬 콘텐츠만 공개하고 리모트 콘텐츠는 비공개"
@ -1999,6 +2027,7 @@ _role:
descriptionOfRateLimitFactor: "작을수록 제한이 완화되고, 클수록 제한이 강화됩니다." descriptionOfRateLimitFactor: "작을수록 제한이 완화되고, 클수록 제한이 강화됩니다."
canHideAds: "광고 숨기기" canHideAds: "광고 숨기기"
canSearchNotes: "노트 검색 이용 가능 여부" canSearchNotes: "노트 검색 이용 가능 여부"
canSearchUsers: "유저 검색 이용"
canUseTranslator: "번역 기능의 사용" canUseTranslator: "번역 기능의 사용"
avatarDecorationLimit: "아바타 장식의 최대 붙임 개수" avatarDecorationLimit: "아바타 장식의 최대 붙임 개수"
canImportAntennas: "안테나 가져오기 허용" canImportAntennas: "안테나 가져오기 허용"
@ -2011,6 +2040,7 @@ _role:
uploadableFileTypes_caption: "MIME 유형을 " uploadableFileTypes_caption: "MIME 유형을 "
uploadableFileTypes_caption2: "파일에 따라서는 유형을 검사하지 못하는 경우가 있습니다. 그러한 파일을 허가하는 경우에는 {x}를 지정으로 추가해주십시오." uploadableFileTypes_caption2: "파일에 따라서는 유형을 검사하지 못하는 경우가 있습니다. 그러한 파일을 허가하는 경우에는 {x}를 지정으로 추가해주십시오."
noteDraftLimit: "서버측 노트 초안 작성 가능 수" noteDraftLimit: "서버측 노트 초안 작성 가능 수"
scheduledNoteLimit: "예약 게시물의 동시 작성 가능 수"
watermarkAvailable: "워터마크 기능의 사용 여부" watermarkAvailable: "워터마크 기능의 사용 여부"
_condition: _condition:
roleAssignedTo: "수동 역할에 이미 할당됨" roleAssignedTo: "수동 역할에 이미 할당됨"
@ -2271,6 +2301,7 @@ _time:
minute: "분" minute: "분"
hour: "시간" hour: "시간"
day: "일" day: "일"
month: "개월"
_2fa: _2fa:
alreadyRegistered: "이미 설정이 완료되었습니다." alreadyRegistered: "이미 설정이 완료되었습니다."
registerTOTP: "인증 앱 설정 시작" registerTOTP: "인증 앱 설정 시작"
@ -2445,7 +2476,7 @@ _widgets:
chooseList: "리스트 선택" chooseList: "리스트 선택"
clicker: "클리커" clicker: "클리커"
birthdayFollowings: "오늘이 생일인 유저" birthdayFollowings: "오늘이 생일인 유저"
chat: "채팅" chat: "채팅하기"
_cw: _cw:
hide: "숨기기" hide: "숨기기"
show: "더 보기" show: "더 보기"
@ -2635,6 +2666,8 @@ _notification:
youReceivedFollowRequest: "새로운 팔로우 요청이 있습니다" youReceivedFollowRequest: "새로운 팔로우 요청이 있습니다"
yourFollowRequestAccepted: "팔로우 요청이 수락되었습니다" yourFollowRequestAccepted: "팔로우 요청이 수락되었습니다"
pollEnded: "투표 결과가 발표되었습니다" pollEnded: "투표 결과가 발표되었습니다"
scheduledNotePosted: "예약 노트가 게시됐습니다."
scheduledNotePostFailed: "예약 노트의 게시에 실패했습니다."
newNote: "새 게시물" newNote: "새 게시물"
unreadAntennaNote: "안테나 {name}" unreadAntennaNote: "안테나 {name}"
roleAssigned: "역할이 부여 되었습니다." roleAssigned: "역할이 부여 되었습니다."
@ -2714,7 +2747,7 @@ _deck:
mentions: "받은 멘션" mentions: "받은 멘션"
direct: "다이렉트" direct: "다이렉트"
roleTimeline: "역할 타임라인" roleTimeline: "역할 타임라인"
chat: "채팅" chat: "채팅하기"
_dialog: _dialog:
charactersExceeded: "최대 글자수를 초과하였습니다! 현재 {current} / 최대 {max}" charactersExceeded: "최대 글자수를 초과하였습니다! 현재 {current} / 최대 {max}"
charactersBelow: "최소 글자수 미만입니다! 현재 {current} / 최소 {min}" charactersBelow: "최소 글자수 미만입니다! 현재 {current} / 최소 {min}"
@ -3160,14 +3193,16 @@ _watermarkEditor:
opacity: "불투명도" opacity: "불투명도"
scale: "크기" scale: "크기"
text: "텍스트" text: "텍스트"
qr: "QR 코드"
position: "위치" position: "위치"
margin: "여백"
type: "종류" type: "종류"
image: "이미지" image: "이미지"
advanced: "고급" advanced: "고급"
angle: "각도"
stripe: "줄무늬" stripe: "줄무늬"
stripeWidth: "라인의 폭" stripeWidth: "라인의 폭"
stripeFrequency: "라인의 수" stripeFrequency: "라인의 수"
angle: "각도"
polkadot: "물방울 무늬" polkadot: "물방울 무늬"
checker: "체크 무늬" checker: "체크 무늬"
polkadotMainDotOpacity: "주요 물방울의 불투명도" polkadotMainDotOpacity: "주요 물방울의 불투명도"
@ -3175,16 +3210,20 @@ _watermarkEditor:
polkadotSubDotOpacity: "서브 물방울의 불투명도" polkadotSubDotOpacity: "서브 물방울의 불투명도"
polkadotSubDotRadius: "서브 물방울의 크기" polkadotSubDotRadius: "서브 물방울의 크기"
polkadotSubDotDivisions: "서브 물방울의 수" polkadotSubDotDivisions: "서브 물방울의 수"
leaveBlankToAccountUrl: "빈칸일 경우 계정의 URL로 됩니다."
_imageEffector: _imageEffector:
title: "이펙트" title: "이펙트"
addEffect: "이펙트를 추가" addEffect: "이펙트를 추가"
discardChangesConfirm: "변경을 취소하고 종료하시겠습니까?" discardChangesConfirm: "변경을 취소하고 종료하시겠습니까?"
nothingToConfigure: "설정 항목이 없습니다."
_fxs: _fxs:
chromaticAberration: "색수차" chromaticAberration: "색수차"
glitch: "글리치" glitch: "글리치"
mirror: "미러" mirror: "미러"
invert: "색 반전" invert: "색 반전"
grayscale: "흑백" grayscale: "흑백"
blur: "흐림 효과"
pixelate: "모자이크"
colorAdjust: "색조 보정" colorAdjust: "색조 보정"
colorClamp: "색 압축" colorClamp: "색 압축"
colorClampAdvanced: "색 압축(고급)" colorClampAdvanced: "색 압축(고급)"
@ -3196,6 +3235,43 @@ _imageEffector:
checker: "체크 무늬" checker: "체크 무늬"
blockNoise: "노이즈 방지" blockNoise: "노이즈 방지"
tearing: "티어링" tearing: "티어링"
fill: "채우기"
_fxProps:
angle: "각도"
scale: "크기"
size: "크기"
radius: "반지름"
samples: "샘플 수"
offset: "위치"
color: "색"
opacity: "불투명도"
normalize: "노멀라이즈"
amount: "양"
lightness: "밝음"
contrast: "대비"
hue: "색조"
brightness: "밝기"
saturation: "채도"
max: "최대 값"
min: "최소 값"
direction: "방향"
phase: "위상"
frequency: "빈도"
strength: "강도"
glitchChannelShift: "글리치"
seed: "시드 값"
redComponent: "빨간색 요소"
greenComponent: "녹색 요소"
blueComponent: "파란색 요소"
threshold: "한계 값"
centerX: "X축 중심"
centerY: "Y축 중심"
zoomLinesSmoothing: "다듬기"
zoomLinesSmoothingDescription: "다듬기와 집중선 폭 설정은 같이 쓸 수 없습니다."
zoomLinesThreshold: "집중선 폭"
zoomLinesMaskSize: "중앙 값"
zoomLinesBlack: "검은색으로 하기"
circle: "원형"
drafts: "초안" drafts: "초안"
_drafts: _drafts:
select: "초안 선택" select: "초안 선택"
@ -3211,3 +3287,22 @@ _drafts:
restoreFromDraft: "초안에서 복원\n" restoreFromDraft: "초안에서 복원\n"
restore: "복원" restore: "복원"
listDrafts: "초안 목록" listDrafts: "초안 목록"
schedule: "게시 예약"
listScheduledNotes: "예약 게시물 목록"
cancelSchedule: "예약 해제"
qr: "QR 코드"
_qr:
showTabTitle: "보기"
readTabTitle: "읽어들이기"
shareTitle: "{name} {acct}"
shareText: "Fediverse로 저를 팔로우해 주세요!"
chooseCamera: "카메라 선택"
cannotToggleFlash: "플래시 선택 불가"
turnOnFlash: "플래시 켜기"
turnOffFlash: "플래시 끄기"
startQr: "코드 리더 재개"
stopQr: "코드 리더 정지"
noQrCodeFound: "QR 코드를 찾을 수 없습니다."
scanFile: "단말기의 이미지 스캔"
raw: "텍스트"
mfm: "MFM"

View File

@ -1083,3 +1083,5 @@ _search:
_watermarkEditor: _watermarkEditor:
image: "Afbeeldingen" image: "Afbeeldingen"
advanced: "Geavanceerd" advanced: "Geavanceerd"
_qr:
showTabTitle: "Weergave"

View File

@ -742,3 +742,10 @@ _watermarkEditor:
text: "Tekst" text: "Tekst"
type: "Type" type: "Type"
image: "Bilder" image: "Bilder"
_imageEffector:
_fxProps:
scale: "Størrelse"
size: "Størrelse"
color: "Farge"
_qr:
raw: "Tekst"

View File

@ -1593,3 +1593,13 @@ _watermarkEditor:
type: "Typ" type: "Typ"
image: "Zdjęcia" image: "Zdjęcia"
advanced: "Zaawansowane" advanced: "Zaawansowane"
_imageEffector:
_fxProps:
scale: "Rozmiar"
size: "Rozmiar"
color: "Kolor"
opacity: "Przezroczystość"
lightness: "Rozjaśnij"
_qr:
showTabTitle: "Wyświetlanie"
raw: "Tekst"

View File

@ -253,6 +253,7 @@ noteDeleteConfirm: "Deseja excluir esta nota?"
pinLimitExceeded: "Não é possível fixar novas notas" pinLimitExceeded: "Não é possível fixar novas notas"
done: "Concluído" done: "Concluído"
processing: "Em Progresso" processing: "Em Progresso"
preprocessing: "Preparando..."
preview: "Pré-visualizar" preview: "Pré-visualizar"
default: "Predefinição" default: "Predefinição"
defaultValueIs: "Predefinição: {value}" defaultValueIs: "Predefinição: {value}"
@ -1054,6 +1055,7 @@ permissionDeniedError: "Operação recusada"
permissionDeniedErrorDescription: "Esta conta não tem permissão para executar esta ação." permissionDeniedErrorDescription: "Esta conta não tem permissão para executar esta ação."
preset: "Predefinições" preset: "Predefinições"
selectFromPresets: "Escolher de predefinições" selectFromPresets: "Escolher de predefinições"
custom: "Personalizado"
achievements: "Conquistas" achievements: "Conquistas"
gotInvalidResponseError: "Resposta do servidor inválida" gotInvalidResponseError: "Resposta do servidor inválida"
gotInvalidResponseErrorDescription: "Servidor fora do ar ou em manutenção. Favor tentar mais tarde." gotInvalidResponseErrorDescription: "Servidor fora do ar ou em manutenção. Favor tentar mais tarde."
@ -1092,6 +1094,7 @@ prohibitedWordsDescription2: "Utilizar espaços irá criar expressões aditivas
hiddenTags: "Hashtags escondidas" hiddenTags: "Hashtags escondidas"
hiddenTagsDescription: "Selecione tags que não serão exibidas na lista de destaques. Várias tags podem ser escolhidas, separadas por linha." hiddenTagsDescription: "Selecione tags que não serão exibidas na lista de destaques. Várias tags podem ser escolhidas, separadas por linha."
notesSearchNotAvailable: "A pesquisa de notas está indisponível." notesSearchNotAvailable: "A pesquisa de notas está indisponível."
usersSearchNotAvailable: "Pesquisa de usuário está indisponível."
license: "Licença" license: "Licença"
unfavoriteConfirm: "Deseja realmente remover dos favoritos?" unfavoriteConfirm: "Deseja realmente remover dos favoritos?"
myClips: "Meus clipes" myClips: "Meus clipes"
@ -1243,7 +1246,7 @@ releaseToRefresh: "Solte para atualizar"
refreshing: "Atualizando..." refreshing: "Atualizando..."
pullDownToRefresh: "Puxe para baixo para atualizar" pullDownToRefresh: "Puxe para baixo para atualizar"
useGroupedNotifications: "Agrupar notificações" useGroupedNotifications: "Agrupar notificações"
signupPendingError: "Houve um problema ao verificar o endereço de email. O link pode ter expirado." emailVerificationFailedError: "Houve um problema ao verificar seu endereço de email. O link pode ter expirado."
cwNotationRequired: "Se \"Esconder conteúdo\" está habilitado, uma descrição deve ser adicionada." cwNotationRequired: "Se \"Esconder conteúdo\" está habilitado, uma descrição deve ser adicionada."
doReaction: "Adicionar reação" doReaction: "Adicionar reação"
code: "Código" code: "Código"
@ -1314,6 +1317,7 @@ acknowledgeNotesAndEnable: "Ative após compreender as precauções."
federationSpecified: "Esse servidor opera com uma lista branca de federação. Interagir com servidores diferentes daqueles designados pela administração não é permitido." federationSpecified: "Esse servidor opera com uma lista branca de federação. Interagir com servidores diferentes daqueles designados pela administração não é permitido."
federationDisabled: "Federação está desabilitada nesse servidor. Você não pode interagir com usuários de outros servidores." federationDisabled: "Federação está desabilitada nesse servidor. Você não pode interagir com usuários de outros servidores."
draft: "Rascunhos" draft: "Rascunhos"
draftsAndScheduledNotes: "Rascunhos e notas agendadas."
confirmOnReact: "Confirmar ao reagir" confirmOnReact: "Confirmar ao reagir"
reactAreYouSure: "Você deseja adicionar uma reação \"{emoji}\"?" reactAreYouSure: "Você deseja adicionar uma reação \"{emoji}\"?"
markAsSensitiveConfirm: "Você deseja definir essa mídia como sensível?" markAsSensitiveConfirm: "Você deseja definir essa mídia como sensível?"
@ -1341,6 +1345,8 @@ postForm: "Campo de postagem"
textCount: "Contagem de caracteres" textCount: "Contagem de caracteres"
information: "Sobre" information: "Sobre"
chat: "Conversas" chat: "Conversas"
directMessage: "Conversar com usuário"
directMessage_short: "Mensagem"
migrateOldSettings: "Migrar configurações antigas de cliente" migrateOldSettings: "Migrar configurações antigas de cliente"
migrateOldSettings_description: "Isso deve ser feito automaticamente. Caso o processo de migração tenha falhado, você pode acioná-lo manualmente. As informações atuais de migração serão substituídas." migrateOldSettings_description: "Isso deve ser feito automaticamente. Caso o processo de migração tenha falhado, você pode acioná-lo manualmente. As informações atuais de migração serão substituídas."
compress: "Comprimir" compress: "Comprimir"
@ -1368,12 +1374,35 @@ redisplayAllTips: "Mostrar todas as \"Dicas e Truques\" novamente"
hideAllTips: "Ocultas todas as \"Dicas e Truques\"" hideAllTips: "Ocultas todas as \"Dicas e Truques\""
defaultImageCompressionLevel: "Nível de compressão de imagem padrão" defaultImageCompressionLevel: "Nível de compressão de imagem padrão"
defaultImageCompressionLevel_description: "Alto, reduz o tamanho do arquivo mas, também, a qualidade da imagem.<br>Alto, reduz o tamanho do arquivo mas, também, a qualidade da imagem." defaultImageCompressionLevel_description: "Alto, reduz o tamanho do arquivo mas, também, a qualidade da imagem.<br>Alto, reduz o tamanho do arquivo mas, também, a qualidade da imagem."
defaultCompressionLevel: "Nível padrão de compressão"
defaultCompressionLevel_description: "Menor compressão preserva a qualidade mas aumenta o tamanho do arquivo.<br>Maior compressão reduz o tamanho do arquivo mas diminui a qualidade."
inMinutes: "Minuto(s)" inMinutes: "Minuto(s)"
inDays: "Dia(s)" inDays: "Dia(s)"
safeModeEnabled: "Modo seguro está habilitado"
pluginsAreDisabledBecauseSafeMode: "Todos os plugins estão desabilitados porque o modo seguro está habilitado."
customCssIsDisabledBecauseSafeMode: "CSS personalizado não está aplicado porque o modo seguro está habilitado."
themeIsDefaultBecauseSafeMode: "Enquanto o modo seguro estiver ativo, o tema padrão é utilizado. Desabilitar o modo seguro reverterá essas mudanças."
thankYouForTestingBeta: "Obrigado por nos ajudar a testar a versão beta!"
createUserSpecifiedNote: "Criar uma nota direta"
schedulePost: "Agendar publicação"
scheduleToPostOnX: "Agendar nota para {x}"
scheduledToPostOnX: "A nota está agendada para {x}"
schedule: "Agendar"
scheduled: "Agendado"
_compression:
_quality:
high: "Qualidade alta"
medium: "Qualidade média"
low: "Qualidade baixa"
_size:
large: "Tamanho grande"
medium: "Tamanho médio"
small: "Tamanho pequeno"
_order: _order:
newest: "Priorizar Mais Novos" newest: "Priorizar Mais Novos"
oldest: "Priorizar Mais Antigos" oldest: "Priorizar Mais Antigos"
_chat: _chat:
messages: "Mensagem"
noMessagesYet: "Ainda não há mensagens" noMessagesYet: "Ainda não há mensagens"
newMessage: "Nova mensagem" newMessage: "Nova mensagem"
individualChat: "Conversa Particular" individualChat: "Conversa Particular"
@ -1461,6 +1490,7 @@ _settings:
contentsUpdateFrequency_description2: "Quando o modo tempo-real está ativado, o conteúdo é atualizado em tempo real, ignorando essa opção." contentsUpdateFrequency_description2: "Quando o modo tempo-real está ativado, o conteúdo é atualizado em tempo real, ignorando essa opção."
showUrlPreview: "Exibir prévia de URL" showUrlPreview: "Exibir prévia de URL"
showAvailableReactionsFirstInNote: "Exibir reações disponíveis no topo." showAvailableReactionsFirstInNote: "Exibir reações disponíveis no topo."
showPageTabBarBottom: "Mostrar barra de aba da página inferiormente"
_chat: _chat:
showSenderName: "Exibir nome de usuário do remetente" showSenderName: "Exibir nome de usuário do remetente"
sendOnEnter: "Pressionar Enter para enviar" sendOnEnter: "Pressionar Enter para enviar"
@ -1634,6 +1664,10 @@ _serverSettings:
fanoutTimelineDbFallback: "\"Fallback\" ao banco de dados" fanoutTimelineDbFallback: "\"Fallback\" ao banco de dados"
fanoutTimelineDbFallbackDescription: "Quando habilitado, a linha do tempo irá recuar ao banco de dados caso consultas adicionais sejam feitas e ela não estiver em cache. Quando desabilitado, o impacto no servidor será reduzido ao eliminar o recuo, mas limita a quantidade de linhas do tempo que podem ser recebidas." fanoutTimelineDbFallbackDescription: "Quando habilitado, a linha do tempo irá recuar ao banco de dados caso consultas adicionais sejam feitas e ela não estiver em cache. Quando desabilitado, o impacto no servidor será reduzido ao eliminar o recuo, mas limita a quantidade de linhas do tempo que podem ser recebidas."
reactionsBufferingDescription: "Quando ativado, o desempenho durante a criação de uma reação será melhorado substancialmente, reduzindo a carga do banco de dados. Porém, a o uso de memória do Redis irá aumentar." reactionsBufferingDescription: "Quando ativado, o desempenho durante a criação de uma reação será melhorado substancialmente, reduzindo a carga do banco de dados. Porém, a o uso de memória do Redis irá aumentar."
remoteNotesCleaning: "Limpeza automática de notas remotas"
remoteNotesCleaning_description: "Quando habilitado, notas remotas obsoletas e não utilizadas serão periodicamente limpadas para previnir sobrecarga no banco de dados."
remoteNotesCleaningMaxProcessingDuration: "Maximizar tempo de processamento da limpeza"
remoteNotesCleaningExpiryDaysForEachNotes: "Mínimo de dias para retenção de notas"
inquiryUrl: "URL de inquérito" inquiryUrl: "URL de inquérito"
inquiryUrlDescription: "Especifique um URL para um formulário de inquérito para a administração ou uma página web com informações de contato." inquiryUrlDescription: "Especifique um URL para um formulário de inquérito para a administração ou uma página web com informações de contato."
openRegistration: "Abrir a criação de contas" openRegistration: "Abrir a criação de contas"
@ -1652,6 +1686,11 @@ _serverSettings:
userGeneratedContentsVisibilityForVisitor: "Visibilidade de conteúdo dos usuários para visitantes" userGeneratedContentsVisibilityForVisitor: "Visibilidade de conteúdo dos usuários para visitantes"
userGeneratedContentsVisibilityForVisitor_description: "Isso é útil para prevenir problemas causados por conteúdo inapropriado de usuários remotos de servidores com pouca ou nenhuma moderação, que pode ser hospedado na internet a partir desse servidor." userGeneratedContentsVisibilityForVisitor_description: "Isso é útil para prevenir problemas causados por conteúdo inapropriado de usuários remotos de servidores com pouca ou nenhuma moderação, que pode ser hospedado na internet a partir desse servidor."
userGeneratedContentsVisibilityForVisitor_description2: "Publicar todo o conteúdo do servidor para a internet pode ser arriscado. Isso é especialmente importante para visitantes que desconhecem a natureza distribuída do conteúdo na internet, pois eles podem acreditar que o conteúdo remoto é criado por usuários desse servidor." userGeneratedContentsVisibilityForVisitor_description2: "Publicar todo o conteúdo do servidor para a internet pode ser arriscado. Isso é especialmente importante para visitantes que desconhecem a natureza distribuída do conteúdo na internet, pois eles podem acreditar que o conteúdo remoto é criado por usuários desse servidor."
restartServerSetupWizardConfirm_title: "Reiniciar o assistente de configuração?"
restartServerSetupWizardConfirm_text: "Algumas configurações atuais serão reiniciadas."
entrancePageStyle: "Estilo da página de entrada"
showTimelineForVisitor: "Mostrar linha do tempo"
showActivitiesForVisitor: "Mostrar atividades"
_userGeneratedContentsVisibilityForVisitor: _userGeneratedContentsVisibilityForVisitor:
all: "Tudo é público" all: "Tudo é público"
localOnly: "Conteúdo local é publicado, conteúdo remoto é privado" localOnly: "Conteúdo local é publicado, conteúdo remoto é privado"
@ -1988,6 +2027,7 @@ _role:
descriptionOfRateLimitFactor: "Valores menores são menos restritivos, valores maiores são mais restritivos." descriptionOfRateLimitFactor: "Valores menores são menos restritivos, valores maiores são mais restritivos."
canHideAds: "Permitir ocultar anúncios" canHideAds: "Permitir ocultar anúncios"
canSearchNotes: "Permitir a busca de notas" canSearchNotes: "Permitir a busca de notas"
canSearchUsers: "Busca de usuário"
canUseTranslator: "Uso do tradutor" canUseTranslator: "Uso do tradutor"
avatarDecorationLimit: "Número máximo de decorações de avatar que podem ser aplicadas" avatarDecorationLimit: "Número máximo de decorações de avatar que podem ser aplicadas"
canImportAntennas: "Permitir importação de antenas" canImportAntennas: "Permitir importação de antenas"
@ -2000,6 +2040,7 @@ _role:
uploadableFileTypes_caption: "Especifica tipos MIME permitidos. Múltiplos tipos MIME podem ser especificados separando-os por linha. Curingas podem ser especificados com um asterisco (*). (exemplo, image/*)" uploadableFileTypes_caption: "Especifica tipos MIME permitidos. Múltiplos tipos MIME podem ser especificados separando-os por linha. Curingas podem ser especificados com um asterisco (*). (exemplo, image/*)"
uploadableFileTypes_caption2: "Alguns tipos de arquivos podem não ser detectados. Para permiti-los, adicione {x} à especificação." uploadableFileTypes_caption2: "Alguns tipos de arquivos podem não ser detectados. Para permiti-los, adicione {x} à especificação."
noteDraftLimit: "Limite de rascunhos possíveis" noteDraftLimit: "Limite de rascunhos possíveis"
scheduledNoteLimit: "Número máximo de notas agendadas simultâneas"
watermarkAvailable: "Disponibilidade da função de marca d'água" watermarkAvailable: "Disponibilidade da função de marca d'água"
_condition: _condition:
roleAssignedTo: "Atribuído a cargos manuais" roleAssignedTo: "Atribuído a cargos manuais"
@ -2260,6 +2301,7 @@ _time:
minute: "Minuto(s)" minute: "Minuto(s)"
hour: "Hora(s)" hour: "Hora(s)"
day: "Dia(s)" day: "Dia(s)"
month: "Mês(es)"
_2fa: _2fa:
alreadyRegistered: "Você já cadastrou um dispositivo de autenticação de dois fatores." alreadyRegistered: "Você já cadastrou um dispositivo de autenticação de dois fatores."
registerTOTP: "Cadastrar aplicativo autenticador" registerTOTP: "Cadastrar aplicativo autenticador"
@ -2434,7 +2476,7 @@ _widgets:
chooseList: "Selecione uma lista" chooseList: "Selecione uma lista"
clicker: "Clicker" clicker: "Clicker"
birthdayFollowings: "Usuários de aniversário hoje" birthdayFollowings: "Usuários de aniversário hoje"
chat: "Conversas" chat: "Conversar com usuário"
_cw: _cw:
hide: "Esconder" hide: "Esconder"
show: "Carregar mais" show: "Carregar mais"
@ -2624,6 +2666,8 @@ _notification:
youReceivedFollowRequest: "Você recebeu um pedido de seguidor" youReceivedFollowRequest: "Você recebeu um pedido de seguidor"
yourFollowRequestAccepted: "Seu pedido de seguidor foi aceito" yourFollowRequestAccepted: "Seu pedido de seguidor foi aceito"
pollEnded: "Os resultados da enquete agora estão disponíveis" pollEnded: "Os resultados da enquete agora estão disponíveis"
scheduledNotePosted: "Nota agendada foi publicada"
scheduledNotePostFailed: "Não foi possível publicar nota agendada"
newNote: "Nova nota" newNote: "Nova nota"
unreadAntennaNote: "Antena {name}" unreadAntennaNote: "Antena {name}"
roleAssigned: "Cargo dado" roleAssigned: "Cargo dado"
@ -2703,7 +2747,7 @@ _deck:
mentions: "Menções" mentions: "Menções"
direct: "Notas diretas" direct: "Notas diretas"
roleTimeline: "Linha do tempo do cargo" roleTimeline: "Linha do tempo do cargo"
chat: "Conversas" chat: "Conversar com usuário"
_dialog: _dialog:
charactersExceeded: "Você excedeu o limite de caracteres! Atualmente em {current} de {max}." charactersExceeded: "Você excedeu o limite de caracteres! Atualmente em {current} de {max}."
charactersBelow: "Você está abaixo do limite mínimo de caracteres! Atualmente em {current} of {min}." charactersBelow: "Você está abaixo do limite mínimo de caracteres! Atualmente em {current} of {min}."
@ -3062,6 +3106,7 @@ _bootErrors:
otherOption1: "Excluir ajustes de cliente e cache" otherOption1: "Excluir ajustes de cliente e cache"
otherOption2: "Iniciar o cliente simples" otherOption2: "Iniciar o cliente simples"
otherOption3: "Iniciar ferramenta de reparo" otherOption3: "Iniciar ferramenta de reparo"
otherOption4: "Abrir Misskey no modo seguro"
_search: _search:
searchScopeAll: "Todos" searchScopeAll: "Todos"
searchScopeLocal: "Local" searchScopeLocal: "Local"
@ -3098,6 +3143,8 @@ _serverSetupWizard:
doYouConnectToFediverse_description1: "Quando conectado com uma rede distribuída de servidores (Fediverso), o conteúdo pode ser trocado com outros servidores." doYouConnectToFediverse_description1: "Quando conectado com uma rede distribuída de servidores (Fediverso), o conteúdo pode ser trocado com outros servidores."
doYouConnectToFediverse_description2: "Conectar com o Fediverso também é chamado de \"federação\"" doYouConnectToFediverse_description2: "Conectar com o Fediverso também é chamado de \"federação\""
youCanConfigureMoreFederationSettingsLater: "Configurações adicionais como especificar servidores para conectar-se com podem ser feitas posteriormente" youCanConfigureMoreFederationSettingsLater: "Configurações adicionais como especificar servidores para conectar-se com podem ser feitas posteriormente"
remoteContentsCleaning: "Limpeza automática de conteúdos recebidos"
remoteContentsCleaning_description: "A federação pode resultar em uma entrada contínua de conteúdo. Habilitar a limpeza automática removerá conteúdo obsoleto e não referenciado do servidor para economizar armazenamento."
adminInfo: "Informações da administração" adminInfo: "Informações da administração"
adminInfo_description: "Define as informações do administrador usadas para receber consultas." adminInfo_description: "Define as informações do administrador usadas para receber consultas."
adminInfo_mustBeFilled: "Deve ser preenchido se o servidor é público ou se a federação está ativa." adminInfo_mustBeFilled: "Deve ser preenchido se o servidor é público ou se a federação está ativa."
@ -3146,14 +3193,16 @@ _watermarkEditor:
opacity: "Opacidade" opacity: "Opacidade"
scale: "Tamanho" scale: "Tamanho"
text: "Texto" text: "Texto"
qr: "Código QR"
position: "Posição" position: "Posição"
margin: "Margem"
type: "Tipo" type: "Tipo"
image: "imagem" image: "imagem"
advanced: "Avançado" advanced: "Avançado"
angle: "Ângulo"
stripe: "Listras" stripe: "Listras"
stripeWidth: "Largura da linha" stripeWidth: "Largura da linha"
stripeFrequency: "Número de linhas" stripeFrequency: "Número de linhas"
angle: "Ângulo"
polkadot: "Bolinhas" polkadot: "Bolinhas"
checker: "Xadrez" checker: "Xadrez"
polkadotMainDotOpacity: "Opacidade da bolinha principal" polkadotMainDotOpacity: "Opacidade da bolinha principal"
@ -3161,16 +3210,20 @@ _watermarkEditor:
polkadotSubDotOpacity: "Opacidade da bolinha secundária" polkadotSubDotOpacity: "Opacidade da bolinha secundária"
polkadotSubDotRadius: "Raio das bolinhas adicionais" polkadotSubDotRadius: "Raio das bolinhas adicionais"
polkadotSubDotDivisions: "Número de bolinhas adicionais" polkadotSubDotDivisions: "Número de bolinhas adicionais"
leaveBlankToAccountUrl: "Deixe em branco para utilizar URL da conta"
_imageEffector: _imageEffector:
title: "Efeitos" title: "Efeitos"
addEffect: "Adicionar efeitos" addEffect: "Adicionar efeitos"
discardChangesConfirm: "Tem certeza que deseja sair? Há mudanças não salvas." discardChangesConfirm: "Tem certeza que deseja sair? Há mudanças não salvas."
nothingToConfigure: "Não há nada para configurar"
_fxs: _fxs:
chromaticAberration: "Aberração cromática" chromaticAberration: "Aberração cromática"
glitch: "Glitch" glitch: "Glitch"
mirror: "Espelho" mirror: "Espelho"
invert: "Inverter Cores" invert: "Inverter Cores"
grayscale: "Tons de Cinza" grayscale: "Tons de Cinza"
blur: "Desfoque"
pixelate: "Pixelizar"
colorAdjust: "Correção de Cores" colorAdjust: "Correção de Cores"
colorClamp: "Compressão de Cores" colorClamp: "Compressão de Cores"
colorClampAdvanced: "Compressão Avançada de Cores" colorClampAdvanced: "Compressão Avançada de Cores"
@ -3182,6 +3235,43 @@ _imageEffector:
checker: "Xadrez" checker: "Xadrez"
blockNoise: "Bloquear Ruído" blockNoise: "Bloquear Ruído"
tearing: "Descontinuidade" tearing: "Descontinuidade"
fill: "Preencher"
_fxProps:
angle: "Ângulo"
scale: "Tamanho"
size: "Tamanho"
radius: "Raio"
samples: "Número de amostras"
offset: "Posição"
color: "Cor"
opacity: "Opacidade"
normalize: "Normalizar"
amount: "Quantidade"
lightness: "Esclarecer"
contrast: "Contraste"
hue: "Matiz"
brightness: "Brilho"
saturation: "Saturação"
max: "Máximo"
min: "Mínimo"
direction: "Direção"
phase: "Fase"
frequency: "Frequência"
strength: "Força"
glitchChannelShift: "Mudança de canal"
seed: "Valor da semente"
redComponent: "Componente vermelho"
greenComponent: "Componente verde"
blueComponent: "Componente azul"
threshold: "Limiar"
centerX: "Centralizar X"
centerY: "Centralizar Y"
zoomLinesSmoothing: "Suavização"
zoomLinesSmoothingDescription: "Suavização e largura das linhas de zoom não podem ser utilizados simultaneamente."
zoomLinesThreshold: "Largura das linhas de zoom"
zoomLinesMaskSize: "Diâmetro do centro"
zoomLinesBlack: "Linhas pretas"
circle: "Circular"
drafts: "Rascunhos" drafts: "Rascunhos"
_drafts: _drafts:
select: "Selecionar Rascunho" select: "Selecionar Rascunho"
@ -3197,3 +3287,22 @@ _drafts:
restoreFromDraft: "Restaurar de Rascunho" restoreFromDraft: "Restaurar de Rascunho"
restore: "Redefinir" restore: "Redefinir"
listDrafts: "Lista de Rascunhos" listDrafts: "Lista de Rascunhos"
schedule: "Agendar nota"
listScheduledNotes: "Lista de notas agendadas"
cancelSchedule: "Cancelar agendamento"
qr: "Código QR"
_qr:
showTabTitle: "Visualizar"
readTabTitle: "Escanear"
shareTitle: "{name} {acct}"
shareText: "Siga-me no Fediverso!"
chooseCamera: "Escolher câmera"
cannotToggleFlash: "Não foi possível ligar a lanterna"
turnOnFlash: "Ligar a lanterna"
turnOffFlash: "Desligar a lanterna"
startQr: "Retornar ao leitor de códigos QR"
stopQr: "Deixar o leitor de códigos QR"
noQrCodeFound: "Nenhum código QR encontrado"
scanFile: "Escanear imagem de dispositivo"
raw: "Texto"
mfm: "MFM"

View File

@ -1400,3 +1400,11 @@ _watermarkEditor:
type: "Tip" type: "Tip"
image: "Imagini" image: "Imagini"
advanced: "Avansat" advanced: "Avansat"
_imageEffector:
_fxProps:
scale: "Dimensiune"
size: "Dimensiune"
offset: "Poziție"
_qr:
showTabTitle: "Arată"
raw: "Text"

View File

@ -1215,12 +1215,12 @@ privacyPolicyUrl: "Ссылка на Политику Конфиденциаль
tosAndPrivacyPolicy: "Условия использования и политика конфиденциальности" tosAndPrivacyPolicy: "Условия использования и политика конфиденциальности"
avatarDecorations: "Украшения для аватара" avatarDecorations: "Украшения для аватара"
attach: "Прикрепить" attach: "Прикрепить"
detachAll: "Убрать всё"
angle: "Угол" angle: "Угол"
flip: "Переворот" flip: "Переворот"
showAvatarDecorations: "Показать украшения для аватара" showAvatarDecorations: "Показать украшения для аватара"
pullDownToRefresh: "Опустите что бы обновить" pullDownToRefresh: "Опустите что бы обновить"
useGroupedNotifications: "Отображать уведомления сгруппировано" useGroupedNotifications: "Отображать уведомления сгруппировано"
signupPendingError: "Возникла проблема с подтверждением вашего адреса электронной почты. Возможно, срок действия ссылки истёк."
cwNotationRequired: "Если включена опция «Скрыть содержимое», необходимо написать аннотацию." cwNotationRequired: "Если включена опция «Скрыть содержимое», необходимо написать аннотацию."
doReaction: "Добавить реакцию" doReaction: "Добавить реакцию"
code: "Код" code: "Код"
@ -1254,7 +1254,7 @@ clipNoteLimitExceeded: "К этому клипу больше нельзя до
performance: "Производительность" performance: "Производительность"
modified: "Изменено" modified: "Изменено"
signinWithPasskey: "Войдите в систему, используя свой пароль" signinWithPasskey: "Войдите в систему, используя свой пароль"
unknownWebAuthnKey: "Не известный ключ " unknownWebAuthnKey: "Неизвестный ключ"
passkeyVerificationFailed: "Ошибка проверка ключа доступа " passkeyVerificationFailed: "Ошибка проверка ключа доступа "
messageToFollower: "Сообщение подписчикам" messageToFollower: "Сообщение подписчикам"
testCaptchaWarning: "Эта функция предназначена для тестирования CAPTCHA. <strong>Не использовать это в рабочей среде</strong>" testCaptchaWarning: "Эта функция предназначена для тестирования CAPTCHA. <strong>Не использовать это в рабочей среде</strong>"
@ -1269,8 +1269,11 @@ availableRoles: "Доступные роли"
federationDisabled: "Федерация отключена для этого сервера. Вы не можете взаимодействовать с пользователями на других серверах." federationDisabled: "Федерация отключена для этого сервера. Вы не можете взаимодействовать с пользователями на других серверах."
draft: "Черновик" draft: "Черновик"
markAsSensitiveConfirm: "Отметить контент как чувствительный?" markAsSensitiveConfirm: "Отметить контент как чувствительный?"
preferences: "Основное"
resetToDefaultValue: "Сбросить настройки до стандартных" resetToDefaultValue: "Сбросить настройки до стандартных"
syncBetweenDevices: "Синхронизировать между устройствами"
postForm: "Форма отправки" postForm: "Форма отправки"
textCount: "Количество символов"
information: "Описание" information: "Описание"
inMinutes: "мин" inMinutes: "мин"
inDays: "сут" inDays: "сут"
@ -1282,6 +1285,11 @@ _chat:
send: "Отправить" send: "Отправить"
_settings: _settings:
webhook: "Вебхук" webhook: "Вебхук"
preferencesBanner: "Вы можете настроить общее поведение клиента по вашим предпочтениям"
timelineAndNote: "Лента и заметки"
_chat:
showSenderName: "Показывать имя отправителя"
sendOnEnter: "Использовать Enter для отправки"
_delivery: _delivery:
stop: "Заморожено" stop: "Заморожено"
_type: _type:
@ -1530,7 +1538,7 @@ _achievements:
description: "Нажато здесь" description: "Нажато здесь"
_justPlainLucky: _justPlainLucky:
title: "Чистая удача" title: "Чистая удача"
description: "Может достаться с вероятностью 0,01% каждые 10 секунд." description: "Может достаться с вероятностью 0,005% каждые 10 секунд."
_setNameToSyuilo: _setNameToSyuilo:
title: "Комплекс бога" title: "Комплекс бога"
description: "Установлено «syuilo» в качестве имени" description: "Установлено «syuilo» в качестве имени"
@ -1558,6 +1566,12 @@ _achievements:
title: "Brain Diver" title: "Brain Diver"
description: "Опубликована ссылка на песню «Brain Diver»" description: "Опубликована ссылка на песню «Brain Diver»"
flavor: "Мисски-Мисски Ла-Ту-Ма" flavor: "Мисски-Мисски Ла-Ту-Ма"
_bubbleGameExplodingHead:
title: "🤯"
description: "Самый большой объект в Bubble game"
_bubbleGameDoubleExplodingHead:
title: "Двойной🤯"
description: "Два самых больших объекта в Bubble game одновременно!"
_role: _role:
new: "Новая роль" new: "Новая роль"
edit: "Изменить роль" edit: "Изменить роль"
@ -2257,4 +2271,16 @@ _watermarkEditor:
image: "Изображения" image: "Изображения"
advanced: "Для продвинутых" advanced: "Для продвинутых"
angle: "Угол" angle: "Угол"
_imageEffector:
_fxProps:
angle: "Угол"
scale: "Размер"
size: "Размер"
offset: "Позиция"
color: "Цвет"
opacity: "Непрозрачность"
lightness: "Осветление"
drafts: "Черновик" drafts: "Черновик"
_qr:
showTabTitle: "Отображение"
raw: "Текст"

View File

@ -1459,3 +1459,13 @@ _watermarkEditor:
type: "Typ" type: "Typ"
image: "Obrázky" image: "Obrázky"
advanced: "Rozšírené" advanced: "Rozšírené"
_imageEffector:
_fxProps:
scale: "Veľkosť"
size: "Veľkosť"
color: "Farba"
opacity: "Priehľadnosť"
lightness: "Zosvetliť"
_qr:
showTabTitle: "Zobraziť"
raw: "Text"

View File

@ -716,3 +716,8 @@ _search:
_watermarkEditor: _watermarkEditor:
scale: "Storlek" scale: "Storlek"
image: "Bilder" image: "Bilder"
_imageEffector:
_fxProps:
scale: "Storlek"
size: "Storlek"
color: "Färg"

View File

@ -253,6 +253,7 @@ noteDeleteConfirm: "ต้องการลบโน้ตนี้ใช่ไ
pinLimitExceeded: "คุณไม่สามารถปักหมุดโน้ตเพิ่มเติมใดๆได้อีก" pinLimitExceeded: "คุณไม่สามารถปักหมุดโน้ตเพิ่มเติมใดๆได้อีก"
done: "เสร็จสิ้น" done: "เสร็จสิ้น"
processing: "กำลังประมวลผล..." processing: "กำลังประมวลผล..."
preprocessing: "กำลังจัดเตรียม..."
preview: "แสดงตัวอย่าง" preview: "แสดงตัวอย่าง"
default: "ค่าเริ่มต้น" default: "ค่าเริ่มต้น"
defaultValueIs: "ค่าเริ่มต้น: {value}" defaultValueIs: "ค่าเริ่มต้น: {value}"
@ -1054,6 +1055,7 @@ permissionDeniedError: "การดำเนินถูกปฏิเสธ"
permissionDeniedErrorDescription: "บัญชีนี้ไม่มีสิทธิ์อนุญาตในการดำเนินการนี้" permissionDeniedErrorDescription: "บัญชีนี้ไม่มีสิทธิ์อนุญาตในการดำเนินการนี้"
preset: "พรีเซ็ต" preset: "พรีเซ็ต"
selectFromPresets: "เลือกจากการพรีเซ็ต" selectFromPresets: "เลือกจากการพรีเซ็ต"
custom: "แบบกำหนดเอง"
achievements: "ความสำเร็จ" achievements: "ความสำเร็จ"
gotInvalidResponseError: "การตอบสนองเซิร์ฟเวอร์ไม่ถูกต้อง" gotInvalidResponseError: "การตอบสนองเซิร์ฟเวอร์ไม่ถูกต้อง"
gotInvalidResponseErrorDescription: "เซิร์ฟเวอร์อาจไม่สามารถเข้าถึงได้หรืออาจจะกำลังอยู่ในระหว่างปรับปรุง กรุณาลองใหม่อีกครั้งในภายหลังนะคะ" gotInvalidResponseErrorDescription: "เซิร์ฟเวอร์อาจไม่สามารถเข้าถึงได้หรืออาจจะกำลังอยู่ในระหว่างปรับปรุง กรุณาลองใหม่อีกครั้งในภายหลังนะคะ"
@ -1092,6 +1094,7 @@ prohibitedWordsDescription2: "ถ้าแยกด้วยเว้นวร
hiddenTags: "แฮชแท็กที่ซ่อนอยู่" hiddenTags: "แฮชแท็กที่ซ่อนอยู่"
hiddenTagsDescription: "เลือกแท็กที่จะไม่แสดงในรายการเทรนด์ สามารถลงทะเบียนหลายแท็กได้โดยขึ้นบรรทัดใหม่" hiddenTagsDescription: "เลือกแท็กที่จะไม่แสดงในรายการเทรนด์ สามารถลงทะเบียนหลายแท็กได้โดยขึ้นบรรทัดใหม่"
notesSearchNotAvailable: "การค้นหาโน้ตไม่พร้อมใช้งาน" notesSearchNotAvailable: "การค้นหาโน้ตไม่พร้อมใช้งาน"
usersSearchNotAvailable: "การค้นหาผู้ใช้ไม่พร้อมใช้งาน"
license: "ใบอนุญาต" license: "ใบอนุญาต"
unfavoriteConfirm: "ลบออกจากรายการโปรดแน่ใจหรอ?" unfavoriteConfirm: "ลบออกจากรายการโปรดแน่ใจหรอ?"
myClips: "คลิปของฉัน" myClips: "คลิปของฉัน"
@ -1243,7 +1246,7 @@ releaseToRefresh: "ปล่อยเพื่อรีเฟรช"
refreshing: "กำลังรีเฟรช..." refreshing: "กำลังรีเฟรช..."
pullDownToRefresh: "ดึงลงเพื่อรีเฟรช" pullDownToRefresh: "ดึงลงเพื่อรีเฟรช"
useGroupedNotifications: "แสดงผลการแจ้งเตือนแบบกลุ่มแล้ว" useGroupedNotifications: "แสดงผลการแจ้งเตือนแบบกลุ่มแล้ว"
signupPendingError: "มีปัญหาในการตรวจสอบที่อยู่อีเมลลิงก์อาจหมดอายุแล้ว" emailVerificationFailedError: "เกิดปัญหาในขณะตรวจสอบอีเมล อาจเป็นไปได้ว่าลิงก์หมดอายุแล้ว"
cwNotationRequired: "หากเปิดใช้งาน “ซ่อนเนื้อหา” จะต้องระบุคำอธิบาย" cwNotationRequired: "หากเปิดใช้งาน “ซ่อนเนื้อหา” จะต้องระบุคำอธิบาย"
doReaction: "เพิ่มรีแอคชั่น" doReaction: "เพิ่มรีแอคชั่น"
code: "โค้ด" code: "โค้ด"
@ -1314,6 +1317,7 @@ acknowledgeNotesAndEnable: "เปิดใช้งานหลังจาก
federationSpecified: "เซิร์ฟเวอร์นี้ดำเนินงานในระบบกลุ่มไวท์ลิสต์ ไม่สามารถติดต่อกับเซิร์ฟเวอร์อื่นที่ไม่ได้รับอนุญาตจากผู้ดูแลระบบได้" federationSpecified: "เซิร์ฟเวอร์นี้ดำเนินงานในระบบกลุ่มไวท์ลิสต์ ไม่สามารถติดต่อกับเซิร์ฟเวอร์อื่นที่ไม่ได้รับอนุญาตจากผู้ดูแลระบบได้"
federationDisabled: "เซิร์ฟเวอร์นี้ปิดใช้งานสหพันธ์ ไม่สามารถติดต่อหรือแลกเปลี่ยนข้อมูลกับผู้ใช้จากเซิร์ฟเวอร์อื่นได้" federationDisabled: "เซิร์ฟเวอร์นี้ปิดใช้งานสหพันธ์ ไม่สามารถติดต่อหรือแลกเปลี่ยนข้อมูลกับผู้ใช้จากเซิร์ฟเวอร์อื่นได้"
draft: "ร่าง" draft: "ร่าง"
draftsAndScheduledNotes: "ร่างและกำหนดเวลาโพสต์"
confirmOnReact: "ยืนยันเมื่อทำการรีแอคชั่น" confirmOnReact: "ยืนยันเมื่อทำการรีแอคชั่น"
reactAreYouSure: "ต้องการใส่รีแอคชั่นด้วย \"{emoji}\" หรือไม่?" reactAreYouSure: "ต้องการใส่รีแอคชั่นด้วย \"{emoji}\" หรือไม่?"
markAsSensitiveConfirm: "ต้องการตั้งค่าสื่อนี้ว่าเป็นเนื้อหาละเอียดอ่อนหรือไม่?" markAsSensitiveConfirm: "ต้องการตั้งค่าสื่อนี้ว่าเป็นเนื้อหาละเอียดอ่อนหรือไม่?"
@ -1341,6 +1345,8 @@ postForm: "แบบฟอร์มการโพสต์"
textCount: "จำนวนอักขระ" textCount: "จำนวนอักขระ"
information: "เกี่ยวกับ" information: "เกี่ยวกับ"
chat: "แชต" chat: "แชต"
directMessage: "แชตเลย"
directMessage_short: "ข้อความ"
migrateOldSettings: "ย้ายข้อมูลการตั้งค่าเก่า" migrateOldSettings: "ย้ายข้อมูลการตั้งค่าเก่า"
migrateOldSettings_description: "โดยปกติจะทำโดยอัตโนมัติ แต่หากด้วยเหตุผลบางประการที่ไม่สามารถย้ายได้สำเร็จ สามารถสั่งย้ายด้วยตนเองได้ การตั้งค่าปัจจุบันจะถูกเขียนทับ" migrateOldSettings_description: "โดยปกติจะทำโดยอัตโนมัติ แต่หากด้วยเหตุผลบางประการที่ไม่สามารถย้ายได้สำเร็จ สามารถสั่งย้ายด้วยตนเองได้ การตั้งค่าปัจจุบันจะถูกเขียนทับ"
compress: "บีบอัด" compress: "บีบอัด"
@ -1366,14 +1372,37 @@ abort: "หยุดและยกเลิก"
tip: "คำแนะนำและเคล็ดลับ" tip: "คำแนะนำและเคล็ดลับ"
redisplayAllTips: "แสดงคำแนะนำและเคล็ดลับทั้งหมดอีกครั้ง" redisplayAllTips: "แสดงคำแนะนำและเคล็ดลับทั้งหมดอีกครั้ง"
hideAllTips: "ซ่อนคำแนะนำและเคล็ดลับทั้งหมด" hideAllTips: "ซ่อนคำแนะนำและเคล็ดลับทั้งหมด"
defaultImageCompressionLevel: "ความละเอียดเริ่มต้นสำหรับการบีบอัดภาพ" defaultImageCompressionLevel: "ค่าการบีบอัดภาพเริ่มต้น"
defaultImageCompressionLevel_description: "หากตั้งค่าต่ำ จะรักษาคุณภาพภาพได้ดีขึ้นแต่ขนาดไฟล์จะเพิ่มขึ้น<br>หากตั้งค่าสูง จะลดขนาดไฟล์ได้ แต่คุณภาพภาพจะลดลง" defaultImageCompressionLevel_description: "หากตั้งค่าต่ำ จะรักษาคุณภาพภาพได้ดีขึ้นแต่ขนาดไฟล์จะเพิ่มขึ้น<br>หากตั้งค่าสูง จะลดขนาดไฟล์ได้ แต่คุณภาพภาพจะลดลง"
defaultCompressionLevel: "ค่าการบีบอัดเริ่มต้น"
defaultCompressionLevel_description: "ถ้าต่ำ จะรักษาคุณภาพได้ แต่ขนาดไฟล์จะเพิ่มขึ้น<br>ถ้าสูง จะลดขนาดไฟล์ได้ แต่คุณภาพจะลดลง"
inMinutes: "นาที" inMinutes: "นาที"
inDays: "วัน" inDays: "วัน"
safeModeEnabled: "โหมดปลอดภัยถูกเปิดใช้งาน"
pluginsAreDisabledBecauseSafeMode: "เนื่องจากโหมดปลอดภัยถูกเปิดใช้งาน ปลั๊กอินทั้งหมดจึงถูกปิดใช้งาน"
customCssIsDisabledBecauseSafeMode: "เนื่องจากโหมดปลอดภัยถูกเปิดใช้งาน CSS แบบกำหนดเองจึงไม่ได้ถูกนำมาใช้"
themeIsDefaultBecauseSafeMode: "ในระหว่างที่โหมดปลอดภัยถูกเปิดใช้งาน จะใช้ธีมเริ่มต้น เมื่อปิดโหมดปลอดภัยจะกลับคืนดังเดิม"
thankYouForTestingBeta: "ขอบคุณที่ให้ความร่วมมือในการทดสอบเวอร์ชันเบต้า!"
createUserSpecifiedNote: "สร้างโน้ตแบบไดเร็กต์"
schedulePost: "กำหนดเวลาให้โพสต์"
scheduleToPostOnX: "กำหนดเวลาให้โพสต์ไว้ที่ {x}"
scheduledToPostOnX: "มีการกำหนดเวลาให้โพสต์ไว้ที่ {x}"
schedule: "กำหนดเวลา"
scheduled: "กำหนดเวลา"
_compression:
_quality:
high: "คุณภาพสูง"
medium: "คุณภาพปานกลาง"
low: "คุณภาพต่ำ"
_size:
large: "ขนาดใหญ่"
medium: "ขนาดปานกลาง"
small: "ขนาดเล็ก"
_order: _order:
newest: "เรียงจากใหม่ไปเก่า" newest: "เรียงจากใหม่ไปเก่า"
oldest: "เรียงจากเก่าไปใหม่" oldest: "เรียงจากเก่าไปใหม่"
_chat: _chat:
messages: "ข้อความ"
noMessagesYet: "ยังไม่มีข้อความ" noMessagesYet: "ยังไม่มีข้อความ"
newMessage: "ข้อความใหม่" newMessage: "ข้อความใหม่"
individualChat: "แชตส่วนตัว" individualChat: "แชตส่วนตัว"
@ -1659,6 +1688,9 @@ _serverSettings:
userGeneratedContentsVisibilityForVisitor_description2: "การเปิดเผยเนื้อหาทั้งหมดในเซิร์ฟเวอร์รวมทั้งเนื้อหาที่รับมาจากระยะไกลสู่สาธารณะบนอินเทอร์เน็ตโดยไม่มีข้อจำกัดใดๆ มีความเสี่ยงโดยเฉพาะอย่างยิ่งสำหรับผู้ชมที่ไม่เข้าใจลักษณะของระบบแบบกระจาย อาจทำให้เกิดความเข้าใจผิดคิดว่าเนื้อหาที่มาจากระยะไกลนั้นเป็นเนื้อหาที่สร้างขึ้นภายในเซิร์ฟเวอร์นี้ จึงควรใช้ความระมัดระวังอย่างมาก" userGeneratedContentsVisibilityForVisitor_description2: "การเปิดเผยเนื้อหาทั้งหมดในเซิร์ฟเวอร์รวมทั้งเนื้อหาที่รับมาจากระยะไกลสู่สาธารณะบนอินเทอร์เน็ตโดยไม่มีข้อจำกัดใดๆ มีความเสี่ยงโดยเฉพาะอย่างยิ่งสำหรับผู้ชมที่ไม่เข้าใจลักษณะของระบบแบบกระจาย อาจทำให้เกิดความเข้าใจผิดคิดว่าเนื้อหาที่มาจากระยะไกลนั้นเป็นเนื้อหาที่สร้างขึ้นภายในเซิร์ฟเวอร์นี้ จึงควรใช้ความระมัดระวังอย่างมาก"
restartServerSetupWizardConfirm_title: "ต้องการเริ่มวิซาร์ดการตั้งค่าเซิร์ฟเวอร์ใหม่หรือไม่?" restartServerSetupWizardConfirm_title: "ต้องการเริ่มวิซาร์ดการตั้งค่าเซิร์ฟเวอร์ใหม่หรือไม่?"
restartServerSetupWizardConfirm_text: "การตั้งค่าบางส่วนในปัจจุบันจะถูกรีเซ็ต" restartServerSetupWizardConfirm_text: "การตั้งค่าบางส่วนในปัจจุบันจะถูกรีเซ็ต"
entrancePageStyle: "สไตล์ของหน้าเพจทางเข้า"
showTimelineForVisitor: "แสดงไทม์ไลน์"
showActivitiesForVisitor: "แสดงกิจกรรม"
_userGeneratedContentsVisibilityForVisitor: _userGeneratedContentsVisibilityForVisitor:
all: "ทั้งหมดสาธารณะ" all: "ทั้งหมดสาธารณะ"
localOnly: "เผยแพร่เป็นสาธารณะเฉพาะเนื้อหาท้องถิ่น เนื้อหาระยะไกลให้เป็นส่วนตัว" localOnly: "เผยแพร่เป็นสาธารณะเฉพาะเนื้อหาท้องถิ่น เนื้อหาระยะไกลให้เป็นส่วนตัว"
@ -1995,6 +2027,7 @@ _role:
descriptionOfRateLimitFactor: "ยิ่งตัวเลขน้อยก็ยิ่งจำกัดน้อย ยิ่งมากก็ยิ่งเข้มงวดมากขึ้น" descriptionOfRateLimitFactor: "ยิ่งตัวเลขน้อยก็ยิ่งจำกัดน้อย ยิ่งมากก็ยิ่งเข้มงวดมากขึ้น"
canHideAds: "ซ่อนโฆษณา" canHideAds: "ซ่อนโฆษณา"
canSearchNotes: "การใช้การค้นหาโน้ต" canSearchNotes: "การใช้การค้นหาโน้ต"
canSearchUsers: "ค้นหาผู้ใช้"
canUseTranslator: "การใช้งานแปล" canUseTranslator: "การใช้งานแปล"
avatarDecorationLimit: "จำนวนของตกแต่งไอคอนสูงสุดที่สามารถติดตั้งได้" avatarDecorationLimit: "จำนวนของตกแต่งไอคอนสูงสุดที่สามารถติดตั้งได้"
canImportAntennas: "อนุญาตให้นำเข้าเสาอากาศ" canImportAntennas: "อนุญาตให้นำเข้าเสาอากาศ"
@ -2007,6 +2040,7 @@ _role:
uploadableFileTypes_caption: "สามารถระบุ MIME type ได้ โดยใช้การขึ้นบรรทัดใหม่เพื่อแยกหลายรายการ และสามารถใช้ดอกจัน (*) เพื่อระบุแบบไวลด์การ์ดได้ (เช่น: image/*)" uploadableFileTypes_caption: "สามารถระบุ MIME type ได้ โดยใช้การขึ้นบรรทัดใหม่เพื่อแยกหลายรายการ และสามารถใช้ดอกจัน (*) เพื่อระบุแบบไวลด์การ์ดได้ (เช่น: image/*)"
uploadableFileTypes_caption2: "ไฟล์บางประเภทอาจไม่สามารถระบุชนิดได้ หากต้องการอนุญาตไฟล์ลักษณะนั้น กรุณาเพิ่ม {x} ลงในรายการที่อนุญาต" uploadableFileTypes_caption2: "ไฟล์บางประเภทอาจไม่สามารถระบุชนิดได้ หากต้องการอนุญาตไฟล์ลักษณะนั้น กรุณาเพิ่ม {x} ลงในรายการที่อนุญาต"
noteDraftLimit: "จำนวนโน้ตฉบับร่างที่สามารถสร้างได้บนฝั่งเซิร์ฟเวอร์" noteDraftLimit: "จำนวนโน้ตฉบับร่างที่สามารถสร้างได้บนฝั่งเซิร์ฟเวอร์"
scheduledNoteLimit: "จำนวนโพสต์กำหนดเวลาที่สร้างพร้อมกันได้"
watermarkAvailable: "มีฟังก์ชั่นลายน้ำให้เลือกใช้" watermarkAvailable: "มีฟังก์ชั่นลายน้ำให้เลือกใช้"
_condition: _condition:
roleAssignedTo: "มอบหมายให้มีบทบาทแบบทำมือ" roleAssignedTo: "มอบหมายให้มีบทบาทแบบทำมือ"
@ -2267,6 +2301,7 @@ _time:
minute: "นาที" minute: "นาที"
hour: "ชั่วโมง" hour: "ชั่วโมง"
day: "วัน" day: "วัน"
month: "เดือน"
_2fa: _2fa:
alreadyRegistered: "คุณได้ลงทะเบียนอุปกรณ์ยืนยันตัวตนแบบ 2 ชั้นแล้ว" alreadyRegistered: "คุณได้ลงทะเบียนอุปกรณ์ยืนยันตัวตนแบบ 2 ชั้นแล้ว"
registerTOTP: "ลงทะเบียนแอพตัวตรวจสอบสิทธิ์" registerTOTP: "ลงทะเบียนแอพตัวตรวจสอบสิทธิ์"
@ -2441,7 +2476,7 @@ _widgets:
chooseList: "เลือกรายชื่อ" chooseList: "เลือกรายชื่อ"
clicker: "คลิกเกอร์" clicker: "คลิกเกอร์"
birthdayFollowings: "วันเกิดผู้ใช้ในวันนี้" birthdayFollowings: "วันเกิดผู้ใช้ในวันนี้"
chat: "แชต" chat: "แชตเลย"
_cw: _cw:
hide: "ซ่อน" hide: "ซ่อน"
show: "โหลดเพิ่มเติม" show: "โหลดเพิ่มเติม"
@ -2631,6 +2666,8 @@ _notification:
youReceivedFollowRequest: "ได้รับคำขอติดตาม" youReceivedFollowRequest: "ได้รับคำขอติดตาม"
yourFollowRequestAccepted: "คำขอติดตามได้รับการอนุมัติแล้ว" yourFollowRequestAccepted: "คำขอติดตามได้รับการอนุมัติแล้ว"
pollEnded: "ผลโพลออกมาแล้ว" pollEnded: "ผลโพลออกมาแล้ว"
scheduledNotePosted: "โน้ตที่กำหนดเวลาไว้ได้ถูกโพสต์แล้ว"
scheduledNotePostFailed: "ล้มเหลวในการโพสต์โน้ตที่กำหนดเวลาไว้"
newNote: "โพสต์ใหม่" newNote: "โพสต์ใหม่"
unreadAntennaNote: "เสาอากาศ {name}" unreadAntennaNote: "เสาอากาศ {name}"
roleAssigned: "ได้รับบทบาท" roleAssigned: "ได้รับบทบาท"
@ -2710,7 +2747,7 @@ _deck:
mentions: "กล่าวถึงคุณ" mentions: "กล่าวถึงคุณ"
direct: "ไดเร็กต์" direct: "ไดเร็กต์"
roleTimeline: "บทบาทไทม์ไลน์" roleTimeline: "บทบาทไทม์ไลน์"
chat: "แชต" chat: "แชตเลย"
_dialog: _dialog:
charactersExceeded: "คุณกำลังมีตัวอักขระเกินขีดจำกัดสูงสุดแล้วนะ! ปัจจุบันอยู่ที่ {current} จาก {max}" charactersExceeded: "คุณกำลังมีตัวอักขระเกินขีดจำกัดสูงสุดแล้วนะ! ปัจจุบันอยู่ที่ {current} จาก {max}"
charactersBelow: "คุณกำลังใช้อักขระต่ำกว่าขีดจำกัดขั้นต่ำเลยนะ! ปัจจุบันอยู่ที่ {current} จาก {min}" charactersBelow: "คุณกำลังใช้อักขระต่ำกว่าขีดจำกัดขั้นต่ำเลยนะ! ปัจจุบันอยู่ที่ {current} จาก {min}"
@ -3069,6 +3106,7 @@ _bootErrors:
otherOption1: "ลบการตั้งค่าและแคชของไคลเอนต์" otherOption1: "ลบการตั้งค่าและแคชของไคลเอนต์"
otherOption2: "เริ่มใช้งานไคลเอนต์แบบง่าย" otherOption2: "เริ่มใช้งานไคลเอนต์แบบง่าย"
otherOption3: "เปิดเครื่องมือซ่อมแซม" otherOption3: "เปิดเครื่องมือซ่อมแซม"
otherOption4: "เริ่มทำงาน Misskey ในโหมดปลอดภัย"
_search: _search:
searchScopeAll: "ทั้งหมด" searchScopeAll: "ทั้งหมด"
searchScopeLocal: "ท้องถิ่น" searchScopeLocal: "ท้องถิ่น"
@ -3155,14 +3193,16 @@ _watermarkEditor:
opacity: "ความทึบแสง" opacity: "ความทึบแสง"
scale: "ขนาด" scale: "ขนาด"
text: "ข้อความ" text: "ข้อความ"
qr: "QR โค้ด"
position: "ตำแหน่ง" position: "ตำแหน่ง"
margin: "ระยะขอบ"
type: "รูปแบบ" type: "รูปแบบ"
image: "รูปภาพ" image: "รูปภาพ"
advanced: "ขั้นสูง" advanced: "ขั้นสูง"
angle: "แองเกิล"
stripe: "ริ้ว" stripe: "ริ้ว"
stripeWidth: "ความกว้างเส้น" stripeWidth: "ความกว้างเส้น"
stripeFrequency: "จำนวนเส้น" stripeFrequency: "จำนวนเส้น"
angle: "แองเกิล"
polkadot: "ลายจุด" polkadot: "ลายจุด"
checker: "ช่องตาราง" checker: "ช่องตาราง"
polkadotMainDotOpacity: "ความทึบของจุดหลัก" polkadotMainDotOpacity: "ความทึบของจุดหลัก"
@ -3170,16 +3210,20 @@ _watermarkEditor:
polkadotSubDotOpacity: "ความทึบของจุดรอง" polkadotSubDotOpacity: "ความทึบของจุดรอง"
polkadotSubDotRadius: "ขนาดของจุดรอง" polkadotSubDotRadius: "ขนาดของจุดรอง"
polkadotSubDotDivisions: "จำนวนจุดรอง" polkadotSubDotDivisions: "จำนวนจุดรอง"
leaveBlankToAccountUrl: "เว้นว่างไว้หากต้องการใช้ URL ของบัญชีแทน"
_imageEffector: _imageEffector:
title: "เอฟเฟกต์" title: "เอฟเฟกต์"
addEffect: "เพิ่มเอฟเฟกต์" addEffect: "เพิ่มเอฟเฟกต์"
discardChangesConfirm: "ต้องการทิ้งการเปลี่ยนแปลงแล้วออกหรือไม่?" discardChangesConfirm: "ต้องการทิ้งการเปลี่ยนแปลงแล้วออกหรือไม่?"
nothingToConfigure: "ไม่มีอะไรให้ตั้งค่า"
_fxs: _fxs:
chromaticAberration: "ความคลาดสี" chromaticAberration: "ความคลาดสี"
glitch: "กลิตช์" glitch: "กลิตช์"
mirror: "กระจก" mirror: "กระจก"
invert: "กลับสี" invert: "กลับสี"
grayscale: "ขาวดำเทา" grayscale: "ขาวดำเทา"
blur: "มัว"
pixelate: "โมเสก"
colorAdjust: "ปรับแก้สี" colorAdjust: "ปรับแก้สี"
colorClamp: "บีบอัดสี" colorClamp: "บีบอัดสี"
colorClampAdvanced: "บีบอัดสี (ขั้นสูง)" colorClampAdvanced: "บีบอัดสี (ขั้นสูง)"
@ -3191,6 +3235,43 @@ _imageEffector:
checker: "ช่องตาราง" checker: "ช่องตาราง"
blockNoise: "บล็อกที่มีการรบกวน" blockNoise: "บล็อกที่มีการรบกวน"
tearing: "ฉีกขาด" tearing: "ฉีกขาด"
fill: "เติมเต็ม"
_fxProps:
angle: "แองเกิล"
scale: "ขนาด"
size: "ขนาด"
radius: "รัศสี"
samples: "จำนวนตัวอย่าง"
offset: "ตำแหน่ง"
color: "สี"
opacity: "ความทึบแสง"
normalize: "นอร์มัลไลซ์"
amount: "จำนวน"
lightness: "สว่าง"
contrast: "คอนทราสต์"
hue: "HUE"
brightness: "ความสว่าง"
saturation: "ความอิ่มตัว"
max: "สูงสุด"
min: "ต่ำสุด"
direction: "ทิศทาง"
phase: "ระยะ"
frequency: "ความถี่"
strength: "ความแรง"
glitchChannelShift: "ความเคลื่อน"
seed: "ซีด"
redComponent: "ส่วนสีแดง"
greenComponent: "ส่วนสีเขียว"
blueComponent: "ส่วนสีน้ำเงิน"
threshold: "เทรชโฮลด์"
centerX: "กลาง X"
centerY: "กลาง Y"
zoomLinesSmoothing: "ทำให้สมูธ"
zoomLinesSmoothingDescription: "ตั้งให้สมูธไม่สามารถใช้ร่วมกับตั้งความกว้างเส้นรวมศูนย์ได้"
zoomLinesThreshold: "ความกว้างเส้นรวมศูนย์"
zoomLinesMaskSize: "ขนาดพื้นที่ตรงกลาง"
zoomLinesBlack: "ทำให้ดำ"
circle: "ทรงกลม"
drafts: "ร่าง" drafts: "ร่าง"
_drafts: _drafts:
select: "เลือกฉบับร่าง" select: "เลือกฉบับร่าง"
@ -3206,3 +3287,22 @@ _drafts:
restoreFromDraft: "คืนค่าจากฉบับร่าง" restoreFromDraft: "คืนค่าจากฉบับร่าง"
restore: "กู้คืน" restore: "กู้คืน"
listDrafts: "รายการฉบับร่าง" listDrafts: "รายการฉบับร่าง"
schedule: "โพสต์กำหนดเวลา"
listScheduledNotes: "รายการโน้ตที่กำหนดเวลาไว้"
cancelSchedule: "ยกเลิกกำหนดเวลา"
qr: "QR โค้ด"
_qr:
showTabTitle: "แสดงผล"
readTabTitle: "แสกน"
shareTitle: "{name}{acct}"
shareText: "โปรดติดตามฉันบน Fediverse ด้วย!"
chooseCamera: "เลือกกล้อง"
cannotToggleFlash: "ไม่สามารถเลือกแสงแฟลชได้"
turnOnFlash: "ปิดแสงแฟลช"
turnOffFlash: "เปิดแสงแฟลช"
startQr: "เริ่มตัวอ่าน QR โค้ด"
stopQr: "หยุดตัวอ่าน QR โค้ด"
noQrCodeFound: "ไม่พบ QR โค้ด"
scanFile: "สแกนภาพจากอุปกรณ์"
raw: "ข้อความ"
mfm: "MFM"

File diff suppressed because it is too large Load Diff

View File

@ -1648,3 +1648,13 @@ _watermarkEditor:
type: "Тип" type: "Тип"
image: "Зображення" image: "Зображення"
advanced: "Розширені" advanced: "Розширені"
_imageEffector:
_fxProps:
scale: "Розмір"
size: "Розмір"
color: "Колір"
opacity: "Непрозорість"
lightness: "Яскравість"
_qr:
showTabTitle: "Відображення"
raw: "Текст"

View File

@ -1102,3 +1102,10 @@ _watermarkEditor:
type: "turi" type: "turi"
image: "Rasmlar" image: "Rasmlar"
advanced: "Murakkab" advanced: "Murakkab"
_imageEffector:
_fxProps:
color: "Rang"
lightness: "Yoritish"
_qr:
showTabTitle: "Displey"
raw: "Matn"

View File

@ -1196,7 +1196,6 @@ showAvatarDecorations: "Hiển thị trang trí ảnh đại diện"
releaseToRefresh: "Thả để làm mới" releaseToRefresh: "Thả để làm mới"
refreshing: "Đang làm mới" refreshing: "Đang làm mới"
pullDownToRefresh: "Kéo xuống để làm mới" pullDownToRefresh: "Kéo xuống để làm mới"
signupPendingError: "Đã xảy ra sự cố khi xác minh địa chỉ email của bạn. Liên kết có thể đã hết hạn."
cwNotationRequired: "Nếu \"Ẩn nội dung\" được bật thì cần phải có chú thích." cwNotationRequired: "Nếu \"Ẩn nội dung\" được bật thì cần phải có chú thích."
decorate: "Trang trí" decorate: "Trang trí"
lastNDays: "{n} ngày trước" lastNDays: "{n} ngày trước"
@ -1817,7 +1816,6 @@ _widgets:
_userList: _userList:
chooseList: "Chọn danh sách" chooseList: "Chọn danh sách"
clicker: "clicker" clicker: "clicker"
chat: "Trò chuyện"
_cw: _cw:
hide: "Ẩn" hide: "Ẩn"
show: "Tải thêm" show: "Tải thêm"
@ -2043,7 +2041,6 @@ _deck:
channel: "Kênh" channel: "Kênh"
mentions: "Lượt nhắc" mentions: "Lượt nhắc"
direct: "Nhắn riêng" direct: "Nhắn riêng"
chat: "Trò chuyện"
_dialog: _dialog:
charactersExceeded: "Bạn nhắn quá giới hạn ký tự!! Hiện nay {current} / giới hạn {max}" charactersExceeded: "Bạn nhắn quá giới hạn ký tự!! Hiện nay {current} / giới hạn {max}"
charactersBelow: "Bạn nhắn quá ít tối thiểu ký tự!! Hiện nay {current} / Tối thiểu {min}" charactersBelow: "Bạn nhắn quá ít tối thiểu ký tự!! Hiện nay {current} / Tối thiểu {min}"
@ -2091,3 +2088,15 @@ _watermarkEditor:
image: "Hình ảnh" image: "Hình ảnh"
advanced: "Nâng cao" advanced: "Nâng cao"
angle: "Góc" angle: "Góc"
_imageEffector:
_fxProps:
angle: "Góc"
scale: "Kích thước"
size: "Kích thước"
offset: "Vị trí"
color: "Màu sắc"
opacity: "Độ trong suốt"
lightness: "Độ sáng"
_qr:
showTabTitle: "Hiển thị"
raw: "Văn bản"

View File

@ -87,7 +87,7 @@ exportRequested: "导出请求已提交,这可能需要花一些时间,导
importRequested: "导入请求已提交,这可能需要花一点时间。" importRequested: "导入请求已提交,这可能需要花一点时间。"
lists: "列表" lists: "列表"
noLists: "列表为空" noLists: "列表为空"
note: "" note: "帖"
notes: "帖子" notes: "帖子"
following: "关注中" following: "关注中"
followers: "关注者" followers: "关注者"
@ -144,15 +144,15 @@ markAsSensitive: "标记为敏感内容"
unmarkAsSensitive: "取消标记为敏感内容" unmarkAsSensitive: "取消标记为敏感内容"
enterFileName: "输入文件名" enterFileName: "输入文件名"
mute: "屏蔽" mute: "屏蔽"
unmute: "取消隐藏" unmute: "取消屏蔽"
renoteMute: "隐藏转帖" renoteMute: "屏蔽转帖"
renoteUnmute: "解除隐藏转帖" renoteUnmute: "取消屏蔽转帖"
block: "屏蔽" block: "拉黑"
unblock: "取消屏蔽" unblock: "取消拉黑"
suspend: "冻结" suspend: "冻结"
unsuspend: "解除冻结" unsuspend: "解除冻结"
blockConfirm: "确定要屏蔽吗?" blockConfirm: "确定要拉黑吗?"
unblockConfirm: "确定要取消屏蔽吗?" unblockConfirm: "确定要取消拉黑吗?"
suspendConfirm: "要冻结吗?" suspendConfirm: "要冻结吗?"
unsuspendConfirm: "要解除冻结吗?" unsuspendConfirm: "要解除冻结吗?"
selectList: "选择列表" selectList: "选择列表"
@ -244,22 +244,23 @@ mediaSilencedInstances: "已隐藏媒体文件的服务器"
mediaSilencedInstancesDescription: "设置要隐藏媒体文件的服务器,以换行分隔。被设置的服务器内所有账号的文件均按照「敏感内容」处理,且将无法使用自定义表情符号。被阻止的实例不受影响。" mediaSilencedInstancesDescription: "设置要隐藏媒体文件的服务器,以换行分隔。被设置的服务器内所有账号的文件均按照「敏感内容」处理,且将无法使用自定义表情符号。被阻止的实例不受影响。"
federationAllowedHosts: "允许联合的服务器" federationAllowedHosts: "允许联合的服务器"
federationAllowedHostsDescription: "设定允许联合的服务器,以换行分隔。" federationAllowedHostsDescription: "设定允许联合的服务器,以换行分隔。"
muteAndBlock: "隐藏和屏蔽" muteAndBlock: "屏蔽/拉黑"
mutedUsers: "已隐藏用户" mutedUsers: "已屏蔽用户"
blockedUsers: "已屏蔽的用户" blockedUsers: "已拉黑的用户"
noUsers: "无用户" noUsers: "无用户"
editProfile: "编辑资料" editProfile: "编辑资料"
noteDeleteConfirm: "确定要删除该帖子吗?" noteDeleteConfirm: "确定要删除该帖子吗?"
pinLimitExceeded: "无法置顶更多了" pinLimitExceeded: "无法置顶更多了"
done: "完成" done: "完成"
processing: "正在处理" processing: "正在处理"
preprocessing: "准备中"
preview: "预览" preview: "预览"
default: "默认" default: "默认"
defaultValueIs: "默认值: {value}" defaultValueIs: "默认值: {value}"
noCustomEmojis: "没有自定义表情符号" noCustomEmojis: "没有自定义表情符号"
noJobs: "没有任务" noJobs: "没有任务"
federating: "联合中" federating: "联合中"
blocked: "已屏蔽" blocked: "已拉黑"
suspended: "停止投递" suspended: "停止投递"
all: "全部" all: "全部"
subscribing: "已订阅" subscribing: "已订阅"
@ -303,7 +304,7 @@ explore: "发现"
messageRead: "已读" messageRead: "已读"
noMoreHistory: "没有更多的历史记录" noMoreHistory: "没有更多的历史记录"
startChat: "开始聊天" startChat: "开始聊天"
nUsersRead: "{n} 人已读" nUsersRead: "{n}人已读"
agreeTo: "勾选则表示已阅读并同意 {0}" agreeTo: "勾选则表示已阅读并同意 {0}"
agree: "同意" agree: "同意"
agreeBelow: "同意以下内容" agreeBelow: "同意以下内容"
@ -395,7 +396,7 @@ basicInfo: "基本信息"
pinnedUsers: "置顶用户" pinnedUsers: "置顶用户"
pinnedUsersDescription: "输入您想要固定到“发现”页面的用户,一行一个。" pinnedUsersDescription: "输入您想要固定到“发现”页面的用户,一行一个。"
pinnedPages: "固定页面" pinnedPages: "固定页面"
pinnedPagesDescription: "输入您要固定到服务器首页的页面路径,一行一个。" pinnedPagesDescription: "输入您要固定到服务器首页的页面路径,以换行符分隔。"
pinnedClipId: "置顶的便签 ID" pinnedClipId: "置顶的便签 ID"
pinnedNotes: "已置顶的帖子" pinnedNotes: "已置顶的帖子"
hcaptcha: "hCaptcha" hcaptcha: "hCaptcha"
@ -428,7 +429,7 @@ notifyAntenna: "开启通知"
withFileAntenna: "仅带有附件的帖子" withFileAntenna: "仅带有附件的帖子"
excludeNotesInSensitiveChannel: "排除敏感频道内的帖子" excludeNotesInSensitiveChannel: "排除敏感频道内的帖子"
enableServiceworker: "启用 ServiceWorker" enableServiceworker: "启用 ServiceWorker"
antennaUsersDescription: "指定用户名,一行一个" antennaUsersDescription: "指定用户名,用换行符进行分隔"
caseSensitive: "区分大小写" caseSensitive: "区分大小写"
withReplies: "包括回复" withReplies: "包括回复"
connectedTo: "您的账号已连到接以下第三方账号" connectedTo: "您的账号已连到接以下第三方账号"
@ -460,7 +461,7 @@ moderationNote: "管理笔记"
moderationNoteDescription: "可以用来记录仅在管理员之间共享的笔记。" moderationNoteDescription: "可以用来记录仅在管理员之间共享的笔记。"
addModerationNote: "添加管理笔记" addModerationNote: "添加管理笔记"
moderationLogs: "管理日志" moderationLogs: "管理日志"
nUsersMentioned: "{n} 被提到" nUsersMentioned: "{n}人投稿"
securityKeyAndPasskey: "安全密钥或 Passkey" securityKeyAndPasskey: "安全密钥或 Passkey"
securityKey: "安全密钥" securityKey: "安全密钥"
lastUsed: "最后使用:" lastUsed: "最后使用:"
@ -477,7 +478,7 @@ notFoundDescription: "没有与指定 URL 对应的页面。"
uploadFolder: "默认上传文件夹" uploadFolder: "默认上传文件夹"
markAsReadAllNotifications: "将所有通知标为已读" markAsReadAllNotifications: "将所有通知标为已读"
markAsReadAllUnreadNotes: "将所有帖子标记为已读" markAsReadAllUnreadNotes: "将所有帖子标记为已读"
markAsReadAllTalkMessages: "将所有聊天标记为已读" markAsReadAllTalkMessages: "将所有私信标记为已读"
help: "帮助" help: "帮助"
inputMessageHere: "在此键入信息" inputMessageHere: "在此键入信息"
close: "关闭" close: "关闭"
@ -597,7 +598,7 @@ recentUsed: "最近使用"
install: "安装" install: "安装"
uninstall: "卸载" uninstall: "卸载"
installedApps: "已授权的应用" installedApps: "已授权的应用"
nothing: "没有" nothing: ""
installedDate: "授权日期" installedDate: "授权日期"
lastUsedDate: "最近使用" lastUsedDate: "最近使用"
state: "状态" state: "状态"
@ -687,10 +688,10 @@ emptyToDisableSmtpAuth: "用户名和密码留空可以禁用 SMTP 验证"
smtpSecure: "在 SMTP 连接中使用隐式 SSL / TLS" smtpSecure: "在 SMTP 连接中使用隐式 SSL / TLS"
smtpSecureInfo: "使用 STARTTLS 时关闭。" smtpSecureInfo: "使用 STARTTLS 时关闭。"
testEmail: "邮件发送测试" testEmail: "邮件发送测试"
wordMute: "隐藏关键词" wordMute: "屏蔽关键词"
wordMuteDescription: "折叠包含指定关键词的帖子。被折叠的帖子可单击展开。" wordMuteDescription: "折叠包含指定关键词的帖子。被折叠的帖子可单击展开。"
hardWordMute: "隐藏硬关键词" hardWordMute: "强屏蔽关键词"
showMutedWord: "显示已隐藏的关键词" showMutedWord: "显示屏蔽关键词"
hardWordMuteDescription: "隐藏包含指定关键词的帖子。与隐藏关键词不同,帖子将完全不会显示。" hardWordMuteDescription: "隐藏包含指定关键词的帖子。与隐藏关键词不同,帖子将完全不会显示。"
regexpError: "正则表达式错误" regexpError: "正则表达式错误"
regexpErrorDescription: "{tab} 隐藏文字的第 {line} 行的正则表达式有错误:" regexpErrorDescription: "{tab} 隐藏文字的第 {line} 行的正则表达式有错误:"
@ -779,7 +780,7 @@ emailVerified: "电子邮件地址已验证"
noteFavoritesCount: "收藏的帖子数" noteFavoritesCount: "收藏的帖子数"
pageLikesCount: "页面点赞次数" pageLikesCount: "页面点赞次数"
pageLikedCount: "页面被点赞次数" pageLikedCount: "页面被点赞次数"
contact: "联系" contact: "联系方式"
useSystemFont: "使用系统默认字体" useSystemFont: "使用系统默认字体"
clips: "便签" clips: "便签"
experimentalFeatures: "实验性功能" experimentalFeatures: "实验性功能"
@ -800,7 +801,7 @@ showTitlebar: "显示标题栏"
clearCache: "清除缓存" clearCache: "清除缓存"
onlineUsersCount: "{n} 人在线" onlineUsersCount: "{n} 人在线"
nUsers: "{n} 用户" nUsers: "{n} 用户"
nNotes: "{n} 帖子" nNotes: "{n}帖子"
sendErrorReports: "发送错误报告" sendErrorReports: "发送错误报告"
sendErrorReportsDescription: "启用后,如果出现问题,可以与 Misskey 共享详细的错误信息,从而帮助提高软件的质量。错误信息包括操作系统版本、浏览器类型、行为历史记录等。" sendErrorReportsDescription: "启用后,如果出现问题,可以与 Misskey 共享详细的错误信息,从而帮助提高软件的质量。错误信息包括操作系统版本、浏览器类型、行为历史记录等。"
myTheme: "我的主题" myTheme: "我的主题"
@ -824,7 +825,7 @@ youAreRunningUpToDateClient: "您所使用的客户端已经是最新的。"
newVersionOfClientAvailable: "新版本的客户端可用。" newVersionOfClientAvailable: "新版本的客户端可用。"
usageAmount: "使用量" usageAmount: "使用量"
capacity: "容量" capacity: "容量"
inUse: "使用" inUse: "使用"
editCode: "编辑代码" editCode: "编辑代码"
apply: "应用" apply: "应用"
receiveAnnouncementFromInstance: "从服务器接收通知" receiveAnnouncementFromInstance: "从服务器接收通知"
@ -869,12 +870,12 @@ noMaintainerInformationWarning: "尚未设置管理员信息。"
noInquiryUrlWarning: "尚未设置联络地址。" noInquiryUrlWarning: "尚未设置联络地址。"
noBotProtectionWarning: "尚未设置 Bot 防御。" noBotProtectionWarning: "尚未设置 Bot 防御。"
configure: "设置" configure: "设置"
postToGallery: "发送到图库" postToGallery: "创建新相册"
postToHashtag: "投稿到这个标签" postToHashtag: "投稿到这个标签"
gallery: "图库" gallery: "相册"
recentPosts: "最新发布" recentPosts: "最新发布"
popularPosts: "热门投稿" popularPosts: "热门投稿"
shareWithNote: "在帖子中分享" shareWithNote: "分享到贴文"
ads: "广告" ads: "广告"
expiration: "截止时间" expiration: "截止时间"
startingperiod: "开始时间" startingperiod: "开始时间"
@ -885,7 +886,7 @@ middle: "中"
low: "低" low: "低"
emailNotConfiguredWarning: "尚未设置电子邮件地址。" emailNotConfiguredWarning: "尚未设置电子邮件地址。"
ratio: "比率" ratio: "比率"
previewNoteText: "预览" previewNoteText: "预览文"
customCss: "自定义 CSS" customCss: "自定义 CSS"
customCssWarn: "这些设置必须有相关的基础知识,不当的配置可能导致客户端无法正常使用。" customCssWarn: "这些设置必须有相关的基础知识,不当的配置可能导致客户端无法正常使用。"
global: "全局" global: "全局"
@ -924,8 +925,8 @@ manageAccounts: "管理账户"
makeReactionsPublic: "将回应设置为公开" makeReactionsPublic: "将回应设置为公开"
makeReactionsPublicDescription: "将您发表过的回应设置成公开可见。" makeReactionsPublicDescription: "将您发表过的回应设置成公开可见。"
classic: "经典" classic: "经典"
muteThread: "隐藏帖子列表" muteThread: "屏蔽帖文串"
unmuteThread: "取消隐藏帖子列表" unmuteThread: "取消屏蔽帖文串"
followingVisibility: "关注的人的公开范围" followingVisibility: "关注的人的公开范围"
followersVisibility: "关注者的公开范围" followersVisibility: "关注者的公开范围"
continueThread: "查看更多帖子" continueThread: "查看更多帖子"
@ -948,17 +949,17 @@ searchByGoogle: "Google"
instanceDefaultLightTheme: "服务器默认浅色主题" instanceDefaultLightTheme: "服务器默认浅色主题"
instanceDefaultDarkTheme: "服务器默认深色主题" instanceDefaultDarkTheme: "服务器默认深色主题"
instanceDefaultThemeDescription: "以对象格式输入主题代码" instanceDefaultThemeDescription: "以对象格式输入主题代码"
mutePeriod: "隐藏期限" mutePeriod: "屏蔽期限"
period: "截止时间" period: "截止时间"
indefinitely: "永久" indefinitely: "永久"
tenMinutes: "10 分钟" tenMinutes: "10分钟"
oneHour: "1 小时" oneHour: "1 小时"
oneDay: "1 天" oneDay: "1天"
oneWeek: "1 周" oneWeek: "1 周"
oneMonth: "1 个月" oneMonth: "1个月"
threeMonths: "3 个月" threeMonths: "3个月"
oneYear: "1 年" oneYear: "1 年"
threeDays: "3 天" threeDays: "3天"
reflectMayTakeTime: "可能需要一些时间才能体现出效果。" reflectMayTakeTime: "可能需要一些时间才能体现出效果。"
failedToFetchAccountInformation: "获取账户信息失败" failedToFetchAccountInformation: "获取账户信息失败"
rateLimitExceeded: "已超过速率限制" rateLimitExceeded: "已超过速率限制"
@ -967,8 +968,8 @@ cropImageAsk: "是否要裁剪图像?"
cropYes: "去裁剪" cropYes: "去裁剪"
cropNo: "就这样吧!" cropNo: "就这样吧!"
file: "文件" file: "文件"
recentNHours: "最近 {n} 小时" recentNHours: "最近{n}小时"
recentNDays: "最近 {n} 天" recentNDays: "最近{n}天"
noEmailServerWarning: "电子邮件服务器未设置。" noEmailServerWarning: "电子邮件服务器未设置。"
thereIsUnresolvedAbuseReportWarning: "有未解决的报告" thereIsUnresolvedAbuseReportWarning: "有未解决的报告"
recommended: "推荐" recommended: "推荐"
@ -1054,6 +1055,7 @@ permissionDeniedError: "操作被拒绝"
permissionDeniedErrorDescription: "本账户没有执行该操作的权限。" permissionDeniedErrorDescription: "本账户没有执行该操作的权限。"
preset: "预设值" preset: "预设值"
selectFromPresets: "从预设值中选择" selectFromPresets: "从预设值中选择"
custom: "自定义"
achievements: "成就" achievements: "成就"
gotInvalidResponseError: "服务器无应答" gotInvalidResponseError: "服务器无应答"
gotInvalidResponseErrorDescription: "您的网络连接可能出现了问题, 或是远程服务器暂时不可用. 请稍后重试。" gotInvalidResponseErrorDescription: "您的网络连接可能出现了问题, 或是远程服务器暂时不可用. 请稍后重试。"
@ -1078,7 +1080,7 @@ postToTheChannel: "发布到频道"
cannotBeChangedLater: "之后不能再更改。" cannotBeChangedLater: "之后不能再更改。"
reactionAcceptance: "接受表情回应" reactionAcceptance: "接受表情回应"
likeOnly: "仅点赞" likeOnly: "仅点赞"
likeOnlyForRemote: "远程仅点赞" likeOnlyForRemote: "全部(远程仅点赞"
nonSensitiveOnly: "仅限非敏感内容" nonSensitiveOnly: "仅限非敏感内容"
nonSensitiveOnlyForLocalLikeOnlyForRemote: "仅限非敏感内容(远程仅点赞)" nonSensitiveOnlyForLocalLikeOnlyForRemote: "仅限非敏感内容(远程仅点赞)"
rolesAssignedToMe: "指派给自己的角色" rolesAssignedToMe: "指派给自己的角色"
@ -1092,6 +1094,7 @@ prohibitedWordsDescription2: "AND 条件用空格分隔,正则表达式用斜
hiddenTags: "隐藏标签" hiddenTags: "隐藏标签"
hiddenTagsDescription: "设定的标签将不会在时间线上显示。可使用换行来设置多个标签。" hiddenTagsDescription: "设定的标签将不会在时间线上显示。可使用换行来设置多个标签。"
notesSearchNotAvailable: "帖子检索不可用" notesSearchNotAvailable: "帖子检索不可用"
usersSearchNotAvailable: "用户检索不可用"
license: "许可信息" license: "许可信息"
unfavoriteConfirm: "确定要取消收藏吗?" unfavoriteConfirm: "确定要取消收藏吗?"
myClips: "我的便签" myClips: "我的便签"
@ -1148,7 +1151,7 @@ youFollowing: "正在关注"
preventAiLearning: "拒绝接受生成式 AI 的学习" preventAiLearning: "拒绝接受生成式 AI 的学习"
preventAiLearningDescription: "要求文章生成 AI 或图像生成 AI 不能够以发布的帖子和图像等内容作为学习对象。这是通过在 HTML 响应中包含 noai 标志来实现的,这不能完全阻止 AI 学习你的发布内容,并不是所有 AI 都会遵守这类请求。" preventAiLearningDescription: "要求文章生成 AI 或图像生成 AI 不能够以发布的帖子和图像等内容作为学习对象。这是通过在 HTML 响应中包含 noai 标志来实现的,这不能完全阻止 AI 学习你的发布内容,并不是所有 AI 都会遵守这类请求。"
options: "选项" options: "选项"
specifyUser: "用户指定" specifyUser: "指定用户"
lookupConfirm: "确定查询?" lookupConfirm: "确定查询?"
openTagPageConfirm: "确定打开话题标签页面?" openTagPageConfirm: "确定打开话题标签页面?"
specifyHost: "指定主机名" specifyHost: "指定主机名"
@ -1243,7 +1246,7 @@ releaseToRefresh: "松开以刷新"
refreshing: "刷新中" refreshing: "刷新中"
pullDownToRefresh: "下拉以刷新" pullDownToRefresh: "下拉以刷新"
useGroupedNotifications: "分组显示通知" useGroupedNotifications: "分组显示通知"
signupPendingError: "确认电子邮件时出现错误。链接可能已过期。" emailVerificationFailedError: "确认电子邮件时出现错误。链接可能已过期。"
cwNotationRequired: "在启用「隐藏内容」时必须输入注释" cwNotationRequired: "在启用「隐藏内容」时必须输入注释"
doReaction: "回应" doReaction: "回应"
code: "代码" code: "代码"
@ -1263,7 +1266,7 @@ replaying: "重播中"
endReplay: "结束回放" endReplay: "结束回放"
copyReplayData: "复制回放数据" copyReplayData: "复制回放数据"
ranking: "排行榜" ranking: "排行榜"
lastNDays: "最近 {n} 天" lastNDays: "最近{n}天"
backToTitle: "返回标题" backToTitle: "返回标题"
hemisphere: "居住地区" hemisphere: "居住地区"
withSensitive: "显示包含敏感媒体的帖子" withSensitive: "显示包含敏感媒体的帖子"
@ -1314,6 +1317,7 @@ acknowledgeNotesAndEnable: "理解注意事项后再开启。"
federationSpecified: "此服务器已开启联合白名单。只能与管理员指定的服务器通信。" federationSpecified: "此服务器已开启联合白名单。只能与管理员指定的服务器通信。"
federationDisabled: "此服务器已禁用联合。无法与其它服务器上的用户通信。" federationDisabled: "此服务器已禁用联合。无法与其它服务器上的用户通信。"
draft: "草稿" draft: "草稿"
draftsAndScheduledNotes: "草稿和定时发送"
confirmOnReact: "发送回应前需要确认" confirmOnReact: "发送回应前需要确认"
reactAreYouSure: "要用「{emoji}」进行回应吗?" reactAreYouSure: "要用「{emoji}」进行回应吗?"
markAsSensitiveConfirm: "要将此媒体标记为敏感吗?" markAsSensitiveConfirm: "要将此媒体标记为敏感吗?"
@ -1341,6 +1345,8 @@ postForm: "投稿窗口"
textCount: "字数" textCount: "字数"
information: "关于" information: "关于"
chat: "聊天" chat: "聊天"
directMessage: "私信"
directMessage_short: "消息"
migrateOldSettings: "迁移旧设置信息" migrateOldSettings: "迁移旧设置信息"
migrateOldSettings_description: "通常设置信息将自动迁移。但如果由于某种原因迁移不成功,则可以手动触发迁移过程。当前的配置信息将被覆盖。" migrateOldSettings_description: "通常设置信息将自动迁移。但如果由于某种原因迁移不成功,则可以手动触发迁移过程。当前的配置信息将被覆盖。"
compress: "压缩" compress: "压缩"
@ -1358,41 +1364,60 @@ advice: "建议"
realtimeMode: "实时模式" realtimeMode: "实时模式"
turnItOn: "开启" turnItOn: "开启"
turnItOff: "关闭" turnItOff: "关闭"
emojiMute: "隐藏表情符号" emojiMute: "屏蔽表情符号"
emojiUnmute: "解除隐藏表情符号" emojiUnmute: "取消屏蔽表情符号"
muteX: "隐藏{x}" muteX: "屏蔽{x}"
unmuteX: "解除隐藏{x}" unmuteX: "取消屏蔽{x}"
abort: "中止" abort: "中止"
tip: "提示和技巧" tip: "提示和技巧"
redisplayAllTips: "重新显示所有的提示和技巧" redisplayAllTips: "重新显示所有的提示和技巧"
hideAllTips: "隐藏所有的提示和技巧" hideAllTips: "隐藏所有的提示和技巧"
defaultImageCompressionLevel: "默认图像压缩等级" defaultImageCompressionLevel: "默认图像压缩等级"
defaultImageCompressionLevel_description: "较低的等级可以保持画质,但会增加文件大小。<br>较高的等级可以减少文件大小,但相对应的画质将会降低。" defaultImageCompressionLevel_description: "较低的等级可以保持画质,但会增加文件大小。<br>较高的等级可以减少文件大小,但相对应的画质将会降低。"
inMinutes: "分" defaultCompressionLevel: "默认压缩等级"
inDays: "日" defaultCompressionLevel_description: "较低的等级可以保持质量,但会增加文件大小。<br>较高的等级可以减少文件大小,但相对应的质量将会降低。"
inMinutes: "分钟"
inDays: "天"
safeModeEnabled: "已启用安全模式" safeModeEnabled: "已启用安全模式"
pluginsAreDisabledBecauseSafeMode: "因启用了安全模式,所有插件均已被禁用。" pluginsAreDisabledBecauseSafeMode: "因启用了安全模式,所有插件均已被禁用。"
customCssIsDisabledBecauseSafeMode: "因启用了安全模式,无法应用自定义 CSS。" customCssIsDisabledBecauseSafeMode: "因启用了安全模式,无法应用自定义 CSS。"
themeIsDefaultBecauseSafeMode: "启用安全模式时将使用默认主题。关闭安全模式后将还原。" themeIsDefaultBecauseSafeMode: "启用安全模式时将使用默认主题。关闭安全模式后将还原。"
thankYouForTestingBeta: "感谢您协助测试 beta 版!"
createUserSpecifiedNote: "创建指定用户的帖子"
schedulePost: "定时发布"
scheduleToPostOnX: "预定在 {x} 发出"
scheduledToPostOnX: "已预定在 {x} 发出"
schedule: "定时"
scheduled: "定时"
_compression:
_quality:
high: "高质量"
medium: "中质量"
low: "低质量"
_size:
large: "大"
medium: "中"
small: "小"
_order: _order:
newest: "从新到旧" newest: "从新到旧"
oldest: "从旧到新" oldest: "从旧到新"
_chat: _chat:
messages: "消息"
noMessagesYet: "还没有消息" noMessagesYet: "还没有消息"
newMessage: "新消息" newMessage: "新消息"
individualChat: "私聊" individualChat: "私聊"
individualChat_description: "可以与特定用户进行一对一聊天。" individualChat_description: "可以与特定用户进行一对一聊天。"
roomChat: "群聊" roomChat: "群聊"
roomChat_description: "可以进行多人聊天。\n就算用户未允许私聊只要接受了邀请仍可以聊天。" roomChat_description: "支持多人同时进行消息交流。\n即使部分用户未开放私信权限只要接受了邀请仍可进行聊天。"
createRoom: "创建房间" createRoom: "创建群组"
inviteUserToChat: "邀请用户来开始聊天" inviteUserToChat: "邀请用户来开始聊天"
yourRooms: "已创建的房间" yourRooms: "创建的群组"
joiningRooms: "已加入的房间" joiningRooms: "已加入的群组"
invitations: "邀请" invitations: "邀请"
noInvitations: "没有邀请" noInvitations: "没有邀请"
history: "历史" history: "历史"
noHistory: "没有历史记录" noHistory: "没有历史记录"
noRooms: "没有房间" noRooms: "没有群组"
inviteUser: "邀请用户" inviteUser: "邀请用户"
sentInvitations: "已发送的邀请" sentInvitations: "已发送的邀请"
join: "加入" join: "加入"
@ -1403,16 +1428,16 @@ _chat:
home: "首页" home: "首页"
send: "发送" send: "发送"
newline: "换行" newline: "换行"
muteThisRoom: "静音此房间" muteThisRoom: "屏蔽该群组"
deleteRoom: "删除房间" deleteRoom: "删除群组"
chatNotAvailableForThisAccountOrServer: "此服务器或者账户还未开启聊天功能。" chatNotAvailableForThisAccountOrServer: "此服务器或者账户还未开启聊天功能。"
chatIsReadOnlyForThisAccountOrServer: "此服务器或者账户内的聊天为只读。无法发布新信息或创建及加入群聊。" chatIsReadOnlyForThisAccountOrServer: "此服务器或者账户内的聊天为只读。无法发布新信息或创建及加入群聊。"
chatNotAvailableInOtherAccount: "对方账户目前处于无法使用聊天的状态。" chatNotAvailableInOtherAccount: "对方的账户当前无法使用私信。"
cannotChatWithTheUser: "无法与此用户聊天" cannotChatWithTheUser: "无法私信该用户"
cannotChatWithTheUser_description: "可能现在无法使用聊天,或者对方未开启聊天。" cannotChatWithTheUser_description: "可能现在无法使用聊天,或者对方未开启聊天。"
youAreNotAMemberOfThisRoomButInvited: "您还未加入此房间,但已收到邀请。如要加入,请接受邀请。" youAreNotAMemberOfThisRoomButInvited: "您还未加入此房间,但已收到邀请。如要加入,请接受邀请。"
doYouAcceptInvitation: "要接受邀请吗?" doYouAcceptInvitation: "要接受邀请吗?"
chatWithThisUser: "聊天" chatWithThisUser: "私信"
thisUserAllowsChatOnlyFromFollowers: "此用户仅接受关注者发起的聊天。" thisUserAllowsChatOnlyFromFollowers: "此用户仅接受关注者发起的聊天。"
thisUserAllowsChatOnlyFromFollowing: "此用户仅接受关注的人发起的聊天。" thisUserAllowsChatOnlyFromFollowing: "此用户仅接受关注的人发起的聊天。"
thisUserAllowsChatOnlyFromMutualFollowing: "此用户仅接受互相关注的人发起的聊天。" thisUserAllowsChatOnlyFromMutualFollowing: "此用户仅接受互相关注的人发起的聊天。"
@ -1659,10 +1684,13 @@ _serverSettings:
allowExternalApRedirect: "允许通过 ActivityPub 重定向查询" allowExternalApRedirect: "允许通过 ActivityPub 重定向查询"
allowExternalApRedirect_description: "启用时,将允许其它服务器通过此服务器查询第三方内容,但有可能导致内容欺骗。" allowExternalApRedirect_description: "启用时,将允许其它服务器通过此服务器查询第三方内容,但有可能导致内容欺骗。"
userGeneratedContentsVisibilityForVisitor: "用户生成内容对非用户的可见性" userGeneratedContentsVisibilityForVisitor: "用户生成内容对非用户的可见性"
userGeneratedContentsVisibilityForVisitor_description: "对于防止难以审核的不适当的远程内容等,通过自己的服务器无意中在互联网上公开等问题很有用。" userGeneratedContentsVisibilityForVisitor_description: "对于防止诸如难以管理的不适当的远程内容通过自己的服务器意外地在互联网上公开等问题很有用。"
userGeneratedContentsVisibilityForVisitor_description2: "包含服务器接收到的远程内容在内,无条件将服务器上的所有内容公开在互联网上存在风险。特别是对去中心化的特性不是很了解的访问者有可能将远程服务器上的内容误认为是在此服务器内生成的,需要特别留意。" userGeneratedContentsVisibilityForVisitor_description2: "包含服务器接收到的远程内容在内,无条件将服务器上的所有内容公开在互联网上存在风险。特别是对去中心化的特性不是很了解的访问者有可能将远程服务器上的内容误认为是在此服务器内生成的,需要特别留意。"
restartServerSetupWizardConfirm_title: "要重新开始服务器初始设定向导吗?" restartServerSetupWizardConfirm_title: "要重新开始服务器初始设定向导吗?"
restartServerSetupWizardConfirm_text: "现有的部分设定将重置。" restartServerSetupWizardConfirm_text: "现有的部分设定将重置。"
entrancePageStyle: "入口页面样式"
showTimelineForVisitor: "显示时间线"
showActivitiesForVisitor: "显示活动"
_userGeneratedContentsVisibilityForVisitor: _userGeneratedContentsVisibilityForVisitor:
all: "全部公开" all: "全部公开"
localOnly: "仅公开本地内容,隐藏远程内容" localOnly: "仅公开本地内容,隐藏远程内容"
@ -1887,7 +1915,7 @@ _achievements:
description: "试图对网盘中的文件夹进行循环嵌套" description: "试图对网盘中的文件夹进行循环嵌套"
_reactWithoutRead: _reactWithoutRead:
title: "有好好读过吗?" title: "有好好读过吗?"
description: "在含有 100 字以上的帖子被发出三秒内做出回应" description: "在含有100字以上的帖子被发出三秒内做出回应"
_clickedClickHere: _clickedClickHere:
title: "点这里" title: "点这里"
description: "点了这里" description: "点了这里"
@ -1989,7 +2017,7 @@ _role:
canUpdateBioMedia: "可以更新头像和横幅" canUpdateBioMedia: "可以更新头像和横幅"
pinMax: "帖子置顶数量限制" pinMax: "帖子置顶数量限制"
antennaMax: "可创建的最大天线数量" antennaMax: "可创建的最大天线数量"
wordMuteMax: "隐藏词的字数限制" wordMuteMax: "屏蔽词的字数限制"
webhookMax: "Webhook 创建数量限制" webhookMax: "Webhook 创建数量限制"
clipMax: "便签创建数量限制" clipMax: "便签创建数量限制"
noteEachClipsMax: "单个便签内的贴文数量限制" noteEachClipsMax: "单个便签内的贴文数量限制"
@ -1999,6 +2027,7 @@ _role:
descriptionOfRateLimitFactor: "值越小限制越少,值越大限制越多。" descriptionOfRateLimitFactor: "值越小限制越少,值越大限制越多。"
canHideAds: "可以隐藏广告" canHideAds: "可以隐藏广告"
canSearchNotes: "是否可以搜索帖子" canSearchNotes: "是否可以搜索帖子"
canSearchUsers: "使用用户检索"
canUseTranslator: "使用翻译功能" canUseTranslator: "使用翻译功能"
avatarDecorationLimit: "可添加头像挂件的最大个数" avatarDecorationLimit: "可添加头像挂件的最大个数"
canImportAntennas: "允许导入天线" canImportAntennas: "允许导入天线"
@ -2006,11 +2035,12 @@ _role:
canImportFollowing: "允许导入关注列表" canImportFollowing: "允许导入关注列表"
canImportMuting: "允许导入隐藏列表" canImportMuting: "允许导入隐藏列表"
canImportUserLists: "允许导入用户列表" canImportUserLists: "允许导入用户列表"
chatAvailability: "允许聊天" chatAvailability: "允许私信"
uploadableFileTypes: "可上传的文件类型" uploadableFileTypes: "可上传的文件类型"
uploadableFileTypes_caption: "指定 MIME 类型。可用换行指定多个类型,也可以用星号(*)作为通配符。(如 image/*" uploadableFileTypes_caption: "指定 MIME 类型。可用换行指定多个类型,也可以用星号(*)作为通配符。(如 image/*"
uploadableFileTypes_caption2: "文件根据文件的不同,可能无法判断其类型。若要允许此类文件,请在指定中添加 {x}。" uploadableFileTypes_caption2: "文件根据文件的不同,可能无法判断其类型。若要允许此类文件,请在指定中添加 {x}。"
noteDraftLimit: "可在服务器上创建多少草稿" noteDraftLimit: "可在服务器上创建多少草稿"
scheduledNoteLimit: "可同时创建的定时帖子数量"
watermarkAvailable: "能否使用水印功能" watermarkAvailable: "能否使用水印功能"
_condition: _condition:
roleAssignedTo: "已分配给手动角色" roleAssignedTo: "已分配给手动角色"
@ -2076,9 +2106,9 @@ _forgotPassword:
ifNoEmail: "如果您没有设置电子邮件地址,请联系管理员。" ifNoEmail: "如果您没有设置电子邮件地址,请联系管理员。"
contactAdmin: "该服务器不支持发送电子邮件。如果您想重设密码,请联系管理员。" contactAdmin: "该服务器不支持发送电子邮件。如果您想重设密码,请联系管理员。"
_gallery: _gallery:
my: "我的图库" my: "我的相册"
liked: "喜欢的图片" liked: "喜欢的相册"
like: "喜欢" like: "喜欢"
unlike: "取消喜欢" unlike: "取消喜欢"
_email: _email:
_follow: _follow:
@ -2144,14 +2174,14 @@ _channel:
edit: "编辑频道" edit: "编辑频道"
setBanner: "设置横幅" setBanner: "设置横幅"
removeBanner: "删除横幅" removeBanner: "删除横幅"
featured: "热" featured: "热"
owned: "管理" owned: "正在管理"
following: "正在关注" following: "正在关注"
usersCount: "有 {n} 人参与" usersCount: "有{n}人参与"
notesCount: "有 {n} 个帖子" notesCount: "有{n}个帖子"
nameAndDescription: "名称与描述" nameAndDescription: "名称与描述"
nameOnly: "仅名称" nameOnly: "仅名称"
allowRenoteToExternal: "允许在频道外转帖及引用" allowRenoteToExternal: "允许转发到频道外和引用"
_menuDisplay: _menuDisplay:
sideFull: "横向" sideFull: "横向"
sideIcon: "横向(图标)" sideIcon: "横向(图标)"
@ -2162,10 +2192,10 @@ _wordMute:
muteWordsDescription: "AND 条件用空格分隔OR 条件用换行符分隔。" muteWordsDescription: "AND 条件用空格分隔OR 条件用换行符分隔。"
muteWordsDescription2: "正则表达式用斜线包裹" muteWordsDescription2: "正则表达式用斜线包裹"
_instanceMute: _instanceMute:
instanceMuteDescription: "隐藏服务器中所有的帖子和转帖,包括这些服务器上用户的回复。" instanceMuteDescription: "屏蔽服务器中所有的帖子和转帖,包括该服务器内用户的回复。"
instanceMuteDescription2: "一行一个" instanceMuteDescription2: "通过换行符分隔进行设置"
title: "下面实例中的帖子将被隐藏。" title: "下面实例中的帖子将被隐藏。"
heading: "已隐藏的服务器" heading: "已屏蔽的服务器"
_theme: _theme:
explore: "寻找主题" explore: "寻找主题"
install: "安装主题" install: "安装主题"
@ -2238,7 +2268,7 @@ _sfx:
noteMy: "我的帖子" noteMy: "我的帖子"
notification: "通知" notification: "通知"
reaction: "选择回应时" reaction: "选择回应时"
chatMessage: "聊天信息" chatMessage: "私信"
_soundSettings: _soundSettings:
driveFile: "使用网盘内的音频" driveFile: "使用网盘内的音频"
driveFileWarn: "选择网盘上的文件" driveFileWarn: "选择网盘上的文件"
@ -2249,28 +2279,29 @@ _soundSettings:
driveFileError: "无法读取声音。请更改设置。" driveFileError: "无法读取声音。请更改设置。"
_ago: _ago:
future: "未来" future: "未来"
justNow: "最近" justNow: "刚刚"
secondsAgo: "{n} 秒前" secondsAgo: "{n}秒前"
minutesAgo: "{n} 分前" minutesAgo: "{n}前"
hoursAgo: "{n} 小时前" hoursAgo: "{n}小时前"
daysAgo: "{n}前" daysAgo: "{n}前"
weeksAgo: "{n} 周前" weeksAgo: "{n}周前"
monthsAgo: "{n} 月前" monthsAgo: "{n}月前"
yearsAgo: "{n} 年前" yearsAgo: "{n}年前"
invalid: "没有" invalid: "没有"
_timeIn: _timeIn:
seconds: "{n}秒后" seconds: "{n}秒后"
minutes: "{n} 分后" minutes: "{n}后"
hours: "{n} 小时后" hours: "{n}小时后"
days: "{n}天后" days: "{n}天后"
weeks: "{n} 周后" weeks: "{n}周后"
months: "{n} 月后" months: "{n}月后"
years: "{n} 年后" years: "{n}年后"
_time: _time:
second: "秒" second: "秒"
minute: "分" minute: "分"
hour: "小时" hour: "小时"
day: "日" day: "天"
month: "个月"
_2fa: _2fa:
alreadyRegistered: "此设备已被注册" alreadyRegistered: "此设备已被注册"
registerTOTP: "开始设置验证器" registerTOTP: "开始设置验证器"
@ -2303,36 +2334,36 @@ _2fa:
_permissions: _permissions:
"read:account": "查看账户信息" "read:account": "查看账户信息"
"write:account": "更改帐户信息" "write:account": "更改帐户信息"
"read:blocks": "查看屏蔽列表" "read:blocks": "查看黑名单"
"write:blocks": "编辑屏蔽列表" "write:blocks": "编辑黑名单"
"read:drive": "查看网盘" "read:drive": "查看网盘"
"write:drive": "管理网盘文件" "write:drive": "管理网盘文件"
"read:favorites": "查看收藏夹" "read:favorites": "查看收藏夹"
"write:favorites": "编辑收藏夹" "write:favorites": "编辑收藏夹"
"read:following": "查看关注信息" "read:following": "查看关注信息"
"write:following": "关注/取消关注" "write:following": "关注/取消关注"
"read:messaging": "查看消息" "read:messaging": "查看私信"
"write:messaging": "撰写或删除消息" "write:messaging": "撰写或删除消息"
"read:mutes": "查看隐藏列表" "read:mutes": "查看屏蔽列表"
"write:mutes": "编辑隐藏列表" "write:mutes": "编辑屏蔽列表"
"write:notes": "撰写或删除帖子" "write:notes": "撰写或删除帖子"
"read:notifications": "查看通知" "read:notifications": "查看通知"
"write:notifications": "管理通知" "write:notifications": "管理通知"
"read:reactions": "查看回应" "read:reactions": "查看回应"
"write:reactions": "回应操作" "write:reactions": "编辑回应"
"write:votes": "投票" "write:votes": "投票"
"read:pages": "查看页面" "read:pages": "查看页面"
"write:pages": "操作页面" "write:pages": "编辑页面"
"read:page-likes": "查看喜欢的页面" "read:page-likes": "查看喜欢的页面"
"write:page-likes": "操作喜欢的页面" "write:page-likes": "管理喜欢的页面"
"read:user-groups": "查看用户组" "read:user-groups": "查看用户组"
"write:user-groups": "操作用户组" "write:user-groups": "编辑用户组"
"read:channels": "查看频道" "read:channels": "查看频道"
"write:channels": "管理频道" "write:channels": "管理频道"
"read:gallery": "浏览图库" "read:gallery": "浏览相册"
"write:gallery": "操作图库" "write:gallery": "编辑相册"
"read:gallery-likes": "读取喜欢的图片" "read:gallery-likes": "浏览喜欢的相册"
"write:gallery-likes": "操作喜欢的图片" "write:gallery-likes": "管理喜欢的相册"
"read:flash": "查看 Play" "read:flash": "查看 Play"
"write:flash": "编辑 Play" "write:flash": "编辑 Play"
"read:flash-likes": "查看 Play 的点赞" "read:flash-likes": "查看 Play 的点赞"
@ -2360,33 +2391,33 @@ _permissions:
"read:admin:roles": "查看角色" "read:admin:roles": "查看角色"
"write:admin:relays": "编辑中继" "write:admin:relays": "编辑中继"
"read:admin:relays": "查看中继" "read:admin:relays": "查看中继"
"write:admin:invite-codes": "编辑邀请码" "write:admin:invite-codes": "管理邀请码"
"read:admin:invite-codes": "查看邀请码" "read:admin:invite-codes": "查看邀请码"
"write:admin:announcements": "编辑公告" "write:admin:announcements": "管理公告"
"read:admin:announcements": "查看公告" "read:admin:announcements": "查看公告"
"write:admin:avatar-decorations": "编辑头像挂件" "write:admin:avatar-decorations": "编辑头像挂件"
"read:admin:avatar-decorations": "查看头像挂件" "read:admin:avatar-decorations": "查看头像挂件"
"write:admin:federation": "编辑联合相关信息" "write:admin:federation": "编辑联合相关信息"
"write:admin:account": "编辑用户账户" "write:admin:account": "编辑用户账户"
"read:admin:account": "查看用户相关情报" "read:admin:account": "查看用户相关情报"
"write:admin:emoji": "编辑表情文字" "write:admin:emoji": "编辑表情符号"
"read:admin:emoji": "查看表情文字" "read:admin:emoji": "查看表情符号"
"write:admin:queue": "编辑作业队列" "write:admin:queue": "编辑作业队列"
"read:admin:queue": "查看作业队列相关情报" "read:admin:queue": "查看作业队列相关情报"
"write:admin:promo": "运营推广说明" "write:admin:promo": "运营推广说明"
"write:admin:drive": "编辑用户网盘" "write:admin:drive": "管理用户网盘"
"read:admin:drive": "查看用户网盘相关情报" "read:admin:drive": "查看用户网盘相关情报"
"read:admin:stream": "使用管理员用的 Websocket API" "read:admin:stream": "使用管理员用的 Websocket API"
"write:admin:ad": "编辑广告" "write:admin:ad": "管理广告"
"read:admin:ad": "查看广告" "read:admin:ad": "查看广告"
"write:invite-codes": "生成邀请码" "write:invite-codes": "生成邀请码"
"read:invite-codes": "获取已发行的邀请码" "read:invite-codes": "获取已发行的邀请码"
"write:clip-favorite": "编辑便签的点赞" "write:clip-favorite": "管理喜欢的便签"
"read:clip-favorite": "查看便签的点赞" "read:clip-favorite": "查看便签的点赞"
"read:federation": "查看联合相关信息" "read:federation": "查看联合相关信息"
"write:report-abuse": "举报用户" "write:report-abuse": "举报用户"
"write:chat": "撰写或删除消息" "write:chat": "撰写或删除消息"
"read:chat": "查看聊天" "read:chat": "查看私信"
_auth: _auth:
shareAccessTitle: "应用程序授权许可" shareAccessTitle: "应用程序授权许可"
shareAccess: "您要授权允许 “{name}” 访问您的帐户吗?" shareAccess: "您要授权允许 “{name}” 访问您的帐户吗?"
@ -2405,7 +2436,7 @@ _antennaSources:
homeTimeline: "已关注用户的帖子" homeTimeline: "已关注用户的帖子"
users: "来自指定用户的帖子" users: "来自指定用户的帖子"
userList: "来自指定列表中的帖子" userList: "来自指定列表中的帖子"
userBlacklist: "除掉已选择用户后所有的帖子" userBlacklist: "过滤指定用户后的所有帖子"
_weekday: _weekday:
sunday: "星期日" sunday: "星期日"
monday: "星期一" monday: "星期一"
@ -2445,7 +2476,7 @@ _widgets:
chooseList: "选择列表" chooseList: "选择列表"
clicker: "点击器" clicker: "点击器"
birthdayFollowings: "今天是他们的生日" birthdayFollowings: "今天是他们的生日"
chat: "聊天" chat: "私信"
_cw: _cw:
hide: "隐藏" hide: "隐藏"
show: "查看更多" show: "查看更多"
@ -2453,26 +2484,26 @@ _cw:
files: "{count} 个文件" files: "{count} 个文件"
_poll: _poll:
noOnlyOneChoice: "需要至少两个选项" noOnlyOneChoice: "需要至少两个选项"
choiceN: "选{n}" choiceN: "选{n}"
noMore: "无法再添加更多了" noMore: "无法再添加更多了"
canMultipleVote: "允许多个投票" canMultipleVote: "允许选择多个选项"
expiration: "截止时间" expiration: "截止时间"
infinite: "永久" infinite: "永久"
at: "指定日期" at: "指定日期"
after: "指定时间" after: "指定时间"
deadlineDate: "截止日期" deadlineDate: "截止日期"
deadlineTime: "时" deadlineTime: ""
duration: "时长" duration: "期限"
votesCount: "{n} 票" votesCount: "{n}票"
totalVotes: "总票数 {n}" totalVotes: "总票数 {n}"
vote: "投票" vote: "投票"
showResult: "显示结果" showResult: "显示结果"
voted: "已投票" voted: "已投票"
closed: "已截止" closed: "已截止"
remainingDays: "{d} {h} 小时后截止" remainingDays: "{d}天{h}小时后截止"
remainingHours: "{h} 小时 {m} 分后截止" remainingHours: "{h} 小时 {m} 分后截止"
remainingMinutes: "{m} {s} 秒后截止" remainingMinutes: "{m}分{s}秒后截止"
remainingSeconds: "{s} 秒后截止" remainingSeconds: "{s}秒后截止"
_visibility: _visibility:
public: "公开" public: "公开"
publicDescription: "您的帖子将出现在全局时间线上" publicDescription: "您的帖子将出现在全局时间线上"
@ -2491,9 +2522,9 @@ _postForm:
quotePlaceholder: "引用这个帖子..." quotePlaceholder: "引用这个帖子..."
channelPlaceholder: "发布到频道…" channelPlaceholder: "发布到频道…"
_placeholders: _placeholders:
a: "现在如何" a: "现在怎么样"
b: "发生了什么" b: "想好发些什么了吗"
c: "你有什么想法" c: "在想些什么呢"
d: "你想要发布些什么吗?" d: "你想要发布些什么吗?"
e: "请写下来吧" e: "请写下来吧"
f: "等待您的发布..." f: "等待您的发布..."
@ -2519,8 +2550,8 @@ _exportOrImport:
favoritedNotes: "收藏的帖子" favoritedNotes: "收藏的帖子"
clips: "便签" clips: "便签"
followingList: "关注中" followingList: "关注中"
muteList: "隐藏" muteList: "屏蔽"
blockingList: "屏蔽" blockingList: "拉黑"
userLists: "列表" userLists: "列表"
excludeMutingUsers: "排除屏蔽用户" excludeMutingUsers: "排除屏蔽用户"
excludeInactiveUsers: "排除不活跃用户" excludeInactiveUsers: "排除不活跃用户"
@ -2566,7 +2597,7 @@ _play:
editThisPage: "编辑此 Play" editThisPage: "编辑此 Play"
viewSource: "查看源代码" viewSource: "查看源代码"
my: "我的 Play" my: "我的 Play"
liked: "点赞的 Play" liked: "喜欢的 Play"
featured: "热门" featured: "热门"
title: "标题" title: "标题"
script: "脚本" script: "脚本"
@ -2583,7 +2614,7 @@ _pages:
editThisPage: "编辑此页面" editThisPage: "编辑此页面"
viewSource: "查看源代码" viewSource: "查看源代码"
viewPage: "查看页面" viewPage: "查看页面"
like: "" like: "喜欢"
unlike: "取消喜欢" unlike: "取消喜欢"
my: "我的页面" my: "我的页面"
liked: "喜欢的页面" liked: "喜欢的页面"
@ -2631,10 +2662,12 @@ _notification:
youGotReply: "来自{name}的回复" youGotReply: "来自{name}的回复"
youGotQuote: "来自{name}的引用" youGotQuote: "来自{name}的引用"
youRenoted: "来自{name}的转发" youRenoted: "来自{name}的转发"
youWereFollowed: "关注了你" youWereFollowed: "关注了你"
youReceivedFollowRequest: "您有新的关注请求" youReceivedFollowRequest: "您有新的关注请求"
yourFollowRequestAccepted: "您的关注请求已通过" yourFollowRequestAccepted: "您的关注请求已通过"
pollEnded: "问卷调查结果已生成。" pollEnded: "问卷调查结果已生成。"
scheduledNotePosted: "定时帖子已发布"
scheduledNotePostFailed: "定时帖子发布失败"
newNote: "新的帖子" newNote: "新的帖子"
unreadAntennaNote: "天线 {name}" unreadAntennaNote: "天线 {name}"
roleAssigned: "授予的角色" roleAssigned: "授予的角色"
@ -2714,7 +2747,7 @@ _deck:
mentions: "提及" mentions: "提及"
direct: "指定用户" direct: "指定用户"
roleTimeline: "角色时间线" roleTimeline: "角色时间线"
chat: "聊天" chat: "私信"
_dialog: _dialog:
charactersExceeded: "已经超过了最大字符数! 当前字符数 {current} / 限制字符数 {max}" charactersExceeded: "已经超过了最大字符数! 当前字符数 {current} / 限制字符数 {max}"
charactersBelow: "低于最小字符数!当前字符数 {current} / 限制字符数 {min}" charactersBelow: "低于最小字符数!当前字符数 {current} / 限制字符数 {min}"
@ -2810,7 +2843,7 @@ _moderationLogTypes:
deleteAccount: "删除了账户" deleteAccount: "删除了账户"
deletePage: "删除了页面" deletePage: "删除了页面"
deleteFlash: "删除了 Play" deleteFlash: "删除了 Play"
deleteGalleryPost: "删除了图库稿件" deleteGalleryPost: "删除相册内容"
deleteChatRoom: "删除聊天室" deleteChatRoom: "删除聊天室"
updateProxyAccountDescription: "更新代理账户的简介" updateProxyAccountDescription: "更新代理账户的简介"
_fileViewer: _fileViewer:
@ -3066,7 +3099,7 @@ _bootErrors:
serverError: "请稍等片刻再重试。若问题仍无法解决,请将以下 Error ID 一起发送给管理员。" serverError: "请稍等片刻再重试。若问题仍无法解决,请将以下 Error ID 一起发送给管理员。"
solution: "以下方法或许可以解决问题:" solution: "以下方法或许可以解决问题:"
solution1: "将浏览器及操作系统更新到最新版本" solution1: "将浏览器及操作系统更新到最新版本"
solution2: "禁用广告屏蔽插件" solution2: "禁用广告拦截插件"
solution3: "清除浏览器缓存" solution3: "清除浏览器缓存"
solution4: "Tor Browser将 dom.webaudio.enabled 设定为 true" solution4: "Tor Browser将 dom.webaudio.enabled 设定为 true"
otherOption: "其它选项" otherOption: "其它选项"
@ -3160,14 +3193,16 @@ _watermarkEditor:
opacity: "不透明度" opacity: "不透明度"
scale: "大小" scale: "大小"
text: "文本" text: "文本"
qr: "二维码"
position: "位置" position: "位置"
margin: "边距"
type: "类型" type: "类型"
image: "图片" image: "图片"
advanced: "高级" advanced: "高级"
angle: "角度"
stripe: "条纹" stripe: "条纹"
stripeWidth: "线条宽度" stripeWidth: "线条宽度"
stripeFrequency: "线条数量" stripeFrequency: "线条数量"
angle: "角度"
polkadot: "波点" polkadot: "波点"
checker: "检查" checker: "检查"
polkadotMainDotOpacity: "主波点的不透明度" polkadotMainDotOpacity: "主波点的不透明度"
@ -3175,16 +3210,20 @@ _watermarkEditor:
polkadotSubDotOpacity: "副波点的不透明度" polkadotSubDotOpacity: "副波点的不透明度"
polkadotSubDotRadius: "副波点的大小" polkadotSubDotRadius: "副波点的大小"
polkadotSubDotDivisions: "副波点的数量" polkadotSubDotDivisions: "副波点的数量"
leaveBlankToAccountUrl: "留空则为账户 URL"
_imageEffector: _imageEffector:
title: "效果" title: "效果"
addEffect: "添加效果" addEffect: "添加效果"
discardChangesConfirm: "丢弃当前设置并退出?" discardChangesConfirm: "丢弃当前设置并退出?"
nothingToConfigure: "还没有设置"
_fxs: _fxs:
chromaticAberration: "色差" chromaticAberration: "色差"
glitch: "故障" glitch: "故障"
mirror: "镜像" mirror: "镜像"
invert: "反转颜色" invert: "反转颜色"
grayscale: "黑白" grayscale: "黑白"
blur: "模糊"
pixelate: "马赛克"
colorAdjust: "色彩校正" colorAdjust: "色彩校正"
colorClamp: "颜色限制" colorClamp: "颜色限制"
colorClampAdvanced: "颜色限制(高级)" colorClampAdvanced: "颜色限制(高级)"
@ -3196,6 +3235,43 @@ _imageEffector:
checker: "检查" checker: "检查"
blockNoise: "块状噪点" blockNoise: "块状噪点"
tearing: "撕裂" tearing: "撕裂"
fill: "填充"
_fxProps:
angle: "角度"
scale: "大小"
size: "大小"
radius: "半径"
samples: "采样数"
offset: "位置"
color: "颜色"
opacity: "不透明度"
normalize: "标准化"
amount: "数量"
lightness: "浅色"
contrast: "对比度"
hue: "色调"
brightness: "亮度"
saturation: "饱和度"
max: "最大值"
min: "最小值"
direction: "方向"
phase: "相位"
frequency: "频率"
strength: "强度"
glitchChannelShift: "错位"
seed: "种子"
redComponent: "红色成分"
greenComponent: "绿色成分"
blueComponent: "蓝色成分"
threshold: "阈值"
centerX: "中心 X "
centerY: "中心 Y"
zoomLinesSmoothing: "平滑"
zoomLinesSmoothingDescription: "平滑和集中线宽度设置不能同时使用。"
zoomLinesThreshold: "集中线宽度"
zoomLinesMaskSize: "中心直径"
zoomLinesBlack: "变成黑色"
circle: "圆形"
drafts: "草稿" drafts: "草稿"
_drafts: _drafts:
select: "选择草稿" select: "选择草稿"
@ -3211,3 +3287,22 @@ _drafts:
restoreFromDraft: "从草稿恢复" restoreFromDraft: "从草稿恢复"
restore: "恢复" restore: "恢复"
listDrafts: "草稿一览" listDrafts: "草稿一览"
schedule: "定时发布"
listScheduledNotes: "定时发布列表"
cancelSchedule: "取消定时"
qr: "二维码"
_qr:
showTabTitle: "显示"
readTabTitle: "读取"
shareTitle: "{name} {acct}"
shareText: "请在 Fediverse 上关注我!"
chooseCamera: "选择相机"
cannotToggleFlash: "无法开关闪光灯"
turnOnFlash: "打开闪光灯"
turnOffFlash: "关闭闪光灯"
startQr: "重新打开二维码扫描器"
stopQr: "关闭二维码扫描器"
noQrCodeFound: "未找到二维码"
scanFile: "扫描设备上的图像"
raw: "文本"
mfm: "MFM"

View File

@ -75,7 +75,7 @@ receiveFollowRequest: "您有新的追隨請求"
followRequestAccepted: "追隨請求已被接受" followRequestAccepted: "追隨請求已被接受"
mention: "提及" mention: "提及"
mentions: "提及" mentions: "提及"
directNotes: "私訊" directNotes: "指定使用者"
importAndExport: "匯入與匯出" importAndExport: "匯入與匯出"
import: "匯入" import: "匯入"
export: "匯出" export: "匯出"
@ -253,6 +253,7 @@ noteDeleteConfirm: "確定刪除此貼文嗎?"
pinLimitExceeded: "不能置頂更多貼文了" pinLimitExceeded: "不能置頂更多貼文了"
done: "完成" done: "完成"
processing: "處理中" processing: "處理中"
preprocessing: "準備中"
preview: "預覽" preview: "預覽"
default: "預設" default: "預設"
defaultValueIs: "預設值:{value}" defaultValueIs: "預設值:{value}"
@ -1054,6 +1055,7 @@ permissionDeniedError: "操作被拒絕"
permissionDeniedErrorDescription: "此帳戶沒有執行這個操作的權限。" permissionDeniedErrorDescription: "此帳戶沒有執行這個操作的權限。"
preset: "預設值" preset: "預設值"
selectFromPresets: "從預設值中選擇" selectFromPresets: "從預設值中選擇"
custom: "自訂"
achievements: "成就" achievements: "成就"
gotInvalidResponseError: "伺服器的回應無效" gotInvalidResponseError: "伺服器的回應無效"
gotInvalidResponseErrorDescription: "伺服器可能已關閉或者在維護中,請稍後再試。" gotInvalidResponseErrorDescription: "伺服器可能已關閉或者在維護中,請稍後再試。"
@ -1092,6 +1094,7 @@ prohibitedWordsDescription2: "空格代表「以及」AND斜線包圍
hiddenTags: "隱藏標籤" hiddenTags: "隱藏標籤"
hiddenTagsDescription: "設定的標籤不會在趨勢中顯示,換行可以設定多個標籤。" hiddenTagsDescription: "設定的標籤不會在趨勢中顯示,換行可以設定多個標籤。"
notesSearchNotAvailable: "無法使用搜尋貼文功能。" notesSearchNotAvailable: "無法使用搜尋貼文功能。"
usersSearchNotAvailable: "無法使用使用者搜尋功能。"
license: "授權" license: "授權"
unfavoriteConfirm: "要取消收錄我的最愛嗎?" unfavoriteConfirm: "要取消收錄我的最愛嗎?"
myClips: "我的摘錄" myClips: "我的摘錄"
@ -1243,7 +1246,7 @@ releaseToRefresh: "放開以更新內容"
refreshing: "載入更新中" refreshing: "載入更新中"
pullDownToRefresh: "往下拉來更新內容" pullDownToRefresh: "往下拉來更新內容"
useGroupedNotifications: "分組顯示通知訊息" useGroupedNotifications: "分組顯示通知訊息"
signupPendingError: "驗證您的電子郵件地址時出現問題。連結可能已過期。" emailVerificationFailedError: "驗證您的電子郵件地址時出現問題。連結可能已過期。"
cwNotationRequired: "如果開啟「隱藏內容」,則需要註解說明。" cwNotationRequired: "如果開啟「隱藏內容」,則需要註解說明。"
doReaction: "做出反應" doReaction: "做出反應"
code: "程式碼" code: "程式碼"
@ -1314,6 +1317,7 @@ acknowledgeNotesAndEnable: "了解注意事項後再開啟。"
federationSpecified: "此伺服器以白名單聯邦的方式運作。除了管理員指定的伺服器外,它無法與其他伺服器互動。" federationSpecified: "此伺服器以白名單聯邦的方式運作。除了管理員指定的伺服器外,它無法與其他伺服器互動。"
federationDisabled: "此伺服器未開啟站台聯邦。無法與其他伺服器上的使用者互動。" federationDisabled: "此伺服器未開啟站台聯邦。無法與其他伺服器上的使用者互動。"
draft: "草稿\n" draft: "草稿\n"
draftsAndScheduledNotes: "草稿與排定發布"
confirmOnReact: "在做出反應前先確認" confirmOnReact: "在做出反應前先確認"
reactAreYouSure: "用「 {emoji} 」反應嗎?" reactAreYouSure: "用「 {emoji} 」反應嗎?"
markAsSensitiveConfirm: "要將這個媒體設定為敏感嗎?" markAsSensitiveConfirm: "要將這個媒體設定為敏感嗎?"
@ -1341,6 +1345,8 @@ postForm: "發文視窗"
textCount: "字數" textCount: "字數"
information: "關於" information: "關於"
chat: "聊天" chat: "聊天"
directMessage: "直接訊息"
directMessage_short: "訊息"
migrateOldSettings: "遷移舊設定資訊" migrateOldSettings: "遷移舊設定資訊"
migrateOldSettings_description: "通常情況下,這會自動進行,但若因某些原因未能順利遷移,您可以手動觸發遷移處理。請注意,當前的設定資訊將會被覆寫。" migrateOldSettings_description: "通常情況下,這會自動進行,但若因某些原因未能順利遷移,您可以手動觸發遷移處理。請注意,當前的設定資訊將會被覆寫。"
compress: "壓縮" compress: "壓縮"
@ -1368,16 +1374,35 @@ redisplayAllTips: "重新顯示所有「提示與技巧」"
hideAllTips: "隱藏所有「提示與技巧」" hideAllTips: "隱藏所有「提示與技巧」"
defaultImageCompressionLevel: "預設的影像壓縮程度" defaultImageCompressionLevel: "預設的影像壓縮程度"
defaultImageCompressionLevel_description: "低的話可以保留畫質,但是會增加檔案的大小。<br>高的話可以減少檔案大小,但是會降低畫質。" defaultImageCompressionLevel_description: "低的話可以保留畫質,但是會增加檔案的大小。<br>高的話可以減少檔案大小,但是會降低畫質。"
defaultCompressionLevel: "預設的壓縮程度"
defaultCompressionLevel_description: "低的話可以保留品質,但是會增加檔案的大小。<br>高的話可以減少檔案大小,但是會降低品質。"
inMinutes: "分鐘" inMinutes: "分鐘"
inDays: "日" inDays: "日"
safeModeEnabled: "啟用安全模式" safeModeEnabled: "啟用安全模式"
pluginsAreDisabledBecauseSafeMode: "由於啟用安全模式,所有的外掛都被停用。" pluginsAreDisabledBecauseSafeMode: "由於啟用安全模式,所有的外掛都被停用。"
customCssIsDisabledBecauseSafeMode: "由於啟用安全模式,所有的客製 CSS 都被停用。" customCssIsDisabledBecauseSafeMode: "由於啟用安全模式,所有的客製 CSS 都被停用。"
themeIsDefaultBecauseSafeMode: "在安全模式啟用期間將使用預設主題。關閉安全模式後會恢復原本的設定。" themeIsDefaultBecauseSafeMode: "在安全模式啟用期間將使用預設主題。關閉安全模式後會恢復原本的設定。"
thankYouForTestingBeta: "感謝您協助驗證 beta 版!"
createUserSpecifiedNote: "建立使用者指定的筆記"
schedulePost: "排定發布"
scheduleToPostOnX: "排定在 {x} 發布"
scheduledToPostOnX: "已排定在 {x} 發布貼文"
schedule: "排定"
scheduled: "排定"
_compression:
_quality:
high: "高品質"
medium: "中品質"
low: "低品質"
_size:
large: "大"
medium: "中"
small: "小"
_order: _order:
newest: "最新的在前" newest: "最新的在前"
oldest: "最舊的在前" oldest: "最舊的在前"
_chat: _chat:
messages: "訊息"
noMessagesYet: "尚無訊息" noMessagesYet: "尚無訊息"
newMessage: "新訊息" newMessage: "新訊息"
individualChat: "ㄧ對一聊天室" individualChat: "ㄧ對一聊天室"
@ -1663,6 +1688,9 @@ _serverSettings:
userGeneratedContentsVisibilityForVisitor_description2: "包括伺服器接收到的遠端內容在內,無條件地將伺服器內所有內容公開到網際網路上是具有風險的。特別是對於不了解分散式架構特性的瀏覽者來說,他們可能會誤以為這些遠端內容是由該伺服器所創建的,因此需要特別留意。" userGeneratedContentsVisibilityForVisitor_description2: "包括伺服器接收到的遠端內容在內,無條件地將伺服器內所有內容公開到網際網路上是具有風險的。特別是對於不了解分散式架構特性的瀏覽者來說,他們可能會誤以為這些遠端內容是由該伺服器所創建的,因此需要特別留意。"
restartServerSetupWizardConfirm_title: "要重新執行伺服器的初始設定精靈嗎?" restartServerSetupWizardConfirm_title: "要重新執行伺服器的初始設定精靈嗎?"
restartServerSetupWizardConfirm_text: "當前的部分設定將會被重設。" restartServerSetupWizardConfirm_text: "當前的部分設定將會被重設。"
entrancePageStyle: "入口頁面的樣式"
showTimelineForVisitor: "顯示時間軸"
showActivitiesForVisitor: "顯示活動"
_userGeneratedContentsVisibilityForVisitor: _userGeneratedContentsVisibilityForVisitor:
all: "全部公開\n" all: "全部公開\n"
localOnly: "僅公開本地內容,遠端內容則不公開\n" localOnly: "僅公開本地內容,遠端內容則不公開\n"
@ -1999,6 +2027,7 @@ _role:
descriptionOfRateLimitFactor: "值越小限制越少,值越大限制越多。" descriptionOfRateLimitFactor: "值越小限制越少,值越大限制越多。"
canHideAds: "不顯示廣告" canHideAds: "不顯示廣告"
canSearchNotes: "可否搜尋貼文" canSearchNotes: "可否搜尋貼文"
canSearchUsers: "可使用使用者搜尋功能"
canUseTranslator: "使用翻譯功能" canUseTranslator: "使用翻譯功能"
avatarDecorationLimit: "頭像可掛上的最大裝飾數量" avatarDecorationLimit: "頭像可掛上的最大裝飾數量"
canImportAntennas: "允許匯入天線" canImportAntennas: "允許匯入天線"
@ -2011,6 +2040,7 @@ _role:
uploadableFileTypes_caption: "請指定 MIME 類型。可以用換行區隔多個類型,也可以使用星號(*作為萬用字元進行指定。例如image/*\n" uploadableFileTypes_caption: "請指定 MIME 類型。可以用換行區隔多個類型,也可以使用星號(*作為萬用字元進行指定。例如image/*\n"
uploadableFileTypes_caption2: "有些檔案可能無法判斷其類型。若要允許這類檔案,請在指定中加入 {x}。" uploadableFileTypes_caption2: "有些檔案可能無法判斷其類型。若要允許這類檔案,請在指定中加入 {x}。"
noteDraftLimit: "伺服器端可建立的貼文草稿數量上限\n" noteDraftLimit: "伺服器端可建立的貼文草稿數量上限\n"
scheduledNoteLimit: "同時建立的排定發布數量"
watermarkAvailable: "浮水印功能是否可用" watermarkAvailable: "浮水印功能是否可用"
_condition: _condition:
roleAssignedTo: "手動指派角色完成" roleAssignedTo: "手動指派角色完成"
@ -2231,7 +2261,7 @@ _theme:
buttonHoverBg: "按鈕背景 (漂浮)" buttonHoverBg: "按鈕背景 (漂浮)"
inputBorder: "輸入框邊框" inputBorder: "輸入框邊框"
badge: "徽章" badge: "徽章"
messageBg: "私訊背景" messageBg: "聊天的背景"
fgHighlighted: "突顯文字" fgHighlighted: "突顯文字"
_sfx: _sfx:
note: "貼文" note: "貼文"
@ -2271,6 +2301,7 @@ _time:
minute: "分鐘" minute: "分鐘"
hour: "小時" hour: "小時"
day: "日" day: "日"
month: "個月"
_2fa: _2fa:
alreadyRegistered: "此裝置已被註冊過了" alreadyRegistered: "此裝置已被註冊過了"
registerTOTP: "開始設定驗證應用程式" registerTOTP: "開始設定驗證應用程式"
@ -2635,6 +2666,8 @@ _notification:
youReceivedFollowRequest: "您有新的追隨請求" youReceivedFollowRequest: "您有新的追隨請求"
yourFollowRequestAccepted: "您的追隨請求已被核准" yourFollowRequestAccepted: "您的追隨請求已被核准"
pollEnded: "問卷調查已產生結果" pollEnded: "問卷調查已產生結果"
scheduledNotePosted: "已排定發布貼文"
scheduledNotePostFailed: "排定發布貼文失敗了"
newNote: "新的貼文" newNote: "新的貼文"
unreadAntennaNote: "天線 {name}" unreadAntennaNote: "天線 {name}"
roleAssigned: "已授予角色" roleAssigned: "已授予角色"
@ -3160,14 +3193,16 @@ _watermarkEditor:
opacity: "透明度" opacity: "透明度"
scale: "大小" scale: "大小"
text: "文字" text: "文字"
qr: "二維條碼"
position: "位置" position: "位置"
margin: "邊界"
type: "類型" type: "類型"
image: "圖片" image: "圖片"
advanced: "進階" advanced: "進階"
angle: "角度"
stripe: "條紋" stripe: "條紋"
stripeWidth: "線條寬度" stripeWidth: "線條寬度"
stripeFrequency: "線條數量" stripeFrequency: "線條數量"
angle: "角度"
polkadot: "波卡圓點" polkadot: "波卡圓點"
checker: "棋盤格" checker: "棋盤格"
polkadotMainDotOpacity: "主圓點的不透明度" polkadotMainDotOpacity: "主圓點的不透明度"
@ -3175,16 +3210,20 @@ _watermarkEditor:
polkadotSubDotOpacity: "子圓點的不透明度" polkadotSubDotOpacity: "子圓點的不透明度"
polkadotSubDotRadius: "子圓點的尺寸" polkadotSubDotRadius: "子圓點的尺寸"
polkadotSubDotDivisions: "子圓點的數量" polkadotSubDotDivisions: "子圓點的數量"
leaveBlankToAccountUrl: "若留空則使用帳戶的 URL"
_imageEffector: _imageEffector:
title: "特效" title: "特效"
addEffect: "新增特效" addEffect: "新增特效"
discardChangesConfirm: "捨棄更改並退出嗎?" discardChangesConfirm: "捨棄更改並退出嗎?"
nothingToConfigure: "無可設定的項目"
_fxs: _fxs:
chromaticAberration: "色差" chromaticAberration: "色差"
glitch: "異常雜訊效果" glitch: "異常雜訊效果"
mirror: "鏡像" mirror: "鏡像"
invert: "反轉色彩" invert: "反轉色彩"
grayscale: "黑白" grayscale: "黑白"
blur: "模糊"
pixelate: "馬賽克"
colorAdjust: "色彩校正" colorAdjust: "色彩校正"
colorClamp: "壓縮色彩" colorClamp: "壓縮色彩"
colorClampAdvanced: "壓縮色彩(進階)" colorClampAdvanced: "壓縮色彩(進階)"
@ -3196,6 +3235,43 @@ _imageEffector:
checker: "棋盤格" checker: "棋盤格"
blockNoise: "阻擋雜訊" blockNoise: "阻擋雜訊"
tearing: "撕裂" tearing: "撕裂"
fill: "填充"
_fxProps:
angle: "角度"
scale: "大小"
size: "大小"
radius: "半徑"
samples: "取樣數"
offset: "位置"
color: "顏色"
opacity: "透明度"
normalize: "正規化"
amount: "數量"
lightness: "亮度"
contrast: "對比度"
hue: "色相"
brightness: "亮度"
saturation: "彩度"
max: "最大值"
min: "最小值"
direction: "方向"
phase: "相位"
frequency: "頻率"
strength: "強度"
glitchChannelShift: "偏移"
seed: "種子值"
redComponent: "紅色成分"
greenComponent: "綠色成分"
blueComponent: "青色成分"
threshold: "閾值"
centerX: "X中心座標"
centerY: "Y中心座標"
zoomLinesSmoothing: "平滑化"
zoomLinesSmoothingDescription: "平滑化與集中線寬度設定不能同時使用。"
zoomLinesThreshold: "集中線的寬度"
zoomLinesMaskSize: "中心直徑"
zoomLinesBlack: "變成黑色"
circle: "圓形"
drafts: "草稿\n" drafts: "草稿\n"
_drafts: _drafts:
select: "選擇草槁" select: "選擇草槁"
@ -3211,3 +3287,22 @@ _drafts:
restoreFromDraft: "從草稿復原\n" restoreFromDraft: "從草稿復原\n"
restore: "還原" restore: "還原"
listDrafts: "草稿清單" listDrafts: "草稿清單"
schedule: "排定發布"
listScheduledNotes: "排定發布列表"
cancelSchedule: "解除排定"
qr: "二維條碼"
_qr:
showTabTitle: "檢視"
readTabTitle: "讀取"
shareTitle: "{name} {acct}"
shareText: "請在聯邦宇宙追隨我吧!"
chooseCamera: "選擇相機"
cannotToggleFlash: "無法切換閃光燈"
turnOnFlash: "開啟閃光燈"
turnOffFlash: "關閉閃光燈"
startQr: "啟動條碼掃描器"
stopQr: "停止條碼掃描器"
noQrCodeFound: "找不到 QR code"
scanFile: "掃描在裝置上的影像"
raw: "文字"
mfm: "MFM"

View File

@ -1,12 +1,12 @@
{ {
"name": "misskey", "name": "misskey",
"version": "2025.8.0-alpha.6", "version": "2025.10.0-beta.0",
"codename": "nasubi", "codename": "nasubi",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/misskey-dev/misskey.git" "url": "https://github.com/misskey-dev/misskey.git"
}, },
"packageManager": "pnpm@10.14.0", "packageManager": "pnpm@10.17.1",
"workspaces": [ "workspaces": [
"packages/frontend-shared", "packages/frontend-shared",
"packages/frontend", "packages/frontend",
@ -27,6 +27,7 @@
"build-misskey-js-with-types": "pnpm build-pre && pnpm --filter backend... --filter=!misskey-js build && pnpm --filter backend generate-api-json --no-build && ncp packages/backend/built/api.json packages/misskey-js/generator/api.json && pnpm --filter misskey-js update-autogen-code && pnpm --filter misskey-js build && pnpm --filter misskey-js api", "build-misskey-js-with-types": "pnpm build-pre && pnpm --filter backend... --filter=!misskey-js build && pnpm --filter backend generate-api-json --no-build && ncp packages/backend/built/api.json packages/misskey-js/generator/api.json && pnpm --filter misskey-js update-autogen-code && pnpm --filter misskey-js build && pnpm --filter misskey-js api",
"start": "pnpm check:connect && cd packages/backend && node ./built/boot/entry.js", "start": "pnpm check:connect && cd packages/backend && node ./built/boot/entry.js",
"start:test": "ncp ./.github/misskey/test.yml ./.config/test.yml && cd packages/backend && cross-env NODE_ENV=test node ./built/boot/entry.js", "start:test": "ncp ./.github/misskey/test.yml ./.config/test.yml && cd packages/backend && cross-env NODE_ENV=test node ./built/boot/entry.js",
"cli": "cd packages/backend && pnpm cli",
"init": "pnpm migrate", "init": "pnpm migrate",
"migrate": "cd packages/backend && pnpm migrate", "migrate": "cd packages/backend && pnpm migrate",
"revert": "cd packages/backend && pnpm revert", "revert": "cd packages/backend && pnpm revert",
@ -52,30 +53,31 @@
"lodash": "4.17.21" "lodash": "4.17.21"
}, },
"dependencies": { "dependencies": {
"cssnano": "7.1.0", "cssnano": "7.1.1",
"esbuild": "0.25.8", "esbuild": "0.25.10",
"execa": "9.6.0", "execa": "9.6.0",
"fast-glob": "3.3.3", "fast-glob": "3.3.3",
"glob": "11.0.3", "glob": "11.0.3",
"ignore-walk": "7.0.0", "ignore-walk": "7.0.0",
"js-yaml": "4.1.0", "js-yaml": "4.1.0",
"postcss": "8.5.6", "postcss": "8.5.6",
"tar": "7.4.3", "tar": "7.5.1",
"terser": "5.43.1", "terser": "5.44.0",
"typescript": "5.9.2" "typescript": "5.9.2"
}, },
"devDependencies": { "devDependencies": {
"@misskey-dev/eslint-plugin": "2.1.0", "@misskey-dev/eslint-plugin": "2.1.0",
"@types/node": "22.17.1", "@types/js-yaml": "4.0.9",
"@typescript-eslint/eslint-plugin": "8.39.0", "@types/node": "22.18.6",
"@typescript-eslint/parser": "8.39.0", "@typescript-eslint/eslint-plugin": "8.44.1",
"@typescript-eslint/parser": "8.44.1",
"cross-env": "7.0.3", "cross-env": "7.0.3",
"cypress": "14.5.4", "cypress": "14.5.4",
"eslint": "9.33.0", "eslint": "9.36.0",
"globals": "16.3.0", "globals": "16.4.0",
"ncp": "2.0.0", "ncp": "2.0.0",
"pnpm": "10.14.0", "pnpm": "10.17.1",
"start-server-and-test": "2.0.13" "start-server-and-test": "2.1.2"
}, },
"optionalDependencies": { "optionalDependencies": {
"@tensorflow/tfjs-core": "4.22.0" "@tensorflow/tfjs-core": "4.22.0"

View File

@ -0,0 +1,58 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
export class PageCountInNote1755168347001 {
name = 'PageCountInNote1755168347001'
async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "note" ADD "pageCount" smallint NOT NULL DEFAULT '0'`);
// Update existing notes
// block_list CTE collects all page blocks on the pages including child blocks in the section blocks.
// The clipped_notes CTE counts how many distinct pages each note block is referenced in.
// Finally, we update the note table with the count of pages for each referenced note.
await queryRunner.query(`
WITH RECURSIVE block_list AS (
(
SELECT
page.id as page_id,
block as block
FROM page
CROSS JOIN LATERAL jsonb_array_elements(page.content) block
WHERE block->>'type' = 'note' OR block->>'type' = 'section'
)
UNION ALL
(
SELECT
block_list.page_id,
child_block AS block
FROM LATERAL (
SELECT page_id, block
FROM block_list
WHERE block_list.block->>'type' = 'section'
) block_list
CROSS JOIN LATERAL jsonb_array_elements(block_list.block->'children') child_block
WHERE child_block->>'type' = 'note' OR child_block->>'type' = 'section'
)
),
clipped_notes AS (
SELECT
(block->>'note') AS note_id,
COUNT(distinct block_list.page_id) AS count
FROM block_list
WHERE block_list.block->>'type' = 'note'
GROUP BY block->>'note'
)
UPDATE note
SET "pageCount" = clipped_notes.count
FROM clipped_notes
WHERE note.id = clipped_notes.note_id;
`);
}
async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "note" DROP COLUMN "pageCount"`);
}
}

View File

@ -0,0 +1,16 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
export class EntrancePageStyle1755574887486 {
name = 'EntrancePageStyle1755574887486'
async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "meta" ADD "clientOptions" jsonb NOT NULL DEFAULT '{}'`);
}
async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "clientOptions"`);
}
}

View File

@ -0,0 +1,18 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
export class NonCascadingPageEyeCatching1756062689648 {
name = 'NonCascadingPageEyeCatching1756062689648'
async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "page" DROP CONSTRAINT "FK_a9ca79ad939bf06066b81c9d3aa"`);
await queryRunner.query(`ALTER TABLE "page" ADD CONSTRAINT "FK_a9ca79ad939bf06066b81c9d3aa" FOREIGN KEY ("eyeCatchingImageId") REFERENCES "drive_file"("id") ON DELETE SET NULL ON UPDATE NO ACTION`);
}
async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "page" DROP CONSTRAINT "FK_a9ca79ad939bf06066b81c9d3aa"`);
await queryRunner.query(`ALTER TABLE "page" ADD CONSTRAINT "FK_a9ca79ad939bf06066b81c9d3aa" FOREIGN KEY ("eyeCatchingImageId") REFERENCES "drive_file"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
}
}

View File

@ -0,0 +1,16 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
export class SensitiveAd1757823175259 {
name = 'SensitiveAd1757823175259'
async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "ad" ADD "isSensitive" boolean NOT NULL DEFAULT false`);
}
async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "ad" DROP COLUMN "isSensitive"`);
}
}

View File

@ -0,0 +1,24 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
export class ScheduledPost1758677617888 {
name = 'ScheduledPost1758677617888'
/**
* @param {QueryRunner} queryRunner
*/
async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "note_draft" ADD "scheduledAt" TIMESTAMP WITH TIME ZONE`);
await queryRunner.query(`ALTER TABLE "note_draft" ADD "isActuallyScheduled" boolean NOT NULL DEFAULT false`);
}
/**
* @param {QueryRunner} queryRunner
*/
async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "note_draft" DROP COLUMN "isActuallyScheduled"`);
await queryRunner.query(`ALTER TABLE "note_draft" DROP COLUMN "scheduledAt"`);
}
}

View File

@ -11,6 +11,7 @@
"start:test": "cross-env NODE_ENV=test node ./built/boot/entry.js", "start:test": "cross-env NODE_ENV=test node ./built/boot/entry.js",
"migrate": "pnpm typeorm migration:run -d ormconfig.js", "migrate": "pnpm typeorm migration:run -d ormconfig.js",
"revert": "pnpm typeorm migration:revert -d ormconfig.js", "revert": "pnpm typeorm migration:revert -d ormconfig.js",
"cli": "node ./built/boot/cli.js",
"check:connect": "node ./scripts/check_connect.js", "check:connect": "node ./scripts/check_connect.js",
"build": "swc src -d built -D --strip-leading-paths", "build": "swc src -d built -D --strip-leading-paths",
"build:test": "swc test-server -d built-test -D --config-file test-server/.swcrc --strip-leading-paths", "build:test": "swc test-server -d built-test -D --config-file test-server/.swcrc --strip-leading-paths",
@ -38,17 +39,17 @@
}, },
"optionalDependencies": { "optionalDependencies": {
"@swc/core-android-arm64": "1.3.11", "@swc/core-android-arm64": "1.3.11",
"@swc/core-darwin-arm64": "1.12.0", "@swc/core-darwin-arm64": "1.13.19",
"@swc/core-darwin-x64": "1.12.0", "@swc/core-darwin-x64": "1.13.19",
"@swc/core-freebsd-x64": "1.3.11", "@swc/core-freebsd-x64": "1.3.11",
"@swc/core-linux-arm-gnueabihf": "1.12.0", "@swc/core-linux-arm-gnueabihf": "1.13.19",
"@swc/core-linux-arm64-gnu": "1.12.0", "@swc/core-linux-arm64-gnu": "1.13.19",
"@swc/core-linux-arm64-musl": "1.12.0", "@swc/core-linux-arm64-musl": "1.13.19",
"@swc/core-linux-x64-gnu": "1.12.0", "@swc/core-linux-x64-gnu": "1.13.19",
"@swc/core-linux-x64-musl": "1.12.0", "@swc/core-linux-x64-musl": "1.13.19",
"@swc/core-win32-arm64-msvc": "1.12.0", "@swc/core-win32-arm64-msvc": "1.13.19",
"@swc/core-win32-ia32-msvc": "1.12.0", "@swc/core-win32-ia32-msvc": "1.13.19",
"@swc/core-win32-x64-msvc": "1.12.0", "@swc/core-win32-x64-msvc": "1.13.19",
"@tensorflow/tfjs": "4.22.0", "@tensorflow/tfjs": "4.22.0",
"@tensorflow/tfjs-node": "4.22.0", "@tensorflow/tfjs-node": "4.22.0",
"bufferutil": "4.0.9", "bufferutil": "4.0.9",
@ -68,31 +69,31 @@
"utf-8-validate": "6.0.5" "utf-8-validate": "6.0.5"
}, },
"dependencies": { "dependencies": {
"@aws-sdk/client-s3": "3.826.0", "@aws-sdk/client-s3": "3.896.0",
"@aws-sdk/lib-storage": "3.826.0", "@aws-sdk/lib-storage": "3.895.0",
"@discordapp/twemoji": "16.0.1", "@discordapp/twemoji": "16.0.1",
"@fastify/accepts": "5.0.2", "@fastify/accepts": "5.0.2",
"@fastify/cookie": "11.0.2", "@fastify/cookie": "11.0.2",
"@fastify/cors": "10.1.0", "@fastify/cors": "10.1.0",
"@fastify/express": "4.0.2", "@fastify/express": "4.0.2",
"@fastify/http-proxy": "10.0.2", "@fastify/http-proxy": "10.0.2",
"@fastify/multipart": "9.0.3", "@fastify/multipart": "9.2.1",
"@fastify/static": "8.2.0", "@fastify/static": "8.2.0",
"@fastify/view": "10.0.2", "@fastify/view": "10.0.2",
"@misskey-dev/sharp-read-bmp": "1.2.0", "@misskey-dev/sharp-read-bmp": "1.2.0",
"@misskey-dev/summaly": "5.2.1", "@misskey-dev/summaly": "5.2.3",
"@napi-rs/canvas": "0.1.71", "@napi-rs/canvas": "0.1.80",
"@nestjs/common": "11.1.3", "@nestjs/common": "11.1.6",
"@nestjs/core": "11.1.3", "@nestjs/core": "11.1.6",
"@nestjs/testing": "11.1.3", "@nestjs/testing": "11.1.6",
"@peertube/http-signature": "1.7.0", "@peertube/http-signature": "1.7.0",
"@sentry/node": "8.55.0", "@sentry/node": "8.55.0",
"@sentry/profiling-node": "8.55.0", "@sentry/profiling-node": "8.55.0",
"@simplewebauthn/server": "12.0.0", "@simplewebauthn/server": "12.0.0",
"@sinonjs/fake-timers": "11.3.1", "@sinonjs/fake-timers": "11.3.1",
"@smithy/node-http-handler": "2.5.0", "@smithy/node-http-handler": "2.5.0",
"@swc/cli": "0.7.7", "@swc/cli": "0.7.8",
"@swc/core": "1.12.0", "@swc/core": "1.13.5",
"@twemoji/parser": "16.0.0", "@twemoji/parser": "16.0.0",
"@types/redis-info": "3.0.3", "@types/redis-info": "3.0.3",
"accepts": "1.3.8", "accepts": "1.3.8",
@ -102,29 +103,29 @@
"bcryptjs": "2.4.3", "bcryptjs": "2.4.3",
"blurhash": "2.0.5", "blurhash": "2.0.5",
"body-parser": "1.20.3", "body-parser": "1.20.3",
"bullmq": "5.53.2", "bullmq": "5.58.8",
"cacheable-lookup": "7.0.0", "cacheable-lookup": "7.0.0",
"cbor": "9.0.2", "cbor": "9.0.2",
"chalk": "5.4.1", "chalk": "5.6.2",
"chalk-template": "1.1.0", "chalk-template": "1.1.2",
"chokidar": "4.0.3", "chokidar": "4.0.3",
"cli-highlight": "2.1.11", "cli-highlight": "2.1.11",
"color-convert": "2.0.1", "color-convert": "2.0.1",
"content-disposition": "0.5.4", "content-disposition": "0.5.4",
"date-fns": "2.30.0", "date-fns": "2.30.0",
"deep-email-validator": "0.1.21", "deep-email-validator": "0.1.21",
"fastify": "5.3.3", "fastify": "5.6.1",
"fastify-raw-body": "5.0.0", "fastify-raw-body": "5.0.0",
"feed": "4.2.2", "feed": "4.2.2",
"file-type": "19.6.0", "file-type": "19.6.0",
"fluent-ffmpeg": "2.1.3", "fluent-ffmpeg": "2.1.3",
"form-data": "4.0.3", "form-data": "4.0.4",
"got": "14.4.7", "got": "14.4.9",
"happy-dom": "16.8.1", "happy-dom": "16.8.1",
"hpagent": "1.2.0", "hpagent": "1.2.0",
"htmlescape": "1.1.1", "htmlescape": "1.1.1",
"http-link-header": "1.1.3", "http-link-header": "1.1.3",
"ioredis": "5.6.1", "ioredis": "5.8.0",
"ip-cidr": "4.0.2", "ip-cidr": "4.0.2",
"ipaddr.js": "2.2.0", "ipaddr.js": "2.2.0",
"is-svg": "5.1.0", "is-svg": "5.1.0",
@ -134,14 +135,14 @@
"jsonld": "8.3.3", "jsonld": "8.3.3",
"jsrsasign": "11.1.0", "jsrsasign": "11.1.0",
"juice": "11.0.1", "juice": "11.0.1",
"meilisearch": "0.51.0", "meilisearch": "0.53.0",
"mfm-js": "0.25.0", "mfm-js": "0.25.0",
"microformats-parser": "2.0.3", "microformats-parser": "2.0.4",
"mime-types": "2.1.35", "mime-types": "2.1.35",
"misskey-js": "workspace:*", "misskey-js": "workspace:*",
"misskey-reversi": "workspace:*", "misskey-reversi": "workspace:*",
"ms": "3.0.0-canary.1", "ms": "3.0.0-canary.202508261828",
"nanoid": "5.1.5", "nanoid": "5.1.6",
"nested-property": "4.0.0", "nested-property": "4.0.0",
"node-fetch": "3.3.2", "node-fetch": "3.3.2",
"nodemailer": "6.10.1", "nodemailer": "6.10.1",
@ -150,9 +151,9 @@
"oauth2orize": "1.12.0", "oauth2orize": "1.12.0",
"oauth2orize-pkce": "0.1.2", "oauth2orize-pkce": "0.1.2",
"os-utils": "0.0.14", "os-utils": "0.0.14",
"otpauth": "9.4.0", "otpauth": "9.4.1",
"parse5": "7.3.0", "parse5": "7.3.0",
"pg": "8.16.0", "pg": "8.16.3",
"pkce-challenge": "4.1.0", "pkce-challenge": "4.1.0",
"probe-image-size": "7.2.3", "probe-image-size": "7.2.3",
"promise-limit": "2.7.0", "promise-limit": "2.7.0",
@ -174,25 +175,25 @@
"slacc": "0.0.10", "slacc": "0.0.10",
"strict-event-emitter-types": "2.0.0", "strict-event-emitter-types": "2.0.0",
"stringz": "2.1.0", "stringz": "2.1.0",
"systeminformation": "5.27.1", "systeminformation": "5.27.10",
"tinycolor2": "1.6.0", "tinycolor2": "1.6.0",
"tmp": "0.2.3", "tmp": "0.2.5",
"tsc-alias": "1.8.16", "tsc-alias": "1.8.16",
"tsconfig-paths": "4.2.0", "tsconfig-paths": "4.2.0",
"typeorm": "0.3.24", "typeorm": "0.3.27",
"typescript": "5.8.3", "typescript": "5.9.2",
"ulid": "2.4.0", "ulid": "2.4.0",
"vary": "1.1.2", "vary": "1.1.2",
"web-push": "3.6.7", "web-push": "3.6.7",
"ws": "8.18.2", "ws": "8.18.3",
"xev": "3.0.2" "xev": "3.0.2"
}, },
"devDependencies": { "devDependencies": {
"@jest/globals": "29.7.0", "@jest/globals": "29.7.0",
"@nestjs/platform-express": "10.4.19", "@nestjs/platform-express": "10.4.20",
"@sentry/vue": "9.28.0", "@sentry/vue": "9.46.0",
"@simplewebauthn/types": "12.0.0", "@simplewebauthn/types": "12.0.0",
"@swc/jest": "0.2.38", "@swc/jest": "0.2.39",
"@types/accepts": "1.3.7", "@types/accepts": "1.3.7",
"@types/archiver": "6.0.3", "@types/archiver": "6.0.3",
"@types/bcryptjs": "2.4.6", "@types/bcryptjs": "2.4.6",
@ -209,19 +210,19 @@
"@types/jsrsasign": "10.5.15", "@types/jsrsasign": "10.5.15",
"@types/mime-types": "2.1.4", "@types/mime-types": "2.1.4",
"@types/ms": "0.7.34", "@types/ms": "0.7.34",
"@types/node": "22.15.31", "@types/node": "22.18.6",
"@types/nodemailer": "6.4.17", "@types/nodemailer": "6.4.19",
"@types/oauth": "0.9.6", "@types/oauth": "0.9.6",
"@types/oauth2orize": "1.11.5", "@types/oauth2orize": "1.11.5",
"@types/oauth2orize-pkce": "0.1.2", "@types/oauth2orize-pkce": "0.1.2",
"@types/pg": "8.15.4", "@types/pg": "8.15.5",
"@types/pug": "2.0.10", "@types/pug": "2.0.10",
"@types/qrcode": "1.5.5", "@types/qrcode": "1.5.5",
"@types/random-seed": "0.3.5", "@types/random-seed": "0.3.5",
"@types/ratelimiter": "3.4.6", "@types/ratelimiter": "3.4.6",
"@types/rename": "1.0.7", "@types/rename": "1.0.7",
"@types/sanitize-html": "2.16.0", "@types/sanitize-html": "2.16.0",
"@types/semver": "7.7.0", "@types/semver": "7.7.1",
"@types/simple-oauth2": "5.0.7", "@types/simple-oauth2": "5.0.7",
"@types/sinonjs__fake-timers": "8.1.5", "@types/sinonjs__fake-timers": "8.1.5",
"@types/supertest": "6.0.3", "@types/supertest": "6.0.3",
@ -230,11 +231,11 @@
"@types/vary": "1.1.3", "@types/vary": "1.1.3",
"@types/web-push": "3.6.4", "@types/web-push": "3.6.4",
"@types/ws": "8.18.1", "@types/ws": "8.18.1",
"@typescript-eslint/eslint-plugin": "8.34.0", "@typescript-eslint/eslint-plugin": "8.44.1",
"@typescript-eslint/parser": "8.34.0", "@typescript-eslint/parser": "8.44.1",
"aws-sdk-client-mock": "4.1.0", "aws-sdk-client-mock": "4.1.0",
"cross-env": "7.0.3", "cross-env": "7.0.3",
"eslint-plugin-import": "2.31.0", "eslint-plugin-import": "2.32.0",
"execa": "8.0.1", "execa": "8.0.1",
"fkill": "9.0.0", "fkill": "9.0.0",
"jest": "29.7.0", "jest": "29.7.0",
@ -242,6 +243,6 @@
"nodemon": "3.1.10", "nodemon": "3.1.10",
"pid-port": "1.0.2", "pid-port": "1.0.2",
"simple-oauth2": "5.1.0", "simple-oauth2": "5.1.0",
"supertest": "7.1.1" "supertest": "7.1.4"
} }
} }

View File

@ -0,0 +1,49 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
import 'reflect-metadata';
import { EventEmitter } from 'node:events';
import { NestFactory } from '@nestjs/core';
import { CommandModule } from '@/cli/CommandModule.js';
import { NestLogger } from '@/NestLogger.js';
import { CommandService } from '@/cli/CommandService.js';
process.title = 'Misskey Cli';
Error.stackTraceLimit = Infinity;
EventEmitter.defaultMaxListeners = 128;
const app = await NestFactory.createApplicationContext(CommandModule, {
logger: new NestLogger(),
});
const commandService = app.get(CommandService);
const command = process.argv[2] ?? 'help';
switch (command) {
case 'help': {
console.log('Available commands:');
console.log(' help - Displays this help message');
console.log(' reset-captcha - Resets the captcha');
break;
}
case 'ping': {
await commandService.ping();
break;
}
case 'reset-captcha': {
await commandService.resetCaptcha();
console.log('Captcha has been reset.');
break;
}
default: {
console.error(`Unrecognized command: ${command}`);
console.error('Use "help" to see available commands.');
process.exit(1);
}
}
process.exit(0);

View File

@ -0,0 +1,23 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { Module } from '@nestjs/common';
import { CoreModule } from '@/core/CoreModule.js';
import { GlobalModule } from '@/GlobalModule.js';
import { CommandService } from './CommandService.js';
@Module({
imports: [
GlobalModule,
CoreModule,
],
providers: [
CommandService,
],
exports: [
CommandService,
],
})
export class CommandModule {}

View File

@ -0,0 +1,49 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { Inject, Injectable } from '@nestjs/common';
import type { Config } from '@/config.js';
import { DI } from '@/di-symbols.js';
import type Logger from '@/logger.js';
import { bindThis } from '@/decorators.js';
import { MetaService } from '@/core/MetaService.js';
@Injectable()
export class CommandService {
private logger: Logger;
constructor(
@Inject(DI.config)
private config: Config,
private metaService: MetaService,
) {
}
@bindThis
public async ping() {
console.log('pong');
}
@bindThis
public async resetCaptcha() {
await this.metaService.update({
enableHcaptcha: false,
hcaptchaSiteKey: null,
hcaptchaSecretKey: null,
enableMcaptcha: false,
mcaptchaSitekey: null,
mcaptchaSecretKey: null,
mcaptchaInstanceUrl: null,
enableRecaptcha: false,
recaptchaSiteKey: null,
recaptchaSecretKey: null,
enableTurnstile: false,
turnstileSiteKey: null,
turnstileSecretKey: null,
enableTestcaptcha: false,
});
}
}

View File

@ -7,6 +7,7 @@ import * as fs from 'node:fs';
import { fileURLToPath } from 'node:url'; import { fileURLToPath } from 'node:url';
import { dirname, resolve } from 'node:path'; import { dirname, resolve } from 'node:path';
import * as yaml from 'js-yaml'; import * as yaml from 'js-yaml';
import { type FastifyServerOptions } from 'fastify';
import type * as Sentry from '@sentry/node'; import type * as Sentry from '@sentry/node';
import type * as SentryVue from '@sentry/vue'; import type * as SentryVue from '@sentry/vue';
import type { RedisOptions } from 'ioredis'; import type { RedisOptions } from 'ioredis';
@ -27,6 +28,7 @@ type Source = {
url?: string; url?: string;
port?: number; port?: number;
socket?: string; socket?: string;
trustProxy?: FastifyServerOptions['trustProxy'];
chmodSocket?: string; chmodSocket?: string;
disableHsts?: boolean; disableHsts?: boolean;
db: { db: {
@ -118,6 +120,7 @@ export type Config = {
url: string; url: string;
port: number; port: number;
socket: string | undefined; socket: string | undefined;
trustProxy: FastifyServerOptions['trustProxy'];
chmodSocket: string | undefined; chmodSocket: string | undefined;
disableHsts: boolean | undefined; disableHsts: boolean | undefined;
db: { db: {
@ -266,6 +269,7 @@ export function loadConfig(): Config {
url: url.origin, url: url.origin,
port: config.port ?? parseInt(process.env.PORT ?? '', 10), port: config.port ?? parseInt(process.env.PORT ?? '', 10),
socket: config.socket, socket: config.socket,
trustProxy: config.trustProxy,
chmodSocket: config.chmodSocket, chmodSocket: config.chmodSocket,
disableHsts: config.disableHsts, disableHsts: config.disableHsts,
host, host,

View File

@ -29,7 +29,7 @@ export class AiService {
} }
@bindThis @bindThis
public async detectSensitive(path: string): Promise<nsfw.PredictionType[] | null> { public async detectSensitive(source: string | Buffer): Promise<nsfw.PredictionType[] | null> {
try { try {
if (isSupportedCpu === undefined) { if (isSupportedCpu === undefined) {
isSupportedCpu = await this.computeIsSupportedCpu(); isSupportedCpu = await this.computeIsSupportedCpu();
@ -51,7 +51,7 @@ export class AiService {
}); });
} }
const buffer = await fs.promises.readFile(path); const buffer = source instanceof Buffer ? source : await fs.promises.readFile(source);
const image = await tf.node.decodeImage(buffer, 3) as any; const image = await tf.node.decodeImage(buffer, 3) as any;
try { try {
const predictions = await this.model.classify(image); const predictions = await this.model.classify(image);

View File

@ -78,6 +78,7 @@ import { ChannelFollowingService } from './ChannelFollowingService.js';
import { ChatService } from './ChatService.js'; import { ChatService } from './ChatService.js';
import { RegistryApiService } from './RegistryApiService.js'; import { RegistryApiService } from './RegistryApiService.js';
import { ReversiService } from './ReversiService.js'; import { ReversiService } from './ReversiService.js';
import { PageService } from './PageService.js';
import { ChartLoggerService } from './chart/ChartLoggerService.js'; import { ChartLoggerService } from './chart/ChartLoggerService.js';
import FederationChart from './chart/charts/federation.js'; import FederationChart from './chart/charts/federation.js';
@ -227,6 +228,7 @@ const $ChannelFollowingService: Provider = { provide: 'ChannelFollowingService',
const $ChatService: Provider = { provide: 'ChatService', useExisting: ChatService }; const $ChatService: Provider = { provide: 'ChatService', useExisting: ChatService };
const $RegistryApiService: Provider = { provide: 'RegistryApiService', useExisting: RegistryApiService }; const $RegistryApiService: Provider = { provide: 'RegistryApiService', useExisting: RegistryApiService };
const $ReversiService: Provider = { provide: 'ReversiService', useExisting: ReversiService }; const $ReversiService: Provider = { provide: 'ReversiService', useExisting: ReversiService };
const $PageService: Provider = { provide: 'PageService', useExisting: PageService };
const $ChartLoggerService: Provider = { provide: 'ChartLoggerService', useExisting: ChartLoggerService }; const $ChartLoggerService: Provider = { provide: 'ChartLoggerService', useExisting: ChartLoggerService };
const $FederationChart: Provider = { provide: 'FederationChart', useExisting: FederationChart }; const $FederationChart: Provider = { provide: 'FederationChart', useExisting: FederationChart };
@ -379,6 +381,7 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting
ChatService, ChatService,
RegistryApiService, RegistryApiService,
ReversiService, ReversiService,
PageService,
ChartLoggerService, ChartLoggerService,
FederationChart, FederationChart,
@ -527,6 +530,7 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting
$ChatService, $ChatService,
$RegistryApiService, $RegistryApiService,
$ReversiService, $ReversiService,
$PageService,
$ChartLoggerService, $ChartLoggerService,
$FederationChart, $FederationChart,
@ -676,6 +680,7 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting
ChatService, ChatService,
RegistryApiService, RegistryApiService,
ReversiService, ReversiService,
PageService,
FederationChart, FederationChart,
NotesChart, NotesChart,
@ -822,6 +827,7 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting
$ChatService, $ChatService,
$RegistryApiService, $RegistryApiService,
$ReversiService, $ReversiService,
$PageService,
$FederationChart, $FederationChart,
$NotesChart, $NotesChart,

View File

@ -21,6 +21,7 @@ import { LoggerService } from '@/core/LoggerService.js';
import type Logger from '@/logger.js'; import type Logger from '@/logger.js';
import { bindThis } from '@/decorators.js'; import { bindThis } from '@/decorators.js';
import type { PredictionType } from 'nsfwjs'; import type { PredictionType } from 'nsfwjs';
import { isMimeImage } from '@/misc/is-mime-image.js';
export type FileInfo = { export type FileInfo = {
size: number; size: number;
@ -204,16 +205,7 @@ export class FileInfoService {
return [sensitive, porn]; return [sensitive, porn];
} }
if ([ if (analyzeVideo && (mime === 'image/apng' || mime.startsWith('video/'))) {
'image/jpeg',
'image/png',
'image/webp',
].includes(mime)) {
const result = await this.aiService.detectSensitive(source);
if (result) {
[sensitive, porn] = judgePrediction(result);
}
} else if (analyzeVideo && (mime === 'image/apng' || mime.startsWith('video/'))) {
const [outDir, disposeOutDir] = await createTempDir(); const [outDir, disposeOutDir] = await createTempDir();
try { try {
const command = FFmpeg() const command = FFmpeg()
@ -281,6 +273,23 @@ export class FileInfoService {
} finally { } finally {
disposeOutDir(); disposeOutDir();
} }
} else if (isMimeImage(mime, 'sharp-convertible-image-with-bmp')) {
/*
* tfjs-node sharp PNG
* 使299x299に事前にリサイズする
*/
const png = await (await sharpBmp(source, mime))
.resize(299, 299, {
withoutEnlargement: false,
})
.rotate()
.flatten({ background: { r: 119, g: 119, b: 119 } }) // 透過部分を18%グレーで塗りつぶす
.png()
.toBuffer();
const result = await this.aiService.detectSensitive(png);
if (result) {
[sensitive, porn] = judgePrediction(result);
}
} }
return [sensitive, porn]; return [sensitive, porn];

View File

@ -6,6 +6,7 @@
import * as http from 'node:http'; import * as http from 'node:http';
import * as https from 'node:https'; import * as https from 'node:https';
import * as net from 'node:net'; import * as net from 'node:net';
import * as stream from 'node:stream';
import ipaddr from 'ipaddr.js'; import ipaddr from 'ipaddr.js';
import CacheableLookup from 'cacheable-lookup'; import CacheableLookup from 'cacheable-lookup';
import fetch from 'node-fetch'; import fetch from 'node-fetch';
@ -26,12 +27,6 @@ export type HttpRequestSendOptions = {
validators?: ((res: Response) => void)[]; validators?: ((res: Response) => void)[];
}; };
declare module 'node:http' {
interface Agent {
createConnection(options: net.NetConnectOpts, callback?: (err: unknown, stream: net.Socket) => void): net.Socket;
}
}
class HttpRequestServiceAgent extends http.Agent { class HttpRequestServiceAgent extends http.Agent {
constructor( constructor(
private config: Config, private config: Config,
@ -41,18 +36,24 @@ class HttpRequestServiceAgent extends http.Agent {
} }
@bindThis @bindThis
public createConnection(options: net.NetConnectOpts, callback?: (err: unknown, stream: net.Socket) => void): net.Socket { public createConnection(options: http.ClientRequestArgs, callback?: (err: Error | null, stream: stream.Duplex) => void): stream.Duplex {
const socket = super.createConnection(options, callback) const socket = super.createConnection(options, callback);
.on('connect', () => {
if (socket == null) {
throw new Error('Failed to create socket');
}
socket.on('connect', () => {
if (socket instanceof net.Socket && process.env.NODE_ENV === 'production') {
const address = socket.remoteAddress; const address = socket.remoteAddress;
if (process.env.NODE_ENV === 'production') { if (address && ipaddr.isValid(address)) {
if (address && ipaddr.isValid(address)) { if (this.isPrivateIp(address)) {
if (this.isPrivateIp(address)) { socket.destroy(new Error(`Blocked address: ${address}`));
socket.destroy(new Error(`Blocked address: ${address}`));
}
} }
} }
}); }
});
return socket; return socket;
} }
@ -80,18 +81,24 @@ class HttpsRequestServiceAgent extends https.Agent {
} }
@bindThis @bindThis
public createConnection(options: net.NetConnectOpts, callback?: (err: unknown, stream: net.Socket) => void): net.Socket { public createConnection(options: http.ClientRequestArgs, callback?: (err: Error | null, stream: stream.Duplex) => void): stream.Duplex {
const socket = super.createConnection(options, callback) const socket = super.createConnection(options, callback);
.on('connect', () => {
if (socket == null) {
throw new Error('Failed to create socket');
}
socket.on('connect', () => {
if (socket instanceof net.Socket && process.env.NODE_ENV === 'production') {
const address = socket.remoteAddress; const address = socket.remoteAddress;
if (process.env.NODE_ENV === 'production') { if (address && ipaddr.isValid(address)) {
if (address && ipaddr.isValid(address)) { if (this.isPrivateIp(address)) {
if (this.isPrivateIp(address)) { socket.destroy(new Error(`Blocked address: ${address}`));
socket.destroy(new Error(`Blocked address: ${address}`));
}
} }
} }
}); }
});
return socket; return socket;
} }

View File

@ -13,7 +13,7 @@ import { extractCustomEmojisFromMfm } from '@/misc/extract-custom-emojis-from-mf
import { extractHashtags } from '@/misc/extract-hashtags.js'; import { extractHashtags } from '@/misc/extract-hashtags.js';
import type { IMentionedRemoteUsers } from '@/models/Note.js'; import type { IMentionedRemoteUsers } from '@/models/Note.js';
import { MiNote } from '@/models/Note.js'; import { MiNote } from '@/models/Note.js';
import type { ChannelFollowingsRepository, ChannelsRepository, FollowingsRepository, InstancesRepository, MiFollowing, MiMeta, MutingsRepository, NotesRepository, NoteThreadMutingsRepository, UserListMembershipsRepository, UserProfilesRepository, UsersRepository } from '@/models/_.js'; import type { BlockingsRepository, ChannelFollowingsRepository, ChannelsRepository, DriveFilesRepository, FollowingsRepository, InstancesRepository, MiFollowing, MiMeta, MutingsRepository, NotesRepository, NoteThreadMutingsRepository, UserListMembershipsRepository, UserProfilesRepository, UsersRepository } from '@/models/_.js';
import type { MiDriveFile } from '@/models/DriveFile.js'; import type { MiDriveFile } from '@/models/DriveFile.js';
import type { MiApp } from '@/models/App.js'; import type { MiApp } from '@/models/App.js';
import { concat } from '@/misc/prelude/array.js'; import { concat } from '@/misc/prelude/array.js';
@ -56,6 +56,7 @@ import { trackPromise } from '@/misc/promise-tracker.js';
import { IdentifiableError } from '@/misc/identifiable-error.js'; import { IdentifiableError } from '@/misc/identifiable-error.js';
import { CollapsedQueue } from '@/misc/collapsed-queue.js'; import { CollapsedQueue } from '@/misc/collapsed-queue.js';
import { CacheService } from '@/core/CacheService.js'; import { CacheService } from '@/core/CacheService.js';
import { isQuote, isRenote } from '@/misc/is-renote.js';
type NotificationType = 'reply' | 'renote' | 'quote' | 'mention'; type NotificationType = 'reply' | 'renote' | 'quote' | 'mention';
@ -192,6 +193,12 @@ export class NoteCreateService implements OnApplicationShutdown {
@Inject(DI.channelFollowingsRepository) @Inject(DI.channelFollowingsRepository)
private channelFollowingsRepository: ChannelFollowingsRepository, private channelFollowingsRepository: ChannelFollowingsRepository,
@Inject(DI.blockingsRepository)
private blockingsRepository: BlockingsRepository,
@Inject(DI.driveFilesRepository)
private driveFilesRepository: DriveFilesRepository,
private userEntityService: UserEntityService, private userEntityService: UserEntityService,
private noteEntityService: NoteEntityService, private noteEntityService: NoteEntityService,
private idService: IdService, private idService: IdService,
@ -221,6 +228,167 @@ export class NoteCreateService implements OnApplicationShutdown {
this.updateNotesCountQueue = new CollapsedQueue(process.env.NODE_ENV !== 'test' ? 60 * 1000 * 5 : 0, this.collapseNotesCount, this.performUpdateNotesCount); this.updateNotesCountQueue = new CollapsedQueue(process.env.NODE_ENV !== 'test' ? 60 * 1000 * 5 : 0, this.collapseNotesCount, this.performUpdateNotesCount);
} }
@bindThis
public async fetchAndCreate(user: {
id: MiUser['id'];
username: MiUser['username'];
host: MiUser['host'];
isBot: MiUser['isBot'];
isCat: MiUser['isCat'];
}, data: {
createdAt: Date;
replyId: MiNote['id'] | null;
renoteId: MiNote['id'] | null;
fileIds: MiDriveFile['id'][];
text: string | null;
cw: string | null;
visibility: string;
visibleUserIds: MiUser['id'][];
channelId: MiChannel['id'] | null;
localOnly: boolean;
reactionAcceptance: MiNote['reactionAcceptance'];
poll: IPoll | null;
apMentions?: MinimumUser[] | null;
apHashtags?: string[] | null;
apEmojis?: string[] | null;
}): Promise<MiNote> {
const visibleUsers = data.visibleUserIds.length > 0 ? await this.usersRepository.findBy({
id: In(data.visibleUserIds),
}) : [];
let files: MiDriveFile[] = [];
if (data.fileIds.length > 0) {
files = await this.driveFilesRepository.createQueryBuilder('file')
.where('file.userId = :userId AND file.id IN (:...fileIds)', {
userId: user.id,
fileIds: data.fileIds,
})
.orderBy('array_position(ARRAY[:...fileIds], "id"::text)')
.setParameters({ fileIds: data.fileIds })
.getMany();
if (files.length !== data.fileIds.length) {
throw new IdentifiableError('801c046c-5bf5-4234-ad2b-e78fc20a2ac7', 'No such file');
}
}
let renote: MiNote | null = null;
if (data.renoteId != null) {
// Fetch renote to note
renote = await this.notesRepository.findOne({
where: { id: data.renoteId },
relations: ['user', 'renote', 'reply'],
});
if (renote == null) {
throw new IdentifiableError('53983c56-e163-45a6-942f-4ddc485d4290', 'No such renote target');
} else if (isRenote(renote) && !isQuote(renote)) {
throw new IdentifiableError('bde24c37-121f-4e7d-980d-cec52f599f02', 'Cannot renote pure renote');
}
// Check blocking
if (renote.userId !== user.id) {
const blockExist = await this.blockingsRepository.exists({
where: {
blockerId: renote.userId,
blockeeId: user.id,
},
});
if (blockExist) {
throw new IdentifiableError('2b4fe776-4414-4a2d-ae39-f3418b8fd4d3', 'You have been blocked by the user');
}
}
if (renote.visibility === 'followers' && renote.userId !== user.id) {
// 他人のfollowers noteはreject
throw new IdentifiableError('90b9d6f0-893a-4fef-b0f1-e9a33989f71a', 'Renote target visibility');
} else if (renote.visibility === 'specified') {
// specified / direct noteはreject
throw new IdentifiableError('48d7a997-da5c-4716-b3c3-92db3f37bf7d', 'Renote target visibility');
}
if (renote.channelId && renote.channelId !== data.channelId) {
// チャンネルのノートに対しリノート要求がきたとき、チャンネル外へのリノート可否をチェック
// リートのユースケースのうち、チャンネル内→チャンネル外は少数だと考えられるため、JOINはせず必要な時に都度取得する
const renoteChannel = await this.channelsRepository.findOneBy({ id: renote.channelId });
if (renoteChannel == null) {
// リノートしたいノートが書き込まれているチャンネルが無い
throw new IdentifiableError('b060f9a6-8909-4080-9e0b-94d9fa6f6a77', 'No such channel');
} else if (!renoteChannel.allowRenoteToExternal) {
// リノート作成のリクエストだが、対象チャンネルがリノート禁止だった場合
throw new IdentifiableError('7e435f4a-780d-4cfc-a15a-42519bd6fb67', 'Channel does not allow renote to external');
}
}
}
let reply: MiNote | null = null;
if (data.replyId != null) {
// Fetch reply
reply = await this.notesRepository.findOne({
where: { id: data.replyId },
relations: ['user'],
});
if (reply == null) {
throw new IdentifiableError('60142edb-1519-408e-926d-4f108d27bee0', 'No such reply target');
} else if (isRenote(reply) && !isQuote(reply)) {
throw new IdentifiableError('f089e4e2-c0e7-4f60-8a23-e5a6bf786b36', 'Cannot reply to pure renote');
} else if (!await this.noteEntityService.isVisibleForMe(reply, user.id)) {
throw new IdentifiableError('11cd37b3-a411-4f77-8633-c580ce6a8dce', 'No such reply target');
} else if (reply.visibility === 'specified' && data.visibility !== 'specified') {
throw new IdentifiableError('ced780a1-2012-4caf-bc7e-a95a291294cb', 'Cannot reply to specified note with different visibility');
}
// Check blocking
if (reply.userId !== user.id) {
const blockExist = await this.blockingsRepository.exists({
where: {
blockerId: reply.userId,
blockeeId: user.id,
},
});
if (blockExist) {
throw new IdentifiableError('b0df6025-f2e8-44b4-a26a-17ad99104612', 'You have been blocked by the user');
}
}
}
if (data.poll) {
if (data.poll.expiresAt != null) {
if (data.poll.expiresAt.getTime() < Date.now()) {
throw new IdentifiableError('0c11c11e-0c8d-48e7-822c-76ccef660068', 'Poll expiration must be future time');
}
}
}
let channel: MiChannel | null = null;
if (data.channelId != null) {
channel = await this.channelsRepository.findOneBy({ id: data.channelId, isArchived: false });
if (channel == null) {
throw new IdentifiableError('bfa3905b-25f5-4894-b430-da331a490e4b', 'No such channel');
}
}
return this.create(user, {
createdAt: data.createdAt,
files: files,
poll: data.poll,
text: data.text,
reply,
renote,
cw: data.cw,
localOnly: data.localOnly,
reactionAcceptance: data.reactionAcceptance,
visibility: data.visibility,
visibleUsers,
channel,
apMentions: data.apMentions,
apHashtags: data.apHashtags,
apEmojis: data.apEmojis,
});
}
@bindThis @bindThis
public async create(user: { public async create(user: {
id: MiUser['id']; id: MiUser['id'];

View File

@ -5,32 +5,18 @@
import { Inject, Injectable } from '@nestjs/common'; import { Inject, Injectable } from '@nestjs/common';
import { In } from 'typeorm'; import { In } from 'typeorm';
import type { noteVisibilities, noteReactionAcceptances } from '@/types.js';
import { DI } from '@/di-symbols.js'; import { DI } from '@/di-symbols.js';
import type { MiNoteDraft, NoteDraftsRepository, MiNote, MiDriveFile, MiChannel, UsersRepository, DriveFilesRepository, NotesRepository, BlockingsRepository, ChannelsRepository } from '@/models/_.js'; import type { MiNoteDraft, NoteDraftsRepository, MiNote, MiDriveFile, MiChannel, UsersRepository, DriveFilesRepository, NotesRepository, BlockingsRepository, ChannelsRepository } from '@/models/_.js';
import { bindThis } from '@/decorators.js'; import { bindThis } from '@/decorators.js';
import { RoleService } from '@/core/RoleService.js'; import { RoleService } from '@/core/RoleService.js';
import { IdService } from '@/core/IdService.js'; import { IdService } from '@/core/IdService.js';
import type { MiLocalUser, MiUser } from '@/models/User.js'; import type { MiLocalUser, MiUser } from '@/models/User.js';
import { IPoll } from '@/models/Poll.js';
import { IdentifiableError } from '@/misc/identifiable-error.js'; import { IdentifiableError } from '@/misc/identifiable-error.js';
import { isRenote, isQuote } from '@/misc/is-renote.js'; import { isRenote, isQuote } from '@/misc/is-renote.js';
import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
import { QueueService } from '@/core/QueueService.js';
export type NoteDraftOptions = { export type NoteDraftOptions = Omit<MiNoteDraft, 'id' | 'userId' | 'user' | 'reply' | 'renote' | 'channel'>;
replyId?: MiNote['id'] | null;
renoteId?: MiNote['id'] | null;
text?: string | null;
cw?: string | null;
localOnly?: boolean | null;
reactionAcceptance?: typeof noteReactionAcceptances[number];
visibility?: typeof noteVisibilities[number];
fileIds?: MiDriveFile['id'][];
visibleUserIds?: MiUser['id'][];
hashtag?: string;
channelId?: MiChannel['id'] | null;
poll?: (IPoll & { expiredAfter?: number | null }) | null;
};
@Injectable() @Injectable()
export class NoteDraftService { export class NoteDraftService {
@ -56,6 +42,7 @@ export class NoteDraftService {
private roleService: RoleService, private roleService: RoleService,
private idService: IdService, private idService: IdService,
private noteEntityService: NoteEntityService, private noteEntityService: NoteEntityService,
private queueService: QueueService,
) { ) {
} }
@ -72,36 +59,43 @@ export class NoteDraftService {
@bindThis @bindThis
public async create(me: MiLocalUser, data: NoteDraftOptions): Promise<MiNoteDraft> { public async create(me: MiLocalUser, data: NoteDraftOptions): Promise<MiNoteDraft> {
//#region check draft limit //#region check draft limit
const policies = await this.roleService.getUserPolicies(me.id);
const currentCount = await this.noteDraftsRepository.countBy({ const currentCount = await this.noteDraftsRepository.countBy({
userId: me.id, userId: me.id,
}); });
if (currentCount >= (await this.roleService.getUserPolicies(me.id)).noteDraftLimit) { if (currentCount >= policies.noteDraftLimit) {
throw new IdentifiableError('9ee33bbe-fde3-4c71-9b51-e50492c6b9c8', 'Too many drafts'); throw new IdentifiableError('9ee33bbe-fde3-4c71-9b51-e50492c6b9c8', 'Too many drafts');
} }
if (data.isActuallyScheduled) {
const currentScheduledCount = await this.noteDraftsRepository.countBy({
userId: me.id,
isActuallyScheduled: true,
});
if (currentScheduledCount >= policies.scheduledNoteLimit) {
throw new IdentifiableError('c3275f19-4558-4c59-83e1-4f684b5fab66', 'Too many scheduled notes');
}
}
//#endregion //#endregion
if (data.poll) { await this.validate(me, data);
if (typeof data.poll.expiresAt === 'number') {
if (data.poll.expiresAt < Date.now()) { const draft = await this.noteDraftsRepository.insertOne({
throw new IdentifiableError('04da457d-b083-4055-9082-955525eda5a5', 'Cannot create expired poll'); ...data,
} id: this.idService.gen(),
} else if (typeof data.poll.expiredAfter === 'number') { userId: me.id,
data.poll.expiresAt = new Date(Date.now() + data.poll.expiredAfter); });
}
if (draft.scheduledAt && draft.isActuallyScheduled) {
this.schedule(draft);
} }
const appliedDraft = await this.checkAndSetDraftNoteOptions(me, this.noteDraftsRepository.create(), data);
appliedDraft.id = this.idService.gen();
appliedDraft.userId = me.id;
const draft = this.noteDraftsRepository.save(appliedDraft);
return draft; return draft;
} }
@bindThis @bindThis
public async update(me: MiLocalUser, draftId: MiNoteDraft['id'], data: NoteDraftOptions): Promise<MiNoteDraft> { public async update(me: MiLocalUser, draftId: MiNoteDraft['id'], data: Partial<NoteDraftOptions>): Promise<MiNoteDraft> {
const draft = await this.noteDraftsRepository.findOneBy({ const draft = await this.noteDraftsRepository.findOneBy({
id: draftId, id: draftId,
userId: me.id, userId: me.id,
@ -111,19 +105,36 @@ export class NoteDraftService {
throw new IdentifiableError('49cd6b9d-848e-41ee-b0b9-adaca711a6b1', 'No such note draft'); throw new IdentifiableError('49cd6b9d-848e-41ee-b0b9-adaca711a6b1', 'No such note draft');
} }
if (data.poll) { //#region check draft limit
if (typeof data.poll.expiresAt === 'number') { const policies = await this.roleService.getUserPolicies(me.id);
if (data.poll.expiresAt < Date.now()) {
throw new IdentifiableError('04da457d-b083-4055-9082-955525eda5a5', 'Cannot create expired poll'); if (!draft.isActuallyScheduled && data.isActuallyScheduled) {
} const currentScheduledCount = await this.noteDraftsRepository.countBy({
} else if (typeof data.poll.expiredAfter === 'number') { userId: me.id,
data.poll.expiresAt = new Date(Date.now() + data.poll.expiredAfter); isActuallyScheduled: true,
});
if (currentScheduledCount >= policies.scheduledNoteLimit) {
throw new IdentifiableError('bacdf856-5c51-4159-b88a-804fa5103be5', 'Too many scheduled notes');
} }
} }
//#endregion
const appliedDraft = await this.checkAndSetDraftNoteOptions(me, draft, data); await this.validate(me, data);
return await this.noteDraftsRepository.save(appliedDraft); const updatedDraft = await this.noteDraftsRepository.createQueryBuilder().update()
.set(data)
.where('id = :id', { id: draftId })
.returning('*')
.execute()
.then((response) => response.raw[0]);
this.clearSchedule(draftId).then(() => {
if (updatedDraft.scheduledAt != null && updatedDraft.isActuallyScheduled) {
this.schedule(updatedDraft);
}
});
return updatedDraft;
} }
@bindThis @bindThis
@ -138,6 +149,8 @@ export class NoteDraftService {
} }
await this.noteDraftsRepository.delete(draft.id); await this.noteDraftsRepository.delete(draft.id);
this.clearSchedule(draftId);
} }
@bindThis @bindThis
@ -154,27 +167,20 @@ export class NoteDraftService {
return draft; return draft;
} }
// 関連エンティティを取得し紐づける部分を共通化する
@bindThis @bindThis
public async checkAndSetDraftNoteOptions( public async validate(
me: MiLocalUser, me: MiLocalUser,
draft: MiNoteDraft, data: Partial<NoteDraftOptions>,
data: NoteDraftOptions, ): Promise<void> {
): Promise<MiNoteDraft> { if (data.pollExpiresAt != null) {
data.visibility ??= 'public'; if (data.pollExpiresAt.getTime() < Date.now()) {
data.localOnly ??= false; throw new IdentifiableError('04da457d-b083-4055-9082-955525eda5a5', 'Cannot create expired poll');
if (data.reactionAcceptance === undefined) data.reactionAcceptance = null; }
if (data.channelId != null) {
data.visibility = 'public';
data.visibleUserIds = [];
data.localOnly = true;
} }
let appliedDraft = draft;
//#region visibleUsers //#region visibleUsers
let visibleUsers: MiUser[] = []; let visibleUsers: MiUser[] = [];
if (data.visibleUserIds != null) { if (data.visibleUserIds != null && data.visibleUserIds.length > 0) {
visibleUsers = await this.usersRepository.findBy({ visibleUsers = await this.usersRepository.findBy({
id: In(data.visibleUserIds), id: In(data.visibleUserIds),
}); });
@ -184,7 +190,7 @@ export class NoteDraftService {
//#region files //#region files
let files: MiDriveFile[] = []; let files: MiDriveFile[] = [];
const fileIds = data.fileIds ?? null; const fileIds = data.fileIds ?? null;
if (fileIds != null) { if (fileIds != null && fileIds.length > 0) {
files = await this.driveFilesRepository.createQueryBuilder('file') files = await this.driveFilesRepository.createQueryBuilder('file')
.where('file.userId = :userId AND file.id IN (:...fileIds)', { .where('file.userId = :userId AND file.id IN (:...fileIds)', {
userId: me.id, userId: me.id,
@ -288,27 +294,37 @@ export class NoteDraftService {
} }
} }
//#endregion //#endregion
}
appliedDraft = { @bindThis
...appliedDraft, public async schedule(draft: MiNoteDraft): Promise<void> {
visibility: data.visibility, if (!draft.isActuallyScheduled) return;
cw: data.cw ?? null, if (draft.scheduledAt == null) return;
fileIds: fileIds ?? [], if (draft.scheduledAt.getTime() <= Date.now()) return;
replyId: data.replyId ?? null,
renoteId: data.renoteId ?? null,
channelId: data.channelId ?? null,
text: data.text ?? null,
hashtag: data.hashtag ?? null,
hasPoll: data.poll != null,
pollChoices: data.poll ? data.poll.choices : [],
pollMultiple: data.poll ? data.poll.multiple : false,
pollExpiresAt: data.poll ? data.poll.expiresAt : null,
pollExpiredAfter: data.poll ? data.poll.expiredAfter ?? null : null,
visibleUserIds: data.visibleUserIds ?? [],
localOnly: data.localOnly,
reactionAcceptance: data.reactionAcceptance,
} satisfies MiNoteDraft;
return appliedDraft; const delay = draft.scheduledAt.getTime() - Date.now();
this.queueService.postScheduledNoteQueue.add(draft.id, {
noteDraftId: draft.id,
}, {
delay,
removeOnComplete: {
age: 3600 * 24 * 7, // keep up to 7 days
count: 30,
},
removeOnFail: {
age: 3600 * 24 * 7, // keep up to 7 days
count: 100,
},
});
}
@bindThis
public async clearSchedule(draftId: MiNoteDraft['id']): Promise<void> {
const jobs = await this.queueService.postScheduledNoteQueue.getJobs(['delayed', 'waiting', 'active']);
for (const job of jobs) {
if (job.data.noteDraftId === draftId) {
await job.remove();
}
}
} }
} }

View File

@ -0,0 +1,223 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { Inject, Injectable } from '@nestjs/common';
import { DataSource, In, Not } from 'typeorm';
import { DI } from '@/di-symbols.js';
import {
type NotesRepository,
MiPage,
type PagesRepository,
MiDriveFile,
type UsersRepository,
MiNote,
} from '@/models/_.js';
import { bindThis } from '@/decorators.js';
import { RoleService } from '@/core/RoleService.js';
import { IdService } from '@/core/IdService.js';
import type { MiUser } from '@/models/User.js';
import { IdentifiableError } from '@/misc/identifiable-error.js';
import { ModerationLogService } from '@/core/ModerationLogService.js';
export interface PageBody {
title: string;
name: string;
summary: string | null;
content: Array<Record<string, any>>;
variables: Array<Record<string, any>>;
script: string;
eyeCatchingImage?: MiDriveFile | null;
font: string;
alignCenter: boolean;
hideTitleWhenPinned: boolean;
}
@Injectable()
export class PageService {
constructor(
@Inject(DI.db)
private db: DataSource,
@Inject(DI.pagesRepository)
private pagesRepository: PagesRepository,
@Inject(DI.notesRepository)
private notesRepository: NotesRepository,
@Inject(DI.usersRepository)
private usersRepository: UsersRepository,
private roleService: RoleService,
private moderationLogService: ModerationLogService,
private idService: IdService,
) {
}
@bindThis
public async create(
me: MiUser,
body: PageBody,
): Promise<MiPage> {
await this.pagesRepository.findBy({
userId: me.id,
name: body.name,
}).then(result => {
if (result.length > 0) {
throw new IdentifiableError('1a79e38e-3d83-4423-845b-a9d83ff93b61');
}
});
const page = await this.pagesRepository.insertOne(new MiPage({
id: this.idService.gen(),
updatedAt: new Date(),
title: body.title,
name: body.name,
summary: body.summary,
content: body.content,
variables: body.variables,
script: body.script,
eyeCatchingImageId: body.eyeCatchingImage ? body.eyeCatchingImage.id : null,
userId: me.id,
visibility: 'public',
alignCenter: body.alignCenter,
hideTitleWhenPinned: body.hideTitleWhenPinned,
font: body.font,
}));
const referencedNotes = this.collectReferencedNotes(page.content);
if (referencedNotes.length > 0) {
await this.notesRepository.increment({ id: In(referencedNotes) }, 'pageCount', 1);
}
return page;
}
@bindThis
public async update(
me: MiUser,
pageId: MiPage['id'],
body: Partial<PageBody>,
): Promise<void> {
await this.db.transaction(async (transaction) => {
const page = await transaction.findOne(MiPage, {
where: {
id: pageId,
},
lock: { mode: 'for_no_key_update' },
});
if (page == null) {
throw new IdentifiableError('66aefd3c-fdb2-4a71-85ae-cc18bea85d3f');
}
if (page.userId !== me.id) {
throw new IdentifiableError('d0017699-8256-46f1-aed4-bc03bed73616');
}
if (body.name != null) {
await transaction.findBy(MiPage, {
id: Not(pageId),
userId: me.id,
name: body.name,
}).then(result => {
if (result.length > 0) {
throw new IdentifiableError('d05bfe24-24b6-4ea2-a3ec-87cc9bf4daa4');
}
});
}
await transaction.update(MiPage, page.id, {
updatedAt: new Date(),
title: body.title,
name: body.name,
summary: body.summary === undefined ? page.summary : body.summary,
content: body.content,
variables: body.variables,
script: body.script,
alignCenter: body.alignCenter,
hideTitleWhenPinned: body.hideTitleWhenPinned,
font: body.font,
eyeCatchingImageId: body.eyeCatchingImage === undefined ? undefined : (body.eyeCatchingImage?.id ?? null),
});
console.log("page.content", page.content);
if (body.content != null) {
const beforeReferencedNotes = this.collectReferencedNotes(page.content);
const afterReferencedNotes = this.collectReferencedNotes(body.content);
const removedNotes = beforeReferencedNotes.filter(noteId => !afterReferencedNotes.includes(noteId));
const addedNotes = afterReferencedNotes.filter(noteId => !beforeReferencedNotes.includes(noteId));
if (removedNotes.length > 0) {
await transaction.decrement(MiNote, { id: In(removedNotes) }, 'pageCount', 1);
}
if (addedNotes.length > 0) {
await transaction.increment(MiNote, { id: In(addedNotes) }, 'pageCount', 1);
}
}
});
}
@bindThis
public async delete(me: MiUser, pageId: MiPage['id']): Promise<void> {
await this.db.transaction(async (transaction) => {
const page = await transaction.findOne(MiPage, {
where: {
id: pageId,
},
lock: { mode: 'pessimistic_write' }, // same lock level as DELETE
});
if (page == null) {
throw new IdentifiableError('66aefd3c-fdb2-4a71-85ae-cc18bea85d3f');
}
if (!await this.roleService.isModerator(me) && page.userId !== me.id) {
throw new IdentifiableError('d0017699-8256-46f1-aed4-bc03bed73616');
}
await transaction.delete(MiPage, page.id);
if (page.userId !== me.id) {
const user = await this.usersRepository.findOneByOrFail({ id: page.userId });
this.moderationLogService.log(me, 'deletePage', {
pageId: page.id,
pageUserId: page.userId,
pageUserUsername: user.username,
page,
});
}
const referencedNotes = this.collectReferencedNotes(page.content);
if (referencedNotes.length > 0) {
await transaction.decrement(MiNote, { id: In(referencedNotes) }, 'pageCount', 1);
}
});
}
collectReferencedNotes(content: MiPage['content']): string[] {
const referencingNotes = new Set<string>();
const recursiveCollect = (content: unknown[]) => {
for (const contentElement of content) {
if (typeof contentElement === 'object'
&& contentElement !== null
&& 'type' in contentElement) {
if (contentElement.type === 'note'
&& 'note' in contentElement
&& typeof contentElement.note === 'string') {
referencingNotes.add(contentElement.note);
}
if (contentElement.type === 'section'
&& 'children' in contentElement
&& Array.isArray(contentElement.children)) {
recursiveCollect(contentElement.children);
}
}
}
};
recursiveCollect(content);
return [...referencingNotes];
}
}

View File

@ -16,11 +16,13 @@ import {
RelationshipJobData, RelationshipJobData,
UserWebhookDeliverJobData, UserWebhookDeliverJobData,
SystemWebhookDeliverJobData, SystemWebhookDeliverJobData,
PostScheduledNoteJobData,
} from '../queue/types.js'; } from '../queue/types.js';
import type { Provider } from '@nestjs/common'; import type { Provider } from '@nestjs/common';
export type SystemQueue = Bull.Queue<Record<string, unknown>>; export type SystemQueue = Bull.Queue<Record<string, unknown>>;
export type EndedPollNotificationQueue = Bull.Queue<EndedPollNotificationJobData>; export type EndedPollNotificationQueue = Bull.Queue<EndedPollNotificationJobData>;
export type PostScheduledNoteQueue = Bull.Queue<PostScheduledNoteJobData>;
export type DeliverQueue = Bull.Queue<DeliverJobData>; export type DeliverQueue = Bull.Queue<DeliverJobData>;
export type InboxQueue = Bull.Queue<InboxJobData>; export type InboxQueue = Bull.Queue<InboxJobData>;
export type DbQueue = Bull.Queue; export type DbQueue = Bull.Queue;
@ -41,6 +43,12 @@ const $endedPollNotification: Provider = {
inject: [DI.config], inject: [DI.config],
}; };
const $postScheduledNote: Provider = {
provide: 'queue:postScheduledNote',
useFactory: (config: Config) => new Bull.Queue(QUEUE.POST_SCHEDULED_NOTE, baseQueueOptions(config, QUEUE.POST_SCHEDULED_NOTE)),
inject: [DI.config],
};
const $deliver: Provider = { const $deliver: Provider = {
provide: 'queue:deliver', provide: 'queue:deliver',
useFactory: (config: Config) => new Bull.Queue(QUEUE.DELIVER, baseQueueOptions(config, QUEUE.DELIVER)), useFactory: (config: Config) => new Bull.Queue(QUEUE.DELIVER, baseQueueOptions(config, QUEUE.DELIVER)),
@ -89,6 +97,7 @@ const $systemWebhookDeliver: Provider = {
providers: [ providers: [
$system, $system,
$endedPollNotification, $endedPollNotification,
$postScheduledNote,
$deliver, $deliver,
$inbox, $inbox,
$db, $db,
@ -100,6 +109,7 @@ const $systemWebhookDeliver: Provider = {
exports: [ exports: [
$system, $system,
$endedPollNotification, $endedPollNotification,
$postScheduledNote,
$deliver, $deliver,
$inbox, $inbox,
$db, $db,
@ -113,6 +123,7 @@ export class QueueModule implements OnApplicationShutdown {
constructor( constructor(
@Inject('queue:system') public systemQueue: SystemQueue, @Inject('queue:system') public systemQueue: SystemQueue,
@Inject('queue:endedPollNotification') public endedPollNotificationQueue: EndedPollNotificationQueue, @Inject('queue:endedPollNotification') public endedPollNotificationQueue: EndedPollNotificationQueue,
@Inject('queue:postScheduledNote') public postScheduledNoteQueue: PostScheduledNoteQueue,
@Inject('queue:deliver') public deliverQueue: DeliverQueue, @Inject('queue:deliver') public deliverQueue: DeliverQueue,
@Inject('queue:inbox') public inboxQueue: InboxQueue, @Inject('queue:inbox') public inboxQueue: InboxQueue,
@Inject('queue:db') public dbQueue: DbQueue, @Inject('queue:db') public dbQueue: DbQueue,
@ -129,6 +140,7 @@ export class QueueModule implements OnApplicationShutdown {
await Promise.all([ await Promise.all([
this.systemQueue.close(), this.systemQueue.close(),
this.endedPollNotificationQueue.close(), this.endedPollNotificationQueue.close(),
this.postScheduledNoteQueue.close(),
this.deliverQueue.close(), this.deliverQueue.close(),
this.inboxQueue.close(), this.inboxQueue.close(),
this.dbQueue.close(), this.dbQueue.close(),

View File

@ -31,6 +31,7 @@ import type {
DbQueue, DbQueue,
DeliverQueue, DeliverQueue,
EndedPollNotificationQueue, EndedPollNotificationQueue,
PostScheduledNoteQueue,
InboxQueue, InboxQueue,
ObjectStorageQueue, ObjectStorageQueue,
RelationshipQueue, RelationshipQueue,
@ -44,6 +45,7 @@ import type * as Bull from 'bullmq';
export const QUEUE_TYPES = [ export const QUEUE_TYPES = [
'system', 'system',
'endedPollNotification', 'endedPollNotification',
'postScheduledNote',
'deliver', 'deliver',
'inbox', 'inbox',
'db', 'db',
@ -92,6 +94,7 @@ export class QueueService {
@Inject('queue:system') public systemQueue: SystemQueue, @Inject('queue:system') public systemQueue: SystemQueue,
@Inject('queue:endedPollNotification') public endedPollNotificationQueue: EndedPollNotificationQueue, @Inject('queue:endedPollNotification') public endedPollNotificationQueue: EndedPollNotificationQueue,
@Inject('queue:postScheduledNote') public postScheduledNoteQueue: PostScheduledNoteQueue,
@Inject('queue:deliver') public deliverQueue: DeliverQueue, @Inject('queue:deliver') public deliverQueue: DeliverQueue,
@Inject('queue:inbox') public inboxQueue: InboxQueue, @Inject('queue:inbox') public inboxQueue: InboxQueue,
@Inject('queue:db') public dbQueue: DbQueue, @Inject('queue:db') public dbQueue: DbQueue,
@ -103,6 +106,7 @@ export class QueueService {
for (const def of REPEATABLE_SYSTEM_JOB_DEF) { for (const def of REPEATABLE_SYSTEM_JOB_DEF) {
this.systemQueue.upsertJobScheduler(def.name, { this.systemQueue.upsertJobScheduler(def.name, {
pattern: def.pattern, pattern: def.pattern,
immediately: false,
}, { }, {
name: def.name, name: def.name,
opts: { opts: {
@ -716,6 +720,7 @@ export class QueueService {
switch (type) { switch (type) {
case 'system': return this.systemQueue; case 'system': return this.systemQueue;
case 'endedPollNotification': return this.endedPollNotificationQueue; case 'endedPollNotification': return this.endedPollNotificationQueue;
case 'postScheduledNote': return this.postScheduledNoteQueue;
case 'deliver': return this.deliverQueue; case 'deliver': return this.deliverQueue;
case 'inbox': return this.inboxQueue; case 'inbox': return this.inboxQueue;
case 'db': return this.dbQueue; case 'db': return this.dbQueue;
@ -755,8 +760,8 @@ export class QueueService {
@bindThis @bindThis
public async queueRetryJob(queueType: typeof QUEUE_TYPES[number], jobId: string) { public async queueRetryJob(queueType: typeof QUEUE_TYPES[number], jobId: string) {
const queue = this.getQueue(queueType); const queue = this.getQueue(queueType);
const job: Bull.Job | null = await queue.getJob(jobId); const job = await queue.getJob(jobId);
if (job) { if (job != null) {
if (job.finishedOn != null) { if (job.finishedOn != null) {
await job.retry(); await job.retry();
} else { } else {
@ -768,8 +773,8 @@ export class QueueService {
@bindThis @bindThis
public async queueRemoveJob(queueType: typeof QUEUE_TYPES[number], jobId: string) { public async queueRemoveJob(queueType: typeof QUEUE_TYPES[number], jobId: string) {
const queue = this.getQueue(queueType); const queue = this.getQueue(queueType);
const job: Bull.Job | null = await queue.getJob(jobId); const job = await queue.getJob(jobId);
if (job) { if (job != null) {
await job.remove(); await job.remove();
} }
} }
@ -802,8 +807,8 @@ export class QueueService {
@bindThis @bindThis
public async queueGetJob(queueType: typeof QUEUE_TYPES[number], jobId: string) { public async queueGetJob(queueType: typeof QUEUE_TYPES[number], jobId: string) {
const queue = this.getQueue(queueType); const queue = this.getQueue(queueType);
const job: Bull.Job | null = await queue.getJob(jobId); const job = await queue.getJob(jobId);
if (job) { if (job != null) {
return this.packJobData(job); return this.packJobData(job);
} else { } else {
throw new Error(`Job not found: ${jobId}`); throw new Error(`Job not found: ${jobId}`);

View File

@ -31,6 +31,7 @@ import { FanoutTimelineService } from '@/core/FanoutTimelineService.js';
import { NotificationService } from '@/core/NotificationService.js'; import { NotificationService } from '@/core/NotificationService.js';
import type { OnApplicationShutdown, OnModuleInit } from '@nestjs/common'; import type { OnApplicationShutdown, OnModuleInit } from '@nestjs/common';
// misskey-js の rolePolicies と同期すべし
export type RolePolicies = { export type RolePolicies = {
gtlAvailable: boolean; gtlAvailable: boolean;
ltlAvailable: boolean; ltlAvailable: boolean;
@ -43,6 +44,7 @@ export type RolePolicies = {
canManageCustomEmojis: boolean; canManageCustomEmojis: boolean;
canManageAvatarDecorations: boolean; canManageAvatarDecorations: boolean;
canSearchNotes: boolean; canSearchNotes: boolean;
canSearchUsers: boolean;
canUseTranslator: boolean; canUseTranslator: boolean;
canHideAds: boolean; canHideAds: boolean;
driveCapacityMb: number; driveCapacityMb: number;
@ -67,6 +69,7 @@ export type RolePolicies = {
chatAvailability: 'available' | 'readonly' | 'unavailable'; chatAvailability: 'available' | 'readonly' | 'unavailable';
uploadableFileTypes: string[]; uploadableFileTypes: string[];
noteDraftLimit: number; noteDraftLimit: number;
scheduledNoteLimit: number;
watermarkAvailable: boolean; watermarkAvailable: boolean;
}; };
@ -82,6 +85,7 @@ export const DEFAULT_POLICIES: RolePolicies = {
canManageCustomEmojis: false, canManageCustomEmojis: false,
canManageAvatarDecorations: false, canManageAvatarDecorations: false,
canSearchNotes: false, canSearchNotes: false,
canSearchUsers: true,
canUseTranslator: true, canUseTranslator: true,
canHideAds: false, canHideAds: false,
driveCapacityMb: 100, driveCapacityMb: 100,
@ -98,20 +102,22 @@ export const DEFAULT_POLICIES: RolePolicies = {
userEachUserListsLimit: 50, userEachUserListsLimit: 50,
rateLimitFactor: 1, rateLimitFactor: 1,
avatarDecorationLimit: 1, avatarDecorationLimit: 1,
canImportAntennas: true, canImportAntennas: false,
canImportBlocking: true, canImportBlocking: false,
canImportFollowing: true, canImportFollowing: false,
canImportMuting: true, canImportMuting: false,
canImportUserLists: true, canImportUserLists: false,
chatAvailability: 'available', chatAvailability: 'available',
uploadableFileTypes: [ uploadableFileTypes: [
'text/plain', 'text/plain',
'text/csv',
'application/json', 'application/json',
'image/*', 'image/*',
'video/*', 'video/*',
'audio/*', 'audio/*',
], ],
noteDraftLimit: 10, noteDraftLimit: 10,
scheduledNoteLimit: 1,
watermarkAvailable: true, watermarkAvailable: true,
}; };
@ -402,6 +408,7 @@ export class RoleService implements OnApplicationShutdown, OnModuleInit {
canManageCustomEmojis: calc('canManageCustomEmojis', vs => vs.some(v => v === true)), canManageCustomEmojis: calc('canManageCustomEmojis', vs => vs.some(v => v === true)),
canManageAvatarDecorations: calc('canManageAvatarDecorations', vs => vs.some(v => v === true)), canManageAvatarDecorations: calc('canManageAvatarDecorations', vs => vs.some(v => v === true)),
canSearchNotes: calc('canSearchNotes', vs => vs.some(v => v === true)), canSearchNotes: calc('canSearchNotes', vs => vs.some(v => v === true)),
canSearchUsers: calc('canSearchUsers', vs => vs.some(v => v === true)),
canUseTranslator: calc('canUseTranslator', vs => vs.some(v => v === true)), canUseTranslator: calc('canUseTranslator', vs => vs.some(v => v === true)),
canHideAds: calc('canHideAds', vs => vs.some(v => v === true)), canHideAds: calc('canHideAds', vs => vs.some(v => v === true)),
driveCapacityMb: calc('driveCapacityMb', vs => Math.max(...vs)), driveCapacityMb: calc('driveCapacityMb', vs => Math.max(...vs)),
@ -435,6 +442,7 @@ export class RoleService implements OnApplicationShutdown, OnModuleInit {
return [...set]; return [...set];
}), }),
noteDraftLimit: calc('noteDraftLimit', vs => Math.max(...vs)), noteDraftLimit: calc('noteDraftLimit', vs => Math.max(...vs)),
scheduledNoteLimit: calc('scheduledNoteLimit', vs => Math.max(...vs)),
watermarkAvailable: calc('watermarkAvailable', vs => vs.some(v => v === true)), watermarkAvailable: calc('watermarkAvailable', vs => vs.some(v => v === true)),
}; };
} }

View File

@ -85,6 +85,7 @@ function generateDummyNote(override?: Partial<MiNote>): MiNote {
renoteCount: 10, renoteCount: 10,
repliesCount: 5, repliesCount: 5,
clippedCount: 0, clippedCount: 0,
pageCount: 0,
reactions: {}, reactions: {},
visibility: 'public', visibility: 'public',
uri: null, uri: null,
@ -243,7 +244,6 @@ export class WebhookTestService {
case 'reaction': case 'reaction':
return; return;
default: { default: {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const _exhaustiveAssertion: never = params.type; const _exhaustiveAssertion: never = params.type;
return; return;
} }
@ -326,7 +326,6 @@ export class WebhookTestService {
break; break;
} }
default: { default: {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const _exhaustiveAssertion: never = params.type; const _exhaustiveAssertion: never = params.type;
return; return;
} }
@ -411,7 +410,7 @@ export class WebhookTestService {
name: user.name, name: user.name,
username: user.username, username: user.username,
host: user.host, host: user.host,
avatarUrl: user.avatarId == null ? null : user.avatarUrl, avatarUrl: (user.avatarId == null ? null : user.avatarUrl) ?? '',
avatarBlurhash: user.avatarId == null ? null : user.avatarBlurhash, avatarBlurhash: user.avatarId == null ? null : user.avatarBlurhash,
avatarDecorations: user.avatarDecorations.map(it => ({ avatarDecorations: user.avatarDecorations.map(it => ({
id: it.id, id: it.id,

View File

@ -54,12 +54,13 @@ export class ChatEntityService {
const message = typeof src === 'object' ? src : await this.chatMessagesRepository.findOneByOrFail({ id: src }); const message = typeof src === 'object' ? src : await this.chatMessagesRepository.findOneByOrFail({ id: src });
const reactions: { user: Packed<'UserLite'>; reaction: string; }[] = []; // userは削除されている可能性があるのでnull許容
const reactions: { user: Packed<'UserLite'> | null; reaction: string; }[] = [];
for (const record of message.reactions) { for (const record of message.reactions) {
const [userId, reaction] = record.split('/'); const [userId, reaction] = record.split('/');
reactions.push({ reactions.push({
user: packedUsers?.get(userId) ?? await this.userEntityService.pack(userId), user: packedUsers?.get(userId) ?? await this.userEntityService.pack(userId).catch(() => null),
reaction, reaction,
}); });
} }
@ -76,7 +77,7 @@ export class ChatEntityService {
toRoom: message.toRoomId ? (packedRooms?.get(message.toRoomId) ?? await this.packRoom(message.toRoom ?? message.toRoomId, me)) : undefined, toRoom: message.toRoomId ? (packedRooms?.get(message.toRoomId) ?? await this.packRoom(message.toRoom ?? message.toRoomId, me)) : undefined,
fileId: message.fileId, fileId: message.fileId,
file: message.fileId ? (packedFiles?.get(message.fileId) ?? await this.driveFileEntityService.pack(message.file ?? message.fileId)) : null, file: message.fileId ? (packedFiles?.get(message.fileId) ?? await this.driveFileEntityService.pack(message.file ?? message.fileId)) : null,
reactions, reactions: reactions.filter((r): r is { user: Packed<'UserLite'>; reaction: string; } => r.user != null),
}; };
} }
@ -108,6 +109,7 @@ export class ChatEntityService {
} }
} }
// TODO: packedUsersに削除されたユーザーもnullとして含める
const [packedUsers, packedFiles, packedRooms] = await Promise.all([ const [packedUsers, packedFiles, packedRooms] = await Promise.all([
this.userEntityService.packMany(users, me) this.userEntityService.packMany(users, me)
.then(users => new Map(users.map(u => [u.id, u]))), .then(users => new Map(users.map(u => [u.id, u]))),
@ -183,12 +185,13 @@ export class ChatEntityService {
const message = typeof src === 'object' ? src : await this.chatMessagesRepository.findOneByOrFail({ id: src }); const message = typeof src === 'object' ? src : await this.chatMessagesRepository.findOneByOrFail({ id: src });
const reactions: { user: Packed<'UserLite'>; reaction: string; }[] = []; // userは削除されている可能性があるのでnull許容
const reactions: { user: Packed<'UserLite'> | null; reaction: string; }[] = [];
for (const record of message.reactions) { for (const record of message.reactions) {
const [userId, reaction] = record.split('/'); const [userId, reaction] = record.split('/');
reactions.push({ reactions.push({
user: packedUsers?.get(userId) ?? await this.userEntityService.pack(userId), user: packedUsers?.get(userId) ?? await this.userEntityService.pack(userId).catch(() => null),
reaction, reaction,
}); });
} }
@ -202,7 +205,7 @@ export class ChatEntityService {
toRoomId: message.toRoomId!, toRoomId: message.toRoomId!,
fileId: message.fileId, fileId: message.fileId,
file: message.fileId ? (packedFiles?.get(message.fileId) ?? await this.driveFileEntityService.pack(message.file ?? message.fileId)) : null, file: message.fileId ? (packedFiles?.get(message.fileId) ?? await this.driveFileEntityService.pack(message.file ?? message.fileId)) : null,
reactions, reactions: reactions.filter((r): r is { user: Packed<'UserLite'>; reaction: string; } => r.user != null),
}; };
} }

View File

@ -109,6 +109,7 @@ export class MetaEntityService {
maxNoteTextLength: MAX_NOTE_TEXT_LENGTH, maxNoteTextLength: MAX_NOTE_TEXT_LENGTH,
defaultLightTheme, defaultLightTheme,
defaultDarkTheme, defaultDarkTheme,
clientOptions: instance.clientOptions,
ads: ads.map(ad => ({ ads: ads.map(ad => ({
id: ad.id, id: ad.id,
url: ad.url, url: ad.url,
@ -116,6 +117,7 @@ export class MetaEntityService {
ratio: ad.ratio, ratio: ad.ratio,
imageUrl: ad.imageUrl, imageUrl: ad.imageUrl,
dayOfWeek: ad.dayOfWeek, dayOfWeek: ad.dayOfWeek,
isSensitive: ad.isSensitive ? true : undefined,
})), })),
notesPerOneAd: instance.notesPerOneAd, notesPerOneAd: instance.notesPerOneAd,
enableEmail: instance.enableEmail, enableEmail: instance.enableEmail,

View File

@ -105,6 +105,8 @@ export class NoteDraftEntityService implements OnModuleInit {
const packed: Packed<'NoteDraft'> = await awaitAll({ const packed: Packed<'NoteDraft'> = await awaitAll({
id: noteDraft.id, id: noteDraft.id,
createdAt: this.idService.parse(noteDraft.id).date.toISOString(), createdAt: this.idService.parse(noteDraft.id).date.toISOString(),
scheduledAt: noteDraft.scheduledAt?.getTime() ?? null,
isActuallyScheduled: noteDraft.isActuallyScheduled,
userId: noteDraft.userId, userId: noteDraft.userId,
user: packedUsers?.get(noteDraft.userId) ?? this.userEntityService.pack(noteDraft.user ?? noteDraft.userId, me), user: packedUsers?.get(noteDraft.userId) ?? this.userEntityService.pack(noteDraft.user ?? noteDraft.userId, me),
text: text, text: text,
@ -112,13 +114,13 @@ export class NoteDraftEntityService implements OnModuleInit {
visibility: noteDraft.visibility, visibility: noteDraft.visibility,
localOnly: noteDraft.localOnly, localOnly: noteDraft.localOnly,
reactionAcceptance: noteDraft.reactionAcceptance, reactionAcceptance: noteDraft.reactionAcceptance,
visibleUserIds: noteDraft.visibility === 'specified' ? noteDraft.visibleUserIds : undefined, visibleUserIds: noteDraft.visibleUserIds,
hashtag: noteDraft.hashtag ?? undefined, hashtag: noteDraft.hashtag,
fileIds: noteDraft.fileIds, fileIds: noteDraft.fileIds,
files: packedFiles != null ? this.packAttachedFiles(noteDraft.fileIds, packedFiles) : this.driveFileEntityService.packManyByIds(noteDraft.fileIds), files: packedFiles != null ? this.packAttachedFiles(noteDraft.fileIds, packedFiles) : this.driveFileEntityService.packManyByIds(noteDraft.fileIds),
replyId: noteDraft.replyId, replyId: noteDraft.replyId,
renoteId: noteDraft.renoteId, renoteId: noteDraft.renoteId,
channelId: noteDraft.channelId ?? undefined, channelId: noteDraft.channelId,
channel: channel ? { channel: channel ? {
id: channel.id, id: channel.id,
name: channel.name, name: channel.name,
@ -127,6 +129,12 @@ export class NoteDraftEntityService implements OnModuleInit {
allowRenoteToExternal: channel.allowRenoteToExternal, allowRenoteToExternal: channel.allowRenoteToExternal,
userId: channel.userId, userId: channel.userId,
} : undefined, } : undefined,
poll: noteDraft.hasPoll ? {
choices: noteDraft.pollChoices,
multiple: noteDraft.pollMultiple,
expiresAt: noteDraft.pollExpiresAt?.toISOString(),
expiredAfter: noteDraft.pollExpiredAfter,
} : null,
...(opts.detail ? { ...(opts.detail ? {
reply: noteDraft.replyId ? nullIfEntityNotFound(this.noteEntityService.pack(noteDraft.replyId, me, { reply: noteDraft.replyId ? nullIfEntityNotFound(this.noteEntityService.pack(noteDraft.replyId, me, {
@ -138,13 +146,6 @@ export class NoteDraftEntityService implements OnModuleInit {
detail: true, detail: true,
skipHide: opts.skipHide, skipHide: opts.skipHide,
})) : undefined, })) : undefined,
poll: noteDraft.hasPoll ? {
choices: noteDraft.pollChoices,
multiple: noteDraft.pollMultiple,
expiresAt: noteDraft.pollExpiresAt?.toISOString(),
expiredAfter: noteDraft.pollExpiredAfter,
} : undefined,
} : {} ), } : {} ),
}); });

View File

@ -49,15 +49,12 @@ export class NoteReactionEntityService implements OnModuleInit {
public async pack( public async pack(
src: MiNoteReaction['id'] | MiNoteReaction, src: MiNoteReaction['id'] | MiNoteReaction,
me?: { id: MiUser['id'] } | null | undefined, me?: { id: MiUser['id'] } | null | undefined,
options?: { options?: object,
withNote: boolean;
},
hints?: { hints?: {
packedUser?: Packed<'UserLite'> packedUser?: Packed<'UserLite'>
}, },
): Promise<Packed<'NoteReaction'>> { ): Promise<Packed<'NoteReaction'>> {
const opts = Object.assign({ const opts = Object.assign({
withNote: false,
}, options); }, options);
const reaction = typeof src === 'object' ? src : await this.noteReactionsRepository.findOneByOrFail({ id: src }); const reaction = typeof src === 'object' ? src : await this.noteReactionsRepository.findOneByOrFail({ id: src });
@ -67,9 +64,6 @@ export class NoteReactionEntityService implements OnModuleInit {
createdAt: this.idService.parse(reaction.id).date.toISOString(), createdAt: this.idService.parse(reaction.id).date.toISOString(),
user: hints?.packedUser ?? await this.userEntityService.pack(reaction.user ?? reaction.userId, me), user: hints?.packedUser ?? await this.userEntityService.pack(reaction.user ?? reaction.userId, me),
type: this.reactionService.convertLegacyReaction(reaction.reaction), type: this.reactionService.convertLegacyReaction(reaction.reaction),
...(opts.withNote ? {
note: await this.noteEntityService.pack(reaction.note ?? reaction.noteId, me),
} : {}),
}; };
} }
@ -77,16 +71,50 @@ export class NoteReactionEntityService implements OnModuleInit {
public async packMany( public async packMany(
reactions: MiNoteReaction[], reactions: MiNoteReaction[],
me?: { id: MiUser['id'] } | null | undefined, me?: { id: MiUser['id'] } | null | undefined,
options?: { options?: object,
withNote: boolean;
},
): Promise<Packed<'NoteReaction'>[]> { ): Promise<Packed<'NoteReaction'>[]> {
const opts = Object.assign({ const opts = Object.assign({
withNote: false,
}, options); }, options);
const _users = reactions.map(({ user, userId }) => user ?? userId); const _users = reactions.map(({ user, userId }) => user ?? userId);
const _userMap = await this.userEntityService.packMany(_users, me) const _userMap = await this.userEntityService.packMany(_users, me)
.then(users => new Map(users.map(u => [u.id, u]))); .then(users => new Map(users.map(u => [u.id, u])));
return Promise.all(reactions.map(reaction => this.pack(reaction, me, opts, { packedUser: _userMap.get(reaction.userId) }))); return Promise.all(reactions.map(reaction => this.pack(reaction, me, opts, { packedUser: _userMap.get(reaction.userId) })));
} }
@bindThis
public async packWithNote(
src: MiNoteReaction['id'] | MiNoteReaction,
me?: { id: MiUser['id'] } | null | undefined,
options?: object,
hints?: {
packedUser?: Packed<'UserLite'>
},
): Promise<Packed<'NoteReactionWithNote'>> {
const opts = Object.assign({
}, options);
const reaction = typeof src === 'object' ? src : await this.noteReactionsRepository.findOneByOrFail({ id: src });
return {
id: reaction.id,
createdAt: this.idService.parse(reaction.id).date.toISOString(),
user: hints?.packedUser ?? await this.userEntityService.pack(reaction.user ?? reaction.userId, me),
type: this.reactionService.convertLegacyReaction(reaction.reaction),
note: await this.noteEntityService.pack(reaction.note ?? reaction.noteId, me),
};
}
@bindThis
public async packManyWithNote(
reactions: MiNoteReaction[],
me?: { id: MiUser['id'] } | null | undefined,
options?: object,
): Promise<Packed<'NoteReactionWithNote'>[]> {
const opts = Object.assign({
}, options);
const _users = reactions.map(({ user, userId }) => user ?? userId);
const _userMap = await this.userEntityService.packMany(_users, me)
.then(users => new Map(users.map(u => [u.id, u])));
return Promise.all(reactions.map(reaction => this.packWithNote(reaction, me, opts, { packedUser: _userMap.get(reaction.userId) })));
}
} }

View File

@ -21,7 +21,18 @@ import type { OnModuleInit } from '@nestjs/common';
import type { UserEntityService } from './UserEntityService.js'; import type { UserEntityService } from './UserEntityService.js';
import type { NoteEntityService } from './NoteEntityService.js'; import type { NoteEntityService } from './NoteEntityService.js';
const NOTE_REQUIRED_NOTIFICATION_TYPES = new Set(['note', 'mention', 'reply', 'renote', 'renote:grouped', 'quote', 'reaction', 'reaction:grouped', 'pollEnded'] as (typeof groupedNotificationTypes[number])[]); const NOTE_REQUIRED_NOTIFICATION_TYPES = new Set([
'note',
'mention',
'reply',
'renote',
'renote:grouped',
'quote',
'reaction',
'reaction:grouped',
'pollEnded',
'scheduledNotePosted',
] as (typeof groupedNotificationTypes[number])[]);
@Injectable() @Injectable()
export class NotificationEntityService implements OnModuleInit { export class NotificationEntityService implements OnModuleInit {

View File

@ -471,8 +471,8 @@ export class UserEntityService implements OnModuleInit {
(profile.followersVisibility === 'followers') && (relation && relation.isFollowing) ? user.followersCount : (profile.followersVisibility === 'followers') && (relation && relation.isFollowing) ? user.followersCount :
null; null;
const isModerator = isMe && isDetailed ? this.roleService.isModerator(user) : null; const isModerator = isMe && isDetailed ? this.roleService.isModerator(user) : undefined;
const isAdmin = isMe && isDetailed ? this.roleService.isAdministrator(user) : null; const isAdmin = isMe && isDetailed ? this.roleService.isAdministrator(user) : undefined;
const unreadAnnouncements = isMe && isDetailed ? const unreadAnnouncements = isMe && isDetailed ?
(await this.announcementService.getUnreadAnnouncements(user)).map((announcement) => ({ (await this.announcementService.getUnreadAnnouncements(user)).map((announcement) => ({
createdAt: this.idService.parse(announcement.id).date.toISOString(), createdAt: this.idService.parse(announcement.id).date.toISOString(),
@ -481,6 +481,7 @@ export class UserEntityService implements OnModuleInit {
const notificationsInfo = isMe && isDetailed ? await this.getNotificationsInfo(user.id) : null; const notificationsInfo = isMe && isDetailed ? await this.getNotificationsInfo(user.id) : null;
// TODO: 例えば avatarUrl: true など間違った型を設定しても型エラーにならないのをどうにかする(ジェネリクス使わない方法で実装するしかなさそう?)
const packed = { const packed = {
id: user.id, id: user.id,
name: user.name, name: user.name,

View File

@ -22,7 +22,7 @@ import { packedFollowingSchema } from '@/models/json-schema/following.js';
import { packedMutingSchema } from '@/models/json-schema/muting.js'; import { packedMutingSchema } from '@/models/json-schema/muting.js';
import { packedRenoteMutingSchema } from '@/models/json-schema/renote-muting.js'; import { packedRenoteMutingSchema } from '@/models/json-schema/renote-muting.js';
import { packedBlockingSchema } from '@/models/json-schema/blocking.js'; import { packedBlockingSchema } from '@/models/json-schema/blocking.js';
import { packedNoteReactionSchema } from '@/models/json-schema/note-reaction.js'; import { packedNoteReactionSchema, packedNoteReactionWithNoteSchema } from '@/models/json-schema/note-reaction.js';
import { packedHashtagSchema } from '@/models/json-schema/hashtag.js'; import { packedHashtagSchema } from '@/models/json-schema/hashtag.js';
import { packedInviteCodeSchema } from '@/models/json-schema/invite-code.js'; import { packedInviteCodeSchema } from '@/models/json-schema/invite-code.js';
import { packedPageBlockSchema, packedPageSchema } from '@/models/json-schema/page.js'; import { packedPageBlockSchema, packedPageSchema } from '@/models/json-schema/page.js';
@ -65,6 +65,7 @@ import {
packedMetaDetailedSchema, packedMetaDetailedSchema,
packedMetaLiteSchema, packedMetaLiteSchema,
} from '@/models/json-schema/meta.js'; } from '@/models/json-schema/meta.js';
import { packedUserWebhookSchema } from '@/models/json-schema/user-webhook.js';
import { packedSystemWebhookSchema } from '@/models/json-schema/system-webhook.js'; import { packedSystemWebhookSchema } from '@/models/json-schema/system-webhook.js';
import { packedAbuseReportNotificationRecipientSchema } from '@/models/json-schema/abuse-report-notification-recipient.js'; import { packedAbuseReportNotificationRecipientSchema } from '@/models/json-schema/abuse-report-notification-recipient.js';
import { packedChatMessageSchema, packedChatMessageLiteSchema, packedChatMessageLiteForRoomSchema, packedChatMessageLiteFor1on1Schema } from '@/models/json-schema/chat-message.js'; import { packedChatMessageSchema, packedChatMessageLiteSchema, packedChatMessageLiteForRoomSchema, packedChatMessageLiteFor1on1Schema } from '@/models/json-schema/chat-message.js';
@ -92,6 +93,7 @@ export const refs = {
Note: packedNoteSchema, Note: packedNoteSchema,
NoteDraft: packedNoteDraftSchema, NoteDraft: packedNoteDraftSchema,
NoteReaction: packedNoteReactionSchema, NoteReaction: packedNoteReactionSchema,
NoteReactionWithNote: packedNoteReactionWithNoteSchema,
NoteFavorite: packedNoteFavoriteSchema, NoteFavorite: packedNoteFavoriteSchema,
Notification: packedNotificationSchema, Notification: packedNotificationSchema,
DriveFile: packedDriveFileSchema, DriveFile: packedDriveFileSchema,
@ -133,6 +135,7 @@ export const refs = {
MetaLite: packedMetaLiteSchema, MetaLite: packedMetaLiteSchema,
MetaDetailedOnly: packedMetaDetailedOnlySchema, MetaDetailedOnly: packedMetaDetailedOnlySchema,
MetaDetailed: packedMetaDetailedSchema, MetaDetailed: packedMetaDetailedSchema,
UserWebhook: packedUserWebhookSchema,
SystemWebhook: packedSystemWebhookSchema, SystemWebhook: packedSystemWebhookSchema,
AbuseReportNotificationRecipient: packedAbuseReportNotificationRecipientSchema, AbuseReportNotificationRecipient: packedAbuseReportNotificationRecipientSchema,
ChatMessage: packedChatMessageSchema, ChatMessage: packedChatMessageSchema,

View File

@ -54,10 +54,17 @@ export class MiAd {
length: 8192, nullable: false, length: 8192, nullable: false,
}) })
public memo: string; public memo: string;
@Column('integer', { @Column('integer', {
default: 0, nullable: false, default: 0, nullable: false,
}) })
public dayOfWeek: number; public dayOfWeek: number;
@Column('boolean', {
default: false,
})
public isSensitive: boolean;
constructor(data: Partial<MiAd>) { constructor(data: Partial<MiAd>) {
if (data == null) return; if (data == null) return;

View File

@ -716,6 +716,11 @@ export class MiMeta {
default: 90, // days default: 90, // days
}) })
public remoteNotesCleaningExpiryDaysForEachNotes: number; public remoteNotesCleaningExpiryDaysForEachNotes: number;
@Column('jsonb', {
default: { },
})
public clientOptions: Record<string, any>;
} }
export type SoftwareSuspension = { export type SoftwareSuspension = {

View File

@ -114,6 +114,13 @@ export class MiNote {
}) })
public clippedCount: number; public clippedCount: number;
// The number of note page blocks referencing this note.
// This column is used by Remote Note Cleaning and manually updated rather than automatically with triggers.
@Column('smallint', {
default: 0,
})
public pageCount: number;
@Column('jsonb', { @Column('jsonb', {
default: {}, default: {},
}) })

View File

@ -126,7 +126,7 @@ export class MiNoteDraft {
@JoinColumn() @JoinColumn()
public channel: MiChannel | null; public channel: MiChannel | null;
// 以下、Pollについて追加 //#region 以下、Pollについて追加
@Column('boolean', { @Column('boolean', {
default: false, default: false,
@ -151,13 +151,15 @@ export class MiNoteDraft {
}) })
public pollExpiredAfter: number | null; public pollExpiredAfter: number | null;
// ここまで追加 //#endregion
constructor(data: Partial<MiNoteDraft>) { @Column('timestamp with time zone', {
if (data == null) return; nullable: true,
})
public scheduledAt: Date | null;
for (const [k, v] of Object.entries(data)) { @Column('boolean', {
(this as any)[k] = v; default: false,
} })
} public isActuallyScheduled: boolean;
} }

View File

@ -9,7 +9,9 @@ import { MiNote } from './Note.js';
import { MiAccessToken } from './AccessToken.js'; import { MiAccessToken } from './AccessToken.js';
import { MiRole } from './Role.js'; import { MiRole } from './Role.js';
import { MiDriveFile } from './DriveFile.js'; import { MiDriveFile } from './DriveFile.js';
import { MiNoteDraft } from './NoteDraft.js';
// misskey-js の notificationTypes と同期すべし
export type MiNotification = { export type MiNotification = {
type: 'note'; type: 'note';
id: string; id: string;
@ -59,6 +61,16 @@ export type MiNotification = {
createdAt: string; createdAt: string;
notifierId: MiUser['id']; notifierId: MiUser['id'];
noteId: MiNote['id']; noteId: MiNote['id'];
} | {
type: 'scheduledNotePosted';
id: string;
createdAt: string;
noteId: MiNote['id'];
} | {
type: 'scheduledNotePostFailed';
id: string;
createdAt: string;
noteDraftId: MiNoteDraft['id'];
} | { } | {
type: 'receiveFollowRequest'; type: 'receiveFollowRequest';
id: string; id: string;

View File

@ -69,7 +69,7 @@ export class MiPage {
public eyeCatchingImageId: MiDriveFile['id'] | null; public eyeCatchingImageId: MiDriveFile['id'] | null;
@ManyToOne(type => MiDriveFile, { @ManyToOne(type => MiDriveFile, {
onDelete: 'CASCADE', onDelete: 'SET NULL',
}) })
@JoinColumn() @JoinColumn()
public eyeCatchingImage: MiDriveFile | null; public eyeCatchingImage: MiDriveFile | null;

View File

@ -60,5 +60,10 @@ export const packedAdSchema = {
optional: false, optional: false,
nullable: false, nullable: false,
}, },
isSensitive: {
type: 'boolean',
optional: false,
nullable: false,
},
}, },
} as const; } as const;

View File

@ -71,6 +71,10 @@ export const packedMetaLiteSchema = {
type: 'string', type: 'string',
optional: false, nullable: true, optional: false, nullable: true,
}, },
clientOptions: {
type: 'object',
optional: false, nullable: false,
},
disableRegistration: { disableRegistration: {
type: 'boolean', type: 'boolean',
optional: false, nullable: false, optional: false, nullable: false,
@ -191,6 +195,10 @@ export const packedMetaLiteSchema = {
type: 'integer', type: 'integer',
optional: false, nullable: false, optional: false, nullable: false,
}, },
isSensitive: {
type: 'boolean',
optional: true, nullable: false,
},
}, },
}, },
}, },

View File

@ -23,7 +23,7 @@ export const packedNoteDraftSchema = {
}, },
cw: { cw: {
type: 'string', type: 'string',
optional: true, nullable: true, optional: false, nullable: true,
}, },
userId: { userId: {
type: 'string', type: 'string',
@ -37,27 +37,23 @@ export const packedNoteDraftSchema = {
}, },
replyId: { replyId: {
type: 'string', type: 'string',
optional: true, nullable: true, optional: false, nullable: true,
format: 'id', format: 'id',
example: 'xxxxxxxxxx',
}, },
renoteId: { renoteId: {
type: 'string', type: 'string',
optional: true, nullable: true, optional: false, nullable: true,
format: 'id', format: 'id',
example: 'xxxxxxxxxx',
}, },
reply: { reply: {
type: 'object', type: 'object',
optional: true, nullable: true, optional: true, nullable: true,
ref: 'Note', ref: 'Note',
description: 'The reply target note contents if exists. If the reply target has been deleted since the draft was created, this will be null while replyId is not null.',
}, },
renote: { renote: {
type: 'object', type: 'object',
optional: true, nullable: true, optional: true, nullable: true,
ref: 'Note', ref: 'Note',
description: 'The renote target note contents if exists. If the renote target has been deleted since the draft was created, this will be null while renoteId is not null.',
}, },
visibility: { visibility: {
type: 'string', type: 'string',
@ -66,7 +62,7 @@ export const packedNoteDraftSchema = {
}, },
visibleUserIds: { visibleUserIds: {
type: 'array', type: 'array',
optional: true, nullable: false, optional: false, nullable: false,
items: { items: {
type: 'string', type: 'string',
optional: false, nullable: false, optional: false, nullable: false,
@ -75,7 +71,7 @@ export const packedNoteDraftSchema = {
}, },
fileIds: { fileIds: {
type: 'array', type: 'array',
optional: true, nullable: false, optional: false, nullable: false,
items: { items: {
type: 'string', type: 'string',
optional: false, nullable: false, optional: false, nullable: false,
@ -93,11 +89,11 @@ export const packedNoteDraftSchema = {
}, },
hashtag: { hashtag: {
type: 'string', type: 'string',
optional: true, nullable: false, optional: false, nullable: true,
}, },
poll: { poll: {
type: 'object', type: 'object',
optional: true, nullable: true, optional: false, nullable: true,
properties: { properties: {
expiresAt: { expiresAt: {
type: 'string', type: 'string',
@ -124,9 +120,8 @@ export const packedNoteDraftSchema = {
}, },
channelId: { channelId: {
type: 'string', type: 'string',
optional: true, nullable: true, optional: false, nullable: true,
format: 'id', format: 'id',
example: 'xxxxxxxxxx',
}, },
channel: { channel: {
type: 'object', type: 'object',
@ -160,12 +155,20 @@ export const packedNoteDraftSchema = {
}, },
localOnly: { localOnly: {
type: 'boolean', type: 'boolean',
optional: true, nullable: false, optional: false, nullable: false,
}, },
reactionAcceptance: { reactionAcceptance: {
type: 'string', type: 'string',
optional: false, nullable: true, optional: false, nullable: true,
enum: ['likeOnly', 'likeOnlyForRemote', 'nonSensitiveOnly', 'nonSensitiveOnlyForLocalLikeOnlyForRemote', null], enum: ['likeOnly', 'likeOnlyForRemote', 'nonSensitiveOnly', 'nonSensitiveOnlyForLocalLikeOnlyForRemote', null],
}, },
scheduledAt: {
type: 'number',
optional: false, nullable: true,
},
isActuallyScheduled: {
type: 'boolean',
optional: false, nullable: false,
},
}, },
} as const; } as const;

View File

@ -10,7 +10,6 @@ export const packedNoteReactionSchema = {
type: 'string', type: 'string',
optional: false, nullable: false, optional: false, nullable: false,
format: 'id', format: 'id',
example: 'xxxxxxxxxx',
}, },
createdAt: { createdAt: {
type: 'string', type: 'string',
@ -28,3 +27,33 @@ export const packedNoteReactionSchema = {
}, },
}, },
} as const; } as const;
export const packedNoteReactionWithNoteSchema = {
type: 'object',
properties: {
id: {
type: 'string',
optional: false, nullable: false,
format: 'id',
},
createdAt: {
type: 'string',
optional: false, nullable: false,
format: 'date-time',
},
user: {
type: 'object',
optional: false, nullable: false,
ref: 'UserLite',
},
type: {
type: 'string',
optional: false, nullable: false,
},
note: {
type: 'object',
optional: false, nullable: false,
ref: 'Note',
},
},
} as const;

View File

@ -207,6 +207,36 @@ export const packedNotificationSchema = {
optional: false, nullable: false, optional: false, nullable: false,
}, },
}, },
}, {
type: 'object',
properties: {
...baseSchema.properties,
type: {
type: 'string',
optional: false, nullable: false,
enum: ['scheduledNotePosted'],
},
note: {
type: 'object',
ref: 'Note',
optional: false, nullable: false,
},
},
}, {
type: 'object',
properties: {
...baseSchema.properties,
type: {
type: 'string',
optional: false, nullable: false,
enum: ['scheduledNotePostFailed'],
},
noteDraft: {
type: 'object',
ref: 'NoteDraft',
optional: false, nullable: false,
},
},
}, { }, {
type: 'object', type: 'object',
properties: { properties: {

View File

@ -212,6 +212,10 @@ export const packedRolePoliciesSchema = {
type: 'boolean', type: 'boolean',
optional: false, nullable: false, optional: false, nullable: false,
}, },
canSearchUsers: {
type: 'boolean',
optional: false, nullable: false,
},
canUseTranslator: { canUseTranslator: {
type: 'boolean', type: 'boolean',
optional: false, nullable: false, optional: false, nullable: false,
@ -313,6 +317,10 @@ export const packedRolePoliciesSchema = {
type: 'integer', type: 'integer',
optional: false, nullable: false, optional: false, nullable: false,
}, },
scheduledNoteLimit: {
type: 'integer',
optional: false, nullable: false,
},
watermarkAvailable: { watermarkAvailable: {
type: 'boolean', type: 'boolean',
optional: false, nullable: false, optional: false, nullable: false,

View File

@ -0,0 +1,55 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { webhookEventTypes } from '@/models/Webhook.js';
export const packedUserWebhookSchema = {
type: 'object',
properties: {
id: {
type: 'string',
format: 'id',
optional: false, nullable: false,
},
userId: {
type: 'string',
format: 'id',
optional: false, nullable: false,
},
name: {
type: 'string',
optional: false, nullable: false,
},
on: {
type: 'array',
items: {
type: 'string',
optional: false, nullable: false,
enum: webhookEventTypes,
},
},
url: {
type: 'string',
optional: false, nullable: false,
},
secret: {
type: 'string',
optional: false, nullable: false,
},
active: {
type: 'boolean',
optional: false, nullable: false,
},
latestSentAt: {
type: 'string',
format: 'date-time',
optional: false, nullable: true,
},
latestStatus: {
type: 'integer',
optional: false, nullable: true,
},
},
} as const;

View File

@ -65,7 +65,7 @@ export const packedUserLiteSchema = {
avatarUrl: { avatarUrl: {
type: 'string', type: 'string',
format: 'url', format: 'url',
nullable: true, optional: false, nullable: false, optional: false,
}, },
avatarBlurhash: { avatarBlurhash: {
type: 'string', type: 'string',
@ -465,11 +465,11 @@ export const packedMeDetailedOnlySchema = {
}, },
isModerator: { isModerator: {
type: 'boolean', type: 'boolean',
nullable: true, optional: false, nullable: false, optional: false,
}, },
isAdmin: { isAdmin: {
type: 'boolean', type: 'boolean',
nullable: true, optional: false, nullable: false, optional: false,
}, },
injectFeaturedNote: { injectFeaturedNote: {
type: 'boolean', type: 'boolean',
@ -591,7 +591,7 @@ export const packedMeDetailedOnlySchema = {
}, },
mutedInstances: { mutedInstances: {
type: 'array', type: 'array',
nullable: true, optional: false, nullable: false, optional: false,
items: { items: {
type: 'string', type: 'string',
nullable: false, optional: false, nullable: false, optional: false,
@ -609,6 +609,8 @@ export const packedMeDetailedOnlySchema = {
quote: { optional: true, ...notificationRecieveConfig }, quote: { optional: true, ...notificationRecieveConfig },
reaction: { optional: true, ...notificationRecieveConfig }, reaction: { optional: true, ...notificationRecieveConfig },
pollEnded: { optional: true, ...notificationRecieveConfig }, pollEnded: { optional: true, ...notificationRecieveConfig },
scheduledNotePosted: { optional: true, ...notificationRecieveConfig },
scheduledNotePostFailed: { optional: true, ...notificationRecieveConfig },
receiveFollowRequest: { optional: true, ...notificationRecieveConfig }, receiveFollowRequest: { optional: true, ...notificationRecieveConfig },
followRequestAccepted: { optional: true, ...notificationRecieveConfig }, followRequestAccepted: { optional: true, ...notificationRecieveConfig },
roleAssigned: { optional: true, ...notificationRecieveConfig }, roleAssigned: { optional: true, ...notificationRecieveConfig },

View File

@ -10,6 +10,7 @@ import { QueueLoggerService } from './QueueLoggerService.js';
import { QueueProcessorService } from './QueueProcessorService.js'; import { QueueProcessorService } from './QueueProcessorService.js';
import { DeliverProcessorService } from './processors/DeliverProcessorService.js'; import { DeliverProcessorService } from './processors/DeliverProcessorService.js';
import { EndedPollNotificationProcessorService } from './processors/EndedPollNotificationProcessorService.js'; import { EndedPollNotificationProcessorService } from './processors/EndedPollNotificationProcessorService.js';
import { PostScheduledNoteProcessorService } from './processors/PostScheduledNoteProcessorService.js';
import { InboxProcessorService } from './processors/InboxProcessorService.js'; import { InboxProcessorService } from './processors/InboxProcessorService.js';
import { UserWebhookDeliverProcessorService } from './processors/UserWebhookDeliverProcessorService.js'; import { UserWebhookDeliverProcessorService } from './processors/UserWebhookDeliverProcessorService.js';
import { SystemWebhookDeliverProcessorService } from './processors/SystemWebhookDeliverProcessorService.js'; import { SystemWebhookDeliverProcessorService } from './processors/SystemWebhookDeliverProcessorService.js';
@ -79,6 +80,7 @@ import { RelationshipProcessorService } from './processors/RelationshipProcessor
UserWebhookDeliverProcessorService, UserWebhookDeliverProcessorService,
SystemWebhookDeliverProcessorService, SystemWebhookDeliverProcessorService,
EndedPollNotificationProcessorService, EndedPollNotificationProcessorService,
PostScheduledNoteProcessorService,
DeliverProcessorService, DeliverProcessorService,
InboxProcessorService, InboxProcessorService,
AggregateRetentionProcessorService, AggregateRetentionProcessorService,

Some files were not shown because too many files have changed in this diff Show More