Compare commits

...

479 Commits

Author SHA1 Message Date
44d7652171 12.14.0 2020-02-18 21:35:16 +09:00
c9ed15b682 add missing image (#5967)
fix for explore banner
2020-02-18 21:33:51 +09:00
8faad646ae New Crowdin translations (#5971)
* New translations ja-JP.yml (Chinese Simplified)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Kannada)
2020-02-18 21:33:38 +09:00
1d50bc3382 Fix bug 2020-02-18 21:27:47 +09:00
da4af041af ログビューア実装 2020-02-18 21:27:43 +09:00
e2ff408f2f Implement object storage settings 2020-02-18 21:12:05 +09:00
50d1500dfc 12.13.0 2020-02-18 19:50:04 +09:00
94441f93a5 New Crowdin translations (#5969)
* New translations ja-JP.yml (Kannada)

* New translations ja-JP.yml (Kannada)

* New translations ja-JP.yml (Kannada)

* New translations ja-JP.yml (Kannada)

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

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Spanish)
2020-02-18 19:48:14 +09:00
5f712fbf3c Implement photo widget 2020-02-18 19:47:30 +09:00
1c757f10e0 Update CHANGELOG.md 2020-02-18 19:36:20 +09:00
0508d5f643 Add activity widget 2020-02-18 19:31:11 +09:00
d9986b7a2f Implement featured note injection 2020-02-18 19:05:11 +09:00
3d79e7a136 Improve paging 2020-02-18 18:19:11 +09:00
52fb1237ec Imprement promo read 2020-02-18 18:14:38 +09:00
8a7197726e Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2020-02-18 17:54:13 +09:00
b7f5458684 Fix bug 2020-02-18 17:53:56 +09:00
52710f3810 管理者はモデレーターに変更できないように (#5970)
* 管理者をモデレーターに変更できないように

* Change error message
2020-02-18 17:53:52 +09:00
a54de07260 Resolve #5963 2020-02-18 08:41:32 +09:00
aa2c8d101e Fix type 2020-02-18 08:13:47 +09:00
1441fd93b9 Clean up 2020-02-18 08:05:27 +09:00
4a585e8920 Improve chart logging 2020-02-18 03:03:34 +09:00
8c4245a09d Update core.ts 2020-02-18 02:27:18 +09:00
e4af16989a Fix bug 2020-02-18 01:25:02 +09:00
5dc0944fe8 Resolve #5949 2020-02-18 01:12:35 +09:00
b4d24f4377 12.12.0 2020-02-17 07:24:16 +09:00
67be47b8db New Crowdin translations (#5961)
* New translations ja-JP.yml (English)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Spanish)

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

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Spanish)

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

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

* New translations ja-JP.yml (Chinese Simplified)
2020-02-17 07:23:58 +09:00
e382982d32 Fix bug 2020-02-17 07:23:39 +09:00
b09b74b5da 🎨 2020-02-17 07:14:03 +09:00
c628bdb7a6 Fix glitch 2020-02-17 06:48:04 +09:00
2fcf6fb0fd UI tweak 2020-02-17 06:43:52 +09:00
4f3fc9ffd0 🎨 2020-02-17 06:39:41 +09:00
15839a7399 🎨 2020-02-17 06:37:39 +09:00
26b3a14a63 Clean up 2020-02-17 06:23:18 +09:00
f2f0799df1 Update app.vue 2020-02-17 05:38:00 +09:00
6c99c32100 i18n 2020-02-17 03:19:27 +09:00
93d25a2a34 ユーザー設定とクライアント設定を分離 2020-02-17 03:10:51 +09:00
88f5ec59d7 🎨 2020-02-17 02:41:03 +09:00
586d3c4db7 Better instance page 2020-02-17 02:27:14 +09:00
f45fb56e15 Improve instance info page 2020-02-17 02:21:27 +09:00
8fe153c7c1 12.11.0 2020-02-16 22:53:35 +09:00
36a8720fbb New Crowdin translations (#5948)
* New translations ja-JP.yml (English)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Korean)

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

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (German)
2020-02-16 22:53:16 +09:00
9cbfdc94d9 Clean up 2020-02-16 22:46:51 +09:00
091923764d Implement image dialog 2020-02-16 22:46:18 +09:00
dc39caed1e Resolve #5942 2020-02-16 22:15:49 +09:00
bcd7d1f007 Update CHANGELOG.md 2020-02-16 21:11:44 +09:00
40d4dc0474 Refactor 2020-02-16 21:11:27 +09:00
02ac30c0d0 Resolve #5958 2020-02-16 21:10:52 +09:00
518bc92673 Clean up 2020-02-16 21:05:17 +09:00
a5b92e316c Refactor: Extract scroll utility functions 2020-02-16 20:58:41 +09:00
828c7b66a0 Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2020-02-16 20:54:33 +09:00
93474eaa06 2回目以降の読み込みは30個までフェッチするように 2020-02-16 20:54:25 +09:00
237f366aa2 Update notification (#5956)
* Add icon for messaging

This will add icon within messaging

* Update messaging-room.message.vue

Link to missing icon

* Update notification.vue

fix renote icon in notification

https://github.com/syuilo/misskey/issues/5955
2020-02-16 20:21:05 +09:00
714bcf28d5 テーマの切り替え時に時計の色が変わるように (#5959)
* テーマの切り替え時に時計の色が変わるように

* ディレイを追加
2020-02-16 20:20:02 +09:00
420eeb4d68 Clean up 2020-02-15 23:42:52 +09:00
bc6daf4a2e Update CHANGELOG.md 2020-02-15 23:16:50 +09:00
6f7832c09b API doc 2020-02-15 23:13:59 +09:00
bef67fa275 Update trend.ts 2020-02-15 23:01:41 +09:00
05d7198667 🎨 2020-02-15 22:51:46 +09:00
df0bfc14e5 🎨 2020-02-15 22:21:35 +09:00
3f28f7451f Prefetch aicons 2020-02-15 21:56:21 +09:00
dbb9199d6f Fix widget bg (#5952) 2020-02-15 21:42:45 +09:00
72cb3b03af Update CHANGELOG.md 2020-02-15 21:39:59 +09:00
d0085f00ed Fix #5950 2020-02-15 21:39:38 +09:00
43734f027b Refactoring 2020-02-15 21:33:32 +09:00
bb903cab40 🎨 2020-02-15 18:47:50 +09:00
92f765bc47 Update sequential-entrance.vue 2020-02-15 18:42:43 +09:00
742889a035 Update sequential-entrance.vue 2020-02-15 18:39:45 +09:00
24453ebcc3 Improve banner animation performance 2020-02-15 17:44:26 +09:00
8b8ab1bf5c Update CHANGELOG.md 2020-02-15 17:33:51 +09:00
e9bc9b8675 Fix bug 2020-02-15 17:31:45 +09:00
eeaa27c7ca Improve usability 2020-02-15 09:22:16 +09:00
ccea1755fc なんか 2020-02-15 09:10:49 +09:00
c32a5d602b 🎨 2020-02-15 08:52:21 +09:00
2a04f2ca4d Improve follow-requests page 2020-02-15 08:42:21 +09:00
37c80e8ef5 Improve wallpaper feature 2020-02-15 08:29:59 +09:00
1dce62e42a 🎨 2020-02-15 07:54:20 +09:00
ec222378c4 12.10.0 2020-02-15 04:32:48 +09:00
ac930a1c6a New Crowdin translations (#5947)
* New translations ja-JP.yml (English)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Spanish)
2020-02-15 04:30:54 +09:00
5ccd5ad56e Add driveFiles index 2020-02-15 04:29:57 +09:00
67da90530b Use em 2020-02-15 04:02:32 +09:00
b7f3753615 Use em 2020-02-15 03:57:43 +09:00
d21d38509c Font size setting 2020-02-15 03:44:40 +09:00
a59e1c0345 Use em 2020-02-15 03:25:54 +09:00
7ab613b394 Use em 2020-02-15 03:24:09 +09:00
c00ab0fbe2 Api key setting 2020-02-15 03:18:33 +09:00
87451b1223 Add header clock 2020-02-15 02:54:42 +09:00
d2b61229a3 Improve usability 2020-02-15 02:39:27 +09:00
980584020a 🎨 2020-02-15 02:26:45 +09:00
a43d0dafa5 🎨 2020-02-15 02:20:10 +09:00
d5c1e7e579 Resolve #5928 2020-02-15 02:16:11 +09:00
55bdf0d618 🎨 2020-02-15 01:40:38 +09:00
44f7c13ad4 ✌️ 2020-02-15 01:39:14 +09:00
7bd1a3c8ac Update CHANGELOG.md 2020-02-15 01:33:58 +09:00
4f1981df03 サイドバーメニューからアカウントを作成できるように (#5910)
* メニューからアカウントを作成できるようにした

* i18n

* Update signup.vue

Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
2020-02-15 01:33:08 +09:00
8689a998aa New Crowdin translations (#5938)
* New translations ja-JP.yml (English)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)
2020-02-15 01:19:53 +09:00
079bb8d722 🎨 2020-02-15 01:18:48 +09:00
65c0b6c7da Resolve #5939 2020-02-15 01:03:59 +09:00
84958af4ce Improve doc page 2020-02-15 00:27:53 +09:00
c53b59914b doc 2020-02-15 00:17:21 +09:00
8ffd9ab2d9 Create reaction.ja-JP.md 2020-02-15 00:11:01 +09:00
0305caf504 Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2020-02-15 00:02:10 +09:00
3012e4ffe0 Update CHANGELOG.md 2020-02-15 00:00:53 +09:00
585f3c3d3e Fix Oops! (#5945) 2020-02-14 23:59:54 +09:00
f1d07dfbed Fix favicon provide 2020-02-14 23:55:31 +09:00
cddfc55110 ✌️ 2020-02-14 23:55:13 +09:00
a2ce072ae7 アナログ時計ウィジェットを移植 (#5944)
* アナログ時計ウィジェットを移植

* analog-clock -> clock
2020-02-14 23:31:24 +09:00
439563c5d6 サムネイルをJPEGで生成するように (#5941) 2020-02-14 11:40:45 +09:00
962617b4f4 Update CHANGELOG.md 2020-02-14 01:28:15 +09:00
4a202f0f7e 12.9.0 2020-02-14 01:26:28 +09:00
6e6b12519a Refactor 2020-02-14 01:24:05 +09:00
f5f7654f4b Improve custom emoji managemant 2020-02-14 01:09:39 +09:00
5ac4c48ad1 動きのあるMFMを無効にするオプション 2020-02-13 23:20:12 +09:00
7e18fd18b0 Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2020-02-13 23:11:14 +09:00
fb30c479ea Update CHANGELOG.md 2020-02-13 23:11:11 +09:00
DW
f40dcbfe13 Fix for CASCADE DELETE not being federated (#5812)
* Fix for CASCADE DELETE not being federated

* Use JOIN to get user

* fix typo
2020-02-13 23:08:33 +09:00
8755b5f353 Fix bug 2020-02-13 22:48:56 +09:00
691482bb28 Update dependencies 🚀 2020-02-13 22:39:23 +09:00
4248bb8ce0 New Crowdin translations (#5931)
* New translations ja-JP.yml (English)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Spanish)
2020-02-13 22:35:22 +09:00
a5653e33d3 Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2020-02-13 22:13:35 +09:00
072dc1c7e6 Clean up 2020-02-13 22:13:31 +09:00
d76fceae85 Fix #5935 2020-02-13 22:13:24 +09:00
86107b2710 Fix For Messaging Icon (#5933)
* Add icon for messaging

This will add icon within messaging

* Update messaging-room.message.vue

Link to missing icon
2020-02-13 15:53:02 +09:00
a473768bef 🎨 2020-02-13 11:54:12 +09:00
f7fe13a177 i18n 2020-02-13 11:46:02 +09:00
acd29d22eb Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2020-02-13 11:45:02 +09:00
c228155514 Fix #5930 2020-02-13 11:44:58 +09:00
b601b98d5c New Crowdin translations (#5929)
* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Spanish)
2020-02-13 06:02:36 +09:00
1cd3419688 Refactor 2020-02-13 05:08:01 +09:00
6f5f233bb5 12.8.0 2020-02-13 03:13:30 +09:00
d33492cd49 New Crowdin translations (#5926)
* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)
2020-02-13 03:12:58 +09:00
83ad9f369f OSネイティブの絵文字を使用オプション 2020-02-13 03:11:37 +09:00
3a78b62520 Update about-misskey.vue 2020-02-13 03:01:39 +09:00
2479f75d8a インスタンス情報ページとMisskey情報ページを分離するなど 2020-02-13 02:48:52 +09:00
f0d187f71e Add crowdin link 2020-02-13 02:35:50 +09:00
056942391a Update CHANGELOG.md 2020-02-13 02:18:33 +09:00
2feef81516 グループ招待の通知とか
Resolve #5880
Resolve #5927
2020-02-13 02:17:54 +09:00
037d4b581b フランス語と関西弁を有効に (#5925) 2020-02-12 22:40:35 +09:00
da4cf6fdb4 New Crowdin translations (#5924)
* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)
2020-02-12 22:40:18 +09:00
848bcd5a63 Update CHANGELOG.md 2020-02-12 08:05:26 +09:00
7b60b6c6dc New Crowdin translations (#5921)
* New translations ja-JP.yml (Chinese Simplified)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (English)

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

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Spanish)

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

* New translations ja-JP.yml (Kannada)

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

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

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Dutch)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Norwegian)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (Portuguese)

* New translations ja-JP.yml (Russian)

* New translations ja-JP.yml (Spanish)

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

* New translations ja-JP.yml (Kannada)
2020-02-12 08:00:07 +09:00
fbc801d1da 言語切り替え 2020-02-12 07:12:58 +09:00
2f18f82e3d 🎨 2020-02-12 06:43:22 +09:00
c2d5a96bb6 翻訳の抜けを修正その2 (#5893)
* Missing translation

* use npx

* ✌️

* Update ja-JP.yml

* Update signup.vue

* Update ja-JP.yml

* Update messaging-room.vue

* Update ja-JP.yml

* Update signup.vue

* Update ja-JP.yml

* Update signin.vue

* Update ja-JP.yml

* Update index.vue

* Update ja-JP.yml

* Update signup.vue

Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
2020-02-12 06:27:11 +09:00
46575d4f04 Fix #5919 2020-02-12 06:19:31 +09:00
5e7be93980 Resolve #5907 2020-02-12 06:01:59 +09:00
3f749c6540 良い感じに 2020-02-12 05:21:08 +09:00
2a7d4ee866 Update sequential-entrance.vue 2020-02-12 03:31:46 +09:00
083095ded6 Update sequential-entrance.vue 2020-02-12 03:31:20 +09:00
7207663f37 🎨 2020-02-12 02:56:42 +09:00
66b49c909a 🎨 2020-02-12 02:55:35 +09:00
ab469aa243 Update CHANGELOG.md 2020-02-12 02:52:45 +09:00
afa4563e1e Update paging.ts 2020-02-12 02:52:43 +09:00
320b3d8617 🎨 2020-02-12 02:52:37 +09:00
7493429b4d 🎨 2020-02-12 02:35:03 +09:00
d70f7a717b Fix #5918 2020-02-12 01:01:17 +09:00
4ab38b7894 タイムラインを放置すると先頭の投稿が見えなくなるのを修正 Fix #5903 (#5913)
* seqent fix

* comment

* ✌️
2020-02-12 00:38:29 +09:00
2068407be0 Update app.vue 2020-02-12 00:31:48 +09:00
10a7369fec サーバーから切断されましたのダイアログは時間をおいて表示するように (#5916)
* timeout disconnect dialog

* 70ms

* 150ms
2020-02-11 22:57:09 +09:00
9fb5579701 12.7.1 2020-02-11 20:08:47 +09:00
b3cf883a44 New Crowdin translations (#5908)
* New translations ja-JP.yml (Chinese Simplified)

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

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Korean)
2020-02-11 20:08:11 +09:00
f65e27c07c Fix #5914 2020-02-11 20:05:47 +09:00
b587fefe44 12.7.0 2020-02-10 23:45:31 +09:00
2511114c28 なんかもうめっちゃ変えた
Resolve #5846
2020-02-10 23:17:42 +09:00
9cd267fee5 🎨 2020-02-10 21:41:35 +09:00
aeac96a4f7 New Crowdin translations (#5901)
* New translations ja-JP.yml (Chinese Simplified)

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

* New translations ja-JP.yml (Chinese Simplified)
2020-02-10 21:40:30 +09:00
88a75e2a99 🎨 2020-02-10 21:37:37 +09:00
e14760775b 🎨 2020-02-10 21:30:59 +09:00
9e7e464ba5 Clean up 2020-02-10 21:28:29 +09:00
060d4fd27f 🎨 2020-02-10 21:27:17 +09:00
940578d062 🎨 2020-02-10 21:16:04 +09:00
9cf42d8b33 Better self link detection 2020-02-10 20:51:17 +09:00
1d62d2924e 🎨 2020-02-10 20:47:02 +09:00
e23bac47ba 🎨 2020-02-10 20:44:59 +09:00
b5d38adfcc 🎨 2020-02-10 20:32:57 +09:00
f30513b20b Fix #5902 2020-02-10 20:29:44 +09:00
ade1e40395 12.6.0 2020-02-10 07:25:49 +09:00
c93b8677e4 New Crowdin translations (#5899)
* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Korean)

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

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Spanish)
2020-02-10 07:25:32 +09:00
62683d8878 なんかもうめっちゃ変えた
Resolve #5900
2020-02-10 07:23:43 +09:00
3d1239c1b4 Better initial widgets 2020-02-10 05:44:47 +09:00
5268bade66 Better widgets 2020-02-10 05:42:03 +09:00
514eb39a14 ユーザーページからグループに招待できるように 2020-02-10 05:03:01 +09:00
18628b821e Better title adjust logic 2020-02-10 04:04:10 +09:00
344fbe6bcd Note page title 2020-02-10 03:55:33 +09:00
afb8cd2dc1 Update CHANGELOG.md 2020-02-10 03:51:58 +09:00
1a5f385eb5 Improve mfm link 2020-02-10 03:48:45 +09:00
8df7864064 Clean up 2020-02-10 03:16:34 +09:00
9ca60bad7f Update url-preview-popup.vue 2020-02-10 03:13:24 +09:00
bd828bb072 Better resize observe 2020-02-10 03:13:22 +09:00
892cb44d84 Resolve #3644 2020-02-10 02:59:00 +09:00
517ea6a119 Refactor 2020-02-10 02:42:06 +09:00
ba8ffda32a New Crowdin translations (#5884)
* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Korean)

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

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Korean)

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

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

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

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

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

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

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

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

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

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

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Korean)
2020-02-09 22:47:54 +09:00
90a9cf376e 12.5.0 2020-02-09 22:44:07 +09:00
16d6c55407 🎨 2020-02-09 22:25:36 +09:00
f3508d15a3 Refactor 2020-02-09 22:25:32 +09:00
0add490097 Update ja-JP.yml 2020-02-09 22:05:56 +09:00
2d2d1bd58d Refactor 2020-02-09 22:00:45 +09:00
7813c8a942 Fix #5896 2020-02-09 22:00:38 +09:00
ac5453232f お知らせの固定表示 (#5887)
* お知らせの固定

* ✌️

* Update index.home.vue

Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
2020-02-09 21:31:17 +09:00
e78e5274d3 Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2020-02-09 20:53:08 +09:00
982520bcef fix typo #5890 2020-02-09 20:53:00 +09:00
7abd91f031 いくつかのスタイルを調整 (#5894)
* Chrome(Android)で誕生日欄が崩れていたのを修正

* 入力欄のフォントを親要素から継承するように変更
2020-02-09 19:59:28 +09:00
b93bfb7e5c 🎨 2020-02-09 19:40:15 +09:00
2b20c34c1e Add search shortcut 2020-02-09 19:34:26 +09:00
0f63acea5b Update messaging-room.vue 2020-02-09 19:31:23 +09:00
e600fb7096 Fix #5888 2020-02-09 19:29:49 +09:00
b63fc71865 i18n 2020-02-09 19:18:06 +09:00
23e7650983 Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2020-02-09 18:53:31 +09:00
01b5ccfdc6 Fix #5891 2020-02-09 18:52:53 +09:00
cc72f91465 Fix cannot update (#5890) 2020-02-09 12:47:50 +09:00
45cb5ff4ef 12.4.1 2020-02-09 03:56:39 +09:00
390279a4a8 Fix #5885 2020-02-09 03:49:18 +09:00
851dececab 非ログイン時に検索欄がズレていたのを修正 (#5883)
* 非ログイン時に検索欄がズレていたのを修正

* flexboxを用いてセンタリングを行うように変更
2020-02-09 03:42:18 +09:00
482afa93a2 Update avatars.vue 2020-02-09 03:41:11 +09:00
25bdbd7ae0 Fix #5886 2020-02-09 03:40:09 +09:00
527a639242 Update ja-JP.yml 2020-02-09 03:33:17 +09:00
0d5e000ad3 12.4.0 2020-02-09 00:01:01 +09:00
f4cb467e7a New Crowdin translations (#5882)
* New translations ja-JP.yml (Chinese Simplified)

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

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

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

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

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

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

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

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Korean)
2020-02-08 23:59:47 +09:00
2f6b0b142a nanka iroiro 2020-02-08 23:52:40 +09:00
78c2535c3c ✌️ 2020-02-08 22:42:35 +09:00
26260392a8 Fix bug 2020-02-08 22:23:44 +09:00
aa573c0063 Create ActivityでattributedToの補完とaudienceのコピーを行うように (#5873)
* attributedTo

* Create

* copy audiences between activity <=> object

* やっぱり匿名GETのpublicは必要

* fix
2020-02-08 21:40:06 +09:00
b2859bcd2a Fix defalut note visibility setting (#5881)
* Fix default note visibility setting

* refactor

* missing translation

* fix
2020-02-08 20:02:15 +09:00
b58dd8c704 12.3.0 2020-02-08 18:37:00 +09:00
09c96286f9 🎨 2020-02-08 18:35:42 +09:00
f2d2089c21 New Crowdin translations (#5849)
* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Spanish)

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

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

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

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

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

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

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (English)

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

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Spanish)
2020-02-08 18:03:56 +09:00
79c366d1f2 Update container.vue 2020-02-08 18:02:28 +09:00
c97ce5255f i18n 2020-02-08 17:52:36 +09:00
1fb66254a4 🎨 2020-02-08 17:49:54 +09:00
2d74f0507b 🎨 2020-02-08 17:36:23 +09:00
9c06544c46 wip 2020-02-08 16:51:27 +09:00
641dad586f 🎨 2020-02-08 15:50:04 +09:00
016144b960 wip 2020-02-08 15:47:16 +09:00
4d6c8efe44 wip 2020-02-08 15:17:35 +09:00
860a7d1eeb wip 2020-02-08 15:11:12 +09:00
2389857be8 🎨 2020-02-08 14:31:51 +09:00
18458f418f [wip] フォルダー名の変更と削除機能を実装 (#5874)
* フォルダーの削除機能を実装

* フォルダ名の変更を実装

* ダイアログの削除(v11準拠)とエラーメッセージを表示するように

* ダイアログのテキストのkeypathを変更
2020-02-08 13:09:38 +09:00
e812d054bc Clean up 2020-02-08 13:06:42 +09:00
44d2c0195a 翻訳の抜けを修正 (#5875)
* missing translation

* fix

* fix

* ✌️
2020-02-08 13:06:09 +09:00
42b4949b7f Update app.vue 2020-02-08 12:49:22 +09:00
d915ae0807 Resolve #5879 2020-02-08 12:46:14 +09:00
8eec8ea35f Fix #5844 2020-02-08 12:13:15 +09:00
023e0ba7aa Revert "Better page transition"
This reverts commit d0d3b70c73.
2020-02-08 11:54:39 +09:00
d0d3b70c73 Better page transition 2020-02-08 11:33:32 +09:00
a509045b25 Fix bug 2020-02-08 11:33:25 +09:00
7be6501571 EmojiReaction => EmojiReact (#5877) 2020-02-07 21:37:24 +09:00
bb4c35d481 fix #5854 2020-02-07 20:25:49 +09:00
47ea84957d docs 2020-02-07 19:45:15 +09:00
fc76f7874e Docs 2020-02-07 19:43:37 +09:00
77a778acf1 Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2020-02-07 19:15:12 +09:00
ff059d1268 wip docs 2020-02-07 19:15:08 +09:00
53bb5012b9 非ログイン時にエラーが発生していたのを修正 (#5872) 2020-02-07 11:39:44 +09:00
09a3a977d7 👀 (#5869) 2020-02-07 09:43:26 +09:00
04db5944d1 Fix #5854 2020-02-07 02:38:02 +09:00
9c97bb431c markdown 2020-02-07 01:20:04 +09:00
38215f2cf9 Fix wrong url on list page (#5865) 2020-02-07 00:19:40 +09:00
01e7a01daf Clean up 2020-02-06 23:27:47 +09:00
c2a8e29ef9 Not found page 2020-02-06 23:20:59 +09:00
15a41e31b0 Fix #5856 2020-02-06 23:12:27 +09:00
294c9840de 12.2.0 2020-02-06 22:27:32 +09:00
568ecd9477 Resolve #5861 2020-02-06 22:25:45 +09:00
169f3ed541 Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2020-02-06 22:18:26 +09:00
ff7ae427fd Resolve #5860 2020-02-06 22:18:23 +09:00
1597415340 PWAとしてインストールできなかったのを修正 (#5863)
* pwa

* ✌️
2020-02-06 22:11:27 +09:00
47f3261b9f Update CHANGELOG.md 2020-02-06 22:10:55 +09:00
9e68eefbb7 Resolve #5859 2020-02-06 22:10:33 +09:00
630c531d99 Improve messaging form 2020-02-06 19:22:15 +09:00
c7da2a4b5f Resolve #5857 2020-02-06 19:11:14 +09:00
692078f490 🎨 2020-02-06 18:49:57 +09:00
0e29e864c8 Refactor 2020-02-06 18:25:25 +09:00
1b7a601d27 Fix i18n 2020-02-06 17:50:59 +09:00
a96076ee5b 🎨 2020-02-06 17:48:05 +09:00
d580622d1b Update ja-JP.yml 2020-02-06 17:44:41 +09:00
6edccad4dd 12.1.0 2020-02-06 17:29:59 +09:00
8fa47dbcb1 🎨 2020-02-06 17:28:45 +09:00
157f4bbc21 Update CHANGELOG.md 2020-02-06 17:26:09 +09:00
3b0d0df068 i18n 2020-02-06 17:25:04 +09:00
69802a9f00 Resolve #5850 2020-02-06 17:21:28 +09:00
b940da45af Update CHANGELOG.md 2020-02-06 17:11:46 +09:00
bd6de0e204 Fix #5848 (#5853) 2020-02-06 17:11:02 +09:00
958074e347 Update CHANGELOG.md 2020-02-06 17:08:05 +09:00
988ac80087 Correct Like id generation (#5852) 2020-02-06 17:07:37 +09:00
1c7c72181e Fix #5838 2020-02-06 17:05:19 +09:00
6857153367 Fix bug 2020-02-06 17:02:32 +09:00
0a3a0f3beb Update sequential-entrance.vue 2020-02-06 14:55:27 +09:00
e92e83746d Refactor 2020-02-06 14:37:29 +09:00
3b34b3e9ea Fix #5843 2020-02-06 14:29:36 +09:00
9506f53691 Update CHANGELOG.md 2020-02-06 14:25:36 +09:00
92dc6db134 Update CHANGELOG.md 2020-02-06 14:24:43 +09:00
1b88a7bc03 Fix #5842 and refactoring 2020-02-06 14:23:01 +09:00
781cebf194 12.0.0 2020-02-06 09:35:15 +09:00
b0c21aa233 12.0.0-beta.3 2020-02-06 09:17:30 +09:00
b58afb0414 Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2020-02-06 09:12:32 +09:00
16b275a6b9 Update CHANGELOG.md 2020-02-06 09:12:20 +09:00
ac9612eb49 Fix nyaize 2 (#5841)
* Korean, English Nyaziation and special case exclusion

* Remove single en and unused

* order of exclude

* nl

* code style
2020-02-06 09:11:26 +09:00
416accbe78 Renoteを解除できるように
Resolve #2231
2020-02-06 09:09:24 +09:00
ee0531b048 12.0.0-beta.2 2020-02-05 21:47:04 +09:00
e80da3c865 Update CHANGELOG.md 2020-02-05 21:42:33 +09:00
712a90d502 Fix bug 2020-02-05 21:41:54 +09:00
ab995930ff Refactor 2020-02-05 21:41:49 +09:00
5dc27b6d4b Fix bug 2020-02-05 21:38:19 +09:00
391a0a1e0d Refactor 2020-02-05 21:29:41 +09:00
8d1db30129 Refactor: Better key name 2020-02-05 21:29:19 +09:00
a0f35e240f Update post-form.vue 2020-02-05 21:28:51 +09:00
570f4e921b Update CHANGELOG.md 2020-02-05 21:12:08 +09:00
ddd7b04646 korean nyaize 2020-02-05 21:11:24 +09:00
3c4bae763f Revert "Korean, English Nyaziation and special case exclusion (#5813)"
This reverts commit c110f0860e.
2020-02-05 20:56:28 +09:00
75e360ae7a 12.0.0-beta.1 2020-02-05 15:42:08 +09:00
90225f9d33 Update fetch-meta.ts 2020-02-05 15:41:14 +09:00
bb555ab8ff 🎨 2020-02-05 15:12:08 +09:00
868f6a1f0c Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2020-02-05 14:39:56 +09:00
a3c1a29fbf Refactor 2020-02-05 14:39:52 +09:00
f0c218200c Merge pull request #5823 from syuilo/patch/autogen/v11
[AUTOMATED] Update README.md
2020-02-05 13:37:18 +09:00
9200b1cac2 Update CHANGELOG.md 2020-02-05 11:39:46 +09:00
28c2063043 12.0.0-alpha.15 2020-02-05 10:17:30 +09:00
8818648740 プロキシアカウントをユーザー名ではなくIDで保存するように 2020-02-05 10:15:09 +09:00
ce589fee8c Fix bug 2020-02-05 09:50:03 +09:00
f86cfdb1ce Update privacy.vue 2020-02-05 09:43:55 +09:00
55cbf2c66e localOnlyを記憶できるように 2020-02-05 09:42:58 +09:00
00515d35b9 Update README.md [AUTOGEN] 2020-02-05 09:42:12 +09:00
5ce2bdf117 Fix #5799 2020-02-05 09:29:18 +09:00
e65275da95 Update post-form.vue 2020-02-05 09:21:51 +09:00
399903a462 localOnly 2020-02-05 09:15:28 +09:00
9a30314e17 Update CHANGELOG.md 2020-02-05 09:07:57 +09:00
2170a9fedb Update CHANGELOG.md 2020-02-05 09:01:27 +09:00
0c291d1d8d Fix bug nado 2020-02-05 08:59:24 +09:00
d765a43166 Update supported locales 2020-02-05 08:39:12 +09:00
45d42d1063 New Crowdin translations (#5793)
* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Spanish)
2020-02-05 08:37:11 +09:00
c5103672c9 Update CHANGELOG.md 2020-02-05 08:11:33 +09:00
8e21458e16 コンポーネントの活性時に再計算するように (#5829) 2020-02-05 07:54:49 +09:00
aade954dd7 Fix #5798 (#5816)
* Fix #5798

* clean

* Update src/client/components/post-form-attaches.vue

Co-Authored-By: Satsuki Yanagi <17376330+u1-liquid@users.noreply.github.com>

* nest

Co-authored-by: Satsuki Yanagi <17376330+u1-liquid@users.noreply.github.com>
2020-02-04 09:20:10 +09:00
3ae73555a9 Update CHANGELOG.md 2020-02-04 08:38:48 +09:00
DW
c110f0860e Korean, English Nyaziation and special case exclusion (#5813) 2020-02-04 08:30:49 +09:00
b7a4f286b0 リモート投稿にリモートでされたリアクションが表示されるように (#5817)
* 第3インスタンスへのLikeも受け入れるように

* リアクション済みだったらエラーにせずに置き換えるように

* Likeを第3インスタンスにdeliverするように

* fix

* fix

* 同じリアクションがすでにされていたら何もしない

* リモートから自身の投稿へリアクションした場合にエラーにならないように
2020-02-04 08:26:00 +09:00
f640da911b Add Unicode 12.1 Emojis (#5825)
* 絵文字ピッカーにSHIBUYA 109を追加

* Emoji regex for Unicode 12.1

* 絵文字テーブルに Unicode 12.1 分を追加
2020-02-04 08:20:51 +09:00
9e0347d3f9 Merge pull request #5815 from syuilo/patch/autogen/v11
[AUTOMATED] Update README.md
2020-02-04 00:22:47 +09:00
67496de411 AP inboxの最小リトライ間隔 1秒→1分 (#5818) 2020-02-03 21:05:38 +09:00
2a5a055d1c ページバック前に判定を追加 (#5822) 2020-02-03 21:05:13 +09:00
7075b66aa5 Update README.md [AUTOGEN] 2020-02-03 01:34:13 +09:00
93457eacf7 Merge pull request #5807 from syuilo/patch/autogen/v11
[AUTOMATED] Update README.md
2020-02-03 01:33:30 +09:00
2d1a72b218 Update CHANGELOG.md 2020-02-02 12:10:43 +09:00
DW
2db861991a Add ZWSP when federating emojis for Mastodon compatibility (#5810)
* Add ZWSP when federating emojis for Mastodon compatibility

* Use unicode escape sequence
2020-02-02 12:10:23 +09:00
DW
391500bdac Allow wider window for totp verification (#5811)
As server time and client time may not necessarily match
2020-02-02 11:50:15 +09:00
5b63c23ae1 Fix: emoji関連のリポジトリへのライセンス表記が必要 (#5809)
* .

* rename

* idx

* a
2020-02-02 06:11:14 +09:00
34a7e2888d Update README.md 2020-02-02 06:10:04 +09:00
700c343f7c Update CHANGELOG.md 2020-02-02 06:07:56 +09:00
c30960d6bf Fix hashtags contained in private notes are shown in trends (#5805)
* Update trend.ts

* Fix query

* Update create.ts

* Update create.ts

* Update trend.ts
2020-02-02 05:42:58 +09:00
ccceaabb52 Update README.md [AUTOGEN] 2020-02-02 01:05:10 +09:00
721531c5b5 Merge pull request #5795 from syuilo/patch/autogen/v11
[AUTOMATED] Update README.md
2020-02-02 01:04:42 +09:00
4f8a8f86bf Update CHANGELOG.md 2020-02-01 20:12:56 +09:00
d773c220c7 Update yarn.lock 2020-02-01 18:21:28 +09:00
b9a0d25601 Update package.json 2020-02-01 18:13:59 +09:00
6e776650be 🎨 2020-02-01 17:26:17 +09:00
cfe9452e92 Fix bug 2020-02-01 17:26:12 +09:00
03b4f19a4c Maintainerはクライアントに表示するようになった 2020-02-01 17:16:17 +09:00
a74c790ccb 12.0.0-alpha.14 2020-02-01 17:11:38 +09:00
05f9135e30 🎨 2020-02-01 17:10:56 +09:00
6f115c6d81 ")"が抜けていたので追加 (#5802) 2020-02-01 17:02:46 +09:00
f04002188d Resolve #5513 2020-02-01 16:57:12 +09:00
d00e4433ee Fix test (#5801) 2020-02-01 15:48:50 +09:00
2c1b26a988 ノートをウォッチした後にメニューが開けなくなるのを修正 (#5797) 2020-02-01 12:19:43 +09:00
ace59fa717 Fix style 2020-02-01 11:44:31 +09:00
1d1fc87920 Fix bug 2020-02-01 11:35:49 +09:00
f976f32ea9 Update .gitignore 2020-02-01 11:10:30 +09:00
cb3dd91a8c Update user.ts 2020-02-01 11:09:29 +09:00
e2610c52f3 Update router.ts 2020-02-01 10:57:47 +09:00
de239b6d67 Add note 2020-02-01 10:03:16 +09:00
149de5b17b Improve navigation 2020-02-01 09:59:55 +09:00
d47d6bb12b Fix bug 2020-02-01 09:45:30 +09:00
c30c71c338 Rename theme 2020-02-01 09:21:28 +09:00
a941c05d75 Update router.ts 2020-02-01 09:19:05 +09:00
50fd020509 Update CHANGELOG.md 2020-02-01 09:17:35 +09:00
4ec264755f Update router.ts 2020-02-01 09:16:18 +09:00
53f018aae6 Fix bug 2020-02-01 09:12:04 +09:00
38dded5061 Update avatar.vue 2020-02-01 09:01:20 +09:00
59070cd626 Keep alive index page 2020-02-01 09:00:22 +09:00
5875409841 Fix bug 2020-02-01 07:49:02 +09:00
251bf4bd61 Improve usability 2020-02-01 07:42:21 +09:00
958c59b065 Improve autocomplete 2020-02-01 07:38:40 +09:00
46b0c5f354 ✌️ 2020-02-01 07:20:17 +09:00
7ed3448e13 Resolve #1669 2020-02-01 07:16:52 +09:00
d355f3f77c Update gulpfile.ts 2020-02-01 06:32:21 +09:00
08b72eb8c7 Update README.md [AUTOGEN] 2020-01-31 18:11:11 +09:00
3f2f4fa32e Merge pull request #5786 from syuilo/patch/autogen/v11
[AUTOMATED] Update README.md
2020-01-31 18:10:58 +09:00
7fe6b1f84f Better migration 2020-01-31 16:57:13 +09:00
2cca14a625 Show patrons 2020-01-31 16:33:36 +09:00
856925f2ca Fix style 2020-01-31 15:50:46 +09:00
a774767676 Fix bug 2020-01-31 15:45:19 +09:00
299ec075e2 Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2020-01-31 15:25:41 +09:00
17a04e2676 Update icon 2020-01-31 15:25:38 +09:00
dd3df080d3 Update CHANGELOG.md 2020-01-31 13:42:29 +09:00
960b3c0aeb Update CHANGELOG.md 2020-01-31 13:34:40 +09:00
84bf879b7d Update follow-button.vue 2020-01-31 12:01:13 +09:00
a5cf189caa Improve follow button 2020-01-31 11:58:59 +09:00
73e7c1bf67 Refactor 2020-01-31 11:38:52 +09:00
acd64f58e3 Resolve #2230 2020-01-31 11:35:18 +09:00
259254aca8 Add patreon link 2020-01-31 07:05:03 +09:00
783fa161a1 Update ja-JP.yml 2020-01-31 07:01:56 +09:00
963c7761f2 Pages 2020-01-31 07:01:45 +09:00
1d6947d321 New Crowdin translations (#5792)
* New translations ja-JP.yml (Chinese Simplified)

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

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Dutch)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Norwegian)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (Portuguese)

* New translations ja-JP.yml (Russian)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Japanese, Kansai)
2020-01-31 05:33:31 +09:00
27ffb192f0 Fix style 2020-01-31 05:21:41 +09:00
7c64d677cb Fix style 2020-01-31 05:20:10 +09:00
f1f8e6dfd3 Update CHANGELOG.md 2020-01-31 05:18:23 +09:00
635afdf53f Fix password reset 2020-01-31 05:15:59 +09:00
99b5d94b11 Show moderator badge 2020-01-31 05:09:52 +09:00
db24dddeff Make notifications widget flexible (#5791)
* Make notifications widget flexible

* fix
2020-01-31 04:53:16 +09:00
1f8334dcb7 fix 2020-01-30 20:27:14 +09:00
0252e9b4b7 Fix duplicated disconnected dialog (Fix #5782) (#5790)
* Fix #5782
fix duplicated disconnected dialog

* fix
2020-01-30 19:57:22 +09:00
13abd6596e Add some themes 🎨 2020-01-30 19:39:07 +09:00
d8ab7f158c Update CHANGELOG.md 2020-01-30 19:00:11 +09:00
5a97b67785 Fix 2020-01-30 19:00:08 +09:00
711aa564c1 AP audience (visibility) パースの修正 (#5783)
* Refactor audience

* audienceのないAP Object 対応

* fix

* Update src/remote/activitypub/audience.ts

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

* Update src/remote/activitypub/audience.ts

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

Co-authored-by: Acid Chicken (硫酸鶏) <root@acid-chicken.com>
Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
2020-01-30 18:58:13 +09:00
f6987c72ac Make timeline widget flexible (#5788) 2020-01-30 18:32:09 +09:00
9107895754 Fix bug 2020-01-30 18:31:08 +09:00
3dbc175091 Update CHANGELOG.md 2020-01-30 18:01:26 +09:00
6dee3678fe Update CHANGELOG.md 2020-01-30 17:58:53 +09:00
f55550cdeb Update CHANGELOG.md 2020-01-30 17:57:26 +09:00
1446a20c70 Update CHANGELOG.md 2020-01-30 17:44:41 +09:00
eafaebb0f9 Fix typo in CHANGELOG.md (#5789) 2020-01-30 17:31:20 +09:00
de0d7701f9 Update CHANGELOG.md 2020-01-30 17:27:21 +09:00
8e94c47362 Update CHANGELOG.md 2020-01-30 14:48:14 +09:00
48e9898db1 2fa setting 2020-01-30 13:05:14 +09:00
64dcd9d697 🎨 2020-01-30 11:12:58 +09:00
a7f337e8e4 Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2020-01-30 11:10:48 +09:00
24c047b662 _section --> _card 2020-01-30 11:10:42 +09:00
e97bfe5696 Handle EmojiReaction activitiy (#5492)
* Handle some additional reaction activities

* Revert "Handle some additional reaction activities"

This reverts commit 1462ff12de08e8810023658e8ff7b5ee8bd7965b.

* EmojiReaction
2020-01-30 08:03:50 +09:00
fb9fed545e ✌️ 2020-01-30 07:53:19 +09:00
964bfb36d8 Improve avatar/banner setting 2020-01-30 07:13:36 +09:00
8b32157cf1 Fix bug 2020-01-30 06:23:34 +09:00
f5d5d26b0e Adjust page style 2020-01-30 06:19:18 +09:00
9f4da44b59 Fix 2020-01-30 06:11:35 +09:00
ee0cbab4e4 Fix bug 2020-01-30 06:09:36 +09:00
c44e8e6bf1 Emoji copy 2020-01-30 06:06:50 +09:00
5ceffb2c17 Add moderator switch 2020-01-30 06:00:43 +09:00
96648b651e isMarkedAsClosed --> isSuspended 2020-01-30 05:56:14 +09:00
31abd2f59b Fix bug 2020-01-30 05:45:15 +09:00
f6154dc0af v12 (#5712)
Co-authored-by: MeiMei <30769358+mei23@users.noreply.github.com>
Co-authored-by: Satsuki Yanagi <17376330+u1-liquid@users.noreply.github.com>
2020-01-30 04:37:25 +09:00
a5955c1123 Add Event activity-type support (#5785) 2020-01-30 01:38:05 +09:00
23f262c2e4 Add Group and Organization to validActor (#5784) 2020-01-30 01:36:44 +09:00
39640b264d Update README.md [AUTOGEN] 2020-01-30 00:01:10 +09:00
4845770880 Merge pull request #5779 from syuilo/patch/autogen/v11
[AUTOMATED] Update README.md
2020-01-30 00:00:22 +09:00
c2b6b7b179 Update README.md [AUTOGEN] 2020-01-29 00:05:06 +09:00
777c5a8704 Update README.md [AUTOGEN] (#5776) 2020-01-29 00:01:35 +09:00
467304b470 Update README.md [AUTOGEN] 2020-01-28 00:02:12 +09:00
c8ba5add8c Update README.md [AUTOGEN] (#5765) 2020-01-28 00:01:05 +09:00
bbcc09d426 Allow 'internal' device in WebAuthN (#5756) 2020-01-27 05:38:40 +09:00
01c07d120f Resolve #5762 (#5770) 2020-01-27 05:37:53 +09:00
0c1076c917 userListチャンネルのオーナーチェック Fix #5772 (#5773)
* userListチャンネルのオーナーチェック Fix #5772

* comment
2020-01-27 05:36:59 +09:00
cff91a7674 Update README.md [AUTOGEN] (#5764) 2020-01-25 22:21:28 +09:00
fa8f9c286d Update README.md [AUTOGEN] (#5763) 2020-01-25 22:15:12 +09:00
ad22491cc0 Update README.md [AUTOGEN] (#5759) 2020-01-25 21:31:54 +09:00
1fc936965c Update README.md [AUTOGEN] (#5752) 2020-01-25 20:45:07 +09:00
9c062643e1 Update README.md [AUTOGEN] (#5749) 2020-01-24 02:00:42 +09:00
f9ad250112 Update README.md [AUTOGEN] (#5747) 2020-01-24 01:59:51 +09:00
990ad0e01d Update README.md [AUTOGEN] (#5745) 2020-01-23 17:18:27 +09:00
683974fa58 Update README.md [AUTOGEN] (#5743) 2020-01-23 17:17:18 +09:00
a3eee05cea Update README.md [AUTOGEN] (#5741) 2020-01-22 07:28:27 +09:00
93dae4ec1c Update README.md [AUTOGEN] (#5740) 2020-01-22 07:27:44 +09:00
84178ba38a APの流量制限とリトライ期間の変更 (#5734)
* AP rate limit

* AP Job attempts

* fix
2020-01-20 14:14:09 +09:00
46aaf8fa9a AP Actorの鍵とkeyIdのフォーマットの変更 (#5733)
* Node PKCS#8

* keyIdを#main-key形式に
2020-01-20 04:51:44 +09:00
5a950cf991 Fix syuilo#5729 (#5732) 2020-01-20 01:53:17 +09:00
75cb7f8b36 Fix #5728 (#5731) 2020-01-20 01:52:35 +09:00
79cbf0888c Redis subscriberで認証ができないのを修正 Fix #5727 (#5730) 2020-01-20 01:51:18 +09:00
10f237be95 Add mark-admin command (#5705)
* mark-admin command

* no cli
2020-01-20 01:50:12 +09:00
85971d3d88 Fix: PagesでDRPWPMが最初のしか出てこない (#5707) 2020-01-19 03:38:59 +09:00
26b193d39d fix (#5710) 2020-01-19 03:38:22 +09:00
ab1b0cc840 Allow CORS requests in /.well-known/* routes (#5717)
* Allow CORS requests in /.well-known/* routes

* Fix bug
2020-01-16 04:46:43 +09:00
9703ba5340 ファイルと画像認識処理の改善 (#5690)
* dimensions制限とリファクタ

* comment

* 不要な変更削除

* use fromFile など

* Add probe-image-size.d.ts

* えーCRLFで作るなよ…

* Update src/@types/probe-image-size.d.ts

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

* fix d.ts

* Update src/@types/probe-image-size.d.ts

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

* Update src/@types/probe-image-size.d.ts

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

* fix

Co-authored-by: Acid Chicken (硫酸鶏) <root@acid-chicken.com>
2020-01-12 16:40:58 +09:00
d09d06e4cb Refactor 2020-01-10 16:23:58 +09:00
3ed76718a8 Remove needless await 2020-01-10 16:04:25 +09:00
45aae00ad5 Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2020-01-10 15:55:44 +09:00
c62a16ae64 Add some log for debugging 2020-01-10 15:55:40 +09:00
e6b93c1dbb Fix #5687 (#5701) 2020-01-10 11:16:08 +09:00
350310c4c2 ドキュメントのNode.js最小バージョンを修正 (#5700)
@typescript-eslint/parserが11.10.1以上じゃないと入らない

> error @typescript-eslint/parser@2.3.3: The engine "node" is incompatible with this module. Expected version "^8.10.0 || ^10.13.0 || >=11.10.1". Got "11.7.0"

https://github.com/syuilo/misskey/runs/274115939
2020-01-09 17:46:29 +09:00
1811725b9d ローカルタイムラインのテストを修正 (#5699)
visibility=specifiedな投稿はローカルタイムラインに流れない
2020-01-09 17:29:03 +09:00
c0938fe372 Update README.md [AUTOGEN] (#5698) 2020-01-09 16:50:43 +09:00
0f25c74415 カスタム絵文字リアクションでないものは絵文字クエリをしないように (#5693)
* カスタム絵文字リアクションの絵文字がNoteに添付されないのを修正

* ねんのため

* 記述順

* カスタム絵文字リアクションでないものは絵文字クエリをしないように
2020-01-09 14:37:48 +09:00
3ecb0ab161 Add GitHub Actions (#5522)
* add .github/workflows/nodejs.yml

* fix

* GitHub Actions: Node.js 8.xはサポートしない

* add .github/workflows/docker.yml

* Dockerビルドをキャッシュするように

* Run test in github actions

* 同リポジトリ内からのプルリクだと無駄に二回走るのを抑制

* 6925c00のdocker.ymlへの適応忘れ

* fix .circleci/misskey/test.yml

* test実行時にDBとかredisとか動かすように

* fix

* fix tests (#5544)

* fix test

* fix compile errors

* PATH引き継ぎでchild_process.spawn時のENOENTを修正

*  サーバー起動処理を共通化

* fix coding style

* fd=4をipcに使うように

* fix port

* fix

* fix ws port

* #4033 にテストケースを追従

* fix?

* fix??

* fix

* fix

* fix

* maybe fix

* fix

* node 10.xサポートしてなかった

* 11.10じゃないとだめだった

* fix

* remove chart test

* fix

* chart test復活

* fix

* 一回一回コネクションを閉じる

* Revert "一回一回コネクションを閉じる"

This reverts commit 56e35cf4f83070744c8dd852f1a7075011d88828.

* 一回一回sync→dropしてるのをやめてみる

* fix

* fix

* …

* キャッシュを切ってみる

* add ts to require target

* omg fix

* Revert "キャッシュを切ってみる"

This reverts commit 88161c59d2ea769ddf87143ba4fd4660a06afdf2.

* done呼び忘れ

* 実際の文字数リミットと違ってたので対応

* テストケースがバグってたので修正

* Revert "一回一回sync→dropしてるのをやめてみる"

This reverts commit a9e543ba2eef790ac7a14ae8799b898765748e35.

* fix

* fix

* fix

* fix?

* fix

* chartのconnectionを分離する

* fix

* fix

* fix tsconfig?

* Revert "fix tsconfig?"

This reverts commit ba9269eaf65507ff97ec1dd2e27260fb2cf0510b.

* fix

* TS_NODE_FILES を scripts の方で指定

* Windowsェ

* Circle CIの実行条件をmasterへのpushのみに

Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
2020-01-09 14:35:04 +09:00
16fb7c4557 11.37.1 2020-01-07 23:35:29 +09:00
8aafafe416 Fix #5688 (#5689)
* Resolve #5688

* あああああ

* 😇

* :thinking_face:

* Update detect-mine.ts

Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
2020-01-07 23:34:17 +09:00
1231 changed files with 37763 additions and 74509 deletions

View File

@ -1,76 +1,12 @@
version: 2.1
executors:
default:
working_directory: /tmp/workspace
docker:
- image: misskey/ci:v11-node11
- image: circleci/redis:latest
- image: circleci/postgres:latest
docker:
working_directory: /tmp/workspace
docker:
- image: docker:latest
jobs:
build:
executor: default
steps:
- checkout
- run:
name: Ensure yarn.lock
command: |
touch yarn.lock
- restore_cache:
name: Restore npm package caches
keys:
- yarn-v1-arch-{{ arch }}-env-{{ .Environment.variableName }}-package-{{ checksum "package.json" }}-lock-{{ checksum "yarn.lock" }}
- yarn-v1-arch-{{ arch }}-env-{{ .Environment.variableName }}-package-{{ checksum "package.json" }}-
- yarn-v1-arch-{{ arch }}-env-{{ .Environment.variableName }}-
- yarn-v1-arch-{{ arch }}-
- yarn-v1-
- run:
name: Install Dependencies
command: |
yarn install
- run:
name: Configure
command: |
cp .circleci/misskey/default.yml .config
cp .circleci/misskey/test.yml .config
- run:
name: Build
command: |
yarn build
touch yarn.lock
- save_cache:
name: Cache npm packages
key: yarn-v1-arch-{{ arch }}-env-{{ .Environment.variableName }}-package-{{ checksum "package.json" }}-lock-{{ checksum "yarn.lock" }}
paths:
- node_modules
- persist_to_workspace:
root: .
paths:
- .
test:
parameters:
executor:
type: string
default: "default"
executor: <<parameters.executor>>
steps:
- attach_workspace:
at: /tmp/workspace
- run:
name: Test
command: |
yarn test
touch yarn.lock
- save_cache:
name: Cache npm packages
key: yarn-v1-arch-{{ arch }}-env-{{ .Environment.variableName }}-package-{{ checksum "package.json" }}-lock-{{ checksum "yarn.lock" }}
paths:
- node_modules
docker:
parameters:
with_deploy:
@ -102,55 +38,8 @@ jobs:
workflows:
version: 2
nodejs:
jobs:
- hold:
name: manual-build-trigger
type: approval
filters:
branches:
ignore: master
- build:
name: manual-build
requires:
- manual-build-trigger
filters:
branches:
ignore: master
- build:
name: auto-build
filters:
branches:
only: master
- test:
name: manual-test
requires:
- manual-build
filters:
branches:
ignore: master
- test:
name: auto-test
requires:
- auto-build
filters:
branches:
only: master
docker:
jobs:
- hold:
name: manual-build-trigger
type: approval
filters:
branches:
ignore: master
- docker:
name: manual-build
requires:
- manual-build-trigger
filters:
branches:
ignore: master
- docker:
name: auto-build
with_deploy: true

View File

@ -1,12 +1,12 @@
url: 'http://misskey.local'
port: 80
mongodb:
port: 8080
db:
host: localhost
port: 27017
db: misskey
user: syuilo
port: 5432
db: test-misskey
user: postgres
pass: ''
redis:
host: localhost
port: 6379
pass: ''
id: aid

View File

@ -1,13 +1,12 @@
url: 'http://misskey.local'
port: 80
mongodb:
port: 8080
db:
host: localhost
port: 27017
port: 5432
db: test-misskey
user: admin
user: postgres
pass: ''
# __REDIS__
redis:
host: localhost
port: 6379
pass: ''
id: aid

View File

@ -111,10 +111,6 @@ id: 'aid'
# ┌─────────────────────┐
#───┘ Other configuration └─────────────────────────────────────
# If enabled:
# The first account created is automatically marked as Admin.
autoAdmin: true
# Whether disable HSTS
#disableHsts: true
@ -125,6 +121,14 @@ autoAdmin: true
# deliverJobConcurrency: 128
# inboxJobConcurrency: 16
# Job rate limiter
# deliverJobPerSec: 128
# inboxJobPerSec: 16
# Job attempts
# deliverJobMaxAttempts: 12
# inboxJobMaxAttempts: 8
# IP address family used for outgoing request (ipv4, ipv6 or dual)
#outgoingAddressFamily: ipv4

1
.github/CODEOWNERS vendored
View File

@ -6,7 +6,6 @@
/.github/ @syuilo @AyaMorisawa @acid-chicken
/.vscode/ @acid-chicken
/assets/ @syuilo # @tamaina
/cli/ @syuilo
/docs/ @syuilo
/docs/*.en.md @AyaMorisawa # @skid9000
# /docs/*.fr.md @BoFFire

18
.github/workflows/docker.yml vendored Normal file
View File

@ -0,0 +1,18 @@
name: Docker build
on:
push:
branches:
- master
- develop
pull_request:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Pull previous build result (for cache)
run: docker pull misskey/misskey:latest
- name: Build docker container
run: docker build --cache-from misskey/misskey:latest -t misskey/misskey .

42
.github/workflows/nodejs.yml vendored Normal file
View File

@ -0,0 +1,42 @@
name: Node.js CI
on:
push:
branches:
- master
- develop
pull_request:
jobs:
build_and_test:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [11.10.x, 12.x]
services:
postgres:
image: postgres:10-alpine
ports:
- 5432:5432
env:
POSTGRES_DB: test-misskey
redis:
image: redis:alpine
ports:
- 6379:6379
steps:
- uses: actions/checkout@v1
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: Install dependencies
run: yarn install
- name: Copy Configure
run: cp .circleci/misskey/*.yml .config
- name: Build
run: yarn build
- name: Test
run: yarn test

1
.gitignore vendored
View File

@ -7,6 +7,7 @@
# Node.js
/node_modules
report.*.json
# config
/.config/*

5
.imgbotconfig Normal file
View File

@ -0,0 +1,5 @@
{
"ignoredFiles": [
"test/resources/*"
]
}

View File

@ -1,6 +1,311 @@
ChangeLog
=========
12.14.0 (2020/02/18)
-------------------
### ✨Improvements
* オブジェクトストレージの設定を実装
* サーバーログビューア実装
12.13.0 (2020/02/18)
-------------------
### ✨Improvements
* プロモーションノート機能を実装
* インスタンス管理者が、重要なお知らせやユーザーにやってもらいたいアンケートなどをタイムラインの途中に挿入する機能
* プロモーションされる期限を設定できる
* 複数のプロモーションがある場合はランダムに選択されて表示される
* ユーザーがプロモーションを個別に非表示にすることもできる
* ハイライトインジェクション機能を実装
* タイムラインの途中におすすめのノートを表示できる機能
* 設定で有効/無効を切り替えられる
* アクティビティウィジェットを実装
* フォトウィジェットを実装
* タイムラインの一番上までスクロールできるように
* 管理者はモデレーターに変更できないように
### 🐛Fixes
* admin/show-users APIがadminかつmoderator設定されているとき使えない問題を修正
12.12.0 (2020/02/17)
-------------------
### ✨Improvements
* インスタンス情報ページを強化
* インスタンス設定ページを強化
* 設定ページをアカウント設定ページとクライアント設定ページに分離
* UIの調整
12.11.0 (2020/02/16)
-------------------
### ✨Improvements
* 投稿詳細ページで前後の投稿を見れるように
* 自分のfollowersートはRenoteできるように
* 画像ダイアログを実装
* フォロー申請ページの調整
* 壁紙設定の強化
* 画面が狭い状態でMisskeyを起動した場合でも、画面幅が広がったときにウィジェットを表示するように
* 「もっと読み込む」したときの読み込み量を増量
### 🐛Fixes
* 認証なしでグローバルTLにアクセスすると妙なエラーが返る問題を修正
* API docが見れない問題を修正
* 画面右上に当たり判定があるのを修正
12.10.0 (2020/02/15)
-------------------
### ✨Improvements
* アンテナの受信ソースにグループを指定できるように
* 時計ウィジェットを追加
* ログアウトせずに新しいアカウントを追加できるように
* フォントサイズを設定できるように
* APIキー設定を実装
### 🐛Fixes
* v12アップデート後にトップページアクセスでOops!になっちゃうのを修正
* drive/files APIのパフォーマンスを改善
12.9.0 (2020/02/14)
-------------------
### ✨Improvements
* カスタム絵文字の管理を強化
* 動きのあるMFMを無効にするオプションを追加
### 🐛Fixes
* タイムラインに自分の返信と自分への返信と投稿者自身への返信以外の返信が含まれている問題を修正
* グループがない状態でグループチャットを開始しようとするとフリーズする問題を修正
* 通知インジケーターがずれる問題を修正
* AP: 投稿を削除したときに関係する投稿の削除アクティビティが連合されない問題を修正
12.8.0 (2020/02/13)
--------------------
### ✨Improvements
* タイムラインなどを遡っているときは新しいアイテムが来てもスクロールしないように
* 表示言語を切り替えられるように
* グループに招待されたときの通知を追加
* フランス語と関西弁を有効に
* OSネイティブの絵文字を使用オプションを追加
### 🐛Fixes
* リストを追加するとエラーが出る問題を修正
* タイムラインを放置すると先頭の投稿が見えなくなるのを修正
12.7.1 (2020/02/11)
--------------------
### 🐛Fixes
* 非ログイン時にページが表示されない問題を修正
12.7.0 (2020/02/10)
--------------------
### ✨Improvements
* ノートの文字数制限の設定を復活
* デザインの調整
### 🐛Fixes
* 中国語で表示できない問題を修正
12.6.0 (2020/02/10)
--------------------
### ✨Improvements
* リンクにホバーするとURLプレビューを表示するように
* ユーザーページからグループに招待できるように
* ウィジェットはブラウザごとに記憶するように
### 🐛Fixes
* 要素の幅を判定する処理が上手くいかないことがある問題を修正
12.5.0 (2020/02/09)
--------------------
### ✨Improvements
* チュートリアルを実装
* 検索のキーボードショートカットを追加
* タイムラインを遡っている状況でないときに、誰かをフォローまたはフォロー解除したときにタイムラインをリロードするように
### 🐛Fixes
* グループチャットが開始できない問題を修正
* Renoteメニューが開けない問題を修正
* 誕生日設定が崩れていたのを修正
* キャッシュが削除できない問題を修正
12.4.1 (2020/02/09)
--------------------
### 🐛Fixes
* グループの招待をacceptもrejectも出来ない問題を修正
* 非ログイン時に検索欄がズレていたのを修正
* バックグラウンドで受信したタイムラインの投稿のリアクションが受信されていない問題を修正
12.4.0 (2020/02/09)
--------------------
### ✨Improvements
* ローカルのみをデフォルトで操作できるように
* キーボード操作を改善
* AP: Create ActivityでattributedToの補完とaudienceのコピーを行うように
### 🐛Fixes
* ページ遷移してもナビゲーションが閉じない問題を修正
* デフォルトの公開範囲のリストにホームがなかったので復活
12.3.0 (2020/02/08)
--------------------
### ✨Improvements
* グループ実装
* /share実装
* 指定したURLのページが見つからなかった時のページを実装
* ドキュメント実装
* AP: EmojiReaction => EmojiReact
### 🐛Fixes
* 画面の縦の幅が狭いとメニューが一部隠れる問題を修正
* リストの設定ページが開けなかった問題を修正
* drive-file-thumbnailのicon-subがおかしい問題を修正
* ドライブのフォルダー名の変更と削除ができない問題を修正
12.2.0 (2020/02/06)
--------------------
### ✨Improvements
* UIのアニメーションを無効にできるように
* トークで絵文字ピッカーを表示できるように
* 戻るボタンだけでなく、ホームボタンを押してホームに戻ったときもスクロール位置を復元するように
* タブを見ていないときのタイムライン通知を削除
### 🐛Fixes
* PWAとしてインストールできなかったのを修正
* トークでドライブからファイルを添付出来ない問題を修正
12.1.0 (2020/02/06)
--------------------
### ✨Improvements
* サーバー切断時に自動でリロードできるように
### 🐛Fixes
* もっと読み込むを続けていくと表示が遅くなっていく問題を修正
* Renote メニューが自分の投稿のRenoteでない限り表示されない問題を修正
* MFM jump, spin, title が効かない問題を修正
* AP: Likeで正しいActivity IDを提示するように修正
* AP: Misskey以外からのトークの返信が受け取れないのを修正
12.0.0 indigo (2020/02/06)
--------------------
Misskey v12では、クライアントが設計し直され、全く新しいUIに生まれ変わりました。
レスポンシブになり、ひとつのコードで様々なデバイスに対応できるようにしました。
各部で使用されるアニメーションは、ブラウザネイティブのトランジションを使用することでよりスムーズになりました。
目に見える変更だけではなく、内部的にも軽量化などの改善があります。
また、指定した条件にマッチする投稿を抽出できるタイムラインの追加や、インタラクティブな通知など、新機能もいくつかあります。
まだ未実装の機能(ウィジェット、テーマエディタ、リバーシ、フグパンチボタンなど)がありますが、今後のアップデートで復活します。
内部的には、コンポーネントの重複が解消され、ローカリゼーションも整理されたので、今後メンテナンスしやすくなっています。
さらに技術的なことを言うと、スタイルの記述に従来のStylusに代わってSCSSを採用し、開発の際にブラウザで編集したスタイルを持ってきやすくなるなどの改善が行なわれています。また、FontAwesomeコンポーネントに文字列形式でアイコンを指定するのをやめ、使用する都度アイコンをインポートするようにしました。これによりTree ShakingやCode Splittingとの相性が良くなります。
v12ではいくつかインスタンスにとって破壊的な変更がありますので、アップデートする前に以下の変更をお読みになりデータ(お知らせ)のバックアップなどお願いします。
アップデートが上手くいかない場合は、クリーンビルド(builtディレクトリを消した後、再度build)をお試しください。
### ⚠Breaking Changes
* お知らせがリセットされます。
* 通知がリセットされます。
* アカウントの外部サービス連携情報がリセットされます。
* インスタンスの閉鎖情報がリセットされます。
* プロキシアカウント設定情報がリセットされます。
* モデレーターがインスタンス設定を閲覧したり変更したりできなくなります(それらができるのはAdminのみになります)。
* モデレーターが出来るのは、ユーザーのサイレンス/凍結などに限られます。
* 従来と同じ権限を与えたい場合、モデレーターをAdminに設定することを検討してください(Adminは複数人設定可能です)。
* notes/search APIのページングがoffsetではなくuntilId方式に
* クライアントのテーマのフォーマットが調整されました。
* 旧テーマを変換してインポートする機能が予定されています
* ノートに位置情報を添付できる機能を廃止
* ノートに何のアプリから投稿したかという情報を含めるのを廃止
* Meta APIでサーバー内部の情報(マシン名、CPU情報など)を含めるのを廃止
### ✨Improvements
* Webクライアントを一新
* Syuilo Design System (仮称)を採用し、各コンポーネントが統一され一貫したデザインに
* レスポンシブデザインになり、デスクトップ/タブレット/スマートフォンで同じ機能が使えるように
* 複数アカウントに対応し、簡単に別のアカウントに切り替えられるように
* フォロー通知から直接フォローバックすることができるように
* 通知から直接フォローリクエストを許可/拒否できるように
* ユーザーの登録日を表示するように
* タイムラインウィジェットを追加
* 投稿フォームでメンションを追加するのが簡単に
* Renoteを解除できるように
* スマホ/タブレットでも絵文字ピッカーを使えるように
* ユーザーを選択する操作が便利に
* ユーザーページからユーザーにメッセージを送れるように
* ユーザーページからユーザーとトークを開始できるように
* ユーザーページからユーザー名をコピーできるように
* 非ログイン時のトップページにLTLではなくハイライトを表示するように
* 「戻る」ボタンを追加し、PWAフレンドリーに
* ストリーミングが切断された時にリロードできるようになり、PWAフレンドリーに
* タイムラインからユーザーページ等に遷移して戻ったときにタイムラインが初期化されないように
* 管理画面のカスタム絵文字一覧でページネーションを実装
* 二段階認証のトークンの有効期限を長く
* ESCキーでダイアログを閉じられるように
* 軽量化
* お知らせ機能の強化
* お知らせが未読か既読か管理されるようになり、未読のお知らせがあると分かりやすく表示されるように
* 何人がお知らせを読んだか分かるように
* アンテナ機能
* 指定した条件(キーワード、ファイル添付の有無など)にマッチする投稿のタイムラインを見れる機能
* 新しい投稿があったとき通知するようにもできる
* ウィジェットとしても表示可能
* Elasticsearchをインストールしなくても全文検索できるように
* リモートのカスタム絵文字をコピーしてくる機能を追加
* 自分の送ったフォローリクエストが承認されたときの通知を追加
* 絵文字判定正規表現と絵文字テーブルにUnicode 12.1分を追加
* TwemojiではサポートしているけどピッカーにないShibuya 109の絵文字を追加
* 韓国語のnyaizeを強化
* 外部サービス連携情報をプロフィールに表示しないように
* 今後個別に表示するかどうか設定できるようになる予定
* ハイライト投稿の並びを人気順ではなく投稿日時順に
* AIDのイズがあまりよくないのを改善
* WebAuthNで internal というタイプもあるようなのでそれも使えるように
* Allow CORS requests in /.well-known/* routes
* AP: リモート投稿にリモートでされたリアクションが表示されるように
* AP: Eventタイプのアクティビティをサポート
* AP: GroupとOrganizationを正規のActorとして受け付けるように
* AP: deliver/inbox 処理にインスタンス全体で流量制限をかけられるように
* AP: deliverのリトライ期間を長めにして、回数を変更できるように
* AP: Actorの鍵とkeyIdのフォーマットの変更
* 投稿する度にMastodonから3つずつリクエストが飛んできてしまう問題が解決し、双方の負荷が減って MastodonへのAP 配信所要時間が1/4~1/5に
* PixelFedへの配信ができるように
* AP: PixelFedのハッシュタグをハッシュタグ扱いできるように
* 他多数
### 🐛Fixes
* ミュートしている人からのリアクション通知があると、通知があると表示される問題を修正
* 投稿メニューを開いて操作した後にもう一度メニューを開こうとしてもできない問題を修正
* リモートのートのURLが書かれていた場合、動作がおかしい問題を修正
* リストTLだとTでのTLフォーカスが効かない問題を修正
* OAuth認証画面の配色がおかしい問題を修正
* 設定画面で、アバターを更新してもアバターの画像がその場で更新されない問題を修正
* 投稿詳細/ユーザー詳細 画面でadminや公式アカウントマークが表示されない問題を修正
* ハッシュタグ検索が遅い問題を修正
* APIのリクエスト方法(websocket/HTTP)によって返ってくるエラーの内容に違いがある問題を修正
* ストリーミングのuserListチャンネルで存在しないリストでもsubscribeできて、リストのIDがわかれば他人のリストでもsubscribeできる問題を修正
* Redis subscriberで認証ができないのを修正
* ファイルと画像認識処理の改善
* カスタム絵文字リアクションでないものは絵文字クエリをしないように
* トレンドで非公開な投稿のハッシュタグを集計しないように
* nyaizeの適用範囲の修正
* URLまでnyaizeされている問題を修正
* ハッシュタグまでnyaizeされている問題を修正
*
* 投稿フォームでCWが下書きに保存されない問題を修正
* 投稿フォームで公開範囲が下書きに保存されない問題を修正
* messaging/messages/read APIが正しく動作していなかった問題を修正
* TypeError: Cannot read property 'stack' of undefined が出ることがある問題を修正
* AP: カスタム絵文字を連続して書くと他のサービスでカスタム絵文字と認識されない問題を修正
* AP: audience (visibility) パースの修正
* AP: inboxの最小リトライ間隔 1秒→1分
* Pages: VERSION 変数が常に null な問題を修正
* Pages: DRPWPMが最初のしか出てこない問題を修正
* Pages: MY_NOTES_COUNT 変数が機能していなかったので削除
* Pages: MY_FOLLOWERS_COUNT 変数が機能していなかったので削除
* Pages: MY_FOLLOWING_COUNT 変数が機能していなかったので削除
11.37.1 (2020/01/07)
--------------------
### 🐛Fixes
* ファイルがアップロードできない問題を修正
11.37.0 (2020/01/07)
--------------------
### ✨Improvements

15
COPYING Normal file
View File

@ -0,0 +1,15 @@
Unless otherwise stated this repository is
Copyright © 2014-2020 syuilo and contributers
And is distributed under The GNU Affero General Public License Version 3, you should have received a copy of the license file as LICENSE.
Misskey includes several third-party Open-Source softwares.
Unicode emoji regular expressions by Twitter, Inc.
License: MIT
https://github.com/twitter/twemoji-parser/blob/master/LICENSE.md
Emoji keywords for Unicode 11 and below by Mu-An Chiou
License: MIT
https://github.com/muan/emojilib/blob/master/LICENSE

View File

@ -103,15 +103,16 @@ Please see the [Contribution Guide](./CONTRIBUTING.md).
----------------------------------------------------------------
<!-- PATREON_START -->
<table><tr>
<td><img src="https://c8.patreon.com/2/200/20832595" alt="Roujo" width="100"></td>
<td><img src="https://c8.patreon.com/2/200/27956229" alt="Oliver Maximilian Seidel" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/12190916/fb7fa7983c14425f890369535b1506a4/3.png?token-time=2145916800&token-hash=oH_i7gJjNT7Ot6j9JiVwy7ZJIBqACVnzLqlz4YrDAZA%3D" alt="weepjp" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/605366/c9dc408fdcbf412fb183ca5b06235f8d/1.jpeg?token-time=2145916800&token-hash=oaqsjLqOFjWN5I9hm2epOaTXaEtKwQUy5OW-EpAz6-g%3D" alt="Jon Leibowitz" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/19045173/cb91c0f345c24d4ebfd05f19906d5e26/1.png?token-time=2145916800&token-hash=o_zKBytJs_AxHwSYw_5R8eD0eSJe3RoTR3kR3Q0syN0%3D" alt="kiritan" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/24430516/b1964ac5b9f746d2a12ff53dbc9aa40a/1.jpg?token-time=2145916800&token-hash=bmEiMGYpp3bS7hCCbymjGGsHBZM3AXuBOFO3Kro37PU%3D" alt="Eduardo Quiros" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/14215107/1cbe1912c26143919fa0faca16f12ce1/2.png?token-time=2145916800&token-hash=v0KzlXjyiq18u6aSxyy9qIUxSCAx-nnHlO7MzhSA6Mc%3D" alt="Nesakko" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/14215107/1cbe1912c26143919fa0faca16f12ce1/3.png?token-time=2145916800&token-hash=Zq1TCK2tdY7xudEm_aV70bc_wxmol6pNj3ZWbpFUNbI%3D" alt="Nesakko" width="100"></td>
<td><img src="https://c8.patreon.com/2/200/776209" alt="Denshi" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/3075183/c2ae575c604e420297f000ccc396e395/1.jpeg?token-time=2145916800&token-hash=O9qmPtpo6wWb0OuvnkEekhk_1WO2MTdytLr7ZgsAr80%3D" alt="Liaizon Wakest" width="100"></td>
</tr><tr>
<td><a href="https://www.patreon.com/user?u=20832595">Roujo</a></td>
<td><a href="https://www.patreon.com/user?u=27956229">Oliver Maximilian Seidel</a></td>
<td><a href="https://www.patreon.com/weepjp">weepjp</a></td>
<td><a href="https://www.patreon.com/jonleibowitz">Jon Leibowitz</a></td>
@ -119,9 +120,9 @@ Please see the [Contribution Guide](./CONTRIBUTING.md).
<td><a href="https://www.patreon.com/user?u=24430516">Eduardo Quiros</a></td>
<td><a href="https://www.patreon.com/Nesakko">Nesakko</a></td>
<td><a href="https://www.patreon.com/user?u=776209">Denshi</a></td>
<td><a href="https://www.patreon.com/wakest">Liaizon Wakest</a></td>
</tr></table>
<table><tr>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/3075183/c2ae575c604e420297f000ccc396e395/1.jpeg?token-time=2145916800&token-hash=O9qmPtpo6wWb0OuvnkEekhk_1WO2MTdytLr7ZgsAr80%3D" alt="Liaizon Wakest" width="100"></td>
<td><img src="https://c8.patreon.com/2/200/557245" alt="mkatze" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/23915207/25428766ecd745478e600b3d7f871eb2/1.png?token-time=2145916800&token-hash=urCLLA4KjJZX92Y1CxcBP4d8bVTHGkiaPnQZp-Tqz68%3D" alt="kabo2468y" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/8249688/4aacf36b6b244ab1bc6653591b6640df/2.png?token-time=2145916800&token-hash=1ZEf2w6L34253cZXS_HlVevLEENWS9QqrnxGUAYblPo%3D" alt="AureoleArk" width="100"></td>
@ -130,7 +131,9 @@ Please see the [Contribution Guide](./CONTRIBUTING.md).
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/18899730/6a22797f68254034a854d69ea2445fc8/1.png?token-time=2145916800&token-hash=b_uj57yxo5VzkSOUS7oXE_762dyOTB_oxzbO6lFNG3k%3D" alt="YuzuRyo61" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/5788159/af42076ab3354bb49803cfba65f94bee/1.jpg?token-time=2145916800&token-hash=iSaxp_Yr2-ZiU2YVi9rcpZZj9mj3UvNSMrZr4CU4qtA%3D" alt="mewl hayabusa" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/11357794/923ce94cd8c44ba788ee931907881839/1.png?token-time=2145916800&token-hash=9nEQje_eMvUjq9a7L3uBqW-MQbS-rRMaMgd7UYVoFNM%3D" alt="mydarkstar" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/28779508/3cd4cb7f017f4ee0864341e3464d42f9/1.png?token-time=2145916800&token-hash=eGQtR15be44kgvh8fw2Jx8Db4Bv15YBp2ldxh0EKRxA%3D" alt="S Y" width="100"></td>
</tr><tr>
<td><a href="https://www.patreon.com/wakest">Liaizon Wakest</a></td>
<td><a href="https://www.patreon.com/user?u=557245">mkatze</a></td>
<td><a href="https://www.patreon.com/user?u=23915207">kabo2468y</a></td>
<td><a href="https://www.patreon.com/AureoleArk">AureoleArk</a></td>
@ -139,60 +142,57 @@ Please see the [Contribution Guide](./CONTRIBUTING.md).
<td><a href="https://www.patreon.com/Yuzulia">YuzuRyo61</a></td>
<td><a href="https://www.patreon.com/hs_sh_net">mewl hayabusa</a></td>
<td><a href="https://www.patreon.com/mydarkstar">mydarkstar</a></td>
<td><a href="https://www.patreon.com/user?u=28779508">S Y</a></td>
</tr></table>
<table><tr>
<td><img src="https://c8.patreon.com/2/200/16542964" alt="Takumi Sugita" width="100"></td>
<td><img src="https://c8.patreon.com/2/200/17866454" alt="sikyosyounin" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/5881381/6235ca5d3fb04c8e95ef5b4ff2abcc18/3.png?token-time=2145916800&token-hash=KjfQL8nf3AIf6WqzLshBYAyX44piAqOAZiYXgZS_H6A%3D" alt="YUKIMOCHI" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/26340354/08834cf767b3449e93098ef73a434e2f/2.png?token-time=2145916800&token-hash=nyM8DnKRL8hR47HQ619mUzsqVRpkWZjgtgBU9RY15Uc%3D" alt="totokoro" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/19356899/496b4681d33b4520bd7688e0fd19c04d/2.jpeg?token-time=2145916800&token-hash=_sTj3dUBOhn9qwiJ7F19Qd-yWWfUqJC_0jG1h0agEqQ%3D" alt="sheeta.s" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/5827393/59893c191dda408f9cabd0f20a3a5627/1.jpeg?token-time=2145916800&token-hash=i9N05vOph-eP1LTLb9_npATjYOpntL0ZsHNaZFSsPmE%3D" alt="motcha" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/13737140/1adf7835017d479280d90fe8d30aade2/1.png?token-time=2145916800&token-hash=0pdle8h5pDZrww0BDOjdz6zO-HudeGTh36a3qi1biVU%3D" alt="Satsuki Yanagi" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/17880724/311738c8a48f4a6b9443c2445a75adde/1.jpe?token-time=2145916800&token-hash=CPxGQhKIlEaa6WUcgbyHixyKEhakiw9RFdOhsIJBQ_o%3D" alt="takimura" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/16900731/619ab87cc08448439222631ebb26802f/1.gif?token-time=2145916800&token-hash=o27K7M02s1z-LkDUEO5Oa7cu-GviRXeOXxryi4o_6VU%3D" alt="Atsuko Tominaga" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/17880724/311738c8a48f4a6b9443c2445a75adde/1.jpg?token-time=2145916800&token-hash=nVAntpybQrznE0rg05keLrSE6ogPKJXB13rmrJng42c%3D" alt="takimura" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/13100201/fc5be4fa90444f09a9c8a06f72385272/1.png?token-time=2145916800&token-hash=i8PjlgfOB2LPEdbtWyx8ZPsBKhGcNZqcw_FQmH71UGU%3D" alt="aqz tamaina" width="100"></td>
</tr><tr>
<td><a href="https://www.patreon.com/user?u=16542964">Takumi Sugita</a></td>
<td><a href="https://www.patreon.com/user?u=17866454">sikyosyounin</a></td>
<td><a href="https://www.patreon.com/yukimochi">YUKIMOCHI</a></td>
<td><a href="https://www.patreon.com/user?u=26340354">totokoro</a></td>
<td><a href="https://www.patreon.com/user?u=19356899">sheeta.s</a></td>
<td><a href="https://www.patreon.com/user?u=5827393">motcha</a></td>
<td><a href="https://www.patreon.com/user?u=13737140">Satsuki Yanagi</a></td>
<td><a href="https://www.patreon.com/takimura">takimura</a></td>
<td><a href="https://www.patreon.com/user?u=16900731">Atsuko Tominaga</a></td>
<td><a href="https://www.patreon.com/aqz">aqz tamaina</a></td>
</tr></table>
<table><tr>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/16900731/619ab87cc08448439222631ebb26802f/1.gif?token-time=2145916800&token-hash=o27K7M02s1z-LkDUEO5Oa7cu-GviRXeOXxryi4o_6VU%3D" alt="Atsuko Tominaga" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/4389829/9f709180ac714651a70f74a82f3ffdb9/3.png?token-time=2145916800&token-hash=FTm3WVom4dJ9NwWMU4OpCL_8Yc13WiwEbKrDPyTZTPs%3D" alt="natalie" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/5923936/2a743cbfbff946c2af3f09026047c0da/2.png?token-time=2145916800&token-hash=h6yphW1qnM0n_NOWaf8qtszMRLXEwIxfk5beu4RxdT0%3D" alt="noellabo" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/2384390/5681180e1efb46a8b28e0e8d4c8b9037/1.jpg?token-time=2145916800&token-hash=SJcMy-Q1BcS940-LFUVOMfR7-5SgrzsEQGhYb3yowFk%3D" alt="CG" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/18072312/98e894d960314fa7bc236a72a39488fe/1.jpe?token-time=2145916800&token-hash=qA8j97lIZNc-74AuZ0p4F3ms6sKPeKjtNt2vEuwpsyo%3D" alt="Hekovic" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/18072312/98e894d960314fa7bc236a72a39488fe/1.jpg?token-time=2145916800&token-hash=7bkMqTwHPRsJPGAq42PYdDXDZBVGLqdgr1ZmBxX8GFQ%3D" alt="Hekovic" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/24641572/b4fd175424814f15b0ca9178d2d2d2e4/1.png?token-time=2145916800&token-hash=e2fyqdbuJbpCckHcwux7rbuW6OPkKdERcus0u2wIEWU%3D" alt="uroco @99" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/4503830/ccf2cc867ea64de0b524bb2e24b9a1cb/1.jpeg?token-time=2145916800&token-hash=L55UhJ0rcuNAH3w_ryeeGN4hC6taoOixyAhraEi0bzw%3D" alt="dansup" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/5731881/4b6038e6cda34c04b83a5fcce3806a93/1.png?token-time=2145916800&token-hash=hBayGfOmQH3kRMdNnDe4oCZD_9fsJWSt29xXR3KRMVk%3D" alt="Nokotaro Takeda" width="100"></td>
<td><img src="https://c8.patreon.com/2/200/23932002" alt="nenohi" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/12531784/93a45137841849329ba692da92ac7c60/1.jpeg?token-time=2145916800&token-hash=vGe7wXGqmA8Q7m-kDNb6fyGdwk-Dxk4F-ut8ZZu51RM%3D" alt="Takashi Shibuya" width="100"></td>
</tr><tr>
<td><a href="https://www.patreon.com/user?u=16900731">Atsuko Tominaga</a></td>
<td><a href="https://www.patreon.com/user?u=4389829">natalie</a></td>
<td><a href="https://www.patreon.com/noellabo">noellabo</a></td>
<td><a href="https://www.patreon.com/Corset">CG</a></td>
<td><a href="https://www.patreon.com/hekovic">Hekovic</a></td>
<td><a href="https://www.patreon.com/user?u=24641572">uroco @99</a></td>
<td><a href="https://www.patreon.com/dansup">dansup</a></td>
</tr></table>
<table><tr>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/5731881/4b6038e6cda34c04b83a5fcce3806a93/1.png?token-time=2145916800&token-hash=hBayGfOmQH3kRMdNnDe4oCZD_9fsJWSt29xXR3KRMVk%3D" alt="Nokotaro Takeda" width="100"></td>
<td><img src="https://c8.patreon.com/2/200/23932002" alt="nenohi" width="100"></td>
</tr><tr>
<td><a href="https://www.patreon.com/takenoko">Nokotaro Takeda</a></td>
<td><a href="https://www.patreon.com/user?u=23932002">nenohi</a></td>
<td><a href="https://www.patreon.com/user?u=12531784">Takashi Shibuya</a></td>
</tr></table>
**Last updated:** Sun, 05 Jan 2020 05:37:07 UTC
**Last updated:** Wed, 05 Feb 2020 00:42:12 UTC
<!-- PATREON_END -->
:four_leaf_clover: Copyright
----------------------------------------------------------------
> Copyright (c) 2014-2020 syuilo
Misskey is open-source software licensed under the [GNU AGPLv3](LICENSE).
[![][agpl-3.0-badge]][AGPL-3.0]
[agpl-3.0]: https://www.gnu.org/licenses/agpl-3.0.en.html
[agpl-3.0-badge]: https://img.shields.io/badge/license-AGPL--3.0-444444.svg?style=for-the-badge
[backer-url]: #backers
[backer-badge]: https://opencollective.com/misskey/backers/badge.svg
[backers-image]: https://opencollective.com/misskey/backers.svg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

BIN
assets/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

View File

@ -1,53 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
id="svg8"
version="1.1"
viewBox="0 0 135.46667 135.46667"
height="512"
width="512">
<defs
id="defs2" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
style="fill:#2fa3bc;fill-opacity:1"
transform="translate(-30.809093,-111.78601)"
id="layer1">
<g
style="fill:#2fa3bc;fill-opacity:1"
transform="matrix(1.096096,0,0,1.096096,-2.960633,-44.023579)"
id="g4502">
<g
id="g5125"
transform="translate(-1.3333333e-6,-1.3439941e-6)"
style="fill:#2fa3bc;fill-opacity:1">
<g
aria-label="Mi"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:141.03404236px;line-height:476.69509888px;font-family:'OTADESIGN Rounded';-inkscape-font-specification:'OTADESIGN Rounded';letter-spacing:0px;word-spacing:0px;fill:#2fa3bc;fill-opacity:1;stroke:none;stroke-width:0.28950602px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
id="text4489"
transform="matrix(0.91391326,0,0,0.91391326,7.9719907,17.595761)">
<path
id="path5210"
transform="matrix(0.26412464,0,0,0.26412464,24.988264,136.28626)"
d="m 62.474609,76.585938 c -7.47555,0 -14.595784,1.246427 -21.359375,3.738281 C 29.011968,84.595952 19.044417,92.249798 11.212891,103.28516 3.7373405,113.96451 0,125.88934 0,139.06055 v 233.8789 c 0,17.08697 6.0510264,31.85913 18.154297,44.31836 12.459246,12.10327 27.233346,18.15625 44.320312,18.15625 17.442947,0 32.215089,-6.05298 44.318361,-18.15625 12.45925,-12.45923 18.68945,-27.23139 18.68945,-44.31836 V 330.4082 c 0.13441,-9.21122 9.6225,-6.79429 14.41797,0 8.98111,15.55395 28.02226,28.91242 50.19141,28.83594 22.16915,-0.0764 40.58194,-11.03699 50.19336,-28.83594 3.63981,-4.29263 13.89902,-11.60675 14.95117,0 v 42.53125 c 0,17.08697 6.05102,31.85913 18.15429,44.31836 12.45923,12.10327 27.23335,18.15625 44.32032,18.15625 17.44294,0 32.21509,-6.05298 44.31836,-18.15625 12.45923,-12.45923 18.68945,-27.23139 18.68945,-44.31836 v -233.8789 c 0,-13.17121 -3.9146,-25.09604 -11.74609,-35.77539 -7.47557,-11.035362 -17.26588,-18.689208 -29.36914,-22.960941 -7.11956,-2.491854 -14.23982,-3.738281 -21.35938,-3.738281 -19.22286,0 -35.41865,7.476649 -48.58984,22.427734 l -63.40235,74.199218 c -1.42391,1.06791 -6.14093,9.23242 -16.16015,9.23242 -10.01923,0 -14.20109,-8.16451 -15.625,-9.23242 L 110.53125,99.013672 C 97.716024,84.062587 81.697447,76.585938 62.474609,76.585938 Z m 395.060551,0 c -14.9511,-10e-7 -27.76596,5.340179 -38.44532,16.019531 -10.32338,10.323381 -15.48437,22.961011 -15.48437,37.912111 0,14.9511 5.16099,27.76596 15.48437,38.44531 10.67936,10.32338 23.49422,15.48633 38.44532,15.48633 14.95109,0 27.76596,-5.16295 38.44531,-15.48633 C 506.65982,158.28354 512,145.46868 512,130.51758 512,115.56648 506.65982,102.92885 495.98047,92.605469 485.30112,81.926117 472.48625,76.585938 457.53516,76.585938 Z m 0.5332,118.541012 c -14.9511,0 -27.76596,5.34018 -38.44531,16.01953 -10.67936,10.67936 -16.01758,23.49422 -16.01758,38.44532 v 131.89062 c 0,14.9511 5.33822,27.76596 16.01758,38.44531 10.67935,10.32339 23.49421,15.48633 38.44531,15.48633 14.9511,0 27.58873,-5.16294 37.91211,-15.48633 C 506.65982,409.24838 512,396.43352 512,381.48242 V 249.5918 c 0,-14.9511 -5.34018,-27.76596 -16.01953,-38.44532 -10.32338,-10.67935 -22.96101,-16.01953 -37.91211,-16.01953 z"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:'OTADESIGN Rounded';-inkscape-font-specification:'OTADESIGN Rounded';fill:#2fa3bc;fill-opacity:1;stroke-width:1.09609616px" />
</g>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 4.1 KiB

BIN
assets/icon.afdesign Normal file

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 430 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 671 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1015 B

View File

@ -1,91 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
id="svg8"
version="1.1"
viewBox="0 0 135.46667 135.46667"
height="512"
width="512"
sodipodi:docname="icon.svg"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
inkscape:export-filename="H:\misskey\assets\icons\512.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96">
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="965"
id="namedview10"
showgrid="false"
inkscape:snap-bbox="true"
inkscape:bbox-nodes="true"
inkscape:snap-page="true"
inkscape:zoom="0.921875"
inkscape:cx="219.9952"
inkscape:cy="361.00053"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg8" />
<defs
id="defs2" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<rect
style="opacity:1;fill:#2ba3bc;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.32291675;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal"
id="rect828"
width="135.46667"
height="135.46667"
x="1.896631e-16"
y="0" />
<g
transform="matrix(0.57430748,0,0,0.57430748,11.070705,-35.453717)"
id="layer1"
style="stroke-width:1.74122751;fill:#ffffff;fill-opacity:1">
<g
transform="matrix(1.096096,0,0,1.096096,-2.960633,-44.023579)"
id="g4502"
style="stroke-width:1.74122751;fill:#ffffff;fill-opacity:1">
<g
id="g5125"
transform="translate(-1.3333333e-6,-1.3439941e-6)"
style="fill:#ffffff;fill-opacity:1;stroke-width:1.74122751">
<g
aria-label="Mi"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:141.03404236px;line-height:476.69509888px;font-family:'OTADESIGN Rounded';-inkscape-font-specification:'OTADESIGN Rounded';letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.50409585px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
id="text4489"
transform="matrix(0.91391326,0,0,0.91391326,7.9719907,17.595761)">
<path
id="path5210"
transform="matrix(0.26412464,0,0,0.26412464,24.988264,136.28626)"
d="m 62.474609,76.585938 c -7.47555,0 -14.595784,1.246427 -21.359375,3.738281 C 29.011968,84.595952 19.044417,92.249798 11.212891,103.28516 3.7373405,113.96451 0,125.88934 0,139.06055 v 233.8789 c 0,17.08697 6.0510264,31.85913 18.154297,44.31836 12.459246,12.10327 27.233346,18.15625 44.320312,18.15625 17.442947,0 32.215089,-6.05298 44.318361,-18.15625 12.45925,-12.45923 18.68945,-27.23139 18.68945,-44.31836 V 330.4082 c 0.13441,-9.21122 9.6225,-6.79429 14.41797,0 8.98111,15.55395 28.02226,28.91242 50.19141,28.83594 22.16915,-0.0764 40.58194,-11.03699 50.19336,-28.83594 3.63981,-4.29263 13.89902,-11.60675 14.95117,0 v 42.53125 c 0,17.08697 6.05102,31.85913 18.15429,44.31836 12.45923,12.10327 27.23335,18.15625 44.32032,18.15625 17.44294,0 32.21509,-6.05298 44.31836,-18.15625 12.45923,-12.45923 18.68945,-27.23139 18.68945,-44.31836 v -233.8789 c 0,-13.17121 -3.9146,-25.09604 -11.74609,-35.77539 -7.47557,-11.035362 -17.26588,-18.689208 -29.36914,-22.960941 -7.11956,-2.491854 -14.23982,-3.738281 -21.35938,-3.738281 -19.22286,0 -35.41865,7.476649 -48.58984,22.427734 l -63.40235,74.199218 c -1.42391,1.06791 -6.14093,9.23242 -16.16015,9.23242 -10.01923,0 -14.20109,-8.16451 -15.625,-9.23242 L 110.53125,99.013672 C 97.716024,84.062587 81.697447,76.585938 62.474609,76.585938 Z m 395.060551,0 c -14.9511,-10e-7 -27.76596,5.340179 -38.44532,16.019531 -10.32338,10.323381 -15.48437,22.961011 -15.48437,37.912111 0,14.9511 5.16099,27.76596 15.48437,38.44531 10.67936,10.32338 23.49422,15.48633 38.44532,15.48633 14.95109,0 27.76596,-5.16295 38.44531,-15.48633 C 506.65982,158.28354 512,145.46868 512,130.51758 512,115.56648 506.65982,102.92885 495.98047,92.605469 485.30112,81.926117 472.48625,76.585938 457.53516,76.585938 Z m 0.5332,118.541012 c -14.9511,0 -27.76596,5.34018 -38.44531,16.01953 -10.67936,10.67936 -16.01758,23.49422 -16.01758,38.44532 v 131.89062 c 0,14.9511 5.33822,27.76596 16.01758,38.44531 10.67935,10.32339 23.49421,15.48633 38.44531,15.48633 14.9511,0 27.58873,-5.16294 37.91211,-15.48633 C 506.65982,409.24838 512,396.43352 512,381.48242 V 249.5918 c 0,-14.9511 -5.34018,-27.76596 -16.01953,-38.44532 -10.32338,-10.67935 -22.96101,-16.01953 -37.91211,-16.01953 z"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:'OTADESIGN Rounded';-inkscape-font-specification:'OTADESIGN Rounded';fill:#ffffff;fill-opacity:1;stroke-width:1.90855289px"
inkscape:connector-curvature="0" />
</g>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 5.6 KiB

View File

@ -1,51 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
id="svg8"
version="1.1"
viewBox="0 0 135.46667 135.46667"
height="512"
width="512">
<defs
id="defs2" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
transform="translate(-30.809093,-111.78601)"
id="layer1">
<g
transform="matrix(1.096096,0,0,1.096096,-2.960633,-44.023579)"
id="g4502">
<g
id="g5125"
transform="translate(-1.3333333e-6,-1.3439941e-6)"
style="fill:#000000;fill-opacity:1">
<g
aria-label="Mi"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:141.03404236px;line-height:476.69509888px;font-family:'OTADESIGN Rounded';-inkscape-font-specification:'OTADESIGN Rounded';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.28950602px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
id="text4489"
transform="matrix(0.91391326,0,0,0.91391326,7.9719907,17.595761)">
<path
id="path5210"
transform="matrix(0.26412464,0,0,0.26412464,24.988264,136.28626)"
d="m 62.474609,76.585938 c -7.47555,0 -14.595784,1.246427 -21.359375,3.738281 C 29.011968,84.595952 19.044417,92.249798 11.212891,103.28516 3.7373405,113.96451 0,125.88934 0,139.06055 v 233.8789 c 0,17.08697 6.0510264,31.85913 18.154297,44.31836 12.459246,12.10327 27.233346,18.15625 44.320312,18.15625 17.442947,0 32.215089,-6.05298 44.318361,-18.15625 12.45925,-12.45923 18.68945,-27.23139 18.68945,-44.31836 V 330.4082 c 0.13441,-9.21122 9.6225,-6.79429 14.41797,0 8.98111,15.55395 28.02226,28.91242 50.19141,28.83594 22.16915,-0.0764 40.58194,-11.03699 50.19336,-28.83594 3.63981,-4.29263 13.89902,-11.60675 14.95117,0 v 42.53125 c 0,17.08697 6.05102,31.85913 18.15429,44.31836 12.45923,12.10327 27.23335,18.15625 44.32032,18.15625 17.44294,0 32.21509,-6.05298 44.31836,-18.15625 12.45923,-12.45923 18.68945,-27.23139 18.68945,-44.31836 v -233.8789 c 0,-13.17121 -3.9146,-25.09604 -11.74609,-35.77539 -7.47557,-11.035362 -17.26588,-18.689208 -29.36914,-22.960941 -7.11956,-2.491854 -14.23982,-3.738281 -21.35938,-3.738281 -19.22286,0 -35.41865,7.476649 -48.58984,22.427734 l -63.40235,74.199218 c -1.42391,1.06791 -6.14093,9.23242 -16.16015,9.23242 -10.01923,0 -14.20109,-8.16451 -15.625,-9.23242 L 110.53125,99.013672 C 97.716024,84.062587 81.697447,76.585938 62.474609,76.585938 Z m 395.060551,0 c -14.9511,-10e-7 -27.76596,5.340179 -38.44532,16.019531 -10.32338,10.323381 -15.48437,22.961011 -15.48437,37.912111 0,14.9511 5.16099,27.76596 15.48437,38.44531 10.67936,10.32338 23.49422,15.48633 38.44532,15.48633 14.95109,0 27.76596,-5.16295 38.44531,-15.48633 C 506.65982,158.28354 512,145.46868 512,130.51758 512,115.56648 506.65982,102.92885 495.98047,92.605469 485.30112,81.926117 472.48625,76.585938 457.53516,76.585938 Z m 0.5332,118.541012 c -14.9511,0 -27.76596,5.34018 -38.44531,16.01953 -10.67936,10.67936 -16.01758,23.49422 -16.01758,38.44532 v 131.89062 c 0,14.9511 5.33822,27.76596 16.01758,38.44531 10.67935,10.32339 23.49421,15.48633 38.44531,15.48633 14.9511,0 27.58873,-5.16294 37.91211,-15.48633 C 506.65982,409.24838 512,396.43352 512,381.48242 V 249.5918 c 0,-14.9511 -5.34018,-27.76596 -16.01953,-38.44532 -10.32338,-10.67935 -22.96101,-16.01953 -37.91211,-16.01953 z"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:'OTADESIGN Rounded';-inkscape-font-specification:'OTADESIGN Rounded';fill:#000000;fill-opacity:1;stroke-width:1.09609616px" />
</g>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 4.1 KiB

View File

@ -88,7 +88,7 @@ Just `docker-compose up -d`. GLHF!
7. `docker-compose stop && docker-compose up -d`
### How to execute [cli commands](manage.en.md):
`docker-compose run --rm web node cli/mark-admin @example`
`docker-compose run --rm web node built/tools/mark-admin @example`
----------------------------------------------------------------

View File

@ -55,7 +55,7 @@ Utilisez la commande `docker-compose up -d`. GLHF!
7. `docker-compose stop && docker-compose up -d`
### Comment exécuter des [commandes](manage.fr.md)
`docker-compose run --rm web node cli/mark-admin @example`
`docker-compose run --rm web node built/tools/mark-admin @example`
### Configuration d'ElasticSearch (pour la fonction de recherche)
*1.* Préparation de l'environnement

View File

@ -89,7 +89,7 @@ docker-compose run --rm web yarn run init
### cliコマンドを実行する方法:
`docker-compose run --rm web node cli/mark-admin @example`
`docker-compose run --rm web node built/tools/mark-admin @example`
----------------------------------------------------------------

View File

@ -5,14 +5,10 @@ coming soon
## Mark as 'admin' user
``` shell
node cli/mark-admin (User-ID or Username)
node built/tools/mark-admin (Username)
```
e.g.
``` shell
# By id
node cli/mark-admin 57d01a501fdf2d07be417afe
# By username
node cli/suspend @syuilo
node built/tools/mark-admin @syuilo
```

View File

@ -5,14 +5,10 @@ coming soon
## Marquer un utilisateur en tant que 'admin'
``` shell
node cli/mark-admin (ID utilisateur ou nom d'utilisateur)
node built/tools/mark-admin (nom d'utilisateur)
```
Exemple :
``` shell
# Par id
node cli/mark-admin 57d01a501fdf2d07be417afe
# Par nom d'utilisateur
node cli/suspend @syuilo
node built/tools/mark-admin @syuilo
```

View File

@ -5,14 +5,10 @@ coming soon
## 管理者ユーザーを設定する
``` shell
node cli/mark-admin (ユーザーID または ユーザー名)
node built/tools/mark-admin (ユーザー名)
```
例:
``` shell
# ユーザーID
node cli/mark-admin 57d01a501fdf2d07be417afe
# ユーザー名
node cli/mark-admin @syuilo
node built/tools/mark-admin @syuilo
```

View File

@ -22,7 +22,7 @@ adduser --disabled-password --disabled-login misskey
Please install and setup these softwares:
#### Dependencies :package:
* **[Node.js](https://nodejs.org/en/)** >= 11.7.0
* **[Node.js](https://nodejs.org/en/)** >= 11.10.1
* **[PostgreSQL](https://www.postgresql.org/)** >= 10
* **[Redis](https://redis.io/)**

View File

@ -22,7 +22,7 @@ adduser --disabled-password --disabled-login misskey
Installez les paquets suivants :
#### Dépendences :package:
* **[Node.js](https://nodejs.org/en/)** >= 11.7.0
* **[Node.js](https://nodejs.org/en/)** >= 11.10.1
* **[PostgreSQL](https://www.postgresql.org/)** >= 10
* **[Redis](https://redis.io/)**

View File

@ -22,7 +22,7 @@ adduser --disabled-password --disabled-login misskey
これらのソフトウェアをインストール・設定してください:
#### 依存関係 :package:
* **[Node.js](https://nodejs.org/en/)** (11.7.0以上)
* **[Node.js](https://nodejs.org/en/)** (11.10.1以上)
* **[PostgreSQL](https://www.postgresql.org/)** (10以上)
* **[Redis](https://redis.io/)**

View File

@ -2,38 +2,26 @@
* Gulp tasks
*/
import * as fs from 'fs';
import * as gulp from 'gulp';
import * as ts from 'gulp-typescript';
const sourcemaps = require('gulp-sourcemaps');
import tslint from 'gulp-tslint';
const stylus = require('gulp-stylus');
import * as rimraf from 'rimraf';
import * as chalk from 'chalk';
import * as rename from 'gulp-rename';
import * as mocha from 'gulp-mocha';
import * as replace from 'gulp-replace';
import * as rimraf from 'rimraf';
import * as rename from 'gulp-rename';
const cleanCSS = require('gulp-clean-css');
const terser = require('gulp-terser');
const sass = require('gulp-dart-sass');
const fiber = require('fibers');
const locales = require('./locales');
const env = process.env.NODE_ENV || 'development';
const isDebug = env !== 'production';
if (isDebug) {
console.warn(chalk.yellow.bold('WARNING! NODE_ENV is not "production".'));
console.warn(chalk.yellow.bold(' built script will not be compressed.'));
}
const meta = require('./package.json');
gulp.task('build:ts', () => {
const tsProject = ts.createProject('./tsconfig.json');
return tsProject
.src()
.pipe(sourcemaps.init())
.pipe(tsProject())
.on('error', () => {})
.pipe(sourcemaps.write('.', { includeContent: false, sourceRoot: '../built' }))
.pipe(gulp.dest('./built/'));
});
@ -41,37 +29,70 @@ gulp.task('build:copy:views', () =>
gulp.src('./src/server/web/views/**/*').pipe(gulp.dest('./built/server/web/views'))
);
gulp.task('build:copy:fonts', () =>
gulp.src('./node_modules/three/examples/fonts/**/*').pipe(gulp.dest('./built/client/assets/fonts/'))
);
gulp.task('build:copy:locales', cb => {
fs.mkdirSync('./built/client/assets/locales', { recursive: true });
gulp.task('build:copy', gulp.parallel('build:copy:views', 'build:copy:fonts', () =>
for (const [lang, locale] of Object.entries(locales)) {
fs.writeFileSync(`./built/client/assets/locales/${lang}.${meta.version}.json`, JSON.stringify(locale), 'utf-8');
}
cb();
});
gulp.task('build:copy', gulp.parallel('build:copy:views', 'build:copy:locales', () =>
gulp.src([
'./src/const.json',
'./src/emojilist.json',
'./src/server/web/views/**/*',
'./src/**/assets/**/*',
'!./src/client/app/**/assets/**/*'
'!./src/client/assets/**/*'
]).pipe(gulp.dest('./built/'))
));
gulp.task('lint', () =>
gulp.src('./src/**/*.ts')
.pipe(tslint({
formatter: 'verbose'
}))
.pipe(tslint.report())
gulp.task('clean', cb =>
rimraf('./built', cb)
);
gulp.task('format', () =>
gulp.src('./src/**/*.ts')
.pipe(tslint({
formatter: 'verbose',
fix: true
}))
.pipe(tslint.report())
gulp.task('cleanall', gulp.parallel('clean', cb =>
rimraf('./node_modules', cb)
));
gulp.task('build:client:styles', () =>
gulp.src('./src/client/style.scss')
.pipe(sass({ fiber }))
.pipe(cleanCSS())
.pipe(gulp.dest('./built/client/assets/'))
);
gulp.task('copy:client', () =>
gulp.src([
'./assets/**/*',
'./src/client/assets/**/*',
])
.pipe(rename(path => {
path.dirname = path.dirname!.replace('assets', '.');
}))
.pipe(gulp.dest('./built/client/assets/'))
);
gulp.task('copy:docs', () =>
gulp.src([
'./src/docs/**/*',
])
.pipe(gulp.dest('./built/client/assets/docs/'))
);
gulp.task('build:client', gulp.parallel(
'build:client:styles',
'copy:client',
'copy:docs'
));
gulp.task('build', gulp.parallel(
'build:ts',
'build:copy',
'build:client',
));
gulp.task('mocha', () =>
gulp.src('./test/**/*.ts')
.pipe(mocha({
@ -82,62 +103,4 @@ gulp.task('mocha', () =>
gulp.task('test', gulp.task('mocha'));
gulp.task('clean', cb =>
rimraf('./built', cb)
);
gulp.task('cleanall', gulp.parallel('clean', cb =>
rimraf('./node_modules', cb)
));
gulp.task('build:client:script', () => {
const client = require('./built/meta.json');
return gulp.src(['./src/client/app/boot.js', './src/client/app/safe.js'])
.pipe(replace('VERSION', JSON.stringify(client.version)))
.pipe(replace('ENV', JSON.stringify(env)))
.pipe(replace('LANGS', JSON.stringify(Object.keys(locales))))
.pipe(terser({
toplevel: true
}))
.pipe(gulp.dest('./built/client/assets/'));
});
gulp.task('build:client:styles', () =>
gulp.src('./src/client/app/init.css')
.pipe(cleanCSS())
.pipe(gulp.dest('./built/client/assets/'))
);
gulp.task('copy:client', () =>
gulp.src([
'./assets/**/*',
'./src/client/assets/**/*',
'./src/client/app/*/assets/**/*'
])
.pipe(rename(path => {
path.dirname = path.dirname!.replace('assets', '.');
}))
.pipe(gulp.dest('./built/client/assets/'))
);
gulp.task('doc', () =>
gulp.src('./src/docs/**/*.styl')
.pipe(stylus())
.pipe(cleanCSS())
.pipe(gulp.dest('./built/docs/assets/'))
);
gulp.task('build:client', gulp.parallel(
'build:client:script',
'build:client:styles',
'copy:client'
));
gulp.task('build', gulp.parallel(
'build:ts',
'build:copy',
'build:client',
'doc'
));
gulp.task('default', gulp.task('build'));

View File

@ -1 +0,0 @@
---

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,954 +1,39 @@
---
meta:
lang: "Deutsch"
common:
misskey: "Ein ⭐ des Fediversums"
about-title: "Ein ⭐ des Fediversums."
about: "Danke, dass Du Misskey gefunden hast. Misskey ist eine <b>dezentralisierte Microblogging-Plattform</b>, welche auf der ganzen Welt verteilt ist. Da es innerhalb es Fediversums existiert (ein Universum, in dem verschiedene Soziale Netzwerke organisiert sind), ist es unmittelbar mit anderen sozialen Netzwerken verbunden. Warum nimmst du dir nicht einmal eine Auszeit von dem Trubel der Stadt und tauchst in das neue Internet hinein?"
intro:
title: "Was ist Misskey?"
about: "Misskey ist eine Quelloffene, <b>dezentralisierte microblogging Software</b>. Es bietet eine erweiterbare Benutzeroberfläche, verschiedenste Möglichkeiten auf Beiträge zu reagieren, kostenlosen Datenspeicher, und andere fortschrittliche Funktionen. Zusätzlich ist Misskey dazu in der Lage, sich mittels des Fediverse mit beliebig vielen anderen ActivityPub-kompatiblen Diensten zu verbinden. Wenn du zum Beispiel einen Betrag mit Misskey abschickst, wird dieser auch für Nutzer von Mastodon oder Pleroma sichtbar sein. So ähnlich wie eine Radioübertragung zwischen Planeten."
features: "Funktionen"
rich-contents: "Notizen"
rich-contents-desc: "Poste einfach deine Ideen, Interessen und alles, was du teilen möchtest. Gestalte deine Nachrichten, teile deine Lieblingsbilder, sende Dateien und Videos und erstelle Umfragen das und mehr kann Misskey!"
reaction: "Reaktionen"
reaction-desc: "Der einfachste Weg, deine Gefühle mit anderen zu teilen. Mit Misskey kannst du auf verschiedenste Arten auf Beiträge reagieren, statt nur zu „liken“."
ui: "Benutzeroberfläche"
ui-desc: "Geschmäcker sind verschieden. Deswegen ist Misskeys Oberfläche hochanpassbar und modular. Mache die Startseite zu deiner Startseite, indem du das Layout deiner Timeline änderst und mit Widgets staffierst."
drive: "Drive"
drive-desc: "Du willst ein hochgeladenes Foto nochmal posten? Deine Dateien benennen und in Ordnern sortieren? Misskeys Drive ist der beste Ort dafür. Damit wird das Teilen zum Kinderspiel!"
outro: "Probiere Misskey aus und entdecke Misskeys einzigartige Funktionen. Wenn dir diese Instanz nicht zusagt, nimm einfach eine andere. Dank Misskeys dezentralem System kannst du dich überall mit deinen Freunden verbinden. Also dann, GLHF!"
application-authorization: "Autorisierte Anwendungen"
close: "Schließen"
do-not-copy-paste: "Bitte keinen Code einfügen. Ihr Account könnte gefährdet werden."
load-more: "Mehr laden"
enter-password: "Bitte Passwort eingeben"
2fa: "Zwei-Faktor-Authentifizierung"
customize-home: "Layout Anpassen"
featured-notes: "Beliebt"
dark-mode: "Dunkler Modus"
signin: "Einloggen"
signup: "Registrieren"
signout: "Ausloggen"
reload-to-apply-the-setting: "Die Seite muss zum Übernehmen dieser Einstellung aktualisiert werden. Soll die Seite jetzt neu geladen werden?"
fetching-as-ap-object: "Hole Daten…"
delete-confirm: "Diesen Beitrag löschen?"
notification-types:
reply: "Antworten"
renote: "Anmerkung"
got-it: "Verstanden!"
customization-tips:
title: "Anpassung-Tipps"
paragraph: "<p>Du kannst deine Startseite anpassen, indem du Widgets hinzufügst und verschiebst.</p><p><strong>Klicke <strong>rechts</strong></strong> auf ein Widget, um dessen Aussehen zu verändern.</p><p>Um ein Widget zu löschen, klicke und ziehe es auf den <strong>Papierkorb</strong> am Kopfende der Seite.</p><p>Wenn du fertig bist, drücke auf den Beenden-Knopf oben rechts.</p>"
gotit: "Verstanden!"
notification:
file-uploaded: "Datei hochgeladen!"
message-from: "Nachricht von {}:"
reversi-invited: "Zu einem Spiel eingeladen"
reversi-invited-by: "Eingeladen von {}:"
notified-by: "Benachrichtigt von {}:"
reply-from: "Antwort von {}:"
quoted-by: "Zitiert von {}:"
time:
unknown: "Unbekannt"
future: "Zukunft"
just_now: "Gerade eben"
seconds_ago: "vor {} Sekunde(n)"
minutes_ago: "vor {} Minute(n)"
hours_ago: "vor {} Stunde(n)"
days_ago: "vor {} Tag(en)"
weeks_ago: "vor {} Woche(n)"
months_ago: "vor {} Monat(en)"
years_ago: "vor {} Jahr(en)"
month-and-day: "{day}/{month}"
trash: "Papierkorb"
drive: "Drive"
pages: "Seite"
messaging: "Unterhaltungen"
home: "Home"
deck: "Deck"
_lang_: "Deutsch"
monthAndDay: "{day}/{month}"
search: "Suchen"
notifications: "Benachrichtigungen"
username: "Benutzername"
password: "Passwort"
fetchingAsApObject: "Aus Fediverse holen"
ok: "OK"
gotIt: "Verstanden!"
cancel: "Abbrechen"
enterUsername: "Benutzername eingeben"
renotedBy: "Renote von {user}"
noNotes: "Keine Notizen"
noNotifications: "Keine Benachrichtigungen"
instance: "Instanz"
settings: "Einstellungen"
profile: "Profil"
timeline: "Zeitleiste"
noAccountDescription: "Keine Selbsteinführung"
login: "Einloggen"
loggingIn: "Einloggen in bearbeitung"
logout: "Ausloggen"
signup: "Registrieren"
uploading: "Upload läuft"
save: "Speichern"
users: "Benutzer"
addUser: "Benutzer hinzufügen"
copyUsername: "Benutzernamen kopieren"
selectUser: "Benutzer wählen"
instances: "Instanz"
mutedUsers: "Stummgestellte Benutzer"
blockedUsers: "Blockierte Benutzer"
noUsers: "Keine Benutzer"
_widgets:
notifications: "Benachrichtigungen"
timeline: "Zeitleiste"
explore: "Entdecken"
following: "Folgt"
followers: "Folgende"
favorites: "Favoriten"
permissions:
"read:account": "Accountinformationen anzeigen."
"write:account": "Accountinformationen bearbeiten."
"read:blocks": "Blöcke anzeigen"
"write:blocks": "Auf Sperrungen zugreifen"
"read:drive": "Dateien anzeigen"
"write:drive": "Dateien bearbeiten"
"read:favorites": "Favoriten anzeigen"
"write:favorites": "Auf Favoriten zugreifen"
"read:following": "Follower-Daten lesen"
"write:following": "Folgestatus bearbeiten"
"read:messaging": "Unterhaltung anzeigen"
"write:messaging": "Unterhaltung bearbeiten"
"read:mutes": "Stummschaltungen lesen"
"write:mutes": "Stummschaltungen bearbeiten"
"write:notes": "Beiträge löschen und verfassen"
"read:notifications": "Benachrichtigungen lesen"
"write:notifications": "Benachrichtigungen bearbeiten"
"read:reactions": "Reaktionen sehen"
"write:reactions": "Reaktionen hinzufügen und bearbeiten"
"write:votes": "Abstimmen"
empty-timeline-info:
follow-users-to-make-your-timeline: "Beiträge von Benutzern, denen du folgst, werden in der Zeitleiste angezeigt."
explore: "Benutzer finden"
post-form:
reply: "Antworten"
renote: "Anmerkung"
enter-username: "Bitte gib einen Benutzernamen ein"
username-prompt: "Bitte gib einen Benutzernamen ein"
weekday-short:
sunday: "So"
monday: "Mo"
tuesday: "Di"
wednesday: "Mi"
thursday: "Do"
friday: "Fr"
saturday: "Sa"
weekday:
sunday: "Sonntag"
monday: "Montag"
tuesday: "Dienstag"
wednesday: "Mittwoch"
thursday: "Donnerstag"
friday: "Freitag"
saturday: "Samstag"
reactions:
like: "Gefällt mir"
love: "Lieben"
laugh: "Lachen"
hmm: "Hmm...?"
surprise: "Wow"
congrats: "Glückwunsch!"
angry: "Wütend"
confused: "Verwirrt"
rip: "RIP"
pudding: "Pudding"
note-visibility:
public: "Öffentlich"
home: "Startseite"
home-desc: "Auf die Startseite posten"
followers: "Abonnenten"
followers-desc: "Nur für diejenigen sichtbar, die dir folgen"
specified: "Direkt"
specified-desc: "Nur für bestimmte Benutzer sichtbar"
local-public: "Öffentlich (nur lokal)"
local-home: "Home (nur lokal)"
local-followers: "Follower (nur lokal)"
note-placeholders:
a: "Was machst du gerade?"
b: "Was ist so passiert?"
c: "Was geht dir durch den Kopf?"
d: "Willst du etwas sagen?"
e: "Schreib hier etwas!"
f: "Warte darauf, das du schreibst..."
settings: "Einstellungen"
_settings:
profile: "Dein Profil"
notification: "Benachrichtigungen"
apps: "Anwendungen"
tags: "Hashtags"
mute-and-block: "Stummschalten/Blocken"
blocking: "Blocken"
security: "Sicherheit"
signin: "Login-Verlauf"
password: "Passwort"
other: "Mehr"
appearance: "Designs"
behavior: "Verhalten"
fetch-on-scroll: "Unendliches laden beim scrollen"
fetch-on-scroll-desc: "Wenn beim scrollen das Ende erreicht wird, lädt die Anwendung automatisch neue Inhalte nach."
note-visibility: "Sichtbarkeit von Beiträgen"
default-note-visibility: "Die Standardsichtbarkeit"
remember-note-visibility: "Erinnerung an Sichtbarkeit von Beiträgen"
web-search-engine: "Web-Suchmaschine"
web-search-engine-desc: "Beispiel: https://www.google.de/search?q={{query}}"
keep-cw: "Inhaltswarnung beibehalten"
keep-cw-desc: "Wenn auf einen Beitrag geantwortet wird, wird die Inhaltswarnung des Originalbeitrags übernommen."
i-like-sushi: "Ich bevorzuge Sushi anstelle von Pudding"
show-reversi-board-labels: "Zeige Reihen- und Spaltenbeschreibungen in Reversi an"
use-avatar-reversi-stones: "Avatar als Stein in Reversi anzeigen"
disable-animated-mfm: "Animierten Text in Beiträgen deaktivieren"
disable-showing-animated-images: "Animierte Grafiken deaktivieren"
suggest-recent-hashtags: "Beim Verfassen von Beiträgen letzte Hashtags anzeigen"
always-show-nsfw: "Sensible Inhalte (NSFW) immer anzeigen"
always-mark-nsfw: "Meine Anhänge immer als NSFW markieren"
show-full-acct: "Servername bei Benutzernamen immer anzeigen"
show-via: "„via“ anzeigen"
reduce-motion: "Animationen der Benutzeroberfläche reduzieren"
this-setting-is-this-device-only: "Nur auf diesem Gerät"
use-os-default-emojis: "Betriebssystem-Emojis nutzen"
line-width: "Linienstärke"
line-width-thin: "Dünn"
line-width-normal: "Normal"
line-width-thick: "Dick"
font-size: "Schriftgröße"
font-size-x-small: "Sehr klein"
font-size-small: "Klein"
font-size-medium: "Normal"
font-size-large: "Groß"
font-size-x-large: "Sehr groß"
deck-column-align: "Spaltenaufteilung der Deck-Ansicht"
deck-column-align-center: "Mitte"
deck-column-align-left: "Links"
deck-column-align-flexible: "Flexibel"
deck-column-width: "Spaltenbreite des Decks"
deck-column-width-narrow: "Sehr eng"
deck-column-width-narrower: "Eng"
deck-column-width-normal: "Normal"
deck-column-width-wider: "Breit"
deck-column-width-wide: "Sehr breit"
use-shadow: "Nutze Schatten"
rounded-corners: "Abgerundete Ecken"
circle-icons: "Kreisförmige Avatar"
contrasted-acct: "Nutzernamen kontrastreicher darstellen"
wallpaper: "Hintergrund"
choose-wallpaper: "Hintergrund auswählen"
delete-wallpaper: "Hintergrund entfernen"
post-form-on-timeline: "Beitragsformular über Timeline anzeigen"
show-clock-on-header: "Uhr am oberen rechten Rand anzeigen"
show-reply-target: "Zeige bei einer Antwort die ursprüngliche Nachricht"
timeline: "Timeline"
show-my-renotes: "Zeige eigene Renotes in der Timeline"
show-renoted-my-notes: "Zeige Renotes deiner Posts in der Timeline"
show-local-renotes: "Zeige Renotes lokaler Posts in der Timeline"
remain-deleted-note: "Gelöschte Beiträge weiterhin anzeigen"
sound: "Töne"
enable-sounds: "Töne aktivieren"
enable-sounds-desc: "Spiel einen Ton ab beim Erhalten eines Beitrags bzw. einer Nachricht. Diese Einstellung wird im Browser gespeichert."
volume: "Lautstärke"
test: "Test"
update: "Misskey-Update"
version: "Version:"
latest-version: "Neuste Version:"
update-checking: "Suche nach Updates"
do-update: "Nach Updates suchen"
update-settings: "Erweiterte Einstellungen"
no-updates: "Kein Update verfügbar"
no-updates-desc: "Misskey ist aktuell."
update-available: "Eine neue Version ist verfügbar!"
update-available-desc: "Änderungen werden beim Neuladen der Seite angewendet."
advanced-settings: "Erweiterte Einstellungen"
debug-mode: "Debug-Modus einschalten"
debug-mode-desc: "Diese Einstellung wird im Browser gespeichert."
navbar-position: "Postion der Navigationsleiste"
navbar-position-top: "Oben"
navbar-position-left: "Links"
navbar-position-right: "Rechts"
i-am-under-limited-internet: "Ich möchte Datenvolumen sparen"
post-style: "Beitrags-Anzeigestil"
post-style-standard: "Standard"
post-style-smart: "Smart"
notification-position: "Benachrichtigungen anzeigen"
notification-position-bottom: "Unten"
notification-position-top: "Oben"
disable-via-mobile: "Beitrag nicht als „vom Handy“ markieren"
load-raw-images: "Anhänge in voller Größe laden"
load-remote-media: "Zeige Inhalte von fremden Servern"
save: "Speichern"
saved: "Gespeichert"
preview: "Vorschau"
search: "Suche"
delete: "Löschen"
loading: "Laden"
ok: "Okay"
cancel: "Abbrechen"
update-available-title: "Aktualisierung verfügbar"
update-available: "Eine neue Version von Misskey ist verfügbar ({newer}, aktuell ist {current}). Lade die Seite neu um die aktuelle Version zu laden"
my-token-regenerated: "Dein Token wurde generiert. Du wirst jetzt abgemeldet."
hide-password: "Passwort verbergen"
show-password: "Passwort zeigen"
enter-username: "Kontonamen eingeben"
do-not-use-in-production: "Dies ist eine Entwicklungsversion. Nicht in einer Produktivumgebung verwenden."
user-suspended: "Dieser Nutzer wurde gesperrt."
is-remote-user: "Diese Nutzerinformationen können unvollständig sein."
is-remote-post: "Dies ist ein entfernter Post."
view-on-remote: "Vollständige Infos auf Ursprungsserver anzeigen"
renoted-by: "Renote von {user}"
no-notes: "Keine Beiträge"
turn-on-darkmode: "Dunkles Design"
turn-off-darkmode: "Helles Design"
error:
title: "Allgemeiner Fehler"
retry: "Erneut versuchen"
reversi:
drawn: "Unentschieden"
my-turn: "Du bist am Zug"
opponent-turn: "Dein Gegner ist an der Reihe"
turn-of: "{name}s Zug"
past-turn-of: "Zug von {name}"
won: "{name} hat gewonnen"
black: "Schwarz"
white: "Weiß"
total: "Gesamt"
this-turn: "{count}. Zug"
widgets:
analog-clock: "Analoge Uhr"
profile: "Profil"
calendar: "Kalender"
timemachine: "Kalender (Zeitmaschine)"
activity: "Aktivitäten"
rss: "RSS Leser"
memo: "Notizen"
trends: "Trends"
photo-stream: "Bilder"
posts-monitor: "Beitrags-Aktivität"
slideshow: "Diashow"
version: "Version"
broadcast: "Ankündigungen"
notifications: "Benachrichtigungen"
users: "Empfohlene Benutzer"
polls: "Umfrage"
post-form: "\"Neuer Beitrag\"-Formular"
server: "Server-Info"
nav: "Navigation"
tips: "Tipps"
hashtags: "Hashtags"
queue: "Warteschlange"
dev: "Fehler beim Erstellen der Applikation. Bitte versuche es erneut."
ai-chan-kawaii: "Ai-chan kawaii!"
you: "Du"
auth/views/form.vue:
share-access: "Erlaubst Du <i>{name}</i> auf deinen Account zuzugreifen?"
permission-ask: "Diese Applikation benötigt folgende Berechtigungen:"
cancel: "Abbrechen"
accept: "Zugriff erlauben."
auth/views/index.vue:
loading: "Lädt"
denied: "Autorisierung der Anwendung wurde verweigert."
denied-paragraph: "Diese App kann nicht auf deinen Account zugreifen."
already-authorized: "Diese Anwendung ist bereits autorisiert."
allowed: "Autorisierung der Anwendung wurde erlaubt."
callback-url: "Zur App zurückkehren"
please-go-back: "Bitte gehe zurück zur Anwendung."
error: "Sitzung ist nicht vorhanden."
sign-in: "Bitte melde dich an."
common/views/pages/explore.vue:
pinned-users: "Vorgeschlagen"
popular-users: "Beliebt"
recently-updated-users: "Kürzlich aktiv"
recently-registered-users: "Neue Benutzer"
popular-tags: "Beliebte Tags"
federated: "Aus dem Fediverse"
explore: "{host} erkunden"
users-info: "Momentan sind {users} Nutzer hier registriert"
common/views/components/url-preview.vue:
enable-player: "Player öffnen"
disable-player: "Player schließen"
common/views/components/user-list.vue:
no-users: "Keine Benutzer"
common/views/components/games/reversi/reversi.vue:
matching:
waiting-for: "Warten auf {}"
cancel: "Abbrechen"
common/views/components/games/reversi/reversi.game.vue:
surrender: "Aufgeben"
surrendered: "durch Aufgabe"
is-llotheo: "Der niedrigere gewinnt (Llotheo)"
looped-map: "Spielbrettenden verbinden"
can-put-everywhere: "Setzen ist überall erlaubt"
common/views/components/games/reversi/reversi.index.vue:
title: "Misskey Reversi"
sub-title: "Spiele Reversi mit deinen Freunden!"
invite: "Einladen"
rule: "Spielanleitung"
mode-invite: "Einladen"
all-games: "Alle Spiele"
enter-username: "Bitte gib einen Benutzernamen ein"
game-state:
ended: "Fertig"
common/views/components/games/reversi/reversi.room.vue:
settings-of-the-game: "Spieleinstellungen"
choose-map: "Wähle eine Karte"
random: "Zufällige Auswahl"
black-or-white: "Schwarz/Weiß"
black-is: "Schwarz ist {}"
rules: "Regeln"
is-llotheo: "Der niedrigere gewinnt (Llotheo)"
looped-map: "Spielbrettenden verbinden"
can-put-everywhere: "Setzen ist überall erlaubt"
settings-of-the-bot: "Bot-Einstellungen"
this-game-is-started-soon: "Spiel beginnt gleich"
waiting-for-other: "Warte auf den Gegner"
waiting-for-me: "Warten, bis du bereit bist"
waiting-for-both: "Vorbereiten…"
cancel: "Abbrechen"
ready: "Bereit"
common/views/components/connect-failed.vue:
title: "Verbindung zum Server ist fehlgeschlagen"
description: "Entweder gibt es ein Problem mit deiner Internetverbindung oder der Server ist zur Zeit nicht erreichbar oder wird gewartet. Bitte versuche es später noch einmal."
thanks: "Vielen Dank für das nutzen von Misskey."
troubleshoot: "Problembehandlung"
common/views/components/connect-failed.troubleshooter.vue:
title: "Problembehandlung"
network: "Netzwerkverbindung"
checking-network: "Prüfen der Netzwerkverbindung"
internet: "Internetverbindung"
checking-internet: "Internetverbindung wird getestet"
server: "Serververbindung"
checking-server: "Überprüfung der Server-Verbindung"
finding: "Nach dem Problem suchen"
no-network: "Keine Netzwerkverbindung"
no-network-desc: "Bitte stelle sicher, dass du mit dem Internet verbunden bist."
no-internet: "Keine Internetverbindung"
no-internet-desc: "Bitte vergewissere dich, dass du mit dem Internet verbunden bist."
no-server: "Verbindung mit dem Server nicht möglich"
no-server-desc: "Die Internetverbindung scheint in Ordnung zu sein, aber eine Verbindung mit dem Misskey-Server konnte nicht hergestellt werden. Möglicherweise ist dieser zur Zeit offline oder wird gewartet. Bitte versuche es später noch einmal."
success: "Erfolgreich mit dem Misskey-Server verbunden"
success-desc: "Die Verbindung scheint zu funktionieren. Bitte lade die Seite neu."
flush: "Cache leeren"
set-version: "Version angeben"
common/views/components/media-banner.vue:
sensitive: "Dieser Inhalt ist NSFW"
click-to-show: "Klicke zum den Inhalt anzusehen"
common/views/components/theme.vue:
theme: "Design"
light-theme: "Thema"
dark-theme: "Thema während des Nachtmodus"
light-themes: "Helles Thema"
dark-themes: "Dunkles Thema"
install-a-theme: "Design wird installiert"
theme-code: "Design-Quelltext"
install: "Anwenden"
installed: "\"{}\" wurde installiert"
create-a-theme: "Thema erstellen"
save-created-theme: "Thema speichern"
primary-color: "Primäre Farbe"
secondary-color: "Sekundäre Farbe"
text-color: "Textfarbe"
base-theme: "Basisthema"
base-theme-light: "Hell"
base-theme-dark: "Dunkel"
find-more-theme: "Mehr Designs finden"
theme-name: "Name des Themas"
preview-created-theme: "Vorschau"
invalid-theme: "Thema ist ungültig"
already-installed: "Thema ist bereits installiert"
saved: "Gespeichert"
manage-themes: "Designs verwalten"
builtin-themes: "Standard-Designs"
my-themes: "Meine Designs"
installed-themes: "Installierte Designs"
select-theme: "Design wählen"
uninstall: "Deinstallieren"
uninstalled: "„{}“ wurde deinstalliert"
author: "Autor"
desc: "Beschreibung"
export: "Exportieren"
import: "Importieren"
import-by-code: "oder Quelltext einfügen"
theme-name-required: "Design-Name ist erforderlich"
common/views/components/cw-button.vue:
hide: "Ausblenden"
show: "Mehr"
chars: "{count} Zeichen"
files: "{count} Dateien"
poll: "Umfrage"
common/views/components/messaging.vue:
search-user: "Einen Nutzer suchen"
you: "Du"
no-history: "Keine Chronik"
user: "Benutzer"
group: "Gruppen"
common/views/components/messaging-room.vue:
no-history: "Keine weitere Chronik vorhanden"
new-message: "Neue Nachricht"
common/views/components/messaging-room.form.vue:
input-message-here: "Nachricht hier eingeben"
send: "Senden"
attach-from-local: "Wähle Dateien von deinem PC aus"
attach-from-drive: "Wähle Dateien von deinem Speicher aus"
common/views/components/messaging-room.message.vue:
is-read: "Gelesen"
deleted: "Diese Nachricht wurde gelöscht"
common/views/components/nav.vue:
about: "Über"
stats: "Statistiken"
status: "Status"
wiki: "Wiki"
donors: "Spender"
repository: "Quellcode"
develop: "Entwickler"
feedback: "Feedback"
common/views/components/note-menu.vue:
mention: "Erwähnungen"
detail: "Details"
copy-content: "Inhalt kopieren"
copy-link: "Link kopieren"
favorite: "Diesen Beitrag favorisieren"
unfavorite: "Aus Favoriten entfernen"
watch: "Beobachten"
unwatch: "Nicht mehr beobachten"
pin: "An die Profilseite pinnen"
unpin: "Lösen"
delete: "Löschen"
delete-confirm: "Diesen Beitrag löschen?"
remote: "Auf Quelle anzeigen"
common/views/components/user-menu.vue:
mention: "Erwähnungen"
mute: "Stummschalten"
unmute: "Stummschaltung aufheben"
mute-confirm: "Bist du sicher, dass du diesen Nutzer stummschalten möchtest?"
unmute-confirm: "Stummschaltung für diesen Nutzer aufheben?"
block: "Sperren"
unblock: "Sperrung aufheben"
block-confirm: "Diesen Nutzer wirklich sperren?"
common/views/components/poll.vue:
vote-to: "Stimme für '{}'"
vote-count: "{} Stimmen"
vote: "Abstimmen"
show-result: "Zeige Ergebnis"
voted: "Abgestimmt"
common/views/components/poll-editor.vue:
no-only-one-choice: "Du musst zwei oder mehr Entscheidungen angeben"
choice-n: "Auswahl {}"
remove: "Diese Auswahl entfernen"
add: "+ Eine Auswahl hinzufügen"
destroy: "Diese Abstimmung löschen"
day: "So"
common/views/components/reaction-picker.vue:
choose-reaction: "Wähle eine Reaktion aus"
common/views/components/emoji-picker.vue:
activity: "Aktivität"
common/views/components/signin.vue:
_profile:
username: "Benutzername"
password: "Passwort"
token: "Token"
signing-in: "Melde an..."
or: "Oder"
common/views/components/signup.vue:
username: "Benutzername"
checking: "Überprüfung..."
available: "Verfügbar"
unavailable: "Nicht verfügbar"
error: "Verbindungsfehler"
invalid-format: "Benutze nur Buchstaben, Zahlen und _"
too-short: "Bitte mindestens ein Zeichen eingeben"
too-long: "Bitte maximal 20 Zeichen verwenden"
password: "Passwort"
password-placeholder: "Wir empfehlen mindestens 8 Zeichen"
weak-password: "Schwaches Passwort"
normal-password: "Normales Passwort"
strong-password: "Starkes Passwort"
retype: "Wiederholen"
retype-placeholder: "Bitte das Passwort erneut eingeben"
password-matched: "OK"
password-not-matched: "Stimmt nicht überein"
recaptcha: "Captcha"
create: "Account erstellen"
some-error: "Die Anmeldung konnte aufgrund eines Fehler nicht abgeschlossen werden. Bitte versuche es erneut."
common/views/components/special-message.vue:
new-year: "Frohes neues Jahr!"
christmas: "Frohe Weihnachten!"
common/views/components/stream-indicator.vue:
connecting: "Verbindung wird hergestellt"
reconnecting: "Erneut verbinden"
connected: "Verbindung hergestellt"
common/views/components/notification-settings.vue:
title: "Benachrichtigungen"
common/views/components/uploader.vue:
waiting: "Warten"
common/views/components/visibility-chooser.vue:
public: "Öffentlich"
home: "Home"
home-desc: "Auf die Startseite posten"
followers: "Folgende"
followers-desc: "Nur für diejenigen sichtbar, die dir folgen"
specified: "Direkt"
specified-desc: "Nur für bestimmte Benutzer sichtbar"
local-public: "Öffentlich (nur lokal)"
local-home: "Home (nur lokal)"
local-followers: "Follower (nur lokal)"
common/views/components/profile-editor.vue:
title: "Dein Profil"
name: "Name"
avatar: "Avatar"
banner: "Banner"
save: "Speichern"
unable-to-process: "Der Vorgang konnte nicht abgeschlossen werden"
export: "Exportieren"
import: "Importieren"
export-targets:
user-lists: "Listen"
enter-password: "Bitte Passwort eingeben"
common/views/components/user-group-editor.vue:
invite: "Einladen"
common/views/components/user-lists.vue:
user-lists: "Listen"
common/views/components/user-groups.vue:
user-groups: "Gruppen"
owned-groups: "Meine Gruppen"
invites: "Einladen"
common/views/widgets/broadcast.vue:
fetching: "Laden"
no-broadcasts: "Keine Broadcasts"
have-a-nice-day: "Schönen Tag!"
next: "Nächster"
common/views/widgets/photo-stream.vue:
title: "Fotostream"
no-photos: "Keine Fotos"
common/views/widgets/posts-monitor.vue:
title: "Beitrags-Aktivität"
toggle: "Sicht umschalten"
common/views/widgets/server.vue:
title: "Serverinformationen"
toggle: "Sicht umschalten"
common/views/widgets/memo.vue:
title: "Notizen"
memo: "Schreib hier!"
save: "Speichern"
desktop:
banner: "Banner"
avatar: "Avatar"
unable-to-process: "Der Vorgang konnte nicht abgeschlossen werden"
desktop/views/components/activity.chart.vue:
total: "Schwarz ... komplett"
notes: "Blau ... Hinweise"
replies: "Rot ... Antworten"
renotes: "Grün ... Anmerkungen"
desktop/views/components/activity.vue:
title: "Aktivität"
toggle: "Sichten umschalten"
desktop/views/components/calendar.vue:
prev: "Vorheriger Monat"
next: "Nächster Monat"
go: "Klicke zur Navigation"
desktop/views/components/choose-file-from-drive-window.vue:
upload: "Dateien von deinem PC hochladen"
cancel: "Abbrechen"
ok: "OK"
choose-prompt: "Wähle eine Datei aus"
desktop/views/components/choose-folder-from-drive-window.vue:
cancel: "Abbrechen"
ok: "OK"
choose-prompt: "Wähle einen Ordner"
desktop/views/components/crop-window.vue:
skip: "Zuschneiden überspringen"
cancel: "Abbrechen"
ok: "OK"
desktop/views/components/drive-window.vue:
used: "benutzt"
desktop/views/components/drive.file.vue:
avatar: "Avatar"
banner: "Banner"
contextmenu:
rename: "Umbenennen"
copy-url: "URL kopieren"
download: "Download"
set-as-avatar: "Als Avatar festlegen"
set-as-banner: "Setze als Banner"
open-in-app: "In der App öffnen"
add-app: "App hinzufügen"
rename-file: "Datei umbennen"
input-new-file-name: "Gib den neuen Dateinamen an"
copied: "Kopieren erfolgreich"
copied-url-to-clipboard: "URL wurde in die Zwischenablage kopiert"
desktop/views/components/drive.folder.vue:
unable-to-process: "Der Vorgang konnte nicht abgeschlossen werden"
circular-reference-detected: "Das Zielverzeichnis ist innerhalb des Verzeichnisses, dass du verschieben möchtest"
unhandled-error: "Unbekannter Fehler"
contextmenu:
move-to-this-folder: "Verschiebe in diesen Ordner"
show-in-new-window: "In einem neuen Fenster anzeigen"
rename: "Umbenennen"
rename-folder: "Ordner umbenennen"
input-new-folder-name: "Namen für neuen Ordner eingeben"
desktop/views/components/drive.vue:
search: "Suchen"
empty-draghover: "Herzlich Willkommen!"
empty-drive: "Dein Speicher ist leer"
empty-drive-description: "Du kannst rechts klicken und \"Datei hochladen\" auswählen oder eine Datei per Drag and Drop auf das Fenster ziehen."
empty-folder: "Dieser Ordner ist leer"
unable-to-process: "Der Vorgang konnte nicht beendet werden"
circular-reference-detected: "Das Zielverzeichnis ist innerhalb des Verzeichnisses, dass du verschieben möchtest"
unhandled-error: "Unbekannter Fehler"
url-upload: "Von einer URL hochladen"
url-of-file: "URL der Datei, welche du hochladen möchtest"
url-upload-requested: "Upload angefordert"
may-take-time: "Es kann eine Weile dauern, bis der Upload fertiggestellt ist."
create-folder: "Ein Verzeichnis erstellen"
folder-name: "Ordnername"
contextmenu:
create-folder: "Ein Verzeichnis erstellen"
upload: "Eine Datei hochladen"
url-upload: "Von einer URL hochladen"
desktop/views/components/followers.vue:
empty: "Dir scheint niemand zu folgen."
desktop/views/components/following.vue:
empty: "Du folgst niemanden"
desktop/views/components/home.vue:
done: "Beenden"
add-widget: "Widget hinzufügen:"
add: "Hinzufügen"
desktop/views/input-dialog.vue:
cancel: "Abbrechen"
ok: "OK"
desktop/views/components/note-detail.vue:
private: "Dieser Beitrag ist privat"
deleted: "Dieser Beitrag wurde entfernt"
location: "Ort"
renote: "Anmerkung"
add-reaction: "Reaktion hinzufügen"
desktop/views/components/note.vue:
reply: "Antworten"
renote: "Anmerkung"
detail: "Details"
private: "Dieser Beitrag ist privat"
deleted: "Dieser Beitrag wurde entfernt"
desktop/views/components/notes.vue:
error: "Laden fehlgeschlagen."
retry: "Erneut versuchen"
desktop/views/components/notifications.vue:
empty: "Keine Benachrichtigungen"
desktop/views/components/post-form.vue:
posted: "Gepostet!"
replied: "Geantwortet!"
reposted: "Weitergesagt!"
note-failed: "Anmerkung fehlgeschlagen"
reply-failed: "Antwort fehlgeschlagen"
renote-failed: "Anmerkung fehlgeschlagen"
desktop/views/components/post-form-window.vue:
note: "Neuer Beitrag"
reply: "Antworten"
attaches: "{} Medien hinzugefügt"
uploading-media: "Lade {} Medien hoch"
desktop/views/components/progress-dialog.vue:
waiting: "Warten"
desktop/views/components/renote-form.vue:
quote: "Zitieren..."
cancel: "Abbrechen"
renote: "Anmerkung"
reposting: "Weitersagen..."
success: "Weitergesagt!"
failure: "Weitersagen fehlgeschlagen"
desktop/views/components/renote-form-window.vue:
title: "Bist du dir sicher, dass du das weitersagen willst?"
desktop/views/components/settings.2fa.vue:
url: "https://www.google.de/intl/de/landing/2step/"
register: "Ein Gerät registrieren"
already-registered: "Das Gerät wurde bereits registriert"
unregister: "Abschalten"
unregistered: "Zwei-Faktor-Authentifizierung wurde deaktiviert."
enter-password: "Bitte Passwort eingeben"
token: "Token"
common/views/components/api-settings.vue:
enter-password: "Bitte Passwort eingeben"
console:
parameter: "Parameter"
send: "Senden"
common/views/components/drive-settings.vue:
in-use: "benutzt"
stats: "Statistiken"
common/views/components/mute-and-block.vue:
unmute-confirm: "Stummschaltung für diesen Nutzer aufheben?"
save: "Speichern"
desktop/views/components/sub-note-content.vue:
private: "Dieser Beitrag ist privat"
deleted: "Dieser Beitrag wurde entfernt"
poll: "Umfrage"
desktop/views/components/settings.tags.vue:
add: "Hinzufügen"
save: "Speichern"
desktop/views/components/timeline.vue:
home: "Home"
local: "Lokal"
global: "Global"
list: "Listen"
desktop/views/components/ui.header.account.vue:
profile: "Dein Profil"
lists: "Listen"
groups: "Gruppen"
desktop/views/components/ui.header.nav.vue:
game: "Spielen"
desktop/views/components/ui.header.notifications.vue:
title: "Benachrichtigungen"
desktop/views/components/ui.header.post.vue:
post: "Einen neuen Post erstellen"
desktop/views/components/ui.header.search.vue:
placeholder: "Suchen"
desktop/views/components/users-list.vue:
fetching: "Lade…"
admin/views/dashboard.vue:
drive: "Drive"
admin/views/abuse.vue:
details: "Details"
remove-report: "Löschen"
admin/views/instance.vue:
recaptcha-preview: "Vorschau"
invite: "Einladen"
save: "Speichern"
saved: "Gespeichert"
test-email: "Test"
admin/views/charts.vue:
drive: "Drive"
admin/views/drive.vue:
origin:
local: "Lokal"
delete: "Löschen"
admin/views/users.vue:
username: "Benutzername"
users:
origin:
local: "Lokal"
admin/views/emoji.vue:
add-emoji:
add: "Hinzufügen"
emojis:
remove: "Löschen"
admin/views/announcements.vue:
save: "Speichern"
remove: "Löschen"
add: "Hinzufügen"
saved: "Gespeichert"
admin/views/federation.vue:
status: "Status"
save: "Speichern"
desktop/views/pages/note.vue:
prev: "Vorheriger Kommentar"
next: "Nächster Kommentar"
desktop/views/pages/selectdrive.vue:
title: "Wähle Datei(en) aus"
ok: "OK"
cancel: "Abbrechen"
desktop/views/pages/user-list.users.vue:
username: "Benutzername"
desktop/views/pages/user/user.followers-you-know.vue:
loading: "Laden"
desktop/views/pages/user/user.friends.vue:
loading: "Laden"
desktop/views/pages/user/user.photos.vue:
loading: "Laden"
no-photos: "Keine Fotos"
desktop/views/pages/user/user.header.vue:
month: "Mo"
day: "So"
desktop/views/widgets/notifications.vue:
title: "Benachrichtigungen"
desktop/views/widgets/polls.vue:
title: "Umfrage"
nothing: "Keine Benachrichtigungen"
desktop/views/widgets/trends.vue:
nothing: "Keine Benachrichtigungen"
mobile/views/components/drive.vue:
used: "benutzt"
folder-name: "Ordnername"
url-prompt: "URL der Datei, welche du hochladen möchtest"
mobile/views/components/drive.file-detail.vue:
download: "Download"
rename: "Umbenennen"
mobile/views/components/note.vue:
private: "Dieser Beitrag ist privat"
deleted: "Dieser Beitrag wurde entfernt"
location: "Ort"
mobile/views/components/note-detail.vue:
reply: "Antworten"
private: "Dieser Beitrag ist privat"
deleted: "Dieser Beitrag wurde entfernt"
location: "Ort"
mobile/views/components/notifications.vue:
empty: "Keine Benachrichtigungen"
mobile/views/components/sub-note-content.vue:
private: "Dieser Beitrag ist privat"
deleted: "Dieser Beitrag wurde entfernt"
poll: "Umfrage"
mobile/views/components/ui.nav.vue:
notifications: "Benachrichtigungen"
search: "Suchen"
user-lists: "Listen"
user-groups: "Gruppen"
game: "Spielen"
about: "Über"
mobile/views/pages/drive.vue:
contextmenu:
upload: "Eine Datei hochladen"
create-folder: "Ein Verzeichnis erstellen"
mobile/views/pages/home.vue:
home: "Home"
local: "Lokal"
global: "Global"
mobile/views/pages/widgets.vue:
add-widget: "Hinzufügen"
customization-tips: "Anpassungs-Tipps"
mobile/views/pages/widgets/activity.vue:
activity: "Aktivität"
mobile/views/pages/note.vue:
prev: "Vorheriger Kommentar"
next: "Nächster Kommentar"
mobile/views/pages/search.vue:
search: "Suchen"
mobile/views/pages/notifications.vue:
notifications: "Benachrichtigungen"
mobile/views/pages/user/home.vue:
activity: "Aktivität"
keywords: "Schlagwörter"
mobile/views/pages/user/home.photos.vue:
no-photos: "Keine Fotos"
deck:
home: "Home"
local: "Lokal"
global: "Global"
notifications: "Benachrichtigungen"
list: "Listen"
rename: "Umbenennen"
deck/deck.user-column.vue:
following: "Folgen"
followers: "Folgende"
images: "Bilder"
activity: "Aktivität"
timeline: "Zeitleiste"
pinned-notes: "Angeheftete Beiträge"
docs:
edit-this-page-on-github: "Hast Du einen Fehler gefunden oder Lust, diese Dokumentation zu verbessern?"
edit-this-page-on-github-link: "Seite auf GitHub bearbeiten!"
dev/views/index.vue:
manage-apps: "Anwendungen verwalten"
dev/views/apps.vue:
manage-apps: "Anwendungen verwalten"
create-app: "Anwendung erstellen"
app-missing: "Keine Anwendungen"
dev/views/new-app.vue:
create-app: "Erstelle Anwendung"
app-name: "Name der Anwendung"
app-name-desc: "Der Name der Anwendung"
app-overview: "Beschreibung der Anwendung"
callback-url: "Callback-URL (optional)"
callback-url-desc: "Die URL, auf die nach erfolgreicher Authentifizierung umgeleitet werden soll."
authority: "Berechtigungen"
authority-desc: "Nur die hier eingetragenen Berechtigungen, werden per API zur Verfügung stehen."
authority-warning: "Dies kann auch nach dem erstellen der Anwendung geändert werden, allerdings werden dann alle bisher generierten Token ungültig."
pages:
pin-this-page: "An die Profilseite pinnen"
unpin-this-page: "Lösen"
like: "Gefällt mir"
blocks:
post: "\"Neuer Beitrag\"-Formular"
script:
categories:
random: "Zufällige Auswahl"
list: "Listen"
blocks:
_join:
arg1: "Listen"
random: "Zufällige Auswahl"
_randomPick:
arg1: "Listen"
_dailyRandomPick:
arg1: "Listen"
_seedRandomPick:
arg2: "Listen"
_pick:
arg1: "Listen"
_listLen:
arg1: "Listen"
types:
array: "Listen"
room:
save: "Speichern"
saved: "Gespeichert"
furnitures:
moon: "Mond"
bin: "Papierkorb"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -14,19 +14,19 @@ const merge = (...args) => args.reduce((a, c) => ({
}), {});
const languages = [
'cs-CZ',
'da-DK',
'de-DE',
//'cs-CZ',
//'da-DK',
//'de-DE',
'en-US',
'es-ES',
'fr-FR',
'ja-JP',
'ja-KS',
'ko-KR',
'nl-NL',
'pl-PL',
//'nl-NL',
//'pl-PL',
'zh-CN',
'zh-TW',
//'zh-TW',
];
const primaries = {

View File

@ -1,6 +0,0 @@
---
meta:
lang: "Italiano"
common:
misskey: "A ⭐ of the fediverse"
about-title: "A ⭐ of the fediverse."

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

34
locales/kn-IN.yml Normal file
View File

@ -0,0 +1,34 @@
---
_lang_: "ಕನ್ನಡ"
introMisskey: "ಸ್ವಾಗತ! Misskey ಓಪನ್ ಸೋರ್ಸ್ ಒಕ್ಕೂಟ ಮೈಕ್ರೋಬ್ಲಾಗಿಂಗ್ ಸೇವೆಯಾಗಿದೆ.\n ಏನಾಗುತ್ತಿದೆ ಎಂಬುದನ್ನು ಹಂಚಿಕೊಳ್ಳಲು ಅಥವಾ ನಿಮ್ಮ ಬಗ್ಗೆ ಎಲ್ಲರಿಗೂ ಹೇಳಲು \"ಟಿಪ್ಪಣಿ\"ಗಳನ್ನು ರಚಿಸಿ📡\n \"ಸ್ಪಂದನೆ\" ಕ್ರಿಯೆಯೊಂದಿಗೆ, ನೀವು ಎಲ್ಲರ ಟಿಪ್ಪಣಿಗಳಿಗೆ ತ್ವರಿತವಾಗಿ ಸ್ಪಂದನೆಗಳನ್ನು ಕೂಡ ಸೇರಿಸಬಹುದು.👍\n ಹೊಸ ಜಗತ್ತನ್ನು ಅನ್ವೇಷಿಸಿ🚀"
monthAndDay: "{month}ನೇ ತಿಂಗಳ {day}ನೇ ದಿನ"
search: "ಹುಡುಕು"
notifications: "ಅಧಿಸೂಚನೆಗಳು"
username: "ಬಳಕೆಹೆಸರು"
password: "ಗುಪ್ತಪದ"
fetchingAsApObject: "ಒಕ್ಕೂಟದಿಂದ ಪಡೆಯಲಾಗುತ್ತಿದೆ..."
ok: "ಸರಿ"
gotIt: "ಅರ್ಥವಾಯಿತು!"
cancel: "ರದ್ದು"
enterUsername: "ಬಳಕೆಹೆಸರನ್ನು ಭರ್ತಿ ಮಾಡಿ"
renotedBy: "{user} ಪುನರಾವರ್ತಿಸಿದರು"
noNotes: "ಟಿಪ್ಪಣಿಗಳಿಲ್ಲ"
noNotifications: "ಅಧಿಸೂಚನೆಗಳಿಲ್ಲ"
instance: "ನಿದರ್ಶನ"
settings: "ಸಿದ್ಧತೆಗಳು"
profile: "ಪ್ರೊಫೈಲು"
timeline: "ಸಮಯಸಾಲು"
noAccountDescription: "ಇವರು ಸ್ವಯಂ ಪರಿಚಯ ರಚಿಸಿಲ್ಲ"
login: "ಪ್ರವೇಶ"
loggingIn: "ಪ್ರವೇಶಿಸುತ್ತಾ..."
logout: "ಆಚೆಗೆ"
signup: "ನೋಂದಣಿ"
uploading: "ಅಪ್‌ಲೋಡಾಗುತ್ತಿದೆ"
save: "ಉಳಿಸಿ"
users: "ಬಳಕೆದಾರ"
instances: "ನಿದರ್ಶನ"
_widgets:
notifications: "ಅಧಿಸೂಚನೆಗಳು"
timeline: "ಸಮಯಸಾಲು"
_profile:
username: "ಬಳಕೆಹೆಸರು"

File diff suppressed because it is too large Load Diff

View File

@ -1,701 +1,2 @@
---
meta:
lang: "Nederlands"
common:
misskey: "Deel alles met anderen die ook Misskey gebruiken."
about-title: "Een ster van het fediverse"
about: "Bedankt voor het ontdekken van Misskey. Misskey is een <b>gedecentraliseerd microblogging platform</b> geboren op aarde. Omdat het bestaat binnen het Fediverse (een georganiseerd universum van verschillende sociale mediaplatformen), staat het verbonden met andere sociale medieplatformen. Neem een pauze van de stedelijke drukte, en duik in het nieuwe intenet?"
intro:
title: "Wat is Misskey?"
about: "Misskey is een open source <b>gedecentraliseerd blogplatform</b>. Het heeft een gesofisticeerde, volledig aanpasbare gebruikersinterface, uitgebreide reactiemogelijkheden voor posts, gratis geïntegreerd bestandsoplagbeheer en andere geavanceerde mogelijkheden. Daarnaast staat Misskey verbonden aan een netwerksysteem genaam het \"Fediverse\", hiermee kunnen we communiceren met andere gebruikers op andere SNSs. Dit betekent dat wanneer je iets post het niet enkel verstuurd wordt naar andere Misskey gebruikers, maar ook naar gebruikers op Mastodon en Pleroma. Stel je voor dat een planeet een radiosignaal verzendt naar een andere planeet als manier van communiceren."
features: "Kenmerken"
rich-contents: "Bericht"
rich-contents-desc: "Post jouw idee, hot topic, wat je ook maar wil delen. Maak jouw teksten aantrekkelijk met je favoriete foto's, verzend bestanden, zelfs video's, of maak een poll. Dit zijn enkele van de mogelijkheden die Misskey aanbiedt!"
reaction: "Reactie"
reaction-desc: "Dé makkelijkste manier om jouw gevoelens uit te drukken. Met Misskey kan je verschillende reacties toevoegen aan jouw posts. Andere SNSs hebben enkel maar een \"vind ik leuk\" reactie."
ui: "Interface"
ui-desc: "Niet één UI past nij iedereen. Daarom heeft Misskey een uitgebreide keuze om de UI naar jouw hand te zetten. Je kan jouw nieuwe thuis zo origineel maken als je zelf wil door jouw tijdslijn aan te passen door widgets te verplaatsen en hun look te veranderen. Zo maak je van Misskey jouw eigen stek."
drive: "Drive"
drive-desc: "Wil je een foto posten die je reeds het geüpload? Wens je georganiseerde map met zelfgekozen naam maken voor al jouw bestanden? De beste oplossing voor jou is Misskey Drive. Dit maakt het supermakkelijk om jouw bestanden online te delen."
application-authorization: "Geauthoriseerde applicaties"
close: "Sluiten"
do-not-copy-paste: "Gelieve de code hier niet in te geven of te plakken. De account kan gecompromiseerd zijn."
load-more: "Laad meer resultaten"
enter-password: "Voer het wachtwoord in"
2fa: "Tweestapsverificatie"
customize-home: "Layout aanpassen"
featured-notes: "Uitgelicht"
dark-mode: "Donker thema"
signin: "Aanmelden"
signup: "Registreren"
signout: "Afmelden"
reload-to-apply-the-setting: "Herlaad de pagina om je aanpassingen te bekijken. Wil je de pagina nu herladen?"
fetching-as-ap-object: "Verzenden naar Fediverse"
unfollow-confirm: "Wil stoppen met {name} te volgen?"
delete-confirm: "Ben je zeker dat je dit bericht wil verwijderen?"
signin-required: "Gelieve in te loggen"
notification-type: "Notificatietype"
notification-types:
all: "Alle"
pollVote: "Stemmen"
follow: "Volgend"
receiveFollowRequest: "Volgverzoeken"
reply: "Beantwoorden"
quote: "Bron"
mention: "Vermeldingen"
reaction: "Reactie"
got-it: "Ik snap het!"
customization-tips:
title: "Aanpassingstips"
gotit: "Ik snap het!"
notification:
file-uploaded: "Je bestand is geüpload"
message-from: "Bericht van {}:"
reversi-invited: "Uitgenodigd voor spel"
notified-by: "Bemerkt door: {}"
reply-from: "Antwoord van: {}"
quoted-by: "Geciteerd door: {}"
time:
unknown: "onbekend"
future: "toekomstig"
just_now: "zojuist"
seconds_ago: "{}s geleden"
minutes_ago: "{}m geleden"
hours_ago: "{}u geleden"
days_ago: "{}d geleden"
weeks_ago: "{}week/weken geleden"
months_ago: "{}maand(en) geleden"
years_ago: "{}jaar geleden"
month-and-day: "{day} {month}"
trash: "Prullenbak"
drive: "Drive"
pages: "Pagina's"
messaging: "Gesprekken"
home: "Startpagina"
deck: "Deck"
timeline: "Tijdlijn"
followers: "Volgers"
favorites: "Deze notitie toevoegen aan favorieten"
permissions:
"write:votes": "Stemmen"
post-form:
submit: "Bericht"
reply: "Beantwoorden"
add-visible-user: "Gebruiker toevoegen"
weekday-short:
sunday: "Z"
monday: "M"
tuesday: "D"
wednesday: "W"
thursday: "D"
friday: "V"
saturday: "Z"
reactions:
like: "Leuk"
love: "Geweldig"
laugh: "Grappig"
hmm: "Eh...?"
surprise: "Wauw"
congrats: "Gefeliciteerd!"
angry: "Boos"
confused: "Verward"
pudding: "Pudding"
note-visibility:
home: "Startpagina"
followers: "Volgers"
_settings:
profile: "Je profiel"
notification: "Meldingen"
password: "Wachtwoord"
reactions: "Reactie"
deck-column-align-center: "Centreren"
deck-column-align-left: "Links"
timeline: "Tijdlijn"
navbar-position-left: "Links"
search: "Zoeken"
delete: "Verwijderen"
loading: "Bezig met laden"
update-available: "Er is een nieuwe versie van Misskey beschikbaar: {newer} (de huidige versie is {current}). Herlaad de pagina om de update toe te passen."
my-token-regenerated: "Je sleutel is gegenereerd; je wordt nu uitgelogd."
widgets:
profile: "Je profiel"
activity: "Activiteit"
trends: "Populair"
photo-stream: "Fotostream"
notifications: "Meldingen"
users: "Aanbevolen gebruikers"
server: "Serverinformatie"
you: "Jij"
auth/views/form.vue:
cancel: "Annuleren"
auth/views/index.vue:
loading: "Bezig met laden"
common/views/components/games/reversi/reversi.vue:
matching:
cancel: "Annuleren"
common/views/components/games/reversi/reversi.room.vue:
cancel: "Annuleren"
common/views/components/connect-failed.vue:
title: "Verbinden met server mislukt"
description: "Er is een probleem met je internetverbinding, de server ligt plat of er wordt aan gewerkt. {Probeer} het later opnieuw."
thanks: "Bedankt voor het gebruiken van Misskey."
troubleshoot: "Probleemoplossing"
common/views/components/connect-failed.troubleshooter.vue:
title: "Probleemoplossing"
network: "Netwerkverbinding"
checking-network: "Bezig met controleren van netwerkverbinding"
internet: "Internetverbinding"
checking-internet: "Bezig met controleren van internetverbinding"
server: "Serververbinding"
checking-server: "Bezig met controleren van serververbinding"
finding: "Bezig met vaststellen van probleem"
no-network: "Er is geen internetverbinding"
no-network-desc: "Zorg ervoor dat je verbonden bent met een netwerk."
no-internet: "Er is geen internetverbinding"
no-internet-desc: "Zorg ervoor dat je verbonden bent met het internet."
no-server: "Verbinden met Misskey-server mislukt"
no-server-desc: "De netwerkverbinding van je computer is goed, maar er kan geen verbinding worden gemaakt met de Misskey-server. Het kan dat de server plat ligt of dat eraan wordt gewerkt. Probeer het later opnieuw."
success: "Verbonden met de Misskey-server"
success-desc: "Het verbinden lijkt te lukken. Herlaad de pagina."
flush: "Cache leegmaken"
set-version: "Versie opgeven"
common/views/components/theme.vue:
desc: "Omschrijving"
common/views/components/messaging.vue:
search-user: "Gebruiker zoeken"
you: "Jij"
no-history: "Geen geschiedenis"
user: "Gebruiker"
common/views/components/messaging-room.vue:
no-history: "Er is geen verdere geschiedenis"
new-message: "Nieuw bericht"
common/views/components/messaging-room.form.vue:
input-message-here: "Voer hier je bericht in"
send: "Versturen"
attach-from-local: "Bestanden bijvoegen van je computer"
attach-from-drive: "Bestanden bijvoegen van je Drive"
common/views/components/messaging-room.message.vue:
is-read: "Gelezen"
deleted: "Dit bericht is verwijderd"
common/views/components/nav.vue:
about: "Over"
stats: "Statistieken"
status: "Status"
donors: "Donateurs"
repository: "Broncode"
develop: "Ontwikkelaars"
feedback: "Feedback"
common/views/components/note-menu.vue:
favorite: "Deze notitie toevoegen aan favorieten"
pin: "Vastmaken aan profielpagina"
delete: "Verwijderen"
remote: "Origineel tonen"
common/views/components/poll.vue:
vote-to: "Stemmen op '{}'"
vote-count: "{} stemmen"
vote: "Stemmen"
show-result: "Resultaten tonen"
voted: "Gestemd"
common/views/components/poll-editor.vue:
no-only-one-choice: "Je moet twee of meer keuzes invoeren."
choice-n: "Keuze {}"
remove: "Deze keuze verwijderen"
add: "+ Keuze toevoegen"
destroy: "Deze peiling vernietigen"
day: "Z"
common/views/components/reaction-picker.vue:
choose-reaction: "Kies een reactie"
common/views/components/emoji-picker.vue:
activity: "Activiteit"
common/views/components/signin.vue:
username: "Gebruikersnaam"
password: "Wachtwoord"
token: "Sleutel"
signing-in: "Bezig met inloggen..."
common/views/components/signup.vue:
username: "Gebruikersnaam"
checking: "Bezig met controleren..."
available: "Beschikbaar"
unavailable: "Niet beschikbaar"
error: "Netwerkfout"
invalid-format: "Gebruik alleen letters, cijfers en -."
too-short: "Voer minimaal 1 teken in!"
too-long: "Voer maximaal 20 tekens in."
password: "Wachtwoord"
password-placeholder: "Wij raden aan meer dan 8 tekens te gebruiken."
weak-password: "Zwak"
normal-password: "'t Ken net"
strong-password: "Sterk"
retype: "Opnieuw invoeren"
retype-placeholder: "Wachtwoord bevestigen"
password-matched: "Oké"
password-not-matched: "Komt niet overeen"
recaptcha: "Verifiëren"
create: "Account creëren"
some-error: "Het creëren van een account is mislukt. Probeer het opnieuw."
common/views/components/special-message.vue:
new-year: "Gelukkig nieuwjaar!"
christmas: "Fijne kerstdagen!"
common/views/components/stream-indicator.vue:
connecting: "Bezig met verbinden"
reconnecting: "Bezig met herverbinden"
connected: "Verbonden"
common/views/components/notification-settings.vue:
title: "Meldingen"
common/views/components/github-setting.vue:
detail: "Details bekijken..."
common/views/components/discord-setting.vue:
detail: "Details bekijken..."
common/views/components/uploader.vue:
waiting: "Bezig met wachten"
common/views/components/visibility-chooser.vue:
home: "Startpagina"
followers: "Volgers"
common/views/components/profile-editor.vue:
title: "Je profiel"
name: "Naam"
avatar: "Gebruikersafbeelding"
banner: "Omslagfoto"
unable-to-process: "De operatie kan niet worden voltooid."
export-targets:
following-list: "Volgend"
user-lists: "Lijsten"
enter-password: "Voer het wachtwoord in"
common/views/components/user-list-editor.vue:
users: "Gebruiker"
add-user: "Gebruiker toevoegen"
common/views/components/user-lists.vue:
user-lists: "Lijsten"
common/views/widgets/broadcast.vue:
fetching: "Bezig met ophalen"
no-broadcasts: "Geen uitzendingen"
have-a-nice-day: "Fijne dag!"
next: "Volgende"
common/views/widgets/photo-stream.vue:
title: "Fotostream"
no-photos: "Geen foto's"
common/views/widgets/posts-monitor.vue:
toggle: "Schakelen tussen weergaven"
common/views/widgets/server.vue:
title: "Serverinformatie"
toggle: "Schakelen tussen weergaven"
common/views/pages/follow.vue:
signed-in-as: "Ingelogd als {}"
follow: "Volgend"
desktop:
banner: "Omslagfoto"
avatar: "Gebruikersafbeelding"
unable-to-process: "De operatie kan niet worden voltooid."
desktop/views/components/activity.chart.vue:
total: "Zwart ... totaal"
notes: "Blauw ... notities"
replies: "Rood ... antwoorden"
renotes: "Groen ... gedeelde notities"
desktop/views/components/activity.vue:
title: "Activiteit"
toggle: "Schakelen tussen weergaven"
desktop/views/components/calendar.vue:
prev: "Vorige maand"
next: "Volgende maand"
go: "Klik om te navigeren"
desktop/views/components/choose-file-from-drive-window.vue:
upload: "Bestanden uploaden van je computer"
cancel: "Annuleren"
ok: "Oké"
choose-prompt: "Kies een bestand"
desktop/views/components/choose-folder-from-drive-window.vue:
cancel: "Annuleren"
ok: "Oké"
choose-prompt: "Kies een map"
desktop/views/components/crop-window.vue:
skip: "Bijsnijden overslaan"
cancel: "Annuleren"
ok: "Oké"
desktop/views/components/drive-window.vue:
used: "gebruikt"
desktop/views/components/drive.file.vue:
avatar: "Gebruikersafbeelding"
banner: "Omslagfoto"
contextmenu:
rename: "Naam wijzigen"
copy-url: "URL kopiëren"
download: "Downloaden"
set-as-avatar: "Instellen als gebruikersafbeelding"
set-as-banner: "Instellen als omslagfoto"
open-in-app: "Openen in app"
add-app: "App toevoegen"
rename-file: "Bestandsnaam wijzigen"
input-new-file-name: "Voer een nieuwe naam in"
copied: "Gekopieerd"
copied-url-to-clipboard: "URL gekopieerd naar klembord"
desktop/views/components/drive.folder.vue:
unable-to-process: "De operatie kan niet worden voltooid."
circular-reference-detected: "De bestemmingsmap is een submap van de map die je wilt verplaatsen."
unhandled-error: "Onbekende fout"
contextmenu:
move-to-this-folder: "Verplaatsen naar deze map"
show-in-new-window: "Openen in nieuw venster"
rename: "Naam wijzigen"
rename-folder: "Mapnaam wijzigen"
input-new-folder-name: "Voer een nieuwe naam in"
desktop/views/components/drive.vue:
search: "Zoeken"
empty-draghover: "Welkom!"
empty-drive: "Je schijf is leeg"
empty-drive-description: "Je kunt ook uploaden door te klikken met de rechtermuisknop en te kiezen voor \"Bestand uploaden\" of door een bestand naar dit venster te slepen."
empty-folder: "Deze map is leeg"
unable-to-process: "De operatie kan niet worden voltooid."
circular-reference-detected: "De bestemmingsmap is een submap van de te verplaatsen map."
unhandled-error: "Onbekende fout"
url-upload: "Uploaden via URL"
url-of-file: "URL van het te uploaden bestand"
url-upload-requested: "Uploadverzoek"
may-take-time: "Het kan even duren voordat het uploaden voltooid is."
create-folder: "Map creëren"
folder-name: "Mapnaam"
contextmenu:
create-folder: "Map creëren"
upload: "Bestand uploaden"
url-upload: "Uploaden via URL"
desktop/views/components/followers-window.vue:
followers: "Volgers van {}"
desktop/views/components/followers.vue:
empty: "Het lijkt erop dat je geen volgers hebt."
desktop/views/components/following-window.vue:
following: "Volgend {}"
desktop/views/components/following.vue:
empty: "Je volgt niemand."
desktop/views/components/game-window.vue:
game: "Othello"
desktop/views/components/home.vue:
done: "Versturen"
add-widget: "Widget toevoegen:"
add: "Toevoegen"
desktop/views/input-dialog.vue:
cancel: "Annuleren"
ok: "Oké"
desktop/views/components/note-detail.vue:
private: "(dit bericht is privé)"
location: "Locatie"
add-reaction: "Reactie"
desktop/views/components/note.vue:
reply: "Beantwoorden"
add-reaction: "Reactie"
private: "(dit bericht is privé)"
desktop/views/components/notes.vue:
error: "Laden mislukt."
retry: "Opnieuw proberen"
desktop/views/components/notifications.vue:
empty: "Geen meldingen"
desktop/views/components/post-form.vue:
posted: "Geplaatst!"
replied: "Beantwoord!"
reposted: "Hergeplaatst!"
note-failed: "Noteren mislukt"
reply-failed: "Beantwoorden mislukt"
renote-failed: "Renote mislukt"
desktop/views/components/post-form-window.vue:
note: "Nieuwe notitie"
reply: "Beantwoorden"
attaches: "{} media bijgevoegd"
uploading-media: "Bezig met uploaden van media {}"
desktop/views/components/progress-dialog.vue:
waiting: "Bezig met wachten"
desktop/views/components/renote-form.vue:
quote: "Citeren..."
cancel: "Annuleren"
reposting: "Bezig met herplaatsen..."
success: "Hergeplaatst!"
failure: "Renote mislukt"
desktop/views/components/renote-form-window.vue:
title: "Weet je zeker dat je deze notitie wilt renoten?"
desktop/views/components/settings.2fa.vue:
intro: "Als je verificatie in twee stappen instelt, dan heb je niet alleen een wachtwoord nodig bij het inloggen, maar ook een geregistreerd fysiek apparaat (zoals je smartphone). Dit verhoogt de veiligheid. "
detail: "Details bekijken..."
url: "https://www.google.com/landing/2step/"
caution: "Als je geen toegang meer hebt tot je apparaat, dan kun je niet meer verbinden met Misskey!"
register: "Apparaat registreren"
already-registered: "Er is al een apparaat geregistreerd"
unregister: "Uitschakelen"
unregistered: "Authenticatie in twee stappen is uitgeschakeld."
enter-password: "Voer het wachtwoord in"
authenticator: "Installeer eerst Google Authenticator op je apparaat:"
howtoinstall: "Hoe installeer ik dit?"
token: "Sleutel"
scan: "Scan daarna de QR-code:"
done: "Voer de op je apparaat getoonde sleutel in:"
submit: "Versturen"
success: "Instellen voltooid!"
failed: "Instellen mislukt. Zorg ervoor dat de sleutel juist is."
info: "Vanaf nu moet je ook de op je apparaat getoonde sleutel tonen bij het inloggen op Misskey."
common/views/components/api-settings.vue:
enter-password: "Voer het wachtwoord in"
console:
parameter: "Parameters"
send: "Versturen"
common/views/components/drive-settings.vue:
in-use: "gebruikt"
stats: "Statistieken"
default-upload-folder-name: "Map(pen)"
desktop/views/components/sub-note-content.vue:
private: "(dit bericht is privé)"
poll: "Peilingen"
desktop/views/components/settings.tags.vue:
add: "Toevoegen"
desktop/views/components/timeline.vue:
home: "Startpagina"
local: "Lokaal"
global: "Algemeen"
list: "Lijsten"
desktop/views/components/ui.header.account.vue:
profile: "Je profiel"
lists: "Lijsten"
desktop/views/components/ui.header.nav.vue:
game: "Othello spelen"
desktop/views/components/ui.header.notifications.vue:
title: "Meldingen"
desktop/views/components/ui.header.post.vue:
post: "Nieuw bericht opstellen"
desktop/views/components/ui.header.search.vue:
placeholder: "Zoeken"
desktop/views/components/user-preview.vue:
notes: "Berichten"
following: "Volgend"
followers: "Volgers"
desktop/views/components/users-list.vue:
all: "Alle"
iknow: "die ik ken"
fetching: "Bezig met laden…"
desktop/views/components/users-list-item.vue:
followed: "Volgt jou"
desktop/views/components/window.vue:
popout: "Uitvouwen"
close: "Sluiten"
admin/views/index.vue:
users: "Gebruiker"
admin/views/dashboard.vue:
notes: "Bericht"
drive: "Drive"
admin/views/abuse.vue:
remove-report: "Verwijderen"
admin/views/charts.vue:
notes: "Bericht"
users: "Gebruiker"
drive: "Drive"
admin/views/drive.vue:
origin:
local: "Lokaal"
delete: "Verwijderen"
admin/views/users.vue:
username: "Gebruikersnaam"
users:
title: "Gebruiker"
state:
all: "Alle"
origin:
local: "Lokaal"
admin/views/emoji.vue:
add-emoji:
add: "Toevoegen"
emojis:
remove: "Verwijderen"
admin/views/announcements.vue:
remove: "Verwijderen"
add: "Toevoegen"
admin/views/federation.vue:
notes: "Bericht"
users: "Gebruiker"
followers: "Volgers"
status: "Status"
states:
all: "Alle"
desktop/views/pages/welcome.vue:
timeline: "Tijdlijn"
desktop/views/pages/note.vue:
prev: "Vorige notitie"
next: "Volgende notitie"
desktop/views/pages/selectdrive.vue:
title: "Bestand(en) kiezen"
ok: "Oké"
cancel: "Annuleren"
upload: "Bestanden uploaden van je PC"
desktop/views/pages/user-list.users.vue:
users: "Gebruiker"
add-user: "Gebruiker toevoegen"
username: "Gebruikersnaam"
desktop/views/pages/user/user.followers-you-know.vue:
title: "Volgers die je kent"
loading: "Bezig met laden"
no-users: "Geen gebruikers"
desktop/views/pages/user/user.friends.vue:
title: "Frequent beantwoord"
loading: "Bezig met laden"
no-users: "Geen gebruikers"
desktop/views/pages/user/user.photos.vue:
title: "Foto's"
loading: "Bezig met laden"
no-photos: "Geen foto's"
desktop/views/pages/user/user.header.vue:
posts: "Bericht"
following: "Volgend"
followers: "Volgers"
month: "M"
day: "Z"
follows-you: "Volgt jou"
desktop/views/pages/user/user.timeline.vue:
default: "Berichten"
with-replies: "Berichten en antwoorden"
with-media: "Media"
desktop/views/widgets/notifications.vue:
title: "Meldingen"
desktop/views/widgets/polls.vue:
title: "Peilingen"
refresh: "Anderen tonen"
nothing: "Niks"
desktop/views/widgets/post-form.vue:
title: "Bericht"
note: "Bericht"
desktop/views/widgets/profile.vue:
update-banner: "Klik om je omslagfoto te wijzigen"
update-avatar: "Klik om je gebruikersafbeelding te wijzigen"
desktop/views/widgets/trends.vue:
title: "Populair"
refresh: "Anderen tonen"
nothing: "Niks"
desktop/views/widgets/users.vue:
title: "Aanbevolen gebruikers"
refresh: "Anderen tonen"
no-one: "Niemand"
mobile/views/components/drive.vue:
used: "gebruikt"
folder-count: "Map(pen)"
count-separator: ", "
file-count: "Bestand(en)"
nothing-in-drive: "Niks"
folder-is-empty: "Deze map is leeg"
folder-name: "Mapnaam"
url-prompt: "URL van het te uploaden bestand"
mobile/views/components/drive-file-chooser.vue:
select-file: "Kies een bestand"
mobile/views/components/drive-folder-chooser.vue:
select-folder: "Kies een map"
mobile/views/components/drive.file-detail.vue:
download: "Downloaden"
rename: "Naam wijzigen"
move: "Verplaatsen"
hash: "Hash (md5)"
common/views/components/follow-button.vue:
follow: "Volgend"
mobile/views/components/note.vue:
private: "(dit bericht is privé)"
location: "Locatie"
mobile/views/components/note-detail.vue:
reply: "Beantwoorden"
reaction: "Reactie"
private: "(dit bericht is privé)"
location: "Locatie"
mobile/views/components/notifications.vue:
empty: "Geen meldingen"
mobile/views/components/sub-note-content.vue:
private: "(dit bericht is privé)"
media-count: "{} media"
poll: "Peiling"
mobile/views/components/ui.nav.vue:
timeline: "Tijdlijn"
notifications: "Meldingen"
search: "Zoeken"
user-lists: "Lijsten"
game: "Othello spelen"
about: "Over Misskey"
mobile/views/pages/drive.vue:
contextmenu:
upload: "Bestand uploaden"
create-folder: "Map creëren"
mobile/views/pages/home.vue:
home: "Startpagina"
local: "Lokaal"
global: "Algemeen"
mobile/views/pages/widgets.vue:
add-widget: "Toevoegen"
customization-tips: "Aanpassingstips"
mobile/views/pages/widgets/activity.vue:
activity: "Activiteit"
mobile/views/pages/note.vue:
title: "Bericht"
prev: "Vorige notitie"
next: "Volgende notitie"
mobile/views/pages/games/reversi.vue:
reversi: "Othello"
mobile/views/pages/search.vue:
search: "Zoeken"
mobile/views/pages/selectdrive.vue:
select-file: "Kies een bestand"
mobile/views/pages/notifications.vue:
notifications: "Meldingen"
mobile/views/pages/settings.vue:
signed-in-as: "Ingelogd als {}"
mobile/views/pages/user.vue:
follows-you: "Volgt jou"
following: "Volgend"
followers: "Volgers"
notes: "Berichten"
overview: "Overzicht"
timeline: "Tijdlijn"
media: "Media"
mobile/views/pages/user/home.vue:
recent-notes: "Recente notities"
images: "Afbeeldingen"
activity: "Activiteit"
keywords: "Sleutelwoorden"
domains: "Domeinnamen"
frequently-replied-users: "Frequent beantwoord"
followers-you-know: "Volgers die je kent"
last-used-at: "Laatst actief"
mobile/views/pages/user/home.photos.vue:
no-photos: "Geen foto's"
deck:
home: "Startpagina"
local: "Lokaal"
global: "Algemeen"
notifications: "Meldingen"
list: "Lijsten"
rename: "Naam wijzigen"
deck/deck.user-column.vue:
follows-you: "Volgt jou"
posts: "Bericht"
following: "Volgend"
followers: "Volgers"
images: "Afbeeldingen"
activity: "Activiteit"
timeline: "Tijdlijn"
docs:
edit-this-page-on-github: "Heb je een fout ontdekt of wil je bijdragen aan de documentatie? "
edit-this-page-on-github-link: "Bewerk deze pagina op GitHub!"
pages:
pin-this-page: "Vastmaken aan profielpagina"
like: "Leuk"
blocks:
image: "Afbeeldingen"
script:
categories:
list: "Lijsten"
blocks:
_join:
arg1: "Lijsten"
_randomPick:
arg1: "Lijsten"
_dailyRandomPick:
arg1: "Lijsten"
_seedRandomPick:
arg2: "Lijsten"
_pick:
arg1: "Lijsten"
_listLen:
arg1: "Lijsten"
types:
array: "Lijsten"
room:
translate: "Verplaatsen"
furnitures:
moon: "Maan"
bin: "Prullenbak"
_lang_: "Nederlands"

View File

@ -1,528 +1,2 @@
---
meta:
lang: "Norsk Bokmål"
common:
misskey: "En ⭐ av fediverse"
about-title: "En ⭐ av fediverse"
about: "Takk for at du fant Misskey. Misskey er en <b>desentralisert mikroblogging platform</b> født på jorden. Siden den eksisterer sammen med Fediverset (Et univers hvor forskjellige sosiale media-plattformer blir organisert), så blir den gjensidig tilknyttet med andre sosiale media-plattformer. Hvorfor ikke ta en pause fra kjas og mas fra storbyen og hoppe inn i en ny type internett?"
intro:
title: "Hva er Misskey?"
features: "Funksjoner"
rich-contents: "Innlegg"
drive: "Disk"
close: "Lukk"
notification-types:
all: "Alle"
follow: "Følger"
reply: "Svar"
got-it: "Skjønner!"
notification:
file-uploaded: "Filen ble lastet opp!"
message-from: "Melding fra {}:"
reversi-invited: "Invitert til et spill"
reversi-invited-by: "Invitert av {}:"
notified-by: "Invitert av {}:"
reply-from: "Svar fra {}:"
quoted-by: "Sitert av {}:"
time:
unknown: "ukjent"
future: "fremtidig"
just_now: "akkurat nå"
seconds_ago: "{} sekunder siden"
minutes_ago: "{} minutter siden"
hours_ago: "{} t siden"
days_ago: "{} d siden"
weeks_ago: "{} uke(r) siden"
months_ago: "{} måned(er) siden"
years_ago: "{} år siden"
month-and-day: "{day}/{month}"
trash: "Papirkurv"
drive: "Disk"
home: "Hjem"
followers: "Følgere"
favorites: "Merket som favoritt"
permissions:
"write:votes": "Stem"
post-form:
submit: "Innlegg"
reply: "Svar"
error: "Feil"
weekday-short:
sunday: "S"
monday: "M"
tuesday: "T"
wednesday: "O"
thursday: "T"
friday: "F"
saturday: "L"
weekday:
sunday: "Søndag"
monday: "Mandag"
tuesday: "Tirsdag"
wednesday: "Onsdag"
thursday: "Torsdag"
friday: "Fredag"
saturday: "Lørdag"
reactions:
like: "Lik"
love: "Elsk"
laugh: "Le"
hmm: "Hmm…?"
surprise: "Wow"
congrats: "Gratulerer!"
angry: "Sint"
confused: "Forvirret"
rip: "RIP"
pudding: "Pudding"
note-visibility:
public: "Offentlig"
home: "Hjem"
followers: "Følgere"
specified: "Direkte"
_settings:
notification: "Notifikasjon"
password: "Passord"
save: "Lagre"
search: "Søk"
delete: "Slett"
loading: "Laster inn..."
update-available: "En ny versjon av Misskey er nå tilgjengelig ({newer}, nåværende versjon er {current}). Last inn siden igjen for at oppdateringen skal tre i kraft."
my-token-regenerated: "Ditt synbol har blitt generert. Du vil nå bli utlogget."
reversi:
black: "Sort"
white: "Hvit"
total: "Totalt"
widgets:
calendar: "Kalender"
memo: "Notis"
trends: "Populært nå"
version: "Versjon"
notifications: "Notifikasjon"
tips: "Tips"
you: "Du"
auth/views/form.vue:
cancel: "Avbryt"
auth/views/index.vue:
loading: "Laster inn..."
common/views/components/games/reversi/reversi.vue:
matching:
cancel: "Avbryt"
common/views/components/games/reversi/reversi.game.vue:
surrender: "Gi opp"
common/views/components/games/reversi/reversi.index.vue:
invite: "Inviter"
rule: "Slik spiller du"
mode-invite: "Inviter"
game-state:
ended: "Ferdig"
playing: "Pågår"
common/views/components/games/reversi/reversi.room.vue:
random: "Tilfeldig"
black-is: "Sort er {}"
rules: "Regler"
waiting-for-both: "Venter på deg"
cancel: "Avbryt"
ready: "Klar"
cancel-ready: "Avbryt \"Klar\""
common/views/components/connect-failed.vue:
title: "Kunne ikke koble til tjeneren."
description: "Det er enten et problem med internettilknytningen din, eller så har tjeneren blitt tatt ned for vedlikehold. {Prøv igjen} senere."
common/views/components/media-banner.vue:
sensitive: "Sensitivt innhold"
common/views/components/theme.vue:
text-color: "Tekstfarge"
base-theme-dark: "Mørk"
theme-name: "Tema navn"
author: "Forfatter"
desc: "Beskrivelse"
common/views/components/cw-button.vue:
hide: "Skjul"
common/views/components/messaging.vue:
you: "Du"
user: "Bruker"
common/views/components/messaging-room.form.vue:
send: "Send"
common/views/components/messaging-room.message.vue:
is-read: "Lest"
common/views/components/nav.vue:
stats: "Statistikk"
status: "Status"
wiki: "Wiki"
donors: "Donatorer"
repository: "Kodelager"
develop: "Utviklere"
common/views/components/note-menu.vue:
detail: "Detaljer"
favorite: "Merket som favoritt"
pin: "Fest til profilen din"
delete: "Slett"
common/views/components/poll.vue:
vote-count: "{} stemmer"
vote: "Stem"
show-result: "Vis resultater"
voted: "Stemt"
common/views/components/poll-editor.vue:
choice-n: "Valg {}"
day: "S"
common/views/components/signin.vue:
username: "Brukernavn"
password: "Passord"
token: "Token"
or: "Eller"
common/views/components/signup.vue:
username: "Brukernavn"
error: "Nettverksfeil"
password: "Passord"
retype: "Gjenta"
recaptcha: "Captcha"
common/views/components/stream-indicator.vue:
connecting: "Tilkobler"
reconnecting: "Kobler til på nytt"
connected: "Tilkoblet"
common/views/components/notification-settings.vue:
title: "Notifikasjon"
common/views/components/github-setting.vue:
detail: "Detaljer..."
common/views/components/discord-setting.vue:
detail: "Detaljer..."
common/views/components/uploader.vue:
waiting: "Venter"
common/views/components/visibility-chooser.vue:
public: "Offentlig"
home: "Hjem"
followers: "Følgere"
specified: "Direkte"
common/views/components/profile-editor.vue:
name: "Navn"
avatar: "Avatar"
banner: "Banner"
save: "Lagre"
export-targets:
following-list: "Følger"
user-lists: "Lister"
common/views/components/user-list-editor.vue:
users: "Bruker"
common/views/components/user-group-editor.vue:
invite: "Inviter"
common/views/components/user-lists.vue:
user-lists: "Lister"
list-name: "Liste navn"
common/views/components/user-groups.vue:
invites: "Inviter"
common/views/widgets/broadcast.vue:
fetching: "Henter"
next: "Neste"
common/views/widgets/calendar.vue:
year: "År {}"
month: "Måned {}"
day: "Dag {}"
today: "I dag:"
this-month: "Denne måneden:"
this-year: "Dette året:"
common/views/widgets/memo.vue:
title: "Notis"
save: "Lagre"
common/views/pages/follow.vue:
follow: "Følg"
desktop:
banner: "Banner"
avatar: "Avatar"
desktop/views/components/calendar.vue:
prev: "Forrige måned"
next: "Neste måned"
desktop/views/components/choose-file-from-drive-window.vue:
cancel: "Avbryt"
ok: "Ok"
desktop/views/components/choose-folder-from-drive-window.vue:
cancel: "Avbryt"
ok: "Ok"
desktop/views/components/crop-window.vue:
cancel: "Avbryt"
ok: "Ok"
desktop/views/components/drive-window.vue:
used: "brukt"
desktop/views/components/drive.file.vue:
avatar: "Avatar"
banner: "Banner"
nsfw: "NSFW"
contextmenu:
rename: "Endre navn"
copied: "Kopiert"
desktop/views/components/drive.folder.vue:
contextmenu:
rename: "Endre navn"
desktop/views/components/drive.vue:
search: "Søk"
desktop/views/components/media-video.vue:
sensitive: "Innholdet er NSFW"
desktop/views/components/game-window.vue:
game: "Reversi"
desktop/views/components/home.vue:
done: "Fullført"
add: "Legg til"
desktop/views/input-dialog.vue:
cancel: "Avbryt"
ok: "Ok"
desktop/views/components/note-detail.vue:
location: "Lokasjon"
desktop/views/components/note.vue:
reply: "Svar"
detail: "Detaljer"
desktop/views/components/notes.vue:
retry: "Prøv på nytt"
desktop/views/components/post-form-window.vue:
note: "Nytt innlegg"
reply: "Svar"
desktop/views/components/progress-dialog.vue:
waiting: "Venter"
desktop/views/components/renote-form.vue:
cancel: "Avbryt"
desktop/views/components/settings.2fa.vue:
detail: "Detaljer..."
unregister: "Avregistrer"
token: "Token"
submit: "Send"
common/views/components/media-image.vue:
sensitive: "Innholdet er NSFW"
common/views/components/api-settings.vue:
console:
parameter: "Parametere"
send: "Send"
common/views/components/drive-settings.vue:
in-use: "brukt"
stats: "Statistikk"
default-upload-folder-name: "Mappe(r)"
common/views/components/mute-and-block.vue:
save: "Lagre"
desktop/views/components/settings.tags.vue:
add: "Legg til"
save: "Lagre"
desktop/views/components/timeline.vue:
home: "Hjem"
local: "Lokalt"
global: "Globalt"
list: "Lister"
list-name: "Liste navn"
desktop/views/components/ui.header.vue:
adjective: "-san"
desktop/views/components/ui.header.account.vue:
lists: "Lister"
admin: "Admin"
desktop/views/components/ui.header.nav.vue:
game: "Spill"
desktop/views/components/ui.header.notifications.vue:
title: "Notifikasjon"
desktop/views/components/ui.header.post.vue:
post: "Skriv nytt innlegg"
desktop/views/components/ui.header.search.vue:
placeholder: "Søk"
desktop/views/components/user-preview.vue:
notes: "Innlegg"
following: "Følger"
followers: "Følgere"
desktop/views/components/users-list.vue:
all: "Alle"
iknow: "Du kjenner"
desktop/views/components/window.vue:
close: "Lukk"
admin/views/index.vue:
users: "Bruker"
announcements: "Kunngjøringer"
admin/views/dashboard.vue:
notes: "Innlegg"
drive: "Disk"
admin/views/logs.vue:
levels:
info: "Informasjon"
error: "Feil"
admin/views/abuse.vue:
details: "Detaljer"
remove-report: "Slett"
admin/views/instance.vue:
invite: "Inviter"
save: "Lagre"
admin/views/charts.vue:
notes: "Innlegg"
users: "Bruker"
drive: "Disk"
admin/views/drive.vue:
origin:
local: "Lokalt"
delete: "Slett"
admin/views/users.vue:
username: "Brukernavn"
users:
title: "Bruker"
state:
all: "Alle"
origin:
local: "Lokalt"
admin/views/moderators.vue:
logs:
info: "Informasjon"
admin/views/emoji.vue:
add-emoji:
add: "Legg til"
emojis:
remove: "Slett"
admin/views/announcements.vue:
announcements: "Kunngjøringer"
save: "Lagre"
remove: "Slett"
add: "Legg til"
admin/views/federation.vue:
notes: "Innlegg"
users: "Bruker"
followers: "Følgere"
status: "Status"
states:
all: "Alle"
save: "Lagre"
desktop/views/pages/welcome.vue:
announcements: "Kunngjøringer"
info: "Informasjon"
desktop/views/pages/note.vue:
prev: "Forrige innlegg"
next: "Neste innlegg"
desktop/views/pages/selectdrive.vue:
ok: "Ok"
cancel: "Avbryt"
desktop/views/pages/user-list.users.vue:
users: "Bruker"
username: "Brukernavn"
desktop/views/pages/user/user.followers-you-know.vue:
loading: "Laster inn"
desktop/views/pages/user/user.friends.vue:
loading: "Laster inn"
desktop/views/pages/user/user.photos.vue:
title: "Bilder"
loading: "Laster inn"
desktop/views/pages/user/user.header.vue:
posts: "Innlegg"
following: "Følger"
followers: "Følgere"
month: "M"
day: "S"
desktop/views/pages/user/user.timeline.vue:
default: "Innlegg"
with-replies: "Innlegg og svar"
with-media: "Media"
desktop/views/widgets/notifications.vue:
title: "Notifikasjon"
desktop/views/widgets/polls.vue:
refresh: "Oppdater"
desktop/views/widgets/post-form.vue:
title: "Innlegg"
note: "Innlegg"
desktop/views/widgets/trends.vue:
title: "Populært nå"
refresh: "Oppdater"
desktop/views/widgets/users.vue:
refresh: "Oppdater"
no-one: "Ingen"
mobile/views/components/drive.vue:
used: "brukt"
folder-count: "Mappe(r)"
count-separator: ","
file-count: "Fil(er)"
mobile/views/components/drive.file.vue:
nsfw: "NSFW"
mobile/views/components/drive.file-detail.vue:
rename: "Endre navn"
move: "Flytt"
exif: "EXIF"
nsfw: "NSFW"
mobile/views/components/media-video.vue:
sensitive: "Innholdet er NSFW"
common/views/components/follow-button.vue:
follow: "Følger"
mobile/views/components/note.vue:
location: "Lokasjon"
mobile/views/components/note-detail.vue:
reply: "Svar"
location: "Lokasjon"
mobile/views/components/note-preview.vue:
admin: "admin"
bot: "bot"
cat: "katt"
mobile/views/components/note-sub.vue:
admin: "admin"
bot: "bot"
cat: "katt"
mobile/views/components/ui.header.vue:
adjective: "Mr."
mobile/views/components/ui.nav.vue:
notifications: "Notifikasjon"
search: "Søk"
user-lists: "Lister"
game: "Spill"
admin: "Admin"
mobile/views/pages/home.vue:
home: "Hjem"
local: "Lokalt"
global: "Globalt"
mobile/views/pages/widgets.vue:
add-widget: "Legg til"
mobile/views/pages/note.vue:
title: "Innlegg"
prev: "Forrige innlegg"
next: "Neste innlegg"
mobile/views/pages/games/reversi.vue:
reversi: "Reversi"
mobile/views/pages/search.vue:
search: "Søk"
mobile/views/pages/notifications.vue:
notifications: "Notifikasjon"
mobile/views/pages/user.vue:
following: "Følger"
followers: "Følgere"
notes: "Innlegg"
overview: "Oversikt"
media: "Media"
mobile/views/pages/user/home.vue:
recent-notes: "Nylige innlegg"
images: "Bilder"
keywords: "Nøkkelord"
deck:
home: "Hjem"
local: "Lokalt"
global: "Globalt"
notifications: "Notifikasjon"
list: "Lister"
rename: "Endre navn"
deck/deck.user-column.vue:
posts: "Innlegg"
following: "Følger"
followers: "Følgere"
images: "Bilder"
pages:
pin-this-page: "Fest til profilen din"
like: "Lik"
blocks:
image: "Bilder"
script:
categories:
random: "Tilfeldig"
list: "Lister"
blocks:
_join:
arg1: "Lister"
random: "Tilfeldig"
_randomPick:
arg1: "Lister"
_dailyRandomPick:
arg1: "Lister"
_seedRandomPick:
arg2: "Lister"
_pick:
arg1: "Lister"
_listLen:
arg1: "Lister"
types:
array: "Lister"
room:
translate: "Flytt"
save: "Lagre"
furnitures:
moon: "Måne"
bin: "Papirkurv"
_lang_: "Norsk Bokmål"

File diff suppressed because it is too large Load Diff

View File

@ -1,288 +1,2 @@
---
meta:
lang: "Português"
common:
misskey: "Uma ⭐ do fediverso"
about-title: "Uma ⭐ do fediverso."
about: "Obrigado por encontrar Misskey. Uma <b>plataforma descentralizada de microblog</b> nascida na Terra. Já que ela existe no Fediverso (um universo onde várias plataformas de mídia social são organizadas), ela é ligada com outras plataformas.Por que você não tira uma folga do agito e confusão da cidade, e mergulha em uma nova internet?"
intro:
title: "O que é Misskey?"
about: "Misskey é um <b>serviço de microblog descentralizado</b>. Personalização sofisticada da interface, variedade de reações a posts, armazenamento de arquivos grátis com gerenciamento integrado e outras funções avançadas estão disponíveis. Um sistema em rede chamado \"Fediverso\" permite que nos comuniquemos com usuários em outras redes sociais. Se você postar algo, por exemplo, seu post não será mandado apenas para o Misskey, mas também para o Mastodon. Apenas imagine que o planeta está enviando ondas de rádio para outros planetas para se comunicar."
features: "Recursos"
rich-contents: "Post"
rich-contents-desc: "Apenas poste suas ideias, temas do momento e qualquer coisa que você queira compartilhar. Você pode querer decorar suas palavras, anexar suas imagens favoritas, enviar arquivos, inclusive vídeos ou criar uma enquete. Essas são as coisas que você pode fazer em Misskey."
reaction: "Reações"
reaction-desc: "あなたの気持ちを伝える最も簡単な方法です。Misskeyは、他のユーザーの投稿に様々なリアクションを付けることができます。いちどMisskeyのリアクション機能を体験してしまうと、もう「いいね」の概念しか存在しないSNSには戻れなくなるかもしれません"
application-authorization: "Aplicativos autorizados"
close: "Fechar"
do-not-copy-paste: "Por favor, não digite ou copie o código aqui. A conta pode ser comprometida."
notification-types:
follow: "Seguindo"
got-it: "Entendi!"
customization-tips:
title: "Dicas de personalização"
gotit: "Entendi!"
notification:
file-uploaded: "Arquivo enviado!"
message-from: "Mensagem de {}:"
reversi-invited: "Convidado a jogar"
reversi-invited-by: "Convidado por {}:"
notified-by: "Notificado por {}:"
reply-from: "Resposta de {}:"
quoted-by: "Citado por {}:"
time:
unknown: "Desconhecido"
future: "futuro"
just_now: "agora"
seconds_ago: "{} sec atrás"
minutes_ago: "{} min atrás"
hours_ago: "{} h atrás"
days_ago: "{} d atrás"
weeks_ago: "{} sem atrás"
months_ago: "{} m atrás"
years_ago: "{} ano(s) atrás"
month-and-day: "{day}/{month}"
trash: "Lixo"
timeline: "Linha do tempo"
followers: "Seguidores"
post-form:
enter-username: "Digite o nome de usuário."
username-prompt: "Digite o nome de usuário."
weekday-short:
sunday: "Dom"
monday: "Seg"
tuesday: "Ter"
wednesday: "Qua"
thursday: "Qui"
friday: "Sex"
saturday: "Seb"
weekday:
sunday: "domingo"
monday: "segunda"
tuesday: "terça"
wednesday: "quarta"
thursday: "quinta"
friday: "sexta"
saturday: "sábado"
reactions:
like: "Curtir"
love: "Amei"
laugh: "Riso"
hmm: "Hmm...?"
surprise: "Uau"
congrats: "Parabéns!"
angry: "Raiva"
confused: "Confuso"
rip: "RIP"
pudding: "Pudim"
note-visibility:
followers: "Seguidores"
note-placeholders:
a: "O que está fazendo?"
b: "O que está acontecendo?"
c: "No que está pensando?"
d: "Quer postar algo?"
e: "Escreva aqui"
f: "Esperando você escrever."
_settings:
timeline: "Linha do tempo"
search: "Buscar"
delete: "Apagar"
loading: "Carregando"
update-available-title: "Atualização disponível"
update-available: "Uma nova versão de Misskey está disponível ({newer}). A versão atual é {current}. Recarregue a página para atualizar."
my-token-regenerated: "Seu token foi recriado, portanto você foi deslogado."
enter-username: "Digite o nome de usuário."
reversi:
drawn: "Empatado"
my-turn: "Seu turno"
opponent-turn: "Turno do oponente"
black: "Pretas"
white: "Brancas"
total: "Total"
widgets:
analog-clock: "Relógio analógico"
profile: "Perfil"
calendar: "Calendário"
timemachine: "Calendário (máquina do tempo)"
activity: "Atividade"
rss: "Leitor de RSS"
memo: "Nota adesiva"
trends: "Tendências"
posts-monitor: "Gráfico de publicações"
version: "Versão"
notifications: "Notificações"
users: "Usuário sugeridos"
polls: "Enquetes"
post-form: "Formulário de publicação"
server: "Informações do servidor"
nav: "Navegação"
tips: "Dicas"
hashtags: "Hashtags"
you: "Você"
auth/views/form.vue:
permission-ask: "Este aplicativo precisa das seguintes permissões:"
cancel: "Cancelar"
accept: "Permitir acesso"
auth/views/index.vue:
loading: "Carregando"
already-authorized: "Este aplicativo já foi autorizado"
allowed: "Aplicativos com acesso autorizado"
callback-url: "Voltando ao aplicativo"
please-go-back: "Por favor, volte ao aplicativo."
error: "A sessão não existe."
sign-in: "Por favor, entre."
common/views/components/games/reversi/reversi.index.vue:
invite: "Convidar"
rule: "Como jogar"
mode-invite: "Convidar"
mode-invite-desc: "Convidar um usuário para jogar"
invitations: "Você foi convidado!"
my-games: "Meu jogo"
all-games: "Todos os jogos"
enter-username: "Digite o nome de usuário."
game-state:
ended: "Terminado"
common/views/components/games/reversi/reversi.room.vue:
rules: "Regras"
cancel: "Cancelar"
common/views/components/connect-failed.troubleshooter.vue:
flush: "Limpar o cache"
common/views/components/theme.vue:
desc: "Descrição"
common/views/components/cw-button.vue:
poll: "Enquetes"
common/views/components/messaging.vue:
you: "Você"
common/views/components/note-menu.vue:
delete: "Apagar"
common/views/components/poll-editor.vue:
day: "Dom"
common/views/components/visibility-chooser.vue:
followers: "Seguidores"
common/views/components/profile-editor.vue:
name: "Nome"
export-targets:
following-list: "Seguindo"
common/views/components/user-group-editor.vue:
invite: "Convidar"
common/views/components/user-groups.vue:
invites: "Convidar"
common/views/widgets/posts-monitor.vue:
title: "Gráfico de publicações"
common/views/widgets/memo.vue:
title: "Nota adesiva"
common/views/pages/follow.vue:
follow: "Seguindo"
desktop/views/components/choose-file-from-drive-window.vue:
upload: "Envie arquivos do seu dispositivo"
ok: "OK"
desktop/views/components/choose-folder-from-drive-window.vue:
ok: "OK"
desktop/views/components/crop-window.vue:
ok: "OK"
desktop/views/input-dialog.vue:
ok: "OK"
common/views/components/api-settings.vue:
console:
parameter: "Parâmetros"
desktop/views/components/sub-note-content.vue:
poll: "Enquetes"
desktop/views/components/user-preview.vue:
following: "Seguindo"
followers: "Seguidores"
desktop/views/components/users-list-item.vue:
followed: "Te segue"
admin/views/abuse.vue:
remove-report: "Apagar"
admin/views/instance.vue:
invite: "Convidar"
admin/views/drive.vue:
delete: "Apagar"
admin/views/emoji.vue:
emojis:
remove: "Apagar"
admin/views/announcements.vue:
remove: "Apagar"
admin/views/federation.vue:
followers: "Seguidores"
desktop/views/pages/welcome.vue:
timeline: "Timeline"
powered-by-misskey: "Desenvolvido por <b>Misskey</b>."
desktop/views/pages/drive.vue:
title: "Drive Misskey"
desktop/views/pages/note.vue:
prev: "Nota anterior"
next: "Próxima nota"
desktop/views/pages/selectdrive.vue:
title: "Selecione um arquivo"
ok: "OK"
cancel: "Cancelar"
upload: "Envie arquivos do seu dispositivo"
desktop/views/pages/search.vue:
not-available: "A pesquisa está desligada nas configurações desta instância."
desktop/views/pages/user/user.followers-you-know.vue:
loading: "Carregando"
desktop/views/pages/user/user.friends.vue:
loading: "Carregando"
desktop/views/pages/user/user.photos.vue:
loading: "Carregando"
desktop/views/pages/user/user.header.vue:
following: "Seguindo"
followers: "Seguidores"
month: "Seg"
day: "Dom"
follows-you: "Te segue"
desktop/views/pages/user/user.timeline.vue:
with-media: "Mídia"
desktop/views/widgets/polls.vue:
title: "Enquetes"
common/views/components/follow-button.vue:
follow: "Seguindo"
mobile/views/components/sub-note-content.vue:
poll: "Enquetes"
mobile/views/components/ui.nav.vue:
timeline: "Linha do tempo"
mobile/views/pages/widgets.vue:
customization-tips: "Dicas de personalização"
mobile/views/pages/note.vue:
prev: "Nota anterior"
next: "Próxima nota"
mobile/views/pages/search.vue:
search: "Pesquisar"
mobile/views/pages/user.vue:
follows-you: "Te segue"
following: "Seguindo"
followers: "Seguidores"
notes: "Posts"
timeline: "Linha do tempo"
media: "Mídia"
mobile/views/pages/user/home.vue:
recent-notes: "Notas recentes"
images: "Imagens"
activity: "Atividade"
keywords: "Palavras chave"
domains: "Domínios"
followers-you-know: "Seguidores que você conhece"
last-used-at: "Ativo pela última vez"
mobile/views/pages/user/home.photos.vue:
no-photos: "Sem fotos"
deck/deck.user-column.vue:
follows-you: "Te segue"
following: "Seguindo"
followers: "Seguidores"
images: "Imagens"
timeline: "Linha do tempo"
docs:
edit-this-page-on-github-link: "Edite esta página no GitHub!"
dev/views/index.vue:
manage-apps: "Gerenciar aplicativos"
pages:
like: "Curtir"
blocks:
image: "Imagens"
post: "Formulário de publicação"
room:
furnitures:
moon: "Lua"
bin: "Lixo"
_lang_: "Português"

View File

@ -1,171 +1,2 @@
---
meta:
lang: "Русский язык"
common:
misskey: "Мы — ⭐ fediverse"
about-title: "Мы — ⭐ fediverse"
about: "Спасибо, что нашли Misskey. Misskey — это <b>децентрализованная платформа для микроблоггинга</b> родом с планеты Земля. Поскольку она существует внутри Fediverse (вселенной различных социальных платформ), она связана с другими платформами. Отдохните от шума большого города — и познакомьтесь с новым интернетом."
intro:
title: "Что такое Misskey?"
about: "Misskey - это <b>децентрализованный сервис микроблогинга</b> с открытым исходным кодом. Он имеет такие функции, как: навороченный, полностью настраиваемый пользовательский интерфейс, множество реакций на посты, бесплатное хранилище файлов с интегрированной системой управления и ещё куча передовых фишек. А ещё сетевая система под названием “Fediverse” позволяет нам общаться с пользователями других социальных сетей. Например, если ты что-нибудь запостишь, то твой пост будет отослан не только в Misskey, но ещё и mastodon. Просто представь, что планета посылает микроволны на другую планету для коммуникации."
features: "Особенности"
rich-contents: "Посты"
rich-contents-desc: "Просто выложи свою идею, актуальные темы и всё, что тебе хочется показать миру. Ты можешь декорировать свои слова, прикреплять свои любимые картинки, отправлять файлы с фильмами и создать голосование - это те вещи, которые ты можешь сделать с помощью Misskey!"
reaction: "Реакции"
reaction-desc: "あなたの気持ちを伝える最も簡単な方法です。Misskeyは、他のユーザーの投稿に様々なリアクションを付けることができます。いちどMisskeyのリアクション機能を体験してしまうと、もう「いいね」の概念しか存在しないSNSには戻れなくなるかもしれません。"
ui: "Интерфейс"
ui-desc: "Нет такого интерфейса, понравившегося всем. Поэтому у Misskey имеется пользовательский интерфейс, широко настраиваемый под ваши вкусы. Создай себе уникальную домашнюю страницу редактируя, подстраивая оформление ленты и размещая виджеты, которые тоже можно кастомизировать."
drive: "Хранилище файлов"
drive-desc: "Хотите запостить картинку, которую уже отправляли ранее? Хочется сортировать, переименовать и создать папку для ваших выложенных файлов? Тогда Misskey Drive - это лучшее решение для вас. Очень лёгкий способ делиться своими файлами онлайн."
outro: "Попробуйте будущие, уникальные для Misskey функции своими глазами! Если чувствуете, что это не в вашем вкусе, то попробуйте другие инстанции, ведь Misskey - это децентрализованная социальная сеть, так что ты можешь с лёгкостью найти себе товарищей. И наконец, GLHF!"
application-authorization: "Авторизация приложений"
close: "Закрыть"
do-not-copy-paste: "Пожалуйста, не вводите и не вставляйте сюда код. Аккаунту может угрожать опасность."
load-more: "Загрузить больше"
enter-password: "Пожалуйста, введите ваш пароль"
2fa: "Двухфакторная аутентификация"
customize-home: "Настройка домашней страницы"
featured-notes: "Рекомендуемые"
dark-mode: "Тёмная тема"
signin: "Войти"
signup: "Регистрация"
signout: "Выйти"
reload-to-apply-the-setting: "Вам необходимо перезагрузить страницу, чтобы применить настройки. Вы хотите перезагрузить сейчас?"
customization-tips:
title: "Советы по настройке"
gotit: "Понятно!"
notification:
file-uploaded: "Файл отправлен!"
message-from: "Сообщение от {}:"
reversi-invited: "Приглашён в игру"
reversi-invited-by: "Был приглашён {}:"
notified-by: "Был приглашён {}:"
reply-from: "Ответ от {}:"
quoted-by: "Цитировано {}:"
time:
unknown: "неизвестно"
future: "сейчас"
just_now: "сейчас"
seconds_ago: "{} секунд назад"
minutes_ago: "{} минут назад"
hours_ago: "{} часов назад"
days_ago: "{} дней назад"
weeks_ago: "{} недель назад"
months_ago: "{} месяцев назад"
years_ago: "{} лет назад"
month-and-day: "{day}.{month}"
trash: "Мусорное ведро"
drive: "Drive"
pages: "Страницы"
messaging: "Чат"
timeline: "Лента"
followers: "Подписчики"
favorites: "Избранное"
post-form:
reply: "Ответить"
create-poll: "Создать опрос"
weekday-short:
sunday: "Вс"
monday: "Пн"
tuesday: "Вт"
wednesday: "Ср"
thursday: "Чт"
friday: "Пт"
saturday: "Сб"
weekday:
sunday: "Воскресенье"
monday: "Понедельник"
tuesday: "Вторник"
wednesday: "Среда"
thursday: "Четверг"
friday: "Пятница"
saturday: "Суббота"
reactions:
like: "Нравится"
laugh: "Ха-Ха"
rip: "RIP"
do-not-use-in-production: "Эта сборка для разработчиков. Не используйте в продакшне."
error:
title: "Что-то пошло не так :("
retry: "Повторить"
reversi:
drawn: "Ничья"
my-turn: "Ваш ход"
opponent-turn: "Ход оппонента"
turn-of: "Ход {name}"
past-turn-of: "Ход {name}"
won: "{name} победил"
black: "Чёрный"
white: "Белый"
total: "Всего"
this-turn: "Ход {count}"
widgets:
analog-clock: "Аналоговые часы"
profile: "Профиль"
calendar: "Календарь"
timemachine: "Календарь (машина времени)"
activity: "Активность"
rss: "Ридер RSS"
memo: "Заметка"
trends: "Популярное"
photo-stream: "Фотопоток"
slideshow: "Слайдшоу"
version: "Версия"
notifications: "Уведомления"
users: "Рекомендованные пользователи"
polls: "Голосования"
server: "Информация о сервере"
hashtags: "Хэштеги"
dev: "Не удалось создать приложение. Пожалуйста, попробуйте ещё раз."
ai-chan-kawaii: "Ai-chan kawaii!"
auth/views/form.vue:
share-access: "Вы разрешаете <i>{name}</i> получить доступ к вашему аккаунту?"
common/views/components/games/reversi/reversi.index.vue:
game-state:
ended: "Завершено"
playing: "В процессе"
common/views/components/games/reversi/reversi.room.vue:
settings-of-the-game: "Настройки игры"
random: "Случайно"
black-or-white: "Чёрные/Белые"
black-is: "{} ходит чёрными"
rules: "Правила"
settings-of-the-bot: "Настройки бота"
this-game-is-started-soon: "Игра вот-вот начнётся"
waiting-for-other: "Ожидание оппонента"
cancel: "Отмена"
ready: "Готов"
common/views/components/connect-failed.vue:
title: "Невозможно подключиться к серверу"
common/views/components/cw-button.vue:
poll: "Голосования"
common/views/components/poll-editor.vue:
day: "Вс"
common/views/widgets/memo.vue:
title: "Заметка"
desktop/views/components/sub-note-content.vue:
poll: "Голосования"
admin/views/dashboard.vue:
drive: "Хранилище файлов"
admin/views/charts.vue:
drive: "Хранилище файлов"
desktop/views/pages/user/user.header.vue:
month: "Пн"
day: "Вс"
desktop/views/widgets/polls.vue:
title: "Голосования"
mobile/views/components/sub-note-content.vue:
poll: "Голосования"
mobile/views/pages/widgets.vue:
customization-tips: "Советы по настройке"
pages:
like: "Нравится"
script:
categories:
random: "Случайно"
blocks:
random: "Случайно"
room:
furnitures:
moon: "Луна"
bin: "Мусорное ведро"
_lang_: "Русский язык"

File diff suppressed because it is too large Load Diff

View File

@ -1,91 +1,2 @@
---
meta:
lang: "中文(繁体)"
common:
intro:
title: "什麽是 Misskey 呢?"
rich-contents: "發佈"
reaction: "回應"
drive: "雲端硬碟"
close: "關閉"
enter-password: "請輸入密碼"
2fa: "雙重身份驗證"
dark-mode: "夜間模式"
signup: "註冊"
signout: "登出"
notification:
reversi-invited: "您已被邀請加入壹場遊戲"
reversi-invited-by: "來自{}的邀請"
notified-by: "來自{}的邀請"
time:
future: "未來"
just_now: "剛剛"
drive: "雲端硬碟"
weekday:
sunday: "週日"
monday: "週一"
tuesday: "週二"
wednesday: "週三"
thursday: "週四"
friday: "週五"
saturday: "週六"
reactions:
like: "贊"
love: "喜歡"
congrats: "恭喜"
_settings:
password: "密碼"
font-size: "字體大小"
font-size-x-small: "小"
font-size-small: "較小"
deck-column-width-wide: "寬"
timeline: "時間軸"
common/views/components/connect-failed.troubleshooter.vue:
flush: "清除快取"
common/views/components/theme.vue:
light-themes: "淺色主題"
dark-themes: "深色主題"
install-a-theme: "安裝主題"
save-created-theme: "保存主題"
common/views/components/signin.vue:
signin-with-twitter: "用 Twitter 帳號登入"
signin-with-github: "用 GitHub 帳號登入"
signin-with-discord: "用 Discord 帳號登入"
login-failed: "登錄失敗。 請檢查用戶名和密碼。"
common/views/components/signup.vue:
invitation-code: "邀請碼"
username: "用戶名"
available: "可用"
too-long: "請不要超過20個字元"
password: "密碼"
password-placeholder: "建議至少8個字元"
common/views/components/stream-indicator.vue:
connecting: "正在連線"
reconnecting: "正在重新連線"
connected: "已建立連線"
common/views/components/integration-settings.vue:
disconnect: "中斷連線"
common/views/components/github-setting.vue:
reconnect: "重新連線"
disconnect: "中斷連線"
common/views/components/discord-setting.vue:
reconnect: "重新連線"
disconnect: "中斷連線"
common/views/components/language-settings.vue:
recommended: "推薦"
auto: "自動"
specify-language: "指定語言"
common/views/components/profile-editor.vue:
title: "個人資料"
name: "名稱"
birthday: "生日:"
privacy: "隱私"
admin/views/dashboard.vue:
drive: "雲端硬碟"
admin/views/charts.vue:
drive: "雲端硬碟"
pages:
like: "贊"
room:
furnitures:
moon: "月"
_lang_: "中文(繁体)"

View File

@ -0,0 +1,34 @@
import {MigrationInterface, QueryRunner} from "typeorm";
export class v121579267006611 implements MigrationInterface {
name = 'v121579267006611'
public async up(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`CREATE TABLE "announcement" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "text" character varying(8192) NOT NULL, "title" character varying(256) NOT NULL, "imageUrl" character varying(1024), CONSTRAINT "PK_e0ef0550174fd1099a308fd18a0" PRIMARY KEY ("id"))`, undefined);
await queryRunner.query(`CREATE INDEX "IDX_118ec703e596086fc4515acb39" ON "announcement" ("createdAt") `, undefined);
await queryRunner.query(`CREATE TABLE "announcement_read" ("id" character varying(32) NOT NULL, "userId" character varying(32) NOT NULL, "announcementId" character varying(32) NOT NULL, CONSTRAINT "PK_4b90ad1f42681d97b2683890c5e" PRIMARY KEY ("id"))`, undefined);
await queryRunner.query(`CREATE INDEX "IDX_8288151386172b8109f7239ab2" ON "announcement_read" ("userId") `, undefined);
await queryRunner.query(`CREATE INDEX "IDX_603a7b1e7aa0533c6c88e9bfaf" ON "announcement_read" ("announcementId") `, undefined);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_924fa71815cfa3941d003702a0" ON "announcement_read" ("userId", "announcementId") `, undefined);
await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "isVerified"`, undefined);
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "announcements"`, undefined);
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "enableEmojiReaction"`, undefined);
await queryRunner.query(`ALTER TABLE "announcement_read" ADD CONSTRAINT "FK_8288151386172b8109f7239ab28" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined);
await queryRunner.query(`ALTER TABLE "announcement_read" ADD CONSTRAINT "FK_603a7b1e7aa0533c6c88e9bfafe" FOREIGN KEY ("announcementId") REFERENCES "announcement"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined);
}
public async down(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`ALTER TABLE "announcement_read" DROP CONSTRAINT "FK_603a7b1e7aa0533c6c88e9bfafe"`, undefined);
await queryRunner.query(`ALTER TABLE "announcement_read" DROP CONSTRAINT "FK_8288151386172b8109f7239ab28"`, undefined);
await queryRunner.query(`ALTER TABLE "meta" ADD "enableEmojiReaction" boolean NOT NULL DEFAULT true`, undefined);
await queryRunner.query(`ALTER TABLE "meta" ADD "announcements" jsonb NOT NULL DEFAULT '[]'`, undefined);
await queryRunner.query(`ALTER TABLE "user" ADD "isVerified" boolean NOT NULL DEFAULT false`, undefined);
await queryRunner.query(`DROP INDEX "IDX_924fa71815cfa3941d003702a0"`, undefined);
await queryRunner.query(`DROP INDEX "IDX_603a7b1e7aa0533c6c88e9bfaf"`, undefined);
await queryRunner.query(`DROP INDEX "IDX_8288151386172b8109f7239ab2"`, undefined);
await queryRunner.query(`DROP TABLE "announcement_read"`, undefined);
await queryRunner.query(`DROP INDEX "IDX_118ec703e596086fc4515acb39"`, undefined);
await queryRunner.query(`DROP TABLE "announcement"`, undefined);
}
}

View File

@ -0,0 +1,14 @@
import {MigrationInterface, QueryRunner} from "typeorm";
export class v1221579270193251 implements MigrationInterface {
name = 'v1221579270193251'
public async up(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`ALTER TABLE "announcement_read" ADD "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL`, undefined);
}
public async down(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`ALTER TABLE "announcement_read" DROP COLUMN "createdAt"`, undefined);
}
}

View File

@ -0,0 +1,14 @@
import {MigrationInterface, QueryRunner} from "typeorm";
export class v1231579282808087 implements MigrationInterface {
name = 'v1231579282808087'
public async up(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`ALTER TABLE "announcement" ADD "updatedAt" TIMESTAMP WITH TIME ZONE`, undefined);
}
public async down(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`ALTER TABLE "announcement" DROP COLUMN "updatedAt"`, undefined);
}
}

View File

@ -0,0 +1,16 @@
import {MigrationInterface, QueryRunner} from "typeorm";
export class v1241579544426412 implements MigrationInterface {
name = 'v1241579544426412'
public async up(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`ALTER TABLE "notification" ADD "followRequestId" character varying(32)`, undefined);
await queryRunner.query(`ALTER TABLE "notification" ADD CONSTRAINT "FK_bd7fab507621e635b32cd31892c" FOREIGN KEY ("followRequestId") REFERENCES "follow_request"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined);
}
public async down(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`ALTER TABLE "notification" DROP CONSTRAINT "FK_bd7fab507621e635b32cd31892c"`, undefined);
await queryRunner.query(`ALTER TABLE "notification" DROP COLUMN "followRequestId"`, undefined);
}
}

View File

@ -0,0 +1,54 @@
import {MigrationInterface, QueryRunner} from "typeorm";
export class v1251579977526288 implements MigrationInterface {
name = 'v1251579977526288'
public async up(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`CREATE TABLE "clip" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "name" character varying(128) NOT NULL, "isPublic" boolean NOT NULL DEFAULT false, CONSTRAINT "PK_f0685dac8d4dd056d7255670b75" PRIMARY KEY ("id"))`, undefined);
await queryRunner.query(`CREATE INDEX "IDX_2b5ec6c574d6802c94c80313fb" ON "clip" ("userId") `, undefined);
await queryRunner.query(`CREATE TABLE "clip_note" ("id" character varying(32) NOT NULL, "noteId" character varying(32) NOT NULL, "clipId" character varying(32) NOT NULL, CONSTRAINT "PK_e94cda2f40a99b57e032a1a738b" PRIMARY KEY ("id"))`, undefined);
await queryRunner.query(`CREATE INDEX "IDX_a012eaf5c87c65da1deb5fdbfa" ON "clip_note" ("noteId") `, undefined);
await queryRunner.query(`CREATE INDEX "IDX_ebe99317bbbe9968a0c6f579ad" ON "clip_note" ("clipId") `, undefined);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_6fc0ec357d55a18646262fdfff" ON "clip_note" ("noteId", "clipId") `, undefined);
await queryRunner.query(`CREATE TYPE "antenna_src_enum" AS ENUM('home', 'all', 'list')`, undefined);
await queryRunner.query(`CREATE TABLE "antenna" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "name" character varying(128) NOT NULL, "src" "antenna_src_enum" NOT NULL, "userListId" character varying(32), "keywords" jsonb NOT NULL DEFAULT '[]', "withFile" boolean NOT NULL, "expression" character varying(2048), "notify" boolean NOT NULL, "hasNewNote" boolean NOT NULL DEFAULT false, CONSTRAINT "PK_c170b99775e1dccca947c9f2d5f" PRIMARY KEY ("id"))`, undefined);
await queryRunner.query(`CREATE INDEX "IDX_6446c571a0e8d0f05f01c78909" ON "antenna" ("userId") `, undefined);
await queryRunner.query(`CREATE TABLE "antenna_note" ("id" character varying(32) NOT NULL, "noteId" character varying(32) NOT NULL, "antennaId" character varying(32) NOT NULL, CONSTRAINT "PK_fb28d94d0989a3872df19fd6ef8" PRIMARY KEY ("id"))`, undefined);
await queryRunner.query(`CREATE INDEX "IDX_bd0397be22147e17210940e125" ON "antenna_note" ("noteId") `, undefined);
await queryRunner.query(`CREATE INDEX "IDX_0d775946662d2575dfd2068a5f" ON "antenna_note" ("antennaId") `, undefined);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_335a0bf3f904406f9ef3dd51c2" ON "antenna_note" ("noteId", "antennaId") `, undefined);
await queryRunner.query(`ALTER TABLE "note" DROP COLUMN "geo"`, undefined);
await queryRunner.query(`ALTER TABLE "clip" ADD CONSTRAINT "FK_2b5ec6c574d6802c94c80313fb2" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined);
await queryRunner.query(`ALTER TABLE "clip_note" ADD CONSTRAINT "FK_a012eaf5c87c65da1deb5fdbfa3" FOREIGN KEY ("noteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined);
await queryRunner.query(`ALTER TABLE "clip_note" ADD CONSTRAINT "FK_ebe99317bbbe9968a0c6f579adf" FOREIGN KEY ("clipId") REFERENCES "clip"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined);
await queryRunner.query(`ALTER TABLE "antenna" ADD CONSTRAINT "FK_6446c571a0e8d0f05f01c789096" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined);
await queryRunner.query(`ALTER TABLE "antenna" ADD CONSTRAINT "FK_709d7d32053d0dd7620f678eeb9" FOREIGN KEY ("userListId") REFERENCES "user_list"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined);
await queryRunner.query(`ALTER TABLE "antenna_note" ADD CONSTRAINT "FK_bd0397be22147e17210940e125b" FOREIGN KEY ("noteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined);
await queryRunner.query(`ALTER TABLE "antenna_note" ADD CONSTRAINT "FK_0d775946662d2575dfd2068a5f5" FOREIGN KEY ("antennaId") REFERENCES "antenna"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined);
}
public async down(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`ALTER TABLE "antenna_note" DROP CONSTRAINT "FK_0d775946662d2575dfd2068a5f5"`, undefined);
await queryRunner.query(`ALTER TABLE "antenna_note" DROP CONSTRAINT "FK_bd0397be22147e17210940e125b"`, undefined);
await queryRunner.query(`ALTER TABLE "antenna" DROP CONSTRAINT "FK_709d7d32053d0dd7620f678eeb9"`, undefined);
await queryRunner.query(`ALTER TABLE "antenna" DROP CONSTRAINT "FK_6446c571a0e8d0f05f01c789096"`, undefined);
await queryRunner.query(`ALTER TABLE "clip_note" DROP CONSTRAINT "FK_ebe99317bbbe9968a0c6f579adf"`, undefined);
await queryRunner.query(`ALTER TABLE "clip_note" DROP CONSTRAINT "FK_a012eaf5c87c65da1deb5fdbfa3"`, undefined);
await queryRunner.query(`ALTER TABLE "clip" DROP CONSTRAINT "FK_2b5ec6c574d6802c94c80313fb2"`, undefined);
await queryRunner.query(`ALTER TABLE "note" ADD "geo" jsonb`, undefined);
await queryRunner.query(`DROP INDEX "IDX_335a0bf3f904406f9ef3dd51c2"`, undefined);
await queryRunner.query(`DROP INDEX "IDX_0d775946662d2575dfd2068a5f"`, undefined);
await queryRunner.query(`DROP INDEX "IDX_bd0397be22147e17210940e125"`, undefined);
await queryRunner.query(`DROP TABLE "antenna_note"`, undefined);
await queryRunner.query(`DROP INDEX "IDX_6446c571a0e8d0f05f01c78909"`, undefined);
await queryRunner.query(`DROP TABLE "antenna"`, undefined);
await queryRunner.query(`DROP TYPE "antenna_src_enum"`, undefined);
await queryRunner.query(`DROP INDEX "IDX_6fc0ec357d55a18646262fdfff"`, undefined);
await queryRunner.query(`DROP INDEX "IDX_ebe99317bbbe9968a0c6f579ad"`, undefined);
await queryRunner.query(`DROP INDEX "IDX_a012eaf5c87c65da1deb5fdbfa"`, undefined);
await queryRunner.query(`DROP TABLE "clip_note"`, undefined);
await queryRunner.query(`DROP INDEX "IDX_2b5ec6c574d6802c94c80313fb"`, undefined);
await queryRunner.query(`DROP TABLE "clip"`, undefined);
}
}

View File

@ -0,0 +1,18 @@
import {MigrationInterface, QueryRunner} from "typeorm";
export class v1261579993013959 implements MigrationInterface {
name = 'v1261579993013959'
public async up(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`ALTER TABLE "antenna" DROP COLUMN "hasNewNote"`, undefined);
await queryRunner.query(`ALTER TABLE "antenna_note" ADD "read" boolean NOT NULL DEFAULT false`, undefined);
await queryRunner.query(`CREATE INDEX "IDX_9937ea48d7ae97ffb4f3f063a4" ON "antenna_note" ("read") `, undefined);
}
public async down(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`DROP INDEX "IDX_9937ea48d7ae97ffb4f3f063a4"`, undefined);
await queryRunner.query(`ALTER TABLE "antenna_note" DROP COLUMN "read"`, undefined);
await queryRunner.query(`ALTER TABLE "antenna" ADD "hasNewNote" boolean NOT NULL DEFAULT false`, undefined);
}
}

View File

@ -0,0 +1,24 @@
import {MigrationInterface, QueryRunner} from "typeorm";
export class v1271580069531114 implements MigrationInterface {
name = 'v1271580069531114'
public async up(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`ALTER TABLE "antenna" ADD "users" character varying(1024) array NOT NULL DEFAULT '{}'::varchar[]`, undefined);
await queryRunner.query(`ALTER TABLE "antenna" ADD "caseSensitive" boolean NOT NULL DEFAULT false`, undefined);
await queryRunner.query(`ALTER TYPE "public"."antenna_src_enum" RENAME TO "antenna_src_enum_old"`, undefined);
await queryRunner.query(`CREATE TYPE "antenna_src_enum" AS ENUM('home', 'all', 'users', 'list')`, undefined);
await queryRunner.query(`ALTER TABLE "antenna" ALTER COLUMN "src" TYPE "antenna_src_enum" USING "src"::"text"::"antenna_src_enum"`, undefined);
await queryRunner.query(`DROP TYPE "antenna_src_enum_old"`, undefined);
}
public async down(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`CREATE TYPE "antenna_src_enum_old" AS ENUM('home', 'all', 'list')`, undefined);
await queryRunner.query(`ALTER TABLE "antenna" ALTER COLUMN "src" TYPE "antenna_src_enum_old" USING "src"::"text"::"antenna_src_enum_old"`, undefined);
await queryRunner.query(`DROP TYPE "antenna_src_enum"`, undefined);
await queryRunner.query(`ALTER TYPE "antenna_src_enum_old" RENAME TO "antenna_src_enum"`, undefined);
await queryRunner.query(`ALTER TABLE "antenna" DROP COLUMN "caseSensitive"`, undefined);
await queryRunner.query(`ALTER TABLE "antenna" DROP COLUMN "users"`, undefined);
}
}

View File

@ -0,0 +1,16 @@
import {MigrationInterface, QueryRunner} from "typeorm";
export class v1281580148575182 implements MigrationInterface {
name = 'v1281580148575182'
public async up(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`ALTER TABLE "note" DROP CONSTRAINT "FK_ec5c201576192ba8904c345c5cc"`, undefined);
await queryRunner.query(`ALTER TABLE "note" DROP COLUMN "appId"`, undefined);
}
public async down(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`ALTER TABLE "note" ADD "appId" character varying(32)`, undefined);
await queryRunner.query(`ALTER TABLE "note" ADD CONSTRAINT "FK_ec5c201576192ba8904c345c5cc" FOREIGN KEY ("appId") REFERENCES "app"("id") ON DELETE SET NULL ON UPDATE NO ACTION`, undefined);
}
}

View File

@ -0,0 +1,14 @@
import {MigrationInterface, QueryRunner} from "typeorm";
export class v1291580154400017 implements MigrationInterface {
name = 'v1291580154400017'
public async up(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`ALTER TABLE "antenna" ADD "withReplies" boolean NOT NULL DEFAULT false`, undefined);
}
public async down(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`ALTER TABLE "antenna" DROP COLUMN "withReplies"`, undefined);
}
}

View File

@ -0,0 +1,19 @@
import {MigrationInterface, QueryRunner} from "typeorm";
export class v12101580276619901 implements MigrationInterface {
name = 'v12101580276619901'
public async up(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`TRUNCATE TABLE "notification"`, undefined);
await queryRunner.query(`ALTER TABLE "notification" DROP COLUMN "type"`, undefined);
await queryRunner.query(`CREATE TYPE "notification_type_enum" AS ENUM('follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollVote', 'receiveFollowRequest', 'followRequestAccepted')`, undefined);
await queryRunner.query(`ALTER TABLE "notification" ADD "type" "notification_type_enum" NOT NULL`, undefined);
}
public async down(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`ALTER TABLE "notification" DROP COLUMN "type"`, undefined);
await queryRunner.query(`DROP TYPE "notification_type_enum"`, undefined);
await queryRunner.query(`ALTER TABLE "notification" ADD "type" character varying(32) NOT NULL`, undefined);
}
}

View File

@ -0,0 +1,18 @@
import {MigrationInterface, QueryRunner} from "typeorm";
export class v12111580331224276 implements MigrationInterface {
name = 'v12111580331224276'
public async up(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`ALTER TABLE "instance" DROP COLUMN "isMarkedAsClosed"`, undefined);
await queryRunner.query(`ALTER TABLE "instance" ADD "isSuspended" boolean NOT NULL DEFAULT false`, undefined);
await queryRunner.query(`CREATE INDEX "IDX_34500da2e38ac393f7bb6b299c" ON "instance" ("isSuspended") `, undefined);
}
public async down(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`DROP INDEX "IDX_34500da2e38ac393f7bb6b299c"`, undefined);
await queryRunner.query(`ALTER TABLE "instance" DROP COLUMN "isSuspended"`, undefined);
await queryRunner.query(`ALTER TABLE "instance" ADD "isMarkedAsClosed" boolean NOT NULL DEFAULT false`, undefined);
}
}

View File

@ -0,0 +1,46 @@
import {MigrationInterface, QueryRunner} from "typeorm";
export class v12121580508795118 implements MigrationInterface {
name = 'v12121580508795118'
public async up(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "twitter"`, undefined);
await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "twitterAccessToken"`, undefined);
await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "twitterAccessTokenSecret"`, undefined);
await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "twitterUserId"`, undefined);
await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "twitterScreenName"`, undefined);
await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "github"`, undefined);
await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "githubAccessToken"`, undefined);
await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "githubId"`, undefined);
await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "githubLogin"`, undefined);
await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "discord"`, undefined);
await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "discordAccessToken"`, undefined);
await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "discordRefreshToken"`, undefined);
await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "discordExpiresDate"`, undefined);
await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "discordId"`, undefined);
await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "discordUsername"`, undefined);
await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "discordDiscriminator"`, undefined);
await queryRunner.query(`ALTER TABLE "user_profile" ADD "integrations" jsonb NOT NULL DEFAULT '{}'`, undefined);
}
public async down(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "integrations"`, undefined);
await queryRunner.query(`ALTER TABLE "user_profile" ADD "discordDiscriminator" character varying(64) DEFAULT NULL`, undefined);
await queryRunner.query(`ALTER TABLE "user_profile" ADD "discordUsername" character varying(64) DEFAULT NULL`, undefined);
await queryRunner.query(`ALTER TABLE "user_profile" ADD "discordId" character varying(64) DEFAULT NULL`, undefined);
await queryRunner.query(`ALTER TABLE "user_profile" ADD "discordExpiresDate" character varying(64)`, undefined);
await queryRunner.query(`ALTER TABLE "user_profile" ADD "discordRefreshToken" character varying(64) DEFAULT NULL`, undefined);
await queryRunner.query(`ALTER TABLE "user_profile" ADD "discordAccessToken" character varying(64) DEFAULT NULL`, undefined);
await queryRunner.query(`ALTER TABLE "user_profile" ADD "discord" boolean NOT NULL DEFAULT false`, undefined);
await queryRunner.query(`ALTER TABLE "user_profile" ADD "githubLogin" character varying(64) DEFAULT NULL`, undefined);
await queryRunner.query(`ALTER TABLE "user_profile" ADD "githubId" character varying(64)`, undefined);
await queryRunner.query(`ALTER TABLE "user_profile" ADD "githubAccessToken" character varying(64) DEFAULT NULL`, undefined);
await queryRunner.query(`ALTER TABLE "user_profile" ADD "github" boolean NOT NULL DEFAULT false`, undefined);
await queryRunner.query(`ALTER TABLE "user_profile" ADD "twitterScreenName" character varying(64) DEFAULT NULL`, undefined);
await queryRunner.query(`ALTER TABLE "user_profile" ADD "twitterUserId" character varying(64) DEFAULT NULL`, undefined);
await queryRunner.query(`ALTER TABLE "user_profile" ADD "twitterAccessTokenSecret" character varying(64) DEFAULT NULL`, undefined);
await queryRunner.query(`ALTER TABLE "user_profile" ADD "twitterAccessToken" character varying(64) DEFAULT NULL`, undefined);
await queryRunner.query(`ALTER TABLE "user_profile" ADD "twitter" boolean NOT NULL DEFAULT false`, undefined);
}
}

View File

@ -0,0 +1,14 @@
import {MigrationInterface, QueryRunner} from "typeorm";
export class v12131580543501339 implements MigrationInterface {
name = 'v12131580543501339'
public async up(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`CREATE INDEX "IDX_NOTE_TAGS" ON "note" USING gin ("tags")`, undefined);
}
public async down(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`DROP INDEX "IDX_NOTE_TAGS"`, undefined);
}
}

View File

@ -0,0 +1,20 @@
import {MigrationInterface, QueryRunner} from "typeorm";
export class v12141580864313253 implements MigrationInterface {
name = 'v12141580864313253'
public async up(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`ALTER TABLE "meta" RENAME COLUMN "proxyAccount" TO "proxyAccountId"`, undefined);
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "proxyAccountId"`, undefined);
await queryRunner.query(`ALTER TABLE "meta" ADD "proxyAccountId" character varying(32)`, undefined);
await queryRunner.query(`ALTER TABLE "meta" ADD CONSTRAINT "FK_ab1bc0c1e209daa77b8e8d212ad" FOREIGN KEY ("proxyAccountId") REFERENCES "user"("id") ON DELETE SET NULL ON UPDATE NO ACTION`, undefined);
}
public async down(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`ALTER TABLE "meta" DROP CONSTRAINT "FK_ab1bc0c1e209daa77b8e8d212ad"`, undefined);
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "proxyAccountId"`, undefined);
await queryRunner.query(`ALTER TABLE "meta" ADD "proxyAccountId" character varying(128)`, undefined);
await queryRunner.query(`ALTER TABLE "meta" RENAME COLUMN "proxyAccountId" TO "proxyAccount"`, undefined);
}
}

View File

@ -0,0 +1,38 @@
import {MigrationInterface, QueryRunner} from "typeorm";
export class userGroupInvitation1581526429287 implements MigrationInterface {
name = 'userGroupInvitation1581526429287'
public async up(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`CREATE TABLE "user_group_invitation" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "userGroupId" character varying(32) NOT NULL, CONSTRAINT "PK_160c63ec02bf23f6a5c5e8140d6" PRIMARY KEY ("id"))`, undefined);
await queryRunner.query(`CREATE INDEX "IDX_bfbc6305547539369fe73eb144" ON "user_group_invitation" ("userId") `, undefined);
await queryRunner.query(`CREATE INDEX "IDX_5cc8c468090e129857e9fecce5" ON "user_group_invitation" ("userGroupId") `, undefined);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_e9793f65f504e5a31fbaedbf2f" ON "user_group_invitation" ("userId", "userGroupId") `, undefined);
await queryRunner.query(`ALTER TABLE "notification" ADD "userGroupInvitationId" character varying(32)`, undefined);
await queryRunner.query(`ALTER TYPE "public"."notification_type_enum" RENAME TO "notification_type_enum_old"`, undefined);
await queryRunner.query(`CREATE TYPE "notification_type_enum" AS ENUM('follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollVote', 'receiveFollowRequest', 'followRequestAccepted', 'groupInvited')`, undefined);
await queryRunner.query(`ALTER TABLE "notification" ALTER COLUMN "type" TYPE "notification_type_enum" USING "type"::"text"::"notification_type_enum"`, undefined);
await queryRunner.query(`DROP TYPE "notification_type_enum_old"`, undefined);
await queryRunner.query(`COMMENT ON COLUMN "notification"."type" IS 'The type of the Notification.'`, undefined);
await queryRunner.query(`ALTER TABLE "user_group_invitation" ADD CONSTRAINT "FK_bfbc6305547539369fe73eb144a" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined);
await queryRunner.query(`ALTER TABLE "user_group_invitation" ADD CONSTRAINT "FK_5cc8c468090e129857e9fecce5a" FOREIGN KEY ("userGroupId") REFERENCES "user_group"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined);
await queryRunner.query(`ALTER TABLE "notification" ADD CONSTRAINT "FK_8fe87814e978053a53b1beb7e98" FOREIGN KEY ("userGroupInvitationId") REFERENCES "user_group_invitation"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined);
}
public async down(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`ALTER TABLE "notification" DROP CONSTRAINT "FK_8fe87814e978053a53b1beb7e98"`, undefined);
await queryRunner.query(`ALTER TABLE "user_group_invitation" DROP CONSTRAINT "FK_5cc8c468090e129857e9fecce5a"`, undefined);
await queryRunner.query(`ALTER TABLE "user_group_invitation" DROP CONSTRAINT "FK_bfbc6305547539369fe73eb144a"`, undefined);
await queryRunner.query(`COMMENT ON COLUMN "notification"."type" IS ''`, undefined);
await queryRunner.query(`CREATE TYPE "notification_type_enum_old" AS ENUM('follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollVote', 'receiveFollowRequest', 'followRequestAccepted')`, undefined);
await queryRunner.query(`ALTER TABLE "notification" ALTER COLUMN "type" TYPE "notification_type_enum_old" USING "type"::"text"::"notification_type_enum_old"`, undefined);
await queryRunner.query(`DROP TYPE "notification_type_enum"`, undefined);
await queryRunner.query(`ALTER TYPE "notification_type_enum_old" RENAME TO "notification_type_enum"`, undefined);
await queryRunner.query(`ALTER TABLE "notification" DROP COLUMN "userGroupInvitationId"`, undefined);
await queryRunner.query(`DROP INDEX "IDX_e9793f65f504e5a31fbaedbf2f"`, undefined);
await queryRunner.query(`DROP INDEX "IDX_5cc8c468090e129857e9fecce5"`, undefined);
await queryRunner.query(`DROP INDEX "IDX_bfbc6305547539369fe73eb144"`, undefined);
await queryRunner.query(`DROP TABLE "user_group_invitation"`, undefined);
}
}

View File

@ -0,0 +1,28 @@
import {MigrationInterface, QueryRunner} from "typeorm";
export class userGroupAntenna1581695816408 implements MigrationInterface {
name = 'userGroupAntenna1581695816408'
public async up(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`ALTER TABLE "antenna" ADD "userGroupJoiningId" character varying(32)`, undefined);
await queryRunner.query(`ALTER TYPE "public"."antenna_src_enum" RENAME TO "antenna_src_enum_old"`, undefined);
await queryRunner.query(`CREATE TYPE "antenna_src_enum" AS ENUM('home', 'all', 'users', 'list', 'group')`, undefined);
await queryRunner.query(`ALTER TABLE "antenna" ALTER COLUMN "src" TYPE "antenna_src_enum" USING "src"::"text"::"antenna_src_enum"`, undefined);
await queryRunner.query(`DROP TYPE "antenna_src_enum_old"`, undefined);
await queryRunner.query(`ALTER TABLE "antenna" DROP COLUMN "users"`, undefined);
await queryRunner.query(`ALTER TABLE "antenna" ADD "users" character varying(1024) array NOT NULL DEFAULT '{}'::varchar[]`, undefined);
await queryRunner.query(`ALTER TABLE "antenna" ADD CONSTRAINT "FK_ccbf5a8c0be4511133dcc50ddeb" FOREIGN KEY ("userGroupJoiningId") REFERENCES "user_group_joining"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined);
}
public async down(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`ALTER TABLE "antenna" DROP CONSTRAINT "FK_ccbf5a8c0be4511133dcc50ddeb"`, undefined);
await queryRunner.query(`ALTER TABLE "antenna" DROP COLUMN "users"`, undefined);
await queryRunner.query(`ALTER TABLE "antenna" ADD "users" character varying array NOT NULL DEFAULT '{}'`, undefined);
await queryRunner.query(`CREATE TYPE "antenna_src_enum_old" AS ENUM('home', 'all', 'users', 'list')`, undefined);
await queryRunner.query(`ALTER TABLE "antenna" ALTER COLUMN "src" TYPE "antenna_src_enum_old" USING "src"::"text"::"antenna_src_enum_old"`, undefined);
await queryRunner.query(`DROP TYPE "antenna_src_enum"`, undefined);
await queryRunner.query(`ALTER TYPE "antenna_src_enum_old" RENAME TO "antenna_src_enum"`, undefined);
await queryRunner.query(`ALTER TABLE "antenna" DROP COLUMN "userGroupJoiningId"`, undefined);
}
}

View File

@ -0,0 +1,14 @@
import {MigrationInterface, QueryRunner} from "typeorm";
export class driveUserFolderIdIndex1581708415836 implements MigrationInterface {
name = 'driveUserFolderIdIndex1581708415836'
public async up(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`CREATE INDEX "IDX_55720b33a61a7c806a8215b825" ON "drive_file" ("userId", "folderId", "id") `, undefined);
}
public async down(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`DROP INDEX "IDX_55720b33a61a7c806a8215b825"`, undefined);
}
}

View File

@ -0,0 +1,28 @@
import {MigrationInterface, QueryRunner} from "typeorm";
export class promo1581979837262 implements MigrationInterface {
name = 'promo1581979837262'
public async up(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`CREATE TABLE "promo_note" ("noteId" character varying(32) NOT NULL, "expiresAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, CONSTRAINT "REL_e263909ca4fe5d57f8d4230dd5" UNIQUE ("noteId"), CONSTRAINT "PK_e263909ca4fe5d57f8d4230dd5c" PRIMARY KEY ("noteId"))`, undefined);
await queryRunner.query(`CREATE INDEX "IDX_83f0862e9bae44af52ced7099e" ON "promo_note" ("userId") `, undefined);
await queryRunner.query(`CREATE TABLE "promo_read" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "noteId" character varying(32) NOT NULL, CONSTRAINT "PK_61917c1541002422b703318b7c9" PRIMARY KEY ("id"))`, undefined);
await queryRunner.query(`CREATE INDEX "IDX_9657d55550c3d37bfafaf7d4b0" ON "promo_read" ("userId") `, undefined);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_2882b8a1a07c7d281a98b6db16" ON "promo_read" ("userId", "noteId") `, undefined);
await queryRunner.query(`ALTER TABLE "promo_note" ADD CONSTRAINT "FK_e263909ca4fe5d57f8d4230dd5c" FOREIGN KEY ("noteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined);
await queryRunner.query(`ALTER TABLE "promo_read" ADD CONSTRAINT "FK_9657d55550c3d37bfafaf7d4b05" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined);
await queryRunner.query(`ALTER TABLE "promo_read" ADD CONSTRAINT "FK_a46a1a603ecee695d7db26da5f4" FOREIGN KEY ("noteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined);
}
public async down(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`ALTER TABLE "promo_read" DROP CONSTRAINT "FK_a46a1a603ecee695d7db26da5f4"`, undefined);
await queryRunner.query(`ALTER TABLE "promo_read" DROP CONSTRAINT "FK_9657d55550c3d37bfafaf7d4b05"`, undefined);
await queryRunner.query(`ALTER TABLE "promo_note" DROP CONSTRAINT "FK_e263909ca4fe5d57f8d4230dd5c"`, undefined);
await queryRunner.query(`DROP INDEX "IDX_2882b8a1a07c7d281a98b6db16"`, undefined);
await queryRunner.query(`DROP INDEX "IDX_9657d55550c3d37bfafaf7d4b0"`, undefined);
await queryRunner.query(`DROP TABLE "promo_read"`, undefined);
await queryRunner.query(`DROP INDEX "IDX_83f0862e9bae44af52ced7099e"`, undefined);
await queryRunner.query(`DROP TABLE "promo_note"`, undefined);
}
}

View File

@ -0,0 +1,14 @@
import {MigrationInterface, QueryRunner} from "typeorm";
export class featuredInjecttion1582019042083 implements MigrationInterface {
name = 'featuredInjecttion1582019042083'
public async up(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`ALTER TABLE "user_profile" ADD "injectFeaturedNote" boolean NOT NULL DEFAULT true`, undefined);
}
public async down(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "injectFeaturedNote"`, undefined);
}
}

View File

@ -1,8 +1,8 @@
{
"name": "misskey",
"author": "syuilo <i@syuilo.com>",
"version": "11.37.0",
"codename": "daybreak",
"author": "syuilo <syuilotan@yahoo.co.jp>",
"version": "12.14.0",
"codename": "indigo",
"repository": {
"type": "git",
"url": "https://github.com/syuilo/misskey.git"
@ -22,7 +22,7 @@
"clean": "gulp clean",
"cleanall": "gulp cleanall",
"lint": "gulp lint",
"test": "gulp test",
"test": "cross-env TS_NODE_FILES=true gulp test",
"format": "gulp format"
},
"resolutions": {
@ -30,29 +30,31 @@
"lodash": "^4.17.13"
},
"dependencies": {
"@elastic/elasticsearch": "7.5.0",
"@fortawesome/fontawesome-svg-core": "1.2.26",
"@fortawesome/free-brands-svg-icons": "5.12.0",
"@fortawesome/free-regular-svg-icons": "5.12.0",
"@fortawesome/free-solid-svg-icons": "5.12.0",
"@elastic/elasticsearch": "7.6.0",
"@fortawesome/fontawesome-svg-core": "1.2.27",
"@fortawesome/free-brands-svg-icons": "5.12.1",
"@fortawesome/free-regular-svg-icons": "5.12.1",
"@fortawesome/free-solid-svg-icons": "5.12.1",
"@fortawesome/vue-fontawesome": "0.1.9",
"@juggle/resize-observer": "3.0.2",
"@koa/cors": "3.0.0",
"@koa/multer": "2.0.2",
"@koa/router": "8.0.5",
"@koa/router": "8.0.8",
"@types/bcryptjs": "2.4.2",
"@types/bull": "3.10.6",
"@types/bull": "3.12.0",
"@types/cbor": "5.0.0",
"@types/dateformat": "3.0.1",
"@types/double-ended-queue": "2.1.1",
"@types/glob": "7.1.1",
"@types/gulp": "4.0.6",
"@types/gulp-mocha": "0.0.32",
"@types/gulp-rename": "0.0.33",
"@types/gulp-replace": "0.0.31",
"@types/is-url": "1.2.28",
"@types/js-yaml": "3.12.1",
"@types/js-yaml": "3.12.2",
"@types/jsdom": "12.2.4",
"@types/katex": "0.11.0",
"@types/koa": "2.11.0",
"@types/koa": "2.11.1",
"@types/koa-bodyparser": "4.3.0",
"@types/koa-compress": "2.0.9",
"@types/koa-cors": "0.0.0",
@ -61,62 +63,62 @@
"@types/koa-mount": "4.0.0",
"@types/koa-send": "4.1.2",
"@types/koa-views": "2.0.4",
"@types/koa__cors": "3.0.0",
"@types/koa__cors": "3.0.1",
"@types/koa__multer": "2.0.1",
"@types/koa__router": "8.0.2",
"@types/lolex": "5.1.0",
"@types/mocha": "5.2.7",
"@types/node": "13.1.4",
"@types/markdown-it": "0.0.9",
"@types/mocha": "7.0.1",
"@types/node": "13.7.1",
"@types/nodemailer": "6.4.0",
"@types/nprogress": "0.2.0",
"@types/oauth": "0.9.1",
"@types/parse5": "5.0.2",
"@types/parsimmon": "1.10.0",
"@types/parsimmon": "1.10.1",
"@types/portscanner": "2.1.0",
"@types/pug": "2.0.4",
"@types/qrcode": "1.3.4",
"@types/random-seed": "0.3.3",
"@types/ratelimiter": "2.1.28",
"@types/redis": "2.8.14",
"@types/redis": "2.8.15",
"@types/rename": "1.0.1",
"@types/request": "2.48.4",
"@types/request-promise-native": "1.0.17",
"@types/request-stats": "3.0.0",
"@types/rimraf": "2.0.3",
"@types/seedrandom": "2.4.28",
"@types/sharp": "0.23.1",
"@types/sharp": "0.24.0",
"@types/showdown": "1.9.3",
"@types/speakeasy": "2.0.5",
"@types/systeminformation": "3.54.1",
"@types/tinycolor2": "1.4.2",
"@types/tmp": "0.1.0",
"@types/uuid": "3.4.6",
"@types/uuid": "3.4.7",
"@types/web-push": "3.3.0",
"@types/webpack": "4.41.1",
"@types/webpack": "4.41.6",
"@types/webpack-stream": "3.2.10",
"@types/websocket": "1.0.0",
"@types/ws": "6.0.4",
"@typescript-eslint/parser": "2.15.0",
"@types/ws": "7.2.1",
"@typescript-eslint/parser": "2.19.2",
"agentkeepalive": "4.1.0",
"animejs": "3.1.0",
"apexcharts": "3.12.0",
"apexcharts": "3.15.6",
"autobind-decorator": "2.4.0",
"autosize": "4.0.2",
"autwh": "0.1.0",
"aws-sdk": "2.598.0",
"aws-sdk": "2.617.0",
"bcryptjs": "2.4.3",
"bootstrap": "4.4.1",
"bootstrap-vue": "2.1.0",
"bull": "3.12.1",
"cafy": "15.2.1",
"cbor": "5.0.1",
"chai": "4.2.0",
"chalk": "3.0.0",
"chart.js": "2.9.3",
"cli-highlight": "2.1.4",
"commander": "4.1.0",
"commander": "4.1.1",
"content-disposition": "0.5.3",
"crc-32": "1.2.0",
"css-loader": "3.4.1",
"css-loader": "3.4.2",
"cssnano": "4.1.10",
"dateformat": "3.0.3",
"diskusage": "1.1.3",
@ -125,27 +127,29 @@
"eslint-plugin-vue": "6.1.2",
"eventemitter3": "4.0.0",
"feed": "4.1.0",
"file-type": "13.0.1",
"fibers": "4.0.2",
"file-type": "14.1.2",
"fluent-ffmpeg": "2.1.2",
"glob": "7.1.6",
"gulp": "4.0.2",
"gulp-clean-css": "4.2.0",
"gulp-dart-sass": "0.9.1",
"gulp-mocha": "7.0.2",
"gulp-rename": "2.0.0",
"gulp-replace": "1.0.0",
"gulp-sourcemaps": "2.6.5",
"gulp-stylus": "2.7.0",
"gulp-terser": "1.2.0",
"gulp-tslint": "8.1.4",
"gulp-typescript": "5.0.1",
"hard-source-webpack-plugin": "0.13.1",
"html-minifier": "4.0.0",
"http-signature": "1.3.1",
"https-proxy-agent": "4.0.0",
"https-proxy-agent": "5.0.0",
"insert-text-at-cursor": "0.3.0",
"is-root": "2.1.0",
"is-svg": "4.2.0",
"is-svg": "4.2.1",
"js-yaml": "3.13.1",
"jsdom": "15.2.1",
"jsdom": "16.1.0",
"json5": "2.1.1",
"json5-loader": "3.0.0",
"jsrsasign": "8.0.12",
@ -164,11 +168,12 @@
"loader-utils": "1.2.3",
"lolex": "5.1.2",
"lookup-dns-cache": "2.1.0",
"mocha": "7.0.0",
"markdown-it": "10.0.0",
"mocha": "7.0.1",
"moji": "0.5.1",
"ms": "2.1.2",
"multer": "1.4.2",
"nested-property": "1.0.2",
"nested-property": "1.0.4",
"node-fetch": "2.6.0",
"nodemailer": "6.4.2",
"nprogress": "0.2.0",
@ -176,11 +181,13 @@
"os-utils": "0.0.14",
"parse5": "5.1.1",
"parsimmon": "1.13.0",
"pg": "7.17.0",
"pg": "7.18.1",
"portal-vue": "2.1.7",
"portscanner": "2.2.0",
"postcss-loader": "3.0.0",
"prismjs": "1.18.0",
"progress-bar-webpack-plugin": "1.12.1",
"prismjs": "1.19.0",
"probe-image-size": "5.0.0",
"progress-bar-webpack-plugin": "2.1.0",
"promise-limit": "2.7.0",
"promise-sequential": "1.1.1",
"pug": "2.0.4",
@ -191,45 +198,45 @@
"randomcolor": "0.5.4",
"ratelimiter": "3.4.0",
"recaptcha-promise": "0.1.3",
"reconnecting-websocket": "4.2.0",
"redis": "2.8.0",
"reconnecting-websocket": "4.4.0",
"redis": "3.0.2",
"redis-lock": "0.1.4",
"reflect-metadata": "0.1.13",
"rename": "1.0.4",
"request": "2.88.0",
"request": "2.88.2",
"request-promise-native": "1.0.8",
"request-stats": "3.0.0",
"require-all": "3.0.0",
"rimraf": "3.0.0",
"rimraf": "3.0.2",
"rndstr": "1.0.0",
"s-age": "1.1.2",
"sass": "1.25.0",
"sass-loader": "8.0.2",
"seedrandom": "3.0.5",
"sharp": "0.23.4",
"sharp": "0.24.0",
"showdown": "1.9.1",
"showdown-highlightjs-extension": "0.1.2",
"speakeasy": "2.0.0",
"stringz": "2.0.0",
"style-loader": "1.1.2",
"stylus": "0.54.7",
"stylus-loader": "3.0.2",
"style-loader": "1.1.3",
"summaly": "2.3.1",
"syslog-pro": "1.0.0",
"systeminformation": "4.17.3",
"systeminformation": "4.21.2",
"syuilo-password-strength": "0.0.1",
"terser-webpack-plugin": "2.3.1",
"terser-webpack-plugin": "2.3.4",
"textarea-caret": "3.1.0",
"three": "0.112.1",
"three": "0.113.2",
"tinycolor2": "1.4.1",
"tmp": "0.1.0",
"ts-loader": "6.2.1",
"ts-node": "8.5.4",
"tslint": "5.20.1",
"ts-node": "8.6.2",
"tslint": "6.0.0",
"tslint-sonarts": "1.9.0",
"typeorm": "0.2.22",
"typescript": "3.7.4",
"typescript": "3.7.5",
"ulid": "2.3.0",
"url-loader": "3.0.0",
"uuid": "3.3.3",
"uuid": "3.4.0",
"v-animate-css": "0.0.3",
"v-debounce": "0.1.2",
"vue": "2.6.11",
@ -237,28 +244,28 @@
"vue-content-loading": "1.6.0",
"vue-cropperjs": "4.0.1",
"vue-i18n": "8.15.3",
"vue-js-modal": "1.3.31",
"vue-json-pretty": "1.6.3",
"vue-loader": "15.8.3",
"vue-loader": "15.9.0",
"vue-marquee-text-component": "1.1.1",
"vue-meta": "2.3.2",
"vue-prism-component": "1.1.1",
"vue-router": "3.1.3",
"vue-router": "3.1.5",
"vue-sequential-entrance": "1.1.3",
"vue-style-loader": "4.1.2",
"vue-svg-inline-loader": "1.4.4",
"vue-svg-inline-loader": "1.4.5",
"vue-template-compiler": "2.6.11",
"vuedraggable": "2.23.2",
"vuewordcloud": "18.7.11",
"vuex": "3.1.2",
"vuex-persistedstate": "2.7.0",
"vuex-persistedstate": "2.7.1",
"web-push": "3.4.3",
"webpack": "4.41.5",
"webpack-cli": "3.3.10",
"webpack": "4.41.6",
"webpack-cli": "3.3.11",
"websocket": "1.0.31",
"ws": "7.2.1",
"xev": "2.0.1"
},
"devDependencies": {
"@types/fluent-ffmpeg": "2.1.12"
"@types/fluent-ffmpeg": "2.1.12",
"cross-env": "6.0.3"
}
}

View File

@ -1,3 +0,0 @@
declare module '*/const.json' {
const copyright: string;
}

27
src/@types/probe-image-size.d.ts vendored Normal file
View File

@ -0,0 +1,27 @@
declare module 'probe-image-size' {
import { ReadStream } from 'fs';
type ProbeOptions = {
retries: 1;
timeout: 30000;
};
type ProbeResult = {
width: number;
height: number;
length?: number;
type: string;
mime: string;
wUnits: 'in' | 'mm' | 'cm' | 'pt' | 'pc' | 'px' | 'em' | 'ex';
hUnits: 'in' | 'mm' | 'cm' | 'pt' | 'pc' | 'px' | 'em' | 'ex';
url?: string;
};
function probeImageSize(src: string | ReadStream, options?: ProbeOptions): Promise<ProbeResult>;
function probeImageSize(src: string | ReadStream, callback: (err: Error | null, result?: ProbeResult) => void): void;
function probeImageSize(src: string | ReadStream, options: ProbeOptions, callback: (err: Error | null, result?: ProbeResult) => void): void;
namespace probeImageSize {} // Hack
export = probeImageSize;
}

View File

@ -27,7 +27,7 @@ function greet() {
console.log(' ' + chalk.gray(v) + (' |___|\n'.substr(v.length)));
//#endregion
console.log(' Misskey is maintained by @syuilo, @AyaMorisawa, @mei23, @acid-chicken, and @rinsuki.');
console.log(' Misskey is an open-source decentralized microblogging platform.');
console.log(chalk.keyword('orange')(' If you like Misskey, please donate to support development. https://www.patreon.com/syuilo'));
console.log('');
@ -77,7 +77,6 @@ export async function masterMain() {
if (!program.noDaemons) {
require('../daemons/server-stats').default();
require('../daemons/notes-stats').default();
require('../daemons/queue-stats').default();
require('../daemons/janitor').default();
}

1242
src/client/app.vue Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,150 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="512"
height="512"
viewBox="0 0 135.46667 135.46667"
version="1.1"
id="svg8"
inkscape:version="0.92.1 r15371"
sodipodi:docname="header-icon.dark.svg"
inkscape:export-filename="C:\Users\syuilo\projects\misskey\assets\favicon\32.png"
inkscape:export-xdpi="6"
inkscape:export-ydpi="6">
<defs
id="defs2">
<inkscape:path-effect
effect="simplify"
id="path-effect5115"
is_visible="true"
steps="1"
threshold="0.000408163"
smooth_angles="360"
helper_size="0"
simplify_individual_paths="false"
simplify_just_coalesce="false"
simplifyindividualpaths="false"
simplifyJustCoalesce="false" />
<inkscape:path-effect
effect="simplify"
id="path-effect5111"
is_visible="true"
steps="1"
threshold="0.000408163"
smooth_angles="360"
helper_size="0"
simplify_individual_paths="false"
simplify_just_coalesce="false"
simplifyindividualpaths="false"
simplifyJustCoalesce="false" />
<inkscape:path-effect
effect="simplify"
id="path-effect5104"
is_visible="true"
steps="1"
threshold="0.000408163"
smooth_angles="360"
helper_size="0"
simplify_individual_paths="false"
simplify_just_coalesce="false"
simplifyindividualpaths="false"
simplifyJustCoalesce="false" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.4142136"
inkscape:cx="114.309"
inkscape:cy="251.50613"
inkscape:document-units="px"
inkscape:current-layer="g4502"
showgrid="true"
units="px"
inkscape:snap-bbox="true"
inkscape:bbox-nodes="true"
inkscape:snap-bbox-edge-midpoints="false"
inkscape:snap-smooth-nodes="true"
inkscape:snap-center="true"
inkscape:snap-page="true"
inkscape:window-width="1920"
inkscape:window-height="1027"
inkscape:window-x="-8"
inkscape:window-y="1072"
inkscape:window-maximized="1"
inkscape:snap-object-midpoints="true"
inkscape:snap-midpoints="true"
inkscape:object-paths="true"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
objecttolerance="1"
guidetolerance="1"
inkscape:snap-nodes="false"
inkscape:snap-others="false">
<inkscape:grid
type="xygrid"
id="grid4504"
spacingx="4.2333334"
spacingy="4.2333334"
empcolor="#ff3fff"
empopacity="0.25098039"
empspacing="4" />
</sodipodi:namedview>
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="レイヤー 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-30.809093,-111.78601)">
<g
id="g4502"
transform="matrix(1.096096,0,0,1.096096,-2.960633,-44.023579)">
<g
style="fill-opacity:1"
transform="translate(-1.3333333e-6,-1.3439941e-6)"
id="g5125">
<g
transform="matrix(0.91391326,0,0,0.91391326,7.9719907,17.595761)"
id="text4489"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:141.03404236px;line-height:476.69509888px;font-family:'OTADESIGN Rounded';-inkscape-font-specification:'OTADESIGN Rounded';letter-spacing:0px;word-spacing:0px;fill-opacity:1;stroke:none;stroke-width:0.28950602px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
aria-label="Mi">
<path
sodipodi:nodetypes="zccssscssccscczzzccsccsscscsccz"
inkscape:connector-curvature="0"
id="path5210"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:'OTADESIGN Rounded';-inkscape-font-specification:'OTADESIGN Rounded';fill-opacity:1;stroke-width:0.28950602px"
d="m 75.196381,231.17126 c -5.855419,0.0202 -10.885068,-3.50766 -13.2572,-7.61584 -1.266603,-1.79454 -3.772419,-2.43291 -3.807919,0 v 11.2332 c 0,4.51309 -1.645397,8.41504 -4.936191,11.70583 -3.196772,3.19677 -7.098714,4.79516 -11.705826,4.79516 -4.513089,0 -8.415031,-1.59839 -11.705825,-4.79516 -3.196772,-3.29079 -4.795158,-7.19274 -4.795158,-11.70583 v -61.7729 c 0,-3.47884 0.987238,-6.6286 2.961715,-9.44928 2.068499,-2.91471 4.701135,-4.9362 7.897906,-6.06447 1.786431,-0.65816 3.666885,-0.98724 5.641362,-0.98724 5.077225,0 9.308247,1.97448 12.693064,5.92343 1.786431,1.97448 2.820681,3.00873 3.102749,3.10275 0,0 13.408119,16.21319 13.78421,16.49526 0.376091,0.28206 1.480789,2.43848 4.127113,2.43848 2.646324,0 3.89218,-2.15642 4.26827,-2.43848 0.376091,-0.28207 13.784088,-16.49526 13.784088,-16.49526 0.09402,0.094 1.081261,-0.94022 2.961715,-3.10275 3.478837,-3.94895 7.756866,-5.92343 12.834096,-5.92343 1.88045,0 3.76091,0.32908 5.64136,0.98724 3.19677,1.12827 5.7824,3.14976 7.75688,6.06447 2.06849,2.82068 3.10274,5.97044 3.10274,9.44928 v 61.7729 c 0,4.51309 -1.6454,8.41504 -4.93619,11.70583 -3.19677,3.19677 -7.09871,4.79516 -11.70582,4.79516 -4.51309,0 -8.41504,-1.59839 -11.705828,-4.79516 -3.196772,-3.29079 -4.795158,-7.19274 -4.795158,-11.70583 v -11.2332 c -0.277898,-3.06563 -2.987588,-1.13379 -3.948953,0 -2.538613,4.70114 -7.401781,7.59567 -13.2572,7.61584 z" />
<path
inkscape:connector-curvature="0"
id="path5212"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:'OTADESIGN Rounded';-inkscape-font-specification:'OTADESIGN Rounded';fill-opacity:1;stroke-width:0.28950602px"
d="m 145.83461,185.00361 q -5.92343,0 -10.15445,-4.08999 -4.08999,-4.23102 -4.08999,-10.15445 0,-5.92343 4.08999,-10.01342 4.23102,-4.23102 10.15445,-4.23102 5.92343,0 10.15445,4.23102 4.23102,4.08999 4.23102,10.01342 0,5.92343 -4.23102,10.15445 -4.23102,4.08999 -10.15445,4.08999 z m 0.14103,2.82068 q 5.92343,0 10.01342,4.23102 4.23102,4.23102 4.23102,10.15445 v 34.83541 q 0,5.92343 -4.23102,10.15445 -4.08999,4.08999 -10.01342,4.08999 -5.92343,0 -10.15445,-4.08999 -4.23102,-4.23102 -4.23102,-10.15445 v -34.83541 q 0,-5.92343 4.23102,-10.15445 4.23102,-4.23102 10.15445,-4.23102 z" />
</g>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 7.0 KiB

View File

@ -1,30 +0,0 @@
/**
* Admin
*/
import VueRouter from 'vue-router';
// Style
import './style.styl';
import init from '../init';
import Index from './views/index.vue';
import NotFound from '../common/views/pages/not-found.vue';
init(launch => {
document.title = 'Admin';
// Init router
const router = new VueRouter({
mode: 'history',
base: '/admin/',
routes: [
{ path: '/:page', component: Index },
{ path: '/', redirect: '/dashboard' },
{ path: '*', component: NotFound }
]
});
// Launch the app
launch(router);
});

View File

@ -1,6 +0,0 @@
@import "../app"
@import "../reset"
html
height 100%
background var(--bg)

View File

@ -1,83 +0,0 @@
<template>
<div>
<ui-card>
<template #title><fa :icon="faExclamationCircle"/> {{ $t('title') }}</template>
<section class="fit-top">
<sequential-entrance animation="entranceFromTop" delay="25">
<div v-for="report in userReports" :key="report.id" class="haexwsjc">
<ui-horizon-group inputs>
<ui-input :value="report.user | acct" type="text" readonly>
<span>{{ $t('target') }}</span>
</ui-input>
<ui-input :value="report.reporter | acct" type="text" readonly>
<span>{{ $t('reporter') }}</span>
</ui-input>
</ui-horizon-group>
<ui-textarea :value="report.comment" readonly>
<span>{{ $t('details') }}</span>
</ui-textarea>
<ui-button @click="removeReport(report)">{{ $t('remove-report') }}</ui-button>
</div>
</sequential-entrance>
<ui-button v-if="existMore" @click="fetchUserReports">{{ $t('@.load-more') }}</ui-button>
</section>
</ui-card>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import i18n from '../../i18n';
import { faExclamationCircle } from '@fortawesome/free-solid-svg-icons';
export default Vue.extend({
i18n: i18n('admin/views/abuse.vue'),
data() {
return {
limit: 10,
untilId: undefined,
userReports: [],
existMore: false,
faExclamationCircle
};
},
mounted() {
this.fetchUserReports();
},
methods: {
fetchUserReports() {
this.$root.api('admin/abuse-user-reports', {
untilId: this.untilId,
limit: this.limit + 1
}).then(reports => {
if (reports.length == this.limit + 1) {
reports.pop();
this.existMore = true;
} else {
this.existMore = false;
}
this.userReports = this.userReports.concat(reports);
this.untilId = this.userReports[this.userReports.length - 1].id;
});
},
removeReport(report) {
this.$root.api('admin/remove-abuse-user-report', {
reportId: report.id
}).then(() => {
this.userReports = this.userReports.filter(r => r.id != report.id);
});
}
}
});
</script>
<style lang="stylus" scoped>
.haexwsjc
padding-bottom 16px
border-bottom solid 1px var(--faceDivider)
</style>

View File

@ -1,91 +0,0 @@
<template>
<div>
<ui-card>
<template #title><fa :icon="faBroadcastTower"/> {{ $t('announcements') }}</template>
<section v-for="(announcement, i) in announcements" class="fit-top">
<ui-input v-model="announcement.title" @change="save">
<span>{{ $t('title') }}</span>
</ui-input>
<ui-textarea v-model="announcement.text">
<span>{{ $t('text') }}</span>
</ui-textarea>
<ui-input v-model="announcement.image">
<span>{{ $t('image-url') }}</span>
</ui-input>
<ui-horizon-group class="fit-bottom">
<ui-button @click="save()"><fa :icon="['far', 'save']"/> {{ $t('save') }}</ui-button>
<ui-button @click="remove(i)"><fa :icon="['far', 'trash-alt']"/> {{ $t('remove') }}</ui-button>
</ui-horizon-group>
</section>
<section>
<ui-button @click="add"><fa :icon="faPlus"/> {{ $t('add') }}</ui-button>
</section>
</ui-card>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import i18n from '../../i18n';
import { faBroadcastTower, faPlus } from '@fortawesome/free-solid-svg-icons';
export default Vue.extend({
i18n: i18n('admin/views/announcements.vue'),
data() {
return {
announcements: [],
faBroadcastTower, faPlus
};
},
created() {
this.$root.getMeta().then(meta => {
this.announcements = meta.announcements;
});
},
methods: {
add() {
this.announcements.unshift({
title: '',
text: '',
image: null
});
},
remove(i) {
this.$root.dialog({
type: 'warning',
text: this.$t('_remove.are-you-sure').replace('$1', this.announcements.find((_, j) => j == i).title),
showCancelButton: true
}).then(({ canceled }) => {
if (canceled) return;
this.announcements = this.announcements.filter((_, j) => j !== i);
this.save(true);
this.$root.dialog({
type: 'success',
text: this.$t('_remove.removed')
});
});
},
save(silent) {
this.$root.api('admin/update-meta', {
announcements: this.announcements
}).then(() => {
if (!silent) {
this.$root.dialog({
type: 'success',
text: this.$t('saved')
});
}
}).catch(e => {
this.$root.dialog({
type: 'error',
text: e
});
});
}
}
});
</script>

View File

@ -1,109 +0,0 @@
<template>
<div class="hyhctythnmwihguaaapnbrbszsjqxpio">
<table>
<thead>
<tr>
<th><fa :icon="faExchangeAlt"/> In/Out</th>
<th><fa :icon="faBolt"/> Activity</th>
<th><fa icon="server"/> Host</th>
<th><fa icon="user"/> Actor</th>
</tr>
</thead>
<tbody>
<tr v-for="log in logs" :key="log.id">
<td :class="log.direction">{{ log.direction == 'in' ? '<' : '>' }} {{ log.direction }}</td>
<td>{{ log.activity }}</td>
<td>{{ log.host }}</td>
<td>@{{ log.actor }}</td>
</tr>
</tbody>
</table>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import { faBolt, faExchangeAlt } from '@fortawesome/free-solid-svg-icons';
export default Vue.extend({
data() {
return {
logs: [],
connection: null,
faBolt, faExchangeAlt
};
},
mounted() {
this.connection = this.$root.stream.useSharedConnection('apLog');
this.connection.on('log', this.onLog);
this.connection.on('logs', this.onLogs);
this.connection.send('requestLog', {
id: Math.random().toString().substr(2, 8),
length: 50
});
},
beforeDestroy() {
this.connection.dispose();
},
methods: {
onLog(log) {
log.id = Math.random();
this.logs.unshift(log);
if (this.logs.length > 50) this.logs.pop();
},
onLogs(logs) {
for (const log of logs.reverse()) {
this.onLog(log)
}
}
}
});
</script>
<style lang="stylus" scoped>
.hyhctythnmwihguaaapnbrbszsjqxpio
display block
padding 12px 16px 16px 16px
height 250px
overflow auto
box-shadow 0 2px 4px rgba(0, 0, 0, 0.1)
background var(--adminDashboardCardBg)
border-radius 8px
> table
width 100%
max-width 100%
overflow auto
border-spacing 0
border-collapse collapse
color var(--adminDashboardCardFg)
font-size 14px
thead
border-bottom solid 1px var(--adminDashboardCardDivider)
tr
th
font-weight normal
text-align left
tbody
tr
&:nth-child(odd)
background rgba(0, 0, 0, 0.025)
th, td
padding 8px 16px
min-width 128px
td.in
color #d26755
td.out
color #55bb83
</style>

View File

@ -1,527 +0,0 @@
<template>
<div class="qvgidhudpqhjttdhxubzuyrhyzgslujw">
<header>
<b><fa :icon="['far', 'chart-bar']"/> {{ $t('title') }}:</b>
<select v-model="src">
<optgroup :label="$t('federation')">
<option value="federation-instances">{{ $t('charts.federation-instances') }}</option>
<option value="federation-instances-total">{{ $t('charts.federation-instances-total') }}</option>
</optgroup>
<optgroup :label="$t('users')">
<option value="users">{{ $t('charts.users') }}</option>
<option value="users-total">{{ $t('charts.users-total') }}</option>
<option value="active-users">{{ $t('charts.active-users') }}</option>
</optgroup>
<optgroup :label="$t('notes')">
<option value="notes">{{ $t('charts.notes') }}</option>
<option value="local-notes">{{ $t('charts.local-notes') }}</option>
<option value="remote-notes">{{ $t('charts.remote-notes') }}</option>
<option value="notes-total">{{ $t('charts.notes-total') }}</option>
</optgroup>
<optgroup :label="$t('drive')">
<option value="drive-files">{{ $t('charts.drive-files') }}</option>
<option value="drive-files-total">{{ $t('charts.drive-files-total') }}</option>
<option value="drive">{{ $t('charts.drive') }}</option>
<option value="drive-total">{{ $t('charts.drive-total') }}</option>
</optgroup>
<optgroup :label="$t('network')">
<option value="network-requests">{{ $t('charts.network-requests') }}</option>
<option value="network-time">{{ $t('charts.network-time') }}</option>
<option value="network-usage">{{ $t('charts.network-usage') }}</option>
</optgroup>
</select>
<div>
<span @click="span = 'day'" :class="{ active: span == 'day' }">{{ $t('per-day') }}</span> | <span @click="span = 'hour'" :class="{ active: span == 'hour' }">{{ $t('per-hour') }}</span>
</div>
</header>
<div ref="chart"></div>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import i18n from '../../i18n';
import * as tinycolor from 'tinycolor2';
import ApexCharts from 'apexcharts';
const limit = 90;
const sum = (...arr) => arr.reduce((r, a) => r.map((b, i) => a[i] + b));
const negate = arr => arr.map(x => -x);
export default Vue.extend({
i18n: i18n('admin/views/charts.vue'),
data() {
return {
chart: null,
src: 'notes',
span: 'hour',
chartInstance: null
};
},
computed: {
data(): any {
if (this.chart == null) return null;
switch (this.src) {
case 'federation-instances': return this.federationInstancesChart(false);
case 'federation-instances-total': return this.federationInstancesChart(true);
case 'users': return this.usersChart(false);
case 'users-total': return this.usersChart(true);
case 'active-users': return this.activeUsersChart();
case 'notes': return this.notesChart('combined');
case 'local-notes': return this.notesChart('local');
case 'remote-notes': return this.notesChart('remote');
case 'notes-total': return this.notesTotalChart();
case 'drive': return this.driveChart();
case 'drive-total': return this.driveTotalChart();
case 'drive-files': return this.driveFilesChart();
case 'drive-files-total': return this.driveFilesTotalChart();
case 'network-requests': return this.networkRequestsChart();
case 'network-time': return this.networkTimeChart();
case 'network-usage': return this.networkUsageChart();
}
},
stats(): any[] {
const stats =
this.span == 'day' ? this.chart.perDay :
this.span == 'hour' ? this.chart.perHour :
null;
return stats;
}
},
watch: {
src() {
this.render();
},
span() {
this.render();
}
},
async mounted() {
this.now = new Date();
const [perHour, perDay] = await Promise.all([Promise.all([
this.$root.api('charts/federation', { limit: limit, span: 'hour' }),
this.$root.api('charts/users', { limit: limit, span: 'hour' }),
this.$root.api('charts/active-users', { limit: limit, span: 'hour' }),
this.$root.api('charts/notes', { limit: limit, span: 'hour' }),
this.$root.api('charts/drive', { limit: limit, span: 'hour' }),
this.$root.api('charts/network', { limit: limit, span: 'hour' })
]), Promise.all([
this.$root.api('charts/federation', { limit: limit, span: 'day' }),
this.$root.api('charts/users', { limit: limit, span: 'day' }),
this.$root.api('charts/active-users', { limit: limit, span: 'day' }),
this.$root.api('charts/notes', { limit: limit, span: 'day' }),
this.$root.api('charts/drive', { limit: limit, span: 'day' }),
this.$root.api('charts/network', { limit: limit, span: 'day' })
])]);
const chart = {
perHour: {
federation: perHour[0],
users: perHour[1],
activeUsers: perHour[2],
notes: perHour[3],
drive: perHour[4],
network: perHour[5]
},
perDay: {
federation: perDay[0],
users: perDay[1],
activeUsers: perDay[2],
notes: perDay[3],
drive: perDay[4],
network: perDay[5]
}
};
this.chart = chart;
this.render();
},
beforeDestroy() {
this.chartInstance.destroy();
},
methods: {
setSrc(src) {
this.src = src;
},
render() {
if (this.chartInstance) {
this.chartInstance.destroy();
}
this.chartInstance = new ApexCharts(this.$refs.chart, {
chart: {
type: 'area',
height: 300,
animations: {
dynamicAnimation: {
enabled: false
}
},
toolbar: {
show: false
},
zoom: {
enabled: false
}
},
dataLabels: {
enabled: false
},
grid: {
clipMarkers: false,
borderColor: 'rgba(0, 0, 0, 0.1)',
xaxis: {
lines: {
show: true,
}
},
},
stroke: {
curve: 'straight',
width: 2
},
legend: {
labels: {
colors: tinycolor(getComputedStyle(document.documentElement).getPropertyValue('--text')).toRgbString()
},
},
xaxis: {
type: 'datetime',
labels: {
style: {
colors: tinycolor(getComputedStyle(document.documentElement).getPropertyValue('--text')).toRgbString()
}
},
axisBorder: {
color: 'rgba(0, 0, 0, 0.1)'
},
axisTicks: {
color: 'rgba(0, 0, 0, 0.1)'
},
},
yaxis: {
labels: {
formatter: this.data.bytes ? v => Vue.filter('bytes')(v, 0) : v => Vue.filter('number')(v),
style: {
color: tinycolor(getComputedStyle(document.documentElement).getPropertyValue('--text')).toRgbString()
}
}
},
series: this.data.series
});
this.chartInstance.render();
},
getDate(i: number) {
const y = this.now.getFullYear();
const m = this.now.getMonth();
const d = this.now.getDate();
const h = this.now.getHours();
return (
this.span == 'day' ? new Date(y, m, d - i) :
this.span == 'hour' ? new Date(y, m, d, h - i) :
null
);
},
format(arr) {
return arr.map((v, i) => ({ x: this.getDate(i).getTime(), y: v }));
},
federationInstancesChart(total: boolean): any {
return {
series: [{
name: 'Instances',
data: this.format(total
? this.stats.federation.instance.total
: sum(this.stats.federation.instance.inc, negate(this.stats.federation.instance.dec))
)
}]
};
},
notesChart(type: string): any {
return {
series: [{
name: 'All',
type: 'line',
data: this.format(type == 'combined'
? sum(this.stats.notes.local.inc, negate(this.stats.notes.local.dec), this.stats.notes.remote.inc, negate(this.stats.notes.remote.dec))
: sum(this.stats.notes[type].inc, negate(this.stats.notes[type].dec))
)
}, {
name: 'Renotes',
type: 'area',
data: this.format(type == 'combined'
? sum(this.stats.notes.local.diffs.renote, this.stats.notes.remote.diffs.renote)
: this.stats.notes[type].diffs.renote
)
}, {
name: 'Replies',
type: 'area',
data: this.format(type == 'combined'
? sum(this.stats.notes.local.diffs.reply, this.stats.notes.remote.diffs.reply)
: this.stats.notes[type].diffs.reply
)
}, {
name: 'Normal',
type: 'area',
data: this.format(type == 'combined'
? sum(this.stats.notes.local.diffs.normal, this.stats.notes.remote.diffs.normal)
: this.stats.notes[type].diffs.normal
)
}]
};
},
notesTotalChart(): any {
return {
series: [{
name: 'Combined',
type: 'line',
data: this.format(sum(this.stats.notes.local.total, this.stats.notes.remote.total))
}, {
name: 'Local',
type: 'area',
data: this.format(this.stats.notes.local.total)
}, {
name: 'Remote',
type: 'area',
data: this.format(this.stats.notes.remote.total)
}]
};
},
usersChart(total: boolean): any {
return {
series: [{
name: 'Combined',
type: 'line',
data: this.format(total
? sum(this.stats.users.local.total, this.stats.users.remote.total)
: sum(this.stats.users.local.inc, negate(this.stats.users.local.dec), this.stats.users.remote.inc, negate(this.stats.users.remote.dec))
)
}, {
name: 'Local',
type: 'area',
data: this.format(total
? this.stats.users.local.total
: sum(this.stats.users.local.inc, negate(this.stats.users.local.dec))
)
}, {
name: 'Remote',
type: 'area',
data: this.format(total
? this.stats.users.remote.total
: sum(this.stats.users.remote.inc, negate(this.stats.users.remote.dec))
)
}]
};
},
activeUsersChart(): any {
return {
series: [{
name: 'Combined',
type: 'line',
data: this.format(sum(this.stats.activeUsers.local.count, this.stats.activeUsers.remote.count))
}, {
name: 'Local',
type: 'area',
data: this.format(this.stats.activeUsers.local.count)
}, {
name: 'Remote',
type: 'area',
data: this.format(this.stats.activeUsers.remote.count)
}]
};
},
driveChart(): any {
return {
bytes: true,
series: [{
name: 'All',
type: 'line',
data: this.format(
sum(
this.stats.drive.local.incSize,
negate(this.stats.drive.local.decSize),
this.stats.drive.remote.incSize,
negate(this.stats.drive.remote.decSize)
)
)
}, {
name: 'Local +',
type: 'area',
data: this.format(this.stats.drive.local.incSize)
}, {
name: 'Local -',
type: 'area',
data: this.format(negate(this.stats.drive.local.decSize))
}, {
name: 'Remote +',
type: 'area',
data: this.format(this.stats.drive.remote.incSize)
}, {
name: 'Remote -',
type: 'area',
data: this.format(negate(this.stats.drive.remote.decSize))
}]
};
},
driveTotalChart(): any {
return {
bytes: true,
series: [{
name: 'Combined',
type: 'line',
data: this.format(sum(this.stats.drive.local.totalSize, this.stats.drive.remote.totalSize))
}, {
name: 'Local',
type: 'area',
data: this.format(this.stats.drive.local.totalSize)
}, {
name: 'Remote',
type: 'area',
data: this.format(this.stats.drive.remote.totalSize)
}]
};
},
driveFilesChart(): any {
return {
series: [{
name: 'All',
type: 'line',
data: this.format(
sum(
this.stats.drive.local.incCount,
negate(this.stats.drive.local.decCount),
this.stats.drive.remote.incCount,
negate(this.stats.drive.remote.decCount)
)
)
}, {
name: 'Local +',
type: 'area',
data: this.format(this.stats.drive.local.incCount)
}, {
name: 'Local -',
type: 'area',
data: this.format(negate(this.stats.drive.local.decCount))
}, {
name: 'Remote +',
type: 'area',
data: this.format(this.stats.drive.remote.incCount)
}, {
name: 'Remote -',
type: 'area',
data: this.format(negate(this.stats.drive.remote.decCount))
}]
};
},
driveFilesTotalChart(): any {
return {
series: [{
name: 'Combined',
type: 'line',
data: this.format(sum(this.stats.drive.local.totalCount, this.stats.drive.remote.totalCount))
}, {
name: 'Local',
type: 'area',
data: this.format(this.stats.drive.local.totalCount)
}, {
name: 'Remote',
type: 'area',
data: this.format(this.stats.drive.remote.totalCount)
}]
};
},
networkRequestsChart(): any {
return {
series: [{
name: 'Incoming',
data: this.format(this.stats.network.incomingRequests)
}]
};
},
networkTimeChart(): any {
const data = [];
for (let i = 0; i < limit; i++) {
data.push(this.stats.network.incomingRequests[i] != 0 ? (this.stats.network.totalTime[i] / this.stats.network.incomingRequests[i]) : 0);
}
return {
series: [{
name: 'Avg time',
data: this.format(data)
}]
};
},
networkUsageChart(): any {
return {
bytes: true,
series: [{
name: 'Incoming',
data: this.format(this.stats.network.incomingBytes)
}, {
name: 'Outgoing',
data: this.format(this.stats.network.outgoingBytes)
}]
};
},
}
});
</script>
<style lang="stylus" scoped>
.qvgidhudpqhjttdhxubzuyrhyzgslujw
display block
flex 1
padding 32px 24px
padding-bottom 0
box-shadow 0 2px 4px rgba(0, 0, 0, 0.1)
background var(--face)
border-radius 8px
> header
display flex
margin 0 8px
padding 0 0 8px 0
font-size 1em
color var(--adminDashboardCardFg)
border-bottom solid 1px var(--adminDashboardCardDivider)
> b
margin-right 8px
> *:last-child
margin-left auto
*
&:not(.active)
color var(--primary)
cursor pointer
</style>

View File

@ -1,185 +0,0 @@
<template>
<div class="zyknedwtlthezamcjlolyusmipqmjgxz">
<div>
<header>
<span><fa icon="microchip"/> CPU <span>{{ cpuP }}%</span></span>
<span v-if="meta">{{ meta.cpu.model }}</span>
</header>
<div ref="cpu"></div>
</div>
<div>
<header>
<span><fa icon="memory"/> MEM <span>{{ memP }}%</span></span>
<span v-if="meta"></span>
</header>
<div ref="mem"></div>
</div>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import ApexCharts from 'apexcharts';
export default Vue.extend({
props: ['connection'],
data() {
return {
stats: [],
cpuChart: null,
memChart: null,
cpuP: '',
memP: '',
meta: null
};
},
watch: {
stats(stats) {
this.cpuChart.updateSeries([{
data: stats.map((x, i) => ({ x: i, y: x.cpu_usage }))
}]);
this.memChart.updateSeries([{
data: stats.map((x, i) => ({ x: i, y: (x.mem.used / x.mem.total) }))
}]);
}
},
mounted() {
this.$root.getMeta().then(meta => {
this.meta = meta;
});
this.connection.on('stats', this.onStats);
this.connection.on('statsLog', this.onStatsLog);
this.connection.send('requestLog', {
id: Math.random().toString().substr(2, 8),
length: 200
});
const chartOpts = {
chart: {
type: 'area',
height: 200,
animations: {
dynamicAnimation: {
enabled: false
}
},
toolbar: {
show: false
},
zoom: {
enabled: false
}
},
dataLabels: {
enabled: false
},
grid: {
clipMarkers: false,
borderColor: 'rgba(0, 0, 0, 0.1)'
},
stroke: {
curve: 'straight',
width: 2
},
tooltip: {
enabled: false
},
series: [{
data: []
}],
xaxis: {
type: 'numeric',
labels: {
show: false
},
tooltip: {
enabled: false
}
},
yaxis: {
show: false,
min: 0,
max: 1
}
};
this.cpuChart = new ApexCharts(this.$refs.cpu, chartOpts);
this.memChart = new ApexCharts(this.$refs.mem, chartOpts);
this.cpuChart.render();
this.memChart.render();
},
beforeDestroy() {
this.connection.off('stats', this.onStats);
this.connection.off('statsLog', this.onStatsLog);
this.cpuChart.destroy();
this.memChart.destroy();
},
methods: {
onStats(stats) {
this.stats.push(stats);
if (this.stats.length > 200) this.stats.shift();
this.cpuP = (stats.cpu_usage * 100).toFixed(0);
this.memP = (stats.mem.used / stats.mem.total * 100).toFixed(0);
},
onStatsLog(statsLog) {
for (const stats of statsLog.reverse()) {
this.onStats(stats);
}
}
}
});
</script>
<style lang="stylus" scoped>
.zyknedwtlthezamcjlolyusmipqmjgxz
display flex
> div
display block
flex 1
padding 20px 12px 0 12px
box-shadow 0 2px 4px rgba(0, 0, 0, 0.1)
background var(--face)
border-radius 8px
&:first-child
margin-right 16px
> header
display flex
padding 0 8px
margin-bottom -16px
color var(--adminDashboardCardFg)
font-size 14px
> span
&:last-child
margin-left auto
opacity 0.7
> span
opacity 0.7
> div
margin-bottom -10px
@media (max-width 1000px)
display block
margin-bottom 26px
> div
&:first-child
margin-right 0
margin-bottom 26px
</style>

View File

@ -1,196 +0,0 @@
<template>
<div class="mzxlfysy">
<div>
<header>
<span><fa :icon="faInbox"/> In</span>
<span v-if="latestStats">{{ latestStats.inbox.activeSincePrevTick | number }} / {{ latestStats.inbox.delayed | number }}</span>
</header>
<div ref="in"></div>
</div>
<div>
<header>
<span><fa :icon="faPaperPlane"/> Out</span>
<span v-if="latestStats">{{ latestStats.deliver.activeSincePrevTick | number }} / {{ latestStats.deliver.delayed | number }}</span>
</header>
<div ref="out"></div>
</div>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import { faInbox } from '@fortawesome/free-solid-svg-icons';
import { faPaperPlane } from '@fortawesome/free-regular-svg-icons';
import ApexCharts from 'apexcharts';
const limit = 150;
export default Vue.extend({
data() {
return {
stats: [],
inChart: null,
outChart: null,
faInbox, faPaperPlane
};
},
computed: {
latestStats(): any {
return this.stats[this.stats.length - 1];
}
},
watch: {
stats(stats) {
this.inChart.updateSeries([{
data: stats.map((x, i) => ({ x: i, y: x.inbox.activeSincePrevTick }))
}, {
data: stats.map((x, i) => ({ x: i, y: x.inbox.active }))
}, {
data: stats.map((x, i) => ({ x: i, y: x.inbox.waiting }))
}, {
data: stats.map((x, i) => ({ x: i, y: x.inbox.delayed }))
}]);
this.outChart.updateSeries([{
data: stats.map((x, i) => ({ x: i, y: x.deliver.activeSincePrevTick }))
}, {
data: stats.map((x, i) => ({ x: i, y: x.deliver.active }))
}, {
data: stats.map((x, i) => ({ x: i, y: x.deliver.waiting }))
}, {
data: stats.map((x, i) => ({ x: i, y: x.deliver.delayed }))
}]);
}
},
mounted() {
const chartOpts = {
chart: {
type: 'area',
height: 200,
animations: {
dynamicAnimation: {
enabled: false
}
},
toolbar: {
show: false
},
zoom: {
enabled: false
}
},
dataLabels: {
enabled: false
},
grid: {
clipMarkers: false,
borderColor: 'rgba(0, 0, 0, 0.1)'
},
stroke: {
curve: 'straight',
width: 2
},
tooltip: {
enabled: false
},
legend: {
show: false
},
colors: ['#00E396', '#00BCD4', '#FFB300', '#e53935'],
series: [{ data: [] }, { data: [] }, { data: [] }, { data: [] }] as any,
xaxis: {
type: 'numeric',
labels: {
show: false
},
tooltip: {
enabled: false
}
},
yaxis: {
show: false,
min: 0,
}
};
this.inChart = new ApexCharts(this.$refs.in, chartOpts);
this.outChart = new ApexCharts(this.$refs.out, chartOpts);
this.inChart.render();
this.outChart.render();
const connection = this.$root.stream.useSharedConnection('queueStats');
connection.on('stats', this.onStats);
connection.on('statsLog', this.onStatsLog);
connection.send('requestLog', {
id: Math.random().toString().substr(2, 8),
length: limit
});
this.$once('hook:beforeDestroy', () => {
connection.dispose();
this.inChart.destroy();
this.outChart.destroy();
});
},
methods: {
onStats(stats) {
this.stats.push(stats);
if (this.stats.length > limit) this.stats.shift();
},
onStatsLog(statsLog) {
for (const stats of statsLog.reverse()) {
this.onStats(stats);
}
}
}
});
</script>
<style lang="stylus" scoped>
.mzxlfysy
display flex
> div
display block
flex 1
padding 20px 12px 0 12px
box-shadow 0 2px 4px rgba(0, 0, 0, 0.1)
background var(--face)
border-radius 8px
&:first-child
margin-right 16px
> header
display flex
padding 0 8px
margin-bottom -16px
color var(--adminDashboardCardFg)
font-size 14px
> span
&:last-child
margin-left auto
opacity 0.7
> span
opacity 0.7
> div
margin-bottom -10px
@media (max-width 1000px)
display block
margin-bottom 26px
> div
&:first-child
margin-right 0
margin-bottom 26px
</style>

View File

@ -1,286 +0,0 @@
<template>
<div class="obdskegsannmntldydackcpzezagxqfy">
<header v-if="meta">
<p><b>Misskey</b><span>{{ meta.version }}</span></p>
<p><b>Machine</b><span>{{ meta.machine }}</span></p>
<p><b>OS</b><span>{{ meta.os }}</span></p>
<p><b>Node</b><span>{{ meta.node }}</span></p>
<p>{{ $t('@.ai-chan-kawaii') }}</p>
</header>
<marquee-text v-if="instances.length > 0" class="instances" :repeat="10" :duration="60">
<span v-for="instance in instances" class="instance">
<b :style="{ background: instance.bg }">{{ instance.host }}</b>{{ instance.notesCount | number }} / {{ instance.usersCount | number }}
</span>
</marquee-text>
<div v-if="stats" class="stats">
<div>
<div>
<div><fa icon="user"/></div>
<div>
<span>{{ $t('accounts') }}</span>
<b>{{ stats.originalUsersCount | number }}</b>
</div>
</div>
<div>
<span><fa icon="home"/> {{ $t('this-instance') }}</span>
<span @click="setChartSrc('users')"><fa :icon="['far', 'chart-bar']"/></span>
</div>
</div>
<div>
<div>
<div><fa icon="pencil-alt"/></div>
<div>
<span>{{ $t('notes') }}</span>
<b>{{ stats.originalNotesCount | number }}</b>
</div>
</div>
<div>
<span><fa icon="home"/> {{ $t('this-instance') }}</span>
<span @click="setChartSrc('notes')"><fa :icon="['far', 'chart-bar']"/></span>
</div>
</div>
<div>
<div>
<div><fa :icon="faDatabase"/></div>
<div>
<span>{{ $t('drive') }}</span>
<b>{{ stats.driveUsageLocal | bytes }}</b>
</div>
</div>
<div>
<span><fa icon="home"/> {{ $t('this-instance') }}</span>
<span @click="setChartSrc('drive')"><fa :icon="['far', 'chart-bar']"/></span>
</div>
</div>
<div>
<div>
<div><fa :icon="['far', 'hdd']"/></div>
<div>
<span>{{ $t('instances') }}</span>
<b>{{ stats.instances | number }}</b>
</div>
</div>
<div>
<span><fa icon="globe"/> {{ $t('federated') }}</span>
<span @click="setChartSrc('federation-instances-total')"><fa :icon="['far', 'chart-bar']"/></span>
</div>
</div>
</div>
<div class="charts">
<x-charts ref="charts"/>
</div>
<div class="queue">
<x-queue/>
</div>
<div class="cpu-memory">
<x-cpu-memory :connection="connection"/>
</div>
<div class="ap">
<x-ap-log/>
</div>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import i18n from '../../i18n';
import XCpuMemory from "./dashboard.cpu-memory.vue";
import XQueue from "./dashboard.queue-charts.vue";
import XCharts from "./dashboard.charts.vue";
import XApLog from "./dashboard.ap-log.vue";
import { faDatabase } from '@fortawesome/free-solid-svg-icons';
import MarqueeText from 'vue-marquee-text-component';
import randomColor from 'randomcolor';
export default Vue.extend({
i18n: i18n('admin/views/dashboard.vue'),
components: {
XCpuMemory,
XQueue,
XCharts,
XApLog,
MarqueeText
},
data() {
return {
stats: null,
connection: null,
meta: null,
instances: [],
faDatabase
};
},
created() {
this.connection = this.$root.stream.useSharedConnection('serverStats');
this.updateStats();
this.$root.getMeta().then(meta => {
this.meta = meta;
});
this.$root.api('federation/instances', {
sort: '+notes'
}).then(instances => {
for (const i of instances) {
i.bg = randomColor({
seed: i.host,
luminosity: 'dark'
});
}
this.instances = instances;
});
},
beforeDestroy() {
this.connection.dispose();
},
methods: {
setChartSrc(src) {
this.$refs.charts.setSrc(src);
},
updateStats() {
this.$root.api('stats', {}, true).then(stats => {
this.stats = stats;
});
}
}
});
</script>
<style lang="stylus" scoped>
.obdskegsannmntldydackcpzezagxqfy
padding 16px
@media (min-width 500px)
padding 16px
> header
display flex
padding-bottom 16px
border-bottom solid 1px var(--adminDashboardHeaderBorder)
color var(--adminDashboardHeaderFg)
font-size 14px
white-space nowrap
@media (max-width 1000px)
display none
> p
display block
margin 0 32px 0 0
overflow hidden
text-overflow ellipsis
> b
&:after
content ':'
margin-right 8px
&:last-child
margin-left auto
margin-right 0
> .instances
padding 16px
color var(--adminDashboardHeaderFg)
font-size 13px
>>> .instance
margin 0 10px
> b
padding 2px 6px
margin-right 4px
border-radius 4px
color #fff
> .stats
display flex
justify-content space-between
margin-bottom 16px
> div
flex 1
margin-right 16px
color var(--adminDashboardCardFg)
box-shadow 0 2px 4px rgba(0, 0, 0, 0.1)
background var(--adminDashboardCardBg)
border-radius 8px
&:last-child
margin-right 0
> div:first-child
display flex
align-items center
text-align center
&:last-child
margin-right 0
> div:first-child
padding 16px 24px
font-size 28px
> div:last-child
flex 1
padding 16px 32px 16px 0
text-align right
> span
font-size 70%
opacity 0.7
> b
display block
> div:last-child
display flex
padding 6px 16px
border-top solid 1px var(--adminDashboardCardDivider)
> span
font-size 70%
opacity 0.7
&:last-child
margin-left auto
cursor pointer
@media (max-width 900px)
display grid
grid-template-columns 1fr 1fr
grid-template-rows 1fr 1fr
gap 16px
> div
margin-right 0
@media (max-width 500px)
display block
> div:not(:last-child)
margin-bottom 16px
> .charts
margin-bottom 16px
> .queue
margin-bottom 16px
> .cpu-memory
margin-bottom 16px
</style>

View File

@ -1,61 +0,0 @@
<template>
<div>
<ui-card>
<template #title><fa :icon="faDatabase"/> {{ $t('tables') }}</template>
<section v-if="tables">
<div v-for="table in Object.keys(tables)"><b>{{ table }}</b> {{ tables[table].count | number }} {{ tables[table].size | bytes }}</div>
</section>
<section>
<header><fa :icon="faBroom"/> {{ $t('vacuum') }}</header>
<ui-info>{{ $t('vacuum-info') }}</ui-info>
<ui-switch v-model="fullVacuum">FULL</ui-switch>
<ui-switch v-model="analyzeVacuum">ANALYZE</ui-switch>
<ui-button @click="vacuum()"><fa :icon="faBroom"/> {{ $t('vacuum') }}</ui-button>
<ui-info warn>{{ $t('vacuum-exclamation') }}</ui-info>
</section>
</ui-card>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import i18n from '../../i18n';
import { faDatabase, faBroom } from '@fortawesome/free-solid-svg-icons';
export default Vue.extend({
i18n: i18n('admin/views/db.vue'),
data() {
return {
tables: null,
fullVacuum: true,
analyzeVacuum: true,
faDatabase, faBroom
};
},
mounted() {
this.fetch();
},
methods: {
fetch() {
this.$root.api('admin/get-table-stats').then(tables => {
this.tables = tables;
});
},
vacuum() {
this.$root.api('admin/vacuum', {
full: this.fullVacuum,
analyze: this.analyzeVacuum,
}).then(() => {
this.$root.dialog({
type: 'success',
splash: true
});
});
},
}
});
</script>

View File

@ -1,292 +0,0 @@
<template>
<div>
<ui-card>
<template #title><fa :icon="faTerminal"/> {{ $t('operation') }}</template>
<section class="fit-top">
<ui-input v-model="target" type="text">
<span>{{ $t('fileid-or-url') }}</span>
</ui-input>
<ui-horizon-group>
<ui-button @click="findAndToggleSensitive(true)"><fa :icon="faEyeSlash"/> {{ $t('mark-as-sensitive') }}</ui-button>
<ui-button @click="findAndToggleSensitive(false)"><fa :icon="faEye"/> {{ $t('unmark-as-sensitive') }}</ui-button>
</ui-horizon-group>
<ui-button @click="findAndDel()"><fa :icon="faTrashAlt"/> {{ $t('delete') }}</ui-button>
<ui-button @click="show()"><fa :icon="faSearch"/> {{ $t('lookup') }}</ui-button>
<ui-textarea v-if="file" :value="file | json5" readonly tall style="margin-top:16px;"></ui-textarea>
</section>
<section>
<ui-button @click="cleanUp()"><fa :icon="faTrashAlt"/> {{ $t('clean-up') }}</ui-button>
<ui-button @click="cleanRemoteFiles()"><fa :icon="faTrashAlt"/> {{ $t('clean-remote-files') }}</ui-button>
</section>
</ui-card>
<ui-card>
<template #title><fa :icon="faCloud"/> {{ $t('@.drive') }}</template>
<section class="fit-top">
<ui-horizon-group inputs>
<ui-select v-model="sort">
<template #label>{{ $t('sort.title') }}</template>
<option value="-createdAt">{{ $t('sort.createdAtAsc') }}</option>
<option value="+createdAt">{{ $t('sort.createdAtDesc') }}</option>
<option value="-size">{{ $t('sort.sizeAsc') }}</option>
<option value="+size">{{ $t('sort.sizeDesc') }}</option>
</ui-select>
<ui-select v-model="origin">
<template #label>{{ $t('origin.title') }}</template>
<option value="combined">{{ $t('origin.combined') }}</option>
<option value="local">{{ $t('origin.local') }}</option>
<option value="remote">{{ $t('origin.remote') }}</option>
</ui-select>
</ui-horizon-group>
<sequential-entrance animation="entranceFromTop" delay="25">
<div class="kidvdlkg" v-for="file in files">
<div @click="file._open = !file._open">
<div>
<x-file-thumbnail class="thumbnail" :file="file" fit="contain" @click="showFileMenu(file)"/>
</div>
<div>
<header>
<b>{{ file.name }}</b>
<span class="username">@{{ file.user | acct }}</span>
</header>
<div>
<div>
<span style="margin-right:16px;">{{ file.type }}</span>
<span>{{ file.size | bytes }}</span>
</div>
<div><mk-time :time="file.createdAt" mode="detail"/></div>
</div>
</div>
</div>
<div v-show="file._open">
<ui-input readonly :value="file.url"></ui-input>
<ui-horizon-group>
<ui-button @click="toggleSensitive(file)" v-if="file.isSensitive"><fa :icon="faEye"/> {{ $t('unmark-as-sensitive') }}</ui-button>
<ui-button @click="toggleSensitive(file)" v-else><fa :icon="faEyeSlash"/> {{ $t('mark-as-sensitive') }}</ui-button>
<ui-button @click="del(file)"><fa :icon="faTrashAlt"/> {{ $t('delete') }}</ui-button>
</ui-horizon-group>
</div>
</div>
</sequential-entrance>
<ui-button v-if="existMore" @click="fetch">{{ $t('@.load-more') }}</ui-button>
</section>
</ui-card>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import i18n from '../../i18n';
import { faCloud, faTerminal, faSearch } from '@fortawesome/free-solid-svg-icons';
import { faTrashAlt, faEye, faEyeSlash } from '@fortawesome/free-regular-svg-icons';
import XFileThumbnail from '../../common/views/components/drive-file-thumbnail.vue';
export default Vue.extend({
i18n: i18n('admin/views/drive.vue'),
components: {
XFileThumbnail
},
data() {
return {
file: null,
target: null,
sort: '+createdAt',
origin: 'combined',
limit: 10,
offset: 0,
files: [],
existMore: false,
faCloud, faTrashAlt, faEye, faEyeSlash, faTerminal, faSearch
};
},
watch: {
sort() {
this.files = [];
this.offset = 0;
this.fetch();
},
origin() {
this.files = [];
this.offset = 0;
this.fetch();
}
},
mounted() {
this.fetch();
},
methods: {
async fetchFile() {
try {
return await this.$root.api('drive/files/show', this.target.startsWith('http') ? { url: this.target } : { fileId: this.target });
} catch (e) {
if (e == 'file-not-found') {
this.$root.dialog({
type: 'error',
text: this.$t('file-not-found')
});
} else {
this.$root.dialog({
type: 'error',
text: e.toString()
});
}
}
},
fetch() {
this.$root.api('admin/drive/files', {
origin: this.origin,
sort: this.sort,
offset: this.offset,
limit: this.limit + 1
}).then(files => {
if (files.length == this.limit + 1) {
files.pop();
this.existMore = true;
} else {
this.existMore = false;
}
for (const x of files) {
x._open = false;
}
this.files = this.files.concat(files);
this.offset += this.limit;
});
},
async del(file: any) {
const process = async () => {
await this.$root.api('drive/files/delete', { fileId: file.id });
this.$root.dialog({
type: 'success',
text: this.$t('deleted')
});
};
await process().catch(e => {
this.$root.dialog({
type: 'error',
text: e.toString()
});
});
},
toggleSensitive(file: any) {
this.$root.api('drive/files/update', {
fileId: file.id,
isSensitive: !file.isSensitive
}).then(() => {
file.isSensitive = !file.isSensitive;
});
},
async show() {
const file = await this.fetchFile();
this.$root.api('admin/drive/show-file', { fileId: file.id }).then(info => {
this.file = info;
});
},
async findAndToggleSensitive(sensitive) {
const process = async () => {
const file = await this.fetchFile();
await this.$root.api('drive/files/update', {
fileId: file.id,
isSensitive: sensitive
});
this.$root.dialog({
type: 'success',
text: sensitive ? this.$t('marked-as-sensitive') : this.$t('unmarked-as-sensitive')
});
};
await process().catch(e => {
this.$root.dialog({
type: 'error',
text: e.toString()
});
});
},
async findAndDel() {
const process = async () => {
const file = await this.fetchFile();
await this.$root.api('drive/files/delete', { fileId: file.id });
this.$root.dialog({
type: 'success',
text: this.$t('deleted')
});
};
await process().catch(e => {
this.$root.dialog({
type: 'error',
text: e.toString()
});
});
},
cleanRemoteFiles() {
this.$root.dialog({
type: 'warning',
text: this.$t('clean-remote-files-are-you-sure'),
showCancelButton: true
}).then(({ canceled }) => {
if (canceled) return;
this.$root.api('admin/drive/clean-remote-files');
this.$root.dialog({
type: 'success',
splash: true
});
});
},
cleanUp() {
this.$root.api('admin/drive/cleanup');
this.$root.dialog({
type: 'success',
splash: true
});
}
}
});
</script>
<style lang="stylus" scoped>
.kidvdlkg
padding 16px 0
border-top solid 1px var(--faceDivider)
> div:first-child
display flex
cursor pointer
> div:nth-child(1)
> .thumbnail
display flex
width 64px
height 64px
background-size cover
background-position center center
> div:nth-child(2)
flex 1
padding-left 16px
@media (max-width 500px)
font-size 14px
> header
word-break break-word
> .username
margin-left 8px
opacity 0.7
</style>

View File

@ -1,185 +0,0 @@
<template>
<div>
<ui-card>
<template #title><fa icon="plus"/> {{ $t('add-emoji.title') }}</template>
<section class="fit-top">
<ui-horizon-group inputs>
<ui-input v-model="name">
<span>{{ $t('add-emoji.name') }}</span>
<template #desc>{{ $t('add-emoji.name-desc') }}</template>
</ui-input>
<ui-input v-model="category" :datalist="categoryList">
<span>{{ $t('add-emoji.category') }}</span>
</ui-input>
<ui-input v-model="aliases">
<span>{{ $t('add-emoji.aliases') }}</span>
<template #desc>{{ $t('add-emoji.aliases-desc') }}</template>
</ui-input>
</ui-horizon-group>
<ui-input v-model="url">
<template #icon><fa icon="link"/></template>
<span>{{ $t('add-emoji.url') }}</span>
</ui-input>
<ui-info>{{ $t('add-emoji.info') }}</ui-info>
<ui-button @click="add">{{ $t('add-emoji.add') }}</ui-button>
</section>
</ui-card>
<ui-card>
<template #title><fa :icon="faGrin"/> {{ $t('emojis.title') }}</template>
<section v-for="emoji in emojis" :key="emoji.name" class="oryfrbft">
<div>
<img :src="emoji.url" :alt="emoji.name" style="width: 64px;"/>
</div>
<div>
<ui-horizon-group>
<ui-input v-model="emoji.name">
<span>{{ $t('add-emoji.name') }}</span>
</ui-input>
<ui-input v-model="emoji.category" :datalist="categoryList">
<span>{{ $t('add-emoji.category') }}</span>
</ui-input>
<ui-input v-model="emoji.aliases">
<span>{{ $t('add-emoji.aliases') }}</span>
</ui-input>
</ui-horizon-group>
<ui-input v-model="emoji.url">
<template #icon><fa icon="link"/></template>
<span>{{ $t('add-emoji.url') }}</span>
</ui-input>
<ui-horizon-group class="fit-bottom">
<ui-button @click="updateEmoji(emoji)"><fa :icon="['far', 'save']"/> {{ $t('emojis.update') }}</ui-button>
<ui-button @click="removeEmoji(emoji)"><fa :icon="['far', 'trash-alt']"/> {{ $t('emojis.remove') }}</ui-button>
</ui-horizon-group>
</div>
</section>
</ui-card>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import i18n from '../../i18n';
import { faGrin } from '@fortawesome/free-regular-svg-icons';
import { unique } from '../../../../prelude/array';
export default Vue.extend({
i18n: i18n('admin/views/emoji.vue'),
data() {
return {
name: '',
category: '',
url: '',
aliases: '',
emojis: [],
faGrin
};
},
mounted() {
this.fetchEmojis();
},
computed: {
categoryList() {
return unique(this.emojis.map((x: any) => x.category || '').filter((x: string) => x !== ''));
}
},
methods: {
add() {
this.$root.api('admin/emoji/add', {
name: this.name,
category: this.category,
url: this.url,
aliases: this.aliases.split(' ').filter(x => x.length > 0)
}).then(() => {
this.$root.dialog({
type: 'success',
text: this.$t('add-emoji.added')
});
this.fetchEmojis();
}).catch(e => {
this.$root.dialog({
type: 'error',
text: e
});
});
},
fetchEmojis() {
this.$root.api('admin/emoji/list').then(emojis => {
for (const e of emojis) {
e.aliases = (e.aliases || []).join(' ');
}
this.emojis = emojis;
});
},
updateEmoji(emoji) {
this.$root.api('admin/emoji/update', {
id: emoji.id,
name: emoji.name,
category: emoji.category,
url: emoji.url,
aliases: emoji.aliases.split(' ').filter(x => x.length > 0)
}).then(() => {
this.$root.dialog({
type: 'success',
text: this.$t('updated')
});
}).catch(e => {
this.$root.dialog({
type: 'error',
text: e
});
});
},
removeEmoji(emoji) {
this.$root.dialog({
type: 'warning',
text: this.$t('remove-emoji.are-you-sure').replace('$1', emoji.name),
showCancelButton: true
}).then(({ canceled }) => {
if (canceled) return;
this.$root.api('admin/emoji/remove', {
id: emoji.id
}).then(() => {
this.$root.dialog({
type: 'success',
text: this.$t('remove-emoji.removed')
});
this.fetchEmojis();
}).catch(e => {
this.$root.dialog({
type: 'error',
text: e
});
});
});
}
}
});
</script>
<style lang="stylus" scoped>
.oryfrbft
@media (min-width 500px)
display flex
> div:first-child
@media (max-width 500px)
padding-bottom 16px
> img
vertical-align bottom
> div:last-child
flex 1
@media (min-width 500px)
padding-left 16px
</style>

View File

@ -1,553 +0,0 @@
<template>
<div>
<ui-card>
<template #title><fa :icon="faTerminal"/> {{ $t('instance') }}</template>
<section class="fit-top">
<ui-input class="target" v-model="target" type="text" @enter="showInstance()">
<span>{{ $t('host') }}</span>
<template #prefix><fa :icon="faServer"/></template>
</ui-input>
<ui-button @click="showInstance()"><fa :icon="faSearch"/> {{ $t('lookup') }}</ui-button>
<div class="instance" v-if="instance">
<ui-horizon-group inputs>
<ui-input :value="instance.host" type="text" readonly>
<span>{{ $t('host') }}</span>
<template #prefix><fa :icon="faServer"/></template>
</ui-input>
<ui-input :value="instance.caughtAt | date" type="text" readonly>
<span>{{ $t('caught-at') }}</span>
<template #prefix><fa :icon="faCrosshairs"/></template>
</ui-input>
</ui-horizon-group>
<ui-horizon-group inputs>
<ui-input :value="instance.notesCount | number" type="text" readonly>
<span>{{ $t('notes') }}</span>
<template #prefix><fa :icon="faEnvelopeOpenText"/></template>
</ui-input>
<ui-input :value="instance.usersCount | number" type="text" readonly>
<span>{{ $t('users') }}</span>
<template #prefix><fa :icon="faUsers"/></template>
</ui-input>
</ui-horizon-group>
<ui-horizon-group inputs>
<ui-input :value="instance.followingCount | number" type="text" readonly>
<span>{{ $t('following') }}</span>
<template #prefix><fa :icon="faCaretDown"/></template>
</ui-input>
<ui-input :value="instance.followersCount | number" type="text" readonly>
<span>{{ $t('followers') }}</span>
<template #prefix><fa :icon="faCaretUp"/></template>
</ui-input>
</ui-horizon-group>
<ui-horizon-group inputs>
<ui-input :value="instance.latestRequestSentAt | date" type="text" readonly>
<span>{{ $t('latest-request-sent-at') }}</span>
<template #prefix><fa :icon="faPaperPlane"/></template>
</ui-input>
<ui-input :value="instance.latestStatus" type="text" readonly>
<span>{{ $t('status') }}</span>
<template #prefix><fa :icon="faTrafficLight"/></template>
</ui-input>
</ui-horizon-group>
<ui-input :value="instance.latestRequestReceivedAt | date" type="text" readonly>
<span>{{ $t('latest-request-received-at') }}</span>
<template #prefix><fa :icon="faInbox"/></template>
</ui-input>
<ui-switch v-model="instance.isMarkedAsClosed" @change="updateInstance()">{{ $t('marked-as-closed') }}</ui-switch>
<details>
<summary>{{ $t('charts') }}</summary>
<ui-horizon-group inputs>
<ui-select v-model="chartSrc">
<option value="requests">{{ $t('chart-srcs.requests') }}</option>
<option value="users">{{ $t('chart-srcs.users') }}</option>
<option value="users-total">{{ $t('chart-srcs.users-total') }}</option>
<option value="notes">{{ $t('chart-srcs.notes') }}</option>
<option value="notes-total">{{ $t('chart-srcs.notes-total') }}</option>
<option value="ff">{{ $t('chart-srcs.ff') }}</option>
<option value="ff-total">{{ $t('chart-srcs.ff-total') }}</option>
<option value="drive-usage">{{ $t('chart-srcs.drive-usage') }}</option>
<option value="drive-usage-total">{{ $t('chart-srcs.drive-usage-total') }}</option>
<option value="drive-files">{{ $t('chart-srcs.drive-files') }}</option>
<option value="drive-files-total">{{ $t('chart-srcs.drive-files-total') }}</option>
</ui-select>
<ui-select v-model="chartSpan">
<option value="hour">{{ $t('chart-spans.hour') }}</option>
<option value="day">{{ $t('chart-spans.day') }}</option>
</ui-select>
</ui-horizon-group>
<div ref="chart"></div>
</details>
<details>
<summary>{{ $t('delete-all-files') }}</summary>
<ui-button @click="deleteAllFiles()" style="margin-top: 16px;"><fa :icon="faTrashAlt"/> {{ $t('delete-all-files') }}</ui-button>
</details>
<details>
<summary>{{ $t('remove-all-following') }}</summary>
<ui-button @click="removeAllFollowing()" style="margin-top: 16px;"><fa :icon="faMinusCircle"/> {{ $t('remove-all-following') }}</ui-button>
<ui-info warn>{{ $t('remove-all-following-info', { host: instance.host }) }}</ui-info>
</details>
</div>
</section>
</ui-card>
<ui-card>
<template #title><fa :icon="faServer"/> {{ $t('instances') }}</template>
<section class="fit-top">
<ui-horizon-group inputs>
<ui-select v-model="sort">
<template #label>{{ $t('sort') }}</template>
<option value="-caughtAt">{{ $t('sorts.caughtAtAsc') }}</option>
<option value="+caughtAt">{{ $t('sorts.caughtAtDesc') }}</option>
<option value="-lastCommunicatedAt">{{ $t('sorts.lastCommunicatedAtAsc') }}</option>
<option value="+lastCommunicatedAt">{{ $t('sorts.lastCommunicatedAtDesc') }}</option>
<option value="-notes">{{ $t('sorts.notesAsc') }}</option>
<option value="+notes">{{ $t('sorts.notesDesc') }}</option>
<option value="-users">{{ $t('sorts.usersAsc') }}</option>
<option value="+users">{{ $t('sorts.usersDesc') }}</option>
<option value="-following">{{ $t('sorts.followingAsc') }}</option>
<option value="+following">{{ $t('sorts.followingDesc') }}</option>
<option value="-followers">{{ $t('sorts.followersAsc') }}</option>
<option value="+followers">{{ $t('sorts.followersDesc') }}</option>
<option value="-driveUsage">{{ $t('sorts.driveUsageAsc') }}</option>
<option value="+driveUsage">{{ $t('sorts.driveUsageDesc') }}</option>
<option value="-driveFiles">{{ $t('sorts.driveFilesAsc') }}</option>
<option value="+driveFiles">{{ $t('sorts.driveFilesDesc') }}</option>
</ui-select>
<ui-select v-model="state">
<template #label>{{ $t('state') }}</template>
<option value="all">{{ $t('states.all') }}</option>
<option value="blocked">{{ $t('states.blocked') }}</option>
<option value="notResponding">{{ $t('states.not-responding') }}</option>
<option value="markedAsClosed">{{ $t('states.marked-as-closed') }}</option>
</ui-select>
</ui-horizon-group>
<div class="instances">
<header>
<span>{{ $t('host') }}</span>
<span>{{ $t('notes') }}</span>
<span>{{ $t('users') }}</span>
<span>{{ $t('following') }}</span>
<span>{{ $t('followers') }}</span>
<span>{{ $t('status') }}</span>
</header>
<div v-for="instance in instances" :style="{ opacity: instance.isNotResponding ? 0.5 : 1 }">
<a @click.prevent="showInstance(instance.host)" rel="nofollow noopener" target="_blank" :href="`https://${instance.host}`" :style="{ textDecoration: instance.isMarkedAsClosed ? 'line-through' : 'none' }">{{ instance.host }}</a>
<span>{{ instance.notesCount | number }}</span>
<span>{{ instance.usersCount | number }}</span>
<span>{{ instance.followingCount | number }}</span>
<span>{{ instance.followersCount | number }}</span>
<span>{{ instance.latestStatus }}</span>
</div>
</div>
<ui-info v-if="instances.length == limit">{{ $t('result-is-truncated', { n: limit }) }}</ui-info>
</section>
</ui-card>
<ui-card>
<template #title><fa :icon="faBan"/> {{ $t('blocked-hosts') }}</template>
<section class="fit-top">
<ui-textarea v-model="blockedHosts">
<template #desc>{{ $t('blocked-hosts-info') }}</template>
</ui-textarea>
<ui-button @click="saveBlockedHosts">{{ $t('save') }}</ui-button>
</section>
</ui-card>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import i18n from '../../i18n';
import { faPaperPlane } from '@fortawesome/free-regular-svg-icons';
import { faTrashAlt, faBan, faGlobe, faTerminal, faSearch, faMinusCircle, faServer, faCrosshairs, faEnvelopeOpenText, faUsers, faCaretDown, faCaretUp, faTrafficLight, faInbox } from '@fortawesome/free-solid-svg-icons';
import ApexCharts from 'apexcharts';
import * as tinycolor from 'tinycolor2';
const chartLimit = 90;
const sum = (...arr) => arr.reduce((r, a) => r.map((b, i) => a[i] + b));
const negate = arr => arr.map(x => -x);
export default Vue.extend({
i18n: i18n('admin/views/federation.vue'),
filters: {
date: v => v ? new Date(v).toLocaleString() : 'N/A'
},
data() {
return {
instance: null,
target: null,
sort: '+lastCommunicatedAt',
state: 'all',
limit: 100,
instances: [],
chart: null,
chartSrc: 'requests',
chartSpan: 'hour',
chartInstance: null,
blockedHosts: '',
faTrashAlt, faBan, faGlobe, faTerminal, faSearch, faMinusCircle, faServer, faCrosshairs, faEnvelopeOpenText, faUsers, faCaretDown, faCaretUp, faPaperPlane, faTrafficLight, faInbox
};
},
computed: {
data(): any {
if (this.chart == null) return null;
switch (this.chartSrc) {
case 'requests': return this.requestsChart();
case 'users': return this.usersChart(false);
case 'users-total': return this.usersChart(true);
case 'notes': return this.notesChart(false);
case 'notes-total': return this.notesChart(true);
case 'ff': return this.ffChart(false);
case 'ff-total': return this.ffChart(true);
case 'drive-usage': return this.driveUsageChart(false);
case 'drive-usage-total': return this.driveUsageChart(true);
case 'drive-files': return this.driveFilesChart(false);
case 'drive-files-total': return this.driveFilesChart(true);
}
},
stats(): any[] {
const stats =
this.chartSpan == 'day' ? this.chart.perDay :
this.chartSpan == 'hour' ? this.chart.perHour :
null;
return stats;
}
},
watch: {
sort() {
this.fetchInstances();
},
state() {
this.fetchInstances();
},
async instance() {
this.now = new Date();
const [perHour, perDay] = await Promise.all([
this.$root.api('charts/instance', { host: this.instance.host, limit: chartLimit, span: 'hour' }),
this.$root.api('charts/instance', { host: this.instance.host, limit: chartLimit, span: 'day' }),
]);
const chart = {
perHour: perHour,
perDay: perDay
};
this.chart = chart;
this.renderChart();
},
chartSrc() {
this.renderChart();
},
chartSpan() {
this.renderChart();
}
},
mounted() {
this.fetchInstances();
this.$root.getMeta().then(meta => {
this.blockedHosts = meta.blockedHosts.join('\n');
});
},
beforeDestroy() {
this.chartInstance.destroy();
},
methods: {
showInstance(target?: string) {
this.$root.api('federation/show-instance', {
host: target || this.target
}).then(instance => {
if (instance == null) {
this.$root.dialog({
type: 'error',
text: this.$t('instance-not-registered')
});
} else {
this.instance = instance;
this.target = '';
}
});
},
fetchInstances() {
this.instances = [];
this.$root.api('federation/instances', {
blocked: this.state === 'blocked' ? true : null,
notResponding: this.state === 'notResponding' ? true : null,
markedAsClosed: this.state === 'markedAsClosed' ? true : null,
sort: this.sort,
limit: this.limit
}).then(instances => {
this.instances = instances;
});
},
removeAllFollowing() {
this.$root.api('admin/federation/remove-all-following', {
host: this.instance.host
}).then(() => {
this.$root.dialog({
type: 'success',
splash: true
});
});
},
deleteAllFiles() {
this.$root.api('admin/federation/delete-all-files', {
host: this.instance.host
}).then(() => {
this.$root.dialog({
type: 'success',
splash: true
});
});
},
updateInstance() {
this.$root.api('admin/federation/update-instance', {
host: this.instance.host,
isBlocked: this.instance.isBlocked || false,
isClosed: this.instance.isMarkedAsClosed || false
});
},
setSrc(src) {
this.chartSrc = src;
},
renderChart() {
if (this.chartInstance) {
this.chartInstance.destroy();
}
this.chartInstance = new ApexCharts(this.$refs.chart, {
chart: {
type: 'area',
height: 300,
animations: {
dynamicAnimation: {
enabled: false
}
},
toolbar: {
show: false
},
zoom: {
enabled: false
}
},
dataLabels: {
enabled: false
},
grid: {
clipMarkers: false,
borderColor: 'rgba(0, 0, 0, 0.1)'
},
stroke: {
curve: 'straight',
width: 2
},
tooltip: {
theme: this.$store.state.device.darkmode ? 'dark' : 'light'
},
legend: {
labels: {
colors: tinycolor(getComputedStyle(document.documentElement).getPropertyValue('--text')).toRgbString()
},
},
xaxis: {
type: 'datetime',
labels: {
style: {
colors: tinycolor(getComputedStyle(document.documentElement).getPropertyValue('--text')).toRgbString()
}
},
axisBorder: {
color: 'rgba(0, 0, 0, 0.1)'
},
axisTicks: {
color: 'rgba(0, 0, 0, 0.1)'
},
},
yaxis: {
labels: {
formatter: this.data.bytes ? v => Vue.filter('bytes')(v, 0) : v => Vue.filter('number')(v),
style: {
color: tinycolor(getComputedStyle(document.documentElement).getPropertyValue('--text')).toRgbString()
}
}
},
series: this.data.series
});
this.chartInstance.render();
},
getDate(i: number) {
const y = this.now.getFullYear();
const m = this.now.getMonth();
const d = this.now.getDate();
const h = this.now.getHours();
return (
this.chartSpan == 'day' ? new Date(y, m, d - i) :
this.chartSpan == 'hour' ? new Date(y, m, d, h - i) :
null
);
},
format(arr) {
return arr.map((v, i) => ({ x: this.getDate(i).getTime(), y: v }));
},
requestsChart(): any {
return {
series: [{
name: 'Incoming',
data: this.format(this.stats.requests.received)
}, {
name: 'Outgoing (succeeded)',
data: this.format(this.stats.requests.succeeded)
}, {
name: 'Outgoing (failed)',
data: this.format(this.stats.requests.failed)
}]
};
},
usersChart(total: boolean): any {
return {
series: [{
name: 'Users',
type: 'area',
data: this.format(total
? this.stats.users.total
: sum(this.stats.users.inc, negate(this.stats.users.dec))
)
}]
};
},
notesChart(total: boolean): any {
return {
series: [{
name: 'Notes',
type: 'area',
data: this.format(total
? this.stats.notes.total
: sum(this.stats.notes.inc, negate(this.stats.notes.dec))
)
}]
};
},
ffChart(total: boolean): any {
return {
series: [{
name: 'Following',
type: 'area',
data: this.format(total
? this.stats.following.total
: sum(this.stats.following.inc, negate(this.stats.following.dec))
)
}, {
name: 'Followers',
type: 'area',
data: this.format(total
? this.stats.followers.total
: sum(this.stats.followers.inc, negate(this.stats.followers.dec))
)
}]
};
},
driveUsageChart(total: boolean): any {
return {
bytes: true,
series: [{
name: 'Drive usage',
type: 'area',
data: this.format(total
? this.stats.drive.totalUsage
: sum(this.stats.drive.incUsage, negate(this.stats.drive.decUsage))
)
}]
};
},
driveFilesChart(total: boolean): any {
return {
series: [{
name: 'Drive files',
type: 'area',
data: this.format(total
? this.stats.drive.totalFiles
: sum(this.stats.drive.incFiles, negate(this.stats.drive.decFiles))
)
}]
};
},
saveBlockedHosts() {
this.$root.api('admin/update-meta', {
blockedHosts: this.blockedHosts ? this.blockedHosts.split('\n') : []
}).then(() => {
this.$root.dialog({
type: 'success',
text: this.$t('saved')
});
}).catch(e => {
this.$root.dialog({
type: 'error',
text: e
});
});
}
}
});
</script>
<style lang="stylus" scoped>
.target
margin-bottom 16px !important
.instances
width 100%
> header
display flex
> *
color var(--text)
font-weight bold
> div
display flex
> * > *
flex 1
overflow auto
&:first-child
min-width 200px
</style>

View File

@ -1,297 +0,0 @@
<template>
<div class="mk-admin" :class="{ isMobile }">
<header v-show="isMobile">
<button class="nav" @click="navOpend = true"><fa icon="bars"/></button>
<span>MisskeyMyAdmin</span>
</header>
<div class="nav-backdrop"
v-if="navOpend && isMobile"
@click="navOpend = false"
@touchstart="navOpend = false"
></div>
<nav v-show="navOpend">
<div class="mi">
<img svg-inline src="../assets/header-icon.svg"/>
</div>
<div class="me">
<img class="avatar" :src="$store.state.i.avatarUrl" alt="avatar"/>
<p class="name"><mk-user-name :user="$store.state.i"/></p>
</div>
<ul>
<li><router-link to="/dashboard" active-class="active"><fa icon="home" fixed-width/>{{ $t('dashboard') }}</router-link></li>
<li><router-link to="/instance" active-class="active"><fa icon="cog" fixed-width/>{{ $t('instance') }}</router-link></li>
<li><router-link to="/queue" active-class="active"><fa :icon="faTasks" fixed-width/>{{ $t('queue') }}</router-link></li>
<li><router-link to="/logs" active-class="active"><fa :icon="faStream" fixed-width/>{{ $t('logs') }}</router-link></li>
<li><router-link to="/db" active-class="active"><fa :icon="faDatabase" fixed-width/>{{ $t('db') }}</router-link></li>
<li><router-link to="/moderators" active-class="active"><fa :icon="faHeadset" fixed-width/>{{ $t('moderators') }}</router-link></li>
<li><router-link to="/users" active-class="active"><fa icon="users" fixed-width/>{{ $t('users') }}</router-link></li>
<li><router-link to="/drive" active-class="active"><fa icon="cloud" fixed-width/>{{ $t('@.drive') }}</router-link></li>
<li><router-link to="/federation" active-class="active"><fa :icon="faGlobe" fixed-width/>{{ $t('federation') }}</router-link></li>
<li><router-link to="/emoji" active-class="active"><fa :icon="faGrin" fixed-width/>{{ $t('emoji') }}</router-link></li>
<li><router-link to="/announcements" active-class="active"><fa icon="broadcast-tower" fixed-width/>{{ $t('announcements') }}</router-link></li>
<li><router-link to="/abuse" active-class="active"><fa :icon="faExclamationCircle" fixed-width/>{{ $t('abuse') }}</router-link></li>
</ul>
<div class="back-to-misskey">
<a href="/"><fa :icon="faArrowLeft"/> {{ $t('back-to-misskey') }}</a>
</div>
<div class="version">
<small>Misskey {{ version }}</small>
</div>
</nav>
<main>
<div class="page">
<div v-if="page == 'dashboard'"><x-dashboard/></div>
<div v-if="page == 'instance'"><x-instance/></div>
<div v-if="page == 'queue'"><x-queue/></div>
<div v-if="page == 'logs'"><x-logs/></div>
<div v-if="page == 'db'"><x-db/></div>
<div v-if="page == 'moderators'"><x-moderators/></div>
<div v-if="page == 'users'"><x-users/></div>
<div v-if="page == 'emoji'"><x-emoji/></div>
<div v-if="page == 'announcements'"><x-announcements/></div>
<div v-if="page == 'drive'"><x-drive/></div>
<div v-if="page == 'federation'"><x-federation/></div>
<div v-if="page == 'abuse'"><x-abuse/></div>
</div>
</main>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import i18n from '../../i18n';
import { version } from '../../config';
import XDashboard from './dashboard.vue';
import XInstance from './instance.vue';
import XQueue from './queue.vue';
import XLogs from './logs.vue';
import XDb from './db.vue';
import XModerators from './moderators.vue';
import XEmoji from './emoji.vue';
import XAnnouncements from './announcements.vue';
import XUsers from './users.vue';
import XDrive from './drive.vue';
import XAbuse from './abuse.vue';
import XFederation from './federation.vue';
import { faHeadset, faArrowLeft, faGlobe, faExclamationCircle, faTasks, faStream, faDatabase } from '@fortawesome/free-solid-svg-icons';
import { faGrin } from '@fortawesome/free-regular-svg-icons';
// Detect the user agent
const ua = navigator.userAgent.toLowerCase();
const isMobile = /mobile|iphone|ipad|android/.test(ua);
export default Vue.extend({
i18n: i18n('admin/views/index.vue'),
components: {
XDashboard,
XInstance,
XQueue,
XLogs,
XDb,
XModerators,
XEmoji,
XAnnouncements,
XUsers,
XDrive,
XAbuse,
XFederation,
},
provide: {
isMobile
},
data() {
return {
version,
isMobile,
navOpend: !isMobile,
faGrin,
faArrowLeft,
faHeadset,
faGlobe,
faExclamationCircle,
faTasks,
faStream,
faDatabase,
};
},
computed: {
page() {
return this.$route.params.page;
}
}
});
</script>
<style lang="stylus" scoped>
.mk-admin
$headerHeight = 48px
display flex
height 100%
> header
position fixed
top 0
z-index 10000
width 100%
color var(--mobileHeaderFg)
background-color var(--mobileHeaderBg)
box-shadow 0 1px 0 rgba(#000, 0.075)
&, *
user-select none
> span
display block
line-height $headerHeight
text-align center
> .nav
display block
position absolute
top 0
left 0
z-index 10001
padding 0
width $headerHeight
font-size 1.4em
line-height $headerHeight
border-right solid 1px rgba(#000, 0.1)
> [data-icon]
transition all 0.2s ease
> nav
position fixed
z-index 20001
top 0
left 0
width 250px
height 100vh
overflow auto
background #333
color #fff
> .mi
text-align center
> svg
width 24px
height 82px
vertical-align top
fill #fff
opacity 0.7
> .me
display flex
margin 0 16px 16px 16px
padding 16px 0
align-items center
border-top solid 1px #555
border-bottom solid 1px #555
> .avatar
height 48px
border-radius 100%
vertical-align middle
> .name
margin 0 16px
padding 0
color #fff
overflow hidden
text-overflow ellipsis
white-space nowrap
font-size 15px
> .back-to-misskey
margin 16px 16px 0 16px
padding 0
border-top solid 1px #555
> a
display block
padding 16px 4px
color inherit
text-decoration none
color #eee
font-size 15px
&:hover
color #fff
> [data-icon]
margin-right 6px
> .version
margin 0 16px 16px 16px
padding-top 16px
border-top solid 1px #555
text-align center
> small
opacity 0.7
> ul
margin 0
padding 0
list-style none
font-size 15px
> li > a
display block
padding 10px 16px
margin 0
user-select none
color #eee
transition margin-left 0.2s ease
&:hover
color #fff
> [data-icon]
margin-right 6px
&.active
margin-left 8px
color var(--primary) !important
&:after
content ""
display block
position absolute
top 0
right 0
bottom 0
margin auto 0
height 0
border-top solid 16px transparent
border-right solid 16px var(--bg)
border-bottom solid 16px transparent
border-left solid 16px transparent
> .nav-backdrop
position fixed
top 0
left 0
z-index 20000
width 100%
height 100%
background var(--mobileNavBackdrop)
> main
width 100%
padding 0 0 0 250px
> .page
max-width 1150px
@media (min-width 500px)
padding 16px
&.isMobile
> main
padding $headerHeight 0 0 0
</style>

View File

@ -1,523 +0,0 @@
<template>
<div>
<ui-card>
<template #title><fa icon="cog"/> {{ $t('instance') }}</template>
<section class="fit-top">
<ui-input :value="host" readonly>{{ $t('host') }}</ui-input>
<ui-input v-model="name">{{ $t('instance-name') }}</ui-input>
<ui-textarea v-model="description">{{ $t('instance-description') }}</ui-textarea>
<ui-input v-model="iconUrl"><template #icon><fa icon="link"/></template>{{ $t('icon-url') }}</ui-input>
<ui-input v-model="mascotImageUrl"><template #icon><fa icon="link"/></template>{{ $t('logo-url') }}</ui-input>
<ui-input v-model="bannerUrl"><template #icon><fa icon="link"/></template>{{ $t('banner-url') }}</ui-input>
<ui-input v-model="ToSUrl"><template #icon><fa icon="link"/></template>{{ $t('tos-url') }}</ui-input>
<details>
<summary>{{ $t('advanced-config') }}</summary>
<ui-input v-model="errorImageUrl"><template #icon><fa icon="link"/></template>{{ $t('error-image-url') }}</ui-input>
<ui-input v-model="languages"><template #icon><fa icon="language"/></template>{{ $t('languages') }}<template #desc>{{ $t('languages-desc') }}</template></ui-input>
<ui-input v-model="repositoryUrl"><template #icon><fa icon="link"/></template>{{ $t('repository-url') }}</ui-input>
<ui-input v-model="feedbackUrl"><template #icon><fa icon="link"/></template>{{ $t('feedback-url') }}</ui-input>
</details>
</section>
<section class="fit-bottom">
<header><fa :icon="faHeadset"/> {{ $t('maintainer-config') }}</header>
<ui-input v-model="maintainerName">{{ $t('maintainer-name') }}</ui-input>
<ui-input v-model="maintainerEmail" type="email"><template #icon><fa :icon="farEnvelope"/></template>{{ $t('maintainer-email') }}</ui-input>
</section>
<section>
<ui-switch v-model="disableRegistration">{{ $t('disable-registration') }}</ui-switch>
<ui-button v-if="disableRegistration" @click="invite">{{ $t('invite') }}</ui-button>
</section>
<section>
<ui-button @click="updateMeta"><fa :icon="faSave"/> {{ $t('save') }}</ui-button>
</section>
</ui-card>
<ui-card>
<template #title><fa :icon="faPencilAlt"/> {{ $t('note-and-tl') }}</template>
<section class="fit-top fit-bottom">
<ui-input v-model="maxNoteTextLength">{{ $t('max-note-text-length') }}</ui-input>
</section>
<section>
<ui-switch v-model="disableLocalTimeline">{{ $t('disable-local-timeline') }}</ui-switch>
<ui-switch v-model="disableGlobalTimeline">{{ $t('disable-global-timeline') }}</ui-switch>
<ui-info>{{ $t('disabling-timelines-info') }}</ui-info>
</section>
<section>
<ui-switch v-model="enableEmojiReaction">{{ $t('enable-emoji-reaction') }}</ui-switch>
<ui-switch v-model="useStarForReactionFallback">{{ $t('use-star-for-reaction-fallback') }}</ui-switch>
</section>
<section>
<ui-button @click="updateMeta"><fa :icon="faSave"/> {{ $t('save') }}</ui-button>
</section>
</ui-card>
<ui-card>
<template #title><fa icon="cloud"/> {{ $t('drive-config') }}</template>
<section>
<ui-switch v-model="useObjectStorage">{{ $t('use-object-storage') }}</ui-switch>
<template v-if="useObjectStorage">
<ui-info>
<i18n path="object-storage-s3-info">
<a href="https://docs.aws.amazon.com/general/latest/gr/rande.html" target="_blank">{{ $t('object-storage-s3-info-here') }}</a>
</i18n>
</ui-info>
<ui-info>{{ $t('object-storage-gcs-info') }}</ui-info>
<ui-input v-model="objectStorageBaseUrl" :disabled="!useObjectStorage">{{ $t('object-storage-base-url') }}</ui-input>
<ui-horizon-group inputs>
<ui-input v-model="objectStorageBucket" :disabled="!useObjectStorage">{{ $t('object-storage-bucket') }}</ui-input>
<ui-input v-model="objectStoragePrefix" :disabled="!useObjectStorage">{{ $t('object-storage-prefix') }}</ui-input>
</ui-horizon-group>
<ui-input v-model="objectStorageEndpoint" :disabled="!useObjectStorage">{{ $t('object-storage-endpoint') }}</ui-input>
<ui-horizon-group inputs>
<ui-input v-model="objectStorageRegion" :disabled="!useObjectStorage">{{ $t('object-storage-region') }}</ui-input>
<ui-input v-model="objectStoragePort" type="number" :disabled="!useObjectStorage">{{ $t('object-storage-port') }}</ui-input>
</ui-horizon-group>
<ui-horizon-group inputs>
<ui-input v-model="objectStorageAccessKey" :disabled="!useObjectStorage"><template #icon><fa icon="key"/></template>{{ $t('object-storage-access-key') }}</ui-input>
<ui-input v-model="objectStorageSecretKey" :disabled="!useObjectStorage"><template #icon><fa icon="key"/></template>{{ $t('object-storage-secret-key') }}</ui-input>
</ui-horizon-group>
<ui-switch v-model="objectStorageUseSSL" :disabled="!useObjectStorage">{{ $t('object-storage-use-ssl') }}</ui-switch>
</template>
</section>
<section>
<ui-switch v-model="cacheRemoteFiles">{{ $t('cache-remote-files') }}<template #desc>{{ $t('cache-remote-files-desc') }}</template></ui-switch>
<ui-switch v-model="proxyRemoteFiles">{{ $t('proxy-remote-files') }}<template #desc>{{ $t('proxy-remote-files-desc') }}</template></ui-switch>
</section>
<section class="fit-top fit-bottom">
<ui-input v-model="localDriveCapacityMb" type="number">{{ $t('local-drive-capacity-mb') }}<template #suffix>MB</template><template #desc>{{ $t('mb') }}</template></ui-input>
<ui-input v-model="remoteDriveCapacityMb" type="number" :disabled="!cacheRemoteFiles">{{ $t('remote-drive-capacity-mb') }}<template #suffix>MB</template><template #desc>{{ $t('mb') }}</template></ui-input>
</section>
<section>
<ui-button @click="updateMeta"><fa :icon="faSave"/> {{ $t('save') }}</ui-button>
</section>
</ui-card>
<ui-card>
<template #title><fa :icon="faThumbtack"/> {{ $t('pinned-users') }}</template>
<section class="fit-top">
<ui-textarea v-model="pinnedUsers">
<template #desc>{{ $t('pinned-users-info') }}</template>
</ui-textarea>
<ui-button @click="updateMeta"><fa :icon="faSave"/> {{ $t('save') }}</ui-button>
</section>
</ui-card>
<ui-card>
<template #title><fa :icon="faGhost"/> {{ $t('proxy-account-config') }}</template>
<section>
<ui-info>{{ $t('proxy-account-info') }}</ui-info>
<ui-input v-model="proxyAccount"><template #prefix>@</template>{{ $t('proxy-account-username') }}<template #desc>{{ $t('proxy-account-username-desc') }}</template></ui-input>
<ui-info warn>{{ $t('proxy-account-warn') }}</ui-info>
</section>
<section>
<ui-button @click="updateMeta"><fa :icon="faSave"/> {{ $t('save') }}</ui-button>
</section>
</ui-card>
<ui-card>
<template #title><fa :icon="farEnvelope"/> {{ $t('email-config') }}</template>
<section>
<ui-switch v-model="enableEmail">{{ $t('enable-email') }}<template #desc>{{ $t('email-config-info') }}</template></ui-switch>
<template v-if="enableEmail">
<ui-input v-model="email" type="email" :disabled="!enableEmail">{{ $t('email') }}</ui-input>
<ui-horizon-group inputs>
<ui-input v-model="smtpHost" :disabled="!enableEmail">{{ $t('smtp-host') }}</ui-input>
<ui-input v-model="smtpPort" type="number" :disabled="!enableEmail">{{ $t('smtp-port') }}</ui-input>
</ui-horizon-group>
<ui-switch v-model="smtpAuth">{{ $t('smtp-auth') }}</ui-switch>
<ui-horizon-group inputs>
<ui-input v-model="smtpUser" :disabled="!enableEmail || !smtpAuth">{{ $t('smtp-user') }}</ui-input>
<ui-input v-model="smtpPass" type="password" :with-password-toggle="true" :disabled="!enableEmail || !smtpAuth">{{ $t('smtp-pass') }}</ui-input>
</ui-horizon-group>
<ui-switch v-model="smtpSecure" :disabled="!enableEmail">{{ $t('smtp-secure') }}<template #desc>{{ $t('smtp-secure-info') }}</template></ui-switch>
<ui-button @click="testEmail()">{{ $t('test-email') }}</ui-button>
</template>
</section>
<section>
<ui-button @click="updateMeta"><fa :icon="faSave"/> {{ $t('save') }}</ui-button>
</section>
</ui-card>
<ui-card>
<template #title><fa :icon="faBolt"/> {{ $t('serviceworker-config') }}</template>
<section>
<ui-switch v-model="enableServiceWorker">{{ $t('enable-serviceworker') }}<template #desc>{{ $t('serviceworker-info') }}</template></ui-switch>
<template v-if="enableServiceWorker">
<ui-info>{{ $t('vapid-info') }}<br><code>npm i web-push -g<br>web-push generate-vapid-keys</code></ui-info>
<ui-horizon-group inputs class="fit-bottom">
<ui-input v-model="swPublicKey" :disabled="!enableServiceWorker"><template #icon><fa icon="key"/></template>{{ $t('vapid-publickey') }}</ui-input>
<ui-input v-model="swPrivateKey" :disabled="!enableServiceWorker"><template #icon><fa icon="key"/></template>{{ $t('vapid-privatekey') }}</ui-input>
</ui-horizon-group>
</template>
</section>
<section>
<ui-button @click="updateMeta"><fa :icon="faSave"/> {{ $t('save') }}</ui-button>
</section>
</ui-card>
<ui-card>
<template #title><fa :icon="faShieldAlt"/> {{ $t('recaptcha-config') }}</template>
<section :class="enableRecaptcha ? 'fit-bottom' : ''">
<ui-switch v-model="enableRecaptcha">{{ $t('enable-recaptcha') }}</ui-switch>
<template v-if="enableRecaptcha">
<ui-info>{{ $t('recaptcha-info') }}</ui-info>
<ui-info warn>{{ $t('recaptcha-info2') }}</ui-info>
<ui-horizon-group inputs>
<ui-input v-model="recaptchaSiteKey" :disabled="!enableRecaptcha"><template #icon><fa icon="key"/></template>{{ $t('recaptcha-site-key') }}</ui-input>
<ui-input v-model="recaptchaSecretKey" :disabled="!enableRecaptcha"><template #icon><fa icon="key"/></template>{{ $t('recaptcha-secret-key') }}</ui-input>
</ui-horizon-group>
</template>
</section>
<section v-if="enableRecaptcha && recaptchaSiteKey">
<header>{{ $t('recaptcha-preview') }}</header>
<div ref="recaptcha" style="margin: 16px 0 0 0;" :key="recaptchaSiteKey"></div>
</section>
<section>
<ui-button @click="updateMeta"><fa :icon="faSave"/> {{ $t('save') }}</ui-button>
</section>
</ui-card>
<ui-card>
<template #title><fa :icon="faShieldAlt"/> {{ $t('external-service-integration-config') }}</template>
<section>
<header><fa :icon="['fab', 'twitter']"/> {{ $t('twitter-integration-config') }}</header>
<ui-switch v-model="enableTwitterIntegration">{{ $t('enable-twitter-integration') }}</ui-switch>
<template v-if="enableTwitterIntegration">
<ui-horizon-group>
<ui-input v-model="twitterConsumerKey" :disabled="!enableTwitterIntegration"><template #icon><fa icon="key"/></template>{{ $t('twitter-integration-consumer-key') }}</ui-input>
<ui-input v-model="twitterConsumerSecret" :disabled="!enableTwitterIntegration"><template #icon><fa icon="key"/></template>{{ $t('twitter-integration-consumer-secret') }}</ui-input>
</ui-horizon-group>
<ui-info>{{ $t('twitter-integration-info', { url: `${url}/api/tw/cb` }) }}</ui-info>
</template>
</section>
<section>
<header><fa :icon="['fab', 'github']"/> {{ $t('github-integration-config') }}</header>
<ui-switch v-model="enableGithubIntegration">{{ $t('enable-github-integration') }}</ui-switch>
<template v-if="enableGithubIntegration">
<ui-horizon-group>
<ui-input v-model="githubClientId" :disabled="!enableGithubIntegration"><template #icon><fa icon="key"/></template>{{ $t('github-integration-client-id') }}</ui-input>
<ui-input v-model="githubClientSecret" :disabled="!enableGithubIntegration"><template #icon><fa icon="key"/></template>{{ $t('github-integration-client-secret') }}</ui-input>
</ui-horizon-group>
<ui-info>{{ $t('github-integration-info', { url: `${url}/api/gh/cb` }) }}</ui-info>
</template>
</section>
<section>
<header><fa :icon="['fab', 'discord']"/> {{ $t('discord-integration-config') }}</header>
<ui-switch v-model="enableDiscordIntegration">{{ $t('enable-discord-integration') }}</ui-switch>
<template v-if="enableDiscordIntegration">
<ui-horizon-group>
<ui-input v-model="discordClientId" :disabled="!enableDiscordIntegration"><template #icon><fa icon="key"/></template>{{ $t('discord-integration-client-id') }}</ui-input>
<ui-input v-model="discordClientSecret" :disabled="!enableDiscordIntegration"><template #icon><fa icon="key"/></template>{{ $t('discord-integration-client-secret') }}</ui-input>
</ui-horizon-group>
<ui-info>{{ $t('discord-integration-info', { url: `${url}/api/dc/cb` }) }}</ui-info>
</template>
</section>
<section>
<ui-button @click="updateMeta"><fa :icon="faSave"/> {{ $t('save') }}</ui-button>
</section>
</ui-card>
<details>
<summary style="color:var(--text);">{{ $t('advanced-config') }}</summary>
<ui-card>
<template #title><fa :icon="faHashtag"/> {{ $t('hidden-tags') }}</template>
<section class="fit-top">
<ui-textarea v-model="hiddenTags">
<template #desc>{{ $t('hidden-tags-info') }}</template>
</ui-textarea>
<ui-button @click="updateMeta"><fa :icon="faSave"/> {{ $t('save') }}</ui-button>
</section>
</ui-card>
<ui-card>
<template #title>summaly Proxy</template>
<section class="fit-top fit-bottom">
<ui-input v-model="summalyProxy">URL</ui-input>
</section>
<section>
<ui-button @click="updateMeta"><fa :icon="faSave"/> {{ $t('save') }}</ui-button>
</section>
</ui-card>
</details>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import i18n from '../../i18n';
import { url, host } from '../../config';
import { toUnicode } from 'punycode';
import { faHeadset, faShieldAlt, faGhost, faUserPlus, faBolt, faThumbtack, faPencilAlt, faHashtag } from '@fortawesome/free-solid-svg-icons';
import { faEnvelope as farEnvelope, faSave } from '@fortawesome/free-regular-svg-icons';
export default Vue.extend({
i18n: i18n('admin/views/instance.vue'),
data() {
return {
url,
host: toUnicode(host),
maintainerName: null,
maintainerEmail: null,
ToSUrl: null,
repositoryUrl: "https://github.com/syuilo/misskey",
feedbackUrl: null,
disableRegistration: false,
disableLocalTimeline: false,
disableGlobalTimeline: false,
enableEmojiReaction: true,
useStarForReactionFallback: false,
mascotImageUrl: null,
bannerUrl: null,
errorImageUrl: null,
iconUrl: null,
name: null,
description: null,
languages: null,
cacheRemoteFiles: false,
proxyRemoteFiles: false,
localDriveCapacityMb: null,
remoteDriveCapacityMb: null,
maxNoteTextLength: null,
enableRecaptcha: false,
recaptchaSiteKey: null,
recaptchaSecretKey: null,
enableTwitterIntegration: false,
twitterConsumerKey: null,
twitterConsumerSecret: null,
enableGithubIntegration: false,
githubClientId: null,
githubClientSecret: null,
enableDiscordIntegration: false,
discordClientId: null,
discordClientSecret: null,
proxyAccount: null,
summalyProxy: null,
enableEmail: false,
email: null,
smtpSecure: false,
smtpHost: null,
smtpPort: null,
smtpUser: null,
smtpPass: null,
smtpAuth: false,
enableServiceWorker: false,
swPublicKey: null,
swPrivateKey: null,
pinnedUsers: '',
hiddenTags: '',
useObjectStorage: false,
objectStorageBaseUrl: null,
objectStorageBucket: null,
objectStoragePrefix: null,
objectStorageEndpoint: null,
objectStorageRegion: null,
objectStoragePort: null,
objectStorageAccessKey: null,
objectStorageSecretKey: null,
objectStorageUseSSL: false,
faHeadset, faShieldAlt, faGhost, faUserPlus, farEnvelope, faBolt, faThumbtack, faPencilAlt, faSave, faHashtag
};
},
created() {
this.$root.getMeta(true).then(meta => {
this.maintainerName = meta.maintainerName;
this.maintainerEmail = meta.maintainerEmail;
this.ToSUrl = meta.ToSUrl;
this.repositoryUrl = meta.repositoryUrl;
this.feedbackUrl = meta.feedbackUrl;
this.disableRegistration = meta.disableRegistration;
this.disableLocalTimeline = meta.disableLocalTimeline;
this.disableGlobalTimeline = meta.disableGlobalTimeline;
this.enableEmojiReaction = meta.enableEmojiReaction;
this.useStarForReactionFallback = meta.useStarForReactionFallback;
this.mascotImageUrl = meta.mascotImageUrl;
this.bannerUrl = meta.bannerUrl;
this.errorImageUrl = meta.errorImageUrl;
this.iconUrl = meta.iconUrl;
this.name = meta.name;
this.description = meta.description;
this.languages = meta.langs.join(' ');
this.cacheRemoteFiles = meta.cacheRemoteFiles;
this.proxyRemoteFiles = meta.proxyRemoteFiles;
this.localDriveCapacityMb = meta.driveCapacityPerLocalUserMb;
this.remoteDriveCapacityMb = meta.driveCapacityPerRemoteUserMb;
this.maxNoteTextLength = meta.maxNoteTextLength;
this.enableRecaptcha = meta.enableRecaptcha;
this.recaptchaSiteKey = meta.recaptchaSiteKey;
this.recaptchaSecretKey = meta.recaptchaSecretKey;
this.proxyAccount = meta.proxyAccount;
this.enableTwitterIntegration = meta.enableTwitterIntegration;
this.twitterConsumerKey = meta.twitterConsumerKey;
this.twitterConsumerSecret = meta.twitterConsumerSecret;
this.enableGithubIntegration = meta.enableGithubIntegration;
this.githubClientId = meta.githubClientId;
this.githubClientSecret = meta.githubClientSecret;
this.enableDiscordIntegration = meta.enableDiscordIntegration;
this.discordClientId = meta.discordClientId;
this.discordClientSecret = meta.discordClientSecret;
this.summalyProxy = meta.summalyProxy;
this.enableEmail = meta.enableEmail;
this.email = meta.email;
this.smtpSecure = meta.smtpSecure;
this.smtpHost = meta.smtpHost;
this.smtpPort = meta.smtpPort;
this.smtpUser = meta.smtpUser;
this.smtpPass = meta.smtpPass;
this.smtpAuth = meta.smtpUser != null && meta.smtpUser !== '';
this.enableServiceWorker = meta.enableServiceWorker;
this.swPublicKey = meta.swPublickey;
this.swPrivateKey = meta.swPrivateKey;
this.pinnedUsers = meta.pinnedUsers.join('\n');
this.hiddenTags = meta.hiddenTags.join('\n');
this.useObjectStorage = meta.useObjectStorage;
this.objectStorageBaseUrl = meta.objectStorageBaseUrl;
this.objectStorageBucket = meta.objectStorageBucket;
this.objectStoragePrefix = meta.objectStoragePrefix;
this.objectStorageEndpoint = meta.objectStorageEndpoint;
this.objectStorageRegion = meta.objectStorageRegion;
this.objectStoragePort = meta.objectStoragePort;
this.objectStorageAccessKey = meta.objectStorageAccessKey;
this.objectStorageSecretKey = meta.objectStorageSecretKey;
this.objectStorageUseSSL = meta.objectStorageUseSSL;
});
},
mounted() {
const renderRecaptchaPreview = () => {
if (!(window as any).grecaptcha) return;
if (!this.$refs.recaptcha) return;
if (!this.recaptchaSiteKey) return;
(window as any).grecaptcha.render(this.$refs.recaptcha, {
sitekey: this.recaptchaSiteKey
});
};
window.onRecaotchaLoad = () => {
renderRecaptchaPreview();
};
const head = document.getElementsByTagName('head')[0];
const script = document.createElement('script');
script.setAttribute('src', 'https://www.google.com/recaptcha/api.js?onload=onRecaotchaLoad');
head.appendChild(script);
this.$watch('enableRecaptcha', () => {
renderRecaptchaPreview();
});
this.$watch('recaptchaSiteKey', () => {
renderRecaptchaPreview();
});
},
methods: {
invite() {
this.$root.api('admin/invite').then(x => {
this.$root.dialog({
type: 'info',
text: x.code
});
}).catch(e => {
this.$root.dialog({
type: 'error',
text: e
});
});
},
async testEmail() {
this.$root.api('admin/send-email', {
to: this.maintainerEmail,
subject: 'Test email',
text: 'Yo'
}).then(x => {
this.$root.dialog({
type: 'success',
splash: true
});
}).catch(e => {
this.$root.dialog({
type: 'error',
text: e
});
});
},
updateMeta() {
this.$root.api('admin/update-meta', {
maintainerName: this.maintainerName,
maintainerEmail: this.maintainerEmail,
ToSUrl: this.ToSUrl,
repositoryUrl: this.repositoryUrl,
feedbackUrl: this.feedbackUrl,
disableRegistration: this.disableRegistration,
disableLocalTimeline: this.disableLocalTimeline,
disableGlobalTimeline: this.disableGlobalTimeline,
enableEmojiReaction: this.enableEmojiReaction,
useStarForReactionFallback: this.useStarForReactionFallback,
mascotImageUrl: this.mascotImageUrl,
bannerUrl: this.bannerUrl,
errorImageUrl: this.errorImageUrl,
iconUrl: this.iconUrl,
name: this.name,
description: this.description,
langs: this.languages ? this.languages.split(' ') : [],
cacheRemoteFiles: this.cacheRemoteFiles,
proxyRemoteFiles: this.proxyRemoteFiles,
localDriveCapacityMb: parseInt(this.localDriveCapacityMb, 10),
remoteDriveCapacityMb: parseInt(this.remoteDriveCapacityMb, 10),
maxNoteTextLength: parseInt(this.maxNoteTextLength, 10),
enableRecaptcha: this.enableRecaptcha,
recaptchaSiteKey: this.recaptchaSiteKey,
recaptchaSecretKey: this.recaptchaSecretKey,
proxyAccount: this.proxyAccount,
enableTwitterIntegration: this.enableTwitterIntegration,
twitterConsumerKey: this.twitterConsumerKey,
twitterConsumerSecret: this.twitterConsumerSecret,
enableGithubIntegration: this.enableGithubIntegration,
githubClientId: this.githubClientId,
githubClientSecret: this.githubClientSecret,
enableDiscordIntegration: this.enableDiscordIntegration,
discordClientId: this.discordClientId,
discordClientSecret: this.discordClientSecret,
summalyProxy: this.summalyProxy,
enableEmail: this.enableEmail,
email: this.email,
smtpSecure: this.smtpSecure,
smtpHost: this.smtpHost,
smtpPort: parseInt(this.smtpPort, 10),
smtpUser: this.smtpAuth ? this.smtpUser : '',
smtpPass: this.smtpAuth ? this.smtpPass : '',
enableServiceWorker: this.enableServiceWorker,
swPublicKey: this.swPublicKey,
swPrivateKey: this.swPrivateKey,
pinnedUsers: this.pinnedUsers ? this.pinnedUsers.split('\n') : [],
hiddenTags: this.hiddenTags ? this.hiddenTags.split('\n') : [],
useObjectStorage: this.useObjectStorage,
objectStorageBaseUrl: this.objectStorageBaseUrl ? this.objectStorageBaseUrl : null,
objectStorageBucket: this.objectStorageBucket ? this.objectStorageBucket : null,
objectStoragePrefix: this.objectStoragePrefix ? this.objectStoragePrefix : null,
objectStorageEndpoint: this.objectStorageEndpoint ? this.objectStorageEndpoint : null,
objectStorageRegion: this.objectStorageRegion ? this.objectStorageRegion : null,
objectStoragePort: this.objectStoragePort ? this.objectStoragePort : null,
objectStorageAccessKey: this.objectStorageAccessKey ? this.objectStorageAccessKey : null,
objectStorageSecretKey: this.objectStorageSecretKey ? this.objectStorageSecretKey : null,
objectStorageUseSSL: this.objectStorageUseSSL,
}).then(() => {
this.$root.dialog({
type: 'success',
text: this.$t('saved')
});
}).catch(e => {
this.$root.dialog({
type: 'error',
text: e
});
});
}
}
});
</script>

View File

@ -1,119 +0,0 @@
<template>
<div>
<ui-card>
<template #title><fa :icon="faStream"/> {{ $t('logs') }}</template>
<section class="fit-top">
<ui-horizon-group inputs>
<ui-input v-model="domain" :debounce="true">
<span>{{ $t('domain') }}</span>
</ui-input>
<ui-select v-model="level">
<template #label>{{ $t('level') }}</template>
<option value="all">{{ $t('levels.all') }}</option>
<option value="info">{{ $t('levels.info') }}</option>
<option value="success">{{ $t('levels.success') }}</option>
<option value="warning">{{ $t('levels.warning') }}</option>
<option value="error">{{ $t('levels.error') }}</option>
<option value="debug">{{ $t('levels.debug') }}</option>
</ui-select>
</ui-horizon-group>
<div class="nqjzuvev">
<code v-for="log in logs" :key="log.id" :class="log.level">
<details>
<summary><mk-time :time="log.createdAt"/> [{{ log.domain.join('.') }}] {{ log.message }}</summary>
<vue-json-pretty v-if="log.data" :data="log.data"></vue-json-pretty>
</details>
</code>
</div>
<ui-button @click="deleteAll()">{{ $t('delete-all') }}</ui-button>
</section>
</ui-card>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import i18n from '../../i18n';
import { faStream } from '@fortawesome/free-solid-svg-icons';
import VueJsonPretty from 'vue-json-pretty';
export default Vue.extend({
i18n: i18n('admin/views/logs.vue'),
components: {
VueJsonPretty
},
data() {
return {
logs: [],
level: 'all',
domain: '',
faStream
};
},
watch: {
level() {
this.logs = [];
this.fetch();
},
domain() {
this.logs = [];
this.fetch();
}
},
mounted() {
this.fetch();
},
methods: {
fetch() {
this.$root.api('admin/logs', {
level: this.level === 'all' ? null : this.level,
domain: this.domain === '' ? null : this.domain,
limit: 100
}).then(logs => {
this.logs = logs.reverse();
});
},
deleteAll() {
this.$root.api('admin/delete-logs').then(() => {
this.$root.dialog({
type: 'success',
splash: true
});
});
}
}
});
</script>
<style lang="stylus" scoped>
.nqjzuvev
padding 8px
background #000
color #fff
font-size 14px
> code
display block
&.error
color #f00
&.warning
color #ff0
&.success
color #0f0
&.debug
opacity 0.7
</style>

View File

@ -1,127 +0,0 @@
<template>
<div>
<ui-card>
<template #title><fa icon="plus"/> {{ $t('add-moderator.title') }}</template>
<section class="fit-top">
<ui-input v-model="username" type="text">
<template #prefix>@</template>
</ui-input>
<ui-horizon-group>
<ui-button @click="add" :disabled="changing">{{ $t('add-moderator.add') }}</ui-button>
<ui-button @click="remove" :disabled="changing">{{ $t('add-moderator.remove') }}</ui-button>
</ui-horizon-group>
</section>
</ui-card>
<ui-card>
<template #title>{{ $t('logs.title') }}</template>
<section class="fit-top">
<sequential-entrance animation="entranceFromTop" delay="25">
<div v-for="log in logs" :key="log.id" class="">
<ui-horizon-group inputs>
<ui-input :value="log.user | acct" type="text" readonly>
<span>{{ $t('logs.moderator') }}</span>
</ui-input>
<ui-input :value="log.type" type="text" readonly>
<span>{{ $t('logs.type') }}</span>
</ui-input>
<ui-input :value="log.createdAt | date" type="text" readonly>
<span>{{ $t('logs.at') }}</span>
</ui-input>
</ui-horizon-group>
<ui-textarea :value="JSON.stringify(log.info, null, 4)" readonly>
<span>{{ $t('logs.info') }}</span>
</ui-textarea>
</div>
</sequential-entrance>
<ui-button v-if="existMoreLogs" @click="fetchLogs">{{ $t('@.load-more') }}</ui-button>
</section>
</ui-card>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import i18n from '../../i18n';
import parseAcct from "../../../../misc/acct/parse";
export default Vue.extend({
i18n: i18n('admin/views/moderators.vue'),
data() {
return {
username: '',
changing: false,
logs: [],
untilLogId: null,
existMoreLogs: false
};
},
created() {
this.fetchLogs();
},
methods: {
async add() {
this.changing = true;
const process = async () => {
const user = await this.$root.api('users/show', parseAcct(this.username));
await this.$root.api('admin/moderators/add', { userId: user.id });
this.$root.dialog({
type: 'success',
text: this.$t('add-moderator.added')
});
};
await process().catch(e => {
this.$root.dialog({
type: 'error',
text: e.toString()
});
});
this.changing = false;
},
async remove() {
this.changing = true;
const process = async () => {
const user = await this.$root.api('users/show', parseAcct(this.username));
await this.$root.api('admin/moderators/remove', { userId: user.id });
this.$root.dialog({
type: 'success',
text: this.$t('add-moderator.removed')
});
};
await process().catch(e => {
this.$root.dialog({
type: 'error',
text: e.toString()
});
});
this.changing = false;
},
fetchLogs() {
this.$root.api('admin/show-moderation-logs', {
untilId: this.untilId,
limit: 10 + 1
}).then(logs => {
if (logs.length == 10 + 1) {
logs.pop();
this.existMoreLogs = true;
} else {
this.existMoreLogs = false;
}
this.logs = this.logs.concat(logs);
this.untilLogId = this.logs[this.logs.length - 1].id;
});
},
}
});
</script>

View File

@ -1,181 +0,0 @@
<template>
<div>
<ui-info warn v-if="latestStats && latestStats.waiting > 0">The queue is jammed.</ui-info>
<ui-horizon-group inputs v-if="latestStats" class="fit-bottom">
<ui-input :value="latestStats.activeSincePrevTick | number" type="text" readonly>
<span>Process</span>
<template #prefix><fa :icon="fasPlayCircle"/></template>
<template #suffix>jobs/tick</template>
</ui-input>
<ui-input :value="latestStats.active | number" type="text" readonly>
<span>Active</span>
<template #prefix><fa :icon="farPlayCircle"/></template>
<template #suffix>jobs</template>
</ui-input>
<ui-input :value="latestStats.waiting | number" type="text" readonly>
<span>Waiting</span>
<template #prefix><fa :icon="faStopCircle"/></template>
<template #suffix>jobs</template>
</ui-input>
<ui-input :value="latestStats.delayed | number" type="text" readonly>
<span>Delayed</span>
<template #prefix><fa :icon="faStopwatch"/></template>
<template #suffix>jobs</template>
</ui-input>
</ui-horizon-group>
<div ref="chart" class="wptihjuy"></div>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import i18n from '../../i18n';
import ApexCharts from 'apexcharts';
import * as tinycolor from 'tinycolor2';
import { faStopwatch, faPlayCircle as fasPlayCircle } from '@fortawesome/free-solid-svg-icons';
import { faStopCircle, faPlayCircle as farPlayCircle } from '@fortawesome/free-regular-svg-icons';
export default Vue.extend({
i18n: i18n('admin/views/queue.vue'),
props: {
type: {
type: String,
required: true
},
connection: {
required: true
},
limit: {
type: Number,
required: true
}
},
data() {
return {
stats: [],
chart: null,
faStopwatch, faStopCircle, farPlayCircle, fasPlayCircle
};
},
computed: {
latestStats(): any {
return this.stats.length > 0 ? this.stats[this.stats.length - 1][this.type] : null;
}
},
watch: {
stats(stats) {
this.chart.updateSeries([{
name: 'Process',
type: 'area',
data: stats.map((x, i) => ({ x: i, y: x[this.type].activeSincePrevTick }))
}, {
name: 'Active',
type: 'area',
data: stats.map((x, i) => ({ x: i, y: x[this.type].active }))
}, {
name: 'Waiting',
type: 'line',
data: stats.map((x, i) => ({ x: i, y: x[this.type].waiting }))
}, {
name: 'Delayed',
type: 'line',
data: stats.map((x, i) => ({ x: i, y: x[this.type].delayed }))
}]);
},
},
mounted() {
this.chart = new ApexCharts(this.$refs.chart, {
chart: {
id: this.type,
group: 'queue',
type: 'area',
height: 200,
animations: {
dynamicAnimation: {
enabled: false
}
},
toolbar: {
show: false
},
zoom: {
enabled: false
}
},
dataLabels: {
enabled: false
},
grid: {
clipMarkers: false,
borderColor: 'rgba(0, 0, 0, 0.1)',
xaxis: {
lines: {
show: true,
}
},
},
stroke: {
curve: 'straight',
width: 2
},
tooltip: {
enabled: false
},
legend: {
labels: {
colors: tinycolor(getComputedStyle(document.documentElement).getPropertyValue('--text')).toRgbString()
},
},
series: [] as any,
colors: ['#00E396', '#00BCD4', '#FFB300', '#e53935'],
xaxis: {
type: 'numeric',
labels: {
show: false
},
tooltip: {
enabled: false
}
},
yaxis: {
show: false,
min: 0,
}
});
this.chart.render();
this.connection.on('stats', this.onStats);
this.connection.on('statsLog', this.onStatsLog);
this.$once('hook:beforeDestroy', () => {
if (this.chart) this.chart.destroy();
});
},
methods: {
onStats(stats) {
this.stats.push(stats);
if (this.stats.length > this.limit) this.stats.shift();
},
onStatsLog(statsLog) {
for (const stats of statsLog.reverse()) {
this.onStats(stats);
}
},
}
});
</script>
<style lang="stylus" scoped>
.wptihjuy
min-height 200px !important
margin -8px
</style>

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