Compare commits

...

316 Commits

Author SHA1 Message Date
tamaina
c454a44785 wip hashtags 2023-07-03 09:18:54 +00:00
tamaina
41250d997b wip gallery 2023-07-03 08:57:13 +00:00
tamaina
a97d379c84 wip following 2023-07-03 08:44:25 +00:00
tamaina
535e778033 format 2023-07-03 06:15:35 +00:00
tamaina
726fdb9e93 wip 2023-07-03 06:14:32 +00:00
tamaina
ae3ce71bb2 flash 2023-07-03 05:59:23 +00:00
tamaina
106062fa23 wip 2023-07-03 05:50:13 +00:00
tamaina
42990fe6b6 wip 2023-07-03 05:45:38 +00:00
tamaina
dc787f7a76 nigiri tubusu 2023-07-03 05:43:01 +00:00
syuilo
83a6902997 Merge branch 'develop' into mkjs-n 2023-07-03 14:38:01 +09:00
syuilo
84d3a06637 Merge branch 'develop' of https://github.com/misskey-dev/misskey into develop 2023-07-03 14:35:10 +09:00
syuilo
60cddf87d8 Update MkRetentionLineChart.vue 2023-07-03 14:35:07 +09:00
tamaina
1c5606ca72 update schema-type 2023-07-03 05:28:38 +00:00
tamaina
02405287d1 ????????? 2023-07-03 05:06:23 +00:00
tamaina
bd9c084a3a follow 2023-07-03 04:38:55 +00:00
tamaina
cef5feaee2 Merge branch 'develop' into mkjs-n 2023-07-03 04:35:13 +00:00
mappi
6157616b37 fix(frontend): sparkle内にリンクを入れるとクリック不能になる問題の修正 (#11075)
* wip

* Fix 11021
2023-07-03 11:27:56 +09:00
syuilo
af3258dc79 perf(backend): make some features optionable
Resolve #11064
Resolve #11065
2023-07-02 16:02:32 +09:00
tamaina
734c41aba5 perf(frontend): MkImgWithBlurhashでblurhash描画に使うcanvasは再利用するようにする (#10966)
* blurhashを描画するためのcanvasは再利用する

* Revert "perf(frontend): WebGL contextの数を減らす"

This reverts commit aeb8955ca2.

* MkAvatarは平均色だけにする

* clean up

* fix
2023-07-02 13:46:49 +09:00
tamaina
fe16b16fc3 Merge branch 'develop' into mkjs-n 2023-07-02 03:30:52 +00:00
syuilo
a1327fa9e1 perf(backend): allow get for some endpoints 2023-07-02 08:28:26 +09:00
tamaina
f4cc9e3d2e Merge branch 'develop' into mkjs-n 2023-06-30 07:16:14 +00:00
Kagami Sascha Rosylight
1b1f82a2e2 feat(backend): accept OAuth bearer token (#11052)
* feat(backend): accept OAuth bearer token

* refactor

* Update packages/backend/src/server/api/ApiCallService.ts

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

* Update packages/backend/src/server/api/ApiCallService.ts

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

* fix

* kind: permission for account moved error

* also for suspended error

* Update packages/backend/src/server/api/StreamingApiServerService.ts

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

---------

Co-authored-by: Acid Chicken (硫酸鶏) <root@acid-chicken.com>
Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
2023-06-28 13:37:13 +09:00
Kagami Sascha Rosylight
d48172e9d1 refactor(backend/test): add interface UserToken (#11050) 2023-06-27 08:07:20 +09:00
Yuriha
58a898dfe0 Fix offscreencanvas undefined (#11017)
* Suppress ReferenceError on some environments (i.e. older iOS)

* fix

* fix

* lint

* adopt suggestion by acid-chicken
2023-06-26 10:45:14 +09:00
Kagami Sascha Rosylight
d23ad8b511 fix(backend): APIエラーのHTTP status code変更 (#11047) 2023-06-26 10:09:12 +09:00
syuilo
8099bc24e1 refactor(backend): use node16 for moduleResolution (#10938)
* refactor(backend): use node16 for moduleResolution

* update deps

* Update tsconfig.json

* ✌️

* revive KEYWORD

* restore strict-event-emitter-types dependency

* restore ms dependency

* cancel redundant import reorder

* fix

* Delete ms.ts

* remove rndstr

---------

Co-authored-by: Kagami Sascha Rosylight <saschanaz@outlook.com>
2023-06-25 21:13:15 +09:00
Kagami Sascha Rosylight
ef354e94f2 refactor(backend): replace rndstr with secureRndstr (#11044)
* refactor(backend): replace rndstr with secureRndstr

* Update pnpm-lock.yaml

* .js
2023-06-25 11:04:33 +09:00
Kagami Sascha Rosylight
7bb8c71543 chore(backend, misskey-js): add type for signup (#11043)
* chore(backend, misskey-js): add type for signup

* rerun
2023-06-25 08:34:18 +09:00
Kagami Sascha Rosylight
a2c0573f84 refactor(backend): replace private-ip with ipaddr.js (#11041)
* refactor(backend): replace private-ip with ipaddr.js

* restore ip-cidr
2023-06-25 06:35:09 +09:00
Kagami Sascha Rosylight
5d922e3084 chore(frontend): use @vitest/coverage-v8 2023-06-24 15:20:15 +02:00
Kagami Sascha Rosylight
f0b5860b9c chore(misskey-js): fix invalid version string format 2023-06-24 14:20:28 +02:00
syuilo
fd4c43786a chore(dev): use buraha via npm 2023-06-24 18:22:53 +09:00
syuilo
60cc7f62e6 update deps 2023-06-24 13:11:53 +09:00
syuilo
dc27ba6f03 enhance(frontend): improve ux of deck scroll
Resolve #11007
2023-06-24 12:58:26 +09:00
syuilo
3fe1c862f6 update misskey-js version 2023-06-24 12:46:30 +09:00
Yuriha
33a2c0b59e Make role tag clickable on user pages (#11019) 2023-06-24 07:51:44 +09:00
Caipira
e8c5117b2d fix(backend): Resolve missing parseObjectId in IdService (#11039) 2023-06-23 16:30:47 +09:00
Balazs Nadasdi
e2261b63e9 fix: clear queue endpoint error with redis script (#11037)
Error message:
```
ReplyError: ERR value is not an integer or out of range script: 720d973b3877f92b4fb3285ced83c97cdd204979, on @user_script:209.
```

The whole error can be tracked back to one of the arguments, which is
`Infinity` in the codebase, but it has to be a number.

The documentation in bullmq says `0` is unlimited[^1], and bullmq tries to
parse the argument with `tonumber` which returns with `-9223372036854775808` if
the argument is `"Infinity"` which is out of bound.

```
127.0.0.1:6379> eval 'return tonumber(ARGV[3])' '2' 'slippy.xyz:queue:inbox:inbox:delayed' 'slippy.xyz:queue:inbox:inbox:events' 'slippy.xyz:queue:inbox:inbox:' '1687183763944' Infinity 'delayed'
(integer) -9223372036854775808
127.0.0.1:6379>
```

[^1]: https://github.com/taskforcesh/bullmq/blob/master/src/commands/cleanJobsInSet-2.lua#L10

Signed-off-by: Efertone <efertone@pm.me>
2023-06-22 15:56:40 +09:00
tamaina
4d021f315f wip 2023-06-20 07:38:15 +00:00
tamaina
bad25a804c wip 2023-06-20 07:20:55 +00:00
tamaina
019199168e add 2023-06-20 07:17:38 +00:00
tamaina
8122cb3a86 Merge branch 'develop' into mkjs-n 2023-06-20 06:52:36 +00:00
NoriDev
8c7bcdf998 fix(client): サーバーメトリクスが90度傾いている (#11012) 2023-06-17 13:54:54 +09:00
tamaina
ab02fd3ec4 drive/folders 2023-06-16 06:49:29 +00:00
tamaina
028e7c00ae 移行作業再開 2023-06-16 06:40:54 +00:00
tamaina
27b6921d3c follow upstream 2023-06-16 06:21:11 +00:00
tamaina
3ec19e0b00 Merge branch 'develop' into mkjs-n 2023-06-16 06:14:29 +00:00
syuilo
f5dfb64a52 ユーザー統計表示機能を削除
Resolve #10998
2023-06-13 14:13:33 +09:00
syuilo
fa7fd9ce25 fix image of MkError.vue 2023-06-11 15:38:06 +09:00
syuilo
63971f1cd8 13.13.2 2023-06-11 10:03:33 +09:00
syuilo
b1313fbca8 Merge branch 'develop' of https://github.com/misskey-dev/misskey into develop 2023-06-11 10:01:41 +09:00
syuilo
f1b0c54f6e New Crowdin updates (#10971)
* New translations ja-JP.yml (Chinese Simplified)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (English)

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

* New translations ja-JP.yml (Turkish)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (English)
2023-06-11 10:01:30 +09:00
syuilo
94c09f1441 🎨 2023-06-11 09:53:07 +09:00
syuilo
46222d0258 tweak of f3a16bcd6 2023-06-10 17:41:52 +09:00
syuilo
c59a30ec09 Update CHANGELOG.md 2023-06-10 17:27:35 +09:00
nenohi
f3a16bcd6d ロールのユーザーリストを非公開にできるように (#10987)
* ロールのユーザーリストを非公開にできるように

* Changelog update
2023-06-10 17:26:48 +09:00
syuilo
f69627939b Update misskey-js.api.md 2023-06-10 13:45:30 +09:00
syuilo
e8420ad90b fix(backend): キャッシュが溜まり続けないように
Related #10984
2023-06-10 13:45:11 +09:00
syuilo
6182a1cb2c enhance(backend): WebSocketのPing/Pongをプロトコル制御フレームの物で判別する
Resolve #10969
2023-06-09 17:07:57 +09:00
syuilo
308ab8f177 chore 2023-06-09 16:11:28 +09:00
syuilo
359fbd78c1 Merge branch 'develop' of https://github.com/misskey-dev/misskey into develop 2023-06-09 15:53:43 +09:00
syuilo
dd733ec1d0 enhance(frontend): サーバーのテーマ設定を別ページに分離 2023-06-09 15:53:40 +09:00
tamaina
5e680500e5 chore: instance → server 2023-06-09 06:32:09 +00:00
atsuchan
0465e74521 Fix: enhance: タイムラインにフォロイーの行った他人へのリプライを含めるかどうかの設定をアカウントに保存するのをやめるように (#10982) 2023-06-09 14:08:35 +09:00
Ebise Lutica
34a32a8334 エラー画像URLを設定可能に (#10959)
* エラー画像URLを設定可能に

* Update CHANGELOG.md

* 設定したエラーアイコンをprefetchするようにbase.pugを変更

* 不足していたデータを追加

* enhance(frontend): デザイン調整
2023-06-09 14:00:53 +09:00
syuilo
3941c73db0 tweak of 6032c2be1 2023-06-09 12:55:27 +09:00
syuilo
703f3a8e37 Merge branch 'develop' of https://github.com/misskey-dev/misskey into develop 2023-06-09 12:51:19 +09:00
syuilo
6032c2be1c fix(frontend): Scrolling Issue in Safari for Top and Bottom Bars
fix #10977
2023-06-09 12:51:16 +09:00
syuilo
13870c63b0 add note 2023-06-09 12:47:36 +09:00
mappi
88083925ce Update CHANGELOG.md (#10979) 2023-06-09 12:09:21 +09:00
Outvi V
95b2148bfe fix: correctly check the sensitivity flag (#10976) 2023-06-09 10:13:46 +09:00
syuilo
8ccf954065 Update misskey-js.api.md 2023-06-06 09:37:36 +09:00
syuilo
e456c6a9c1 13.13.1 2023-06-06 09:17:11 +09:00
syuilo
68c5426fd5 Merge branch 'develop' of https://github.com/misskey-dev/misskey into develop 2023-06-06 09:16:40 +09:00
syuilo
29856a9129 tweak of 981e6f996 2023-06-06 09:16:38 +09:00
syuilo
f4943bc5bb New translations ja-JP.yml (Japanese, Kansai) (#10954) 2023-06-06 09:09:46 +09:00
syuilo
aeb8955ca2 perf(frontend): WebGL contextの数を減らす
#10960
2023-06-06 09:09:23 +09:00
syuilo
981e6f996e fix(frontend): タブがアクティブな間はstreamが切断されないように
Fix #10952
2023-06-06 09:04:57 +09:00
CaffeeLake
8263cc0094 Fix: #10955 TypeError: JSON5.parse is not a function (#10956)
* Fix: JSON5.parse is not a function

* update changelog

* update chglog

---------

Co-authored-by: tamaina <tamaina@hotmail.co.jp>
2023-06-05 21:44:28 +09:00
tamaina
fa051a2a5f 🎨 2023-06-05 12:35:23 +00:00
tamaina
ce252143c3 chore: Please write more detailed environmental information in your bug report. 2023-06-05 12:29:52 +00:00
syuilo
259be258aa Merge branch 'develop' of https://github.com/misskey-dev/misskey into develop 2023-06-05 18:06:44 +09:00
Yuriha
2d5bb40ad0 Condensedlines reflow once (#10944)
* perf: Update MkCondensedLine styles after reading all dimensions

* perf: reduce reflow in MkCondensedLine

* lint

* Update packages/frontend/src/components/global/MkCondensedLine.vue

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

* Update packages/frontend/src/components/global/MkCondensedLine.vue

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

---------

Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
Co-authored-by: Acid Chicken (硫酸鶏) <root@acid-chicken.com>
2023-06-05 18:06:33 +09:00
syuilo
db7fb1c688 Merge branch 'develop' of https://github.com/misskey-dev/misskey into develop 2023-06-05 18:05:32 +09:00
syuilo
6b0685a25c [ci skip] New Crowdin updates (#10947)
* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Chinese Traditional)
2023-06-05 18:05:20 +09:00
syuilo
618d07158a 13.13.0 2023-06-05 18:05:03 +09:00
syuilo
a63a417fd4 Merge branch 'develop' of https://github.com/misskey-dev/misskey into develop 2023-06-05 18:04:54 +09:00
syuilo
4443dba717 Update basic.cy.js 2023-06-05 18:04:51 +09:00
tamaina
565c502bbf fix(backend): pageのピン留めを解除することができない問題を修正
Fix #10950
2023-06-05 09:04:30 +00:00
tamaina
9e716fd813 fix(frontend): MkUserPopupが省略されないのを修正
Fix #10870
2023-06-05 08:58:00 +00:00
syuilo
34e1b52b38 Update e2e.js 2023-06-05 17:45:24 +09:00
tamaina
8401117293 format 2023-06-05 07:50:55 +00:00
tamaina
ced5638b80 wip 2023-06-05 07:49:39 +00:00
tamaina
b532ad8cd4 wip 2023-06-05 07:36:48 +00:00
tamaina
b818f2308d wip 2023-06-05 07:28:11 +00:00
tamaina
b697b2f651 wip 2023-06-05 07:16:21 +00:00
tamaina
0571b83978 wip 2023-06-05 06:55:13 +00:00
tamaina
b519ff1e10 clean up 2023-06-05 06:39:06 +00:00
tamaina
601eb65cfb fix 2023-06-05 06:38:58 +00:00
tamaina
59f4bf2a74 wip 2023-06-05 06:35:59 +00:00
tamaina
a5a9540eac wip 2023-06-05 06:09:43 +00:00
tamaina
bb46030677 chartsSchemasオブジェクトに集約 2023-06-05 06:05:36 +00:00
tamaina
9530cb01b9 wip 2023-06-05 05:46:35 +00:00
tamaina
fd223a8538 Merge branch 'develop' into mkjs-n 2023-06-05 05:12:03 +00:00
syuilo
0cb3c7481c fix typo: schema -> scheme 2023-06-05 10:55:18 +09:00
tamaina
4c52f3b286 SignInはcreatedAtをtoISOStringする 2023-06-04 18:42:08 +00:00
tamaina
edc38fc2c7 そもそもPacked<'...'>は常にSerializedである 2023-06-04 18:39:39 +00:00
tamaina
4a104af304 Use Serialized in EntityService 2023-06-04 18:26:05 +00:00
tamaina
a1b243bbda fix 2023-06-04 17:53:24 +00:00
tamaina
6bd7a0d0aa clean up 2023-06-04 17:51:14 +00:00
tamaina
80bd84932c wip 2023-06-04 17:50:42 +00:00
tamaina
7f28b7334c wip 2023-06-04 17:42:10 +00:00
tamaina
669cfb1e29 wip 2023-06-04 17:37:00 +00:00
tamaina
47fae30aba wip 2023-06-04 17:27:52 +00:00
tamaina
64bbfc2107 wip 2023-06-04 17:22:53 +00:00
tamaina
1e2178b717 wip 2023-06-04 17:20:33 +00:00
tamaina
b5852f6053 clean up 2023-06-04 16:42:11 +00:00
tamaina
35b1f73b51 wip 2023-06-04 16:41:45 +00:00
tamaina
f651ca4b48 wip 2023-06-04 15:39:43 +00:00
tamaina
8bad11c559 wip 2023-06-04 15:34:11 +00:00
tamaina
aead5305a7 wip 2023-06-04 15:13:53 +00:00
tamaina
de9a5d515d wip 2023-06-04 15:07:21 +00:00
tamaina
7f51ace0ff fix 2023-06-04 15:05:35 +00:00
tamaina
586cfbe880 clean up 2023-06-04 15:05:10 +00:00
tamaina
f7f8845801 wip 2023-06-04 15:05:01 +00:00
tamaina
93d111bfb6 wip 2023-06-04 14:59:14 +00:00
tamaina
1f64b7c9ea fix 2023-06-04 14:56:59 +00:00
tamaina
c4f434aa01 wip 2023-06-04 14:56:36 +00:00
tamaina
4001c974a6 region 2023-06-04 14:51:58 +00:00
tamaina
2fc2f2d616 wip 2023-06-04 14:48:23 +00:00
tamaina
f81479ad05 Merge branch 'develop' into mkjs-n 2023-06-04 13:31:14 +00:00
syuilo
db623dda22 New Crowdin updates (#10943)
* New translations ja-JP.yml (Russian)

* New translations ja-JP.yml (Russian)

* New translations ja-JP.yml (Arabic)

* New translations ja-JP.yml (Russian)

* New translations ja-JP.yml (Russian)

* New translations ja-JP.yml (Russian)
2023-06-04 14:31:03 +09:00
syuilo
1177528c25 fix backend e2e 2023-06-04 14:03:46 +09:00
mappi
a7abf941c0 fix:vue-plyr廃止追加対応(Audio要素のコンテキストメニューをブラウザデフォルトに) (#10940)
* wip

* add comment

* fix quotes
2023-06-02 16:31:25 +09:00
syuilo
5230ec883e fix(backend): 7日経過して無効化されたアンテナを再度有効化する方法がない問題を修正
Fix #10476
2023-06-02 15:18:34 +09:00
syuilo
482b00df77 🎨 2023-06-02 14:13:36 +09:00
syuilo
91d790bbb6 update deps 2023-06-02 11:34:38 +09:00
syuilo
40295ae57d fix style
Fix #10870
2023-06-02 11:03:59 +09:00
syuilo
3857cd589f New Crowdin updates (#10935)
* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Norwegian)

* New translations ja-JP.yml (Norwegian)

* New translations ja-JP.yml (Chinese Simplified)
2023-06-02 09:13:51 +09:00
syuilo
9eaca966a4 perf(backend): terminate stalled websocket connections
Resolve #10885
2023-06-02 09:13:41 +09:00
Acid Chicken (硫酸鶏)
8bdf0dd135 test: ignore MkImgWithBlurhash to avoid unstable snapshots 2023-06-01 23:27:58 +09:00
tamaina
eedc8049db fix(frontend): make scrollbar-color track transparent
Fix #9414
2023-06-01 12:03:07 +00:00
syuilo
23f272cc7d [ci skip] update patrons 2023-06-01 19:55:33 +09:00
syuilo
15450b18e8 [ci skip] make enableCondensedLineForAcct false by default
for performance
2023-06-01 19:50:51 +09:00
syuilo
50aeaf7498 [ci skip] 🎨 2023-06-01 19:45:06 +09:00
syuilo
861bfa06a8 🎨 2023-06-01 18:07:30 +09:00
Acid Chicken (硫酸鶏)
3b30ee3130 test: fix vitest 2023-06-01 08:50:26 +00:00
syuilo
f6830885d7 tweak of cd8274888 2023-06-01 17:34:56 +09:00
syuilo
ff56511638 13.13.0-beta.7 2023-06-01 17:20:25 +09:00
Acid Chicken (硫酸鶏)
337dd97b49 perf(#10923): CSS Modules のクラス名をインライン化する (#10930)
* perf(#10923): unwind css module class name

* perf(#10923): support multiple components

* refactor: clean up

* refactor(#10923): avoid `useCssModule()`

* fix(#10923): allow direct literal class name

* fix(#10923): avoid computed class name

* fix(#10923): allow literal keys

* fix(#10923): typo

* fix(#10923): invalid class names

* chore: test

* revert: test

This reverts commit 5c7ef366ec.

* fix(#10923): hidden tale

* perf(#10923): also unwind scoped css contained components

* perf(#10923): `normalizeClass` AOT compilation

---------

Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
2023-06-01 17:19:46 +09:00
syuilo
146e89edd0 Update index.d.ts 2023-06-01 17:19:11 +09:00
syuilo
cd82748889 enhance(frontend): 追加の絵文字用辞書をダウンロードできるように
Resolve #10921
2023-06-01 17:10:53 +09:00
syuilo
2c0b10b0ee refactor 2023-06-01 16:28:24 +09:00
syuilo
6c09361ec6 🎨 2023-06-01 13:50:13 +09:00
SASAGAWA Kiyoshi
3089a86c8e fix: テーマにプロパティ 'fgOnWhite' を追加してフォローボタンのスタイルを調整 (#10931)
* fix: add theme property 'fgOnWhite' and fix styles of follow button.

* fix: add theme property 'fgOnWhite' and fix styles of follow button.
2023-06-01 13:29:44 +09:00
syuilo
ec2f05d4f7 fix(backend): i/notificationsのsinceIdが機能しない問題を修正
Fix #10902
2023-06-01 13:28:43 +09:00
syuilo
31a8129cb9 New translations ja-JP.yml (Korean) (#10933) 2023-06-01 13:20:43 +09:00
syuilo
8cc6c2c864 New Crowdin updates (#10929)
* New translations ja-JP.yml (Korean)

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

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

* New translations ja-JP.yml (Norwegian)
2023-06-01 09:29:29 +09:00
syuilo
a4de927df8 Merge branch 'develop' of https://github.com/misskey-dev/misskey into develop 2023-06-01 09:20:39 +09:00
syuilo
a2c77a0944 Update style.scss 2023-06-01 09:20:37 +09:00
syuilo
d8a564c6a0 🎨 2023-06-01 08:54:37 +09:00
syuilo
ff94b64c91 🎨 2023-06-01 07:51:02 +09:00
tamaina
1cc616b86c fix(frontend): disconnect ResizeObserver 2023-05-31 16:04:01 +00:00
syuilo
6addf9002c tweak ui 2023-05-31 18:03:43 +09:00
mappi
6dd219b6c7 fix: Firefoxにおける絵文字ピッカーのTabキーフォーカス問題の修正 (#10926)
* fix 10744

* fix 10744

* Update CHANGELOG.md

* add comment
2023-05-31 14:03:54 +09:00
syuilo
a535142e82 13.13.0-beta.6 2023-05-31 13:43:36 +09:00
syuilo
9521519cb8 reafactor 2023-05-31 13:41:38 +09:00
syuilo
e11f82c300 refactor 2023-05-31 13:27:59 +09:00
kabo2468
aba0755880 enhance(client): MFMのx2, scale, positionが含まれていたらノートをたたむようにした (#10165)
* enhance(client): MFMのx2, scale, positionが含まれていたらノートをたたむようにした

* Update CHANGELOG.md

---------

Co-authored-by: tamaina <tamaina@hotmail.co.jp>
2023-05-31 12:57:40 +09:00
syuilo
821bb1c476 perf(frontend): サーバーにカスタム絵文字の種類が多い場合のパフォーマンスの改善
Resolve #10925
2023-05-31 12:42:24 +09:00
syuilo
14da0a65f7 tweak ui 2023-05-31 12:24:00 +09:00
syuilo
8e5d31eb5c New Crowdin updates (#10918)
* 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 (Norwegian)

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

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Norwegian)

* New translations ja-JP.yml (Norwegian)

* New translations ja-JP.yml (Norwegian)
2023-05-31 09:06:29 +09:00
tamaina
f8f3304164 fix(frontend/MkNoteDetailed): fix css module 2023-05-30 16:24:45 +00:00
syuilo
d7efdd7123 perf(frontend): minify file names
Resolve #10924
2023-05-30 18:55:22 +09:00
syuilo
4256e20a7f 13.13.0-beta.5 2023-05-30 17:39:37 +09:00
syuilo
f2d9e3105d fix(frontend): Pagesのコンテンツが表示されない・作成や編集ができない問題を修正
Fix #10908
2023-05-30 17:37:38 +09:00
syuilo
a6cd97ca9a fix(backend): 「アクセストークンの管理」画面でアプリの情報が表示されない問題を修正
Fix #10920
2023-05-30 17:27:47 +09:00
syuilo
a4a171781b clean up 2023-05-30 15:23:21 +09:00
syuilo
8e8e3dbe4e refactor 2023-05-30 15:18:08 +09:00
syuilo
de71845b35 🎨 2023-05-30 14:38:13 +09:00
syuilo
a3a47b8d35 🎨 2023-05-30 14:34:55 +09:00
syuilo
f091007882 refactor 2023-05-30 12:16:39 +09:00
syuilo
8f14b42e81 perf: インスタンスデフォルトテーマを予めjson5 -> jsonに変換しておくことでjson5を初期バンドルに含めずに済むように 2023-05-30 11:51:29 +09:00
syuilo
8b33a70fc4 vue-plyrやめるなど
- 問題点が多い
- バンドルサイズ削減
2023-05-30 11:32:29 +09:00
syuilo
dc031b1d07 perf(frontend): emojilistのサイズ削減 2023-05-30 11:18:40 +09:00
syuilo
f551b6d15e Merge branch 'develop' of https://github.com/misskey-dev/misskey into develop 2023-05-30 10:21:08 +09:00
syuilo
0a2ac58b82 refactor 2023-05-30 10:20:06 +09:00
tamaina
6198313c49 akiramemasita 2023-05-29 17:19:20 +00:00
tamaina
90a22fe32f ✌️ 2023-05-29 17:16:53 +00:00
tamaina
3918473e29 wip 2023-05-29 17:03:20 +00:00
tamaina
931cea75b6 serial 2023-05-29 16:47:49 +00:00
tamaina
68a2aa3efd wip 2023-05-29 16:39:03 +00:00
tamaina
dbeb1856ac ServerInfo 2023-05-29 16:30:50 +00:00
tamaina
07bbadbbdc wip 2023-05-29 16:26:16 +00:00
tamaina
78558eb666 wip 2023-05-29 16:09:42 +00:00
tamaina
bc15dde742 wip 2023-05-29 16:01:04 +00:00
tamaina
9135d2757e wip 2023-05-29 14:17:25 +00:00
tamaina
a1c96d9bcb wip 2023-05-29 14:11:51 +00:00
tamaina
94f25d9cdd wip 2023-05-29 14:09:13 +00:00
tamaina
e1b4a0438e RoleCondFormulaValue: property type assertion 2023-05-29 14:03:39 +00:00
tamaina
93ea327660 wip 2023-05-29 13:28:31 +00:00
tamaina
9ce6f99cad Merge branch 'develop' into mkjs-n 2023-05-29 13:05:52 +00:00
tamaina
3c07d3fc08 use pnpm@8.6.0 2023-05-29 13:05:43 +00:00
tamaina
d647df7f63 Merge branch 'develop' into mkjs-n 2023-05-29 13:02:41 +00:00
syuilo
c6ea7f754c New Crowdin updates (#10917)
* New translations ja-JP.yml (German)

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

* New translations ja-JP.yml (English)
2023-05-29 20:08:31 +09:00
syuilo
101e8d7adb refactor 2023-05-29 20:05:46 +09:00
syuilo
19b96ff650 refactor 2023-05-29 19:56:17 +09:00
syuilo
bd66a3f148 🎨 2023-05-29 19:37:03 +09:00
syuilo
7f235275c9 🎨 2023-05-29 19:35:11 +09:00
syuilo
3097bb6c7d refactor 2023-05-29 18:22:15 +09:00
syuilo
f469f555e8 New Crowdin updates (#10916)
* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Arabic)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Norwegian)

* New translations ja-JP.yml (Russian)

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

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

* New translations ja-JP.yml (Indonesian)

* New translations ja-JP.yml (Thai)

* New translations ja-JP.yml (Japanese, Kansai)
2023-05-29 17:53:05 +09:00
syuilo
115167e6da update deps 2023-05-29 17:52:55 +09:00
syuilo
a1200ad886 lint 2023-05-29 17:24:46 +09:00
syuilo
25d1b66ca4 refactor 2023-05-29 17:22:09 +09:00
syuilo
c5f9b1c224 lint 2023-05-29 17:13:45 +09:00
syuilo
8c66fad96b lint 2023-05-29 17:13:12 +09:00
syuilo
afa4cd9112 13.13.0-beta.4 2023-05-29 13:34:55 +09:00
syuilo
f930eaee02 perf(backend): use websockets/ws instead of theturtle32/WebSocket-Node (#10884)
* perf(backend): use websockets/ws instead of theturtle32/WebSocket-Node

Resolve #10883

* refactor

* Update StreamingApiServerService.ts

* Update StreamingApiServerService.ts

* ✌️

* Update StreamingApiServerService.ts

* fix main stream init

* fix timing 2

* setIntervalの重複を避ける(気休め)

* add comment

* ✌️

---------

Co-authored-by: tamaina <tamaina@hotmail.co.jp>
2023-05-29 13:32:19 +09:00
syuilo
b35b9bc27f Update QueueProcessorService.ts 2023-05-29 13:30:57 +09:00
syuilo
4790ddfad6 refactor of QueueProcessorService 2023-05-29 13:30:26 +09:00
syuilo
b6f21b6edb refactor 2023-05-29 13:21:26 +09:00
syuilo
fd7b77c542 enhance(backend): migrate bull to bullmq (#10910)
* wip

* wip

* Update QueueService.ts

* wip

* refactor

* ✌️

* fix

* Update QueueStatsService.ts

* refactor

* Update ApNoteService.ts

* Update mock-resolver.ts

* refactor

* Update mock-resolver.ts
2023-05-29 11:54:49 +09:00
tamaina
7cbd852fe5 pnpm devでCtrl+Cで終了させてもプロセスが完全に殺せないのを修正 (#10914) 2023-05-29 06:37:13 +09:00
tamaina
a80003cde5 fix(frontend): Zen UIで、デッキ設定で直接/以外を表示したときデッキに戻るボタンを表示 (#10909)
* fix(frontend): デッキ設定で直接/以外を表示したときのZen UIでデッキに戻るボタン

* fix style

* ?zenが指定されていた場合はボタンを表示しない
2023-05-28 20:58:39 +09:00
tamaina
654c93b0ce wip 2023-05-27 19:17:29 +00:00
tamaina
8d36911f90 wip 2023-05-27 17:28:47 +00:00
tamaina
84835be483 wip 2023-05-27 16:42:44 +00:00
tamaina
35f90e94c9 wip 2023-05-27 16:12:42 +00:00
tamaina
5268a55996 wip 2023-05-27 16:06:42 +00:00
tamaina
53ad4b18e5 Merge branch 'develop' into mkjs-n 2023-05-27 15:44:57 +00:00
syuilo
54b6b79559 Update endpoints.ts 2023-05-26 17:11:22 +09:00
syuilo
b4cfa412b0 Merge branch 'develop' into mkjs-n 2023-05-26 17:11:10 +09:00
tamaina
dfdfc8fab4 wip 2023-05-26 07:53:19 +00:00
tamaina
b14d3cdc32 fix 2023-05-26 07:48:48 +00:00
tamaina
82a17ea427 wip 2023-05-26 07:44:47 +00:00
tamaina
a57df6f2ca wip 2023-05-26 07:39:13 +00:00
tamaina
41c353e24d wip 2023-05-26 07:32:15 +00:00
tamaina
bca9c54923 wip 2023-05-26 07:20:14 +00:00
tamaina
ce5faa8ff5 wip 2023-05-26 07:18:15 +00:00
tamaina
0ef7a3db0f Merge branch 'develop' into mkjs-n 2023-05-26 07:01:29 +00:00
tamaina
c264b01658 fix pnpm-lock 2023-05-25 17:31:25 +00:00
tamaina
e07ed1b312 Merge branch 'develop' into mkjs-n 2023-05-26 02:25:32 +09:00
tamaina
c0bd1b82ab wip 2023-05-25 16:53:29 +00:00
tamaina
d7fe783c46 Merge branch 'develop' into mkjs-n 2023-05-25 14:49:51 +00:00
tamaina
1b6ac7888b wip 2023-05-22 05:20:19 +00:00
tamaina
86f4e206f4 wip 2023-05-22 04:50:18 +00:00
tamaina
e689dcdd73 reqに$refを許可しない 2023-05-22 03:20:49 +00:00
tamaina
810d065d21 wip 2023-05-22 01:43:00 +00:00
tamaina
8adf2701d2 fix 2023-05-21 18:53:22 +00:00
tamaina
11f41a6e8d wip 2023-05-21 18:50:32 +00:00
tamaina
8d1569567f backend endpoints wip 2023-05-21 18:49:44 +00:00
tamaina
23545bcbbb wip 2023-05-21 16:45:39 +00:00
tamaina
aea6950b46 wip 2023-05-21 16:44:29 +00:00
tamaina
d7d3f00488 wip 2023-05-21 16:35:48 +00:00
tamaina
307bc2a38e fix... 2023-05-21 15:15:25 +00:00
tamaina
919af7b967 ??? 2023-05-21 15:01:06 +00:00
tamaina
359f0b21b0 ? 2023-05-21 14:19:32 +00:00
tamaina
79f71acd42 wip 2023-05-21 14:15:45 +00:00
tamaina
89480d9029 wip 2023-05-21 14:06:11 +00:00
tamaina
0853b2fe42 wip 2023-05-21 13:53:55 +00:00
tamaina
13fe20d47e wip 2023-05-21 12:54:39 +00:00
tamaina
361ab296c7 Merge branch 'develop' into mkjs-n 2023-05-21 12:11:22 +00:00
tamaina
e76c1d8956 Merge branch 'develop' into mkjs-n 2023-05-19 22:45:50 +09:00
tamaina
0709ec5d82 Merge branch 'develop' into mkjs-n 2023-05-19 07:37:04 +00:00
tamaina
f7a0213af9 Merge branch 'develop' into mkjs-n 2023-05-19 07:26:36 +00:00
tamaina
9b27fffb0e Merge branch 'develop' into mkjs-n 2023-05-19 07:23:31 +00:00
tamaina
c0cbbe6072 Merge branch 'develop' into mkjs-n 2023-05-19 07:16:42 +00:00
tamaina
13fc093602 test 2023-05-15 09:44:23 +00:00
tamaina
ca29fdc795 fix 2023-05-15 09:19:36 +00:00
tamaina
03a2501b45 wip 2023-05-15 18:16:27 +09:00
tamaina
69ba41bd8d wip 2023-05-15 17:59:30 +09:00
tamaina
5f2bbea6de wip 2023-05-15 17:53:51 +09:00
tamaina
49dc995f1e ✌️ 2023-05-15 08:45:38 +00:00
tamaina
15ef1a082d wip 2023-05-15 08:42:47 +00:00
tamaina
cdfab72b35 wip 2023-05-15 17:39:41 +09:00
tamaina
37142d7495 wip 2023-05-15 17:30:52 +09:00
tamaina
b6d04f5d5b update 2023-05-12 14:12:54 +00:00
tamaina
5e268f0611 wip endpoints 2023-05-12 07:54:50 +00:00
tamaina
2afa664864 update 2023-05-12 07:42:36 +00:00
tamaina
64f4bb6a90 Merge branch 'develop' into mkjs-n 2023-05-12 07:03:20 +00:00
tamaina
00cc846729 clean up 2023-05-10 19:22:21 +00:00
tamaina
4f5d77391f wip~~ 2023-05-10 19:18:48 +00:00
tamaina
ac99cdce8b wip 2023-05-10 17:48:21 +00:00
tamaina
3324f3fa15 test 2023-05-10 17:34:13 +00:00
tamaina
56a1e436f3 wip 2023-05-10 16:55:36 +00:00
tamaina
ad6c5275ec wip 2023-05-10 16:22:21 +00:00
tamaina
0e08c56bc7 wip 2023-05-10 15:58:46 +00:00
tamaina
3e13bb4cd7 fix 2023-05-10 15:55:04 +00:00
tamaina
d3ecb02644 wip 2023-05-10 15:50:15 +00:00
tamaina
f3bc232419 wip 2023-05-10 15:12:37 +00:00
tamaina
00b1fd2ee3 wip 2023-05-10 15:07:37 +00:00
tamaina
44e819bf6a wip 2023-05-10 15:01:45 +00:00
tamaina
49e32ebf2b wip 2023-05-10 14:58:45 +00:00
tamaina
66447d13c1 wip 2023-05-10 14:53:26 +00:00
tamaina
5bb2d71231 wip 2023-05-10 14:48:12 +00:00
tamaina
32e489e536 wip 2023-05-10 14:45:31 +00:00
tamaina
fc10a9026c wip 2023-05-10 14:37:01 +00:00
tamaina
9699bac704 wip 2023-05-10 14:32:46 +00:00
tamaina
d328a8cefc wip 2023-05-10 14:21:54 +00:00
tamaina
34edf950ff wip 2023-05-10 14:20:52 +00:00
tamaina
7d8fa48d47 Merge branch 'develop' into mkjs-n 2023-05-10 14:20:07 +00:00
tamaina
96e04738c0 Merge branch 'develop' into mkjs-n 2023-05-10 08:04:38 +00:00
tamaina
e4c36bbd7a Merge branch 'develop' into mkjs-n 2023-05-04 12:33:48 +00:00
tamaina
0ee1dab2bc fix 2023-05-04 11:13:03 +00:00
tamaina
47e3792105 update 2023-05-04 11:03:03 +00:00
tamaina
0040aca841 fix 2023-05-04 10:57:55 +00:00
tamaina
41a822c34c wip 2023-05-04 10:56:53 +00:00
tamaina
55c217da73 wip 2023-05-04 10:56:24 +00:00
tamaina
ff85376306 fix 2023-05-02 17:57:56 +00:00
tamaina
ef15b9c0d3 wip 2023-05-02 17:31:17 +00:00
tamaina
abefddb90e Merge branch 'mkjs-n' of https://github.com/misskey-dev/misskey into mkjs-n 2023-05-02 16:51:48 +00:00
tamaina
3fcee7c4bd /schemas/Note 2023-05-02 16:51:41 +00:00
tamaina
d18750cb97 Merge branch 'develop' into mkjs-n 2023-05-03 01:24:08 +09:00
tamaina
6c53d1fdb7 Merge branch 'develop' into mkjs-n 2023-05-02 21:19:38 +09:00
tamaina
e9355bf918 wip 2023-05-02 12:05:17 +00:00
647 changed files with 23825 additions and 17599 deletions

View File

@@ -39,8 +39,22 @@ Please include errors from the developer console and/or server log files if you
<!-- Tell us where on the platform it happens -->
<!-- DO NOT WRITE "latest". Please provide the specific version. -->
Misskey version:
PostgreSQL version:
Redis version:
Your OS:
Your browser:
### 💻 Frontend
* Model and OS of the device(s):
<!-- Example: MacBook Pro (14inch, 2021), macOS Ventura 13.4 -->
* Browser:
<!-- Example: Chrome 113.0.5672.126 -->
* Server URL:
<!-- Example: misskey.io -->
* Misskey:
13.x.x
### 🛰 Backend (for server admin)
<!-- If you are using a managed service, put that after the version. -->
* Installation Method or Hosting Service: <!-- Example: docker compose, k8s/docker, systemd, "Misskey install shell script", development environment -->
* Misskey: 13.x.x
* Node: 18.x.x
* PostgreSQL: 15.x.x
* Redis: 7.x.x
* OS and Architecture: <!-- Example: Ubuntu 22.04.2 LTS aarch64 -->

View File

@@ -12,6 +12,37 @@
-->
## 13.x.x (unreleased)
### General
- identicon生成を無効にしてパフォーマンスを向上させることができるようになりました
- サーバーのマシン情報の公開を無効にしてパフォーマンスを向上させることができるようになりました
### Client
- Fix: サーバーメトリクスが90度傾いている
- Fix: sparkle内にリンクを入れるとクリック不能になる問題の修正
## 13.13.2
### General
- エラー時や項目が存在しないときなどのアイコン画像をサーバー管理者が設定できるように
- ロールが付与されているユーザーリストを非公開にできるように
- サーバーの負荷が非常に高いため、ユーザー統計表示機能を削除しました
### Client
- Fix: タブがバックグラウンドでもstreamが切断されないように
### Server
- Fix: キャッシュが溜まり続けないように
## 13.13.1
### Client
- Fix: タブがアクティブな間はstreamが切断されないように
### Server
- Fix: api/metaで`TypeError: JSON5.parse is not a function`エラーが発生する問題を修正
## 13.13.0
### General
@@ -32,13 +63,23 @@
- ハッシュタグのノート一覧ページから、そのハッシュタグで投稿するボタンを追加
- アカウント初期設定ウィザードに戻るボタンを追加
- アカウントの初期設定ウィザードにあとでボタンを追加
- サーバーにカスタム絵文字の種類が多い場合のパフォーマンスの改善
- Fix: URLプレビューで情報が取得できなかった際の挙動を修正
- Fix: Safari、Firefoxでの新規登録時、パスワードマネージャーにメールアドレスが登録されていた挙動を修正
- fix:ロールタイムラインが無効でも投稿が流れてしまう問題の修正
- fix:ロールタイムラインにて全ての投稿が流れてしまう問題の修正
- Fix: ロールタイムラインが無効でも投稿が流れてしまう問題の修正
- Fix: ロールタイムラインにて全ての投稿が流れてしまう問題の修正
- Fix: 「アクセストークンの管理」画面でアプリの情報が表示されない問題の修正
- Fix: Firefoxにおける絵文字ピッカーのTabキーフォーカス問題の修正
- Fix: フォローボタンがテーマのカラースキームによって視認性が悪くなる問題を修正
- 新しいプロパティ `fgOnWhite` が追加されました
### Server
- bullをbull-mqにアップグレードし、ジョブキューのパフォーマンスを改善
- ストリーミングのパフォーマンスを改善
- Fix: 無効化されたアンテナにアクセスがあった際に再度有効化するように
- Fix: お知らせの画像URLを空にできない問題を修正
- Fix: i/notificationsのsinceIdが機能しない問題を修正
- Fix: pageのピン留めを解除することができない問題を修正
## 13.12.2
@@ -78,11 +119,12 @@ Meilisearchの設定に`index`が必要になりました。値はMisskeyサー
## 13.12.0
### NOTE
- Node.js 18.6.0以上が必要になりました
- Node.js 18.16.0以上が必要になりました
### General
- アカウントの引っ越し(フォロワー引き継ぎ)に対応
- Meilisearchを全文検索に使用できるようになりました
* 「フォロワーのみ」の投稿は検索結果に表示されません。
- 新規登録前に簡潔なルールをユーザーに表示できる、サーバールール機能を追加
- ユーザーへの自分用メモ機能
* ユーザーに対して、自分だけが見られるメモを追加できるようになりました。
@@ -363,6 +405,7 @@ Meilisearchの設定に`index`が必要になりました。値はMisskeyサー
- アンテナでCWも検索対象にするように
- ノートの操作部をホバー時のみ表示するオプションを追加
- サウンドを追加
- enhance(client): MFMのx2, scale, positionが含まれていたらートをたたむように
- サーバーのパフォーマンスを改善
### Bugfixes

View File

@@ -169,25 +169,20 @@ describe('After user signed in', () => {
cy.get('[data-cy-user-setup-user-description] textarea').type('ほげ');
// TODO: アイコン設定テスト
cy.get('[data-cy-user-setup-back]').click();
cy.get('[data-cy-user-setup-continue]').click();
// プライバシー設定
cy.get('[data-cy-user-setup-back]').click();
cy.get('[data-cy-user-setup-continue]').click();
// フォローはスキップ
cy.get('[data-cy-user-setup-back]').click();
cy.get('[data-cy-user-setup-continue]').click();
// プッシュ通知設定はスキップ
cy.get('[data-cy-user-setup-back]').click();
cy.get('[data-cy-user-setup-continue]').click();
cy.get('[data-cy-user-setup-back]').click();
cy.get('[data-cy-user-setup-continue]').click();
});
});

View File

@@ -21,6 +21,8 @@ import './commands'
Cypress.on('uncaught:exception', (err, runnable) => {
if ([
'The source image cannot be decoded',
// Chrome
'ResizeObserver loop limit exceeded',

View File

@@ -2,6 +2,7 @@
_lang_: "العربية"
headlineMisskey: "شبكة مرتبطة بالملاحظات"
introMisskey: "اهلا بك! ميسكي هو منصة تدوين مصغر لا مركزية ومفتوحة المصدر.\nيمكنك مشاركة \"ملاحظات\" عن ما يجري حولك، وإخبار الجميع عن نفسك 📡\nتسمح لك \"الانفعالات\" بتعبير عن شعورك حول ملاحظات الآخرين 👍\nاكتشف عالمًا جديدًا 🚀"
poweredByMisskeyDescription: "{name} هو إحدى الخِدمات التي تستخدم المنصة مفتوحة المصدر <b>ميسكي</b> (يشار إليه كمثيل ميسكي)"
monthAndDay: "{day}/{month}"
search: "البحث"
notifications: "الإشعارات"
@@ -49,6 +50,7 @@ deleteAndEdit: "إزالة وإعادة الصياغة"
deleteAndEditConfirm: "أمتأكد من حذف الملاحظة؟ ستفقد كل مشاركاتها، والتفاعلات، والردود عليها."
addToList: "أضفه إلى قائمة"
sendMessage: "أرسل رسالة"
copyRSS: "انسخ رابط RSS"
copyUsername: "انسخ اسم المستخدم"
searchUser: "ابحث عن مستخدمين"
reply: "رد"
@@ -102,6 +104,8 @@ renoted: "أُعيد نشره"
cantRenote: "لا يمكن إعادة نشر الملاحظة"
cantReRenote: "لا يمكنك إعادة نشر ملاحظة معاد نشرها"
quote: "اقتبس"
inChannelRenote: "إعادة نشر في قناة"
inChannelQuote: "اقتباس في قناة"
pinnedNote: "ملاحظة مدبسة"
pinned: "دبّسها على الصفحة الشخصية"
you: "أنت"
@@ -119,6 +123,8 @@ unmarkAsSensitive: "ألغ تعيينه كمحتوى حساس"
enterFileName: "ادخل اسم الملف"
mute: "اكتم"
unmute: "إلغاء الكتم"
renoteMute: "اكتم إعادة النشر"
renoteUnmute: "ارفع الكتم عن إعادة النشر"
block: "احجب"
unblock: "إلغاء الحجب"
suspend: "علِق"
@@ -141,6 +147,7 @@ emojiUrl: "رابط الإيموجي"
addEmoji: "إضافة إيموجي"
settingGuide: "الإعدادات المستحسنة"
cacheRemoteFiles: "خزن مؤقتا الملفات البعيدة"
cacheRemoteFilesDescription: "إذا عُطل هذا الإعداد، ستُحمل الملفات من المثيل البعيد، هذا سيقلل من المساحة المستغلة على القرص لكن سيزيد حجم تدفق البيانات وهذا لأن الصور المصغرة لن تولّد."
flagAsBot: "علّمه كحساب آلي"
flagAsBotDescription: "فعّل هذا الخيار إذا كان هذا الحساب يُدار عبر برمجية. إذا فُعل فسيكون بمثابة علامة للمطورين الآخرين لتجنب سلاسل لا متناهية من التفاعل بين حسابات الآلية وضبط أنظمة ميسكي للتعامل مع هذا الحساب كآلي."
flagAsCat: "علّم هذا الحساب كحساب قط"
@@ -253,14 +260,15 @@ startMessaging: "ابدأ محادثة"
nUsersRead: "قرأه {n}"
agreeTo: "اوافق على {0}"
agree: "أقبل"
agreeBelow: "أقبل ما يلي"
basicNotesBeforeCreateAccount: "ملاحظات مهمة"
termsOfService: "شروط الخدمة"
start: "البداية"
home: "الرئيسي"
remoteUserCaution: "هذه المعلومات قد لا تكون مكتملة بما أن المستخدم من مثيل بعيد."
activity: "النشاط"
images: "الصور"
image: "الصور"
images: "صور"
image: "صور"
birthday: "تاريخ الميلاد"
yearsOld: "{age} سنة"
registeredDate: "انضم في"
@@ -362,6 +370,7 @@ antennaExcludeKeywords: "الكلمات المفتاحية المستثناة"
antennaKeywordsDescription: "افصل بينهم بمسافة لاستخدام معامل \"و\" أو بسطر لاستخدام معامل \"أو\""
notifyAntenna: "نبهني بصول ملاحظات جديدة"
withFileAntenna: "ملاحظات تحوي ملفات فقط"
enableServiceworker: "فعّل إرسال الإشعارات للمتصفح"
antennaUsersDescription: "اكتب اسم مستخدم لكل سطر"
caseSensitive: "حساسية حالة الأحرف"
withReplies: "بالردود"
@@ -391,6 +400,7 @@ moderation: "الإشراف"
nUsersMentioned: "{n} مستخدمين أُشير إليهم"
securityKey: "مفتاح الأمان"
lastUsed: "آخر استخدام"
lastUsedAt: "آخر استخدام: {t}"
unregister: "إلغاء التسجيل"
passwordLessLogin: "لِج مِن دون كلمة سرية"
resetPassword: "أعد تعيين كلمتك السرية"
@@ -441,6 +451,7 @@ or: "أو"
language: "اللغة"
uiLanguage: "لغة واجهة المستخدم"
aboutX: "عن {x}"
emojiStyle: "نمط الوجوه التعبيرية"
noHistory: "السجل فارغ"
signinHistory: "تاريخ تسجيل الدخول"
doing: "انتظر لحظة"
@@ -451,6 +462,7 @@ createAccount: "أنشئ حسابًا"
existingAccount: "الحسابات الموجودة"
regenerate: "أعِد التوليد"
fontSize: "حجم الخط"
limitTo: "سقفهُ لـ{x}"
noFollowRequests: "ليس لديك طلبات متابعة معلقة"
openImageInNewTab: "إفتح الصورة بصفحة جديدة"
dashboard: "لوحة التحكم"
@@ -479,6 +491,7 @@ objectStorageUseProxyDesc: "عطل هذا الخيار إذا لم ترد است
serverLogs: "سجلات الخادم"
deleteAll: "حذف الكل"
showFixedPostForm: "أظهر نموذج الكتابة في أعلى الصفحة"
showFixedPostFormInChannel: "أظهر نموذج الكتابة في أعلى الخط الزمني (قنوات)"
newNoteRecived: "هناك ملاحظات جديدة"
sounds: "الرنات"
sound: "الرنات"
@@ -514,6 +527,7 @@ userSilenced: "كُتم هذا المستخدم."
yourAccountSuspendedTitle: "هذا الحساب معلق"
yourAccountSuspendedDescription: "عُلق الحساب بسبب انتهاك شروط خدمة المثيل و ما شابه. إذا أردت معرفة التفصيل تواصل مع مدير المثيل. رجاءً لا تنشئ حساب جديد."
accountDeleted: "حُذف الحساب"
accountDeletedDescription: "حُذف هذا الحساب."
menu: "القائمة"
divider: "فاصل"
addItem: "إضافة عنصر"
@@ -539,6 +553,7 @@ author: "الكاتب"
leaveConfirm: "لديك تغييرات غير محفوظة. أتريد المتابعة دون حفظها؟"
manage: "إدارة "
plugins: "الإضافات"
preferencesBackups: "النُسخ الاحتياطية للإعدادات"
useFullReactionPicker: "استخدم الحجم الكامل لمنتقي التفاعلات"
width: "العرض"
height: "الإرتفاع"
@@ -648,6 +663,7 @@ contact: "التواصل"
useSystemFont: "استخدم الخط الافتراضية للنظام"
clips: "مشابك"
experimentalFeatures: "ميّزات اختبارية"
experimental: "اختباري"
developer: "المطور"
makeExplorable: "أظهر الحساب في صفحة \"استكشاف\""
makeExplorableDescription: "بتعطيل هذا الخيار لن يظهر حسابك في صفحة \"استكشاف\""
@@ -669,6 +685,7 @@ accentColor: "طابع لوني"
textColor: "لون النص"
saveAs: "احفظ كـ..."
advanced: "متقدم"
advancedSettings: "إعدادات متقدمة"
value: "القيمة"
createdAt: "أُنشئ في"
updatedAt: "حُدّث في"
@@ -733,6 +750,7 @@ popularPosts: "المشاركات المتداولة"
shareWithNote: "شاركه في ملاحظة"
ads: "الإعلانات"
expiration: "ينتهي استطلاع الرأي في"
startingperiod: "ابدأ"
memo: "تذكير"
priority: "الأولوية"
high: "عالية"
@@ -763,6 +781,7 @@ lastCommunication: "آخر تواصل"
resolved: "عولج"
unresolved: "لم يعالج"
breakFollow: "إلغاء الاشتراك"
breakFollowConfirm: "أمتأكد من إزالة المتابِع ؟"
itsOn: "مفعّل"
itsOff: "معطّل"
emailRequiredForSignup: "عنوان البريد الإلكتروني إلزامي للتسجيل"
@@ -777,6 +796,7 @@ muteThread: "اكتم النقاش"
unmuteThread: "ارفع الكتم عن النقاش"
ffVisibility: "مرئية المتابِعين/المتابَعين"
ffVisibilityDescription: "يسمح لك بتحديد من يمكنهم رؤية متابِعيك ومتابَعيك."
continueThread: "اعرض بقية النقاش"
deleteAccountConfirm: "سيحذف حسابك نهائيًا، أتريد المتابعة؟"
incorrectPassword: "كلمة السر خاطئة."
voteConfirm: "متيقِّن من تصويتك لـ {choice}؟"
@@ -798,25 +818,127 @@ tenMinutes: "10 دقائق"
oneHour: "ساعة"
oneDay: "يوم"
oneWeek: "أسبوع"
oneMonth: "شهر"
failedToFetchAccountInformation: "تعذر جلب معلومات الحساب"
cropNo: "استخدمها كما هي"
file: "الملفات"
recentNHours: "آخر {n} ساعة"
recentNDays: "آخر {n} أيام"
noEmailServerWarning: "خادم البريد غير مضبوط."
thereIsUnresolvedAbuseReportWarning: "توجد بلاغات غير معالجة."
recommended: "مقترح"
driveCapOverrideLabel: "غيّر حجم قرص التخزين لهذا المستخدم"
driveCapOverrideCaption: "أعد الحجم إلى القيمة الافتراضية بإدخال 0 أو أقل."
requireAdminForView: "لاستعراض هذه الصفحة وجب عليك الولوج كمدير."
typeToConfirm: "أدخل {x} للتأكيد"
deleteAccount: "احذف الحساب"
document: "التوثيق"
numberOfPageCache: "عدد الصفحات المخزنة مؤقتًا"
logoutConfirm: "أتريد الخروج؟"
lastActiveDate: "آخر استخدام"
statusbar: "شريط الحالة"
pleaseSelect: "حدد خيارًا"
reverse: "اقلب"
colored: "ملوّن"
label: "التسمية"
type: "نوع"
speed: "سرعة"
slow: "بطيء"
fast: "سريع"
sensitiveMediaDetection: "التعرف على المحتوى الحساس"
localOnly: "المحلي فقط"
failedToUpload: "فشل الرفع"
cannotUploadBecauseInappropriate: "تعذر رفع الملف لوجود محتوى حساس فيه."
cannotUploadBecauseNoFreeSpace: "تعذر رفع الملف لنقص مساحة التخزين."
cannotUploadBecauseExceedsFileSizeLimit: "تعذر رفع الملف بسبب تجاوز حجمه للحد المسموح"
beta: "بيتا"
navbar: "شريط التنقل"
shuffle: "خلط"
account: "الحسابات"
move: "أنقل"
pushNotification: "إرسال الإشعارات"
subscribePushNotification: "فعّل إرسال الإشعارات"
unsubscribePushNotification: "عطل إرسال الإشعارات"
pushNotificationAlreadySubscribed: "إرسال الإشعارات مفعل سلفًا"
pushNotificationNotSupported: "متصفحك لا يدعم إرسال الإشعارات أو المثيل لا يدعمها."
sendPushNotificationReadMessage: "احذف الإشعارات فور قراءتها"
sendPushNotificationReadMessageCaption: "هذا قد يزيد من معدل استهلاك الطاقة لجهازك."
caption: "التعليق التوضيحي"
tools: "أدوات"
cannotLoad: "تعذر التحميل"
like: "أعجبني"
unlike: "ألغِ الإعجاب"
show: "المظهر"
neverShow: "لا تظهره مجددًا"
didYouLikeMisskey: "هل أعجبك ميسكي؟"
roles: "الأدوار"
role: "الدور"
noRole: "لم يُعثر على دور"
normalUser: "مستخدم عادي"
undefined: "غير معرّف"
color: "اللون"
manageCustomEmojis: "إدارة الإيموجي المخصصة"
cannotPerformTemporary: "غير متاح مؤقتاً"
permissionDeniedError: "رُفضة العملية"
preset: "إعدادات مسبقة"
selectFromPresets: "اختر من الإعدادات المسبقة"
achievements: "الإنجازات"
gotInvalidResponseError: "استجابة غير متوقعة من الخادم"
gotInvalidResponseErrorDescription: "يتعذر الوصول إلى الخادم أوأنه يُصان، رجاءً حاول لاحقًا."
thisPostMayBeAnnoying: "هذا قد يزعج الآخرين."
thisPostMayBeAnnoyingHome: "أنشر في الخط الزمني الرئيس"
thisPostMayBeAnnoyingCancel: "ألغِ"
internalServerError: "خطأ داخلي في الخادم"
internalServerErrorDescription: "واجه الخادم خطأ غي متوقع."
copyErrorInfo: "انسخ تفاصيل الخطأ"
joinThisServer: "سجل في هذا المثيل"
exploreOtherServers: "اعثر على مثيل آخر"
disableFederationOk: "عطّل"
invitationRequiredToRegister: "هذا المثيل للمدعوين فقط. لتسجيل فيه تحتاج رمزًا صالحًا."
postToTheChannel: "انشر في قناة"
cannotBeChangedLater: "لا يمكن تغييره لاحقًا."
reactionAcceptance: "قبول التفاعلات"
rolesAssignedToMe: "الأدوار المسندة إلي"
resetPasswordConfirm: "هل تريد إعادة تعيين كلمة السر؟"
noteIdOrUrl: "معرف الملاحظة أو رابطها"
video: "فيديو"
videos: "فيديوهات"
accountMigration: "ترحيل الحساب"
accountMoved: "نقل هذا المستخدم حسابه:"
accountMovedShort: "رُحل هذا الحساب."
operationForbidden: "عملية ممنوعة"
forceShowAds: "أظهر الإعلانات التجارية دائما"
vertical: "عمودي"
horizontal: "جانبي"
position: "الموضع"
serverRules: "قوانين الخادم"
pleaseConfirmBelowBeforeSignup: "رجاءً وافق على ما يلي قبل التسجيل."
pleaseAgreeAllToContinue: "للمتابعة وافق على الحقول أعلاه."
continue: "متابعة"
preservedUsernames: "أسماء المستخدمين المحجوزة"
preservedUsernamesDescription: "قائمة بأسماء المستخدمين المحجوزة كلٌ في سطر. لن يُقبل التسجيل بهذه الأسماء وستبقى محصورة على التسجيل اليدوي بواسطة المديرين. لن يتأثر المستخدمون الذين يملكون هذه الأسماء سلفًا."
archive: "الأرشيف"
youFollowing: "متابَع"
options: "خيارات"
_role:
new: "دور جديد"
edit: "حرر الأدوار"
name: "اسم الدور"
description: "وصف الدور"
permission: "أذونات الدور"
assignTarget: "نوع الإسناد"
options: "خيارات"
policies: "السياسة العامة"
priority: "الأولوية"
_priority:
low: "منخفضة"
middle: "متوسط"
high: "عالية"
_options:
canManageCustomEmojis: "إدارة الإيموجي المخصصة"
_condition:
isLocal: "مستخدم محلي"
isRemote: "مستخدم بعيد"
_emailUnavailable:
used: "هذا البريد الإلكتروني مستخدم"
format: "صيغة البريد الإلكتروني غير صالحة"
@@ -1064,6 +1186,7 @@ _widgets:
onlineUsers: "المتّصلون"
jobQueue: "قائمة الانتظار"
serverMetric: "إحصائيات الخادم"
userList: "قائمة المستخدمين"
_userList:
chooseList: "اختر قائمة"
_cw:
@@ -1127,6 +1250,7 @@ _profile:
changeBanner: "غيّر اللافتة"
_exportOrImport:
allNotes: "كل الملاحظات"
favoritedNotes: " الملاحظات المفضلة"
followingList: "المتابَعون"
muteList: "المستخدمون المكتومون"
blockingList: "المستخدمون المحجوبون"
@@ -1145,6 +1269,8 @@ _charts:
notesTotal: "إجمالي الملاحظات"
filesIncDec: "تباين عدد الملفات"
filesTotal: "العدد الإجمالي للملفات"
storageUsageIncDec: "التباين في استغلال مساحة التخزين"
storageUsageTotal: "اجمالي مساحة التخزين المستغلة"
_instanceCharts:
requests: "الطلبات"
users: "تباين عدد المستخدمين"
@@ -1205,7 +1331,7 @@ _pages:
text: "نص"
textarea: "حقل نصي"
section: "قسم"
image: "الصور"
image: "صور"
button: "زرّ"
note: "ملاحظة مضمّنة"
_note:
@@ -1264,3 +1390,5 @@ _deck:
_webhookSettings:
name: "الإسم"
active: "مفعّل"
_events:
reaction: "عند تلقي تفاعل"

View File

@@ -52,6 +52,8 @@ addToList: "Zu Liste hinzufügen"
sendMessage: "Nachricht senden"
copyRSS: "RSS kopieren"
copyUsername: "Benutzernamen kopieren"
copyUserId: "Benutzer-ID kopieren"
copyNoteId: "Notiz-ID kopieren"
searchUser: "Nach einem Benutzer suchen"
reply: "Antworten"
loadMore: "Mehr laden"
@@ -790,6 +792,7 @@ noMaintainerInformationWarning: "Betreiberinformationen sind nicht konfiguriert.
noBotProtectionWarning: "Schutz vor Bots ist nicht konfiguriert."
configure: "Konfigurieren"
postToGallery: "Neuen Galeriebeitrag erstellen"
postToHashtag: "Mit diesem Hashtag senden"
gallery: "Galerie"
recentPosts: "Neue Beiträge"
popularPosts: "Beliebte Beiträge"
@@ -823,6 +826,7 @@ translatedFrom: "Aus {x} übersetzt"
accountDeletionInProgress: "Die Löschung deines Benutzerkontos ist momentan in Bearbeitung."
usernameInfo: "Ein Name, durch den dein Benutzerkonto auf diesem Server identifiziert werden kann. Du kannst das Alphabet (a~z, A~Z), Ziffern (0~9) oder Unterstriche (_) verwenden. Benutzernamen können später nicht geändert werden."
aiChanMode: "Ai-Modus"
devMode: "Entwicklermodus"
keepCw: "Inhaltswarnungen beibehalten"
pubSub: "Pub/Sub Benutzerkonten"
lastCommunication: "Letzte Kommunikation"
@@ -832,6 +836,8 @@ breakFollow: "Follower entfernen"
breakFollowConfirm: "Diesen Follower wirklich entfernen?"
itsOn: "Eingeschaltet"
itsOff: "Ausgeschaltet"
on: "An"
off: "Aus"
emailRequiredForSignup: "Angabe einer Email-Adresse als benötigt markieren"
unread: "Ungelesen"
filter: "Filter"
@@ -985,7 +991,9 @@ 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"
likeOnlyForRemote: "Alle (Nur \"Gefällt mir\" für fremde Instanzen)"
nonSensitiveOnly: "Keine Sensitiven"
nonSensitiveOnlyForLocalLikeOnlyForRemote: "Keine Sensitiven (Nur \"Gefällt mir\" von fremden Instanzen)"
rolesAssignedToMe: "Mir zugewiesene Rollen"
resetPasswordConfirm: "Wirklich Passwort zurücksetzen?"
sensitiveWords: "Sensible Wörter"
@@ -1043,6 +1051,18 @@ preventAiLearning: "Verwendung in machinellem Lernen (Generative bzw. Prediktive
preventAiLearningDescription: "Fordert Crawler auf, gepostetes Text- oder Bildmaterial usw. nicht in Datensätzen für maschinelles Lernen (Generative bzw. Prediktive AI/KI) zu verwenden. Dies wird durch das Hinzufügen einer \"noai\"-Flag in der HTML-Antwort des jeweiligen Inhalts erreicht. Da diese Flag jedoch ignoriert werden kann, ist eine vollständige Verhinderung hierdurch nicht möglich."
options: "Optionen"
specifyUser: "Spezifischer Benutzer"
failedToPreviewUrl: "Vorschau nicht anzeigbar"
update: "Aktualisieren"
rolesThatCanBeUsedThisEmojiAsReaction: "Rollen, die dieses Emoji als Reaktion verwenden können"
rolesThatCanBeUsedThisEmojiAsReactionEmptyDescription: "Sind keine Rollen angegeben, kann jeder dieses Emoji als Reaktion verwenden."
rolesThatCanBeUsedThisEmojiAsReactionPublicRoleWarn: "Diese Rollen müssen öffentlich sein."
cancelReactionConfirm: "Möchtest du deine Reaktion wirklich löschen?"
changeReactionConfirm: "Möchtest du deine Reaktion wirklich ändern?"
later: "Später"
goToMisskey: "Zu Misskey"
additionalEmojiDictionary: "Zusätzliche Emoji-Wörterbücher"
installed: "Installiert"
branding: "Branding"
_initialAccountSetting:
accountCreated: "Dein Konto wurde erfolgreich erstellt!"
letsStartAccountSetup: "Lass uns nun dein Konto einrichten."
@@ -1057,6 +1077,7 @@ _initialAccountSetting:
haveFun: "Viel Spaß mit {name}!"
ifYouNeedLearnMore: "Besuche {link}, falls du mehr über {name} (Misskey) lernen möchtest."
skipAreYouSure: "Die Kontoeinrichtung wirklich überspringen?"
laterAreYouSure: "Die Kontoeinrichtung wirklich später erledigen?"
_serverRules:
description: "Eine Reihe von Regeln, die vor der Registrierung angezeigt werden. Eine Zusammenfassung der Nutzungsbedingungen anzuzeigen ist empfohlen."
_accountMigration:
@@ -1073,7 +1094,7 @@ _accountMigration:
migrationConfirm: "Dieses Konto wirklich zu {account} umziehen? Sobald der Umzug beginnt, kann er nicht rückgängig gemacht werden, und dieses Konto nicht wieder im ursprünglichen Zustand verwendet werden."
movedAndCannotBeUndone: "\nDieses Konto wurde migriert.\nDiese Aktion ist unwiderruflich."
postMigrationNote: "Dieses Konto wird 24 Stunden nach Abschluss der Migration allen Konten, denen es derzeit folgt, nicht mehr folgen.\n\nSowohl die Anzahl der Follower als auch die der Konten, denen dieses Konto folgt, wird dann auf Null gesetzt. Um zu vermeiden, dass Follower dieses Kontos dessen Beiträge, welche nur für Follower bestimmt sind, nicht mehr sehen können, werden sie diesem Konto jedoch weiterhin folgen."
movedTo: "Umzugsziel:"
movedTo: "Neues Konto:"
_achievements:
earnedAt: "Freigeschaltet am"
_types:
@@ -1327,7 +1348,7 @@ _role:
condition: "Bedingung"
isConditionalRole: "Dies ist eine konditionale Rolle."
isPublic: "Öffentliche Rolle"
descriptionOfIsPublic: "Ist dies aktiviert, so kann jeder die Liste der Benutzer, die dieser Rolle zugewiesen sind, einsehen. Zusätzlich wird diese Rolle im Profil zugewiesener Benutzer angezeigt."
descriptionOfIsPublic: "Diese Rolle wird im Profil zugewiesener Benutzer angezeigt."
options: "Optionen"
policies: "Richtlinien"
baseRole: "Rollenvorlage"
@@ -1336,8 +1357,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."
isExplorable: "Rollenchronik veröffentlichen"
descriptionOfIsExplorable: "Ist dies aktiviert, so ist die Rollenchronik dieser Rolle frei zugänglich. Die Chronik von Rollen, welche nicht öffentlich sind, wird auch bei Aktivierung nicht veröffentlicht."
isExplorable: "Benutzerliste veröffentlichen"
descriptionOfIsExplorable: "Ist dies aktiviert, so ist die Chronik dieser Rolle, sowie eine Liste der Benutzer mit dieser Rolle, frei zugänglich."
displayOrder: "Position"
descriptionOfDisplayOrder: "Je höher die Nummer, desto höher die UI-Position."
canEditMembersByModerator: "Moderatoren können Benutzern diese Rolle zuweisen"

View File

@@ -52,6 +52,8 @@ addToList: "Add to list"
sendMessage: "Send a message"
copyRSS: "Copy RSS"
copyUsername: "Copy username"
copyUserId: "Copy user ID"
copyNoteId: "Copy note ID"
searchUser: "Search for a user"
reply: "Reply"
loadMore: "Load more"
@@ -790,6 +792,7 @@ noMaintainerInformationWarning: "Maintainer information is not configured."
noBotProtectionWarning: "Bot protection is not configured."
configure: "Configure"
postToGallery: "Create new gallery post"
postToHashtag: "Post to this hashtag"
gallery: "Gallery"
recentPosts: "Recent posts"
popularPosts: "Popular posts"
@@ -823,6 +826,7 @@ translatedFrom: "Translated from {x}"
accountDeletionInProgress: "Account deletion is currently in progress"
usernameInfo: "A name that identifies your account from others on this server. You can use the alphabet (a~z, A~Z), digits (0~9) or underscores (_). Usernames cannot be changed later."
aiChanMode: "Ai Mode"
devMode: "Developer mode"
keepCw: "Keep content warnings"
pubSub: "Pub/Sub Accounts"
lastCommunication: "Last communication"
@@ -832,6 +836,8 @@ breakFollow: "Remove follower"
breakFollowConfirm: "Really remove this follower?"
itsOn: "Enabled"
itsOff: "Disabled"
on: "On"
off: "Off"
emailRequiredForSignup: "Require email address for sign-up"
unread: "Unread"
filter: "Filter"
@@ -985,7 +991,9 @@ postToTheChannel: "Post to channel"
cannotBeChangedLater: "This cannot be changed later."
reactionAcceptance: "Reaction Acceptance"
likeOnly: "Only likes"
likeOnlyForRemote: "Only likes for remote instances"
likeOnlyForRemote: "All (Only likes for remote instances)"
nonSensitiveOnly: "Non-sensitive only"
nonSensitiveOnlyForLocalLikeOnlyForRemote: "Non-sensitive only (Only likes from remote)"
rolesAssignedToMe: "Roles assigned to me"
resetPasswordConfirm: "Really reset your password?"
sensitiveWords: "Sensitive words"
@@ -1043,6 +1051,18 @@ preventAiLearning: "Reject usage in Machine Learning (Generative AI)"
preventAiLearningDescription: "Requests crawlers to not use posted text or image material etc. in machine learning (Predictive / Generative AI) data sets. This is achieved by adding a \"noai\" HTML-Response flag to the respective content. A complete prevention can however not be achieved through this flag, as it may simply be ignored."
options: "Options"
specifyUser: "Specific user"
failedToPreviewUrl: "Could not preview"
update: "Update"
rolesThatCanBeUsedThisEmojiAsReaction: "Roles that can use this emoji as reaction"
rolesThatCanBeUsedThisEmojiAsReactionEmptyDescription: "If no roles are specified, anyone can use this emoji as reaction."
rolesThatCanBeUsedThisEmojiAsReactionPublicRoleWarn: "These roles must be public."
cancelReactionConfirm: "Really delete your reaction?"
changeReactionConfirm: "Really change your reaction?"
later: "Later"
goToMisskey: "To Misskey"
additionalEmojiDictionary: "Additional emoji dictionaries"
installed: "Installed"
branding: "Branding"
_initialAccountSetting:
accountCreated: "Your account was successfully created!"
letsStartAccountSetup: "For starters, let's set up your profile."
@@ -1057,6 +1077,7 @@ _initialAccountSetting:
haveFun: "Enjoy {name}!"
ifYouNeedLearnMore: "If you'd like to learn more about how to use {name} (Misskey), please visit {link}."
skipAreYouSure: "Really skip profile setup?"
laterAreYouSure: "Really do profile setup later?"
_serverRules:
description: "A set of rules to be displayed before registration. Setting a summary of the Terms of Service is recommended."
_accountMigration:
@@ -1073,7 +1094,7 @@ _accountMigration:
migrationConfirm: "Really migrate this account to {account}? Once started, this process cannot be stopped or taken back, and you will not be able to use this account in its original state anymore."
movedAndCannotBeUndone: "\nThis account has been migrated.\nMigration cannot be reversed."
postMigrationNote: "This account will unfollow all accounts it is currently following 24 hours after migration finishes.\nBoth the number of follows and followers will then become zero. To avoid your followers from being unable to see followers only posts of this account, they will however continue following this account."
movedTo: "Account to move to:"
movedTo: "New account:"
_achievements:
earnedAt: "Unlocked at"
_types:
@@ -1327,7 +1348,7 @@ _role:
condition: "Condition"
isConditionalRole: "This is a conditional role."
isPublic: "Public role"
descriptionOfIsPublic: "Anyone will be able to view a list of users assigned to this role. In addition, this role will be displayed in the profiles of assigned users."
descriptionOfIsPublic: "This role will be displayed in the profiles of assigned users."
options: "Options"
policies: "Policies"
baseRole: "Role template"
@@ -1336,8 +1357,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."
isExplorable: "Role timeline is public"
descriptionOfIsExplorable: "This role's timeline will become publicly accessible if enabled. Timelines of non-public roles will not be made public even if set."
isExplorable: "Make role explorable"
descriptionOfIsExplorable: "This role's timeline and the list of users with this will be made public if enabled."
displayOrder: "Position"
descriptionOfDisplayOrder: "The higher the number, the higher its UI position."
canEditMembersByModerator: "Allow moderators to edit the list of members for this role"

View File

@@ -20,6 +20,7 @@ noNotes: "No hay notas"
noNotifications: "No hay notificaciones"
instance: "Instancia"
settings: "Configuración"
notificationSettings: "Configurar las notificaciones"
basicSettings: "Configuración Básica"
otherSettings: "Configuración avanzada"
openInWindow: "Abrir en una ventana"
@@ -262,8 +263,10 @@ noMoreHistory: "El historial se ha acabado"
startMessaging: "Iniciar chat"
nUsersRead: "Leído por {n} personas"
agreeTo: "De acuerdo con {0}"
agree: "De acuerdo."
agreeBelow: "Estoy de acuerdo con lo siguiente"
basicNotesBeforeCreateAccount: "Notas básicas"
termsOfService: "Términos y condiciones"
start: "Comenzar"
home: "Inicio"
remoteUserCaution: "Para el usuario remoto, la información está incompleta"
@@ -473,6 +476,8 @@ createAccount: "Crear cuenta"
existingAccount: "Cuenta existente"
regenerate: "Regenerar"
fontSize: "Tamaño de la letra"
mediaListWithOneImageAppearance: "Altura de la lista de medios con una sola imagen."
limitTo: "{x} hasta un máximo de"
noFollowRequests: "No hay solicitudes de seguimiento"
openImageInNewTab: "Abrir imagen en nueva pestaña"
dashboard: "Panel de control"
@@ -555,6 +560,7 @@ accountDeletedDescription: "Esta cuenta ha sido borrada."
menu: "Menú"
divider: "Divisor"
addItem: "Agregar elemento"
rearrange: "Ordenar"
relays: "Relés"
addRelay: "Agregar relé"
inboxUrl: "Inbox URL"
@@ -698,6 +704,8 @@ contact: "Contacto"
useSystemFont: "Utilizar la tipografía por defecto del sistema"
clips: "Clip"
experimentalFeatures: "Características experimentales"
experimental: "Función experimental"
thisIsExperimentalFeature: "Se trata de una función experimental. Las especificaciones pueden cambiar o puede que no funcione correctamente."
developer: "Desarrolladores"
makeExplorable: "Hacer visible la cuenta en \"Explorar\""
makeExplorableDescription: "Si desactiva esta opción, su cuenta no aparecerá en la sección \"Explorar\"."
@@ -991,9 +999,12 @@ largeNoteReactions: "Agrandar las reacciones de las notas"
noteIdOrUrl: "ID o URL de la nota"
accountMigration: "Migración de cuenta"
accountMoved: "Este usuario se ha mudado a una nueva cuenta:"
accountMovedShort: "Esta cuenta ha sido migrada."
horizontal: "Horizontal"
youFollowing: "Siguiendo"
options: "Opción"
_initialAccountSetting:
accountCreated: "¡La cuenta ha sido creada!"
_accountMigration:
moveFrom: "Trasladar de otra cuenta a ésta"
moveFromLabel: "Cuenta desde la que se realiza el traslado:"
@@ -1174,6 +1185,8 @@ _achievements:
_client30min:
title: "Un descansito"
description: "30 minutos dedicados a Misskey"
_client60min:
title: "Viendo mucho Misskey."
_noteDeletedWithin1min:
title: "Ah... Mejor no..."
description: "Borrar una nota antes que de pase 1 minuto"

View File

@@ -908,12 +908,14 @@ neverShow: "Ne plus afficher"
remindMeLater: "Peut-être plus tard"
roles: "Rôles"
role: "Rôles"
noRole: "Aucun rôle"
normalUser: "Simple utilisateur·rice"
assign: "Attribuer"
color: "Couleur"
manageCustomEmojis: "Gestion des émojis personnalisés"
preset: "Préréglage"
selectFromPresets: "Sélectionner à partir des préréglages"
thisPostMayBeAnnoying: "Cette note peut gêner d'autres personnes."
thisPostMayBeAnnoyingCancel: "Annuler"
license: "Licence"
video: "Vidéo"
@@ -921,6 +923,7 @@ videos: "Vidéos"
dataSaver: "Économiseur de données"
accountMigration: "Migration de compte"
accountMoved: "Cet·te utilisateur·rice a migré son compte vers :"
addMemo: "Ajouter un mémo"
notificationDisplay: "Style des notifications"
leftTop: "En haut à gauche"
rightTop: "En haut à droite"
@@ -935,6 +938,8 @@ _achievements:
_notes1:
description: "Publiez votre première note"
flavor: "Passez un bon moment avec Misskey !"
_notes100:
title: "Beaucoup de notes"
_notes100000:
title: "ALL YOUR NOTE ARE BELONG TO US"
_login3:
@@ -985,6 +990,8 @@ _achievements:
title: "Joyeux Anniversaire !"
_loggedInOnNewYearsDay:
title: "Bonne année !"
_cookieClicked:
flavor: "Attendez une minute, vous êtes sur le mauvais site web ?"
_role:
assignTarget: "Attribuer"
priority: "Priorité"

View File

@@ -20,6 +20,7 @@ noNotes: "Tidak ada catatan"
noNotifications: "Tidak ada pemberitahuan"
instance: "Instansi"
settings: "Pengaturan"
notificationSettings: "Atur Notifikasi"
basicSettings: "Pengaturan umum"
otherSettings: "Pengaturan lainnya"
openInWindow: "Buka di jendela"
@@ -261,8 +262,10 @@ noMoreHistory: "Tidak ada sejarah lagi"
startMessaging: "Mulai mengirim pesan"
nUsersRead: "Dibaca oleh {n}"
agreeTo: "Saya setuju kepada {0}"
agree: "Setuju"
agreeBelow: "Saya setuju dengan di bawah ini"
basicNotesBeforeCreateAccount: "Catatan penting"
termsOfService: "Syarat dan ketentuan"
start: "Mulai"
home: "Beranda"
remoteUserCaution: "Informasi ini mungkin tidak mutakhir, karena pengguna ini berasal dari instansi luar."

5
locales/index.d.ts vendored
View File

@@ -1063,6 +1063,11 @@ export interface Locale {
"changeReactionConfirm": string;
"later": string;
"goToMisskey": string;
"additionalEmojiDictionary": string;
"installed": string;
"branding": string;
"enableServerMachineStats": string;
"enableIdenticonGeneration": string;
"_initialAccountSetting": {
"accountCreated": string;
"letsStartAccountSetup": string;

View File

@@ -1060,6 +1060,11 @@ cancelReactionConfirm: "リアクションを取り消しますか?"
changeReactionConfirm: "リアクションを変更しますか?"
later: "あとで"
goToMisskey: "Misskeyへ"
additionalEmojiDictionary: "絵文字の追加辞書"
installed: "インストール済み"
branding: "ブランディング"
enableServerMachineStats: "サーバーのマシン情報を公開する"
enableIdenticonGeneration: "ユーザーごとのIdenticon生成を有効にする"
_initialAccountSetting:
accountCreated: "アカウントの作成が完了しました!"
@@ -1349,8 +1354,8 @@ _role:
conditional: "コンディショナル"
condition: "条件"
isConditionalRole: "これはコンディショナルロールです。"
isPublic: "ロールを公開"
descriptionOfIsPublic: "ロールにアサインされたユーザーを誰でも見ることができます。また、ユーザーのプロフィールでこのロールが表示されます。"
isPublic: "公開ロール"
descriptionOfIsPublic: "ユーザーのプロフィールでこのロールが表示されます。"
options: "オプション"
policies: "ポリシー"
baseRole: "ベースロール"
@@ -1359,8 +1364,8 @@ _role:
iconUrl: "アイコン画像のURL"
asBadge: "バッジとして表示"
descriptionOfAsBadge: "オンにすると、ユーザー名の横にロールのアイコンが表示されます。"
isExplorable: "ロールタイムラインを公開"
descriptionOfIsExplorable: "オンにすると、ロールのタイムラインを公開します。ロールの公開がオフの場合、タイムラインの公開はされません。"
isExplorable: "ユーザーを見つけやすくする"
descriptionOfIsExplorable: "オンにすると、「みつける」でメンバー一覧が公開されるほか、ロールのタイムラインが利用可能になります。"
displayOrder: "表示順"
descriptionOfDisplayOrder: "数値が大きいほどUI上で先頭に表示されます。"
canEditMembersByModerator: "モデレーターのメンバー編集を許可"

View File

@@ -8,7 +8,7 @@ search: "探す"
notifications: "通知"
username: "ユーザー名"
password: "パスワード"
forgotPassword: "パスワード忘れてもうた"
forgotPassword: "パスワード忘れたん?"
fetchingAsApObject: "今ちと連合に照会しとるで"
ok: "ええで"
gotIt: "ほい"
@@ -47,11 +47,13 @@ copyContent: "内容をコピー"
copyLink: "リンクをコピー"
delete: "ほかす"
deleteAndEdit: "ほかして直す"
deleteAndEditConfirm: "このノートをほかしてもっかい直す?このノートへのリアクション、Renote、返信も全部消えるんやけどそれでもええん"
deleteAndEditConfirm: "このノートをほかしてもっかい直す?このノートへのツッコミ、Renote、返信も全部消えるんやけどそれでもええん"
addToList: "リストに入れたる"
sendMessage: "メッセージを送る"
copyRSS: "RSSをコピー"
copyUsername: "ユーザー名をコピー"
copyUserId: "ユーザーIDをコピー"
copyNoteId: "ートIDをコピー"
searchUser: "ユーザーを検索"
reply: "返事"
loadMore: "まだまだあるで!"
@@ -790,6 +792,7 @@ noMaintainerInformationWarning: "管理者情報が設定されてへんで"
noBotProtectionWarning: "Botプロテクションが設定されてへんで。"
configure: "設定する"
postToGallery: "ギャラリーへ投稿"
postToHashtag: "このハッシュタグで投稿"
gallery: "ギャラリー"
recentPosts: "最近の投稿"
popularPosts: "人気の投稿"
@@ -823,6 +826,7 @@ translatedFrom: "{x}から翻訳するで"
accountDeletionInProgress: "アカウント削除しとるで待っとってなー"
usernameInfo: "サーバー上であんたのアカウントをあんたやと分かるようにするための名前やで。アルファベット(a~z, A~Z)、数字(0~9)、それとアンダーバー(_)が使って考えてな。この名前は後から変更することはできへんからちゃんと考えるんやで。"
aiChanMode: "藍モードやで"
devMode: "開発者モード"
keepCw: "CWを維持するで"
pubSub: "Pub/Subのアカウント"
lastCommunication: "直近の通信"
@@ -832,6 +836,8 @@ breakFollow: "フォロワーを解除するで"
breakFollowConfirm: "フォロワー解除してもええか?"
itsOn: "オンになっとるよ"
itsOff: "オフになってるで"
on: "オン"
off: "オフ"
emailRequiredForSignup: "アカウント登録にメールアドレスを必須にするで"
unread: "未読"
filter: "フィルタ"
@@ -986,6 +992,8 @@ cannotBeChangedLater: "後からは変えられへんで。"
reactionAcceptance: "ツッコミの受け入れ"
likeOnly: "いいねだけ"
likeOnlyForRemote: "リモートからはいいねだけな"
nonSensitiveOnly: "センシティブじゃないやつだけ"
nonSensitiveOnlyForLocalLikeOnlyForRemote: "センシティブじゃないやつだけ (リモートはいいねだけ)"
rolesAssignedToMe: "自分に割り当てられたロール"
resetPasswordConfirm: "パスワード作り直すんでええな?"
sensitiveWords: "けったいな単語"
@@ -1043,6 +1051,17 @@ preventAiLearning: "生成AIの学習に使わんといて"
preventAiLearningDescription: "他の文章生成AIとか画像生成AIに、投稿したートとか画像なんかを勝手に使わんように頼むで。具体的にはnoaiフラグをHTMLレスポンスに含めるんやけど、これ聞いてくれるんはAIの気分次第やから、使われる可能性もちょっとはあるな。"
options: "オプション"
specifyUser: "ユーザー指定"
failedToPreviewUrl: "プレビューできへん"
update: "更新"
rolesThatCanBeUsedThisEmojiAsReaction: "ツッコミとして使えるロール"
rolesThatCanBeUsedThisEmojiAsReactionEmptyDescription: "ロールが一個も指定されてへんかったら、誰でもツッコミとして使えるで。"
rolesThatCanBeUsedThisEmojiAsReactionPublicRoleWarn: "ロールは公開ロールじゃないとアカンで。"
cancelReactionConfirm: "ツッコむんをやっぱやめるか?"
changeReactionConfirm: "ツッコミを別のに変えるか?"
later: "あとで"
goToMisskey: "Misskeyへ"
additionalEmojiDictionary: "絵文字の追加辞書"
installed: "インストール済み"
_initialAccountSetting:
accountCreated: "アカウント作り終わったで。"
letsStartAccountSetup: "アカウントの初期設定をしよか。"
@@ -1057,6 +1076,7 @@ _initialAccountSetting:
haveFun: "{name}、楽しんでな~"
ifYouNeedLearnMore: "{name}(Misskey)の使い方とかをよー知りたいんやったら{link}をみてな。"
skipAreYouSure: "初期設定飛ばすか?"
laterAreYouSure: "初期設定あとでやり直すん?"
_serverRules:
description: "新規登録前に見せる、サーバーの簡潔なルールを設定すんで。内容は使うための決め事の要約とすることを推奨するわ。"
_accountMigration:
@@ -1614,7 +1634,7 @@ _timelineTutorial:
step2_2: "最初のノートは、自己紹介とか「{name}始めてみたんや」とかがええと思うで。"
step3_1: "投稿できた?"
step3_2: "あんたのノートがタイムラインに出てきたら成功や。"
step4_1: "ノートには、「リアクション」を付けれるで。"
step4_1: "ノートには、「ツッコミ」を付けれるで。"
step4_2: "ツッコむんやったら、ノートの「+」マークを押して、好きな絵文字を選ぶで。"
_2fa:
alreadyRegistered: "もう設定終わっとるわ。"

View File

@@ -52,6 +52,8 @@ addToList: "리스트에 추가"
sendMessage: "메시지 보내기"
copyRSS: "RSS 복사"
copyUsername: "유저명 복사"
copyUserId: "유저 ID 복사"
copyNoteId: "노트 ID 복사"
searchUser: "사용자 검색"
reply: "답글"
loadMore: "더 보기"
@@ -505,7 +507,7 @@ objectStoragePrefixDesc: "이 Prefix 의 디렉토리 아래에 파일이 저장
objectStorageEndpoint: "Endpoint"
objectStorageEndpointDesc: "AWS S3의 경우 공란, 다른 서비스의 경우 각 서비스의 가이드에 맞게 endpoint를 설정해주세요. '<host>' 혹은 '<host>:<port>' 와 같이 지정합니다."
objectStorageRegion: "Region"
objectStorageRegionDesc: "'xx-east-1'와 같이 region을 지정해주세요. 사용하는 서비스에 region 개념이 없는 경우, 비워 두거나 'us-east-1'으로 설정해 주세요."
objectStorageRegionDesc: "'xx-east-1'와 같이 region을 지정해 주세요. 사용하는 서비스에 region 개념이 없는 경우 'us-east-1'으로 설정해 주세요. AWS 설정 파일 또는 환경 변수를 참조할 경우에는 비워주세요."
objectStorageUseSSL: "SSL 사용"
objectStorageUseSSLDesc: "API 호출시 HTTPS 를 사용하지 않는 경우 OFF 로 설정해 주세요"
objectStorageUseProxy: "연결에 프록시를 사용"
@@ -790,6 +792,7 @@ noMaintainerInformationWarning: "관리자 정보가 설정되어 있지 않습
noBotProtectionWarning: "Bot 방어가 설정되어 있지 않습니다."
configure: "설정하기"
postToGallery: "갤러리에 업로드"
postToHashtag: "이 해시태그에 게시"
gallery: "갤러리"
recentPosts: "최근 포스트"
popularPosts: "인기 포스트"
@@ -823,6 +826,7 @@ translatedFrom: "{x}에서 번역"
accountDeletionInProgress: "계정 삭제 작업을 진행하고 있습니다"
usernameInfo: "서버상에서 계정을 식별하기 위한 이름. 알파벳(a~z, A~Z), 숫자(0~9) 및 언더바(_)를 사용할 수 있습니다. 사용자명은 나중에 변경할 수 없습니다."
aiChanMode: "아이 모드"
devMode: "개발자 모드"
keepCw: "CW 유지하기"
pubSub: "Pub/Sub 계정"
lastCommunication: "마지막 통신"
@@ -830,8 +834,10 @@ resolved: "해결됨"
unresolved: "해결되지 않음"
breakFollow: "팔로워 해제"
breakFollowConfirm: "팔로우를 해제하시겠습니까?"
itsOn: "켜"
itsOff: "꺼"
itsOn: "켜져 있습니다"
itsOff: "꺼져 있습니다"
on: "켜짐"
off: "꺼짐"
emailRequiredForSignup: "가입할 때 이메일 주소 입력을 필수로 하기"
unread: "읽지 않음"
filter: "필터"
@@ -864,7 +870,7 @@ instanceDefaultLightTheme: "서버 기본 라이트 테마"
instanceDefaultDarkTheme: "서버 기본 다크 테마"
instanceDefaultThemeDescription: "객체 형식의 테마 코드를 입력해 주세요."
mutePeriod: "뮤트할 기간"
period: "투표 기한"
period: "기간"
indefinitely: "무기한"
tenMinutes: "10분"
oneHour: "1시간"
@@ -986,10 +992,13 @@ cannotBeChangedLater: "나중에 변경할 수 없습니다."
reactionAcceptance: "리액션 수신"
likeOnly: "좋아요만 받기"
likeOnlyForRemote: "리모트에서는 좋아요만 받기"
nonSensitiveOnly: "열람 주의로 설정되지 않았을 때만 받기"
nonSensitiveOnlyForLocalLikeOnlyForRemote: "열람 주의로 설정되지 않았을 때만 받기 (리모트에서는 좋아요만 받기)"
rolesAssignedToMe: "나에게 할당된 역할"
resetPasswordConfirm: "비밀번호를 재설정하시겠습니까?"
sensitiveWords: "민감한 단어"
sensitiveWordsDescription: "설정한 단어가 포함된 노트의 공개 범위를 '홈'으로 강제합니다. 개행으로 구분하여 여러 개를 지정할 수 있습니다."
sensitiveWordsDescription2: "공백으로 구분하면 AND 지정이 되며, 키워드를 슬래시로 둘러싸면 정규 표현식이 됩니다."
notesSearchNotAvailable: "노트 검색을 이용하실 수 없습니다."
license: "라이선스"
unfavoriteConfirm: "즐겨찾기를 해제하시겠습니까?"
@@ -1038,31 +1047,47 @@ thisChannelArchived: "이 채널은 아카이브되었습니다."
displayOfNote: "노트 표시"
initialAccountSetting: "초기 설정"
youFollowing: "팔로잉"
preventAiLearning: "기계학습(생성형 AI)으로의 사용을 거부"
preventAiLearningDescription: "외부의 문장 생성 AI나 이미지 생성 AI에 대해 제출한 노트나 이미지 등의 콘텐츠를 학습의 대상으로 사용하지 않도록 요구합니다. 다만, 이 요구사항을 지킬 의무는 없기 때문에 학습을 완전히 방지하는 것은 아닙니다."
options: "옵션"
specifyUser: "사용자 지정"
failedToPreviewUrl: "미리 볼 수 없음"
update: "업데이트"
rolesThatCanBeUsedThisEmojiAsReaction: "이 이모지를 리액션으로 사용할 수 있는 역할"
rolesThatCanBeUsedThisEmojiAsReactionEmptyDescription: "역할을 지정하지 않으면, 누구나 이 이모지를 리액션으로 사용할 수 있습니다."
rolesThatCanBeUsedThisEmojiAsReactionPublicRoleWarn: "역할은 공개로 설정되어 있어야 합니다."
cancelReactionConfirm: "리액션을 취소하시겠습니까?"
changeReactionConfirm: "리액션을 변경하시겠습니까?"
later: "나중에"
goToMisskey: "Misskey로"
additionalEmojiDictionary: "이모지 추가 사전"
installed: "설치됨"
_initialAccountSetting:
accountCreated: "계정 생성이 완료되었습니다!"
letsStartAccountSetup: "계정의 초기 설정을 진행합니다."
letsFillYourProfile: "우선 나의 프로필을 설정해 보아요."
profileSetting: "프로필 설정"
privacySetting: "프라이버시 설정"
theseSettingsCanEditLater: "이 설정들은 나중에도 변경할 수 있습니다."
youCanEditMoreSettingsInSettingsPageLater: "이 외에도 '설정' 페이지에서 다양한 설정을 나의 입맛에 게 조절할 수 있습니다. 꼭 확인해 보세요!"
youCanEditMoreSettingsInSettingsPageLater: "이 외에도 '설정' 페이지에서 다양한 설정을 나의 입맛에 게 조절할 수 있습니다. 꼭 확인해 보세요!"
followUsers: "관심사가 맞는 유저를 팔로우하여 타임라인을 가꾸어 봅시다."
pushNotificationDescription: "푸시 알림을 활성화하면 {name}의 알림을 나의 기기에서 받아볼 수 있게 됩니다."
initialAccountSettingCompleted: "초기 설정을 모두 마쳤습니다!"
haveFun: "{name}와 함께 즐거운 시간 보내세요!"
ifYouNeedLearnMore: "{name}(Misskey)의 사용 방법에 대해 자세히 알아보려면 {link}를 참고해 주세요."
skipAreYouSure: "초기 설정을 넘기시겠습니까?"
skipAreYouSure: "초기 설정을 중단하시겠습니까?"
laterAreYouSure: "초기 설정을 나중에 진행하시겠습니까?"
_serverRules:
description: "회원 가입 이전에 간단하게 표시할 서버 규칙입니다. 이용 약관의 요약으로 구성하는 것을 추천합니다."
_accountMigration:
moveFrom: "다른 계정에서 이 계정으로 이사"
moveFromSub: "다른 계정에 대한 별칭을 생성"
moveFromLabel: "기존 계정:"
moveFromLabel: "기존 계정 #{n}"
moveFromDescription: "다른 계정에서 이 계정으로 팔로워를 가져오려면, 우선 여기에서 별칭을 지정해야 합니다. 반드시 이사하기 전에 지정해야 합니다! 기존 계정을 다음과 같은 형식으로 입력해 주십시오: @person@instance.com"
moveTo: "이 계정에서 다른 계정으로 이사"
moveToLabel: "이사할 계정:"
moveCannotBeUndone: "한 번 이사하면, 두 번 다시 되돌릴 수 없습니다."
moveAccountDescription: "이 작업은 취소할 수 없습니다. 먼저 이사할 계정에서 이 계정에 대한 별칭을 지정하였는지 다시 한 번 확인해 주십시오. 별칭을 지정한 다음, 이사할 계정을 다음과 같은 형식으로 입력해 주십시오: @person@instance.com"
moveAccountDescription: "새 계정으로 이전합니다.\n ・팔로워가 새 계정을 자동으로 팔로우 합니다\n ・이 계정에서 팔로우는 모두 해제됩니다\n ・이 계정으로는 노트 작성 등을 할 수 없게 됩니다\n\n팔로워는 자동으로 이전되지만, 팔로우는 수동으로 진행해야 합니다. 이전하기 전에 이 계정에서 팔로우를 내보내고, 이전 후에는 즉시 이전한 계정에서 가져오기를 진행하십시오.\n리스트・뮤트・차단에 대해서도 마찬가지이므로 수동으로 이전해야 합니다.\n\n(이 설명은 이 서버(Misskey v13.12.0 이후)의 사양입니다. Mastodon 등의 다른 ActivityPub 소프트웨어에서는 작동이 다를 수 있습니다.)"
moveAccountHowTo: "계정을 이사하려면 우선 이사갈 계정에서 이 계정에 대한 별칭을 지정해야 합니다.\n별칭을 작성한 다음, 이사갈 계정을 다음과 같이 입력하십시오:\n@username@server.example.com"
startMigration: "이사하기"
migrationConfirm: "정말로 이 계정을 {account} 으로 이전하시겠습니까? 한 번 이전한 다음에는 취소할 수 없으며, 두 번 다시 원래 상태로 복구할 수 없습니다.\n이사할 계정에서 계정 별칭을 지정하였는지 다시 한 번 확인하십시오."
@@ -1491,7 +1516,7 @@ _menuDisplay:
hide: "숨기기"
_wordMute:
muteWords: "뮤트할 단어"
muteWordsDescription: "공백으로 구분하는 경우 AND, 줄바꿈으로 구분하는 경우 OR로 지정됩니다"
muteWordsDescription: "공백으로 구분하는 경우 AND, 줄바꿈으로 구분하는 경우 OR로 지정됩니다."
muteWordsDescription2: "정규 표현식을 사용하려면 키워드를 빗금표(/)로 감싸 주세요."
softDescription: "지정한 조건의 노트를 타임라인에서 숨깁니다."
hardDescription: "지정한 조건의 노트를 타임라인에 추가하지 않습니다. 타임라인에 추가되지 않은 노트는 조건을 변경해도 표시되지 않습니다."

View File

@@ -1,21 +1,31 @@
---
_lang_: "Norsk Bokmål"
headlineMisskey: "Et nettverk forbundet med Notes"
introMisskey: "Velkommen! Misskey er en desentralisert mikrobloggtjeneste med åpen kildekode.\nOpprett \"Notes\" for å dele tankene dine med alle rundt deg. 📡\nMed \"reaksjoner\" kan du også raskt gi uttrykk for hva du synes om alles Notes. 👍\nLa oss utforske en ny verden! 🚀"
monthAndDay: "{day}-{month}"
search: "Søk"
notifications: "Varsler"
username: "Brukernavn"
password: "Passord"
forgotPassword: "Glemt passord"
fetchingAsApObject: "Henter fra Fediverse..."
ok: "OK"
gotIt: "Skjønner"
cancel: "Avbryt"
noThankYou: "Avbryt"
noThankYou: "Ikke nå"
enterUsername: "Skriv inn brukernavn"
renotedBy: "Renotes av {user}"
noNotes: "Ingen Notes"
noNotifications: "Ingen varsler"
instance: "Server"
settings: "Innstillinger"
notificationSettings: "Varslingsinnstillinger"
basicSettings: "Grunnleggende innstillinger"
otherSettings: "Andre innstillinger"
openInWindow: "Åpne i vindu"
profile: "Profil"
timeline: "Tidslinje"
noAccountDescription: "Denne brukeren har ikke skrevet sin biografi ennå."
login: "Logg inn"
loggingIn: "Logget inn"
logout: "Logg ut"
@@ -24,17 +34,21 @@ uploading: "Laster opp"
save: "Lagre"
users: "Brukere"
addUser: "Legg til bruker"
favorite: "Favoritt"
favorite: "Legg til i favoritter"
favorites: "Favoritter"
unfavorite: "Fjern favoritt"
pin: "Fest"
unpin: "Opphev festing"
unfavorite: "Fjern fra favoritter"
favorited: "Lagt til i favoritter."
alreadyFavorited: "Allerede lagt til i favoritter."
cantFavorite: "Kunne ikke legge til i favoritter."
pin: "Fest til profil"
unpin: "Fjern fra profil"
copyContent: "Kopier innhold"
copyLink: "Kopier lenke"
delete: "Slett"
deleteAndEdit: "Slett og rediger"
deleteAndEditConfirm: "Er du sikker på at du vil slette denne Noten og redigere den? Du vil miste alle reaksjoner, Renotes og svar på den."
addToList: "Legg til i liste"
sendMessage: "Send melding"
sendMessage: "Send en melding"
copyRSS: "Kopier RSS"
copyUsername: "Kopier brukernavn"
searchUser: "Søk brukere"
@@ -42,140 +56,290 @@ reply: "Svar"
loadMore: "Vis mer"
showMore: "Vis mer"
showLess: "Lukk"
youGotNewFollower: "fulgte deg"
followRequestAccepted: "Følgeforespørsel akseptert"
importAndExport: "Importer og eksporter"
import: "Importer"
export: "Eksporter"
files: "Filer"
download: "Nedlastinger"
driveFileDeleteConfirm: "Er du sikker på at du vil slette \"{name}\"? Det vil også forsvinne fra alt innhold som bruker det."
unfollowConfirm: "Er du sikker på at du vil slutte å følge {name}?"
importRequested: "Du har bedt om import. Dette kan ta en stund."
lists: "Lister"
noLists: "Ingen lister"
following: "Følg"
note: "Note"
notes: "Notes"
following: "Følger"
followers: "Følgere"
followsYou: "Følger deg"
createList: "Opprett liste"
error: "Feil"
somethingHappened: "En feil har oppstått"
retry: "Prøv igjen"
pageLoadError: "Kunne ikke hente side."
serverIsDead: "Denne serveren svarer ikke. Vennligst vent en stund og prøv igjen."
enterListName: "Skriv inn et navn på listen"
privacy: "Personvern"
defaultNoteVisibility: "Standard synlighet"
follow: "Følg"
followRequest: "Følgeforespørsel"
followRequests: "Følgeforespørsel"
unfollow: "Avfølg"
followRequestPending: "Venter på godkjenning"
enterEmoji: "Skriv inn en emoji"
renote: "Renote"
renoted: "Renotet."
cantRenote: "Dette innlegget kan ikke renotes."
cantReRenote: "En Renote kan ikke renotes."
quote: "Sitat"
pinned: "Fest"
inChannelRenote: "Renote kun for kanal"
inChannelQuote: "Sitat kun for kanal"
pinnedNote: "Festet Note"
pinned: "Fest til profil"
you: "Du"
clickToShow: "Klikk for å vise"
add: "Legg til"
reaction: "Reaksjon"
reactions: "Reaksjoner"
reactionSetting: "Reaksjoner som vises i reaksjonsvelgeren"
reactionSettingDescription2: "Dra for å endre rekkefølgen, klikk for å slette, trykk \"+\" for å legge til."
rememberNoteVisibility: "Husk innstillingene for synlighet av Notes"
attachCancel: "Fjern vedlegg"
enterFileName: "Skriv inn filnavn"
mute: "Skjul"
unmute: "Vis"
renoteMute: "Skjul Renotes"
renoteUnmute: "Vis Renotes"
block: "Blokker"
unblock: "Opphev blokkering"
blockConfirm: "Blokker?"
selectList: "Velg liste"
selectChannel: "Velg kanal"
suspend: "Suspender"
blockConfirm: "Er du sikker på at du vil blokke denne kontoen?"
unblockConfirm: "Er du sikker på at du vil oppheve blokkeringen av denne kontoen?"
suspendConfirm: "Er du sikker på at du vil suspendere denne kontoen?"
selectList: "Velg en liste"
selectChannel: "Velg en kanal"
selectAntenna: "Velg en antenne"
selectWidget: "Velg en widget"
editWidgets: "Rediger widgeter"
editWidgetsExit: "Ferdig"
emoji: "Emoji"
emojis: "Emojier"
addEmoji: "Legg til emoji"
settingGuide: "Anbefalte innstillinger"
flagAsBot: "Merk denne kontoen som en bot"
flagAsBotDescription: "Aktiver dette alternativet hvis denne kontoen styres av et program. Hvis det er aktivert, vil det fungere som et flagg for andre utviklere for å forhindre endeløse interaksjonskjeder med andre roboter og justere Misskeys interne systemer til å behandle denne kontoen som en bot."
flagAsCat: "Merk denne kontoen som en katt"
flagAsCatDescription: "Aktiver dette alternativet for å merke denne kontoen som en katt."
flagShowTimelineReplies: "Vis svar i tidslinje"
addAccount: "Legg til konto"
selectUser: "Velg bruker"
instances: "Server"
reloadAccountsList: "Last inn kontoliste på nytt"
loginFailed: "Kunne ikke logge inn"
general: "Generelt"
searchWith: "Søk: {q}"
youHaveNoLists: "Du har ingen lister"
followConfirm: "Er du sikker på at du vil følge {name}?"
host: "Vert"
selectUser: "Velg en bruker"
recipient: "Mottaker"
annotation: "Kommentarer"
federation: "Føderasjon"
instances: "Servere"
registeredAt: "Registrerte seg"
latestRequestReceivedAt: "Siste forespørsel mottatt"
latestStatus: "Siste status"
charts: "Diagrammer"
perHour: "Per time"
perDay: "Per dag"
stopActivityDelivery: "Slutt å sende aktiviteter"
blockThisInstance: "Blokker denne serveren"
operations: "Operasjoner"
software: "Programvare"
version: "Versjon"
metadata: "Metadata"
withNFiles: "{n} fil(er)"
network: "Nettverk"
instanceInfo: "Serverinformasjon"
statistics: "Statistikk"
clearQueue: "Tøm kø"
clearQueueConfirmTitle: "Vil du tømme kø?"
clearQueueConfirmTitle: "Er du sikker på at du vil tømme køen?"
blockedInstances: "Blokkerte severe"
blockedInstancesDescription: "Skriv opp vertsnavnene til serverne du vil blokkere, atskilt med linjeskift. Serverne i listen vil ikke lenger kunne kommunisere med denne serveren."
muteAndBlock: "Skjul og blokker"
mutedUsers: "Skjulte brukere"
blockedUsers: "Blokkerte brukere"
noUsers: "Det er ingen brukere"
editProfile: "Rediger profil"
noteDeleteConfirm: "Er du sikker på at du vil slette denne Noten?"
pinLimitExceeded: "Du kan ikke feste flere."
noCustomEmojis: "Ingen emoji"
intro: "Installasjonen av Misskey er ferdig! Vennligst opprett en administratorkonto."
done: "Ferdig"
default: "Standard"
defaultValueIs: "Standard: {value}"
noCustomEmojis: "Det er ingen emoji"
noJobs: "Det er ingen jobber"
blocked: "Blokkert"
suspended: "Suspendert"
all: "Alle"
notResponding: "Svarer ikke"
changePassword: "Endre passord"
security: "Sikkerhet"
retypedNotMatch: "Inngangene stemmer ikke overens."
currentPassword: "Nåværende passord"
newPassword: "Nytt passord"
newPasswordRetype: "Nytt passord (gjenta)"
attachFile: "Legg ved filer"
more: "Mer!"
noSuchUser: "Bruker ikke funnet"
announcements: "Kunngjøringer"
remove: "Slett"
removed: "Slettet"
removed: "Vellykket slettet"
removeAreYouSure: "Er du sikker på at du vil fjerne \"{x}\"?"
deleteAreYouSure: "Er du sikker på at du vil slette \"{x}\"?"
saved: "Lagret"
upload: "Laste opp"
keepOriginalUploading: "Behold originalbildet"
fromUrl: "Fra URL"
uploadFromUrl: "Last opp fra en URL"
uploadFromUrlDescription: "URL til filen du vil laste opp"
explore: "Utforsk"
messageRead: "Lest"
agree: "Jeg godtar"
nUsersRead: "lest av {n}"
agreeTo: "Jeg godtar {0}"
agree: "Godta"
agreeBelow: "Jeg godtar følgende"
basicNotesBeforeCreateAccount: "Viktige merknader"
termsOfService: "Vilkår for bruk"
home: "Hjem"
activity: "Aktivitet"
images: "Bilder"
image: "Bilder"
image: "Bilde"
birthday: "Bursdag"
yearsOld: "{age} år gammel"
theme: "Temaer"
light: "Lys"
dark: "Mørk"
lightThemes: "Lyse temaer"
darkThemes: "Mørke temaer"
syncDeviceDarkMode: "Synkroniser mørkmodus med enhetens innstillinger"
fileName: "Filnavn"
selectFile: "Velg fil"
selectFiles: "Velg fil"
selectFolder: "Velg mappe"
selectFolders: "Velg mappe"
selectFile: "Velg en fil"
selectFiles: "Velg filer"
selectFolder: "Velg en mappe"
selectFolders: "Velg mapper"
renameFile: "Endre filnavn"
folderName: "Mappenavn"
createFolder: "Opprett mappe"
createFolder: "Opprett en mappe"
renameFolder: "Endre mappenavn"
deleteFolder: "Slett mappe"
addFile: "Legg til fil"
deleteFolder: "Slett denne mappen"
addFile: "Legg til en fil"
emptyFolder: "Denne mappen er tom"
unableToDelete: "Kan ikke slette"
inputNewFileName: "Skriv inn et nytt filnavn"
inputNewDescription: "Skriv inn ny bildetekst"
inputNewFolderName: "Skriv inn et nytt mappenavn"
circularReferenceFolder: "Målmappen er en undermappe til mappen du ønsker å flytte."
hasChildFilesOrFolders: "Siden denne mappen ikke er tom, kan den ikke slettes."
copyUrl: "Kopier URL"
rename: "Endre navn"
doNothing: "Gjør ingenting"
avatar: "Avatar"
banner: "Banner"
doNothing: "Ignorer"
accept: "Tillatt"
reject: "Avslå"
instanceName: "Servernavn"
thisYear: "I år"
instanceDescription: "Serverbeskrivelse"
thisYear: "År"
thisMonth: "Måned"
today: "I dag"
dayX: "{day}"
monthX: "{month}"
yearX: "{year}"
pages: "Sider"
pinnedUsers: "Festete brukrere"
pinnedPages: "Festete sider"
integration: "Integrasjon"
enableLocalTimeline: "Aktiver lokal tidslinje"
enableGlobalTimeline: "Aktiver global tidslinje"
disablingTimelinesInfo: "Administratorer og Moderatorer vil alltid ha tilgang til alle tidslinjer, selv om de ikke er aktivert."
registration: "Registrer"
enableRegistration: "Aktiver registrering av nye brukere"
invite: "Inviter"
basicInfo: "Grunnleggende informasjon"
pinnedUsers: "Festede brukrere"
pinnedUsersDescription: "Liste over brukernavn atskilt med linjeskift som skal festes i \"Utforsk\" fanen."
pinnedPages: "Festede sider"
pinnedNotes: "Festet Note"
hcaptcha: "hCaptcha"
enableHcaptcha: "Aktiver hCaptcha"
recaptcha: "reCAPTCHA"
enableRecaptcha: "Aktiver reCAPTCHA"
turnstile: "Turnstile"
enableTurnstile: "Aktiver Turnstile"
antennas: "Antenner"
name: "Navn"
antennaSource: "Antennekilde"
notifyAntenna: "Varsle om nye Notes"
withFileAntenna: "Bare Notes med filer"
notesAndReplies: "Notes og svar"
popularUsers: "Populære brukere"
exploreUsersCount: "Det finnes {count} brukere"
exploreFediverse: "Utforsk Fediverse"
userList: "Lister"
about: "Infomasjon"
about: "Informasjon"
aboutMisskey: "Om Misskey"
newPasswordIs: "Det nye passordet er \"{password}\"."
share: "Del"
notFound: "Ikke funnet"
markAsReadAllNotifications: "Merk alle varsler som lest"
markAsReadAllUnreadNotes: "Merk alle Notes som lest"
help: "Hjelp"
inputMessageHere: "Skriv inn melding her"
close: "Lukk"
invites: "Inviter"
members: "Medlemmer"
title: "Tittel"
text: "Tekst"
next: "Neste"
retype: "Gjenta"
quoteAttached: "Sitat"
noMessagesYet: "Ingen meldinger ennå"
newMessageExists: "Det er nye meldinger"
onlyOneFileCanBeAttached: "Du kan bare legge ved én fil i en melding"
invitations: "Inviter"
available: "Tilgjengelig"
unavailable: "Utilgjengelig"
tooShort: "For kort"
tooLong: "For langt"
weakPassword: "Svakt passord"
normalPassword: "Gjennomsnittlig passord"
strongPassword: "Sterkt passord"
signinWith: "Logg inn med {x}"
signinFailed: "Kunne ikke logge inn. Det oppgitte brukernavnet eller passordet er feil."
or: "eller"
language: "Språk"
aboutX: "Om {x}"
category: "Kategorier"
category: "Kategori"
createAccount: "Opprett konto"
openImageInNewTab: "Åpne bilder i ny fane"
clientSettings: "Klientinnstillinger"
accountSettings: "Kontoinnstillinger"
objectStorageRegion: "Region"
objectStorageUseSSL: "Bruk SSL"
objectStorageUseProxy: "Bruk Proxy"
deleteAll: "Slett alt"
newNoteRecived: "Det er nye Notes"
listen: "Lytt"
none: "Ingen"
volume: "Volum"
chooseEmoji: "Velg emoji"
recentUsed: "Sist brukte"
install: "Installer"
uninstall: "Avinstaller"
nothing: "Ingenting"
deleteAllFiles: "Slett alle filer"
deleteAllFilesConfirm: "Vil du slette alle filer?"
deleteAllFilesConfirm: "Er du sikker på at du vil slette alle filer?"
userSuspended: "Denne brukeren har blitt suspendert."
accountDeleted: "Kontoen blir slettet"
accountDeletedDescription: "Denne kontoen blir slettet"
accountDeletedDescription: "Denne kontoen har blitt slettet."
menu: "Meny"
poll: "Avstemning"
description: "Beskrivelse"
@@ -186,6 +350,7 @@ small: "Liten"
notificationType: "Varseltype"
edit: "Rediger"
email: "E-post"
smtpHost: "Vert"
smtpUser: "Brukernavn"
smtpPass: "Passord"
userSaysSomething: "{name} sa noe"
@@ -201,16 +366,25 @@ reportAbuse: "Rappoter"
send: "Send"
openInNewTab: "Åpne i ny fane"
waitingFor: "Venter på {x}"
random: "Tilfeldig"
system: "System"
desktop: "Skrivebord"
i18nInfo: "Misskey oversettes til flere språk av frivillige. Du kan hjelpe til på {link}."
followingCount: "Følger"
followersCount: "Følgere"
yes: "Ja"
no: "Nei"
contact: "Kontakt"
developer: "Utvikler"
makeExplorable: "Gjør konto synlig i \"Utforsk\""
makeExplorableDescription: "Hvis du slår av dette, vises ikke kontoen din i \"Utforsk\" delen."
left: "Venstre"
nNotes: "{n} Notes"
saveAs: "Lagre som"
value: "Verdi"
deleteConfirm: "Vil du slette?"
invalidValue: "Verdien er ugyldig."
closeAccount: "Avslutt konto"
emailNotification: "E-postvarsler"
inChannelSearch: "Søk i kanal"
clear: "Tøm"
@@ -224,16 +398,23 @@ accounts: "Kontoer"
switch: "Bytt"
gallery: "Galleri"
ads: "Annonser"
memo: "Notat"
high: "Høy"
low: "Lav"
sent: "Send"
sent: "Sendt"
received: "Mottatt"
learnMore: "Les mer"
misskeyUpdated: "Misskey har blitt oppdatert!"
translate: "Oversett"
translatedFrom: "Oversatt fra {x}"
unread: "Ulest"
manageAccounts: "Administrer konto"
classic: "Klassisk"
muteThread: "Skjul denne tråden"
unmuteThread: "Vis denne tråden"
continueThread: "Vis fortsettelse av tråden"
hide: "Skjul"
smartphone: "Smarttelefon"
tablet: "Nettbrett"
auto: "Automatisk"
size: "Størrelse"
@@ -249,10 +430,10 @@ check: "Sjekk"
deleteAccount: "Slett konto"
document: "Dokumenter"
logoutConfirm: "Vil du logge ut?"
pleaseSelect: "Vennligst velg"
pleaseSelect: "Velg et alternativ"
type: "Type"
beta: "Beta"
account: "Kontoer"
account: "Konto"
move: "Flytt"
pushNotification: "Push-varsler"
tools: "Verktøy"
@@ -268,6 +449,7 @@ role: "Rolle"
color: "Farge"
youCannotCreateAnymore: "Du kan ikke opprette flere."
cannotPerformTemporary: "Midlertidig utilgjengelig"
achievements: "Prestasjoner"
thisPostMayBeAnnoyingCancel: "Avbryt"
exploreOtherServers: "Utforsk andre severe"
letsLookAtTimeline: "La oss se på tidslinje"
@@ -283,6 +465,26 @@ _initialAccountSetting:
theseSettingsCanEditLater: "Du kan endre disse innstillingene senere."
_achievements:
_types:
_notes10:
title: "Noen Notes"
_notes100:
title: "Mange Notes"
_notes500:
title: "Dekket i Notes"
_notes1000:
title: "Et fjell av Notes"
_notes5000:
title: "Overfylte Notes"
_notes10000:
title: "Super Notes"
_notes20000:
title: "Trenger... mer... Notes..."
_notes30000:
title: "Notes Notes Notes!"
_notes40000:
title: "Note fabrikk"
_notes50000:
title: "Planet av Notes"
_notes100000:
flavor: "Du har jammen mye å si."
_noteFavorited1:
@@ -311,11 +513,25 @@ _achievements:
_justPlainLucky:
title: "Rett og slett heldig"
_setNameToSyuilo:
description: "Du har satt navnet ditt til \"syuilo\""
description: "Du satte navnet ditt til \"syuilo\""
_passedSinceAccountCreated1:
title: "Ett års jubileum"
description: "Det har gått ett år siden kontoen din ble opprettet"
_passedSinceAccountCreated2:
title: "To års jubileum"
description: "Det har gått to år siden kontoen din ble opprettet"
_passedSinceAccountCreated3:
title: "Tre års jubileum"
description: "Det har gått tre år siden kontoen din ble opprettet"
_loggedInOnBirthday:
title: "Gratulerer med dagen"
description: "Du logget inn på bursdagen din"
_loggedInOnNewYearsDay:
title: "Godt nytt år"
description: "Du logget inn på årets første dag"
_cookieClicked:
description: "Du klikket på kjeksen"
flavor: "Er du på riktig nettsted?"
_brainDiver:
title: "Brain Diver"
flavor: "Misskey-Misskey La-Tu-Ma"
@@ -333,6 +549,9 @@ _ad:
_gallery:
like: "Liker!"
unlike: "Liker ikke"
_email:
_follow:
title: "fulgte deg"
_preferencesBackups:
saveNew: "Lagre som ny"
cannotSave: "Kunne ikke lagre"
@@ -351,6 +570,8 @@ _channel:
featured: "Populært"
following: "Følger"
nameAndDescription: "Navn og beskrivelse"
_menuDisplay:
hide: "Skjul"
_wordMute:
soft: "Myk"
hard: "Hard"
@@ -360,15 +581,17 @@ _theme:
key: "Nøkkel"
keys:
link: "Lenke"
renote: "Renote"
_sfx:
note: "Notes"
notification: "Varsler"
_ago:
future: "Fremitid"
justNow: "Akkurat nå"
secondsAgo: "{n} sekunder siden"
minutesAgo: "{n} minutter siden"
hoursAgo: "{n} timer siden"
daysAgo: "{n} dager siden"
secondsAgo: "{n}s siden"
minutesAgo: "{n}m siden"
hoursAgo: "{n}t siden"
daysAgo: "{n}d siden"
weeksAgo: "{n} uker siden"
monthsAgo: "{n} måneder siden"
yearsAgo: "{n} år siden"
@@ -380,6 +603,7 @@ _time:
day: "Dager"
_timelineTutorial:
title: "Hvordan bruke Misskey"
step2_2: "Hva med å skrive en selvpresentasjon, eller bare \"Hei {name}!\" hvis du ikke har lyst?"
_2fa:
renewTOTPCancel: "Avbryt"
_weekday:
@@ -392,18 +616,22 @@ _weekday:
saturday: "Lørdag"
_widgets:
profile: "Profil"
instanceInfo: "Serverinformasjon"
notifications: "Varsler"
timeline: "Tidslinje"
calendar: "Kalender"
trends: "Populært"
clock: "Klokke"
activity: "Aktivitet"
photos: "Bilder"
federation: "Føderasjon"
button: "Knapp"
aiscriptApp: "AiScript App"
userList: "Brukerliste"
_userList:
chooseList: "Velg liste"
_cw:
hide: "Skjul"
show: "Vis mer"
_poll:
noOnlyOneChoice: "Trenger minst to valger."
@@ -424,6 +652,7 @@ _postForm:
_profile:
name: "Navn"
username: "Brukernavn"
description: "Biografi"
metadataContent: "Innhold"
_exportOrImport:
followingList: "Følg"
@@ -431,6 +660,7 @@ _exportOrImport:
blockingList: "Blokker"
userLists: "Lister"
_charts:
federation: "Føderasjon"
filesIncDec: "Forskjell på antall filer"
_instanceCharts:
users: "Forskjell på antall brukere"
@@ -442,14 +672,18 @@ _play:
new: "Opprett Play"
edit: "Rediger Play"
featured: "Populært"
title: "Tittel"
summary: "Beskrivelse"
_pages:
invalidNameText: "Pass på at sidetittelen ikke er tom"
like: "Liker"
unlike: "Liker ikke"
my: "Mine sider"
featured: "Populært"
contents: "Innhold"
title: "Tittel"
url: "Side URL"
hideTitleWhenPinned: "Skjul sidetittel når festet til profil"
fontSerif: "Serif"
fontSansSerif: "Sans Serif"
selectType: "Velg type"
@@ -459,13 +693,18 @@ _pages:
image: "Bilde"
button: "Knapp"
_notification:
youWereFollowed: "fulgte deg"
unreadAntennaNote: "Antenne {name}"
achievementEarned: "Prestasjon låst opp"
_types:
follow: "Følg"
follow: "Nye følgere"
reply: "Svar"
quote: "Sitat"
reaction: "Reaksjon"
renote: "Renotes"
quote: "Sitater"
reaction: "Reaksjoner"
_actions:
reply: "Svar"
renote: "Renote"
_deck:
swapLeft: "Flytt til venstre"
swapRight: "Flytt til høyre"
@@ -477,6 +716,7 @@ _deck:
_columns:
notifications: "Varsler"
tl: "Tidslinje"
antenna: "Antenner"
list: "Lister"
channel: "Kanaler"
direct: "Direkte"

View File

@@ -2,7 +2,7 @@
_lang_: "Русский"
headlineMisskey: "Сеть, сплетённая из заметок"
introMisskey: "Добро пожаловать! Misskey — это децентрализованный сервис микроблогов с открытым исходным кодом.\nПишите «заметки» — делитесь со всеми происходящим вокруг или рассказывайте о себе 📡\nСтавьте «реакции» — выражайте свои чувства и эмоции от заметок других 👍\nОткройте для себя новый мир 🚀"
poweredByMisskeyDescription: "{name} один из инстансов (также называемый экземпляром Misskey), использующий платформу с открытым исходным кодом <b>Misskey</b>."
poweredByMisskeyDescription: "{name} сервис на платформе с открытым исходным кодом <b>Misskey</b>, называемый инстансом Misskey."
monthAndDay: "{day}.{month}"
search: "Поиск"
notifications: "Уведомления"
@@ -560,6 +560,7 @@ accountDeletedDescription: "Эта учетная запись удалена"
menu: "Меню"
divider: "Линия-разделитель"
addItem: "Добавить элемент"
rearrange: "Сортировать по"
relays: "Ретрансляторы"
addRelay: "Добавить ретранслятор"
inboxUrl: "URL ящика входящих сообщений"
@@ -648,8 +649,8 @@ abuseReported: "Жалоба отправлена. Большое спасибо
reporter: "Сообщивший"
reporteeOrigin: "О ком сообщено"
reporterOrigin: "Кто сообщил"
forwardReport: "Перенаправление отчета на инстант."
forwardReportIsAnonymous: "Удаленный инстант не сможет увидеть вашу информацию и будет отображаться как анонимная системная учетная запись."
forwardReport: "Отправить жалобу на инстанс автора."
forwardReportIsAnonymous: "Жалоба на удалённый инстанс будет отправлена анонимно. Вместо ваших данных у получателя будет отображена системная учётная запись."
send: "Отправить"
abuseMarkAsResolved: "Отметить жалобу как решённую"
openInNewTab: "Открыть в новой вкладке"
@@ -822,6 +823,7 @@ translatedFrom: "Перевод. Язык оригинала — {x}"
accountDeletionInProgress: "В настоящее время выполняется удаление учетной записи"
usernameInfo: "Имя, которое отличает вашу учетную запись от других на этом сервере. Вы можете использовать алфавит (a~z, A~Z), цифры (0~9) или символы подчеркивания (_). Имена пользователей не могут быть изменены позже."
aiChanMode: "Режим Ай"
devMode: "Режим разработчика"
keepCw: "Сохраняйте Предупреждения о содержимом"
pubSub: "Учётные записи Pub/Sub"
lastCommunication: "Последнее сообщение"
@@ -913,8 +915,8 @@ cannotUploadBecauseInappropriate: "Файл не может быть загру
cannotUploadBecauseNoFreeSpace: "Файл не может быть загружен, так как не осталось места на диске"
cannotUploadBecauseExceedsFileSizeLimit: "Файл не может быть загружен, так как он превышает лимит размера файла."
beta: "Бета"
enableAutoSensitive: "Автоматическое определение NSFW"
enableAutoSensitiveDescription: "Если доступно, используйте машинное обучение для автоматической установки флага NSFW на носителе. Даже если эта функция отключена, она может быть установлена ​​автоматически в зависимости от инстанта."
enableAutoSensitive: "Автоматическое определение содержимого не для всех"
enableAutoSensitiveDescription: "Позволяет определять наличие содержимого не для всех при помощи искусственного интеллекта там, где это возможно. Даже если эту опцию отключить, она всё равно может быть включена на весь инстанс."
activeEmailValidationDescription: "Если включено, будет проводиться более строгая проверка адреса электронной почты, в том числе на то, что он действительный и не временный. Если же отключено, то проверяется только корректность написания адреса."
navbar: "Панель навигации"
shuffle: "Перемешать"
@@ -989,6 +991,7 @@ rolesAssignedToMe: "Мои роли"
resetPasswordConfirm: "Сбросить пароль?"
sensitiveWords: "Чувствительные слова"
sensitiveWordsDescription: "Установите общедоступный диапазон заметки, содержащей заданное слово, на домашний. Можно сделать несколько настроек, разделив их переносами строк."
sensitiveWordsDescription2: "Разделение пробелом создаёт спецификацию AND, а разделение косой чертой создаёт регулярное выражение."
notesSearchNotAvailable: "Поиск заметок недоступен"
license: "Лицензия"
unfavoriteConfirm: "Удалить избранное?"
@@ -1004,6 +1007,7 @@ noteIdOrUrl: "ID или ссылка на заметку"
video: "Видео"
videos: "Видео"
dataSaver: "Экономия трафика"
renotesList: "Репосты"
horizontal: "Сбоку"
youFollowing: "Подписки"
options: "Настройки ролей"
@@ -1178,6 +1182,9 @@ _achievements:
_client30min:
title: "Перерыв на обед"
description: "Прошло 30 минут с момента запуска клиента"
_client60min:
title: "Не наглядеться на Misskey"
description: "Misskey был открыт 60 минут подряд"
_noteDeletedWithin1min:
title: "Ой, нет!"
description: "Заметка удалена через минуту после публикации"
@@ -1280,6 +1287,7 @@ _role:
canInvite: "Может создавать пригласительные коды"
canManageCustomEmojis: "Управлять пользовательскими эмодзи"
driveCapacity: "Доступное пространство на «диске»"
alwaysMarkNsfw: "Всегда отмечать файлы как «не для всех»"
pinMax: "Доступное количество закреплённых заметок"
antennaMax: "Доступное количество антенн"
wordMuteMax: "Доступное количество знаков в списке скрытия слов"
@@ -1307,7 +1315,7 @@ _sensitiveMediaDetection:
description: "Машинное обучение может быть использовано для автоматического обнаружения чувствительных медиа для модерации. Нагрузка на сервер увеличивается незначительно."
sensitivity: "Чувствительность обнаружения"
sensitivityDescription: "Более низкая чувствительность уменьшает количество ложных срабатываний (false positives). Повышение чувствительности уменьшает утечку при обнаружении (ложноотрицательные результаты)."
setSensitiveFlagAutomatically: "Установить флаг NSFW"
setSensitiveFlagAutomatically: "Обозначить как не для всех"
setSensitiveFlagAutomaticallyDescription: "Даже если этот параметр отключен, результат оценки сохраняется внутри системы."
analyzeVideos: "Анализировать видео?"
analyzeVideosDescription: "Анализируйте видео в дополнение к неподвижным изображениям. Нагрузка на сервер немного увеличивается."
@@ -1526,6 +1534,16 @@ _time:
minute: "мин"
hour: "ч"
day: "сут"
_timelineTutorial:
title: "Как пользоваться Misskey"
step1_1: "Это лицо Misskey, так называемая лента. Ваш инстанс, {name}, покажет тут все опубликованные на нём заметки в хронологическом порядке."
step1_2: "Здесь есть несколько лент. К примеру «персональная» лента отображает заметки тех, на кого вы подписаны. А «местная» — заметки тех, кого приютил {name}."
step2_1: "Что ж, теперь самое время опубликовать заметку. Если нажать вверху страницы на изображение карандаша, появится форма для текста."
step2_2: "Почему бы не написать немного о себе? Ну, или хотя бы «Привет, {name}»?"
step3_1: "Справились с первой заметкой?"
step3_2: "Отлично, теперь она должна появиться в вашей ленте."
step4_1: "А ещё здесь можно делиться своими реакциями на заметки."
step4_2: "Отмечайте реакции, нажимая на символ «+» под заметкой и выбирая значок по душе."
_2fa:
alreadyRegistered: "Двухфакторная аутентификация уже настроена."
registerTOTP: "Начните настраивать приложение-аутентификатор"
@@ -1866,6 +1884,9 @@ _deck:
_dialog:
charactersExceeded: "Превышено максимальное количество символов! У вас {current} / из {max}"
charactersBelow: "Это ниже минимального количества символов! У вас {current} / из {min}"
_disabledTimeline:
title: "Лента отключена"
description: "Ваша текущая роль не позволяет пользоваться этой лентой."
_webhookSettings:
name: "Название"
active: "Вкл."

View File

@@ -560,6 +560,7 @@ accountDeletedDescription: "บัญชีนี้ถูกลบไปแล
menu: "เมนู"
divider: "ตัวแบ่ง"
addItem: "เพิ่มรายการ"
rearrange: "จัดใหม่"
relays: "รีเลย์"
addRelay: "เพิ่มรีเลย์"
inboxUrl: "อินบ็อกซ์ URL"
@@ -1030,6 +1031,7 @@ continue: "ดำเนินการต่อ"
preservedUsernames: "ชื่อผู้ใช้ที่สงวนไว้"
preservedUsernamesDescription: "ลิสต์ชื่อผู้ใช้ที่จะสำรองโดยคั่นด้วยการแบ่งบรรทัดนั้น เพราะสิ่งเหล่านี้จะไม่สามารถทำได้ในระหว่างการสร้างบัญชีตามปกติ บัญชีที่มีอยู่แล้วนั้นโดยใช้ชื่อผู้ใช้เหล่านี้จะไม่ได้รับผลกระทบอะไร"
createNoteFromTheFile: "เรียบเรียงโน้ตจากไฟล์นี้"
archive: "เก็บถาวร"
youFollowing: "ติดตามแล้ว"
options: "ตัวเลือกบทบาท"
_serverRules:
@@ -1329,6 +1331,7 @@ _role:
canInvite: "สร้างรหัสเชิญอินสแตนซ์"
canManageCustomEmojis: "จัดการอีโมจิแบบกำหนดเอง"
driveCapacity: "ความจุของไดรฟ์"
alwaysMarkNsfw: "ทำเครื่องหมายไฟล์ว่าเป็น NSFW เสมอ"
pinMax: "จํานวนสูงสุดของโน้ตที่ปักหมุดไว้"
antennaMax: "จำนวนสูงสุดของเสาอากาศ"
wordMuteMax: "จำนวนอักขระสูงสุดที่อนุญาตในการปิดเสียงคำ"
@@ -1580,6 +1583,12 @@ _time:
minute: "นาที"
hour: "ชั่วโมง"
day: "วัน"
_timelineTutorial:
title: "วิธีใช้งาน Misskey"
step3_1: "เสร็จสิ้นการโพสต์โน้ตย่อแรกของคุณแล้วอย่างงั้นหรอ?"
step3_2: "ไชโย! ตอนนี้โน้ตย่อแรกของคุณได้ปรากฏบนไทม์ไลน์ของคุณแล้วนะ"
step4_1: "คุณยังสามารถแนบ \"ปฏิกิริยา\" ไปกับโน้ตได้อีกด้วยนะค่ะ"
step4_2: "หากต้องการแนบการแสดงความรู้สึก ให้กดเครื่องหมาย \"+\" บนโน้ตแล้วเลือกอิโมจิที่คุณต้องการแสดงความรู้สึกที่ตนเองชอบได้เลย"
_2fa:
alreadyRegistered: "คุณได้ลงทะเบียนอุปกรณ์ยืนยันตัวตนแบบ 2 ชั้นแล้ว"
registerTOTP: "ลงทะเบียนแอพตัวตรวจสอบสิทธิ์"

View File

@@ -1,6 +1,7 @@
---
_lang_: "Türkçe"
introMisskey: "Açık kaynaklı bir dağıtılmış mikroblog hizmeti olan Misskey'e hoş geldiniz.\nMisskey, neler olup bittiğini paylaşmak ve herkese sizden bahsetmek için \"notlar\" oluşturmanıza olanak tanıyan, açık kaynaklı, dağıtılmış bir mikroblog hizmetidir.\nHerkesin notlarına kendi tepkilerinizi hızlıca eklemek için \"Tepkiler\" özelliğini de kullanabilirsiniz👍.\nYeni bir dünyayı keşfedin🚀."
poweredByMisskeyDescription: "name}Açık kaynak bir platform\n<b>Misskey</b>Dünya'nın en sunucularında biri。"
monthAndDay: "{month}Ay {day}Gün"
search: "Arama"
notifications: "Bildirim"
@@ -13,7 +14,9 @@ cancel: "İptal"
enterUsername: "Kullanıcı adınızı giriniz"
noNotes: "Notlar mevcut değil."
noNotifications: "Bildirim bulunmuyor"
instance: "Sunucu"
settings: "Ayarlar"
notificationSettings: "Bildirim Ayarları"
basicSettings: "Temel Ayarlar"
otherSettings: "Diğer Ayarlar"
openInWindow: "Bir pencere ile aç"
@@ -21,9 +24,11 @@ profile: "Profil"
timeline: "Zaman çizelgesi"
noAccountDescription: "Bu kullanıcı henüz biyografisini yazmadı"
login: "Giriş Yap "
loggingIn: "Oturum aç"
logout: ıkış Yap"
signup: "Kayıt Ol"
uploading: "Yükleniyor"
save: "Kaydet"
users: "Kullanıcı"
addUser: "Kullanıcı Ekle"
favorite: "Favoriler"
@@ -31,6 +36,7 @@ favorites: "Favoriler"
unfavorite: "Favorilerden Kaldır"
favorited: "Favorilerime eklendi."
alreadyFavorited: "Zaten favorilerinizde kayıtlı."
cantFavorite: "Favorilere kayıt yapılamadı"
pin: "Sabitlenmiş"
unpin: "Sabitlemeyi kaldır"
copyContent: "İçeriği kopyala"
@@ -40,23 +46,88 @@ deleteAndEdit: "Sil ve yeniden düzenle"
deleteAndEditConfirm: "Bu notu silip yeniden düzenlemek istiyor musunuz? Bu nota ilişkin tüm Tepkiler, Yeniden Notlar ve Yanıtlar da silinecektir."
addToList: "Listeye ekle"
sendMessage: "Mesaj Gönder"
copyRSS: "RSSKopyala"
copyUsername: "Kullanıcı Adını Kopyala"
copyUserId: "KullanıcıyıKopyala"
copyNoteId: "Kimlik notunu kopyala"
searchUser: "Kullanıcıları ara"
reply: "yanıt"
loadMore: "Devamını yükle"
showMore: "Devamını yükle"
lists: "Listeler"
noLists: "Liste yok"
note: "not"
notes: "notlar"
following: "takipçi"
followers: "takipçi"
followsYou: "seni takip ediyor"
createList: "Liste oluştur"
manageLists: "Yönetici Listeleri"
error: "hata"
follow: "takipçi"
followRequest: "Takip isteği"
followRequests: "Takip istekleri"
unfollow: "takip etmeyi bırak"
followRequestPending: "Bekleyen Takip Etme Talebi"
enterEmoji: "Emoji Giriniz"
renote: "vazgeçme"
unrenote: "not alma"
renoted: "yeniden adlandırılmış"
cantRenote: "Ayrılamama"
cantReRenote: "not alabilirmiyim"
quote: "alıntı"
pinnedNote: "Sabitlenen"
pinned: "Sabitlenmiş"
you: "sen"
unmute: "sesi aç"
renoteMute: "sesi kapat"
renoteUnmute: "sesi açmayı iptal et"
block: "engelle"
unblock: "engellemeyi kaldır"
suspend: "askıya al"
unsuspend: "askıya alma"
blockConfirm: "Onayı engelle"
unblockConfirm: "engellemeyi kaldır onayla"
selectChannel: "Kanal seç"
flagAsBot: "Bot olarak işaretle"
instances: "Sunucu"
remove: "Sil"
pinnedNotes: "Sabitlenen"
userList: "Listeler"
smtpUser: "Kullanıcı Adı"
smtpPass: "Şifre"
user: "Kullanıcı"
searchByGoogle: "Arama"
_theme:
keys:
renote: "vazgeçme"
_sfx:
note: "notlar"
notification: "Bildirim"
_widgets:
profile: "Profil"
notifications: "Bildirim"
timeline: "Zaman çizelgesi"
_cw:
show: "Devamını yükle"
_visibility:
followers: "takipçi"
_profile:
username: "Kullanıcı Adı"
_exportOrImport:
followingList: "takipçi"
blockingList: "engelle"
userLists: "Listeler"
_notification:
_types:
follow: "takipçi"
renote: "vazgeçme"
quote: "alıntı"
_actions:
reply: "yanıt"
renote: "vazgeçme"
_deck:
_columns:
notifications: "Bildirim"
tl: "Zaman çizelgesi"
list: "Listeler"

View File

@@ -52,6 +52,8 @@ addToList: "添加至列表"
sendMessage: "发送"
copyRSS: "复制RSS"
copyUsername: "复制用户名"
copyUserId: "复制用户ID"
copyNoteId: "复制帖子ID"
searchUser: "搜索用户"
reply: "回复"
loadMore: "查看更多"
@@ -560,6 +562,7 @@ accountDeletedDescription: "此帐户已经被删除。"
menu: "菜单"
divider: "分割线"
addItem: "添加项目"
rearrange: "排序方式"
relays: "中继"
addRelay: "添加中继"
inboxUrl: "Inbox URL"
@@ -789,6 +792,7 @@ noMaintainerInformationWarning: "管理人员信息未设置。"
noBotProtectionWarning: "Bot保护未设置。"
configure: "设置"
postToGallery: "发送到图库"
postToHashtag: "投稿到这个标签"
gallery: "图库"
recentPosts: "最新发布"
popularPosts: "热门投稿"
@@ -822,6 +826,7 @@ translatedFrom: "从 {x} 翻译"
accountDeletionInProgress: "正在删除账户"
usernameInfo: "在服务器上唯一标识您的帐户的名称。您可以使用字母 (a ~ z, A ~ Z)、数字 (0 ~ 9) 和下划线 (_)。用户名以后不能更改。"
aiChanMode: "小蓝模式"
devMode: "开发者模式"
keepCw: "回复时维持隐藏内容"
pubSub: "Pub/Sub账户"
lastCommunication: "最近通信"
@@ -831,6 +836,8 @@ breakFollow: "移除关注者"
breakFollowConfirm: "你想取消关注吗?"
itsOn: "已开启"
itsOff: "已关闭"
on: "开启"
off: "关闭"
emailRequiredForSignup: "注册账户需要电子邮件地址"
unread: "未读"
filter: "筛选"
@@ -985,10 +992,13 @@ cannotBeChangedLater: "之后不能再更改。"
reactionAcceptance: "接受表情回应"
likeOnly: "仅点赞"
likeOnlyForRemote: "远程仅点赞"
nonSensitiveOnly: "仅限非敏感内容"
nonSensitiveOnlyForLocalLikeOnlyForRemote: "仅限非敏感内容(远程仅点赞)"
rolesAssignedToMe: "指派给自己的角色"
resetPasswordConfirm: "确定重置密码?"
sensitiveWords: "敏感词"
sensitiveWordsDescription: "将包含设置词的帖子的可见范围设置为首页。可以通过用换行符分隔来设置多个。"
sensitiveWordsDescription2: "用空格分割关键词作为AND格式用斜线包裹关键字来构成正则表达式。"
notesSearchNotAvailable: "帖子检索不可用"
license: "许可信息"
unfavoriteConfirm: "确定要取消收藏吗?"
@@ -1028,28 +1038,61 @@ pleaseConfirmBelowBeforeSignup: "在这个服务器上注册账号前,请确
pleaseAgreeAllToContinue: "必须全部勾选「同意」才能够继续。"
continue: "继续"
preservedUsernames: "保留的用户名"
preservedUsernamesDescription: "列出需要保留的用户名,使用换行来作为分割。被指定的用户名在建立账户时无法使用,但由管理员所创建的账户不受该限制。此外,现有的账户也不会受到影响。"
createNoteFromTheFile: "从文件创建帖子"
archive: "归档"
channelArchiveConfirmTitle: "要将{name}归档吗?"
channelArchiveConfirmDescription: "归档后,在频道列表与搜索结果中不会显示,也无法发布新的贴文。"
thisChannelArchived: "该频道已被归档。"
displayOfNote: "显示帖子"
initialAccountSetting: "初始设置"
youFollowing: "正在关注"
preventAiLearning: "拒绝接受生成式AI的学习"
preventAiLearningDescription: "要求文章生成AI或图像生成AI不能够以发布的帖子和图像等内容作为学习对象。这是通过在HTML响应中包含noai标志来实现的这不能完全阻止AI学习你的发布内容并不是所有AI都会遵守这类请求。"
options: "选项"
specifyUser: "用户指定"
failedToPreviewUrl: "无法预览"
update: "更新"
rolesThatCanBeUsedThisEmojiAsReaction: "可以使用表情作为回应的角色"
rolesThatCanBeUsedThisEmojiAsReactionEmptyDescription: "在没有指定角色的情况下,任何人都可以使用表情作为回应。"
rolesThatCanBeUsedThisEmojiAsReactionPublicRoleWarn: "角色必须是公开的。"
cancelReactionConfirm: "要取消回应吗?"
changeReactionConfirm: "要更改回应吗?"
later: "一会再说"
goToMisskey: "去往Misskey"
additionalEmojiDictionary: "表情符号追加字典"
installed: "已安装"
_initialAccountSetting:
accountCreated: "账户创建完成了!"
letsStartAccountSetup: "来进行帐户的初始设置吧。"
letsFillYourProfile: "首先,来设定你的个人档案吧!"
profileSetting: "个人资料设置"
privacySetting: "隐私设置"
theseSettingsCanEditLater: "也可以在稍后修改这里的设置。"
youCanEditMoreSettingsInSettingsPageLater: "还可以在「设置」页面进行其它各种设置,稍后就来确认一下看看吧。"
followUsers: "为了建立属于你自己的时间线,试着去关注你感兴趣的用户吧。"
pushNotificationDescription: "启用推送通知的话,就可以在设备上受到来自{name}的通知了。"
initialAccountSettingCompleted: "初始设定已经完成了!"
haveFun: "希望{name}在这里玩得开心!"
ifYouNeedLearnMore: "关于{name}(Misskey)的使用方法,详见{link}。"
skipAreYouSure: "要跳过初始设置吗?"
laterAreYouSure: "要稍后再进行初始设定吗?"
_serverRules:
description: "在新用户注册前显示服务器的简单规则。推荐显示服务条款的主要内容。"
_accountMigration:
moveFrom: "从别的账号迁移到此账户"
moveFromSub: "为另一个账户建立别名"
moveFromLabel: "迁移前的账户"
moveFromDescription: "如果迁移时需要继承其他账户的关注者,请在此创造别名。此操作需要在实行迁移之前完成!请如已下输入需要迁移的账户:@person@instance.com"
moveTo: "把这个账户迁移到新的账户"
moveToLabel: "迁移后的账户"
moveCannotBeUndone: "一旦迁移账户,就无法撤销。"
moveAccountDescription: "此操作无法取消。请先确认您已在迁移后的账户上,为此账户创造了别名。创造别名后,请如以下输入您的迁移后的账户:@person@instance.com"
moveAccountHowTo: "要进行账户迁移,请现在目标账户中为此账户建立一个别名。\n建立别名后请像这样输入目标账户@username@server.example.com"
startMigration: "迁移"
migrationConfirm: "确定要把此账户迁移到{account}吗?一旦确定后,此操作无法取消,此账户也无法以原来的状态使用。\n同时请确认迁移后的账户已创造别名。"
movedAndCannotBeUndone: "该账户已被迁移。\n迁移操作无法撤销。"
postMigrationNote: "这个账户的关注会在迁移操作后的24小时后解除。该账户的「关注中」和「关注者」皆会变为0。由于不会解除关注关系你的关注者仍然可以继续查看该账户发补给关注者的帖子。"
movedTo: "迁移后的账户"
_achievements:
earnedAt: "达成时间"
@@ -1331,6 +1374,7 @@ _role:
canInvite: "发放服务器邀请码"
canManageCustomEmojis: "管理自定义表情符号"
driveCapacity: "网盘容量"
alwaysMarkNsfw: "总是将文件标记为NSFW"
pinMax: "帖子置顶数量限制"
antennaMax: "可创建的最大天线数量"
wordMuteMax: "屏蔽词的字数限制"
@@ -1583,8 +1627,15 @@ _time:
hour: "小时"
day: "日"
_timelineTutorial:
title: "Misskey的使用方法"
step1_1: "这个画面是「时间线」。{name}的投稿会按照帖子的发布时间顺序来显示。"
step1_2: "时间线有许多种类,比如在「首页时间线」中展现的是你关注的人的贴文;而在「本地时间线」中展现的是{name}里全部用户的贴文。"
step2_1: "那么接下来,试着写一些什么东西来发布吧!你可以通过点击屏幕上的铅笔图标来打开投稿页面。"
step2_2: "第一次发布的帖子内容,建议包含自我介绍,以及「开始使用{name}了」。"
step3_1: "将想说的话发出去了吗?"
step3_2: "太棒了!现在你可以在你的时间线中看到刚刚发布的帖子了。"
step4_1: "试着对帖子使用「回应」吧!"
step4_2: "在他人的帖子上按下「+」图标,即可选择想要的表情来进行「回应」。"
_2fa:
alreadyRegistered: "此设备已被注册"
registerTOTP: "开始设置认证应用"

View File

@@ -52,6 +52,8 @@ addToList: "加入至清單"
sendMessage: "發送訊息"
copyRSS: "複製RSS"
copyUsername: "複製使用者名稱"
copyUserId: "複製使用者ID"
copyNoteId: "複製貼文ID"
searchUser: "搜尋使用者"
reply: "回覆"
loadMore: "載入更多"
@@ -790,6 +792,7 @@ noMaintainerInformationWarning: "尚未設定管理員信息。"
noBotProtectionWarning: "尚未設定Bot防護。"
configure: "設定"
postToGallery: "發佈到相簿"
postToHashtag: "以此主題標籤發布"
gallery: "相簿"
recentPosts: "最新貼文"
popularPosts: "熱門的貼文"
@@ -823,6 +826,7 @@ translatedFrom: "從 {x} 翻譯"
accountDeletionInProgress: "正在刪除帳戶"
usernameInfo: "在伺服器上您的帳戶是唯一的識別名稱。您可以使用字母 (a ~ z, A ~ Z)、數字 (0 ~ 9) 和下底線 (_)。之後帳戶名是不能更改的。"
aiChanMode: "小藍模式"
devMode: "開發者模式"
keepCw: "保持CW"
pubSub: "Pub/Sub 帳戶"
lastCommunication: "最近的通信"
@@ -832,6 +836,8 @@ breakFollow: "解除追隨者"
breakFollowConfirm: "確定要取消被追隨嗎?"
itsOn: "已開啟"
itsOff: "已關閉"
on: "開啟"
off: "關閉"
emailRequiredForSignup: "註冊帳戶需要電子郵件地址"
unread: "未讀"
filter: "篩選"
@@ -986,6 +992,8 @@ cannotBeChangedLater: "之後不能變更。"
reactionAcceptance: "接受表情反應"
likeOnly: "僅限讚"
likeOnlyForRemote: "遠端僅限讚"
nonSensitiveOnly: "僅限非敏感"
nonSensitiveOnlyForLocalLikeOnlyForRemote: "僅限非敏感(遠端僅限按讚)"
rolesAssignedToMe: "指派給自己的角色"
resetPasswordConfirm: "重設密碼?"
sensitiveWords: "敏感詞"
@@ -1039,14 +1047,28 @@ thisChannelArchived: "這個頻道已被封存。"
displayOfNote: "顯示貼文"
initialAccountSetting: "初始設定"
youFollowing: "追隨中"
preventAiLearning: "拒絕接受生式AI的學習"
preventAiLearningDescription: "要求外部的文章生AI或圖像生AI不以發布的貼文和圖像等內容為學習對象。這是透過在HTML響應中包含noai旗標來實現的但不能完全防止AI的學習因為這要看該AI是否遵守這個要求。"
preventAiLearning: "拒絕接受生式AI的訓練"
preventAiLearningDescription: "要求外部的文章生成式AI或圖像生成式AI不以發布的貼文和圖像等內容為學習對象。這是透過在HTML響應中包含noai旗標來實現的但不能完全防止AI的學習因為這要看該AI是否遵守這個要求。"
options: "選項"
specifyUser: "指定使用者"
failedToPreviewUrl: "無法預覽"
update: "更新"
rolesThatCanBeUsedThisEmojiAsReaction: "可以當成反應使用的角色"
rolesThatCanBeUsedThisEmojiAsReactionEmptyDescription: "如果是未指定角色的情況,則任何人都可以被當成反應來使用。"
rolesThatCanBeUsedThisEmojiAsReactionPublicRoleWarn: "角色必須是公開的角色。"
cancelReactionConfirm: "要取消做出的反應嗎?"
changeReactionConfirm: "要變更做出的反應嗎?"
later: "稍後再說"
goToMisskey: "往Misskey"
additionalEmojiDictionary: "表情符號的附加辭典"
installed: "已安裝"
branding: "品牌宣傳"
_initialAccountSetting:
accountCreated: "帳戶已建立完成!"
letsStartAccountSetup: "來進行帳戶的初始設定吧。"
letsFillYourProfile: "首先,來設定您的個人檔案吧。"
profileSetting: "個人檔案設定"
privacySetting: "隱私設定"
theseSettingsCanEditLater: "這裡的設定可以在之後變更。"
youCanEditMoreSettingsInSettingsPageLater: "除此之外,還可以在「設定」頁面進行各種設定。之後請確認看看。"
followUsers: "為了構築時間軸,試著追蹤您感興趣的使用者吧。"
@@ -1055,6 +1077,7 @@ _initialAccountSetting:
haveFun: "盡情享受{name}吧!"
ifYouNeedLearnMore: "關於如何使用{name}(Misskey)的詳細資訊,請見{link}。"
skipAreYouSure: "要略過初始設定嗎?"
laterAreYouSure: "稍後再重新進行初始設定嗎?"
_serverRules:
description: "設定伺服器的簡要規則,在新的註冊之前顯示。建議的內容是使用條款的摘要。"
_accountMigration:

View File

@@ -1,12 +1,12 @@
{
"name": "misskey",
"version": "13.13.0-beta.3",
"version": "13.13.2",
"codename": "nasubi",
"repository": {
"type": "git",
"url": "https://github.com/misskey-dev/misskey.git"
},
"packageManager": "pnpm@8.5.1",
"packageManager": "pnpm@8.6.0",
"workspaces": [
"packages/frontend",
"packages/backend",
@@ -51,16 +51,16 @@
"gulp-replace": "1.1.4",
"gulp-terser": "2.1.0",
"js-yaml": "4.1.0",
"typescript": "5.0.4"
"typescript": "5.1.3"
},
"devDependencies": {
"@types/gulp": "4.0.10",
"@types/gulp-rename": "2.0.1",
"@typescript-eslint/eslint-plugin": "5.59.5",
"@typescript-eslint/parser": "5.59.5",
"@typescript-eslint/eslint-plugin": "5.60.0",
"@typescript-eslint/parser": "5.60.0",
"cross-env": "7.0.3",
"cypress": "12.13.0",
"eslint": "8.40.0",
"cypress": "12.15.0",
"eslint": "8.43.0",
"start-server-and-test": "2.0.0"
},
"optionalDependencies": {

View File

@@ -17,7 +17,7 @@
"paths": {
"@/*": ["*"]
},
"target": "es2021"
"target": "es2022"
},
"minify": false
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -0,0 +1,17 @@
export class ErrorImageUrl1685973839966 {
name = 'ErrorImageUrl1685973839966'
async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "errorImageUrl"`);
await queryRunner.query(`ALTER TABLE "meta" ADD "serverErrorImageUrl" character varying(1024)`);
await queryRunner.query(`ALTER TABLE "meta" ADD "notFoundImageUrl" character varying(1024)`);
await queryRunner.query(`ALTER TABLE "meta" ADD "infoImageUrl" character varying(1024)`);
}
async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "infoImageUrl"`);
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "notFoundImageUrl"`);
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "serverErrorImageUrl"`);
await queryRunner.query(`ALTER TABLE "meta" ADD "errorImageUrl" character varying(1024) DEFAULT 'https://xn--931a.moe/aiart/yubitun.png'`);
}
}

View File

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

View File

@@ -35,6 +35,7 @@
"@swc/core-win32-x64-msvc": "1.3.56",
"@tensorflow/tfjs": "4.4.0",
"@tensorflow/tfjs-node": "4.4.0",
"bufferutil": "^4.0.7",
"slacc-android-arm-eabi": "0.0.9",
"slacc-android-arm64": "0.0.9",
"slacc-darwin-arm64": "0.0.9",
@@ -46,39 +47,40 @@
"slacc-linux-arm64-musl": "0.0.9",
"slacc-linux-x64-gnu": "0.0.9",
"slacc-win32-arm64-msvc": "0.0.9",
"slacc-win32-x64-msvc": "0.0.9"
"slacc-win32-x64-msvc": "0.0.9",
"utf-8-validate": "^6.0.3"
},
"dependencies": {
"@aws-sdk/client-s3": "3.321.1",
"@aws-sdk/lib-storage": "3.321.1",
"@aws-sdk/node-http-handler": "3.321.1",
"@bull-board/api": "5.2.0",
"@bull-board/fastify": "5.2.0",
"@bull-board/ui": "5.2.0",
"@bull-board/api": "5.5.3",
"@bull-board/fastify": "5.5.3",
"@bull-board/ui": "5.5.3",
"@discordapp/twemoji": "14.1.2",
"@fastify/accepts": "4.1.0",
"@fastify/accepts": "4.2.0",
"@fastify/cookie": "8.3.0",
"@fastify/cors": "8.2.1",
"@fastify/http-proxy": "9.1.0",
"@fastify/multipart": "7.6.0",
"@fastify/static": "6.10.1",
"@fastify/cors": "8.3.0",
"@fastify/http-proxy": "9.2.1",
"@fastify/multipart": "7.7.0",
"@fastify/static": "6.10.2",
"@fastify/view": "7.4.1",
"@nestjs/common": "9.4.2",
"@nestjs/core": "9.4.2",
"@nestjs/testing": "9.4.2",
"@nestjs/common": "10.0.3",
"@nestjs/core": "10.0.3",
"@nestjs/testing": "10.0.3",
"@peertube/http-signature": "1.7.0",
"@sinonjs/fake-timers": "10.0.2",
"@sinonjs/fake-timers": "10.3.0",
"@swc/cli": "0.1.62",
"@swc/core": "1.3.59",
"@swc/core": "1.3.66",
"accepts": "1.3.8",
"ajv": "8.12.0",
"archiver": "5.3.1",
"autwh": "0.1.0",
"bcryptjs": "2.4.3",
"blurhash": "2.0.5",
"bull": "4.10.4",
"cacheable-lookup": "6.1.0",
"cbor": "8.1.0",
"bullmq": "4.1.0",
"cacheable-lookup": "7.0.0",
"cbor": "9.0.0",
"chalk": "5.2.0",
"chalk-template": "0.4.0",
"chokidar": "3.5.3",
@@ -88,37 +90,37 @@
"date-fns": "2.30.0",
"deep-email-validator": "0.1.21",
"escape-regexp": "0.0.1",
"fastify": "4.17.0",
"fastify": "4.18.0",
"feed": "4.2.2",
"file-type": "18.4.0",
"file-type": "18.5.0",
"fluent-ffmpeg": "2.1.2",
"form-data": "4.0.0",
"got": "12.6.0",
"happy-dom": "9.19.2",
"got": "13.0.0",
"happy-dom": "9.20.3",
"hpagent": "1.2.0",
"ioredis": "5.3.2",
"ip-cidr": "3.1.0",
"ipaddr.js": "2.1.0",
"is-svg": "4.3.2",
"js-yaml": "4.1.0",
"jsdom": "21.1.1",
"jsdom": "22.1.0",
"json5": "2.2.3",
"jsonld": "8.1.1",
"jsonld": "8.2.0",
"jsrsasign": "10.8.6",
"meilisearch": "0.32.4",
"meilisearch": "0.33.0",
"mfm-js": "0.23.3",
"mime-types": "2.1.35",
"misskey-js": "workspace:*",
"ms": "3.0.0-canary.1",
"nested-property": "4.0.0",
"node-fetch": "3.3.1",
"nodemailer": "6.9.2",
"nodemailer": "6.9.3",
"nsfwjs": "2.4.2",
"oauth": "0.10.0",
"os-utils": "0.0.14",
"otpauth": "9.1.2",
"parse5": "7.1.2",
"pg": "8.11.0",
"private-ip": "3.0.0",
"probe-image-size": "7.2.3",
"promise-limit": "2.7.0",
"pug": "3.0.2",
@@ -127,37 +129,34 @@
"qrcode": "1.5.3",
"random-seed": "0.3.0",
"ratelimiter": "3.4.1",
"re2": "1.18.0",
"re2": "1.19.1",
"redis-lock": "0.1.4",
"reflect-metadata": "0.1.13",
"rename": "1.0.4",
"rndstr": "1.0.0",
"rss-parser": "3.13.0",
"rxjs": "7.8.1",
"s-age": "1.1.2",
"sanitize-html": "2.10.0",
"seedrandom": "3.0.5",
"semver": "7.5.1",
"sanitize-html": "2.11.0",
"semver": "7.5.3",
"sharp": "0.32.1",
"sharp-read-bmp": "github:misskey-dev/sharp-read-bmp",
"slacc": "0.0.9",
"strict-event-emitter-types": "2.0.0",
"stringz": "2.1.0",
"summaly": "github:misskey-dev/summaly",
"systeminformation": "5.17.12",
"systeminformation": "5.18.4",
"tinycolor2": "1.6.0",
"tmp": "0.2.1",
"tsc-alias": "1.8.6",
"tsconfig-paths": "4.2.0",
"twemoji-parser": "14.0.0",
"typeorm": "0.3.16",
"typescript": "5.0.4",
"typeorm": "0.3.17",
"typescript": "5.1.3",
"ulid": "2.3.0",
"unzipper": "0.10.11",
"unzipper": "0.10.14",
"uuid": "9.0.0",
"vary": "1.1.2",
"web-push": "3.6.1",
"websocket": "1.0.34",
"web-push": "3.6.3",
"ws": "8.13.0",
"xev": "3.0.2"
},
@@ -167,23 +166,23 @@
"@types/accepts": "1.3.5",
"@types/archiver": "5.3.2",
"@types/bcryptjs": "2.4.2",
"@types/bull": "4.10.0",
"@types/cbor": "6.0.0",
"@types/color-convert": "2.0.0",
"@types/content-disposition": "0.5.5",
"@types/escape-regexp": "0.0.1",
"@types/fluent-ffmpeg": "2.1.21",
"@types/jest": "29.5.1",
"@types/jest": "29.5.2",
"@types/js-yaml": "4.0.5",
"@types/jsdom": "21.1.1",
"@types/jsonld": "1.5.8",
"@types/jsonld": "1.5.9",
"@types/jsrsasign": "10.5.8",
"@types/mime-types": "2.1.1",
"@types/node": "20.2.3",
"@types/ms": "^0.7.31",
"@types/node": "20.3.1",
"@types/node-fetch": "3.0.3",
"@types/nodemailer": "6.4.8",
"@types/oauth": "0.9.1",
"@types/pg": "8.10.1",
"@types/pg": "8.10.2",
"@types/pug": "2.0.6",
"@types/punycode": "2.1.0",
"@types/qrcode": "1.5.0",
@@ -198,19 +197,20 @@
"@types/tinycolor2": "1.4.3",
"@types/tmp": "0.2.3",
"@types/unzipper": "0.10.6",
"@types/uuid": "9.0.1",
"@types/uuid": "9.0.2",
"@types/vary": "1.1.0",
"@types/web-push": "3.3.2",
"@types/websocket": "1.0.5",
"@types/ws": "8.5.4",
"@typescript-eslint/eslint-plugin": "5.59.5",
"@typescript-eslint/parser": "5.59.5",
"@types/ws": "8.5.5",
"@typescript-eslint/eslint-plugin": "5.60.0",
"@typescript-eslint/parser": "5.60.0",
"aws-sdk-client-mock": "2.1.1",
"cross-env": "7.0.3",
"eslint": "8.40.0",
"eslint": "8.43.0",
"eslint-plugin-import": "2.27.5",
"execa": "6.1.0",
"jest": "29.5.0",
"jest-mock": "29.5.0"
"jest-mock": "29.5.0",
"schema-type": "github:misskey-dev/schema-type"
}
}

View File

@@ -100,7 +100,7 @@ export class GlobalModule implements OnApplicationShutdown {
@Inject(DI.redisForSub) private redisForSub: Redis.Redis,
) {}
async onApplicationShutdown(signal: string): Promise<void> {
public async dispose(): Promise<void> {
if (process.env.NODE_ENV === 'test') {
// XXX:
// Shutting down the existing connections causes errors on Jest as
@@ -116,4 +116,8 @@ export class GlobalModule implements OnApplicationShutdown {
this.redisForSub.disconnect(),
]);
}
async onApplicationShutdown(signal: string): Promise<void> {
await this.dispose();
}
}

View File

@@ -190,6 +190,6 @@ function tryCreateUrl(url: string) {
try {
return new URL(url);
} catch (e) {
throw `url="${url}" is not a valid URL.`;
throw new Error(`url="${url}" is not a valid URL.`);
}
}

View File

@@ -4,83 +4,7 @@ import type { User } from '@/models/entities/User.js';
import { DI } from '@/di-symbols.js';
import { bindThis } from '@/decorators.js';
import { NotificationService } from '@/core/NotificationService.js';
export const ACHIEVEMENT_TYPES = [
'notes1',
'notes10',
'notes100',
'notes500',
'notes1000',
'notes5000',
'notes10000',
'notes20000',
'notes30000',
'notes40000',
'notes50000',
'notes60000',
'notes70000',
'notes80000',
'notes90000',
'notes100000',
'login3',
'login7',
'login15',
'login30',
'login60',
'login100',
'login200',
'login300',
'login400',
'login500',
'login600',
'login700',
'login800',
'login900',
'login1000',
'passedSinceAccountCreated1',
'passedSinceAccountCreated2',
'passedSinceAccountCreated3',
'loggedInOnBirthday',
'loggedInOnNewYearsDay',
'noteClipped1',
'noteFavorited1',
'myNoteFavorited1',
'profileFilled',
'markedAsCat',
'following1',
'following10',
'following50',
'following100',
'following300',
'followers1',
'followers10',
'followers50',
'followers100',
'followers300',
'followers500',
'followers1000',
'collectAchievements30',
'viewAchievements3min',
'iLoveMisskey',
'foundTreasure',
'client30min',
'client60min',
'noteDeletedWithin1min',
'postedAtLateNight',
'postedAt0min0sec',
'selfQuote',
'htl20npm',
'viewInstanceChart',
'outputHelloWorldOnScratchpad',
'open3windows',
'driveFolderCircularReference',
'reactWithoutRead',
'clickedClickHere',
'justPlainLucky',
'setNameToSyuilo',
'cookieClicked',
'brainDiver',
] as const;
import { ACHIEVEMENT_TYPES } from 'misskey-js';
@Injectable()
export class AchievementService {

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/json-schema.js';
import type { Packed } from 'misskey-js';
import { DI } from '@/di-symbols.js';
import type { MutingsRepository, NotesRepository, AntennasRepository, UserListJoiningsRepository } from '@/models/index.js';
import { UtilityService } from '@/core/UtilityService.js';
@@ -55,11 +55,6 @@ export class AntennaService implements OnApplicationShutdown {
this.redisForSub.on('message', this.onRedisMessage);
}
@bindThis
public onApplicationShutdown(signal?: string | undefined) {
this.redisForSub.off('message', this.onRedisMessage);
}
@bindThis
private async onRedisMessage(_: string, data: string): Promise<void> {
const obj = JSON.parse(data);
@@ -196,4 +191,14 @@ export class AntennaService implements OnApplicationShutdown {
return this.antennas;
}
@bindThis
public dispose(): void {
this.redisForSub.off('message', this.onRedisMessage);
}
@bindThis
public onApplicationShutdown(signal?: string | undefined): void {
this.dispose();
}
}

View File

@@ -166,7 +166,23 @@ export class CacheService implements OnApplicationShutdown {
}
@bindThis
public onApplicationShutdown(signal?: string | undefined) {
public dispose(): void {
this.redisForSub.off('message', this.onMessage);
this.userByIdCache.dispose();
this.localUserByNativeTokenCache.dispose();
this.localUserByIdCache.dispose();
this.uriPersonCache.dispose();
this.userProfileCache.dispose();
this.userMutingsCache.dispose();
this.userBlockingCache.dispose();
this.userBlockedCache.dispose();
this.renoteMutingsCache.dispose();
this.userFollowingsCache.dispose();
this.userFollowingChannelsCache.dispose();
}
@bindThis
public onApplicationShutdown(signal?: string | undefined): void {
this.dispose();
}
}

View File

@@ -30,7 +30,7 @@ export class CaptchaService {
}, { throwErrorWhenResponseNotOk: false });
if (!res.ok) {
throw `${res.status}`;
throw new Error(`${res.status}`);
}
return await res.json() as CaptchaResponse;
@@ -39,48 +39,48 @@ export class CaptchaService {
@bindThis
public async verifyRecaptcha(secret: string, response: string | null | undefined): Promise<void> {
if (response == null) {
throw 'recaptcha-failed: no response provided';
throw new Error('recaptcha-failed: no response provided');
}
const result = await this.getCaptchaResponse('https://www.recaptcha.net/recaptcha/api/siteverify', secret, response).catch(err => {
throw `recaptcha-request-failed: ${err}`;
throw new Error(`recaptcha-request-failed: ${err}`);
});
if (result.success !== true) {
const errorCodes = result['error-codes'] ? result['error-codes'].join(', ') : '';
throw `recaptcha-failed: ${errorCodes}`;
throw new Error(`recaptcha-failed: ${errorCodes}`);
}
}
@bindThis
public async verifyHcaptcha(secret: string, response: string | null | undefined): Promise<void> {
if (response == null) {
throw 'hcaptcha-failed: no response provided';
throw new Error('hcaptcha-failed: no response provided');
}
const result = await this.getCaptchaResponse('https://hcaptcha.com/siteverify', secret, response).catch(err => {
throw `hcaptcha-request-failed: ${err}`;
throw new Error(`hcaptcha-request-failed: ${err}`);
});
if (result.success !== true) {
const errorCodes = result['error-codes'] ? result['error-codes'].join(', ') : '';
throw `hcaptcha-failed: ${errorCodes}`;
throw new Error(`hcaptcha-failed: ${errorCodes}`);
}
}
@bindThis
public async verifyTurnstile(secret: string, response: string | null | undefined): Promise<void> {
if (response == null) {
throw 'turnstile-failed: no response provided';
throw new Error('turnstile-failed: no response provided');
}
const result = await this.getCaptchaResponse('https://challenges.cloudflare.com/turnstile/v0/siteverify', secret, response).catch(err => {
throw `turnstile-request-failed: ${err}`;
throw new Error(`turnstile-request-failed: ${err}`);
});
if (result.success !== true) {
const errorCodes = result['error-codes'] ? result['error-codes'].join(', ') : '';
throw `turnstile-failed: ${errorCodes}`;
throw new Error(`turnstile-failed: ${errorCodes}`);
}
}
}

View File

@@ -1,4 +1,4 @@
import { Inject, Injectable } from '@nestjs/common';
import { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common';
import { DataSource, In, IsNull } from 'typeorm';
import * as Redis from 'ioredis';
import { DI } from '@/di-symbols.js';
@@ -18,7 +18,7 @@ import type { Serialized } from '@/server/api/stream/types.js';
const parseEmojiStrRegexp = /^(\w+)(?:@([\w.-]+))?$/;
@Injectable()
export class CustomEmojiService {
export class CustomEmojiService implements OnApplicationShutdown {
private cache: MemoryKVCache<Emoji | null>;
public localEmojisCache: RedisSingleCache<Map<string, Emoji>>;
@@ -349,4 +349,14 @@ export class CustomEmojiService {
this.cache.set(`${emoji.name} ${emoji.host}`, emoji);
}
}
@bindThis
public dispose(): void {
this.cache.dispose();
}
@bindThis
public onApplicationShutdown(signal?: string | undefined): void {
this.dispose();
}
}

View File

@@ -2,8 +2,7 @@ import * as fs from 'node:fs';
import * as stream from 'node:stream';
import * as util from 'node:util';
import { Inject, Injectable } from '@nestjs/common';
import IPCIDR from 'ip-cidr';
import PrivateIp from 'private-ip';
import ipaddr from 'ipaddr.js';
import chalk from 'chalk';
import got, * as Got from 'got';
import { parse } from 'content-disposition';
@@ -123,15 +122,15 @@ export class DownloadService {
public async downloadTextFile(url: string): Promise<string> {
// Create temp file
const [path, cleanup] = await createTemp();
this.logger.info(`text file: Temp file is ${path}`);
try {
// write content at URL to temp file
await this.downloadUrl(url, path);
const text = await util.promisify(fs.readFile)(path, 'utf8');
return text;
} finally {
cleanup();
@@ -140,13 +139,14 @@ export class DownloadService {
@bindThis
private isPrivateIp(ip: string): boolean {
const parsedIp = ipaddr.parse(ip);
for (const net of this.config.allowedPrivateNetworks ?? []) {
const cidr = new IPCIDR(net);
if (cidr.contains(ip)) {
if (parsedIp.match(ipaddr.parseCIDR(net))) {
return false;
}
}
return PrivateIp(ip) ?? false;
return parsedIp.range() !== 'unicast';
}
}

View File

@@ -1,4 +1,4 @@
import { Inject, Injectable } from '@nestjs/common';
import { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common';
import * as Redis from 'ioredis';
import type { InstancesRepository } from '@/models/index.js';
import type { Instance } from '@/models/entities/Instance.js';
@@ -9,7 +9,7 @@ import { UtilityService } from '@/core/UtilityService.js';
import { bindThis } from '@/decorators.js';
@Injectable()
export class FederatedInstanceService {
export class FederatedInstanceService implements OnApplicationShutdown {
public federatedInstanceCache: RedisKVCache<Instance | null>;
constructor(
@@ -77,4 +77,14 @@ export class FederatedInstanceService {
this.federatedInstanceCache.set(result.host, result);
}
@bindThis
public dispose(): void {
this.federatedInstanceCache.dispose();
}
@bindThis
public onApplicationShutdown(signal?: string | undefined): void {
this.dispose();
}
}

View File

@@ -116,14 +116,14 @@ export class FetchInstanceMetadataService {
const wellknown = await this.httpRequestService.getJson('https://' + instance.host + '/.well-known/nodeinfo')
.catch(err => {
if (err.statusCode === 404) {
throw 'No nodeinfo provided';
throw new Error('No nodeinfo provided');
} else {
throw err.statusCode ?? err.message;
}
}) as Record<string, unknown>;
if (wellknown.links == null || !Array.isArray(wellknown.links)) {
throw 'No wellknown links';
throw new Error('No wellknown links');
}
const links = wellknown.links as any[];
@@ -134,7 +134,7 @@ export class FetchInstanceMetadataService {
const link = lnik2_1 ?? lnik2_0 ?? lnik1_0;
if (link == null) {
throw 'No nodeinfo link provided';
throw new Error('No nodeinfo link provided');
}
const info = await this.httpRequestService.getJson(link.href)

View File

@@ -16,11 +16,11 @@ import type {
UserListStreamTypes,
RoleTimelineStreamTypes,
} from '@/server/api/stream/types.js';
import type { Packed } from '@/misc/json-schema.js';
import type { Packed } from 'misskey-js';
import { DI } from '@/di-symbols.js';
import type { Config } from '@/config.js';
import { bindThis } from '@/decorators.js';
import { Role } from '@/models';
import { Role } from '@/models/index.js';
@Injectable()
export class GlobalEventService {

View File

@@ -5,7 +5,7 @@ import type { Config } from '@/config.js';
import { genAid, parseAid } from '@/misc/id/aid.js';
import { genMeid, parseMeid } from '@/misc/id/meid.js';
import { genMeidg, parseMeidg } from '@/misc/id/meidg.js';
import { genObjectId } from '@/misc/id/object-id.js';
import { genObjectId, parseObjectId } from '@/misc/id/object-id.js';
import { bindThis } from '@/decorators.js';
import { parseUlid } from '@/misc/id/ulid.js';
@@ -38,7 +38,7 @@ export class IdService {
public parse(id: string): { date: Date; } {
switch (this.method) {
case 'aid': return parseAid(id);
case 'objectid':
case 'objectid': return parseObjectId(id);
case 'meid': return parseMeid(id);
case 'meidg': return parseMeidg(id);
case 'ulid': return parseUlid(id);

View File

@@ -3,7 +3,7 @@ import { DI } from '@/di-symbols.js';
import type { Config } from '@/config.js';
import Logger from '@/logger.js';
import { bindThis } from '@/decorators.js';
import type { KEYWORD } from 'color-convert/conversions';
import type { KEYWORD } from 'color-convert/conversions.js';
@Injectable()
export class LoggerService {

View File

@@ -120,8 +120,13 @@ export class MetaService implements OnApplicationShutdown {
}
@bindThis
public onApplicationShutdown(signal?: string | undefined) {
public dispose(): void {
clearInterval(this.intervalId);
this.redisForSub.off('message', this.onMessage);
}
@bindThis
public onApplicationShutdown(signal?: string | undefined): void {
this.dispose();
}
}

View File

@@ -510,7 +510,7 @@ export class NoteCreateService implements OnApplicationShutdown {
if (data.poll && data.poll.expiresAt) {
const delay = data.poll.expiresAt.getTime() - Date.now();
this.queueService.endedPollNotificationQueue.add({
this.queueService.endedPollNotificationQueue.add(note.id, {
noteId: note.id,
}, {
delay,
@@ -790,7 +790,13 @@ export class NoteCreateService implements OnApplicationShutdown {
return mentionedUsers;
}
onApplicationShutdown(signal?: string | undefined) {
@bindThis
public dispose(): void {
this.#shutdownController.abort();
}
@bindThis
public onApplicationShutdown(signal?: string | undefined): void {
this.dispose();
}
}

View File

@@ -3,7 +3,7 @@ import { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common';
import { In } from 'typeorm';
import { DI } from '@/di-symbols.js';
import type { User } from '@/models/entities/User.js';
import type { Packed } from '@/misc/json-schema.js';
import type { Packed } from 'misskey-js';
import type { Note } from '@/models/entities/Note.js';
import { IdService } from '@/core/IdService.js';
import { GlobalEventService } from '@/core/GlobalEventService.js';
@@ -122,7 +122,13 @@ export class NoteReadService implements OnApplicationShutdown {
}
}
onApplicationShutdown(signal?: string | undefined): void {
@bindThis
public dispose(): void {
this.#shutdownController.abort();
}
@bindThis
public onApplicationShutdown(signal?: string | undefined): void {
this.dispose();
}
}

View File

@@ -152,7 +152,13 @@ export class NotificationService implements OnApplicationShutdown {
*/
}
onApplicationShutdown(signal?: string | undefined): void {
@bindThis
public dispose(): void {
this.#shutdownController.abort();
}
@bindThis
public onApplicationShutdown(signal?: string | undefined): void {
this.dispose();
}
}

View File

@@ -1,9 +1,9 @@
import { Inject, Injectable } from '@nestjs/common';
import { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common';
import push from 'web-push';
import * as Redis from 'ioredis';
import { DI } from '@/di-symbols.js';
import type { Config } from '@/config.js';
import type { Packed } from '@/misc/json-schema';
import type { Packed } from 'misskey-js';
import { getNoteSummary } from '@/misc/get-note-summary.js';
import type { SwSubscription, SwSubscriptionsRepository } from '@/models/index.js';
import { MetaService } from '@/core/MetaService.js';
@@ -42,7 +42,7 @@ function truncateBody<T extends keyof PushNotificationsTypes>(type: T, body: Pus
}
@Injectable()
export class PushNotificationService {
export class PushNotificationService implements OnApplicationShutdown {
private subscriptionsCache: RedisKVCache<SwSubscription[]>;
constructor(
@@ -115,4 +115,14 @@ export class PushNotificationService {
});
}
}
@bindThis
public dispose(): void {
this.subscriptionsCache.dispose();
}
@bindThis
public onApplicationShutdown(signal?: string | undefined): void {
this.dispose();
}
}

View File

@@ -1,42 +1,11 @@
import { setTimeout } from 'node:timers/promises';
import { Inject, Module, OnApplicationShutdown } from '@nestjs/common';
import Bull from 'bull';
import * as Bull from 'bullmq';
import { DI } from '@/di-symbols.js';
import type { Config } from '@/config.js';
import { QUEUE, baseQueueOptions } from '@/queue/const.js';
import type { Provider } from '@nestjs/common';
import type { DeliverJobData, InboxJobData, DbJobData, ObjectStorageJobData, EndedPollNotificationJobData, WebhookDeliverJobData, RelationshipJobData, DbJobMap } from '../queue/types.js';
function q<T>(config: Config, name: string, limitPerSec = -1) {
return new Bull<T>(name, {
redis: {
port: config.redisForJobQueue.port,
host: config.redisForJobQueue.host,
family: config.redisForJobQueue.family == null ? 0 : config.redisForJobQueue.family,
password: config.redisForJobQueue.pass,
db: config.redisForJobQueue.db ?? 0,
},
prefix: config.redisForJobQueue.prefix ? `${config.redisForJobQueue.prefix}:queue` : 'queue',
limiter: limitPerSec > 0 ? {
max: limitPerSec,
duration: 1000,
} : undefined,
settings: {
backoffStrategies: {
apBackoff,
},
},
});
}
// ref. https://github.com/misskey-dev/misskey/pull/7635#issue-971097019
function apBackoff(attemptsMade: number, err: Error) {
const baseDelay = 60 * 1000; // 1min
const maxBackoff = 8 * 60 * 60 * 1000; // 8hours
let backoff = (Math.pow(2, attemptsMade) - 1) * baseDelay;
backoff = Math.min(backoff, maxBackoff);
backoff += Math.round(backoff * Math.random() * 0.2);
return backoff;
}
import type { DeliverJobData, InboxJobData, EndedPollNotificationJobData, WebhookDeliverJobData, RelationshipJobData } from '../queue/types.js';
export type SystemQueue = Bull.Queue<Record<string, unknown>>;
export type EndedPollNotificationQueue = Bull.Queue<EndedPollNotificationJobData>;
@@ -49,49 +18,49 @@ export type WebhookDeliverQueue = Bull.Queue<WebhookDeliverJobData>;
const $system: Provider = {
provide: 'queue:system',
useFactory: (config: Config) => q(config, 'system'),
useFactory: (config: Config) => new Bull.Queue(QUEUE.SYSTEM, baseQueueOptions(config, QUEUE.SYSTEM)),
inject: [DI.config],
};
const $endedPollNotification: Provider = {
provide: 'queue:endedPollNotification',
useFactory: (config: Config) => q(config, 'endedPollNotification'),
useFactory: (config: Config) => new Bull.Queue(QUEUE.ENDED_POLL_NOTIFICATION, baseQueueOptions(config, QUEUE.ENDED_POLL_NOTIFICATION)),
inject: [DI.config],
};
const $deliver: Provider = {
provide: 'queue:deliver',
useFactory: (config: Config) => q(config, 'deliver', config.deliverJobPerSec ?? 128),
useFactory: (config: Config) => new Bull.Queue(QUEUE.DELIVER, baseQueueOptions(config, QUEUE.DELIVER)),
inject: [DI.config],
};
const $inbox: Provider = {
provide: 'queue:inbox',
useFactory: (config: Config) => q(config, 'inbox', config.inboxJobPerSec ?? 16),
useFactory: (config: Config) => new Bull.Queue(QUEUE.INBOX, baseQueueOptions(config, QUEUE.INBOX)),
inject: [DI.config],
};
const $db: Provider = {
provide: 'queue:db',
useFactory: (config: Config) => q(config, 'db'),
useFactory: (config: Config) => new Bull.Queue(QUEUE.DB, baseQueueOptions(config, QUEUE.DB)),
inject: [DI.config],
};
const $relationship: Provider = {
provide: 'queue:relationship',
useFactory: (config: Config) => q(config, 'relationship', config.relashionshipJobPerSec ?? 64),
useFactory: (config: Config) => new Bull.Queue(QUEUE.RELATIONSHIP, baseQueueOptions(config, QUEUE.RELATIONSHIP)),
inject: [DI.config],
};
const $objectStorage: Provider = {
provide: 'queue:objectStorage',
useFactory: (config: Config) => q(config, 'objectStorage'),
useFactory: (config: Config) => new Bull.Queue(QUEUE.OBJECT_STORAGE, baseQueueOptions(config, QUEUE.OBJECT_STORAGE)),
inject: [DI.config],
};
const $webhookDeliver: Provider = {
provide: 'queue:webhookDeliver',
useFactory: (config: Config) => q(config, 'webhookDeliver', 64),
useFactory: (config: Config) => new Bull.Queue(QUEUE.WEBHOOK_DELIVER, baseQueueOptions(config, QUEUE.WEBHOOK_DELIVER)),
inject: [DI.config],
};
@@ -131,7 +100,7 @@ export class QueueModule implements OnApplicationShutdown {
@Inject('queue:webhookDeliver') public webhookDeliverQueue: WebhookDeliverQueue,
) {}
async onApplicationShutdown(signal: string): Promise<void> {
public async dispose(): Promise<void> {
if (process.env.NODE_ENV === 'test') {
// XXX:
// Shutting down the existing connections causes errors on Jest as
@@ -151,4 +120,8 @@ export class QueueModule implements OnApplicationShutdown {
this.webhookDeliverQueue.close(),
]);
}
async onApplicationShutdown(signal: string): Promise<void> {
await this.dispose();
}
}

View File

@@ -1,6 +1,5 @@
import { Inject, Injectable } from '@nestjs/common';
import { v4 as uuid } from 'uuid';
import Bull from 'bull';
import type { IActivity } from '@/core/activitypub/type.js';
import type { DriveFile } from '@/models/entities/DriveFile.js';
import type { Webhook, webhookEventTypes } from '@/models/entities/Webhook.js';
@@ -11,6 +10,7 @@ import type { Antenna } from '@/server/api/endpoints/i/import-antennas.js';
import type { DbQueue, DeliverQueue, EndedPollNotificationQueue, InboxQueue, ObjectStorageQueue, RelationshipQueue, SystemQueue, WebhookDeliverQueue } from './QueueModule.js';
import type { DbJobData, RelationshipJobData, ThinUser } from '../queue/types.js';
import type httpSignature from '@peertube/http-signature';
import type * as Bull from 'bullmq';
@Injectable()
export class QueueService {
@@ -26,7 +26,43 @@ export class QueueService {
@Inject('queue:relationship') public relationshipQueue: RelationshipQueue,
@Inject('queue:objectStorage') public objectStorageQueue: ObjectStorageQueue,
@Inject('queue:webhookDeliver') public webhookDeliverQueue: WebhookDeliverQueue,
) {}
) {
this.systemQueue.add('tickCharts', {
}, {
repeat: { pattern: '55 * * * *' },
removeOnComplete: true,
});
this.systemQueue.add('resyncCharts', {
}, {
repeat: { pattern: '0 0 * * *' },
removeOnComplete: true,
});
this.systemQueue.add('cleanCharts', {
}, {
repeat: { pattern: '0 0 * * *' },
removeOnComplete: true,
});
this.systemQueue.add('aggregateRetention', {
}, {
repeat: { pattern: '0 0 * * *' },
removeOnComplete: true,
});
this.systemQueue.add('clean', {
}, {
repeat: { pattern: '0 0 * * *' },
removeOnComplete: true,
});
this.systemQueue.add('checkExpiredMutings', {
}, {
repeat: { pattern: '*/5 * * * *' },
removeOnComplete: true,
});
}
@bindThis
public deliver(user: ThinUser, content: IActivity | null, to: string | null, isSharedInbox: boolean) {
@@ -42,11 +78,10 @@ export class QueueService {
isSharedInbox,
};
return this.deliverQueue.add(data, {
return this.deliverQueue.add(to, data, {
attempts: this.config.deliverJobMaxAttempts ?? 12,
timeout: 1 * 60 * 1000, // 1min
backoff: {
type: 'apBackoff',
type: 'custom',
},
removeOnComplete: true,
removeOnFail: true,
@@ -60,11 +95,10 @@ export class QueueService {
signature,
};
return this.inboxQueue.add(data, {
return this.inboxQueue.add('', data, {
attempts: this.config.inboxJobMaxAttempts ?? 8,
timeout: 5 * 60 * 1000, // 5min
backoff: {
type: 'apBackoff',
type: 'custom',
},
removeOnComplete: true,
removeOnFail: true,
@@ -212,7 +246,7 @@ export class QueueService {
private generateToDbJobData<T extends 'importFollowingToDb' | 'importBlockingToDb', D extends DbJobData<T>>(name: T, data: D): {
name: string,
data: D,
opts: Bull.JobOptions,
opts: Bull.JobsOptions,
} {
return {
name,
@@ -299,10 +333,10 @@ export class QueueService {
}
@bindThis
private generateRelationshipJobData(name: 'follow' | 'unfollow' | 'block' | 'unblock', data: RelationshipJobData, opts: Bull.JobOptions = {}): {
private generateRelationshipJobData(name: 'follow' | 'unfollow' | 'block' | 'unblock', data: RelationshipJobData, opts: Bull.JobsOptions = {}): {
name: string,
data: RelationshipJobData,
opts: Bull.JobOptions,
opts: Bull.JobsOptions,
} {
return {
name,
@@ -351,11 +385,10 @@ export class QueueService {
eventId: uuid(),
};
return this.webhookDeliverQueue.add(data, {
return this.webhookDeliverQueue.add(webhook.id, data, {
attempts: 4,
timeout: 1 * 60 * 1000, // 1min
backoff: {
type: 'apBackoff',
type: 'custom',
},
removeOnComplete: true,
removeOnFail: true,
@@ -367,11 +400,11 @@ export class QueueService {
this.deliverQueue.once('cleaned', (jobs, status) => {
//deliverLogger.succ(`Cleaned ${jobs.length} ${status} jobs`);
});
this.deliverQueue.clean(0, 'delayed');
this.deliverQueue.clean(0, 0, 'delayed');
this.inboxQueue.once('cleaned', (jobs, status) => {
//inboxLogger.succ(`Cleaned ${jobs.length} ${status} jobs`);
});
this.inboxQueue.clean(0, 'delayed');
this.inboxQueue.clean(0, 0, 'delayed');
}
}

View File

@@ -8,12 +8,12 @@ import { DI } from '@/di-symbols.js';
import { bindThis } from '@/decorators.js';
import { MetaService } from '@/core/MetaService.js';
import { CacheService } from '@/core/CacheService.js';
import type { RoleCondFormulaValue } from '@/models/entities/Role.js';
import type { RoleCondFormulaValue } from 'misskey-js/built/schemas/role.js';
import { UserEntityService } from '@/core/entities/UserEntityService.js';
import { StreamMessages } from '@/server/api/stream/types.js';
import { IdService } from '@/core/IdService.js';
import { GlobalEventService } from '@/core/GlobalEventService.js';
import type { Packed } from '@/misc/json-schema';
import type { Packed } from 'misskey-js';
import type { OnApplicationShutdown } from '@nestjs/common';
export type RolePolicies = {
@@ -433,7 +433,13 @@ export class RoleService implements OnApplicationShutdown {
}
@bindThis
public onApplicationShutdown(signal?: string | undefined) {
public dispose(): void {
this.redisForSub.off('message', this.onMessage);
this.roleAssignmentByUserIdCache.dispose();
}
@bindThis
public onApplicationShutdown(signal?: string | undefined): void {
this.dispose();
}
}

View File

@@ -107,7 +107,10 @@ export class UserBlockingService implements OnModuleInit {
if (this.userEntityService.isLocalUser(followee)) {
this.userEntityService.pack(followee, followee, {
detail: true,
}).then(packed => this.globalEventService.publishMainStream(followee.id, 'meUpdated', packed));
}).then(packed => {
this.globalEventService.publishMainStream(followee.id, 'meUpdated', packed);
return packed; // somehow this is needed by typescript
});
}
if (this.userEntityService.isLocalUser(follower) && !silent) {
@@ -122,6 +125,8 @@ export class UserBlockingService implements OnModuleInit {
user: packed,
});
}
return packed; // somehow this is needed by typescript
});
}

View File

@@ -7,7 +7,7 @@ import PerUserFollowingChart from '@/core/chart/charts/per-user-following.js';
import { GlobalEventService } from '@/core/GlobalEventService.js';
import { IdService } from '@/core/IdService.js';
import { isDuplicateKeyValueError } from '@/misc/is-duplicate-key-value-error.js';
import type { Packed } from '@/misc/json-schema.js';
import type { Packed } from 'misskey-js';
import InstanceChart from '@/core/chart/charts/instance.js';
import { FederatedInstanceService } from '@/core/FederatedInstanceService.js';
import { WebhookService } from '@/core/WebhookService.js';
@@ -267,7 +267,7 @@ export class UserFollowingService implements OnModuleInit {
this.userEntityService.pack(followee.id, follower, {
detail: true,
}).then(async packed => {
this.globalEventService.publishMainStream(follower.id, 'follow', packed as Packed<'UserDetailedNotMe'>);
this.globalEventService.publishMainStream(follower.id, 'follow', packed);
const webhooks = (await this.webhookService.getActiveWebhooks()).filter(x => x.userId === follower.id && x.on.includes('follow'));
for (const webhook of webhooks) {

View File

@@ -1,4 +1,4 @@
import { Inject, Injectable } from '@nestjs/common';
import { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common';
import * as Redis from 'ioredis';
import type { User } from '@/models/entities/User.js';
import type { UserKeypairsRepository } from '@/models/index.js';
@@ -8,7 +8,7 @@ import { DI } from '@/di-symbols.js';
import { bindThis } from '@/decorators.js';
@Injectable()
export class UserKeypairService {
export class UserKeypairService implements OnApplicationShutdown {
private cache: RedisKVCache<UserKeypair>;
constructor(
@@ -31,4 +31,14 @@ export class UserKeypairService {
public async getUserKeypair(userId: User['id']): Promise<UserKeypair> {
return await this.cache.fetch(userId);
}
@bindThis
public dispose(): void {
this.cache.dispose();
}
@bindThis
public onApplicationShutdown(signal?: string | undefined): void {
this.dispose();
}
}

View File

@@ -81,7 +81,12 @@ export class WebhookService implements OnApplicationShutdown {
}
@bindThis
public onApplicationShutdown(signal?: string | undefined) {
public dispose(): void {
this.redisForSub.off('message', this.onMessage);
}
@bindThis
public onApplicationShutdown(signal?: string | undefined): void {
this.dispose();
}
}

View File

@@ -1,4 +1,4 @@
import { Inject, Injectable } from '@nestjs/common';
import { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common';
import escapeRegexp from 'escape-regexp';
import { DI } from '@/di-symbols.js';
import type { NotesRepository, UserPublickeysRepository, UsersRepository } from '@/models/index.js';
@@ -30,7 +30,7 @@ export type UriParseResult = {
};
@Injectable()
export class ApDbResolverService {
export class ApDbResolverService implements OnApplicationShutdown {
private publicKeyCache: MemoryKVCache<UserPublickey | null>;
private publicKeyByUserIdCache: MemoryKVCache<UserPublickey | null>;
@@ -162,4 +162,15 @@ export class ApDbResolverService {
key,
};
}
@bindThis
public dispose(): void {
this.publicKeyCache.dispose();
this.publicKeyByUserIdCache.dispose();
}
@bindThis
public onApplicationShutdown(signal?: string | undefined): void {
this.dispose();
}
}

View File

@@ -94,7 +94,7 @@ class LdSignature {
@bindThis
private getLoader() {
return async (url: string): Promise<any> => {
if (!url.match('^https?\:\/\/')) throw `Invalid URL ${url}`;
if (!url.match('^https?\:\/\/')) throw new Error(`Invalid URL ${url}`);
if (this.preLoad) {
if (url in CONTEXTS) {
@@ -126,7 +126,7 @@ class LdSignature {
timeout: this.loderTimeout,
}, { throwErrorWhenResponseNotOk: false }).then(res => {
if (!res.ok) {
throw `${res.status} ${res.statusText}`;
throw new Error(`${res.status} ${res.statusText}`);
} else {
return res.json();
}

View File

@@ -18,6 +18,7 @@ import { PollService } from '@/core/PollService.js';
import { StatusError } from '@/misc/status-error.js';
import { UtilityService } from '@/core/UtilityService.js';
import { bindThis } from '@/decorators.js';
import { checkHttps } from '@/misc/check-https.js';
import { getOneApId, getApId, getOneApHrefNullable, validPost, isEmoji, getApType } from '../type.js';
// eslint-disable-next-line @typescript-eslint/consistent-type-imports
import { ApLoggerService } from '../ApLoggerService.js';
@@ -32,7 +33,6 @@ import { ApQuestionService } from './ApQuestionService.js';
import { ApImageService } from './ApImageService.js';
import type { Resolver } from '../ApResolverService.js';
import type { IObject, IPost } from '../type.js';
import { checkHttps } from '@/misc/check-https.js';
@Injectable()
export class ApNoteService {
@@ -230,7 +230,7 @@ export class ApNoteService {
quote = results.filter((x): x is { status: 'ok', res: Note | null } => x.status === 'ok').map(x => x.res).find(x => x);
if (!quote) {
if (results.some(x => x.status === 'temperror')) {
throw 'quote resolve failed';
throw new Error('quote resolve failed');
}
}
}
@@ -311,7 +311,7 @@ export class ApNoteService {
// ブロックしてたら中断
const meta = await this.metaService.fetch();
if (this.utilityService.isBlockedHost(meta.blockedHosts, this.utilityService.extractDbHost(uri))) throw { statusCode: 451 };
if (this.utilityService.isBlockedHost(meta.blockedHosts, this.utilityService.extractDbHost(uri))) throw new StatusError('blocked host', 451);
const unlock = await this.appLockService.getApLock(uri);

View File

@@ -60,7 +60,8 @@ export class ChartManagementService implements OnApplicationShutdown {
}, 1000 * 60 * 20);
}
async onApplicationShutdown(signal: string): Promise<void> {
@bindThis
public async dispose(): Promise<void> {
clearInterval(this.saveIntervalId);
if (process.env.NODE_ENV !== 'test') {
await Promise.all(
@@ -68,4 +69,9 @@ export class ChartManagementService implements OnApplicationShutdown {
);
}
}
@bindThis
async onApplicationShutdown(signal: string): Promise<void> {
await this.dispose();
}
}

View File

@@ -1,17 +1,7 @@
import Chart from '../../core.js';
export const name = 'activeUsers';
export const schema = {
'readWrite': { intersection: ['read', 'write'] },
'read': { uniqueIncrement: true },
'write': { uniqueIncrement: true },
'registeredWithinWeek': { uniqueIncrement: true },
'registeredWithinMonth': { uniqueIncrement: true },
'registeredWithinYear': { uniqueIncrement: true },
'registeredOutsideWeek': { uniqueIncrement: true },
'registeredOutsideMonth': { uniqueIncrement: true },
'registeredOutsideYear': { uniqueIncrement: true },
} as const;
import { chartsSchemas } from 'misskey-js/built/schemas/charts.js';
export const name = 'activeUsers' as const;
export const schema = chartsSchemas[name];
export const entity = Chart.schemaToEntity(name, schema);

View File

@@ -1,11 +1,7 @@
import Chart from '../../core.js';
export const name = 'apRequest';
export const schema = {
'deliverFailed': { },
'deliverSucceeded': { },
'inboxReceived': { },
} as const;
import { chartsSchemas } from 'misskey-js/built/schemas/charts.js';
export const name = 'apRequest' as const;
export const schema = chartsSchemas[name];
export const entity = Chart.schemaToEntity(name, schema);

View File

@@ -1,16 +1,7 @@
import Chart from '../../core.js';
export const name = 'drive';
export const schema = {
'local.incCount': {},
'local.incSize': {}, // in kilobyte
'local.decCount': {},
'local.decSize': {}, // in kilobyte
'remote.incCount': {},
'remote.incSize': {}, // in kilobyte
'remote.decCount': {},
'remote.decSize': {}, // in kilobyte
} as const;
import { chartsSchemas } from 'misskey-js/built/schemas/charts.js';
export const name = 'drive' as const;
export const schema = chartsSchemas[name];
export const entity = Chart.schemaToEntity(name, schema);

View File

@@ -1,16 +1,7 @@
import Chart from '../../core.js';
export const name = 'federation';
export const schema = {
'deliveredInstances': { uniqueIncrement: true, range: 'small' },
'inboxInstances': { uniqueIncrement: true, range: 'small' },
'stalled': { uniqueIncrement: true, range: 'small' },
'sub': { accumulate: true, range: 'small' },
'pub': { accumulate: true, range: 'small' },
'pubsub': { accumulate: true, range: 'small' },
'subActive': { accumulate: true, range: 'small' },
'pubActive': { accumulate: true, range: 'small' },
} as const;
import { chartsSchemas } from 'misskey-js/built/schemas/charts.js';
export const name = 'federation' as const;
export const schema = chartsSchemas[name];
export const entity = Chart.schemaToEntity(name, schema);

View File

@@ -1,32 +1,7 @@
import Chart from '../../core.js';
export const name = 'instance';
export const schema = {
'requests.failed': { range: 'small' },
'requests.succeeded': { range: 'small' },
'requests.received': { range: 'small' },
'notes.total': { accumulate: true },
'notes.inc': {},
'notes.dec': {},
'notes.diffs.normal': {},
'notes.diffs.reply': {},
'notes.diffs.renote': {},
'notes.diffs.withFile': {},
'users.total': { accumulate: true },
'users.inc': { range: 'small' },
'users.dec': { range: 'small' },
'following.total': { accumulate: true },
'following.inc': { range: 'small' },
'following.dec': { range: 'small' },
'followers.total': { accumulate: true },
'followers.inc': { range: 'small' },
'followers.dec': { range: 'small' },
'drive.totalFiles': { accumulate: true },
'drive.incFiles': {},
'drive.decFiles': {},
'drive.incUsage': {}, // in kilobyte
'drive.decUsage': {}, // in kilobyte
} as const;
import { chartsSchemas } from 'misskey-js/built/schemas/charts.js';
export const name = 'instance' as const;
export const schema = chartsSchemas[name];
export const entity = Chart.schemaToEntity(name, schema, true);

View File

@@ -1,22 +1,7 @@
import Chart from '../../core.js';
export const name = 'notes';
export const schema = {
'local.total': { accumulate: true },
'local.inc': {},
'local.dec': {},
'local.diffs.normal': {},
'local.diffs.reply': {},
'local.diffs.renote': {},
'local.diffs.withFile': {},
'remote.total': { accumulate: true },
'remote.inc': {},
'remote.dec': {},
'remote.diffs.normal': {},
'remote.diffs.reply': {},
'remote.diffs.renote': {},
'remote.diffs.withFile': {},
} as const;
import { chartsSchemas } from 'misskey-js/built/schemas/charts.js';
export const name = 'notes' as const;
export const schema = chartsSchemas[name];
export const entity = Chart.schemaToEntity(name, schema);

View File

@@ -1,14 +1,7 @@
import Chart from '../../core.js';
export const name = 'perUserDrive';
export const schema = {
'totalCount': { accumulate: true },
'totalSize': { accumulate: true }, // in kilobyte
'incCount': { range: 'small' },
'incSize': {}, // in kilobyte
'decCount': { range: 'small' },
'decSize': {}, // in kilobyte
} as const;
import { chartsSchemas } from 'misskey-js/built/schemas/charts.js';
export const name = 'perUserDrive' as const;
export const schema = chartsSchemas[name];
export const entity = Chart.schemaToEntity(name, schema, true);

View File

@@ -1,20 +1,7 @@
import Chart from '../../core.js';
export const name = 'perUserFollowing';
export const schema = {
'local.followings.total': { accumulate: true },
'local.followings.inc': { range: 'small' },
'local.followings.dec': { range: 'small' },
'local.followers.total': { accumulate: true },
'local.followers.inc': { range: 'small' },
'local.followers.dec': { range: 'small' },
'remote.followings.total': { accumulate: true },
'remote.followings.inc': { range: 'small' },
'remote.followings.dec': { range: 'small' },
'remote.followers.total': { accumulate: true },
'remote.followers.inc': { range: 'small' },
'remote.followers.dec': { range: 'small' },
} as const;
import { chartsSchemas } from 'misskey-js/built/schemas/charts.js';
export const name = 'perUserFollowing' as const;
export const schema = chartsSchemas[name];
export const entity = Chart.schemaToEntity(name, schema, true);

View File

@@ -1,15 +1,7 @@
import Chart from '../../core.js';
export const name = 'perUserNotes';
export const schema = {
'total': { accumulate: true },
'inc': { range: 'small' },
'dec': { range: 'small' },
'diffs.normal': { range: 'small' },
'diffs.reply': { range: 'small' },
'diffs.renote': { range: 'small' },
'diffs.withFile': { range: 'small' },
} as const;
import { chartsSchemas } from 'misskey-js/built/schemas/charts.js';
export const name = 'perUserNotes' as const;
export const schema = chartsSchemas[name];
export const entity = Chart.schemaToEntity(name, schema, true);

View File

@@ -1,12 +1,7 @@
import Chart from '../../core.js';
export const name = 'perUserPv';
export const schema = {
'upv.user': { uniqueIncrement: true, range: 'small' },
'pv.user': { range: 'small' },
'upv.visitor': { uniqueIncrement: true, range: 'small' },
'pv.visitor': { range: 'small' },
} as const;
import { chartsSchemas } from 'misskey-js/built/schemas/charts.js';
export const name = 'perUserPv' as const;
export const schema = chartsSchemas[name];
export const entity = Chart.schemaToEntity(name, schema, true);

View File

@@ -1,10 +1,7 @@
import Chart from '../../core.js';
export const name = 'perUserReaction';
export const schema = {
'local.count': { range: 'small' },
'remote.count': { range: 'small' },
} as const;
import { chartsSchemas } from 'misskey-js/built/schemas/charts.js';
export const name = 'perUserReactions' as const;
export const schema = chartsSchemas[name];
export const entity = Chart.schemaToEntity(name, schema, true);

View File

@@ -1,11 +1,7 @@
import Chart from '../../core.js';
import { chartsSchemas } from 'misskey-js/built/schemas/charts.js';
export const name = 'testGrouped';
export const schema = {
'foo.total': { accumulate: true },
'foo.inc': {},
'foo.dec': {},
} as const;
export const schema = chartsSchemas[name];
export const entity = Chart.schemaToEntity(name, schema, true);

View File

@@ -1,11 +1,7 @@
import Chart from '../../core.js';
import { chartsSchemas } from 'misskey-js/built/schemas/charts.js';
export const name = 'testIntersection';
export const schema = {
'a': { uniqueIncrement: true },
'b': { uniqueIncrement: true },
'aAndB': { intersection: ['a', 'b'] },
} as const;
export const schema = chartsSchemas[name];
export const entity = Chart.schemaToEntity(name, schema);

View File

@@ -1,9 +1,7 @@
import Chart from '../../core.js';
import { chartsSchemas } from 'misskey-js/built/schemas/charts.js';
export const name = 'testUnique';
export const schema = {
'foo': { uniqueIncrement: true },
} as const;
export const schema = chartsSchemas[name];
export const entity = Chart.schemaToEntity(name, schema);

View File

@@ -1,11 +1,7 @@
import Chart from '../../core.js';
import { chartsSchemas } from 'misskey-js/built/schemas/charts.js';
export const name = 'test';
export const schema = {
'foo.total': { accumulate: true },
'foo.inc': {},
'foo.dec': {},
} as const;
export const schema = chartsSchemas[name];
export const entity = Chart.schemaToEntity(name, schema);

View File

@@ -1,14 +1,7 @@
import Chart from '../../core.js';
import { chartsSchemas } from 'misskey-js/built/schemas/charts.js';
export const name = 'users';
export const schema = {
'local.total': { accumulate: true },
'local.inc': { range: 'small' },
'local.dec': { range: 'small' },
'remote.total': { accumulate: true },
'remote.inc': { range: 'small' },
'remote.dec': { range: 'small' },
} as const;
export const schema = chartsSchemas[name];
export const entity = Chart.schemaToEntity(name, schema);

View File

@@ -10,22 +10,12 @@ import { dateUTC, isTimeSame, isTimeBefore, subtractTime, addTime } from '@/misc
import type Logger from '@/logger.js';
import { bindThis } from '@/decorators.js';
import type { Repository, DataSource } from 'typeorm';
import type { ChartSchema as Schema, ChartResult, Unflatten } from 'misskey-js/built/schemas';
const COLUMN_PREFIX = '___' as const;
const UNIQUE_TEMP_COLUMN_PREFIX = 'unique_temp___' as const;
const COLUMN_DELIMITER = '_' as const;
type Schema = Record<string, {
uniqueIncrement?: boolean;
intersection?: string[] | ReadonlyArray<string>;
range?: 'big' | 'small' | 'medium';
// previousな値を引き継ぐかどうか
accumulate?: boolean;
}>;
type KeyToColumnName<T extends string> = T extends `${infer R1}.${infer R2}` ? `${R1}${typeof COLUMN_DELIMITER}${KeyToColumnName<R2>}` : T;
type Columns<S extends Schema> = {
@@ -64,47 +54,6 @@ export type KVs<S extends Schema> = {
[K in keyof S]: number;
};
type ChartResult<T extends Schema> = {
[P in keyof T]: number[];
};
type UnionToIntersection<T> = (T extends any ? (x: T) => any : never) extends (x: infer R) => any ? R : never;
type UnflattenSingleton<K extends string, V> = K extends `${infer A}.${infer B}`
? { [_ in A]: UnflattenSingleton<B, V>; }
: { [_ in K]: V; };
type Unflatten<T extends Record<string, any>> = UnionToIntersection<
{
[K in Extract<keyof T, string>]: UnflattenSingleton<K, T[K]>;
}[Extract<keyof T, string>]
>;
type ToJsonSchema<S> = {
type: 'object';
properties: {
[K in keyof S]: S[K] extends number[] ? { type: 'array'; items: { type: 'number'; }; } : ToJsonSchema<S[K]>;
},
required: (keyof S)[];
};
export function getJsonSchema<S extends Schema>(schema: S): ToJsonSchema<Unflatten<ChartResult<S>>> {
const jsonSchema = {
type: 'object',
properties: {} as Record<string, unknown>,
required: [],
};
for (const k in schema) {
jsonSchema.properties[k] = {
type: 'array',
items: { type: 'number' },
};
}
return jsonSchema as ToJsonSchema<Unflatten<ChartResult<S>>>;
}
/**
* 様々なチャートの管理を司るクラス
*/

View File

@@ -5,6 +5,7 @@ import { awaitAll } from '@/misc/prelude/await-all.js';
import type { AbuseUserReport } from '@/models/entities/AbuseUserReport.js';
import { UserEntityService } from './UserEntityService.js';
import { bindThis } from '@/decorators.js';
import type { Packed } from 'misskey-js';
@Injectable()
export class AbuseUserReportEntityService {
@@ -19,7 +20,7 @@ export class AbuseUserReportEntityService {
@bindThis
public async pack(
src: AbuseUserReport['id'] | AbuseUserReport,
) {
): Promise<Packed<'AbuseUserReport'>> {
const report = typeof src === 'object' ? src : await this.abuseUserReportsRepository.findOneByOrFail({ id: src });
return await awaitAll({
@@ -46,7 +47,7 @@ export class AbuseUserReportEntityService {
@bindThis
public packMany(
reports: any[],
) {
): Promise<Packed<'AbuseUserReport'>[]> {
return Promise.all(reports.map(x => this.pack(x)));
}
}

View File

@@ -1,7 +1,7 @@
import { Inject, Injectable } from '@nestjs/common';
import { DI } from '@/di-symbols.js';
import type { AntennasRepository } from '@/models/index.js';
import type { Packed } from '@/misc/json-schema.js';
import type { Packed } from 'misskey-js';
import type { Antenna } from '@/models/entities/Antenna.js';
import { bindThis } from '@/decorators.js';

View File

@@ -1,7 +1,7 @@
import { Inject, Injectable } from '@nestjs/common';
import { DI } from '@/di-symbols.js';
import type { AccessTokensRepository, AppsRepository } from '@/models/index.js';
import type { Packed } from '@/misc/json-schema.js';
import type { Packed } from 'misskey-js';
import type { App } from '@/models/entities/App.js';
import type { User } from '@/models/entities/User.js';
import { bindThis } from '@/decorators.js';

View File

@@ -6,6 +6,7 @@ import type { AuthSession } from '@/models/entities/AuthSession.js';
import type { User } from '@/models/entities/User.js';
import { AppEntityService } from './AppEntityService.js';
import { bindThis } from '@/decorators.js';
import type { Packed } from 'misskey-js';
@Injectable()
export class AuthSessionEntityService {
@@ -21,7 +22,7 @@ export class AuthSessionEntityService {
public async pack(
src: AuthSession['id'] | AuthSession,
me?: { id: User['id'] } | null | undefined,
) {
): Promise<Packed<'AuthSession'>> {
const session = typeof src === 'object' ? src : await this.authSessionsRepository.findOneByOrFail({ id: src });
return await awaitAll({

View File

@@ -2,11 +2,12 @@ import { Inject, Injectable } from '@nestjs/common';
import { DI } from '@/di-symbols.js';
import type { BlockingsRepository } from '@/models/index.js';
import { awaitAll } from '@/misc/prelude/await-all.js';
import type { Packed } from '@/misc/json-schema.js';
import type { Packed } from 'misskey-js';
import type { Blocking } from '@/models/entities/Blocking.js';
import type { User } from '@/models/entities/User.js';
import { bindThis } from '@/decorators.js';
import { UserEntityService } from './UserEntityService.js';
import type { Serialized } from 'schema-type';
@Injectable()
export class BlockingEntityService {
@@ -39,7 +40,7 @@ export class BlockingEntityService {
public packMany(
blockings: any[],
me: { id: User['id'] },
) {
): Promise<Packed<'Blocking'>[]> {
return Promise.all(blockings.map(x => this.pack(x, me)));
}
}

View File

@@ -1,8 +1,7 @@
import { Inject, Injectable } from '@nestjs/common';
import { DI } from '@/di-symbols.js';
import type { ChannelFavoritesRepository, ChannelFollowingsRepository, ChannelsRepository, DriveFilesRepository, NoteUnreadsRepository, NotesRepository } from '@/models/index.js';
import type { Packed } from '@/misc/json-schema.js';
import type { } from '@/models/entities/Blocking.js';
import type { Packed } from 'misskey-js';
import type { User } from '@/models/entities/User.js';
import type { Channel } from '@/models/entities/Channel.js';
import { bindThis } from '@/decorators.js';

View File

@@ -2,8 +2,7 @@ import { Inject, Injectable } from '@nestjs/common';
import { DI } from '@/di-symbols.js';
import type { ClipFavoritesRepository, ClipsRepository, User } from '@/models/index.js';
import { awaitAll } from '@/misc/prelude/await-all.js';
import type { Packed } from '@/misc/json-schema.js';
import type { } from '@/models/entities/Blocking.js';
import type { Packed } from 'misskey-js';
import type { Clip } from '@/models/entities/Clip.js';
import { bindThis } from '@/decorators.js';
import { UserEntityService } from './UserEntityService.js';
@@ -47,7 +46,7 @@ export class ClipEntityService {
public packMany(
clips: Clip[],
me?: { id: User['id'] } | null | undefined,
) {
): Promise<Packed<'Clip'>[]> {
return Promise.all(clips.map(x => this.pack(x, me)));
}
}

View File

@@ -3,7 +3,7 @@ import { DataSource, In } from 'typeorm';
import { DI } from '@/di-symbols.js';
import type { NotesRepository, DriveFilesRepository } from '@/models/index.js';
import type { Config } from '@/config.js';
import type { Packed } from '@/misc/json-schema.js';
import type { Packed } from 'misskey-js';
import { awaitAll } from '@/misc/prelude/await-all.js';
import type { User } from '@/models/entities/User.js';
import type { DriveFile } from '@/models/entities/DriveFile.js';
@@ -265,11 +265,11 @@ export class DriveFileEntityService {
public async packManyByIdsMap(
fileIds: DriveFile['id'][],
options?: PackOptions,
): Promise<Map<Packed<'DriveFile'>['id'], Packed<'DriveFile'> | null>> {
): Promise<Map<Packed<'DriveFile'>>['id'], Serialized<Packed<'DriveFile'> | null>> {
if (fileIds.length === 0) return new Map();
const files = await this.driveFilesRepository.findBy({ id: In(fileIds) });
const packedFiles = await this.packMany(files, options);
const map = new Map<Packed<'DriveFile'>['id'], Packed<'DriveFile'> | null>(packedFiles.map(f => [f.id, f]));
const map = new Map<Packed<'DriveFile'>>['id'], Serialized<Packed<'DriveFile'> | null>(packedFiles.map(f => [f.id, f]));
for (const id of fileIds) {
if (!map.has(id)) map.set(id, null);
}

View File

@@ -2,8 +2,7 @@ import { Inject, Injectable } from '@nestjs/common';
import { DI } from '@/di-symbols.js';
import type { DriveFilesRepository, DriveFoldersRepository } from '@/models/index.js';
import { awaitAll } from '@/misc/prelude/await-all.js';
import type { Packed } from '@/misc/json-schema.js';
import type { } from '@/models/entities/Blocking.js';
import type { Packed } from 'misskey-js';
import type { DriveFolder } from '@/models/entities/DriveFolder.js';
import { bindThis } from '@/decorators.js';

View File

@@ -1,8 +1,7 @@
import { Inject, Injectable } from '@nestjs/common';
import { DI } from '@/di-symbols.js';
import type { EmojisRepository } from '@/models/index.js';
import type { Packed } from '@/misc/json-schema.js';
import type { } from '@/models/entities/Blocking.js';
import type { Packed } from 'misskey-js';
import type { Emoji } from '@/models/entities/Emoji.js';
import { bindThis } from '@/decorators.js';

View File

@@ -2,8 +2,7 @@ import { Inject, Injectable } from '@nestjs/common';
import { DI } from '@/di-symbols.js';
import type { FlashsRepository, FlashLikesRepository } from '@/models/index.js';
import { awaitAll } from '@/misc/prelude/await-all.js';
import type { Packed } from '@/misc/json-schema.js';
import type { } from '@/models/entities/Blocking.js';
import type { Packed } from 'misskey-js';
import type { User } from '@/models/entities/User.js';
import type { Flash } from '@/models/entities/Flash.js';
import { bindThis } from '@/decorators.js';

View File

@@ -1,7 +1,6 @@
import { Inject, Injectable } from '@nestjs/common';
import { DI } from '@/di-symbols.js';
import type { FlashLikesRepository } from '@/models/index.js';
import type { } from '@/models/entities/Blocking.js';
import type { User } from '@/models/entities/User.js';
import type { FlashLike } from '@/models/entities/FlashLike.js';
import { bindThis } from '@/decorators.js';

View File

@@ -1,11 +1,11 @@
import { Inject, Injectable } from '@nestjs/common';
import { DI } from '@/di-symbols.js';
import type { FollowRequestsRepository } from '@/models/index.js';
import type { } from '@/models/entities/Blocking.js';
import type { User } from '@/models/entities/User.js';
import type { FollowRequest } from '@/models/entities/FollowRequest.js';
import { UserEntityService } from './UserEntityService.js';
import { bindThis } from '@/decorators.js';
import { Packed } from 'misskey-js';
@Injectable()
export class FollowRequestEntityService {
@@ -21,7 +21,7 @@ export class FollowRequestEntityService {
public async pack(
src: FollowRequest['id'] | FollowRequest,
me?: { id: User['id'] } | null | undefined,
) {
): Promise<Packed<'FollowRequest'>> {
const request = typeof src === 'object' ? src : await this.followRequestsRepository.findOneByOrFail({ id: src });
return {

View File

@@ -2,8 +2,7 @@ import { Inject, Injectable } from '@nestjs/common';
import { DI } from '@/di-symbols.js';
import type { FollowingsRepository } from '@/models/index.js';
import { awaitAll } from '@/misc/prelude/await-all.js';
import type { Packed } from '@/misc/json-schema.js';
import type { } from '@/models/entities/Blocking.js';
import type { Packed } from 'misskey-js';
import type { User } from '@/models/entities/User.js';
import type { Following } from '@/models/entities/Following.js';
import { bindThis } from '@/decorators.js';

View File

@@ -1,7 +1,6 @@
import { Inject, Injectable } from '@nestjs/common';
import { DI } from '@/di-symbols.js';
import type { GalleryLikesRepository } from '@/models/index.js';
import type { } from '@/models/entities/Blocking.js';
import type { GalleryLike } from '@/models/entities/GalleryLike.js';
import { GalleryPostEntityService } from './GalleryPostEntityService.js';
import { bindThis } from '@/decorators.js';

View File

@@ -2,8 +2,7 @@ import { Inject, Injectable } from '@nestjs/common';
import { DI } from '@/di-symbols.js';
import type { GalleryLikesRepository, GalleryPostsRepository } from '@/models/index.js';
import { awaitAll } from '@/misc/prelude/await-all.js';
import type { Packed } from '@/misc/json-schema.js';
import type { } from '@/models/entities/Blocking.js';
import type { Packed } from 'misskey-js';
import type { User } from '@/models/entities/User.js';
import type { GalleryPost } from '@/models/entities/GalleryPost.js';
import { bindThis } from '@/decorators.js';

View File

@@ -1,8 +1,7 @@
import { Inject, Injectable } from '@nestjs/common';
import { DI } from '@/di-symbols.js';
import type { HashtagsRepository } from '@/models/index.js';
import type { Packed } from '@/misc/json-schema.js';
import type { } from '@/models/entities/Blocking.js';
import type { Packed } from 'misskey-js';
import type { Hashtag } from '@/models/entities/Hashtag.js';
import { bindThis } from '@/decorators.js';
import { UserEntityService } from './UserEntityService.js';

View File

@@ -1,8 +1,7 @@
import { Inject, Injectable } from '@nestjs/common';
import { DI } from '@/di-symbols.js';
import type { InstancesRepository } from '@/models/index.js';
import type { Packed } from '@/misc/json-schema.js';
import type { } from '@/models/entities/Blocking.js';
import type { Packed } from 'misskey-js';
import type { Instance } from '@/models/entities/Instance.js';
import { MetaService } from '@/core/MetaService.js';
import { bindThis } from '@/decorators.js';

View File

@@ -2,10 +2,10 @@ import { Inject, Injectable } from '@nestjs/common';
import { DI } from '@/di-symbols.js';
import type { ModerationLogsRepository } from '@/models/index.js';
import { awaitAll } from '@/misc/prelude/await-all.js';
import type { } from '@/models/entities/Blocking.js';
import type { ModerationLog } from '@/models/entities/ModerationLog.js';
import { UserEntityService } from './UserEntityService.js';
import { bindThis } from '@/decorators.js';
import type { Packed } from 'misskey-js';
@Injectable()
export class ModerationLogEntityService {
@@ -20,7 +20,7 @@ export class ModerationLogEntityService {
@bindThis
public async pack(
src: ModerationLog['id'] | ModerationLog,
) {
): Promise<Packed<'ModerationLog'>> {
const log = typeof src === 'object' ? src : await this.moderationLogsRepository.findOneByOrFail({ id: src });
return await awaitAll({
@@ -38,8 +38,7 @@ export class ModerationLogEntityService {
@bindThis
public packMany(
reports: any[],
) {
): Promise<Packed<'ModerationLog'>[]> {
return Promise.all(reports.map(x => this.pack(x)));
}
}

View File

@@ -2,8 +2,7 @@ import { Inject, Injectable } from '@nestjs/common';
import { DI } from '@/di-symbols.js';
import type { MutingsRepository } from '@/models/index.js';
import { awaitAll } from '@/misc/prelude/await-all.js';
import type { Packed } from '@/misc/json-schema.js';
import type { } from '@/models/entities/Blocking.js';
import type { Packed } from 'misskey-js';
import type { User } from '@/models/entities/User.js';
import type { Muting } from '@/models/entities/Muting.js';
import { bindThis } from '@/decorators.js';

View File

@@ -3,7 +3,7 @@ import { DataSource, In } from 'typeorm';
import * as mfm from 'mfm-js';
import { ModuleRef } from '@nestjs/core';
import { DI } from '@/di-symbols.js';
import type { Packed } from '@/misc/json-schema.js';
import type { Packed } from 'misskey-js';
import { nyaize } from '@/misc/nyaize.js';
import { awaitAll } from '@/misc/prelude/await-all.js';
import type { User } from '@/models/entities/User.js';

View File

@@ -1,7 +1,7 @@
import { Inject, Injectable } from '@nestjs/common';
import { DI } from '@/di-symbols.js';
import type { NoteFavoritesRepository } from '@/models/index.js';
import type { } from '@/models/entities/Blocking.js';
import type { Packed } from 'misskey-js';
import type { User } from '@/models/entities/User.js';
import type { NoteFavorite } from '@/models/entities/NoteFavorite.js';
import { NoteEntityService } from './NoteEntityService.js';
@@ -21,7 +21,7 @@ export class NoteFavoriteEntityService {
public async pack(
src: NoteFavorite['id'] | NoteFavorite,
me?: { id: User['id'] } | null | undefined,
) {
): Promise<Packed<'NoteFavorite'>> {
const favorite = typeof src === 'object' ? src : await this.noteFavoritesRepository.findOneByOrFail({ id: src });
return {

View File

@@ -1,10 +1,9 @@
import { Inject, Injectable } from '@nestjs/common';
import { DI } from '@/di-symbols.js';
import type { NoteReactionsRepository } from '@/models/index.js';
import type { Packed } from '@/misc/json-schema.js';
import type { Packed } from 'misskey-js';
import { bindThis } from '@/decorators.js';
import type { OnModuleInit } from '@nestjs/common';
import type { } from '@/models/entities/Blocking.js';
import type { User } from '@/models/entities/User.js';
import type { NoteReaction } from '@/models/entities/NoteReaction.js';
import type { ReactionService } from '../ReactionService.js';

View File

@@ -6,10 +6,10 @@ import type { AccessTokensRepository, FollowRequestsRepository, NoteReactionsRep
import { awaitAll } from '@/misc/prelude/await-all.js';
import type { Notification } from '@/models/entities/Notification.js';
import type { Note } from '@/models/entities/Note.js';
import type { Packed } from '@/misc/json-schema.js';
import type { Packed } from 'misskey-js';
import { bindThis } from '@/decorators.js';
import { isNotNull } from '@/misc/is-not-null.js';
import { notificationTypes } from '@/types.js';
import { notificationTypes } from 'misskey-js';
import type { OnModuleInit } from '@nestjs/common';
import type { CustomEmojiService } from '../CustomEmojiService.js';
import type { UserEntityService } from './UserEntityService.js';

View File

@@ -2,8 +2,7 @@ import { Inject, Injectable } from '@nestjs/common';
import { DI } from '@/di-symbols.js';
import type { DriveFilesRepository, PagesRepository, PageLikesRepository } from '@/models/index.js';
import { awaitAll } from '@/misc/prelude/await-all.js';
import type { Packed } from '@/misc/json-schema.js';
import type { } from '@/models/entities/Blocking.js';
import type { Packed } from 'misskey-js';
import type { User } from '@/models/entities/User.js';
import type { Page } from '@/models/entities/Page.js';
import type { DriveFile } from '@/models/entities/DriveFile.js';

View File

@@ -1,7 +1,6 @@
import { Inject, Injectable } from '@nestjs/common';
import { DI } from '@/di-symbols.js';
import type { PageLikesRepository } from '@/models/index.js';
import type { } from '@/models/entities/Blocking.js';
import type { User } from '@/models/entities/User.js';
import type { PageLike } from '@/models/entities/PageLike.js';
import { PageEntityService } from './PageEntityService.js';

View File

@@ -2,8 +2,7 @@ import { Inject, Injectable } from '@nestjs/common';
import { DI } from '@/di-symbols.js';
import type { RenoteMutingsRepository } from '@/models/index.js';
import { awaitAll } from '@/misc/prelude/await-all.js';
import type { Packed } from '@/misc/json-schema.js';
import type { } from '@/models/entities/Blocking.js';
import type { Packed } from 'misskey-js';
import type { User } from '@/models/entities/User.js';
import type { RenoteMuting } from '@/models/entities/RenoteMuting.js';
import { bindThis } from '@/decorators.js';

View File

@@ -8,6 +8,7 @@ import type { Role } from '@/models/entities/Role.js';
import { bindThis } from '@/decorators.js';
import { DEFAULT_POLICIES } from '@/core/RoleService.js';
import { UserEntityService } from './UserEntityService.js';
import type { Packed } from 'misskey-js';
@Injectable()
export class RoleEntityService {
@@ -26,7 +27,7 @@ export class RoleEntityService {
public async pack(
src: Role['id'] | Role,
me?: { id: User['id'] } | null | undefined,
) {
): Promise<Packed<'Role'>> {
const role = typeof src === 'object' ? src : await this.rolesRepository.findOneByOrFail({ id: src });
const assignedCount = await this.roleAssignmentsRepository.createQueryBuilder('assign')
@@ -37,7 +38,7 @@ export class RoleEntityService {
}))
.getCount();
const policies = { ...role.policies };
const policies: { [x: string]: Packed<'RolePolicy'> } = { ...role.policies };
for (const [k, v] of Object.entries(DEFAULT_POLICIES)) {
if (policies[k] == null) policies[k] = {
useDefault: true,
@@ -72,8 +73,7 @@ export class RoleEntityService {
public packMany(
roles: any[],
me: { id: User['id'] },
) {
): Promise<Packed<'Role'>[]> {
return Promise.all(roles.map(x => this.pack(x, me)));
}
}

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