Compare commits

..

290 Commits

Author SHA1 Message Date
Kagami Sascha Rosylight
0b0a416566 Merge remote-tracking branch 'origin/develop' into misskey-js 2023-03-25 07:58:26 +01:00
syuilo
5be54451a8 Update CHANGELOG.md 2023-03-25 08:44:26 +09:00
syuilo
458b9feb62 New Crowdin updates (#10405)
* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Japanese, Kansai)
2023-03-25 08:36:15 +09:00
syuilo
e7fc998459 New Crowdin updates (#10404)
* New translations ja-JP.yml (Romanian)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Arabic)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Italian)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (Russian)

* New translations ja-JP.yml (Slovak)

* New translations ja-JP.yml (Ukrainian)

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

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

* 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 (Japanese, Kansai)
2023-03-24 20:03:44 +09:00
syuilo
da2483f7fe fix test 2023-03-24 19:09:02 +09:00
syuilo
31f3f5f0f0 enhance(backend): リモートサーバーのチャート生成を無効にするオプションを追加 2023-03-24 19:08:08 +09:00
syuilo
09a846a45c enhance(backend): use ❤️ for reaction fallback 2023-03-24 18:55:31 +09:00
syuilo
4edc7d8956 enhance of f01e6ef6bf 2023-03-24 18:48:42 +09:00
syuilo
6a29b182ee perf(backend): ドライブのチャートはローカルユーザーのみ生成するように 2023-03-24 18:37:08 +09:00
syuilo
46f99755db refactor 2023-03-24 18:29:39 +09:00
syuilo
05cba6d357 fix: add missing import 2023-03-24 17:03:03 +09:00
syuilo
c4e536ddbf Merge branch 'develop' of https://github.com/misskey-dev/misskey into develop 2023-03-24 17:01:47 +09:00
syuilo
d42c35cae7 13.10.3 2023-03-24 17:01:38 +09:00
syuilo
8a1ccd123d New Crowdin updates (#10392)
* New translations ja-JP.yml (Thai)

* New translations ja-JP.yml (Italian)

* New translations ja-JP.yml (Italian)

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

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Romanian)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Arabic)

* New translations ja-JP.yml (Catalan)

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Greek)

* New translations ja-JP.yml (Italian)

* 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 (Russian)

* 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 Simplified)

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

* 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 (Croatian)

* New translations ja-JP.yml (Uyghur)

* New translations ja-JP.yml (Lojban)

* New translations ja-JP.yml (Sinhala)

* New translations ja-JP.yml (Kannada)

* New translations ja-JP.yml (Lao)

* New translations ja-JP.yml (Haitian Creole)

* New translations ja-JP.yml (Kabyle)

* New translations ja-JP.yml (Japanese, Kansai)
2023-03-24 17:00:42 +09:00
syuilo
cabed6098d perf(frontend): cache user lists 2023-03-24 16:58:57 +09:00
syuilo
5f52b13325 enhance(frontend): クリップボタンをノートアクションに追加できるように 2023-03-24 16:54:37 +09:00
syuilo
e438091113 refactor(backend): rename cache class 2023-03-24 16:43:42 +09:00
syuilo
4a17906530 Merge branch 'develop' of https://github.com/misskey-dev/misskey into develop 2023-03-24 16:01:38 +09:00
syuilo
ab26a8016d fix(server): 空のアンテナが作成できるのを修正 2023-03-24 16:01:35 +09:00
kakkokari-gtyih
972963913b i18n: Webhook 設定画面に翻訳を追加 (#10379)
* Webhook 設定画面に翻訳を追加

* fix: typo

---------

Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
2023-03-24 15:44:26 +09:00
syuilo
f01e6ef6bf enhance(backend): リモートユーザーのチャート生成を無効にするオプションを追加 2023-03-24 15:43:36 +09:00
Acid Chicken (硫酸鶏)
7f9a41b05c fix: redesign cat ears (#10039)
* fix: viewing disgusting objects when user is a cat with having transparent avatar

* chore: mask cat ears when useBlurEffect is enabled

* fix: typo

* style: add comment

* chore: shrink mask

* chore: blur mask

* refactor: minify

* chore: use SVG to determine ear color

* style: comment

* refactor: use `<component>`

* refactor: separate cat definitions

* refactor: use singleton SVG definitions

* perf: use CSS instead of SVG

* refactor: unused definer

* refactor: not used anymore

* refactor: minify

* refactor: minify

* fix: import
2023-03-23 18:06:26 +09:00
syuilo
41d1b1b8c9 enhance: コンディショナルロールの条件に「投稿数が~以下」「投稿数が~以上」を追加
Resolve #10395
2023-03-23 17:18:38 +09:00
syuilo
48a97d25e5 fix(client): センシティブワードの一覧にピン留めユーザーのIDが表示される問題を修正
Fix #10398
2023-03-23 17:07:46 +09:00
YS
658901a47f bump aws-sdk to v3 for s3 (#10363)
* indent

* aws-sdk v3移行
2023-03-23 13:48:14 +09:00
syuilo
050787238b fix(backend): 絵文字を編集すると保存できないことがある問題を修正
Fix #10384
2023-03-22 18:45:55 +09:00
syuilo
fb42721160 13.10.2 2023-03-22 18:29:50 +09:00
syuilo
573634706d Merge branch 'develop' of https://github.com/misskey-dev/misskey into develop 2023-03-22 18:29:19 +09:00
syuilo
c6fc9af77a fix(client): ドライブファイルのメニューが正常に動作しない問題を修正
Fix #10387
2023-03-22 18:29:17 +09:00
syuilo
2474c7f4cb New Crowdin updates (#10386)
* New translations ja-JP.yml (German)

* New translations ja-JP.yml (English)
2023-03-22 18:26:23 +09:00
syuilo
d2f9798894 Merge branch 'develop' of https://github.com/misskey-dev/misskey into develop 2023-03-22 16:27:53 +09:00
syuilo
38815f6214 13.10.1 2023-03-22 16:27:39 +09:00
syuilo
640ad17854 New Crowdin updates (#10374)
* New translations ja-JP.yml (Chinese Simplified)

* New translations ja-JP.yml (Italian)

* New translations ja-JP.yml (Spanish)

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

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

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Chinese Traditional)
2023-03-22 16:26:27 +09:00
syuilo
24a3a0bbff fix(client): An error occurs when you press the Play button of Misskey Play
Fix #10381
2023-03-22 16:26:11 +09:00
syuilo
78a3d78a7f fix drive-cleaner 2023-03-22 09:09:43 +09:00
syuilo
9a40a4e315 Update packages/backend/test/utils.ts
Co-authored-by: Acid Chicken (硫酸鶏) <root@acid-chicken.com>
2023-03-22 08:59:50 +09:00
CyberRex
7331de0bce feat: queue force promote (#10370)
* feat: queue force promote

* Update CHANGELOG.md

* small fix
2023-03-22 08:58:23 +09:00
syuilo
75888a55c3 New Crowdin updates (#10369)
* New translations ja-JP.yml (German)

* New translations ja-JP.yml (English)
2023-03-20 20:49:10 +09:00
syuilo
dac4fbcb1e tweak settings/navbar.vue 2023-03-20 20:35:49 +09:00
syuilo
5e1014c072 Update CHANGELOG.md 2023-03-20 20:22:24 +09:00
Ekke
21b10603fe feat(frontend): ナビゲーションバーのカスタマイズをドラッグ&ドロップで行えるようにする (#10356)
* feat(frontend): ナビゲーションバーのカスタマイズをドラッグ&ドロップで行えるようにする

* eslintのエラーを修正

* ハンドルをつかんでドラッグするように変更

* eslintのエラーを修正

* デザインの軽微な変更

* 修正

* Update CHANGELOG.md

* Update CHANGELOG.md

* ドラッグハンドルを3本線から2本線に

---------

Co-authored-by: root <root@Adam-Windows>
2023-03-20 20:21:54 +09:00
syuilo
54630edb0f enhance: 使われてないアンテナは自動停止されるように
Resolve #9373
2023-03-20 20:12:38 +09:00
choco
eb5781465b fix(users/show): ユーザーが見つからなかった場合に404ステータスコードを返す (#10344)
* fix(users/show): ユーザーが見つからなかった場合に404ステータスコードを返す

* test(users/show): ステータスコードの期待値を修正
2023-03-20 14:26:11 +09:00
syuilo
3014e3e5f8 Update CHANGELOG.md 2023-03-20 14:25:21 +09:00
nenohi
e152047912 絵文字の名前に@や:が使用できる (#9964)
* fix(#9918)名前の一致でもエラーとするように

* 判定を逆に

* )の位置間違えてる

* カテゴリ分けとかしたときにエラーになる

* エラー消し

* こういうこと・・・?
2023-03-20 14:24:18 +09:00
syuilo
3d6aaa7aaa tweak drive-cleaner 2023-03-20 13:20:21 +09:00
syuilo
32c60c774c fix indentation 2023-03-20 13:00:21 +09:00
syuilo
bf5706ef6e Update CHANGELOG.md 2023-03-20 12:58:55 +09:00
CyberRex
1d6f43aa30 feat: drive cleaner (#10366)
* feat: drive-cleaner

* Update CHANGELOG.md
2023-03-20 12:58:06 +09:00
syuilo
4a989f7ebb Update CHANGELOG.md 2023-03-19 20:28:50 +09:00
kakkokari-gtyih
866aded6bc fix: PC版設定ページでスマホ用UIが表示されるのを防ぐリダイレクトを追加 (#10326)
* (Fix misskey-dev#10324)設定画面:PC版UIへのリダイレクトをルート遷移時にも実行

* Update changelog

* (fix) missing semicolon

* (fix) strict equals
2023-03-19 20:28:19 +09:00
Kagami Sascha Rosylight
e542a030e4 fix(backend/URLPreviewService): エラーでHTTP 422を出すように (#10339)
* fix(backend/URLPreviewService): エラーでHTTP 402を出すように

* fix import
2023-03-19 20:27:17 +09:00
Nanashia
2e051c5871 test(backend): Add tests for clips (#10358) 2023-03-19 20:26:38 +09:00
Kagami Sascha Rosylight
9044fa5d1a Merge branch 'develop' into misskey-js 2023-03-19 10:26:30 +01:00
syuilo
37b8f40151 New Crowdin updates (#10349)
* New translations ja-JP.yml (Chinese Simplified)

* New translations ja-JP.yml (Chinese Simplified)
2023-03-19 17:08:39 +09:00
syuilo
3b3086510c Update CHANGELOG.md 2023-03-19 17:07:00 +09:00
syuilo
8b1b3e3b54 Update CHANGELOG.md 2023-03-19 17:06:12 +09:00
kakkokari-gtyih
459d3053d3 fix: 非ログイン時に「Misskeyについて」ページから投稿フォームが出ないようにする (#10345)
* (fix misskey-dev#9486) 非ログイン時の I ❤ Misskey のふるまい

* 「キャンセル」ボタンにより適切な翻訳をあてる

* Update CHANGELOG.md

* もともと用意されていたサインイン確認関数に置き換え

* Update CHANGELOG.md

* 独自ダイアログでなくなった以上、async指定は要らないので解除

* ボタンをそもそも非表示にする
2023-03-19 17:05:31 +09:00
syuilo
15d9c0f74c Update CHANGELOG.md 2023-03-19 17:04:01 +09:00
Kagami Sascha Rosylight
c091d9e6d5 feat(frontend/MkUrlPreview): oEmbedのサポート (#10306)
* feat(frontend/MkUrlPreview): oEmbedのサポート

* Update CHANGELOG.md

* Update CHANGELOG.md

* Update CHANGELOG.md

* playerとoEmbedの統合

* Update CHANGELOG.md

* loading=lazyはここでは不要

* border: 0

* プレビュー直後にautoplayできる機能の復旧

* add test

* refactor test

* explain about cache

* expandPreviewはもう使わない

* summaly v4

* update summaly

* scrolling=no to fix pixiv

---------

Co-authored-by: tamaina <tamaina@hotmail.co.jp>
2023-03-19 16:59:31 +09:00
syuilo
4d73080da1 perf(backend): improve performance of timeline apis 2023-03-19 16:52:38 +09:00
syuilo
497ffde233 Update CHANGELOG.md 2023-03-19 15:47:29 +09:00
atsuchan
793dacef19 Fix: foreignkey on reports (#9753) 2023-03-19 15:46:24 +09:00
syuilo
7699b49d33 enhance(client): add ads page 2023-03-18 14:30:16 +09:00
Nanashia
8571c692ba test(backend): Add tests for web resources (#10341) 2023-03-18 09:01:10 +09:00
tamaina
3757d3ab88 update pnpm 2023-03-17 13:39:35 +00:00
syuilo
68906395ba New translations ja-JP.yml (Italian) (#10343) 2023-03-17 21:17:51 +09:00
syuilo
ac66550666 13.10.0 2023-03-17 20:43:36 +09:00
syuilo
e5ad37e6d0 update aiscript 2023-03-17 20:41:25 +09:00
syuilo
ed51209172 絵文字のライセンスを表示できるように 2023-03-17 20:24:47 +09:00
syuilo
2be93b1fe6 New Crowdin updates (#10254)
* New translations ja-JP.yml (Korean)

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

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

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (English)

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

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

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

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

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (English)

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

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

* New translations ja-JP.yml (Italian)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Korean)

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

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Italian)

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

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

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

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

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

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

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

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

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (English)

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

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

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

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

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

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

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

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

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Italian)

* New translations ja-JP.yml (Italian)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Japanese, Kansai)
2023-03-17 20:08:43 +09:00
Kagami Sascha Rosylight
3bb343e2fc Merge branch 'develop' into misskey-js 2023-03-17 11:11:21 +01:00
syuilo
ac0e0122f6 refactor 2023-03-17 15:09:43 +09:00
Kagami Sascha Rosylight
f2fd8bfac1 Update Dockerfile 2023-03-16 23:05:48 +01:00
Kagami Sascha Rosylight
1602ad843a Update pnpm-lock.yaml 2023-03-16 22:42:46 +01:00
Kagami Sascha Rosylight
e68236bd84 Update package.json 2023-03-16 22:35:52 +01:00
Kagami Sascha Rosylight
447b6f9e5f upgrade @types/node 2023-03-16 22:30:12 +01:00
Kagami Sascha Rosylight
746bc322b7 types too 2023-03-16 22:24:59 +01:00
Kagami Sascha Rosylight
a6aee82fcf upgrade jest 2023-03-16 22:23:52 +01:00
Kagami Sascha Rosylight
6095b33ab2 fix vite build 2023-03-16 22:13:42 +01:00
Kagami Sascha Rosylight
5ac094e51b fix lint errors 2023-03-16 21:38:20 +01:00
Kagami Sascha Rosylight
bdf013d547 Update pnpm-lock.yaml 2023-03-16 21:35:58 +01:00
Kagami Sascha Rosylight
96a2dda153 Update package.json 2023-03-16 21:32:16 +01:00
Kagami Sascha Rosylight
d69d2c8e8d Update test-misskey-js.yml 2023-03-16 21:24:22 +01:00
Kagami Sascha Rosylight
8736bb42f2 Update test-misskey-js.yml 2023-03-16 21:22:39 +01:00
Kagami Sascha Rosylight
effd78dc98 skip pnpm/action-setup? 2023-03-16 21:18:32 +01:00
Kagami Sascha Rosylight
634ce0fa49 Update misskey-js.api.md 2023-03-16 21:18:08 +01:00
Kagami Sascha Rosylight
6e6a5222cd enable corepack first 2023-03-16 21:14:55 +01:00
Kagami Sascha Rosylight
ce5a9630ca update workflows 2023-03-16 21:13:21 +01:00
Kagami Sascha Rosylight
d123722616 chore: integrate misskey-js as a workspace item 2023-03-16 21:07:16 +01:00
syuilo
b644567735 feat: clip favorite
Resolve #10337
2023-03-16 17:24:49 +09:00
syuilo
8ae9d2eaa8 enhance: カスタム絵文字にライセンス情報を付与できるように
Resolve #10091
2023-03-16 15:08:48 +09:00
syuilo
a9bc22e4e6 Update NotificationService.ts 2023-03-16 14:36:21 +09:00
syuilo
89e2c302dd refactor(backend): integrate CreateNotificationService to NotificationService 2023-03-16 14:24:11 +09:00
syuilo
0944c1cd6f update tabler-icons 2023-03-16 14:14:14 +09:00
syuilo
9cc58fd3bc Update CHANGELOG.md 2023-03-16 12:13:52 +09:00
syuilo
925cc06aea enhance(client): tweak search page 2023-03-16 11:56:20 +09:00
syuilo
6da6c4dd45 enhance(client): update AiScript to 0.13.0 2023-03-15 18:26:59 +09:00
syuilo
f9cdcc9bc6 Merge branch 'develop' of https://github.com/misskey-dev/misskey into develop 2023-03-15 18:09:03 +09:00
syuilo
63068fc0c2 fix(server): prevent creation of empty antennas 2023-03-15 18:09:00 +09:00
kakkokari-gtyih
7ff467e8e0 feat(client): Navbar の設定項目に「プロフィール」を追加 (#10332)
* feat: navbar項目 自プロフィールを追加 (misskey-dev#10330)

* change CHANGELOG.md
2023-03-15 18:01:56 +09:00
syuilo
a8bd3e8e53 Update AggregateRetentionProcessorService.ts 2023-03-15 17:45:59 +09:00
syuilo
58fc17e3b6 fix: tweak retention rate aggregation 2023-03-15 17:43:13 +09:00
タービン
42833cd921 Fix #10261 (#10323) 2023-03-15 10:44:24 +09:00
CyberRex
c05c504c86 Deliverキューに宛先がSharedInboxかどうかのフラグを追加 ( #10298 関係 ) (#10317)
* enhance(backend): 配送先が410 Goneで応答してきた場合配送停止するように

* Update CHANGELOG.md

* Deliverキューのデータに宛先がSharedInboxかどうかのフラグを追加

* Fix lint

* Mapを使用するように

* Fix typo
2023-03-14 19:11:31 +09:00
YS
3cb669a852 fix: クエリキャッシュ無効化時の絵文字操作エラーを解消 (#10320)
* disabledCache: trueのときにqueryResultCacheへアクセスしないように

* append changelog
2023-03-14 09:37:14 +09:00
Cj-bc
850addc619 user schemaにあるany型を厳格にした (#10319)
使用されている箇所から、これらのプロパティの型はstring型に限定出来そうということが分かった。
又、OpenAPIv3の仕様上はanyは使えないため修正した。

related: https://github.com/misskey-dev/misskey/issues/10308

* Update CHANGELOG
2023-03-13 23:13:51 +09:00
syuilo
7887ccc993 Merge branch 'develop' of https://github.com/misskey-dev/misskey into develop 2023-03-13 20:04:38 +09:00
Kisaragi
191233143f refactor(frontend): 引数の型を強くし、関数内部のas anyを除去 (#10315) 2023-03-13 20:04:14 +09:00
syuilo
1a62ca52a0 chore(client): tweak admin/roles page 2023-03-13 20:02:53 +09:00
syuilo
5d1ccb9bdc enhance: make configurable to whether notes search available by role
Resolve #10318
2023-03-13 17:52:24 +09:00
syuilo
7f16b50e73 feat: sensitive word 2023-03-13 17:37:22 +09:00
CyberRex
b18df999cd enhance(backend): 配送先が410 Goneで応答してきた場合配送停止するように (#10298)
* enhance(backend): 配送先が410 Goneで応答してきた場合配送停止するように

* Update CHANGELOG.md
2023-03-13 09:46:53 +09:00
Kagami Sascha Rosylight
0d2bee787d fix(frontend/XHome): fall back to user.uri if user.url does not exist (#10313)
* fix(frontend/XHome): fall back to user.uri if user.url does not exist

* Update CHANGELOG.md
2023-03-13 09:46:33 +09:00
YS
44213812b8 空文字列のobjectStorageEndtpoinをnullと同様に扱う (#10312) 2023-03-13 09:45:21 +09:00
syuilo
7e9d3d9b2f Merge branch 'develop' of https://github.com/misskey-dev/misskey into develop 2023-03-12 20:57:04 +09:00
syuilo
a43398ce1d refactor(test): rename variable for INestApplicationContext 2023-03-12 20:57:01 +09:00
tamaina
dff0bee748 fix: Do not use avif (#10301)
* fix: Do not use avif

* fix

* fix
2023-03-12 17:31:52 +09:00
syuilo
ba98abc97b Merge branch 'develop' of https://github.com/misskey-dev/misskey into develop 2023-03-12 16:45:11 +09:00
atsuchan
4215a11d9a パスワードリセットがおささってしまわないようにする (#10304)
Add dialog to Password reset
2023-03-12 16:44:41 +09:00
syuilo
8ac5c35f09 enhance(client): 設定から自分のロールを確認できるように 2023-03-12 16:39:16 +09:00
syuilo
7c2d8d73ce enhance: ロールの並び順を設定可能に 2023-03-12 16:38:08 +09:00
Kagami Sascha Rosylight
57cac0aa23 fix(backend/ApRendererService): allow announces with visibility: followers (#10291)
* fix(backend/ApRendererService): allow announces with visibility: followers

* Update CHANGELOG.md

---------

Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
2023-03-12 12:11:37 +09:00
atsuchan
31488da40c タイムラインを正常に無効化できるように (#10299)
* タイムラインを正常に無効化できるように

Timeline can be disabled successfully

* Tune: disabled timeline to update disabled state immediately

カラムの判定の場所をこっちにしないとリアルタイムで更新が反映されないので変更(タイムラインを正常に無効化できるように)

* modify disabled timeline icon to ti-circle-minus

無効化されたタイムラインのアイコンをTabler iconのti-circle-minusに修正

Co-authored-by: Acid Chicken (硫酸鶏) <root@acid-chicken.com>

---------

Co-authored-by: Acid Chicken (硫酸鶏) <root@acid-chicken.com>
2023-03-12 10:20:33 +09:00
Kagami Sascha Rosylight
1ea4469bec fix(frontend/MkSignup): prevent uncaught errors from interrupted signup (#10265)
* fix(frontend/MkSignup): prevent uncaught errors from interrupted signup

* nullable sitekey

---------

Co-authored-by: tamaina <tamaina@hotmail.co.jp>
2023-03-11 14:32:13 +09:00
Nanashia
4e7e377987 add backend 2fa test (#10289) 2023-03-11 14:13:39 +09:00
tamaina
88e3d3e8cb enhance(server): 画像圧縮周り(主にサムネイルの仕様)の変更 (#10287)
* DriveService, is-mime-image

* static, previewをavifに, アニメーション画像でもthumbnailを生成

* fallback

* animated: true

* fix

* avatarはwebp

* revert ?? file.url

---------

Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
2023-03-11 14:11:40 +09:00
syuilo
cc7fd2f68a Update CHANGELOG.md 2023-03-11 13:40:46 +09:00
(Fairy)Phy
488754437d fix(frontend): Safariでプラグインが複数ある場合に正常に読み込まれない問題を修正 (#10290)
* Safariでプラグインが複数ある場合に正常に読み込まれない問題を修正

* Update packages/frontend/src/init.ts

Co-authored-by: rinsuki <428rinsuki+git@gmail.com>

* Update packages/frontend/src/init.ts

Co-authored-by: rinsuki <428rinsuki+git@gmail.com>

---------

Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
Co-authored-by: rinsuki <428rinsuki+git@gmail.com>
2023-03-11 13:40:22 +09:00
Kagami Sascha Rosylight
4094ab58aa fix(backend/DriveService): gracely skip when getting NoSuchKey error from S3 (#10292)
* fix(backend/DriveService): gracely skip when getting NoSuchKey error from S3

* Update CHANGELOG.md

* import type
2023-03-11 13:35:51 +09:00
Kisaragi
0ac1fc846b refactor(backend): 必要ないas anyを消去 (#10293) 2023-03-11 08:51:37 +09:00
syuilo
65b1524f92 enhance(client): 付箋ウィジェットの高さを設定可能に 2023-03-10 19:51:35 +09:00
nenohi
e13202a452 Issue:#9828対応 (#9916) 2023-03-10 19:30:21 +09:00
syuilo
787404638a fix(client): プロフィールで設定した情報が削除できない
Fix #10279
2023-03-10 18:48:57 +09:00
syuilo
533fe2d607 Update ja-JP.yml 2023-03-10 18:07:11 +09:00
syuilo
c12e3c46ff Update about-misskey.vue 2023-03-10 18:05:35 +09:00
syuilo
99f3f0917f tweak postgresql entities
Fix #10266
2023-03-10 14:53:56 +09:00
syuilo
258bd3c905 Merge branch 'develop' of https://github.com/misskey-dev/misskey into develop 2023-03-10 14:22:42 +09:00
syuilo
5de8930058 refactor: rename schema to json-schema 2023-03-10 14:22:37 +09:00
YS
b7c26dc29d 絵文字ピッカーのすべての絵文字でマウスホバー時にtitle表示されるように (#9765)
* 絵文字ピッカーの絵文字アイコン選択のコンポーネント化とすべてでtitle表示

* コンポーネント化を取り消し、イベントとデータ属性で行う

* fix typo

---------

Co-authored-by: tamaina <tamaina@hotmail.co.jp>
2023-03-10 14:15:49 +09:00
syuilo
66aef2e716 🎨 2023-03-10 14:07:34 +09:00
syuilo
c0bad443ff update deps 2023-03-10 14:00:14 +09:00
Kisaragi
a81ebc5966 chore(backend): fix typo in warning message (#10284) 2023-03-10 13:21:23 +09:00
syuilo
c717f1f3a9 Update CHANGELOG.md 2023-03-10 09:38:21 +09:00
Kagami Sascha Rosylight
3f53cbd8f6 fix(backend/DriveService): convert WebP/AVIF to WebP (#10239)
* fix(backend/DriveService): convert transparent WebP/AVIF to PNG

* webpにする

その希望が複数ありましたので

* Update packages/backend/src/core/DriveService.ts

Co-authored-by: Acid Chicken (硫酸鶏) <root@acid-chicken.com>

* update test

* webpはwebpublicにできる

---------

Co-authored-by: Acid Chicken (硫酸鶏) <root@acid-chicken.com>
Co-authored-by: tamaina <tamaina@hotmail.co.jp>
2023-03-10 09:37:22 +09:00
Kagami Sascha Rosylight
e0b7633a7a enhance(backend): restore OpenAPI endpoints (#10281)
* enhance(backend): restore OpenAPI endpoints

* Update CHANGELOG.md

* version

* set max-age

* update redoc

* follow redoc documentation

---------

Co-authored-by: tamaina <tamaina@hotmail.co.jp>
2023-03-10 02:37:44 +09:00
Launchpad
caf646fcb0 fix(client): Solve the problem of not automatically jumping to /admin/overview when accessing the /admin page for the second time (#10264)
Co-authored-by: tamaina <tamaina@hotmail.co.jp>
2023-03-10 02:22:47 +09:00
kabo2468
228c92f2ca ドライブのファイルを消すときの文章を「ノートは消えない」と修正 (#10096)
* Update ja-JP.yml

* Update ja-JP.yml
2023-03-10 02:16:00 +09:00
tamaina
89393aaf95 Merge pull request #10248 from saschanaz/alt-pre-line
fix(frontend/MkMediaList): altメッセージのnewlineを認識
2023-03-10 00:17:06 +09:00
tamaina
5888da19b8 Merge pull request #10282 from misskey-dev/saschanaz-patch-1
fix(frontend/widget): federation widgetのdata-cyも移動
2023-03-09 23:28:47 +09:00
Kagami Sascha Rosylight
ef773520e6 fix(frontend/widget): federation widgetのdata-cyも移動
fcb6e0adb9 の後テストが落ちている
2023-03-09 15:09:49 +01:00
tamaina
dc49a24f07 Merge pull request #9970 from saschanaz/mkusername-empty
fix(backend/ApPersonService): normalize empty value of `name` into an absent value
2023-03-09 22:36:26 +09:00
syuilo
fcb6e0adb9 chore(test): data属性がclassになっているのを修正 2023-03-09 19:59:11 +09:00
Acid Chicken (硫酸鶏)
93ea9c2033 chore(frontend): add debugger for #6864 (#10270) 2023-03-09 14:35:38 +09:00
tamaina
c75afad64a enhance: アカウント削除時のクライアントの挙動をいい感じにするなど (#10002)
* refreshAccounts
Resolve #9322

* アカウント管理画面でリストを更新するように

* Update packages/frontend/src/account.ts

Co-authored-by: Acid Chicken (硫酸鶏) <root@acid-chicken.com>

* ✌️

* クライアント起動時は現在ログインしているアカウントのみリフレッシュする

* clean up

* なんかめっちゃ変えた

* refactor

* refactor

* fix lint

---------

Co-authored-by: Acid Chicken (硫酸鶏) <root@acid-chicken.com>
2023-03-09 14:27:16 +09:00
RyotaK
a4ca127ebd fix: 登録メール送信時に重複確認を行う (#10231)
* fix: 登録メール送信時に重複確認を行う

* try-catchを使う必要はない

* Remove spaces
2023-03-09 12:57:34 +09:00
Kagami Sascha Rosylight
4835f0fb43 fix(frontend): GIFバナーの復活など (#10247)
* Restore GIF banner

* Add ALT banner, detect APNG too

* Add vitest

* Add CI for vitest

* Upload coverage?

* frontend
2023-03-09 12:48:39 +09:00
syuilo
6607b39235 fix(client): ロールで広告を無効にするとadmin/adsでプレビューがでてこない
Fix #10272
2023-03-09 12:28:40 +09:00
Ebise Lutica
9d1a874ddc フォローリクエストのUI改善 (#10275)
* フォローリクエストのUI改善

* Update CHANGELOG.md
2023-03-09 12:17:34 +09:00
syuilo
965433bea9 chore(dev): add pull_request_template.md for github bug 2023-03-09 08:11:17 +09:00
syuilo
7fd17232cc chore(dev): update pull request templates 2023-03-09 08:06:22 +09:00
mmorita
aad70a97db fix: チャンネルの編集権限をチャンネル所有者とモデレーターに限定する (#10268)
* チャンネルの編集権限をチャンネルオーナーとモデレーターに限定する

* PR 指摘点対応(共有ボタンを全員に表示、$i の nullable 対応、fix a typo)

* everyOne -> share
2023-03-09 07:58:53 +09:00
tamaina
97a43bc30f fix(server): videoThumbnailGeneratorが適用されない問題を修正 2023-03-08 19:57:52 +00:00
RyotaK
116dd097bd fix: 登録フォームにおける競合状態を修正 (#10267)
* fix: 登録フォームにおける競合状態を修正

* エラーを修正
2023-03-08 16:32:13 +09:00
syuilo
dd6569a1bb feat: Reaction acceptance (#10256)
* wip

* wip

* デフォルト設定
2023-03-08 08:56:47 +09:00
syuilo
4c2f7c64cc feat: Per-user renote mute (#10249)
* feat: per-user renote muting

From FoundKey/c414f24a2c https://akkoma.dev/FoundKeyGang/FoundKey

* Update ja-JP.yml

* Delete renote-muting.ts

* rename

* fix ids

* lint

* fix

* Update CHANGELOG.md

* リノートをミュートしたユーザー一覧を見れるように

* 🎨

* add test

* fix test

---------

Co-authored-by: Hélène <pleroma-dev@helene.moe>
2023-03-08 08:56:09 +09:00
syuilo
8bf6911d4b refactor(dev): separate test workflows 2023-03-07 20:23:44 +09:00
syuilo
6fe13f1a63 lint fix 2023-03-07 20:17:19 +09:00
danominium
4f0bb70118 fix(backend): ブロックホストがない場合はINクエリを生成しない。 (#10258)
空のINクエリはシンタックスエラーとなるため。
2023-03-07 20:09:20 +09:00
syuilo
b20703c185 tweak of 0554dd8375 2023-03-07 19:48:51 +09:00
syuilo
0554dd8375 enhance(client): DM作成時にメンションも含むように 2023-03-07 17:12:46 +09:00
syuilo
1ef6bec133 Update about-misskey.vue 2023-03-07 16:54:19 +09:00
RyotaK
6feead5185 fix: 登録時のフォームにおいて送信できる条件を修正 (#10238)
* fix: 登録時のフォームにおいて送信できる条件を修正

* テストを追加
2023-03-07 16:07:13 +09:00
syuilo
60c1af674f chore(client): tweak default sound setting 2023-03-07 09:51:37 +09:00
syuilo
3ecb863372 enhance(client): improve mute-block page 2023-03-07 09:37:02 +09:00
syuilo
2b884ba338 enhance(server): tweak notes/featured api 2023-03-07 08:41:10 +09:00
Kagami Sascha Rosylight
d90a98a8a7 fix(frontend/MkMediaList): altメッセージのnewlineを認識 2023-03-06 22:02:51 +01:00
Kagami Sascha Rosylight
5651353c27 Merge branch 'develop' into mkusername-empty 2023-03-06 07:51:17 +01:00
syuilo
31f9ea31b9 [ci skip] chore(client): showNoteActionsOnlyHover変更時にリロードダイアログを出すように 2023-03-06 11:53:04 +09:00
syuilo
5ccbeda86a Merge branch 'develop' of https://github.com/misskey-dev/misskey into develop 2023-03-06 02:14:56 +00:00
syuilo
f20abb4ee5 fix(client): みつけるのロール一覧でコンディショナルロールが含まれるのを修正 2023-03-06 02:12:35 +00:00
tamaina
7852815fc3 update CHANGELOG.md 2023-03-06 02:08:06 +00:00
tamaina
6778111891 update CHANGELOG.md 2023-03-06 02:04:53 +00:00
syuilo
b719f6cd1c New Crowdin updates (#10223)
* New translations ja-JP.yml (Thai)

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

* New translations ja-JP.yml (Italian)

* New translations ja-JP.yml (Italian)
2023-03-06 10:32:36 +09:00
tamaina
6bb11492fa update CHANGELOG.md 2023-03-06 01:31:44 +00:00
tamaina
87d0f56dc7 fix correctFilename extが.から始まる場合も考慮する 2023-03-06 01:17:13 +00:00
syuilo
824398509d Update CHANGELOG.md 2023-03-05 22:01:06 +09:00
Acid Chicken (硫酸鶏)
b1c173ec4f fix(docker): cannot build docker image on some environments (#10220) 2023-03-05 22:00:17 +09:00
arrow2nd
8c9c89a137 fix(frontend): ユーザーページのバッジ表示を適切に折り返すように (#10222)
* fix(frontend): ユーザーページのバッジ表示を適切に折り返すように

* Update CHANGELOG.md
2023-03-05 21:59:41 +09:00
syuilo
353b1cc682 [ci skip] 🎨 2023-03-05 20:52:26 +09:00
syuilo
9f73c23b38 [ci skip] fix(client): fix post button of channel 2023-03-05 20:48:46 +09:00
syuilo
517a7f96c8 [ci skip] Update CHANGELOG.md 2023-03-05 20:46:18 +09:00
syuilo
e844710ef2 13.9.2 2023-03-05 20:32:02 +09:00
syuilo
d6d0b9659f Merge branch 'develop' of https://github.com/misskey-dev/misskey into develop 2023-03-05 20:28:43 +09:00
syuilo
4480fa1efe refactor(client): use css module 2023-03-05 20:28:39 +09:00
syuilo
f8ab34734c enhance(client): tweak MkFolder component 2023-03-05 20:28:27 +09:00
tamaina
65d7c47647 Merge branch 'develop' of https://github.com/misskey-dev/misskey into develop 2023-03-05 11:16:41 +00:00
tamaina
428046e710 chore: remove deprecated vs code extention 2023-03-05 11:16:26 +00:00
tamaina
1641ae1d96 Merge pull request #10213 from Ry0taK/fix/disable-jest-autorun
fix: Jestの自動実行を無効に
2023-03-05 20:13:37 +09:00
tamaina
b23407807c Merge pull request #10206 from Khsmty/fix-devcontainer-pnpm
fix: devcontainer で pnpm が command not found になるのを修正
2023-03-05 20:10:55 +09:00
tamaina
2bb0a5ac6e Merge pull request #10207 from Ry0taK/fix/devcontainer-on-macos
fix: macOS上でDev Containersが動作しない問題を修正
2023-03-05 20:07:16 +09:00
syuilo
aa01ba7cce enhance(client): tweak brain diver detection 2023-03-05 20:00:37 +09:00
syuilo
b4835c7e01 New Crowdin updates (#10214)
* New translations ja-JP.yml (German)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Japanese, Kansai)
2023-03-05 19:37:26 +09:00
Ry0taK
f5b63d8287 fix: Jestの自動実行を無効に 2023-03-05 14:40:41 +09:00
RyotaK
8e8c2b40f9 fix: pnpm dev時にファイルが空ならバックエンドの起動を待つように (#10210) 2023-03-05 14:33:23 +09:00
jojobii
ad43011fb8 change: deprecate link to Misskey Forum in favor of GitHub Discussions (#10212)
see: https://forum.misskey.io/d/112-misskey-forum-to-end-service-at-the-end-of-this-month
2023-03-05 14:32:43 +09:00
syuilo
7b8e1e6913 enhance(client): tweak signup form 2023-03-05 14:05:28 +09:00
Ry0taK
d53a177e7b fix: macOS上でDevContainerが動作しない問題を修正 2023-03-05 12:48:27 +09:00
syuilo
85d93133d3 Update about-misskey.vue 2023-03-05 11:34:46 +09:00
syuilo
4cf3bc53c2 New Crowdin updates (#10184)
* New translations ja-JP.yml (Chinese Simplified)

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

* New translations ja-JP.yml (Italian)

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

* New translations ja-JP.yml (Lao)

* New translations ja-JP.yml (Thai)

* New translations ja-JP.yml (Lao)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Italian)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Thai)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Thai)

* New translations ja-JP.yml (Lao)

* New translations ja-JP.yml (Lao)

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

* New translations ja-JP.yml (Chinese Traditional)
2023-03-05 11:12:40 +09:00
syuilo
ae7d17d121 fix of b9a3b2c165 2023-03-05 11:11:36 +09:00
syuilo
b9a3b2c165 enhance(server): make identicon same between local and remote
Resolve #10200
2023-03-05 11:09:55 +09:00
syuilo
ba2630c615 tweak of 8e5e6f90cb 2023-03-05 10:59:44 +09:00
syuilo
8e5e6f90cb fix(client): PWAでlangがnullになる現象の応急処置
#10202
2023-03-05 10:57:54 +09:00
syuilo
f6c6ffaf64 Merge branch 'develop' of https://github.com/misskey-dev/misskey into develop 2023-03-05 10:48:07 +09:00
syuilo
5c88c17d15 fix(client): ロールの権限で「一般ユーザー」のロールがいきなり設定できない問題を修正
Fix #10203
2023-03-05 10:48:04 +09:00
Khsmty
68ab056b3c fix: pnpm が command not found になるのを修正 2023-03-05 01:47:08 +00:00
tamaina
c54712233c Dev Container周り
Related to #10201
2023-03-05 01:06:30 +09:00
rinsuki
ccdac0ca96 docker: build assets on native arch (#10080)
* docker: build assets on native arch

* 消しすぎた
2023-03-04 21:36:52 +09:00
tamaina
c36e7d1a07 enhance(server): メディアプロキシでico,bmpを読めるように (#10186)
* enhance(server): downloadUrlでContent-Dispositionからファイル名を取得
Resolve #10036
Resolve #4750

* untitled

* オブジェクトストレージのContent-Dispositionのファイル名の拡張子をContent-Typeに添ったものにする

* ✌️

* tiff

* fix filename

* add test

* /files/でもContent-Disposition

* enhance(server): メディアプロキシでico,bmpを読めるように
Fix #10120

* comment

* fix test

---------

Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
2023-03-04 19:23:11 +09:00
nexryai
72b315491b Fix: If mail delivery is disabled on the server, make the settings page indicate this (#10191)
Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
2023-03-04 19:19:55 +09:00
Ikumi Nakamura
6dd9374b99 chore: Replace tab with space (#10185) 2023-03-04 17:42:03 +09:00
syuilo
1711ae7156 🎨 2023-03-04 17:36:11 +09:00
syuilo
320c2bf771 Update CHANGELOG.md 2023-03-04 17:19:21 +09:00
syuilo
3f507241ca chore(client): tweak default value of numberOfPageCache 2023-03-04 17:19:18 +09:00
tamaina
2d551a8598 enhance(server): downloadUrlでContent-Dispositionからファイル名を取得 (#10150)
* enhance(server): downloadUrlでContent-Dispositionからファイル名を取得
Resolve #10036
Resolve #4750

* untitled

* オブジェクトストレージのContent-Dispositionのファイル名の拡張子をContent-Typeに添ったものにする

* ✌️

* tiff

* fix filename

* add test

* /files/でもContent-Disposition

* comment

* fix test
2023-03-04 16:51:07 +09:00
rinsuki
49f0837729 fix(server): DriveFile related N+1 query when call note packMany (again) (#10190)
* Revert "Revert "fix(server): DriveFile related N+1 query when call note packMany (#10133)""

This reverts commit a7c82eeabc.

* packManyByIdsMap: 存在チェックをしてなかったものは null を入れるように

* Note.packMany で reply とか renote がもうあったらそのファイルも引く

* テストを書く

* fix test

* fix test

* fix test

* fix test
2023-03-04 16:48:50 +09:00
syuilo
e4fc9ea816 enhance(client): improve channel ui 2023-03-04 10:50:21 +09:00
syuilo
b303d65450 fix(client): Viteで This assignment will throw because "role" is a constantというエラーが出る
Fix #10187
2023-03-04 10:36:48 +09:00
syuilo
dcd4d80869 enhance(client): improve channel ui 2023-03-04 10:34:54 +09:00
syuilo
aee7ed992b enhance(client): add share button to clip and channel page
Resolve #10183
2023-03-04 10:17:45 +09:00
syuilo
7e8700514f 13.9.1 2023-03-03 20:45:17 +09:00
syuilo
c8aa55636f Merge branch 'develop' of https://github.com/misskey-dev/misskey into develop 2023-03-03 20:44:59 +09:00
syuilo
1fed0ff564 New Crowdin updates (#10176)
* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Vietnamese)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Vietnamese)

* New translations ja-JP.yml (Vietnamese)

* New translations ja-JP.yml (Vietnamese)

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

* New translations ja-JP.yml (Vietnamese)

* New translations ja-JP.yml (Vietnamese)
2023-03-03 20:44:43 +09:00
syuilo
ad7ecbaf37 通知部分は残す
Co-Authored-By: rinsuki <428rinsuki+contact.github@gmail.com>
2023-03-03 20:43:31 +09:00
syuilo
a7c82eeabc Revert "fix(server): DriveFile related N+1 query when call note packMany (#10133)"
This reverts commit 452a48e7f4.
2023-03-03 20:26:44 +09:00
tamaina
da3fcf178e fix CHANGELOG.md 2023-03-03 06:12:34 +00:00
syuilo
5d46c1c9bb (CSS完全に)理解した 2023-03-03 14:55:56 +09:00
syuilo
1b33653f1b 13.9.0 2023-03-03 12:32:05 +09:00
syuilo
af24011eec clean up 2023-03-03 12:31:41 +09:00
syuilo
87c6d0cbee 🎨 2023-03-03 12:29:34 +09:00
syuilo
3066a133ac fix(client): prevent null reference error 2023-03-03 11:43:53 +09:00
syuilo
436190966c New Crowdin updates (#10114)
* New translations ja-JP.yml (Italian)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Russian)

* New translations ja-JP.yml (Italian)

* New translations ja-JP.yml (Italian)

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

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (English)

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

* New translations ja-JP.yml (Italian)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Thai)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Arabic)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Italian)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (Russian)

* New translations ja-JP.yml (Slovak)

* New translations ja-JP.yml (Ukrainian)

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

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

* 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 (Japanese, Kansai)

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

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

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Slovak)

* New translations ja-JP.yml (Thai)

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

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

* New translations ja-JP.yml (Italian)
2023-03-03 11:37:32 +09:00
syuilo
b4e96181f5 localization: インスタンス -> サーバー
Resolve #7599
2023-03-03 11:36:26 +09:00
Kagami Sascha Rosylight
61215e50ff test(backend): APIテストの復活 (#10163)
* Revert 1c5291f818

* APIテストの復活

* apiテストの移行

* moduleNameMapper修正

* simpleGetでthrowしないように

status確認しているので要らない

* longer timeout

* ローカルでは問題ないのになんで

* case sensitive

* Run Nest instance within the current process

* Skip some setIntervals

* wait for 5 seconds

* kill them all!!

* logHeapUsage: true

* detectOpenHandlesがじゃましているらしい

* maxWorkers=1?

* restore drive api tests

* workerIdleMemoryLimit: 500MB

* 1024MiB

* Wait what
2023-03-03 11:13:12 +09:00
kabo2468
53987fadd7 fix(server): チャンネルでミュートが正しく機能していないのを修正 (#10166)
* fix(server): チャンネルでミュートが正しく機能していないのを修正

* Update CHANGELOG.md
2023-03-03 10:30:21 +09:00
syuilo
8a561bdb78 Update CHANGELOG.md 2023-03-03 10:09:51 +09:00
rinsuki
452a48e7f4 fix(server): DriveFile related N+1 query when call note packMany (#10133)
* fix(server): DriveFile related N+1 query when call note packMany

* Update packages/backend/src/misc/is-not-null.ts

Co-authored-by: Acid Chicken (硫酸鶏) <root@acid-chicken.com>

* ignore lint

* 途中でやめたやつが混入していた

* fix: 順番通りである必要がある場所で順番通りになっていなかった

---------

Co-authored-by: Acid Chicken (硫酸鶏) <root@acid-chicken.com>
2023-03-03 10:06:59 +09:00
syuilo
5248395fc5 update sounds 2023-03-03 09:41:33 +09:00
syuilo
cf8a7f93d5 🎨 2023-03-03 08:48:52 +09:00
syuilo
187a698d54 🎨 2023-03-02 20:47:24 +09:00
syuilo
ebd7b27075 clean up 2023-03-02 18:40:55 +09:00
syuilo
dad915e522 enhance(client): provide sticktyFooter 2023-03-02 18:40:43 +09:00
Kagami Sascha Rosylight
896400a6c9 refactor(frontend): add explicit Promise<void> return types in os.ts (#10156) 2023-03-02 15:05:05 +09:00
syuilo
fdf7605074 refactor(client): use css modules 2023-03-02 14:38:45 +09:00
syuilo
ea1cff499a update sounds 2023-03-02 08:36:15 +09:00
syuilo
b392564165 Update about-misskey.vue 2023-03-02 08:36:06 +09:00
syuilo
39e41d7424 🎨 2023-03-01 17:30:23 +09:00
syuilo
afa9c1f6f0 Update CHANGELOG.md 2023-03-01 17:22:32 +09:00
syuilo
47b1b09b21 enhance(client): add new sounds 2023-03-01 17:22:17 +09:00
Kagami Sascha Rosylight
44058f8b85 enhance(e2e): more resilient version of visit('/') (#10128) 2023-03-01 15:32:53 +09:00
Kagami Sascha Rosylight
6d82371449 fix(frontend): read KeyboardEvent.key instead of which/code (#10083) 2023-03-01 15:24:09 +09:00
KokiSakano
830fabef12 refactor: plugin.tsの型を修正する (#10027)
* refactor:plugin内のすべての関数にreturn typeを設定

* fix:pluginContextsから取得できない場合は早期リターンする

* fix:valueがstring以外の時は早期リターンする

* fix:valueが取得できる時以外は早期リターンする

* fix:pluginに型をつける

* fix:絞り込みをassertStringに変更

* fix:修正漏れ

* fix:valToJsからvalueを取得するように変更
2023-03-01 15:19:20 +09:00
Khsmty
c34e7e6e08 enhance(client): Renote した時の表示をリップルエフェクトと toast に (#10116)
* enhance(client): Renote した時の表示を toast に

* fix: lint エラー

* enhance(client): Renote した時の表示をリップルエフェクトに

* toast も追加

* rippleeffect のタイミング変更

* toast の位置を header に被らないように
2023-03-01 14:55:57 +09:00
syuilo
78d66d3806 🎨 2023-03-01 14:54:02 +09:00
syuilo
44f041587c 🎨 2023-03-01 14:46:53 +09:00
syuilo
d0bbeeee52 🎨 2023-03-01 14:22:53 +09:00
syuilo
9e5278d276 fix of #10145 2023-03-01 12:02:37 +09:00
syuilo
064a6bf065 🎨 2023-03-01 10:56:51 +09:00
syuilo
1c5291f818 feat: 時限ロール (#10145)
* feat: 時限ロール

* クライアントから期限を確認できるように

* リファクタとか

* fix test

* fix test

* fix test

* clean up
2023-03-01 10:20:03 +09:00
syuilo
7c3a390763 enhance(client): ノートの操作部をホバー時のみ表示するオプション 2023-02-28 20:53:32 +09:00
syuilo
83a67606a9 enhance(server): make antenna handle cw
Resolve #10140
2023-02-28 20:20:23 +09:00
tamaina
c1e69e7a53 enhance(client): emojisはIndexedDBに保存する (#10121)
* enhance(client): emojisはIndexedDBに保存する

* lastEmojisFetchedAt
2023-02-28 20:10:52 +09:00
syuilo
570f331477 Update CHANGELOG.md 2023-02-28 19:56:04 +09:00
tamaina
ffe3386e5b fix(sw): プッシュ通知でカスタム絵文字リアクションを表示できるように (#10122)
* fix(sw): プッシュ通知でカスタム絵文字リアクションを表示できるように
Fix #10117
/emoji/*.webpにbadgeモードを

* ?

* ✌️

* fix
2023-02-28 19:55:31 +09:00
牛蒡
c63447e194 enhance: Play の「ソースを表示」にシンタックスハイライトを当てる (#10107)
* シンタックスハイライトを当てる

* fix
2023-02-28 17:38:43 +09:00
tamaina
17d0bde50e fix(client): photoswipe(画像の拡大表示)がなんか変 (#10138)
* fix(client): photoswipe(画像の拡大表示)がなんか変
Fix  #10037

* important

---------

Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
2023-02-28 17:26:42 +09:00
syuilo
4ea978000d Update CHANGELOG.md 2023-02-28 17:14:55 +09:00
tamaina
12932d2831 fix: 外部メディアプロキシ使用時にアバタークロップができない問題を修正 (#10142)
* wip

* fix

* Update packages/frontend/src/scripts/media-proxy.ts

Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>

---------

Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
2023-02-28 17:14:23 +09:00
syuilo
1ba848e5f5 dev: introduce Reviewer lottery 2023-02-28 17:08:20 +09:00
syuilo
a6ea9de4b9 Update 03_release.md 2023-02-28 16:51:04 +09:00
syuilo
746770ac3b fix Serialized type 2023-02-28 16:46:25 +09:00
syuilo
ab7a8a2dae enhance(client): 招待コードが必要なことが分かりやすいように 2023-02-28 16:05:05 +09:00
syuilo
b60c985203 fix(server): メールアドレス更新時にバリデーションが正しく行われていないのを修正 2023-02-28 15:31:48 +09:00
syuilo
785c67ea8d 🎨 2023-02-28 15:27:54 +09:00
Kagami Sascha Rosylight
647a018362 fix(backend): return HTTP 404 for any unknown api endpoint paths (#10130)
* fix(backend): return HTTP 400 for any invalid api endpoint paths

* 404
2023-02-27 18:01:43 +09:00
Kagami Sascha Rosylight
b468330ed9 Merge branch 'develop' into mkusername-empty 2023-02-25 20:04:48 +01:00
Kagami Sascha Rosylight
8c64f999dc Add test 2023-02-19 09:49:18 +01:00
Kagami Sascha Rosylight
cf2b1c1e00 Merge branch 'develop' into mkusername-empty 2023-02-19 09:26:27 +01:00
Kagami Sascha Rosylight
194d656bb4 fix: normalize empty value of name into an absent value 2023-02-17 09:06:48 +01:00
503 changed files with 20834 additions and 4857 deletions

View File

@@ -7,5 +7,18 @@
"ghcr.io/devcontainers-contrib/features/pnpm:2": {}
},
"forwardPorts": [3000],
"postCreateCommand": "sudo chmod 755 .devcontainer/init.sh && .devcontainer/init.sh"
"postCreateCommand": "sudo chmod 755 .devcontainer/init.sh && .devcontainer/init.sh",
"customizations": {
"vscode": {
"extensions": [
"editorconfig.editorconfig",
"dbaeumer.vscode-eslint",
"Vue.volar",
"Vue.vscode-typescript-vue-plugin",
"Orta.vscode-jest",
"dbaeumer.vscode-eslint",
"mrmlnc.vscode-json5"
]
}
}
}

View File

@@ -16,7 +16,7 @@ services:
- external_network
redis:
restart: always
restart: unless-stopped
image: redis:7-alpine
networks:
- internal_network

View File

@@ -4,6 +4,7 @@ set -xe
sudo chown -R node /workspace
git submodule update --init
pnpm config set store-dir /home/node/.local/share/pnpm/store
pnpm install --frozen-lockfile
cp .devcontainer/devcontainer.yml .config/default.yml
pnpm build

View File

@@ -25,6 +25,8 @@ fluent-emojis/
!.yarn/sdks
!.yarn/versions
.pnpm-store
.idea/
packages/*/.vscode/
packages/backend/test/docker-compose.yml

View File

@@ -4,14 +4,20 @@ Thank you for your PR! Before creating a PR, please check the contribution guide
https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md
-->
# What
## What
<!-- このPRで何をしたのか どう変わるのか? -->
<!-- What did you do with this PR? How will it change things? -->
# Why
## Why
<!-- なぜそうするのか? どういう意図なのか? 何が困っているのか? -->
<!-- Why do you do it? What are your intentions? What is the problem? -->
# Additional info (optional)
## Additional info (optional)
<!-- テスト観点など -->
<!-- Test perspective, etc -->
## Checklist
- [ ] Read the [contribution guide](https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md)
- [ ] Test working in a local environment
- [ ] (If needed) Update CHANGELOG.md
- [ ] (If possible) Add tests

View File

@@ -4,14 +4,20 @@ Thank you for your PR! Before creating a PR, please check the contribution guide
https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md
-->
# What
## What
<!-- このPRで何をしたのか どう変わるのか? -->
<!-- What did you do with this PR? How will it change things? -->
# Why
## Why
<!-- なぜそうするのか? どういう意図なのか? 何が困っているのか? -->
<!-- Why do you do it? What are your intentions? What is the problem? -->
# Additional info (optional)
## Additional info (optional)
<!-- テスト観点など -->
<!-- Test perspective, etc -->
## Checklist
- [ ] Read the [contribution guide](https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md)
- [ ] Test working in a local environment
- [ ] (If needed) Update CHANGELOG.md
- [ ] (If possible) Add tests

View File

@@ -10,6 +10,7 @@ https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md#release
- 他にこのリリースに含めなければならない変更は無いか
- 全体的な変更内容を俯瞰し問題は無いか
- レビューされていないコミットがある場合は、それが問題ないか
- 最終的な動作確認を行い問題は無いか
などを確認し、リリースする準備が整っていると思われる場合は approve してください。

23
.github/pull_request_template.md vendored Normal file
View File

@@ -0,0 +1,23 @@
<!-- お読みください / README
PRありがとうございます PRを作成する前に、コントリビューションガイドをご確認ください:
Thank you for your PR! Before creating a PR, please check the contribution guide:
https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md
-->
## What
<!-- このPRで何をしたのか どう変わるのか? -->
<!-- What did you do with this PR? How will it change things? -->
## Why
<!-- なぜそうするのか? どういう意図なのか? 何が困っているのか? -->
<!-- Why do you do it? What are your intentions? What is the problem? -->
## Additional info (optional)
<!-- テスト観点など -->
<!-- Test perspective, etc -->
## Checklist
- [ ] Read the [contribution guide](https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md)
- [ ] Test working in a local environment
- [ ] (If needed) Update CHANGELOG.md
- [ ] (If possible) Add tests

10
.github/reviewer-lottery.yml vendored Normal file
View File

@@ -0,0 +1,10 @@
groups:
- name: devs
reviewers: 2
internal_reviewers: 1
usernames:
- syuilo
- acid-chicken
- EbiseLutica
- rinsuki
- tamaina

36
.github/workflows/api.yml vendored Normal file
View File

@@ -0,0 +1,36 @@
name: API report
on: [push, pull_request]
jobs:
report:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3.3.0
- run: corepack enable
- name: Setup Node.js
uses: actions/setup-node@v3.6.0
with:
node-version: 18.x
cache: 'pnpm'
- name: Install dependencies
run: pnpm i --frozen-lockfile
- name: Build
run: pnpm --filter misskey-js build
- name: Check files
run: ls packages/misskey-js/built
- name: API report
run: pnpm --filter misskey-js api-prod
- name: Show report
if: always()
run: cat packages/misskey-js/temp/misskey-js.api.md

View File

@@ -36,6 +36,7 @@ jobs:
- backend
- frontend
- sw
- misskey-js
steps:
- uses: actions/checkout@v3.3.0
with:
@@ -61,6 +62,7 @@ jobs:
matrix:
workspace:
- backend
- misskey-js
steps:
- uses: actions/checkout@v3.3.0
with:

13
.github/workflows/reviewer_lottery.yml vendored Normal file
View File

@@ -0,0 +1,13 @@
name: "Reviewer lottery"
on:
pull_request_target:
types: [opened, ready_for_review, reopened]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: uesteibar/reviewer-lottery@v2
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}

59
.github/workflows/test-backend.yml vendored Normal file
View File

@@ -0,0 +1,59 @@
name: Test (backend)
on:
push:
branches:
- master
- develop
pull_request:
jobs:
jest:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18.x]
services:
postgres:
image: postgres:13
ports:
- 54312:5432
env:
POSTGRES_DB: test-misskey
POSTGRES_HOST_AUTH_METHOD: trust
redis:
image: redis:6
ports:
- 56312:6379
steps:
- uses: actions/checkout@v3.3.0
with:
submodules: true
- name: Install pnpm
uses: pnpm/action-setup@v2
with:
version: 7
run_install: false
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3.6.0
with:
node-version: ${{ matrix.node-version }}
cache: 'pnpm'
- run: corepack enable
- run: pnpm i --frozen-lockfile
- name: Check pnpm-lock.yaml
run: git diff --exit-code pnpm-lock.yaml
- name: Copy Configure
run: cp .github/misskey/test.yml .config
- name: Build
run: pnpm build
- name: Test
run: pnpm jest-and-coverage
- name: Upload Coverage
uses: codecov/codecov-action@v3
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: ./packages/backend/coverage/coverage-final.json

View File

@@ -1,4 +1,4 @@
name: Test
name: Test (frontend)
on:
push:
@@ -8,26 +8,13 @@ on:
pull_request:
jobs:
jest:
vitest:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18.x]
services:
postgres:
image: postgres:13
ports:
- 54312:5432
env:
POSTGRES_DB: test-misskey
POSTGRES_HOST_AUTH_METHOD: trust
redis:
image: redis:6
ports:
- 56312:6379
steps:
- uses: actions/checkout@v3.3.0
with:
@@ -51,12 +38,12 @@ jobs:
- name: Build
run: pnpm build
- name: Test
run: pnpm jest-and-coverage
run: pnpm --filter frontend test-and-coverage
- name: Upload Coverage
uses: codecov/codecov-action@v3
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: ./packages/backend/coverage/coverage-final.json
files: ./packages/frontend/coverage/coverage-final.json
e2e:
runs-on: ubuntu-latest

52
.github/workflows/test-misskey-js.yml vendored Normal file
View File

@@ -0,0 +1,52 @@
# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
name: Test (misskey.js)
on:
push:
branches: [ develop ]
pull_request:
branches: [ develop ]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18.x]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
steps:
- name: Checkout
uses: actions/checkout@v3.3.0
- run: corepack enable
- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3.6.0
with:
node-version: ${{ matrix.node-version }}
cache: 'pnpm'
- name: Install dependencies
run: pnpm i --frozen-lockfile
- name: Check pnpm-lock.yaml
run: git diff --exit-code pnpm-lock.yaml
- name: Build
run: pnpm --filter misskey-js build
- name: Test
run: pnpm --filter misskey-js test
env:
CI: true
- name: Upload Coverage
uses: codecov/codecov-action@v3
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: ./packages/misskey-js/coverage/coverage-final.json

4
.gitignore vendored
View File

@@ -20,6 +20,9 @@ packages/frontend/.yarn/cache
packages/backend/.yarn/cache
packages/sw/.yarn/cache
# pnpm
.pnpm-store
# Cypress
cypress/screenshots
cypress/videos
@@ -52,6 +55,7 @@ api-docs.json
.DS_Store
/files
ormconfig.json
temp
# blender backups
*.blend1

View File

@@ -1,9 +1,11 @@
{
"recommendations": [
"editorconfig.editorconfig",
"eg2.vscode-npm-script",
"dbaeumer.vscode-eslint",
"Vue.volar",
"Vue.vscode-typescript-vue-plugin"
"Vue.vscode-typescript-vue-plugin",
"Orta.vscode-jest",
"dbaeumer.vscode-eslint",
"mrmlnc.vscode-json5"
]
}

View File

@@ -5,5 +5,6 @@
"typescript.tsdk": "node_modules/typescript/lib",
"files.associations": {
"*.test.ts": "typescript"
}
},
"jest.autoRun": "off"
}

View File

@@ -1,15 +1,137 @@
<!--
## 13.x.x (unreleased)
### Improvements
-
### Bugfixes
### General
-
### Client
-
### Server
-
You should also include the user name that made the change.
-->
## 13.10.3
### General
- コンディショナルロールの条件に「投稿数が~以下」「投稿数が~以上」を追加
- リアクション非対応AP実装からのLikeアクティビティの解釈を👍から♥に
### Client
- クリップボタンをノートアクションに追加できるように
- センシティブワードの一覧にピン留めユーザーのIDが表示される問題を修正
### Server
- リモートユーザーのチャート生成を無効にするオプションを追加
- リモートサーバーのチャート生成を無効にするオプションを追加
- ドライブのチャートはローカルユーザーのみ生成するように
- 空のアンテナが作成できるのを修正
## 13.10.2
### Server
- 絵文字を編集すると保存できないことがある問題を修正
### Client
- ドライブファイルのメニューが正常に動作しない問題を修正
## 13.10.1
### Client
- Misskey PlayのPlayボタンを押した時にエラーが発生する問題を修正
## 13.10.0
### General
- ユーザーごとにRenoteをミュートできるように
- ノートごとに絵文字リアクションを受け取るか設定できるように
- クリップをお気に入りに登録できるように
- ノート検索の利用可否をロールで制御可能に(デフォルトでオフ)
- ロールの並び順を設定可能に
- カスタム絵文字にライセンス情報を付与できるように
- 指定した文字列を含む投稿の公開範囲をホームにできるように
- 使われてないアンテナは自動停止されるように
### Client
- 設定から自分のロールを確認できるように
- 広告一覧ページを追加
- ドライブクリーナーを追加
- DM作成時にメンションも含むように
- フォロー申請のボタンのデザインを改善
- 付箋ウィジェットの高さを設定可能に
- APオブジェクトを入力してフェッチする機能とユーザーやートの検索機能を分離
- ナビゲーションバーの項目に「プロフィール」を追加できるように
- ナビゲーションバーのカスタマイズをドラッグ&ドロップで行えるように
- ジョブキューの再試行をワンクリックでできるように
- AiScriptを0.13.1に更新
- oEmbedをサポートしているウェブサイトのプレビューができるように
- YouTubeをoEmbedでロードし、プレビューで共有ボタンを押すとOSの共有画面がでるように
- ([FirefoxでSpotifyのプレビューを開けるとフルサイズじゃなくプレビューサイズだけ再生できる問題](https://bugzilla.mozilla.org/show_bug.cgi?id=1792395)があります)
- (すでにブラウザーでキャッシュされたリンクに対しては以前のプレビュー行動が行われてます。その場合、ブラウザーのキャッシュをクリアしてまた試してください。)
- プロフィールで設定した情報が削除できない問題を修正
- ロールで広告を無効にするとadmin/adsでプレビューがでてこない問題を修正
- /api-consoleページにアクセスすると404が出る問題を修正
- Safariでプラグインが複数ある場合に正常に読み込まれない問題を修正
- Bookwyrmのユーザーのプロフィールページで「リモートで表示」をタップしても反応がない問題を修正
- 非ログイン時の「Misskeyについて」の表示を修正
- PC版にて「設定」「コントロールパネル」のリンクを2度以上続けてクリックした際に空白のページが表示される問題を修正
### Server
- OpenAPIエンドポイントを復旧
- WebP/AVIF/JPEGのweb公開用画像は、サーバーサイドではJPEGではなくWebPに変換するように
- アニメーション画像のサムネイルを生成するように
- アクティブユーザー数チャートの記録上限値を拡張
- Playのソースコード上限文字数を2倍に拡張
- 配送先サーバーが410 Goneで応答してきた場合は自動で配送停止をするように
- avatarBlurHash/bannerBlurHashの型をstringに限定
- タイムライン取得時のパフォーマンスを改善
- SMTP Login id length is too short
- API上で`visibility``followers`に設定してrenoteすると連合や削除で不具合が発生する問題を修正
- AWS S3からのファイル削除でNoSuchKeyエラーが出ると進めらない状態になる問題を修正
- `disableCache: true`を設定している場合に絵文字管理操作でエラーが出る問題を修正
- リテンション分析が上手く機能しないことがあるのを修正
- 空のアンテナが作成できないように修正
- 特定の条件で通報が見れない問題を修正
- 絵文字の名前に任意の文字が使用できる問題を修正
## 13.9.2 (2023/03/06)
### Improvements
- クリップ、チャンネルページに共有ボタンを追加
- チャンネルでタイムライン上部に投稿フォームを表示するかどうかのオプションを追加
- ブラウザでメディアプロキシ(/proxy)からファイルを保存した際に、なるべくオリジナルのファイル名を継承するように
- ドライブの「URLからアップロード」で、content-dispositionのfilenameがあればそれをファイル名に
- Identiconがローカルとリモートで同じになるように
- これまでのIdenticonは異なる画像になります
- サーバーのパフォーマンスを改善
### Bugfixes
- ロールの権限で「一般ユーザー」のロールがいきなり設定できない問題を修正
- ユーザーページのバッジ表示を適切に折り返すように @arrow2nd
- fix(client): みつけるのロール一覧でコンディショナルロールが含まれるのを修正
- macOSでDev Containerが動作しない問題を修正 @RyotaK
## 13.9.1 (2023/03/03)
### Bugfixes
- ノートに添付したファイルが表示されない場合があるのを修正
## 13.9.0 (2023/03/03)
### Improvements
- 時限ロール
- アンテナでCWも検索対象にするように
- ノートの操作部をホバー時のみ表示するオプションを追加
- サウンドを追加
- サーバーのパフォーマンスを改善
### Bugfixes
- 外部メディアプロキシ使用時にアバタークロップができない問題を修正
- fix(server): メールアドレス更新時にバリデーションが正しく行われていないのを修正
- fix(server): チャンネルでミュートが正しく機能していないのを修正
- プッシュ通知でカスタム絵文字リアクションを表示できなかった問題を修正
## 13.8.1 (2023/02/26)
### Bugfixes
@@ -209,8 +331,8 @@ You should also include the user name that made the change.
## 13.3.2 (2023/02/04)
### Improvements
- 外部メディアプロキシへの対応を強化しました
外部メディアプロキシのFastify実装を作りました
- 外部メディアプロキシへの対応を強化しました
外部メディアプロキシのFastify実装を作りました
https://github.com/misskey-dev/media-proxy
- Server: improve performance
@@ -373,7 +495,7 @@ You should also include the user name that made the change.
- ユーザーごとのドライブ容量設定はロールに統合されました。
- インスタンスデフォルトのドライブ容量設定はロールに統合されました。アップデート後、ベースロールもしくはコンディショナルロールでドライブ容量を編集してください。
- LTL/GTLの解放状態はロールに統合されました。
- Dockerの実行をrootで行わないようにしました。Dockerかつオブジェクトストレージを使用していない場合は`chown -hR 991.991 ./files`を実行してください。
- Dockerの実行をrootで行わないようにしました。Dockerかつオブジェクトストレージを使用していない場合は`chown -hR 991.991 ./files`を実行してください。
https://github.com/misskey-dev/misskey/pull/9560
#### For users
@@ -601,7 +723,7 @@ You should also include the user name that made the change.
## 12.112.2 (2022/07/08)
### Bugfixes
- Fix Docker doesn't work @mei23
- Fix Docker doesn't work @mei23
Still not working on arm64 environment. (See 12.112.0)
## 12.112.1 (2022/07/07)
@@ -643,7 +765,7 @@ same as 12.112.0
- Improve player detection in URL preview @mei23
- Add Badge Image to Push Notification #8012 @tamaina
- Server: Improve performance
- Server: Supports IPv6 on Redis transport. @mei23
- Server: Supports IPv6 on Redis transport. @mei23
IPv4/IPv6 is used by default. You can tune this behavior via `redis.family`.
- Server: Add possibility to log IP addresses of users @syuilo
- Add additional drive capacity change support @CyberRex0

View File

@@ -15,7 +15,7 @@ Before creating an issue, please check the following:
- To avoid duplication, please search for similar issues before creating a new issue.
- Do not use Issues to ask questions or troubleshooting.
- Issues should only be used to feature requests, suggestions, and bug tracking.
- Please ask questions or troubleshooting in the [Misskey Forum](https://forum.misskey.io/) or [Discord](https://discord.gg/Wp8gVStHW3).
- Please ask questions or troubleshooting in ~~the [Misskey Forum](https://forum.misskey.io/)~~ [GitHub Discussions](https://github.com/misskey-dev/misskey/discussions) or [Discord](https://discord.gg/Wp8gVStHW3).
> **Warning**
> Do not close issues that are about to be resolved. It should remain open until a commit that actually resolves it is merged.

View File

@@ -2,7 +2,9 @@
ARG NODE_VERSION=18.13.0-bullseye
FROM node:${NODE_VERSION} AS builder
# build assets & compile TypeScript
FROM --platform=$BUILDPLATFORM node:${NODE_VERSION} AS native-builder
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,target=/var/lib/apt,sharing=locked \
@@ -21,6 +23,7 @@ COPY --link ["scripts", "./scripts"]
COPY --link ["packages/backend/package.json", "./packages/backend/"]
COPY --link ["packages/frontend/package.json", "./packages/frontend/"]
COPY --link ["packages/sw/package.json", "./packages/sw/"]
COPY --link ["packages/misskey-js/package.json", "./packages/misskey-js/"]
RUN --mount=type=cache,target=/root/.local/share/pnpm/store,sharing=locked \
pnpm i --frozen-lockfile --aggregate-output
@@ -33,33 +36,49 @@ RUN git submodule update --init
RUN pnpm build
RUN rm -rf .git/
FROM node:${NODE_VERSION}-slim AS runner
# build native dependencies for target platform
FROM --platform=$TARGETPLATFORM node:${NODE_VERSION} AS target-builder
RUN apt-get update \
&& apt-get install -yqq --no-install-recommends \
build-essential
RUN corepack enable
WORKDIR /misskey
COPY --link ["pnpm-lock.yaml", "pnpm-workspace.yaml", "package.json", "./"]
COPY --link ["scripts", "./scripts"]
COPY --link ["packages/backend/package.json", "./packages/backend/"]
RUN --mount=type=cache,target=/root/.local/share/pnpm/store,sharing=locked \
pnpm i --frozen-lockfile --aggregate-output
FROM --platform=$TARGETPLATFORM node:${NODE_VERSION}-slim AS runner
ARG UID="991"
ARG GID="991"
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,target=/var/lib/apt,sharing=locked \
rm -f /etc/apt/apt.conf.d/docker-clean \
; echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache \
&& apt-get update \
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
ffmpeg tini curl \
&& corepack enable \
&& groupadd -g "${GID}" misskey \
&& useradd -l -u "${UID}" -g "${GID}" -m -d /misskey misskey \
&& find / -type f -perm /u+s -ignore_readdir_race -exec chmod u-s {} \; \
&& find / -type f -perm /g+s -ignore_readdir_race -exec chmod g-s {} \;
&& find / -type d -path /proc -prune -o -type f -perm /u+s -ignore_readdir_race -exec chmod u-s {} \; \
&& find / -type d -path /proc -prune -o -type f -perm /g+s -ignore_readdir_race -exec chmod g-s {} \; \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists
USER misskey
WORKDIR /misskey
COPY --chown=misskey:misskey --from=builder /misskey/node_modules ./node_modules
COPY --chown=misskey:misskey --from=builder /misskey/built ./built
COPY --chown=misskey:misskey --from=builder /misskey/packages/backend/node_modules ./packages/backend/node_modules
COPY --chown=misskey:misskey --from=builder /misskey/packages/backend/built ./packages/backend/built
COPY --chown=misskey:misskey --from=builder /misskey/packages/frontend/node_modules ./packages/frontend/node_modules
COPY --chown=misskey:misskey --from=builder /misskey/fluent-emojis /misskey/fluent-emojis
COPY --chown=misskey:misskey --from=target-builder /misskey/node_modules ./node_modules
COPY --chown=misskey:misskey --from=target-builder /misskey/packages/backend/node_modules ./packages/backend/node_modules
COPY --chown=misskey:misskey --from=native-builder /misskey/built ./built
COPY --chown=misskey:misskey --from=native-builder /misskey/packages/backend/built ./packages/backend/built
COPY --chown=misskey:misskey --from=native-builder /misskey/fluent-emojis /misskey/fluent-emojis
COPY --chown=misskey:misskey . ./
ENV NODE_ENV=production

View File

@@ -3,16 +3,16 @@ kind: Deployment
metadata:
name: {{ include "misskey.fullname" . }}
labels:
{{- include "misskey.labels" . | nindent 4 }}
{{- include "misskey.labels" . | nindent 4 }}
spec:
selector:
matchLabels:
{{- include "misskey.selectorLabels" . | nindent 6 }}
{{- include "misskey.selectorLabels" . | nindent 6 }}
replicas: 1
template:
metadata:
labels:
{{- include "misskey.selectorLabels" . | nindent 8 }}
{{- include "misskey.selectorLabels" . | nindent 8 }}
spec:
containers:
- name: misskey

View File

@@ -11,4 +11,4 @@ spec:
protocol: TCP
name: http
selector:
{{- include "misskey.selectorLabels" . | nindent 4 }}
{{- include "misskey.selectorLabels" . | nindent 4 }}

View File

@@ -10,14 +10,14 @@ describe('Before setup instance', () => {
});
it('successfully loads', () => {
cy.visit('/');
cy.visitHome();
});
it('setup instance', () => {
cy.visit('/');
cy.visitHome();
cy.intercept('POST', '/api/admin/accounts/create').as('signup');
cy.get('[data-cy-admin-username] input').type('admin');
cy.get('[data-cy-admin-password] input').type('admin1234');
cy.get('[data-cy-admin-ok]').click();
@@ -43,22 +43,39 @@ describe('After setup instance', () => {
});
it('successfully loads', () => {
cy.visit('/');
cy.visitHome();
});
it('signup', () => {
cy.visit('/');
cy.visitHome();
cy.intercept('POST', '/api/signup').as('signup');
cy.get('[data-cy-signup]').click();
cy.get('[data-cy-signup-submit]').should('be.disabled');
cy.get('[data-cy-signup-username] input').type('alice');
cy.get('[data-cy-signup-submit]').should('be.disabled');
cy.get('[data-cy-signup-password] input').type('alice1234');
cy.get('[data-cy-signup-submit]').should('be.disabled');
cy.get('[data-cy-signup-password-retype] input').type('alice1234');
cy.get('[data-cy-signup-submit]').should('not.be.disabled');
cy.get('[data-cy-signup-submit]').click();
cy.wait('@signup');
});
it('signup with duplicated username', () => {
cy.registerUser('alice', 'alice1234');
cy.visitHome();
// ユーザー名が重複している場合の挙動確認
cy.get('[data-cy-signup]').click();
cy.get('[data-cy-signup-username] input').type('alice');
cy.get('[data-cy-signup-password] input').type('alice1234');
cy.get('[data-cy-signup-password-retype] input').type('alice1234');
cy.get('[data-cy-signup-submit]').should('be.disabled');
});
});
describe('After user signup', () => {
@@ -79,11 +96,11 @@ describe('After user signup', () => {
});
it('successfully loads', () => {
cy.visit('/');
cy.visitHome();
});
it('signin', () => {
cy.visit('/');
cy.visitHome();
cy.intercept('POST', '/api/signin').as('signin');
@@ -101,7 +118,7 @@ describe('After user signup', () => {
userId: this.alice.id,
});
cy.visit('/');
cy.visitHome();
cy.get('[data-cy-signin]').click();
cy.get('[data-cy-signin-username] input').type('alice');
@@ -112,7 +129,7 @@ describe('After user signup', () => {
});
});
describe('After user singed in', () => {
describe('After user signed in', () => {
beforeEach(() => {
cy.resetState();
@@ -141,6 +158,19 @@ describe('After user singed in', () => {
cy.get('[data-cy-open-post-form-submit]').click();
cy.contains('Hello, Misskey!');
});
it('open note form with hotkey', () => {
// Wait until the page loads
cy.get('[data-cy-open-post-form]').should('be.visible');
// Use trigger() to give different `code` to test if hotkeys also work on non-QWERTY keyboards.
cy.document().trigger("keydown", { eventConstructor: 'KeyboardEvent', key: "n", code: "KeyL" });
// See if the form is opened
cy.get('[data-cy-post-form-text]').should('be.visible');
// Close it
cy.focused().trigger("keydown", { eventConstructor: 'KeyboardEvent', key: "Escape", code: "Escape" });
// See if the form is closed
cy.get('[data-cy-post-form-text]').should('not.be.visible');
});
});

View File

@@ -29,17 +29,17 @@ describe('After user signed in', () => {
it('first widget should be removed', () => {
cy.get('.mk-widget-edit').click();
cy.get('.data-cy-customize-container:first-child .data-cy-customize-container-remove._button').click();
cy.get('.data-cy-customize-container').should('have.length', 2);
cy.get('[data-cy-customize-container]:first-child [data-cy-customize-container-remove]._button').click();
cy.get('[data-cy-customize-container]').should('have.length', 2);
});
function buildWidgetTest(widgetName) {
it(`${widgetName} widget should get added`, () => {
cy.get('.mk-widget-edit').click();
cy.get('.mk-widget-select select').select(widgetName, { force: true });
cy.get('.data-cy-bg._modalBg.data-cy-transparent').click({ multiple: true, force: true });
cy.get('[data-cy-bg]._modalBg[data-cy-transparent]').click({ multiple: true, force: true });
cy.get('.mk-widget-add').click({ force: true });
cy.get(`.data-cy-mkw-${widgetName}`).should('exist');
cy.get(`[data-cy-mkw-${widgetName}]`).should('exist');
});
}

View File

@@ -24,6 +24,11 @@
// -- This will overwrite an existing command --
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
Cypress.Commands.add('visitHome', () => {
cy.visit('/');
cy.get('button', { timeout: 30000 }).should('be.visible');
})
Cypress.Commands.add('resetState', () => {
cy.window(win => {
win.indexedDB.deleteDatabase('keyval-store');
@@ -43,7 +48,7 @@ Cypress.Commands.add('registerUser', (username, password, isAdmin = false) => {
});
Cypress.Commands.add('login', (username, password) => {
cy.visit('/');
cy.visitHome();
cy.intercept('POST', '/api/signin').as('signin');

View File

@@ -545,7 +545,6 @@ tokenRequested: "منح حق الوصول إلى الحساب"
pluginTokenRequestedDescription: "ستتمكن الإضافة من استخدام هذه الأذونات."
notificationType: "أنواع الإشعارات"
edit: "التعديل"
useStarForReactionFallback: "استخدم ★ كبديل إذا كان التفاعل مجهولًا"
emailServer: "خادم البريد الإلكتروني"
emailConfigInfo: "يستخدم لتأكيد عنوان بريدك الإلكتروني ولإعادة تعيين كلمة المرور إن نسيتها."
email: "البريد الإلكتروني "
@@ -785,6 +784,7 @@ size: "الحجم"
numberOfColumn: "عدد الأعمدة"
searchByGoogle: "غوغل"
mutePeriod: "مدة الكتم"
period: "ينتهي استطلاع الرأي في"
indefinitely: "أبدًا"
tenMinutes: "10 دقائق"
oneHour: "ساعة"
@@ -1274,3 +1274,7 @@ _deck:
channel: "القنوات"
mentions: "الإشارات"
direct: "مباشرة"
_webhookSettings:
name: "الإسم"
active: "مفعّل"

View File

@@ -562,7 +562,6 @@ tokenRequested: "অ্যাকাউন্টে অ্যাক্সেস
pluginTokenRequestedDescription: "এই প্লাগইনটি এখানে দেওয়া অনুমুতিসমূহ ব্যাবহার করবে"
notificationType: "বিজ্ঞপ্তির ধরন"
edit: "সম্পাদনা"
useStarForReactionFallback: "রিঅ্যাকশনের ইমোজি না জানলে ★ ব্যবহার করুন"
emailServer: "ইমেইল সার্ভার"
enableEmail: "ইমেইল বিতরণ চালু করুন"
emailConfigInfo: "আপনার ইমেল ঠিকানা নিশ্চিত করতে এবং আপনার পাসওয়ার্ড পুনরায় সেট করতে ব্যবহৃত হয়"
@@ -819,6 +818,7 @@ instanceDefaultLightTheme: "ইন্সট্যান্সের ডিফল
instanceDefaultDarkTheme: "ইন্সট্যান্সের ডিফল্ট ডার্ক থিম"
instanceDefaultThemeDescription: "অবজেক্ট ফরম্যাটে থিম কোড লিখুন"
mutePeriod: "মিউটের সময়কাল"
period: "পোলের সময়সীমা"
indefinitely: "অনির্দিষ্ট"
tenMinutes: "১০ মিনিট"
oneHour: "১ ঘণ্টা"
@@ -1353,3 +1353,7 @@ _deck:
channel: "চ্যানেলগুলি"
mentions: "উল্লেখসমূহ"
direct: "ডাইরেক্ট নোটগুলি"
_webhookSettings:
name: "নাম"
active: "চালু"

View File

@@ -460,3 +460,4 @@ _deck:
list: "Llistes"
mentions: "Mencions"
direct: "Publicacions directes"

View File

@@ -776,3 +776,7 @@ _deck:
list: "Seznamy"
channel: "Kanály"
mentions: "Zmínění"
_webhookSettings:
name: "Jméno"
active: "Zapnuto"

View File

@@ -1,2 +1,3 @@
---
_lang_: "Dansk"

View File

@@ -122,6 +122,8 @@ unmarkAsSensitive: "Als nicht NSFW markieren"
enterFileName: "Dateinamen eingeben"
mute: "Stummschalten"
unmute: "Stummschaltung aufheben"
renoteMute: "Renotes stummschalten"
renoteUnmute: "Renote-Stummschaltung aufheben"
block: "Blockieren"
unblock: "Blockierung aufheben"
suspend: "Sperren"
@@ -153,6 +155,7 @@ flagShowTimelineReplies: "Antworten in der Chronik anzeigen"
flagShowTimelineRepliesDescription: "Ist diese Option aktiviert, so werden Antworten von Benutzern auf die Notizen anderer Benutzer in der Chronik angezeigt."
autoAcceptFollowed: "Follow-Anfragen von Benutzern, denen du folgst, automatisch akzeptieren"
addAccount: "Benutzerkonto hinzufügen"
reloadAccountsList: "Benutzerkontoliste aktualisieren"
loginFailed: "Anmeldung fehlgeschlagen"
showOnRemote: "Auf Ursprungsinstanz ansehen"
general: "Allgemein"
@@ -345,7 +348,7 @@ basicInfo: "Grundlegende Informationen"
pinnedUsers: "Angeheftete Benutzer"
pinnedUsersDescription: "Gib durch Leerzeichen getrennte Benutzer an, die an die \"Erkunden\"-Seite angeheftet werden sollen."
pinnedPages: "Angeheftete Seiten"
pinnedPagesDescription: "Gib durch Leerzeilen getrennte Pfäde zu Seiten an, die an die Startseite dieser Instanz angeheftet werden sollen.\n"
pinnedPagesDescription: "Gib durch Leerzeilen getrennte Pfade zu Seiten an, die an die Startseite dieser Instanz angeheftet werden sollen."
pinnedClipId: "ID des anzuheftenden Clips"
pinnedNotes: "Angeheftete Notizen"
hcaptcha: "hCaptcha"
@@ -404,7 +407,7 @@ securityKey: "Sicherheitsschlüssel"
lastUsed: "Zuletzt benutzt"
lastUsedAt: "Zuletzt verwendet: {t}"
unregister: "Deaktivieren"
passwordLessLogin: "Passwortloses Anmelden einrichten"
passwordLessLogin: "Passwortloses Anmelden"
passwordLessLoginDescription: "Ermöglicht passwortfreies Einloggen, nur via Security-Token oder Passkey"
resetPassword: "Passwort zurücksetzen"
newPasswordIs: "Das neue Passwort ist „{password}“"
@@ -457,6 +460,7 @@ aboutX: "Über {x}"
emojiStyle: "Emoji-Stil"
native: "Nativ"
disableDrawer: "Keine ausfahrbaren Menüs verwenden"
showNoteActionsOnlyHover: "Aktionen für Notizen nur bei Mouseover anzeigen"
noHistory: "Kein Verlauf gefunden"
signinHistory: "Anmeldungsverlauf"
enableAdvancedMfm: "Erweitertes MFM aktivieren"
@@ -505,6 +509,7 @@ objectStorageSetPublicRead: "Bei Upload auf \"public-read\" stellen"
serverLogs: "Serverprotokolle"
deleteAll: "Alle löschen"
showFixedPostForm: "Bereich zum Schreiben neuer Notizen am Anfang der Chronik anzeigen"
showFixedPostFormInChannel: "Bereich zum Schreiben neuer Notizen am Anfang der Chronik anzeigen (Kanäle)"
newNoteRecived: "Es gibt neue Notizen"
sounds: "Töne"
sound: "Töne"
@@ -542,6 +547,10 @@ userSuspended: "Dieser Benutzer wurde gesperrt."
userSilenced: "Dieser Benutzer wurde instanzweit stummgeschaltet."
yourAccountSuspendedTitle: "Dieses Benutzerkonto ist gesperrt"
yourAccountSuspendedDescription: "Dieses Benutzerkonto wurde gesperrt, da es gegen die Nutzungsbedingungen dieses Servers verstoßen hat. Trete mit dem Betreiber in Kontakt, falls du weitere Details erfahren möchtest. Bitte erstelle kein neues Benutzerkonto."
tokenRevoked: "Ungültiger Token"
tokenRevokedDescription: "Der Token ist abgelaufen. Bitte melde dich erneut an."
accountDeleted: "Benutzerkonto wurde gelöscht"
accountDeletedDescription: "Dieses Konto wurde gelöscht."
menu: "Menü"
divider: "Trenner"
addItem: "Element hinzufügen"
@@ -585,7 +594,6 @@ tokenRequested: "Zugriff zum Benutzerkonto gewähren"
pluginTokenRequestedDescription: "Dieses Plugin wird die hier konfigurierten Berechtigungen verwenden können."
notificationType: "Art der Benachrichtigung"
edit: "Bearbeiten"
useStarForReactionFallback: "Verwende ★ falls das Reaktions-Emoji unbekannt ist"
emailServer: "Email-Server"
enableEmail: "Email-Versand aktivieren"
emailConfigInfo: "Zur Email-Bestätigung bei Registrierung oder zum Zurücksetzen des Passworts verwendet"
@@ -847,11 +855,13 @@ instanceDefaultLightTheme: "Instanzweites Standardfarbschema (Hell)"
instanceDefaultDarkTheme: "Instanzweites Standardfarbschema (Dunkel)"
instanceDefaultThemeDescription: "Gib den Farbschemencode im Objektformat ein."
mutePeriod: "Stummschaltungsdauer"
period: "Zeitlimit"
indefinitely: "Dauerhaft"
tenMinutes: "10 Minuten"
oneHour: "Eine Stunde"
oneDay: "Einen Tag"
oneWeek: "Eine Woche"
oneMonth: "1 Monat"
reflectMayTakeTime: "Es kann etwas dauern, bis sich dies widerspiegelt."
failedToFetchAccountInformation: "Benutzerkontoinformationen konnten nicht abgefragt werden"
rateLimitExceeded: "Versuchsanzahl überschritten"
@@ -951,6 +961,25 @@ joinThisServer: "Bei dieser Instanz registrieren"
exploreOtherServers: "Eine andere Instanz finden"
letsLookAtTimeline: "Die Chronik durchstöbern"
disableFederationWarn: "Dies deaktiviert Föderation, aber alle Notizen bleiben, sofern nicht umgestellt, öffentlich. In den meisten Fällen wird diese Option nicht benötigt."
invitationRequiredToRegister: "Diese Instanz ist einladungsbasiert. Du musst einen validen Einladungscode eingeben, um dich zu registrieren."
emailNotSupported: "Diese Instanz unterstützt das Versenden von Emails nicht"
postToTheChannel: "In Kanal senden"
cannotBeChangedLater: "Kann später nicht mehr geändert werden."
reactionAcceptance: "Reaktionsannahme"
likeOnly: "Nur \"Gefällt mir\""
likeOnlyForRemote: "Nur \"Gefällt mir\" für fremde Instanzen"
rolesAssignedToMe: "Mir zugewiesene Rollen"
resetPasswordConfirm: "Wirklich Passwort zurücksetzen?"
sensitiveWords: "Sensible Wörter"
sensitiveWordsDescription: "Die Notizsichtbarkeit aller Notizen, die diese Wörter enthalten, wird automatisch auf \"Startseite\" gesetzt. Durch Zeilenumbrüche können mehrere konfiguriert werden."
notesSearchNotAvailable: "Die Notizsuche ist nicht verfügbar."
license: "Lizenz"
unfavoriteConfirm: "Wirklich aus Favoriten entfernen?"
myClips: "Meine Clips"
drivecleaner: "Drive-Reiniger"
retryAllQueuesNow: "Sofort Warteschlangen erneut ausführen"
retryAllQueuesConfirmTitle: "Wirklich erneut versuchen?"
retryAllQueuesConfirmText: "Dies wird zu einer temporären Erhöhung der Serverlast führen."
_achievements:
earnedAt: "Freigeschaltet am"
_types:
@@ -1098,7 +1127,7 @@ _achievements:
title: "Beliebt"
description: "Die Anzahl deiner Follower hat 100 überschritten"
_followers300:
title: "Stellt euch bitte in einer Reihe auf"
title: "Eine geordnete Reihe, bitte!"
description: "Die Anzahl deiner Follower hat 300 überschritten"
_followers500:
title: "Funkmast"
@@ -1159,7 +1188,7 @@ _achievements:
description: "Du hast hier geklickt"
_justPlainLucky:
title: "Pures Glück"
description: "Kann alle 10 Sekunden mit einer Warscheinlichkeit von 0.01% erhalten werden"
description: "Kann alle 10 Sekunden mit einer Warscheinlichkeit von 0.005% erhalten werden"
_setNameToSyuilo:
title: "Gottkomplex"
description: "Setze deinen Namen auf \"syuilo\""
@@ -1210,6 +1239,8 @@ _role:
iconUrl: "Icon-URL"
asBadge: "Als Abzeichen anzeigen"
descriptionOfAsBadge: "Ist dies aktiviert, so wird das Icon dieser Rolle an der Seite der Namen von Benutzern mit dieser Rolle angezeigt."
displayOrder: "Position"
descriptionOfDisplayOrder: "Je höher die Nummer, desto höher die UI-Position."
canEditMembersByModerator: "Moderatoren können Benutzern diese Rolle zuweisen"
descriptionOfCanEditMembersByModerator: "Wenn aktiviert, so können Moderatoren und Adminstratoren anderen Benutzern diese Rolle zuweisen bzw. diese Zuweisung aufheben. Wenn deaktiviert, so ist es nur Administratoren möglich, Zuweisungen dieser Rolle zu verwalten."
priority: "Priorität"
@@ -1235,6 +1266,7 @@ _role:
rateLimitFactor: "Versuchsanzahl"
descriptionOfRateLimitFactor: "Je niedriger desto weniger restriktiv, je höher destro restriktiver."
canHideAds: "Kann Werbung ausblenden"
canSearchNotes: "Nutzung der Notizsuchfunktion"
_condition:
isLocal: "Lokaler Benutzer"
isRemote: "Benutzer fremder Instanz"
@@ -1244,6 +1276,8 @@ _role:
followersMoreThanOrEq: "Hat X oder mehr Follower"
followingLessThanOrEq: "Folgt X oder weniger Benutzern"
followingMoreThanOrEq: "Folgt X oder mehr Benutzern"
notesLessThanOrEq: "Beitragszahl ist kleiner-gleich"
notesMoreThanOrEq: "Beitragszahl ist größer-gleich"
and: "UND-Bedingung"
or: "ODER-Bedingung"
not: "NICHT-Bedingung"
@@ -1506,7 +1540,7 @@ _2fa:
step2Url: "Nutzt du ein Desktopprogramm kannst du alternativ diese URL eingeben:"
step3Title: "Authentifizierungsscode eingeben"
step3: "Gib zum Abschluss den Token ein, der von deiner App angezeigt wird."
step4: "Alle folgenden Anmeldungsversuche werden ab sofort die Eingabe eines solchen Tokens benötigen."
step4: "Alle folgenden Anmeldeversuche werden ab sofort die Eingabe eines solchen Tokens benötigen."
securityKeyNotSupported: "Dein Browser unterstützt keine Security-Tokens."
registerTOTPBeforeKey: "Um einen Security-Token oder einen Passkey zu registrieren, musst du zuerst eine Authentifizierungs-App registrieren."
securityKeyInfo: "Du kannst neben Fingerabdruck- oder PIN-Authentifizierung auf deinem Gerät auch Anmeldung mit Hilfe eines FIDO2-kompatiblen Hardware-Sicherheitsschlüssels einrichten."
@@ -1836,3 +1870,13 @@ _deck:
_dialog:
charactersExceeded: "Maximallänge überschritten! Momentan {current} von {max}"
charactersBelow: "Minimallänge unterschritten! Momentan {current} von {min}"
_disabledTimeline:
title: "Chronik deaktiviert"
description: "Mit deinen jetzigen Rollen ist diese Chronik nicht verfügbar."
_drivecleaner:
orderBySizeDesc: "Absteigende Dateigrößen"
orderByCreatedAtAsc: "Aufsteigendes Erstelldatum"
_webhookSettings:
name: "Name"
active: "Aktiviert"

View File

@@ -392,3 +392,6 @@ _deck:
antenna: "Αντένες"
list: "Λίστα"
mentions: "Επισημάνσεις"
_webhookSettings:
name: "Όνομα"

View File

@@ -67,7 +67,7 @@ import: "Import"
export: "Export"
files: "Files"
download: "Download"
driveFileDeleteConfirm: "Are you sure you want to delete the file \"{name}\"? Notes with this file attached will also be deleted."
driveFileDeleteConfirm: "Are you sure you want to delete \"{name}\"? All notes with this file attached will also be deleted."
unfollowConfirm: "Are you sure you want to unfollow {name}?"
exportRequested: "You've requested an export. This may take a while. It will be added to your Drive once completed."
importRequested: "You've requested an import. This may take a while."
@@ -122,6 +122,8 @@ unmarkAsSensitive: "Unmark as NSFW"
enterFileName: "Enter filename"
mute: "Mute"
unmute: "Unmute"
renoteMute: "Mute Renotes"
renoteUnmute: "Unmute Renotes"
block: "Block"
unblock: "Unblock"
suspend: "Suspend"
@@ -153,6 +155,7 @@ flagShowTimelineReplies: "Show replies in timeline"
flagShowTimelineRepliesDescription: "Shows replies of users to notes of other users in the timeline if turned on."
autoAcceptFollowed: "Automatically approve follow requests from users you're following"
addAccount: "Add account"
reloadAccountsList: "Reload account list"
loginFailed: "Failed to sign in"
showOnRemote: "View on remote instance"
general: "General"
@@ -197,7 +200,7 @@ clearQueueConfirmText: "Any undelivered notes remaining in the queue will not be
clearCachedFiles: "Clear cache"
clearCachedFilesConfirm: "Are you sure that you want to delete all cached remote files?"
blockedInstances: "Blocked Instances"
blockedInstancesDescription: "List the hostnames of the instances that you want to block. Listed instances will no longer be able to communicate with this instance."
blockedInstancesDescription: "List the hostnames of the instances that you want to block separated by linebreaks. Listed instances will no longer be able to communicate with this instance."
muteAndBlock: "Mutes and Blocks"
mutedUsers: "Muted users"
blockedUsers: "Blocked users"
@@ -457,6 +460,7 @@ aboutX: "About {x}"
emojiStyle: "Emoji style"
native: "Native"
disableDrawer: "Don't use drawer-style menus"
showNoteActionsOnlyHover: "Only show note actions on hover"
noHistory: "No history available"
signinHistory: "Login history"
enableAdvancedMfm: "Enable advanced MFM"
@@ -505,6 +509,7 @@ objectStorageSetPublicRead: "Set \"public-read\" on upload"
serverLogs: "Server logs"
deleteAll: "Delete all"
showFixedPostForm: "Display the posting form at the top of the timeline"
showFixedPostFormInChannel: "Display the posting form at the top of the timeline (Channels)"
newNoteRecived: "There are new notes"
sounds: "Sounds"
sound: "Sounds"
@@ -525,7 +530,7 @@ nothing: "There's nothing to see here"
installedDate: "Authorized at"
lastUsedDate: "Last used at"
state: "State"
sort: "Sort"
sort: "Sorting order"
ascendingOrder: "Ascending"
descendingOrder: "Descending"
scratchpad: "Scratchpad"
@@ -542,6 +547,10 @@ userSuspended: "This user has been suspended."
userSilenced: "This user is being silenced."
yourAccountSuspendedTitle: "This account is suspended"
yourAccountSuspendedDescription: "This account has been suspended due to breaking the server's terms of services or similar. Contact the administrator if you would like to know a more detailed reason. Please do not create a new account."
tokenRevoked: "Invalid token"
tokenRevokedDescription: "This token has expired. Please log in again."
accountDeleted: "Account deleted"
accountDeletedDescription: "This account has been deleted."
menu: "Menu"
divider: "Divider"
addItem: "Add Item"
@@ -585,7 +594,6 @@ tokenRequested: "Grant access to account"
pluginTokenRequestedDescription: "This plugin will be able to use the permissions set here."
notificationType: "Notification type"
edit: "Edit"
useStarForReactionFallback: "Use ★ as fallback if the reaction emoji is unknown"
emailServer: "Email server"
enableEmail: "Enable email distribution"
emailConfigInfo: "Used to confirm your email during sign-up or if you forget your password"
@@ -847,11 +855,13 @@ instanceDefaultLightTheme: "Instance-wide default light theme"
instanceDefaultDarkTheme: "Instance-wide default dark theme"
instanceDefaultThemeDescription: "Enter the theme code in object format."
mutePeriod: "Mute duration"
period: "Time limit"
indefinitely: "Permanently"
tenMinutes: "10 minutes"
oneHour: "One hour"
oneDay: "One day"
oneWeek: "One week"
oneMonth: "One month"
reflectMayTakeTime: "It may take some time for this to be reflected."
failedToFetchAccountInformation: "Could not fetch account information"
rateLimitExceeded: "Rate limit exceeded"
@@ -951,6 +961,28 @@ joinThisServer: "Sign up at this instance"
exploreOtherServers: "Look for another instance"
letsLookAtTimeline: "Have a look at the timeline"
disableFederationWarn: "This will disable federation, but posts will continue to be public unless set otherwise. You usually do not need to use this setting."
invitationRequiredToRegister: "This instance is invite-only. You must enter a valid invite code sign up."
emailNotSupported: "This instance does not support sending emails"
postToTheChannel: "Post to channel"
cannotBeChangedLater: "This cannot be changed later."
reactionAcceptance: "Reaction Acceptance"
likeOnly: "Only likes"
likeOnlyForRemote: "Only likes for remote instances"
rolesAssignedToMe: "Roles assigned to me"
resetPasswordConfirm: "Really reset your password?"
sensitiveWords: "Sensitive words"
sensitiveWordsDescription: "The visibility of all notes containing any of the configured words will be set to \"Home\" automatically. You can list multiple by separating them via line breaks."
notesSearchNotAvailable: "Note search is unavailable."
license: "License"
unfavoriteConfirm: "Really remove from favorites?"
myClips: "My clips"
drivecleaner: "Drive Cleaner"
retryAllQueuesNow: "Retry running all queues"
retryAllQueuesConfirmTitle: "Really retry all?"
retryAllQueuesConfirmText: "This will temporarily increase the server load."
enableChartsForRemoteUser: "Generate remote user data charts"
enableChartsForFederatedInstances: "Generate remote instance data charts"
showClipButtonInNoteFooter: "Add \"Clip\" to note action menu"
_achievements:
earnedAt: "Unlocked at"
_types:
@@ -1210,6 +1242,8 @@ _role:
iconUrl: "Icon URL"
asBadge: "Show as badge"
descriptionOfAsBadge: "This role's icon will be displayed next to the username of users with this role if turned on."
displayOrder: "Position"
descriptionOfDisplayOrder: "The higher the number, the higher its UI position."
canEditMembersByModerator: "Allow moderators to edit the list of members for this role"
descriptionOfCanEditMembersByModerator: "When turned on, moderators as well as administrators will be able to assign and unassign users to this role. When turned off, only administrators will be able to assign users."
priority: "Priority"
@@ -1235,6 +1269,7 @@ _role:
rateLimitFactor: "Rate limit"
descriptionOfRateLimitFactor: "Lower rate limits are less restrictive, higher ones more restrictive. "
canHideAds: "Can hide ads"
canSearchNotes: "Usage of note search"
_condition:
isLocal: "Local user"
isRemote: "Remote user"
@@ -1244,6 +1279,8 @@ _role:
followersMoreThanOrEq: "Has X or more followers"
followingLessThanOrEq: "Follows X or fewer accounts"
followingMoreThanOrEq: "Follows X or more accounts"
notesLessThanOrEq: "Post count is less than/equal to"
notesMoreThanOrEq: "Post count is greater than/equal to"
and: "AND-Condition"
or: "OR-Condition"
not: "NOT-Condition"
@@ -1836,3 +1873,24 @@ _deck:
_dialog:
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}."
_disabledTimeline:
title: "Timeline disabled"
description: "You cannot use this timeline under your current roles."
_drivecleaner:
orderBySizeDesc: "Descending Filesizes"
orderByCreatedAtAsc: "Ascending Dates"
_webhookSettings:
createWebhook: "Create Webhook"
name: "Name"
secret: "Secret"
events: "Webhook Events"
active: "Enabled"
_events:
follow: "When following a user"
followed: "When being followed"
note: "When posting a note"
reply: "When receiving a reply"
renote: "When renoted"
reaction: "When receiving a reaction"
mention: "When being mentioned"

View File

@@ -122,6 +122,8 @@ unmarkAsSensitive: "Desmarcar como sensible"
enterFileName: "Ingrese el nombre del archivo"
mute: "Silenciar"
unmute: "Dejar de silenciar"
renoteMute: "Silenciar renota"
renoteUnmute: "Desilenciar renota"
block: "Bloquear"
unblock: "Dejar de bloquear"
suspend: "Suspender"
@@ -153,6 +155,7 @@ flagShowTimelineReplies: "Mostrar respuestas a las notas en la biografía"
flagShowTimelineRepliesDescription: "Cuando se marca, la línea de tiempo muestra respuestas a otras notas además de las notas del usuario"
autoAcceptFollowed: "Aceptar automáticamente las solicitudes de seguimiento de los usuarios que sigues"
addAccount: "Agregar Cuenta"
reloadAccountsList: "Recargar lista de cuentas"
loginFailed: "Error al iniciar sesión."
showOnRemote: "Ver en una instancia remota"
general: "General"
@@ -457,6 +460,7 @@ aboutX: "Acerca de {x}"
emojiStyle: "Estilo de emoji"
native: "Nativo"
disableDrawer: "No mostrar los menús en cajones"
showNoteActionsOnlyHover: "Mostrar acciones de la nota sólo al pasar el cursor"
noHistory: "No hay datos en el historial"
signinHistory: "Historial de ingresos"
enableAdvancedMfm: "Habilitar MFM avanzado"
@@ -505,6 +509,7 @@ objectStorageSetPublicRead: "Seleccionar \"public-read\" al subir "
serverLogs: "Registros del servidor"
deleteAll: "Eliminar todos"
showFixedPostForm: "Mostrar el formulario de las entradas encima de la línea de tiempo"
showFixedPostFormInChannel: "Mostrar el formulario de publicación por encima de la cronología (Canales)"
newNoteRecived: "Tienes una nota nueva"
sounds: "Sonidos"
sound: "Sonidos"
@@ -542,6 +547,10 @@ userSuspended: "Este usuario ha sido suspendido."
userSilenced: "Este usuario ha sido silenciado."
yourAccountSuspendedTitle: "Esta cuenta ha sido suspendida"
yourAccountSuspendedDescription: "Esta cuenta ha sido suspendida debido a violaciones de los términos de servicio del servidor y otras razones. Para más información, póngase en contacto con el administrador. Por favor, no cree una nueva cuenta."
tokenRevoked: "Token inválido"
tokenRevokedDescription: "Este token expiró, vuelve a iniciar sesión."
accountDeleted: "Cuenta borrada"
accountDeletedDescription: "Esta cuenta ha sido borrada."
menu: "Menú"
divider: "Divisor"
addItem: "Agregar elemento"
@@ -585,7 +594,6 @@ tokenRequested: "Permiso de acceso a la cuenta"
pluginTokenRequestedDescription: "Este plugin podrá usar los permisos descritos aquí"
notificationType: "Tipo de notificación"
edit: "Editar"
useStarForReactionFallback: "En caso de que los emojis de reacciones no sean claros, usar en su lugar una estrella"
emailServer: "Servidor de correo"
enableEmail: "Activar el envío de correos electrónicos"
emailConfigInfo: "Usar en caso de validación de correo electrónico y pedido de contraseña"
@@ -847,11 +855,13 @@ instanceDefaultLightTheme: "Tema claro por defecto de la instancia"
instanceDefaultDarkTheme: "Tema oscuro por defecto de la instancia"
instanceDefaultThemeDescription: "Ingrese el código del tema en formato objeto"
mutePeriod: "Período de silenciamiento"
period: "Termina el"
indefinitely: "Sin límite de tiempo"
tenMinutes: "10 minutos"
oneHour: "1 hora"
oneDay: "1 día"
oneWeek: "1 semana"
oneMonth: "1 mes"
reflectMayTakeTime: "Puede pasar un tiempo hasta que se reflejen los cambios"
failedToFetchAccountInformation: "No se pudo obtener información de la cuenta"
rateLimitExceeded: "Se excedió el límite de peticiones"
@@ -951,6 +961,25 @@ joinThisServer: "Registrarse en esta instancia"
exploreOtherServers: "Buscar otra instancia"
letsLookAtTimeline: "Mirar la línea de tiempo local"
disableFederationWarn: "Esto desactivará la federación, pero las publicaciones segurán siendo públicas al menos que se configure diferente. Usualmente no necesitas usar esta configuración."
invitationRequiredToRegister: "Esta instancia está configurada sólo por invitación, tienes que ingresar un código de invitación válido."
emailNotSupported: "Esta instancia no soporta el envío de correo electrónico"
postToTheChannel: "Publicar en el canal"
cannotBeChangedLater: "Esto no podrá ser cambiado después."
reactionAcceptance: "Aceptación de reacciones"
likeOnly: "Sólo 'me gusta'"
likeOnlyForRemote: "Sólo reacciones de instancias remotas"
rolesAssignedToMe: "Roles asignados a mí"
resetPasswordConfirm: "¿Realmente quieres cambiar la contraseña?"
sensitiveWords: "Palabras sensibles"
sensitiveWordsDescription: "La visibilidad de todas las notas que contienen cualquiera de las palabras configuradas serán puestas en \"Inicio\" automáticamente. Puedes enumerás varias separándolas con saltos de línea"
notesSearchNotAvailable: "No se puede buscar una nota"
license: "Licencia"
unfavoriteConfirm: "¿Desea quitar de favoritos?"
myClips: "Mis clips"
drivecleaner: "Limpiador del Drive"
retryAllQueuesNow: "Reintentar inmediatamente todas las colas"
retryAllQueuesConfirmTitle: "Desea ¿reintentar inmediatamente todas las colas?"
retryAllQueuesConfirmText: "La carga del servidor está incrementándose temporalmente "
_achievements:
earnedAt: "Desbloqueado el"
_types:
@@ -1210,6 +1239,8 @@ _role:
iconUrl: "URL del ícono"
asBadge: "Mostrar como emblema"
descriptionOfAsBadge: "Este ícono de rol se mostrará a lado del nombre de usuario cuando este rol se encuentre activo."
displayOrder: "Posición"
descriptionOfDisplayOrder: "Entre más alto el número, mayor es la posición en la interfaz."
canEditMembersByModerator: "Permitir a los moderadores editar los miembros"
descriptionOfCanEditMembersByModerator: "Si se activa, los moderadores, al igual que los administradores, serán capaces de asignar/quitar usuarios a éste rol. Si se desactiva, sólo los administradores podrán hacerlo."
priority: "Prioridad"
@@ -1235,6 +1266,7 @@ _role:
rateLimitFactor: "Limitador"
descriptionOfRateLimitFactor: "Límites más bajos son menos restrictivos, más altos menos restrictivos"
canHideAds: "Puede ocultar anuncios"
canSearchNotes: "Uso de la búsqueda de notas"
_condition:
isLocal: "Usuario local"
isRemote: "Usuario remoto"
@@ -1836,3 +1868,13 @@ _deck:
_dialog:
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}."
_disabledTimeline:
title: "Línea de tiempo deshabilitada"
description: "No puedes usar esta línea de tiempo con tus roles actuales."
_drivecleaner:
orderBySizeDesc: "Más grandes"
orderByCreatedAtAsc: "Más antiguos"
_webhookSettings:
name: "Nombre"
active: "Activado"

View File

@@ -527,7 +527,7 @@ updateRemoteUser: "Mettre à jour les informations de lutilisateur·rice dist
deleteAllFiles: "Supprimer tous les fichiers"
deleteAllFilesConfirm: "Êtes-vous sûr·e de vouloir supprimer tous les fichiers ?"
removeAllFollowing: "Retenir tous les abonnements"
removeAllFollowingDescription: "Se désabonner de tous les comptes de {host}. Veuillez lancer cette action uniquement si linstance nexiste plus."
removeAllFollowingDescription: "Se désabonner de tous les comptes de {host}. Veuillez lancer cette action dans les cas où linstance nexiste plus, etc."
userSuspended: "Cet·te utilisateur·rice a été suspendu·e."
userSilenced: "Cette utilisateur·trice a été mis·e en sourdine."
yourAccountSuspendedTitle: "Ce compte est suspendu"
@@ -575,7 +575,6 @@ tokenRequested: "Autoriser l'accès au compte"
pluginTokenRequestedDescription: "Ce plugin pourra utiliser les autorisations définies ici."
notificationType: "Type de notifications"
edit: "Editer"
useStarForReactionFallback: "Utiliser ★ comme alternative si lémoji de réaction est inconnu"
emailServer: "Serveur mail"
enableEmail: "Activer la distribution de courriel"
emailConfigInfo: "Utilisé pour confirmer votre adresse de courriel et la réinitialisation de votre mot de passe en cas doubli."
@@ -833,6 +832,7 @@ instanceDefaultLightTheme: "Thème clair par défaut sur toute linstance"
instanceDefaultDarkTheme: "Thème sombre par défaut sur toute linstance"
instanceDefaultThemeDescription: "Saisissez le code du thème en format objet."
mutePeriod: "Durée de mise en sourdine"
period: "Fin du sondage"
indefinitely: "Illimité"
tenMinutes: "10 minutes"
oneHour: "1 heure"
@@ -1467,3 +1467,7 @@ _deck:
channel: "Canaux"
mentions: "Mentions"
direct: "Direct"
_webhookSettings:
name: "Nom"
active: "Activé"

View File

@@ -1 +1,2 @@
---

View File

@@ -1 +1,2 @@
---

View File

@@ -579,7 +579,6 @@ tokenRequested: "Berikan ijin akses ke akun"
pluginTokenRequestedDescription: "Plugin ini dapat menggunakan setelan ijin disini."
notificationType: "Jenis pemberitahuan"
edit: "Sunting"
useStarForReactionFallback: "Gunakan ★ sebagai fallback jika reaksi emoji tidak diketahui"
emailServer: "Peladen surel"
enableEmail: "Nyalakan distribusi surel"
emailConfigInfo: "Digunakan untuk mengonfirmasi surel kamu disaat mendaftar dan lupa kata sandi"
@@ -839,6 +838,7 @@ instanceDefaultLightTheme: "Bawaan instan tema terang"
instanceDefaultDarkTheme: "Bawaan instan tema gelap"
instanceDefaultThemeDescription: "Masukkan kode tema di format obyek."
mutePeriod: "Batas waktu bisu"
period: "Batas akhir"
indefinitely: "Selamanya"
tenMinutes: "10 Menit"
oneHour: "1 Jam"
@@ -1803,3 +1803,7 @@ _deck:
channel: "Kanal"
mentions: "Sebutan"
direct: "Langsung"
_webhookSettings:
name: "Nama"
active: "Aktif"

View File

@@ -54,8 +54,8 @@ copyUsername: "Copia nome utente"
searchUser: "Cerca utente"
reply: "Rispondi"
loadMore: "Mostra di più"
showMore: "Mostra di più"
showLess: "Chiudi"
showMore: "Espandi"
showLess: "Comprimi"
youGotNewFollower: "Ha iniziato a seguirti"
receiveFollowRequest: "Hai ricevuto una richiesta di follow"
followRequestAccepted: "Richiesta di follow accettata"
@@ -75,8 +75,8 @@ lists: "Liste"
noLists: "Nessuna lista"
note: "Nota"
notes: "Note"
following: "Lǝ segui"
followers: "Followers"
following: "Follow"
followers: "Follower"
followsYou: "Ti segue"
createList: "Aggiungi una nuova lista"
manageLists: "Gestisci liste"
@@ -94,7 +94,7 @@ defaultNoteVisibility: "Privacy predefinita delle note"
follow: "Segui"
followRequest: "Richiesta di follow"
followRequests: "Richieste di follow"
unfollow: "Smetti di seguire"
unfollow: "Non seguire"
followRequestPending: "Richiesta in approvazione"
enterEmoji: "Inserisci emoji"
renote: "Rinota"
@@ -122,6 +122,8 @@ unmarkAsSensitive: "Segna come non sensibile"
enterFileName: "Nome del file"
mute: "Silenzia"
unmute: "Riattiva l'audio"
renoteMute: "Silenzia i Rinota"
renoteUnmute: "Non silenziare i Rinota"
block: "Blocca"
unblock: "Sblocca"
suspend: "Sospendi"
@@ -153,15 +155,16 @@ flagShowTimelineReplies: "Mostra le risposte alle note sulla timeline."
flagShowTimelineRepliesDescription: "Se è attiva, la timeline mostra le risposte alle altre note dell'utente oltre a quelle dell'utente stesso."
autoAcceptFollowed: "Accetta automaticamente le richieste di follow da utenti che già segui"
addAccount: "Aggiungi profilo"
reloadAccountsList: "Ricarica l'elenco dei profili"
loginFailed: "Accesso non riuscito"
showOnRemote: "Visualizza sull'istanza remota"
showOnRemote: "Leggi sull'istanza remota"
general: "Generali"
wallpaper: "Sfondo"
setWallpaper: "Imposta sfondo"
removeWallpaper: "Elimina lo sfondo"
searchWith: "Cerca: {q}"
youHaveNoLists: "Non hai ancora creato nessuna lista"
followConfirm: "Sei sicur@ di voler seguire {name}?"
followConfirm: "Vuoi seguire {name}?"
proxyAccount: "Profilo proxy"
proxyAccountDescription: "Un profilo proxy funziona come follower per i profili remoti, sotto certe condizioni. Ad esempio, quando un profilo locale ne inserisce uno remoto in una lista (senza seguirlo), se nessun altro segue quel profilo remoto, le attività non possono essere distribuite. Dunque, il profilo proxy le seguirà per tutti."
host: "Server remoto"
@@ -221,7 +224,7 @@ subscribing: "Iscrizione"
publishing: "Pubblicazione"
notResponding: "Nessuna risposta"
instanceFollowing: "Seguiti dall'istanza"
instanceFollowers: "Followers dell'istanza"
instanceFollowers: "Follower dell'istanza"
instanceUsers: "Utenti dell'istanza"
changePassword: "Aggiorna Password"
security: "Sicurezza"
@@ -393,13 +396,19 @@ about: "Informazioni"
aboutMisskey: "Informazioni di Misskey"
administrator: "Amministratore"
token: "Token"
2fa: "Autenticazione a due fattori"
totp: "App di autenticazione"
totpDescription: "Inserisci un codice OTP tramite un'app di autenticazione"
moderator: "Moderatore"
moderation: "moderazione"
nUsersMentioned: "{n} profili menzionati"
securityKeyAndPasskey: "Chiave di sicurezza e accesso"
securityKey: "Chiave di sicurezza"
lastUsed: "Ultima attività"
lastUsedAt: "Uso più recente: {t}"
unregister: "Annulla l'iscrizione"
passwordLessLogin: "Accedi senza password"
passwordLessLoginDescription: "Accedi senza password, usando la chiave di sicurezza"
resetPassword: "Reimposta password"
newPasswordIs: "La tua nuova password è「{password}」"
reduceUiAnimation: "Ridurre le animazioni dell'interfaccia"
@@ -451,6 +460,7 @@ aboutX: "Informazioni su {x}"
emojiStyle: "Stile emoji"
native: "Nativo"
disableDrawer: "Non mostrare il menù sul drawer"
showNoteActionsOnlyHover: "Mostra le azioni delle Note solo al passaggio del mouse"
noHistory: "Nessuna cronologia"
signinHistory: "Storico degli accessi al profilo"
enableAdvancedMfm: "Attiva MFM avanzati"
@@ -499,6 +509,7 @@ objectStorageSetPublicRead: "Imposta \"visibilità pubblica\" al momento di cari
serverLogs: "Log del server"
deleteAll: "Cancella cronologia"
showFixedPostForm: "Visualizzare la finestra di pubblicazione in cima alla timeline"
showFixedPostFormInChannel: "Per i canali, mostra il modulo di pubblicazione in cima alla timeline"
newNoteRecived: "Vedi le nuove note"
sounds: "Impostazioni suoni"
sound: "Impostazioni suoni"
@@ -536,6 +547,10 @@ userSuspended: "L'utente è in sospensione"
userSilenced: "L'utente è silenziat@."
yourAccountSuspendedTitle: "Questo profilo è sospeso"
yourAccountSuspendedDescription: "Questo profilo è stato sospeso a causa di una violazione del regolamento. Per informazioni, contattare l'amministrazione. Si prega di non creare un nuovo account."
tokenRevoked: "Il token non è valido"
tokenRevokedDescription: "Il token di accesso è scaduto. Per favore, accedi nuovamente."
accountDeleted: "Profilo eliminato"
accountDeletedDescription: "Questo profilo è stato eliminato."
menu: "Menù"
divider: "Linea di separazione"
addItem: "Aggiungi elemento"
@@ -550,8 +565,8 @@ enableInfiniteScroll: "Abilita scorrimento infinito"
visibility: "Visibilità"
poll: "Sondaggio"
useCw: "Nascondere media"
enablePlayer: "Apri in lettore video"
disablePlayer: "Chiudi lettore video"
enablePlayer: "Visualizza"
disablePlayer: "Chiudi"
expandTweet: "Espandi tweet"
themeEditor: "Editor di temi"
description: "Descrizione"
@@ -579,7 +594,6 @@ tokenRequested: "Autorizza accesso al profilo"
pluginTokenRequestedDescription: "Il plugin potrà utilizzare le autorizzazioni impostate qui."
notificationType: "Tipo di notifiche"
edit: "Modifica"
useStarForReactionFallback: "Se è sconosciuto l'emoji di reazione, usare la ★ come alternativa."
emailServer: "Server email"
enableEmail: "Abilita consegna email"
emailConfigInfo: "Utilizzato per verificare il tuo indirizzo di posta elettronica e per reimpostare la tua password"
@@ -773,6 +787,7 @@ popularPosts: "Le più visualizzate"
shareWithNote: "Condividere in nota"
ads: "Pubblicità"
expiration: "Scadenza"
startingperiod: "Periodo di inizio"
memo: "Promemoria"
priority: "Priorità"
high: "Alta"
@@ -804,7 +819,8 @@ pubSub: "Publish/Subscribe del profilo"
lastCommunication: "La comunicazione più recente"
resolved: "Risolto"
unresolved: "Non risolto"
breakFollow: "Smetti di seguire"
breakFollow: "Non seguire"
breakFollowConfirm: "Vuoi davvero togliere follower?"
itsOn: "Abilitato"
itsOff: "Disabilitato"
emailRequiredForSignup: "L'ndirizzo e-mail è obbligatorio per registrarsi"
@@ -839,11 +855,13 @@ instanceDefaultLightTheme: "Istanza, tema luminoso predefinito."
instanceDefaultDarkTheme: "Istanza, tema scuro predefinito."
instanceDefaultThemeDescription: "Compilare il codice del tema nel modulo dell'oggetto."
mutePeriod: "Durata del mute"
period: "Scadenza"
indefinitely: "Non scade"
tenMinutes: "10 minuti"
oneHour: "1 ora"
oneDay: "1 giorno"
oneWeek: "1 settimana"
oneMonth: "Un mese"
reflectMayTakeTime: "Potrebbe essere necessario un po' di tempo perché ciò abbia effetto."
failedToFetchAccountInformation: "Impossibile recuperare le informazioni sul profilo"
rateLimitExceeded: "Superato il limite di richieste."
@@ -939,6 +957,29 @@ collapseRenotes: "Comprimi i Rinota già letti"
internalServerError: "Errore interno del server"
internalServerErrorDescription: "Si è verificato un errore imprevisto all'interno del server"
copyErrorInfo: "Copia le informazioni sull'errore"
joinThisServer: "Registrati su questa istanza"
exploreOtherServers: "Trova altre istanze"
letsLookAtTimeline: "Sbircia la timeline"
disableFederationWarn: "Disabilita la federazione. Questo cambiamento non rende le pubblicazioni private. Di solito non è necessario abilitare questa opzione."
invitationRequiredToRegister: "L'accesso a questo nodo è solo ad invito. Devi inserire un codice d'invito valido. Puoi richiedere un codice all'amministratore."
emailNotSupported: "L'istanza non supporta l'invio di email"
postToTheChannel: "Pubblica sul canale"
cannotBeChangedLater: "Non sarà più modificabile"
reactionAcceptance: "Accettazione reazioni"
likeOnly: "Solo i Like"
likeOnlyForRemote: "Solo Like remoti"
rolesAssignedToMe: "I miei ruoli"
resetPasswordConfirm: "Vuoi reimpostare la password?"
sensitiveWords: "Parole sensibili"
sensitiveWordsDescription: "Imposta automaticamente \"Home\" alla visibilità delle Note che contengono una qualsiasi parola tra queste configurate. Puoi separarle per riga."
notesSearchNotAvailable: "Non è possibile cercare tra le Note."
license: "Licenza"
unfavoriteConfirm: "Vuoi davvero rimuovere la preferenza?"
myClips: "Le mie Clip"
drivecleaner: "Drive cleaner"
retryAllQueuesNow: "Ritenta di consumare tutte le code"
retryAllQueuesConfirmTitle: "Vuoi ritentare adesso?"
retryAllQueuesConfirmText: "Potrebbe sovraccaricare il server temporaneamente."
_achievements:
earnedAt: "Data di conseguimento"
_types:
@@ -1075,7 +1116,7 @@ _achievements:
description: "Hai seguito 300 profili"
_followers1:
title: "Il primo profilo tuo Follower"
description: "Hai ottenuto il tuo primo Follower"
description: "Hai ottenuto il tuo primo profilo Follower"
_followers10:
title: "Follow me!"
description: "Hai ottenuto 10 profili Follower"
@@ -1198,6 +1239,8 @@ _role:
iconUrl: "URL dell'icona"
asBadge: "Mostra come badge"
descriptionOfAsBadge: "Se indicato, accanto al nome utente viene visualizzata l'icona del ruolo."
displayOrder: "Ordine di visualizzazione"
descriptionOfDisplayOrder: "I valori più alti vengono visualizzati per primi"
canEditMembersByModerator: "Anche i Moderatori assegnano profili a questo ruolo"
descriptionOfCanEditMembersByModerator: "Se disattivo, potranno farlo solamente gli Amministratori."
priority: "Priorità"
@@ -1223,6 +1266,7 @@ _role:
rateLimitFactor: "Limite del rapporto"
descriptionOfRateLimitFactor: "I rapporti più bassi sono meno restrittivi, quelli più alti lo sono di più."
canHideAds: "Può nascondere i banner"
canSearchNotes: "Ricercare nelle Note"
_condition:
isLocal: "Profilo locale"
isRemote: "Profilo remoto"
@@ -1486,13 +1530,28 @@ _tutorial:
step8_3: "Potrai modificare questa impostazione."
_2fa:
alreadyRegistered: "La configurazione è stata già completata."
registerTOTP: "Registra un'app di autenticazione"
passwordToTOTP: "Inserire la password"
step1: "Innanzitutto, installare sul dispositivo un'applicazione di autenticazione come {a} o {b}."
step2: "Quindi, scansionare il codice QR visualizzato con l'app."
step2Click: "Cliccando sul codice QR, puoi registrarlo con l'app di autenticazione o il portachiavi installato sul tuo dispositivo."
step2Url: "Nell'applicazione desktop inserire il seguente URL: "
step3Title: "Inserisci il codice di verifica"
step3: "Inserite il token visualizzato nell'app e il gioco è fatto."
step4: "D'ora in poi, quando si accede, si inserisce il token nello stesso modo."
securityKeyNotSupported: "Il tuo browser non supporta le chiavi di sicurezza."
registerTOTPBeforeKey: "Ti occorre un'app di autenticazione con OTP, prima di registrare la chiave di sicurezza."
securityKeyInfo: "È possibile impostare il dispositivo per accedere utilizzando una chiave di sicurezza hardware che supporta FIDO2 o un'impronta digitale o un PIN sul dispositivo."
chromePasskeyNotSupported: "Le passkey di Chrome non sono attualmente supportate."
registerSecurityKey: "Registra la chiave di sicurezza"
securityKeyName: "Inserisci il nome della chiave"
tapSecurityKey: "Segui le istruzioni del browser e registra la chiave di sicurezza."
removeKey: "Elimina la chiave di sicurezza"
removeKeyConfirm: "Vuoi davvero eliminare \"{name}\"?"
whyTOTPOnlyRenew: "Se c'è una chiave di sicurezza attiva, non è possibile rimuovere l'app di autenticazione."
renewTOTP: "Riconfigura l'app di autenticazione"
renewTOTPConfirm: "I codici di verifica nelle app di autenticazione esistenti smetteranno di funzionare"
renewTOTPOk: "Ripristina"
renewTOTPCancel: "No grazie"
_permissions:
"read:account": "Visualizza le informazioni sul profilo"
@@ -1504,7 +1563,7 @@ _permissions:
"read:favorites": "Visualizza i tuoi preferiti"
"write:favorites": "Gestisci i tuoi preferiti"
"read:following": "Vedi le informazioni di follow"
"write:following": "Seguiti/ Smetti di seguire"
"write:following": "Seguire / Non seguire altri profili"
"read:messaging": "Visualizzare la chat"
"write:messaging": "Gestire la chat"
"read:mutes": "Vedi i profili silenziati"
@@ -1582,7 +1641,7 @@ _widgets:
clicker: "Cliccaggio"
_cw:
hide: "Nascondere"
show: "Mostra di più"
show: "Apri..."
chars: "{count} caratteri"
files: "{count} file"
_poll:
@@ -1612,10 +1671,12 @@ _visibility:
publicDescription: "Visibile per tutti sul Fediverso"
home: "Home"
homeDescription: "Visibile solo sulla timeline \"Home\""
followers: "Followers"
followersDescription: "Visibile solo per i tuoi followers"
followers: "Follower"
followersDescription: "Visibile solo per i tuoi follower"
specified: "Nota diretta"
specifiedDescription: "Visibile solo ai profili menzionati"
disableFederation: "Interrompi la federazione"
disableFederationDescription: "Non spedire attività alle altre istanze remote"
_postForm:
replyPlaceholder: "Rispondi a questa nota..."
quotePlaceholder: "Cita questa nota..."
@@ -1642,7 +1703,7 @@ _profile:
_exportOrImport:
allNotes: "Tutte le note"
favoritedNotes: "Note preferite"
followingList: "Follows"
followingList: "Follow"
muteList: "Elenco profili silenziati"
blockingList: "Elenco profili bloccati"
userLists: "Liste"
@@ -1771,6 +1832,7 @@ _notification:
pollEnded: "Sondaggio chiuso."
receiveFollowRequest: "Richiesta di follow ricevuta"
followRequestAccepted: "Richiesta di follow accettata"
achievementEarned: "Risultato raggiunto"
app: "Notifiche da applicazioni"
_actions:
followBack: "Segui"
@@ -1803,3 +1865,16 @@ _deck:
channel: "Canale"
mentions: "Menzioni"
direct: "Diretta"
_dialog:
charactersExceeded: "Hai superato il limite di {max} caratteri! ({corrente})"
charactersBelow: "Sei al di sotto del minimo di {min} caratteri! ({corrente})"
_disabledTimeline:
title: "Timeline disabilitata"
description: "Il tuo ruolo non ha i permessi per accedere a questa timeline"
_drivecleaner:
orderBySizeDesc: "Dal più grande al più piccolo"
orderByCreatedAtAsc: "Dal più vecchio al più recente"
_webhookSettings:
name: "Nome"
active: "Attivo"

View File

@@ -2,7 +2,7 @@ _lang_: "日本語"
headlineMisskey: "ノートでつながるネットワーク"
introMisskey: "ようこそMisskeyは、オープンソースの分散型マイクロブログサービスです。\n「ート」を作成して、いま起こっていることを共有したり、あなたについて皆に発信しよう📡\n「リアクション」機能で、皆のートに素早く反応を追加することもできます👍\n新しい世界を探検しよう🚀"
poweredByMisskeyDescription: "{name}は、オープンソースのプラットフォーム<b>Misskey</b>を使ったサービス(Misskeyインスタンスと呼ばれます)のひとつです。"
poweredByMisskeyDescription: "{name}は、オープンソースのプラットフォーム<b>Misskey</b>のサーバーのひとつです。"
monthAndDay: "{month}月 {day}日"
search: "検索"
notifications: "通知"
@@ -18,7 +18,7 @@ enterUsername: "ユーザー名を入力"
renotedBy: "{user}がRenote"
noNotes: "ノートはありません"
noNotifications: "通知はありません"
instance: "インスタンス"
instance: "サーバー"
settings: "設定"
basicSettings: "基本設定"
otherSettings: "その他の設定"
@@ -67,7 +67,7 @@ import: "インポート"
export: "エクスポート"
files: "ファイル"
download: "ダウンロード"
driveFileDeleteConfirm: "ファイル「{name}」を削除しますか?このファイルを添付したノートも消えます。"
driveFileDeleteConfirm: "ファイル「{name}」を削除しますか?このファイルを使用した全てのコンテンツからも削除されます。"
unfollowConfirm: "{name}のフォローを解除しますか?"
exportRequested: "エクスポートをリクエストしました。これには時間がかかる場合があります。エクスポートが終わると、「ドライブ」に追加されます。"
importRequested: "インポートをリクエストしました。これには時間がかかる場合があります。"
@@ -122,6 +122,8 @@ unmarkAsSensitive: "閲覧注意を解除する"
enterFileName: "ファイル名を入力"
mute: "ミュート"
unmute: "ミュート解除"
renoteMute: "リノートをミュート"
renoteUnmute: "リノートのミュートを解除"
block: "ブロック"
unblock: "ブロック解除"
suspend: "凍結"
@@ -153,6 +155,7 @@ flagShowTimelineReplies: "タイムラインにノートへの返信を表示す
flagShowTimelineRepliesDescription: "オンにすると、タイムラインにユーザーのノート以外にもそのユーザーの他のノートへの返信を表示します。"
autoAcceptFollowed: "フォロー中ユーザーからのフォロリクを自動承認"
addAccount: "アカウントを追加"
reloadAccountsList: "アカウントリストの情報を更新"
loginFailed: "ログインに失敗しました"
showOnRemote: "リモートで表示"
general: "全般"
@@ -163,13 +166,13 @@ searchWith: "検索: {q}"
youHaveNoLists: "リストがありません"
followConfirm: "{name}をフォローしますか?"
proxyAccount: "プロキシアカウント"
proxyAccountDescription: "プロキシアカウントは、特定の条件下でユーザーのリモートフォローを代行するアカウントです。例えば、ユーザーがリモートユーザーをリストに入れたとき、リストに入れられたユーザーを誰もフォローしていないとアクティビティがインスタンスに配達されないため、代わりにプロキシアカウントがフォローするようにします。"
proxyAccountDescription: "プロキシアカウントは、特定の条件下でユーザーのリモートフォローを代行するアカウントです。例えば、ユーザーがリモートユーザーをリストに入れたとき、リストに入れられたユーザーを誰もフォローしていないとアクティビティがサーバーに配達されないため、代わりにプロキシアカウントがフォローするようにします。"
host: "ホスト"
selectUser: "ユーザーを選択"
recipient: "宛先"
annotation: "注釈"
federation: "連合"
instances: "インスタンス"
instances: "サーバー"
registeredAt: "初観測"
latestRequestReceivedAt: "直近のリクエスト受信"
latestStatus: "直近のステータス"
@@ -178,7 +181,7 @@ charts: "チャート"
perHour: "1時間ごと"
perDay: "1日ごと"
stopActivityDelivery: "アクティビティの配送を停止"
blockThisInstance: "このインスタンスをブロック"
blockThisInstance: "このサーバーをブロック"
operations: "操作"
software: "ソフトウェア"
version: "バージョン"
@@ -189,15 +192,15 @@ jobQueue: "ジョブキュー"
cpuAndMemory: "CPUとメモリ"
network: "ネットワーク"
disk: "ディスク"
instanceInfo: "インスタンス情報"
instanceInfo: "サーバー情報"
statistics: "統計"
clearQueue: "キューをクリア"
clearQueueConfirmTitle: "キューをクリアしますか?"
clearQueueConfirmText: "未配達の投稿は配送されなくなります。通常この操作を行う必要はありません。"
clearCachedFiles: "キャッシュをクリア"
clearCachedFilesConfirm: "キャッシュされたリモートファイルをすべて削除しますか?"
blockedInstances: "ブロックしたインスタンス"
blockedInstancesDescription: "ブロックしたいインスタンスのホストを改行で区切って設定します。ブロックされたインスタンスは、このインスタンスとやり取りできなくなります。サブドメインもブロックされます。"
blockedInstances: "ブロックしたサーバー"
blockedInstancesDescription: "ブロックしたいサーバーのホストを改行で区切って設定します。ブロックされたサーバーは、このサーバーとやり取りできなくなります。サブドメインもブロックされます。"
muteAndBlock: "ミュートとブロック"
mutedUsers: "ミュートしたユーザー"
blockedUsers: "ブロックしたユーザー"
@@ -220,9 +223,9 @@ all: "全て"
subscribing: "購読中"
publishing: "配信中"
notResponding: "応答なし"
instanceFollowing: "インスタンスのフォロー"
instanceFollowers: "インスタンスのフォロワー"
instanceUsers: "インスタンスのユーザー"
instanceFollowing: "サーバーのフォロー"
instanceFollowers: "サーバーのフォロワー"
instanceUsers: "サーバーのユーザー"
changePassword: "パスワードを変更"
security: "セキュリティ"
retypedNotMatch: "入力が一致しません。"
@@ -314,8 +317,8 @@ unwatch: "ウォッチ解除"
accept: "許可"
reject: "拒否"
normal: "正常"
instanceName: "インスタンス名"
instanceDescription: "インスタンスの紹介"
instanceName: "サーバー名"
instanceDescription: "サーバーの紹介"
maintainerName: "管理者の名前"
maintainerEmail: "管理者のメールアドレス"
tosUrl: "利用規約URL"
@@ -345,7 +348,7 @@ basicInfo: "基本情報"
pinnedUsers: "ピン留めユーザー"
pinnedUsersDescription: "「みつける」ページなどにピン留めしたいユーザーを改行で区切って記述します。"
pinnedPages: "ピン留めページ"
pinnedPagesDescription: "インスタンスのトップページにピン留めしたいページのパスを改行で区切って記述します。"
pinnedPagesDescription: "サーバーのトップページにピン留めしたいページのパスを改行で区切って記述します。"
pinnedClipId: "ピン留めするクリップのID"
pinnedNotes: "ピン留めされたノート"
hcaptcha: "hCaptcha"
@@ -457,6 +460,7 @@ aboutX: "{x}について"
emojiStyle: "絵文字のスタイル"
native: "ネイティブ"
disableDrawer: "メニューをドロワーで表示しない"
showNoteActionsOnlyHover: "ノートのアクションをホバー時のみ表示する"
noHistory: "履歴はありません"
signinHistory: "ログイン履歴"
enableAdvancedMfm: "高度なMFMを有効にする"
@@ -505,6 +509,7 @@ objectStorageSetPublicRead: "アップロード時に'public-read'を設定す
serverLogs: "サーバーログ"
deleteAll: "全て削除"
showFixedPostForm: "タイムライン上部に投稿フォームを表示する"
showFixedPostFormInChannel: "タイムライン上部に投稿フォームを表示する(チャンネル)"
newNoteRecived: "新しいノートがあります"
sounds: "サウンド"
sound: "サウンド"
@@ -537,11 +542,15 @@ updateRemoteUser: "リモートユーザー情報の更新"
deleteAllFiles: "すべてのファイルを削除"
deleteAllFilesConfirm: "すべてのファイルを削除しますか?"
removeAllFollowing: "フォローを全解除"
removeAllFollowingDescription: "{host}からのフォローをすべて解除します。そのインスタンスがもう存在しなくなった場合などに実行してください。"
removeAllFollowingDescription: "{host}からのフォローをすべて解除します。そのサーバーがもう存在しなくなった場合などに実行してください。"
userSuspended: "このユーザーは凍結されています。"
userSilenced: "このユーザーはサイレンスされています。"
yourAccountSuspendedTitle: "アカウントが凍結されています"
yourAccountSuspendedDescription: "このアカウントは、サーバーの利用規約に違反したなどの理由により、凍結されています。詳細については管理者までお問い合わせください。新しいアカウントを作らないでください。"
tokenRevoked: "トークンが無効です"
tokenRevokedDescription: "ログイントークンが失効しています。ログインし直してください。"
accountDeleted: "アカウントは削除されています"
accountDeletedDescription: "このアカウントは削除されています。"
menu: "メニュー"
divider: "分割線"
addItem: "項目を追加"
@@ -585,7 +594,6 @@ tokenRequested: "アカウントへのアクセス許可"
pluginTokenRequestedDescription: "このプラグインはここで設定した権限を行使できるようになります。"
notificationType: "通知の種類"
edit: "編集"
useStarForReactionFallback: "リアクション絵文字が不明な場合、代わりに★を使う"
emailServer: "メールサーバー"
enableEmail: "メール配信機能を有効化する"
emailConfigInfo: "メールアドレスの確認やパスワードリセットの際に使います"
@@ -603,7 +611,7 @@ testEmail: "配信テスト"
wordMute: "ワードミュート"
regexpError: "正規表現エラー"
regexpErrorDescription: "{tab}ワードミュートの{line}行目の正規表現にエラーが発生しました:"
instanceMute: "インスタンスミュート"
instanceMute: "サーバーミュート"
userSaysSomething: "{name}が何かを言いました"
makeActive: "アクティブにする"
display: "表示"
@@ -634,15 +642,15 @@ abuseReported: "内容が送信されました。ご報告ありがとうござ
reporter: "通報者"
reporteeOrigin: "通報先"
reporterOrigin: "通報元"
forwardReport: "リモートインスタンスに通報を転送する"
forwardReportIsAnonymous: "リモートインスタンスからはあなたの情報は見れず、匿名のシステムアカウントとして表示されます。"
forwardReport: "リモートサーバーに通報を転送する"
forwardReportIsAnonymous: "リモートサーバーからはあなたの情報は見れず、匿名のシステムアカウントとして表示されます。"
send: "送信"
abuseMarkAsResolved: "対応済みにする"
openInNewTab: "新しいタブで開く"
openInSideView: "サイドビューで開く"
defaultNavigationBehaviour: "デフォルトのナビゲーション"
editTheseSettingsMayBreakAccount: "これらの設定を編集するとアカウントが破損する可能性があります。"
instanceTicker: "ノートのインスタンス情報"
instanceTicker: "ノートのサーバー情報"
waitingFor: "{x}を待っています"
random: "ランダム"
system: "システム"
@@ -731,7 +739,7 @@ capacity: "容量"
inUse: "使用中"
editCode: "コードを編集"
apply: "適用"
receiveAnnouncementFromInstance: "インスタンスからのお知らせを受け取る"
receiveAnnouncementFromInstance: "サーバーからのお知らせを受け取る"
emailNotification: "メール通知"
publish: "公開"
inChannelSearch: "チャンネル内検索"
@@ -759,7 +767,7 @@ active: "アクティブ"
offline: "オフライン"
notRecommended: "非推奨"
botProtection: "Botプロテクション"
instanceBlocking: "インスタンスブロック"
instanceBlocking: "サーバーブロック"
selectAccount: "アカウントを選択"
switchAccount: "アカウントを切り替え"
enabled: "有効"
@@ -843,15 +851,17 @@ themeColor: "テーマカラー"
size: "サイズ"
numberOfColumn: "列の数"
searchByGoogle: "検索"
instanceDefaultLightTheme: "インスタンスデフォルトのライトテーマ"
instanceDefaultDarkTheme: "インスタンスデフォルトのダークテーマ"
instanceDefaultLightTheme: "サーバーデフォルトのライトテーマ"
instanceDefaultDarkTheme: "サーバーデフォルトのダークテーマ"
instanceDefaultThemeDescription: "オブジェクト形式のテーマコードを記入します。"
mutePeriod: "ミュートする期限"
period: "期限"
indefinitely: "無期限"
tenMinutes: "10分"
oneHour: "1時間"
oneDay: "1日"
oneWeek: "1週間"
oneMonth: "1ヶ月"
reflectMayTakeTime: "反映されるまで時間がかかる場合があります。"
failedToFetchAccountInformation: "アカウント情報の取得に失敗しました"
rateLimitExceeded: "レート制限を超えました"
@@ -895,7 +905,7 @@ cannotUploadBecauseInappropriate: "不適切な内容を含む可能性がある
cannotUploadBecauseNoFreeSpace: "ドライブの空き容量が無いためアップロードできません。"
beta: "ベータ"
enableAutoSensitive: "自動NSFW判定"
enableAutoSensitiveDescription: "利用可能な場合は、機械学習を利用して自動でメディアにNSFWフラグを設定します。この機能をオフにしても、インスタンスによっては自動で設定されることがあります。"
enableAutoSensitiveDescription: "利用可能な場合は、機械学習を利用して自動でメディアにNSFWフラグを設定します。この機能をオフにしても、サーバーによっては自動で設定されることがあります。"
activeEmailValidationDescription: "ユーザーのメールアドレスのバリデーションを、捨てアドかどうかや実際に通信可能かどうかなどを判定しより積極的に行います。オフにすると単に文字列として正しいかどうかのみチェックされます。"
navbar: "ナビゲーションバー"
shuffle: "シャッフル"
@@ -905,7 +915,7 @@ pushNotification: "プッシュ通知"
subscribePushNotification: "プッシュ通知を有効化"
unsubscribePushNotification: "プッシュ通知を停止する"
pushNotificationAlreadySubscribed: "プッシュ通知は有効です"
pushNotificationNotSupported: "ブラウザかインスタンスがプッシュ通知に非対応"
pushNotificationNotSupported: "ブラウザかサーバーがプッシュ通知に非対応"
sendPushNotificationReadMessage: "通知やメッセージが既読になったらプッシュ通知を削除する"
sendPushNotificationReadMessageCaption: "「{emptyPushNotificationMessage}」という通知が一瞬表示されるようになります。端末の電池消費量が増加する可能性があります。"
windowMaximize: "最大化"
@@ -951,6 +961,28 @@ joinThisServer: "このサーバーに登録する"
exploreOtherServers: "他のサーバーを探す"
letsLookAtTimeline: "タイムラインを見てみる"
disableFederationWarn: "連合が無効になっています。無効にしても投稿が非公開にはなりません。ほとんどの場合、このオプションを有効にする必要はありません。"
invitationRequiredToRegister: "現在このサーバーは招待制です。招待コードをお持ちの方のみ登録できます。"
emailNotSupported: "このサーバーではメール配信はサポートされていません"
postToTheChannel: "チャンネルに投稿"
cannotBeChangedLater: "後から変更できません。"
reactionAcceptance: "リアクションの受け入れ"
likeOnly: "いいねのみ"
likeOnlyForRemote: "リモートからはいいねのみ"
rolesAssignedToMe: "自分に割り当てられたロール"
resetPasswordConfirm: "パスワードリセットしますか?"
sensitiveWords: "センシティブワード"
sensitiveWordsDescription: "設定したワードが含まれるノートの公開範囲をホームにします。改行で区切って複数設定できます。"
notesSearchNotAvailable: "ノート検索は利用できません。"
license: "ライセンス"
unfavoriteConfirm: "お気に入り解除しますか?"
myClips: "自分のクリップ"
drivecleaner: "ドライブクリーナー"
retryAllQueuesNow: "すべてのキューを今すぐ再試行"
retryAllQueuesConfirmTitle: "今すぐ再試行しますか?"
retryAllQueuesConfirmText: "一時的にサーバーの負荷が増大することがあります。"
enableChartsForRemoteUser: "リモートユーザーのチャートを生成"
enableChartsForFederatedInstances: "リモートサーバーのチャートを生成"
showClipButtonInNoteFooter: "ノートのアクションにクリップを追加"
_achievements:
earnedAt: "獲得日時"
@@ -1142,7 +1174,7 @@ _achievements:
description: "ホームタイムラインの流速が20npmを越す"
_viewInstanceChart:
title: "アナリスト"
description: "インスタンスのチャートを表示した"
description: "サーバーのチャートを表示した"
_outputHelloWorldOnScratchpad:
title: "Hello, world!"
description: "スクラッチパッドで hello world を出力した"
@@ -1179,7 +1211,7 @@ _achievements:
_loggedInOnNewYearsDay:
title: "あけましておめでとうございます"
description: "元日にログインした"
flavor: "今年も弊インスタンスをよろしくお願いします"
flavor: "今年も弊サーバーをよろしくお願いします"
_cookieClicked:
title: "クッキーをクリックするゲーム"
description: "クッキーをクリックした"
@@ -1195,7 +1227,7 @@ _role:
name: "ロール名"
description: "ロールの説明"
permission: "ロールの権限"
descriptionOfPermission: "<b>モデレーター</b>は基本的なモデレーションに関する操作を行えます。\n<b>管理者</b>はインスタンスの全ての設定を変更できます。"
descriptionOfPermission: "<b>モデレーター</b>は基本的なモデレーションに関する操作を行えます。\n<b>管理者</b>はサーバーの全ての設定を変更できます。"
assignTarget: "アサイン"
descriptionOfAssignTarget: "<b>マニュアル</b>は誰がこのロールに含まれるかを手動で管理します。\n<b>コンディショナル</b>は条件を設定し、それに合致するユーザーが自動で含まれるようになります。"
manual: "マニュアル"
@@ -1212,6 +1244,8 @@ _role:
iconUrl: "アイコン画像のURL"
asBadge: "バッジとして表示"
descriptionOfAsBadge: "オンにすると、ユーザー名の横にロールのアイコンが表示されます。"
displayOrder: "表示順"
descriptionOfDisplayOrder: "数値が大きいほどUI上で先頭に表示されます。"
canEditMembersByModerator: "モデレーターのメンバー編集を許可"
descriptionOfCanEditMembersByModerator: "オンにすると、管理者に加えてモデレーターもこのロールへユーザーをアサイン/アサイン解除できるようになります。オフにすると管理者のみが行えます。"
priority: "優先度"
@@ -1223,7 +1257,7 @@ _role:
gtlAvailable: "グローバルタイムラインの閲覧"
ltlAvailable: "ローカルタイムラインの閲覧"
canPublicNote: "パブリック投稿の許可"
canInvite: "インスタンス招待コードの発行"
canInvite: "サーバー招待コードの発行"
canManageCustomEmojis: "カスタム絵文字の管理"
driveCapacity: "ドライブ容量"
pinMax: "ノートのピン留めの最大数"
@@ -1237,6 +1271,7 @@ _role:
rateLimitFactor: "レートリミット"
descriptionOfRateLimitFactor: "小さいほど制限が緩和され、大きいほど制限が強化されます。"
canHideAds: "広告の非表示"
canSearchNotes: "ノート検索の利用可否"
_condition:
isLocal: "ローカルユーザー"
isRemote: "リモートユーザー"
@@ -1246,6 +1281,8 @@ _role:
followersMoreThanOrEq: "フォロワー数が~以上"
followingLessThanOrEq: "フォロー数が~以下"
followingMoreThanOrEq: "フォロー数が~以上"
notesLessThanOrEq: "投稿数が~以下"
notesMoreThanOrEq: "投稿数が~以上"
and: "~かつ~"
or: "~または~"
not: "~ではない"
@@ -1292,7 +1329,7 @@ _ad:
_forgotPassword:
enterEmail: "アカウントに登録したメールアドレスを入力してください。そのアドレス宛てに、パスワードリセット用のリンクが送信されます。"
ifNoEmail: "メールアドレスを登録していない場合は、管理者までお問い合わせください。"
contactAdmin: "このインスタンスではメールがサポートされていないため、パスワードリセットを行う場合は管理者までお問い合わせください。"
contactAdmin: "このサーバーではメールがサポートされていないため、パスワードリセットを行う場合は管理者までお問い合わせください。"
_gallery:
my: "自分の投稿"
@@ -1390,10 +1427,10 @@ _wordMute:
mutedNotes: "ミュートされたノート"
_instanceMute:
instanceMuteDescription: "ミュートしたインスタンスのユーザーへの返信を含めて、設定したインスタンスの全てのートとRenoteをミュートします。"
instanceMuteDescription: "ミュートしたサーバーのユーザーへの返信を含めて、設定したサーバーの全てのートとRenoteをミュートします。"
instanceMuteDescription2: "改行で区切って設定します"
title: "設定したインスタンスのノートを隠します。"
heading: "ミュートするインスタンス"
title: "設定したサーバーのノートを隠します。"
heading: "ミュートするサーバー"
_theme:
explore: "テーマを探す"
@@ -1613,7 +1650,7 @@ _weekday:
_widgets:
profile: "プロフィール"
instanceInfo: "インスタンス情報"
instanceInfo: "サーバー情報"
memo: "付箋"
notifications: "通知"
timeline: "タイムライン"
@@ -1627,7 +1664,7 @@ _widgets:
digitalClock: "デジタル時計"
unixClock: "UNIX時計"
federation: "連合"
instanceCloud: "インスタンスクラウド"
instanceCloud: "サーバークラウド"
postForm: "投稿フォーム"
slideshow: "スライドショー"
button: "ボタン"
@@ -1681,7 +1718,7 @@ _visibility:
specified: "ダイレクト"
specifiedDescription: "指定したユーザーのみに公開"
disableFederation: "連合なし"
disableFederationDescription: "他インスタンスへの配信を行いません"
disableFederationDescription: "他サーバーへの配信を行いません"
_postForm:
replyPlaceholder: "このノートに返信..."
@@ -1889,3 +1926,27 @@ _deck:
_dialog:
charactersExceeded: "最大文字数を超えています! 現在 {current} / 制限 {max}"
charactersBelow: "最小文字数を下回っています! 現在 {current} / 制限 {min}"
_disabledTimeline:
title: "無効化されたタイムライン"
description: "現在のロールでは、このタイムラインを使用することはできません。"
_drivecleaner:
orderBySizeDesc: "サイズが大きい順"
orderByCreatedAtAsc: "追加日が古い順"
_webhookSettings:
createWebhook: "Webhookを作成"
name: "名前"
secret: "シークレット"
events: "Webhookを実行するタイミング"
active: "有効"
_events:
follow: "フォローしたとき"
followed: "フォローされたとき"
note: "ノートを投稿したとき"
reply: "返信されたとき"
renote: "Renoteされたとき"
reaction: "リアクションがあったとき"
mention: "メンションされたとき"

View File

@@ -2,7 +2,7 @@
_lang_: "日本語 (関西弁)"
headlineMisskey: "ノートでつながるネットワーク"
introMisskey: "ようお越しMisskeyは、オープンソースの分散型マイクロブログサービスやねん。\n「ート」を作って、いま起こっとることを共有したり、あんたについて皆に発信しよう📡\n「リアクション」機能で、皆のートに素早く反応を追加したりもできるで✌\nほな新しい世界を探検しよか🚀"
poweredByMisskeyDescription: "{name}は、オープンソースのプラットフォーム<b>Misskey</b>を使ったサービス(Misskeyインスタンスと呼ばれるやつや)のひとつやで。"
poweredByMisskeyDescription: "{name}は、オープンソースのプラットフォーム<b>Misskey</b>のサーバーのひとつなんやで。"
monthAndDay: "{month}月 {day}日"
search: "探す"
notifications: "通知"
@@ -15,13 +15,13 @@ gotIt: "ほい"
cancel: "やめとく"
noThankYou: "やめとく"
enterUsername: "ユーザー名を入れてや"
renotedBy: "{user}がRenote"
noNotes: "ノートあらへん"
noNotifications: "通知あらへん"
instance: "インスタンス"
renotedBy: "{user}がRenoteしたで"
noNotes: "ノートなんてあらへん"
noNotifications: "通知なんてあらへん"
instance: "サーバー"
settings: "設定"
basicSettings: "基本設定"
otherSettings: "その他の設定"
otherSettings: "ほかの設定"
openInWindow: "ウィンドウで開くで"
profile: "プロフィール"
timeline: "タイムライン"
@@ -55,7 +55,7 @@ searchUser: "ユーザーを検索"
reply: "返事"
loadMore: "まだまだあるで!"
showMore: "まだまだあるで!"
showLess: "閉じる"
showLess: "さいなら"
youGotNewFollower: "フォローされたで"
receiveFollowRequest: "フォローリクエストされたで"
followRequestAccepted: "フォローが承認されたで"
@@ -84,12 +84,12 @@ error: "エラー"
somethingHappened: "なんかアカンことが起こったで"
retry: "もっぺんやる?"
pageLoadError: "ページの読み込みに失敗してもうたわ…"
pageLoadErrorDescription: "これは普通ネットワークかブラウザキャッシュが原因やからね。キャッシュをクリアするか、もうちっとだけ待ってくれへん"
pageLoadErrorDescription: "これは普通ならネットワークかブラウザキャッシュが悪さしてるんよ。キャッシュをほかすか、もうちっとだけ待ってくれへん?"
serverIsDead: "サーバーからの応答がないで。もうちょい待ってから試してみてな。"
youShouldUpgradeClient: "このページを表示するには、リロードして新しいバージョンのクライアントを使ってなー。"
enterListName: "リスト名を入れてや"
privacy: "プライバシー"
makeFollowManuallyApprove: "他人のフォローは許可してからや!"
makeFollowManuallyApprove: "ええって言わなフォローできへんようにする"
defaultNoteVisibility: "もとからの公開範囲"
follow: "フォロー"
followRequest: "フォローを頼む"
@@ -113,7 +113,7 @@ sensitive: "ちょっとアカンやつやで"
add: "増やす"
reaction: "リアクション"
reactions: "リアクション"
reactionSetting: "Reaction that will be displayed in Picker. "
reactionSetting: "ピッカーに出しとくリアクション"
reactionSettingDescription2: "ドラッグで並び替え、クリックで削除、+を押して追加やで。"
rememberNoteVisibility: "公開範囲覚えといて"
attachCancel: "のっけるのやめる"
@@ -122,6 +122,8 @@ unmarkAsSensitive: "そこまでアカンことないやろ"
enterFileName: "ファイル名を入れてや"
mute: "ミュート"
unmute: "ミュートやめたる"
renoteMute: "リノートは見いひん"
renoteUnmute: "リノートもやっぱ見るわ"
block: "ブロック"
unblock: "ブロックやめたる"
suspend: "凍結"
@@ -145,20 +147,21 @@ addEmoji: "絵文字を追加"
settingGuide: "ええ感じの設定"
cacheRemoteFiles: "リモートのファイルをキャッシュする"
cacheRemoteFilesDescription: "この設定を切っとくと、リモートファイルをキャッシュせず直リンクするようになるで。サーバーの容量は節約できるけど、サムネイルが作られんくなるから通信量が増えるで。"
flagAsBot: "Botで"
flagAsBotDescription: "もしこのアカウントプログラムによって運用されるんやったら、このフラグをオンにしてたのむで。オンにすると、反応の連鎖を防ぐためのフラグとして他の開発者に役立ったり、Misskeyのシステム上での扱いがBotに合ったもんになるんやで。"
flagAsBot: "Botにするで"
flagAsBotDescription: "もしこのアカウントプログラム使うて運用るんやったら、このフラグをオンにして。オンにすれば、反応がバーッて連鎖するのを避けるために開発者が使うたり、Misskeyのシステム上での扱いがBotに合ったもんになるからな。"
flagAsCat: "Catやで"
flagAsCatDescription: "ワレ、猫ちゃんならこのフラグをつけてみ?"
flagShowTimelineReplies: "タイムラインにノートへの返信を表示するで"
flagShowTimelineRepliesDescription: "オンにしたら、タイムラインにユーザーのノートの他にもそのユーザーの他のノートへの返信を表示するで。"
autoAcceptFollowed: "フォローしとるユーザーからのフォローリクエストを勝手に許可しとく"
addAccount: "アカウントを追加"
reloadAccountsList: "アカウントリストの情報を更新"
loginFailed: "ログインに失敗してもうた…"
showOnRemote: "リモートで見る"
general: "全般"
wallpaper: "壁紙"
setWallpaper: "壁紙を設定"
removeWallpaper: "壁紙を削除"
removeWallpaper: "壁紙ほかす"
searchWith: "検索: {q}"
youHaveNoLists: "リストがあらへんで?"
followConfirm: "{name}をフォローしてええか?"
@@ -169,7 +172,7 @@ selectUser: "ユーザーを選ぶ"
recipient: "宛先"
annotation: "注釈"
federation: "連合"
instances: "インスタンス"
instances: "サーバー"
registeredAt: "初観測"
latestRequestReceivedAt: "ちょっと前のリクエスト受信"
latestStatus: "ちょっと前のステータス"
@@ -178,7 +181,7 @@ charts: "チャート"
perHour: "1時間ごと"
perDay: "1日ごと"
stopActivityDelivery: "アクティビティの配送をやめる"
blockThisInstance: "このインスタンスをブロック"
blockThisInstance: "このサーバーをブロックすんで"
operations: "操作"
software: "ソフトウェア"
version: "バージョン"
@@ -189,28 +192,28 @@ jobQueue: "ジョブキュー"
cpuAndMemory: "CPUとメモリ"
network: "ネットワーク"
disk: "ディスク"
instanceInfo: "インスタンス情報"
instanceInfo: "サーバー情報"
statistics: "統計"
clearQueue: "キューにさいなら"
clearQueueConfirmTitle: "キューをクリアしまっか?"
clearQueueConfirmText: "未配達の投稿は配送されなくなるで。通常この操作を行う必要はあらへんや。"
clearQueueConfirmText: "未配達の投稿は配送されなくなるで。ふつうこの操作を行う必要は無いんやけどな。"
clearCachedFiles: "キャッシュにさいなら"
clearCachedFilesConfirm: "キャッシュされとるリモートファイルをみんなほかしてええか?"
blockedInstances: "インスタンスブロック"
blockedInstancesDescription: "ブロックしたいインスタンスのホストを改行で区切って設定してな。ブロックされてもうたインスタンスとはもう金輪際やり取りできひんくなるで。"
blockedInstances: "ブロックしたサーバー"
blockedInstancesDescription: "ブロックしたいサーバーのホストを改行で区切って設定してな。ブロックされてもうたサーバーとはもう金輪際やり取りできひんくなるで。ついでにそのサブドメインもブロックするで。"
muteAndBlock: "ミュートとブロック"
mutedUsers: "ミュートしたユーザー"
blockedUsers: "ブロックしたユーザー"
noUsers: "ユーザーはおらん"
noUsers: "ユーザーはおらん"
editProfile: "プロフィールをいじる"
noteDeleteConfirm: "このノートを削除しまっか?"
pinLimitExceeded: "これ以上ピン留めできひん"
intro: "Misskeyのインストールが完了してん!管理者アカウントを作ってや。"
intro: "Misskeyのインストールが完了したで!管理者アカウントを作ってや。"
done: "でけた"
processing: "処理しとる"
preview: "プレビュー"
default: "デフォルト"
defaultValueIs: "デフォルト"
defaultValueIs: "デフォルト: {value}"
noCustomEmojis: "絵文字はあらへん"
noJobs: "ジョブはあらへん"
federating: "連合しとる"
@@ -220,17 +223,17 @@ all: "みんな"
subscribing: "購読しとる"
publishing: "配信しとる"
notResponding: "応答してへんで"
instanceFollowing: "インスタンスのフォロー"
instanceFollowers: "インスタンスのフォロワー\n"
instanceUsers: "インスタンスのユーザー"
instanceFollowing: "サーバーのフォロー"
instanceFollowers: "サーバーのフォロワー\n"
instanceUsers: "サーバーのユーザー"
changePassword: "パスワード変える"
security: "セキュリティ"
retypedNotMatch: "そやないねん。"
retypedNotMatch: "入れたやつ同じになってないで。"
currentPassword: "今のパスワード"
newPassword: "今度のパスワード"
newPassword: "のパスワード"
newPasswordRetype: "今度のパスワード(もっぺん入れて)"
attachFile: "ファイルのっける"
more: "他のやつ!"
more: "他の"
featured: "ハイライト"
usernameOrUserId: "ユーザー名かユーザーID"
noSuchUser: "ユーザーが見つからへんで"
@@ -238,15 +241,15 @@ lookup: "見てきて"
announcements: "お知らせ"
imageUrl: "画像URL"
remove: "ほかす"
removed: "削除したで!"
removed: "ほかしたで!"
removeAreYouSure: "「{x}」はほかしてええか?"
deleteAreYouSure: "「{x}」はほかしてええか?"
resetAreYouSure: "リセットしてええん?"
saved: "保存したで!"
messaging: "チャット"
upload: "アップロード"
keepOriginalUploading: "オリジナル画像を保持するわ"
keepOriginalUploadingDescription: "画像を上げるときにオリジナル版を保持するで。オフにしたら上げたときにブラウザでWeb公開用の画像を生成するで。 "
keepOriginalUploading: "オリジナル画像のまんま"
keepOriginalUploadingDescription: "画像を上げるときにオリジナル版のまんまにするで。オフにしたら上げたときにブラウザでWeb公開用の画像を生成するで。 "
fromDrive: "ドライブから"
fromUrl: "URLから"
uploadFromUrl: "URLアップロード"
@@ -272,8 +275,8 @@ yearsOld: "{age}歳"
registeredDate: "始めた日"
location: "場所"
theme: "テーマ"
themeForLightMode: "ライトモードではこのテーマつこて"
themeForDarkMode: "ダークモードではこのテーマつこて"
themeForLightMode: "ライトモードではこのテーマ使うて"
themeForDarkMode: "ダークモードではこのテーマ使うて"
light: "ライト"
dark: "ダーク"
lightThemes: "デイゲーム"
@@ -289,13 +292,13 @@ renameFile: "ファイル名をいらう"
folderName: "フォルダー名"
createFolder: "フォルダー作る"
renameFolder: "フォルダー名を変える"
deleteFolder: "フォルダーを消してまう"
deleteFolder: "フォルダーをほかす"
addFile: "ファイルを追加"
emptyDrive: "ドライブにはなんも残っとらん"
emptyFolder: "ふぉろだーにはなんも残っとらん"
emptyFolder: "このフォルダーは空や"
unableToDelete: "消そうおもってんけどな、あかんかったわ"
inputNewFileName: "今度のファイル名は何にするん?"
inputNewDescription: "新しいキャプションを入力しましょ"
inputNewDescription: "新しいキャプションを入れてや"
inputNewFolderName: "今度のフォルダ名は何にするん?"
circularReferenceFolder: "移動先のフォルダーは、移動するフォルダーのサブフォルダーや。"
hasChildFilesOrFolders: "このフォルダ、まだなんか入っとるから消されへん"
@@ -303,8 +306,8 @@ copyUrl: "URLをコピー"
rename: "名前を変えるで"
avatar: "アイコン"
banner: "バナー"
nsfw: "閲覧注意"
whenServerDisconnected: "サーバーとの接続が切れたとき"
nsfw: "見るんは気いつけてな"
whenServerDisconnected: "サーバーとの接続が失くなってしもうたとき"
disconnectedFromServer: "サーバーが機嫌悪いねん"
reload: "リロード"
doNothing: "何もせんとく"
@@ -314,10 +317,10 @@ unwatch: "ウォッチやめる"
accept: "ええで"
reject: "あかん"
normal: "ええ感じ"
instanceName: "インスタンス名"
instanceDescription: "インスタンスの紹介"
maintainerName: "管理者の名前"
maintainerEmail: "管理者のメールアドレス"
instanceName: "サーバー名"
instanceDescription: "サーバーの紹介"
maintainerName: "管理者はんの名前"
maintainerEmail: "管理者はんのメールアドレス"
tosUrl: "利用規約のURL"
thisYear: "今年"
thisMonth: "今月"
@@ -329,23 +332,23 @@ pages: "ページ"
integration: "連携"
connectService: "つなげるで"
disconnectService: "切るで"
enableLocalTimeline: "ローカルタイムラインを使えるようにする"
enableGlobalTimeline: "グローバルタイムラインを使えるようにする"
enableLocalTimeline: "ローカルタイムラインを使えるようにする"
enableGlobalTimeline: "グローバルタイムラインを使えるようにする"
disablingTimelinesInfo: "ここらへんのタイムラインを使えんようにしてしもても、管理者とモデレーターは使えるままになってるで、そうやなかったら不便やからな。"
registration: "登録"
enableRegistration: "一見さんでも誰でもいらっしゃ~い"
invite: "来てや"
driveCapacityPerLocalAccount: "ローカルユーザーひとりあたりのドライブ容量"
driveCapacityPerRemoteAccount: "リモートユーザーひとりあたりのドライブ容量"
driveCapacityPerLocalAccount: "ローカルユーザーはんひとりあたりのドライブ容量"
driveCapacityPerRemoteAccount: "リモートユーザーはんひとりあたりのドライブ容量"
inMb: "メガバイト単位"
iconUrl: "アイコン画像のURL"
bannerUrl: "バナー画像のURL"
backgroundImageUrl: "背景画像のURL"
basicInfo: "基本情報"
pinnedUsers: "ピン留めしたユーザー"
pinnedUsersDescription: "「みつける」ページとかにピン留めしたいユーザーをここに書けばええんやで。他ん人との名前は改行で区切ればええんやで。"
pinnedUsersDescription: "「みつける」ページとかにピン留めしたいユーザーをここに書けばええんやで。ユーザー毎に改行してや。"
pinnedPages: "ピン留めページ"
pinnedPagesDescription: "インスタンスのいっちゃん上にピン留めしたいページのパスを改行で区切って記述してな"
pinnedPagesDescription: "サーバーのいっちゃん上にピン留めしたいページのパスを改行で区切って記述してな"
pinnedClipId: "ピン留めするクリップのID"
pinnedNotes: "ピン留めされとるノート"
hcaptcha: "hCaptchaキャプチャ"
@@ -370,7 +373,7 @@ antennaExcludeKeywords: "除外キーワード"
antennaKeywordsDescription: "スペースで区切ったるとAND指定で、改行で区切ったるとOR指定や"
notifyAntenna: "新しいノートを通知すんで"
withFileAntenna: "なんか添付されたノートだけ"
enableServiceworker: "ServiceWorkerをつこて"
enableServiceworker: "ブラウザにプッシュ通知が行くようにする"
antennaUsersDescription: "ユーザー名を改行で区切ったってな"
caseSensitive: "大文字と小文字は別もんや"
withReplies: "返信も入れたって"
@@ -395,23 +398,23 @@ administrator: "管理者"
token: "トークン"
2fa: "二要素認証"
totp: "認証アプリ"
totpDescription: "認証アプリ使てワンタイムパスワードを入れる"
totpDescription: "認証アプリ使てワンタイムパスワードを入れる"
moderator: "モデレーター"
moderation: "モデレーション"
nUsersMentioned: "{n}人が投稿"
securityKeyAndPasskey: "セキュリティキー・パスキー"
securityKey: "セキュリティキー"
lastUsed: "最後につこうた日"
lastUsedAt: "最後に使たん: {t}"
lastUsedAt: "最後に使たん: {t}"
unregister: "登録やめる"
passwordLessLogin: "パスワード無くてもログインできるようにする"
passwordLessLoginDescription: "パスワードやなくて、セキュリティキーとかパスキーだけでログインするわ"
passwordLessLoginDescription: "パスワードなんかいらん、セキュリティキーとかパスキーだけでログインするわ"
resetPassword: "パスワードをリセット"
newPasswordIs: "今度のパスワードは「{password}」や"
reduceUiAnimation: "UIの動きやアニメーションを減らす"
reduceUiAnimation: "UIの動きやアニメーションを少なする"
share: "わけわけ"
notFound: "見つからへんね"
notFoundDescription: "指定されたURLに該当するページはあらへんやった。"
notFoundDescription: "言われたURLにはまるページはなかった。"
uploadFolder: "とりあえずアップロードしたやつ置いとく所"
cacheClear: "キャッシュをほかす"
markAsReadAllNotifications: "通知はもう全て読んだわっ"
@@ -419,37 +422,37 @@ markAsReadAllUnreadNotes: "投稿は全て読んだわっ"
markAsReadAllTalkMessages: "チャットはもうぜんぶ読んだわっ"
help: "ヘルプ"
inputMessageHere: "ここにメッセージ書いてや"
close: "閉じる"
close: "さいなら"
invites: "来てや"
members: "メンバー"
members: "メンバーはん"
transfer: "譲渡"
title: "タイトル"
text: "テキスト"
enable: "有効にするで"
next: "次"
retype: "もっかい入力"
noteOf: "{user}のノート"
noteOf: "{user}はんのノート"
quoteAttached: "引用付いとるで"
quoteQuestion: "引用として添付してもええか?"
noMessagesYet: "まだチャットはあらへんで"
newMessageExists: "新しいメッセージがきたで"
onlyOneFileCanBeAttached: "すまん、メッセージに添付できるファイルはひとつだけなん。"
onlyOneFileCanBeAttached: "ごめんな、メッセージに添付できるファイルはひとつだけなん。"
signinRequired: "ログインしてくれへん?"
invitations: "来てや"
invitationCode: "招待コード"
checking: "確認しとるで"
available: "利用できる\n"
available: "使えるで"
unavailable: "利用できん"
usernameInvalidFormat: "a~z、A~Z、0~9、_が使えるで"
tooShort: "短すぎやろ!"
tooLong: "長すぎやろ!"
weakPassword: "へぼいパスワード"
normalPassword: "普通のパスワード"
normalPassword: "ぼちぼちのパスワード"
strongPassword: "ええ感じのパスワード"
passwordMatched: "よし!一致や!"
passwordNotMatched: "一致しとらんで?"
signinWith: "{x}でログイン"
signinFailed: "ログインできんかったで。もっかいユーザー名とパスワードを確認してみて。"
signinFailed: "ログインできんかったで。もっかいユーザー名とパスワードを確認してみて。"
or: "それか"
language: "言語"
uiLanguage: "UIの表示言語"
@@ -457,7 +460,8 @@ aboutX: "{x}について"
emojiStyle: "絵文字のスタイル"
native: "ネイティブ"
disableDrawer: "メニューをドロワーで表示せぇへん"
noHistory: "履歴はあらへんねぇ。"
showNoteActionsOnlyHover: "ノートの操作部をホバー時のみ表示するで"
noHistory: "履歴はないわ。"
signinHistory: "ログイン履歴"
enableAdvancedMfm: "ややこしいMFMもありにする"
enableAnimatedMfm: "動きがやかましいMFMも許したる"
@@ -465,12 +469,12 @@ doing: "やっとるがな"
category: "カテゴリ"
tags: "タグ"
docSource: "このドキュメントのソース"
createAccount: "アカウントを作"
existingAccount: "既存のアカウント"
regenerate: "再生成"
fontSize: "フォントサイズ"
createAccount: "アカウントを作るで"
existingAccount: "前に作ったアカウント"
regenerate: "もっぺん生成するで"
fontSize: "字の大きさ"
noFollowRequests: "フォロー申請はあらへんで"
openImageInNewTab: "画像を新しいタブで開く"
openImageInNewTab: "画像を新しいタブで開く"
dashboard: "ダッシュボード"
local: "ローカル"
remote: "リモート"
@@ -503,8 +507,9 @@ objectStorageUseProxy: "Proxyを使う"
objectStorageUseProxyDesc: "API接続にproxy使わんのやったら切ってくれへん"
objectStorageSetPublicRead: "アップロードした時に'public-read'を設定してや"
serverLogs: "サーバーログ"
deleteAll: "全て削除してや"
deleteAll: "全部ほかす"
showFixedPostForm: "タイムラインの上の方で投稿できるようにやってくれへん?"
showFixedPostFormInChannel: "タイムラインの上の方で投稿できるようにするわ(チャンネル)"
newNoteRecived: "新しいノートがあるで"
sounds: "サウンド"
sound: "サウンド"
@@ -512,11 +517,11 @@ listen: "聴く"
none: "なし"
showInPage: "ページで表示"
popout: "ポップアウト"
volume: "音量"
masterVolume: "全体の音量"
volume: "やかましさ"
masterVolume: "全体のやかましさ"
details: "もっと"
chooseEmoji: "絵文字を選ぶ"
unableToProcess: "なんか作業が止まってしまったようやね"
unableToProcess: "なんか奥の方で詰まってもうた"
recentUsed: "最近使ったやつ"
install: "インストール"
uninstall: "アンインストール"
@@ -534,14 +539,18 @@ output: "出力"
script: "スクリプト"
disablePagesScript: "Pagesのスクリプトを無効にしてや"
updateRemoteUser: "リモートユーザー情報の更新してくれん?"
deleteAllFiles: "すべてのファイルを削除"
deleteAllFilesConfirm: "ホンマにすべてのファイルを削除するん?消したもんはもう戻ってこんのやで?"
deleteAllFiles: "ファイルを全部ほかす"
deleteAllFilesConfirm: "ホンマにファイル全部ほかすんか?消したもんはもう戻ってこんのやで?"
removeAllFollowing: "フォローを全解除"
removeAllFollowingDescription: "{host}からのフォローをすべて解除するで。そのインスタンスが消えて無くなった時とかには便利な機能やで。"
userSuspended: "このユーザーは...凍結されとる。"
userSilenced: "このユーザーは...サイレンスされとる。"
yourAccountSuspendedTitle: "あんたのアカウント凍結されとるで"
yourAccountSuspendedDescription: "あんたのアカウントは、サーバーの利用規約に違反したとかの理由で、凍結されとるで。細かいことは管理者までお問い合わせたってなー。絶対に新しいアカウント作ったらあかんで。絶対やで。"
tokenRevoked: "トークンが無効やで"
tokenRevokedDescription: "ログイントークンが失効しとるで。もっかいログインしてもろてもええか?"
accountDeleted: "アカウントは削除されとるで"
accountDeletedDescription: "このアカウントは削除されとるで。"
menu: "メニュー"
divider: "分割線"
addItem: "項目を追加"
@@ -564,7 +573,7 @@ description: "説明"
describeFile: "キャプションを付ける"
enterFileDescription: "キャプションを入力"
author: "作者"
leaveConfirm: "未保存の変更があるで!ほかしてええか?"
leaveConfirm: "あんた、いじったのにまだ保存してないで!ほかしてええか?"
manage: "管理"
plugins: "プラグイン"
preferencesBackups: "設定のバックアップ"
@@ -585,7 +594,6 @@ tokenRequested: "アカウントへのアクセス許してやったらどうや
pluginTokenRequestedDescription: "このプラグインはここで設定した権限を使えるようになるで。"
notificationType: "通知の種類"
edit: "編集"
useStarForReactionFallback: "リアクションがようわからん場合、★を使う"
emailServer: "メールサーバー"
enableEmail: "メール配信を受け取る"
emailConfigInfo: "メールアドレスの確認とかパスワードリセットの時に使うで"
@@ -598,12 +606,12 @@ smtpUser: "ユーザー名"
smtpPass: "パスワード"
emptyToDisableSmtpAuth: "ユーザー名とパスワードになんも入れんかったら、SMTP認証を無効化するで"
smtpSecure: "SMTP 接続に暗黙的なSSL/TLSを使用する"
smtpSecureInfo: "STARTTLS使っとる時はオフにするで。"
smtpSecureInfo: "STARTTLS使っとる時はオフにしてや。"
testEmail: "配信テスト"
wordMute: "ワードミュート"
regexpError: "正規表現エラー"
regexpErrorDescription: "{tab}ワードミュートの{line}行目の正規表現にエラーが出てきたで:"
instanceMute: "インスタンスミュート"
instanceMute: "サーバーミュート"
userSaysSomething: "{name}が何か言うとるわ"
makeActive: "使うで"
display: "表示"
@@ -622,7 +630,7 @@ useGlobalSettingDesc: "オンにすると、アカウントの通知設定が使
other: "その他"
regenerateLoginToken: "ログイントークンを再生成"
regenerateLoginTokenDescription: "ログインに使われる内部トークンをもっかい作るで。いつもならこれをやる必要はないで。もっかい作ると、全部のデバイスでログアウトされるで気ぃつけてなー。"
setMultipleBySeparatingWithSpace: "スペースで区切って複数設定できるで。"
setMultipleBySeparatingWithSpace: "スペースで区切って何個でも設定できるで。"
fileIdOrUrl: "ファイルIDかURL"
behavior: "動作"
sample: "サンプル"
@@ -634,7 +642,7 @@ abuseReported: "無事内容が送信されたみたいやで。おおきに〜
reporter: "通報者"
reporteeOrigin: "通報先"
reporterOrigin: "通報元"
forwardReport: "リモートインスタンスに通報を転送するで"
forwardReport: "リモートサーバーに通報を転送するで"
forwardReportIsAnonymous: "リモートインスタンスからはあんたの情報は見れへんくって、匿名のシステムアカウントとして表示されるで。"
send: "送信"
abuseMarkAsResolved: "対応したで"
@@ -642,7 +650,7 @@ openInNewTab: "新しいタブで開く"
openInSideView: "サイドビューで開く"
defaultNavigationBehaviour: "デフォルトのナビゲーション"
editTheseSettingsMayBreakAccount: "このへんの設定をようわからんままイジるとアカウントが壊れて使えんくなるかも知れへんで?"
instanceTicker: "ノートのインスタンス情報"
instanceTicker: "ノートのサーバー情報"
waitingFor: "{x}を待っとるで"
random: "ランダム"
system: "システム"
@@ -653,7 +661,7 @@ createNew: "新しく作るで"
optional: "任意"
createNewClip: "新しいクリップを作るで"
unclip: "クリップ解除するで"
confirmToUnclipAlreadyClippedNote: "このノートはすでにクリップ「{name}」に含まれとるで。ノートをこのクリップから除外したる"
confirmToUnclipAlreadyClippedNote: "このノートはすでにクリップ「{name}」に含まれとるで。ノートをこのクリップから除外しよか"
public: "パブリック"
i18nInfo: "Misskeyは有志によっていろんな言語に翻訳されとるで。{link}で翻訳に協力したってやー。"
manageAccessTokens: "アクセストークンの管理"
@@ -670,15 +678,15 @@ receivedReactionsCount: "リアクションされた数"
pollVotesCount: "アンケートに投票した数"
pollVotedCount: "アンケートに投票された数"
yes: "ええで"
no: "あかん"
no: "あかん"
driveFilesCount: "ドライブのファイル数"
driveUsage: "ドライブ使用量やで"
noCrawle: "クローラーによるインデックスを拒否するで"
noCrawleDescription: "検索エンジンにあんたのユーザーページ、ート、Pagesとかのコンテンツを登録(インデックス)せぇへんように頼むで。"
noCrawleDescription: "検索エンジンにあんたのユーザーページ、ート、Pagesとかのコンテンツを登録(インデックス)せんように頼むで。邪魔すんねんやったら帰って〜。"
lockedAccountInfo: "フォローを承認制にしとっても、ノートの公開範囲を「フォロワー」にせぇへん限り、誰でもあんたのノートを見れるで。"
alwaysMarkSensitive: "デフォルトでメディアを閲覧注意にするで"
loadRawImages: "添付画像のサムネイルをオリジナル画質にするで"
disableShowingAnimatedImages: "アニメーション画像を再生しやへんで"
disableShowingAnimatedImages: "アニメーション画像を再生せんとくで"
verificationEmailSent: "無事確認のメールを送れたで。メールに書いてあるリンクにアクセスして、設定を完了してなー。"
notSet: "未設定"
emailVerified: "メールアドレスは確認されたで"
@@ -688,14 +696,14 @@ pageLikedCount: "Pageにええやんと思ってくれた数"
contact: "連絡先"
useSystemFont: "システムのデフォルトのフォントを使うで"
clips: "クリップ"
experimentalFeatures: "実験的機能やで"
experimentalFeatures: "おためし機能やで"
developer: "開発者やで"
makeExplorable: "アカウントを見つけやすくするで"
makeExplorableDescription: "オフにすると、「みつける」にアカウントが載らんくなるで。"
showGapBetweenNotesInTimeline: "タイムラインのノートを離して表示するで"
duplicate: "複製"
left: "左"
center: "中"
center: "真ん中"
wide: "広い"
narrow: "狭い"
reloadToApplySetting: "設定はページリロード後に反映されるで。今リロードしとくか?"
@@ -706,7 +714,7 @@ onlineUsersCount: "{n}人が起きとるで"
nUsers: "{n}ユーザー"
nNotes: "{n}ノート"
sendErrorReports: "エラーリポートを送る"
sendErrorReportsDescription: "オンにしたら、なんか変なことが起きたときにエラーの詳細がMisskeyに共有されて、ソフトウェアの品質向上に役立てられるんや。エラー情報には、OSのバージョン、ブラウザの種類、行動履歴なが含まれるで。"
sendErrorReportsDescription: "オンにしたら、変なことが起きたときにエラーの詳細がMisskeyに送られて、ソフトウェアの品質向上に使えるようになるで。エラー情報には、OSのバージョン、ブラウザの種類、行動履歴なんかが含まれるで。"
myTheme: "マイテーマ"
backgroundColor: "背景"
accentColor: "アクセント"
@@ -847,11 +855,13 @@ instanceDefaultLightTheme: "インスタンスの最初の明るいテーマ"
instanceDefaultDarkTheme: "インスタンスの最初の暗いテーマ"
instanceDefaultThemeDescription: "オブジェクト形式のテーマコードを記入するで。"
mutePeriod: "ミュートする期間"
period: "期限"
indefinitely: "無期限"
tenMinutes: "10分"
oneHour: "1時間"
oneDay: "1日"
oneWeek: "1週間"
oneMonth: "1ヶ月"
reflectMayTakeTime: "反映されるまで時間がかかることがあるで"
failedToFetchAccountInformation: "アカウントの取得に失敗したみたいや…"
rateLimitExceeded: "レート制限が超えたみたいやで"
@@ -873,7 +883,7 @@ isSystemAccount: "システムが自動で作成・管理しとるアカウン
typeToConfirm: "この操作をやるんなら {x} と入力してなー"
deleteAccount: "アカウント削除するで"
document: "ドキュメント"
numberOfPageCache: "ページキャッシュ数やで"
numberOfPageCache: "ページ、どんだけキャッシュすんの?"
numberOfPageCacheDescription: "増やすと使いやすくなる、負荷とメモリ使用量が増えてくで。一長一短やな。"
logoutConfirm: "ログアウトしまっか?"
lastActiveDate: "最後に使った日時"
@@ -906,7 +916,7 @@ subscribePushNotification: "プッシュ通知をオンにするで"
unsubscribePushNotification: "プッシュ通知を止めるで"
pushNotificationAlreadySubscribed: "プッシュ通知はオンになってるで"
pushNotificationNotSupported: "ブラウザかインスタンスがプッシュ通知に対応してないみたいやで。"
sendPushNotificationReadMessage: "通知やメッセージが既読ったらプッシュ通知を消すで"
sendPushNotificationReadMessage: "通知やメッセージが既読になったらプッシュ通知を消すで"
sendPushNotificationReadMessageCaption: "「{emptyPushNotificationMessage}」っていう表示が一瞬表示されるようになるで。端末の電池使用量が増える可能性があるで。"
windowMaximize: "最大化"
windowRestore: "元に戻す"
@@ -943,7 +953,7 @@ thisPostMayBeAnnoying: "この投稿は迷惑かもしらんで。"
thisPostMayBeAnnoyingHome: "ホームに投稿"
thisPostMayBeAnnoyingCancel: "やめとく"
thisPostMayBeAnnoyingIgnore: "このまま投稿"
collapseRenotes: "見たことあるRenoteは省略やで"
collapseRenotes: "見たことあるRenoteは飛ばして表示するで"
internalServerError: "サーバー内部エラー"
internalServerErrorDescription: "サーバー内部でよう分からんエラーやわ"
copyErrorInfo: "エラー情報をコピー"
@@ -951,6 +961,28 @@ joinThisServer: "このサーバーに登録するわ"
exploreOtherServers: "他のサーバー見てみる"
letsLookAtTimeline: "タイムライン見てみーや"
disableFederationWarn: "連合が無効になっとるで。無効にしても投稿は非公開ってわけちゃうねん。大体の場合はこのオプションを有効にする必要は別にないで。"
invitationRequiredToRegister: "今このサーバー招待制になってもうてんねん。招待コードを持っとるんやったら登録できるで。"
emailNotSupported: "このサーバーはメール配信がサポートされてへんみたいやわ"
postToTheChannel: "チャンネルに投稿"
cannotBeChangedLater: "後からは変えられへんで。"
reactionAcceptance: "リアクションの受け入れ"
likeOnly: "いいねだけ"
likeOnlyForRemote: "リモートからはいいねだけな"
rolesAssignedToMe: "自分に割り当てられたロール"
resetPasswordConfirm: "パスワード作り直すんでええな?"
sensitiveWords: "けったいな単語"
sensitiveWordsDescription: "設定した単語が入っとるノートの公開範囲をホームにしたるわ。改行で区切ったら複数設定できるで。"
notesSearchNotAvailable: "ノート検索は使われへんで。"
license: "ライセンス"
unfavoriteConfirm: "ほんまに気に入らんの?"
myClips: "自分のクリップ"
drivecleaner: "ドライブキレイキレイ"
retryAllQueuesNow: "キューを全部もっかいやり直す"
retryAllQueuesConfirmTitle: "もっかいやってみるか?"
retryAllQueuesConfirmText: "一時的にサーバー重なるかもしれへんで。"
enableChartsForRemoteUser: "リモートユーザーのチャートを作る"
enableChartsForFederatedInstances: "リモートサーバーのチャートを作る"
showClipButtonInNoteFooter: "ノートのアクションにクリップを追加"
_achievements:
earnedAt: "貰った日ぃ"
_types:
@@ -968,7 +1000,7 @@ _achievements:
title: "ノートの生駒山"
description: "ートを500回投稿した"
_notes1000:
title: "ノートの山"
title: "ノートの六甲山"
description: "ートを1,000回投稿した"
_notes5000:
title: "箕面の滝からノート"
@@ -1068,7 +1100,7 @@ _achievements:
description: "プロフィールを設定した"
_markedAsCat:
title: "吾輩は猫やねん"
description: "アカウントCatになってもうた"
description: "アカウントCatにしたった"
flavor: "名前はまだないねん。"
_following1:
title: "はじめてのフォロー"
@@ -1210,6 +1242,8 @@ _role:
iconUrl: "アイコン画像のURL"
asBadge: "バッジとして見せる"
descriptionOfAsBadge: "オンにすると、ユーザー名の横んとこにロールのアイコンが表示されるで。"
displayOrder: "表示順"
descriptionOfDisplayOrder: "数がでかいほど、UI上で先に表示されるで。"
canEditMembersByModerator: "モデレーターのメンバー編集を許可"
descriptionOfCanEditMembersByModerator: "オンにすると、管理者に加えてモデレーターもこのロールへユーザーをアサイン/アサイン解除できるようになるで。オフにすると管理者のみが行えるで。"
priority: "優先度"
@@ -1235,6 +1269,7 @@ _role:
rateLimitFactor: "レートリミット"
descriptionOfRateLimitFactor: "ちっちゃいほど制限が緩くなって、大きいほど制限されるで。"
canHideAds: "広告を表示させへん"
canSearchNotes: "ノート検索を使わすかどうか"
_condition:
isLocal: "ローカルユーザー"
isRemote: "リモートユーザー"
@@ -1244,6 +1279,8 @@ _role:
followersMoreThanOrEq: "フォロワー数が~以上"
followingLessThanOrEq: "フォロー数が~以下"
followingMoreThanOrEq: "フォロー数が~以上"
notesLessThanOrEq: "投稿数が~以下しかない"
notesMoreThanOrEq: "投稿を~以上しとる"
and: "~かつ~"
or: "~または~"
not: "~ではない"
@@ -1369,7 +1406,7 @@ _wordMute:
mutedNotes: "ミュートされたノート"
_instanceMute:
instanceMuteDescription: "ミュートしたインスタンスのユーザーへの返信を含めて、設定したインスタンスの全てのートとRenoteをミュートにするで。"
instanceMuteDescription2: "改行で区切って設定するで"
instanceMuteDescription2: "改行で区切って設定するんやで"
title: "設定したインスタンスのノートを隠すで。"
heading: "ミュートするインスタンス"
_theme:
@@ -1456,7 +1493,7 @@ _sfx:
channel: "チャンネル通知"
_ago:
future: "未来"
justNow: "たった今"
justNow: "ついさっき"
secondsAgo: "{n}秒前"
minutesAgo: "{n}分前"
hoursAgo: "{n}時間前"
@@ -1579,7 +1616,7 @@ _weekday:
saturday: "土曜日"
_widgets:
profile: "プロフィール"
instanceInfo: "インスタンス情報"
instanceInfo: "サーバー情報"
memo: "付箋"
notifications: "通知"
timeline: "タイムライン"
@@ -1682,7 +1719,7 @@ _charts:
apRequest: "リクエスト"
usersIncDec: "ユーザーの増減"
usersTotal: "ユーザーの合計"
activeUsers: "アクティブユーザー数"
activeUsers: "いまおるユーザー数"
notesIncDec: "ノートの増減"
localNotesIncDec: "ローカルのノートの増減"
remoteNotesIncDec: "リモートのノートの増減"
@@ -1836,3 +1873,24 @@ _deck:
_dialog:
charactersExceeded: "最大の文字数を上回っとるで!今は {current} / 最大でも {max}"
charactersBelow: "最小の文字数を下回っとるで!今は {current} / 最低でも {min}"
_disabledTimeline:
title: "使われへんタイムライン"
description: "あんたの今のロールやったら、このタイムラインは使われへんで。"
_drivecleaner:
orderBySizeDesc: "サイズのでかい順"
orderByCreatedAtAsc: "追加日の古い順"
_webhookSettings:
createWebhook: "Webhookをつくる"
name: "名前"
secret: "シークレット"
events: "Webhookを投げるタイミング"
active: "有効"
_events:
follow: "フォローしたとき~!"
followed: "フォローもらったとき~!"
note: "ノートを投稿したとき~!"
reply: "返信があるとき~!"
renote: "Renoteされるとき"
reaction: "リアクションがあるとき~!"
mention: "メンションがあるとき~!"

View File

@@ -1 +1,2 @@
---

View File

@@ -103,3 +103,4 @@ _deck:
_columns:
notifications: "Ilɣuyen"
list: "Tibdarin"

View File

@@ -83,3 +83,4 @@ _deck:
notifications: "ಅಧಿಸೂಚನೆಗಳು"
tl: "ಸಮಯಸಾಲು"
mentions: "ಹೆಸರಿಸಿದ"

View File

@@ -2,7 +2,7 @@
_lang_: "한국어"
headlineMisskey: "노트로 연결되는 네트워크"
introMisskey: "환영합니다! Misskey는 오픈 소스 분산형 마이크로 블로그 서비스입니다.\n'노트'를 작성해서 지금 일어나고 있는 일을 공유하거나, 당신만의 이야기를 모두에게 발신하세요📡\n'리액션' 기능으로 친구의 노트에 총알같이 반응을 추가할 수도 있습니다👍\n새로운 세계를 탐험해 보세요🚀"
poweredByMisskeyDescription: "{name}은(는) 오픈소스 플랫폼<b>Misskey</b>를 사용한 서비스(Misskey 인스턴스라고 불립니다) 중 하나입니다."
poweredByMisskeyDescription: "{name}은(는) 오픈소스 플랫폼<b>Misskey</b>를 사용한 서 중 하나입니다."
monthAndDay: "{month}월 {day}일"
search: "검색"
notifications: "알림"
@@ -18,7 +18,7 @@ enterUsername: "유저명 입력"
renotedBy: "{user}님의 리노트"
noNotes: "노트가 없습니다"
noNotifications: "표시할 알림이 없습니다"
instance: "인스턴스"
instance: "서버"
settings: "설정"
basicSettings: "기본 설정"
otherSettings: "기타 설정"
@@ -122,6 +122,8 @@ unmarkAsSensitive: "열람주의 해제"
enterFileName: "파일명을 입력"
mute: "뮤트"
unmute: "뮤트 해제"
renoteMute: "리노트를 뮤트"
renoteUnmute: "리노트 뮤트 해제"
block: "차단"
unblock: "차단 해제"
suspend: "정지"
@@ -153,6 +155,7 @@ flagShowTimelineReplies: "타임라인에 노트의 답글을 표시하기"
flagShowTimelineRepliesDescription: "이 설정을 활성화하면 타임라인에 다른 유저 간의 답글을 표시합니다."
autoAcceptFollowed: "팔로우 중인 유저로부터의 팔로우 요청을 자동 수락"
addAccount: "계정 추가"
reloadAccountsList: "계정 리스트 정보 갱신"
loginFailed: "로그인에 실패했습니다"
showOnRemote: "리모트에서 보기"
general: "일반"
@@ -163,13 +166,13 @@ searchWith: "검색: {q}"
youHaveNoLists: "리스트가 없습니다"
followConfirm: "{name}님을 팔로우 하시겠습니까?"
proxyAccount: "프록시 계정"
proxyAccountDescription: "프록시 계정은 특정 조건 하에서 유저의 리모트 팔로우를 대행하는 계정입니다. 예를 들면, 유저가 리모트 유저를 리스트에 넣었을 때, 리스트에 들어간 유저를 아무도 팔로우한 적이 없다면 액티비티가 인스턴스로 배달되지 않기 때문에, 대신 프록시 계정이 해당 유저를 팔로우하도록 합니다."
proxyAccountDescription: "프록시 계정은 특정 조건 하에서 유저의 리모트 팔로우를 대행하는 계정입니다. 예를 들면, 유저가 리모트 유저를 리스트에 넣었을 때, 리스트에 들어간 유저를 아무도 팔로우한 적이 없다면 액티비티가 서버로 배달되지 않기 때문에, 대신 프록시 계정이 해당 유저를 팔로우하도록 합니다."
host: "호스트"
selectUser: "유저 선택"
recipient: "수신인"
annotation: "내용에 대한 주석"
federation: "연합"
instances: "인스턴스"
instances: "서버"
registeredAt: "등록 날짜"
latestRequestReceivedAt: "마지막으로 요청을 받은 시간"
latestStatus: "마지막 상태"
@@ -178,7 +181,7 @@ charts: "차트"
perHour: "1시간마다"
perDay: "1일마다"
stopActivityDelivery: "액티비티 보내지 않기"
blockThisInstance: "이 인스턴스를 차단"
blockThisInstance: "이 서버를 차단"
operations: "작업"
software: "소프트웨어"
version: "버전"
@@ -189,15 +192,15 @@ jobQueue: "작업 대기열"
cpuAndMemory: "CPU와 메모리"
network: "네트워크"
disk: "디스크"
instanceInfo: "인스턴스 정보"
instanceInfo: "서버 정보"
statistics: "통계"
clearQueue: "대기열 비우기"
clearQueueConfirmTitle: "대기열을 비우시겠습니까?"
clearQueueConfirmText: "대기열에 남아 있는 노트는 더이상 연합되지 않습니다. 보통의 경우 이 작업은 필요하지 않습니다."
clearCachedFiles: "캐시 비우기"
clearCachedFilesConfirm: "캐시된 리모트 파일을 모두 삭제하시겠습니까?"
blockedInstances: "차단된 인스턴스"
blockedInstancesDescription: "차단하려는 인스턴스의 호스트 이름을 줄바꿈으로 구분하여 설정합니다. 차단된 인스턴스는 이 인스턴스와 통신할 수 없게 됩니다."
blockedInstances: "차단된 서버"
blockedInstancesDescription: "차단하려는 서버의 호스트 이름을 줄바꿈으로 구분하여 설정합니다. 차단된 인스턴스는 이 인스턴스와 통신할 수 없게 됩니다."
muteAndBlock: "뮤트 및 차단"
mutedUsers: "뮤트한 유저"
blockedUsers: "차단한 유저"
@@ -220,9 +223,9 @@ all: "전체"
subscribing: "구독 중"
publishing: "배포 중"
notResponding: "응답 없음"
instanceFollowing: "인스턴스의 팔로잉"
instanceFollowers: "인스턴스의 팔로워"
instanceUsers: "인스턴스의 유저"
instanceFollowing: "서버의 팔로잉"
instanceFollowers: "서버의 팔로워"
instanceUsers: "서버의 유저"
changePassword: "비밀번호 변경"
security: "보안"
retypedNotMatch: "입력이 일치하지 않습니다."
@@ -314,8 +317,8 @@ unwatch: "지켜보기 해제"
accept: "허가"
reject: "거부"
normal: "정상"
instanceName: "인스턴스 이름"
instanceDescription: "인스턴스 소개"
instanceName: "서버 이름"
instanceDescription: "서버 소개"
maintainerName: "관리자 이름"
maintainerEmail: "관리자 이메일"
tosUrl: "이용약관 URL"
@@ -345,7 +348,7 @@ basicInfo: "기본 정보"
pinnedUsers: "고정된 유저"
pinnedUsersDescription: "\"발견하기\" 페이지 등에 고정하고 싶은 유저를 한 줄에 한 명씩 적습니다."
pinnedPages: "고정한 페이지"
pinnedPagesDescription: "인스턴스의 대문에 고정하고 싶은 페이지의 경로를 한 줄에 하나씩 적습니다."
pinnedPagesDescription: "서버의 대문에 고정하고 싶은 페이지의 경로를 한 줄에 하나씩 적습니다."
pinnedClipId: "고정할 클립의 ID"
pinnedNotes: "고정해놓은 노트"
hcaptcha: "hCaptcha"
@@ -393,13 +396,19 @@ about: "정보"
aboutMisskey: "Misskey에 대하여"
administrator: "관리자"
token: "토큰"
2fa: "2단계 인증"
totp: "인증 앱"
totpDescription: "인증 앱을 사용하여 일회성 비밀번호 입력"
moderator: "모더레이터"
moderation: "모더레이션"
nUsersMentioned: "{n}명이 언급함"
securityKeyAndPasskey: "보안 키 또는 패스 키"
securityKey: "보안 키"
lastUsed: "마지막 사용"
lastUsedAt: "마지막 사용: {t}"
unregister: "등록 해제"
passwordLessLogin: "비밀번호 없이 로그인"
passwordLessLoginDescription: "비밀번호를 사용하지 않고 보안 키 또는 패스 키 등으로만 로그인합니다."
resetPassword: "비밀번호 재설정"
newPasswordIs: "새로운 비밀번호는 \"{password}\" 입니다"
reduceUiAnimation: "UI의 애니메이션을 줄이기"
@@ -451,6 +460,7 @@ aboutX: "{x}에 대하여"
emojiStyle: "이모지 스타일"
native: "네이티브"
disableDrawer: "드로어 메뉴를 사용하지 않기"
showNoteActionsOnlyHover: "노트 액션 버튼을 마우스를 올렸을 때에만 표시"
noHistory: "기록이 없습니다"
signinHistory: "로그인 기록"
enableAdvancedMfm: "고급 MFM을 활성화"
@@ -499,6 +509,7 @@ objectStorageSetPublicRead: "업로드할 때 'public-read'를 설정하기"
serverLogs: "서버 로그"
deleteAll: "모두 삭제"
showFixedPostForm: "타임라인 상단에 글 작성란을 표시"
showFixedPostFormInChannel: "채널 타임라인 상단에 글 작성란을 표시"
newNoteRecived: "새 노트가 있습니다"
sounds: "소리"
sound: "소리"
@@ -531,11 +542,13 @@ updateRemoteUser: "리모트 유저 정보 갱신"
deleteAllFiles: "모든 파일 삭제"
deleteAllFilesConfirm: "모든 파일을 삭제하시겠습니까?"
removeAllFollowing: "모든 팔로잉 해제"
removeAllFollowingDescription: "{host}(으)로부터 모든 팔로잉을 해제합니다. 해당 인스턴스가 더 이상 존재하지 않게 된 경우 등에 실행해 주세요."
removeAllFollowingDescription: "{host}(으)로부터 모든 팔로잉을 해제합니다. 해당 서버가 더 이상 존재하지 않게 된 경우 등에 실행해 주세요."
userSuspended: "이 계정은 정지된 상태입니다."
userSilenced: "이 계정은 사일런스된 상태입니다."
yourAccountSuspendedTitle: "계정이 정지되었습니다"
yourAccountSuspendedDescription: "이 계정은 서버의 이용 약관을 위반하거나, 기타 다른 이유로 인해 정지되었습니다. 자세한 사항은 관리자에게 문의해 주십시오. 계정을 새로 생성하지 마십시오."
accountDeleted: "계정이 정지되었습니다"
accountDeletedDescription: "이 계정이 삭제되었습니다."
menu: "메뉴"
divider: "구분선"
addItem: "항목 추가"
@@ -579,7 +592,6 @@ tokenRequested: "계정 접근 허용"
pluginTokenRequestedDescription: "이 플러그인은 여기서 설정한 권한을 사용할 수 있게 됩니다."
notificationType: "알림 유형"
edit: "편집"
useStarForReactionFallback: "알 수 없는 리액션 이모지 대신 ★ 사용"
emailServer: "메일 서버"
enableEmail: "이메일 송신 기능 활성화"
emailConfigInfo: "가입 시 메일 주소 확인이나 비밀번호 초기화 시에 사용합니다."
@@ -597,7 +609,7 @@ testEmail: "이메일 전송 테스트"
wordMute: "단어 뮤트"
regexpError: "정규 표현식 오류"
regexpErrorDescription: "{tab}단어 뮤트 {line}행의 정규 표현식에 오류가 발생했습니다:"
instanceMute: "인스턴스 뮤트"
instanceMute: "서버 뮤트"
userSaysSomething: "{name}님이 무언가를 말했습니다"
makeActive: "활성화"
display: "표시"
@@ -628,15 +640,15 @@ abuseReported: "신고를 보냈습니다. 신고해 주셔서 감사합니다."
reporter: "신고자"
reporteeOrigin: "피신고자"
reporterOrigin: "신고자"
forwardReport: "리모트 인스턴스에도 신고 내용 보내기"
forwardReportIsAnonymous: "리모트 인스턴스에서는 나의 정보를 볼 수 없으며, 익명의 시스템 계정으로 표시됩니다."
forwardReport: "리모트 서버에도 신고 내용 보내기"
forwardReportIsAnonymous: "리모트 서버에서는 나의 정보를 볼 수 없으며, 익명의 시스템 계정으로 표시됩니다."
send: "전송"
abuseMarkAsResolved: "해결됨으로 표시"
openInNewTab: "새 탭에서 열기"
openInSideView: "사이드뷰로 열기"
defaultNavigationBehaviour: "기본 탐색 동작"
editTheseSettingsMayBreakAccount: "이 설정을 변경하면 계정이 손상될 수 있습니다."
instanceTicker: "노트의 인스턴스 정보"
instanceTicker: "노트의 서버 정보"
waitingFor: "{x}을(를) 기다리고 있습니다"
random: "랜덤"
system: "시스템"
@@ -725,7 +737,7 @@ capacity: "용량"
inUse: "사용중"
editCode: "코드 수정"
apply: "적용"
receiveAnnouncementFromInstance: "이 인스턴스의 알림을 이메일로 수신할게요"
receiveAnnouncementFromInstance: "이 서버의 알림을 이메일로 수신할게요"
emailNotification: "메일 알림"
publish: "게시"
inChannelSearch: "채널에서 검색"
@@ -753,7 +765,7 @@ active: "최근에 활동함"
offline: "오프라인"
notRecommended: "추천하지 않음"
botProtection: "Bot 방어"
instanceBlocking: "인스턴스 차단"
instanceBlocking: "서버 차단"
selectAccount: "계정 선택"
switchAccount: "계정 바꾸기"
enabled: "활성화"
@@ -773,6 +785,7 @@ popularPosts: "인기 포스트"
shareWithNote: "노트로 공유"
ads: "광고"
expiration: "기한"
startingperiod: "시작 기간"
memo: "메모"
priority: "우선순위"
high: "높음"
@@ -805,6 +818,7 @@ lastCommunication: "마지막 통신"
resolved: "해결됨"
unresolved: "해결되지 않음"
breakFollow: "팔로워 해제"
breakFollowConfirm: "팔로우를 해제하시겠습니까?"
itsOn: "켜짐"
itsOff: "꺼짐"
emailRequiredForSignup: "가입할 때 이메일 주소 입력을 필수로 하기"
@@ -835,15 +849,17 @@ themeColor: "테마 컬러"
size: "크기"
numberOfColumn: "한 줄에 보일 리액션의 수"
searchByGoogle: "검색"
instanceDefaultLightTheme: "인스턴스 기본 라이트 테마"
instanceDefaultDarkTheme: "인스턴스 기본 다크 테마"
instanceDefaultLightTheme: "서버 기본 라이트 테마"
instanceDefaultDarkTheme: "서버 기본 다크 테마"
instanceDefaultThemeDescription: "객체 형식의 테마 코드를 입력해 주세요."
mutePeriod: "뮤트할 기간"
period: "투표 기한"
indefinitely: "무기한"
tenMinutes: "10분"
oneHour: "1시간"
oneDay: "1일"
oneWeek: "일주일"
oneMonth: "1개월"
reflectMayTakeTime: "반영되기까지 시간이 걸릴 수 있습니다."
failedToFetchAccountInformation: "계정 정보를 가져오지 못했습니다"
rateLimitExceeded: "요청 제한 횟수를 초과하였습니다"
@@ -887,7 +903,7 @@ cannotUploadBecauseInappropriate: "이 파일은 부적절한 내용을 포함
cannotUploadBecauseNoFreeSpace: "드라이브 용량이 부족하여 업로드할 수 없습니다."
beta: "베타"
enableAutoSensitive: "자동 NSFW 탐지"
enableAutoSensitiveDescription: "이용 가능할 경우 기계학습을 통해 자동으로 미디어 NSFW를 설정합니다. 이 기능을 해제하더라도, 인스턴스 정책에 따라 자동으로 설정될 수 있습니다."
enableAutoSensitiveDescription: "이용 가능할 경우 기계학습을 통해 자동으로 미디어 NSFW를 설정합니다. 이 기능을 해제하더라도, 서버 정책에 따라 자동으로 설정될 수 있습니다."
activeEmailValidationDescription: "유저가 입력한 메일 주소가 일회용 메일인지, 실제로 통신할 수 있는 지 엄격하게 검사합니다. 해제할 경우 이메일 형식에 대해서만 검사합니다."
navbar: "내비게이션 바"
shuffle: "셔플"
@@ -897,7 +913,7 @@ pushNotification: "푸시 알림"
subscribePushNotification: "푸시 알림 켜기"
unsubscribePushNotification: "푸시 알림 끄기"
pushNotificationAlreadySubscribed: "푸시 알림이 이미 켜져 있습니다"
pushNotificationNotSupported: "브라우저나 인스턴스에서 푸시 알림이 지원되지 않습니다"
pushNotificationNotSupported: "브라우저나 서버에서 푸시 알림이 지원되지 않습니다"
sendPushNotificationReadMessage: "푸시 알림이나 메시지를 읽은 뒤 푸시 알림을 삭제"
sendPushNotificationReadMessageCaption: "「{emptyPushNotificationMessage}」이라는 알림이 잠깐 표시됩니다. 기기의 전력 소비량이 증가할 수 있습니다."
windowMaximize: "최대화"
@@ -939,6 +955,14 @@ collapseRenotes: "이미 본 리노트를 간략화하기"
internalServerError: "내부 서버 오류"
internalServerErrorDescription: "내부 서버에서 예기치 않은 오류가 발생했습니다."
copyErrorInfo: "오류 정보 복사"
joinThisServer: "이 서버에 가입"
exploreOtherServers: "다른 서버 둘러보기"
letsLookAtTimeline: "타임라인 구경하기"
disableFederationWarn: "연합이 비활성화됩니다. 비활성화해도 게시물이 비공개가 되지는 않습니다. 대부분의 경우 이 옵션을 활성화할 필요가 없습니다."
invitationRequiredToRegister: "현재 이 서버는 비공개입니다. 회원가입을 하시려면 초대 코드가 필요합니다."
emailNotSupported: "이 서버에서는 메일 전송을 지원하지 않습니다"
postToTheChannel: "채널에 게시하기"
cannotBeChangedLater: "나중에 변경할 수 없습니다."
_achievements:
earnedAt: "달성 일시"
_types:
@@ -1129,7 +1153,7 @@ _achievements:
description: "1분 사이에 홈 타임라인에 노트가 20개 넘게 생성되었습니다"
_viewInstanceChart:
title: "애널리스트"
description: "인스턴스의 차트를 열었습니다"
description: "서버의 차트를 열었습니다"
_outputHelloWorldOnScratchpad:
title: "Hello, world!"
description: "스크래치패드에서 hello world를 출력했습니다"
@@ -1166,7 +1190,7 @@ _achievements:
_loggedInOnNewYearsDay:
title: "새해 복 많이 받으세요"
description: "새해 첫 날에 로그인했습니다"
flavor: "올해에도 저희 인스턴스에 관심을 가져 주셔서 감사합니다"
flavor: "올해에도 저희 서버에 관심을 가져 주셔서 감사합니다"
_cookieClicked:
title: "쿠키를 클릭하는 게임"
description: "쿠키를 클릭했습니다"
@@ -1181,7 +1205,7 @@ _role:
name: "역할 이름"
description: "역할 설명"
permission: "역할 권한"
descriptionOfPermission: "<b>모더레이터</b>는 기본적인 중재와 관련된 작업을 수행할 수 있습니다.\n<b>관리자</b>는 인스턴스의 모든 설정을 변경할 수 있습니다."
descriptionOfPermission: "<b>모더레이터</b>는 기본적인 중재와 관련된 작업을 수행할 수 있습니다.\n<b>관리자</b>는 서버의 모든 설정을 변경할 수 있습니다."
assignTarget: "할당 대상"
descriptionOfAssignTarget: "<b>수동</b>을 선택하면 누가 이 역할에 포함되는지를 수동으로 관리할 수 있습니다.\n<b>조건부</b>를 선택하면 조건을 설정해 일치하는 사용자를 자동으로 포함되게 할 수 있습니다."
manual: "수동"
@@ -1209,7 +1233,7 @@ _role:
gtlAvailable: "글로벌 타임라인 보이기"
ltlAvailable: "로컬 타임라인 보이기"
canPublicNote: "공개 노트 허용"
canInvite: "인스턴스 초대 코드 발행"
canInvite: "서버 초대 코드 발행"
canManageCustomEmojis: "커스텀 이모지 관리"
driveCapacity: "드라이브 용량"
pinMax: "고정할 수 있는 노트 수"
@@ -1271,7 +1295,7 @@ _ad:
_forgotPassword:
enterEmail: "여기에 계정에 등록한 메일 주소를 입력해 주세요. 입력한 메일 주소로 비밀번호 재설정 링크를 발송합니다."
ifNoEmail: "메일 주소를 등록하지 않은 경우, 관리자에 문의해 주십시오."
contactAdmin: "이 인스턴스에서는 메일 기능이 지원되지 않습니다. 비밀번호를 재설정하려면 관리자에게 문의해 주십시오."
contactAdmin: "이 서버에서는 메일 기능이 지원되지 않습니다. 비밀번호를 재설정하려면 관리자에게 문의해 주십시오."
_gallery:
my: "내 갤러리"
liked: "좋아요 한 갤러리"
@@ -1356,10 +1380,10 @@ _wordMute:
hard: "보다 높은 수준"
mutedNotes: "뮤트된 노트"
_instanceMute:
instanceMuteDescription: "뮤트한 인스턴스에서 오는 답글을 포함한 모든 노트와 Renote를 뮤트합니다."
instanceMuteDescription: "뮤트한 서버에서 오는 답글을 포함한 모든 노트와 Renote를 뮤트합니다."
instanceMuteDescription2: "한 줄에 하나씩 입력해 주세요"
title: "지정한 인스턴스의 노트를 숨깁니다."
heading: "뮤트할 인스턴스"
title: "지정한 서버의 노트를 숨깁니다."
heading: "뮤트할 서버"
_theme:
explore: "테마 찾아보기"
install: "테마 설치"
@@ -1452,7 +1476,7 @@ _ago:
weeksAgo: "{n}주 전"
monthsAgo: "{n}개월 전"
yearsAgo: "{n}년 전"
invalid: "아무것도 없습니다"
invalid: "없음"
_time:
second: "초"
minute: "분"
@@ -1472,7 +1496,7 @@ _tutorial:
step4_1: "노트 작성을 끝내셨나요?"
step4_2: "당신의 노트가 타임라인에 표시되어 있다면 성공입니다."
step5_1: "이제, 다른 사람을 팔로우하여 타임라인을 활기차게 만들어보도록 합시다."
step5_2: "{featured}에서 이 인스턴스의 인기 노트를 보실 수 있습니다. {explore}에서는 인기 사용자를 찾을 수 있구요. 마음에 드는 사람을 골라 팔로우해 보세요!"
step5_2: "{featured}에서 이 서버의 인기 노트를 보실 수 있습니다. {explore}에서는 인기 사용자를 찾을 수 있구요. 마음에 드는 사람을 골라 팔로우해 보세요!"
step5_3: "다른 유저를 팔로우하려면 해당 유저의 아이콘을 클릭하여 프로필 페이지를 띄운 후, 팔로우 버튼을 눌러 주세요."
step5_4: "사용자에 따라 팔로우가 승인될 때까지 시간이 걸릴 수 있습니다."
step6_1: "타임라인에 다른 사용자의 노트가 나타난다면 성공입니다."
@@ -1486,14 +1510,29 @@ _tutorial:
step8_3: "알림 설정은 나중에도 변경할 수 있습니다."
_2fa:
alreadyRegistered: "이미 설정이 완료되었습니다."
registerTOTP: "인증 앱 설정 시작"
passwordToTOTP: "비밀번호를 입력하세요."
step1: "먼저, {a}나 {b}등의 인증 앱을 사용 중인 디바이스에 설치합니다."
step2: "그 후, 표시되어 있는 QR코드를 앱으로 스캔합니다."
step2Click: "QR 코드를 클릭하면 기기에 설치된 인증 앱에 등록할 수 있습니다."
step2Url: "데스크톱 앱에서는 다음 URL을 입력하세요:"
step3Title: "인증 코드 입력"
step3: "앱에 표시된 토큰을 입력하시면 완료됩니다."
step4: "다음 로그인부터는 토큰을 입력해야 합니다."
securityKeyNotSupported: "이 브라우저는 보안 키를 지원하지 않습니다."
registerTOTPBeforeKey: "보안 키 또는 패스키를 등록하려면 인증 앱을 등록하십시오."
securityKeyInfo: "FIDO2를 지원하는 하드웨어 보안 키 혹은 디바이스의 지문인식이나 화면잠금 PIN을 이용해서 로그인하도록 설정할 수 있습니다."
chromePasskeyNotSupported: "현재 Chrome의 패스키는 지원되지 않습니다."
registerSecurityKey: "보안 키 또는 패스키 등록"
securityKeyName: "키 이름 입력"
tapSecurityKey: "브라우저의 지시에 따라 보안 키 또는 패스키를 등록하여 주십시오"
removeKey: "보안 키를 삭제"
removeKeyConfirm: "{name} 을(를) 삭제하시겠습니까?"
renewTOTPCancel: "나중에"
whyTOTPOnlyRenew: "보안 키가 등록되어 있는 경우 인증 앱을 해제할 수 없습니다."
renewTOTP: "인증 앱 재설정"
renewTOTPConfirm: "기존에 등록되어 있던 인증 키는 사용하지 못하게 됩니다."
renewTOTPOk: "재설정"
renewTOTPCancel: "취소"
_permissions:
"read:account": "계정의 정보를 봅니다"
"write:account": "계정의 정보를 변경합니다"
@@ -1552,7 +1591,7 @@ _weekday:
saturday: "토요일"
_widgets:
profile: "프로필"
instanceInfo: "인스턴스 정보"
instanceInfo: "서버 정보"
memo: "스티커 메모"
notifications: "알림"
timeline: "타임라인"
@@ -1566,7 +1605,7 @@ _widgets:
digitalClock: "디지털 시계"
unixClock: "UNIX 시계"
federation: "연합"
instanceCloud: "인스턴스 구름"
instanceCloud: "서버 구름"
postForm: "글 입력란"
slideshow: "슬라이드 쇼"
button: "버튼"
@@ -1616,6 +1655,8 @@ _visibility:
followersDescription: "팔로워에게만 공개"
specified: "다이렉트"
specifiedDescription: "지정한 유저에게만 공개"
disableFederation: "연합에 보내지 않기"
disableFederationDescription: "다른 서버로 보내지 않습니다"
_postForm:
replyPlaceholder: "이 노트에 답글..."
quotePlaceholder: "이 노트를 인용..."
@@ -1771,6 +1812,7 @@ _notification:
pollEnded: "투표가 종료됨"
receiveFollowRequest: "팔로우 요청을 받았을 때"
followRequestAccepted: "팔로우 요청이 승인되었을 때"
achievementEarned: "도전 과제 획득"
app: "연동된 앱을 통한 알림"
_actions:
followBack: "팔로우"
@@ -1803,3 +1845,10 @@ _deck:
channel: "채널"
mentions: "받은 멘션"
direct: "다이렉트"
_dialog:
charactersExceeded: "최대 글자수를 초과하였습니다! 현재 {current} / 최대 {min}"
charactersBelow: "최소 글자수 미만입니다! 현재 {current} / 최소 {min}"
_webhookSettings:
name: "이름"
active: "활성화"

View File

@@ -168,7 +168,9 @@ done: "ສຳເລັດ"
processing: "ກຳລັງປະມວນຜົນ"
preview: "ສະແດງເປັນຕົວຢ່າງ"
default: "ຄ່າເລີ່ມຕົ້ນ"
federating: "ສະຫະພັນ"
blocked: "ບລັອກແລ້ວ "
suspended: "ໂຈະ"
all: "ທັງໝົດ"
subscribing: "ສະໝັກສະມາຊິກແລັວ"
publishing: "ການ​ພິມ​ເຜີຍ​ແຜ່"
@@ -177,15 +179,35 @@ instanceFollowing: "ກຳລັງຕິດຕາມສຸດຕົວຢ່າ
instanceFollowers: "ຜູ້ຕິດຕາມຕົວຢ່າງ"
instanceUsers: "ຜູ້​ຊົມ​ໃຊ້​ຂອງ​ຕົວ​ຢ່າງ​ນີ້​"
changePassword: "ປ່ຽນ​ລະ​ຫັດ​ຜ່ານ"
security: "ຄວາມປອດໄພ"
retypedNotMatch: "ວັດສະດຸປ້ອນບໍ່ກົງກັນ"
currentPassword: "ລະຫັດຜ່ານປະຈຸບັນ"
more: "ເພີ່ມເຕີມ!"
featured: "ໄຮໄລທ໌"
usernameOrUserId: "ຊື່ຜູ້ໃຊ້ ຫຼື id ຜູ້ໃຊ້"
noSuchUser: "ບໍ່ພົບຜູ້ໃຊ້"
lookup: "ຄົ້ນ​ຫາ"
announcements: "ປະກາດ"
imageUrl: "URL ຮູບພາບ"
remove: "ລຶບ"
removed: "ລຶບແລ້ວ"
resetAreYouSure: "ຣີ​ເຊັດບໍ?"
saved: "ບັນທຶກແລ້ວ"
messaging: "ແຊ໋ດ"
upload: "ອັບໂຫຼດ"
keepOriginalUploading: "ຮັກສາຮູບພາບຕົ້ນສະບັບ"
fromUrl: "ຈາກ URL"
uploadFromUrl: "ອັບໂຫຼດຈາກ URL"
uploadFromUrlDescription: "URL ຂອງໄຟລ໌ທີ່ທ່ານຕ້ອງການອັບໂຫລດ"
messageRead: "ອ່ານແລ້ວ"
startMessaging: "ເລີ່ມການສົນທະນາໃໝ່"
nUsersRead: "ອ່ານໂດຍ {n}"
tos: "ເງື່ອນໄຂການໃຫ້ບໍລິການ"
start: "ເລີ່ມຕົ້ນນຳໃຊ້ເລີຍ"
home: "ໜ້າຫຼັກ"
images: "ຮູບພາບ"
birthday: "ວັນເກີດ"
yearsOld: "{age} ປີ"
registeredDate: "ວັນທີ່ເປັນສະມາຊິກ"
location: "ທີ່ຕັ້ງ"
theme: "ແທ໋ມ"
@@ -193,17 +215,96 @@ light: "ສະຫວ່າງ"
dark: "ມືດ"
lightThemes: "ຊຸດຮູບແບບສະຫວ່າງ"
darkThemes: "ຮູບແບບສີສັນມືດ"
drive: "ຂັບ"
fileName: "ຊື່ໄຟລ໌"
selectFile: "ເລືອກໄຟລ໌"
selectFiles: "ເລືອກໄຟລ໌"
selectFolder: "ເລືອກໂຟລເດີ"
selectFolders: "ເລືອກໂຟລເດີ"
renameFile: "ປ່ຽນຊື່ໄຟລ໌"
folderName: "ຊື່ໂຟນເດີ"
createFolder: "​ສ້າງ​ໂຟ​ລ​ເດີ"
renameFolder: "ປ່ຽນຊື່ໂຟນເດີນີ້"
deleteFolder: "ລົບໂຟ​ລ​ເດີ​"
addFile: "ເພີ່ມໄຟລ໌"
emptyDrive: "Drive ຂອງທ່ານຫວ່າງເປົ່າ"
emptyFolder: "ໂຟນເດີນີ້ເປົ່າຫວ່າງ"
unableToDelete: "ບໍ່​ສາ​ມາດລົບໄດ້"
inputNewFileName: "ໃສ່ຊື່ໄຟລ໌ໃໝ່"
inputNewDescription: "ໃສ່ຄຳບັນຍາຍໃໝ່"
inputNewFolderName: "ໃສ່ຊື່ໂຟນເດີໃໝ່"
circularReferenceFolder: "ໂຟນເດີປາຍທາງແມ່ນໂຟນເດີຍ່ອຍຂອງໂຟນເດີທີ່ທ່ານຕ້ອງການຍ້າຍ"
rename: "ປ່ຽນຊື່"
nsfw: "NSFW"
watch: "ເບິ່ງ"
unwatch: "ຢຸດເບິ່ງ"
accept: "ອະນຸຍາດ"
reject: "ປະຕິເສດ"
normal: "ປົກກະຕິ"
instanceName: "ຊື່ເຊີເວີ້"
instanceDescription: "ຄໍາອະທິບາຍຕົວຢ່າງ"
maintainerName: "ຜູ້ດູແລ"
maintainerEmail: "ອີເມວ admin"
tosUrl: "ເງື່ອນໄຂການໃຫ້ບໍລິການ URL"
thisYear: "ປີນີ້"
thisMonth: "ເດືອນນີ້"
today: "ມື້ນີ້"
dayX: "ວັນ {day}"
monthX: "ເດືອນ {month}"
yearX: "ປີ {year}"
pages: "ໜ້າ"
integration: "ຄວາມສຳພັນຂອງ"
connectService: "ເຊື່ອມຕໍ່"
disconnectService: "ຕັດການເຊື່ອມຕໍ່"
enableLocalTimeline: "ເປີດໃຊ້ທາມລາຍທ້ອງຖິ່ນ"
enableGlobalTimeline: "ເປີດໃຊ້ທາມລາຍທົ່ວໂລກ"
disablingTimelinesInfo: "ຜູ້ເບິ່ງແຍງລະບົບ ແລະຜູ້ຄວບຄຸມຈະມີການເຂົ້າເຖິງທຸກກຳນົດເວລາ, ເຖິງແມ່ນວ່າຈະບໍ່ໄດ້ເປີດໃຊ້ງານກໍຕາມ"
registration: "ລົງທະບຽນ"
enableRegistration: "ເປີດໃຊ້ການລົງທະບຽນຜູ້ໃຊ້ໃໝ່"
invite: "ເຊີນ"
driveCapacityPerLocalAccount: "ຄວາມອາດສາມາດຂັບຕໍ່ຜູ້ໃຊ້ທ້ອງຖິ່ນ"
driveCapacityPerRemoteAccount: "ໄດຣຟ໌ຄວາມອາດສາມາດຕໍ່ຜູ້ໃຊ້ທາງໄກ"
pinnedNotes: "ບັນທຶກທີ່ປັກໝຸດໄວ້"
userList: "ລາຍການ"
about: "ກ່ຽວກັບ"
aboutMisskey: "ກ່ຽວກັບ Misskey"
administrator: "ຜູ້ບໍລິຫານ"
share: "ແບ່ງປັນ"
notFound: "ບໍ່ພົບ"
cacheClear: "ລຶບລ້າງແຄສ"
invites: "ເຊີນ"
title: "ຫົວຂໍ້"
text: "ຂໍ້ຄວາມ"
enable: "ເປີດໃຊ້"
next: "ຕໍ່ໄປ"
invitations: "ເຊີນ"
language: "ພາສາ"
native: "ພາ​ສາ​ແມ່"
category: "ຫມວດຫມູ່"
tags: "ແທ໋ກ"
createAccount: "ສ້າງບັນຊີ"
existingAccount: "ທີ່ມີຢູ່"
dashboard: "ໜ້າປັດ"
local: "ທ້ອງຖິ່ນ"
objectStorageRegion: "ພາກ​ພື້ນ"
sounds: "ສຽງ"
sound: "ສຽງ"
none: "ບໍ່ມີ"
volume: "ລະດັບສຽງ"
details: "ລາຍລະອຽດ"
install: "ຕິດຕັ້ງ"
uninstall: "ຖອນການຕິດຕັ້ງ"
state: "ສະຖານະ"
sort: "ຈັດຮຽງໂດຍ"
ascendingOrder: "ນ້ອຍໄປຫາໃຫຍ່"
descendingOrder: "ໃຫຍ່ຫານ້ອຍ"
output: "ຜົນຜະລິດ"
script: "ບົດ​ຄວາມ"
smtpHost: "ໂຮດສ"
smtpUser: "ຊື່ຜູ້ໃຊ້"
smtpPass: "ລະຫັດຜ່ານ"
clearCache: "ລຶບລ້າງແຄສ"
info: "ກ່ຽວກັບ"
user: "ຜູ້ໃຊ້ຕ່າງໆ"
searchByGoogle: "ຄົ້ນຫາ"
file: "ໄຟລ໌"
@@ -244,6 +345,8 @@ _charts:
federation: "ສະຫະພັນ"
_timelines:
home: "ໜ້າຫຼັກ"
_play:
script: "ບົດ​ຄວາມ"
_pages:
blocks:
image: "ຮູບພາບ"
@@ -265,3 +368,4 @@ _deck:
list: "ລາຍການ"
channel: "ຊ່ອງ"
mentions: "ກ່າວເຖິງ"

View File

@@ -483,3 +483,6 @@ _deck:
antenna: "Antennes"
list: "Lijsten"
mentions: "Vermeldingen"
_webhookSettings:
name: "Naam"

View File

@@ -1,2 +1,3 @@
---
_lang_: "Norsk Bokmål"

View File

@@ -564,7 +564,6 @@ tokenRequested: "Przydziel dostęp do konta"
pluginTokenRequestedDescription: "Ta wtyczka będzie mogła korzystać z ustawionych tu uprawnień."
notificationType: "Rodzaj powiadomień"
edit: "Edytuj"
useStarForReactionFallback: "Użyj ★ jako zapasowego emoji, gdy emoji reakcji jest nieznane"
emailServer: "Serwer poczty e-mail"
enableEmail: "Włącz dostarczanie wiadomości e-mail"
emailConfigInfo: "Wykorzystywany do potwierdzenia adresu e-mail w trakcie rejestracji, lub gdy zapomnisz hasła"
@@ -810,6 +809,7 @@ auto: "Automatycznie"
size: "Rozmiar"
numberOfColumn: "Liczba kolumn"
searchByGoogle: "Szukaj"
period: "Ankieta kończy się"
indefinitely: "Nigdy"
tenMinutes: "10 minut"
oneHour: "1 godzina"
@@ -1357,3 +1357,7 @@ _deck:
channel: "Kanały"
mentions: "Wspomnienia"
direct: "Bezpośredni"
_webhookSettings:
name: "Nazwa"
active: "Właczono"

View File

@@ -555,3 +555,6 @@ _deck:
list: "Listas"
mentions: "Menções"
direct: "Notas diretas"
_webhookSettings:
name: "Nome"

View File

@@ -561,7 +561,6 @@ tokenRequested: "Acordă acces la cont"
pluginTokenRequestedDescription: "Acest plugin va putea să folosească permisiunile setate aici."
notificationType: "Tipul notificării"
edit: "Editează"
useStarForReactionFallback: "Folosește ★ ca fallback dacă emoji-ul este necunoscut"
emailServer: "Server email"
enableEmail: "Activează distribuția de emailuri"
emailConfigInfo: "Folosit pentru a confirma emailul tău în timpul logări dacă îți uiți parola"
@@ -702,3 +701,6 @@ _deck:
list: "Liste"
channel: "Canale"
mentions: "Mențiuni"
_webhookSettings:
name: "Nume"

View File

@@ -393,13 +393,19 @@ about: "Описание"
aboutMisskey: "О Misskey"
administrator: "Администратор"
token: "Токен"
2fa: "2-х факторная аутентификация"
totp: "Приложение-аутентификатор"
totpDescription: "Описание приложения-аутентификатора"
moderator: "Модератор"
moderation: "Модерация"
nUsersMentioned: "Упомянуло пользователей: {n}"
securityKeyAndPasskey: "Ключ безопасности и парольная фраза"
securityKey: "Ключ безопасности"
lastUsed: "Последнее использование"
lastUsedAt: "Последнее использование: {t}"
unregister: "Отписаться"
passwordLessLogin: "Настроить вход без пароля"
passwordLessLoginDescription: "Вход без пароля"
resetPassword: "Сброс пароля:"
newPasswordIs: "Новый пароль — «{password}»."
reduceUiAnimation: "Уменьшить анимацию в пользовательском интерфейсе"
@@ -579,7 +585,6 @@ tokenRequested: "Открыть доступ к учётной записи"
pluginTokenRequestedDescription: "Это расширение сможет пользоваться разрешениями, установленными здесь."
notificationType: "Тип уведомления"
edit: "Изменить"
useStarForReactionFallback: "Ставить ★ в качестве реакции вместо неизвестного эмодзи"
emailServer: "Сервер электронной почты"
enableEmail: "Включить обмен электронной почтой"
emailConfigInfo: "Используется для подтверждения адреса электронной почты и сброса пароля."
@@ -773,6 +778,7 @@ popularPosts: "Популярные публикации"
shareWithNote: "Поделиться заметкой"
ads: "Реклама"
expiration: "Опрос длится"
startingperiod: "Начальный период"
memo: "Памятка"
priority: "Приоритет"
high: "Высокий"
@@ -805,6 +811,7 @@ lastCommunication: "Последнее сообщение"
resolved: "Решено"
unresolved: "Без решения"
breakFollow: "Отписка"
breakFollowConfirm: "Удалить из подписок пользователя ?"
itsOn: "Включено"
itsOff: "Выключено"
emailRequiredForSignup: "Для регистрации учётной записи нужен адрес электронной почты"
@@ -839,6 +846,7 @@ instanceDefaultLightTheme: "Светлая тема по умолчанию"
instanceDefaultDarkTheme: "Темная тема по умолчанию"
instanceDefaultThemeDescription: "Описание темы по умолчанию для инстанса"
mutePeriod: "Продолжительность скрытия"
period: "Опрос длится"
indefinitely: "вечно"
tenMinutes: "10 минут"
oneHour: "1 час"
@@ -939,6 +947,10 @@ collapseRenotes: "Свернуть репосты"
internalServerError: "Внутренняя ошибка сервера"
internalServerErrorDescription: "Внутри сервера произошла непредвиденная ошибка."
copyErrorInfo: "Скопировать код ошибки"
joinThisServer: "Присоединяйтесь к этому серверу"
exploreOtherServers: "Искать другие сервера"
letsLookAtTimeline: "Давайте посмотрим на ленту"
disableFederationWarn: "Объединение отключено. Если вы отключите это, сообщение не будет приватным. В большинстве случаев вам не нужно включать эту опцию."
_achievements:
earnedAt: "Разблокировано в"
_types:
@@ -1486,13 +1498,28 @@ _tutorial:
step8_3: "Эту настройку вы всегда сможете поменять"
_2fa:
alreadyRegistered: "Двухфакторная аутентификация уже настроена."
registerTOTP: "Начните настраивать приложение-аутентификатор"
passwordToTOTP: "Пожалуйста, введите свой пароль"
step1: "Прежде всего, установите на устройство приложение для аутентификации, например, {a} или {b}."
step2: "Далее отсканируйте отображаемый QR-код при помощи приложения."
step2Click: "Нажав на QR-код, вы можете зарегистрироваться с помощью приложения для аутентификации или брелка для ключей, установленного на вашем устройстве."
step2Url: "Если пользуетесь приложением на компьютере, можете ввести в него эту строку (URL):"
step3Title: "Введите проверочный код"
step3: "И наконец, введите код, который покажет приложение."
step4: "Теперь при каждом входе на сайт вам нужно будет вводить код из приложения аналогичным образом."
securityKeyNotSupported: "Ваш браузер не поддерживает ключи безопасности."
registerTOTPBeforeKey: "Чтобы зарегистрировать ключ безопасности и пароль, сначала настройте приложение аутентификации."
securityKeyInfo: "Вы можете настроить вход с помощью аппаратного ключа безопасности, поддерживающего FIDO2, или отпечатка пальца или PIN-кода на устройстве."
chromePasskeyNotSupported: "В настоящее время Chrome не поддерживает пароль-ключи."
registerSecurityKey: "Зарегистрируйте ключ безопасности ・Passkey"
securityKeyName: "Введите имя для ключа"
tapSecurityKey: "Пожалуйста, следуйте инструкциям в вашем браузере, чтобы зарегистрировать свой ключ безопасности или пароль"
removeKey: "Удалить ключ безопасности"
removeKeyConfirm: "Удалить резервную копию «{name}»?"
whyTOTPOnlyRenew: "Если ключ безопасности зарегистрирован, вы не сможете отключить приложение аутентификации."
renewTOTP: "Перенастроите приложение аутентификации"
renewTOTPConfirm: "Проверочный код предыдущего приложения для аутентификации больше не будет доступен"
renewTOTPOk: "Настроить"
renewTOTPCancel: "Нет, спасибо"
_permissions:
"read:account": "Просматривать данные учётной записи"
@@ -1616,6 +1643,8 @@ _visibility:
followersDescription: "Только вашим подписчикам"
specified: "Личное"
specifiedDescription: "Тем, кого укажете"
disableFederation: "Отключить федерацию"
disableFederationDescription: "Не доставляет в другие экземпляры"
_postForm:
replyPlaceholder: "Ответ на заметку..."
quotePlaceholder: "Пояснение к цитате..."
@@ -1771,6 +1800,7 @@ _notification:
pollEnded: "Окончания опросов"
receiveFollowRequest: "Получен запрос на подписку"
followRequestAccepted: "Запрос на подписку одобрен"
achievementEarned: "Получение достижений"
app: "Уведомления из приложений"
_actions:
followBack: "отвечает взаимной подпиской"
@@ -1803,3 +1833,10 @@ _deck:
channel: "Каналы"
mentions: "Упоминания"
direct: "Личное"
_dialog:
charactersExceeded: "Превышено максимальное количество символов! У вас {current} / из {max}"
charactersBelow: "Это ниже минимального количества символов! У вас {current} / из {min}"
_webhookSettings:
name: "Название"
active: "Вкл."

View File

@@ -1 +1,2 @@
---

View File

@@ -103,6 +103,8 @@ renoted: "Preposlané."
cantRenote: "Tento príspevok sa nedá preposlať."
cantReRenote: "Odpoveď nemôže byť odstránená."
quote: "Citovať"
inChannelRenote: "Preposlania v kanáli"
inChannelQuote: "Citácie v kanáli"
pinnedNote: "Pripnuté poznámky"
pinned: "Pripnúť"
you: "Vy"
@@ -129,6 +131,7 @@ unblockConfirm: "Naozaj chcete odblokovať tento účet?"
suspendConfirm: "Naozaj chcete zmraziť tento účet?"
unsuspendConfirm: "Naozaj chcete odmraziť tento účet?"
selectList: "Vyberte zoznam"
selectChannel: "Zvoľte kanál"
selectAntenna: "Vyberte anténu"
selectWidget: "Vyberte widget"
editWidgets: "Upraviť widget"
@@ -256,6 +259,8 @@ noMoreHistory: "To je všetko"
startMessaging: "Začať chat"
nUsersRead: "prečítané {n} používateľmi"
agreeTo: "Súhlasím s {0}"
agreeBelow: "Súhlasím s nasledovným"
basicNotesBeforeCreateAccount: "Základné bezpečnostné opatrenia"
tos: "Podmienky používania"
start: "Začať"
home: "Domov"
@@ -388,13 +393,19 @@ about: "Informácie"
aboutMisskey: "O Misskey"
administrator: "Administrátor"
token: "Token"
2fa: "Dvojfaktorové overenie (2FA)"
totp: "Overovacia aplikácia"
totpDescription: "Zadajte jednorazové heslo z overovacej aplikácie"
moderator: "Moderátor"
moderation: "Moderovanie"
nUsersMentioned: "{n} používateľov spomenulo"
securityKeyAndPasskey: "Bezpečnostný kľúč/heslo"
securityKey: "Bezpečnostný kľúč"
lastUsed: "Naposledy použité"
lastUsedAt: "Naposledy použité: {t}"
unregister: "Odregistrovať"
passwordLessLogin: "Nastaviť bezheslové prihlásenie"
passwordLessLoginDescription: "Prihlásenie bez hesla, len bezpečnostným kľúčom alebo prístupovým kľúčom"
resetPassword: "Resetovať heslo"
newPasswordIs: "Nové heslo je \"{password}\""
reduceUiAnimation: "Menej UI animácií"
@@ -446,8 +457,11 @@ aboutX: "O {x}"
emojiStyle: "Štýl emoji"
native: "Natívne"
disableDrawer: "Nepoužívať šuflíkové menu"
showNoteActionsOnlyHover: "Ovládacie prvky poznámky sa zobrazujú len po nabehnutí myši"
noHistory: "Žiadna história"
signinHistory: "História prihlásení"
enableAdvancedMfm: "Povolenie pokročilého MFM"
enableAnimatedMfm: "Povoliť animované MFM"
doing: "Pracujem..."
category: "Kategórie"
tags: "Značky"
@@ -556,6 +570,7 @@ manage: "Administrácia"
plugins: "Pluginy"
preferencesBackups: "Zálohy nastavení"
deck: "Deck"
undeck: "Oddokovať"
useBlurEffectForModal: "Použiť efekt rozmazania na okná"
useFullReactionPicker: "Použiť plnú veľkosť výberu reakcií"
width: "Šírka"
@@ -571,7 +586,6 @@ tokenRequested: "Povoliť prístup k účtu"
pluginTokenRequestedDescription: "Tento plugin bude môcť používať oprávnenia nastavené tu."
notificationType: "Typ oznámenia"
edit: "Upraviť"
useStarForReactionFallback: "Použiť ★ keď emoji reakcie nie je známe"
emailServer: "Email server"
enableEmail: "Zapnúť email"
emailConfigInfo: "Používa sa na overenie emaily pri registrácii alebo pri zabudnutí hesla"
@@ -765,6 +779,7 @@ popularPosts: "Populárne príspevky"
shareWithNote: "Zdieľať s poznámkou"
ads: "Reklamy"
expiration: "Ukončiť hlasovanie"
startingperiod: "Začiatok"
memo: "Memo"
priority: "Priorita"
high: "Vysoká"
@@ -831,11 +846,13 @@ instanceDefaultLightTheme: "Predvolená svetlá téma"
instanceDefaultDarkTheme: "Predvolená tmavá téma"
instanceDefaultThemeDescription: "Vložte kód témy v objektovom formáte"
mutePeriod: "Trvanie stíšenia"
period: "Ukončiť hlasovanie"
indefinitely: "Navždy"
tenMinutes: "10 minút"
oneHour: "1 hodina"
oneDay: "1 deň"
oneWeek: "1 týždeň"
oneMonth: "1 mesiac"
reflectMayTakeTime: "Zmeny môžu chvíľu trvať kým sa prejavia."
failedToFetchAccountInformation: "Nepodarilo sa načítať informácie o účte."
rateLimitExceeded: "Prekročený limit rýchlosti"
@@ -1457,3 +1474,7 @@ _deck:
channel: "Kanály"
mentions: "Zmienky"
direct: "Priame poznámky"
_webhookSettings:
name: "Názov"
active: "Zapnuté"

View File

@@ -442,3 +442,6 @@ _deck:
antenna: "Antenner"
list: "Listor"
mentions: "Omnämningar"
_webhookSettings:
active: "Aktiverad"

View File

@@ -268,7 +268,7 @@ remoteUserCaution: "เนื่องจากผู้ใช้งานรา
activity: "กิจกรรม"
images: "รูปภาพ"
birthday: "วันเกิด"
yearsOld: "{อายุ} ปี"
yearsOld: "{age} ปี"
registeredDate: "วันที่สมัครสมาชิก"
location: "ตำแหน่งที่ตั้ง"
theme: "ธีม"
@@ -457,6 +457,7 @@ aboutX: "เกี่ยวกับ {x}"
emojiStyle: "สไตล์อิโมจิ"
native: "ภาษาแม่"
disableDrawer: "อย่าใช้ลิ้นชักสไตล์เมนู"
showNoteActionsOnlyHover: "แสดงการดำเนินการเฉพาะโน้ตเมื่อโฮเวอร์"
noHistory: "ไม่มีรายการ"
signinHistory: "ประวัติการเข้าสู่ระบบ"
enableAdvancedMfm: "เปิดใช้งาน MFM ขั้นสูง"
@@ -505,6 +506,7 @@ objectStorageSetPublicRead: "ตั้งค่า \"public-read\" ในกา
serverLogs: "บันทึกของเซิร์ฟเวอร์"
deleteAll: "ลบทั้งหมด"
showFixedPostForm: "แสดงแบบฟอร์มการโพสต์ที่ด้านบนสุดของไทม์ไลน์"
showFixedPostFormInChannel: "แสดงแบบฟอร์มกำลังโพสต์ที่ด้านบนของไทม์ไลน์ (แชนแนล)"
newNoteRecived: "มีโน้ตใหม่"
sounds: "เสียง"
sound: "เสียง"
@@ -542,6 +544,8 @@ userSuspended: "ผู้ใช้รายนี้ถูกระงับก
userSilenced: "ผู้ใช้รายนี้กำลังถูกปิดกั้น"
yourAccountSuspendedTitle: "บัญชีนี้นั้นถูกระงับ"
yourAccountSuspendedDescription: "บัญชีนี้ถูกระงับ เนื่องจากละเมิดข้อกำหนดในการให้บริการของเซิร์ฟเวอร์หรืออาจจะละเมิดหลักเกณฑ์ชุมชน หรือ อาจจะโดนร้องเรียนเรื่องการละเมิดลิขสิทธิ์และอื่นๆอย่างต่อเนื่องซ้ำๆ หากคุณคิดว่าไม่ได้ทำผิดจริงๆหรือตัดสินผิดพลาด ได้โปรดกรุณาติดต่อผู้ดูแลระบบหากคุณต้องการทราบเหตุผลโดยละเอียดเพิ่มเติม และขอความกรุณาอย่าสร้างบัญชีใหม่"
tokenRevoked: "โทเค็นไม่ถูกต้อง"
accountDeleted: "ลบบัญชีแล้ว"
menu: "เมนู"
divider: "ตัวแบ่ง"
addItem: "เพิ่มรายการ"
@@ -585,7 +589,6 @@ tokenRequested: "ให้สิทธิ์การเข้าถึงบั
pluginTokenRequestedDescription: "ปลั๊กอินนี้จะสามารถใช้การอนุญาตที่ตั้งค่าไว้ที่นี่นะ"
notificationType: "ประเภทการแจ้งเตือน"
edit: "แก้ไข"
useStarForReactionFallback: "ใช้ ★ เป็นทางเลือกแทนถ้าหากไม่ทราบอิโมจิ"
emailServer: "อีเมล์เซิร์ฟเวอร์"
enableEmail: "เปิดใช้งานการกระจายอีเมล"
emailConfigInfo: "ใช้เพื่อยืนยันอีเมลของคุณระหว่างการสมัครหรือถ้าหากคุณลืมรหัสผ่าน"
@@ -847,11 +850,13 @@ instanceDefaultLightTheme: "ธีมสว่างค่าเริ่มต
instanceDefaultDarkTheme: "ธีมมืดค่าเริ่มต้นอินสแตนซ์"
instanceDefaultThemeDescription: "ป้อนรหัสธีมในรูปแบบออบเจ็กต์"
mutePeriod: "ระยะเวลาปิดเสียง"
period: "สิ้นสุดการสำรวจความคิดเห็น"
indefinitely: "ตลอดไป"
tenMinutes: "10 นาที"
oneHour: "1 ชั่วโมง"
oneDay: "1 วัน"
oneWeek: "1 สัปดาห์"
oneMonth: "หนึ่งเดือน"
reflectMayTakeTime: "อาจจำเป็นต้องใช้เวลาสักระยะหนึ่งจึงจะเห็นแสดงผลได้นะ"
failedToFetchAccountInformation: "ไม่สามารถเรียกดึงข้อมูลบัญชีได้"
rateLimitExceeded: "เกินขีดจำกัดอัตรา"
@@ -951,6 +956,22 @@ joinThisServer: "ลงชื่อสมัครใช้ในอินสแ
exploreOtherServers: "มองหาอินสแตนซ์อื่น"
letsLookAtTimeline: "ลองดูที่ไทม์ไลน์"
disableFederationWarn: "การดำเนินการนี้ถ้าหากจะปิดใช้งานการรวมศูนย์ แต่โพสต์ดังกล่าวนั้นจะยังคงเป็นสาธารณะต่อไป ยกเว้นแต่ว่าจะตั้งค่าเป็นอย่างอื่น โดยปกติคุณไม่จำเป็นต้องใช้การตั้งค่านี้นะ"
invitationRequiredToRegister: "อินสแตนซ์นี้เป็นแบบรับเชิญเท่านั้น คุณต้องป้อนรหัสเชิญที่ถูกต้องถึงจะลงทะเบียนได้นะค่ะ"
emailNotSupported: "อินสแตนซ์นี้ไม่รองรับการส่งอีเมลนะค่ะ"
postToTheChannel: "โพสต์ลงช่อง"
cannotBeChangedLater: "สิ่งนี้ไม่สามารถเปลี่ยนแปลงได้ในภายหลังนะ"
likeOnly: "ที่ชอบเท่านั้น"
resetPasswordConfirm: "รีเซ็ตรหัสผ่านของคุณจริงๆหรอ?"
sensitiveWords: "คำที่ละเอียดอ่อน"
sensitiveWordsDescription: "การเปิดเผยโน้ตทั้งหมดที่มีคำที่กำหนดค่าไว้จะถูกตั้งค่าเป็น \"หน้าแรก\" โดยอัตโนมัติ คุณยังสามารถแสดงหลายรายการได้โดยแยกรายการโดยใช้ตัวแบ่งบรรทัดได้นะ"
notesSearchNotAvailable: "การค้นหาโน้ตไม่พร้อมใช้งานนะค่ะ"
license: "ใบอนุญาต"
unfavoriteConfirm: "ลบออกจากรายการโปรดแน่ใจหรอ?"
myClips: "คลิปของฉัน"
drivecleaner: "ทำความสะอาดไดรฟ์"
retryAllQueuesNow: "ลองเรียกใช้คิวทั้งหมดอีกครั้ง"
retryAllQueuesConfirmTitle: "ลองใหม่ทั้งหมดจริงๆหรอแน่ใจนะ?"
retryAllQueuesConfirmText: "สิ่งนี้จะเพิ่มการโหลดเซิร์ฟเวอร์ชั่วคราวนะ"
_achievements:
earnedAt: "ได้รับเมื่อ"
_types:
@@ -1210,6 +1231,8 @@ _role:
iconUrl: "ไอคอน URL"
asBadge: "แสดงเป็นตรา"
descriptionOfAsBadge: "ไอคอนของบทบาทนี้จะปรากฏถัดจากชื่อผู้ใช้ของผู้ใช้งานด้วยบทบาทนี้ถ้าหากเปิดใช้งาน"
displayOrder: "ตำแหน่ง"
descriptionOfDisplayOrder: "ยิ่งตัวเลขสูง ตำแหน่ง UI ก็ยิ่งสูงขึ้นนะ"
canEditMembersByModerator: "อนุญาตให้ผู้ดูแลแก้ไขสมาชิก"
descriptionOfCanEditMembersByModerator: "เมื่อเปิดใช้ ผู้ดูแลนอกเหนือจากผู้ดูแลระบบแล้ว จะสามารถกำหนดและยกเลิกการมอบหมายบทบาทนี้ให้กับผู้ใช้ได้ เมื่อปิด เฉพาะผู้ดูแลระบบเท่านั้นที่จะสามารถกำหนดผู้ใช้ได้นะ"
priority: "ลำดับความสำคัญ"
@@ -1235,6 +1258,7 @@ _role:
rateLimitFactor: "ขีดจำกัดอัตรา"
descriptionOfRateLimitFactor: "ขีดจํากัดอัตราที่ต่ำกว่ามีข้อจํากัดน้อยกว่าข้อจํากัดที่สูงกว่า"
canHideAds: "ซ่อนโฆษณา"
canSearchNotes: "การใช้การค้นหาโน้ต"
_condition:
isLocal: "ผู้ใช้ภายใน"
isRemote: "ผู้ใช้ระยะไกล"
@@ -1836,3 +1860,13 @@ _deck:
_dialog:
charactersExceeded: "คุณกำลังมีตัวอักขระเกินขีดจำกัดสูงสุดแล้วนะ! ปัจจุบันอยู่ที่ {current} จาก {max}"
charactersBelow: "คุณกำลังใช้อักขระต่ำกว่าขีดจำกัดขั้นต่ำเลยนะ! ปัจจุบันอยู่ที่ {current} จาก {min}"
_disabledTimeline:
title: "ปิดใช้งานไทม์ไลน์"
description: "คุณไม่สามารถใช้ไทม์ไลน์นี้ภายใต้บทบาทปัจจุบันของคุณได้"
_drivecleaner:
orderBySizeDesc: "ขนาดไฟล์จากมากไปหาน้อย"
orderByCreatedAtAsc: "วันที่จากน้อยไปหามาก"
_webhookSettings:
name: "ชื่อ"
active: "เปิดใช้งาน"

View File

@@ -60,3 +60,4 @@ _deck:
_columns:
notifications: "Bildirim"
tl: "Zaman çizelgesi"

View File

@@ -2,3 +2,4 @@
_lang_: "ياپونچە"
search: "ئىزدەش"
searchByGoogle: "ئىزدەش"

View File

@@ -576,7 +576,6 @@ tokenRequested: "Надати доступ до акаунту"
pluginTokenRequestedDescription: "Цей плагін зможе використовувати дозволи які тут вказані."
notificationType: "Тип сповіщення"
edit: "Редагувати"
useStarForReactionFallback: "Використовувати ★ як запасний варіант, якщо емодзі реакції невідомий"
emailServer: "Email сервер"
enableEmail: "Увімкнути функцію доставки пошти"
emailConfigInfo: "Використовується для підтвердження електронної пошти підчас реєстрації, а також для відновлення паролю."
@@ -831,6 +830,7 @@ searchByGoogle: "Пошук"
instanceDefaultLightTheme: "Світла тема за промовчанням"
instanceDefaultDarkTheme: "Темна тема за промовчанням"
mutePeriod: "Тривалість приховування"
period: "Опитування закінчується"
indefinitely: "Ніколи"
tenMinutes: "10 хвилин"
oneHour: "1 година"
@@ -1638,3 +1638,7 @@ _deck:
channel: "Канали"
mentions: "Згадки"
direct: "Особисте"
_webhookSettings:
name: "Ім'я"
active: "Увімкнено"

View File

@@ -2,6 +2,7 @@
_lang_: "Tiếng Việt"
headlineMisskey: "Mạng xã hội liên hợp"
introMisskey: "Xin chào! Misskey là một nền tảng tiểu blog phi tập trung mã nguồn mở.\nViết \"tút\" để chia sẻ những suy nghĩ của bạn 📡\nBằng \"biểu cảm\", bạn có thể bày tỏ nhanh chóng cảm xúc của bạn với các tút 👍\nHãy khám phá một thế giới mới! 🚀"
poweredByMisskeyDescription: "{name} là một trong những chủ máy của <b>Misskey</b> là nền tảng mã nguồn mở"
monthAndDay: "{day} tháng {month}"
search: "Tìm kiếm"
notifications: "Thông báo"
@@ -10,12 +11,13 @@ password: "Mật khẩu"
forgotPassword: "Quên mật khẩu"
fetchingAsApObject: "Đang nạp dữ liệu từ Fediverse..."
ok: "Đồng ý"
gotIt: "Đã hiểu!"
gotIt: "Hiểu rồi!"
cancel: "Hủy"
noThankYou: "Không, cảm ơn"
enterUsername: "Nhập tên người dùng"
renotedBy: "Chia sẻ bởi {user}"
noNotes: "Chưa có t nào."
noNotifications: "Không có thông báo"
noNotes: "Chưa có bài viết nào."
noNotifications: "Chưa có thông báo"
instance: "Máy chủ"
settings: "Cài đặt"
basicSettings: "Thiết lập chung"
@@ -47,6 +49,7 @@ deleteAndEdit: "Sửa"
deleteAndEditConfirm: "Bạn có chắc muốn sửa tút này? Những biểu cảm, lượt trả lời và đăng lại sẽ bị mất."
addToList: "Thêm vào danh sách"
sendMessage: "Gửi tin nhắn"
copyRSS: "Sao chép RSS"
copyUsername: "Chép tên người dùng"
searchUser: "Tìm kiếm người dùng"
reply: "Trả lời"
@@ -65,13 +68,13 @@ export: "Xuất dữ liệu"
files: "Tập tin"
download: "Tải xuống"
driveFileDeleteConfirm: "Bạn có chắc muốn xóa tập tin \"{name}\"? Tút liên quan cũng sẽ bị xóa theo."
unfollowConfirm: "Bạn có chắc muốn ngưng theo dõi {name}?"
unfollowConfirm: "Bạn ngng theo dõi {name}?"
exportRequested: "Đang chuẩn bị xuất tập tin. Quá trình này có thể mất ít phút. Nó sẽ được tự động thêm vào Drive sau khi hoàn thành."
importRequested: "Bạn vừa yêu cầu nhập dữ liệu. Quá trình này có thể mất ít phút."
lists: "Danh sách"
noLists: "Bạn chưa có danh sách nào"
note: "t"
notes: "t"
note: "Bài viết"
notes: "Bài Viết"
following: "Đang theo dõi"
followers: "Người theo dõi"
followsYou: "Theo dõi bạn"
@@ -88,7 +91,7 @@ enterListName: "Đặt tên cho danh sách"
privacy: "Bảo mật"
makeFollowManuallyApprove: "Yêu cầu theo dõi cần được duyệt"
defaultNoteVisibility: "Kiểu tút mặc định"
follow: "Đang theo dõi"
follow: "Theo dõi"
followRequest: "Gửi yêu cầu theo dõi"
followRequests: "Yêu cầu theo dõi"
unfollow: "Ngưng theo dõi"
@@ -100,7 +103,9 @@ renoted: "Đã đăng lại."
cantRenote: "Không thể đăng lại tút này."
cantReRenote: "Không thể đăng lại một tút đăng lại."
quote: "Trích dẫn"
pinnedNote: "Tút ghim"
inChannelRenote: "Chia sẻ trong kênh này"
inChannelQuote: "Trích dẫn trong kênh này"
pinnedNote: "Bài viết đã ghim"
pinned: "Ghim"
you: "Bạn"
clickToShow: "Nhấn để xem"
@@ -126,6 +131,7 @@ unblockConfirm: "Bạn có chắc muốn bỏ chặn người này?"
suspendConfirm: "Bạn có chắc muốn vô hiệu hóa người này?"
unsuspendConfirm: "Bạn có chắc muốn bỏ vô hiệu hóa người này?"
selectList: "Chọn danh sách"
selectChannel: "Lựa chọn kênh"
selectAntenna: "Chọn một antenna"
selectWidget: "Chọn tiện ích"
editWidgets: "Sửa tiện ích"
@@ -141,8 +147,8 @@ cacheRemoteFiles: "Tập tin cache từ xa"
cacheRemoteFilesDescription: "Khi tùy chọn này bị tắt, các tập tin từ xa sẽ được tải trực tiếp từ máy chủ khác. Điều này sẽ giúp giảm dung lượng lưu trữ nhưng lại tăng lưu lượng truy cập, vì hình thu nhỏ sẽ không được tạo."
flagAsBot: "Đánh dấu đây là tài khoản bot"
flagAsBotDescription: "Bật tùy chọn này nếu tài khoản này được kiểm soát bởi một chương trình. Nếu được bật, nó sẽ được đánh dấu để các nhà phát triển khác ngăn chặn chuỗi tương tác vô tận với các bot khác và điều chỉnh hệ thống nội bộ của Misskey để coi tài khoản này như một bot."
flagAsCat: "Tài khoản này là mèo"
flagAsCatDescription: "Bật tùy chọn này để đánh dấu tài khoản là một con mèo."
flagAsCat: "Chế độ Mèeeeeeeeeeo!!"
flagAsCatDescription: "Nếu mà em là một con mèo thì cứ bật nó kiu mèo mèo mèeeeeeeo!! "
flagShowTimelineReplies: "Hiện lượt trả lời trong bảng tin"
flagShowTimelineRepliesDescription: "Hiện lượt trả lời của người bạn theo dõi trên tút của những người khác."
autoAcceptFollowed: "Tự động phê duyệt theo dõi từ những người mà bạn đang theo dõi"
@@ -155,7 +161,7 @@ setWallpaper: "Đặt ảnh bìa"
removeWallpaper: "Xóa ảnh bìa"
searchWith: "Tìm kiếm: {q}"
youHaveNoLists: "Bạn chưa có danh sách nào"
followConfirm: "Bạn có chắc muốn theo dõi {name}"
followConfirm: "Bạn theo dõi {name}"
proxyAccount: "Tài khoản proxy"
proxyAccountDescription: "Tài khoản proxy là tài khoản hoạt động như một người theo dõi từ xa cho người dùng trong những điều kiện nhất định. Ví dụ: khi người dùng thêm người dùng từ xa vào danh sách, hoạt động của người dùng từ xa sẽ không được chuyển đến phiên bản nếu không có người dùng cục bộ nào theo dõi người dùng đó, vì vậy tài khoản proxy sẽ theo dõi."
host: "Host"
@@ -198,7 +204,7 @@ blockedUsers: "Người đã chặn"
noUsers: "Chưa có ai"
editProfile: "Sửa hồ sơ"
noteDeleteConfirm: "Bạn có chắc muốn xóa tút này?"
pinLimitExceeded: "Bạn đã đạt giới hạn số lượng tút có thể ghim"
pinLimitExceeded: "Bạn không thể ghim bài viết nữa"
intro: "Đã cài đặt Misskey! Xin hãy tạo tài khoản admin."
done: "Xong"
processing: "Đang xử lý"
@@ -253,6 +259,8 @@ noMoreHistory: "Không còn gì để đọc"
startMessaging: "Bắt đầu trò chuyện"
nUsersRead: "đọc bởi {n}"
agreeTo: "Tôi đồng ý {0}"
agreeBelow: "Đồng ý với nội dung dưới đây"
basicNotesBeforeCreateAccount: "Những điều cơ bản cần chú ý "
tos: "Điều khoản dịch vụ"
start: "Bắt đầu"
home: "Trang chính"
@@ -339,7 +347,7 @@ pinnedUsersDescription: "Liệt kê mỗi hàng một tên người dùng xuốn
pinnedPages: "Trang đã ghim"
pinnedPagesDescription: "Liệt kê các trang thú vị để ghim trên máy chủ."
pinnedClipId: "ID của clip muốn ghim"
pinnedNotes: "Tút ghim"
pinnedNotes: "Bài viết đã ghim"
hcaptcha: "hCaptcha"
enableHcaptcha: "Bật hCaptcha"
hcaptchaSiteKey: "Khóa của trang"
@@ -348,6 +356,8 @@ recaptcha: "reCAPTCHA"
enableRecaptcha: "Bật reCAPTCHA"
recaptchaSiteKey: "Khóa của trang"
recaptchaSecretKey: "Khóa bí mật"
turnstile: "Turnstile"
enableTurnstile: "Áp dụng Turnstile"
turnstileSiteKey: "Khóa của trang"
turnstileSecretKey: "Khóa bí mật"
avoidMultiCaptchaConfirm: "Dùng nhiều hệ thống Captcha có thể gây nhiễu giữa chúng. Bạn có muốn tắt các hệ thống Captcha khác hiện đang hoạt động không? Nếu bạn muốn chúng tiếp tục được bật, hãy nhấn hủy."
@@ -383,13 +393,19 @@ about: "Giới thiệu"
aboutMisskey: "Về Misskey"
administrator: "Quản trị viên"
token: "Token"
2fa: "Xác thực 2 yếu tố"
totp: "Ứng dụng xác thực"
totpDescription: "Nhắn mã OTP bằng ứng dụng xác thực"
moderator: "Kiểm duyệt viên"
moderation: "Kiểm duyệt"
nUsersMentioned: "Dùng bởi {n} người"
securityKeyAndPasskey: "Mã bảo mật・Passkey"
securityKey: "Khóa bảo mật"
lastUsed: "Dùng lần cuối"
lastUsedAt: "Lần cuối sử dụng: {t}"
unregister: "Hủy đăng ký"
passwordLessLogin: "Đăng nhập không mật khẩu"
passwordLessLoginDescription: "Đăng nhập bằng chỉ mã bảo mật hoặc passkey, không sử dụng mật khẩu."
resetPassword: "Đặt lại mật khẩu"
newPasswordIs: "Mật khẩu mới là \"{password}\""
reduceUiAnimation: "Giảm chuyển động UI"
@@ -423,7 +439,7 @@ invitations: "Mời"
invitationCode: "Mã mời"
checking: "Đang kiểm tra..."
available: "Khả dụng"
unavailable: "Không khả dụng"
unavailable: "Không sử dụng được"
usernameInvalidFormat: "Bạn có thể dùng viết hoa/viết thường, chữ số, và dấu gạch dưới."
tooShort: "Quá ngắn"
tooLong: "Quá dài"
@@ -438,9 +454,13 @@ or: "Hoặc"
language: "Ngôn ngữ"
uiLanguage: "Ngôn ngữ giao diện"
aboutX: "Giới thiệu {x}"
emojiStyle: "Kiểu cách Emoji"
native: "Bản xứ"
disableDrawer: "Không dùng menu thanh bên"
noHistory: "Không có dữ liệu"
signinHistory: "Lịch sử đăng nhập"
enableAdvancedMfm: "Xem bài MFM chất lượng cao."
enableAnimatedMfm: "Xem bài MFM có chuyển động"
doing: "Đang xử lý..."
category: "Phân loại"
tags: "Thẻ"
@@ -565,7 +585,6 @@ tokenRequested: "Cấp quyền truy cập vào tài khoản"
pluginTokenRequestedDescription: "Plugin này sẽ có thể sử dụng các quyền được đặt ở đây."
notificationType: "Loại thông báo"
edit: "Sửa"
useStarForReactionFallback: "Dùng ★ nếu emoji biểu cảm không có"
emailServer: "Email máy chủ"
enableEmail: "Bật phân phối email"
emailConfigInfo: "Được dùng để xác minh email của bạn lúc đăng ký hoặc nếu bạn quên mật khẩu của mình"
@@ -628,7 +647,7 @@ random: "Ngẫu nhiên"
system: "Hệ thống"
switchUi: "Chuyển đổi giao diện người dùng"
desktop: "Desktop"
clip: "Ghim"
clip: "Lưu bài viết"
createNew: "Tạo mới"
optional: "Không bắt buộc"
createNewClip: "Tạo một ghim mới"
@@ -667,7 +686,7 @@ pageLikesCount: "Số lượng trang đã thích"
pageLikedCount: "Số lượng thích trang đã nhận"
contact: "Liên hệ"
useSystemFont: "Dùng phông chữ mặc định của hệ thống"
clips: "Ghim"
clips: "Lưu bài viết"
experimentalFeatures: "Tính năng thử nghiệm"
developer: "Nhà phát triển"
makeExplorable: "Không hiện tôi trong \"Khám phá\""
@@ -693,6 +712,7 @@ accentColor: "Màu phụ"
textColor: "Màu chữ"
saveAs: "Lưu thành"
advanced: "Nâng cao"
advancedSettings: "Cài đặt nâng cao"
value: "Giá trị"
createdAt: "Ngày tạo"
updatedAt: "Cập nhật lúc"
@@ -758,6 +778,7 @@ popularPosts: "Tút được xem nhiều nhất"
shareWithNote: "Chia sẻ kèm với tút"
ads: "Quảng cáo"
expiration: "Thời hạn"
startingperiod: "Thời gian bắt đầu\n"
memo: "Lưu ý"
priority: "Ưu tiên"
high: "Cao"
@@ -790,6 +811,7 @@ lastCommunication: "Lần giao tiếp cuối"
resolved: "Đã xử lý"
unresolved: "Chờ xử lý"
breakFollow: "Xóa người theo dõi"
breakFollowConfirm: "Bạn bỏ theo dõi tài khoản này không?"
itsOn: "Đã bật"
itsOff: "Đã tắt"
emailRequiredForSignup: "Yêu cầu địa chỉ email khi đăng ký"
@@ -824,16 +846,19 @@ instanceDefaultLightTheme: "Theme máy chủ Sáng-Rộng"
instanceDefaultDarkTheme: "Theme máy chủ Tối-Rộng"
instanceDefaultThemeDescription: "Nhập mã theme trong định dạng đối tượng."
mutePeriod: "Thời hạn ẩn"
period: "Thời hạn"
indefinitely: "Vĩnh viễn"
tenMinutes: "10 phút"
oneHour: "1 giờ"
oneDay: "1 ngày"
oneWeek: "1 tuần"
oneMonth: "1 tháng"
reflectMayTakeTime: "Có thể mất một thời gian để điều này được áp dụng."
failedToFetchAccountInformation: "Không thể lấy thông tin tài khoản"
rateLimitExceeded: "Giới hạn quá mức"
cropImage: "Cắt hình ảnh"
cropImageAsk: "Bạn có muốn cắt ảnh này?"
cropNo: "Để nguyên"
file: "Tập tin"
recentNHours: "{n}h trước"
recentNDays: "{n} ngày trước"
@@ -876,15 +901,231 @@ navbar: "Thanh điều hướng"
shuffle: "Xáo trộn"
account: "Tài khoản của bạn"
move: "Di chuyển"
pushNotification: "Thông báo đẩy"
subscribePushNotification: "Bật thông báo đẩy"
unsubscribePushNotification: "Tắt thông báo đẩy"
pushNotificationAlreadySubscribed: "Đang bật thông báo đẩy"
sendPushNotificationReadMessage: "Xóa thông báo đẩy sau khi đọc thông báo hay tin nhắn"
sendPushNotificationReadMessageCaption: "Thông báo như {emptyPushNotificationMessage} sẽ hiển thị trong giây phút. Tiêu tốn pin của máy bạn có thể tăng lên hơn nữa."
windowMaximize: "Phóng to"
windowRestore: "Khôi phục"
caption: "Mô tả"
loggedInAsBot: "Đang đăng nhập bằng tài khoản Bot"
tools: "Công Cụ"
cannotLoad: "Không tải được"
numberOfProfileView: "Số lần mở hồ sơ"
like: "Thích"
unlike: "Bỏ lượt thích"
numberOfLikes: "Lượt thích"
show: "Hiển thị"
neverShow: "Không hiển thị nữa"
remindMeLater: "Để sau"
didYouLikeMisskey: "Bạn có ưa thích Mískey không?"
pleaseDonate: "Misskey là phần mềm miễn phí mà {host} đang sử dụng. Xin mong bạn quyên góp cho chúng tôi để chúng tôi có thể tiếp tục phát triển dịch vụ này. Xin cảm ơn!!"
roles: "Vai trò"
role: "Vai trò"
normalUser: "Người dùng bình thường"
undefined: "Chưa xác định"
color: "Màu sắc"
manageCustomEmojis: "Quản lý CustomEmoji"
cannotPerformTemporary: "Tạm thời không sử dụng được"
cannotPerformTemporaryDescription: "Tạm thời không sử dụng được vì lần số điều kiện quá giới hạn. Thử lại sau mọt lát nữa."
achievements: "Thành tích"
gotInvalidResponseError: "Không nhận được trả lời chủ máy"
gotInvalidResponseErrorDescription: "Chủ máy có lẻ ngừng hoạt động hoặc bảo trí. Thử lại sau một lát nữa. "
thisPostMayBeAnnoying: "Bạn đăng bài này có thể làm phiền cho người ta."
thisPostMayBeAnnoyingHome: "Đăng trên trang chính"
thisPostMayBeAnnoyingCancel: "Từ chối"
thisPostMayBeAnnoyingIgnore: "Đăng bài để nguyên"
collapseRenotes: "Không hiển thị bài viết đã từng xem"
internalServerError: "Lỗi trong chủ máy"
internalServerErrorDescription: "Trong chủ máy lỗi bất ngờ xảy ra"
copyErrorInfo: "Sao chép thông tin lỗi"
joinThisServer: "Đăng ký trên chủ máy này"
exploreOtherServers: "Tìm chủ máy khác"
letsLookAtTimeline: "Thử xem Timeline"
_achievements:
earnedAt: "Ngày thu nhận"
_types:
_notes1:
title: "just setting up my msky"
description: "Lần đầu tiên đăng bài"
flavor: "Chúc bạn trên Miskey vui vẻ nha!!"
_notes10:
title: "Một số bài viết"
description: "Đăng bài 10 lần"
_notes100:
title: "Rất nhiều bài biết"
description: "Đăng bài 100 lần"
_notes500:
title: "Như đầy bài viết"
description: "Đăng bài 500 lần"
_notes1000:
title: "Ngọn núi bài viết"
description: "Đăng bài 1000 lần"
_notes5000:
title: "Bài viết chảy như suối"
description: "Đăng bài 5000 lần"
_notes10000:
title: "Bài Viết siu nhìu"
description: "Đăng bài 10000 lần"
_notes20000:
title: "Need more note"
description: "Đã đăng bài 20,000 lần rồi"
_notes30000:
title: "ĐĂNG VỚI BÀI"
description: "Đã đăng bài 30,000 lần rồi"
_notes40000:
title: "Nhà xưởng dăng bài"
description: "Đã đăng bài 40,000 lần rồi"
_notes50000:
title: "Hàng tinh đăng bài"
description: "Đã đăng bài 50,000 lần rồi"
_notes100000:
flavor: "Liệu viết bài gì tầm này vậy? "
_login3:
title: "Sơ cấp I"
description: "Tổng số ngày đăng nhập đạt 3 ngày"
flavor: "Từ nay các bạn cứ xem như mình là một Misskist đó"
_login7:
title: "Sơ cấp II"
description: "Tổng số ngày đăng nhập đạt 7 ngày"
flavor: "Bạn dần quen chưa? "
_login15:
title: "Sơ cấp III"
description: "Tổng số ngày đăng nhập đạt 7 ngày"
_login30:
title: "Misskist cấp I"
description: "Tổng số ngày đăng nhập đạt 30 ngày"
_login60:
title: "Misskist cấp II"
description: "Tổng số ngày đăng nhập đạt 60 ngày"
_login100:
title: "Misskist cấp III"
description: "Tổng số ngày đăng nhập đạt 100 ngày"
flavor: "Người dùng này, chính vì đó là một Misskist"
_login200:
title: "Khách hàng thường xuyên cấp I"
description: "Tổng số ngày đăng nhập đạt 200 ngày"
_login300:
title: "Khách hàng thường xuyên cấp II"
description: "Tổng số ngày đăng nhập đạt 300 ngày"
_login400:
title: "Khách hàng thường xuyên cấp III"
description: "Tổng số ngày đăng nhập đạt 400 ngày"
_markedAsCat:
title: "Tôi là một con mèo"
description: "Bật chế độ mèo"
flavor: "Mà tên chưa có"
_following1:
title: "Theo dõi đầu tiên"
description: "Lần đầu tiên theo dõi "
_following10:
title: "Cứ theo dõi và theo dõi"
description: "Vừa theo dõi hơn 10 người"
_following50:
title: "Bạn bè nhiều quá"
description: "Vừa theo dõi hơn 50 người"
_following100:
title: "Trăm bạn bè"
description: "Vừa theo dõi vượt lên 100 người"
_following300:
title: "Quá nhiều bạn bè"
description: "Vừa theo dõi vượt lên 300 người"
_followers1:
title: "Ai đầu tiên theo dõi bạn"
description: "Lần đầu tiên được theo dõi"
_followers10:
title: "FOLLOW ME!!"
description: "Người theo dõi bạn vượt lên 10 người"
_followers500:
title: "Trạm phát sóng"
_followers1000:
title: "Người có tầm ảnh hưởng"
description: "Người theo dõi bạn vượt lên 1000 người"
_collectAchievements30:
title: "Người sưu tập thành tích"
description: "Vừa lấy thành tích hơn 30 cái"
_viewAchievements3min:
title: "Yêu Thành tích"
description: "Ngắm danh sách thành tích đến tận hơn 3 phút"
_iLoveMisskey:
title: "Tôi Yêu Misskey"
description: "Đăng lời nói \"I ❤ #Misskey\""
flavor: "Xin chân thành cảm ơn bạn đã sử dụng Misskey!! by Đội ngũ phát triển"
_foundTreasure:
title: "Tìm kiếm kho báu"
description: "Tìm thấy được những kho báu cất giấu"
_client30min:
title: "Giải lao xỉu"
_noteDeletedWithin1min:
title: "Xem như không có gì đâu nha"
_postedAtLateNight:
title: "Loài ăn đêm"
description: "Đăng bài trong đêm khuya "
_postedAt0min0sec:
title: "Tín hiệu báo giờ"
description: "Đăng bài vào 0 phút 0 giây"
flavor: "Piiiiiii ĐÂY LÀ TIẾNG NÓI VIỆT NAM"
_selfQuote:
title: "Nói đến bản thân"
description: "Trích dẫn bài viết của mình"
_htl20npm:
title: "Timeline trôi như con sông"
description: "Timeline trang chính tốc độ vượt lên 20npm"
_viewInstanceChart:
title: "Nhà phân tích"
description: "Xem biểu đồ của chủ máy"
_outputHelloWorldOnScratchpad:
title: "Chào thế giới!"
_open3windows:
title: "Nhiều cửa sổ"
description: "Mở cửa sổ hơn 3 cửa sổ"
_reactWithoutRead:
title: "Bài này bạn đọc kỹ chứ? "
description: "Phản hồi trong vọng 3 giây sau bài viết có hơn 100 ký tự mới được đăng lên"
_clickedClickHere:
title: "Bấm đây"
description: "Bấm chỗ này"
_justPlainLucky:
title: "Chỉ là một cuộc máy mắn"
description: "Mỗi 10 giây thu nhận được với tỷ lệ 0.005%"
_setNameToSyuilo:
title: "Ngưỡng mộ với vị thần"
description: "Đạt tên là syuilo"
_loggedInOnBirthday:
title: "Sinh nhật vủi vẻ"
description: "Đăng nhập vào ngày sinh"
_loggedInOnNewYearsDay:
title: "Chức mừng năm mới"
description: "Đăng nhập vào Tết Nguyên đàn dương lịch"
flavor: "Chúc bạn năm mới AN KHANG THỊNH VƯỢNG, VẠN SỰ NHƯ Ý!!"
_cookieClicked:
flavor: "Bạn nhầm phầm mềm chứ?"
_role:
priority: "Ưu tiên"
_priority:
low: "Thấp"
middle: "Vừa"
high: "Cao"
_options:
gtlAvailable: "Xem Timeline xã hội"
ltlAvailable: "Xem Timeline trong máy chủ này"
canPublicNote: "Cho phép đăng bài công khai"
canManageCustomEmojis: "Quản lý CustomEmoji"
driveCapacity: "Dữ liệu Drive"
pinMax: "Giới hạn ghim bài viết"
antennaMax: "Giới hạn tạo ăng ten"
canHideAds: "Tắt quảng cáo"
_condition:
createdMoreThan: "Trôi qua sau khi lập tài khoản"
followersLessThanOrEq: "Người theo dõi ít hơn "
followersMoreThanOrEq: "Người theo dõi có trở lên"
followingLessThanOrEq: "Theo dõi ít hơn "
followingMoreThanOrEq: "Theo dõi có trở lên"
and: ""
or: " hay là "
not: "Không phải "
_sensitiveMediaDetection:
description: "Giảm nỗ lực kiểm duyệt máy chủ thông qua việc tự động nhận dạng media NSFW thông qua học máy. Điều này sẽ làm tăng một chút áp lực trên máy chủ."
sensitivity: "Phát hiện nhạy cảm"
@@ -1131,15 +1372,23 @@ _tutorial:
step7_1: "Xin chúc mừng! Bây giờ bạn đã hoàn thành phần hướng dẫn cơ bản của Misskey."
step7_2: "Nếu bạn muốn tìm hiểu thêm về Misskey, hãy thử phần {help}."
step7_3: "Bây giờ, chúc may mắn và vui vẻ với Misskey! 🚀"
step8_1: "Cuối cùng, bạn hãy bật thông báo đẩy nha!"
step8_2: "Nhận thông báo đẩy bạn sẽ có thể thấy phản hồi, theo dõi, lượt nhắc được trong khi đóng Misskey"
_2fa:
alreadyRegistered: "Bạn đã đăng ký thiết bị xác minh 2 bước."
passwordToTOTP: "Nhắn mật mã"
step1: "Trước tiên, hãy cài đặt một ứng dụng xác minh (chẳng hạn như {a} hoặc {b}) trên thiết bị của bạn."
step2: "Sau đó, quét mã QR hiển thị trên màn hình này."
step2Url: "Bạn cũng có thể nhập URL này nếu sử dụng một chương trình máy tính:"
step3: "Nhập mã token do ứng dụng của bạn cung cấp để hoàn tất thiết lập."
step4: "Kể từ bây giờ, những lần đăng nhập trong tương lai sẽ yêu cầu mã token đăng nhập đó."
securityKeyInfo: "Bên cạnh xác minh bằng vân tay hoặc mã PIN, bạn cũng có thể thiết lập xác minh thông qua khóa bảo mật phần cứng hỗ trợ FIDO2 để bảo mật hơn nữa cho tài khoản của mình."
removeKey: "Xóa mã bảo mật"
removeKeyConfirm: "Xóa bản sao lưu {name}?"
renewTOTP: "Cài đặt lại ứng dụng xác thực"
renewTOTPConfirm: "Mã xác nhận cũ của ứng dụng xác thực không thể sử dụng được nữa"
renewTOTPOk: "Cài đặt lại"
renewTOTPCancel: "Không, cảm ơn"
_permissions:
"read:account": "Xem thông tin tài khoản của bạn"
"write:account": "Sửa thông tin tài khoản của bạn"
@@ -1174,12 +1423,15 @@ _permissions:
"read:gallery-likes": "Xem danh sách các tút đã thích trong thư viện của tôi"
"write:gallery-likes": "Sửa danh sách các tút đã thích trong thư viện của tôi"
_auth:
shareAccessTitle: "Cho phép truy cập app"
shareAccess: "Bạn có muốn cho phép \"{name}\" truy cập vào tài khoản này không?"
shareAccessAsk: "Bạn có chắc muốn cho phép ứng dụng này truy cập vào tài khoản của mình không?"
permission: "{name} đang yêu cầu quyền hạn dưới đây"
permissionAsk: "Ứng dụng này yêu cầu các quyền sau"
pleaseGoBack: "Vui lòng quay lại ứng dụng"
callback: "Quay lại ứng dụng"
denied: "Truy cập bị từ chối"
pleaseLogin: "Bạn phải đăng nhập để cho ứng dụng phép truy cập"
_antennaSources:
all: "Toàn bộ tút"
homeTimeline: "Tút từ những người đã theo dõi"
@@ -1217,9 +1469,12 @@ _widgets:
jobQueue: "Công việc chờ xử lý"
serverMetric: "Thống kê máy chủ"
aiscript: "AiScript console"
aiscriptApp: "AiScript App"
aichan: "Ai"
userList: "Danh sách người dùng"
_userList:
chooseList: "Chọn danh sách"
clicker: "clicker"
_cw:
hide: "Ẩn"
show: "Tải thêm"
@@ -1256,6 +1511,8 @@ _visibility:
followersDescription: "Dành riêng cho người theo dõi"
specified: "Nhắn riêng"
specifiedDescription: "Chỉ người được nhắc đến mới thấy"
disableFederation: "Không liên hợp"
disableFederationDescription: "Không đưa tin cho chủ máy khác"
_postForm:
replyPlaceholder: "Trả lời tút này"
quotePlaceholder: "Trích dẫn tút này"
@@ -1265,7 +1522,7 @@ _postForm:
b: "Hôm nay bạn có gì vui?"
c: "Bạn đang nghĩ gì?"
d: "Bạn muốn nói gì?"
e: "Bắt đầu viết..."
e: "Cứ viết trên đây"
f: "Đang chờ bạn viết..."
_profile:
name: "Tên"
@@ -1281,6 +1538,7 @@ _profile:
changeBanner: "Đổi ảnh bìa"
_exportOrImport:
allNotes: "Toàn bộ tút"
favoritedNotes: "Bài viết đã thích"
followingList: "Đang theo dõi"
muteList: "Ẩn"
blockingList: "Chặn"
@@ -1319,7 +1577,16 @@ _timelines:
social: "Xã hội"
global: "Liên hợp"
_play:
new: "Tạo Play mới"
edit: "Edit play"
created: "Bạn vừa tạo play rồi"
updated: "Bạn vừa cập nhật play rồi"
deleted: "Bạn vừa xóa play rồi"
pageSetting: "Cài đặt play"
editThisPage: "Edit play này"
viewSource: "Xem mã nguồn"
my: "Play của mình"
liked: "Play đã thích"
featured: "Nổi tiếng"
title: "Tựa đề"
script: "Kịch bản"
@@ -1387,7 +1654,9 @@ _notification:
youReceivedFollowRequest: "Bạn vừa có một yêu cầu theo dõi"
yourFollowRequestAccepted: "Yêu cầu theo dõi của bạn đã được chấp nhận"
pollEnded: "Cuộc bình chọn đã kết thúc"
unreadAntennaNote: "Ăng ten"
emptyPushNotificationMessage: "Đã cập nhật thông báo đẩy"
achievementEarned: "Hoàn thành Achievement"
_types:
all: "Toàn bộ"
follow: "Đang theo dõi"
@@ -1399,6 +1668,7 @@ _notification:
pollEnded: "Bình chọn kết thúc"
receiveFollowRequest: "Yêu cầu theo dõi"
followRequestAccepted: "Yêu cầu theo dõi được chấp nhận"
achievementEarned: "Hoàn thành Achievement"
app: "Từ app liên kết"
_actions:
followBack: "đã theo dõi lại bạn"
@@ -1431,3 +1701,10 @@ _deck:
channel: "Kênh"
mentions: "Lượt nhắc"
direct: "Nhắn riêng"
_dialog:
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}"
_webhookSettings:
name: "Tên"
active: "Đã bật"

View File

@@ -2,7 +2,7 @@
_lang_: "中文(简体)"
headlineMisskey: "通过帖子连接在一起的网络"
introMisskey: "欢迎Misskey是一个开源的、去中心化的“微博客”服务。\n通过编写「帖文」来和大家分享你的以及你周围的事情吧📡\n通过「回应」功能可以让你快速地对大家的帖文表达反馈👍\n来探索新的世界吧🚀"
poweredByMisskeyDescription: "{name} 开源平台 <b>Misskey</b> 驱动(也被称为 Misskey 实例)"
poweredByMisskeyDescription: "{name} 开源平台 <b>Misskey</b> 的服务器之一。"
monthAndDay: "{month}月 {day}日"
search: "搜索"
notifications: "通知"
@@ -18,7 +18,7 @@ enterUsername: "输入用户名"
renotedBy: "由 {user} 转贴"
noNotes: "没有帖子"
noNotifications: "无通知"
instance: "实例"
instance: "服务器"
settings: "设置"
basicSettings: "基本设置"
otherSettings: "其他设置"
@@ -122,6 +122,8 @@ unmarkAsSensitive: "取消标记为敏感内容"
enterFileName: "请输入文件名"
mute: "屏蔽"
unmute: "解除屏蔽"
renoteMute: "屏蔽转帖"
renoteUnmute: "解除屏蔽转帖"
block: "拉黑"
unblock: "取消拉黑"
suspend: "冻结"
@@ -144,7 +146,7 @@ emojiUrl: "表情符号地址"
addEmoji: "添加表情符号"
settingGuide: "推荐配置"
cacheRemoteFiles: "远程文件缓存"
cacheRemoteFilesDescription: "当禁用此设定时远程文件将直接从远程实例载入。禁用后会减小储存空间需求,但是会增加流量,因为缩略图不会被生成。"
cacheRemoteFilesDescription: "当禁用此设定时远程文件将直接从远程服务器载入。禁用后会减小储存空间需求,但是会增加流量,因为缩略图不会被生成。"
flagAsBot: "这是一个机器人账号"
flagAsBotDescription: "如果此帐户由程序控制请启用此项。启用后此标志可以帮助其他开发人员防止机器人之间产生无限互动的行为并让Misskey的内部系统将此帐户识别为机器人。"
flagAsCat: "将这个账户设定为一只猫"
@@ -153,8 +155,9 @@ flagShowTimelineReplies: "在时间线上显示帖子的回复"
flagShowTimelineRepliesDescription: "启用时,时间线除了显示用户的帖子外,还会显示其他用户对帖子的回复。"
autoAcceptFollowed: "自动允许关注者的关注"
addAccount: "添加账户"
reloadAccountsList: "更新账户列表"
loginFailed: "登录失败"
showOnRemote: "转到所在实例显示"
showOnRemote: "转到所在服务器显示"
general: "常规设置"
wallpaper: "壁纸"
setWallpaper: "设置壁纸"
@@ -169,7 +172,7 @@ selectUser: "选择用户"
recipient: "收件人"
annotation: "注解"
federation: "联合"
instances: "实例"
instances: "服务器"
registeredAt: "初次观测"
latestRequestReceivedAt: "上次收到的请求"
latestStatus: "最后状态"
@@ -178,7 +181,7 @@ charts: "图表"
perHour: "每小时"
perDay: "每天"
stopActivityDelivery: "停止发送活动"
blockThisInstance: "阻止此实例向本实例推流"
blockThisInstance: "阻止此服务器向本服务器推流"
operations: "操作"
software: "软件"
version: "版本"
@@ -189,15 +192,15 @@ jobQueue: "作业队列"
cpuAndMemory: "CPU和内存"
network: "网络"
disk: "存储"
instanceInfo: "实例信息"
instanceInfo: "服务器信息"
statistics: "统计"
clearQueue: "清除队列"
clearQueueConfirmTitle: "确定清除队列?"
clearQueueConfirmText: "未送达的帖子将不会送达。 通常,您不需要这样做。"
clearCachedFiles: "清除缓存"
clearCachedFilesConfirm: "确定要清除缓存文件?"
blockedInstances: "被阻拦的实例"
blockedInstancesDescription: "设定要阻拦的实例,以换行来进行分割。被阻拦的实例将无法与本实例进行交换通讯。"
blockedInstances: "被阻拦的服务器"
blockedInstancesDescription: "设定要阻拦的服务器,以换行来进行分割。被阻拦的服务器将无法与本服务器进行交换通讯。"
muteAndBlock: "屏蔽/拉黑"
mutedUsers: "已屏蔽用户"
blockedUsers: "被拉黑的用户"
@@ -220,9 +223,9 @@ all: "全部"
subscribing: "已订阅"
publishing: "投递中"
notResponding: "没有响应"
instanceFollowing: "关注实例"
instanceFollowers: "关注实例"
instanceUsers: "实例用户"
instanceFollowing: "关注服务器"
instanceFollowers: "关注的服务器"
instanceUsers: "服务器用户"
changePassword: "修改密码"
security: "安全"
retypedNotMatch: "两次输入不一致!"
@@ -264,7 +267,7 @@ basicNotesBeforeCreateAccount: "基本注意事项"
tos: "服务条款"
start: "开始"
home: "首页"
remoteUserCaution: "由于此用户来自其它实例,显示的信息可能不完整。"
remoteUserCaution: "由于此用户来自其它服务器,显示的信息可能不完整。"
activity: "活动"
images: "图片"
birthday: "生日"
@@ -314,8 +317,8 @@ unwatch: "取消关注"
accept: "允许"
reject: "拒绝"
normal: "正常"
instanceName: "实例名称"
instanceDescription: "实例介绍"
instanceName: "服务器名称"
instanceDescription: "服务器简介"
maintainerName: "管理员名称"
maintainerEmail: "管理员电子邮箱"
tosUrl: "服务条款URL"
@@ -345,7 +348,7 @@ basicInfo: "基本信息"
pinnedUsers: "置顶用户"
pinnedUsersDescription: "在「发现」页面中使用换行标记想要置顶的用户。"
pinnedPages: "固定页面"
pinnedPagesDescription: "输入您要固定到实例首页的页面路径,以换行符分隔。"
pinnedPagesDescription: "输入您要固定到服务器首页的页面路径,以换行符分隔。"
pinnedClipId: "置顶的便签ID"
pinnedNotes: "已置顶的帖子"
hcaptcha: "hCaptcha"
@@ -355,7 +358,7 @@ hcaptchaSecretKey: "hCaptcha 密钥(SecretKey)"
recaptcha: "reCAPTCHA"
enableRecaptcha: "启用 reCAPTCHA\n(请注意, 此功能在中国大陆不可用. 如果启用, 可能导致无法正常使用登录或注册等功能)"
recaptchaSiteKey: "网站密钥"
recaptchaSecretKey: "reCAPTCHA 密钥"
recaptchaSecretKey: "reCAPTCHA 密钥(SecretKey)"
turnstile: "Turnstile"
enableTurnstile: "启用Turnstile"
turnstileSiteKey: "网站密钥"
@@ -457,6 +460,7 @@ aboutX: "关于 {x}"
emojiStyle: "emoji 的样式"
native: "原生"
disableDrawer: "不显示抽屉菜单"
showNoteActionsOnlyHover: "仅在悬停时显示帖子操作"
noHistory: "没有历史记录"
signinHistory: "登录历史"
enableAdvancedMfm: "启用扩展MFM"
@@ -488,7 +492,7 @@ showFeaturedNotesInTimeline: "在时间线上显示热门推荐"
objectStorage: "对象存储"
useObjectStorage: "使用对象存储"
objectStorageBaseUrl: "Base URL"
objectStorageBaseUrlDesc: "用于引用的URL如果您正在使用CDN或反向代理请指定其URL例如S3“https://<bucket>.s3.amazonaws.com”GCS“https://storage.googleapis.com/<bucket>”"
objectStorageBaseUrlDesc: "这里是用于参考的URL如果您正在使用CDN或反向代理请指定其URL例如S3“https://<bucket>.s3.amazonaws.com”GCS“https://storage.googleapis.com/<bucket>”"
objectStorageBucket: "存储桶"
objectStorageBucketDesc: "请指定使用的对象存储服务的存储桶名称。"
objectStoragePrefix: "前缀"
@@ -505,6 +509,7 @@ objectStorageSetPublicRead: "上传时设置为public-read"
serverLogs: "服务器日志"
deleteAll: "全部删除"
showFixedPostForm: "在时间线顶部显示发帖框"
showFixedPostFormInChannel: "在时间线顶部显示发帖对话框(频道)"
newNoteRecived: "有新的帖子"
sounds: "提示音"
sound: "提示音"
@@ -537,11 +542,15 @@ updateRemoteUser: "更新远程用户信息"
deleteAllFiles: "删除所有文件"
deleteAllFilesConfirm: "要删除所有文件吗?"
removeAllFollowing: "取消所有关注"
removeAllFollowingDescription: "取消{host}的所有关注者。当实例不存在时执行。"
removeAllFollowingDescription: "取消{host}的所有关注者。当服务器不再存在时执行。"
userSuspended: "该用户已被冻结。"
userSilenced: "该用户已被禁言。"
yourAccountSuspendedTitle: "账户已被冻结"
yourAccountSuspendedDescription: "由于违反了服务器的服务条款或其他原因,该账户已被冻结。 您可以与管理员联系以了解更多信息。 请不要创建一个新的账户。"
tokenRevoked: "令牌无效"
tokenRevokedDescription: "登录令牌已经失效。请重新登录。"
accountDeleted: "帐户已删除"
accountDeletedDescription: "此帐户已经被删除。"
menu: "菜单"
divider: "分割线"
addItem: "添加项目"
@@ -585,7 +594,6 @@ tokenRequested: "允许访问账户"
pluginTokenRequestedDescription: "此插件将能够拥有此处设置的权限"
notificationType: "通知类型"
edit: "编辑"
useStarForReactionFallback: "如果回应的是未知表情符号,则使用★作为代替"
emailServer: "邮件服务器"
enableEmail: "启用发送邮件功能"
emailConfigInfo: "用于确认电子邮件和密码重置"
@@ -634,15 +642,15 @@ abuseReported: "内容已发送。感谢您提交信息。"
reporter: "举报者"
reporteeOrigin: "举报来源"
reporterOrigin: "举报者来源"
forwardReport: "将该举报信息转发给远程实例"
forwardReportIsAnonymous: "勾选则在远程实例上显示的举报者是匿名的系统账号,而不是您的账号。"
forwardReport: "将该举报信息转发给远程服务器"
forwardReportIsAnonymous: "勾选则在远程服务器上显示的举报者是匿名的系统账号,而不是您的账号。"
send: "发送"
abuseMarkAsResolved: "处理完毕"
openInNewTab: "在新标签页中打开"
openInSideView: "在侧边栏中打开"
defaultNavigationBehaviour: "默认导航"
editTheseSettingsMayBreakAccount: "编辑这些设置可以会损坏您的账号"
instanceTicker: "帖子的实例信息"
instanceTicker: "帖子的服务器来源"
waitingFor: "等待{x}"
random: "随机"
system: "系统"
@@ -731,7 +739,7 @@ capacity: "容量"
inUse: "已使用"
editCode: "编辑代码"
apply: "应用"
receiveAnnouncementFromInstance: "从实例接收通知"
receiveAnnouncementFromInstance: "从服务器接收通知"
emailNotification: "邮件通知"
publish: "发布"
inChannelSearch: "频道内搜索"
@@ -759,7 +767,7 @@ active: "活动"
offline: "离线"
notRecommended: "不推荐"
botProtection: "Bot防御"
instanceBlocking: "被阻拦的实例"
instanceBlocking: "被阻拦的服务器"
selectAccount: "选择账户"
switchAccount: "切换账户"
enabled: "已启用"
@@ -806,7 +814,7 @@ translatedFrom: "从 {x} 翻译"
accountDeletionInProgress: "正在删除账户"
usernameInfo: "在服务器上唯一标识您的帐户的名称。您可以使用字母 (a ~ z, A ~ Z)、数字 (0 ~ 9) 和下划线 (_)。用户名以后不能更改。"
aiChanMode: "小蓝模式"
keepCw: "保留CW"
keepCw: "回复时维持隐藏内容"
pubSub: "Pub/Sub账户"
lastCommunication: "最近通信"
resolved: "已解决"
@@ -843,15 +851,17 @@ themeColor: "主题颜色"
size: "大小"
numberOfColumn: "列数"
searchByGoogle: "Google"
instanceDefaultLightTheme: "实例默认浅色主题"
instanceDefaultDarkTheme: "实例默认深色主题"
instanceDefaultLightTheme: "服务器默认浅色主题"
instanceDefaultDarkTheme: "服务器默认深色主题"
instanceDefaultThemeDescription: "以对象格式键入主题代码"
mutePeriod: "屏蔽期限"
period: "截止时间"
indefinitely: "永久"
tenMinutes: "10分钟"
oneHour: "1小时"
oneDay: "1天"
oneWeek: "1周"
oneMonth: "1 个月"
reflectMayTakeTime: "可能需要一些时间才能体现出效果。"
failedToFetchAccountInformation: "获取账户信息失败"
rateLimitExceeded: "已超過速率限制"
@@ -895,7 +905,7 @@ cannotUploadBecauseInappropriate: "因为可能含有不适宜的内容,无法
cannotUploadBecauseNoFreeSpace: "因为已无可用空间,无法上传。"
beta: "测试"
enableAutoSensitive: "自动 NSFW 识别"
enableAutoSensitiveDescription: "如果可用,请使用机器学习在媒体上自动设置 NSFW 标志。即使关闭此功能,也可能会根据实例自动设置。"
enableAutoSensitiveDescription: "如果可用,请使用机器学习在媒体上自动设置 NSFW 标志。即使关闭此功能,也可能会根据服务器自动设置。"
activeEmailValidationDescription: "开启用户的电子邮件地址验证,判断它是一次性的电子邮件地址,还是可以实际通信的地址。关闭时,则只检查字符串是否正确。"
navbar: "导航栏"
shuffle: "随机"
@@ -905,7 +915,7 @@ pushNotification: "推送通知"
subscribePushNotification: "启用推送通知消息"
unsubscribePushNotification: "停用推送通知消息"
pushNotificationAlreadySubscribed: "推送通知消息已启用"
pushNotificationNotSupported: "浏览器或实例不支持推送通知消息"
pushNotificationNotSupported: "浏览器或服务器不支持推送通知消息"
sendPushNotificationReadMessage: "删除已读推送通知消息"
sendPushNotificationReadMessageCaption: "“{emptyPushNotificationMessage}”的通知消息将会显示。您终端设备的电池消耗可能会增加。"
windowMaximize: "最大化"
@@ -947,10 +957,29 @@ collapseRenotes: "省略显示已经看过的转发内容"
internalServerError: "内部服务器错误"
internalServerErrorDescription: "内部服务器发生了预期外的错误"
copyErrorInfo: "复制错误信息"
joinThisServer: "在本实例上注册"
exploreOtherServers: "探索其他实例"
joinThisServer: "在本服务器上注册"
exploreOtherServers: "探索其他服务器"
letsLookAtTimeline: "时间线"
disableFederationWarn: "联合被禁用。 禁用它并不能使帖子变成私人的。 在大多数情况下,这个选项不需要被启用。"
invitationRequiredToRegister: "此服务器目前只允许拥有邀请码的人注册。"
emailNotSupported: "此服务器不支持发送邮件"
postToTheChannel: "发布到频道"
cannotBeChangedLater: "之后不能再更改。"
reactionAcceptance: "接受表情回应"
likeOnly: "仅点赞"
likeOnlyForRemote: "远程仅点赞"
rolesAssignedToMe: "指派给自己的角色"
resetPasswordConfirm: "确定重置密码?"
sensitiveWords: "敏感词"
sensitiveWordsDescription: "将包含设置词的帖子的可见范围设置为首页。可以通过用换行符分隔来设置多个。"
notesSearchNotAvailable: "帖子检索不可用"
license: "许可信息"
unfavoriteConfirm: "确定要取消收藏吗?"
myClips: "我的便签"
drivecleaner: "网盘整理"
retryAllQueuesNow: "立刻重试所有队列"
retryAllQueuesConfirmTitle: "要再尝试一次吗?"
retryAllQueuesConfirmText: "可能会使服务器负荷在一定时间内增加"
_achievements:
earnedAt: "达成时间"
_types:
@@ -1123,7 +1152,7 @@ _achievements:
title: "休息一下!"
description: "启动客户端超过30分钟"
_noteDeletedWithin1min:
title: "无话可说"
title: "欲言又止"
description: "发帖后一分钟内就将其删除"
_postedAtLateNight:
title: "夜猫子"
@@ -1141,7 +1170,7 @@ _achievements:
description: "在首页时间线的流速超过20npm"
_viewInstanceChart:
title: "分析师"
description: "查看了实例信息中的图表"
description: "查看了服务器信息中的图表"
_outputHelloWorldOnScratchpad:
title: "Hello, world!"
description: "在AiScript控制台中输出 hello world"
@@ -1178,7 +1207,7 @@ _achievements:
_loggedInOnNewYearsDay:
title: "恭贺新禧"
description: "在元旦登入"
flavor: "今年也请对本实例多多指教!"
flavor: "今年也请对本服务器多多指教!"
_cookieClicked:
title: "点击饼干小游戏"
description: "点击了可疑的饼干"
@@ -1193,7 +1222,7 @@ _role:
name: "角色名称"
description: "角色描述"
permission: "角色权限"
descriptionOfPermission: "<b>监察员</b>可以执行基本审核操作。\n<b>管理员</b>可以更改实例的所有设置。"
descriptionOfPermission: "<b>监察员</b>可以执行基本审核操作。\n<b>管理员</b>可以更改服务器的所有设置。"
assignTarget: "授权对象"
descriptionOfAssignTarget: "<b>手动</b>指手动选择谁被包括在这个角色中。\n<b>符合条件</b>指设置条件以自动包括符合条件的用户。"
manual: "手动"
@@ -1210,6 +1239,8 @@ _role:
iconUrl: "图标URL"
asBadge: "作为徽章显示"
descriptionOfAsBadge: "开启后,用户名旁边将会出现角色图标。"
displayOrder: "显示顺序"
descriptionOfDisplayOrder: "数字越大,显示位置越靠前。"
canEditMembersByModerator: "允许监察者编辑成员"
descriptionOfCanEditMembersByModerator: "如果选中,监察者和管理员都能够为用户分配/取消分配角色。如果未选中,则只有管理员可以执行此操作。"
priority: "优先级"
@@ -1235,6 +1266,7 @@ _role:
rateLimitFactor: "速率限制"
descriptionOfRateLimitFactor: "值越小限制越少,值越大限制越多。"
canHideAds: "可以隐藏广告"
canSearchNotes: "是否可以搜索帖子"
_condition:
isLocal: "是本地用户"
isRemote: "是远程用户"
@@ -1283,7 +1315,7 @@ _ad:
_forgotPassword:
enterEmail: "请输入您验证账号时用的电子邮箱地址,密码重置链接将发送至该邮箱上。"
ifNoEmail: "如果您没有使用电子邮件地址进行验证,请联系管理员。"
contactAdmin: "该实例不支持发送电子邮件。如果您想重设密码,请联系管理员。"
contactAdmin: "该服务器不支持发送电子邮件。如果您想重设密码,请联系管理员。"
_gallery:
my: "我的图库"
liked: "喜欢的图片"
@@ -1368,10 +1400,10 @@ _wordMute:
hard: "硬屏蔽"
mutedNotes: "被屏蔽的帖子"
_instanceMute:
instanceMuteDescription: "屏蔽配置实例中的所有帖子和转帖,包括实例的用户回复。"
instanceMuteDescription: "屏蔽配置服务器中的所有帖子和转帖,包括这些服务器上的用户回复。"
instanceMuteDescription2: "设置时用换行符来分隔"
title: "隐藏实例已设置的帖子。"
heading: "屏蔽实例"
title: "隐藏服务器已设置的帖子。"
heading: "屏蔽服务器"
_theme:
explore: "寻找主题"
install: "安装主题"
@@ -1430,9 +1462,9 @@ _theme:
infoFg: "信息文本"
infoWarnBg: "警告背景"
infoWarnFg: "警告文本"
cwBg: "CW 按钮背景"
cwFg: "CW 按钮文本"
cwHoverBg: "CW 按钮背景(悬停)"
cwBg: "隐藏内容按钮背景"
cwFg: "隐藏内容按钮文本"
cwHoverBg: "隐藏内容按钮背景(悬停)"
toastBg: "Toast通知背景"
toastFg: "Toast通知文本"
buttonBg: "按钮背景"
@@ -1509,7 +1541,7 @@ _2fa:
step4: "从现在开始,任何登录操作都将要求您提供动态口令。"
securityKeyNotSupported: "您的浏览器不支持安全密钥。"
registerTOTPBeforeKey: "要注册安全密钥或Passkey请先设置验证器应用程序。"
securityKeyInfo: "您可以设置使用支持FIDO2的硬件安全密钥、设备上的指纹或PIN来保护您的登录过程。"
securityKeyInfo: "注册兼容 WebAuthn 的密钥,例如支持 FIDO2 的硬件安全密钥、设备上的生物识别功能、PIN 码以及 Passkey 等。"
chromePasskeyNotSupported: "目前不支持 Chrome 的Passkey。"
registerSecurityKey: "注册安全密钥或Passkey"
securityKeyName: "输入密钥名称"
@@ -1579,7 +1611,7 @@ _weekday:
saturday: "星期六"
_widgets:
profile: "个人资料"
instanceInfo: "实例信息"
instanceInfo: "服务器信息"
memo: "便签"
notifications: "通知"
timeline: "时间线"
@@ -1593,7 +1625,7 @@ _widgets:
digitalClock: "数字时钟"
unixClock: "UNIX时钟"
federation: "联邦宇宙"
instanceCloud: "实例云"
instanceCloud: "服务器云"
postForm: "投稿窗口"
slideshow: "幻灯片展示"
button: "按钮"
@@ -1644,7 +1676,7 @@ _visibility:
specified: "指定用户"
specifiedDescription: "仅发送至指定用户"
disableFederation: "不参与联合"
disableFederationDescription: "不发送到其他实例"
disableFederationDescription: "不发送到其他服务器"
_postForm:
replyPlaceholder: "回复这个帖子..."
quotePlaceholder: "引用这个帖子..."
@@ -1660,7 +1692,7 @@ _profile:
name: "昵称"
username: "用户名"
description: "个人简介"
youCanIncludeHashtags: "你可以在个人简介中包含一#标签。"
youCanIncludeHashtags: "你可以在个人简介中包含一#标签。"
metadata: "附加信息"
metadataEdit: "附加信息编辑"
metadataDescription: "最多可以在个人资料中以表格形式显示四条其他信息。"
@@ -1836,3 +1868,13 @@ _deck:
_dialog:
charactersExceeded: "已经超过了最大字符数! 当前字符数 {current} / 限制字符数 {max}"
charactersBelow: "低于最小字符数!当前字符数 {current} / 限制字符数 {min}"
_disabledTimeline:
title: "时间线已禁用"
description: "您不能在当前角色使用时间线。"
_drivecleaner:
orderBySizeDesc: "按大小降序排列"
orderByCreatedAtAsc: "按添加日期降序排列"
_webhookSettings:
name: "名称"
active: "已启用"

View File

@@ -122,14 +122,16 @@ unmarkAsSensitive: "取消標記為敏感內容"
enterFileName: "請輸入檔案名稱"
mute: "靜音"
unmute: "解除靜音"
renoteMute: "將轉發貼文靜音"
renoteUnmute: "解除轉發貼文的靜音"
block: "封鎖"
unblock: "解除封鎖"
suspend: "凍結"
unsuspend: "解除凍結"
blockConfirm: "確定要封鎖此用戶?"
unblockConfirm: "確定解除封鎖此用戶?"
suspendConfirm: "確定凍結此帳"
unsuspendConfirm: "確定解凍此帳"
suspendConfirm: "確定凍結此帳"
unsuspendConfirm: "確定解凍此帳"
selectList: "選擇清單"
selectChannel: "選擇頻道"
selectAntenna: "選擇天線"
@@ -153,6 +155,7 @@ flagShowTimelineReplies: "在時間軸上顯示貼文的回覆"
flagShowTimelineRepliesDescription: "啟用時,時間線除了顯示用戶的貼文以外,還會顯示用戶對其他貼文的回覆。"
autoAcceptFollowed: "自動追隨中使用者的追隨請求"
addAccount: "添加帳戶"
reloadAccountsList: "更新帳戶清單的資訊"
loginFailed: "登入失敗"
showOnRemote: "轉到所在實例顯示"
general: "一般"
@@ -169,7 +172,7 @@ selectUser: "選取使用者"
recipient: "收件人"
annotation: "註解"
federation: "站台聯邦"
instances: "實例"
instances: "伺服器"
registeredAt: "初次觀測"
latestRequestReceivedAt: "上次收到的請求"
latestStatus: "最後狀態"
@@ -403,7 +406,7 @@ securityKeyAndPasskey: "安全金鑰・Passkey"
securityKey: "安全金鑰"
lastUsed: "上次使用"
lastUsedAt: "最後使用:{t}"
unregister: "註銷帳"
unregister: "註銷帳"
passwordLessLogin: "設置無密碼登入"
passwordLessLoginDescription: "不使用密碼,以安全金鑰或 Passkey 登入"
resetPassword: "重置密碼"
@@ -457,6 +460,7 @@ aboutX: "關於{x}"
emojiStyle: "表情符號的風格"
native: "原生"
disableDrawer: "不顯示下拉式選單"
showNoteActionsOnlyHover: "僅在游標停留時顯示貼文的操作選項"
noHistory: "沒有歷史紀錄"
signinHistory: "登入歷史"
enableAdvancedMfm: "啟用高級MFM"
@@ -505,6 +509,7 @@ objectStorageSetPublicRead: "上傳時設定為\"public-read\""
serverLogs: "伺服器日誌"
deleteAll: "刪除所有記錄"
showFixedPostForm: "於時間軸頁頂顯示「發送貼文」方框"
showFixedPostFormInChannel: "於時間軸頁頂顯示「發送貼文」方框(頻道)"
newNoteRecived: "發現新的貼文"
sounds: "音效"
sound: "音效"
@@ -526,8 +531,8 @@ installedDate: "安裝時間"
lastUsedDate: "最後上線日期"
state: "狀態"
sort: "排序"
ascendingOrder: "遞增"
descendingOrder: "遞減"
ascendingOrder: "昇冪"
descendingOrder: "降冪"
scratchpad: "暫存記憶體"
scratchpadDescription: "AiScript控制台為AiScript提供了實驗環境。您可以在此編寫、執行和確認代碼與Misskey互動的结果。"
output: "輸出"
@@ -542,6 +547,10 @@ userSuspended: "該使用者已被停用"
userSilenced: "該用戶已被禁言。"
yourAccountSuspendedTitle: "帳戶已被凍結"
yourAccountSuspendedDescription: "由於違反了伺服器的服務條款或其他原因,該帳戶已被凍結。 您可以與管理員連繫以了解更多訊息。 請不要創建一個新的帳戶。"
tokenRevoked: "權杖無效"
tokenRevokedDescription: "登入權杖失效,請重新登入。"
accountDeleted: "帳戶已被刪除"
accountDeletedDescription: "這個帳戶已被刪除。"
menu: "選單"
divider: "分割線"
addItem: "新增項目"
@@ -585,7 +594,6 @@ tokenRequested: "允許存取帳戶"
pluginTokenRequestedDescription: "此外掛將擁有在此設定的權限。"
notificationType: "通知形式"
edit: "編輯"
useStarForReactionFallback: "以★代替未知的表情符號"
emailServer: "電郵伺服器"
enableEmail: "啟用發送電郵功能"
emailConfigInfo: "用於確認電郵地址及密碼重置"
@@ -669,8 +677,8 @@ sentReactionsCount: "反應發送次數"
receivedReactionsCount: "收到反應次數"
pollVotesCount: "已統計的投票數"
pollVotedCount: "已投票數"
yes: "確定"
no: "取消"
yes: ""
no: ""
driveFilesCount: "雲端硬碟檔案數量"
driveUsage: "雲端硬碟使用量"
noCrawle: "拒絕搜尋引擎索引"
@@ -847,11 +855,13 @@ instanceDefaultLightTheme: "實例預設的淺色主題"
instanceDefaultDarkTheme: "實例預設的深色主題"
instanceDefaultThemeDescription: "輸入物件形式的主题代碼"
mutePeriod: "靜音的期限"
period: "期限"
indefinitely: "無期限"
tenMinutes: "10分鐘"
oneHour: "1小時"
oneDay: "1天"
oneWeek: "1週"
oneMonth: "1個月"
reflectMayTakeTime: "可能需要一些時間才會出現效果。"
failedToFetchAccountInformation: "取得帳戶資訊失敗"
rateLimitExceeded: "已超過速率限制"
@@ -868,10 +878,10 @@ recommended: "推薦"
check: "檢查"
driveCapOverrideLabel: "更改這個使用者的雲端硬碟容量上限"
driveCapOverrideCaption: "如果指定0以下的值就會被取消。"
requireAdminForView: "必須以管理員帳登入才可以檢視。"
isSystemAccount: "由系統自動建立與管理的帳。"
requireAdminForView: "必須以管理員帳登入才可以檢視。"
isSystemAccount: "由系統自動建立與管理的帳。"
typeToConfirm: "要執行這項操作,請輸入 {x} "
deleteAccount: "刪除帳"
deleteAccount: "刪除帳"
document: "文件"
numberOfPageCache: "快取頁面數"
numberOfPageCacheDescription: "增加數量會提高便利性,但也會增加負荷與記憶體使用量。"
@@ -911,7 +921,7 @@ sendPushNotificationReadMessageCaption: "「{emptyPushNotificationMessage}」通
windowMaximize: "最大化"
windowRestore: "復原"
caption: "標題"
loggedInAsBot: "以機器人帳登入中"
loggedInAsBot: "以機器人帳登入中"
tools: "工具"
cannotLoad: "無法載入"
numberOfProfileView: "個人檔案檢視次數"
@@ -951,6 +961,25 @@ joinThisServer: "在此伺服器上註冊"
exploreOtherServers: "探索其他伺服器"
letsLookAtTimeline: "看看時間軸"
disableFederationWarn: "聯邦被停用了。即使停用也不會讓您的貼文不公開,在大多數情況下,不需要啟用這個選項。"
invitationRequiredToRegister: "目前這個伺服器為邀請制,必須擁有邀請碼才能註冊。"
emailNotSupported: "這個伺服器不支援寄送郵件"
postToTheChannel: "發布到頻道"
cannotBeChangedLater: "之後不能變更。"
reactionAcceptance: "接受表情反應"
likeOnly: "僅限讚"
likeOnlyForRemote: "遠端僅限讚"
rolesAssignedToMe: "指派給自己的角色"
resetPasswordConfirm: "重設密碼?"
sensitiveWords: "敏感詞"
sensitiveWordsDescription: "將含有設定詞彙的貼文可見性設為發送至首頁。可以用換行來進行複數的設定。"
notesSearchNotAvailable: "無法使用搜尋貼文功能。"
license: "授權"
unfavoriteConfirm: "要取消收錄我的最愛嗎?"
myClips: "我的摘錄"
drivecleaner: "雲端硬碟清掃器"
retryAllQueuesNow: "立刻重試所有佇列"
retryAllQueuesConfirmTitle: "要現在重試嗎?"
retryAllQueuesConfirmText: "伺服器的負荷可能會暫時增加。"
_achievements:
earnedAt: "獲得日期"
_types:
@@ -1210,6 +1239,8 @@ _role:
iconUrl: "圖示的URL"
asBadge: "顯示為徽章"
descriptionOfAsBadge: "開啟的話,角色圖示會顯示在用戶名旁邊。"
displayOrder: "顯示順序"
descriptionOfDisplayOrder: "數字越大顯示在UI上的越上面。"
canEditMembersByModerator: "允許編輯審查員的成員"
descriptionOfCanEditMembersByModerator: "如果開啟,管理員與審查員都可以為使用者指派/解除指派該角色。如果關閉,則只有管理員可以執行。"
priority: "優先級"
@@ -1235,6 +1266,7 @@ _role:
rateLimitFactor: "速率限制"
descriptionOfRateLimitFactor: "值越小限制越少,值越大限制越多。"
canHideAds: "不顯示廣告"
canSearchNotes: "可否搜尋貼文"
_condition:
isLocal: "本地使用者"
isRemote: "遠端使用者"
@@ -1473,7 +1505,7 @@ _time:
_tutorial:
title: "Misskey使用方法"
step1_1: "歡迎!"
step1_2: "此為「時間軸」頁面,它會按照時間順序顯示你「追隨」的人發出的「貼文」"
step1_2: "此為「時間軸」頁面,它會按照時間順序顯示你「追隨」的人發出的「貼文」"
step1_3: "由於你沒有發佈任何貼文,也沒有追隨任何人,所以你的時間軸目前是空的。"
step2_1: "在發文或追隨其他人之前先讓我們設定一下個人資料吧。"
step2_2: "提供一些關於自己的資訊來讓其他人更有追隨你的意願。"
@@ -1706,7 +1738,7 @@ _instanceCharts:
_timelines:
home: "首頁"
local: "本地"
social: "社"
social: "社"
global: "公開"
_play:
new: "新增Play"
@@ -1836,3 +1868,13 @@ _deck:
_dialog:
charactersExceeded: "已超過最大字數!現在 {current} / 限制 {max}"
charactersBelow: "低於最少字數!現在 {current} / 限制 {max}"
_disabledTimeline:
title: "停用的時間軸"
description: "目前的角色無法使用這個時間軸。"
_drivecleaner:
orderBySizeDesc: "檔案由大到小"
orderByCreatedAtAsc: "依照加入的日期順序"
_webhookSettings:
name: "名稱"
active: "已啟用"

View File

@@ -1,12 +1,12 @@
{
"name": "misskey",
"version": "13.8.1",
"version": "13.10.3",
"codename": "nasubi",
"repository": {
"type": "git",
"url": "https://github.com/misskey-dev/misskey.git"
},
"packageManager": "pnpm@7.27.0",
"packageManager": "pnpm@7.29.3",
"workspaces": [
"packages/frontend",
"packages/backend",
@@ -31,8 +31,8 @@
"e2e": "pnpm start-server-and-test start:test http://localhost:61812 cy:run",
"jest": "cd packages/backend && pnpm jest",
"jest-and-coverage": "cd packages/backend && pnpm jest-and-coverage",
"test": "pnpm jest",
"test-and-coverage": "pnpm jest-and-coverage",
"test": "pnpm -r test",
"test-and-coverage": "pnpm -r test-and-coverage",
"format": "pnpm exec gulp format",
"clean": "node ./scripts/clean.js",
"clean-all": "node ./scripts/clean-all.js",
@@ -55,12 +55,12 @@
"devDependencies": {
"@types/gulp": "4.0.10",
"@types/gulp-rename": "2.0.1",
"@typescript-eslint/eslint-plugin": "5.53.0",
"@typescript-eslint/parser": "5.53.0",
"@typescript-eslint/eslint-plugin": "5.54.1",
"@typescript-eslint/parser": "5.54.1",
"cross-env": "7.0.3",
"cypress": "12.7.0",
"eslint": "8.35.0",
"start-server-and-test": "1.15.4"
"start-server-and-test": "2.0.0"
},
"optionalDependencies": {
"@tensorflow/tfjs-core": "4.2.0"

View File

@@ -19,6 +19,6 @@
</head>
<body>
<redoc spec-url="/api.json" expand-responses="200" expand-single-schema-field="true"></redoc>
<script src="https://cdn.jsdelivr.net/npm/redoc@2.0.0-rc.50/bundles/redoc.standalone.js" integrity="sha256-WJbngBWN9vp6vkEuzeoSj5tE5saW9Hfj6/SinkzhL2s=" crossorigin="anonymous"></script>
<script src="https://cdn.redoc.ly/redoc/latest/bundles/redoc.standalone.js"></script>
</body>
</html>

View File

@@ -91,7 +91,7 @@ module.exports = {
// See https://github.com/swc-project/jest/issues/64#issuecomment-1029753225
// TODO: Use `--allowImportingTsExtensions` on TypeScript 5.0 so that we can
// directly import `.ts` files without this hack.
'^(\\.{1,2}/.*)\\.js$': '$1',
'^((?:\\.{1,2}|[A-Z:])*/.*)\\.js$': '$1',
},
// An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader
@@ -160,7 +160,7 @@ module.exports = {
testMatch: [
"<rootDir>/test/unit/**/*.ts",
"<rootDir>/src/**/*.test.ts",
//"<rootDir>/test/e2e/**/*.ts"
"<rootDir>/test/e2e/**/*.ts",
],
// An array of regexp pattern strings that are matched against all test paths, matched tests are skipped
@@ -207,4 +207,13 @@ module.exports = {
// watchman: true,
extensionsToTreatAsEsm: ['.ts'],
testTimeout: 60000,
// Let Jest kill the test worker whenever it grows too much
// (It seems there's a known memory leak issue in Node.js' vm.Script used by Jest)
// https://github.com/facebook/jest/issues/11956
maxWorkers: 1, // Make it use worker (that can be killed and restarted)
logHeapUsage: true, // To debug when out-of-memory happens on CI
workerIdleMemoryLimit: '1GiB', // Limit the worker to 1GB (GitHub Workflows dies at 2GB)
};

View File

@@ -0,0 +1,16 @@
export class addRenoteMuting1665091090561 {
constructor() {
this.name = 'addRenoteMuting1665091090561';
}
async up(queryRunner) {
await queryRunner.query(`CREATE TABLE "renote_muting" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "muteeId" character varying(32) NOT NULL, "muterId" character varying(32) NOT NULL, CONSTRAINT "PK_renoteMuting_id" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE INDEX "IDX_renote_muting_createdAt" ON "muting" ("createdAt") `);
await queryRunner.query(`CREATE INDEX "IDX_renote_muting_muteeId" ON "muting" ("muteeId") `);
await queryRunner.query(`CREATE INDEX "IDX_renote_muting_muterId" ON "muting" ("muterId") `);
}
async down(queryRunner) {
}
}

View File

@@ -0,0 +1,15 @@
export class fixforeignkeyreports1675053125067 {
name = 'fixforeignkeyreports1675053125067'
async up(queryRunner) {
await queryRunner.query(`CREATE INDEX IF NOT EXISTS "IDX_a9021cc2e1feb5f72d3db6e9f5" ON "abuse_user_report" ("targetUserId")`);
await queryRunner.query(`DELETE FROM "abuse_user_report" WHERE "targetUserId" NOT IN (SELECT "id" FROM "user")`);
await queryRunner.query(`ALTER TABLE "abuse_user_report" DROP CONSTRAINT IF EXISTS "FK_a9021cc2e1feb5f72d3db6e9f5f"`);
await queryRunner.query(`ALTER TABLE "abuse_user_report" ADD CONSTRAINT "FK_a9021cc2e1feb5f72d3db6e9f5f" FOREIGN KEY ("targetUserId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
}
async down(queryRunner) {
await queryRunner.query(`DROP INDEX "public"."IDX_a9021cc2e1feb5f72d3db6e9f5"`);
await queryRunner.query(`ALTER TABLE "abuse_user_report" DROP CONSTRAINT "FK_a9021cc2e1feb5f72d3db6e9f5f"`);
}
}

View File

@@ -0,0 +1,13 @@
export class roleAssignmentExpiresAt1677570181236 {
name = 'roleAssignmentExpiresAt1677570181236'
async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "role_assignment" ADD "expiresAt" TIMESTAMP WITH TIME ZONE`);
await queryRunner.query(`CREATE INDEX "IDX_539b6c08c05067599743bb6389" ON "role_assignment" ("expiresAt") `);
}
async down(queryRunner) {
await queryRunner.query(`DROP INDEX "public"."IDX_539b6c08c05067599743bb6389"`);
await queryRunner.query(`ALTER TABLE "role_assignment" DROP COLUMN "expiresAt"`);
}
}

View File

@@ -0,0 +1,11 @@
export class perNoteReactionAcceptance1678164627293 {
name = 'perNoteReactionAcceptance1678164627293'
async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "note" ADD "reactionAcceptance" character varying(64)`);
}
async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "note" DROP COLUMN "reactionAcceptance"`);
}
}

View File

@@ -0,0 +1,68 @@
export class tweakVarcharLength1678426061773 {
name = 'tweakVarcharLength1678426061773'
async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "name" TYPE character varying(1024)`, undefined);
await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "maintainerName" TYPE character varying(1024)`, undefined);
await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "maintainerEmail" TYPE character varying(1024)`, undefined);
await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "langs" TYPE character varying(1024) array`, undefined);
await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "pinnedUsers" TYPE character varying(1024) array`, undefined);
await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "hiddenTags" TYPE character varying(1024) array`, undefined);
await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "blockedHosts" TYPE character varying(1024) array`, undefined);
await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "themeColor" TYPE character varying(1024)`, undefined);
await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "mascotImageUrl" TYPE character varying(1024)`, undefined);
await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "bannerUrl" TYPE character varying(1024)`, undefined);
await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "backgroundImageUrl" TYPE character varying(1024)`, undefined);
await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "logoImageUrl" TYPE character varying(1024)`, undefined);
await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "errorImageUrl" TYPE character varying(1024)`, undefined);
await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "iconUrl" TYPE character varying(1024)`, undefined);
await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "hcaptchaSiteKey" TYPE character varying(1024)`, undefined);
await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "hcaptchaSecretKey" TYPE character varying(1024)`, undefined);
await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "recaptchaSiteKey" TYPE character varying(1024)`, undefined);
await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "recaptchaSecretKey" TYPE character varying(1024)`, undefined);
await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "turnstileSiteKey" TYPE character varying(1024)`, undefined);
await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "turnstileSecretKey" TYPE character varying(1024)`, undefined);
await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "summalyProxy" TYPE character varying(1024)`, undefined);
await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "email" TYPE character varying(1024)`, undefined);
await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "smtpHost" TYPE character varying(1024)`, undefined);
await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "smtpUser" TYPE character varying(1024)`, undefined);
await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "smtpPass" TYPE character varying(1024)`, undefined);
await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "swPublicKey" TYPE character varying(1024)`, undefined);
await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "swPrivateKey" TYPE character varying(1024)`, undefined);
await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "deeplAuthKey" TYPE character varying(1024)`, undefined);
await queryRunner.query(`ALTER TABLE "meta" RENAME COLUMN "ToSUrl" TO "termsOfServiceUrl"`);
await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "termsOfServiceUrl" TYPE character varying(1024)`, undefined);
await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "repositoryUrl" TYPE character varying(1024)`, undefined);
await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "feedbackUrl" TYPE character varying(1024)`, undefined);
await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "objectStorageBucket" TYPE character varying(1024)`, undefined);
await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "objectStoragePrefix" TYPE character varying(1024)`, undefined);
await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "objectStorageBaseUrl" TYPE character varying(1024)`, undefined);
await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "objectStorageEndpoint" TYPE character varying(1024)`, undefined);
await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "objectStorageRegion" TYPE character varying(1024)`, undefined);
await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "objectStorageAccessKey" TYPE character varying(1024)`, undefined);
await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "objectStorageSecretKey" TYPE character varying(1024)`, undefined);
await queryRunner.query(`ALTER TABLE "flash" ALTER COLUMN "script" TYPE character varying(65536)`, undefined);
await queryRunner.query(`ALTER TABLE "__chart__active_users" ALTER COLUMN "___readWrite" TYPE integer`);
await queryRunner.query(`ALTER TABLE "__chart__active_users" ALTER COLUMN "___read" TYPE integer`);
await queryRunner.query(`ALTER TABLE "__chart__active_users" ALTER COLUMN "___write" TYPE integer`);
await queryRunner.query(`ALTER TABLE "__chart__active_users" ALTER COLUMN "___registeredWithinWeek" TYPE integer`);
await queryRunner.query(`ALTER TABLE "__chart__active_users" ALTER COLUMN "___registeredWithinMonth" TYPE integer`);
await queryRunner.query(`ALTER TABLE "__chart__active_users" ALTER COLUMN "___registeredWithinYear" TYPE integer`);
await queryRunner.query(`ALTER TABLE "__chart__active_users" ALTER COLUMN "___registeredOutsideWeek" TYPE integer`);
await queryRunner.query(`ALTER TABLE "__chart__active_users" ALTER COLUMN "___registeredOutsideMonth" TYPE integer`);
await queryRunner.query(`ALTER TABLE "__chart__active_users" ALTER COLUMN "___registeredOutsideYear" TYPE integer`);
await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ALTER COLUMN "___readWrite" TYPE integer`);
await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ALTER COLUMN "___read" TYPE integer`);
await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ALTER COLUMN "___write" TYPE integer`);
await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ALTER COLUMN "___registeredWithinWeek" TYPE integer`);
await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ALTER COLUMN "___registeredWithinMonth" TYPE integer`);
await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ALTER COLUMN "___registeredWithinYear" TYPE integer`);
await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ALTER COLUMN "___registeredOutsideWeek" TYPE integer`);
await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ALTER COLUMN "___registeredOutsideMonth" TYPE integer`);
await queryRunner.query(`ALTER TABLE "__chart_day__active_users" ALTER COLUMN "___registeredOutsideYear" TYPE integer`);
}
async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "meta" RENAME COLUMN "termsOfServiceUrl" TO "ToSUrl"`);
}
}

View File

@@ -0,0 +1,13 @@
export class removeUnused1678427401214 {
name = 'removeUnused1678427401214'
async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "pinnedPages"`);
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "pinnedClipId"`);
}
async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "meta" ADD "pinnedClipId" character varying(32)`);
await queryRunner.query(`ALTER TABLE "meta" ADD "pinnedPages" character varying(512) array NOT NULL DEFAULT '{/featured,/channels,/explore,/pages,/about-misskey}'`);
}
}

View File

@@ -0,0 +1,11 @@
export class roleDisplayOrder1678602320354 {
name = 'roleDisplayOrder1678602320354'
async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "role" ADD "displayOrder" integer NOT NULL DEFAULT '0'`);
}
async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "role" DROP COLUMN "displayOrder"`);
}
}

View File

@@ -0,0 +1,11 @@
export class sensitiveWords1678694614599 {
name = 'sensitiveWords1678694614599'
async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "meta" ADD "sensitiveWords" character varying(1024) array NOT NULL DEFAULT '{}'`);
}
async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "sensitiveWords"`);
}
}

View File

@@ -0,0 +1,14 @@
export class retentionDateKey1678869617549 {
name = 'retentionDateKey1678869617549'
async up(queryRunner) {
await queryRunner.query(`TRUNCATE TABLE "retention_aggregation"`, undefined);
await queryRunner.query(`ALTER TABLE "retention_aggregation" ADD "dateKey" character varying(512) NOT NULL`);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_f7c3576b37bd2eec966ae24477" ON "retention_aggregation" ("dateKey") `);
}
async down(queryRunner) {
await queryRunner.query(`DROP INDEX "public"."IDX_f7c3576b37bd2eec966ae24477"`);
await queryRunner.query(`ALTER TABLE "retention_aggregation" DROP COLUMN "dateKey"`);
}
}

View File

@@ -0,0 +1,11 @@
export class addPropsForCustomEmoji1678945242650 {
name = 'addPropsForCustomEmoji1678945242650'
async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "emoji" ADD "license" character varying(1024)`);
}
async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "emoji" DROP COLUMN "license"`);
}
}

View File

@@ -0,0 +1,23 @@
export class clipFavorite1678953978856 {
name = 'clipFavorite1678953978856'
async up(queryRunner) {
await queryRunner.query(`CREATE TABLE "clip_favorite" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "clipId" character varying(32) NOT NULL, CONSTRAINT "PK_1b539f43906f05ebcabe752a977" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE INDEX "IDX_25a31662b0b0cc9af6549a9d71" ON "clip_favorite" ("userId") `);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_b1754a39d0b281e07ed7c078ec" ON "clip_favorite" ("userId", "clipId") `);
await queryRunner.query(`ALTER TABLE "clip" ADD "lastClippedAt" TIMESTAMP WITH TIME ZONE`);
await queryRunner.query(`CREATE INDEX "IDX_a3eac04ae2aa9e221e7596114a" ON "clip" ("lastClippedAt") `);
await queryRunner.query(`ALTER TABLE "clip_favorite" ADD CONSTRAINT "FK_25a31662b0b0cc9af6549a9d711" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "clip_favorite" ADD CONSTRAINT "FK_fce61c7986cee54393e79f1d849" FOREIGN KEY ("clipId") REFERENCES "clip"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
}
async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "clip_favorite" DROP CONSTRAINT "FK_fce61c7986cee54393e79f1d849"`);
await queryRunner.query(`ALTER TABLE "clip_favorite" DROP CONSTRAINT "FK_25a31662b0b0cc9af6549a9d711"`);
await queryRunner.query(`DROP INDEX "public"."IDX_a3eac04ae2aa9e221e7596114a"`);
await queryRunner.query(`ALTER TABLE "clip" DROP COLUMN "lastClippedAt"`);
await queryRunner.query(`DROP INDEX "public"."IDX_b1754a39d0b281e07ed7c078ec"`);
await queryRunner.query(`DROP INDEX "public"."IDX_25a31662b0b0cc9af6549a9d71"`);
await queryRunner.query(`DROP TABLE "clip_favorite"`);
}
}

View File

@@ -0,0 +1,17 @@
export class antennaActive1679309757174 {
name = 'antennaActive1679309757174'
async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "antenna" ADD "lastUsedAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT 'now'`);
await queryRunner.query(`ALTER TABLE "antenna" ADD "isActive" boolean NOT NULL DEFAULT true`);
await queryRunner.query(`CREATE INDEX "IDX_084c2abb8948ef59a37dce6ac1" ON "antenna" ("lastUsedAt") `);
await queryRunner.query(`CREATE INDEX "IDX_36ef5192a1ce55ed0e40aa4db5" ON "antenna" ("isActive") `);
}
async down(queryRunner) {
await queryRunner.query(`DROP INDEX "public"."IDX_36ef5192a1ce55ed0e40aa4db5"`);
await queryRunner.query(`DROP INDEX "public"."IDX_084c2abb8948ef59a37dce6ac1"`);
await queryRunner.query(`ALTER TABLE "antenna" DROP COLUMN "isActive"`);
await queryRunner.query(`ALTER TABLE "antenna" DROP COLUMN "lastUsedAt"`);
}
}

View File

@@ -0,0 +1,11 @@
export class enableChartsForRemoteUser1679639483253 {
name = 'enableChartsForRemoteUser1679639483253'
async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "meta" ADD "enableChartsForRemoteUser" boolean NOT NULL DEFAULT true`);
}
async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "enableChartsForRemoteUser"`);
}
}

View File

@@ -0,0 +1,11 @@
export class cleanup1679651580149 {
name = 'cleanup1679651580149'
async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "useStarForReactionFallback"`);
}
async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "meta" ADD "useStarForReactionFallback" boolean NOT NULL DEFAULT false`);
}
}

View File

@@ -0,0 +1,11 @@
export class enableChartsForFederatedInstances1679652081809 {
name = 'enableChartsForFederatedInstances1679652081809'
async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "meta" ADD "enableChartsForFederatedInstances" boolean NOT NULL DEFAULT true`);
}
async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "enableChartsForFederatedInstances"`);
}
}

View File

@@ -15,37 +15,40 @@
"typecheck": "tsc --noEmit",
"eslint": "eslint --quiet \"src/**/*.ts\"",
"lint": "pnpm typecheck && pnpm eslint",
"jest": "cross-env NODE_ENV=test node --experimental-vm-modules --experimental-import-meta-resolve node_modules/jest/bin/jest.js --forceExit --runInBand --detectOpenHandles",
"jest-and-coverage": "cross-env NODE_ENV=test node --experimental-vm-modules --experimental-import-meta-resolve node_modules/jest/bin/jest.js --coverage --forceExit --runInBand --detectOpenHandles",
"jest": "cross-env NODE_ENV=test node --experimental-vm-modules --experimental-import-meta-resolve node_modules/jest/bin/jest.js --forceExit",
"jest-and-coverage": "cross-env NODE_ENV=test node --experimental-vm-modules --experimental-import-meta-resolve node_modules/jest/bin/jest.js --coverage --forceExit",
"jest-clear": "cross-env NODE_ENV=test node --experimental-vm-modules --experimental-import-meta-resolve node_modules/jest/bin/jest.js --clearCache",
"test": "pnpm jest",
"test-and-coverage": "pnpm jest-and-coverage"
},
"optionalDependencies": {
"@swc/core-android-arm64": "^1.3.11",
"@swc/core-darwin-arm64": "^1.3.36",
"@swc/core-darwin-x64": "^1.3.36",
"@swc/core-linux-arm-gnueabihf": "^1.3.36",
"@swc/core-linux-arm64-gnu": "^1.3.36",
"@swc/core-linux-arm64-musl": "^1.3.36",
"@swc/core-linux-x64-gnu": "^1.3.36",
"@swc/core-linux-x64-musl": "^1.3.36",
"@swc/core-win32-arm64-msvc": "^1.3.36",
"@swc/core-win32-ia32-msvc": "^1.3.36",
"@swc/core-win32-x64-msvc": "^1.3.36",
"@swc/core-darwin-arm64": "^1.3.38",
"@swc/core-darwin-x64": "^1.3.38",
"@swc/core-linux-arm-gnueabihf": "^1.3.38",
"@swc/core-linux-arm64-gnu": "^1.3.38",
"@swc/core-linux-arm64-musl": "^1.3.38",
"@swc/core-linux-x64-gnu": "^1.3.38",
"@swc/core-linux-x64-musl": "^1.3.38",
"@swc/core-win32-arm64-msvc": "^1.3.38",
"@swc/core-win32-ia32-msvc": "^1.3.38",
"@swc/core-win32-x64-msvc": "^1.3.38",
"@tensorflow/tfjs": "4.2.0",
"@tensorflow/tfjs-node": "4.2.0"
},
"dependencies": {
"@bull-board/api": "4.12.1",
"@bull-board/fastify": "4.12.1",
"@bull-board/ui": "4.12.1",
"@aws-sdk/client-s3": "^3.294.0",
"@aws-sdk/lib-storage": "^3.294.0",
"@aws-sdk/node-http-handler": "^3.292.0",
"@bull-board/api": "5.0.0",
"@bull-board/fastify": "5.0.0",
"@bull-board/ui": "5.0.0",
"@discordapp/twemoji": "14.0.2",
"@fastify/accepts": "4.1.0",
"@fastify/cookie": "8.3.0",
"@fastify/cors": "8.2.0",
"@fastify/http-proxy": "8.4.0",
"@fastify/multipart": "7.4.1",
"@fastify/multipart": "7.4.2",
"@fastify/static": "6.9.0",
"@fastify/view": "7.4.1",
"@nestjs/common": "9.3.9",
@@ -54,12 +57,11 @@
"@peertube/http-signature": "1.7.0",
"@sinonjs/fake-timers": "10.0.2",
"@swc/cli": "0.1.62",
"@swc/core": "1.3.36",
"@swc/core": "1.3.38",
"accepts": "1.3.8",
"ajv": "8.12.0",
"archiver": "5.3.1",
"autwh": "0.1.0",
"aws-sdk": "2.1318.0",
"bcryptjs": "2.4.3",
"blurhash": "2.0.5",
"bull": "4.10.4",
@@ -74,12 +76,12 @@
"date-fns": "2.29.3",
"deep-email-validator": "0.1.21",
"escape-regexp": "0.0.1",
"fastify": "4.13.0",
"fastify": "4.14.1",
"feed": "4.2.2",
"file-type": "18.2.1",
"fluent-ffmpeg": "2.1.2",
"form-data": "4.0.0",
"got": "12.5.3",
"got": "12.6.0",
"happy-dom": "8.9.0",
"hpagent": "1.2.0",
"ioredis": "4.28.5",
@@ -92,7 +94,7 @@
"jsrsasign": "10.6.1",
"mfm-js": "0.23.3",
"mime-types": "2.1.35",
"misskey-js": "0.0.15",
"misskey-js": "../misskey-js",
"ms": "3.0.0-canary.1",
"nested-property": "4.0.0",
"node-fetch": "3.3.0",
@@ -102,7 +104,7 @@
"os-utils": "0.0.14",
"otpauth": "^9.0.2",
"parse5": "7.1.2",
"pg": "8.9.0",
"pg": "8.10.0",
"private-ip": "3.0.0",
"probe-image-size": "7.2.3",
"promise-limit": "2.7.0",
@@ -124,13 +126,14 @@
"seedrandom": "3.0.5",
"semver": "7.3.8",
"sharp": "0.31.3",
"sharp-read-bmp": "github:misskey-dev/sharp-read-bmp",
"strict-event-emitter-types": "2.0.0",
"stringz": "2.1.0",
"summaly": "github:misskey-dev/summaly",
"systeminformation": "5.17.10",
"systeminformation": "5.17.12",
"tinycolor2": "1.6.0",
"tmp": "0.2.1",
"tsc-alias": "1.8.2",
"tsc-alias": "1.8.3",
"tsconfig-paths": "4.1.2",
"twemoji-parser": "14.0.0",
"typeorm": "0.3.11",
@@ -145,8 +148,7 @@
"xev": "3.0.2"
},
"devDependencies": {
"@jest/globals": "29.4.3",
"@redocly/openapi-core": "1.0.0-beta.123",
"@jest/globals": "29.5.0",
"@swc/jest": "0.2.24",
"@types/accepts": "1.3.5",
"@types/archiver": "5.3.1",
@@ -164,7 +166,7 @@
"@types/jsonld": "1.5.8",
"@types/jsrsasign": "10.5.5",
"@types/mime-types": "2.1.1",
"@types/node": "18.14.1",
"@types/node": "18.15.0",
"@types/node-fetch": "3.0.3",
"@types/nodemailer": "6.4.7",
"@types/oauth": "0.9.1",
@@ -176,7 +178,7 @@
"@types/ratelimiter": "3.4.4",
"@types/redis": "4.0.11",
"@types/rename": "1.0.4",
"@types/sanitize-html": "2.8.0",
"@types/sanitize-html": "2.8.1",
"@types/semver": "7.3.13",
"@types/sharp": "0.31.1",
"@types/sinonjs__fake-timers": "8.1.2",
@@ -188,13 +190,14 @@
"@types/web-push": "3.3.2",
"@types/websocket": "1.0.5",
"@types/ws": "8.5.4",
"@typescript-eslint/eslint-plugin": "5.52.0",
"@typescript-eslint/parser": "5.53.0",
"@typescript-eslint/eslint-plugin": "5.54.1",
"@typescript-eslint/parser": "5.54.1",
"aws-sdk-client-mock": "^2.1.1",
"cross-env": "7.0.3",
"eslint": "8.35.0",
"eslint-plugin-import": "2.27.5",
"execa": "6.1.0",
"jest": "29.4.3",
"jest-mock": "29.4.3"
"jest": "29.5.0",
"jest-mock": "29.5.0"
}
}

View File

@@ -1,3 +1,4 @@
import { setTimeout } from 'node:timers/promises';
import { Global, Inject, Module } from '@nestjs/common';
import Redis from 'ioredis';
import { DataSource } from 'typeorm';
@@ -57,6 +58,14 @@ export class GlobalModule implements OnApplicationShutdown {
) {}
async onApplicationShutdown(signal: string): Promise<void> {
if (process.env.NODE_ENV === 'test') {
// XXX:
// Shutting down the existing connections causes errors on Jest as
// Misskey has asynchronous postgres/redis connections that are not
// awaited.
// Let's wait for some random time for them to finish.
await setTimeout(5000);
}
await Promise.all([
this.db.destroy(),
this.redisClient.disconnect(),

View File

@@ -16,12 +16,14 @@ export async function server() {
app.enableShutdownHooks();
const serverService = app.get(ServerService);
serverService.launch();
await serverService.launch();
app.get(ChartManagementService).start();
app.get(JanitorService).start();
app.get(QueueStatsService).start();
app.get(ServerStatsService).start();
return app;
}
export async function jobQueue() {

View File

@@ -3,7 +3,7 @@ import type { UserProfilesRepository, UsersRepository } from '@/models/index.js'
import type { User } from '@/models/entities/User.js';
import { DI } from '@/di-symbols.js';
import { bindThis } from '@/decorators.js';
import { CreateNotificationService } from '@/core/CreateNotificationService.js';
import { NotificationService } from '@/core/NotificationService.js';
export const ACHIEVEMENT_TYPES = [
'notes1',
@@ -90,7 +90,7 @@ export class AchievementService {
@Inject(DI.userProfilesRepository)
private userProfilesRepository: UserProfilesRepository,
private createNotificationService: CreateNotificationService,
private notificationService: NotificationService,
) {
}
@@ -114,7 +114,7 @@ export class AchievementService {
}],
});
this.createNotificationService.createNotification(userId, 'achievementEarned', {
this.notificationService.createNotification(userId, 'achievementEarned', {
achievement: type,
});
}

View File

@@ -10,7 +10,7 @@ import { isUserRelated } from '@/misc/is-user-related.js';
import { GlobalEventService } from '@/core/GlobalEventService.js';
import { PushNotificationService } from '@/core/PushNotificationService.js';
import * as Acct from '@/misc/acct.js';
import type { Packed } from '@/misc/schema.js';
import type { Packed } from '@/misc/json-schema.js';
import { DI } from '@/di-symbols.js';
import type { MutingsRepository, NotesRepository, AntennaNotesRepository, AntennasRepository, UserListJoiningsRepository } from '@/models/index.js';
import { UtilityService } from '@/core/UtilityService.js';
@@ -71,12 +71,14 @@ export class AntennaService implements OnApplicationShutdown {
this.antennas.push({
...body,
createdAt: new Date(body.createdAt),
lastUsedAt: new Date(body.lastUsedAt),
});
break;
case 'antennaUpdated':
this.antennas[this.antennas.findIndex(a => a.id === body.id)] = {
...body,
createdAt: new Date(body.createdAt),
lastUsedAt: new Date(body.lastUsedAt),
};
break;
case 'antennaDeleted':
@@ -171,13 +173,15 @@ export class AntennaService implements OnApplicationShutdown {
.filter(xs => xs.length > 0);
if (keywords.length > 0) {
if (note.text == null) return false;
if (note.text == null && note.cw == null) return false;
const _text = (note.text ?? '') + '\n' + (note.cw ?? '');
const matched = keywords.some(and =>
and.every(keyword =>
antenna.caseSensitive
? note.text!.includes(keyword)
: note.text!.toLowerCase().includes(keyword.toLowerCase()),
? _text.includes(keyword)
: _text.toLowerCase().includes(keyword.toLowerCase()),
));
if (!matched) return false;
@@ -189,13 +193,15 @@ export class AntennaService implements OnApplicationShutdown {
.filter(xs => xs.length > 0);
if (excludeKeywords.length > 0) {
if (note.text == null) return false;
if (note.text == null && note.cw == null) return false;
const _text = (note.text ?? '') + '\n' + (note.cw ?? '');
const matched = excludeKeywords.some(and =>
and.every(keyword =>
antenna.caseSensitive
? note.text!.includes(keyword)
: note.text!.toLowerCase().includes(keyword.toLowerCase()),
? _text.includes(keyword)
: _text.toLowerCase().includes(keyword.toLowerCase()),
));
if (matched) return false;
@@ -213,7 +219,9 @@ export class AntennaService implements OnApplicationShutdown {
@bindThis
public async getAntennas() {
if (!this.antennasFetched) {
this.antennas = await this.antennasRepository.find();
this.antennas = await this.antennasRepository.findBy({
isActive: true,
});
this.antennasFetched = true;
}

View File

@@ -5,7 +5,6 @@ import { AntennaService } from './AntennaService.js';
import { AppLockService } from './AppLockService.js';
import { AchievementService } from './AchievementService.js';
import { CaptchaService } from './CaptchaService.js';
import { CreateNotificationService } from './CreateNotificationService.js';
import { CreateSystemUserService } from './CreateSystemUserService.js';
import { CustomEmojiService } from './CustomEmojiService.js';
import { DeleteAccountService } from './DeleteAccountService.js';
@@ -82,6 +81,7 @@ import { HashtagEntityService } from './entities/HashtagEntityService.js';
import { InstanceEntityService } from './entities/InstanceEntityService.js';
import { ModerationLogEntityService } from './entities/ModerationLogEntityService.js';
import { MutingEntityService } from './entities/MutingEntityService.js';
import { RenoteMutingEntityService } from './entities/RenoteMutingEntityService.js';
import { NoteEntityService } from './entities/NoteEntityService.js';
import { NoteFavoriteEntityService } from './entities/NoteFavoriteEntityService.js';
import { NoteReactionEntityService } from './entities/NoteReactionEntityService.js';
@@ -125,7 +125,6 @@ const $AntennaService: Provider = { provide: 'AntennaService', useExisting: Ante
const $AppLockService: Provider = { provide: 'AppLockService', useExisting: AppLockService };
const $AchievementService: Provider = { provide: 'AchievementService', useExisting: AchievementService };
const $CaptchaService: Provider = { provide: 'CaptchaService', useExisting: CaptchaService };
const $CreateNotificationService: Provider = { provide: 'CreateNotificationService', useExisting: CreateNotificationService };
const $CreateSystemUserService: Provider = { provide: 'CreateSystemUserService', useExisting: CreateSystemUserService };
const $CustomEmojiService: Provider = { provide: 'CustomEmojiService', useExisting: CustomEmojiService };
const $DeleteAccountService: Provider = { provide: 'DeleteAccountService', useExisting: DeleteAccountService };
@@ -203,6 +202,7 @@ const $HashtagEntityService: Provider = { provide: 'HashtagEntityService', useEx
const $InstanceEntityService: Provider = { provide: 'InstanceEntityService', useExisting: InstanceEntityService };
const $ModerationLogEntityService: Provider = { provide: 'ModerationLogEntityService', useExisting: ModerationLogEntityService };
const $MutingEntityService: Provider = { provide: 'MutingEntityService', useExisting: MutingEntityService };
const $RenoteMutingEntityService: Provider = { provide: 'RenoteMutingEntityService', useExisting: RenoteMutingEntityService };
const $NoteEntityService: Provider = { provide: 'NoteEntityService', useExisting: NoteEntityService };
const $NoteFavoriteEntityService: Provider = { provide: 'NoteFavoriteEntityService', useExisting: NoteFavoriteEntityService };
const $NoteReactionEntityService: Provider = { provide: 'NoteReactionEntityService', useExisting: NoteReactionEntityService };
@@ -248,7 +248,6 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting
AppLockService,
AchievementService,
CaptchaService,
CreateNotificationService,
CreateSystemUserService,
CustomEmojiService,
DeleteAccountService,
@@ -325,6 +324,7 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting
InstanceEntityService,
ModerationLogEntityService,
MutingEntityService,
RenoteMutingEntityService,
NoteEntityService,
NoteFavoriteEntityService,
NoteReactionEntityService,
@@ -365,7 +365,6 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting
$AppLockService,
$AchievementService,
$CaptchaService,
$CreateNotificationService,
$CreateSystemUserService,
$CustomEmojiService,
$DeleteAccountService,
@@ -442,6 +441,7 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting
$InstanceEntityService,
$ModerationLogEntityService,
$MutingEntityService,
$RenoteMutingEntityService,
$NoteEntityService,
$NoteFavoriteEntityService,
$NoteReactionEntityService,
@@ -483,7 +483,6 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting
AppLockService,
AchievementService,
CaptchaService,
CreateNotificationService,
CreateSystemUserService,
CustomEmojiService,
DeleteAccountService,
@@ -559,6 +558,7 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting
InstanceEntityService,
ModerationLogEntityService,
MutingEntityService,
RenoteMutingEntityService,
NoteEntityService,
NoteFavoriteEntityService,
NoteReactionEntityService,
@@ -599,7 +599,6 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting
$AppLockService,
$AchievementService,
$CaptchaService,
$CreateNotificationService,
$CreateSystemUserService,
$CustomEmojiService,
$DeleteAccountService,
@@ -675,6 +674,7 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting
$InstanceEntityService,
$ModerationLogEntityService,
$MutingEntityService,
$RenoteMutingEntityService,
$NoteEntityService,
$NoteFavoriteEntityService,
$NoteReactionEntityService,
@@ -708,4 +708,4 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting
//#endregion
],
})
export class CoreModule {}
export class CoreModule { }

View File

@@ -1,118 +0,0 @@
import { Inject, Injectable } from '@nestjs/common';
import type { MutingsRepository, NotificationsRepository, UserProfilesRepository, UsersRepository } from '@/models/index.js';
import type { User } from '@/models/entities/User.js';
import type { Notification } from '@/models/entities/Notification.js';
import { GlobalEventService } from '@/core/GlobalEventService.js';
import { IdService } from '@/core/IdService.js';
import { DI } from '@/di-symbols.js';
import { NotificationEntityService } from '@/core/entities/NotificationEntityService.js';
import { PushNotificationService } from '@/core/PushNotificationService.js';
import { bindThis } from '@/decorators.js';
@Injectable()
export class CreateNotificationService {
constructor(
@Inject(DI.usersRepository)
private usersRepository: UsersRepository,
@Inject(DI.userProfilesRepository)
private userProfilesRepository: UserProfilesRepository,
@Inject(DI.notificationsRepository)
private notificationsRepository: NotificationsRepository,
@Inject(DI.mutingsRepository)
private mutingsRepository: MutingsRepository,
private notificationEntityService: NotificationEntityService,
private idService: IdService,
private globalEventService: GlobalEventService,
private pushNotificationService: PushNotificationService,
) {
}
@bindThis
public async createNotification(
notifieeId: User['id'],
type: Notification['type'],
data: Partial<Notification>,
): Promise<Notification | null> {
if (data.notifierId && (notifieeId === data.notifierId)) {
return null;
}
const profile = await this.userProfilesRepository.findOneBy({ userId: notifieeId });
const isMuted = profile?.mutingNotificationTypes.includes(type);
// Create notification
const notification = await this.notificationsRepository.insert({
id: this.idService.genId(),
createdAt: new Date(),
notifieeId: notifieeId,
type: type,
// 相手がこの通知をミュートしているようなら、既読を予めつけておく
isRead: isMuted,
...data,
} as Partial<Notification>)
.then(x => this.notificationsRepository.findOneByOrFail(x.identifiers[0]));
const packed = await this.notificationEntityService.pack(notification, {});
// Publish notification event
this.globalEventService.publishMainStream(notifieeId, 'notification', packed);
// 2秒経っても(今回作成した)通知が既読にならなかったら「未読の通知がありますよ」イベントを発行する
setTimeout(async () => {
const fresh = await this.notificationsRepository.findOneBy({ id: notification.id });
if (fresh == null) return; // 既に削除されているかもしれない
if (fresh.isRead) return;
//#region ただしミュートしているユーザーからの通知なら無視
const mutings = await this.mutingsRepository.findBy({
muterId: notifieeId,
});
if (data.notifierId && mutings.map(m => m.muteeId).includes(data.notifierId)) {
return;
}
//#endregion
this.globalEventService.publishMainStream(notifieeId, 'unreadNotification', packed);
this.pushNotificationService.pushNotification(notifieeId, 'notification', packed);
if (type === 'follow') this.emailNotificationFollow(notifieeId, await this.usersRepository.findOneByOrFail({ id: data.notifierId! }));
if (type === 'receiveFollowRequest') this.emailNotificationReceiveFollowRequest(notifieeId, await this.usersRepository.findOneByOrFail({ id: data.notifierId! }));
}, 2000);
return notification;
}
// TODO
//const locales = await import('../../../../locales/index.js');
// TODO: locale ファイルをクライアント用とサーバー用で分けたい
@bindThis
private async emailNotificationFollow(userId: User['id'], follower: User) {
/*
const userProfile = await UserProfiles.findOneByOrFail({ userId: userId });
if (!userProfile.email || !userProfile.emailNotificationTypes.includes('follow')) return;
const locale = locales[userProfile.lang ?? 'ja-JP'];
const i18n = new I18n(locale);
// TODO: render user information html
sendEmail(userProfile.email, i18n.t('_email._follow.title'), `${follower.name} (@${Acct.toString(follower)})`, `${follower.name} (@${Acct.toString(follower)})`);
*/
}
@bindThis
private async emailNotificationReceiveFollowRequest(userId: User['id'], follower: User) {
/*
const userProfile = await UserProfiles.findOneByOrFail({ userId: userId });
if (!userProfile.email || !userProfile.emailNotificationTypes.includes('receiveFollowRequest')) return;
const locale = locales[userProfile.lang ?? 'ja-JP'];
const i18n = new I18n(locale);
// TODO: render user information html
sendEmail(userProfile.email, i18n.t('_email._receiveFollowRequest.title'), `${follower.name} (@${Acct.toString(follower)})`, `${follower.name} (@${Acct.toString(follower)})`);
*/
}
}

View File

@@ -8,7 +8,7 @@ import type { DriveFile } from '@/models/entities/DriveFile.js';
import type { Emoji } from '@/models/entities/Emoji.js';
import type { EmojisRepository, Note } from '@/models/index.js';
import { bindThis } from '@/decorators.js';
import { Cache } from '@/misc/cache.js';
import { KVCache } from '@/misc/cache.js';
import { UtilityService } from '@/core/UtilityService.js';
import type { Config } from '@/config.js';
import { ReactionService } from '@/core/ReactionService.js';
@@ -16,7 +16,7 @@ import { query } from '@/misc/prelude/url.js';
@Injectable()
export class CustomEmojiService {
private cache: Cache<Emoji | null>;
private cache: KVCache<Emoji | null>;
constructor(
@Inject(DI.config)
@@ -34,7 +34,7 @@ export class CustomEmojiService {
private globalEventService: GlobalEventService,
private reactionService: ReactionService,
) {
this.cache = new Cache<Emoji | null>(1000 * 60 * 60 * 12);
this.cache = new KVCache<Emoji | null>(1000 * 60 * 60 * 12);
}
@bindThis
@@ -44,6 +44,7 @@ export class CustomEmojiService {
category: string | null;
aliases: string[];
host: string | null;
license: string | null;
}): Promise<Emoji> {
const emoji = await this.emojisRepository.insert({
id: this.idService.genId(),
@@ -55,10 +56,11 @@ export class CustomEmojiService {
originalUrl: data.driveFile.url,
publicUrl: data.driveFile.webpublicUrl ?? data.driveFile.url,
type: data.driveFile.webpublicType ?? data.driveFile.type,
license: data.license,
}).then(x => this.emojisRepository.findOneByOrFail(x.identifiers[0]));
if (data.host == null) {
await this.db.queryResultCache!.remove(['meta_emojis']);
await this.db.queryResultCache?.remove(['meta_emojis']);
this.globalEventService.publishBroadcastStream('emojiAdded', {
emoji: await this.emojiEntityService.packDetailed(emoji.id),

View File

@@ -6,6 +6,7 @@ import IPCIDR from 'ip-cidr';
import PrivateIp from 'private-ip';
import chalk from 'chalk';
import got, * as Got from 'got';
import { parse } from 'content-disposition';
import { DI } from '@/di-symbols.js';
import type { Config } from '@/config.js';
import { HttpRequestService } from '@/core/HttpRequestService.js';
@@ -32,13 +33,18 @@ export class DownloadService {
}
@bindThis
public async downloadUrl(url: string, path: string): Promise<void> {
public async downloadUrl(url: string, path: string): Promise<{
filename: string;
}> {
this.logger.info(`Downloading ${chalk.cyan(url)} to ${chalk.cyanBright(path)} ...`);
const timeout = 30 * 1000;
const operationTimeout = 60 * 1000;
const maxSize = this.config.maxFileSize ?? 262144000;
const urlObj = new URL(url);
let filename = urlObj.pathname.split('/').pop() ?? 'untitled';
const req = got.stream(url, {
headers: {
'User-Agent': this.config.userAgent,
@@ -77,6 +83,14 @@ export class DownloadService {
req.destroy();
}
}
const contentDisposition = res.headers['content-disposition'];
if (contentDisposition != null) {
const parsed = parse(contentDisposition);
if (parsed.parameters.filename) {
filename = parsed.parameters.filename;
}
}
}).on('downloadProgress', (progress: Got.Progress) => {
if (progress.transferred > maxSize) {
this.logger.warn(`maxSize exceeded (${progress.transferred} > ${maxSize}) on downloadProgress`);
@@ -95,6 +109,10 @@ export class DownloadService {
}
this.logger.succ(`Download finished: ${chalk.cyan(url)}`);
return {
filename,
};
}
@bindThis

View File

@@ -2,7 +2,9 @@ import * as fs from 'node:fs';
import { Inject, Injectable } from '@nestjs/common';
import { v4 as uuid } from 'uuid';
import sharp from 'sharp';
import { sharpBmp } from 'sharp-read-bmp';
import { IsNull } from 'typeorm';
import { DeleteObjectCommandInput, PutObjectCommandInput, NoSuchKey } from '@aws-sdk/client-s3';
import { DI } from '@/di-symbols.js';
import type { DriveFilesRepository, UsersRepository, DriveFoldersRepository, UserProfilesRepository } from '@/models/index.js';
import type { Config } from '@/config.js';
@@ -33,7 +35,8 @@ import { UserEntityService } from '@/core/entities/UserEntityService.js';
import { FileInfoService } from '@/core/FileInfoService.js';
import { bindThis } from '@/decorators.js';
import { RoleService } from '@/core/RoleService.js';
import type S3 from 'aws-sdk/clients/s3.js';
import { correctFilename } from '@/misc/correct-filename.js';
import { isMimeImage } from '@/misc/is-mime-image.js';
type AddFileArgs = {
/** User who wish to add file */
@@ -78,6 +81,7 @@ type UploadFromUrlArgs = {
export class DriveService {
private registerLogger: Logger;
private downloaderLogger: Logger;
private deleteLogger: Logger;
constructor(
@Inject(DI.config)
@@ -115,6 +119,7 @@ export class DriveService {
const logger = new Logger('drive', 'blue');
this.registerLogger = logger.createSubLogger('register', 'yellow');
this.downloaderLogger = logger.createSubLogger('downloader');
this.deleteLogger = logger.createSubLogger('delete');
}
/***
@@ -168,7 +173,7 @@ export class DriveService {
//#region Uploads
this.registerLogger.info(`uploading original: ${key}`);
const uploads = [
this.upload(key, fs.createReadStream(path), type, name),
this.upload(key, fs.createReadStream(path), type, ext, name),
];
if (alts.webpublic) {
@@ -176,7 +181,7 @@ export class DriveService {
webpublicUrl = `${ baseUrl }/${ webpublicKey }`;
this.registerLogger.info(`uploading webpublic: ${webpublicKey}`);
uploads.push(this.upload(webpublicKey, alts.webpublic.data, alts.webpublic.type, name));
uploads.push(this.upload(webpublicKey, alts.webpublic.data, alts.webpublic.type, alts.webpublic.ext, name));
}
if (alts.thumbnail) {
@@ -184,7 +189,7 @@ export class DriveService {
thumbnailUrl = `${ baseUrl }/${ thumbnailKey }`;
this.registerLogger.info(`uploading thumbnail: ${thumbnailKey}`);
uploads.push(this.upload(thumbnailKey, alts.thumbnail.data, alts.thumbnail.type));
uploads.push(this.upload(thumbnailKey, alts.thumbnail.data, alts.thumbnail.type, alts.thumbnail.ext));
}
await Promise.all(uploads);
@@ -273,8 +278,8 @@ export class DriveService {
}
}
if (!['image/jpeg', 'image/png', 'image/webp', 'image/avif', 'image/svg+xml'].includes(type)) {
this.registerLogger.debug('web image and thumbnail not created (not an required file)');
if (!isMimeImage(type, 'sharp-convertible-image-with-bmp')) {
this.registerLogger.debug('web image and thumbnail not created (cannot convert by sharp)');
return {
webpublic: null,
thumbnail: null,
@@ -283,22 +288,16 @@ export class DriveService {
let img: sharp.Sharp | null = null;
let satisfyWebpublic: boolean;
let isAnimated: boolean;
try {
img = sharp(path);
img = await sharpBmp(path, type);
const metadata = await img.metadata();
const isAnimated = metadata.pages && metadata.pages > 1;
// skip animated
if (isAnimated) {
return {
webpublic: null,
thumbnail: null,
};
}
isAnimated = !!(metadata.pages && metadata.pages > 1);
satisfyWebpublic = !!(
type !== 'image/svg+xml' && type !== 'image/webp' && type !== 'image/avif' &&
type !== 'image/svg+xml' && // security reason
type !== 'image/avif' && // not supported by Mastodon and MS Edge
!(metadata.exif ?? metadata.iptc ?? metadata.xmp ?? metadata.tifftagPhotoshop) &&
metadata.width && metadata.width <= 2048 &&
metadata.height && metadata.height <= 2048
@@ -314,15 +313,13 @@ export class DriveService {
// #region webpublic
let webpublic: IImage | null = null;
if (generateWeb && !satisfyWebpublic) {
if (generateWeb && !satisfyWebpublic && !isAnimated) {
this.registerLogger.info('creating web image');
try {
if (['image/jpeg', 'image/webp', 'image/avif'].includes(type)) {
webpublic = await this.imageProcessingService.convertSharpToJpeg(img, 2048, 2048);
} else if (['image/png'].includes(type)) {
webpublic = await this.imageProcessingService.convertSharpToPng(img, 2048, 2048);
} else if (['image/svg+xml'].includes(type)) {
webpublic = await this.imageProcessingService.convertSharpToWebp(img, 2048, 2048);
} else if (['image/png', 'image/bmp', 'image/svg+xml'].includes(type)) {
webpublic = await this.imageProcessingService.convertSharpToPng(img, 2048, 2048);
} else {
this.registerLogger.debug('web image not created (not an required image)');
@@ -332,6 +329,7 @@ export class DriveService {
}
} else {
if (satisfyWebpublic) this.registerLogger.info('web image not created (original satisfies webpublic)');
else if (isAnimated) this.registerLogger.info('web image not created (animated image)');
else this.registerLogger.info('web image not created (from remote)');
}
// #endregion webpublic
@@ -340,10 +338,10 @@ export class DriveService {
let thumbnail: IImage | null = null;
try {
if (['image/jpeg', 'image/webp', 'image/avif', 'image/png', 'image/svg+xml'].includes(type)) {
thumbnail = await this.imageProcessingService.convertSharpToWebp(img, 498, 280);
if (isAnimated) {
thumbnail = await this.imageProcessingService.convertSharpToWebp(sharp(path, { animated: true }), 374, 317, { alphaQuality: 70 });
} else {
this.registerLogger.debug('thumbnail not created (not an required file)');
thumbnail = await this.imageProcessingService.convertSharpToWebp(img, 498, 422);
}
} catch (err) {
this.registerLogger.warn('thumbnail not created (an error occured)', err as Error);
@@ -360,7 +358,7 @@ export class DriveService {
* Upload to ObjectStorage
*/
@bindThis
private async upload(key: string, stream: fs.ReadStream | Buffer, type: string, filename?: string) {
private async upload(key: string, stream: fs.ReadStream | Buffer, type: string, ext?: string | null, filename?: string) {
if (type === 'image/apng') type = 'image/png';
if (!FILE_TYPE_BROWSERSAFE.includes(type)) type = 'application/octet-stream';
@@ -372,26 +370,26 @@ export class DriveService {
Body: stream,
ContentType: type,
CacheControl: 'max-age=31536000, immutable',
} as S3.PutObjectRequest;
} as PutObjectCommandInput;
if (filename) params.ContentDisposition = contentDisposition('inline', filename);
if (filename) params.ContentDisposition = contentDisposition(
'inline',
// 拡張子からContent-Typeを設定してそうな挙動を示すオブジェクトストレージ (upcloud?) も存在するので、
// 許可されているファイル形式でしか拡張子をつけない
ext ? correctFilename(filename, ext) : filename,
);
if (meta.objectStorageSetPublicRead) params.ACL = 'public-read';
const s3 = this.s3Service.getS3(meta);
const upload = s3.upload(params, {
partSize: s3.endpoint.hostname === 'storage.googleapis.com' ? 500 * 1024 * 1024 : 8 * 1024 * 1024,
});
await upload.promise()
await this.s3Service.upload(meta, params)
.then(
result => {
if (result) {
if ('Bucket' in result) { // CompleteMultipartUploadCommandOutput
this.registerLogger.debug(`Uploaded: ${result.Bucket}/${result.Key} => ${result.Location}`);
} else {
this.registerLogger.error(`Upload Result Empty: key = ${key}, filename = ${filename}`);
} else { // AbortMultipartUploadCommandOutput
this.registerLogger.error(`Upload Result Aborted: key = ${key}, filename = ${filename}`);
}
},
})
.catch(
err => {
this.registerLogger.error(`Upload Failed: key = ${key}, filename = ${filename}`, err);
},
@@ -466,7 +464,12 @@ export class DriveService {
//}
// detect name
const detectedName = name ?? (info.type.ext ? `untitled.${info.type.ext}` : 'untitled');
const detectedName = correctFilename(
// DriveFile.nameは256文字, validateFileNameは200文字制限であるため、
// extを付加してデータベースの文字数制限に当たることはまずない
(name && this.driveFileEntityService.validateFileName(name)) ? name : 'untitled',
info.type.ext,
);
if (user && !force) {
// Check if there is a file with the same hash
@@ -522,10 +525,10 @@ export class DriveService {
};
const properties: {
width?: number;
height?: number;
orientation?: number;
} = {};
width?: number;
height?: number;
orientation?: number;
} = {};
if (info.width) {
properties['width'] = info.width;
@@ -610,17 +613,20 @@ export class DriveService {
if (user) {
this.driveFileEntityService.pack(file, { self: true }).then(packedFile => {
// Publish driveFileCreated event
// Publish driveFileCreated event
this.globalEventService.publishMainStream(user.id, 'driveFileCreated', packedFile);
this.globalEventService.publishDriveStream(user.id, 'fileCreated', packedFile);
});
}
// 統計を更新
this.driveChart.update(file, true);
this.perUserDriveChart.update(file, true);
if (file.userHost !== null) {
this.instanceChart.updateDrive(file, true);
if (file.userHost == null) {
// ローカルユーザーのみ
this.perUserDriveChart.update(file, true);
} else {
if ((await this.metaService.fetch()).enableChartsForFederatedInstances) {
this.instanceChart.updateDrive(file, true);
}
}
return file;
@@ -686,7 +692,7 @@ export class DriveService {
@bindThis
private async deletePostProcess(file: DriveFile, isExpired = false) {
// リモートファイル期限切れ削除後は直リンクにする
// リモートファイル期限切れ削除後は直リンクにする
if (isExpired && file.userHost !== null && file.uri != null) {
this.driveFilesRepository.update(file.id, {
isLink: true,
@@ -703,24 +709,37 @@ export class DriveService {
this.driveFilesRepository.delete(file.id);
}
// 統計を更新
this.driveChart.update(file, false);
this.perUserDriveChart.update(file, false);
if (file.userHost !== null) {
this.instanceChart.updateDrive(file, false);
if (file.userHost == null) {
// ローカルユーザーのみ
this.perUserDriveChart.update(file, false);
} else {
if ((await this.metaService.fetch()).enableChartsForFederatedInstances) {
this.instanceChart.updateDrive(file, false);
}
}
}
@bindThis
public async deleteObjectStorageFile(key: string) {
const meta = await this.metaService.fetch();
try {
const param = {
Bucket: meta.objectStorageBucket,
Key: key,
} as DeleteObjectCommandInput;
const s3 = this.s3Service.getS3(meta);
await s3.deleteObject({
Bucket: meta.objectStorageBucket!,
Key: key,
}).promise();
await this.s3Service.delete(meta, param);
} catch (err: any) {
if (err.name === 'NoSuchKey') {
this.deleteLogger.warn(`The object storage had no such key to delete: ${key}. Skipping this.`, err as Error);
return;
} else {
throw new Error(`Failed to delete the file from the object storage with the given key: ${key}`, {
cause: err,
});
}
}
}
@bindThis
@@ -736,24 +755,19 @@ export class DriveService {
requestIp = null,
requestHeaders = null,
}: UploadFromUrlArgs): Promise<DriveFile> {
let name = new URL(url).pathname.split('/').pop() ?? null;
if (name == null || !this.driveFileEntityService.validateFileName(name)) {
name = null;
}
// If the comment is same as the name, skip comment
// (image.name is passed in when receiving attachment)
if (comment !== null && name === comment) {
comment = null;
}
// Create temp file
const [path, cleanup] = await createTemp();
try {
// write content at URL to temp file
await this.downloadService.downloadUrl(url, path);
const { filename: name } = await this.downloadService.downloadUrl(url, path);
// If the comment is same as the name, skip comment
// (image.name is passed in when receiving attachment)
if (comment !== null && name === comment) {
comment = null;
}
const driveFile = await this.addFile({ user, path, name, comment, folderId, force, isLink, url, uri, sensitive, requestIp, requestHeaders });
this.downloaderLogger.succ(`Got: ${driveFile.id}`);
return driveFile!;

View File

@@ -1,7 +1,7 @@
import { Inject, Injectable } from '@nestjs/common';
import type { InstancesRepository } from '@/models/index.js';
import type { Instance } from '@/models/entities/Instance.js';
import { Cache } from '@/misc/cache.js';
import { KVCache } from '@/misc/cache.js';
import { IdService } from '@/core/IdService.js';
import { DI } from '@/di-symbols.js';
import { UtilityService } from '@/core/UtilityService.js';
@@ -9,7 +9,7 @@ import { bindThis } from '@/decorators.js';
@Injectable()
export class FederatedInstanceService {
private cache: Cache<Instance>;
private cache: KVCache<Instance>;
constructor(
@Inject(DI.instancesRepository)
@@ -18,7 +18,7 @@ export class FederatedInstanceService {
private utilityService: UtilityService,
private idService: IdService,
) {
this.cache = new Cache<Instance>(1000 * 60 * 60);
this.cache = new KVCache<Instance>(1000 * 60 * 60);
}
@bindThis

View File

@@ -16,7 +16,7 @@ import type {
UserListStreamTypes,
UserStreamTypes,
} from '@/server/api/stream/types.js';
import type { Packed } from '@/misc/schema.js';
import type { Packed } from '@/misc/json-schema.js';
import { DI } from '@/di-symbols.js';
import type { Config } from '@/config.js';
import { bindThis } from '@/decorators.js';

View File

@@ -15,15 +15,28 @@ export type IImageStream = {
type: string;
};
export type IImageStreamable = IImage | IImageStream;
export type IImageSharp = {
data: sharp.Sharp;
ext: string | null;
type: string;
};
export type IImageStreamable = IImage | IImageStream | IImageSharp;
export const webpDefault: sharp.WebpOptions = {
quality: 85,
quality: 77,
alphaQuality: 95,
lossless: false,
nearLossless: false,
smartSubsample: true,
mixed: true,
effort: 2,
};
export const avifDefault: sharp.AvifOptions = {
quality: 60,
lossless: false,
effort: 2,
};
import { bindThis } from '@/decorators.js';
@@ -37,36 +50,6 @@ export class ImageProcessingService {
) {
}
/**
* Convert to JPEG
* with resize, remove metadata, resolve orientation, stop animation
*/
@bindThis
public async convertToJpeg(path: string, width: number, height: number): Promise<IImage> {
return this.convertSharpToJpeg(await sharp(path), width, height);
}
@bindThis
public async convertSharpToJpeg(sharp: sharp.Sharp, width: number, height: number): Promise<IImage> {
const data = await sharp
.resize(width, height, {
fit: 'inside',
withoutEnlargement: true,
})
.rotate()
.jpeg({
quality: 85,
progressive: true,
})
.toBuffer();
return {
data,
ext: 'jpg',
type: 'image/jpeg',
};
}
/**
* Convert to WebP
* with resize, remove metadata, resolve orientation, stop animation
@@ -78,29 +61,22 @@ export class ImageProcessingService {
@bindThis
public async convertSharpToWebp(sharp: sharp.Sharp, width: number, height: number, options: sharp.WebpOptions = webpDefault): Promise<IImage> {
const data = await sharp
.resize(width, height, {
fit: 'inside',
withoutEnlargement: true,
})
.rotate()
.webp(options)
.toBuffer();
const result = this.convertSharpToWebpStream(sharp, width, height, options);
return {
data,
ext: 'webp',
type: 'image/webp',
data: await result.data.toBuffer(),
ext: result.ext,
type: result.type,
};
}
@bindThis
public convertToWebpStream(path: string, width: number, height: number, options: sharp.WebpOptions = webpDefault): IImageStream {
public convertToWebpStream(path: string, width: number, height: number, options: sharp.WebpOptions = webpDefault): IImageSharp {
return this.convertSharpToWebpStream(sharp(path), width, height, options);
}
@bindThis
public convertSharpToWebpStream(sharp: sharp.Sharp, width: number, height: number, options: sharp.WebpOptions = webpDefault): IImageStream {
public convertSharpToWebpStream(sharp: sharp.Sharp, width: number, height: number, options: sharp.WebpOptions = webpDefault): IImageSharp {
const data = sharp
.resize(width, height, {
fit: 'inside',
@@ -115,13 +91,56 @@ export class ImageProcessingService {
type: 'image/webp',
};
}
/**
* Convert to Avif
* with resize, remove metadata, resolve orientation, stop animation
*/
@bindThis
public async convertToAvif(path: string, width: number, height: number, options: sharp.AvifOptions = avifDefault): Promise<IImage> {
return this.convertSharpToAvif(sharp(path), width, height, options);
}
@bindThis
public async convertSharpToAvif(sharp: sharp.Sharp, width: number, height: number, options: sharp.AvifOptions = avifDefault): Promise<IImage> {
const result = this.convertSharpToAvifStream(sharp, width, height, options);
return {
data: await result.data.toBuffer(),
ext: result.ext,
type: result.type,
};
}
@bindThis
public convertToAvifStream(path: string, width: number, height: number, options: sharp.AvifOptions = avifDefault): IImageSharp {
return this.convertSharpToAvifStream(sharp(path), width, height, options);
}
@bindThis
public convertSharpToAvifStream(sharp: sharp.Sharp, width: number, height: number, options: sharp.AvifOptions = avifDefault): IImageSharp {
const data = sharp
.resize(width, height, {
fit: 'inside',
withoutEnlargement: true,
})
.rotate()
.avif(options);
return {
data,
ext: 'avif',
type: 'image/avif',
};
}
/**
* Convert to PNG
* with resize, remove metadata, resolve orientation, stop animation
*/
@bindThis
public async convertToPng(path: string, width: number, height: number): Promise<IImage> {
return this.convertSharpToPng(await sharp(path), width, height);
return this.convertSharpToPng(sharp(path), width, height);
}
@bindThis

View File

@@ -2,7 +2,7 @@ import { Inject, Injectable } from '@nestjs/common';
import { IsNull } from 'typeorm';
import type { LocalUser } from '@/models/entities/User.js';
import type { UsersRepository } from '@/models/index.js';
import { Cache } from '@/misc/cache.js';
import { KVCache } from '@/misc/cache.js';
import { DI } from '@/di-symbols.js';
import { CreateSystemUserService } from '@/core/CreateSystemUserService.js';
import { bindThis } from '@/decorators.js';
@@ -11,7 +11,7 @@ const ACTOR_USERNAME = 'instance.actor' as const;
@Injectable()
export class InstanceActorService {
private cache: Cache<LocalUser>;
private cache: KVCache<LocalUser>;
constructor(
@Inject(DI.usersRepository)
@@ -19,7 +19,7 @@ export class InstanceActorService {
private createSystemUserService: CreateSystemUserService,
) {
this.cache = new Cache<LocalUser>(Infinity);
this.cache = new KVCache<LocalUser>(Infinity);
}
@bindThis

View File

@@ -1,6 +1,7 @@
import { setImmediate } from 'node:timers/promises';
import * as mfm from 'mfm-js';
import { In, DataSource } from 'typeorm';
import { Inject, Injectable } from '@nestjs/common';
import { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common';
import { extractMentions } from '@/misc/extract-mentions.js';
import { extractCustomEmojisFromMfm } from '@/misc/extract-custom-emojis-from-mfm.js';
import { extractHashtags } from '@/misc/extract-hashtags.js';
@@ -18,7 +19,7 @@ import { isDuplicateKeyValueError } from '@/misc/is-duplicate-key-value-error.js
import { checkWordMute } from '@/misc/check-word-mute.js';
import type { Channel } from '@/models/entities/Channel.js';
import { normalizeForSearch } from '@/misc/normalize-for-search.js';
import { Cache } from '@/misc/cache.js';
import { KVCache } from '@/misc/cache.js';
import type { UserProfile } from '@/models/entities/UserProfile.js';
import { RelayService } from '@/core/RelayService.js';
import { FederatedInstanceService } from '@/core/FederatedInstanceService.js';
@@ -29,7 +30,7 @@ import PerUserNotesChart from '@/core/chart/charts/per-user-notes.js';
import InstanceChart from '@/core/chart/charts/instance.js';
import ActiveUsersChart from '@/core/chart/charts/active-users.js';
import { GlobalEventService } from '@/core/GlobalEventService.js';
import { CreateNotificationService } from '@/core/CreateNotificationService.js';
import { NotificationService } from '@/core/NotificationService.js';
import { WebhookService } from '@/core/WebhookService.js';
import { HashtagService } from '@/core/HashtagService.js';
import { AntennaService } from '@/core/AntennaService.js';
@@ -43,8 +44,9 @@ import { RemoteUserResolveService } from '@/core/RemoteUserResolveService.js';
import { bindThis } from '@/decorators.js';
import { DB_MAX_NOTE_TEXT_LENGTH } from '@/const.js';
import { RoleService } from '@/core/RoleService.js';
import { MetaService } from '@/core/MetaService.js';
const mutedWordsCache = new Cache<{ userId: UserProfile['userId']; mutedWords: UserProfile['mutedWords']; }[]>(1000 * 60 * 5);
const mutedWordsCache = new KVCache<{ userId: UserProfile['userId']; mutedWords: UserProfile['mutedWords']; }[]>(1000 * 60 * 5);
type NotificationType = 'reply' | 'renote' | 'quote' | 'mention';
@@ -58,7 +60,7 @@ class NotificationManager {
constructor(
private mutingsRepository: MutingsRepository,
private createNotificationService: CreateNotificationService,
private notificationService: NotificationService,
notifier: { id: User['id']; },
note: Note,
) {
@@ -99,7 +101,7 @@ class NotificationManager {
// 通知される側のユーザーが通知する側のユーザーをミュートしていない限りは通知する
if (!mentioneesMutedUserIds.includes(this.notifier.id)) {
this.createNotificationService.createNotification(x.target, x.reason, {
this.notificationService.createNotification(x.target, x.reason, {
notifierId: this.notifier.id,
noteId: this.note.id,
});
@@ -124,6 +126,7 @@ type Option = {
files?: DriveFile[] | null;
poll?: IPoll | null;
localOnly?: boolean | null;
reactionAcceptance?: Note['reactionAcceptance'];
cw?: string | null;
visibility?: string;
visibleUsers?: MinimumUser[] | null;
@@ -137,7 +140,9 @@ type Option = {
};
@Injectable()
export class NoteCreateService {
export class NoteCreateService implements OnApplicationShutdown {
#shutdownController = new AbortController();
constructor(
@Inject(DI.config)
private config: Config,
@@ -178,7 +183,7 @@ export class NoteCreateService {
private globalEventService: GlobalEventService,
private queueService: QueueService,
private noteReadService: NoteReadService,
private createNotificationService: CreateNotificationService,
private notificationService: NotificationService,
private relayService: RelayService,
private federatedInstanceService: FederatedInstanceService,
private hashtagService: HashtagService,
@@ -188,11 +193,12 @@ export class NoteCreateService {
private apDeliverManagerService: ApDeliverManagerService,
private apRendererService: ApRendererService,
private roleService: RoleService,
private metaService: MetaService,
private notesChart: NotesChart,
private perUserNotesChart: PerUserNotesChart,
private activeUsersChart: ActiveUsersChart,
private instanceChart: InstanceChart,
) {}
) { }
@bindThis
public async create(user: {
@@ -226,7 +232,9 @@ export class NoteCreateService {
if (data.channel != null) data.localOnly = true;
if (data.visibility === 'public' && data.channel == null) {
if ((await this.roleService.getUserPolicies(user.id)).canPublicNote === false) {
if ((data.text != null) && (await this.metaService.fetch()).sensitiveWords.some(w => data.text!.includes(w))) {
data.visibility = 'home';
} else if ((await this.roleService.getUserPolicies(user.id)).canPublicNote === false) {
data.visibility = 'home';
}
}
@@ -313,7 +321,10 @@ export class NoteCreateService {
const note = await this.insertNote(user, data, tags, emojis, mentionedUsers);
setImmediate(() => this.postNoteCreated(note, user, data, silent, tags!, mentionedUsers!));
setImmediate('post created', { signal: this.#shutdownController.signal }).then(
() => this.postNoteCreated(note, user, data, silent, tags!, mentionedUsers!),
() => { /* aborted, ignore this */ },
);
return note;
}
@@ -340,6 +351,7 @@ export class NoteCreateService {
emojis,
userId: user.id,
localOnly: data.localOnly!,
reactionAcceptance: data.reactionAcceptance,
visibility: data.visibility as any,
visibleUserIds: data.visibility === 'specified'
? data.visibleUsers
@@ -379,7 +391,7 @@ export class NoteCreateService {
// 投稿を作成
try {
if (insert.hasPoll) {
// Start transaction
// Start transaction
await this.db.transaction(async transactionalEntityManager => {
await transactionalEntityManager.insert(Note, insert);
@@ -402,7 +414,7 @@ export class NoteCreateService {
return insert;
} catch (e) {
// duplicate key error
// duplicate key error
if (isDuplicateKeyValueError(e)) {
const err = new Error('Duplicated note');
err.name = 'duplicated';
@@ -423,15 +435,20 @@ export class NoteCreateService {
createdAt: User['createdAt'];
isBot: User['isBot'];
}, data: Option, silent: boolean, tags: string[], mentionedUsers: MinimumUser[]) {
// 統計を更新
const meta = await this.metaService.fetch();
this.notesChart.update(note, true);
this.perUserNotesChart.update(user, note, true);
if (meta.enableChartsForRemoteUser || (user.host == null)) {
this.perUserNotesChart.update(user, note, true);
}
// Register host
if (this.userEntityService.isRemoteUser(user)) {
this.federatedInstanceService.fetch(user.host).then(i => {
this.federatedInstanceService.fetch(user.host).then(async i => {
this.instancesRepository.increment({ id: i.id }, 'notesCount', 1);
this.instanceChart.updateNote(i.host, note, true);
if ((await this.metaService.fetch()).enableChartsForFederatedInstances) {
this.instanceChart.updateNote(i.host, note, true);
}
});
}
@@ -546,7 +563,7 @@ export class NoteCreateService {
}
});
const nm = new NotificationManager(this.mutingsRepository, this.createNotificationService, user, note);
const nm = new NotificationManager(this.mutingsRepository, this.notificationService, user, note);
await this.createMentionedEvents(mentionedUsers, note, nm);
@@ -756,4 +773,8 @@ export class NoteCreateService {
return mentionedUsers;
}
onApplicationShutdown(signal?: string | undefined) {
this.#shutdownController.abort();
}
}

View File

@@ -16,6 +16,7 @@ import { ApDeliverManagerService } from '@/core/activitypub/ApDeliverManagerServ
import { UserEntityService } from '@/core/entities/UserEntityService.js';
import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
import { bindThis } from '@/decorators.js';
import { MetaService } from '@/core/MetaService.js';
@Injectable()
export class NoteDeleteService {
@@ -39,6 +40,7 @@ export class NoteDeleteService {
private federatedInstanceService: FederatedInstanceService,
private apRendererService: ApRendererService,
private apDeliverManagerService: ApDeliverManagerService,
private metaService: MetaService,
private notesChart: NotesChart,
private perUserNotesChart: PerUserNotesChart,
private instanceChart: InstanceChart,
@@ -95,14 +97,19 @@ export class NoteDeleteService {
}
//#endregion
// 統計を更新
const meta = await this.metaService.fetch();
this.notesChart.update(note, false);
this.perUserNotesChart.update(user, note, false);
if (meta.enableChartsForRemoteUser || (user.host == null)) {
this.perUserNotesChart.update(user, note, false);
}
if (this.userEntityService.isRemoteUser(user)) {
this.federatedInstanceService.fetch(user.host).then(i => {
this.federatedInstanceService.fetch(user.host).then(async i => {
this.instancesRepository.decrement({ id: i.id }, 'notesCount', 1);
this.instanceChart.updateNote(i.host, note, false);
if ((await this.metaService.fetch()).enableChartsForFederatedInstances) {
this.instanceChart.updateNote(i.host, note, false);
}
});
}
}

View File

@@ -1,9 +1,10 @@
import { Inject, Injectable } from '@nestjs/common';
import { setTimeout } from 'node:timers/promises';
import { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common';
import { In, IsNull, Not } from 'typeorm';
import { DI } from '@/di-symbols.js';
import type { User } from '@/models/entities/User.js';
import type { Channel } from '@/models/entities/Channel.js';
import type { Packed } from '@/misc/schema.js';
import type { Packed } from '@/misc/json-schema.js';
import type { Note } from '@/models/entities/Note.js';
import { IdService } from '@/core/IdService.js';
import { GlobalEventService } from '@/core/GlobalEventService.js';
@@ -15,7 +16,9 @@ import { AntennaService } from './AntennaService.js';
import { PushNotificationService } from './PushNotificationService.js';
@Injectable()
export class NoteReadService {
export class NoteReadService implements OnApplicationShutdown {
#shutdownController = new AbortController();
constructor(
@Inject(DI.usersRepository)
private usersRepository: UsersRepository,
@@ -60,14 +63,14 @@ export class NoteReadService {
});
if (mute.map(m => m.muteeId).includes(note.userId)) return;
//#endregion
// スレッドミュート
const threadMute = await this.noteThreadMutingsRepository.findOneBy({
userId: userId,
threadId: note.threadId ?? note.id,
});
if (threadMute) return;
const unread = {
id: this.idService.genId(),
noteId: note.id,
@@ -77,15 +80,15 @@ export class NoteReadService {
noteChannelId: note.channelId,
noteUserId: note.userId,
};
await this.noteUnreadsRepository.insert(unread);
// 2秒経っても既読にならなかったら「未読の投稿がありますよ」イベントを発行する
setTimeout(async () => {
setTimeout(2000, 'unread note', { signal: this.#shutdownController.signal }).then(async () => {
const exist = await this.noteUnreadsRepository.findOneBy({ id: unread.id });
if (exist == null) return;
if (params.isMentioned) {
this.globalEventService.publishMainStream(userId, 'unreadMention', note.id);
}
@@ -95,8 +98,8 @@ export class NoteReadService {
if (note.channelId) {
this.globalEventService.publishMainStream(userId, 'unreadChannel', note.id);
}
}, 2000);
}
}, () => { /* aborted, ignore it */ });
}
@bindThis
public async read(
@@ -113,24 +116,24 @@ export class NoteReadService {
},
select: ['followeeId'],
})).map(x => x.followeeId));
const myAntennas = (await this.antennaService.getAntennas()).filter(a => a.userId === userId);
const readMentions: (Note | Packed<'Note'>)[] = [];
const readSpecifiedNotes: (Note | Packed<'Note'>)[] = [];
const readChannelNotes: (Note | Packed<'Note'>)[] = [];
const readAntennaNotes: (Note | Packed<'Note'>)[] = [];
for (const note of notes) {
if (note.mentions && note.mentions.includes(userId)) {
readMentions.push(note);
} else if (note.visibleUserIds && note.visibleUserIds.includes(userId)) {
readSpecifiedNotes.push(note);
}
if (note.channelId && followingChannels.has(note.channelId)) {
readChannelNotes.push(note);
}
if (note.user != null) { // たぶんnullになることは無いはずだけど一応
for (const antenna of myAntennas) {
if (await this.antennaService.checkHitAntenna(antenna, note, note.user)) {
@@ -139,14 +142,14 @@ export class NoteReadService {
}
}
}
if ((readMentions.length > 0) || (readSpecifiedNotes.length > 0) || (readChannelNotes.length > 0)) {
// Remove the record
await this.noteUnreadsRepository.delete({
userId: userId,
noteId: In([...readMentions.map(n => n.id), ...readSpecifiedNotes.map(n => n.id), ...readChannelNotes.map(n => n.id)]),
});
// TODO: ↓まとめてクエリしたい
this.noteUnreadsRepository.countBy({
@@ -183,7 +186,7 @@ export class NoteReadService {
noteId: In([...readMentions.map(n => n.id), ...readSpecifiedNotes.map(n => n.id)]),
});
}
if (readAntennaNotes.length > 0) {
await this.antennaNotesRepository.update({
antennaId: In(myAntennas.map(a => a.id)),
@@ -191,14 +194,14 @@ export class NoteReadService {
}, {
read: true,
});
// TODO: まとめてクエリしたい
for (const antenna of myAntennas) {
const count = await this.antennaNotesRepository.countBy({
antennaId: antenna.id,
read: false,
});
if (count === 0) {
this.globalEventService.publishMainStream(userId, 'readAntenna', antenna);
this.pushNotificationService.pushNotification(userId, 'readAntenna', { antennaId: antenna.id });
@@ -213,4 +216,8 @@ export class NoteReadService {
});
}
}
onApplicationShutdown(signal?: string | undefined): void {
this.#shutdownController.abort();
}
}

View File

@@ -1,21 +1,37 @@
import { Inject, Injectable } from '@nestjs/common';
import { setTimeout } from 'node:timers/promises';
import { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common';
import { In } from 'typeorm';
import { DI } from '@/di-symbols.js';
import type { NotificationsRepository } from '@/models/index.js';
import type { MutingsRepository, NotificationsRepository, UserProfilesRepository, UsersRepository } from '@/models/index.js';
import type { User } from '@/models/entities/User.js';
import type { Notification } from '@/models/entities/Notification.js';
import { UserEntityService } from '@/core/entities/UserEntityService.js';
import { bindThis } from '@/decorators.js';
import { GlobalEventService } from './GlobalEventService.js';
import { PushNotificationService } from './PushNotificationService.js';
import { GlobalEventService } from '@/core/GlobalEventService.js';
import { PushNotificationService } from '@/core/PushNotificationService.js';
import { NotificationEntityService } from '@/core/entities/NotificationEntityService.js';
import { IdService } from '@/core/IdService.js';
@Injectable()
export class NotificationService {
export class NotificationService implements OnApplicationShutdown {
#shutdownController = new AbortController();
constructor(
@Inject(DI.usersRepository)
private usersRepository: UsersRepository,
@Inject(DI.userProfilesRepository)
private userProfilesRepository: UserProfilesRepository,
@Inject(DI.notificationsRepository)
private notificationsRepository: NotificationsRepository,
@Inject(DI.mutingsRepository)
private mutingsRepository: MutingsRepository,
private notificationEntityService: NotificationEntityService,
private userEntityService: UserEntityService,
private idService: IdService,
private globalEventService: GlobalEventService,
private pushNotificationService: PushNotificationService,
) {
@@ -67,4 +83,93 @@ export class NotificationService {
private postReadNotifications(userId: User['id'], notificationIds: Notification['id'][]) {
return this.pushNotificationService.pushNotification(userId, 'readNotifications', { notificationIds });
}
@bindThis
public async createNotification(
notifieeId: User['id'],
type: Notification['type'],
data: Partial<Notification>,
): Promise<Notification | null> {
if (data.notifierId && (notifieeId === data.notifierId)) {
return null;
}
const profile = await this.userProfilesRepository.findOneBy({ userId: notifieeId });
const isMuted = profile?.mutingNotificationTypes.includes(type);
// Create notification
const notification = await this.notificationsRepository.insert({
id: this.idService.genId(),
createdAt: new Date(),
notifieeId: notifieeId,
type: type,
// 相手がこの通知をミュートしているようなら、既読を予めつけておく
isRead: isMuted,
...data,
} as Partial<Notification>)
.then(x => this.notificationsRepository.findOneByOrFail(x.identifiers[0]));
const packed = await this.notificationEntityService.pack(notification, {});
// Publish notification event
this.globalEventService.publishMainStream(notifieeId, 'notification', packed);
// 2秒経っても(今回作成した)通知が既読にならなかったら「未読の通知がありますよ」イベントを発行する
setTimeout(2000, 'unread note', { signal: this.#shutdownController.signal }).then(async () => {
const fresh = await this.notificationsRepository.findOneBy({ id: notification.id });
if (fresh == null) return; // 既に削除されているかもしれない
if (fresh.isRead) return;
//#region ただしミュートしているユーザーからの通知なら無視
const mutings = await this.mutingsRepository.findBy({
muterId: notifieeId,
});
if (data.notifierId && mutings.map(m => m.muteeId).includes(data.notifierId)) {
return;
}
//#endregion
this.globalEventService.publishMainStream(notifieeId, 'unreadNotification', packed);
this.pushNotificationService.pushNotification(notifieeId, 'notification', packed);
if (type === 'follow') this.emailNotificationFollow(notifieeId, await this.usersRepository.findOneByOrFail({ id: data.notifierId! }));
if (type === 'receiveFollowRequest') this.emailNotificationReceiveFollowRequest(notifieeId, await this.usersRepository.findOneByOrFail({ id: data.notifierId! }));
}, () => { /* aborted, ignore it */ });
return notification;
}
// TODO
//const locales = await import('../../../../locales/index.js');
// TODO: locale ファイルをクライアント用とサーバー用で分けたい
@bindThis
private async emailNotificationFollow(userId: User['id'], follower: User) {
/*
const userProfile = await UserProfiles.findOneByOrFail({ userId: userId });
if (!userProfile.email || !userProfile.emailNotificationTypes.includes('follow')) return;
const locale = locales[userProfile.lang ?? 'ja-JP'];
const i18n = new I18n(locale);
// TODO: render user information html
sendEmail(userProfile.email, i18n.t('_email._follow.title'), `${follower.name} (@${Acct.toString(follower)})`, `${follower.name} (@${Acct.toString(follower)})`);
*/
}
@bindThis
private async emailNotificationReceiveFollowRequest(userId: User['id'], follower: User) {
/*
const userProfile = await UserProfiles.findOneByOrFail({ userId: userId });
if (!userProfile.email || !userProfile.emailNotificationTypes.includes('receiveFollowRequest')) return;
const locale = locales[userProfile.lang ?? 'ja-JP'];
const i18n = new I18n(locale);
// TODO: render user information html
sendEmail(userProfile.email, i18n.t('_email._receiveFollowRequest.title'), `${follower.name} (@${Acct.toString(follower)})`, `${follower.name} (@${Acct.toString(follower)})`);
*/
}
onApplicationShutdown(signal?: string | undefined): void {
this.#shutdownController.abort();
}
}

View File

@@ -2,7 +2,7 @@ import { Inject, Injectable } from '@nestjs/common';
import push from 'web-push';
import { DI } from '@/di-symbols.js';
import type { Config } from '@/config.js';
import type { Packed } from '@/misc/schema';
import type { Packed } from '@/misc/json-schema';
import { getNoteSummary } from '@/misc/get-note-summary.js';
import type { SwSubscriptionsRepository } from '@/models/index.js';
import { MetaService } from '@/core/MetaService.js';

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