Compare commits

...

171 Commits

Author SHA1 Message Date
syuilo
8cc80faf20 13.0.0-beta.35 2023-01-09 16:27:27 +09:00
syuilo
4d66077f85 Update MkEmojiPicker.vue 2023-01-09 16:27:09 +09:00
syuilo
3ece2dc990 13.0.0-beta.34 2023-01-09 16:16:25 +09:00
syuilo
6071e962f4 Revert "Update vite.config.ts"
This reverts commit c438bd2e27.
2023-01-09 16:16:00 +09:00
syuilo
ed43369797 Update CHANGELOG.md 2023-01-09 16:09:40 +09:00
syuilo
c65957853b 13.0.0-beta.33 2023-01-09 16:08:25 +09:00
syuilo
6a18360269 update mfm-js 2023-01-09 16:07:14 +09:00
syuilo
c438bd2e27 Update vite.config.ts 2023-01-09 15:51:36 +09:00
syuilo
462acc9eee カスタム絵文字一覧情報をmetaから分離 2023-01-09 15:50:25 +09:00
syuilo
e4144a17a4 fix(server): アンテナタイムライン(ストリーミング)が、フォローしていないユーザーの鍵投稿も拾ってしまう問題を修正
Fix #9025
2023-01-09 14:12:42 +09:00
syuilo
3cfd017538 fix(server): 特定のPNG画像のアップロードに失敗する問題を修正
Co-Authored-By: haru <64310155+usbharu@users.noreply.github.com>
2023-01-09 14:03:22 +09:00
syuilo
403849805a enhance(client): force lazy load some images 2023-01-09 14:00:04 +09:00
syuilo
402b234d15 🎨 2023-01-09 13:56:30 +09:00
syuilo
eba6b326fa 13.0.0-beta.32 2023-01-09 13:45:04 +09:00
syuilo
4c9b93a12f 🎨 2023-01-09 13:39:16 +09:00
syuilo
dfee79f841 🎨
Resolve #9498
2023-01-09 13:32:48 +09:00
syuilo
962373cf06 fix(server): 非公開のクリップのURLでOGPレンダリングされる問題を修正
Fix #9129
2023-01-09 13:26:42 +09:00
syuilo
13aa4b64b4 tweak client 2023-01-09 10:07:37 +09:00
syuilo
5ce56886a1 fix 2023-01-09 09:43:28 +09:00
syuilo
2817ca03f5 Update queue.chart.vue 2023-01-09 09:42:11 +09:00
syuilo
e633c3b84b refactor 2023-01-09 09:41:25 +09:00
syuilo
8524e9d735 tweak client 2023-01-09 09:04:35 +09:00
syuilo
91ced90fb2 fix imports 2023-01-09 08:58:16 +09:00
syuilo
2acb3917ba Merge branch 'develop' of https://github.com/misskey-dev/misskey into develop 2023-01-09 08:46:10 +09:00
syuilo
dd78ac089c 🍪 2023-01-08 20:42:45 +09:00
MeiMei
10e526ba56 fix: Escape SQL LIKE (#9493)
* SQL LIKE escape

* CHANGELOG
2023-01-08 20:32:17 +09:00
syuilo
7ed905f76b 🍪 cps 2023-01-08 20:30:19 +09:00
syuilo
5d13e2744f 🎨 2023-01-08 20:21:32 +09:00
syuilo
1d7e0293a8 fix following chart 2023-01-08 20:02:07 +09:00
marihachi
8977d87021 fix typo (#9492) 2023-01-08 19:59:05 +09:00
syuilo
809400ff23 Update CHANGELOG.md 2023-01-08 18:08:43 +09:00
syuilo
4c8dbcc20d 13.0.0-beta.31 2023-01-08 17:44:24 +09:00
syuilo
416dcf884d 🎨 2023-01-08 17:42:51 +09:00
syuilo
09d3ce444a Merge branch 'develop' of https://github.com/misskey-dev/misskey into develop 2023-01-08 17:41:12 +09:00
syuilo
27c2ca5048 feat(client): 🍪👈 2023-01-08 17:41:09 +09:00
syuilo
fceeb1b108 🎨 2023-01-08 17:38:33 +09:00
tamaina
b442c38f41 enhance: Push Notification badges to Tabler Icons (#9406)
* enhance: Push Notification badges to Tabler Icons

* add receiveFollowRequest icon
2023-01-08 16:47:57 +09:00
syuilo
7c2d2676f7 refactor 2023-01-08 16:17:42 +09:00
syuilo
1f6a41cea7 13.0.0-beta.30 2023-01-08 14:30:00 +09:00
syuilo
0d7ee20a77 🎨 2023-01-08 14:29:22 +09:00
syuilo
dcca2350dd 🎨 2023-01-08 14:28:14 +09:00
syuilo
1cfdd4c41a refactor 2023-01-08 14:22:04 +09:00
syuilo
25f4ee7030 Update CHANGELOG.md 2023-01-08 14:19:32 +09:00
syuilo
5320f23017 enhance(client): improve user activity page 2023-01-08 14:17:56 +09:00
syuilo
4ffbbbe6d8 🎨 2023-01-08 13:10:01 +09:00
syuilo
132e45dff4 13.0.0-beta.29 2023-01-08 11:58:00 +09:00
syuilo
01652b72b3 🎨 2023-01-08 11:57:34 +09:00
syuilo
8b1fdb5a3b enhance(client): add theme 2023-01-08 11:55:37 +09:00
syuilo
192add376c fix MkModal animation 2023-01-08 11:47:16 +09:00
syuilo
244ea9593a tweak components 2023-01-08 11:30:40 +09:00
syuilo
f20d7cba74 13.0.0-beta.28 2023-01-08 11:17:02 +09:00
syuilo
a3e282bc75 New Crowdin updates (#9478)
* New translations ja-JP.yml (Thai)

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

* New translations ja-JP.yml (Italian)

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

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Slovak)
2023-01-08 11:16:36 +09:00
syuilo
49a95c34bf Update CHANGELOG.md 2023-01-08 11:16:26 +09:00
Soni L
ecbefce2aa Support remote objects in search (#9479)
* Support remote objects in search

Closes #9428

* Use account instead of localStorage

* Use useRouter instead of mainRouter

Co-authored-by: Chaos <chaoticryptidz@owo.monster>
2023-01-08 11:15:54 +09:00
syuilo
91356b1805 tweak 2023-01-08 11:12:11 +09:00
syuilo
2e2ed1385f delete pollVote notification 2023-01-08 10:54:45 +09:00
syuilo
49f3090edd tweak note componsnt 2023-01-08 10:48:44 +09:00
syuilo
4594fb11de 🎨 2023-01-08 10:32:37 +09:00
syuilo
b93e56d2e5 🎨 2023-01-08 10:24:30 +09:00
syuilo
c550dafb81 tweak note component 2023-01-08 10:20:28 +09:00
syuilo
8709574f3d 🎨 2023-01-08 09:58:35 +09:00
syuilo
1b7043fa79 🎨 2023-01-07 19:57:48 +09:00
syuilo
55ef2393fb 13.0.0-beta.27 2023-01-07 17:44:15 +09:00
syuilo
7769095efb 🎨 2023-01-07 17:39:24 +09:00
syuilo
b8248bdd65 🎨 2023-01-07 17:37:30 +09:00
syuilo
6f4ad581dc 🎨 2023-01-07 17:27:09 +09:00
syuilo
aec94920ab 🎨 2023-01-07 17:20:50 +09:00
syuilo
155ca39063 update aiscript 2023-01-07 17:18:30 +09:00
syuilo
58bfb4dca4 refactor 2023-01-07 15:09:46 +09:00
syuilo
49a0b6c48b fix typo 2023-01-07 15:00:29 +09:00
syuilo
799a653b44 🎨 2023-01-07 15:00:00 +09:00
syuilo
d09e1f4925 refactor 2023-01-07 14:59:54 +09:00
syuilo
cac784af8a fix #9483 2023-01-07 14:44:50 +09:00
syuilo
d7e0ddcbca Merge branch 'develop' of https://github.com/misskey-dev/misskey into develop 2023-01-07 14:33:36 +09:00
syuilo
8c0811a442 🎨 2023-01-07 14:33:33 +09:00
syuilo
bab6f75260 Update CHANGELOG.md 2023-01-07 14:24:33 +09:00
syuilo
54e3fccd87 enhance(server): refactor and tweak emoji proxy 2023-01-07 14:19:25 +09:00
syuilo
6a992b6982 fix chart rendering 2023-01-07 14:10:01 +09:00
syuilo
ecd6fc1db8 🎨 2023-01-07 11:49:04 +09:00
syuilo
d99be6697e enhance(client): donation dialog 2023-01-07 11:49:00 +09:00
syuilo
d2d77b5dc1 Merge branch 'develop' of https://github.com/misskey-dev/misskey into develop 2023-01-07 10:13:07 +09:00
syuilo
91503405b4 refactor(client): typed localStorage 2023-01-07 10:13:02 +09:00
tamaina
c336201084 Merge branch 'develop' of https://github.com/misskey-dev/misskey into develop 2023-01-06 14:01:02 +00:00
tamaina
0f3399753d chore: remove Search from the name of OpenSearch 2023-01-06 14:00:54 +00:00
tamaina
5ec89ea0c3 カスタム絵文字にプロキシを復活 (#9481)
* wip

* Revert "Update ClientServerService.ts"

This reverts commit 88c64ece78.

* Revert "disable custom emoji proxy temporary"

This reverts commit 495d513efd.

* ✌️
2023-01-06 22:34:50 +09:00
syuilo
a42b03c154 13.0.0-beta.26 2023-01-06 20:29:48 +09:00
syuilo
4b181a30da tweak confetti 2023-01-06 20:25:08 +09:00
syuilo
70805e00eb 🎨 2023-01-06 20:19:27 +09:00
syuilo
3551ac328e tweak retention heatmap 2023-01-06 20:01:32 +09:00
syuilo
e36e5df635 chore(client): tweak charts 2023-01-06 20:00:06 +09:00
syuilo
3e7d8b5f17 update deps 2023-01-06 19:59:31 +09:00
syuilo
5846198eee enhance(client): provide THIS_ID and THIS_URL vars to aiscript of flash 2023-01-06 17:19:25 +09:00
syuilo
c14063a921 🎨 2023-01-06 17:07:32 +09:00
syuilo
457670e730 Update MkTime.vue 2023-01-06 16:58:43 +09:00
syuilo
513cef50a2 tweak federation widget 2023-01-06 16:32:34 +09:00
syuilo
88c64ece78 Update ClientServerService.ts 2023-01-06 14:07:34 +09:00
syuilo
a11672d0a5 13.0.0-beta.25 2023-01-06 13:52:14 +09:00
syuilo
46af9515b0 fix style 2023-01-06 13:52:05 +09:00
syuilo
c5cb786054 🎨 2023-01-06 13:50:41 +09:00
syuilo
4d2d6154a3 New Crowdin updates (#9471)
* New translations ja-JP.yml (Romanian)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Arabic)

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Italian)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (Russian)

* New translations ja-JP.yml (Slovak)

* New translations ja-JP.yml (Ukrainian)

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

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

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Vietnamese)

* New translations ja-JP.yml (Indonesian)

* New translations ja-JP.yml (Bengali)

* New translations ja-JP.yml (Thai)

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

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

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Arabic)

* New translations ja-JP.yml (German)

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

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Indonesian)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Swedish)

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

* New translations ja-JP.yml (Arabic)

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

* New translations ja-JP.yml (Italian)

* New translations ja-JP.yml (Italian)
2023-01-06 13:47:34 +09:00
syuilo
495d513efd disable custom emoji proxy temporary
https://github.com/misskey-dev/misskey/pull/9431#issuecomment-1373006446
2023-01-06 13:47:18 +09:00
syuilo
3b617fafdd enhance(client): アップデート時にも花火 2023-01-06 13:43:10 +09:00
syuilo
82c4f694a0 🎨 2023-01-06 13:40:17 +09:00
syuilo
dc5b4a0402 enhance(client): show fireworks when visit user who today is birthday
Resolve #9476
2023-01-06 13:25:49 +09:00
syuilo
6adc0521d8 Update CHANGELOG.md 2023-01-06 12:26:18 +09:00
syuilo
9ac86dacbb Update CHANGELOG.md 2023-01-06 12:13:34 +09:00
syuilo
88f0c10d09 Update CHANGELOG.md 2023-01-06 11:20:09 +09:00
syuilo
4abef6161e 13.0.0-beta.24 2023-01-06 10:47:58 +09:00
syuilo
f6b6f1bc8b 🎨 2023-01-06 10:34:49 +09:00
syuilo
6b2b403d94 Update flash.pug 2023-01-06 10:34:43 +09:00
syuilo
e2ca90b0a1 enhance(server): SSR for flash 2023-01-06 10:20:42 +09:00
syuilo
9aececc921 🎨 2023-01-06 10:11:47 +09:00
syuilo
d25f214a09 🎨 2023-01-06 09:59:17 +09:00
syuilo
aefc8fb7b5 🎨 2023-01-06 09:56:33 +09:00
syuilo
372a17d7f0 refactor 2023-01-06 09:41:14 +09:00
CyberRex
bcc3380cfc fix(backend): Set correct access control of admin/drive/files (#9472) 2023-01-06 08:05:02 +09:00
syuilo
047262ab20 refactor 2023-01-05 21:04:56 +09:00
syuilo
58ae2ccbfa 🎨 2023-01-05 19:50:52 +09:00
syuilo
29f6f5fa5c Update scratchpad.vue 2023-01-05 17:30:21 +09:00
syuilo
8df7530b54 13.0.0-beta.23 2023-01-05 17:27:56 +09:00
tamaina
ded8584fdd miauthのcallback urlをsearchParams.setで作るように (#9470) 2023-01-05 17:18:32 +09:00
syuilo
9734ad42a1 🎨 2023-01-05 17:17:00 +09:00
syuilo
d890383a00 add Ui:C:folder for AiScript 2023-01-05 17:09:36 +09:00
syuilo
1cae688ccb update aiscript 2023-01-05 16:57:49 +09:00
syuilo
6f9aa94e3a fix instance sort 2023-01-05 16:38:12 +09:00
syuilo
df291b00d8 Update CHANGELOG.md 2023-01-05 14:08:21 +09:00
syuilo
5de699e233 13.0.0-beta.22 2023-01-05 14:00:28 +09:00
syuilo
ebe340d510 MisskeyPlay (#9467)
* wip

* wip

* wip

* wip

* wip

* Update ui.ts

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* Update CHANGELOG.md

* wip

* wip

* wip

* wip

* 🎨

* wip

* ✌️
2023-01-05 13:59:48 +09:00
syuilo
5d904b05dd Update CHANGELOG.md 2023-01-05 03:29:50 +09:00
tamaina
b1a75177a0 enhance: RSSウィジェット / RSSティッカーウィジェットをいい感じにする (#9469)
* ✌️

* use useInterval

* ✌️

* rawItems.value.length !== 0

* fix

* https://github.com/misskey-dev/misskey/pull/9469#discussion_r1061763613
2023-01-05 03:28:25 +09:00
syuilo
f51220a5bf 13.0.0-beta.21 2023-01-04 21:23:48 +09:00
syuilo
e1fe06e597 New Crowdin updates (#9458)
* New translations ja-JP.yml (German)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Thai)

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

* New translations ja-JP.yml (Italian)

* New translations ja-JP.yml (Romanian)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Arabic)

* New translations ja-JP.yml (Catalan)

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Italian)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Dutch)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (Portuguese)

* New translations ja-JP.yml (Russian)

* New translations ja-JP.yml (Slovak)

* New translations ja-JP.yml (Swedish)

* New translations ja-JP.yml (Ukrainian)

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

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

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Vietnamese)

* New translations ja-JP.yml (Indonesian)

* New translations ja-JP.yml (Bengali)

* New translations ja-JP.yml (Thai)

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

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Spanish)
2023-01-04 21:22:47 +09:00
tamaina
fa04b7a3c3 Merge branch 'develop' of https://github.com/misskey-dev/misskey into develop 2023-01-04 11:09:15 +00:00
tamaina
e02183bb1b chore: remove unused function (truncateUnreadAntennaNote) 2023-01-04 11:09:05 +00:00
syuilo
9bec87d9a5 Update CHANGELOG.md 2023-01-04 17:54:47 +09:00
syuilo
d306db4ff8 fix(server): pages/likeのエラーIDが重複しているのを修正 2023-01-04 17:41:39 +09:00
syuilo
1ed078d7f9 fix(server): fix pages/update 2023-01-04 17:41:09 +09:00
syuilo
5906de5ca0 🎨 2023-01-04 09:52:49 +09:00
syuilo
697836c17c perf(client): improve MkTime performance 2023-01-04 08:54:54 +09:00
syuilo
c89410cab0 🎨 2023-01-04 08:32:44 +09:00
tamaina
63d8b7986b do yarn cache clean --all in clean-all.js 2023-01-03 14:58:10 +00:00
syuilo
4903af9598 Update CHANGELOG.md 2023-01-03 17:00:15 +09:00
syuilo
441321c170 13.0.0-beta.20 2023-01-03 16:01:23 +09:00
syuilo
e44f83fb9c update AiScript to 0.12.0 2023-01-03 15:51:49 +09:00
syuilo
db1ca28de3 clean up 2023-01-03 14:27:18 +09:00
syuilo
8ee78d97bb 13.0.0-beta.19 2023-01-03 14:21:57 +09:00
syuilo
3500e035cd refactor 2023-01-03 14:21:32 +09:00
syuilo
2d4d3417a2 refactor 2023-01-03 14:17:39 +09:00
syuilo
fb05e86db7 🎨 2023-01-03 14:08:52 +09:00
syuilo
c93f091ba8 perf(client): use shallowRef instead of ref for template reference 2023-01-03 13:37:32 +09:00
syuilo
826e4502cb refactor 2023-01-03 13:09:24 +09:00
syuilo
459151c1f2 clean up 2023-01-03 13:04:58 +09:00
syuilo
aa0eaf37b6 🎨 2023-01-03 10:57:52 +09:00
syuilo
aca445c7c8 13.0.0-beta.18 2023-01-03 10:53:20 +09:00
syuilo
6c10588e77 refactor(client): refactor and performance improve of MkSpacer 2023-01-03 10:46:56 +09:00
syuilo
2184240ef1 perf(client): use shallowRef for html element ref 2023-01-03 10:12:37 +09:00
syuilo
a0af80f8c5 tweak displayLimit of pagination 2023-01-03 09:41:32 +09:00
syuilo
06a3767409 Update CHANGELOG.md 2023-01-03 09:38:18 +09:00
syuilo
4cc71d2443 ✌️ 2023-01-03 09:32:36 +09:00
syuilo
631ffc8cf6 fix style 2023-01-03 09:19:54 +09:00
syuilo
4d0859ce7f drop latestStatus of instance 2023-01-03 09:03:04 +09:00
syuilo
c8bd139713 drop lastCommunicatedAt of instance 2023-01-03 09:00:42 +09:00
syuilo
7093573f0c drop latestRequestSentAt of instance 2023-01-03 08:48:00 +09:00
syuilo
771348e887 PV集計はローカルユーザーのみに 2023-01-03 08:29:25 +09:00
syuilo
21c1e086f9 🎨 2023-01-03 08:26:39 +09:00
syuilo
8a7ed1dc28 13.0.0-beta.17 2023-01-02 20:04:53 +09:00
syuilo
a9f4217214 update deps 2023-01-02 20:02:51 +09:00
syuilo
f598a876eb refactor 2023-01-02 19:58:51 +09:00
syuilo
70ce129478 🎨 2023-01-02 16:41:09 +09:00
syuilo
43c37dd0db fix 2023-01-02 16:41:05 +09:00
syuilo
fb364ce740 fix of #8512
https://github.com/misskey-dev/misskey/pull/8512#issuecomment-1368553870
2023-01-02 16:02:42 +09:00
420 changed files with 8007 additions and 4573 deletions

View File

@@ -11,37 +11,62 @@ You should also include the user name that made the change.
## 13.0.0 (unreleased)
### TL;DR
- New features (Play, new widgets, new charts, 🍪👈, etc)
- Rewriten backend
- Better performance (backend and frontend)
- Various usability improvements
- Various UI tweaks
### Changes
#### For server admins
- Node.js 18.x or later is required
- PostgreSQL 15.x is required
- Misskey not using 15 specific features at 13.0.0, but may do so in the future.
- Elasticsearchのサポートが削除されました
- 代わりに今後任意の検索プロバイダを設定できる仕組みを構想しています。その仕組みを使えば今まで通りElasticsearchも利用できます
- ノートのウォッチ機能が削除されました
- Migrate to Yarn Berry (v3.2.1) @ThatOneCalculator
- You may have to `yarn run clean-all`, `sudo corepack enable` and `yarn set version berry` before running `yarn install` if you're still on yarn classic
#### For users
- ノートのウォッチ機能が削除されました
- アンケートに投票された際に通知が作成されなくなりました
- 新たに動的なPagesを作ることはできなくなりました
- 代わりに今後AiScriptを用いてより柔軟に動的なコンテンツを作成できるMisskey Play機能実装を予定しています。
- 代わりにAiScriptを用いてより柔軟に動的なコンテンツを作成できるMisskey Play機能実装されています。
- AiScriptが0.12.2にアップデートされました
- 0.12.xの変更点についてはこちら https://github.com/syuilo/aiscript/blob/master/CHANGELOG.md#0120
- 0.12.x未満のプラグインは読み込むことはできません
- iOS15以下のデバイスはサポートされなくなりました
- Firefox109以下はサポートされなくなりました
#### For app developers
- API: metaのレスポンスに`emojis`プロパティが含まれなくなりました
- カスタム絵文字一覧情報を取得するには、`emojis`エンドポイントにリクエストします
- API: カスタム絵文字エンティティに`url`プロパティが含まれなくなりました
- 絵文字画像を表示するには、`<instance host>/emoji/<emoji name>.webp`にリクエストすると画像が返ります。
- e.g. `https://p1.a9z.dev/emoji/misskey.webp`
- remote: `https://p1.a9z.dev/emoji/syuilo_birth_present@mk.f72u.net.webp`
- API: `user`および`note`エンティティに`emojis`プロパティが含まれなくなりました
- API: `user`エンティティに`avatarColor`および`bannerColor`プロパティが含まれなくなりました
- API: `instance`エンティティに`latestStatus``lastCommunicatedAt``latestRequestSentAt`プロパティが含まれなくなりました
### Improvements
- Push notification of Antenna note @tamaina
- AVIF support @tamaina
- Add Cloudflare Turnstile CAPTCHA support @CyberRex0
- Misskey Play @syuilo
- Introduce retention-rate aggregation @syuilo
- Make possible to export favorited notes @syuilo
- Add per user pv chart @syuilo
- Push notification of Antenna note @tamaina
- AVIF support @tamaina
- Add Cloudflare Turnstile CAPTCHA support @CyberRex0
- Server: signToActivityPubGet is set to true by default @syuilo
- Server: improve syslog performance @syuilo
- Server: improve note scoring for featured notes @CyberRex0
- Server: delete outdated notifications regularly to improve db performance @syuilo
- Server: delete outdated hard-mutes regularly to improve db performance @syuilo
- Server: delete outdated notes of antenna regularly to improve db performance @syuilo
- Server: improve activitypub deliver performance @syuilo
- Client: use tabler-icons instead of fontawesome to better design @syuilo
- Client: Add AiScript App widget
- Client: Add new gabber kick sounds (thanks for noizenecio)
- Client: Add link to user RSS feed in profile menu @ssmucny
- Client: Compress non-animated PNG files @saschanaz
@@ -52,14 +77,20 @@ You should also include the user name that made the change.
- Client: Make widgets of universal/classic sync between devices @tamaina
- Client: Implement the button to subscribe push notification @tamaina
- Client: Implement the toggle to or not to close push notifications when notifications or messages are read @tamaina
- Client: Improve RSS widget @tamaina
- Client: show Unicode emoji tooltip with its name in MkReactionsViewer.reaction @saschanaz
- Client: OpenSearch support @SoniEx2 @chaoticryptidz
- Client: Support remote objects in search @SoniEx2
- Client: user activity page @syuilo
- Client: add user list widget @syuilo
- Client: add heatmap of daily active users to about page @syuilo
- Client: introduce fluent emoji @syuilo
- Client: add new theme @syuilo
- Client: show fireworks when visit user who today is birthday @syuilo
- Client: show bot warning on screen when logged in as bot account @syuilo
- Client: improve overall performance of client @syuilo
- Client: ui tweaks @syuilo
- Client: clicker game @syuilo
### Bugfixes
- Server: 引用内の文章がnyaizeされてしまう問題を修正 @kabo2468
@@ -68,10 +99,18 @@ You should also include the user name that made the change.
- Server: trim long text of note from ap @syuilo
- Server: Ap inboxの最大ペイロードサイズを64kbに制限 @syuilo
- Server: アンテナの作成数上限を追加 @syuilo
- Server: pages/likeのエラーIDが重複しているのを修正 @syuilo
- Server: pages/updateのパラメータによってはsummaryの値が更新されないのを修正 @syuilo
- Server: Escape SQL LIKE @mei23
- Server: 特定のPNG画像のアップロードに失敗する問題を修正 @usbharu
- Server: 非公開のクリップのURLでOGPレンダリングされる問題を修正 @syuilo
- Server: アンテナタイムライン(ストリーミング)が、フォローしていないユーザーの鍵投稿も拾ってしまう @syuilo
- Client: 日付形式の文字列などがカスタム絵文字として表示されるのを修正 @syuilo
- Client: case insensitive emoji search @saschanaz
- Client: InAppウィンドウが操作できなくなることがあるのを修正 @tamaina
- Client: use proxied image for instance icon @syuilo
- Client: Webhookの編集画面で、内容を保存することができない問題を修正 @m-hayabusa
- Client: Page編集でブロックの移動が行えない問題を修正 @syuilo
- Client: update emoji picker immediately on all input @saschanaz
- Client: チャートのツールチップが画面に残ることがあるのを修正 @syuilo
- Client: fix wrong link in tutorial @syuilo

View File

@@ -164,7 +164,6 @@ annotation: "التعليقات"
federation: "الفديرالية"
instances: "مثيل الخادم"
registeredAt: "مسجل منذ"
latestRequestSentAt: "آخر طلب أرسِل في"
latestRequestReceivedAt: "آخر طلب تُلقي في"
latestStatus: "الحالات الأخيرة"
storageUsage: "مساحة التخزين المستخدمة"
@@ -381,6 +380,7 @@ administrator: "المدير"
token: "الرمز المميز"
twoStepAuthentication: "الإستيثاق بعاملَيْن"
moderator: "مشرِف"
moderation: "الإشراف"
nUsersMentioned: "{n} مستخدمين أُشير إليهم"
securityKey: "مفتاح الأمان"
securityKeyName: "اسم المفتاح"
@@ -814,6 +814,9 @@ colored: "ملوّن"
label: "التسمية"
localOnly: "المحلي فقط"
account: "الحسابات"
cannotLoad: "تعذر التحميل"
like: "أعجبني"
show: "المظهر"
_emailUnavailable:
used: "هذا البريد الإلكتروني مستخدم"
format: "صيغة البريد الإلكتروني غير صالحة"
@@ -1229,6 +1232,11 @@ _timelines:
local: "المحلي"
social: "الاجتماعي"
global: "الشامل"
_play:
viewSource: "اظهر المصدر"
featured: "الأكثر شعبية"
title: "العنوان"
summary: "الوصف"
_pages:
newPage: "أنشئ صفحة جديدة"
editPage: "عدّل الصفحة"
@@ -1294,6 +1302,7 @@ _notification:
yourFollowRequestAccepted: "قُبل طلب المتابعة"
youWereInvitedToGroup: "دُعيت إلى فريقٍ"
pollEnded: "ظهرت نتائج الاستطلاع"
unreadAntennaNote: "هوائي {name}"
_types:
all: "الكل"
follow: "متابِعون جدد"

View File

@@ -164,7 +164,6 @@ annotation: "মন্তব্য"
federation: "ফেডিভার্স"
instances: "ইন্সট্যান্স"
registeredAt: "যোগ দিয়েছেন"
latestRequestSentAt: "শেষ রিকুয়েস্ট পাঠানো হয়েছে"
latestRequestReceivedAt: "শেষ রিকুয়েস্ট গৃহীত হয়েছে"
latestStatus: "সর্বশেষ অবস্থা"
storageUsage: "স্টোরেজের ব্যাবহার"
@@ -852,6 +851,8 @@ colored: "রঙ্গিন"
label: "লেবেল"
localOnly: "শুধুমাত্র লোকাল"
account: "অ্যাকাউন্টগুলি"
like: "পছন্দ করা"
show: "প্রদর্শন"
_emailUnavailable:
used: "এই ইমেইল ঠিকানাটি ইতোমধ্যে ব্যবহৃত হয়েছে"
format: "এই ইমেল ঠিকানাটি সঠিকভাবে লিখা হয়নি"
@@ -1320,6 +1321,12 @@ _timelines:
local: "স্থানীয়"
social: "সামাজিক"
global: "গ্লোবাল"
_play:
viewSource: "উৎস দেখুন"
featured: "জনপ্রিয়"
title: "শিরোনাম"
script: "স্ক্রিপ্ট"
summary: "বর্ণনা"
_pages:
newPage: "নতুন পৃষ্ঠা বানান"
editPage: "পৃষ্ঠাটি সম্পাদনা করুন"

View File

@@ -165,7 +165,6 @@ annotation: "Comentaris"
federation: "Federació"
instances: "Servidors"
registeredAt: "Registrat a"
latestRequestSentAt: "Darrera petició enviada"
latestRequestReceivedAt: "Última petició rebuda"
latestStatus: "Últim estat"
storageUsage: "Emmagatzematge utilitzat"

View File

@@ -161,7 +161,6 @@ annotation: "Komentáře"
federation: "Federace"
instances: "Instance"
registeredAt: "Registrován"
latestRequestSentAt: "Poslední požadavek poslán"
latestRequestReceivedAt: "Poslední požadavek přijat"
latestStatus: "Poslední status"
storageUsage: "Využití úložiště"
@@ -611,6 +610,7 @@ speed: "Rychlost"
slow: "Pomalá"
fast: "Rychlá"
account: "Účty"
show: "Zobrazit"
_ad:
back: "Zpět"
_gallery:
@@ -749,6 +749,9 @@ _charts:
_timelines:
home: "Domů"
global: "Globální"
_play:
script: "Skript"
summary: "Popis"
_pages:
newPage: "Vytvořit novou stránku"
editPage: "Upravit stránku"

View File

@@ -167,7 +167,6 @@ annotation: "Anmerkung"
federation: "Föderation"
instances: "Instanzen"
registeredAt: "Registriert am"
latestRequestSentAt: "Letzte Anfrage gesendet"
latestRequestReceivedAt: "Letzte Anfrage erhalten"
latestStatus: "Neuster Status"
storageUsage: "Verbrauchter Speicherplatz"
@@ -610,7 +609,7 @@ regexpErrorDescription: "Im regulären Ausdruck deiner {tab}en Wortstummschaltun
instanceMute: "Instanzstummschaltungen"
userSaysSomething: "{name} hat etwas gesagt"
makeActive: "Aktivieren"
display: "Anzeigeart"
display: "Anzeigen"
copy: "Kopieren"
metrics: "Metriken"
overview: "Übersicht"
@@ -916,6 +915,15 @@ caption: "Beschreibung"
loggedInAsBot: "Momentan als Bot angemeldet"
tools: "Werkzeuge"
cannotLoad: "Kann nicht geladen werden"
numberOfProfileView: "Profilaufrufe"
like: "Gefällt mir"
unlike: "\"Gefällt mir\" entfernen"
numberOfLikes: "\"Gefällt mir\"-Anzahl"
show: "Anzeigen"
neverShow: "Nicht wieder anzeigen"
remindMeLater: "Vielleicht später"
didYouLikeMisskey: "Gefällt dir Misskey?"
pleaseDonate: "Misskey ist die kostenlose Software, die von {host} verwendet wird. Wir würden uns über Spenden freuen, damit dessen Entwicklung weitergeführt werden kann!"
_sensitiveMediaDetection:
description: "Ermöglicht eine Erleichterung der Servermoderation durch die automatische Erkennungen von NSFW-Medien unter Verwendung von Machine Learning. Hierdurch wird die Serverlast etwas erhöht."
sensitivity: "Erkennungssensitivität"
@@ -1315,6 +1323,7 @@ _widgets:
jobQueue: "Job-Warteschlange"
serverMetric: "Servermetriken"
aiscript: "AiScript-Konsole"
aiscriptApp: "AiScript-Anwendung"
aichan: "Ai"
userList: "Benutzerliste"
_userList:
@@ -1420,6 +1429,21 @@ _timelines:
local: "Lokal"
social: "Sozial"
global: "Global"
_play:
new: "Play erstellen"
edit: "Play bearbeiten"
created: "Play erfolgreich erstellt"
updated: "Play erfolgreich aktualisiert"
deleted: "Play erfolgreich gelöscht"
pageSetting: "Play-Einstellungen"
editThisPage: "Dieses Play bearbeiten"
viewSource: "Quelltext anzeigen"
my: "Meine Plays"
liked: "Mit \"Gefällt mir\" markierte Plays"
featured: "Beliebt"
title: "Titel"
script: "Skript"
summary: "Beschreibung"
_pages:
newPage: "Seite erstellen"
editPage: "Seite bearbeiten"

View File

@@ -167,7 +167,6 @@ annotation: "Comments"
federation: "Federation"
instances: "Instances"
registeredAt: "Registered at"
latestRequestSentAt: "Last request sent"
latestRequestReceivedAt: "Last request received"
latestStatus: "Latest status"
storageUsage: "Storage usage"
@@ -916,6 +915,15 @@ caption: "Caption"
loggedInAsBot: "Currently logged in as bot"
tools: "Tools"
cannotLoad: "Unable to load"
numberOfProfileView: "Profile views"
like: "Like"
unlike: "Unlike"
numberOfLikes: "Likes"
show: "Show"
neverShow: "Don't show again"
remindMeLater: "Maybe later"
didYouLikeMisskey: "Have you taken a liking to Misskey?"
pleaseDonate: "{host} uses the free software, Misskey. We would highly appreciate your donations so development of Misskey can continue!"
_sensitiveMediaDetection:
description: "Reduces the effort of server moderation through automatically recognizing NSFW media via Machine Learning. This will slightly increase the load on the server."
sensitivity: "Detection sensitivity"
@@ -1315,6 +1323,7 @@ _widgets:
jobQueue: "Job Queue"
serverMetric: "Server metrics"
aiscript: "AiScript console"
aiscriptApp: "AiScript App"
aichan: "Ai"
userList: "User list"
_userList:
@@ -1420,6 +1429,21 @@ _timelines:
local: "Local"
social: "Social"
global: "Global"
_play:
new: "Create Play"
edit: "Edit Play"
created: "Play created"
updated: "Play edited"
deleted: "Play deleted"
pageSetting: "Play settings"
editThisPage: "Edit this Play"
viewSource: "View source"
my: "My Plays"
liked: "Liked Plays"
featured: "Popular"
title: "Title"
script: "Script"
summary: "Description"
_pages:
newPage: "Create a new Page"
editPage: "Edit this Page"

View File

@@ -13,6 +13,7 @@ fetchingAsApObject: "Buscando en el fediverso"
ok: "OK"
gotIt: "¡Lo tengo!"
cancel: "Cancelar"
noThankYou: "No gracias"
enterUsername: "Introduce el nombre de usuario"
renotedBy: "Renotado por {user}"
noNotes: "No hay notas"
@@ -48,6 +49,7 @@ deleteAndEdit: "Borrar y editar"
deleteAndEditConfirm: "¿Estás seguro de que quieres borrar esta nota y editarla? Perderás todas las reacciones, renotas y respuestas."
addToList: "Agregar a lista"
sendMessage: "Enviar un mensaje"
copyRSS: "Copiar RSS"
copyUsername: "Copiar nombre de usuario"
searchUser: "Buscar un usuario"
reply: "Responder"
@@ -165,7 +167,6 @@ annotation: "Anotación"
federation: "Federación"
instances: "Instancia"
registeredAt: "Registrado en"
latestRequestSentAt: "Ultimo pedido enviado"
latestRequestReceivedAt: "Ultimo pedido recibido"
latestStatus: "Último status"
storageUsage: "Almacenamiento usado"
@@ -455,6 +456,8 @@ language: "Idioma"
uiLanguage: "Idioma de visualización de la interfaz"
groupInvited: "Invitado al grupo"
aboutX: "Acerca de {x}"
emojiStyle: "Estilo de emoji"
native: "Nativo"
disableDrawer: "No mostrar los menús en cajones"
youHaveNoGroups: "Sin grupos"
joinOrCreateGroup: "Obtenga una invitación para unirse al grupos o puede crear su propio grupo."
@@ -713,6 +716,7 @@ accentColor: "Acento"
textColor: "Texto"
saveAs: "Guardar como…"
advanced: "Avanzado"
advancedSettings: "Configuración avanzada"
value: "Valores"
createdAt: "Fecha de creación"
updatedAt: "Actualizado"
@@ -898,6 +902,22 @@ navbar: "Barra de navegación"
shuffle: "Aleatorio"
account: "Cuentas"
move: "Mover"
pushNotification: "Alerta emergente"
subscribePushNotification: "Activar las notificaciones emergentes"
unsubscribePushNotification: "Desactivar las notificaciones emergentes"
pushNotificationAlreadySubscribed: "Notificaciones emergentes ya activadas"
pushNotificationNotSupported: "El navegador o la instancia no admiten notificaciones push"
sendPushNotificationReadMessage: "Eliminar las notificaciones push después de leer las notificaciones y los mensajes"
sendPushNotificationReadMessageCaption: "La notificación \"{emptyPushNotificationMessage}\" aparecerá momentáneamente. Esto puede aumentar el consumo de batería del dispositivo."
windowMaximize: "Maximizar"
windowRestore: "Regresar"
caption: "Pie de foto"
loggedInAsBot: "Inicio sesión como cuenta bot."
tools: "Utilidades"
cannotLoad: "No se puede cargar."
numberOfProfileView: "Número de vistas de perfil"
like: "¡Muy bien!"
show: "Apariencia"
_sensitiveMediaDetection:
description: "Reduce el esfuerzo de la moderación el el servidor a través del reconocimiento automático de contenido NSFW usando 'Machine Learning'. Esto puede incrementar ligeramente la carga en el servidor."
sensitivity: "Sensibilidad de detección"
@@ -1208,6 +1228,9 @@ _tutorial:
step7_1: "Así terminó la explicación del funcionamiento básico de Misskey. Eso fue todo."
step7_2: "Si quieres conocer más sobre Misskey, prueba con la sección {help}."
step7_3: "Así, disfruta de Misskey 🚀"
step8_1: "Por último, ¿por qué no activar las notificaciones emergentes?"
step8_2: "Al recibir notificaciones emergentes, estarás al tanto de reacciones, seguimientos y menciones incluso cuando Misskey no esté abierto."
step8_3: "La configuración de las notificaciones puede modificarse posteriormente."
_2fa:
alreadyRegistered: "Ya has completado la configuración."
registerDevice: "Registrar dispositivo"
@@ -1295,6 +1318,7 @@ _widgets:
serverMetric: "Estadísticas del servidor"
aiscript: "Consola de AiScript"
aichan: "indigo"
userList: "Lista de usuarios"
_userList:
chooseList: "Seleccione una lista"
_cw:
@@ -1360,6 +1384,7 @@ _profile:
changeBanner: "Cambiar banner"
_exportOrImport:
allNotes: "Todas las notas"
favoritedNotes: "Notas favoritas"
followingList: "Siguiendo"
muteList: "Silenciados"
blockingList: "Bloqueados"
@@ -1397,6 +1422,12 @@ _timelines:
local: "Local"
social: "Social"
global: "Global"
_play:
viewSource: "Ver la fuente"
featured: "Popular"
title: "Título"
script: "Script"
summary: "Descripción"
_pages:
newPage: "Crear página"
editPage: "Editar página"
@@ -1464,6 +1495,7 @@ _notification:
yourFollowRequestAccepted: "Tu solicitud de seguimiento fue aceptada"
youWereInvitedToGroup: "Invitado al grupo"
pollEnded: "Estan disponibles los resultados de la encuesta"
unreadAntennaNote: "Antena {name}"
emptyPushNotificationMessage: "Se han actualizado las notificaciones push"
_types:
all: "Todo"

View File

@@ -2,6 +2,7 @@
_lang_: "Français"
headlineMisskey: "Réseau relié par des notes"
introMisskey: "Bienvenue ! Misskey est un service de microblogage décentralisé, libre et ouvert.\nÉcrivez des « notes » et partagez ce qui se passe à linstant présent, autour de vous avec les autres 📡\nLa fonction « réactions », vous permet également dajouter une réaction rapide aux notes des autres utilisateur·rice·s 👍\nExplorons un nouveau monde 🚀"
poweredByMisskeyDescription: "{nom} est l'un des services propulsés par la plateforme ouverte <b>Misskey</b> (appelée \"instance Misskey\")."
monthAndDay: "{day}/{month}"
search: "Rechercher"
notifications: "Notifications"
@@ -12,6 +13,7 @@ fetchingAsApObject: "Récupération depuis le fédiverse …"
ok: "OK"
gotIt: "Jai compris !"
cancel: "Annuler"
noThankYou: "Pas maintenant"
enterUsername: "Entrer un nom dutilisateur·rice"
renotedBy: "Renoté par {user}"
noNotes: "Aucune note"
@@ -47,6 +49,7 @@ deleteAndEdit: "Supprimer et réécrire"
deleteAndEditConfirm: "Êtes-vous sûr·e de vouloir supprimer cette note et la reformuler ? Vous perdrez toutes les réactions, renotes et réponses y afférentes."
addToList: "Ajouter à une liste"
sendMessage: "Envoyer un message"
copyRSS: "Copier le RSS"
copyUsername: "Copier le nom dutilisateur·rice"
searchUser: "Chercher un·e utilisateur·rice"
reply: "Répondre"
@@ -143,6 +146,7 @@ flagAsBotDescription: "Si ce compte est géré de manière automatisée, choisis
flagAsCat: "Ce compte est un chat"
flagAsCatDescription: "Activer l'option \" Je suis un chat \" pour ce compte."
flagShowTimelineReplies: "Afficher les réponses dans le fil"
flagShowTimelineRepliesDescription: "Affiche les réponses des utilisateurs aux notes des autres utilisateurs dans la timeline si cette option est activée."
autoAcceptFollowed: "Accepter automatiquement les demandes dabonnement venant dutilisateur·rice·s que vous suivez"
addAccount: "Ajouter un compte"
loginFailed: "Échec de la connexion"
@@ -163,7 +167,6 @@ annotation: "Commentaires"
federation: "Fédération"
instances: "Instance"
registeredAt: "Premier contact le"
latestRequestSentAt: "Dernière requête envoyée"
latestRequestReceivedAt: "Dernière requête reçue"
latestStatus: "Dernier statut"
storageUsage: "Stockage utilisé"
@@ -453,6 +456,8 @@ language: "Langue"
uiLanguage: "Langue daffichage de linterface"
groupInvited: "Invité au groupe"
aboutX: "À propos de {x}"
emojiStyle: "Style des émojis"
native: "Natif"
disableDrawer: "Les menus ne s'affichent pas dans le tiroir"
youHaveNoGroups: "Vous navez aucun groupe"
joinOrCreateGroup: "Vous pouvez être invité·e à rejoindre des groupes existants ou créer votre propre nouveau groupe."
@@ -600,6 +605,7 @@ smtpSecureInfo: "Désactiver cette option lorsque STARTTLS est utilisé"
testEmail: "Tester la distribution de courriel"
wordMute: "Filtre de mots"
regexpError: "Erreur dexpression régulière"
regexpErrorDescription: "Une erreur s'est produite dans l'expression régulière sur la ligne {ligne} de votre mot muet {tab} :"
instanceMute: "Instance en sourdine"
userSaysSomething: "{name} a dit quelque chose"
makeActive: "Activer"
@@ -708,6 +714,7 @@ accentColor: "Accentuation"
textColor: "Texte"
saveAs: "Enregistrer sous ..."
advanced: "Avancé"
advancedSettings: "Paramètres avancés"
value: "Valeur"
createdAt: "Date de création"
updatedAt: "Mis à jour le"
@@ -852,6 +859,7 @@ rateLimitExceeded: "Limite de taux dépassée"
cropImage: "Recadrer l'image"
cropImageAsk: "Voulez-vous recadrer cette image ?"
file: "Fichiers"
recentNHours: "Dernières {n} heures"
noEmailServerWarning: "Serveur de courrier non configuré."
thereIsUnresolvedAbuseReportWarning: "Il ny a aucun rapport non résolu."
recommended: "Recommandé"
@@ -891,6 +899,19 @@ navbar: "Barre de navigation"
shuffle: "Lecture aléatoire"
account: "Comptes"
move: "Déplacer"
pushNotification: "Notifications push"
subscribePushNotification: "Autoriser les notifications push"
unsubscribePushNotification: "Désactiver les notifications push"
pushNotificationAlreadySubscribed: "Les notifications push sont déjà activées"
pushNotificationNotSupported: "Votre navigateur ou votre instance ne prend pas en charge les notifications push"
sendPushNotificationReadMessage: "Supprimer les notifications push une fois que les notifications ou messages pertinents ont été lus."
windowRestore: "Restaurer"
caption: "Libellé"
loggedInAsBot: "Connecté actuellement en tant que bot"
tools: "Outils"
cannotLoad: "Chargement impossible"
like: "J'aime"
show: "Affichage"
_sensitiveMediaDetection:
description: "L'apprentissage automatique peut être utilisé pour détecter automatiquement les médias sensibles à modérer. La sollicitation des serveurs augmente légèrement."
sensitivity: "Sensibilité de la détection"
@@ -1201,6 +1222,8 @@ _tutorial:
step7_1: "Félicitations ! Vous avez atteint la fin du tutoriel de base pour lutilisation de Misskey."
step7_2: "Si vous désirez en savoir plus sur Misskey, jetez un œil sur la section {help}."
step7_3: "Bon courage et amusez-vous bien sur Misskey ! 🚀"
step8_1: "Enfin, souhaitez-vous activer les notifications push ?"
step8_2: "En les activant, vous recevrez des notifications pour les mentions, les réactions, les suivis, etc., même lorsque Misskey n'est pas ouvert."
_2fa:
alreadyRegistered: "Configuration déjà achevée."
registerDevice: "Ajouter un nouvel appareil"
@@ -1287,6 +1310,7 @@ _widgets:
serverMetric: "Statistiques du serveur"
aiscript: "Console AiScript"
aichan: "Ai"
userList: "Liste utilisateur"
_userList:
chooseList: "Sélectionner une liste"
_cw:
@@ -1389,6 +1413,12 @@ _timelines:
local: "Local"
social: "Social"
global: "Global"
_play:
viewSource: "Afficher la source"
featured: "Populaire"
title: "Titre"
script: "Script"
summary: "Description"
_pages:
newPage: "Créer une page"
editPage: "Modifier une page"
@@ -1456,6 +1486,7 @@ _notification:
yourFollowRequestAccepted: "Votre demande dabonnement a été accepté"
youWereInvitedToGroup: "Invité·e au groupe"
pollEnded: "Les résultats du sondage sont disponibles"
unreadAntennaNote: "Antenne {name}"
emptyPushNotificationMessage: "Les notifications push ont été mises à jour"
_types:
all: "Toutes"
@@ -1490,6 +1521,7 @@ _deck:
newProfile: "Nouveau profil"
deleteProfile: "Supprimer le profil"
introduction: "Créez linterface parfaite qui vous sied en arrangeant librement les colonnes !"
introduction2: "Cliquez sur le + à droite de l'écran pour ajouter de nouvelles colonnes quand vous le souhaitez."
_columns:
main: "Principale"
widgets: "Widgets"

View File

@@ -164,7 +164,6 @@ annotation: "Keterangan konten"
federation: "Federasi"
instances: "Instansi"
registeredAt: "Terdaftar"
latestRequestSentAt: "Permintaan terakhir dikirim pada"
latestRequestReceivedAt: "Permintaan terakhir diterima pada"
latestStatus: "Status terakhir"
storageUsage: "Penggunaan penyimpanan"
@@ -856,6 +855,10 @@ colored: "Diwarnai"
label: "Label"
localOnly: "Hanya lokal"
account: "Akun"
like: "Suka"
unlike: "Tidak Suka"
numberOfLikes: "Jumlah yang disukai"
show: "Tampilkan"
_emailUnavailable:
used: "Alamat surel ini telah digunakan"
format: "Format tidak valid."
@@ -1221,6 +1224,7 @@ _widgets:
jobQueue: "Antrian kerja"
serverMetric: "Statistik peladen"
aiscript: "Konsol AiScript"
aiscriptApp: "Aplikasi AiScript"
aichan: "Ai"
_userList:
chooseList: "Pilih daftar"
@@ -1324,6 +1328,21 @@ _timelines:
local: "Lokal"
social: "Sosial"
global: "Global"
_play:
new: "Membuat Permainan"
edit: "Menyunting Permainan"
created: "Permainan sudah dibuat"
updated: "Permainan sudah diperbaharui"
deleted: "Hapus permainan"
pageSetting: "Pengaturan permainan"
editThisPage: "Sunting Permainan ini"
viewSource: "Lihat sumber"
my: "Permainan saya"
liked: "Permainan Disukai"
featured: "Populer"
title: "Judul"
script: "Script"
summary: "Deskripsi"
_pages:
newPage: "Buat halaman baru"
editPage: "Sunting halaman"

View File

@@ -1,7 +1,7 @@
---
_lang_: "Italiano"
headlineMisskey: "Rete collegata tramite note"
introMisskey: "Benvenut@! Misskey è un servizio di microblogging decentralizzato, libero e aperto. \nScrivi \"note\" per condividere ciò che sta succedendo adesso o per dire a tutti qualcosa di te. 📡\nGrazie alla funzione \"reazioni\" puoi anche mandare reazioni rapide alle note delle altre persone del Fediverso. 👍\nEsplora un nuovo mondo! 🚀"
introMisskey: "Eccoci! Misskey è un servizio di microblogging decentralizzato, libero e aperto. \n📡 Puoi pubblicare «Note» per condividere ciò che sta succedendo o per dire a tutti qualcosa su di te. \n👍 Puoi reagire inviando emoji rapidi alle «Note» provenienti da altri profili nel Fediverso.\n🚀 Esplora un nuovo mondo insieme a noi!"
poweredByMisskeyDescription: "{name} è uno dei servizi (chiamati istanze) che utilizzano la piattaforma open source <b>Misskey</b>."
monthAndDay: "{day}/{month}"
search: "Cerca"
@@ -28,7 +28,7 @@ timeline: "Timeline"
noAccountDescription: "L'utente non ha ancora scritto niente nella biografia di profilo."
login: "Accedi"
loggingIn: "Accesso in corso..."
logout: "Esci"
logout: "Uscita"
signup: "Iscriviti"
uploading: "Caricamento..."
save: "Salva"
@@ -49,6 +49,7 @@ deleteAndEdit: "Elimina e modifica"
deleteAndEditConfirm: "Vuoi davvero cancellare questa nota e scriverla di nuovo? Verrano eliminate anche tutte le reazioni, Rinote e risposte collegate."
addToList: "Aggiungi alla lista"
sendMessage: "Invia messaggio"
copyRSS: "Copia RSS"
copyUsername: "Copia nome utente"
searchUser: "Cerca utente"
reply: "Rispondi"
@@ -166,7 +167,6 @@ annotation: "Descrizione"
federation: "Federazione"
instances: "Istanza"
registeredAt: "Registrato presso"
latestRequestSentAt: "Ultima richiesta inviata"
latestRequestReceivedAt: "Ultima richiesta ricevuta"
latestStatus: "Ultimo stato"
storageUsage: "Capienza dei dischi"
@@ -456,6 +456,8 @@ language: "Lingua"
uiLanguage: "Lingua di visualizzazione dell'interfaccia"
groupInvited: "Invitat@ al gruppo"
aboutX: "Informazioni su {x}"
emojiStyle: "Stile emoji"
native: "Nativo"
disableDrawer: "Non mostrare il menù sul drawer"
youHaveNoGroups: "Nessun gruppo"
joinOrCreateGroup: "Puoi creare il tuo gruppo o essere invitat@ a gruppi che già esistono."
@@ -714,6 +716,7 @@ accentColor: "Colore principale"
textColor: "Testo"
saveAs: "Salva con nome"
advanced: "Avanzato"
advancedSettings: "Impostazioni avanzate"
value: "Valore"
createdAt: "Data di creazione"
updatedAt: "Aggiornato il"
@@ -873,7 +876,7 @@ deleteAccount: "Eliminazione profilo"
document: "Documento"
numberOfPageCache: "Numero di pagine cache"
numberOfPageCacheDescription: "Aumenta l'usabilità, ma aumenta anche il carico e l'utilizzo della memoria."
logoutConfirm: "Sei sicuro di voler effettuare il logout?"
logoutConfirm: "Vuoi davvero uscire da Misskey? "
lastActiveDate: "Data dell'ultimo utilizzo"
statusbar: "Barra di stato"
pleaseSelect: "Scegli un'opzione"
@@ -910,6 +913,11 @@ windowMaximize: "Ingrandisci"
windowRestore: "Ripristina"
caption: "Didascalia"
loggedInAsBot: "Connessione come Bot"
tools: "Strumenti"
cannotLoad: "Caricamento impossibile"
numberOfProfileView: "Visualizzazioni profilo"
like: "Mi piace!"
show: "Visualizza"
_sensitiveMediaDetection:
description: "L'apprendimento automatico può essere utilizzato per individuare automaticamente i media sensibili da moderare. Il carico del server aumenta leggermente."
sensitivity: "Sensibilità di rilevamento"
@@ -1061,7 +1069,7 @@ _mfm:
sparkleDescription: "Aggiungere effetti particellari scintillanti."
rotate: "Ruota"
rotateDescription: "Ruota con un angolo specificato."
plain: "aereo"
plain: "Testo semplice"
plainDescription: "Disattiva tutta la sintassi interna."
_instanceTicker:
none: "Nascondi"
@@ -1199,13 +1207,13 @@ _time:
day: "giorni"
_tutorial:
title: "Come usare Misskey"
step1_1: "Benvenuto/a!"
step1_1: "Eccoci!"
step1_2: "Questa pagina si chiama una \" Timeline \". Mostra in ordine cronologico le \" note \" delle persone che segui."
step1_3: "Attualmente la tua Timeline è vuota perché non segui alcun profilo e non hai pubblicato alcuna nota ancora."
step2_1: "Prima di scrivere una nota o di seguire altri profili, imposta il tuo di profilo!"
step2_1: "Prima di scrivere una «Nota» o di seguire altri profili, prepara il tuo profilo!"
step2_2: "Aggiungere qualche informazione su di te aumenterà le tue possibilità di essere seguit@ da altre persone. "
step3_1: "Hai finito di impostare il tuo profilo?"
step3_2: "Ora, puoi pubblicare una nota. Facciamo una prova! Premi il pulsante a forma di penna in cima allo schermo per aprire una finestra di dialogo. "
step3_2: "Ora puoi pubblicare una «Nota». Proviamo subito! Premi il bottone con l'icona «penna» per iniziare a scrivere in una finestra di dialogo. "
step3_3: "Scritto il testo della nota, puoi pubblicarla premendo il pulsante nella parte superiore destra della finestra di dialogo."
step3_4: "Non ti viene niente in mente? Perché non scrivi semplicemente \"Ho appena cominciato a usare Misskey\"?"
step4_1: "Hai pubblicato qualcosa?"
@@ -1217,7 +1225,7 @@ _tutorial:
step6_1: "Adesso, dovresti essere in grado di vedere le note dagli altri profili sulla tua timeline."
step6_2: "Puoi anche rispondere alle note con un click, scegliendo le reazioni immediate."
step6_3: "Per inviare una reazione, premi l'icona + della nota e scegli l'emoji che vuoi mandare."
step7_1: "Complimenti! Sei arrivat@ alla fine dell'esercitazione di base su come usare Misskey. "
step7_1: "Congratulazioni! Hai completato l'esercitazione iniziale su come usare Misskey."
step7_2: "Se vuoi saperne di più su Misskey, puoi dare un'occhiata alla sezione {help}."
step7_3: "Da ultimo, buon divertimento su Misskey! 🚀"
step8_1: "Per concludere, vuoi attivare le notifiche push?"
@@ -1309,7 +1317,8 @@ _widgets:
jobQueue: "Coda di lavoro"
serverMetric: "Statistiche server"
aiscript: "Console AiScript"
aichan: "indaco (tintura)"
aichan: "Mascotte Ai"
userList: "Elenco utenti"
_userList:
chooseList: "Seleziona una lista"
_cw:
@@ -1375,6 +1384,7 @@ _profile:
changeBanner: "Cambia intestazione"
_exportOrImport:
allNotes: "Tutte le note"
favoritedNotes: "Note preferite"
followingList: "Follows"
muteList: "Elenco profili silenziati"
blockingList: "Elenco profili bloccati"
@@ -1412,6 +1422,12 @@ _timelines:
local: "Locale"
social: "Sociale"
global: "Federata"
_play:
viewSource: "Visualizza sorgente"
featured: "Popolari"
title: "Titolo"
script: "Script"
summary: "Descrizione"
_pages:
newPage: "Crea pagina"
editPage: "Modifica pagina"

View File

@@ -167,7 +167,6 @@ annotation: "注釈"
federation: "連合"
instances: "インスタンス"
registeredAt: "初観測"
latestRequestSentAt: "直近のリクエスト送信"
latestRequestReceivedAt: "直近のリクエスト受信"
latestStatus: "直近のステータス"
storageUsage: "ストレージ使用量"
@@ -917,6 +916,14 @@ loggedInAsBot: "Botアカウントでログイン中"
tools: "ツール"
cannotLoad: "読み込めません"
numberOfProfileView: "プロフィール表示回数"
like: "いいね!"
unlike: "いいねを解除"
numberOfLikes: "いいね数"
show: "表示"
neverShow: "今後表示しない"
remindMeLater: "また後で"
didYouLikeMisskey: "Misskeyを気に入っていただけましたか"
pleaseDonate: "Misskeyは{host}が使用している無料のソフトウェアです。これからも開発を続けられるように、ぜひ寄付をお願いします!"
_sensitiveMediaDetection:
description: "機械学習を使って自動でセンシティブなメディアを検出し、モデレーションに役立てることができます。サーバーの負荷が少し増えます。"
@@ -1349,10 +1356,12 @@ _widgets:
jobQueue: "ジョブキュー"
serverMetric: "サーバーメトリクス"
aiscript: "AiScriptコンソール"
aiscriptApp: "AiScript App"
aichan: "藍"
userList: "ユーザーリスト"
_userList:
chooseList: "リストを選択"
clicker: "クリッカー"
_cw:
hide: "隠す"
@@ -1464,6 +1473,22 @@ _timelines:
social: "ソーシャル"
global: "グローバル"
_play:
new: "Playの作成"
edit: "Playの編集"
created: "Playを作成しました"
updated: "Playを更新しました"
deleted: "Playを削除しました"
pageSetting: "Play設定"
editThisPage: "このPlayを編集"
viewSource: "ソースを表示"
my: "自分のPlay"
liked: "いいねしたPlay"
featured: "人気"
title: "タイトル"
script: "スクリプト"
summary: "説明"
_pages:
newPage: "ページの作成"
editPage: "ページの編集"
@@ -1526,7 +1551,6 @@ _notification:
youGotReply: "{name}からのリプライ"
youGotQuote: "{name}による引用"
youRenoted: "{name}がRenoteしました"
youGotPoll: "{name}が投票しました"
youGotMessagingMessageFromUser: "{name}からのチャットがあります"
youGotMessagingMessageFromGroup: "{name}のチャットがあります"
youWereFollowed: "フォローされました"
@@ -1545,7 +1569,6 @@ _notification:
renote: "Renote"
quote: "引用"
reaction: "リアクション"
pollVote: "アンケートに投票された"
pollEnded: "アンケートが終了"
receiveFollowRequest: "フォロー申請を受け取った"
followRequestAccepted: "フォローが受理された"

View File

@@ -167,7 +167,6 @@ annotation: "注釈"
federation: "連合"
instances: "インスタンス"
registeredAt: "初観測"
latestRequestSentAt: "ちょっと前のリクエスト送信"
latestRequestReceivedAt: "ちょっと前のリクエスト受信"
latestStatus: "ちょっと前のステータス"
storageUsage: "ストレージ使うた量"
@@ -916,6 +915,8 @@ caption: "キャプション"
loggedInAsBot: "Botアカウントでログイン中やで"
tools: "ツール"
cannotLoad: "読み込めへんで"
like: "ええやん!"
show: "表示"
_sensitiveMediaDetection:
description: "機械学習を使って自動でセンシティブなメディアを検出して、モデレーションに役立てることができるで。サーバーの負荷が少し増えてまうなあ。"
sensitivity: "検出感度やで"
@@ -1419,6 +1420,12 @@ _timelines:
local: "ローカル"
social: "ソーシャル"
global: "グローバル"
_play:
viewSource: "ソースを表示"
featured: "人気"
title: "タイトル"
script: "スクリプト"
summary: "説明"
_pages:
newPage: "ページを作る"
editPage: "ページの編集"

View File

@@ -167,7 +167,6 @@ annotation: "내용에 대한 주석"
federation: "연합"
instances: "인스턴스"
registeredAt: "등록 날짜"
latestRequestSentAt: "마지막으로 요청을 보낸 시간"
latestRequestReceivedAt: "마지막으로 요청을 받은 시간"
latestStatus: "마지막 상태"
storageUsage: "스토리지 사용량"
@@ -916,6 +915,15 @@ caption: "캡션"
loggedInAsBot: "봇 계정으로 로그인중"
tools: "도구"
cannotLoad: "불러오지 못했습니다"
numberOfProfileView: "프로필 뷰 수"
like: "좋아요!"
unlike: "좋아요 취소"
numberOfLikes: "좋아요 수"
show: "표시"
neverShow: "다시 보지 않기"
remindMeLater: "나중에 알림"
didYouLikeMisskey: "Misskey가 마음에 드시나요?"
pleaseDonate: "{host}은(는) 무료 소프트웨어 Misskey를 사용합니다. 후원을 통해 저희의 개발이 이어질 수 있게 도와주세요!"
_sensitiveMediaDetection:
description: "기계학습을 통해 자동으로 민감한 미디어를 탐지하여, 모더레이션에 참고할 수 있도록 합니다. 서버의 부하를 약간 증가시킵니다."
sensitivity: "탐지 민감도"
@@ -1315,6 +1323,7 @@ _widgets:
jobQueue: "작업 대기열"
serverMetric: "서버 통계"
aiscript: "AiScript 콘솔"
aiscriptApp: "AiScript 앱"
aichan: "아이"
userList: "사용자 목록"
_userList:
@@ -1382,6 +1391,7 @@ _profile:
changeBanner: "배너 이미지 변경"
_exportOrImport:
allNotes: "모든 노트"
favoritedNotes: "즐겨찾기한 노트"
followingList: "팔로잉"
muteList: "뮤트"
blockingList: "차단"
@@ -1419,6 +1429,21 @@ _timelines:
local: "로컬"
social: "소셜"
global: "글로벌"
_play:
new: "Play 만들기"
edit: "Play 수정하기"
created: "Play를 생성했습니다"
updated: "Play를 갱신했습니다"
deleted: "Play를 삭제했습니다"
pageSetting: "Play 설정"
editThisPage: "이 Play를 수정"
viewSource: "소스 보기"
my: "나의 Play"
liked: "좋아요 한 Play"
featured: "인기"
title: "제목"
script: "스크립트"
summary: "설명"
_pages:
newPage: "페이지 만들기"
editPage: "페이지 수정"

View File

@@ -165,7 +165,6 @@ annotation: "Reacties"
federation: "Federatie"
instances: "Server"
registeredAt: "Geregistreerd op"
latestRequestSentAt: "Laatste aanvraag verstuurd"
latestRequestReceivedAt: "Laatste aanvraag ontvangen"
latestStatus: "Laatste status"
storageUsage: "Gebruikte opslagruimte"

View File

@@ -165,7 +165,6 @@ annotation: "Komentarze"
federation: "Federacja"
instances: "Instancja"
registeredAt: "Zarejestrowano"
latestRequestSentAt: "Ostatnie żądanie wysłano o"
latestRequestReceivedAt: "Ostatnie żądanie otrzymano o"
latestStatus: "Najnowszy status"
storageUsage: "Użycie pamięci"
@@ -867,6 +866,8 @@ pushNotificationNotSupported: "Przeglądarka lub instancja nie obsługuje powiad
sendPushNotificationReadMessage: "Usuń powiadomienia push po przeczytaniu powiadomień i wiadomości."
sendPushNotificationReadMessageCaption: "Chwilowo pojawi się powiadomienie \"{emptyPushNotificationMessage}\". Może wzrosnąć zużycie baterii urządzenia."
loggedInAsBot: "Jesteś obecnie zalogowany/a jako bot"
like: "Polub"
show: "Wyświetlanie"
_sensitiveMediaDetection:
description: "Zmniejsza wysiłek związany z moderacją serwera dzięki automatycznemu rozpoznawaniu zawartości NSFW za pomocą uczenia maszynowego. To nieznacznie zwiększy obciążenie serwera."
setSensitiveFlagAutomatically: "Oznacz jako NSFW"
@@ -1314,6 +1315,12 @@ _timelines:
local: "Lokalne"
social: "Społeczność"
global: "Globalna"
_play:
viewSource: "Zobacz źródło"
featured: "Wyróżnione"
title: "Tytuł"
script: "Skrypt"
summary: "Opis"
_pages:
newPage: "Utwórz stronę"
editPage: "Edytuj tę stronę"

View File

@@ -164,7 +164,6 @@ annotation: "Anotação"
federation: "União"
instances: "Instância"
registeredAt: "Registrado em"
latestRequestSentAt: "Enviar a solicitação mais recente"
latestRequestReceivedAt: "Recebeu a última solicitação"
latestStatus: "Status mais recente"
storageUsage: "Uso de armazenamento"

View File

@@ -164,7 +164,6 @@ annotation: "Adnotări"
federation: "Federație"
instances: "Instanțe"
registeredAt: "Înregistrat în"
latestRequestSentAt: "Ultima cerere trimisă"
latestRequestReceivedAt: "Ultima cerere primită"
latestStatus: "Ultimul status"
storageUsage: "Utilizare stocare"
@@ -648,6 +647,7 @@ middle: "Mediu"
sent: "Trimite"
searchByGoogle: "Caută"
file: "Fișiere"
show: "Arată"
_email:
_follow:
title: "te-a urmărit"
@@ -691,6 +691,9 @@ _charts:
federation: "Federație"
_timelines:
home: "Acasă"
_play:
script: "Script"
summary: "Descriere"
_pages:
blocks:
image: "Imagini"

View File

@@ -164,7 +164,6 @@ annotation: "Описание"
federation: "Федерация"
instances: "Инстанс"
registeredAt: "Первое наблюдение"
latestRequestSentAt: "Последний отправленный запрос"
latestRequestReceivedAt: "Последний полученный запрос"
latestStatus: "Последний статус"
storageUsage: "Использовано"
@@ -865,6 +864,8 @@ enableAutoSensitiveDescription: "Если доступно, используйт
account: "Учётные записи"
windowMaximize: "Развернуть"
windowRestore: "Восстановить"
like: "Нравится!"
show: "Отображение"
_sensitiveMediaDetection:
description: "Машинное обучение может быть использовано для автоматического обнаружения чувствительных медиа для модерации. Нагрузка на сервер увеличивается незначительно."
setSensitiveFlagAutomatically: "Установить флаг NSFW"
@@ -1333,6 +1334,12 @@ _timelines:
local: "Местная"
social: "Социальная"
global: "Всеобщая"
_play:
viewSource: "Просмотр исходника"
featured: "Популярные"
title: "Заголовок"
script: "Скрипт"
summary: "Описание"
_pages:
newPage: "Создать страницу"
editPage: "Править страницу"

View File

@@ -167,7 +167,6 @@ annotation: "Komentáre"
federation: "Federácia"
instances: "Inštancia"
registeredAt: "Registrácia"
latestRequestSentAt: "Posledná odoslaná požiadavka"
latestRequestReceivedAt: "Posledná prijatá požiadavka"
latestStatus: "Posledný status"
storageUsage: "Využité úložisko"
@@ -912,6 +911,12 @@ windowRestore: "Obnoviť"
caption: "Nadpis"
tools: "Nástroje"
cannotLoad: "Nedá sa načítať."
like: "Páči sa mi"
show: "Zobraziť"
neverShow: "Nabudúce nezobrazovať"
remindMeLater: "Pripomenúť neskôr"
didYouLikeMisskey: "Páči sa vám Misskey?"
pleaseDonate: "Misskey je bezplatný softvér, ktorý používa {host}. Prosím, prispejte, aby sme ho mohli ďalej rozvíjať!"
_sensitiveMediaDetection:
description: "Strojové učenie sa použije na automatickú detekciu citlivých médií na účely ich moderovania. Mierne sa zvýši zaťaženie servera."
sensitivity: "Citlivosť detekcie"
@@ -1414,6 +1419,12 @@ _timelines:
local: "Lokálne"
social: "Sociálne"
global: "Globálne"
_play:
viewSource: "Ukázať zdroj"
featured: "Význačné"
title: "Nadpis"
script: "Skript"
summary: "Popis"
_pages:
newPage: "Vytvoriť novú stránku"
editPage: "Upraviť túto stránku"

View File

@@ -2,6 +2,7 @@
_lang_: "Svenska"
headlineMisskey: "Ett nätverk kopplat av noter"
introMisskey: "Välkommen! Misskey är en öppen och decentraliserad mikrobloggningstjänst.\nSkapa en \"not\" och dela dina tankar med alla runtomkring dig. 📡\nMed \"reaktioner\" kan du snabbt uttrycka dina känslor kring andras noter.👍\nLåt oss utforska en nya värld!🚀"
poweredByMisskeyDescription: "{name} är en tjänst driven av den öppna källkodsplatformen <b>Misskey</b> (benämns \"Misskey instans\")."
monthAndDay: "{day}/{month}"
search: "Sök"
notifications: "Notifikationer"
@@ -12,6 +13,7 @@ fetchingAsApObject: "Hämtar från Fediversum..."
ok: "OK"
gotIt: "Uppfattat!"
cancel: "Avbryt"
noThankYou: "Nej tack"
enterUsername: "Ange användarnamn"
renotedBy: "Omnoterad av {user}"
noNotes: "Inga noteringar"
@@ -47,11 +49,13 @@ deleteAndEdit: "Radera och ändra"
deleteAndEditConfirm: "Är du säker att du vill radera denna not och ändra den? Du kommer förlora alla reaktioner, omnoteringar och svar till den."
addToList: "Lägg till i lista"
sendMessage: "Skicka ett meddelande"
copyRSS: "Kopiera RSS"
copyUsername: "Kopiera användarnamn"
searchUser: "Sök användare"
reply: "Svara"
loadMore: "Ladda mer"
showMore: "Visa mer"
showLess: "Stäng"
youGotNewFollower: "följde dig"
receiveFollowRequest: "Följarförfrågan mottagen"
followRequestAccepted: "Följarförfrågan accepterad"
@@ -163,7 +167,6 @@ annotation: "Kommentarer"
federation: "Federation"
instances: "Instanser"
registeredAt: "Registrerad på"
latestRequestSentAt: "Senaste förfrågan skickad"
latestRequestReceivedAt: "Senaste begäran mottagen"
latestStatus: "Senaste status"
storageUsage: "Använt lagringsutrymme"
@@ -239,6 +242,17 @@ saved: "Sparad"
messaging: "Chatt"
upload: "Ladda upp"
keepOriginalUploading: "Behåll originalbild"
keepOriginalUploadingDescription: "Sparar den originellt uppladdade bilden i sitt i befintliga skick. Om avstängd, kommer en webbversion bli genererad vid uppladdning."
fromDrive: "Från Drive"
fromUrl: "Från en länk"
uploadFromUrl: "Ladda upp från länk"
uploadFromUrlDescription: "Länken av filen du vill ladda upp"
uploadFromUrlRequested: "Uppladdning begärd"
uploadFromUrlMayTakeTime: "Det kan ta tid tills att uppladdningen blir klar."
explore: "Utforska"
messageRead: "Läs"
noMoreHistory: "Det finns ingen mer historik"
startMessaging: "Starta en chatt"
nsfw: "Känsligt innehåll"
pinnedNotes: "Fästad not"
userList: "Listor"

View File

@@ -167,7 +167,6 @@ annotation: "ความคิดเห็น"
federation: "เฟดิเวิร์ส"
instances: "ตัวอย่าง"
registeredAt: "จดทะเบียนที่"
latestRequestSentAt: "ส่งคำขอล่าสุดไปแล้ว"
latestRequestReceivedAt: "ได้รับคำขอล่าสุดไปแล้ว"
latestStatus: "สถานะล่าสุด"
storageUsage: "พื้นที่จัดเก็บข้อมูลที่ใช้ไป"
@@ -916,6 +915,11 @@ caption: "รายละเอียด"
loggedInAsBot: "ล็อกอินเป็นบอตอยู่ในขณะนี้"
tools: "เครื่องมือ"
cannotLoad: "ไม่สามารถโหลดได้"
numberOfProfileView: "มุมมองโปรไฟล์"
like: "ชื่นชอบ"
unlike: "ไม่ชอบ"
numberOfLikes: "จำนวนไลค์"
show: "แสดงผล"
_sensitiveMediaDetection:
description: "ลดความพยายามในการดูแลเซิร์ฟเวอร์ผ่านการจดจำสื่อ NSFW โดยอัตโนมัติผ่านการเรียนรู้ของเครื่อง การทำสิ่งนี้อาจจะเพิ่มภาระบนเซิร์ฟเวอร์เล็กน้อย"
sensitivity: "การตรวจจับความไว"
@@ -1315,6 +1319,7 @@ _widgets:
jobQueue: "คิวงาน"
serverMetric: "ตัวชี้วัดเซิร์ฟเวอร์"
aiscript: "AiScript คอนโซล"
aiscriptApp: "AiScript แอพ"
aichan: "เอไอ"
userList: "รายชื่อผู้ใช้"
_userList:
@@ -1420,6 +1425,21 @@ _timelines:
local: "ในพื้นที่"
social: "โซเชี่ยล"
global: "ทั่วโลก"
_play:
new: "สร้างการเล่น"
edit: "แก้ไขเล่น"
created: "สร้างการเล่นแล้ว"
updated: "แก้ไขการเล่นแล้ว"
deleted: "ลบการเล่นแล้ว"
pageSetting: "ตั้งค่าการเล่น"
editThisPage: "แก้ไข Play นี้"
viewSource: "ดูต้นฉบับ"
my: "มาย เพลย์"
liked: "ไลค์ เพลย์"
featured: "เป็นที่นิยม"
title: "หัวข้อ"
script: "สคริปต์"
summary: "รายละเอียด"
_pages:
newPage: "สร้างหน้าเพจใหม่"
editPage: "แก้ไขหน้าเพจ"

View File

@@ -166,7 +166,6 @@ annotation: "Коментарі"
federation: "Федіверс"
instances: "Інстанс"
registeredAt: "Приєднався(лась)"
latestRequestSentAt: "Останній запит надіслано"
latestRequestReceivedAt: "Останній запит прийнято"
latestStatus: "Останній статус"
storageUsage: "Використання простору"
@@ -893,6 +892,8 @@ unsubscribePushNotification: "Вимкнути push-сповіщення"
windowMaximize: "Розгорнути"
windowRestore: "Відновити"
caption: "Підпис"
like: "Вподобати"
show: "Відображення"
_sensitiveMediaDetection:
sensitivity: "Чутливість детектування"
setSensitiveFlagAutomatically: "Позначити як NSFW"
@@ -1349,6 +1350,12 @@ _timelines:
local: "Локальна"
social: "Соціальна"
global: "Глобальна"
_play:
viewSource: "Переглянути вихідний код"
featured: "Популярні"
title: "Заголовок"
script: "Скрипт"
summary: "Опис"
_pages:
newPage: "Створити сторінку"
editPage: "Редагувати сторінку"

View File

@@ -164,7 +164,6 @@ annotation: "Bình luận"
federation: "Liên hợp"
instances: "Máy chủ"
registeredAt: "Đăng ký vào"
latestRequestSentAt: "Yêu cầu cuối gửi lúc"
latestRequestReceivedAt: "Yêu cầu cuối nhận lúc"
latestStatus: "Trạng thái cuối cùng"
storageUsage: "Dung lượng lưu trữ"
@@ -895,6 +894,8 @@ navbar: "Thanh điều hướng"
shuffle: "Xáo trộn"
account: "Tài khoản của bạn"
move: "Di chuyển"
like: "Thích"
show: "Hiển thị"
_sensitiveMediaDetection:
description: "Giảm nỗ lực kiểm duyệt máy chủ thông qua việc tự động nhận dạng media NSFW thông qua học máy. Điều này sẽ làm tăng một chút áp lực trên máy chủ."
sensitivity: "Phát hiện nhạy cảm"
@@ -1394,6 +1395,12 @@ _timelines:
local: "Máy chủ này"
social: "Xã hội"
global: "Liên hợp"
_play:
viewSource: "Xem mã nguồn"
featured: "Nổi tiếng"
title: "Tựa đề"
script: "Kịch bản"
summary: "Mô tả"
_pages:
newPage: "Tạo Trang mới"
editPage: "Sửa Trang này"

View File

@@ -167,7 +167,6 @@ annotation: "注解"
federation: "联合"
instances: "实例"
registeredAt: "初次观测"
latestRequestSentAt: "上次发送的请求"
latestRequestReceivedAt: "上次收到的请求"
latestStatus: "最后状态"
storageUsage: "已用存储"
@@ -913,9 +912,14 @@ sendPushNotificationReadMessageCaption: "“{emptyPushNotificationMessage}”的
windowMaximize: "最大化"
windowRestore: "还原"
caption: "标题"
loggedInAsBot: "已登录的Bot"
loggedInAsBot: "以Bot账户登录"
tools: "工具"
cannotLoad: "无法加载"
numberOfProfileView: "个人资料展示次数"
like: "点赞!"
unlike: "取消赞"
numberOfLikes: "点赞数"
show: "显示"
_sensitiveMediaDetection:
description: "可以使用机器学习技术自动检测敏感媒体,以便进行审核。服务器负载将略微增加。"
sensitivity: "检测敏感度"
@@ -1049,8 +1053,8 @@ _mfm:
shakeDescription: "显示摇晃的动画效果。"
twitch: "动画(颤抖)"
twitchDescription: "显示强烈颤抖的动画效果。"
spin: "动画(转)"
spinDescription: "显示转的动画效果。"
spin: "动画(转)"
spinDescription: "显示转的动画效果。"
x2: "大"
x2Description: "以大尺寸显示内容。"
x3: "非常大"
@@ -1315,6 +1319,7 @@ _widgets:
jobQueue: "作业队列"
serverMetric: "服务器指标"
aiscript: "AiScript控制台"
aiscriptApp: "AiScript App"
aichan: "小蓝"
userList: "用户列表"
_userList:
@@ -1382,6 +1387,7 @@ _profile:
changeBanner: "修改横幅"
_exportOrImport:
allNotes: "所有帖子"
favoritedNotes: "收藏的帖子"
followingList: "关注中"
muteList: "屏蔽"
blockingList: "拉黑"
@@ -1419,6 +1425,21 @@ _timelines:
local: "本地"
social: "社交"
global: "全局"
_play:
new: "创建Play"
edit: "编辑Play"
created: "创建了一个Play"
updated: "更新了Play"
deleted: "删除了Play"
pageSetting: "Play设置"
editThisPage: "编辑此Play"
viewSource: "查看源代码"
my: "我的Play"
liked: "点赞的Play"
featured: "热门"
title: "标题"
script: "脚本"
summary: "描述"
_pages:
newPage: "创建页面"
editPage: "编辑页面"

View File

@@ -167,7 +167,6 @@ annotation: "註解"
federation: "站台聯邦"
instances: "實例"
registeredAt: "初次觀測"
latestRequestSentAt: "上次發送的請求"
latestRequestReceivedAt: "上次收到的請求"
latestStatus: "最後狀態"
storageUsage: "已使用容量"
@@ -917,6 +916,13 @@ loggedInAsBot: "以機器人帳號登入中"
tools: "工具"
cannotLoad: "無法載入"
numberOfProfileView: "個人檔案檢視次數"
like: "讚"
unlike: "收回讚"
numberOfLikes: "讚數"
show: "檢視"
neverShow: "不再顯示"
remindMeLater: "以後再說"
didYouLikeMisskey: "您是否喜愛Misskey呢"
_sensitiveMediaDetection:
description: "您可以使用機器學習自動檢測敏感媒體並將其用於審核。 伺服器的負荷會稍微增加。"
sensitivity: "檢測敏感度"
@@ -1316,6 +1322,7 @@ _widgets:
jobQueue: "佇列"
serverMetric: "服務器指標 "
aiscript: "AiScript控制台"
aiscriptApp: "AiScript App"
aichan: "小藍"
userList: "使用者列表"
_userList:
@@ -1421,6 +1428,21 @@ _timelines:
local: "本地"
social: "社群"
global: "公開"
_play:
new: "新增Play"
edit: "編輯Play"
created: "已新增Play"
updated: "已更新Play"
deleted: "已刪除Play"
pageSetting: "Play設定"
editThisPage: "編輯這個Play"
viewSource: "檢視原始碼"
my: "自己的Play"
liked: "按了讚的Play"
featured: "人氣"
title: "標題"
script: "腳本"
summary: "描述"
_pages:
newPage: "建立頁面"
editPage: "編輯頁面"

View File

@@ -1,6 +1,6 @@
{
"name": "misskey",
"version": "13.0.0-beta.16",
"version": "13.0.0-beta.35",
"codename": "indigo",
"repository": {
"type": "git",
@@ -53,11 +53,11 @@
"devDependencies": {
"@types/gulp": "4.0.10",
"@types/gulp-rename": "2.0.1",
"@typescript-eslint/eslint-plugin": "5.47.1",
"@typescript-eslint/parser": "5.47.1",
"@typescript-eslint/eslint-plugin": "5.48.0",
"@typescript-eslint/parser": "5.48.0",
"cross-env": "7.0.3",
"cypress": "12.2.0",
"eslint": "^8.30.0",
"cypress": "12.3.0",
"eslint": "^8.31.0",
"start-server-and-test": "1.15.2",
"typescript": "4.9.4"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@@ -1,5 +0,0 @@
Font Awesome Icons
-------------------------
Ⓒ Font Awesome
CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 577 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 844 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 507 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 689 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 772 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 930 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 798 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 991 B

View File

@@ -0,0 +1,24 @@
Tabler Icons
https://github.com/tabler/tabler-icons/blob/master/LICENSE
====
MIT License
Copyright (c) 2020-2022 Paweł Kuna
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

Binary file not shown.

After

Width:  |  Height:  |  Size: 516 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 952 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 829 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 174 B

After

Width:  |  Height:  |  Size: 174 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 414 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1011 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -0,0 +1,11 @@
export class removeLatestRequestSentAt1672703171386 {
name = 'removeLatestRequestSentAt1672703171386'
async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "instance" DROP COLUMN "latestRequestSentAt"`);
}
async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "instance" ADD "latestRequestSentAt" TIMESTAMP WITH TIME ZONE`);
}
}

View File

@@ -0,0 +1,11 @@
export class removeLastCommunicatedAt1672704017999 {
name = 'removeLastCommunicatedAt1672704017999'
async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "instance" DROP COLUMN "lastCommunicatedAt"`);
}
async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "instance" ADD "lastCommunicatedAt" TIMESTAMP WITH TIME ZONE NOT NULL`);
}
}

View File

@@ -0,0 +1,11 @@
export class removeLatestStatus1672704136584 {
name = 'removeLatestStatus1672704136584'
async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "instance" DROP COLUMN "latestStatus"`);
}
async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "instance" ADD "latestStatus" integer`);
}
}

View File

@@ -0,0 +1,29 @@
export class Flash1672822262496 {
name = 'Flash1672822262496'
async up(queryRunner) {
await queryRunner.query(`CREATE TABLE "flash" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL, "title" character varying(256) NOT NULL, "summary" character varying(1024) NOT NULL, "userId" character varying(32) NOT NULL, "script" character varying(16384) NOT NULL, "permissions" character varying(256) array NOT NULL DEFAULT '{}', "likedCount" integer NOT NULL DEFAULT '0', CONSTRAINT "PK_0c01a2c1c5f2266942dd1b3fdbc" PRIMARY KEY ("id")); COMMENT ON COLUMN "flash"."createdAt" IS 'The created date of the Flash.'; COMMENT ON COLUMN "flash"."updatedAt" IS 'The updated date of the Flash.'; COMMENT ON COLUMN "flash"."userId" IS 'The ID of author.'`);
await queryRunner.query(`CREATE INDEX "IDX_149d2e44785707548c82999b01" ON "flash" ("createdAt") `);
await queryRunner.query(`CREATE INDEX "IDX_3aa8ea9a8f15214ad91638c0a7" ON "flash" ("updatedAt") `);
await queryRunner.query(`CREATE INDEX "IDX_9b88250fc2fd009b8f1b5623ed" ON "flash" ("userId") `);
await queryRunner.query(`CREATE TABLE "flash_like" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "flashId" character varying(32) NOT NULL, CONSTRAINT "PK_d110109ee310588d63d6183b233" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE INDEX "IDX_60c4af1c19a7a75f1592f93b28" ON "flash_like" ("userId") `);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_cfbfeeccb0cbedcd660b17eb07" ON "flash_like" ("userId", "flashId") `);
await queryRunner.query(`ALTER TABLE "flash" ADD CONSTRAINT "FK_9b88250fc2fd009b8f1b5623ed5" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "flash_like" ADD CONSTRAINT "FK_60c4af1c19a7a75f1592f93b287" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "flash_like" ADD CONSTRAINT "FK_6c16fe0e93b7a1951eca624b76a" FOREIGN KEY ("flashId") REFERENCES "flash"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
}
async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "flash_like" DROP CONSTRAINT "FK_6c16fe0e93b7a1951eca624b76a"`);
await queryRunner.query(`ALTER TABLE "flash_like" DROP CONSTRAINT "FK_60c4af1c19a7a75f1592f93b287"`);
await queryRunner.query(`ALTER TABLE "flash" DROP CONSTRAINT "FK_9b88250fc2fd009b8f1b5623ed5"`);
await queryRunner.query(`DROP INDEX "public"."IDX_cfbfeeccb0cbedcd660b17eb07"`);
await queryRunner.query(`DROP INDEX "public"."IDX_60c4af1c19a7a75f1592f93b28"`);
await queryRunner.query(`DROP TABLE "flash_like"`);
await queryRunner.query(`DROP INDEX "public"."IDX_9b88250fc2fd009b8f1b5623ed"`);
await queryRunner.query(`DROP INDEX "public"."IDX_3aa8ea9a8f15214ad91638c0a7"`);
await queryRunner.query(`DROP INDEX "public"."IDX_149d2e44785707548c82999b01"`);
await queryRunner.query(`DROP TABLE "flash"`);
}
}

View File

@@ -21,9 +21,9 @@
"@tensorflow/tfjs-node": "4.1.0"
},
"dependencies": {
"@bull-board/api": "^4.9.0",
"@bull-board/fastify": "^4.9.0",
"@bull-board/ui": "^4.9.0",
"@bull-board/api": "^4.10.1",
"@bull-board/fastify": "^4.10.1",
"@bull-board/ui": "^4.10.1",
"@discordapp/twemoji": "14.0.2",
"@fastify/accepts": "4.1.0",
"@fastify/cookie": "^8.3.0",
@@ -37,12 +37,11 @@
"@nestjs/testing": "9.2.1",
"@peertube/http-signature": "1.7.0",
"@sinonjs/fake-timers": "10.0.2",
"@syuilo/aiscript": "0.11.1",
"accepts": "^1.3.8",
"ajv": "8.11.2",
"ajv": "8.12.0",
"archiver": "5.3.1",
"autwh": "0.1.0",
"aws-sdk": "2.1272.0",
"aws-sdk": "2.1289.0",
"bcryptjs": "2.4.3",
"blurhash": "2.0.4",
"bull": "4.10.2",
@@ -57,7 +56,7 @@
"date-fns": "2.29.3",
"deep-email-validator": "0.1.21",
"escape-regexp": "0.0.1",
"fastify": "4.10.2",
"fastify": "4.11.0",
"feed": "4.2.2",
"file-type": "18.0.0",
"fluent-ffmpeg": "2.1.2",
@@ -69,11 +68,11 @@
"is-svg": "4.3.2",
"js-yaml": "4.1.0",
"jsdom": "20.0.3",
"json5": "2.2.2",
"json5": "2.2.3",
"json5-loader": "4.0.1",
"jsonld": "8.1.0",
"jsrsasign": "10.6.1",
"mfm-js": "0.23.0",
"mfm-js": "0.23.1",
"mime-types": "2.1.35",
"misskey-js": "0.0.14",
"ms": "3.0.0-canary.1",
@@ -111,11 +110,11 @@
"stringz": "2.1.0",
"summaly": "2.7.0",
"syslog-pro": "git+https://github.com/misskey-dev/SyslogPro#0.2.9-misskey.2",
"systeminformation": "5.16.9",
"tinycolor2": "1.5.1",
"systeminformation": "5.17.1",
"tinycolor2": "1.5.2",
"tmp": "0.2.1",
"tsc-alias": "1.8.2",
"tsconfig-paths": "4.1.1",
"tsconfig-paths": "4.1.2",
"twemoji-parser": "14.0.0",
"typeorm": "0.3.11",
"ulid": "2.3.0",
@@ -129,7 +128,7 @@
},
"devDependencies": {
"@redocly/openapi-core": "1.0.0-beta.117",
"@swc/core": "1.3.24",
"@swc/core": "1.3.25",
"@swc/jest": "0.2.24",
"@types/accepts": "1.3.5",
"@types/archiver": "5.3.1",
@@ -141,7 +140,7 @@
"@types/escape-regexp": "0.0.1",
"@types/fluent-ffmpeg": "2.1.20",
"@types/ioredis": "4.28.10",
"@types/jest": "29.2.4",
"@types/jest": "29.2.5",
"@types/js-yaml": "4.0.5",
"@types/jsdom": "20.0.1",
"@types/jsonld": "1.5.8",
@@ -161,7 +160,7 @@
"@types/rename": "1.0.4",
"@types/sanitize-html": "2.8.0",
"@types/semver": "7.3.13",
"@types/sharp": "0.31.0",
"@types/sharp": "0.31.1",
"@types/sinonjs__fake-timers": "8.1.2",
"@types/speakeasy": "2.0.7",
"@types/syslog-pro": "^1.0.0",
@@ -172,11 +171,11 @@
"@types/vary": "1.1.0",
"@types/web-push": "3.3.2",
"@types/websocket": "1.0.5",
"@types/ws": "8.5.3",
"@typescript-eslint/eslint-plugin": "5.47.1",
"@typescript-eslint/parser": "5.47.1",
"@types/ws": "8.5.4",
"@typescript-eslint/eslint-plugin": "5.48.0",
"@typescript-eslint/parser": "5.48.0",
"cross-env": "7.0.3",
"eslint": "8.30.0",
"eslint": "8.31.0",
"eslint-plugin-import": "2.26.0",
"execa": "6.1.0",
"jest": "29.3.1",

View File

@@ -15,8 +15,8 @@ import type { Packed } from '@/misc/schema.js';
import { DI } from '@/di-symbols.js';
import type { MutingsRepository, BlockingsRepository, NotesRepository, AntennaNotesRepository, AntennasRepository, UserGroupJoiningsRepository, UserListJoiningsRepository } from '@/models/index.js';
import { UtilityService } from '@/core/UtilityService.js';
import type { OnApplicationShutdown } from '@nestjs/common';
import { bindThis } from '@/decorators.js';
import type { OnApplicationShutdown } from '@nestjs/common';
@Injectable()
export class AntennaService implements OnApplicationShutdown {
@@ -135,7 +135,7 @@ export class AntennaService implements OnApplicationShutdown {
this.globalEventServie.publishMainStream(antenna.userId, 'unreadAntenna', antenna);
this.pushNotificationService.pushNotification(antenna.userId, 'unreadAntennaNote', {
antenna: { id: antenna.id, name: antenna.name },
note: await this.noteEntityService.pack(note)
note: await this.noteEntityService.pack(note),
});
}
}, 2000);
@@ -144,27 +144,19 @@ export class AntennaService implements OnApplicationShutdown {
// NOTE: フォローしているユーザーのノート、リストのユーザーのノート、グループのユーザーのノート指定はパフォーマンス上の理由で無効になっている
/**
* noteUserFollowers / antennaUserFollowing はどちらか一方が指定されていればよい
*/
@bindThis
public async checkHitAntenna(antenna: Antenna, note: (Note | Packed<'Note'>), noteUser: { id: User['id']; username: string; host: string | null; }, noteUserFollowers?: User['id'][], antennaUserFollowing?: User['id'][]): Promise<boolean> {
public async checkHitAntenna(antenna: Antenna, note: (Note | Packed<'Note'>), noteUser: { id: User['id']; username: string; host: string | null; }): Promise<boolean> {
if (note.visibility === 'specified') return false;
if (note.visibility === 'followers') return false;
// アンテナ作成者がノート作成者にブロックされていたらスキップ
const blockings = await this.blockingCache.fetch(noteUser.id, () => this.blockingsRepository.findBy({ blockerId: noteUser.id }).then(res => res.map(x => x.blockeeId)));
if (blockings.some(blocking => blocking === antenna.userId)) return false;
if (note.visibility === 'followers') {
if (noteUserFollowers && !noteUserFollowers.includes(antenna.userId)) return false;
if (antennaUserFollowing && !antennaUserFollowing.includes(note.userId)) return false;
}
if (!antenna.withReplies && note.replyId != null) return false;
if (antenna.src === 'home') {
if (noteUserFollowers && !noteUserFollowers.includes(antenna.userId)) return false;
if (antennaUserFollowing && !antennaUserFollowing.includes(note.userId)) return false;
// TODO
} else if (antenna.src === 'list') {
const listUsers = (await this.userListJoiningsRepository.findBy({
userListId: antenna.userListId!,

View File

@@ -95,6 +95,8 @@ import { UserEntityService } from './entities/UserEntityService.js';
import { UserGroupEntityService } from './entities/UserGroupEntityService.js';
import { UserGroupInvitationEntityService } from './entities/UserGroupInvitationEntityService.js';
import { UserListEntityService } from './entities/UserListEntityService.js';
import { FlashEntityService } from './entities/FlashEntityService.js';
import { FlashLikeEntityService } from './entities/FlashLikeEntityService.js';
import { ApAudienceService } from './activitypub/ApAudienceService.js';
import { ApDbResolverService } from './activitypub/ApDbResolverService.js';
import { ApDeliverManagerService } from './activitypub/ApDeliverManagerService.js';
@@ -216,6 +218,8 @@ const $UserEntityService: Provider = { provide: 'UserEntityService', useExisting
const $UserGroupEntityService: Provider = { provide: 'UserGroupEntityService', useExisting: UserGroupEntityService };
const $UserGroupInvitationEntityService: Provider = { provide: 'UserGroupInvitationEntityService', useExisting: UserGroupInvitationEntityService };
const $UserListEntityService: Provider = { provide: 'UserListEntityService', useExisting: UserListEntityService };
const $FlashEntityService: Provider = { provide: 'FlashEntityService', useExisting: FlashEntityService };
const $FlashLikeEntityService: Provider = { provide: 'FlashLikeEntityService', useExisting: FlashLikeEntityService };
const $ApAudienceService: Provider = { provide: 'ApAudienceService', useExisting: ApAudienceService };
const $ApDbResolverService: Provider = { provide: 'ApDbResolverService', useExisting: ApDbResolverService };
@@ -338,6 +342,8 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting
UserGroupEntityService,
UserGroupInvitationEntityService,
UserListEntityService,
FlashEntityService,
FlashLikeEntityService,
ApAudienceService,
ApDbResolverService,
ApDeliverManagerService,
@@ -455,6 +461,8 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting
$UserGroupEntityService,
$UserGroupInvitationEntityService,
$UserListEntityService,
$FlashEntityService,
$FlashLikeEntityService,
$ApAudienceService,
$ApDbResolverService,
$ApDeliverManagerService,
@@ -572,6 +580,8 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting
UserGroupEntityService,
UserGroupInvitationEntityService,
UserListEntityService,
FlashEntityService,
FlashLikeEntityService,
ApAudienceService,
ApDbResolverService,
ApDeliverManagerService,
@@ -688,6 +698,8 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting
$UserGroupEntityService,
$UserGroupInvitationEntityService,
$UserListEntityService,
$FlashEntityService,
$FlashLikeEntityService,
$ApAudienceService,
$ApDbResolverService,
$ApDeliverManagerService,

View File

@@ -22,7 +22,7 @@ export class FederatedInstanceService {
}
@bindThis
public async registerOrFetchInstanceDoc(host: string): Promise<Instance> {
public async fetch(host: string): Promise<Instance> {
host = this.utilityService.toPuny(host);
const cached = this.cache.get(host);
@@ -35,7 +35,6 @@ export class FederatedInstanceService {
id: this.idService.genId(),
host,
caughtAt: new Date(),
lastCommunicatedAt: new Date(),
}).then(x => this.instancesRepository.findOneByOrFail(x.identifiers[0]));
this.cache.set(host, i);
@@ -45,4 +44,17 @@ export class FederatedInstanceService {
return index;
}
}
@bindThis
public async updateCachePartial(host: string, data: Partial<Instance>): Promise<void> {
host = this.utilityService.toPuny(host);
const cached = this.cache.get(host);
if (cached == null) return;
this.cache.set(host, {
...cached,
...data,
});
}
}

View File

@@ -398,13 +398,13 @@ export class FileInfoService {
.raw()
.ensureAlpha()
.resize(64, 64, { fit: 'inside' })
.toBuffer((err, buffer, { width, height }) => {
.toBuffer((err, buffer, info) => {
if (err) return reject(err);
let hash;
try {
hash = encode(new Uint8ClampedArray(buffer), width, height, 5, 5);
hash = encode(new Uint8ClampedArray(buffer), info.width, info.height, 5, 5);
} catch (e) {
return reject(e);
}

View File

@@ -428,7 +428,7 @@ export class NoteCreateService {
// Register host
if (this.userEntityService.isRemoteUser(user)) {
this.federatedInstanceService.registerOrFetchInstanceDoc(user.host).then(i => {
this.federatedInstanceService.fetch(user.host).then(i => {
this.instancesRepository.increment({ id: i.id }, 'notesCount', 1);
this.instanceChart.updateNote(i.host, note, true);
});

View File

@@ -100,7 +100,7 @@ export class NoteDeleteService {
this.perUserNotesChart.update(user, note, false);
if (this.userEntityService.isRemoteUser(user)) {
this.federatedInstanceService.registerOrFetchInstanceDoc(user.host).then(i => {
this.federatedInstanceService.fetch(user.host).then(i => {
this.instancesRepository.decrement({ id: i.id }, 'notesCount', 1);
this.instanceChart.updateNote(i.host, note, false);
});

View File

@@ -92,13 +92,6 @@ export class PollService {
choice: choice,
userId: user.id,
});
// Notify
this.createNotificationService.createNotification(note.userId, 'pollVote', {
notifierId: user.id,
noteId: note.id,
choice: choice,
});
}
@bindThis

View File

@@ -47,26 +47,6 @@ function truncateBody<T extends keyof pushNotificationsTypes>(type: T, body: pus
return body;
}
function truncateUnreadAntennaNote(notification: pushNotificationsTypes['unreadAntennaNote']): pushNotificationsTypes['unreadAntennaNote'] {
if (notification.note) {
return {
...notification,
note: {
...notification.note,
// textをgetNoteSummaryしたものに置き換える
text: getNoteSummary(('type' in notification && notification.type === 'renote') ? notification.note.renote as Packed<'Note'> : notification.note),
cw: undefined,
reply: undefined,
renote: undefined,
user: undefined as any, // 通知を受け取ったユーザーである場合が多いのでこれも捨てる アンテナの場合も不要なのでいらない
},
};
}
return notification;
}
@Injectable()
export class PushNotificationService {
constructor(

View File

@@ -205,12 +205,12 @@ export class UserFollowingService {
//#region Update instance stats
if (this.userEntityService.isRemoteUser(follower) && this.userEntityService.isLocalUser(followee)) {
this.federatedInstanceService.registerOrFetchInstanceDoc(follower.host).then(i => {
this.federatedInstanceService.fetch(follower.host).then(i => {
this.instancesRepository.increment({ id: i.id }, 'followingCount', 1);
this.instanceChart.updateFollowing(i.host, true);
});
} else if (this.userEntityService.isLocalUser(follower) && this.userEntityService.isRemoteUser(followee)) {
this.federatedInstanceService.registerOrFetchInstanceDoc(followee.host).then(i => {
this.federatedInstanceService.fetch(followee.host).then(i => {
this.instancesRepository.increment({ id: i.id }, 'followersCount', 1);
this.instanceChart.updateFollowers(i.host, true);
});
@@ -323,12 +323,12 @@ export class UserFollowingService {
//#region Update instance stats
if (this.userEntityService.isRemoteUser(follower) && this.userEntityService.isLocalUser(followee)) {
this.federatedInstanceService.registerOrFetchInstanceDoc(follower.host).then(i => {
this.federatedInstanceService.fetch(follower.host).then(i => {
this.instancesRepository.decrement({ id: i.id }, 'followingCount', 1);
this.instanceChart.updateFollowing(i.host, false);
});
} else if (this.userEntityService.isLocalUser(follower) && this.userEntityService.isRemoteUser(followee)) {
this.federatedInstanceService.registerOrFetchInstanceDoc(followee.host).then(i => {
this.federatedInstanceService.fetch(followee.host).then(i => {
this.instancesRepository.decrement({ id: i.id }, 'followersCount', 1);
this.instanceChart.updateFollowers(i.host, false);
});

View File

@@ -348,7 +348,7 @@ export class ApPersonService implements OnModuleInit {
}
// Register host
this.federatedInstanceService.registerOrFetchInstanceDoc(host).then(i => {
this.federatedInstanceService.fetch(host).then(i => {
this.instancesRepository.increment({ id: i.id }, 'usersCount', 1);
this.instanceChart.newUser(i.host);
this.fetchInstanceMetadataService.fetchInstanceMetadata(i);

View File

@@ -86,7 +86,7 @@ export default class FederationChart extends Chart<typeof schema> {
.where(`instance.host IN (${ subInstancesQuery.getQuery() })`)
.andWhere(meta.blockedHosts.length === 0 ? '1=1' : 'instance.host NOT IN (:...blocked)', { blocked: meta.blockedHosts })
.andWhere('instance.isSuspended = false')
.andWhere('instance.lastCommunicatedAt > :gt', { gt: new Date(Date.now() - (1000 * 60 * 60 * 24 * 30)) })
.andWhere('instance.isNotResponding = false')
.getRawOne()
.then(x => parseInt(x.count, 10)),
this.instancesRepository.createQueryBuilder('instance')
@@ -94,7 +94,7 @@ export default class FederationChart extends Chart<typeof schema> {
.where(`instance.host IN (${ pubInstancesQuery.getQuery() })`)
.andWhere(meta.blockedHosts.length === 0 ? '1=1' : 'instance.host NOT IN (:...blocked)', { blocked: meta.blockedHosts })
.andWhere('instance.isSuspended = false')
.andWhere('instance.lastCommunicatedAt > :gt', { gt: new Date(Date.now() - (1000 * 60 * 60 * 24 * 30)) })
.andWhere('instance.isNotResponding = false')
.getRawOne()
.then(x => parseInt(x.count, 10)),
]);

View File

@@ -22,23 +22,25 @@ export class EmojiEntityService {
@bindThis
public async pack(
src: Emoji['id'] | Emoji,
opts: { omitHost?: boolean; omitId?: boolean; } = {},
): Promise<Packed<'Emoji'>> {
const emoji = typeof src === 'object' ? src : await this.emojisRepository.findOneByOrFail({ id: src });
return {
id: emoji.id,
id: opts.omitId ? undefined : emoji.id,
aliases: emoji.aliases,
name: emoji.name,
category: emoji.category,
host: emoji.host,
host: opts.omitHost ? undefined : emoji.host,
};
}
@bindThis
public packMany(
emojis: any[],
opts: { omitHost?: boolean; omitId?: boolean; } = {},
) {
return Promise.all(emojis.map(x => this.pack(x)));
return Promise.all(emojis.map(x => this.pack(x, opts)));
}
}

View File

@@ -0,0 +1,55 @@
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/schema.js';
import type { } from '@/models/entities/Blocking.js';
import type { User } from '@/models/entities/User.js';
import type { Flash } from '@/models/entities/Flash.js';
import { bindThis } from '@/decorators.js';
import { UserEntityService } from './UserEntityService.js';
@Injectable()
export class FlashEntityService {
constructor(
@Inject(DI.flashsRepository)
private flashsRepository: FlashsRepository,
@Inject(DI.flashLikesRepository)
private flashLikesRepository: FlashLikesRepository,
private userEntityService: UserEntityService,
) {
}
@bindThis
public async pack(
src: Flash['id'] | Flash,
me?: { id: User['id'] } | null | undefined,
): Promise<Packed<'Flash'>> {
const meId = me ? me.id : null;
const flash = typeof src === 'object' ? src : await this.flashsRepository.findOneByOrFail({ id: src });
return await awaitAll({
id: flash.id,
createdAt: flash.createdAt.toISOString(),
updatedAt: flash.updatedAt.toISOString(),
userId: flash.userId,
user: this.userEntityService.pack(flash.user ?? flash.userId, me), // { detail: true } すると無限ループするので注意
title: flash.title,
summary: flash.summary,
script: flash.script,
likedCount: flash.likedCount,
isLiked: meId ? await this.flashLikesRepository.findOneBy({ flashId: flash.id, userId: meId }).then(x => x != null) : undefined,
});
}
@bindThis
public packMany(
flashs: Flash[],
me?: { id: User['id'] } | null | undefined,
) {
return Promise.all(flashs.map(x => this.pack(x, me)));
}
}

View File

@@ -0,0 +1,44 @@
import { Inject, Injectable } from '@nestjs/common';
import { DI } from '@/di-symbols.js';
import type { FlashLikesRepository } from '@/models/index.js';
import { awaitAll } from '@/misc/prelude/await-all.js';
import type { Packed } from '@/misc/schema.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';
import { UserEntityService } from './UserEntityService.js';
import { FlashEntityService } from './FlashEntityService.js';
@Injectable()
export class FlashLikeEntityService {
constructor(
@Inject(DI.flashLikesRepository)
private flashLikesRepository: FlashLikesRepository,
private flashEntityService: FlashEntityService,
) {
}
@bindThis
public async pack(
src: FlashLike['id'] | FlashLike,
me?: { id: User['id'] } | null | undefined,
) {
const like = typeof src === 'object' ? src : await this.flashLikesRepository.findOneByOrFail({ id: src });
return {
id: like.id,
flash: await this.flashEntityService.pack(like.flash ?? like.flashId, me),
};
}
@bindThis
public packMany(
likes: any[],
me: { id: User['id'] },
) {
return Promise.all(likes.map(x => this.pack(x, me)));
}
}

View File

@@ -7,8 +7,8 @@ import type { } from '@/models/entities/Blocking.js';
import type { User } from '@/models/entities/User.js';
import type { Instance } from '@/models/entities/Instance.js';
import { MetaService } from '@/core/MetaService.js';
import { UserEntityService } from './UserEntityService.js';
import { bindThis } from '@/decorators.js';
import { UserEntityService } from './UserEntityService.js';
@Injectable()
export class InstanceEntityService {
@@ -33,8 +33,6 @@ export class InstanceEntityService {
notesCount: instance.notesCount,
followingCount: instance.followingCount,
followersCount: instance.followersCount,
latestRequestSentAt: instance.latestRequestSentAt ? instance.latestRequestSentAt.toISOString() : null,
lastCommunicatedAt: instance.lastCommunicatedAt.toISOString(),
isNotResponding: instance.isNotResponding,
isSuspended: instance.isSuspended,
isBlocked: meta.blockedHosts.includes(instance.host),

View File

@@ -98,7 +98,7 @@ export class NotificationEntityService implements OnModuleInit {
}),
reaction: notification.reaction,
} : {}),
...(notification.type === 'pollVote' ? {
...(notification.type === 'pollVote' ? { // TODO: そのうち消す
note: this.noteEntityService.pack(notification.note ?? notification.noteId!, { id: notification.notifieeId }, {
detail: true,
_hint_: options._hintForEachNotes_,

View File

@@ -69,5 +69,7 @@ export const DI = {
adsRepository: Symbol('adsRepository'),
passwordResetRequestsRepository: Symbol('passwordResetRequestsRepository'),
retentionAggregationsRepository: Symbol('retentionAggregationsRepository'),
flashsRepository: Symbol('flashsRepository'),
flashLikesRepository: Symbol('flashLikesRepository'),
//#endregion
};

View File

@@ -3,6 +3,7 @@ import { FILE_TYPE_BROWSERSAFE } from '@/const.js';
const dictionary = {
'safe-file': FILE_TYPE_BROWSERSAFE,
'sharp-convertible-image': ['image/jpeg', 'image/png', 'image/gif', 'image/apng', 'image/vnd.mozilla.apng', 'image/webp', 'image/avif', 'image/svg+xml'],
'sharp-animation-convertible-image': ['image/jpeg', 'image/png', 'image/gif', 'image/webp', 'image/avif', 'image/svg+xml'],
};
export const isMimeImage = (mime: string, type: keyof typeof dictionary): boolean => dictionary[type].includes(mime);

View File

@@ -0,0 +1,3 @@
export function sqlLikeEscape(s: string) {
return s.replace(/([%_])/g, '\\$1');
}

View File

@@ -1,6 +1,6 @@
import { Module } from '@nestjs/common';
import { DI } from '@/di-symbols.js';
import { User, Note, Announcement, AnnouncementRead, App, NoteFavorite, NoteThreadMuting, NoteReaction, NoteUnread, Notification, Poll, PollVote, UserProfile, UserKeypair, UserPending, AttestationChallenge, UserSecurityKey, UserPublickey, UserList, UserListJoining, UserGroup, UserGroupJoining, UserGroupInvitation, UserNotePining, UserIp, UsedUsername, Following, FollowRequest, Instance, Emoji, DriveFile, DriveFolder, Meta, Muting, Blocking, SwSubscription, Hashtag, AbuseUserReport, RegistrationTicket, AuthSession, AccessToken, Signin, MessagingMessage, Page, PageLike, GalleryPost, GalleryLike, ModerationLog, Clip, ClipNote, Antenna, AntennaNote, PromoNote, PromoRead, Relay, MutedNote, Channel, ChannelFollowing, ChannelNotePining, RegistryItem, Webhook, Ad, PasswordResetRequest, RetentionAggregation } from './index.js';
import { User, Note, Announcement, AnnouncementRead, App, NoteFavorite, NoteThreadMuting, NoteReaction, NoteUnread, Notification, Poll, PollVote, UserProfile, UserKeypair, UserPending, AttestationChallenge, UserSecurityKey, UserPublickey, UserList, UserListJoining, UserGroup, UserGroupJoining, UserGroupInvitation, UserNotePining, UserIp, UsedUsername, Following, FollowRequest, Instance, Emoji, DriveFile, DriveFolder, Meta, Muting, Blocking, SwSubscription, Hashtag, AbuseUserReport, RegistrationTicket, AuthSession, AccessToken, Signin, MessagingMessage, Page, PageLike, GalleryPost, GalleryLike, ModerationLog, Clip, ClipNote, Antenna, AntennaNote, PromoNote, PromoRead, Relay, MutedNote, Channel, ChannelFollowing, ChannelNotePining, RegistryItem, Webhook, Ad, PasswordResetRequest, RetentionAggregation, FlashLike, Flash } from './index.js';
import type { DataSource } from 'typeorm';
import type { Provider } from '@nestjs/common';
@@ -388,6 +388,18 @@ const $retentionAggregationsRepository: Provider = {
inject: [DI.db],
};
const $flashsRepository: Provider = {
provide: DI.flashsRepository,
useFactory: (db: DataSource) => db.getRepository(Flash),
inject: [DI.db],
};
const $flashLikesRepository: Provider = {
provide: DI.flashLikesRepository,
useFactory: (db: DataSource) => db.getRepository(FlashLike),
inject: [DI.db],
};
@Module({
imports: [
],
@@ -456,6 +468,8 @@ const $retentionAggregationsRepository: Provider = {
$adsRepository,
$passwordResetRequestsRepository,
$retentionAggregationsRepository,
$flashsRepository,
$flashLikesRepository,
],
exports: [
$usersRepository,
@@ -522,6 +536,8 @@ const $retentionAggregationsRepository: Provider = {
$adsRepository,
$passwordResetRequestsRepository,
$retentionAggregationsRepository,
$flashsRepository,
$flashLikesRepository,
],
})
export class RepositoryModule {}

View File

@@ -0,0 +1,60 @@
import { Entity, Index, JoinColumn, Column, PrimaryColumn, ManyToOne } from 'typeorm';
import { id } from '../id.js';
import { User } from './User.js';
import { DriveFile } from './DriveFile.js';
@Entity()
export class Flash {
@PrimaryColumn(id())
public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the Flash.',
})
public createdAt: Date;
@Index()
@Column('timestamp with time zone', {
comment: 'The updated date of the Flash.',
})
public updatedAt: Date;
@Column('varchar', {
length: 256,
})
public title: string;
@Column('varchar', {
length: 1024,
})
public summary: string;
@Index()
@Column({
...id(),
comment: 'The ID of author.',
})
public userId: User['id'];
@ManyToOne(type => User, {
onDelete: 'CASCADE',
})
@JoinColumn()
public user: User | null;
@Column('varchar', {
length: 16384,
})
public script: string;
@Column('varchar', {
length: 256, array: true, default: '{}',
})
public permissions: string[];
@Column('integer', {
default: 0,
})
public likedCount: number;
}

View File

@@ -0,0 +1,33 @@
import { PrimaryColumn, Entity, Index, JoinColumn, Column, ManyToOne } from 'typeorm';
import { id } from '../id.js';
import { User } from './User.js';
import { Flash } from './Flash.js';
@Entity()
@Index(['userId', 'flashId'], { unique: true })
export class FlashLike {
@PrimaryColumn(id())
public id: string;
@Column('timestamp with time zone')
public createdAt: Date;
@Index()
@Column(id())
public userId: User['id'];
@ManyToOne(type => User, {
onDelete: 'CASCADE',
})
@JoinColumn()
public user: User | null;
@Column(id())
public flashId: Flash['id'];
@ManyToOne(type => Flash, {
onDelete: 'CASCADE',
})
@JoinColumn()
public flash: Flash | null;
}

View File

@@ -59,22 +59,6 @@ export class Instance {
})
public followersCount: number;
/**
* 直近のリクエスト送信日時
*/
@Column('timestamp with time zone', {
nullable: true,
})
public latestRequestSentAt: Date | null;
/**
* 直近のリクエスト送信時のHTTPステータスコード
*/
@Column('integer', {
nullable: true,
})
public latestStatus: number | null;
/**
* 直近のリクエスト受信日時
*/
@@ -83,12 +67,6 @@ export class Instance {
})
public latestRequestReceivedAt: Date | null;
/**
* このインスタンスと最後にやり取りした日時
*/
@Column('timestamp with time zone')
public lastCommunicatedAt: Date;
/**
* このインスタンスと不通かどうか
*/

View File

@@ -55,11 +55,11 @@ export class Notification {
* 通知の種類。
* follow - フォローされた
* mention - 投稿で自分が言及された
* reply - (自分または自分がWatchしている)投稿返信された
* renote - (自分または自分がWatchしている)投稿がRenoteされた
* quote - (自分または自分がWatchしている)投稿が引用Renoteされた
* reaction - (自分または自分がWatchしている)投稿にリアクションされた
* pollVote - (自分または自分がWatchしている)投稿のアンケートに投票された
* reply - 投稿返信された
* renote - 投稿がRenoteされた
* quote - 投稿が引用Renoteされた
* reaction - 投稿にリアクションされた
* pollVote - 投稿のアンケートに投票された (廃止)
* pollEnded - 自分のアンケートもしくは自分が投票したアンケートが終了した
* receiveFollowRequest - フォローリクエストされた
* followRequestAccepted - 自分の送ったフォローリクエストが承認された

View File

@@ -62,6 +62,8 @@ import { UserSecurityKey } from '@/models/entities/UserSecurityKey.js';
import { Webhook } from '@/models/entities/Webhook.js';
import { Channel } from '@/models/entities/Channel.js';
import { RetentionAggregation } from '@/models/entities/RetentionAggregation.js';
import { Flash } from '@/models/entities/Flash.js';
import { FlashLike } from '@/models/entities/FlashLike.js';
import type { Repository } from 'typeorm';
export {
@@ -129,6 +131,8 @@ export {
Webhook,
Channel,
RetentionAggregation,
Flash,
FlashLike,
};
export type AbuseUserReportsRepository = Repository<AbuseUserReport>;
@@ -195,3 +199,5 @@ export type UserSecurityKeysRepository = Repository<UserSecurityKey>;
export type WebhooksRepository = Repository<Webhook>;
export type ChannelsRepository = Repository<Channel>;
export type RetentionAggregationsRepository = Repository<RetentionAggregation>;
export type FlashsRepository = Repository<Flash>;
export type FlashLikesRepository = Repository<FlashLike>;

View File

@@ -3,7 +3,7 @@ export const packedEmojiSchema = {
properties: {
id: {
type: 'string',
optional: false, nullable: false,
optional: true, nullable: false,
format: 'id',
example: 'xxxxxxxxxx',
},
@@ -26,12 +26,8 @@ export const packedEmojiSchema = {
},
host: {
type: 'string',
optional: false, nullable: true,
optional: true, nullable: true,
description: 'The local host is represented with `null`.',
},
url: {
type: 'string',
optional: true, nullable: false,
},
},
} as const;

View File

@@ -32,16 +32,6 @@ export const packedFederationInstanceSchema = {
type: 'number',
optional: false, nullable: false,
},
latestRequestSentAt: {
type: 'string',
optional: false, nullable: true,
format: 'date-time',
},
lastCommunicatedAt: {
type: 'string',
optional: false, nullable: false,
format: 'date-time',
},
isNotResponding: {
type: 'boolean',
optional: false, nullable: false,

View File

@@ -70,6 +70,8 @@ import { UserSecurityKey } from '@/models/entities/UserSecurityKey.js';
import { Webhook } from '@/models/entities/Webhook.js';
import { Channel } from '@/models/entities/Channel.js';
import { RetentionAggregation } from '@/models/entities/RetentionAggregation.js';
import { Flash } from '@/models/entities/Flash.js';
import { FlashLike } from '@/models/entities/FlashLike.js';
import { Config } from '@/config.js';
import MisskeyLogger from '@/logger.js';
@@ -184,6 +186,8 @@ export const entities = [
Webhook,
UserIp,
RetentionAggregation,
Flash,
FlashLike,
...charts,
];

View File

@@ -15,10 +15,10 @@ import ApRequestChart from '@/core/chart/charts/ap-request.js';
import FederationChart from '@/core/chart/charts/federation.js';
import { StatusError } from '@/misc/status-error.js';
import { UtilityService } from '@/core/UtilityService.js';
import { bindThis } from '@/decorators.js';
import { QueueLoggerService } from '../QueueLoggerService.js';
import type Bull from 'bull';
import type { DeliverJobData } from '../types.js';
import { bindThis } from '@/decorators.js';
@Injectable()
export class DeliverProcessorService {
@@ -48,7 +48,6 @@ export class DeliverProcessorService {
) {
this.logger = this.queueLoggerService.logger.createSubLogger('deliver');
this.suspendedHostsCache = new Cache<Instance[]>(1000 * 60 * 60);
this.latest = null;
}
@bindThis
@@ -76,20 +75,18 @@ export class DeliverProcessorService {
}
try {
if (this.latest !== (this.latest = JSON.stringify(job.data.content, null, 2))) {
this.logger.debug(`delivering ${this.latest}`);
}
await this.apRequestService.signedPost(job.data.user, job.data.to, job.data.content);
// Update stats
this.federatedInstanceService.registerOrFetchInstanceDoc(host).then(i => {
this.instancesRepository.update(i.id, {
latestRequestSentAt: new Date(),
latestStatus: 200,
lastCommunicatedAt: new Date(),
isNotResponding: false,
});
this.federatedInstanceService.fetch(host).then(i => {
if (i.isNotResponding) {
this.instancesRepository.update(i.id, {
isNotResponding: false,
});
this.federatedInstanceService.updateCachePartial(host, {
isNotResponding: false,
});
}
this.fetchInstanceMetadataService.fetchInstanceMetadata(i);
@@ -100,13 +97,16 @@ export class DeliverProcessorService {
return 'Success';
} catch (res) {
// Update stats
this.federatedInstanceService.registerOrFetchInstanceDoc(host).then(i => {
this.instancesRepository.update(i.id, {
latestRequestSentAt: new Date(),
latestStatus: res instanceof StatusError ? res.statusCode : null,
isNotResponding: true,
});
// Update stats
this.federatedInstanceService.fetch(host).then(i => {
if (!i.isNotResponding) {
this.instancesRepository.update(i.id, {
isNotResponding: true,
});
this.federatedInstanceService.updateCachePartial(host, {
isNotResponding: true,
});
}
this.instanceChart.requestSent(i.host, false);
this.apRequestChart.deliverFail();
@@ -114,17 +114,17 @@ export class DeliverProcessorService {
});
if (res instanceof StatusError) {
// 4xx
// 4xx
if (res.isClientError) {
// HTTPステータスコード4xxはクライアントエラーであり、それはつまり
// 何回再送しても成功することはないということなのでエラーにはしないでおく
// HTTPステータスコード4xxはクライアントエラーであり、それはつまり
// 何回再送しても成功することはないということなのでエラーにはしないでおく
return `${res.statusCode} ${res.statusMessage}`;
}
// 5xx etc.
throw `${res.statusCode} ${res.statusMessage}`;
} else {
// DNS error, socket error, timeout ...
// DNS error, socket error, timeout ...
throw res;
}
}

View File

@@ -176,10 +176,12 @@ export class InboxProcessorService {
}
// Update stats
this.federatedInstanceService.registerOrFetchInstanceDoc(authUser.user.host).then(i => {
this.federatedInstanceService.fetch(authUser.user.host).then(i => {
this.instancesRepository.update(i.id, {
latestRequestReceivedAt: new Date(),
lastCommunicatedAt: new Date(),
isNotResponding: false,
});
this.federatedInstanceService.updateCachePartial(host, {
isNotResponding: false,
});

View File

@@ -79,10 +79,18 @@ export class MediaProxyServerService {
const { mime, ext } = await this.fileInfoService.detectType(path);
const isConvertibleImage = isMimeImage(mime, 'sharp-convertible-image');
const isAnimationConvertibleImage = isMimeImage(mime, 'sharp-animation-convertible-image');
let image: IImage;
if ('emoji' in request.query && isConvertibleImage) {
const data = await sharp(path, { animated: !('static' in request.query) })
if (!isAnimationConvertibleImage && !('static' in request.query)) {
image = {
data: fs.readFileSync(path),
ext,
type: mime,
};
} else {
const data = await sharp(path, { animated: !('static' in request.query) })
.resize({
height: 128,
withoutEnlargement: true,
@@ -90,11 +98,12 @@ export class MediaProxyServerService {
.webp(webpDefault)
.toBuffer();
image = {
data,
ext: 'webp',
type: 'image/webp',
};
image = {
data,
ext: 'webp',
type: 'image/webp',
};
}
} else if ('static' in request.query && isConvertibleImage) {
image = await this.imageProcessingService.convertToWebp(path, 498, 280);
} else if ('preview' in request.query && isConvertibleImage) {

View File

@@ -1,12 +1,11 @@
import cluster from 'node:cluster';
import * as fs from 'node:fs';
import * as http from 'node:http';
import { Inject, Injectable } from '@nestjs/common';
import Fastify from 'fastify';
import { IsNull } from 'typeorm';
import { GlobalEventService } from '@/core/GlobalEventService.js';
import type { Config } from '@/config.js';
import type { UserProfilesRepository, UsersRepository } from '@/models/index.js';
import type { EmojisRepository, UserProfilesRepository, UsersRepository } from '@/models/index.js';
import { DI } from '@/di-symbols.js';
import type Logger from '@/logger.js';
import { envOption } from '@/env.js';
@@ -39,6 +38,9 @@ export class ServerService {
@Inject(DI.userProfilesRepository)
private userProfilesRepository: UserProfilesRepository,
@Inject(DI.emojisRepository)
private emojisRepository: EmojisRepository,
private userEntityService: UserEntityService,
private apiServerService: ApiServerService,
private streamingApiServerService: StreamingApiServerService,
@@ -77,6 +79,43 @@ export class ServerService {
fastify.register(this.nodeinfoServerService.createServer);
fastify.register(this.wellKnownServerService.createServer);
fastify.get<{ Params: { path: string }; Querystring: { static?: any; }; }>('/emoji/:path(.*)', async (request, reply) => {
const path = request.params.path;
if (!path.match(/^[a-zA-Z0-9\-_@\.]+?\.webp$/)) {
reply.code(404);
return;
}
reply.header('Cache-Control', 'public, max-age=86400');
const name = path.split('@')[0].replace('.webp', '');
const host = path.split('@')[1]?.replace('.webp', '');
const emoji = await this.emojisRepository.findOneBy({
// `@.` is the spec of ReactionService.decodeReaction
host: (host == null || host === '.') ? IsNull() : host,
name: name,
});
reply.header('Content-Security-Policy', 'default-src \'none\'; style-src \'unsafe-inline\'');
if (emoji == null) {
return await reply.redirect('/static-assets/emoji-unknown.png');
}
const url = new URL('/proxy/emoji.webp', this.config.url);
// || emoji.originalUrl してるのは後方互換性のためpublicUrlはstringなので??はだめ)
url.searchParams.set('url', emoji.publicUrl || emoji.originalUrl);
url.searchParams.set('emoji', '1');
if ('static' in request.query) url.searchParams.set('static', '1');
return await reply.redirect(
301,
url.toString(),
);
});
fastify.get<{ Params: { acct: string } }>('/avatar/@:acct', async (request, reply) => {
const { username, host } = Acct.parse(request.params.acct);
const user = await this.usersRepository.findOne({

View File

@@ -220,6 +220,7 @@ import * as ep___messaging_messages_create from './endpoints/messaging/messages/
import * as ep___messaging_messages_delete from './endpoints/messaging/messages/delete.js';
import * as ep___messaging_messages_read from './endpoints/messaging/messages/read.js';
import * as ep___meta from './endpoints/meta.js';
import * as ep___emojis from './endpoints/emojis.js';
import * as ep___miauth_genToken from './endpoints/miauth/gen-token.js';
import * as ep___mute_create from './endpoints/mute/create.js';
import * as ep___mute_delete from './endpoints/mute/delete.js';
@@ -266,6 +267,15 @@ import * as ep___pages_like from './endpoints/pages/like.js';
import * as ep___pages_show from './endpoints/pages/show.js';
import * as ep___pages_unlike from './endpoints/pages/unlike.js';
import * as ep___pages_update from './endpoints/pages/update.js';
import * as ep___flash_create from './endpoints/flash/create.js';
import * as ep___flash_delete from './endpoints/flash/delete.js';
import * as ep___flash_featured from './endpoints/flash/featured.js';
import * as ep___flash_like from './endpoints/flash/like.js';
import * as ep___flash_show from './endpoints/flash/show.js';
import * as ep___flash_unlike from './endpoints/flash/unlike.js';
import * as ep___flash_update from './endpoints/flash/update.js';
import * as ep___flash_my from './endpoints/flash/my.js';
import * as ep___flash_myLikes from './endpoints/flash/my-likes.js';
import * as ep___ping from './endpoints/ping.js';
import * as ep___pinnedUsers from './endpoints/pinned-users.js';
import * as ep___promo_read from './endpoints/promo/read.js';
@@ -541,6 +551,7 @@ const $messaging_messages_create: Provider = { provide: 'ep:messaging/messages/c
const $messaging_messages_delete: Provider = { provide: 'ep:messaging/messages/delete', useClass: ep___messaging_messages_delete.default };
const $messaging_messages_read: Provider = { provide: 'ep:messaging/messages/read', useClass: ep___messaging_messages_read.default };
const $meta: Provider = { provide: 'ep:meta', useClass: ep___meta.default };
const $emojis: Provider = { provide: 'ep:emojis', useClass: ep___emojis.default };
const $miauth_genToken: Provider = { provide: 'ep:miauth/gen-token', useClass: ep___miauth_genToken.default };
const $mute_create: Provider = { provide: 'ep:mute/create', useClass: ep___mute_create.default };
const $mute_delete: Provider = { provide: 'ep:mute/delete', useClass: ep___mute_delete.default };
@@ -587,6 +598,15 @@ const $pages_like: Provider = { provide: 'ep:pages/like', useClass: ep___pages_l
const $pages_show: Provider = { provide: 'ep:pages/show', useClass: ep___pages_show.default };
const $pages_unlike: Provider = { provide: 'ep:pages/unlike', useClass: ep___pages_unlike.default };
const $pages_update: Provider = { provide: 'ep:pages/update', useClass: ep___pages_update.default };
const $flash_create: Provider = { provide: 'ep:flash/create', useClass: ep___flash_create.default };
const $flash_delete: Provider = { provide: 'ep:flash/delete', useClass: ep___flash_delete.default };
const $flash_featured: Provider = { provide: 'ep:flash/featured', useClass: ep___flash_featured.default };
const $flash_like: Provider = { provide: 'ep:flash/like', useClass: ep___flash_like.default };
const $flash_show: Provider = { provide: 'ep:flash/show', useClass: ep___flash_show.default };
const $flash_unlike: Provider = { provide: 'ep:flash/unlike', useClass: ep___flash_unlike.default };
const $flash_update: Provider = { provide: 'ep:flash/update', useClass: ep___flash_update.default };
const $flash_my: Provider = { provide: 'ep:flash/my', useClass: ep___flash_my.default };
const $flash_myLikes: Provider = { provide: 'ep:flash/my-likes', useClass: ep___flash_myLikes.default };
const $ping: Provider = { provide: 'ep:ping', useClass: ep___ping.default };
const $pinnedUsers: Provider = { provide: 'ep:pinned-users', useClass: ep___pinnedUsers.default };
const $promo_read: Provider = { provide: 'ep:promo/read', useClass: ep___promo_read.default };
@@ -866,6 +886,7 @@ const $retention: Provider = { provide: 'ep:retention', useClass: ep___retention
$messaging_messages_delete,
$messaging_messages_read,
$meta,
$emojis,
$miauth_genToken,
$mute_create,
$mute_delete,
@@ -912,6 +933,15 @@ const $retention: Provider = { provide: 'ep:retention', useClass: ep___retention
$pages_show,
$pages_unlike,
$pages_update,
$flash_create,
$flash_delete,
$flash_featured,
$flash_like,
$flash_show,
$flash_unlike,
$flash_update,
$flash_my,
$flash_myLikes,
$ping,
$pinnedUsers,
$promo_read,
@@ -1185,6 +1215,7 @@ const $retention: Provider = { provide: 'ep:retention', useClass: ep___retention
$messaging_messages_delete,
$messaging_messages_read,
$meta,
$emojis,
$miauth_genToken,
$mute_create,
$mute_delete,
@@ -1231,6 +1262,15 @@ const $retention: Provider = { provide: 'ep:retention', useClass: ep___retention
$pages_show,
$pages_unlike,
$pages_update,
$flash_create,
$flash_delete,
$flash_featured,
$flash_like,
$flash_show,
$flash_unlike,
$flash_update,
$flash_my,
$flash_myLikes,
$ping,
$pinnedUsers,
$promo_read,

View File

@@ -219,6 +219,7 @@ import * as ep___messaging_messages_create from './endpoints/messaging/messages/
import * as ep___messaging_messages_delete from './endpoints/messaging/messages/delete.js';
import * as ep___messaging_messages_read from './endpoints/messaging/messages/read.js';
import * as ep___meta from './endpoints/meta.js';
import * as ep___emojis from './endpoints/emojis.js';
import * as ep___miauth_genToken from './endpoints/miauth/gen-token.js';
import * as ep___mute_create from './endpoints/mute/create.js';
import * as ep___mute_delete from './endpoints/mute/delete.js';
@@ -265,6 +266,15 @@ import * as ep___pages_like from './endpoints/pages/like.js';
import * as ep___pages_show from './endpoints/pages/show.js';
import * as ep___pages_unlike from './endpoints/pages/unlike.js';
import * as ep___pages_update from './endpoints/pages/update.js';
import * as ep___flash_create from './endpoints/flash/create.js';
import * as ep___flash_delete from './endpoints/flash/delete.js';
import * as ep___flash_featured from './endpoints/flash/featured.js';
import * as ep___flash_like from './endpoints/flash/like.js';
import * as ep___flash_show from './endpoints/flash/show.js';
import * as ep___flash_unlike from './endpoints/flash/unlike.js';
import * as ep___flash_update from './endpoints/flash/update.js';
import * as ep___flash_my from './endpoints/flash/my.js';
import * as ep___flash_myLikes from './endpoints/flash/my-likes.js';
import * as ep___ping from './endpoints/ping.js';
import * as ep___pinnedUsers from './endpoints/pinned-users.js';
import * as ep___promo_read from './endpoints/promo/read.js';
@@ -538,6 +548,7 @@ const eps = [
['messaging/messages/delete', ep___messaging_messages_delete],
['messaging/messages/read', ep___messaging_messages_read],
['meta', ep___meta],
['emojis', ep___emojis],
['miauth/gen-token', ep___miauth_genToken],
['mute/create', ep___mute_create],
['mute/delete', ep___mute_delete],
@@ -584,6 +595,15 @@ const eps = [
['pages/show', ep___pages_show],
['pages/unlike', ep___pages_unlike],
['pages/update', ep___pages_update],
['flash/create', ep___flash_create],
['flash/delete', ep___flash_delete],
['flash/featured', ep___flash_featured],
['flash/like', ep___flash_like],
['flash/show', ep___flash_show],
['flash/unlike', ep___flash_unlike],
['flash/update', ep___flash_update],
['flash/my', ep___flash_my],
['flash/my-likes', ep___flash_myLikes],
['ping', ep___ping],
['pinned-users', ep___pinnedUsers],
['promo/read', ep___promo_read],

View File

@@ -8,7 +8,7 @@ import { DriveFileEntityService } from '@/core/entities/DriveFileEntityService.j
export const meta = {
tags: ['admin'],
requireCredential: false,
requireCredential: true,
requireModerator: true,
res: {

View File

@@ -5,6 +5,7 @@ import { QueryService } from '@/core/QueryService.js';
import { UtilityService } from '@/core/UtilityService.js';
import { EmojiEntityService } from '@/core/entities/EmojiEntityService.js';
import { DI } from '@/di-symbols.js';
import { sqlLikeEscape } from '@/misc/sql-like-escape.js';
export const meta = {
tags: ['admin'],
@@ -92,7 +93,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
}
if (ps.query) {
q.andWhere('emoji.name like :query', { query: '%' + ps.query + '%' });
q.andWhere('emoji.name like :query', { query: '%' + sqlLikeEscape(ps.query) + '%' });
}
const emojis = await q

View File

@@ -5,6 +5,7 @@ import type { Emoji } from '@/models/entities/Emoji.js';
import { QueryService } from '@/core/QueryService.js';
import { DI } from '@/di-symbols.js';
import { EmojiEntityService } from '@/core/entities/EmojiEntityService.js';
//import { sqlLikeEscape } from '@/misc/sql-like-escape.js';
export const meta = {
tags: ['admin'],
@@ -82,7 +83,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
let emojis: Emoji[];
if (ps.query) {
//q.andWhere('emoji.name ILIKE :q', { q: `%${ps.query}%` });
//q.andWhere('emoji.name ILIKE :q', { q: `%${ sqlLikeEscape(ps.query) }%` });
//const emojis = await q.take(ps.limit).getMany();
emojis = await q.getMany();

View File

@@ -3,6 +3,7 @@ import type { UsersRepository } from '@/models/index.js';
import { Endpoint } from '@/server/api/endpoint-base.js';
import { DI } from '@/di-symbols.js';
import { UserEntityService } from '@/core/entities/UserEntityService.js';
import { sqlLikeEscape } from '@/misc/sql-like-escape.js';
export const meta = {
tags: ['admin'],
@@ -68,7 +69,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
}
if (ps.username) {
query.andWhere('user.usernameLower like :username', { username: ps.username.toLowerCase() + '%' });
query.andWhere('user.usernameLower like :username', { username: sqlLikeEscape(ps.username.toLowerCase()) + '%' });
}
if (ps.hostname) {

View File

@@ -0,0 +1,91 @@
import { IsNull, MoreThan } from 'typeorm';
import { Inject, Injectable } from '@nestjs/common';
import type { EmojisRepository } from '@/models/index.js';
import { Endpoint } from '@/server/api/endpoint-base.js';
import { EmojiEntityService } from '@/core/entities/EmojiEntityService.js';
import type { Config } from '@/config.js';
import { DI } from '@/di-symbols.js';
export const meta = {
tags: ['meta'],
requireCredential: false,
res: {
type: 'object',
optional: false, nullable: false,
properties: {
emojis: {
type: 'array',
optional: false, nullable: false,
items: {
type: 'object',
optional: false, nullable: false,
properties: {
id: {
type: 'string',
optional: false, nullable: false,
format: 'id',
},
aliases: {
type: 'array',
optional: false, nullable: false,
items: {
type: 'string',
optional: false, nullable: false,
},
},
category: {
type: 'string',
optional: false, nullable: true,
},
},
},
},
},
},
} as const;
export const paramDef = {
type: 'object',
properties: {
},
required: [],
} as const;
// eslint-disable-next-line import/no-default-export
@Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> {
constructor(
@Inject(DI.config)
private config: Config,
@Inject(DI.emojisRepository)
private emojisRepository: EmojisRepository,
private emojiEntityService: EmojiEntityService,
) {
super(meta, paramDef, async (ps, me) => {
const emojis = await this.emojisRepository.find({
where: {
host: IsNull(),
},
order: {
category: 'ASC',
name: 'ASC',
},
cache: {
id: 'meta_emojis',
milliseconds: 3600000, // 1 hour
},
});
return {
emojis: await this.emojiEntityService.packMany(emojis, {
omitId: true,
omitHost: true,
}),
};
});
}
}

View File

@@ -4,6 +4,7 @@ import type { InstancesRepository } from '@/models/index.js';
import { InstanceEntityService } from '@/core/entities/InstanceEntityService.js';
import { MetaService } from '@/core/MetaService.js';
import { DI } from '@/di-symbols.js';
import { sqlLikeEscape } from '@/misc/sql-like-escape.js';
export const meta = {
tags: ['federation'],
@@ -64,8 +65,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
case '-followers': query.orderBy('instance.followersCount', 'ASC'); break;
case '+caughtAt': query.orderBy('instance.caughtAt', 'DESC'); break;
case '-caughtAt': query.orderBy('instance.caughtAt', 'ASC'); break;
case '+lastCommunicatedAt': query.orderBy('instance.lastCommunicatedAt', 'DESC'); break;
case '-lastCommunicatedAt': query.orderBy('instance.lastCommunicatedAt', 'ASC'); break;
case '+latestRequestReceivedAt': query.orderBy('instance.latestRequestReceivedAt', 'DESC', 'NULLS LAST'); break;
case '-latestRequestReceivedAt': query.orderBy('instance.latestRequestReceivedAt', 'ASC', 'NULLS FIRST'); break;
default: query.orderBy('instance.id', 'DESC'); break;
}
@@ -120,7 +121,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
}
if (ps.host) {
query.andWhere('instance.host like :host', { host: '%' + ps.host.toLowerCase() + '%' });
query.andWhere('instance.host like :host', { host: '%' + sqlLikeEscape(ps.host.toLowerCase()) + '%' });
}
const instances = await query.take(ps.limit).skip(ps.offset).getMany();

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