Compare commits

...

882 Commits

Author SHA1 Message Date
71d4d51fb2 11.31.0 2019-09-02 06:33:07 +09:00
aaf38f1cbe Update CHANGELOG.md 2019-09-02 06:23:10 +09:00
0e0d6692c0 Fix bug 2019-09-02 06:21:43 +09:00
29f927fe72 Update CHANGELOG.md 2019-09-02 06:21:06 +09:00
ee39d9594e Improve readability 2019-09-02 06:04:12 +09:00
cefd2a4c54 ページURLが空の時currentNameを使うように (#5368)
* ページURLが空の時currentNameを使う

* 空の時はページURLにcurrentNameを代入するように

* Update src/client/app/common/views/pages/page-editor/page-editor.vue

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

* update validator

* Update src/client/app/common/views/pages/page-editor/page-editor.vue

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

* やっぱりuuidは統一

* エラー処理を追加

* some fix

* ちょっとだけ翻訳の追加と改善

* リファクタリング

* Revert "やっぱりuuidは統一"

This reverts commit 965a860504e8b09e5561a4ab862f8bab6a95e8d5.

* やっぱりuuidをわける

* エラー判定をidからcodeに+リファクタリング
2019-09-02 06:02:35 +09:00
a08c20d9af Fix #5353 2019-09-02 05:59:24 +09:00
dc11f1afbf Improve readavility 2019-09-02 05:52:38 +09:00
b0f2b209a2 Fix error 2019-09-02 05:42:30 +09:00
a25fdfd519 Fix #5373 2019-09-02 05:34:25 +09:00
c1aa58596d Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2019-09-02 05:20:17 +09:00
b6a3eb2445 Fix #5379 2019-09-02 05:20:06 +09:00
310f4d2edb New Crowdin translations (#5337)
* New translations ja-JP.yml (Chinese Simplified)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

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

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

* New translations ja-JP.yml (Spanish)

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

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Dutch)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (Spanish)

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

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Polish)

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

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

* New translations ja-JP.yml (Chinese Simplified)
2019-09-02 05:04:24 +09:00
701fee3139 Prevent users from opening note menu when already opened (#5367) 2019-09-02 04:45:01 +09:00
593c2b9517 Proxy for SMTP (#5371) 2019-09-02 04:42:52 +09:00
96b2267cb8 Chart resyncing (#5372)
* wip

* Add test

* Fix test

* Insert moderation log

* Add todo
2019-09-02 04:41:26 +09:00
84730a071a Update README.md [AUTOGEN] (#5377) 2019-09-02 04:06:54 +09:00
d0b0cf8dfb Use npx 2019-09-01 04:31:59 +09:00
749200d22b Show users who sent reaction on hover (#5362)
* Show users who sent reaction on hover

* Support i18n

* detail -> details

* Extract methods

* Update on change
2019-08-31 03:04:36 +09:00
a47baad943 Update dependencies 🚀 2019-08-31 03:01:50 +09:00
50abb51ece Syslog support
Resolve #5355
2019-08-30 08:29:46 +09:00
1f890c5bed Assign URL to each page of admin (#5366)
* Assign URL to each page of admin

* Remove cursor pointer
2019-08-30 04:19:49 +09:00
97f23af86d Assign URL to each page of settings (#5349)
* Assign URL to each page of settings

* Use router-link

* comma

* Use active-class

* Clean up

* space

* comma

* Redirect if mobile

* Redirect to /i/settings/profile

* Clean up
2019-08-29 14:57:28 +09:00
d77aa1f26a 不要なプロパティをレスポンスから削除 2019-08-29 07:34:54 +09:00
0b075ad4e9 Update README.md [AUTOGEN] (#5356) 2019-08-29 05:33:52 +09:00
423f776ed0 Perform animation only when reaction is added (#5359) 2019-08-29 05:20:27 +09:00
084fd8152b Refactor reactions-viewer.vue (#5358) 2019-08-29 05:15:14 +09:00
89d35c2e63 Fix bug 2019-08-29 05:13:03 +09:00
be33581642 Fix animation not being performed on new reaction (#5345)
* Fix animation not being performed on new reaction

* Clean up
2019-08-29 05:11:26 +09:00
2d6d9f30e1 ページURLが他と重複してたらエラーを投げるように (#5354)
* [Page]nameが重複したときの処理を追加

* page-editor側のerr.idにuuidを適用

* refactor

* uuidをわけた
2019-08-28 08:00:05 +09:00
85721065fd Save memo automatically (#5351)
* Save memo automatically

* Use clearTimeout

* Clean up

* Clean up
2019-08-28 02:26:19 +09:00
9d65768d4d [MFM] Fallback to js if specified lang is not available (#5347) 2019-08-27 19:44:49 +09:00
13f69e4291 excludeNsfwやCWのNSFW扱いなど (#5341)
* NoteにisSensitive

* Revert "NoteにisSensitive"

This reverts commit 3d5bcfbaf078ff91257a508f817dd1ef4ea31d7b.

* query excludeNsfw

* AP deliverでCW付きはsensitiveにするように

* excludeNsfwでCW付きも除くように
2019-08-27 17:33:07 +09:00
6a0affcec1 Tune worker/job counts (#5346)
* デフォルトのワーカー数を1に

* Tune default job count
2019-08-27 05:33:24 +09:00
ab6a84cd45 未実装のTLのRenoteクエリを実装 (#5343)
* users/notes includeMyRenotes

* other renotes

* fix target user in users/notes

* users/notesからv10から未実装でありえないオプションを削除

* users/notesのincludeMyRenotesの説明を修正

* remove needless anonymous checks
2019-08-27 03:24:35 +09:00
ba93bf7478 Prevent users from changing the disabled option (#5344) 2019-08-27 02:44:01 +09:00
1c4e1af7c3 Improve post form (#5326)
* Improve post form

* Remove local icon from button
2019-08-25 16:12:01 +09:00
a85f4c4fc4 Resolve #2716 (#5340)
* Resolve #2716

* Update ja-JP.yml
2019-08-25 16:11:20 +09:00
9d6c8806af CWの中のサムネイルのサイズが変なのを修正 (#5339)
* Fix #5338

* Revert "Fix #5338"

This reverts commit 72b32df2b74743bede6fff0dbc37fec352cff51f.

* Fix media-list height

* fix
2019-08-24 19:20:53 +09:00
ff52ea2a7c 11.30.0 2019-08-24 02:28:43 +09:00
f247ee9dd3 New Crowdin translations (#5322)
* New translations ja-JP.yml (English)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Korean)

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

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (Dutch)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Korean)

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

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (Danish)

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

* New translations ja-JP.yml (Spanish)

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

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Korean)
2019-08-24 02:24:24 +09:00
f4cec53ba1 [Room] Make Pinguin customizable 2019-08-24 02:18:21 +09:00
ad70b50fee [Room] Add energy drink 2019-08-23 06:52:42 +09:00
ea7b2b3141 Update README.md [AUTOGEN] (#5335) 2019-08-23 05:06:22 +09:00
c2f932e28b Fix #5324 2019-08-22 19:56:27 +09:00
c637882578 カップ麺をスムーズシェードするように 2019-08-22 19:42:52 +09:00
ef7221e39e Fix holo-display animation glitch 2019-08-22 19:37:01 +09:00
6b571a7799 Improve furniture preview (#5328)
* Improve furniture preview

* improve calc method

* camera.aspectいらないことに気付いた

* refactor & go camera far away

* 対角線の長さで計算するように

* 対角線の計算にhypot()を使用

Co-Authored-By: Aya Morisawa <AyaMorisawa4869@gmail.com>
2019-08-22 18:34:15 +09:00
0638b6cb69 Roomで未保存警告ダイアログなどを追加 (#5332)
* Room保存時にダイアログを表示するように

* Roomから移動するときに未保存ならば警告するように
2019-08-22 18:33:50 +09:00
a39c1706a1 Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2019-08-22 02:40:19 +09:00
c741e27057 [Room] Add holo-display 2019-08-22 02:40:01 +09:00
ede854c215 Update button.vue (#5331) 2019-08-22 02:36:19 +09:00
6a953b4d94 Update yarn.lock (#5327) 2019-08-21 13:04:51 +09:00
1d763096c7 Update room section of CONTRIBUTING.md 2019-08-20 16:16:27 +09:00
630d873ec0 [room]Add cup noodle (#5323)
* [Room] Add cup noodles

* remove ,

* Fix Cup-Noodle Texture
2019-08-20 15:57:42 +09:00
d427957ea7 New Crowdin translations (#5321)
* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Korean)
2019-08-20 02:19:06 +09:00
2430cc0e2c New translations ja-JP.yml (English) (#5320) 2019-08-20 02:04:55 +09:00
e57ee24864 New translations ja-JP.yml (French) (#5319) 2019-08-20 01:55:35 +09:00
3bc05ab3f2 New Crowdin translations (#5318)
* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)
2019-08-20 01:44:22 +09:00
4e50dcfa93 New Crowdin translations (#5313)
* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (English)

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

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

* New translations ja-JP.yml (Chinese Simplified)
2019-08-19 21:24:43 +09:00
fcf5531e5b 🎨 2019-08-19 16:44:55 +09:00
3bef69ee58 🎨 2019-08-19 16:13:08 +09:00
311a4f28b0 Resolve #5298 2019-08-19 16:05:57 +09:00
01e692b353 Refactor 2019-08-19 15:59:36 +09:00
3b445af6fc Improve readability 2019-08-19 15:51:00 +09:00
1e43ece637 [Room] Update model 2019-08-19 14:01:05 +09:00
6f1048c006 11.29.0 2019-08-19 12:39:26 +09:00
d686e70f2b [Room] Better rendering 2019-08-19 12:35:18 +09:00
70f524b82d New Crowdin translations (#5312)
* 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 (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)
2019-08-19 12:17:37 +09:00
79c6475028 Improve readability 2019-08-19 02:19:37 +09:00
7dee5309dc Refactoring 2019-08-19 02:06:37 +09:00
958ec7b03f Fix #5307 2019-08-19 02:02:10 +09:00
9153434906 [Room] Add bin 2019-08-19 01:54:06 +09:00
3a08364c24 [Room] Add some furnitures 2019-08-19 01:45:20 +09:00
a9beeab502 [Room] Better rendering 2019-08-19 01:43:45 +09:00
38c901069a [Room] Better avatar rendering 2019-08-19 01:15:30 +09:00
3f7606060e Update geometry name 2019-08-19 01:01:15 +09:00
777f20e9be Add Trash can (#5309)
new file:   src/client/assets/room/furnitures/trash-can/trash-can.blend
	new file:   src/client/assets/room/furnitures/trash-can/trash-can.glb
2019-08-19 00:51:57 +09:00
8e39aecffe Update room section of CONTRIBUTING.md (#5306)
* Update room section of CONTRIBUTING.md

* Update CONTRIBUTING.md

* Update CONTRIBUTING.md
2019-08-18 23:40:52 +09:00
9e1ab54097 11.28.2 2019-08-18 20:32:23 +09:00
0f9e09f4bd cors 2019-08-18 20:32:04 +09:00
743ebc17b9 Fix #5291 (#5294) 2019-08-18 20:25:12 +09:00
9bc4af76b8 モバイルでもRoomを表示できるように 2019-08-18 19:11:24 +09:00
46fa26426d Fix bug 2019-08-18 19:08:33 +09:00
58d0dc1795 11.28.1 2019-08-18 16:56:42 +09:00
bc11702f7d Fix #5290 2019-08-18 16:55:09 +09:00
6288de5813 Fix #5291 2019-08-18 16:51:27 +09:00
bbf59c7d9f 11.28.0 2019-08-18 16:07:55 +09:00
d7787bacf7 [ImgBot] Optimize images (#5289)
*Total -- 2,381.44kb -> 1,992.59kb (16.33%)

/src/client/assets/room/furnitures/photoframe/photo-uv.png -- 20.34kb -> 2.58kb (87.33%)
/src/client/assets/room/furnitures/pc/motherboard-uv.png -- 21.43kb -> 2.85kb (86.69%)
/src/client/assets/room/furnitures/cardboard-box3/uv.png -- 21.58kb -> 3.51kb (83.72%)
/src/client/assets/room/furnitures/poster-v/uv.png -- 21.85kb -> 3.71kb (83.04%)
/src/client/assets/room/furnitures/milk/milk.png -- 3.76kb -> 0.64kb (82.89%)
/src/client/assets/room/furnitures/server/uv.png -- 22.29kb -> 3.92kb (82.42%)
/src/client/assets/room/furnitures/facial-tissue/facial-tissue.png -- 3.80kb -> 0.67kb (82.3%)
/src/client/assets/room/rooms/washitsu/tatami-uv.png -- 22.27kb -> 3.98kb (82.13%)
/src/client/assets/room/rooms/washitsu/husuma-uv.png -- 22.06kb -> 3.94kb (82.13%)
/src/client/assets/room/furnitures/tv/screen-uv.png -- 20.55kb -> 3.70kb (81.98%)
/src/client/assets/room/furnitures/poster-h/uv.png -- 20.15kb -> 3.70kb (81.65%)
/src/client/assets/room/furnitures/plant/plant-soil-uv.png -- 23.17kb -> 4.40kb (81%)
/src/client/assets/room/furnitures/facial-tissue/facial-tissue-uv.png -- 22.96kb -> 4.37kb (80.99%)
/src/client/assets/room/furnitures/cardboard-box2/uv.png -- 22.36kb -> 4.52kb (79.78%)
/src/client/assets/room/furnitures/book2/uv.png -- 37.36kb -> 8.41kb (77.49%)
/src/client/assets/room/furnitures/server/rack-uv.png -- 26.68kb -> 6.55kb (75.46%)
/src/client/assets/room/furnitures/monitor/screen-uv.png -- 5.81kb -> 1.46kb (74.88%)
/src/client/assets/room/furnitures/milk/milk-uv.png -- 49.21kb -> 16.19kb (67.1%)
/src/client/assets/room/furnitures/eraser/eraser-uv.png -- 27.93kb -> 10.90kb (60.96%)
/src/client/assets/room/furnitures/book2/barcode.png -- 8.71kb -> 3.42kb (60.72%)
/src/client/assets/room/rooms/washitsu/husuma.png -- 4.23kb -> 2.48kb (41.44%)
/src/client/assets/room/furnitures/server/rack.png -- 9.42kb -> 6.88kb (26.92%)
/src/client/assets/room/furnitures/eraser/cover.png -- 10.75kb -> 8.14kb (24.26%)
/src/client/assets/room/furnitures/plant2/soil.png -- 13.06kb -> 10.60kb (18.83%)
/src/client/assets/room/furnitures/plant/plant-soil.png -- 13.06kb -> 10.60kb (18.83%)
/src/client/assets/room/furnitures/monitor/screen.jpg -- 28.93kb -> 24.26kb (16.16%)
/src/client/assets/room/furnitures/cardboard-box3/texture.png -- 18.23kb -> 15.82kb (13.21%)
/src/client/assets/room/furnitures/cardboard-box2/texture.png -- 18.64kb -> 16.48kb (11.56%)
/src/client/assets/room/furnitures/book2/texture.png -- 64.05kb -> 59.59kb (6.97%)
/src/client/assets/room/furnitures/server/server.png -- 121.75kb -> 114.13kb (6.26%)
/src/client/assets/room/furnitures/pc/motherboard.jpg -- 67.25kb -> 63.09kb (6.19%)
/src/client/assets/room/furnitures/photoframe/photo.jpg -- 31.10kb -> 29.79kb (4.22%)
/src/client/assets/room/rooms/washitsu/tatami-single1600.png -- 1,163.42kb -> 1,145.84kb (1.51%)
/src/client/assets/room/rooms/washitsu/tatami.png -- 308.19kb -> 306.37kb (0.59%)
/src/client/assets/room/furnitures/moon/moon.jpg -- 85.11kb -> 85.11kb (0%)

Signed-off-by: ImgBotApp <ImgBotHelp@gmail.com>
2019-08-18 15:06:22 +09:00
23ae0515c4 Update CHANGELOG.md 2019-08-18 15:05:13 +09:00
fe88b34b8a Update node version 2019-08-18 14:56:54 +09:00
74aa031a22 Update dependencies 🚀 2019-08-18 14:56:47 +09:00
6aeed212d9 New Crowdin translations (#5249)
* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Czech)

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

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Spanish)

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

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (Polish)

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

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Czech)

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

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Dutch)
2019-08-18 14:43:30 +09:00
45b972c059 MisskeyRoom (#5267)
* wip

* Add pemcil

* Fix bug

* Update .gitattributes

* Add 🍮

* Better 🍮

* Add color boxes

* Add pc

* Add keyboard

* Add 📦

* Add more 📦

* ✌️

* carpet

* Add plant

* ✌️

* ✌️

* Update room.vue

* Add plant

* ✌️

* ✌️

* ✌️

* ✌️

* ✌️

* 段ボール箱がてかりすぎているのを修正

* Update room.ts

* Render username

* ✌️

* Add new 📦

* Update room.ts

* Remove blender backup files

* Refactor

* Improve performance

* Update room.ts

* Update .gitattributes

* Update room.ts

* Better fan

* Better tissue rendering

* Add 🐧

* Create photoframe2.glb

* chairs

* Add 📖

* fix: HiDPi環境でオブジェクトを選択できない (#5268)

* Better monitor

* ✌️

* Add corkboard

* Add missing blend

* mousepad

* Add missing blend

* Add cube

* 額縁やモニターなどに任意の画像を表示できるように

* Update MisskeyRoom section of CONTRIBUTING.md (#5272)

* Update MisskeyRoom section of CONTRIBUTING.md

* Update CONTRIBUTING.md

* Update CONTRIBUTING.md

* Refactor

* カスタムテクスチャがずれないように

* Remove debug code

* Update furnitures.json5

* 一部の家具の色を自由に変えられるように

* Update ja-JP.yml

* Type annotation

* 家具の色やテクスチャをすぐ反映するように

* Update room.vue

* Update furnitures.json5

* Add 📺

* Update ja-JP.yml

* 床の色を変えられるように

* 和室にできるように

* Update washitsu

* Use MeshLambertMaterial to improve performance

* Use MeshLambertMaterial

* Fix bug

* Refactor

* Update room.ts

* Fix washitsu

* Update room.vue

* Update washistu

* Use MeshLambertMaterial

* Update room.ts

* Set current property value

* Disable reactivity to improve performance a bit

* Fix bug

* Set current carpet color

* Update ja-JP.yml

* Add rubik-cube (#5278)

* Update ja-JP.yml (#5279)

* Update UI

* ルームの設定を追加

* Add room link

* 家具をドラッグで移動や回転できるように

* esnextにする (#5286)

* Fix moduleResolution

* Use uuid v4

* Fix bug

* マットの色を変えられるように

* ✌️

* 異方性フィルタリングするように

* グラフィックの品質をフィルタリングに反映

* Add bloom effect when ultra graphics

* Add posters

* 🎨
2019-08-18 14:41:33 +09:00
7ecfc007a9 updateHashtagを並列で行わないように (#5284) 2019-08-18 12:47:45 +09:00
fc78c75bab Fix: Hashtagがupdateできない (#5285) 2019-08-18 12:46:47 +09:00
59493a0cd9 uuid() と lint (#5288)
* Import only v4 uuid, uuid() without version is deprecated

* Add Missing semicolon
2019-08-18 12:42:58 +09:00
6060c6d56e リモートユーザー向けのNoteUnreadsレコードは作成しないように (#5280) 2019-08-17 14:40:06 +09:00
6cdbb27169 Fix: ドライブアップロード直後に取得できるURLがoriginalじゃない (#5274) 2019-08-17 12:32:52 +09:00
ed8b073e54 タイトルやアイコンがきちんと設定されないことがあるのを修正 (#5265)
* Fix: og:site_nameがbase系ページに正しく反映さんれない

* instanceNameはAPIのmetaじゃなくてog:site_nameを参照するように

* Fix: タイトルが変更されるページから通常ページに遷移してもタイトルが戻らない

* Fix: タイトルが戻らない mobile / notifications

* Fix: faviconの変更が効かないページがある
2019-08-16 14:16:19 +09:00
7dd193636c Fix #5260 2019-08-11 20:13:57 +09:00
01d018510c ユーザー名の突き抜けの修正 (#5261)
* 突き抜け deck フォロリク/vote

* 突き抜け desktop

* notification reactionで絵文字の縦がずれないように

* Fix: ユーザーページの名前が突き抜ける

* Fix: デッキカラムでユーザー名が長いと閉じれなくなる

* デッキのカウントの位置が右になってしまってたのを修正

* デッキヘッダーのellipsis
2019-08-11 19:48:54 +09:00
1c273a0a75 Elasticsearchのインデックス名をconfigで変更できるように (#5257) 2019-08-09 13:04:35 +09:00
fa2c7658a0 PackedUserがサイレンスや凍結の情報を持つように (#5255) 2019-08-08 09:31:40 +09:00
84ca3a7d45 Unified the notation with "Renote" for consistency (#5256)
https://crowdin.com/translate/misskey/3/ja-zhcn#5238
2019-08-08 06:45:39 +09:00
902c73e6ac Update README.md [AUTOGEN] (#5251) 2019-08-06 23:23:01 +09:00
3b626f72e4 Resolve #5247 (#5248) 2019-08-05 10:30:31 +09:00
f5ce137a6b Update README.md [AUTOGEN] (#5246) 2019-08-03 19:56:59 +09:00
3ce9d12361 Update README.md [AUTOGEN] (#5243) 2019-08-02 22:37:31 +09:00
2fe2f3b1eb Update README.md [AUTOGEN] (#5240) 2019-08-02 21:21:31 +09:00
17b3ee41db Update README.md [AUTOGEN] (#5239) 2019-08-01 22:26:11 +09:00
56d2a5d5d3 Modify ssl directive to 'ssl' for listen directive (#5237)
the "ssl" directive is deprecated. 
http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl
2019-08-01 19:12:32 +09:00
3a17ff0983 11.27.1 2019-08-01 15:47:02 +09:00
9a9270bbe9 New Crowdin translations (#5230)
* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (Czech)

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

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

* New translations ja-JP.yml (Chinese Simplified)
2019-08-01 15:44:53 +09:00
512eee4f51 Update README.md [AUTOGEN] (#5236) 2019-08-01 01:32:00 +09:00
db01fa0eef Enable s3ForcePathStyle (#5234) 2019-07-31 18:11:11 +09:00
0c49a1ebd5 11.27.0 2019-07-29 04:36:11 +09:00
636d6394e3 Update CHANGELOG.md 2019-07-29 04:34:56 +09:00
c67c091b3a New Crowdin translations (#5217)
* New translations ja-JP.yml (Chinese Simplified)

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Czech)

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

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Dutch)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Norwegian)

* New translations ja-JP.yml (Portuguese)

* New translations ja-JP.yml (Spanish)

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

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Czech)

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

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Dutch)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Norwegian)

* New translations ja-JP.yml (Spanish)

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

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

* New translations ja-JP.yml (French)

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

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)
2019-07-29 01:56:01 +09:00
333604898c fix #5214 ウィジェットが選択されていないときは追加されないように (#5227)
* fix #5214

* null削除の取り消し

* 空白文字の調整
2019-07-28 14:12:33 +09:00
076ac3b614 Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2019-07-28 10:40:54 +09:00
0e1468b159 Update CHANGELOG.md 2019-07-28 10:40:42 +09:00
66409029e7 非ログイン時の警告処理 (#5219)
* Update note-mixin.ts

* Update note-mixin.ts

* ✌️

* Update note-mixin.ts

* Update note-menu.vue
2019-07-28 10:35:53 +09:00
8ec6b2ec11 Fix error 2019-07-28 10:31:16 +09:00
14736620ec HTTPリクエストのKeep-AliveとPrxoy対応など (#5226)
* DriveのKeep-Alive, Proxy と APのProxy対応

* request系でKeep-Aliveするように

* fix lookup-dns-cache.d.ts

* remove debug output
2019-07-28 09:49:02 +09:00
831ca53b63 「削除して編集」機能を追加 (#5182)
* 「削除して編集」機能を追加

* UXの調整

* 殆どの情報を保持したまま編集できるように

* update lang
2019-07-28 05:33:12 +09:00
6138d46509 AP Emojiのupdatedは採用しないように (#5220)
* AP Emojiのupdatedは採用しない

* updated判定は残す
2019-07-28 05:32:40 +09:00
c3003cb363 Improve mobile notifications view 2019-07-28 05:25:12 +09:00
4277e53433 通知のフィルタ (#5224)
* ✌️

* Deck
2019-07-28 04:44:09 +09:00
6516bd2ade Fix: リンクバリデーションリンクが一瞬表示されてしまう (#5216)
* Fix: リンクバリデーションリンクが一瞬表示されてしまう

* use link
2019-07-26 00:17:34 +09:00
27d22f954a 11.26.2 2019-07-25 02:23:42 +09:00
88f5e8e8e2 Bye moment from package.json (#5215)
* Bye moment from package.json

* Use Mapped types for argument type definition
2019-07-25 01:36:48 +09:00
fd2ae6d3cf Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2019-07-24 02:17:04 +09:00
238edd36f7 Fix error 2019-07-24 02:16:41 +09:00
5d847f9808 Fix: some post form errors (#5212)
* Fix: type mismatch in post-form-attaches

* Fix: 'this is null' in post-form-window
2019-07-24 02:15:40 +09:00
ac914af9c3 Fix #5210 2019-07-23 00:19:29 +09:00
636f90ca0c Improve CONTRIBUTING.md (#5158) 2019-07-22 14:57:23 +09:00
29469bb7c6 Better error 2019-07-22 10:18:27 +09:00
4f043b1841 Update signup.ts 2019-07-22 10:16:25 +09:00
85008303f5 Prevent username reusing 2019-07-22 10:15:00 +09:00
3432d6e615 Update dependencies 🚀 2019-07-22 07:31:02 +09:00
855c990a17 11.26.1 2019-07-21 22:59:57 +09:00
eef2dc2f62 Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2019-07-21 22:59:15 +09:00
fa54140973 Update CHANGELOG.md 2019-07-21 22:58:57 +09:00
e770d32916 New Crowdin translations (#5206)
* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (Czech)
2019-07-21 22:58:51 +09:00
8aeabf530c Patch #5060 (#5205)
* fix #5060

* forgot ";" :p
2019-07-21 22:27:36 +09:00
6fbf1cfc28 Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2019-07-21 21:59:51 +09:00
5480df35bc Update CHANGELOG.md 2019-07-21 21:58:48 +09:00
8b5104d564 Update deprecated vscode extension (#5209) 2019-07-21 21:57:15 +09:00
3c1192d6bf Unignore .vscode/extensions.json (#5208) 2019-07-21 20:27:43 +09:00
eb8ef35122 Fix activity calendar for desktop widget (#5200)
* Fix activity calendar for desktop widget

* fetch past 21 weeks for activity widgets

* Cleanup

* forEach -> map

* Revert "forEach -> map"

This reverts commit b72e180ee4a788ff1a3c2955a061646561b2b735.
2019-07-21 19:12:16 +09:00
8a31e5fd0f Update CHANGELOG.md 2019-07-21 03:27:17 +09:00
751728db84 Update CHANGELOG.md 2019-07-21 03:25:10 +09:00
e695f54ef0 投稿フォームが画面外にはみ出さないように (#5203)
* 上下はみ出したウィンドウは上基準で収めるように

* 投稿フォームを画面より長くしないように
2019-07-20 17:50:01 +09:00
b2ed45ae38 Fix: スクロールしてると絵文字ピッカーの位置がずれる (#5204) 2019-07-20 17:47:40 +09:00
5e36f75f8a Clean up: Remove unused imports 2019-07-20 04:09:33 +09:00
7ac13a386c Improve GenerateVideoThumbnail (#5186)
* Improve GenerateVideoThumbnail

* use fluent-ffmpeg

* Update src/services/drive/generate-video-thumbnail.ts
2019-07-20 03:28:14 +09:00
56c8ad9df3 Improve usability of quote note by pasting url (#5196) 2019-07-20 03:23:16 +09:00
f1ab918ecd Fix question (#5197) 2019-07-20 03:20:06 +09:00
42af8c7695 Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2019-07-20 02:02:48 +09:00
0de2e150cb [ImgBot] Optimize images (#5189)
/assets/ss/user.jpg -- 148.15kb -> 148.15kb (0%)
2019-07-20 01:56:09 +09:00
1ac498c8fe Update README.md [AUTOGEN] (#5199) 2019-07-20 01:53:09 +09:00
545d29a40a Update README.md [AUTOGEN] (#5193) 2019-07-20 00:40:08 +09:00
73bbef2922 Merge branch 'master' into develop 2019-07-19 06:14:21 +09:00
26567cdeb2 🎨 2019-07-19 06:13:56 +09:00
84941cbb97 Update CHANGELOG.md 2019-07-19 04:13:20 +09:00
cd5b24d4eb Merge branch 'develop' 2019-07-19 03:38:05 +09:00
c8abd512e1 11.26.0 2019-07-19 03:37:48 +09:00
de9bd2651b Remove unused import 2019-07-19 03:37:34 +09:00
c432310cae MFMの引用がインライン表示になっている問題を修正 2019-07-19 03:30:37 +09:00
1c95cdffdc Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2019-07-19 03:27:53 +09:00
c3ec668e16 Update CHANGELOG.md 2019-07-19 03:27:49 +09:00
2af79e9855 特定ホストへのメンションの特別処理をクライアントに追加 (#5185)
* 特定ホストへのメンションの特別処理をクライアントに追加

Fix #5168

* Apply suggestions from code review

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

* Apply suggestions from code review

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

* Apply suggestions from code review

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

* Fix indent
2019-07-19 03:13:47 +09:00
f6ac6f9c6f fix #5071 (#5184) 2019-07-18 20:56:48 +09:00
d8c835fa51 Fix signin (#5181)
* Revert "Fix signin history (#5180)"

This reverts commit a97c14a7b7.

* fix signin

* failはfail専用に

* fix password less 200
2019-07-18 05:26:58 +09:00
a97c14a7b7 Fix signin history (#5180)
* Fix #5179

* Fix wrong value in signin history
2019-07-18 04:22:44 +09:00
54ecf97c22 New Crowdin translations (#5175)
* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Czech)

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

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Dutch)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Spanish)

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

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Czech)

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

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Dutch)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Norwegian)

* New translations ja-JP.yml (Spanish)

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

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Czech)

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

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Korean)
2019-07-18 02:03:47 +09:00
9c4e64b7b5 Send Delete activity on suspend (#5165)
* Send Delete Person activity

* Delete activityの後にフォロー解除する

* アカウント削除でもDelete activity
2019-07-18 02:03:28 +09:00
ef44eda69e Mastodonのリンクの所有者認証に対応 (#5161)
* Profile metadata を設定できるように

* API desc
2019-07-18 00:11:39 +09:00
f1a7ab639b Resolve #5117 (#5171)
* Resolve #5117

* 出来立てのユーザーがストリームコネクションを持ってるはずがない
2019-07-18 00:00:03 +09:00
0d8286cb2a Improve #5176 (#5178)
* 🎨

* Follow review

* Remove unnecessary colon
2019-07-17 23:59:21 +09:00
8e4ad4b919 Improve usability of users view (#5176)
* Improve usability of users view

Resolve #5173

* Fix query

* Follow review and fix

* Follow review
2019-07-17 18:59:10 +09:00
9a09ed6290 Cleanup source (#5177)
* Cleanup source

* 🙏
2019-07-17 17:13:38 +09:00
9ca36021b0 Fix #5172 (#5174) 2019-07-17 13:28:27 +09:00
eaebb95827 Update README.md [AUTOGEN] (#5163) 2019-07-17 04:28:11 +09:00
b8cce2067c New translations ja-JP.yml (French) (#5170) 2019-07-17 01:34:32 +09:00
07a0631964 New translations ja-JP.yml (French) (#5169) 2019-07-17 01:25:56 +09:00
ebc2b05231 fix build error (#5162) 2019-07-17 00:59:19 +09:00
4c79dd4e96 Use yarn (#5154)
* Revert "✌️"

This reverts commit b5b437b878.

* Welcome back, yarn.lock

[lockfiles for all](https://yarnpkg.com/blog/2016/11/24/lockfiles-for-all/)

* Use alpine package registry instead of npm's

* Avoid npx

* Remove `"`

* Follow review

refs: https://github.com/syuilo/misskey/pull/5154#discussion_r303227256

* Update lockfile

* Use yarn instead of npm run

refs: https://github.com/syuilo/misskey/pull/5154#discussion_r303227285

* Back to npm

* Follow review

refs: https://github.com/syuilo/misskey/pull/5154#discussion_r303292279
2019-07-15 21:32:09 +09:00
abc57519a7 New Crowdin translations (#5155)
* New translations ja-JP.yml (Chinese Simplified)

* New translations ja-JP.yml (Czech)
2019-07-15 20:47:49 +09:00
a23a10d375 Improve CONTRIBUTING.md (#5157) 2019-07-15 20:47:09 +09:00
01e7716170 (コ`・ヘ・´ケ) (#5156) 2019-07-15 02:28:30 +09:00
0a29ce13b6 Nothing 2019-07-14 11:08:13 +09:00
6d0ee61661 Corriger les omissions 2019-07-14 11:04:27 +09:00
9c684fd6c4 Welcome back, yarn.lock
[lockfiles for all](https://yarnpkg.com/blog/2016/11/24/lockfiles-for-all/)
2019-07-14 10:16:30 +09:00
cbb8edd5ed Revert "Add yarn.lock to .gitignore (#3408)"
This reverts commit e8439679a5.
2019-07-14 10:09:00 +09:00
f933fa0e78 Add FAQ in CONTRIBUTING.md 2019-07-14 10:06:10 +09:00
b3e5198f23 Use yarn instead of npm 2019-07-14 10:04:52 +09:00
6e042ca344 Revert "Docker: Back to npm from yarn (#4730)"
This reverts commit 112a72abdf.
2019-07-14 09:58:45 +09:00
9381842af2 Bye @types/is-root 2019-07-14 09:42:22 +09:00
a6644c540a Update dependency resolutions 2019-07-14 09:38:49 +09:00
063427a660 Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2019-07-14 04:02:41 +09:00
6846067a5d Update CONTRIBUTING.md 2019-07-14 04:02:24 +09:00
b7273c90ae Fix #5128 (#5153) 2019-07-14 03:56:34 +09:00
a6f5e23069 Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2019-07-14 03:54:02 +09:00
f37f22b163 Fix bug 2019-07-14 03:53:45 +09:00
9440fdb2d0 New Crowdin translations (#5152)
* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Korean)
2019-07-14 03:33:31 +09:00
96c19b2607 New Crowdin translations (#5151)
* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Czech)

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

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Norwegian)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Japanese, Kansai)
2019-07-14 03:28:30 +09:00
b34c1379e9 Resolve #3238 2019-07-14 03:18:45 +09:00
0fc965f342 New translations ja-JP.yml (Chinese Simplified) (#5149) 2019-07-13 02:04:09 +09:00
617db05808 New translations ja-JP.yml (Chinese Simplified) (#5148) 2019-07-13 01:45:09 +09:00
6a20ab687c New translations ja-JP.yml (Chinese Simplified) (#5146) 2019-07-13 01:13:50 +09:00
6c3bcdad54 New translations ja-JP.yml (Chinese Simplified) (#5145) 2019-07-13 01:04:06 +09:00
aeea275ec2 New Crowdin translations (#5144)
* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Czech)

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

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Norwegian)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Japanese, Kansai)
2019-07-12 22:36:09 +09:00
b3c6e28717 Improve usability (#5142)
Fix #3862
2019-07-12 22:24:29 +09:00
70691e1523 Fix: proxy-media後のContent-Typeが違う (#5143) 2019-07-12 22:21:47 +09:00
2cb032b0e0 Fix #5140 2019-07-12 03:17:31 +09:00
ebbf5268ac Improve usability 2019-07-12 02:08:13 +09:00
b2030e8403 🎨 2019-07-12 00:40:10 +09:00
82493bb741 Update dependencies 🚀 2019-07-11 23:46:46 +09:00
aa15901c23 New Crowdin translations (#5131)
* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Korean)
2019-07-10 18:47:19 +09:00
0bd4d069a2 New Crowdin translations (#5130)
* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Czech)

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

* New translations ja-JP.yml (Danish)
2019-07-10 18:37:38 +09:00
ab871c6991 Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2019-07-10 18:30:58 +09:00
feec5e88fc Pages: Implement radio button 2019-07-10 18:30:51 +09:00
a091cbb93a Prevent duplicate user registration (#5129) 2019-07-10 03:47:07 +09:00
a59ab79da0 Fix drive browser showing false empty (#5127) 2019-07-09 17:38:14 +09:00
8ca4d39440 Update doc 2019-07-09 17:06:12 +09:00
41d041f701 Merge branch 'develop' 2019-07-09 17:03:38 +09:00
3e516474c2 11.25.1 2019-07-09 17:03:24 +09:00
405c9c258b New translations ja-JP.yml (English) (#5126) 2019-07-09 17:01:28 +09:00
24e389bcf3 Tune font (#5125) 2019-07-09 17:01:08 +09:00
933c83679e Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2019-07-09 16:55:59 +09:00
a7aa924949 Add userId prop 2019-07-09 16:55:55 +09:00
0eb84fe874 Fix bug 2019-07-09 16:55:33 +09:00
2f451fa058 New translations ja-JP.yml (English) (#5123) 2019-07-09 09:53:24 +09:00
2465a377a1 Delete init.ts 2019-07-09 04:09:02 +09:00
697219e946 Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2019-07-09 00:11:18 +09:00
4478298a0a Update uodate docs 2019-07-09 00:11:04 +09:00
925f89720a New translations ja-JP.yml (Korean) (#5121) 2019-07-08 17:02:58 +09:00
0f71d9f47a Merge branch 'develop' 2019-07-08 16:17:47 +09:00
a7ec54ea97 11.25.0 2019-07-08 16:17:14 +09:00
1d43d18b19 🎨 2019-07-08 16:11:52 +09:00
0bcb25a983 New Crowdin translations (#5102)
* New translations ja-JP.yml (Russian)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (Czech)

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

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Czech)

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

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Dutch)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Norwegian)

* New translations ja-JP.yml (Spanish)

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

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Czech)

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

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Dutch)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Norwegian)

* New translations ja-JP.yml (Spanish)

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

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Czech)

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

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Spanish)

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

* 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 (English)
2019-07-08 16:04:24 +09:00
ec1f2a285b Resolve #5116 2019-07-08 16:03:17 +09:00
c2c06694da Allow only one kind of date identifier at once (#5120) 2019-07-08 13:55:22 +09:00
5343b005df Improve paste uploading Resolve #3023 (#4542)
* resolve #3023

* fix

* fix

* better description

* widget

* fix text

* Update post-form.vue

* Fix enter-file-name dialog title text

* Fix type

* On messaging room

* Replace moment.js to original one

* Fix formatDateTimeString
2019-07-08 13:46:31 +09:00
eb783f827c Better display in narrow desktop and choosing client type; Fix #1442, Fix #2106, Resolve #4552 (#4549)
* fix #1442, fix #2106

* revert

* wip

* ✌️

* clean up

* fix

* https://github.com/syuilo/misskey/pull/4549#discussion_r287750004
2019-07-08 04:36:06 +09:00
6064c3ae47 Add semicolons 2019-07-08 04:32:57 +09:00
05862a420f Merge branch 'develop' into pr/4549 2019-07-08 04:27:18 +09:00
393ad283e1 🎨 2019-07-08 04:19:17 +09:00
841c8d619f 既定のアップロード先フォルダを設定できるように 2019-07-08 04:17:53 +09:00
5c2ed9e5d3 11.24.0の注意書きを追記 (#5108) 2019-07-07 19:00:38 +09:00
d39aabc143 Fix notification wrap (#5118) 2019-07-07 18:59:54 +09:00
4628f507e5 公開以外へのリプライ時元の公開範囲で指定したユーザー情報を引き継ぐように (#5119)
* 公開以外へのリプライ時元の公開範囲で指定したユーザー情報を引き継ぐように

* Use users/show userIds
2019-07-07 17:14:08 +09:00
8b05816860 Refactor: Remove needless return 2019-07-07 15:29:08 +09:00
3b8ea90fdc フォルダーを削除できないときダイアログボックスで知らせる (#5111)
* フォルダーを削除できないときダイアログボックスで知らせる

* https://github.com/syuilo/misskey/pull/5111#issuecomment-508959068

かわいい
2019-07-07 14:56:51 +09:00
638458e2c1 Fix: postgres redis cache の option が適用されない (#5114) 2019-07-07 07:59:59 +09:00
bd8d7c3d0f Improve Page
* ページをピン留めできるように
* デッキでカラム内でページを見れるように
2019-07-07 06:56:13 +09:00
4b747d20b7 Use npx to avoid global install of ts-node 2019-07-07 05:26:04 +09:00
351b236014 Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2019-07-07 05:13:21 +09:00
e9251debe0 イベント送信時に指定の変数の値を添付出来るように 2019-07-07 05:12:31 +09:00
22c4842154 https://github.com/syuilo/misskey/pull/4549#discussion_r287750004 2019-07-07 02:22:33 +09:00
788edd3622 fix 2019-07-07 02:22:33 +09:00
5afe96e15a clean up 2019-07-07 02:22:08 +09:00
899fc8a7bd ✌️ 2019-07-07 02:22:08 +09:00
2afcdda058 wip 2019-07-07 02:21:13 +09:00
c2fc637575 revert 2019-07-07 02:18:24 +09:00
82d2b0608f fix #1442, fix #2106 2019-07-07 02:18:24 +09:00
047a46d966 Support password-less login with WebAuthn (#5112)
* Support password-less login with WebAuthn

* Fix initial value of usePasswordLessLogin
2019-07-07 01:38:36 +09:00
e97dd13e81 Pages: ボタンを色付き表示できるように 2019-07-06 23:11:16 +09:00
067e9ec6f4 Fix bug 2019-07-06 22:53:15 +09:00
64397708fd MisskeyPagesにイベント送信ボタンを追加 2019-07-06 18:14:50 +09:00
5ae6b0058f やった (#5110) 2019-07-06 00:46:00 +09:00
c201326906 Merge branch 'develop' 2019-07-05 22:36:13 +09:00
3bc2fe8527 11.24.2 2019-07-05 22:35:52 +09:00
c76c1fc4ef Update CHANGELOG.md 2019-07-05 22:34:34 +09:00
fb3fa06ae7 Update CHANGELOG.md 2019-07-05 22:33:54 +09:00
48353cccae Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2019-07-05 22:32:19 +09:00
65bf863093 Fix #4760 2019-07-05 22:32:15 +09:00
87a6ef0581 Fix: SingleLineなMFMが折り返されてしまう (#5109) 2019-07-05 21:47:18 +09:00
af583d2ef6 Update CHANGELOG.md 2019-07-05 21:21:09 +09:00
68d49bc770 Add PB 2019-07-05 21:18:49 +09:00
d848195a6e チャートで数字が表示される問題を修正 2019-07-05 21:13:52 +09:00
3c5324bbbb Merge branch 'develop' 2019-07-05 18:02:42 +09:00
e2d59293fb 11.24.1 2019-07-05 18:02:29 +09:00
411f038f34 Fix: カスタム絵文字リアクションがたまに文字になってしまう (#5105) 2019-07-05 17:58:54 +09:00
26f2ae093b APNGでもMIME typeはimage/pngにするように (#5100)
* APNGでもMIME typeはimage/pngにするように

* Revert "APNGでもMIME typeはimage/pngにするように"

This reverts commit e579eb2bf44f526cabfa9bd4adc6b4fa84727e3b.

* APNGはファイル送信時のみimage/pngにするように
2019-07-05 17:44:23 +09:00
6a53ccf814 ハッシュタグのトレンドの計算を5分単位で丸める (#5107) 2019-07-05 08:43:56 +09:00
114523e69e Fix WebAuthn login (#5103) 2019-07-05 07:48:12 +09:00
d5caf22d8c Update Emojis immediately (#5106) 2019-07-05 07:45:00 +09:00
a8f945ae8e Update node version (#5101) 2019-07-05 02:48:32 +09:00
d078f78602 Merge branch 'develop' 2019-07-05 02:13:02 +09:00
a5c6145237 11.24.0 2019-07-05 02:12:45 +09:00
50df9f7dff Update node version 2019-07-05 02:12:23 +09:00
7b33522d97 New Crowdin translations (#5082)
* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (Polish)

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

* New translations ja-JP.yml (Polish)

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

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Czech)

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

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Korean)
2019-07-05 02:09:59 +09:00
d3edf03125 Fix errors 2019-07-05 02:00:54 +09:00
d5cd38b459 Create partial type definition for 'jsrsasign' (#5092)
* Create partial type definition for 'jsrsasign'

* Update comments

* Add jsrsasign dependency

* Make some params of Signature class optional

* Make init argument of Signature.init optional
2019-07-05 01:54:16 +09:00
2c76d410ab Resolve #1867 2019-07-04 22:59:52 +09:00
dfd991a6c6 テストメールは管理者アドレスに送信するように 2019-07-04 21:08:47 +09:00
16b81fff38 Resolve #3431 2019-07-04 21:07:02 +09:00
f379a721f1 Fix bug 2019-07-04 20:52:21 +09:00
194a958d40 Update CHANGELOG.md 2019-07-04 20:40:02 +09:00
327ffd3498 Resolve #4321 2019-07-04 20:39:33 +09:00
40276d7f1a テストページ廃止 2019-07-04 20:26:12 +09:00
9254f95679 Update CHANGELOG.md 2019-07-04 15:14:13 +09:00
2e1a9dffbe Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2019-07-04 14:45:33 +09:00
ead5a6a258 APNG support 2019-07-04 14:45:28 +09:00
97002400a8 アバターファイル選択でimage以外は表示しないように (#5098) 2019-07-04 14:31:30 +09:00
5e7a4e4752 Fix MIME 2019-07-03 23:43:09 +09:00
2c955858a0 Add note 2019-07-03 20:31:52 +09:00
a0e56504de Update package.json 2019-07-03 20:31:38 +09:00
d46e9f5abe Update ESLint 🚀 (#5097) 2019-07-03 20:20:02 +09:00
fd94b817ab Implement Webauthn 🎉 (#5088)
* Implement Webauthn 🎉

* Share hexifyAB

* Move hr inside template and add AttestationChallenges janitor daemon

* Apply suggestions from code review

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

* Add newline at the end of file

* Fix stray newline in promise chain

* Ignore var in try{}catch(){} block

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

* Add missing comma

* Add missing semicolon

* Support more attestation formats

* add support for more key types and linter pass

* Refactor

* Refactor

* credentialId --> id

* Fix

* Improve readability

* Add indexes

* fixes for credentialId->id

* Avoid changing store state

* Fix syntax error and code style

* Remove unused import

* Refactor of getkey API

* Create 1561706992953-webauthn.ts

* Update ja-JP.yml

* Add type annotations

* Fix code style

* Specify depedency version

* Fix code style

* Fix janitor daemon and login requesting 2FA regardless of status
2019-07-03 20:18:07 +09:00
f17e229c1e Resolve #5072 2019-07-03 03:58:45 +09:00
96e23b0e5b MFMで連続したスペースがひとつに纏まるのを修正 2019-07-02 20:52:37 +09:00
014b945ea6 Fix test 2019-07-02 20:08:30 +09:00
76693138d3 Fix MFM parsing: Ignore parent [] of URL 2019-07-02 20:05:52 +09:00
10677b57d4 Update dependencies 🚀 2019-07-02 19:20:34 +09:00
5f0ac0f46a Fix #5073 2019-07-02 19:17:14 +09:00
7ffe559525 Resolve #5085 2019-07-02 18:32:24 +09:00
919e3e2fed Update README.md [AUTOGEN] (#5094) 2019-07-02 15:37:24 +09:00
03e999875a リモートファイルの削除が重い問題を修正 2019-07-01 21:12:14 +09:00
ed0070c470 Set job concurrency to reduce performance issue 2019-07-01 20:37:26 +09:00
d764316708 Simplify log domain 2019-07-01 03:25:31 +09:00
06b1203ef9 Create 1561873850023-ChartIndexes.ts 2019-06-30 14:51:57 +09:00
b2cf74e878 Create accept-migration.ts 2019-06-30 04:49:30 +09:00
21064f7859 Add initial migration 2019-06-29 23:19:21 +09:00
bb2d76ffa3 Fix #4926 2019-06-29 23:12:00 +09:00
763b70e01b Revert "Update ormconfig.ts"
This reverts commit 5a349eb376.
2019-06-29 15:58:04 +09:00
5a349eb376 Update ormconfig.ts 2019-06-29 15:31:54 +09:00
0141affe05 Fix: AP object / actor type (#5086)
* attributedToがArrayの場合などに対応

* attachment以外で来るDocument系のObjectに対応

* Renote, Reply 対応

* 表示をいい感じに

* fix type

* revert as const

* Fix Note / Question type

* attributedToのtypeで複合配列を想定する
2019-06-28 18:54:09 +09:00
a8379e3bc9 Use as const
#5089
2019-06-28 16:38:48 +09:00
952789cc1e Use as const
#5089
2019-06-27 18:04:09 +09:00
0500600cdd Merge branch 'develop' 2019-06-25 01:27:51 +09:00
6b897e562a 11.23.1 2019-06-25 01:27:33 +09:00
f74bc309b1 Fix bug 2019-06-25 01:24:01 +09:00
bc83963ac7 English nyaize 2019-06-24 22:20:13 +09:00
94715e6153 Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2019-06-23 16:12:37 +09:00
31a5247b9c 🎨 2019-06-23 16:12:11 +09:00
ac9f77752d New translations ja-JP.yml (Chinese Simplified) (#5081) 2019-06-23 01:53:21 +09:00
73ac2632c2 Merge branch 'develop' 2019-06-23 00:22:33 +09:00
20f11a6701 11.23.0 2019-06-23 00:21:58 +09:00
9bdc67c1f6 New Crowdin translations (#5065)
* 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 (Chinese Simplified)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Korean)

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

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Russian)

* New translations ja-JP.yml (Russian)

* New translations ja-JP.yml (Russian)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Korean)

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

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

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Czech)

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

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Dutch)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Norwegian)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Japanese, Kansai)
2019-06-23 00:21:04 +09:00
bb4ca7b31a Resolve #5010 2019-06-23 00:06:39 +09:00
89f16668e6 Fix #4519 2019-06-22 04:17:02 +09:00
8409b59dea Improve usability 2019-06-22 04:09:53 +09:00
1707002d43 Block all activities from suspended users (#5076) 2019-06-21 15:42:07 +09:00
16b03fc157 Improve url-preview (#5077)
* url-previewリクエスト時にハッシュは除く

* ハッシュだけ違うプレビューカードは表示しない

*  url-previewをユーザーロケールで出し分けるように

* Fix code style
2019-06-21 15:41:02 +09:00
fa0023e541 Fix bug 2019-06-21 15:11:56 +09:00
aec5911821 Improve sync 2019-06-21 15:08:17 +09:00
26f4c038f3 Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2019-06-21 13:06:55 +09:00
6136f6f33a デッキの状態を同期できるように 2019-06-21 13:06:47 +09:00
2b8d0225cc Enable ServiceWorker (#5075) 2019-06-21 11:50:38 +09:00
18184441f1 ホームのカスタマイズ情報を複数のデバイス間で同期できるように 2019-06-21 01:50:01 +09:00
bd83939993 Provide Redis version 2019-06-20 22:55:57 +09:00
2c1932faa7 Add psql version to info page 2019-06-20 22:52:35 +09:00
33d79420eb Fix code style 2019-06-19 17:47:24 +09:00
80d8af84dd Merge branch 'develop' 2019-06-18 19:16:41 +09:00
aac519bf80 11.22.0 2019-06-18 19:15:55 +09:00
d64dffbdda Add index 2019-06-18 17:11:28 +09:00
4015ccef2f Add chart indices 2019-06-18 17:10:28 +09:00
b6f985abaf Update summaly to 2.3.0 2019-06-18 16:58:32 +09:00
2dac8d3d1f Update db.vue 2019-06-18 16:53:14 +09:00
4f284e1bc0 Resolve #5063 2019-06-18 16:49:58 +09:00
b0280355e8 Better request interval 2019-06-18 16:17:20 +09:00
048d88b784 Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2019-06-18 15:56:31 +09:00
bb52ebdc3e Provide version of postgresql 2019-06-18 15:56:03 +09:00
5f2fda85ba Resolve #5069 (#5070) 2019-06-18 15:42:08 +09:00
1331f0b953 Use WHATWG API
> New application code should use the WHATWG API.
2019-06-18 15:27:13 +09:00
736fdabc1d Fix #2637 2019-06-18 15:19:19 +09:00
7096c0ca49 Add note 2019-06-18 14:04:41 +09:00
1a984de8e8 Better error handling 2019-06-18 13:58:59 +09:00
285d0d13f9 Fix MFM URL parsing 2019-06-17 20:15:19 +09:00
63c659bc8f Fix MFM strike parsing 2019-06-16 21:42:57 +09:00
af60b45ee7 Fix MFM italic parsing 2019-06-16 21:30:51 +09:00
e7effd606d Fix test 2019-06-16 21:30:26 +09:00
5042d23bc4 Simplify test 2019-06-16 21:29:31 +09:00
b134467bd3 Add some MFM tests 2019-06-16 21:26:43 +09:00
5cc1aab530 Merge branch 'develop' 2019-06-16 16:09:04 +09:00
49d57ce049 11.21.0 2019-06-16 16:08:36 +09:00
f1feceaf1a Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2019-06-16 16:08:29 +09:00
1204e1c5e4 Update dependencies 🚀 2019-06-16 16:07:57 +09:00
96cf4c30cf New Crowdin translations (#5053)
* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

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

* New translations ja-JP.yml (Korean)

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

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (French)
2019-06-16 16:06:00 +09:00
a3853611ad Fix: オートコンプリートにアニメーション停止が効かない (#5061) 2019-06-16 16:04:27 +09:00
ef7eaaabfa Support Unicode 12.0 Emoji (#5062) 2019-06-16 14:24:37 +09:00
a4a96710b0 閉鎖しているホストにはAP deliverしないように (#5057)
* 閉鎖しているホストにはAP deliverしないように

* fix case
2019-06-15 17:09:59 +09:00
6d08909b2f Refactor 2019-06-15 17:06:03 +09:00
2615368b1e Resolve #365 2019-06-15 00:07:41 +09:00
2bd03ca725 Use halfwidth space instead of fullwidth space in code (#5054) 2019-06-14 22:54:19 +09:00
67dda01fcb image以外はproxyしないように (#5051) 2019-06-14 12:14:23 +09:00
e9dc54c4d9 サムネイル生成でエラーになってもファイルのアップロードを失敗しないように
#5050
2019-06-13 22:59:15 +09:00
fde9fc2891 Make url preview log warn 2019-06-13 22:35:37 +09:00
6e59798e82 Merge branch 'develop' 2019-06-13 18:22:49 +09:00
5e3cc0a3c6 11.20.4 2019-06-13 18:22:31 +09:00
cfb35324d0 Fix bug 2019-06-13 18:15:35 +09:00
9bfbc12afa Add indexes 2019-06-13 15:30:51 +09:00
b41cddaf5a Fix: #5035 (#5048) 2019-06-12 13:47:58 +09:00
1432a7193d 設定でPostgreSQLのクエリー結果のキャッシュを無効できるように (#5046) 2019-06-11 20:49:08 +09:00
20630cb3a0 Update README.md [AUTOGEN] (#5044) 2019-06-11 16:57:52 +09:00
2eb02ae581 Merge branch 'develop' 2019-06-10 23:11:22 +09:00
801f9027aa 11.20.3 2019-06-10 23:11:04 +09:00
802739a2df Fix bug 2019-06-10 23:09:36 +09:00
95b1e1a21d Merge branch 'develop' 2019-06-10 11:44:01 +09:00
b8060a522a 11.20.2 2019-06-10 11:43:45 +09:00
fe2191a491 New Crowdin translations (#5040)
* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Korean)
2019-06-10 11:42:06 +09:00
2891f52817 Merge branch 'riamu' into develop 2019-06-10 11:41:07 +09:00
5bdc44c672 ✌️ (#5041)
related #5020
2019-06-10 01:02:33 +09:00
65d359b57a Fix #5020 2019-06-09 23:07:32 +09:00
7b6e717e23 Merge branch 'develop' 2019-06-07 20:47:56 +09:00
2820f6a621 11.20.1 2019-06-07 20:47:14 +09:00
6f96e05fec New Crowdin translations (#4979)
* New translations ja-JP.yml (Chinese Simplified)

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (French)

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

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Norwegian)

* New translations ja-JP.yml (Spanish)

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

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (French)

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

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Norwegian)

* New translations ja-JP.yml (Spanish)

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

* New translations ja-JP.yml (Danish)

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

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (French)

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

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (Dutch)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Norwegian)

* New translations ja-JP.yml (Portuguese)

* New translations ja-JP.yml (Spanish)

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

* New translations ja-JP.yml (Danish)

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

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

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

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

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

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

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Polish)
2019-06-07 20:43:34 +09:00
4c2c762b87 Fix #5036 2019-06-07 20:40:05 +09:00
81fadfa4ff Fix bug 2019-06-07 20:34:05 +09:00
c227641d50 Update dependencies 🚀 2019-06-07 20:29:13 +09:00
dacc713f99 Fix #5021 2019-06-07 20:24:07 +09:00
a1f794ee05 Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2019-06-07 20:11:38 +09:00
8b2098fc89 Fix bug 2019-06-07 20:11:23 +09:00
4436852de0 Deny 'private' in note visibility (#5031)
Fixes #5028
2019-06-06 19:45:25 +09:00
a8ff1e19dc Add resolutions for polluted packages
for yarn users: Just `yarn install` then vulnerabilities are fixed!
for npm users: Wait for support of 'resolutions' from npm.
2019-06-04 23:06:30 +09:00
d559aa8e6d Update README.md [AUTOGEN] (#5025) 2019-06-04 18:19:16 +09:00
83fedcff3b Add missing semicolon (#5030) 2019-06-04 18:03:56 +09:00
9969cf8816 Update README.md [AUTOGEN] (#5017) 2019-06-02 10:13:11 +09:00
dee48fff12 Update README.md [AUTOGEN] (#5013) 2019-06-01 20:38:46 +09:00
aff80199e5 Fix bug 2019-05-29 12:22:47 +09:00
b9f1a55190 Update README.md [AUTOGEN] (#5003) 2019-05-27 23:44:44 +09:00
07d5bce61a Update README.md [AUTOGEN] (#5001) 2019-05-27 23:15:46 +09:00
834edd216c Fix #4894 (#5000) 2019-05-27 20:04:01 +09:00
4670a3d886 Merge branch 'develop' 2019-05-27 18:07:36 +09:00
78952df364 11.20.0 2019-05-27 18:07:21 +09:00
d69df60da4 Fix 2019-05-27 18:06:01 +09:00
6ca69f6f2e Fix #4999 2019-05-27 18:03:13 +09:00
8e8428b667 Fix bug 2019-05-27 18:01:06 +09:00
5dbe1d448b Improve job queue view 2019-05-27 17:44:51 +09:00
85d8e6f220 Refactoring 2019-05-27 17:23:05 +09:00
72fb23f4d5 Improve drive management 2019-05-27 16:54:47 +09:00
9403ee6495 Improve post form
Resolve #4998
Resolve #1151
2019-05-27 15:38:14 +09:00
94ce4fa780 Fix #4996 (#4997) 2019-05-27 08:41:24 +09:00
911f5c1455 i18n: ページ編集のカウンターの増加値 (#4995) 2019-05-27 00:03:39 +09:00
a6a88af513 Add locales for admin/views/queue.vue (#4993) 2019-05-26 23:14:31 +09:00
fad1352d51 Add locale for admin/views/federation.vue (#4994) 2019-05-26 23:14:09 +09:00
41cdae07c3 Fix #4989 (#4992)
* Fix #4989

* Update
2019-05-26 22:35:25 +09:00
3b0daeac3c Fix #4986 (#4991) 2019-05-26 22:05:09 +09:00
99e4b06468 Merge branch 'develop' 2019-05-26 21:42:19 +09:00
c88576e3e6 11.19.1 2019-05-26 21:42:03 +09:00
4de709fe51 Fix #4990 2019-05-26 21:35:45 +09:00
37e4226c70 Clean up 2019-05-26 21:16:52 +09:00
1a6ed61b91 Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2019-05-26 21:16:37 +09:00
ac641da49c Update CHANGELOG.md 2019-05-26 21:16:27 +09:00
933a79af93 Remove deprecated package @types/file-type (#4987) 2019-05-26 15:09:42 +09:00
f36e3c69b4 Fix #4985 2019-05-26 13:42:53 +09:00
c46bfcc768 Add links in CONTRIBUTING.md (#4984) 2019-05-26 12:48:37 +09:00
c65ccd5eb0 Improve issues description (#4982) 2019-05-26 01:06:36 +09:00
162a740295 Fix #4981 2019-05-26 00:38:26 +09:00
9192e98e3f インスタンス名を空にしてもMisskeyロゴが表示されない問題を修正 2019-05-25 11:50:29 +09:00
fad84203c0 Merge branch 'develop' 2019-05-25 09:22:25 +09:00
622266d200 Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2019-05-25 09:21:50 +09:00
0f6cd3c125 11.19.0 2019-05-25 09:21:21 +09:00
0dfc1fcf13 New Crowdin translations (#4955)
* New translations ja-JP.yml (English)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Korean)

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

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

* New translations ja-JP.yml (Korean)

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

* 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)
2019-05-25 09:11:42 +09:00
efeebd2165 Better migration for UserProfile1556746559567 (#4969) 2019-05-25 09:11:24 +09:00
69a916d506 Fix: Firefoxでトークの下が隠れてしまう (#4974) 2019-05-25 09:10:51 +09:00
114803a86a Fix #4972 2019-05-25 09:07:50 +09:00
7f54c8fa2a 🎨 2019-05-25 09:05:14 +09:00
0af3e15e82 🎨 2019-05-25 09:04:16 +09:00
f9afebc12e Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2019-05-25 08:50:07 +09:00
fc7268fd12 🎨 2019-05-25 08:49:58 +09:00
7e7f94d685 Enable query result cache for meta / stats / hashtags trend (#4978) 2019-05-25 08:35:16 +09:00
3ea7a49c1c Show page title 2019-05-24 19:36:35 +09:00
f596a847c2 Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2019-05-24 19:34:20 +09:00
312ba501a3 Add deck fallback 2019-05-24 19:33:58 +09:00
c6531e8609 Improve localization description (#4976)
* Improve localization description

* Update CONTRIBUTING.md

* Update CONTRIBUTING.md
2019-05-24 19:31:40 +09:00
36c2d0082f MisskeyPagesをホームUIに統合 2019-05-24 19:19:43 +09:00
358bb0fc06 Misskey Pages でURLプレビューを表示するように 2019-05-24 18:11:33 +09:00
5a4f6b4ada Update page-editor.vue 2019-05-24 18:11:12 +09:00
03136caac4 Update instance.vue 2019-05-24 04:57:04 +09:00
e6f78a73ab i18n: reaction-picker.vue (#4971) 2019-05-24 04:25:57 +09:00
bcdab799d0 🎨 2019-05-24 04:17:14 +09:00
50251955cd Improve usability 2019-05-24 03:57:03 +09:00
2270fbf3ee 🎨 2019-05-24 03:46:20 +09:00
deb6485cc2 Update dependency 🚀 2019-05-24 03:31:14 +09:00
6de08d07a3 Support PostgreSQL Extra Connection options (#4970) 2019-05-24 03:26:56 +09:00
f54cd10a04 Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2019-05-23 23:46:20 +09:00
dda7b0c80e Refactor 2019-05-23 23:46:10 +09:00
3ed9e1ff3f Create FUNDING.yml 2019-05-23 22:43:24 +09:00
9c8d26affa Resolve #4967 2019-05-23 14:11:42 +09:00
1e1a7ee858 Add info 2019-05-23 13:38:07 +09:00
9cfb72810c Fix bug (#4958)
4a88cb59
2019-05-22 14:27:10 +09:00
14a774c723 Fix bug 2019-05-22 13:07:58 +09:00
8509adf961 Add group update / transfer API (#4957) 2019-05-22 13:03:18 +09:00
9d75ec799b Better deninition 2019-05-22 13:00:36 +09:00
eed9266ecb align format 2019-05-22 12:58:53 +09:00
4a88cb5968 rename 2019-05-22 12:58:44 +09:00
50d4de19f0 Clean up 2019-05-22 12:56:42 +09:00
c7456224af Fix bug 2019-05-22 12:55:53 +09:00
c1524d9bef デッキでフォロー申請を見れるように 2019-05-22 12:54:28 +09:00
aa1d2545b3 Fetch joined groups on accept group invites (#4956) 2019-05-22 12:25:14 +09:00
1092818203 Add group update / transfer API 2019-05-22 05:06:58 +09:00
d67d163c78 Merge branch 'develop' 2019-05-21 18:13:24 +09:00
a973bd56fe 11.18.1 2019-05-21 18:13:10 +09:00
08b6fda065 Fix bug 2019-05-21 18:09:05 +09:00
d0cc145cb3 Clean up 2019-05-21 18:08:58 +09:00
19588647d6 Improve usability 2019-05-21 18:06:00 +09:00
09da292f1a Fix #4953 2019-05-21 17:43:27 +09:00
c8107ff936 🎨 2019-05-21 17:40:58 +09:00
b44afc1876 iOSで投稿フォームに自動フォーカスしない問題を修正 2019-05-21 17:39:23 +09:00
c26168f22e Merge branch 'develop' 2019-05-21 08:57:10 +09:00
391be342ac 11.18.0 2019-05-21 08:55:26 +09:00
16549f8f84 Add da-DK 2019-05-21 08:51:32 +09:00
2d2b65d9fa New Crowdin translations (#4931)
* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (French)

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

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Spanish)

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

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

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

* New translations ja-JP.yml (French)

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

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Norwegian)

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

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (French)

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

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (Dutch)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Norwegian)

* New translations ja-JP.yml (Spanish)

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

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

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

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (French)

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

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (Dutch)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Norwegian)

* New translations ja-JP.yml (Spanish)

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

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (French)

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

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Norwegian)

* New translations ja-JP.yml (Portuguese)

* New translations ja-JP.yml (Spanish)

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

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Korean)
2019-05-21 08:49:57 +09:00
a12ad37522 Fix 2019-05-21 08:48:15 +09:00
84541faf92 Update dependencies 🚀 2019-05-21 08:46:35 +09:00
c7daaba370 🎨 2019-05-21 08:44:36 +09:00
f128813a5e Fix 2019-05-21 08:23:37 +09:00
699a55ea08 Fix 2019-05-21 08:21:26 +09:00
90a674f99b Refactore 2019-05-21 08:19:29 +09:00
f236d36ed3 Fix 2019-05-21 08:19:23 +09:00
1b2200ccf4 Refactyor 2019-05-21 08:10:37 +09:00
c6353f3502 Improve usability 2019-05-21 06:53:18 +09:00
f09b8a78a0 Improve usability 2019-05-21 06:34:10 +09:00
5f741ac46e Refactoring 2019-05-21 06:31:51 +09:00
a434cfbe0d Fix 2019-05-21 04:26:14 +09:00
cd4c7689b7 Reduce initial bundle size 2019-05-21 04:21:43 +09:00
3cc2049fb3 Reduce initial bundle size 2019-05-21 03:45:07 +09:00
0d3117e472 Fix 2019-05-21 03:40:18 +09:00
b335975c97 Refactoring 2019-05-21 03:20:16 +09:00
5511b6e013 Refactoring 2019-05-21 03:07:11 +09:00
262d5ead51 Clean up 2019-05-20 22:59:10 +09:00
a78b048720 Improve API doc 2019-05-20 22:01:32 +09:00
e7dd5e155d Fix bugs
Use Not(IsNull())
2019-05-20 21:44:16 +09:00
5a3ea38bbf Fix: Delete is not deliver (#4950)
* Fix: Delete is not deliver

* fix
2019-05-20 13:34:51 +09:00
786521eba7 Merge branch 'develop' 2019-05-20 00:12:42 +09:00
202cb3048a 11.17.1 2019-05-20 00:12:19 +09:00
7e642cf700 Fix bug 2019-05-19 23:42:18 +09:00
7732aabc1e Fix bug 2019-05-19 23:29:28 +09:00
1cf9f52eca Merge branch 'develop' 2019-05-19 21:02:32 +09:00
d1d5e10b72 11.17.0 2019-05-19 21:02:17 +09:00
c3fada264f Fix #4938 2019-05-19 20:57:05 +09:00
45eeb74b83 Fix #4948 2019-05-19 20:52:00 +09:00
b9a6e551cd Add unique index 2019-05-19 20:50:08 +09:00
c610e5ed9b Update note-favorite.ts 2019-05-19 20:48:10 +09:00
c2c2824e50 Fix bug 2019-05-19 20:47:41 +09:00
01fab09683 Fix #4945 2019-05-19 20:43:33 +09:00
e103904a04 Resolve #4941 2019-05-19 20:41:23 +09:00
56678cbac0 Update README.md [AUTOGEN] (#4940) 2019-05-19 15:08:16 +09:00
7fade8939d Merge branch 'develop' 2019-05-19 03:22:41 +09:00
daa557f6a3 11.16.1 2019-05-19 03:22:26 +09:00
23a257ed86 Update Dockerfile 2019-05-19 03:21:39 +09:00
05d0620491 Merge branch 'develop' 2019-05-19 02:51:49 +09:00
5225139284 11.16.0 2019-05-19 02:51:28 +09:00
9b2e996cae 🎨 2019-05-19 02:47:31 +09:00
6a561342a4 🎨 2019-05-19 02:39:34 +09:00
429bed2f91 Refactor 2019-05-18 23:16:09 +09:00
200d593414 Add group menu 2019-05-18 22:57:34 +09:00
9dbe12135d Fix bug 2019-05-18 22:54:02 +09:00
318d7f2652 🎨 2019-05-18 22:50:57 +09:00
5a653531e2 Avoid error 2019-05-18 21:22:37 +09:00
c7cc3dcdfd ユーザーグループ
Resolve #3218
2019-05-18 20:36:33 +09:00
61f54f8f74 Fix bug 2019-05-18 00:38:33 +09:00
a3b27fe3a1 Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2019-05-17 19:56:56 +09:00
380749051d ページにいいねできるように 2019-05-17 19:56:47 +09:00
ql3
81625f9fc5 Update gitignore to ignore config files for Intelij-IDEA (#4933) 2019-05-17 02:31:00 +09:00
d6ccb1725b Update API docs 2019-05-17 00:19:23 +09:00
5ce412aeda Merge branch 'develop' 2019-05-16 16:14:00 +09:00
fe6d88e410 11.15.0 2019-05-16 16:13:46 +09:00
a21357248f Dockerを使用している場合、アプデの際にマイグレを自動実行するように 2019-05-16 16:12:30 +09:00
70d710c9a9 管理画面でreCAPTCHAのプレビューを表示するように 2019-05-16 16:08:50 +09:00
183c82fb8d New Crowdin translations (#4924)
* 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 (English)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (French)

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

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Spanish)

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

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (French)

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

* New translations ja-JP.yml (Czech)

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

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

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

* New translations ja-JP.yml (Chinese Simplified)
2019-05-16 13:11:56 +09:00
62cbb92154 Fix #4930 2019-05-16 12:59:09 +09:00
7d70126072 Merge branch 'develop' 2019-05-16 01:18:06 +09:00
54bfffa7b9 11.14.0 2019-05-16 01:16:41 +09:00
3f5b96bf62 Resolve #4928 2019-05-16 01:07:32 +09:00
3d8bbedf1b GIFのサムネイルが生成されないのを修正
#4728
2019-05-15 21:27:20 +09:00
23c9f6a6ca Resolve #4833 2019-05-15 20:41:01 +09:00
5ba8d4949d インスタンスの設定画面を整理 2019-05-15 20:29:47 +09:00
a6befdd541 Fix bug 2019-05-15 17:05:41 +09:00
e5409db0e8 Resolve #4925 2019-05-14 23:54:39 +09:00
678d610cd6 Update CHANGELOG.md 2019-05-14 21:27:20 +09:00
466fe9c368 Merge branch 'develop' 2019-05-14 21:25:24 +09:00
13feaea7b7 11.13.0 2019-05-14 21:25:00 +09:00
e52f9301fa New Crowdin translations (#4878)
* New translations ja-JP.yml (Korean)

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

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

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (French)

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

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Portuguese)

* New translations ja-JP.yml (Spanish)

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

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

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (French)

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

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (Dutch)

* New translations ja-JP.yml (Korean)

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

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

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

* New translations ja-JP.yml (Korean)

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

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (French)

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

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Japanese, Kansai)
2019-05-14 21:18:05 +09:00
1b58e18a6d Update dependencies 🚀 2019-05-14 21:17:29 +09:00
b779ff08e0 特定のインスタンスのファイルをすべて削除できるように 2019-05-14 21:08:35 +09:00
811f9c22d7 🎨 2019-05-14 20:57:24 +09:00
c3529f0691 Improve usability 2019-05-14 20:53:49 +09:00
f9f574532e インスタンスブロックを設定できるように 2019-05-14 20:49:09 +09:00
92dee53dd6 Update note.ts 2019-05-14 12:04:40 +09:00
5d42ee2359 Fix tag cloud on Welcome page (#4922)
Resolve #4754
2019-05-14 10:50:20 +09:00
7c03d37caa Add ToSUrl, repositoryUrl, feedbackUrl (#4921)
* Add ToSUrl, repositoryUrl, feedbackUrl

* modify nodeinfo
2019-05-14 02:57:04 +09:00
b128b593c2 Fix: user menu (#4845) (#4920)
* Fix: Firefoxで自分のメニューが開けないなど

* 自分のユーザーメニューにはミュートなどを表示しないようになど
2019-05-14 02:53:05 +09:00
342e48ed77 Fix meta tags (#4918) 2019-05-14 02:50:23 +09:00
052f8b265d Update README.md [AUTOGEN] (#4916) 2019-05-13 18:03:29 +09:00
2eedc91d74 Update Docker images on CircleCI 2019-05-12 17:27:27 +09:00
410b9ad6bc Fix: ピン留め投稿の表示順がおかしい (#4906)
* Fix: syuilo#4904

* fix comment
2019-05-12 09:37:00 +09:00
24c6dff3e4 Fix #4875 (#4899) 2019-05-11 21:43:08 +09:00
161db7636a Update log.ts 2019-05-11 10:58:34 +09:00
796252357e Merge branch 'develop' 2019-05-10 17:33:21 +09:00
b0344d52e9 11.12.0 2019-05-10 17:32:57 +09:00
8e6da3a0d9 インスタンス運営者がピン留めユーザーを設定できるように
Related #4892
2019-05-10 17:30:28 +09:00
756e4eaeec テキストのリスト内で変数埋め込みできるように 2019-05-10 16:08:01 +09:00
3126d0730a MisskeyPagesで変数を並べ替えられるように 2019-05-10 16:04:32 +09:00
748e9f15df Add notes/unrenote API 2019-05-10 15:53:53 +09:00
7c714f5788 Improve MisskeyPages 2019-05-10 14:18:18 +09:00
d3c3ad839b Update ObjectStorage example (#4890) 2019-05-10 01:46:11 +09:00
168de3c316 Resolve #4870 2019-05-09 23:27:34 +09:00
9e20fc5c88 Validate Note on createNote (#4881) 2019-05-09 15:43:31 +09:00
1ff5151786 Fix: みつけるで人気のタグが表示されない (#4883) 2019-05-09 15:42:56 +09:00
a56738a331 Update README.md [AUTOGEN] (#4877) 2019-05-07 20:55:37 +09:00
2d04a3d6d2 Merge branch 'develop' 2019-05-07 18:56:33 +09:00
e0a55b9100 11.11.2 2019-05-07 18:56:19 +09:00
0a57eecb3a New Crowdin translations (#4812)
* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (French)

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

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (Dutch)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Norwegian)

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

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

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (French)

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

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Portuguese)

* New translations ja-JP.yml (Spanish)

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

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

* New translations ja-JP.yml (English)

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

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (French)

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

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (Dutch)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Norwegian)

* New translations ja-JP.yml (Spanish)

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

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

* New translations ja-JP.yml (English)

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

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (French)

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

* New translations ja-JP.yml (Czech)

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

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Czech)

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

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

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (English)

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

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (French)

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

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (Dutch)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Norwegian)

* New translations ja-JP.yml (Spanish)

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

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (Czech)

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

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (English)
2019-05-07 18:49:51 +09:00
51f98020f6 Fix #4874 2019-05-07 18:48:38 +09:00
70123805e1 Fix #4866 2019-05-07 18:23:12 +09:00
1448b11d00 Clean up 2019-05-07 18:20:18 +09:00
490b81ed05 Fix #4873 2019-05-07 18:14:37 +09:00
96f675abed Fix: IPv4 onlyホストからDualstackホストにAP deliverできない (#4872) 2019-05-07 17:49:25 +09:00
4cd451c613 2段階認証コードの入力フォームタイプの訂正 (#4869)
Fix #4849, Resolve #4848
2019-05-07 08:45:29 +09:00
187792dfc4 Fix bug 2019-05-06 20:09:13 +09:00
3dde561fe5 Resolve #4864 (#4865) 2019-05-06 17:28:55 +09:00
a75ec45172 Merge branch 'develop' 2019-05-05 20:36:25 +09:00
3732ddf75f 11.11.1 2019-05-05 20:36:11 +09:00
b8d8097734 Fix bug 2019-05-05 20:36:09 +09:00
1092532292 Merge branch 'develop' 2019-05-05 20:33:44 +09:00
8a79ba0e2b 11.11.0 2019-05-05 20:33:29 +09:00
ca2949fbb4 MisskeyPagesにリストから選択関数を追加 2019-05-05 20:31:15 +09:00
17b373ac07 ✌️ 2019-05-05 20:16:05 +09:00
7aa66f438f Resolve #4853 2019-05-05 20:12:35 +09:00
73641fd78d Fix #4852 2019-05-05 15:17:29 +09:00
64aac9d6ad Fix #4862 2019-05-05 15:12:25 +09:00
2be13736c8 Update user-profile.ts
#4809
2019-05-05 09:42:38 +09:00
ff4f5fec1d meidg (#4835) 2019-05-05 09:29:15 +09:00
7d64f8abe4 外部サービス連携後のPackedUserがその情報を持つように (#4850) 2019-05-05 09:28:55 +09:00
88e6929e9f 外部サービス連携ログインリンクにアイコン追加 (#4858) 2019-05-05 09:28:23 +09:00
5fb0a995dd 様々な修正 (#4859)
Typo, Redundant code, Syntax error の修正
2019-05-05 09:27:55 +09:00
58a04ce1a5 ログアウトの処理と外部サービス連携Viewがセッションクッキーを作らないように (#4856) 2019-05-05 04:04:30 +09:00
f74e0d9123 Merge branch 'develop' 2019-05-04 15:21:51 +09:00
c6249b82d4 11.10.1 2019-05-04 15:21:35 +09:00
d6131c0b09 MisskeyPagesでページブロックを削除できなくなっていた問題を修正 2019-05-04 15:14:02 +09:00
e62c810b7c Use node 12 2019-05-04 14:53:46 +09:00
2851a1a7ef Update dependencies 🚀 2019-05-04 14:47:28 +09:00
12cd2709d6 Merge branch 'develop' 2019-05-03 18:58:54 +09:00
bf54e58873 11.10.0 2019-05-03 18:58:09 +09:00
6b473e3a5c Fix #4840 2019-05-03 18:55:24 +09:00
4b68abd963 割った余りを求める関数をMisskeyPagesに追加 2019-05-03 18:48:40 +09:00
0e764a2b3e Fix external service authentication (#4846) 2019-05-03 18:38:19 +09:00
9d1ed1eb0d Some import and export fixes (#4842)
* Fix: Mastodon v2.8.0 のフォローリストがインポートできない

* Fix: エクスポートリクエストに失敗してもエラーが出ない (#4821)

* エクスポートファイルでは同一ハッシュチェックをしないように
2019-05-03 18:33:25 +09:00
a09a3465a2 Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2019-05-03 14:49:40 +09:00
001969efaf Improve usability 2019-05-03 14:49:22 +09:00
e7c515da9a Update README.md [AUTOGEN] (#4839) 2019-05-03 14:34:41 +09:00
8367c7dd49 Update README.md [AUTOGEN] (#4837) 2019-05-03 14:32:09 +09:00
55e6cae240 Fix #4834 2019-05-03 09:16:31 +09:00
5553c3fb17 Improve usability 2019-05-03 08:27:46 +09:00
026265cb1e Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2019-05-03 08:22:51 +09:00
289c76a802 Disable ServiceWorker 2019-05-03 08:22:44 +09:00
7c1bc1d6bc Update README.md [AUTOGEN] (#4832) 2019-05-02 19:44:59 +09:00
90cf0d32b5 Update README.md [AUTOGEN] (#4827) 2019-05-02 18:48:48 +09:00
88d934f922 Merge branch 'develop' 2019-05-02 17:57:29 +09:00
abf11bb03c 11.9.0 2019-05-02 17:57:13 +09:00
2d1f50303d Improve MisskeyPages 2019-05-02 17:55:59 +09:00
9fb7c4091f Merge branch 'develop' 2019-05-02 17:18:34 +09:00
2fdec27ab0 11.8.1 2019-05-02 17:18:11 +09:00
aff56469ed Fix bug 2019-05-02 17:15:14 +09:00
419cb7fbad Remove unwanted ! character in user token regex (#4830) 2019-05-02 06:24:32 +09:00
7882851539 Fix TypeScript semantic error (#4828)
ビルドの時こういうエラーが出てます
src/misc/aiscript/evaluator.ts(2,29): error TS7016: Could not find a declaration file for module 'seedrandom'
2019-05-01 22:56:18 +09:00
358299cf0e Merge branch 'develop' 2019-05-01 20:59:18 +09:00
5a2af24869 11.8.0-2 2019-05-01 20:58:59 +09:00
6d35872af5 Merge branch 'develop' 2019-05-01 20:57:23 +09:00
559dfdaa80 11.8.0 2019-05-01 20:56:50 +09:00
79c49bc926 ページのソースを見れるように 2019-05-01 20:48:56 +09:00
76c538ad25 🎨 2019-05-01 19:50:56 +09:00
e76e358d98 Fix bug 2019-05-01 19:50:52 +09:00
76f37671b4 🎨 2019-05-01 19:45:05 +09:00
a9fc176c3c Fix types 2019-05-01 19:31:34 +09:00
8b13e3c327 Refactor 2019-05-01 19:20:47 +09:00
c3cd6ad2d2 Refactoring 2019-05-01 18:33:11 +09:00
3444b9c9c8 Add splitStrByLine function 2019-05-01 16:33:54 +09:00
ca6fc9cd79 Remove strConcat function 2019-05-01 16:07:05 +09:00
4747ae8b61 Improve AiScript 2019-05-01 15:17:24 +09:00
b6c50d63a0 Update ja-JP.yml 2019-05-01 15:04:26 +09:00
52ebf2055e Improve AiScript 2019-05-01 14:54:34 +09:00
d0af2c2a98 Improve MisskeyPages 2019-05-01 10:37:25 +09:00
10216af48a Improve MisskeyPages 2019-05-01 10:05:33 +09:00
d0c8d537f5 Refactor 2019-05-01 09:15:29 +09:00
1903aaf351 Improve API doc
Fix #4825
2019-05-01 04:44:46 +09:00
e6cdf1b995 Fix: mention (あなた宛て) streaming にミュートが効かない (#4823) 2019-04-30 15:53:13 +09:00
2900d22cdc Update CHANGELOG.md 2019-04-30 12:38:07 +09:00
dc072d4706 Merge branch 'develop' 2019-04-30 12:21:31 +09:00
8ae14f146b 11.7.0 2019-04-30 12:20:59 +09:00
57444c6c3f Update page-editor.el.post.vue 2019-04-30 12:17:53 +09:00
759719d124 Improve MisskeyPages 2019-04-30 12:15:41 +09:00
59782973be 🎨 2019-04-30 10:08:55 +09:00
6c647ea91c Improve usability 2019-04-30 07:55:40 +09:00
c9763dabe1 変換関数を追加 2019-04-30 07:49:46 +09:00
da82754659 🎨 2019-04-30 07:43:56 +09:00
a3cc0ad18b 🎨 2019-04-30 07:41:57 +09:00
2e8e5c2751 Improve MisskeyPages
* ifブロック を追加
* ボタンやスイッチなどのテキストに変数使えるようにした
2019-04-30 06:40:02 +09:00
a60d83b101 Fix ogp 2019-04-29 18:15:12 +09:00
6d45265763 Use bigint 2019-04-29 17:38:31 +09:00
42e84b77e1 Merge branch 'develop' 2019-04-29 15:26:43 +09:00
24121cfadb 11.6.0 2019-04-29 15:26:09 +09:00
93093dd288 🎨 2019-04-29 15:20:37 +09:00
53381c04e6 🎨 2019-04-29 15:17:31 +09:00
c6b64e57f1 いくつかの文字列関数を追加 2019-04-29 15:13:04 +09:00
9158426d0a Improve usability 2019-04-29 14:51:04 +09:00
cef26853df Improve usability 2019-04-29 14:46:35 +09:00
c0673884c5 🎨 2019-04-29 14:38:06 +09:00
c98eb64598 Fix bug 2019-04-29 14:37:58 +09:00
8836bd4f3b Merge branch 'develop' 2019-04-29 11:11:17 +09:00
a58df29208 11.5.1 2019-04-29 11:10:59 +09:00
0d64a17d86 Update page.vue 2019-04-29 11:10:50 +09:00
c886c09cdb MisskeyPagesで値が0の変数が表示されない問題を修正 2019-04-29 11:08:35 +09:00
e86d0007c6 Fix error 2019-04-29 11:03:05 +09:00
624ee76e71 Fix bug 2019-04-29 11:00:41 +09:00
9406079cb7 Merge branch 'develop' 2019-04-29 09:29:48 +09:00
cd2de7f893 11.5.0 2019-04-29 09:29:21 +09:00
342061803e Update dependencies 🚀 2019-04-29 09:28:13 +09:00
05b8111c19 Pages (#4811)
* wip

* wip

* wip

* Update page-editor.vue

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* Update page-editor.variable.core.vue

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* Update aiscript.ts

* wip

* Update package.json

* wip

* wip

* wip

* wip

* wip

* Update page.vue

* wip

* wip

* wip

* wip

* more info

* wip fn

* wip

* wip

* wip
2019-04-29 09:11:57 +09:00
747a0b1791 Update define.ts 2019-04-28 19:56:41 +09:00
c05586b53a Improve performance 2019-04-27 11:17:03 +09:00
0cfca4a618 Fix official instance address (#4805)
いくつかのURLが misskey.xyz になってたままだったので misskey.io に訂正
2019-04-26 18:29:56 +09:00
2b8187f7ab Fix bug 2019-04-26 00:54:11 +09:00
291e7e7943 おすすめユーザーに自分自身を含まないように (#4803)
Fix #4790
2019-04-26 00:52:58 +09:00
535d10f469 Improve API console 2019-04-25 14:40:42 +09:00
4cb58c0892 Refactor 2019-04-25 13:27:07 +09:00
6721d27e3f Improve hashtag API 2019-04-25 13:25:10 +09:00
da9dd7c423 Improve API definition 2019-04-25 12:56:52 +09:00
867eb41618 Fix #4415 2019-04-25 12:37:13 +09:00
6fdff13480 Update example.yml 2019-04-25 12:24:18 +09:00
e581ead1ed Update CHANGELOG.md 2019-04-25 12:22:03 +09:00
7495206db2 Merge branch 'develop' 2019-04-25 07:48:29 +09:00
fe87d16d46 11.4.0 2019-04-25 07:48:12 +09:00
0db54386cd Resolve #3119 2019-04-25 07:46:39 +09:00
772258b0b8 Fix #4793 2019-04-25 04:32:01 +09:00
3ef002e14d Fix bug 2019-04-25 04:27:34 +09:00
b90d473ae5 Fix layout 2019-04-25 04:26:58 +09:00
f5091d524b Refactorgin 2019-04-25 04:17:03 +09:00
ee5720df2c Fix #4704 (#4797)
*  Fix #4632

* Fix #4795
2019-04-25 04:07:39 +09:00
afe2037985 Merge branch 'develop' 2019-04-24 20:51:34 +09:00
878cd18144 11.3.1 2019-04-24 20:51:14 +09:00
e8c8f67a09 Update post-form.vue
Close #4792

Co-Authored-By: tamaina <tamaina@hotmail.co.jp>
2019-04-24 20:47:47 +09:00
7b29e7cf7e Fix bug 2019-04-24 20:41:32 +09:00
723d3e6871 Merge branch 'develop' 2019-04-24 15:23:48 +09:00
f063dee12a 11.3.0 2019-04-24 15:23:31 +09:00
db4b315d3d Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2019-04-24 15:21:58 +09:00
64d00b08a3 Improve announcement
* お知らせにMFMを使えるように
* お知らせに画像を添付できるように
2019-04-24 15:21:39 +09:00
74736a941e Update README.md [AUTOGEN] (#4778) 2019-04-24 14:56:23 +09:00
c40366f20a Update README.md [AUTOGEN] (#4777) 2019-04-24 14:55:49 +09:00
d73e52ac2a Create find-by-hash.ts 2019-04-24 14:54:19 +09:00
9fac8a611f Fix response 2019-04-24 14:54:15 +09:00
9c774a50f8 Update attached-notes.ts 2019-04-24 14:54:06 +09:00
4f20ee1909 Rename theme 2019-04-24 14:44:28 +09:00
1440c5bc65 Fix bug 2019-04-24 14:39:59 +09:00
5829b2a7c1 Update CHANGELOG.md 2019-04-24 10:07:27 +09:00
e3c4bc18d0 Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2019-04-24 10:02:49 +09:00
8555ec2f72 Fix #4767 2019-04-24 10:02:31 +09:00
8d7cefbbbe New Crowdin translations (#4771)
* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Chinese Simplified)
2019-04-24 09:54:43 +09:00
5aa5896b22 Cache meta 2019-04-24 08:11:19 +09:00
8a55bdd89d Increase reaction column length 2019-04-24 03:39:11 +09:00
6444ef6444 Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2019-04-24 03:26:10 +09:00
701ab6cc68 Refactor 2019-04-24 03:26:02 +09:00
3c6ce7a943 Update README.md [AUTOGEN] (#4773) 2019-04-24 00:34:48 +09:00
1e54afd217 Update README.md [AUTOGEN] (#4772) 2019-04-24 00:33:55 +09:00
4e90fd3a06 メンテナ名を必須でなくす
Close #4753
2019-04-23 22:48:53 +09:00
0463c6bb0f Refactor API (#4770)
* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* Update description.ts

* wip
2019-04-23 22:35:26 +09:00
f31f986d66 Fix #4768 2019-04-23 02:50:59 +09:00
c203c8302b Add @rinsuki into collaborators (#4762) 2019-04-22 18:19:20 +09:00
dea4a7b389 Merge branch 'develop' 2019-04-22 00:50:14 +09:00
0caf9b0706 11.2.2 2019-04-22 00:49:36 +09:00
5f655c9fd7 Update dependencies 🚀 2019-04-22 00:43:15 +09:00
44aed53998 New Crowdin translations (#4736)
* New translations ja-JP.yml (Chinese Simplified)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (French)

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

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (Dutch)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Spanish)

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

* New translations ja-JP.yml (French)

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

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

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

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (French)

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

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (Dutch)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Norwegian)

* New translations ja-JP.yml (Spanish)

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

* New translations ja-JP.yml (English)

* 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 (Czech)
2019-04-22 00:39:00 +09:00
f9ff621d4a 2段階認証を有効にするとログインできない問題を修正 2019-04-22 00:38:37 +09:00
23a5a75778 Docker: Remove quotes in docker_example.env (#4765)
Docker does not parse quotes in env_file.
As follows if enclosed in quotation marks.

docker_example.env:
POSTGRES_PASSWORD="password"

Environment value in Misskey container:
$ echo $POSTGRES_PASSWORD
"password"

Some users may see this behavior as unexpected.

Dockerはenv_fileのクォーテーションマークを解析しません。
もし値がクォーテーションマークで囲まれていた場合は以下のような動作になります。

docker_example.env:
POSTGRES_PASSWORD="password"

Misskeyのコンテナ内の環境変数:
$ echo $POSTGRES_PASSWORD
"password"

この動作を予期しない動作のように思うユーザーがいるかもしれません。
2019-04-21 23:58:15 +09:00
a78475844a Fix: リモートユーザーの修復処理が自動的に実行されない など for v11 (#4764)
* Fix #4761

* Fix: updatePersonができない
2019-04-21 23:57:44 +09:00
575cf2935e Merge branch 'develop' 2019-04-21 06:52:28 +09:00
ae43aa1bc0 11.2.1 2019-04-21 06:52:01 +09:00
0ba71c6a47 Fix #4752 (#4759) 2019-04-21 02:30:18 +09:00
643f7d1803 Update CHANGELOG.md 2019-04-20 05:19:28 +09:00
5d06da4db2 Update CHANGELOG.md 2019-04-20 05:13:38 +09:00
2934b09361 Fix bug 2019-04-19 21:37:36 +09:00
97341d3fa0 Update README.md [AUTOGEN] (#4748) 2019-04-19 15:37:47 +09:00
a95546ede0 Fix bug 2019-04-19 01:00:17 +09:00
7b44727b23 Merge branch 'develop' 2019-04-18 22:01:45 +09:00
debe648a98 11.2.0 2019-04-18 22:00:53 +09:00
fda8cf77ed Improve warp 2019-04-18 22:00:11 +09:00
8aaab195c6 Fix bug 2019-04-18 21:40:36 +09:00
4096ddcbd0 Use - 2019-04-18 21:36:44 +09:00
ae6cc11ad2 Fix icon 2019-04-18 21:34:56 +09:00
dab7e527de Improve user lists index (#4605)
* wip

* Revert "wip"

This reverts commit 6212831ce3bdae5ce17f8ace9945710ba7696185.

* improve list index

* Update user-lists.vue
2019-04-18 21:33:24 +09:00
8b92feac71 Resolve #4732 2019-04-18 21:29:19 +09:00
4beb3e5755 Fix #4734 (#4745) 2019-04-18 20:46:59 +09:00
55f63229cd Update timemachine.vue 2019-04-18 19:42:40 +09:00
7827aeb695 Resolve #4735 2019-04-18 19:40:23 +09:00
cce768aaac Fix API definition 2019-04-18 14:58:43 +09:00
80b83c0624 間違えた 2019-04-18 14:41:51 +09:00
73b683bb4d Add test 2019-04-18 14:39:49 +09:00
d78a5c0863 Fix #4703 2019-04-18 14:34:47 +09:00
683e5b6abe Add type annotations 2019-04-18 14:29:17 +09:00
653b8f6352 スプラッシュがクリックに反応するように (#4561)
* confirm silence

* Resolve #4554

* Revert "confirm silence"

This reverts commit e1dbdc2bfc0f41c2b308b142c70e9e4573c98cf9.
2019-04-18 03:37:49 +09:00
9ec6afa375 confirm on user menu (#4553) 2019-04-18 03:36:06 +09:00
adff5382ca confirm silence (#4560) 2019-04-18 03:33:51 +09:00
704aabd703 Use menu instead of prompt Fix #4540, Fix #342 (#4575)
* Use menu instead prompt

* fix

* https://bit.ly/2U0JuVt

* fix
2019-04-18 03:32:45 +09:00
f7b1ef0690 アンケートウィジットでもMFMを使用するように v11 (#4741)
* MFM in poll

* use mfm
2019-04-18 03:14:04 +09:00
929982117f Merge branch 'develop' 2019-04-18 01:12:21 +09:00
56a530d769 11.1.6 2019-04-18 01:12:03 +09:00
7ef75fb06b New Crowdin translations (#4692)
* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (French)

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

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (Dutch)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Norwegian)

* New translations ja-JP.yml (Spanish)

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

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (German)

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

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (French)

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

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Spanish)

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

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

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (Czech)
2019-04-18 01:11:06 +09:00
112a72abdf Docker: Back to npm from yarn (#4730)
This commit reverts "Fix Dockerfile #4214" which uses yarn instead of npm.
The cause of the build error is that binding.gyp and src/crypto_key.cc
are missing when installing dependencies.
In other words, yarn did not fix build error.

There is no reason to use yarn, so go back to npm.
2019-04-18 01:09:31 +09:00
71813e03ee Fix bug 2019-04-18 01:05:40 +09:00
9b05b6ef28 Improve readability 2019-04-18 00:57:06 +09:00
54a87b25b3 Remove unused imports 2019-04-18 00:56:10 +09:00
55e97864bd Fix: v11で未認知ユーザーからActivityが飛んできた場合に処理できない (#4733)
* Fix: inboxに未知のユーザーが来ると処理できない

* こうかな
2019-04-18 00:53:00 +09:00
95733c9490 [MFM] Better hashtag parsing 2019-04-18 00:40:56 +09:00
e19ae644f1 Fix indent 2019-04-18 00:13:31 +09:00
ac4ea25267 Better error handling 2019-04-18 00:09:08 +09:00
611e4f34dc Merge branch 'develop' 2019-04-17 19:37:32 +09:00
faf017f333 11.1.5 2019-04-17 19:36:58 +09:00
5eec896615 Better avgColor 2019-04-17 17:13:49 +09:00
17f35174ea 🎨 2019-04-17 17:01:57 +09:00
bf71b31123 Update CONTRIBUTING.md 2019-04-17 16:59:39 +09:00
9399a44c82 Fix error 2019-04-17 16:50:50 +09:00
c96418806f Disable sql log 2019-04-17 16:45:31 +09:00
7945eddef6 Clean up 2019-04-17 14:39:45 +09:00
0ede390fef Refactor 2019-04-17 14:32:59 +09:00
85959a3b9b Fix #4721 Fix #4722 2019-04-17 14:30:31 +09:00
946c3a25b9 Clean up 2019-04-17 07:25:34 +09:00
f9d697128a Update schemas.ts 2019-04-17 04:32:04 +09:00
532ef744f4 Merge branch 'develop' 2019-04-17 02:58:09 +09:00
27a961814b 11.1.4 2019-04-17 02:57:48 +09:00
5a5b65e9bf Clean up 2019-04-17 02:57:36 +09:00
96673ad610 Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2019-04-17 02:51:19 +09:00
a9025aea0d Better response 2019-04-17 02:51:12 +09:00
f38ab0b973 Update delete-file.ts 2019-04-17 02:37:37 +09:00
150dac00cf Update stream.ja-JP.md (#4725) 2019-04-17 02:21:22 +09:00
bcb1a9c5d3 Refactor 2019-04-17 02:19:49 +09:00
2e55aea584 Doc: Update setup documents (#4680)
* Doc: Update setup documents

Use GitHub api to checkout latest release instead of "git tag" command
which cannot accurately determine prerelease tag.
Also, Changed numbered list format because
the shell command is too long to fit on one line.

* Doc: Use tab instead of spaces

* Doc: Use master branch as latest release tag

master branch and latest release is the same.
master branch merges develop branch with each latest release.
2019-04-17 02:15:27 +09:00
4f5a3f0df5 smallint 2019-04-17 02:12:15 +09:00
e265b538cc Fix #4724 2019-04-17 02:11:22 +09:00
b186504718 Metaのアクセスでトランザクションを張るように (#4720)
* admin/instanceでmetaをキャッシュしないように

* Metaのアクセスにトランザクションをかける
2019-04-17 00:45:33 +09:00
fc27890f13 Refactor 2019-04-17 00:34:49 +09:00
a583939767 Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2019-04-17 00:33:10 +09:00
52e3bcfd29 Meta を二重にデータベースに保存できないように 2019-04-17 00:33:02 +09:00
85d29a3f9d Correct syntax error (#4718) 2019-04-17 00:30:34 +09:00
18944d389d Fix space indent in misskey.nginx (#4717)
Tabインデントになっていたものをスペースインデントに変更
2019-04-16 19:41:58 +09:00
e90ac5d6a4 チャートの数値カラムの型を拡張 2019-04-16 17:52:09 +09:00
cb9a6ae774 Update README.md [AUTOGEN] (#4697) 2019-04-16 13:07:00 +09:00
3ef09aa6b2 Docker: Uncomment redis (#4707)
Redis is required since Misskey 11.0.0.
2019-04-16 13:06:36 +09:00
4db22e45a2 fix syuilo#4711 (#4715) 2019-04-16 13:05:47 +09:00
f966d0b32c 色々な修正; Fix #4709 (#4714)
* Fix a la carte 1

* use dialog instead of alert() etc
2019-04-16 13:05:10 +09:00
ba3879a95a Fix: admin/driveのアイコンがずれてる (#4710) 2019-04-16 02:46:47 +09:00
c6cef0162d Merge branch 'develop' 2019-04-16 01:24:00 +09:00
6d09aa86e9 11.1.3 2019-04-16 01:23:26 +09:00
b711f0f9c6 Clean up 2019-04-16 01:22:48 +09:00
8fefb3a4c9 Update authenticate.ts 2019-04-16 01:20:28 +09:00
400cdf0f26 Fix #4705 2019-04-16 01:11:20 +09:00
bce8c5a315 Refactor 2019-04-16 01:05:21 +09:00
f44dc2dd05 Doc: Add "Init DB" section (#4695)
Misskey 11.x requires database initialization.
2019-04-15 23:39:09 +09:00
df950d2fc5 Clean up 2019-04-15 23:37:35 +09:00
5e1f804dd1 Merge branch 'develop' 2019-04-15 23:32:45 +09:00
15de89f2f9 11.1.2 2019-04-15 23:32:26 +09:00
df647a415c Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2019-04-15 23:29:44 +09:00
fc66231f8e Fix #4701 2019-04-15 23:29:26 +09:00
71df3e1566 APIドキュメントの説明とか一部追記 (#4702)
* Define description in generate.ts

* Add description in create.ts
2019-04-15 23:26:20 +09:00
168c22fc98 Fix bug 2019-04-15 23:00:39 +09:00
792ec23d7a Use pureimage instead of canvas 2019-04-15 22:58:04 +09:00
ff625253ce Merge branch 'develop' 2019-04-15 22:09:10 +09:00
8c872c6b22 11.1.1 2019-04-15 22:08:53 +09:00
541f5bc0a6 Fix bug 2019-04-15 21:59:14 +09:00
77ff7b9df0 デフォルトでHTLを表示するように 2019-04-15 21:30:49 +09:00
203cc5075e Fix application-name 2019-04-15 21:17:52 +09:00
7abfcd06da Merge branch 'develop' 2019-04-15 21:02:04 +09:00
724f81c7f3 11.1.0 2019-04-15 21:01:46 +09:00
4d2e98af7b 管理者やモデレーターはレートリミット無効に 2019-04-15 20:52:08 +09:00
08221fdda7 Fix bug 2019-04-15 20:41:56 +09:00
c0f72970b9 Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2019-04-15 20:37:29 +09:00
18bc4a49e8 ランダムにアバターを生成するように 2019-04-15 20:37:21 +09:00
f90b6dbed4 Follow lint 2019-04-15 19:05:35 +09:00
d2d991ff34 Fix error 2019-04-15 18:08:57 +09:00
190a5e175b Fix bug 2019-04-15 16:37:54 +09:00
a05f5a91b8 Merge branch 'develop' 2019-04-15 13:14:58 +09:00
4d02ff27be 11.0.3 2019-04-15 13:14:36 +09:00
df92b41d25 Fix bug 2019-04-15 13:11:17 +09:00
075af96338 Fix error 2019-04-15 12:54:42 +09:00
64bbc55336 Fix bug 2019-04-15 12:52:02 +09:00
06c621acc1 Fix bug 2019-04-15 12:49:38 +09:00
155da0c6a3 Avoid roma-ji naming 2019-04-10 20:30:00 +09:00
849 changed files with 41987 additions and 8441 deletions

View File

@ -4,14 +4,9 @@ executors:
default:
working_directory: /tmp/workspace
docker:
- image: misskey/ci:latest
- image: circleci/mongo:latest
with-redis:
working_directory: /tmp/workspace
docker:
- image: misskey/ci:latest
- image: circleci/mongo:latest
- image: misskey/ci:v11-node11
- image: circleci/redis:latest
- image: circleci/postgres:latest
docker:
working_directory: /tmp/workspace
docker:
@ -62,22 +57,10 @@ jobs:
executor:
type: string
default: "default"
without_redis:
type: boolean
default: false
executor: <<parameters.executor>>
steps:
- attach_workspace:
at: /tmp/workspace
- when:
condition: <<parameters.without_redis>>
steps:
- run:
name: Configure
command: |
mv .config/test.yml .config/test_redis.yml
touch .config/test.yml
cat .config/test_redis.yml | while IFS= read line; do if [[ "$line" = '# __REDIS__' ]]; then break; else echo "$line" >> .config/test.yml; fi; done
- run:
name: Test
command: |
@ -140,32 +123,14 @@ workflows:
branches:
only: master
- test:
name: manual-test-with-redis
executor: with-redis
name: manual-test
requires:
- manual-build
filters:
branches:
ignore: master
- test:
name: auto-test-without-redis
executor: with-redis
requires:
- auto-build
filters:
branches:
only: master
- test:
name: manual-test-with-redis
without_redis: true
requires:
- manual-build
filters:
branches:
ignore: master
- test:
name: auto-test-without-redis
without_redis: true
name: auto-test
requires:
- auto-build
filters:

View File

@ -6,8 +6,6 @@ mongodb:
db: misskey
user: syuilo
pass: ''
drive:
storage: 'db'
redis:
host: localhost
port: 6379

View File

@ -6,8 +6,6 @@ mongodb:
db: test-misskey
user: admin
pass: ''
drive:
storage: 'db'
# __REDIS__
redis:
host: localhost

View File

@ -1,5 +1,4 @@
# db settings
POSTGRES_PASSWORD="example-misskey-pass"
POSTGRES_USER="example-misskey-user"
POSTGRES_DB="misskey"
POSTGRES_PASSWORD=example-misskey-pass
POSTGRES_USER=example-misskey-user
POSTGRES_DB=misskey

View File

@ -8,6 +8,9 @@
# Final accessible URL seen by a user.
url: https://example.tld/
# ONCE YOU HAVE STARTED THE INSTANCE, DO NOT CHANGE THE
# URL SETTINGS AFTER THAT!
# ┌───────────────────────┐
#───┘ Port and TLS settings └───────────────────────────────────
@ -62,6 +65,13 @@ db:
user: example-misskey-user
pass: example-misskey-pass
# Whether disable Caching queries
#disableCache: true
# Extra Connection options
#extra:
# ssl: true
# ┌─────────────────────┐
#───┘ Redis configuration └─────────────────────────────────────
@ -78,47 +88,6 @@ redis:
# port: 9200
# pass: null
# ┌────────────────────────────────────┐
#───┘ File storage (Drive) configuration └──────────────────────
drive:
storage: 'fs'
# OR
# storage: 'minio'
# bucket:
# prefix:
# config:
# endPoint:
# port:
# useSSL:
# accessKey:
# secretKey:
# S3 example
# storage: 'minio'
# bucket: bucket-name
# prefix: files
# config:
# endPoint: s3-us-west-2.amazonaws.com
# region: us-west-2
# useSSL: true
# accessKey: XXX
# secretKey: YYY
# S3 example (with CDN, custom domain)
# storage: 'minio'
# bucket: drive.example.com
# prefix: files
# baseUrl: https://drive.example.com
# config:
# endPoint: s3-us-west-2.amazonaws.com
# region: us-west-2
# useSSL: true
# accessKey: XXX
# secretKey: YYY
# ┌───────────────┐
#───┘ ID generation └───────────────────────────────────────────
@ -132,6 +101,9 @@ drive:
# ulid ... Millisecond accuracy
# objectid ... This is left for backward compatibility
# ONCE YOU HAVE STARTED THE INSTANCE, DO NOT CHANGE THE
# ID SETTINGS AFTER THAT!
id: 'aid'
# ┌─────────────────────┐
@ -144,5 +116,25 @@ autoAdmin: true
# Whether disable HSTS
#disableHsts: true
# Clustering
# Number of worker processes
#clusterLimit: 1
# Job concurrency per worker
# deliverJobConcurrency: 128;
# inboxJobConcurrency: 16;
# IP address family used for outgoing request (ipv4, ipv6 or dual)
#outgoingAddressFamily: ipv4
# Syslog option
#syslog:
# host: localhost
# port: 514
# Proxy for HTTP/HTTPS
#proxy: http://127.0.0.1:3128
# Proxy for SMTP/SMTPS
#proxySmtp: http://127.0.0.1:3128 # use HTTP/1.1 CONNECT
#proxySmtp: socks4://127.0.0.1:1080 # use SOCKS4
#proxySmtp: socks5://127.0.0.1:1080 # use SOCKS5

View File

@ -1,23 +1,23 @@
{
"parserOptions": {
"parser": "typescript-eslint-parser"
"parser": "@typescript-eslint/parser"
},
"extends": [
"eslint:recommended",
"plugin:vue/recommended"
],
"rules": {
"vue/require-v-for-key": false,
"vue/max-attributes-per-line": false,
"vue/html-indent": false,
"vue/html-self-closing": false,
"vue/no-unused-vars": false,
"vue/attributes-order": false,
"vue/require-prop-types": false,
"vue/require-default-prop": false,
"vue/html-closing-bracket-spacing": false,
"vue/singleline-html-element-content-newline": false,
"vue/no-v-html": false,
"vue/require-v-for-key": 0,
"vue/max-attributes-per-line": 0,
"vue/html-indent": 0,
"vue/html-self-closing": 0,
"vue/no-unused-vars": 0,
"vue/attributes-order": 0,
"vue/require-prop-types": 0,
"vue/require-default-prop": 0,
"vue/html-closing-bracket-spacing": 0,
"vue/singleline-html-element-content-newline": 0,
"vue/no-v-html": 0,
"no-console": 0,
"no-unused-vars": 0,
"no-empty": 0

6
.gitattributes vendored
View File

@ -1,5 +1,7 @@
*.svg -diff -text
*.psd -diff -text
*.ai -diff -text
yarn.lock -diff -text
package-lock.json -diff -text
*.mqo -diff -text
*.glb -diff -text
*.blend -diff -text
*.afdesign -diff -text

4
.github/CODEOWNERS vendored
View File

@ -1,7 +1,7 @@
# PATH OWNERS
/.autogen/ @acid-chicken
/.circleci/ @syuilo @acid-chicken
/.config/ @syuilo @AyaMorisawa @mei23 @acid-chicken
/.config/ @syuilo @AyaMorisawa @mei23 @acid-chicken @rinsuki
# /.config/mongo_initdb_example.js @khws4v1
/.github/ @syuilo @AyaMorisawa @acid-chicken
/.vscode/ @acid-chicken
@ -12,7 +12,7 @@
# /docs/*.fr.md @BoFFire
# /docs/docker.*.md @khws4v1
/locales/ @syuilo
/src/ @syuilo @AyaMorisawa @mei23 @acid-chicken
/src/ @syuilo @AyaMorisawa @mei23 @acid-chicken @rinsuki
# /src/crypto_key.cc @akihikodaki
# /src/crypto_key.d.ts @akihikodaki
/.dockerignore @syuilo # @khws4v1

3
.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1,3 @@
# These are supported funding model platforms
patreon: syuilo

25
.gitignore vendored
View File

@ -1,11 +1,21 @@
# Visual Studio Code
/.vscode
!/.vscode/extensions.json
# Intelij-IDEA
/.idea
# Node.js
/node_modules
# config
/.config/*
!/.config/example.yml
!/.config/mongo_initdb_example.js
/.vscode
/node_modules
# misskey
/build
/built
built
/data
/.cache-loader
/db
@ -17,6 +27,13 @@ api-docs.json
*.log
/redis
*.code-workspace
yarn.lock
.DS_Store
/files
ormconfig.json
# blender backups
*.blend1
*.blend2
*.blend3
*.blend4
*.blend5

View File

@ -1 +1 @@
v11.7.0
v12.8.1

View File

@ -2,10 +2,10 @@
"recommendations": [
"ducksoupdev.vue2",
"editorconfig.editorconfig",
"eg2.tslint",
"eg2.vscode-npm-script",
"hollowtree.vue-snippets",
"ms-vscode.typescript-javascript-grammar",
"ms-vscode.vscode-typescript-tslint-plugin",
"octref.vetur",
"sysoev.language-stylus"
]

View File

@ -1,12 +1,738 @@
ChangeLog
=========
If you encounter any problems with updating, please try the following:
1. `npm run clean` or `npm run cleanall`
2. Retry update (Don't forget `npm i`)
11.31.0 (2019/09/02)
--------------------
### ✨Improvements
* Syslogサポート
* チャートの同期機能をAPI経由で使えるように
* SMTPでProxyを使用できるように
* リアクションにホバーすることで誰がリアクションしたか見れるように
* リプライ時、返信元のlocalOnly属性を引き継ぐように
* 引用付き、ローカルのみなどの案内文にアイコン追加
* AP deliver/inbox job の並列度を変更できるように
* clusterLimitの既定値を1に
* AP inbox ジョブの並列度を下げる
* CWが付いた投稿はAP上でNote.sensitiveフラグを付けるように
* メモウィジェットの内容を自動で保存するように
* ページURLが他と重複してたらエラーを投げるように
* ページURLが空の時エラーを投げるように
* リアクションが解除されたときはアニメーションしないように
* 設定の各セクションごとにURLを割り当てるように
* 管理画面の各セクションごとにURLを割り当てるように
### 🐛Fixes
* 未実装のTLのRenoteクエリを実装
* タイムラインAPIのexcludeNsfwオプションを実装
* ユーザーページの投稿一覧の私の投稿にRenoteが表示される問題を修正
* meta APIでemojiプロパティに不要な情報が含まれているのを修正
* モバイル版でドライブのファイルを削除したときの挙動がおかしい問題を修正
* visiblity-chooserにlocalOnly属性が伝わらなかったのを修正
* 言語指定したときコードブロックが表示されない問題を修正
* トークのメッセージがはみ出す問題を修正
* CWの中のサムネイルのサイズが変なのを少し修正
* リアクションが初めて付いた時のエフェクトが消えている問題を修正
* 無効になっているスイッチを操作できる問題を修正
* Mキー連打で画面が真っ暗問題を修正
* AmazonのURLプレビューが出来ない問題を修正
* 表記ゆれを修正
11.30.0 (2019/08/24)
--------------------
### ✨Improvements
* Room: 家具をすべてしまうボタンを追加
* Room: カップ麺追加
* Room: ホログラフィックディスプレイ追加
* Room: エナジードリンク追加
* Room: ピンギンの色を変えられるように
* Room: プレビューの見やすさを向上
* Room保存時にダイアログを表示するように
* Roomから移動するときに未保存ならば警告するように
### 🐛Fixes
* MisskeyRoomからページを戻した時、テキスト入力画面で選択位置変更ができない問題を修正
11.29.0 (2019/08/19)
--------------------
### ✨Improvements
* Room: ソファ追加
* Room: 螺旋階段追加
* Room: ゴミ箱追加
### 🐛Fixes
* Room: 部屋を離れても裏でレンダリングが続く問題を修正
* Room: アバターのレンダリングを修正
* Room: ライティングの調整
11.28.2 (2019/08/18)
--------------------
### 🐛Fixes
* 他人の部屋なのに部屋編集UIが表示されるのを修正
* オブジェクトストレージを使用している場合Roomで画像を読み込めない問題を修正
11.28.1 (2019/08/18)
--------------------
### 🐛Fixes
* オブジェクトストレージを使用している場合Roomで画像を読み込めない問題を修正
* Roomで家具を移動など確定せずに「しまう」と部屋ごと消える問題を修正
11.28.0 (2019/08/18)
--------------------
### ✨Improvements
* 自分の部屋を作れるように
* Delキーを押して投稿を削除するときに確認ダイアログを出すように
* Elasticsearchのインデックス名をconfigで変更できるように
### 🐛Fixes
* コンテンツを遡ってる途中に新しいアイテムが先頭に追加されると上限に達している場合末尾のアイテムが削除される問題を修正
* ユーザー名が突き抜けるのを修正
* ユーザー一覧とかでサイレンス・凍結されたユーザーの状態が表示されてなかったのを修正
* タイトルやアイコンがきちんと設定されないことがあるのを修正
* ドライブアップロード直後に取得できるURLがoriginalじゃない問題を修正
* リモートユーザー向けのNoteUnreadsレコードが作成される問題を修正
* Hashtagがupdateできない問題を修正
* ハッシュタグの更新がタグの数だけ並列で行われてDBを重くしてしまうことがあるのを修正
11.27.1 (2019/08/01)
--------------------
### 🐛Fixes
* オブジェクトストレージに関する問題を修正
11.27.0 (2019/07/29)
--------------------
### ✨Improvements
* 「削除して編集」機能を追加
* HTTPリクエストのKeep-AliveとPrxoy対応(サーバーのパフォーマンス向上)
* 通知を種類でフィルタリングして表示できるように
* モバイルで通知ページを表示することができるように
* 非ログイン時の警告処理
### 🐛Fixes
* リモートの絵文字が更新されない問題を修正
* リンクバリデーションリンクが一瞬表示されてしまう問題を修正
* 選択していない状態でウィジェットが追加できる問題を修正
11.26.2 (2019/07/25)
--------------------
### 🐛Fixes
* すでに使われたことのあるユーザー名を再度使えないように
* モバイルのウィジェットページが常に i/update-client-setting を呼び続ける問題を修正
* 投稿フォームのヘッダに添付ファイル数がちゃんと表示されない問題を修正
11.26.1 (2019/07/21)
--------------------
### 🐛Fixes
* リモートアンケートの期限が保存されないのを修正
* 自分をブロックしているユーザーがおすすめユーザーに表示されている問題を修正
* スクロールしてると絵文字ピッカーの位置がずれる問題を修正
* 投稿フォームが画面外にはみ出さないように
* 投稿フォームの「引用付き」の表示が見づらい問題の修正
* 投稿フォームにもうリノートや引用ノートのデータがある場合はリンクを貼っても「引用として添付しますか?」のダイアログボックスが出ないように
* 「タイムライン上部に投稿フォームを表示する」機能の使用時、ノートを投稿しても引用ノートのデータが残る問題の修正
* デスクトップ版のアクティビティウィジェットの日付とデータの表示が変だったのを修正
11.26.0 (2019/07/19)
--------------------
### ✨Improvements
* モデレーターログを記録して確認できるように
* プロフィールに追加情報を設定できるように
* Mastodonのリンクの所有者認証に対応
* AP: Delete Person アクティビティを配信するように
* AP: Delete アクティビティの後にフォロー解除するように
* AP: アカウント削除でもDelete activityを配信するように
* Pages: ラジオボタンを追加
* AdminページのUsers Viewでユーザーのレコードをクリックすることですぐユーザーを照会できるように
* AdminページのUsers Viewでユーザー一覧からユーザー名とホスト情報で検索できるように
* 特定ホストへのメンションの特別処理をクライアントに追加
* 設定画面でデスクトップ・モバイルモード変更時はすぐにrefreshするか伺うように
* ペーストされたファイル名のテンプレート変更時すぐどのようになるか見れるように
* (コ`・ヘ・´ケ)を追加
### 🐛Fixes
* ログインのログが正しく保存されない問題を修正
* 同じユーザー名のユーザーが作成できてしまうことがある問題を修正
* 報告されたレポート内容が表示されない問題を修正
* リモートのプロフィールの追加情報が表示されない問題を修正
* 「見つける」のタグが大文字小文字区別されている問題を修正
* 管理画面のインスタンス一覧でソートが正しく機能していない問題を修正
* プロフィール設定でバナーに動画を設定すると以降編集ができない問題を修正
* ウェブ検索エンジンの設定でグリッチが発生する問題を修正
* MFMの引用がインライン表示になっている問題を修正
* アンケートの期限入力部分のタイトル表示がおかしい問題を修正
* 画面上の項目がすべていなくなると実際はロードされてないだけのファイルやフォルダーがあるにも関わらず「もっと読み込む」ボタンがなくなり「このフォルダーは空です」っていうplaceholderが表示されてしまう問題を修正
* proxy-media後のContent-Typeが違う問題を修正
* ビルド時にエラーが出るのを修正
11.25.1 (2019/07/09)
--------------------
### 🐛Fixes
* ページイベントが正しくストリームに流れてこない問題を修正
* フォントの調整
11.25.0 (2019/07/08)
--------------------
### ✨Improvements
* パスワード無しログイン機能
* MisskeyPagesにイベント送信ボタンを追加
* MisskeyPagesでボタンを目立たせることができるように
* ページをピン留めできるように
* デッキのカラム内でページを見れるように
* 既定のアップロード先フォルダを設定できるように
* ファイルをペーストしてアップロードするときのファイル名をカスタマイズできるように
* 公開以外へのリプライ時元の公開範囲で指定したユーザー情報を引き継ぐように
* デスクトップ版を使うかモバイル版を使うか手動で設定できるように
* フォルダーを削除できないときダイアログボックスで知らせるように
### 🐛Fixes
* postgres redis cache の option が適用されない問題を修正
* 一部MFMテキストが折り返されず突き抜ける問題を修正
11.24.2 (2019/07/05)
--------------------
### 🐛Fixes
* チャートAPIの返り値が文字列になっていることがある問題を修正
* チャートに数字が表示される問題を修正
* ペタバイト単位が表示できない問題を修正
* SingleLineなMFMが折り返されてしまう問題を修正
11.24.1 (2019/07/05)
--------------------
### 🐛Fixes
* WebAuthnでログインできない問題を修正
* 絵文字の変更事項のmetaへの反映が最大時間遅延される問題を修正
* ハッシュタグのトレンドの計算を5分単位で丸めるように
* APNGでもMIME typeはimage/pngにするように
* カスタム絵文字リアクションがたまに文字になってしまう問題を修正
11.24.0 (2019/07/05)
--------------------
### 注意
- このアップデート後に、`node built/tools/accept-migration Init 1000000000000`してください。
- プロセスを起動(もしくは再起動)する前に[マイグレーション](#migration)の手順を実行してください
### ✨Improvements
* WebAuthnサポート
* APNGサポート
* アバターファイル選択でimage以外は表示しないように
* データベース手動バキューム機能
* メールサーバー設定が正しいか確認できるように
* ピン止めの上限に達したときエラーを表示するように
* AP: attributedTo, to, cc が Array や Object のパターンに対応
* AP: object type が Audio, Document, Image, Page, Video のパターンに対応
* フォロー解除時に確認ダイアログを表示するように
* ユーザー入力ダイアログで、入力時にユーザーの存在を確認するように
### 🐛Fixes
* 自分のインスタンスのルートURIへのリンクが無になる問題を修正
* リモートファイルの削除が重い問題を修正
* 投稿などの連続したスペースがひとつに纏まるのを修正
* MFMのパース修正
* マイグレーション時にエラーが出る問題を修正
11.23.1 (2019/06/25)
--------------------
### 🐛Fixes
* クライアントの設定がリセットされることがある問題を修正
11.23.0 (2019/06/23)
--------------------
### ✨Improvements
* ホーム/デッキのカスタマイズ情報を複数のデバイスで同期できるように
* ホーム/デッキのカスタマイズ情報の複数プリセット切り替え
* サーバー情報にRedisのバージョンを追加
* ServiceWorker有効化
* MisskeyPagesでリストの要素数を取得する関数を追加
* URLプレビューでハッシュだけ違うプレビューカードは表示しないように
* URLプレビューをユーザーロケールで出し分けるように
* リモートの凍結されたアカウントからのアクティビティはすべて無視するように
### 🐛Fixes
* フォロー解除してもフォローボタンがフォロー中のままになる問題を修正
11.22.0 (2019/06/18)
--------------------
### ✨Improvements
* 管理画面でデータベースの各テーブルのレコード数やサイズを確認できるように
* サーバー情報にPostgreSQLのバージョンを追加
### 🐛Fixes
* リモートファイルのダウンロードに失敗することがある問題を修正
* アンケートの期間を日時指定で選択すると日時がUTCになってしまう問題を修正
* MFMのパースを修正
11.21.0 (2019/06/16)
--------------------
### ✨Improvements
* Unicode 12.0 の絵文字に対応
* 閉鎖しているホストにはAP deliverしないように
* image以外はproxyしないように
### 🐛Fixes
* サムネイル生成でエラーになるとファイルのアップロードに失敗する問題を修正
* オートコンプリートにアニメーション停止が効かない問題を修正
11.20.4 (2019/06/13)
--------------------
### 🐛Fixes
* 検索結果がループする問題を修正
* 設定でPostgreSQLのクエリー結果のキャッシュを無効できるように
* 「投稿内の動きのあるテキストを無効にする」だけ反応しない問題を修正
* 特定の操作のデータベースのパフォーマンス調整
11.20.3 (2019/06/10)
--------------------
### 🐛Fixes
* 絵文字サジェストが動作しなくなっていた問題を修正
11.20.2 (2019/06/10)
--------------------
### 🐛Fixes
* Redisにパスワードを設定している場合接続できない問題を修正
* i18n
* など
11.20.1 (2019/06/07)
--------------------
### 🐛Fixes
* リモートファイルのキャッシュをすべて削除するときの動作を修正
* ストリームのハッシュタグチャンネルが死んでいる問題を修正
* Pagesから他の同一インスタンス内のPagesのページへのリンクができない問題を修正
* /api/notes/create 公開範囲private を渡すとタイムアウトする問題を修正
* パスワードの確認が完了しなくてもユーザー登録できる問題を修正
* 依存関係の更新
* i18n
11.20.0 (2019/05/27)
--------------------
### ✨Improvements
* 管理画面からリモートファイルのキャッシュをすべて削除できるように
* 投稿フォームに投稿のURLをペーストしようとすると引用RNにできるように
* モバイル版の投稿フォームにファイルをドロップできるように
* モバイル版でも投稿の下書き自動保存ができるように
* リモートファイルのキャッシュが期限切れになったときにサムネイルが無くならないように
* ジョブキュー管理画面を強化
### 🐛Fixes
* 投稿内のローカルなURLプレビューをクリックしたとき not found になることがある問題を修正
* デスクトップでユーザーページに遷移するときページが再度読み込みされることがある問題を修正
* フォロー申請自動承認オプションが常にオフで表示される問題を修正
* ポートを設定せずに起動したときに適切なエラーメッセージが表示されない問題を修正
* i18n
11.19.1 (2019/05/26)
--------------------
### 🐛Fixes
* タグページを遷移してもタイムラインが変わらない問題を修正
* インスタンス名を空にしてもMisskeyロゴが表示されない問題を修正
* 投稿内のローカルなURLをクリックしたとき not found になることがある問題を修正
* npm run init がプロセス終了しない問題を修正
11.19.0 (2019/05/25)
--------------------
### ✨Improvements
* グループのオーナーを変えられるように
* PagesでURLプレビューを表示するように
* サーバーログを削除できるように
* リンク先が同じインスタンスの投稿内のURLをクリックしたときは新しいタブで開かないように
* PostgreSQLの接続オプションを設定ファイルで設定できるように
* いくつかのAPIでのパフォーマンスを向上
* ユーザビリティの向上
* デザインの調整
### 🐛Fixes
* デッキでユーザーページを遷移したときに前のユーザーのタイムラインが残り続ける問題を修正
* デッキでフォロー申請が見れない問題を修正
* グループ情報が更新できない問題を修正
* Firefoxでトークの下が隠れてしまう問題を修正
* トーク履歴がないと履歴が読み込み中のままになる問題を修正
* 通知で長い名前のユーザーがいると横スクロールが発生する問題を修正
* iOSでの選択ダイアログの動作を修正
11.18.1 (2019/05/21)
--------------------
### 🐛Fixes
* 11.18.0からフォロー/フォロワーのもっと読み込む機能が作動していない問題を修正
* iOSで投稿フォームに自動フォーカスしない問題を修正
* ダークモードでグループ名がみにくい問題を修正
* ハッシュタグタイムラインを読み込んだ時にプログレスバーが残り続ける問題を修正
* ユーザビリティの修正
11.18.0 (2019/05/21)
--------------------
### ✨Improvements
* デザインの調整
### 🐛Fixes
* 投稿の削除が連合しない問題を修正
11.17.1 (2019/05/20)
--------------------
### 🐛Fixes
* トークの通知インジケーターが点灯し続ける問題を修正
* ユーザーグループの読み込みでエラーになることがある問題を修正
11.17.0 (2019/05/19)
--------------------
### 注意
このアップデートを適用した後、プロセスを起動(もしくは再起動)する前に[マイグレーション](#migration)の手順を実行してください
### ✨Improvements
* ユーザーグループを招待制に
### 🐛Fixes
* フォロー申請が表示されない問題を修正
* トークの通知インジケーターが点灯し続ける問題を修正
* 自分を自分のグループから削除できる問題を修正
* 新しいタブでグループトークを開くことができない問題を修正
11.16.1 (2019/05/19)
--------------------
### 🐛Fixes
* Dockerで起動できない問題を修正
11.16.0 (2019/05/19)
--------------------
### 注意
このアップデートを適用した後、プロセスを起動(もしくは再起動)する前に[マイグレーション](#migration)の手順を実行してください
### ✨Improvements
* ユーザーグループ機能を追加
* ページに「いいね」できるように
* UIの改善
### 🐛Fixes
* トークを読み込むときに最大数指定できなかった問題を修正
11.15.0 (2019/05/16)
--------------------
### ✨Improvements
* 管理画面でreCAPTCHAのプレビューを表示するように
### 🐛Fixes
* オブジェクトストレージのリージョンの設定が反映されない問題を修正
11.14.0 (2019/05/16)
--------------------
### 注意
このバージョンからオブジェクトストレージの設定は設定ファイルではなく管理画面から行うようになりました。
オブジェクトストレージを使用している場合、アップデートした後管理画面にアクセスしオブジェクトストレージの設定を再度行ってください。
### ✨Improvements
* 特定のユーザーのファイルをすべて削除できるように
* インスタンスの設定画面を整理
### 🐛Fixes
* GIF画像のサムネイルが生成されないのを修正
* 管理画面の「ログ」で複数の除外条件を設定できない問題を修正
11.13.0 (2019/05/14)
--------------------
### 注意
このアップデートを適用した後、プロセスを起動(もしくは再起動)する前に[マイグレーション](#migration)の手順を実行してください
### ✨Improvements
* 利用規約URL、リポジトリURL、フィードバックURLを設定できるように
* 特定のインスタンスのファイルをすべて削除できるように
* _blankで外部リンクされる可能性がある箇所にnoopenerを追加
* ユーザーや外部インスタンスが生成するリンクにnofollowを追加
* リモートのユーザーページやートページにnoindexを追加
* 自分のユーザーメニューにはミュートなどを表示しないように
* デザインの調整
### 🐛Fixes
* インスタンスブロックを設定できない問題を修正
* ピン留め投稿の表示順がおかしい問題を修正
* 設定の「アップデートを確認」でメッセージが正しく表示されない問題を修正
* Firefoxで自分のメニューが開けない問題を修正
* Welcomeページのタグクラウドが動かない問題を修正
11.12.0 (2019/05/10)
--------------------
### 注意
このアップデートを適用した後、プロセスを起動(もしくは再起動)する前に[マイグレーション](#migration)の手順を実行してください
### ✨ Improvements
* インスタンス運営者がおすすめアカウントを設定できるように
* MisskeyPagesでNAME環境変数がNULLにならないように
* MisskeyPagesにNULL環境変数を追加
* MisskeyPagesで変数を並べ替えられるように
* MisskeyPagesのテキストのリスト内で変数埋め込みできるように
* 自分の指定した投稿のRenoteを全て解除するAPIを追加
### 🐛Fixes
* Noteをpull取得した時にhost名がvalidateされていない問題を修正
* みつけるで人気のタグが表示されない問題を修正
### その他
* アカウントのisVerifiedフラグを廃止
11.11.2 (2019/05/07)
--------------------
### 🐛Fixes
* IPv4 onlyホストからDualstackホストにAP deliverできない問題を修正
* ストリーミングに接続するまでラグがある問題を修正
* 2段階認証のコードが0から始まる時正しく入力できない問題を修正
* ユーザーの更新日時が新しい順で更新日時がnullのユーザーが先頭に来る問題を修正
* 値選択時の問題を修正
* リバーシでマップの変更が反映されない問題を修正
* リバーシで対局終了直後に盤面を巻き戻してもすぐ最終ターンまでリセットされる問題を修正
11.11.1 (2019/05/05)
--------------------
### 🐛Fixes
* MisskeyPagesのリストから選択関数が使えない問題を修正
11.11.0 (2019/05/05)
--------------------
### ✨ Improvements
* MisskeyPagesにリストから選択関数を追加
* MisskeyPagesに確率を指定できるテキストランダム選択関数を追加
* 外部サービス連携ログインリンクにアイコン追加
### 🐛Fixes
* MisskeyPagesでifを入れ子にできなくなっていた問題を修正
* MisskeyPagesで数値入力を作成するとテキスト入力になる問題を修正
* 外部サービス連携に関する問題を修正
11.10.1 (2019/05/04)
--------------------
### 🐛Fixes
* MisskeyPagesでページブロックを削除できなくなっていた問題を修正
### その他
* Node.js v12対応
11.10.0 (2019/05/03)
--------------------
### 注意
このアップデートを適用した後、プロセスを起動(もしくは再起動)する前に[マイグレーション](#migration)の手順を実行してください
### ✨ Improvements
* MisskeyPagesに割った余りを求める関数を追加
* Mastodon v2.8.0 のフォローリストをインポートできるように
* エクスポートリクエストに失敗したらエラーを表示するように
* エクスポートファイルでは同一ハッシュチェックをしないように
### 🐛Fixes
* 2段階認証を設定するとログインできなくなる問題を修正
* ファイルをアップロードできないことがある問題を修正
* リモートファイルをキャッシュしない設定だとサムネイル時にオリジナル画像が表示されない問題を修正
* 外部サービス連携の不具合を修正
11.9.0 (2019/05/02)
-------------------
### ✨ Improvements
* MisskeyPagesで編集時にページブロックをドラッグで並べ替えられるように
* MisskeyPagesにカウンターボタンブロックを追加
11.8.1 (2019/05/02)
-------------------
### 🐛Fixes
* リモートファイルをキャッシュしないオプション有効時にファイルが作成できない問題を修正
11.8.0-2 (2019/05/01)
-------------------
* 11.8.0 のリリース内容が 11.7.0 と同一だったのを修正
11.8.0 (2019/05/01)
-------------------
### ✨ Improvements
* MisskeyPagesで関数を作成できるように
* MisskeyPagesでソースを表示できるように
* MisskeyPagesにシードを与えるランダム関数を追加
* MisskeyPagesに複数行テキストをテキストのリストに変換する関数を追加
### 🐛Fixes
* APIドキュメントが見れなくなっていたのを修正
* mention (あなた宛て) streaming にミュートが効かない問題を修正
* デザインの調整
11.7.0 (2019/04/30)
-------------------
### ✨ Improvements
* MisskeyPagesに ifブロック を追加
* MisskeyPagesに テキストエリア を追加
* MisskeyPagesに 複数行テキスト入力 を追加
* MisskeyPagesに 投稿フォーム を追加
* MisskeyPagesに 変換系関数 を追加
* MisskeyPagesに 環境変数 URL を追加
* MisskeyPagesでボタンやスイッチなどのテキストに変数使えるように
### 🐛Fixes
* OGPのサイト名を修正
* デザインの調整
11.6.0 (2019/04/29)
-------------------
### ✨ Improvements
* AiScriptにいくつかの文字列操作関数を追加
* ページ編集画面にページへのリンクを表示するように
### 🐛Fixes
* MisskeyPagesで数値入力が文字列として扱われる問題を修正
* デザインの調整
11.5.1 (2019/04/29)
-------------------
### 🐛Fixes
* MisskeyPagesで環境変数を別の変数内で使えない問題を修正
* MisskeyPagesで値が0の変数が表示されない問題を修正
11.5.0 (2019/04/29)
-------------------
### 注意
このアップデートを適用した後、プロセスを起動(もしくは再起動)する前に[マイグレーション](migration)の手順を実行してください
### New features
#### MisskeyPages
ページ(記事)を作成できるように。
* 後から何度でも編集できる
* アイキャッチを設定できる
* フォントを設定できる
* 画像を好きな位置に挿入できる
* URLを決められる
* タイトルを設定できる
* 見出しを設定できる
* ページの要約を設定できる(URLプレビュー時などに便利)
* 変数や式(aka AiScript)を使用して動的なページも作れる
* 目次自動生成(coming soon)
ページを気に入ったら「いいね」しよう (coming soon)
### ✨ Improvements
* APIコンソールでパラメータテンプレートを表示するように
### 🐛Fixes
* おすすめユーザーに自分自身が含まれる問題を修正
* ユーザーサジェストで表示名が変わらない問題を修正
11.4.0 (2019/04/25)
-------------------
### ✨ Improvements
* 検索でローカルの投稿のみに絞れるように
* 検索で特定のインスタンスの投稿のみに絞れるように
* 検索で特定のユーザーの投稿のみに絞れるように
### 🐛Fixes
* 投稿が増殖する問題を修正
* ストリームで過去の投稿が流れてくる問題を修正
* モバイル版のユーザーページで遷移してもユーザー名が変わらない問題を修正
* お知らせを切り替えても内容が変わらない問題を修正
11.3.1 (2019/04/24)
-------------------
### 🐛Fixes
* Webからファイルがアップロードできない問題を修正
11.3.0 (2019/04/24)
-------------------
### ✨ Improvements
* お知らせにMFMを使えるように
* お知らせに画像を添付できるように
### 🐛Fixes
* 投稿のタグ検索APIで大文字小文字が区別されていたのを修正
* 公開範囲がホームの投稿がグローバルTLに流れる問題を修正
* モバイルビューの投稿詳細にて acct が長いとアイコンが圧迫面接される問題を修正
11.2.2 (2019/04/22)
-------------------
### 🐛Fixes
* 2段階認証を有効にするとログインできない問題を修正
* リモートユーザーの修復処理が自動的に実行されない問題を修正
* リモートユーザー情報が更新されない問題を修正
11.2.1 (2019/04/21)
-------------------
### 🐛Fixes
* MEIDが25桁になっているのを修正
* リモートユーザー情報が更新されない問題を修正
11.2.0 (2019/04/18)
-------------------
### ✨ Improvements
* 検索で日付(日時)を入力するとタイムラインをその時点まで遡るように
* APIコンソールでエンドポイントをサジェストするように
* モバイル版でドライブのメニューを使いやすく
* サイレンス時に確認を表示するように
* ユーザーメニューでブロックなどの操作を行う時に確認するように
### 🐛Fixes
* アプリケーション連携画面でパーミッションが表示されない問題を修正
* アンケートウィジットでもMFMを使用するように
* フォローしてないユーザーのホーム投稿がSTLに流れてくる問題を修正
* モバイル版でウィジェットを設定できない問題を修正
* スプラッシュがクリックに反応するように
11.1.6 (2019/04/18)
-------------------
### 🐛Fixes
* 未認知ユーザーからActivityが飛んできた場合に処理できない問題を修正
* その投稿を見たのにも関わらずメンションインジケーターが点灯し続ける問題を修正
* ハッシュタグの判定を改善
* サーバーのエラーハンドリングを改善
11.1.5 (2019/04/17)
-------------------
### 🐛Fixes
* ユーザー名に含まれているカスタム絵文字が表示されないことがある問題を修正
* 壁紙の設定ができない問題を修正
* デザインの調整
11.1.4 (2019/04/17)
-------------------
### 🐛Fixes
* タイムライン取得時に削除されたファイルを添付している投稿が含まれているとサーバーでエラーになる問題を修正
* 管理画面のインスタンスメニューで変更前の設定が読み込まれないことがある問題を修正
* 猫ではないのに猫のままで表示される問題を修正
* admin/driveのアイコンがずれてる問題を修正
* チャートで大きな数値を扱えない問題を修正
* UIの修正
11.1.3 (2019/04/16)
-------------------
### 🐛Fixes
* アプリからAPIにリクエストするときにランダムなユーザーがリクエストしたことになる問題を修正
11.1.2 (2019/04/15)
-------------------
### 🐛Fixes
* 画像描画の依存関係を変更
* リモートユーザーのファイルを削除するときに古い方からではなく新しい方から削除されるのを修正
* リアクションしてないのにリアクションしたことになる問題を修正
* APIドキュメントの修正
11.1.1 (2019/04/15)
-------------------
### 🐛Fixes
* Metaタグの application-name を Misskey で固定するように修正
* トークメッセージが既読にならない問題を修正
* デフォルトでHTLを表示するように
11.1.0 (2019/04/15)
-------------------
### ✨ Improvements
* アイコン未設定時にランダムな画像を表示するように
* 管理者やモデレーターはレートリミット無効に
### 🐛Fixes
* メンションの「あなた」インジケーターが表示されない問題を修正
* ブロックAPIでエラーが発生する問題を修正
* プッシュ通知の購読に失敗する問題を修正
11.0.3 (2019/04/15)
-------------------
### 🐛Fixes
* ハッシュタグ検索APIが動作しない問題を修正
* モデレーターなのにアカウントメニューに「管理」が表示されない問題を修正
* プッシュ通知の購読に失敗する問題を修正
* ユーザー取得APIでユーザーを指定しない場合エラーになる問題を修正
11.0.2 (2019/04/15)
-------------------
### 🐛Fixes
* アプリが作成できない問題を修正
* 「ハイライト」が表示されない問題を修正
* リモートの投稿に添付されている画像が小さい問題を修正
@ -15,15 +741,19 @@ If you encounter any problems with updating, please try the following:
11.0.1 (2019/04/15)
-------------------
### ✨ Improvements
* 不要な依存関係を削除
11.0.0 daybreak (2019/04/14)
----------------------------
### ✨ Improvements
* **データベースがMongoDBからPostgreSQLに変更されました**
* **Redisが必須に**
* アカウントを完全に削除できるように
* 投稿フォームで添付ファイルの閲覧注意を確認/設定できるように
* ミュート/ブロック時にそのユーザーの投稿のウォッチをすべて解除するように
### 🐛Fixes
* フォロー申請数が実際より1すくなくなる問題を修正
* リストからアカウント削除したユーザーを削除できない問題を修正
* リストTLでフォローしていないユーザーの非公開投稿が流れる問題を修正
@ -41,7 +771,39 @@ If you encounter any problems with updating, please try the following:
* 依存ライブラリの問題と思わるため、対応が難しい
### Migration
coming soon...
#### 移行の注意点
**以下のデータは引き継がれません**
* 通知
* リモートの投稿
* リバーシの対局
#### 手順
1. v11をインストールしたい場所に syuilo/misskey をクローン
2. config を設定する
* PostgreSQL(`db`)の設定とは別に、v10からMongoDBの設定をコピペしてくる(例は下にあります)
* `id`の設定を`meid`または`objectid`にする
``` yml
db:
host: localhost
port: 5432
db: misskey
user: x
pass: x
mongodb:
user: x
pass: x
host: localhost
port: 27017
db: misskey
```
3. migration ブランチに切り替え
4. `yarn install`
5. `yarn build`
6. `yarn migrate`
7. master ブランチに戻す
8. enjoy
10.100.0
----------

View File

@ -3,28 +3,56 @@
## Issues
Feature suggestions and bug reports are filed in https://github.com/syuilo/misskey/issues .
Before creating a new issue, please search existing issues to avoid duplication.
If you find the existing issue, please add your reaction or comment to the issue.
* Please search existing issues to avoid duplication. If your issue is already filed, please add your reaction or comment to the existing one.
* If you have multiple independent issues, please submit them separately.
## Branches
* **master** branch is tracking the latest release and used for production purposes.
* **develop** branch is where we work for the next release.
* **l10n_develop** branch is reserved for localization management.
## Localization (l10n)
Please use [Crowdin](https://crowdin.com/project/misskey) for localization.
Misskey uses [Crowdin](https://crowdin.com/project/misskey) for localization management.
You can improve our translations with your Crowdin account.
Your changes in Crowdin are automatically submitted as a PR (with the title "New Crowdin translations") to the repository.
The owner [@syuilo](https://github.com/syuilo) merges the PR into the develop branch before the next release.
If your language is not listed in Crowdin, please open an issue.
![Crowdin](https://d322cqt584bo4o.cloudfront.net/misskey/localized.svg)
## Internationalization (i18n)
Misskey uses [vue-i18n](https://github.com/kazupon/vue-i18n).
Misskey uses the Vue.js plugin [Vue I18n](https://github.com/kazupon/vue-i18n).
Documentation of Vue I18n is available at http://kazupon.github.io/vue-i18n/introduction.html .
## Documentation
* Documents for contributors are located in `/docs`.
* Documents for instance admins are located in `/docs`.
* Documents for end users are located in `src/docs`.
* Documents for contributors are located in [`/docs`](/docs).
* Documents for instance admins are located in [`/docs`](/docs).
* Documents for end users are located in [`/src/docs`](/src/docs).
## Test
* Test codes are located in `/test`.
* Test codes are located in [`/test`](/test).
## Continuous integration
Misskey uses CircleCI for automated test.
Configuration files are located in `/.circleci`.
Misskey uses CircleCI for executing automated tests.
Configuration files are located in [`/.circleci`](/.circleci).
## Adding MisskeyRoom items
* Use English for material, object and texture names.
* Use meter for unit of length.
* Your PR should include all source files (e.g. `.png`, `.blend`) of your models (for later editing).
* Your PR must include the glTF binary files (`.glb`) of your models.
* Add a locale key `room.furnitures.YOUR_ITEM` at [`/locales/ja-JP.yml`](/locales/ja-JP.yml).
* Add a furniture definition at [`/src/client/app/common/scripts/room/furnitures.json5`](/src/client/app/common/scripts/room/furnitures.json5).
If you have no experience on 3D modeling, we suggest to use the free 3DCG software [Blender](https://www.blender.org/).
You can find information on glTF 2.0 at [glTF 2.0 — Blender Manual]( https://docs.blender.org/manual/en/dev/addons/io_scene_gltf2.html).
## FAQ
### How to resolve conflictions occurred at yarn.lock?
Just execute `yarn` to fix it.
## Glossary
### AP
@ -45,11 +73,65 @@ Convert な(na) to にゃ(nya)
#### Denyaize
Revert Nyaize
## Code style
### Use semicolon
To avoid ASI Hazard
## TypeScript Coding Style
### Do not omit semicolons
This is to avoid Automatic Semicolon Insertion (ASI) hazard.
Ref:
* https://www.ecma-international.org/ecma-262/#sec-automatic-semicolon-insertion
* https://github.com/tc39/ecma262/pull/1062
### Do not omit curly brackets
Bad:
``` ts
if (foo)
bar;
else
baz;
```
Good:
``` ts
if (foo) {
bar;
} else {
baz;
}
```
As a special case, you can omit the curly brackets if
* the body of the `if`-statement have only one statement and,
* the `if`-statement does not have `else`-clause.
Good:
``` ts
if (foo) bar;
```
Make sure that the condition and the body statement are on the same line.
### Do not use `==` when it can simply be replaced with `===`.
🥰
### Use only boolean (or null related) values in the condition of an `if`-statement.
Bad:
``` ts
if (foo.length)
```
Good:
``` ts
if (foo.length > 0)
```
### Do not use `export default`
This is because the current language support does not work well with `export default`.
Ref:
* https://basarat.gitbooks.io/typescript/docs/tips/defaultIsBad.html
* https://gfx.hatenablog.com/entry/2017/11/24/135343
### Don't use `export default`
Bad:
``` ts
export default function(foo: string): string {
@ -98,6 +180,20 @@ query.andWhere(new Brackets(qb => {
}));
```
### Not `null` in TypeORM
```ts
const foo = await Foos.findOne({
bar: Not(null)
});
```
のようなクエリ(`bar`が`null`ではない)は期待通りに動作しない。
次のようにします:
```ts
const foo = await Foos.findOne({
bar: Not(IsNull())
});
```
### `null` in SQL
SQLを発行する際、パラメータが`null`になる可能性のある場合はSQL文を出し分けなければならない
例えば
@ -167,3 +263,10 @@ const user = await Users.findOne(userId).then(ensure);
// }
// の糖衣構文のような扱いです
```
### Migration作成方法
```
npx ts-node ./node_modules/typeorm/cli.js migration:generate -n 変更の名前
```
作成されたスクリプトは不必要な変更を含むため除去してください。

View File

@ -1,4 +1,4 @@
FROM node:11-alpine AS base
FROM node:12.8-alpine AS base
ENV NODE_ENV=production
@ -21,7 +21,6 @@ RUN apk add --no-cache \
pkgconfig \
python \
zlib-dev
RUN npm i -g yarn
COPY package.json ./
RUN yarn install
@ -40,4 +39,4 @@ COPY --from=builder /misskey/node_modules ./node_modules
COPY --from=builder /misskey/built ./built
COPY . ./
CMD ["npm", "start"]
CMD ["npm", "run", "migrateandstart"]

View File

@ -1,6 +1,6 @@
<a href="https://xn--931a.moe/"><img src="https://github.com/syuilo/misskey/blob/develop/assets/ai-orig.png?raw=true" align="right" height="320px"/></a>
[![Misskey](/assets/title.png)](https://misskey.xyz/)
[![Misskey](/assets/title.png)](https://misskey.io/)
================================================================
[![CircleCI](https://img.shields.io/circleci/project/github/syuilo/misskey.svg?style=for-the-badge&logo=circleci)](https://circleci.com/gh/syuilo/misskey)
@ -10,7 +10,7 @@
**A forever evolving, sophisticated microblogging platform.**
<p align="justify">
<a href="https://misskey.xyz">Misskey</a> is a decentralized microblogging platform born on Earth.
<a href="https://misskey.io">Misskey</a> is a decentralized microblogging platform born on Earth.
Since it exists within the Fediverse (a universe where various social media platforms are organized),
it is mutually linked with other social media platforms.
Why don't you take a short break from the hustle and bustle of the city, and dive into a new Internet? <a href="https://joinmisskey.github.io/">Find an instance!</a>
@ -88,12 +88,14 @@ Please see the [Contribution Guide](./CONTRIBUTING.md).
<td><img src="https://avatars0.githubusercontent.com/u/10798641?s=460&v=4" alt="AyaMorisawa" width="100"></td>
<td><img src="https://avatars1.githubusercontent.com/u/30769358?s=460&v=4" alt="mei23" width="100"></td>
<td><img src="https://avatars2.githubusercontent.com/u/20679825?s=460&v=4" alt="acid-chicken" width="100"></td>
<td><img src="https://avatars2.githubusercontent.com/u/6533808?s=460&v=4" alt="rinsuki" width="100"></td>
</tr>
<tr>
<td align="center"><a href="https://github.com/syuilo">@syuilo</a></td>
<td align="center"><a href="https://github.com/AyaMorisawa">@AyaMorisawa</a></td>
<td align="center"><a href="https://github.com/mei23">@mei23</a></td>
<td align="center"><a href="https://github.com/acid-chicken">@acid-chicken</a></td>
<td align="center"><a href="https://github.com/rinsuki">@rinsuki</a></td>
</tr>
</table>
@ -102,68 +104,66 @@ Please see the [Contribution Guide](./CONTRIBUTING.md).
<!-- PATREON_START -->
<table><tr>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/5888816/36da0f7c15954df0ab13f9abdf227f66/1.jpeg?token-time=2145916800&token-hash=at8QpJXJ8C0zINY_NmoMKv-MhXVoUK-YzTgaJPJzJYU%3D" alt="Hiroshi Seki" 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="weep" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/13099460/43cecdbaa63a40d79bf50a96b9910b9d/1.jpe?token-time=2145916800&token-hash=bqwLTk0Wo0hUJJ8J5y7ii05bLzz-_CDA7Bo0Mp4RFU0%3D" alt="ne_moni" 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/19045173/cb91c0f345c24d4ebfd05f19906d5e26/1.png?token-time=2145916800&token-hash=o_zKBytJs_AxHwSYw_5R8eD0eSJe3RoTR3kR3Q0syN0%3D" alt="kiritan" width="100"></td>
<td><img src="https://c8.patreon.com/2/200/776209" alt="Denshi" 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/12913507/f7181eacafe8469a93033d85f5969c29/4.jpe?token-time=2145916800&token-hash=zEyJqVM7u9d8Ri-65fJYSJcWF1jBH1nJ5a3taRzrTmw%3D" alt="Melilot" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/5670915/ee175f0bfb6347ffa4ea101a8c097bff/1.jpg?token-time=2145916800&token-hash=mPLM9CA-riFHx-myr3bLZJuH2xBRHA9se5VbHhLIOuA%3D" alt="osapon" width="100"></td>
<td><img src="https://c8.patreon.com/2/200/16869916" alt="見当かなみ" width="100"></td>
</tr><tr>
<td><a href="https://www.patreon.com/rane_hs">Hiroshi Seki</a></td>
<td><a href="https://www.patreon.com/weepjp">weep</a></td>
<td><a href="https://www.patreon.com/user?u=13099460">ne_moni</a></td>
<td><a href="https://www.patreon.com/weepjp">weepjp</a></td>
<td><a href="https://www.patreon.com/user?u=19045173">kiritan</a></td>
<td><a href="https://www.patreon.com/user?u=776209">Denshi</a></td>
<td><a href="https://www.patreon.com/user?u=557245">mkatze</a></td>
<td><a href="https://www.patreon.com/user?u=12913507">Melilot</a></td>
<td><a href="https://www.patreon.com/osapon">osapon</a></td>
<td><a href="https://www.patreon.com/user?u=16869916">見当かなみ</a></td>
</tr></table>
<table><tr>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/12021162/963128bb8d14476dbd8407943db8f31a/1.png?token-time=2145916800&token-hash=FMV7cPKBD1TU2WTbl1jg6AcdKSvTb2BSFcDhgc-EO8w%3D" alt="gutfuckllc" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/5670915/ee175f0bfb6347ffa4ea101a8c097bff/1.jpg?token-time=2145916800&token-hash=mPLM9CA-riFHx-myr3bLZJuH2xBRHA9se5VbHhLIOuA%3D" alt="osapon" width="100"></td>
<td><img src="https://c8.patreon.com/2/200/16869916" alt="見当かなみ" width="100"></td>
<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/11357794/923ce94cd8c44ba788ee931907881839/1.png?token-time=2145916800&token-hash=9nEQje_eMvUjq9a7L3uBqW-MQbS-rRMaMgd7UYVoFNM%3D" alt="mydarkstar" width="100"></td>
<td><img src="https://c8.patreon.com/2/200/12718187" alt="Peter G." width="100"></td>
<td><img src="https://c8.patreon.com/2/200/18833336" alt="itiradi" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/13039004/509d0c412eb14ae08d6a812a3054f7d6/1.jpe?token-time=2145916800&token-hash=UQRWf01TwHDV4Cls1K0YAOAjM29ssif7hLVq0ESQ0hs%3D" alt="nemu" 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://c8.patreon.com/2/200/17463605" alt="Sampot" 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/19356899/496b4681d33b4520bd7688e0fd19c04d/2.jpeg?token-time=2145916800&token-hash=_sTj3dUBOhn9qwiJ7F19Qd-yWWfUqJC_0jG1h0agEqQ%3D" alt="sheeta.s" width="100"></td>
</tr><tr>
<td><a href="https://www.patreon.com/gutfuckllc">gutfuckllc</a></td>
<td><a href="https://www.patreon.com/osapon">osapon</a></td>
<td><a href="https://www.patreon.com/user?u=16869916">見当かなみ</a></td>
<td><a href="https://www.patreon.com/Yuzulia">YuzuRyo61</a></td>
<td><a href="https://www.patreon.com/mydarkstar">mydarkstar</a></td>
<td><a href="https://www.patreon.com/user?u=12718187">Peter G.</a></td>
<td><a href="https://www.patreon.com/user?u=18833336">itiradi</a></td>
<td><a href="https://www.patreon.com/user?u=13039004">nemu</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=17463605">Sampot</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=19356899">sheeta.s</a></td>
</tr></table>
<table><tr>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/17195955/be45e5e14c3e48b2bee0456c84e19df4/4.jpe?token-time=2145916800&token-hash=UslrPVM-8TXOe8AapuNiaFYjcIJgPNcU-fKpGbfGJNI%3D" alt="Damillora" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/16900731/935a10339daa4ede8e555903a0707060/1.png?token-time=2145916800&token-hash=c1XAS1qGBPxVdCvnICxtAUmx41mVkMG87h7cIRF9YYE%3D" alt="Atsuko Tominaga" 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/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/13034746/c711c7f58e204ecfbc2fd646bc8a4eee/1.jpe?token-time=2145916800&token-hash=EWxXhVbZYH7KB4IDT3joc8TbIg8zPO40x1r5IDn3R7c%3D" alt="Hiratake" 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>
</tr><tr>
<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/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>
</tr></table>
<table><tr>
<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/619786/32cf01444db24e578cd1982c197f6fc6/1.jpeg?token-time=2145916800&token-hash=d8jBQLMOHD87KtXs5C9fk1o58DMF73pQ-dYH3uZJPBE%3D" alt="Gargron" 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://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/damillora">Damillora</a></td>
<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/hiratake">Hiratake</a></td>
<td><a href="https://www.patreon.com/hekovic">Hekovic</a></td>
<td><a href="https://www.patreon.com/dansup">dansup</a></td>
<td><a href="https://www.patreon.com/mastodon">Gargron</a></td>
<td><a href="https://www.patreon.com/takenoko">Nokotaro Takeda</a></td>
<td><a href="https://www.patreon.com/user?u=12531784">Takashi Shibuya</a></td>
</tr></table>
<table><tr>
</tr><tr>
</tr></table>
**Last updated:** Mon, 15 Apr 2019 01:59:07 UTC
**Last updated:** Sun, 01 Sep 2019 14:07:05 UTC
<!-- PATREON_END -->
:four_leaf_clover: Copyright

Binary file not shown.

Before

Width:  |  Height:  |  Size: 148 KiB

After

Width:  |  Height:  |  Size: 148 KiB

View File

@ -9,9 +9,17 @@ This guide describes how to install and setup Misskey with Docker.
*1.* Download Misskey
----------------------------------------------------------------
1. `git clone -b master git://github.com/syuilo/misskey.git` Clone Misskey repository's master branch.
2. `cd misskey` Move to misskey directory.
3. `git checkout $(git tag -l | grep -Ev -- '-(rc|alpha)\.[0-9]+$' | sort -V | tail -n 1)` Checkout to the [latest release](https://github.com/syuilo/misskey/releases/latest) tag.
1. Clone Misskey repository's master branch.
`git clone -b master git://github.com/syuilo/misskey.git`
2. Move to misskey directory.
`cd misskey`
3. Checkout to the [latest release](https://github.com/syuilo/misskey/releases/latest) tag.
`git checkout master`
*2.* Configure Misskey
----------------------------------------------------------------
@ -57,7 +65,13 @@ Build misskey with the following:
`docker-compose build`
*5.* That is it.
*5.* Init DB
----------------------------------------------------------------
``` shell
docker-compose run --rm web yarn run init
```
*6.* That is it.
----------------------------------------------------------------
Well done! Now you have an environment to run Misskey.
@ -65,9 +79,9 @@ Well done! Now you have an environment to run Misskey.
Just `docker-compose up -d`. GLHF!
### How to update your Misskey server to the latest version
1. `git fetch`
2. `git stash`
3. `git checkout $(git tag -l | grep -Ev -- '-(rc|alpha)\.[0-9]+$' | sort -V | tail -n 1)`
1. `git stash`
2. `git checkout master`
3. `git pull`
4. `git stash pop`
5. `docker-compose build`
6. Check [ChangeLog](../CHANGELOG.md) for migration information

View File

@ -10,9 +10,17 @@ Ce guide explique comment installer et configurer Misskey avec Docker.
*1.* Télécharger Misskey
----------------------------------------------------------------
1. `git clone -b master git://github.com/syuilo/misskey.git` Clone le dépôt de Misskey sur la branche master.
2. `cd misskey` Naviguez dans le dossier du dépôt.
3. `git checkout $(git tag -l | grep -Ev -- '-(rc|alpha)\.[0-9]+$' | sort -V | tail -n 1)` Checkout sur le tag de la [dernière version](https://github.com/syuilo/misskey/releases/latest).
1. Clone le dépôt de Misskey sur la branche master.
`git clone -b master git://github.com/syuilo/misskey.git`
2. Naviguez dans le dossier du dépôt.
`cd misskey`
3. Checkout sur le tag de la [dernière version](https://github.com/syuilo/misskey/releases/latest).
`git checkout master`
*2.* Configuration de Misskey
----------------------------------------------------------------
@ -38,9 +46,9 @@ Parfait, Vous avez un environnement prêt pour démarrer Misskey.
Utilisez la commande `docker-compose up -d`. GLHF!
### How to update your Misskey server to the latest version
1. `git fetch`
2. `git stash`
3. `git checkout $(git tag -l | grep -Ev -- '-(rc|alpha)\.[0-9]+$' | sort -V | tail -n 1)`
1. `git stash`
2. `git checkout master`
3. `git pull`
4. `git stash pop`
5. `docker-compose build`
6. Consultez le [ChangeLog](../CHANGELOG.md) pour avoir les éventuelles informations de migration
@ -52,14 +60,28 @@ Utilisez la commande `docker-compose up -d`. GLHF!
### Configuration d'ElasticSearch (pour la fonction de recherche)
*1.* Préparation de l'environnement
----------------------------------------------------------------
1. `mkdir elasticsearch && chown 1000:1000 elasticsearch` Permet de créer le dossier d'accueil de la base ElasticSearch aves les bons droits
2. `sysctl -w vm.max_map_count=262144` Augmente la valeur max du paramètre map_count du système (valeur minimum pour pouvoir lancer ES)
1. Permet de créer le dossier d'accueil de la base ElasticSearch aves les bons droits
`mkdir elasticsearch && chown 1000:1000 elasticsearch`
2. Augmente la valeur max du paramètre map_count du système (valeur minimum pour pouvoir lancer ES)
`sysctl -w vm.max_map_count=262144`
*2.* Après lancement du docker-compose, initialisation de la base ElasticSearch
----------------------------------------------------------------
1. `docker-compose -it web /bin/sh` Connexion dans le conteneur web
2. `apk add curl` Ajout du paquet curl
3. `curl -X PUT "es:9200/misskey" -H 'Content-Type: application/json' -d'{ "settings" : { "index" : { } }}'` Création de la base ES
1. Connexion dans le conteneur web
`docker-compose -it web /bin/sh`
2. Ajout du paquet curl
`apk add curl`
3. Création de la base ES
`curl -X PUT "es:9200/misskey" -H 'Content-Type: application/json' -d'{ "settings" : { "index" : { } }}'`
4. `exit`
----------------------------------------------------------------

View File

@ -9,9 +9,17 @@ Dockerを使ったMisskey構築方法
*1.* Misskeyのダウンロード
----------------------------------------------------------------
1. `git clone -b master git://github.com/syuilo/misskey.git` masterブランチからMisskeyレポジトリをクローン
2. `cd misskey` misskeyディレクトリに移動
3. `git checkout $(git tag -l | grep -Ev -- '-(rc|alpha)\.[0-9]+$' | sort -V | tail -n 1)` [最新のリリース](https://github.com/syuilo/misskey/releases/latest)を確認
1. masterブランチからMisskeyレポジトリをクローン
`git clone -b master git://github.com/syuilo/misskey.git`
2. misskeyディレクトリに移動
`cd misskey`
3. [最新のリリース](https://github.com/syuilo/misskey/releases/latest)を確認
`git checkout master`
*2.* 設定ファイルの作成と編集
----------------------------------------------------------------
@ -57,7 +65,13 @@ cp docker_example.env docker.env
`docker-compose build`
*5.* 以上です!
*5.* データベースを初期化
----------------------------------------------------------------
``` shell
docker-compose run --rm web yarn run init
```
*6.* 以上です!
----------------------------------------------------------------
お疲れ様でした。これでMisskeyを動かす準備は整いました。
@ -65,9 +79,9 @@ cp docker_example.env docker.env
`docker-compose up -d`するだけです。GLHF!
### Misskeyを最新バージョンにアップデートする方法:
1. `git fetch`
2. `git stash`
3. `git checkout $(git tag -l | grep -Ev -- '-(rc|alpha)\.[0-9]+$' | sort -V | tail -n 1)`
1. `git stash`
2. `git checkout master`
3. `git pull`
4. `git stash pop`
5. `docker-compose build`
6. [ChangeLog](../CHANGELOG.md)でマイグレーション情報を確認する

View File

@ -25,11 +25,10 @@ server {
}
server {
listen 443 http2;
listen [::]:443 http2;
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.tld;
ssl on;
ssl_session_cache shared:ssl_session_cache:10m;
ssl_session_cache shared:ssl_session_cache:10m;
# To use Let's Encrypt certificate
ssl_certificate /etc/letsencrypt/live/example.tld/fullchain.pem;

View File

@ -27,20 +27,38 @@ Please install and setup these softwares:
* **[Redis](https://redis.io/)**
##### Optional
* [Yarn](https://yarnpkg.com/) *Optional but recommended for security reason. If you won't install it, use `npx yarn` instead of `yarn`.*
* [Elasticsearch](https://www.elastic.co/) - required to enable the search feature
* [FFmpeg](https://www.ffmpeg.org/)
*3.* Install Misskey
----------------------------------------------------------------
1. `su - misskey` Connect to misskey user.
2. `git clone -b master git://github.com/syuilo/misskey.git` Clone the misskey repo from master branch.
3. `cd misskey` Navigate to misskey directory
4. `git checkout $(git tag -l | grep -Ev -- '-(rc|alpha)\.[0-9]+$' | sort -V | tail -n 1)` Checkout to the [latest release](https://github.com/syuilo/misskey/releases/latest)
5. `npm install` Install misskey dependencies.
1. Connect to misskey user.
`su - misskey`
2. Clone the misskey repo from master branch.
`git clone -b master git://github.com/syuilo/misskey.git`
3. Navigate to misskey directory
`cd misskey`
4. Checkout to the [latest release](https://github.com/syuilo/misskey/releases/latest)
`git checkout master`
5. Install misskey dependencies.
`yarn`
*4.* Configure Misskey
----------------------------------------------------------------
1. `cp .config/example.yml .config/default.yml` Copy the `.config/example.yml` and rename it to `default.yml`.
1. Copy the `.config/example.yml` and rename it to `default.yml`.
`cp .config/example.yml .config/default.yml`
2. Edit `default.yml`
*5.* Build Misskey
@ -48,21 +66,20 @@ Please install and setup these softwares:
Build misskey with the following:
`NODE_ENV=production npm run build`
`NODE_ENV=production yarn build`
If you're on Debian, you will need to install the `build-essential`, `python` package.
If you're still encountering errors about some modules, use node-gyp:
1. `npm install -g node-gyp`
2. `node-gyp configure`
3. `node-gyp build`
4. `NODE_ENV=production npm run build`
1. `npx node-gyp configure`
2. `npx node-gyp build`
3. `NODE_ENV=production yarn build`
*6.* Init DB
----------------------------------------------------------------
``` shell
npm run init
yarn run init
```
*7.* That is it.
@ -74,43 +91,55 @@ Just `NODE_ENV=production npm start`. GLHF!
### Launch with systemd
1. Create a systemd service here: `/etc/systemd/system/misskey.service`
1. Create a systemd service here
`/etc/systemd/system/misskey.service`
2. Edit it, and paste this and save:
```
[Unit]
Description=Misskey daemon
```
[Unit]
Description=Misskey daemon
[Service]
Type=simple
User=misskey
ExecStart=/usr/bin/npm start
WorkingDirectory=/home/misskey/misskey
Environment="NODE_ENV=production"
TimeoutSec=60
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=misskey
Restart=always
[Service]
Type=simple
User=misskey
ExecStart=/usr/bin/npm start
WorkingDirectory=/home/misskey/misskey
Environment="NODE_ENV=production"
TimeoutSec=60
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=misskey
Restart=always
[Install]
WantedBy=multi-user.target
```
[Install]
WantedBy=multi-user.target
```
3. `systemctl daemon-reload ; systemctl enable misskey` Reload systemd and enable the misskey service.
4. `systemctl start misskey` Start the misskey service.
3. Reload systemd and enable the misskey service.
`systemctl daemon-reload ; systemctl enable misskey`
4. Start the misskey service.
`systemctl start misskey`
You can check if the service is running with `systemctl status misskey`.
### How to update your Misskey server to the latest version
1. `git fetch`
2. `git checkout $(git tag -l | grep -Ev -- '-(rc|alpha)\.[0-9]+$' | sort -V | tail -n 1)`
3. `npm install`
4. `NODE_ENV=production npm run build`
5. Check [ChangeLog](../CHANGELOG.md) for migration information
1. `git checkout master`
2. `git pull`
3. `yarn install`
4. `NODE_ENV=production yarn build`
5. `yarn migrate`
6. Restart your Misskey process to apply changes
7. Enjoy
If you encounter any problems with updating, please try the following:
1. `yarn clean` or `yarn cleanall`
2. Retry update (Don't forget `yarn install`
----------------------------------------------------------------
If you have any questions or troubles, feel free to contact us!

View File

@ -27,20 +27,38 @@ Installez les paquets suivants :
* **[Redis](https://redis.io/)**
##### Optionnels
* [Elasticsearch](https://www.elastic.co/) - requis pour pouvoir activer la fonctionnalité de recherche
* [Yarn](https://yarnpkg.com/) - *recommander pour des raisons de sécurité. Si vous ne l'installez pas, utilisez `npx yarn` au lieu de` yarn`.*
* [Elasticsearch](https://www.elastic.co/) - *requis pour pouvoir activer la fonctionnalité de recherche.*
* [FFmpeg](https://www.ffmpeg.org/)
*3.* Installation de Misskey
----------------------------------------------------------------
1. `su - misskey` Basculez vers l'utilisateur misskey.
2. `git clone -b master git://github.com/syuilo/misskey.git` Clonez la branche master du dépôt misskey.
3. `cd misskey` Accédez au dossier misskey.
4. `git checkout $(git tag -l | grep -Ev -- '-(rc|alpha)\.[0-9]+$' | sort -V | tail -n 1)` Checkout sur le tag de la [version la plus récente](https://github.com/syuilo/misskey/releases/latest)
5. `npm install` Installez les dépendances de misskey.
1. Basculez vers l'utilisateur misskey.
`su - misskey`
2. Clonez la branche master du dépôt misskey.
`git clone -b master git://github.com/syuilo/misskey.git`
3. Accédez au dossier misskey.
`cd misskey`
4. Checkout sur le tag de la [version la plus récente](https://github.com/syuilo/misskey/releases/latest)
`git checkout master`
5. Installez les dépendances de misskey.
`yarn install`
*4.* Création du fichier de configuration
----------------------------------------------------------------
1. `cp .config/example.yml .config/default.yml` Copiez le fichier `.config/example.yml` et renommez-le`default.yml`.
1. Copiez le fichier `.config/example.yml` et renommez-le`default.yml`.
`cp .config/example.yml .config/default.yml`
2. Editez le fichier `default.yml`
*5.* Construction de Misskey
@ -48,60 +66,67 @@ Installez les paquets suivants :
Construisez Misskey comme ceci :
`NODE_ENV=production npm run build`
`NODE_ENV=production yarn build`
Si vous êtes sous Debian, vous serez amené à installer les paquets `build-essential` et `python`.
Si vous rencontrez des erreurs concernant certains modules, utilisez node-gyp:
1. `npm install -g node-gyp`
2. `node-gyp configure`
3. `node-gyp build`
4. `NODE_ENV=production npm run build`
1. `npx node-gyp configure`
2. `npx node-gyp build`
3. `NODE_ENV=production yarn build`
*6.* C'est tout.
----------------------------------------------------------------
Excellent ! Maintenant, vous avez un environnement prêt pour lancer Misskey
### Lancement conventionnel
Lancez tout simplement `NODE_ENV=production npm start`. Bonne chance et amusez-vous bien !
Lancez tout simplement `NODE_ENV=production yarn start`. Bonne chance et amusez-vous bien !
### Démarrage avec systemd
1. Créez un service systemd sur : `/etc/systemd/system/misskey.service`
1. Créez un service systemd sur
`/etc/systemd/system/misskey.service`
2. Editez-le puis copiez et coller ceci dans le fichier :
```
[Unit]
Description=Misskey daemon
```
[Unit]
Description=Misskey daemon
[Service]
Type=simple
User=misskey
ExecStart=/usr/bin/npm start
WorkingDirectory=/home/misskey/misskey
Environment="NODE_ENV=production"
TimeoutSec=60
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=misskey
Restart=always
[Service]
Type=simple
User=misskey
ExecStart=/usr/bin/npm start
WorkingDirectory=/home/misskey/misskey
Environment="NODE_ENV=production"
TimeoutSec=60
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=misskey
Restart=always
[Install]
WantedBy=multi-user.target
```
[Install]
WantedBy=multi-user.target
```
3. `systemctl daemon-reload ; systemctl enable misskey` Redémarre systemd et active le service misskey.
4. `systemctl start misskey` Démarre le service misskey.
3. Redémarre systemd et active le service misskey.
`systemctl daemon-reload ; systemctl enable misskey`
4. Démarre le service misskey.
`systemctl start misskey`
Vous pouvez vérifier si le service a démarré en utilisant la commande `systemctl status misskey`.
### Méthode de mise à jour vers la plus récente version de Misskey
1. `git fetch`
2. `git checkout $(git tag -l | grep -Ev -- '-(rc|alpha)\.[0-9]+$' | sort -V | tail -n 1)`
3. `npm install`
4. `NODE_ENV=production npm run build`
5. Consultez [ChangeLog](../CHANGELOG.md) pour les information de migration.
1. `git checkout master`
2. `git pull`
3. `yarn install`
4. `NODE_ENV=production yarn build`
5. `yarn migrate`
----------------------------------------------------------------

View File

@ -27,21 +27,40 @@ adduser --disabled-password --disabled-login misskey
* **[Redis](https://redis.io/)**
##### オプション
* [Yarn](https://yarnpkg.com/)
* セキュリティの観点から推奨されます。 yarn をインストールしない方針の場合は、文章中の `yarn` を適宜 `npx yarn` と読み替えてください。
* [Elasticsearch](https://www.elastic.co/)
* 検索機能を有効にするためにはインストールが必要です。
* [FFmpeg](https://www.ffmpeg.org/)
*3.* Misskeyのインストール
----------------------------------------------------------------
1. `su - misskey` misskeyユーザーを使用
2. `git clone -b master git://github.com/syuilo/misskey.git` masterブランチからMisskeyレポジトリをクローン
3. `cd misskey` misskeyディレクトリに移動
4. `git checkout $(git tag -l | grep -Ev -- '-(rc|alpha)\.[0-9]+$' | sort -V | tail -n 1)` [最新のリリース](https://github.com/syuilo/misskey/releases/latest)を確認
5. `npm install` Misskeyの依存パッケージをインストール
1. misskeyユーザーを使用
`su - misskey`
2. masterブランチからMisskeyレポジトリをクローン
`git clone -b master git://github.com/syuilo/misskey.git`
3. misskeyディレクトリに移動
`cd misskey`
4. [最新のリリース](https://github.com/syuilo/misskey/releases/latest)を確認
`git checkout master`
5. Misskeyの依存パッケージをインストール
`yarn install`
*4.* 設定ファイルを作成する
----------------------------------------------------------------
1. `cp .config/example.yml .config/default.yml` `.config/example.yml`をコピーし名前を`default.yml`にする。
1. `.config/example.yml`をコピーし名前を`default.yml`にする。
`cp .config/example.yml .config/default.yml`
2. `default.yml` を編集する。
*5.* Misskeyのビルド
@ -49,20 +68,19 @@ adduser --disabled-password --disabled-login misskey
次のコマンドでMisskeyをビルドしてください:
`NODE_ENV=production npm run build`
`NODE_ENV=production yarn build`
Debianをお使いであれば、`build-essential`パッケージをインストールする必要があります。
何らかのモジュールでエラーが発生する場合はnode-gypを使ってください:
1. `npm install -g node-gyp`
2. `node-gyp configure`
3. `node-gyp build`
4. `NODE_ENV=production npm run build`
1. `npx node-gyp configure`
2. `npx node-gyp build`
3. `NODE_ENV=production yarn build`
*6.* データベースを初期化
----------------------------------------------------------------
``` shell
npm run init
yarn run init
```
*7.* 以上です!
@ -70,46 +88,55 @@ npm run init
お疲れ様でした。これでMisskeyを動かす準備は整いました。
### 通常起動
`NODE_ENV=production npm start`するだけです。GLHF!
`NODE_ENV=production yarn start`するだけです。GLHF!
### systemdを用いた起動
1. systemdサービスのファイルを作成: `/etc/systemd/system/misskey.service`
1. systemdサービスのファイルを作成
`/etc/systemd/system/misskey.service`
2. エディタで開き、以下のコードを貼り付けて保存:
```
[Unit]
Description=Misskey daemon
```
[Unit]
Description=Misskey daemon
[Service]
Type=simple
User=misskey
ExecStart=/usr/bin/npm start
WorkingDirectory=/home/misskey/misskey
Environment="NODE_ENV=production"
TimeoutSec=60
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=misskey
Restart=always
[Service]
Type=simple
User=misskey
ExecStart=/usr/bin/npm start
WorkingDirectory=/home/misskey/misskey
Environment="NODE_ENV=production"
TimeoutSec=60
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=misskey
Restart=always
[Install]
WantedBy=multi-user.target
```
CentOSで1024以下のポートを使用してMisskeyを使用する場合は`ExecStart=/usr/bin/sudo /usr/bin/npm start`に変更する必要があります。
[Install]
WantedBy=multi-user.target
```
3. `systemctl daemon-reload ; systemctl enable misskey` systemdを再読み込みしmisskeyサービスを有効化
4. `systemctl start misskey` misskeyサービスの起動
CentOSで1024以下のポートを使用してMisskeyを使用する場合は`ExecStart=/usr/bin/sudo /usr/bin/npm start`に変更する必要があります。
3. systemdを再読み込みしmisskeyサービスを有効化
`systemctl daemon-reload; systemctl enable misskey`
4. misskeyサービスの起動
`systemctl start misskey`
`systemctl status misskey`と入力すると、サービスの状態を調べることができます。
### Misskeyを最新バージョンにアップデートする方法:
1. `git fetch`
2. `git checkout $(git tag -l | grep -Ev -- '-(rc|alpha)\.[0-9]+$' | sort -V | tail -n 1)`
3. `npm install`
4. `NODE_ENV=production npm run build`
5. [ChangeLog](../CHANGELOG.md)でマイグレーション情報を確認する
1. `git checkout master`
2. `git pull`
3. `yarn install`
4. `NODE_ENV=production yarn build`
5. `yarn migrate`
なにか問題が発生した場合は、`npm run clean`または`npm run cleanall`すると直る場合があります。
なにか問題が発生した場合は、`yarn clean`または`yarn cleanall`すると直る場合があります。
----------------------------------------------------------------

View File

@ -47,7 +47,11 @@ gulp.task('build:copy:views', () =>
gulp.src('./src/server/web/views/**/*').pipe(gulp.dest('./built/server/web/views'))
);
gulp.task('build:copy', gulp.parallel('build:copy:views', () =>
gulp.task('build:copy:fonts', () =>
gulp.src('./node_modules/three/examples/fonts/**/*').pipe(gulp.dest('./built/client/assets/fonts/'))
);
gulp.task('build:copy', gulp.parallel('build:copy:views', 'build:copy:fonts', () =>
gulp.src([
'./src/const.json',
'./src/server/web/views/**/*',

View File

@ -34,6 +34,19 @@ common:
signup: "Registrovat"
signout: "Odhlásit"
reload-to-apply-the-setting: "Pro uplatnění tohoto nastavení musíte znovu načíst tuto stránku. Chcete ji načíst teď?"
delete-confirm: "Opravdu chcete smazat tento příspěvek?"
signin-required: "Přihlašte se, prosím"
notification-type: "Typy oznámení"
notification-types:
all: "Všechny"
pollVote: "Hlasy"
follow: "Sledovaní"
receiveFollowRequest: "Žádost o sledování"
reply: "Odpovědi"
quote: "Citace"
renote: "Renotovat"
mention: "Zmínky"
reaction: "Reakce"
got-it: "Rozumím!"
customization-tips:
title: "Tipy pro přizpůsobení"
@ -61,6 +74,7 @@ common:
month-and-day: "{day}. {month}."
trash: "Koš"
drive: "Disk"
pages: "Stránky"
messaging: "Konverzace"
home: "Domů"
deck: "Deck"
@ -70,11 +84,53 @@ common:
followers: "Sledující"
favorites: "Oblíbené"
permissions:
'read:drive': "Prohlížet Disk"
'write:drive': "Pracovat s Diskem"
"read:account": "Zobrazit informace o účtu"
"write:account": "Narábět s účtem"
"read:blocks": "Prohlížet blokování"
"write:blocks": "Narábět s blokováním"
"read:drive": "Prohlížet Disk"
"write:drive": "Pracovat s Diskem"
"read:favorites": "Prohlížet oblíbené"
"write:favorites": "Narábět s oblíbeními"
"read:following": "Prohlížet následování"
"write:following": "Pracovat s následováním"
"read:messaging": "Prohlížet konverzaci"
"write:messaging": "Pracovat s konverzaci"
"read:mutes": "Prohlížet ztlumené"
"write:mutes": "Narábět s utíšeními"
"write:notes": "Narábět s poznámkami"
"read:notifications": "Prohlížet oznámení"
"write:notifications": "Pracovat s oznámeními"
"read:reactions": "Prohlížet reakce"
"write:reactions": "Narabět s reakcemi"
"write:votes": "Hlasovat"
empty-timeline-info:
follow-users-to-make-your-timeline: "Poznámky sledujících se zobrazí ve vaší časové ose"
explore: "Najít uživatele"
post-form:
attach-location-information: "Přidat informace o lokaci"
hide-contents: "Schovat obsah"
reply-placeholder: "Odpovědět na tento příspěvek"
quote-placeholder: "Citovat tento příspěvek"
quote-attached: "Přiložit citaci"
submit: "Odeslat"
reply: "Odpovědět"
renote: "Renotovat"
posting: "Posílání"
attach-media-from-local: "Nahrát soubor z vašeho zařízení"
insert-a-kao: "v('ω')v"
create-poll: "Vytvořit anketu"
text-remain: "zbývá ještě {} znaků"
recent-tags: "Nejnovější"
click-to-tagging: "Klikni pro otágování"
visibility: "Viditelnost"
geolocation-alert: "Vaše zařízení nedalo k dispozici lokaci"
error: "Chyba"
enter-username: "Zadejte své uživatelské jméno"
specified-recipient: "Pro"
add-visible-user: "Přidat uživatele"
username-prompt: "Zadejte své uživatelské jméno"
enter-file-name: "Upravit název souboru"
weekday-short:
sunday: "Ne"
monday: "Po"
@ -141,6 +197,7 @@ common:
remember-note-visibility: "Zapamatovat viditelnost příspěvků"
web-search-engine: "Webové vyhledávače"
web-search-engine-desc: "Například: https://www.google.com/?#q={{query}}"
paste: "Vložit"
keep-cw: "Zachovat varování o obsahu"
keep-cw-desc: "Při odpovědi na příspěvek bude varování o obsahu nastaveno stejně jako původní příspěvek."
i-like-sushi: "Mam radši sushi (než puding)"
@ -178,7 +235,7 @@ common:
deck-column-width-wide: "Široké"
use-shadow: "Používat v rozhraní stíny"
rounded-corners: "Zakulatit rohy v rozhraní"
circle-icons: "Používat kulaté ikony"
circle-icons: "Používat kulaté avatary"
contrasted-acct: "Přidat uživatelskému účtu kontrast"
wallpaper: "Obrázek na pozadí"
choose-wallpaper: "Zvolit pozadí"
@ -223,6 +280,18 @@ common:
disable-via-mobile: "Neoznačovat příspěvky jako „z mobilu“"
load-raw-images: "Zobrazovat obrázky v původní kvalitě"
load-remote-media: "Zobrazovat média ze vzdáleného serveru"
sync: "Synchronizace"
save: "Uložit"
saved: "Uloženo"
room: "Místnost"
_room:
graphicsQuality: "Kvalita grafiky"
_graphicsQuality:
ultra: "Nejvyšší"
high: "Vysoká"
medium: "Střední"
low: "Nízká"
cheep: "Nejnižší"
search: "Hledání"
delete: "Odstranit"
loading: "Načítám..."
@ -231,9 +300,9 @@ common:
update-available-title: "Aktualizace k dispozici"
update-available: "Je k dispozici nová verze Misskey ({newer},vaše verze je {current}). Pro aplikování nové verze znovunačtěte stránku."
my-token-regenerated: "Váš token byl regenerován, proto budete odhlášen/a."
verified-user: "Ověřené účty"
hide-password: "Skrýt heslo"
show-password: "Zobrazit heslo"
enter-username: "Zadejte své uživatelské jméno"
do-not-use-in-production: "Tohle je vývojářský build. Nepoužívejte v produkci."
user-suspended: "Tomuto uživateli byl pozastaven účet."
is-remote-user: "Informace o tomto uživateli nemusí být kompletní."
@ -279,6 +348,7 @@ common:
nav: "Navigace"
tips: "Tipy"
hashtags: "Hashtagy"
queue: "Ve frontě"
dev: "Nepodařilo se vytvořit aplikace. Prosím zkuste to znovu."
ai-chan-kawaii: "Ai-chan kawaii!"
you: "Vy"
@ -289,11 +359,13 @@ auth/views/form.vue:
accept: "Povolit přístup"
auth/views/index.vue:
loading: "Načítám..."
denied-paragraph: "Tato aplikace nebude mít přístup k Vašemu účtu."
already-authorized: "Tato aplikace byla již autorizována."
callback-url: "Zpátky do aplikace."
please-go-back: "Prosím vraťte se zpátky do aplikace."
error: "Taková relace neexistuje."
sign-in: "Prosím přihlaste se."
common/views/pages/explore.vue:
verified-users: "Ověřené účty"
popular-users: "Populární uživatelé"
recently-updated-users: "Nedávno aktívni uživatelé"
recently-registered-users: "Nedávno registrovaní uživatelé"
@ -312,6 +384,7 @@ common/views/components/games/reversi/reversi.vue:
cancel: "Zrušit"
common/views/components/games/reversi/reversi.game.vue:
surrender: "Vzdát se"
surrendered: "Vzdaním se"
looped-map: "Zacyklená mapa"
common/views/components/games/reversi/reversi.index.vue:
title: "Misskey Reversi"
@ -340,23 +413,33 @@ common/views/components/games/reversi/reversi.room.vue:
waiting-for-both: "Připravuji"
cancel: "Zrušit"
ready: "Připraveno"
cancel-ready: "Pokračovat v přípravě"
common/views/components/connect-failed.vue:
title: "Nelze se připojit k serveru"
description: "Nastal problém s Vaším připojením k internetu, nebo server není dostupný nebo zrovna probíhá údržba. Prosím {zkuste to znova} za pár minut."
thanks: "Děkujeme že jste použili Misskey."
troubleshoot: "Odstranění problémů"
common/views/components/connect-failed.troubleshooter.vue:
title: "Poradce při potížích"
network: "Síťové připojení"
checking-network: "Prověřit síťové připojení"
internet: "Připojení k internetu"
checking-internet: "Ověřuji připojení k internetu."
server: "Připojení k serveru"
checking-server: "Spojuji se se serverem"
finding: "Vyšetřování problému"
no-network: "Žádné připojení k síti"
no-network-desc: "Ujistěte se že jste připojeni k Internetu."
no-internet: "Nejste připojeni k internetu"
no-internet-desc: "Jste připojen k síti, ale zdá se že stále chybí připojení k Internetu. Prosím zkontrolujte Vaše připojení k Internetu."
no-server: "Nelze se připojit k serveru Misskey"
success: "Úspěšně se podařilo spojit s Misskey serverem"
flush: "Vyčistit mezipaměť"
common/views/components/media-banner.vue:
sensitive: "Choulostivý obsah"
click-to-show: "Klikněte pro zobrazení"
common/views/components/theme.vue:
theme: "Vzhled"
light-theme: "Motiv pro použití ve světlém vzhledu"
dark-theme: "Motiv pro použití v tmavém vzhledu"
light-themes: "Světlý vzhled"
@ -367,14 +450,18 @@ common/views/components/theme.vue:
installed: "\"{}\" byl nainstalován"
create-a-theme: "Vytvořit motiv"
save-created-theme: "Uložit motiv"
primary-color: "Základní barva"
text-color: "Barva textu"
base-theme: "Základní vzhled"
base-theme-light: "Světlý"
base-theme-dark: "Tmavý"
find-more-theme: "Najít další vzhledy"
theme-name: "Jméno vzhledu"
preview-created-theme: "Náhled"
invalid-theme: "Vzhled není validní"
already-installed: "Tento vzhled je již nainstalován."
saved: "Uloženo"
manage-themes: "Správa vzhledů"
builtin-themes: "Standardní vzhledy"
my-themes: "Moje vzhledy"
installed-themes: "Nainstalované vzhledy"
@ -385,6 +472,7 @@ common/views/components/theme.vue:
desc: "Popis"
export: "Exportovat"
import: "Importovat"
import-by-code: "nebo zkopírujte kód"
theme-name-required: "Jméno vzhledu je povinné"
common/views/components/cw-button.vue:
hide: "Skrýt"
@ -396,14 +484,16 @@ common/views/components/messaging.vue:
search-user: "Najít uživatele"
you: "Vy"
no-history: "Žádná historie"
user: "Uživatel"
group: "Skupina"
start-with-user: "Zahájit konverzaci s uživatelem"
start-with-group: "Zahájit skupinovou konverzaci"
common/views/components/messaging-room.vue:
empty: "Žádné zprávy"
new-message: "Máte novou zprávu"
only-one-file-attached: "Jenom JEDEN soubor může být přiložen ke zprávě."
common/views/components/messaging-room.form.vue:
input-message-here: "Sem zadejte zprávu"
send: "Odeslat"
attach-from-local: "Přiložit soubory z Vašeho zařízení"
only-one-file-attached: "Jenom JEDEN soubor může být přiložen ke zprávě."
common/views/components/messaging-room.message.vue:
is-read: "Přečtené"
deleted: "Tato zpráva byla odstraněna"
@ -416,6 +506,7 @@ common/views/components/nav.vue:
repository: "Úložiště"
develop: "Vývojáři"
feedback: "Zpětná vazba"
tos: "Podmínky užívání"
common/views/components/note-menu.vue:
mention: "Zmínění"
detail: "Více"
@ -429,6 +520,7 @@ common/views/components/note-menu.vue:
unpin: "Odepnout"
delete: "Odstranit"
delete-confirm: "Opravdu chcete smazat tento příspěvek?"
delete-and-edit: "Smazat a upravit"
remote: "Ukázat originální poznámku"
common/views/components/user-menu.vue:
mention: "Zmínění"
@ -444,6 +536,7 @@ common/views/components/user-menu.vue:
suspend: "Zmrazit"
common/views/components/poll.vue:
vote-count: "{} hlasů"
total-votes: "{} hlasů celkem"
vote: "Hlasovat"
show-result: "Podívat se na výsledky"
voted: "Už jste hlasovaly"
@ -454,10 +547,25 @@ common/views/components/poll.vue:
remaining-seconds: "zbývá {s} sekund"
common/views/components/poll-editor.vue:
no-only-one-choice: "Musíte vybrat alespoň dvě možnosti"
choice-n: "Volba {}"
remove: "Odstranit tuto možnost"
add: "+ Přidat možnost"
destroy: "Zahodit dotazník"
multiple: "Více odpovědí je povoleno"
expiration: "Termín"
infinite: "Nekonečne"
at: "Výběr data a času"
no-more: "Více už přidat nemůžete"
deadline-date: "Termín ukončení"
deadline-time: "Doba trvání"
interval: "Trvání"
second: "Sekunda"
minute: "Minuta"
hour: "Hodina"
day: "Ne"
common/views/components/reaction-picker.vue:
choose-reaction: "Vyberte svoji reakci"
input-reaction-placeholder: "nebo vložte Emoji"
common/views/components/emoji-picker.vue:
custom-emoji: "Emoji"
people: "Lidé"
@ -468,9 +576,12 @@ common/views/components/emoji-picker.vue:
objects: "Objekty"
symbols: "Symboly"
flags: "Vlajky"
common/views/components/settings/app-type.vue:
info: "Pro aktivování změn musíte znovu načíst stránky."
common/views/components/signin.vue:
username: "Přezdívka"
password: "Heslo"
token: "Token"
signing-in: "Přihlašování..."
or: "Nebo"
signin-with-twitter: "Přihlásit se pomocí účtu Twitter"
@ -498,6 +609,7 @@ common/views/components/signup.vue:
password-matched: "OK"
password-not-matched: "Neshodují se"
recaptcha: "Potvrzení"
tos: "Podmínky užívání"
create: "Vytvořit účet"
some-error: "Pokus o vytvoření účtu selhal. Prosím zkuste to znovu."
common/views/components/special-message.vue:
@ -536,6 +648,7 @@ common/views/components/visibility-chooser.vue:
home: "Domů"
specified-desc: "Poslat pouze zmíněným uživatelům"
local-public: "Veřejná (pouze místní)"
local-public-desc: "Nepublikovat na vzdálených serverech"
local-home: "Domovská (pouze místní)"
local-followers: "Pro sledující (pouze místní)"
common/views/components/trends.vue:
@ -545,6 +658,8 @@ common/views/components/language-settings.vue:
title: "Zobrazit jazyky"
pick-language: "Zvolte jazyk"
recommended: "Doporučené"
auto: "Automaticky"
specify-language: "Vyberte jazyk"
info: "Pro aktivování změn musíte znovu načíst stránky."
common/views/components/profile-editor.vue:
title: "Profil"
@ -565,12 +680,14 @@ common/views/components/profile-editor.vue:
saved: "Profil byl úspěšně aktualizován"
uploading: "Nahrávám"
upload-failed: "Nahrávání selhalo"
unable-to-process: "Operace nemohla být dokončena."
email: "Nastavení e-mailů"
email-address: "Emailová adresa"
email-verified: "Váš e-mail byl ověřen"
email-not-verified: "Váš email není potvrzen. Prosím zkontrolujte si svou schránku."
export: "Exportovat"
import: "Importovat"
export-and-import: "Import / Export"
export-targets:
following-list: "Seznam sledujících"
mute-list: "Seznam ztlumených uživatelů"
@ -580,6 +697,9 @@ common/views/components/profile-editor.vue:
danger-zone: "Nebezpečná zóna"
delete-account: "Smazat účet"
account-deleted: "Váš účet byl smazán. Může chvilku trvat než zmizí všechna data."
profile-metadata: "Metadata profilu"
metadata-label: "Popis"
metadata-content: "Obsah"
common/views/components/user-list-editor.vue:
users: "Uživatel"
rename: "Přejmenovat seznam"
@ -587,8 +707,34 @@ common/views/components/user-list-editor.vue:
remove-user: "Odebrat z tohoto seznamu"
delete-are-you-sure: "Smazat seznam \"$1\"?"
deleted: "Smazáno"
add-user: "Přidat uživatele"
common/views/components/user-group-editor.vue:
users: "Členové"
rename: "Přejmenovat skupinu"
delete: "Odstranit skupinu"
transfer: "Přesunout skupinu"
transfer-are-you-sure: "Jste si jistí že chcete přidat @$2 do skupiny: $1?"
transferred: "Skupina přesunuta"
remove-user: "Odebrat uživatele z této skupiny"
delete-are-you-sure: "Jste si jistí že chcete smazat skupinu \"$1\"?"
deleted: "Smazáno"
invite: "Pozvat"
invited: "Pozvánka byla úspěšně odeslána"
common/views/components/user-lists.vue:
user-lists: "Seznamy"
create-list: "Vytvořit seznam"
list-name: "Název seznamu"
common/views/components/user-groups.vue:
user-groups: "Skupiny"
create-group: "Vytvořit skupinu"
group-name: "Název skupiny"
owned-groups: "Moje skupiny"
invites: "Pozvat"
reject-invite: "Odmítnout"
common/views/widgets/broadcast.vue:
fetching: "Načítám"
no-broadcasts: "Žádná nová oznámení"
have-a-nice-day: "Přejeme Vám příjemný den!"
next: "Další"
common/views/widgets/calendar.vue:
year: "Rok {}"
@ -615,12 +761,19 @@ common/views/widgets/slideshow.vue:
no-image: "V této složce nebyly nalezeny žádné fotky."
common/views/pages/not-found.vue:
page-not-found: "Stránka nenalezena"
common/views/pages/follow.vue:
following: "Sledování"
follow: "Sledovat"
common/views/pages/follow-requests.vue:
accept: "Přijmout"
reject: "Odmítnout"
desktop:
banner: "Baner"
avatar-crop-title: "Vyberte část, která se zobrazí jako avatar"
avatar: "Avatar"
uploading-avatar: "Nahrál nový avatar"
avatar-updated: "Vaše avatar byl aktualizován"
unable-to-process: "Operace nemohla být dokončena."
invalid-filetype: "Tento formát souboru není podporován"
desktop/views/components/activity.chart.vue:
total: "Černá ... Celkem"
@ -657,7 +810,7 @@ desktop/views/components/drive.file.vue:
rename: "Přejmenovat"
copy-url: "Kopírovat URL"
download: "Stáhnout"
else-files: "Více..."
else-files: "Ostatní"
set-as-avatar: "Nastavit jako avatar"
set-as-banner: "Nastavit jako baner"
open-in-app: "Otevřít v aplikaci"
@ -675,6 +828,7 @@ desktop/views/components/drive.folder.vue:
rename: "Přejmenovat"
rename-folder: "Přejmenovat složku"
input-new-folder-name: "Zadejte nové jméno"
else-folders: "Ostatní"
desktop/views/components/drive.vue:
empty-drive-description: "Klikněte pravým tlačítkem myši pro otevření menu, nebo sem přetáhněte soubor pro nahrání."
empty-folder: "Tato složka je prázdná"
@ -717,27 +871,11 @@ desktop/views/components/notes.vue:
error: "Načítání selhalo."
retry: "Opakovat"
desktop/views/components/post-form.vue:
add-visible-user: "+Přidat uživatele"
attach-location-information: "Přidat informace o lokaci"
hide-contents: "Schovat obsah"
reply-placeholder: "Odpovědět na tento příspěvěk"
quote-placeholder: "Citovat tento příspěvek"
submit: "Příspěvek"
reply: "Odpovědět"
renote: "Renotovat"
posted: "Odesláno!"
replied: "Odpověděno!"
reposted: "Renotováno!"
note-failed: "Nepodařilo se přidat příspěvek"
renote-failed: "Renotování neuspělo"
insert-a-kao: "v('ω')v"
create-poll: "Vytvořit anketu"
text-remain: "{0} znaků zbývá"
recent-tags: "Nejnovější"
visibility: "Viditelnost"
geolocation-alert: "Vaše zařízení nepodporuje lokační službu"
error: "Chyba"
enter-username: "Zadejte své uživatelské jméno..."
desktop/views/components/post-form-window.vue:
note: "Nový příspěvek"
reply: "Odpovědět"
@ -756,6 +894,7 @@ desktop/views/components/renote-form-window.vue:
desktop/views/components/settings.2fa.vue:
detail: "Více…"
url: "https://www.google.cz/landing/2step/"
token: "Token"
common/views/components/media-image.vue:
click-to-show: "Klikněte pro zobrazení"
common/views/components/api-settings.vue:
@ -812,7 +951,9 @@ desktop/views/components/ui.header.vue:
desktop/views/components/ui.header.account.vue:
profile: "Váš profil"
lists: "Seznamy"
groups: "Skupiny"
admin: "Administrace"
room: "Místnost"
desktop/views/components/ui.header.nav.vue:
game: "Hry"
desktop/views/components/ui.header.notifications.vue:
@ -821,13 +962,6 @@ desktop/views/components/ui.header.post.vue:
post: "Nový příspěvek"
desktop/views/components/ui.header.search.vue:
placeholder: "Vyhledávání"
desktop/views/components/received-follow-requests-window.vue:
accept: "Přijmout"
reject: "Odmítnout"
desktop/views/components/user-lists-window.vue:
title: "Seznamy uživatelů"
create-list: "Vytvořit seznam"
list-name: "Název seznamu"
desktop/views/components/user-preview.vue:
notes: "Příspěvky"
desktop/views/components/users-list.vue:
@ -843,7 +977,6 @@ admin/views/index.vue:
users: "Uživatelé"
federation: "Z fedivesmíru"
announcements: "Oznámení"
hashtags: "Hashtagy"
queue: "Fronta úloh"
logs: "Logy"
back-to-misskey: "Zpět na Misskey"
@ -854,6 +987,11 @@ admin/views/dashboard.vue:
instances: "Instance"
this-instance: "Tato instance"
federated: "Z fedivesmíru"
admin/views/logs.vue:
logs: "Logy"
levels:
info: "Informace"
error: "Chyba"
admin/views/abuse.vue:
details: "Popis"
remove-report: "Odstranit"
@ -868,12 +1006,12 @@ admin/views/instance.vue:
maintainer-config: "Informace o administrátorovi"
maintainer-name: "Jméno administrátora"
maintainer-email: "Kontakt na administrátora"
object-storage-endpoint: "Endpoint"
mb: "V megabajtech"
recaptcha-config: "nastavení služby reCAPTCHA"
recaptcha-info: "reCAPTCHA token je povinný. Můžete jej získat na https://www.google.com/recaptcha/intro/"
enable-recaptcha: "povolit reCAPTCHA"
recaptcha-site-key: "reCAPTCHA klíč stránky (site key)"
recaptcha-secret-key: "reCAPTCHA tajný klíč"
recaptcha-preview: "Náhled"
twitter-integration-config: "Nastavení spojení s Twitterem"
twitter-integration-info: "The callback URL is set on {url}."
enable-twitter-integration: "Povolit připojení k Twitteru"
@ -892,12 +1030,12 @@ admin/views/instance.vue:
invite: "Pozvat"
save: "Uložit"
saved: "Uloženo"
user-recommendation-config: "Doporučení uživatelé"
email: "Emailová adresa"
smtp-port: "SMTP Port"
smtp-auth: "Provést SMTP autentikaci"
smtp-user: "SMTP uživatel"
smtp-pass: "SMTP heslo"
test-email: "Test"
serviceworker-config: "ServiceWorker"
enable-serviceworker: "Povolit ServiceWorker"
vapid-publickey: "VAPID veřejný klíč"
@ -944,20 +1082,15 @@ admin/views/users.vue:
reset-password: "Resetovat heslo"
reset-password-confirm: "Opravdu chcete resetovat Vaše heslo?"
password-updated: "Heslo je nyní \"{password}\""
verify: "Ověřit účet"
verify-confirm: "Chcete aby toto byl ověřený účet?"
verified: "Účet se nyní ověřuje"
unverify: "Zrušit ověření účtu"
unverify-confirm: "Opravdu chcete zrušit designaci \"ověřený účet\"?"
unverified: "Ruší se potvrzení účtu"
update-remote-user: "Aktualizovat informace o vzdáleném účtu"
username: "Přezdívka"
host: "Hostitel"
users:
title: "Uživatel"
state:
all: "Všechny"
moderator: "Moderátor"
adminOrModerator: "Admin/Moderátor"
verified: "Ověřený účet"
origin:
title: "Původ"
combined: "Lokální + Vzdálené"
@ -968,6 +1101,11 @@ admin/views/users.vue:
admin/views/moderators.vue:
add-moderator:
title: "Vytvořit moderátora"
logs:
title: "Logy"
moderator: "Moderátoři"
type: "Operace"
info: "Informace"
admin/views/emoji.vue:
add-emoji:
title: "Přidat emoji"
@ -1004,6 +1142,7 @@ admin/views/federation.vue:
host: "Hostitel"
notes: "Poznámky"
users: "Uživatelé"
following: "Sledování"
caught-at: "Vytvořeno"
status: "Status"
latest-request-received-at: "Poslední požadavek přijat"
@ -1022,6 +1161,8 @@ admin/views/federation.vue:
chart-spans:
hour: "za hodinu"
day: "za den"
blocked-hosts: "Blokován"
save: "Uložit"
desktop/views/pages/welcome.vue:
about: "O Misskey"
timeline: "Časová osa"
@ -1060,6 +1201,8 @@ desktop/views/pages/user/user.photos.vue:
no-photos: "Žádné obrázky"
desktop/views/pages/user/user.header.vue:
posts: "Poznámky"
following: "Sledovaní"
followers: "Sledující"
month: "Po"
day: "Ne"
desktop/views/widgets/notifications.vue:
@ -1072,7 +1215,6 @@ mobile/views/components/drive.vue:
used: "využito"
file-count: "Soubor(ů)"
folder-is-empty: "Tato složka je prázdná"
deletion-alert: "Omlouváme se, ale mazání složek ještě nebylo implementováno."
folder-name: "Název složky"
url-prompt: "URL adresa souboru, který chcete nahrát"
uploading: "Byl zahájen upload. Může chvilku trvat než bude dokončen."
@ -1089,6 +1231,7 @@ mobile/views/components/drive.file-detail.vue:
mobile/views/components/media-video.vue:
click-to-show: "Klikněte pro zobrazení"
common/views/components/follow-button.vue:
following: "Sledování"
follow-processing: "Zpracovávám"
mobile/views/components/note.vue:
private: "Tento příspěvek je soukromý"
@ -1108,15 +1251,6 @@ mobile/views/components/note-sub.vue:
admin: "admin"
bot: "bot"
cat: "kočka"
mobile/views/components/post-form.vue:
add-visible-user: "Přidat uživatele"
submit: "Příspěvek"
reply: "Odpovědět"
renote: "Renotovat"
reply-placeholder: "Odpovědět na tento příspěvěk"
location-alert: "Vaše zařízení nepodporuje lokační službu"
error: "Chyba"
username-prompt: "Zadejte uživatelské jméno"
mobile/views/components/sub-note-content.vue:
private: "Tento příspěvek je soukromý"
deleted: "Tento příspěvek byl odstraněn"
@ -1129,12 +1263,15 @@ mobile/views/components/ui.nav.vue:
notifications: "Oznámení"
search: "Vyhledávání"
user-lists: "Seznamy"
user-groups: "Skupiny"
widgets: "Widgety"
game: "Hry"
admin: "Administrace"
about: "O Misskey"
mobile/views/pages/user-lists.vue:
title: "Seznamy"
mobile/views/pages/drive.vue:
contextmenu:
upload: "Nahrát soubor"
create-folder: "Vytvořit složku"
mobile/views/pages/signup.vue:
lets-start: "Váš účet je připraven! 📦"
mobile/views/pages/home.vue:
@ -1151,9 +1288,6 @@ mobile/views/pages/widgets/activity.vue:
activity: "Aktivita"
mobile/views/pages/share.vue:
share-with: "Sdílet na {name}"
mobile/views/pages/received-follow-requests.vue:
accept: "Přijmout"
reject: "Odmítnout"
mobile/views/pages/note.vue:
prev: "Předchozí příspěvěk"
next: "Následující příspěvek"
@ -1163,6 +1297,8 @@ mobile/views/pages/search.vue:
not-found: "Pro '{q}' nebyly nalezeny žádné příspěvky."
mobile/views/pages/selectdrive.vue:
select-file: "Vybrat soubory"
mobile/views/pages/notifications.vue:
notifications: "Oznámení"
mobile/views/pages/user/home.vue:
activity: "Aktivita"
frequently-replied-users: "Častá zmínění"
@ -1185,4 +1321,56 @@ deck/deck.user-column.vue:
activity: "Aktivita"
dev/views/new-app.vue:
app-name-desc: "Jméno vaší aplikace"
app-desc: "Stručný popis nebo představení vaší aplikace."
pages:
pin-this-page: "Připnout"
unpin-this-page: "Odepnout"
like: "Lajk"
title: "Titulek"
blocks:
post: "Formulář pro psaní"
_post:
text: "Obsah"
_textInput:
text: "Titulek"
_textareaInput:
text: "Titulek"
_numberInput:
text: "Titulek"
_switch:
text: "Titulek"
_counter:
text: "Titulek"
_button:
text: "Titulek"
_action:
_dialog:
content: "Obsah"
_radioButton:
title: "Titulek"
script:
categories:
random: "Náhodně"
list: "Seznamy"
blocks:
_join:
arg1: "Seznamy"
random: "Náhodně"
_randomPick:
arg1: "Seznamy"
_dailyRandomPick:
arg1: "Seznamy"
_seedRandomPick:
arg2: "Seznamy"
_pick:
arg1: "Seznamy"
_listLen:
arg1: "Seznamy"
types:
array: "Seznamy"
room:
translate: "Přesunout"
save: "Uložit"
saved: "Uloženo"
furnitures:
moon: "Měsíc"
bin: "Koš"

1919
locales/da-DK.yml Normal file

File diff suppressed because it is too large Load Diff

View File

@ -10,26 +10,39 @@ common:
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!"
adblock:
detected: "Bitte deaktiviere den Werbeblocker."
warning: "<strong>Misskey hat keine Werbung.</strong> Allerdings können Werbeblocker für unerwartete Probleme und fehlende Funktionen sorgen."
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: "Hervorgehobene Beiträge"
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!"
@ -53,22 +66,44 @@ common:
month-and-day: "{day}/{month}"
trash: "Papierkorb"
drive: "Drive"
pages: "Seite"
messaging: "Unterhaltungen"
home: "Home"
deck: "Stapel"
deck: "Deck"
timeline: "Zeitleiste"
explore: "Entdecken"
following: "Folgt"
followers: "Folgende"
favorites: "Diesen Beitrag favorisieren"
favorites: "Favoriten"
permissions:
'read:account': "Accountinformationen anzeigen."
'write:account': "Accountinformationen bearbeiten."
'read:drive': "Dateien anzeigen"
'write:drive': "Dateien bearbeiten"
"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"
@ -141,23 +176,118 @@ common:
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"
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."
verified-user: "Verifizierter Benutzer"
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"
@ -168,8 +298,10 @@ common:
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"
@ -178,7 +310,9 @@ common:
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?"
@ -188,19 +322,37 @@ auth/views/form.vue:
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:
verified-users: "Verifizierter Benutzer"
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!"
@ -218,7 +370,14 @@ common/views/components/games/reversi/reversi.room.vue:
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:
@ -249,10 +408,13 @@ 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"
@ -263,24 +425,39 @@ common/views/components/theme.vue:
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:
empty: "Keine Unterhaltungen"
no-history: "Keine weitere Chronik vorhanden"
resize-form: "Ziehen um die Größe zu verändern"
new-message: "Neue Nachricht"
common/views/components/messaging-room.form.vue:
input-message-here: "Nachricht hier eingeben"
@ -300,12 +477,28 @@ common/views/components/nav.vue:
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"
@ -378,11 +571,20 @@ common/views/components/profile-editor.vue:
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"
@ -392,6 +594,7 @@ 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"
@ -402,6 +605,8 @@ common/views/widgets/memo.vue:
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"
@ -436,7 +641,6 @@ desktop/views/components/drive.file.vue:
rename: "Umbenennen"
copy-url: "URL kopieren"
download: "Download"
else-files: "Anderes…"
set-as-avatar: "Als Avatar festlegen"
set-as-banner: "Setze als Banner"
open-in-app: "In der App öffnen"
@ -479,7 +683,7 @@ desktop/views/components/followers.vue:
desktop/views/components/following.vue:
empty: "Du folgst niemanden"
desktop/views/components/home.vue:
done: "Verbunden"
done: "Beenden"
add-widget: "Widget hinzufügen:"
add: "Hinzufügen"
desktop/views/input-dialog.vue:
@ -493,7 +697,8 @@ desktop/views/components/note-detail.vue:
add-reaction: "Reaktion hinzufügen"
desktop/views/components/note.vue:
reply: "Antworten"
renote: "Anmerken"
renote: "Anmerkung"
detail: "Details"
private: "Dieser Beitrag ist privat"
deleted: "Dieser Beitrag wurde entfernt"
desktop/views/components/notes.vue:
@ -502,27 +707,12 @@ desktop/views/components/notes.vue:
desktop/views/components/notifications.vue:
empty: "Keine Benachrichtigungen"
desktop/views/components/post-form.vue:
add-visible-user: "+Nutzer hinzufügen"
hide-contents: "Inhalt verstecken"
reply-placeholder: "Antworte auf diese Anmerkung..."
quote-placeholder: "Zitiere diese Anmerkung..."
submit: "Abschicken"
reply: "Antworten"
renote: "Anmerken"
posted: "Gepostet!"
replied: "Geantwortet!"
reposted: "Weitergesagt!"
note-failed: "Anmerkung fehlgeschlagen"
reply-failed: "Antwort fehlgeschlagen"
renote-failed: "Anmerkung fehlgeschlagen"
posting: "Posting"
attach-media-from-local: "Medien von deinem PC hinzufügen"
attach-media-from-drive: "Medien von deinem Speicher hinzufügen"
create-poll: "Eine Abstimmung erstellen"
text-remain: "{} Zeichen verbleibend"
visibility: "Sichtbarkeit"
error: "Fehler"
enter-username: "Bitte gib einen Benutzernamen ein..."
desktop/views/components/post-form-window.vue:
note: "Neuer Beitrag"
reply: "Antworten"
@ -572,6 +762,7 @@ desktop/views/components/timeline.vue:
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:
@ -580,17 +771,19 @@ desktop/views/components/ui.header.post.vue:
post: "Einen neuen Post erstellen"
desktop/views/components/ui.header.search.vue:
placeholder: "Suchen"
desktop/views/components/user-lists-window.vue:
title: "Listen"
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:
@ -598,9 +791,8 @@ admin/views/drive.vue:
local: "Lokal"
delete: "Löschen"
admin/views/users.vue:
username: "Benutzername"
users:
state:
verified: "Verifizierter Benutzer"
origin:
local: "Lokal"
admin/views/emoji.vue:
@ -612,8 +804,10 @@ 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"
@ -658,10 +852,6 @@ mobile/views/components/note-detail.vue:
location: "Ort"
mobile/views/components/notifications.vue:
empty: "Keine Benachrichtigungen"
mobile/views/components/post-form.vue:
reply: "Antworten"
renote: "Anmerken"
reply-placeholder: "Antworte auf diese Anmerkung..."
mobile/views/components/sub-note-content.vue:
private: "Dieser Beitrag ist privat"
deleted: "Dieser Beitrag wurde entfernt"
@ -670,10 +860,13 @@ mobile/views/components/ui.nav.vue:
notifications: "Benachrichtigungen"
search: "Suchen"
user-lists: "Listen"
user-groups: "Gruppen"
game: "Spielen"
about: "Über"
mobile/views/pages/user-lists.vue:
title: "Listen"
mobile/views/pages/drive.vue:
contextmenu:
upload: "Eine Datei hochladen"
create-folder: "Ein Verzeichnis erstellen"
mobile/views/pages/home.vue:
home: "Home"
local: "Lokal"
@ -688,6 +881,8 @@ mobile/views/pages/note.vue:
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"
@ -710,25 +905,6 @@ deck/deck.user-column.vue:
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!"
api:
entities:
properties: "Eigenschaften"
endpoints:
params: "Parameter"
no-params: "Keine Parameter."
res: "Antwort"
require-credential: "Dieser Endpunkt erfordert eine Authentifizierung."
require-permission: "Dieser Endpunkt erfordert die {permission} Berechtigung."
has-limit: "Es gibt eine Ratenbegrenzung."
duration-limit: "Es sind maximal {max} Anfragen pro {duration} Millisekunden möglich."
min-interval-limit: "Es ist nur eine Anfrage alle {interval} Millisekunden möglich."
show-src: "Quellcode anzeigen."
show-src-link: "Quellcode auf GitHub anzeigen"
generated: "Dieses Dokument wird automatisch anhand der API-Definition generiert."
props:
name: "Name"
type: "Typ"
description: "Beschreibung"
dev/views/index.vue:
manage-apps: "Anwendungen verwalten"
dev/views/apps.vue:
@ -739,12 +915,41 @@ dev/views/new-app.vue:
create-app: "Erstelle Anwendung"
app-name: "Name der Anwendung"
app-name-desc: "Der Name der Anwendung"
app-name-ex: "z.B. Misskey für iOS"
app-overview: "Beschreibung der Anwendung"
app-desc: "Eine kurze Beschreibung oder Einführung der Anwendung."
app-desc-ex: "z.B. Ein iOS-Client für Misskey."
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

View File

@ -12,7 +12,9 @@ common:
rich-contents: "Posts"
rich-contents-desc: "Escribe sobre tus pensamientos, eventos, todo lo que quieras compartir. Si es necesario, puedes usar varias sintaxis, decorar tus posts y añadir tus imágenes favoritas, archivos de viddeo y encuestas."
reaction: "Reacciones"
reaction-desc: "La forma mas facil de expresar tus emociones. Misskey te permite añadir varios tipos de reacciones a los posts de otros usuarios. La emperiencia emocional en Misskey nunca será igual que en otra red social, donde solo puedes poner \"likes\"."
ui: "Interfaz"
ui-desc: "No hay ninguna interfaz que le vaya bien a todos. Por eso, Misskey tiene una interfaz altamente personalizable para tus gustos. Puedes hacer tu página principal única editando la interfaz de tu timeline y moviendo varios widgets para conseguir hacer de este lugar uno propio."
drive: "Drive"
adblock:
detected: "Por favor, desactive el bloqueador de publicidad."
@ -20,8 +22,20 @@ common:
application-authorization: "Autorizaciones de la aplicación."
close: "Cerrar"
do-not-copy-paste: "Por favor no copies código aquí. Tu cuenta puede resultar comprometida."
load-more: "Leer más"
enter-password: "Escribe una contraseña"
2fa: "Autenticación de dos factores"
customize-home: "Personaliza la página principal"
featured-notes: "Destacados"
dark-mode: "Modo oscuro"
signin: "Iniciar sesión"
signup: "¡Regístrate!"
signout: "Cerrar sesión"
delete-confirm: "¿Seguro que quieres borrar la publicación?"
notification-types:
all: "Todo"
reply: "Responder"
renote: "Volver a publicar"
got-it: "¡Listo!"
customization-tips:
title: "Consejos de personalización"
@ -48,10 +62,34 @@ common:
month-and-day: "{day} de {month}"
trash: "Papelera"
drive: "Drive"
pages: "Páginas"
messaging: "Conversación"
home: "Inicio"
deck: "Deck"
timeline: "Timeline"
explore: "Explorar"
following: "Siguiendo"
followers: "Seguidores"
favorites: "Me gusta esta nota"
permissions:
"read:account": "Ver información de la cuenta"
"write:account": "Editar información de la cuenta"
"read:blocks": "Ver bloques"
"write:blocks": "Editar bloques"
"read:favorites": "Ver favoritos"
"write:favorites": "Editar favoritos"
"read:following": "Ver información de seguidor"
"read:messaging": "Ver conversación"
"read:mutes": "Ver silenciados"
"write:notes": "Crear y eliminar articulos"
"read:notifications": "Ver notificaciones"
"read:reactions": "Ver reacciones"
"write:votes": "Vota"
post-form:
reply: "Responder"
renote: "Volver a publicar"
enter-username: "Ingresar nombre de usuario"
username-prompt: "Ingresar nombre de usuario"
weekday-short:
sunday: "domingo"
monday: "lunes"
@ -97,14 +135,29 @@ common:
d: "¿Quieres decir algo?"
e: "¡Escribe aquí!"
f: "Esperando a que escribas algo..."
settings: "Configuración"
_settings:
profile: "Tu perfil"
notification: "Notificaciones"
apps: "Aplicaciones"
tags: "Etiquetas"
mute-and-block: "Silenciar/Bloquear"
blocking: "Bloquear"
security: "Seguridad"
password: "Contraseña"
other: "Otros"
appearance: "Diseño"
behavior: "Comportamiento"
fetch-on-scroll-desc: "Cuando te deslizas al final de la página nuevo contenido se carga automáticamente."
note-visibility: "Visibilidad de la publicación"
default-note-visibility: "Rango de publicación predeterminado"
web-search-engine: "Buscador web"
web-search-engine-desc: "Ejemplo: https://www.google.com/?#q={{query}}"
this-setting-is-this-device-only: "Solo para este dispositivo"
use-os-default-emojis: "Usar los emoticonos estándar del sistema operativo"
line-width: "Grosor de línea"
line-width-thin: "Fino"
line-width-normal: "Normal"
line-width-thick: "Grosor"
font-size: "Tamaño del texto"
font-size-x-small: "Muy pequeño"
@ -124,26 +177,67 @@ common:
deck-column-width-wide: "Ancho"
use-shadow: "Usar sombras en la Interfaz de Usuario"
rounded-corners: "Esquinas redondeadas en la Interfaz de Usuario"
circle-icons: "Usar iconos circulares"
circle-icons: "Usar avatar circulares"
contrasted-acct: "Añadir contraste al nombre de usuario"
wallpaper: "Fondo de pantalla"
choose-wallpaper: "Escoge un fondo de pantalla"
delete-wallpaper: "Quitar fondo de pantalla"
post-form-on-timeline: "Mostrar el formulario de las entradas encima de la línea de tiempo"
show-clock-on-header: "Muestra el reloj en la parte superior derecha"
show-reply-target: "Mostrar destinatario de la mención"
timeline: "Timeline"
show-my-renotes: "Mostrar mis renotes en la timeline"
show-renoted-my-notes: "Mostrar renotes de mis posts en la timeline"
sound: "Sonido"
enable-sounds: "Habilitar sonido"
volume: "Volúmen"
test: "Prueba"
update: "Actualizar Misskey"
version: "Versión"
latest-version: "Última versión"
update-checking: "Buscando actualizaciones"
no-updates: "No hay actualizaciones disponibles"
no-updates-desc: "Tu Misskey está actualizado"
update-available: "¡Una nueva versión está disponible!"
update-available-desc: "Las actualizaciones se aplicarán cuando la página se vuelva a cargar."
advanced-settings: "Configuraciones avanzadas"
navbar-position-left: "Izquierda"
save: "Guardar"
saved: "Guardado"
search: "Buscar"
delete: "eliminar"
loading: "cargando"
ok: "Confirmar"
cancel: "Cancelar"
update-available-title: "Actualización disponible"
update-available: "Hay disponible una nueva versión de Misskey ({newer}, la versión actual es {current}). Refresca la página para aplicar las actualizaciones."
my-token-regenerated: "Tu token se ha regenerado vas a ser desconectado."
verified-user: "Cuenta verificada"
hide-password: "Ocultar contraseña"
show-password: "Mostrar contraseña"
enter-username: "Ingresar nombre de usuario"
do-not-use-in-production: "Esto está en desarrollo, no usarlo para producción."
user-suspended: "Este usuario ha sido suspendido"
is-remote-user: "La información sobre este usuario puede no estar completa"
is-remote-post: "Es una publicación remota"
view-on-remote: "Consultar el perfil completo"
renoted-by: "Renotado por {user}"
no-notes: "No hay publicaciones"
turn-on-darkmode: "Cambiar a modo oscuro"
turn-off-darkmode: "Modo claro"
error:
title: "Se ha producido un problema :("
retry: "Inténtalo otra vez"
reversi:
drawn: "Empatado"
my-turn: "Mi turno"
opponent-turn: "Turno del oponente"
turn-of: "Turno de {name}"
past-turn-of: "Turno de {name}"
won: "{name} ha ganado"
black: "Negro"
white: "Blanco"
total: "Total"
this-turn: "Turno {count}"
widgets:
analog-clock: "Reloj analógico"
profile: "Perfil"
@ -166,8 +260,12 @@ common:
nav: "Navegación"
tips: "Consejos"
hashtags: "Etiquetas"
queue: "En cola"
dev: "Se ha producido un error creando la aplicación. Intentelo de nuevo."
ai-chan-kawaii: "Ai-chan es muy mona!"
you: "Tú"
auth/views/form.vue:
share-access: "¿Deseas permitir a <i>{name}</i> acceder a tu cuenta?"
permission-ask: "La aplicación requiere los siguientes permisos:"
cancel: "Cancelar"
accept: "Garantizar acceso."
@ -182,7 +280,18 @@ auth/views/index.vue:
error: "Esta sesión no existe."
sign-in: "Por favor inicia sesión."
common/views/pages/explore.vue:
verified-users: "Cuenta verificada"
popular-users: "Usuarios populares"
recently-updated-users: "Usuarios activos recientemente"
recently-registered-users: "Usuarios que se han unido recientemente"
popular-tags: "Etiquetas populares"
federated: "Desde el fediverso"
explore: "Explorar {host}"
users-info: "Actualmente hay {users} registrados aquí"
common/views/components/url-preview.vue:
enable-player: "Activar reproducción"
disable-player: "Cerrar el reproductor"
common/views/components/user-list.vue:
no-users: "No hay usuarios."
common/views/components/games/reversi/reversi.vue:
matching:
waiting-for: "Esperando por {}"
@ -198,6 +307,7 @@ common/views/components/games/reversi/reversi.index.vue:
sub-title: "¡Juega Reversi con tus amigos!"
invite: "Invitar"
rule: "Cómo jugar"
rule-desc: "Reversi es un juego de estrategia para dos jugadores, el cual se juega en un tablero de 8x8. Hay 64 fichas llamadas discos, las cuales son claras de un lado y oscuras del otro. Los jugadores toman turnos colocando fichas en el tablero con su color asignado mirando hacia arriba. Durante una jugada, cualquier disco del color del oponente que esté en fila entre un disco del oponente y otro del mismo color, será volteado para tener el color del jugador que haya hecho la movida. El objetivo del juego es tener la mayoría de los discos de tu color cuando el último cuadro es llenado."
mode-invite: "Invitar"
mode-invite-desc: "Invitar un usuario al juego."
invitations: "¡Has recibido una invitación!"
@ -254,23 +364,40 @@ common/views/components/media-banner.vue:
click-to-show: "Click para mostrar"
common/views/components/theme.vue:
theme: "Tema"
light-theme: "Tema a usar en Light mode"
dark-theme: "Tema a usar en dark mode"
light-themes: "Tema claro"
dark-themes: "Tema oscuro"
install-a-theme: "Instalar tema"
theme-code: "Código del tema"
install: "Instalación"
installed: "\"{}\" se ha instalado"
create-a-theme: "Crear tema"
save-created-theme: "Guardar tema"
primary-color: "Color primario"
secondary-color: "Color secundario"
text-color: "Color del texto"
base-theme: "Tema base"
base-theme-light: "Claro"
base-theme-dark: "Oscuro"
find-more-theme: "Obtener más temas"
theme-name: "Nombre del tema"
preview-created-theme: "Vista previa"
invalid-theme: "No es un tema válido"
already-installed: "Este tema ya está instalado."
saved: "Guardado"
manage-themes: "Gestor de temas"
builtin-themes: "Temas estandar"
my-themes: "Mis temas"
installed-themes: "Temas instalados"
select-theme: "Elegir tema"
uninstall: "Desinstalar"
uninstalled: "\"{}\" ha sido desinstalado"
author: "Autor"
desc: "Descripción"
export: "Exportar"
import: "Importar"
import-by-code: "o pega el código"
common/views/components/cw-button.vue:
show: "Mostrar"
chars: "{count} letras"
@ -281,17 +408,13 @@ common/views/components/messaging.vue:
you: "Tu"
no-history: "Sin historial"
common/views/components/messaging-room.vue:
empty: "Sin conversaciones"
no-history: "El historial se ha acabado"
resize-form: "Arrastra para redimensionar"
new-message: "Nuevo mensaje"
only-one-file-attached: "Un único archivo se puede conectar al mensaje"
common/views/components/messaging-room.form.vue:
input-message-here: "Escribe el mensaje aquí"
send: "Enviar"
attach-from-local: "Adjunta ficheros desde tu PC"
attach-from-drive: "Adjunta ficheros desde tu disco"
only-one-file-attached: "Un único archivo se puede conectar al mensaje"
common/views/components/messaging-room.message.vue:
is-read: "Leer"
deleted: "El mensaje se ha borrado"
@ -342,6 +465,8 @@ common/views/components/emoji-picker.vue:
objects: "Objetos"
symbols: "Símbolos"
flags: "Países"
common/views/components/settings/app-type.vue:
info: "Necesitas recargar la página para que los cambios tengan efecto."
common/views/components/signin.vue:
username: "Usuario"
password: "Contraseña"
@ -384,10 +509,25 @@ common/views/components/stream-indicator.vue:
connected: "Conectado"
common/views/components/notification-settings.vue:
title: "Notificaciones"
common/views/components/integration-settings.vue:
title: "Integraciones"
connect: "Conectar"
disconnect: "Desconectarse"
connected-to: "Estas conectado a la siguiente cuenta"
common/views/components/github-setting.vue:
description: "Una vez conectada tu cuenta de GitHub a Misskey podrás ver la información sobre tu perfil de GitHub y además podrás registrarte mediante tu cuenta de GitHub."
connected-to: "Estas conectado a esta cuenta de GitHub"
detail: "Ver detalles..."
reconnect: "Reconectar"
connect: "Vincular tu cuenta de GitHub"
disconnect: "Desconectarse"
common/views/components/discord-setting.vue:
description: "Una vez conectada tu cuenta de Discord a Misskey podrás ver la información sobre tu perfil de Discord y además podrás registrarte mediante tu cuenta de Discord."
connected-to: "Estas conectado a esta cuenta de Discord"
detail: "Ver detalles..."
reconnect: "Reconectar"
connect: "Vincular tu cuenta de Discord"
disconnect: "Desconectarse"
common/views/components/uploader.vue:
waiting: "Un momento"
common/views/components/visibility-chooser.vue:
@ -399,27 +539,73 @@ common/views/components/visibility-chooser.vue:
specified: "Directo"
specified-desc: "Publica solo para los seguidores que quieras"
local-public: "Público (sólo local)"
local-public-desc: "No publicar para remoto"
local-home: "Inicio (sólo local)"
local-followers: "Seguidores (sólo local)"
common/views/components/trends.vue:
count: "{} usuarios mencionados"
empty: "Ninguna tendencia popular ahora"
common/views/components/language-settings.vue:
title: "Mostrar idioma"
pick-language: "Selecciona un idioma"
recommended: "Recomendado"
auto: "Automático"
specify-language: "Especifica el idioma"
info: "Necesitas recargar la página para que los cambios tengan efecto."
common/views/components/profile-editor.vue:
title: "Perfil"
name: "Nombre"
account: "Cuenta"
location: "Localización"
description: "Acerca de mí"
you-can-include-hashtags: "También puedes incluir hashtags en la descripción de tu perfil."
language: "Idioma"
birthday: "Fecha de nacimiento"
avatar: "Avatar"
banner: "Banner"
is-cat: "Esta cuenta es un gato"
is-bot: "Esta cuenta es un bot"
is-locked: "Las peticiones de seguimiento necesitan aprobación"
careful-bot: "Las peticiones de seguimiento de bots necesitan aprobación"
auto-accept-followed: "Aprobar automaticamente las peticiones de follow de gente a la que sigues"
advanced: "Otros"
privacy: "Privacidad"
save: "Guardar"
saved: "Perfil actualizado con exito"
uploading: "Subiendo"
upload-failed: "Error al subir"
unable-to-process: "La operación no se puede llevar a cabo"
email: "Preferencias de correo"
email-address: "Correo electrónico"
email-verified: "Tu cuenta de correo ha sido verificada."
email-not-verified: "Tu cuenta de correo no está verificada. Por favor comprueba tu bandeja de entrada."
export: "Exportar"
import: "Importar"
export-and-import: "Exportar/Importar"
export-targets:
all-notes: "Todas las notas publicadas"
following-list: "Seguidores"
mute-list: "Silenciar"
blocking-list: "Bloquear"
user-lists: "Listas"
export-requested: "Has solicitado una exportación. Esto puede tardar un rato. Después de que termine la exportación el archivo se añadirá al drive."
import-requested: "Has empezado una importación. Esto puede tardar un rato."
enter-password: "Escribe una contraseña"
danger-zone: "Zona de peligro"
delete-account: "Eliminar cuenta"
account-deleted: "Esta cuenta ha sido eliminada. Puede tardar un rato hasta que toda la información desaparazca."
common/views/components/user-list-editor.vue:
users: "Usuarios"
rename: "Cambiar el nombre de la lista"
delete: "Eliminar lista"
remove-user: "Eliminar de la lista"
common/views/components/user-group-editor.vue:
invite: "Invitar"
common/views/components/user-lists.vue:
user-lists: "Listas"
list-name: "Nombre de lista"
common/views/components/user-groups.vue:
invites: "Invitar"
common/views/widgets/broadcast.vue:
fetching: "Recuperando"
no-broadcasts: "Sin emisión"
@ -478,6 +664,8 @@ common/views/pages/follow.vue:
request-pending: "Solicitud pendiente"
follow-processing: "Solicitud en proceso"
follow-request: "Solicitar suscripción"
common/views/pages/follow-requests.vue:
received-follow-requests: "Solicitudes de seguimiento"
desktop:
banner-crop-title: "Corta la parte que aparece como un banner"
banner: "Banner"
@ -489,6 +677,7 @@ desktop:
uploading-avatar: "Cargando un nuevo avatar"
avatar-updated: "Avatar actualizado"
choose-avatar: "Escoge una imagen de avatar"
unable-to-process: "La operación no se puede llevar a cabo"
invalid-filetype: "Este tipo de archivo no es compatible aquí"
desktop/views/components/activity.chart.vue:
total: "Negro ... Total"
@ -547,6 +736,7 @@ desktop/views/components/drive.folder.vue:
rename: "Renombrar"
rename-folder: "Renombrar carpeta"
input-new-folder-name: "Escribe el nombre nuevo"
else-folders: "Otros"
desktop/views/components/drive.vue:
search: "Buscar"
empty-draghover: "¡Saluda!"
@ -594,7 +784,7 @@ desktop/views/components/note-detail.vue:
add-reaction: "Agregar una reacción"
desktop/views/components/note.vue:
reply: "Responder"
renote: "Republicar"
renote: "Volver a publicar"
add-reaction: "Reacción"
detail: "Detalles"
private: "Esta publicación es privada"
@ -605,32 +795,12 @@ desktop/views/components/notes.vue:
desktop/views/components/notifications.vue:
empty: "No hay notificaciones"
desktop/views/components/post-form.vue:
add-visible-user: "+Agregar usuario"
attach-location-information: "Agregar localización"
hide-contents: "Esconder contenidos"
reply-placeholder: "Responder a esta nota..."
quote-placeholder: "Citar esta nota..."
submit: "Publicar"
reply: "Responder"
renote: "Republicar"
posted: "¡Publicado!"
replied: "¡Respondido!"
reposted: "¡Republicado!"
note-failed: "Error al publicar nota"
reply-failed: "Error al responder"
renote-failed: "Error al republicar"
posting: "Publicando"
attach-media-from-local: "Agregar medios de tu dispositivo"
attach-media-from-drive: "Adjunta multimedia desde tu Disco"
create-poll: "Crea una encuesta"
text-remain: "quedan {} caracteres"
recent-tags: "Reciente"
click-to-tagging: "Click para etiquetar"
visibility: "Visibilidad"
geolocation-alert: "Tu dispositivo no tiene soporte de geolocalización."
error: "Error"
enter-username: "Por favor escribe un nombre de usuario..."
annotations: "Anotaciones a la publicación (opcional)"
desktop/views/components/post-form-window.vue:
note: "Nota nueva"
reply: "Responder"
@ -721,14 +891,6 @@ desktop/views/components/ui.header.post.vue:
post: "Crear una publicación"
desktop/views/components/ui.header.search.vue:
placeholder: "Buscar"
desktop/views/components/received-follow-requests-window.vue:
title: "Solicitudes de seguidores"
accept: "Aceptar"
reject: "Rechazar"
desktop/views/components/user-lists-window.vue:
title: "Listas de usuario"
create-list: "Crear lista"
list-name: "Nombre de lista"
desktop/views/components/user-preview.vue:
notes: "Publicaciones"
following: "Sigue"
@ -742,29 +904,54 @@ admin/views/index.vue:
instance: "Instancia"
moderators: "Moderadores"
users: "Usuarios"
hashtags: "Hashtags"
federation: "Federado"
queue: "Cola de trabajos"
logs: "Registros"
back-to-misskey: "Volver a Misskey"
admin/views/dashboard.vue:
dashboard: "Panel de Control"
accounts: "Cuenta"
notes: "Publicaciones"
drive: "Drive"
instances: "Instancias"
this-instance: "Esta instancia"
federated: "Federado"
admin/views/queue.vue:
title: "Cola"
remove-all-jobs: "Limpiar todos los trabajos pendientes"
queue: "Cola"
admin/views/logs.vue:
logs: "Registros"
admin/views/abuse.vue:
title: "Abuso"
target: "Destinatario"
reporter: "Informador"
details: "Detalles"
remove-report: "eliminar"
admin/views/instance.vue:
instance: "Instancia"
instance-name: "Nombre de la instancia"
instance-description: "Descripción de la instancia"
host: "Host"
recaptcha-secret-key: "clave secreta reCAPTCHA"
banner-url: "URL de la imagen de banner"
error-image-url: "Error en la URL de la imagen"
languages: "Idioma de esta instancia"
languages-desc: "Puedes añadir mas de uno, separado por espacios."
maintainer-config: "Información del administrador"
maintainer-name: "Nombre del administrador"
maintainer-email: "Contactar con el administrador"
drive-config: "Ajustes del Drive"
cache-remote-files: "Mantener en cache los archivos remotos"
recaptcha-preview: "Vista previa"
invite: "Invitar"
save: "Guardar"
saved: "Guardado"
email: "Correo electrónico"
smtp-host: "Host SMTP"
smtp-port: "Puerto SMTP"
smtp-user: "Usuario SMTP"
smtp-pass: "Contraseña SMTP"
test-email: "Prueba"
admin/views/charts.vue:
title: "Gráficos"
per-day: "Por día"
@ -784,13 +971,18 @@ admin/views/drive.vue:
mark-as-sensitive: "Marcar como 'sensible'"
unmark-as-sensitive: "Desmarcar como 'sensible'"
admin/views/users.vue:
username: "Usuario"
host: "Host"
users:
state:
all: "Todo"
moderator: "Moderadores"
verified: "Cuenta verificada"
origin:
local: "Local"
admin/views/moderators.vue:
logs:
title: "Registros"
moderator: "Moderadores"
admin/views/emoji.vue:
add-emoji:
add: "Agregar"
@ -800,12 +992,14 @@ admin/views/announcements.vue:
save: "Guardar"
remove: "eliminar"
add: "Agregar"
saved: "Guardado"
admin/views/federation.vue:
instance: "Instancia"
host: "Host"
following: "Siguiendo"
status: "Estado"
block: "Bloquear"
instances: "Federado"
states:
all: "Todo"
blocked: "Bloquear"
@ -813,6 +1007,8 @@ admin/views/federation.vue:
chart-spans:
hour: "Por hora"
day: "Por día"
blocked-hosts: "Bloquear"
save: "Guardar"
desktop/views/pages/selectdrive.vue:
cancel: "Cancelar"
desktop/views/pages/user-list.users.vue:
@ -865,10 +1061,6 @@ mobile/views/components/note-detail.vue:
location: "Localización"
mobile/views/components/notifications.vue:
empty: "No hay notificaciones"
mobile/views/components/post-form.vue:
reply: "Responder"
renote: "Republicar"
reply-placeholder: "Responder a esta nota..."
mobile/views/components/sub-note-content.vue:
private: "Esta publicación es privada"
deleted: "Esta publicación ha sido removida"
@ -884,8 +1076,10 @@ mobile/views/components/ui.nav.vue:
game: "Juegos"
admin: "Admin"
about: "Sobre"
mobile/views/pages/user-lists.vue:
title: "Listas"
mobile/views/pages/drive.vue:
contextmenu:
upload: "Subir fichero"
create-folder: "Crear una carpeta"
mobile/views/pages/home.vue:
home: "Inicio"
local: "Local"
@ -896,14 +1090,12 @@ mobile/views/pages/widgets.vue:
customization-tips: "Consejos de personalización"
mobile/views/pages/widgets/activity.vue:
activity: "Actividad"
mobile/views/pages/received-follow-requests.vue:
title: "Solicitudes de seguimiento"
accept: "Aceptar"
reject: "Rechazar"
mobile/views/pages/games/reversi.vue:
reversi: "Reversi"
mobile/views/pages/search.vue:
search: "Buscar"
mobile/views/pages/notifications.vue:
notifications: "Notificaciones"
mobile/views/pages/user/home.vue:
activity: "Actividad"
mobile/views/pages/user/home.photos.vue:
@ -918,3 +1110,34 @@ deck:
rename: "Renombrar"
deck/deck.user-column.vue:
activity: "Actividad"
pages:
pin-this-page: "Fijar en el perfil"
like: "Me gusta"
blocks:
post: "Formulario"
script:
categories:
random: "Aleatorio"
list: "Listas"
blocks:
_join:
arg1: "Listas"
random: "Aleatorio"
_randomPick:
arg1: "Listas"
_dailyRandomPick:
arg1: "Listas"
_seedRandomPick:
arg2: "Listas"
_pick:
arg1: "Listas"
_listLen:
arg1: "Listas"
types:
array: "Listas"
room:
save: "Guardar"
saved: "Guardado"
furnitures:
moon: "Luna"
bin: "Papelera"

File diff suppressed because it is too large Load Diff

View File

@ -15,6 +15,7 @@ const merge = (...args) => args.reduce((a, c) => ({
const languages = [
'cs-CZ',
'da-DK',
'de-DE',
'en-US',
'es-ES',

File diff suppressed because it is too large Load Diff

View File

@ -27,6 +27,13 @@ common:
load-more: "もっとあらへんのか!"
enter-password: "パスワードを入れてや"
2fa: "二段階認証"
delete-confirm: "この投稿を削除してもええか?"
notification-types:
all: "すべて"
follow: "フォロー"
reply: "返す"
renote: "Renote"
reaction: "リアクション"
got-it: "ほい"
customization-tips:
title: "カスタマイズのヒント"
@ -60,6 +67,16 @@ common:
following: "フォローしとる"
followers: "フォロワー"
favorites: "お気に入り"
permissions:
"write:votes": "投票するで"
post-form:
submit: "投稿"
reply: "返す"
renote: "Renote"
error: "エラー"
enter-username: "ユーザー名を入力してや"
add-visible-user: "ユーザー増やす"
username-prompt: "ユーザー名を入力してや"
weekday-short:
sunday: "日"
monday: "月"
@ -113,13 +130,15 @@ common:
password: "パスワード"
other: "その他"
timeline: "タイムライン"
save: "保存"
saved: "保存したで!"
search: "検索"
delete: "削除"
loading: "読み込み中"
update-available-title: "更新があんで"
update-available: "Misskeyの新しいバージョンがあんで({newer}。現在{current}をつこてるわ)。ページを再度読み込みしたると更新が適用されるわ。"
my-token-regenerated: "あんさんのトークンが更新されたらしいわ。すまんがとりあえずサインアウトすんで。"
verified-user: "アメちゃん付きアカウント"
enter-username: "ユーザー名を入力してや"
do-not-use-in-production: "開発ビルドや。本番環境で使わんといて!知らんで!"
is-remote-post: "この投稿情報はコピーです。"
view-on-remote: "ちゃんとした情報見せてや!"
@ -179,7 +198,6 @@ auth/views/index.vue:
error: "セッションが存在してへん。"
sign-in: "サインインしてや"
common/views/pages/explore.vue:
verified-users: "アメちゃん付きアカウント"
federated: "連合"
common/views/components/games/reversi/reversi.vue:
matching:
@ -294,18 +312,15 @@ common/views/components/messaging.vue:
search-user: "ユーザーを探す"
you: "あんさん"
no-history: "履歴はあらへんで"
user: "ユーザー"
common/views/components/messaging-room.vue:
empty: "このユーザーと話したことはあらへんで"
no-history: "これより過去の履歴はあらへんで"
resize-form: "ドラッグしてフォームの広さを調整"
new-message: "新しいメッセージがあるで"
only-one-file-attached: "メッセージに添付できんのはひとつのファイルのみやで"
common/views/components/messaging-room.form.vue:
input-message-here: "ここにメッセージ書いてや"
send: "送信"
attach-from-local: "PCからファイルを添付する"
attach-from-drive: "ドライブからファイルを添付する"
only-one-file-attached: "メッセージに添付できんのはひとつのファイルのみやで"
common/views/components/messaging-room.message.vue:
is-read: "既読"
deleted: "このメッセージは削除されたわ"
@ -357,6 +372,8 @@ common/views/components/emoji-picker.vue:
objects: "物"
symbols: "記号"
flags: "旗"
common/views/components/settings/app-type.vue:
info: "ページもっぺん読み込んだら反映したるで。"
common/views/components/signin.vue:
username: "ユーザー名"
password: "パスワード"
@ -450,7 +467,7 @@ common/views/components/profile-editor.vue:
description: "自己紹介"
language: "言語"
birthday: "誕生日"
avatar: "アイコン"
avatar: "アバター"
banner: "バナー"
is-cat: "このアカウントはCatやで"
is-bot: "このアカウントはBotやで"
@ -462,6 +479,7 @@ common/views/components/profile-editor.vue:
saved: "プロフィールを保存したで"
uploading: "アップロードしとります"
upload-failed: "これアップロードでけへんわ"
unable-to-process: "あかん、無理やわ"
email: "メール設定"
email-address: "メールアドレス"
email-verified: "このメールアドレスOKや"
@ -476,6 +494,14 @@ common/views/components/profile-editor.vue:
enter-password: "パスワードを入れてや"
common/views/components/user-list-editor.vue:
users: "ユーザー"
add-user: "ユーザー増やす"
common/views/components/user-group-editor.vue:
invite: "招待"
common/views/components/user-lists.vue:
user-lists: "リスト"
list-name: "リスト名"
common/views/components/user-groups.vue:
invites: "招待"
common/views/widgets/broadcast.vue:
fetching: "見てみるわ…"
no-broadcasts: "お知らせはあらへんで"
@ -534,6 +560,8 @@ common/views/pages/follow.vue:
request-pending: "フォローの許し待っとる"
follow-processing: "今フォロー処理やっとる‥"
follow-request: "フォロー許してくれや!言うてみる"
common/views/pages/follow-requests.vue:
received-follow-requests: "フォロー許してくれや!言うてみる"
desktop:
banner-crop-title: "どこバナーとして出す?"
banner: "バナー"
@ -545,6 +573,7 @@ desktop:
uploading-avatar: "新しいアバターをアップロードしとるで"
avatar-updated: "アバターを更新したで"
choose-avatar: "アバターにする画像選んでや"
unable-to-process: "あかん、無理やわ"
invalid-filetype: "この形式のファイル無理やねん"
desktop/views/components/activity.chart.vue:
total: "黒いの ... 全部"
@ -576,7 +605,7 @@ desktop/views/components/crop-window.vue:
desktop/views/components/drive-window.vue:
used: "使うとる"
desktop/views/components/drive.file.vue:
avatar: "アイコン"
avatar: "アバター"
banner: "バナー"
nsfw: "見たらあかんで"
contextmenu:
@ -585,8 +614,8 @@ desktop/views/components/drive.file.vue:
unmark-as-sensitive: "やっぱ見せたるわ"
copy-url: "URLをコピー"
download: "ダウンロード"
else-files: "まだあんで..."
set-as-avatar: "アイコンにする"
else-files: "その他"
set-as-avatar: "アバターにする"
set-as-banner: "バナーにする"
open-in-app: "アプリで開く"
add-app: "アプリ増やす"
@ -604,6 +633,7 @@ desktop/views/components/drive.folder.vue:
rename: "名前を変えるで"
rename-folder: "フォルダ名を変えるで"
input-new-folder-name: "新しいフォルダ名を入力してや"
else-folders: "その他"
desktop/views/components/drive.vue:
search: "検索"
empty-draghover: "ドロップするにゃ!お魚以外なら何でもいいにゃ!"
@ -662,33 +692,12 @@ desktop/views/components/notes.vue:
desktop/views/components/notifications.vue:
empty: "あらへん!"
desktop/views/components/post-form.vue:
add-visible-user: "+ユーザー増やす"
attach-location-information: "いる場所くっつけるで"
hide-contents: "内容を隠す"
reply-placeholder: "この投稿への返信..."
quote-placeholder: "この投稿を引用..."
submit: "投稿"
reply: "返信"
renote: "Renote"
posted: "投稿したで!"
replied: "返信したで!"
reposted: "Renoteしたで"
note-failed: "投稿に失敗したで"
reply-failed: "返信に失敗したで"
renote-failed: "Renoteでけへん"
posting: "投稿中"
attach-media-from-local: "PCからメディア持ってくる"
attach-media-from-drive: "ドライブからメディア持ってくる"
create-poll: "アンケートを作成"
text-remain: "残り{}文字"
recent-tags: "最近のタグ"
local-only-message: "この投稿はローカルだけ公開されるで"
click-to-tagging: "クリックでタグ付け"
visibility: "公開範囲"
geolocation-alert: "あんさんのつことる端末は位置情報に対応しとらんみたいやわ、知らんけど。"
error: "エラー"
enter-username: "ユーザー名を入力してや"
annotations: "もっと教えてな(別にええけど)"
desktop/views/components/post-form-window.vue:
note: "新規投稿"
reply: "返す"
@ -752,6 +761,7 @@ common/views/components/drive-settings.vue:
max: "容量"
in-use: "使うとる"
stats: "統計"
default-upload-folder-name: "フォルダ"
common/views/components/mute-and-block.vue:
mute-and-block: "ミュートとブロック"
mute: "ミュート"
@ -807,14 +817,6 @@ desktop/views/components/ui.header.post.vue:
post: "新規投稿"
desktop/views/components/ui.header.search.vue:
placeholder: "検索"
desktop/views/components/received-follow-requests-window.vue:
title: "フォロー許してくれや!言うてみる"
accept: "許す"
reject: "許さん"
desktop/views/components/user-lists-window.vue:
title: "リスト"
create-list: "新しいリストを作成"
list-name: "リスト名"
desktop/views/components/user-preview.vue:
notes: "投稿"
following: "フォロー"
@ -836,7 +838,6 @@ admin/views/index.vue:
users: "ユーザー"
federation: "連合"
announcements: "知っといてや"
hashtags: "ハッシュタグ"
back-to-misskey: "Misskeyに戻る"
admin/views/dashboard.vue:
dashboard: "ダッシュボード"
@ -846,6 +847,10 @@ admin/views/dashboard.vue:
instances: "インスタンス"
this-instance: "ワイのインスタンス"
federated: "連合"
admin/views/logs.vue:
levels:
info: "情報"
error: "エラー"
admin/views/abuse.vue:
details: "もっと"
remove-report: "削除"
@ -861,6 +866,7 @@ admin/views/instance.vue:
maintainer-name: "管理者名"
maintainer-email: "管理者の連絡先"
drive-config: "ドライブの設定"
object-storage-endpoint: "エンドポイント"
cache-remote-files: "リモートのファイルをキャッシュする"
cache-remote-files-desc: "この設定を無効にすると、リモートファイルをこっちで保管せずに直接リンク張るようになるで。サーバーのストレージは軽くやろうけど、プライバシー設定で直リンクを向こうにしとるユーザーはファイルが見れへんし、サムネイルが無いから通信量が増えたりするから、普通はオンにしといてな。"
local-drive-capacity-mb: "ローカルユーザーひとりあたりのドライブ容量"
@ -869,8 +875,7 @@ admin/views/instance.vue:
recaptcha-config: "reCAPTCHAの設定"
recaptcha-info: "reCAPTCHAを有効にするにはreCAPTCHAトークンが要るで。https://www.google.com/recaptcha/intro/ にアクセスしてトークンを取得してな。"
enable-recaptcha: "reCAPTCHAを有効にする"
recaptcha-site-key: "reCAPTCHA site key"
recaptcha-secret-key: "reCAPTCHA secret key"
recaptcha-preview: "試してみる"
twitter-integration-config: "Twitter連携の設定"
twitter-integration-info: "コールバックURLは {url} に設定してや。"
enable-twitter-integration: "Twitter連携を有効にする"
@ -897,7 +902,6 @@ admin/views/instance.vue:
invite: "来てや"
save: "保存"
saved: "保存したで!"
user-recommendation-config: "このユーザーええで"
email-config: "メールサーバーの設定"
email-config-info: "メールアドレス確認やパスワードリセットの際に使うで。"
enable-email: "メール配信を有効にする"
@ -949,14 +953,20 @@ admin/views/users.vue:
reset-password: "パスワードをリセット"
password-updated: "パスワードは現在「{password} 」やで"
suspend: "凍結"
username: "ユーザー名"
host: "ホスト"
users:
title: "ユーザー"
state:
all: "すべて"
moderator: "モデレーター"
verified: "アメちゃん付きアカウント"
origin:
local: "ローカル"
admin/views/moderators.vue:
logs:
moderator: "モデレーター"
type: "操作"
info: "情報"
admin/views/emoji.vue:
add-emoji:
add: "増やす"
@ -993,6 +1003,8 @@ admin/views/federation.vue:
chart-spans:
hour: "1時間ごと"
day: "1日ごと"
blocked-hosts: "ブロック"
save: "保存"
desktop/views/pages/welcome.vue:
about: "もうちょい……"
timeline: "タイムライン"
@ -1069,8 +1081,6 @@ mobile/views/components/drive.vue:
file-count: "ファイル"
nothing-in-drive: "ドライブには何もあらへんで。"
folder-is-empty: "このフォルダ何もないわ"
prompt: "何すんの?(数字を入れてや): <1 → ファイルをアップロード | 2 → ファイルをURLでアップロード | 3 → フォルダ作成 | 4 → このフォルダ名を変更 | 5 → このフォルダを移動 | 6 → このフォルダを削除>"
deletion-alert: "フォルダの削除は未実装やねん...。堪忍な!"
folder-name: "フォルダー名"
url-prompt: "このURLのファイルをアップロードしたいねん"
uploading: "アップロードをリクエストしたで。アップロードが完了するまで時間がかかるかも分からん、知らんけど。"
@ -1118,17 +1128,6 @@ mobile/views/components/note-sub.vue:
cat: "cat"
mobile/views/components/notifications.vue:
empty: "あらへん!"
mobile/views/components/post-form.vue:
add-visible-user: "ユーザー増やす"
submit: "投稿"
reply: "返す"
renote: "Renote"
quote-placeholder: "この投稿を持ってくる(オプション)"
reply-placeholder: "この投稿への返信..."
cw-placeholder: "内容への注釈 (オプション)"
location-alert: "あんさんのつことる端末は位置情報に対応しとらんみたいやわ、知らんけど。"
error: "エラー"
username-prompt: "ユーザー名を入力してや"
mobile/views/components/sub-note-content.vue:
private: "この投稿は見せられへんわ"
deleted: "この投稿なんか無くなってもうたわ"
@ -1147,9 +1146,10 @@ mobile/views/components/ui.nav.vue:
game: "ゲーム"
admin: "管理"
about: "Misskeyってなんや"
mobile/views/pages/user-lists.vue:
title: "リスト"
enter-list-name: "リスト名を入力してや"
mobile/views/pages/drive.vue:
contextmenu:
upload: "ファイル上げる"
create-folder: "フォルダー作る"
mobile/views/pages/signup.vue:
lets-start: "📦 始めようや"
mobile/views/pages/followers.vue:
@ -1172,10 +1172,6 @@ mobile/views/pages/widgets/activity.vue:
activity: "やっとること"
mobile/views/pages/share.vue:
share-with: "{name}で共有"
mobile/views/pages/received-follow-requests.vue:
title: "フォロー許してくれや!"
accept: "許す"
reject: "許さん"
mobile/views/pages/note.vue:
title: "投稿"
prev: "前のやつ"
@ -1187,6 +1183,8 @@ mobile/views/pages/search.vue:
not-found: "ワイは「{q}」なんて投稿知らんわ、無いんちゃう?知らんけど。"
mobile/views/pages/selectdrive.vue:
select-file: "ファイル選んでや"
mobile/views/pages/notifications.vue:
notifications: "通知"
mobile/views/pages/settings.vue:
signed-in-as: "あんたは橋の下で拾った{}や!"
mobile/views/pages/user.vue:
@ -1243,25 +1241,6 @@ deck/deck.user-column.vue:
docs:
edit-this-page-on-github: "間違いや改善点を見つけましたか?"
edit-this-page-on-github-link: "このページをGitHubで編集"
api:
entities:
properties: "プロパティ"
endpoints:
params: "パラメータ"
no-params: "パラメータはありません"
res: "レスポンス"
require-credential: "このエンドポイントは認証情報が必須です。"
require-permission: "このエンドポイントは{permission}の権限を必要とします。"
has-limit: "レートリミットがあります。"
duration-limit: "直近{duration}ミリ秒の間のこのエンドポイントへのリクエスト数の合計が{max}を超える場合はリクエストできません。"
min-interval-limit: "前回のリクエストから{interval}ミリ秒経っていない場合はリクエストできません。"
show-src: "このエンドポイントのソースコードも閲覧できます。"
show-src-link: "コードをGitHubで見る"
generated: "このドキュメントはAPI定義に基づき自動生成されています。"
props:
name: "名前"
type: "型"
description: "説明"
dev/views/index.vue:
manage-apps: "アプリの管理"
dev/views/apps.vue:
@ -1272,12 +1251,43 @@ dev/views/new-app.vue:
create-app: "アプリケーション作る"
app-name: "アプリケーションの名前"
app-name-desc: "あんたのアプリの名前。"
app-name-ex: "ex) 関西ミスキー保安協会"
app-overview: "このアプリどんなん?"
app-desc: "あんたのアプリどんなんか教えて"
app-desc-ex: "ex) 関西人なら誰でも口ずさめるこのCMがついにMisskeyへ。"
callback-url: "コールバックURL (無くてもええで)"
callback-url-desc: "ユーザーが認証フォームで認証した後どこに連れてくかを設定できるで"
authority: "権限"
authority-desc: "ここにチェックした機能しかAPIからアクセスできひんから気ぃつけてな"
authority-warning: "アプリ作った後でも変えれるけど、新しいやつ追加したらそん時関連付いてるユーザーキーは全部ほかされるで。"
pages:
pin-this-page: "ピン留め"
unpin-this-page: "ピン留めやめる"
like: "ええやん"
blocks:
image: "画像"
post: "投稿フォーム"
script:
categories:
random: "いんじゃんほい"
list: "リスト"
blocks:
_join:
arg1: "リスト"
random: "いんじゃんほい"
_randomPick:
arg1: "リスト"
_dailyRandomPick:
arg1: "リスト"
_seedRandomPick:
arg2: "リスト"
_pick:
arg1: "リスト"
_listLen:
arg1: "リスト"
types:
array: "リスト"
room:
translate: "移動"
save: "保存"
saved: "保存したで!"
furnitures:
moon: "月"
bin: "ゴミ箱"

File diff suppressed because it is too large Load Diff

View File

@ -8,6 +8,11 @@ common:
reaction: "Reactie"
close: "Sluiten"
enter-password: "Voer het wachtwoord in"
notification-types:
all: "Alle"
follow: "Volgend"
reply: "Beantwoorden"
reaction: "Reactie"
time:
unknown: "onbekend"
future: "toekomstig"
@ -23,6 +28,12 @@ common:
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"
@ -102,10 +113,9 @@ common/views/components/messaging.vue:
search-user: "Gebruiker zoeken"
you: "Jij"
no-history: "Geen geschiedenis"
user: "Gebruiker"
common/views/components/messaging-room.vue:
empty: "Geen gesprekken"
no-history: "Er is geen verdere geschiedenis"
resize-form: "Versleep om grootte te wijzigen"
new-message: "Nieuw bericht"
common/views/components/messaging-room.form.vue:
input-message-here: "Voer hier je bericht in"
@ -194,12 +204,16 @@ common/views/components/profile-editor.vue:
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"
@ -218,6 +232,8 @@ common/views/pages/follow.vue:
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"
@ -252,7 +268,6 @@ desktop/views/components/drive.file.vue:
rename: "Naam wijzigen"
copy-url: "URL kopiëren"
download: "Downloaden"
else-files: "Overig"
set-as-avatar: "Instellen als gebruikersafbeelding"
set-as-banner: "Instellen als omslagfoto"
open-in-app: "Openen in app"
@ -321,21 +336,12 @@ desktop/views/components/notes.vue:
desktop/views/components/notifications.vue:
empty: "Geen meldingen"
desktop/views/components/post-form.vue:
reply-placeholder: "Deze notitie beantwoorden..."
quote-placeholder: "Deze notitie citeren..."
submit: "Bericht"
reply: "Beantwoorden"
posted: "Geplaatst!"
replied: "Beantwoord!"
reposted: "Hergeplaatst!"
note-failed: "Noteren mislukt"
reply-failed: "Beantwoorden mislukt"
renote-failed: "Renote mislukt"
posting: "Bezig met plaatsen"
attach-media-from-local: "Media bijvoegen van je computer"
attach-media-from-drive: "Media bijvoegen uit je Drive"
create-poll: "Peiling creëren"
text-remain: "{} resterende tekens"
desktop/views/components/post-form-window.vue:
note: "Nieuwe notitie"
reply: "Beantwoorden"
@ -378,6 +384,7 @@ common/views/components/api-settings.vue:
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"
@ -399,9 +406,6 @@ desktop/views/components/ui.header.post.vue:
post: "Nieuw bericht opstellen"
desktop/views/components/ui.header.search.vue:
placeholder: "Zoeken"
desktop/views/components/user-lists-window.vue:
title: "Lijsten"
create-list: "Lijst creëren"
desktop/views/components/user-preview.vue:
notes: "Berichten"
following: "Volgend"
@ -421,8 +425,6 @@ admin/views/dashboard.vue:
notes: "Bericht"
admin/views/abuse.vue:
remove-report: "Verwijderen"
admin/views/instance.vue:
user-recommendation-config: "Aanbevolen gebruikers"
admin/views/charts.vue:
notes: "Bericht"
users: "Gebruiker"
@ -431,6 +433,7 @@ admin/views/drive.vue:
local: "Lokaal"
delete: "Verwijderen"
admin/views/users.vue:
username: "Gebruikersnaam"
users:
title: "Gebruiker"
state:
@ -539,11 +542,6 @@ mobile/views/components/note-detail.vue:
location: "Locatie"
mobile/views/components/notifications.vue:
empty: "Geen meldingen"
mobile/views/components/post-form.vue:
add-visible-user: "Gebruiker toevoegen"
submit: "Plaatsen"
reply: "Antwoord"
reply-placeholder: "Deze notitie beantwoorden..."
mobile/views/components/sub-note-content.vue:
private: "(dit bericht is privé)"
media-count: "{} media"
@ -555,8 +553,10 @@ mobile/views/components/ui.nav.vue:
user-lists: "Lijsten"
game: "Othello spelen"
about: "Over Misskey"
mobile/views/pages/user-lists.vue:
title: "Lijsten"
mobile/views/pages/drive.vue:
contextmenu:
upload: "Bestand uploaden"
create-folder: "Map creëren"
mobile/views/pages/home.vue:
home: "Startpagina"
local: "Lokaal"
@ -575,6 +575,8 @@ 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:
@ -614,13 +616,30 @@ deck/deck.user-column.vue:
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!"
api:
entities:
properties: "Eigenschappen"
endpoints:
params: "Parameters"
res: "Antwoord"
props:
name: "Naam"
type: "Type"
description: "Omschrijving"
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"

View File

@ -11,6 +11,10 @@ common:
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!"
@ -37,6 +41,12 @@ common:
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"
@ -72,6 +82,7 @@ common:
_settings:
notification: "Notifikasjon"
password: "Passord"
save: "Lagre"
search: "Søk"
delete: "Slett"
loading: "Laster inn..."
@ -128,6 +139,7 @@ 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:
@ -190,6 +202,13 @@ common/views/components/profile-editor.vue:
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"
@ -251,13 +270,6 @@ desktop/views/components/note.vue:
detail: "Detaljer"
desktop/views/components/notes.vue:
retry: "Prøv på nytt"
desktop/views/components/post-form.vue:
submit: "Send"
reply: "Svar"
posting: "Publiserer"
recent-tags: "Nylig"
visibility: "Synlighet"
error: "Feil"
desktop/views/components/post-form-window.vue:
note: "Nytt innlegg"
reply: "Svar"
@ -279,6 +291,7 @@ common/views/components/api-settings.vue:
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:
@ -303,12 +316,6 @@ desktop/views/components/ui.header.post.vue:
post: "Skriv nytt innlegg"
desktop/views/components/ui.header.search.vue:
placeholder: "Søk"
desktop/views/components/received-follow-requests-window.vue:
accept: "Godta"
reject: "Avslå"
desktop/views/components/user-lists-window.vue:
title: "Brukerlister"
list-name: "Liste navn"
desktop/views/components/user-preview.vue:
notes: "Innlegg"
following: "Følger"
@ -324,6 +331,10 @@ admin/views/index.vue:
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"
@ -339,12 +350,16 @@ admin/views/drive.vue:
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"
@ -362,6 +377,7 @@ admin/views/federation.vue:
status: "Status"
states:
all: "Alle"
save: "Lagre"
desktop/views/pages/welcome.vue:
announcements: "Kunngjøringer"
info: "Informasjon"
@ -433,10 +449,6 @@ mobile/views/components/note-sub.vue:
admin: "admin"
bot: "bot"
cat: "katt"
mobile/views/components/post-form.vue:
submit: "Send"
reply: "Svar"
error: "Feil"
mobile/views/components/ui.header.vue:
adjective: "Mr."
mobile/views/components/ui.nav.vue:
@ -445,17 +457,12 @@ mobile/views/components/ui.nav.vue:
user-lists: "Lister"
game: "Spill"
admin: "Admin"
mobile/views/pages/user-lists.vue:
title: "Lister"
mobile/views/pages/home.vue:
home: "Hjem"
local: "Lokalt"
global: "Globalt"
mobile/views/pages/widgets.vue:
add-widget: "Legg til"
mobile/views/pages/received-follow-requests.vue:
accept: "Godta"
reject: "Avslå"
mobile/views/pages/note.vue:
title: "Innlegg"
prev: "Forrige innlegg"
@ -464,6 +471,8 @@ 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"
@ -486,14 +495,34 @@ deck/deck.user-column.vue:
following: "Følger"
followers: "Følgere"
images: "Bilder"
docs:
api:
entities:
properties: "Egenskaper"
endpoints:
params: "Parametere"
res: "Respons"
props:
name: "Navn"
type: "Type"
description: "Beskrivelse"
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"

View File

@ -28,6 +28,18 @@ common:
signin: "Zaloguj się"
signup: "Rejestracja"
signout: "Wyloguj się"
delete-confirm: "Czy na pewno chcesz usunąć ten wpis?"
notification-type: "Typy powiadomień"
notification-types:
all: "Wszyscy"
pollVote: "Głosy"
follow: "Śledzeni"
receiveFollowRequest: "Prośby o śledzenie"
reply: "Odpowiedzi"
quote: "Cytat"
renote: "Udostępnij"
mention: "Wzmianki"
reaction: "Reakcje"
got-it: "Rozumiem!"
customization-tips:
title: "Wskazówki o dostosowywaniu"
@ -54,6 +66,7 @@ common:
month-and-day: "{month}-{day}"
trash: "Kosz"
drive: "Dysk"
pages: "Strony"
messaging: "Rozmowy"
home: "Strona główna"
deck: "Tablice"
@ -63,9 +76,32 @@ common:
followers: "Śledzący"
favorites: "Moje ulubione"
permissions:
'read:drive': "Wyświetl dysk"
"read:drive": "Wyświetl dysk"
"read:messaging": "Zobacz konwersację"
"write:votes": "Zagłosuj"
empty-timeline-info:
explore: "Poznaj"
post-form:
hide-contents: "Ukryj zawartość"
reply-placeholder: "Odpowiedź na ten wpis…"
quote-placeholder: "Zacytuj ten wpis…"
quote-attached: "Z cytatem"
submit: "Wpis"
reply: "Odpowiedz"
renote: "Udostępnij"
posting: "Wysyłanie"
attach-media-from-local: "Załącz zawartość multimedialną z komputera"
attach-media-from-drive: "Załącz zawartość multimedialną z dysku"
create-poll: "Utwórz ankietę"
text-remain: "pozostałe znaki: {}"
recent-tags: "Ostatnie"
visibility: "Widoczność"
error: "Błąd"
enter-username: "Wprowadź nazwę użytkownika"
specified-recipient: "Adresat"
add-visible-user: "Dodaj użytkownika"
username-prompt: "Wprowadź nazwę użytkownika"
enter-file-name: "Wprowadź nazwę pliku"
weekday-short:
sunday: "N"
monday: "Pn"
@ -126,7 +162,9 @@ common:
behavior: "Zachowanie"
fetch-on-scroll: "Automatycznie ładuj po przeciągnięciu w dół"
note-visibility: "Widoczność wpisów"
remember-note-visibility: "Zapamiętaj widoczność wpisów"
web-search-engine: "Wyszukiwarka internetowa"
paste: "Wklej"
line-width: "Szerokości linii"
line-width-thin: "Cienka"
line-width-normal: "Normalna"
@ -155,6 +193,8 @@ common:
version: "Wersja:"
do-update: "Sprawdź dostępność nowych aktualizacji"
navbar-position-left: "Z lewej"
save: "Zapisz"
saved: "Zapisano"
search: "Szukaj"
delete: "Usuń"
loading: "Ładowanie"
@ -163,9 +203,9 @@ common:
update-available-title: "Aktualizacja jest dostępna"
update-available: "Nowa wersja Misskey jest dostępna ({newer}, obecna to {current}). Odśwież stronę, aby zastosować aktualizację."
my-token-regenerated: "Twój token został wygenerowany. Zostaniesz wylogowany."
verified-user: "Zweryfikowane konto"
hide-password: "Ukryj hasło"
show-password: "Pokaż hasło"
enter-username: "Wprowadź nazwę użytkownika"
view-on-remote: "Dla dopełnienia, zobacz to zdalnie."
renoted-by: "{user} udostępnił(a)"
error:
@ -216,7 +256,8 @@ auth/views/index.vue:
error: "Sesja nie istnieje."
sign-in: "Proszę zalogować się."
common/views/pages/explore.vue:
verified-users: "Zweryfikowane konto"
popular-users: "Popularni użytkownicy"
popular-tags: "Popularne tagi"
common/views/components/games/reversi/reversi.vue:
matching:
waiting-for: "Oczekiwanie na {}"
@ -323,18 +364,15 @@ common/views/components/messaging.vue:
search-user: "Znajdź użytkownika"
you: "Ty"
no-history: "Brak historii"
user: "Użytkownicy"
common/views/components/messaging-room.vue:
empty: "Brak konwersacji"
no-history: "Brak dalszej historii"
resize-form: "Przeciągnij aby zmienić rozmiar"
new-message: "Nowa wiadomość"
only-one-file-attached: "Tylko JEDEN plik może zostać dołączony do wiadomości"
common/views/components/messaging-room.form.vue:
input-message-here: "Wprowadź wiadomość tutaj"
send: "Wyślij"
attach-from-local: "Załącz pliki z komputera"
attach-from-drive: "Załącz pliki z dysku"
only-one-file-attached: "Tylko jeden plik może zostać dołączony do wiadomości"
common/views/components/messaging-room.message.vue:
is-read: "Przeczytano"
deleted: "Wiadomość została usunięta"
@ -393,6 +431,8 @@ common/views/components/emoji-picker.vue:
objects: "Rzeczy"
symbols: "Symbole"
flags: "Flagi"
common/views/components/settings/app-type.vue:
info: "Musisz odświeżyć stronę, aby zmiany zostały uwzględnione."
common/views/components/signin.vue:
username: "Nazwa użytkownika"
password: "Hasło"
@ -493,6 +533,7 @@ common/views/components/profile-editor.vue:
saved: "Pomyślnie zaktualizowano profil"
uploading: "Wysyłanie"
upload-failed: "Wysyłanie nie powiodło się"
unable-to-process: "Nie udało się ukończyć działania."
email: "Ustawienia e-mail"
email-address: "Adres e-mail"
email-verified: "Twój adres e-mail został zweryfikowany."
@ -511,6 +552,15 @@ common/views/components/user-list-editor.vue:
remove-user: "Usuń z tej listy"
delete-are-you-sure: "Usunąć listę \"$1\"?"
deleted: "Usunięto"
add-user: "Dodaj użytkownika"
common/views/components/user-group-editor.vue:
deleted: "Usunięto"
invite: "Zaproś"
common/views/components/user-lists.vue:
user-lists: "Listy"
list-name: "Nazwa listy"
common/views/components/user-groups.vue:
invites: "Zaproś"
common/views/widgets/broadcast.vue:
fetching: "Sprawdzanie"
no-broadcasts: "Brak transmisji"
@ -566,6 +616,8 @@ common/views/pages/follow.vue:
request-pending: "Oczekiwanie na pozwolenie"
follow-processing: "Przetwarzanie śledzenia"
follow-request: "Poproś o śledzenie"
common/views/pages/follow-requests.vue:
received-follow-requests: "Prośby o śledzenie"
desktop:
banner: "Baner"
uploading-banner: "Wysyłanie baneru"
@ -576,6 +628,7 @@ desktop:
uploading-avatar: "Wysyłanie awatara"
avatar-updated: "Wysłano awatar"
choose-avatar: "Wybierz awatar"
unable-to-process: "Nie udało się ukończyć działania."
desktop/views/components/activity.chart.vue:
total: "Czarny … Łącznie"
notes: "Niebieski … Wpisy"
@ -634,6 +687,7 @@ desktop/views/components/drive.folder.vue:
rename: "Zmień nazwę"
rename-folder: "Zmień nazwę katalogu"
input-new-folder-name: "Wprowadź nową nazwę"
else-folders: "Inne"
desktop/views/components/drive.vue:
search: "Szukaj"
empty-draghover: "Przeciągnij tutaj!"
@ -692,33 +746,12 @@ desktop/views/components/notes.vue:
desktop/views/components/notifications.vue:
empty: "Brak powiadomień"
desktop/views/components/post-form.vue:
add-visible-user: "+Dodaj użytkownika"
attach-location-information: "Załącz informacje o lokalizacji"
hide-contents: "Ukryj zawartość"
reply-placeholder: "Odpowiedz na ten wpis…"
quote-placeholder: "Zacytuj ten wpis…"
submit: "Wyślij"
reply: "Odpowiedz"
renote: "Udostępnienie"
posted: "Opublikowano!"
replied: "Odpowiedziano!"
reposted: "Udostępniono!"
note-failed: "Nie udało się wysłać"
reply-failed: "Nie udało się odpowiedzieć"
renote-failed: "Nie udało się udostępnić"
posting: "Wysyłanie"
attach-media-from-local: "Załącz zawartość multimedialną z komputera"
attach-media-from-drive: "Załącz zawartość multimedialną z dysku"
insert-a-kao: "v('ω')v"
create-poll: "Utwórz ankietę"
text-remain: "pozostałe znaki: {}"
recent-tags: "Ostatnie"
click-to-tagging: "Naciśnij aby oznaczyć"
visibility: "Widoczność"
geolocation-alert: "Twoje urządzenie nie obsługuje geolokalizacji."
error: "Bład"
enter-username: "Wprowadź nazwę użytkownika…"
annotations: "Treść ostrzeżenia (opcjonalnie)"
desktop/views/components/post-form-window.vue:
note: "Nowy wpis"
reply: "Odpowiedz"
@ -774,6 +807,7 @@ common/views/components/drive-settings.vue:
max: "Max"
in-use: "użyto"
stats: "Statystyki"
default-upload-folder-name: "Katalog(i)"
common/views/components/mute-and-block.vue:
mute-and-block: "Wycisz / Zablokuj"
mute: "Wycisz"
@ -827,14 +861,6 @@ desktop/views/components/ui.header.post.vue:
post: "Utwórz nowy wpis"
desktop/views/components/ui.header.search.vue:
placeholder: "Szukaj"
desktop/views/components/received-follow-requests-window.vue:
title: "Prośby o śledzenie"
accept: "Zatwierdź"
reject: "Odmów"
desktop/views/components/user-lists-window.vue:
title: "Listy"
create-list: "Utwórz listę"
list-name: "Nazwa listy"
desktop/views/components/user-preview.vue:
notes: "Wpisy"
following: "Śledzeni"
@ -855,18 +881,22 @@ admin/views/index.vue:
moderators: "Moderatorzy"
users: "Użytkownicy"
announcements: "Ogłoszenia"
hashtags: "Hashtagi"
admin/views/dashboard.vue:
dashboard: "Kokpit"
accounts: "Konta"
notes: "Wpisy"
drive: "Dysk"
instances: "Instancja"
admin/views/logs.vue:
levels:
info: "Informacje"
error: "Błąd"
admin/views/abuse.vue:
details: "Szczegóły"
remove-report: "Usuń"
admin/views/instance.vue:
instance: "Instancja"
recaptcha-preview: "Pokaż podgląd"
github-integration-client-id: "Client ID"
github-integration-client-secret: "Client Secret"
discord-integration-client-id: "Client ID"
@ -874,8 +904,8 @@ admin/views/instance.vue:
invite: "Zaproś"
save: "Zapisz"
saved: "Zapisano"
user-recommendation-config: "Polecani użytkownicy"
email: "Adres e-mail"
test-email: "Test"
admin/views/charts.vue:
notes: "Wpisy"
users: "Użytkownicy"
@ -897,6 +927,7 @@ admin/views/drive.vue:
unmark-as-sensitive: "Cofnij oznaczenie jako zawartość wrażliwą"
admin/views/users.vue:
user-not-found: "Nie znaleziono użytkownika"
username: "Nazwa użytkownika"
users:
title: "Użytkownicy"
sort:
@ -904,7 +935,6 @@ admin/views/users.vue:
state:
all: "Wszyscy"
moderator: "Moderatorzy"
verified: "Zweryfikowane konto"
origin:
title: "Źródło"
local: "Lokalny"
@ -913,6 +943,9 @@ admin/views/users.vue:
admin/views/moderators.vue:
add-moderator:
add: "Zarejestruj się"
logs:
moderator: "Moderatorzy"
info: "Informacje"
admin/views/emoji.vue:
add-emoji:
name: "Nazwa Emoji"
@ -950,6 +983,8 @@ admin/views/federation.vue:
blocked: "Zablokuj"
chart-srcs:
requests: "Żądania"
blocked-hosts: "Zablokuj"
save: "Zapisz"
desktop/views/pages/welcome.vue:
about: "O Misskey"
timeline: "Oś czasu"
@ -1025,8 +1060,6 @@ mobile/views/components/drive.vue:
file-count: "Plik(i)"
nothing-in-drive: "Pusto"
folder-is-empty: "Ten katalog jest pusty"
prompt: "Co chcesz zrobić? (wprowadź odpowiednią cyfrę): <1 → Wysłać plik | 2 → Wysłać plik z adresu URL | 3 → Utworzyć katalog | 4 → Zmienić nazwę tego katalogu | 5 → Przenieść ten katalog | 6 → Usunąć ten katalog>"
deletion-alert: "Przepraszamy. Usuwanie katalogów nie zostało jeszcze zaimplementowane."
folder-name: "Nazwa katalogu"
url-prompt: "Adres URL pliku, który chcesz wysłać"
uploading: "Rozpoczęto wysyłanie. Może to trochę potrwać."
@ -1074,17 +1107,6 @@ mobile/views/components/note-sub.vue:
cat: "kot"
mobile/views/components/notifications.vue:
empty: "Brak powiadomień"
mobile/views/components/post-form.vue:
add-visible-user: "Dodaj użytkownika"
submit: "Wyślij"
reply: "Odpowiedz"
renote: "Udostępnij"
quote-placeholder: "Zacytuj ten wpis… (nieobowiązkowe)"
reply-placeholder: "Odpowiedź na ten wpis…"
cw-placeholder: "Treść ostrzeżenia (opcjonalnie)"
location-alert: "Twoje urządzenie nie pozwala na przekazywanie informacji o lokalizacji"
error: "Błąd"
username-prompt: "Wprowadź nazwę użytkownika"
mobile/views/components/sub-note-content.vue:
private: "ten wpis jest prywatny"
deleted: "ten wpis został usunięty"
@ -1102,9 +1124,10 @@ mobile/views/components/ui.nav.vue:
game: "Gry"
admin: "Admin"
about: "O Misskey"
mobile/views/pages/user-lists.vue:
title: "Listy"
enter-list-name: "Wprowadź nazwę listy"
mobile/views/pages/drive.vue:
contextmenu:
upload: "Wyślij plik"
create-folder: "Utwórz katalog"
mobile/views/pages/signup.vue:
lets-start: "Rozpocznijmy! 📦"
mobile/views/pages/home.vue:
@ -1119,10 +1142,6 @@ mobile/views/pages/widgets.vue:
customization-tips: "Wskazówki o dostosowywaniu"
mobile/views/pages/widgets/activity.vue:
activity: "Aktywność"
mobile/views/pages/received-follow-requests.vue:
title: "Prośby o śledzenie"
accept: "Zatwierdź"
reject: "Odmów"
mobile/views/pages/note.vue:
title: "Wpis"
prev: "Poprzedni wpis"
@ -1133,6 +1152,8 @@ mobile/views/pages/search.vue:
search: "Szukaj"
mobile/views/pages/selectdrive.vue:
select-file: "Wybierz plik"
mobile/views/pages/notifications.vue:
notifications: "Powiadomienia"
mobile/views/pages/settings.vue:
signed-in-as: "Zalogowany jako {}"
mobile/views/pages/user.vue:
@ -1188,23 +1209,6 @@ deck/deck.user-column.vue:
docs:
edit-this-page-on-github: "Znalazłeś błąd lub chcesz pomóc w tworzeniu dokumentacji?"
edit-this-page-on-github-link: "Edytuj stronę na GitHubie!"
api:
entities:
properties: "Właściwości"
endpoints:
params: "Parametry"
no-params: "Brak parametrów."
res: "Odpowiedź"
require-credential: "Punkt końcowy wymaga informacji o uwierzytelnieniu."
require-permission: "Ten punkt końcowy wymaga uprawnienia {permission}."
has-limit: "Istnieje limit częstotliwości."
min-interval-limit: "Nie możesz wykonać żądania przed upłynięciem {interval} od ostatniego żądania."
show-src: "Możesz zobaczyć kod źródłowy tego punktu końcowego."
show-src-link: "Zobacz kod na GitHubie"
props:
name: "Nazwa"
type: "Rodzaj"
description: "Opis"
dev/views/index.vue:
manage-apps: "Zarządzaj aplikacjami"
dev/views/apps.vue:
@ -1213,3 +1217,52 @@ dev/views/apps.vue:
dev/views/new-app.vue:
app-name: "Nazwa Aplikacji"
authority: "Uprawnienia"
pages:
pin-this-page: "Przypnij do profilu"
unpin-this-page: "Odepnij"
like: "Lubię"
title: "Tytuł"
blocks:
image: "Zdjęcia"
post: "Formularz tworzenia"
_textInput:
text: "Tytuł"
_textareaInput:
text: "Tytuł"
_numberInput:
text: "Tytuł"
_switch:
text: "Tytuł"
_counter:
text: "Tytuł"
_button:
text: "Tytuł"
_radioButton:
title: "Tytuł"
script:
categories:
random: "Losowy"
list: "Listy"
blocks:
_join:
arg1: "Listy"
random: "Losowy"
_randomPick:
arg1: "Listy"
_dailyRandomPick:
arg1: "Listy"
_seedRandomPick:
arg2: "Listy"
_pick:
arg1: "Listy"
_listLen:
arg1: "Listy"
types:
array: "Listy"
room:
translate: "Przenieś"
save: "Zapisz"
saved: "Zapisano"
furnitures:
moon: "Księżyc"
bin: "Kosz"

View File

@ -18,6 +18,8 @@ common:
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"
@ -45,6 +47,9 @@ common:
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"
@ -89,7 +94,7 @@ common:
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."
verified-user: "Conta verificada"
enter-username: "Digite o nome de usuário."
reversi:
drawn: "Empatado"
my-turn: "Seu turno"
@ -129,8 +134,6 @@ auth/views/index.vue:
please-go-back: "Por favor, volte ao aplicativo."
error: "A sessão não existe."
sign-in: "Por favor, entre."
common/views/pages/explore.vue:
verified-users: "Conta verificada"
common/views/components/games/reversi/reversi.index.vue:
invite: "Convidar"
rule: "Como jogar"
@ -163,6 +166,10 @@ 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:
@ -194,10 +201,6 @@ admin/views/instance.vue:
invite: "Convidar"
admin/views/drive.vue:
delete: "Apagar"
admin/views/users.vue:
users:
state:
verified: "Conta verificada"
admin/views/emoji.vue:
emojis:
remove: "Apagar"
@ -274,18 +277,14 @@ deck/deck.user-column.vue:
timeline: "Linha do tempo"
docs:
edit-this-page-on-github-link: "Edite esta página no GitHub!"
api:
entities:
properties: "Propriedades"
endpoints:
params: "Parâmetros"
no-params: "Sem parâmetros"
res: "Resposta"
show-src-link: "Veja o código no GitHub"
generated: "Este documento foi gerado pelas definições da API."
props:
name: "Nome"
type: "Tipo"
description: "Descrição"
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"

View File

@ -26,6 +26,14 @@ common:
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: "Понятно!"
@ -51,7 +59,14 @@ common:
month-and-day: "{day}.{month}"
trash: "Мусорное ведро"
drive: "Drive"
pages: "Страницы"
messaging: "Чат"
timeline: "Лента"
followers: "Подписчики"
favorites: "Избранное"
post-form:
reply: "Ответить"
create-poll: "Создать опрос"
weekday-short:
sunday: "Вс"
monday: "Пн"
@ -146,3 +161,14 @@ 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: "Мусорное ведро"

File diff suppressed because it is too large Load Diff

View File

@ -86,3 +86,8 @@ admin/views/dashboard.vue:
drive: "雲端硬碟"
admin/views/charts.vue:
drive: "雲端硬碟"
pages:
like: "贊"
room:
furnitures:
moon: "月"

View File

@ -0,0 +1,485 @@
import {MigrationInterface, QueryRunner} from "typeorm";
export class Init1000000000000 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`CREATE TYPE "log_level_enum" AS ENUM('error', 'warning', 'info', 'success', 'debug')`);
await queryRunner.query(`CREATE TABLE "log" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "domain" character varying(64) array NOT NULL DEFAULT '{}'::varchar[], "level" "log_level_enum" NOT NULL, "worker" character varying(8) NOT NULL, "machine" character varying(128) NOT NULL, "message" character varying(1024) NOT NULL, "data" jsonb NOT NULL DEFAULT '{}', CONSTRAINT "PK_350604cbdf991d5930d9e618fbd" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE INDEX "IDX_8e4eb51a35d81b64dda28eed0a" ON "log" ("createdAt") `);
await queryRunner.query(`CREATE INDEX "IDX_8cb40cfc8f3c28261e6f887b03" ON "log" ("domain") `);
await queryRunner.query(`CREATE INDEX "IDX_584b536b49e53ac81beb39a177" ON "log" ("level") `);
await queryRunner.query(`CREATE TABLE "drive_folder" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "name" character varying(128) NOT NULL, "userId" character varying(32), "parentId" character varying(32), CONSTRAINT "PK_7a0c089191f5ebdc214e0af808a" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE INDEX "IDX_02878d441ceae15ce060b73daf" ON "drive_folder" ("createdAt") `);
await queryRunner.query(`CREATE INDEX "IDX_f4fc06e49c0171c85f1c48060d" ON "drive_folder" ("userId") `);
await queryRunner.query(`CREATE INDEX "IDX_00ceffb0cdc238b3233294f08f" ON "drive_folder" ("parentId") `);
await queryRunner.query(`CREATE TABLE "drive_file" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32), "userHost" character varying(128), "md5" character varying(32) NOT NULL, "name" character varying(256) NOT NULL, "type" character varying(128) NOT NULL, "size" integer NOT NULL, "comment" character varying(512), "properties" jsonb NOT NULL DEFAULT '{}', "storedInternal" boolean NOT NULL, "url" character varying(512) NOT NULL, "thumbnailUrl" character varying(512), "webpublicUrl" character varying(512), "accessKey" character varying(256), "thumbnailAccessKey" character varying(256), "webpublicAccessKey" character varying(256), "uri" character varying(512), "src" character varying(512), "folderId" character varying(32), "isSensitive" boolean NOT NULL DEFAULT false, "isLink" boolean NOT NULL DEFAULT false, CONSTRAINT "PK_43ddaaaf18c9e68029b7cbb032e" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE INDEX "IDX_c8dfad3b72196dd1d6b5db168a" ON "drive_file" ("createdAt") `);
await queryRunner.query(`CREATE INDEX "IDX_860fa6f6c7df5bb887249fba22" ON "drive_file" ("userId") `);
await queryRunner.query(`CREATE INDEX "IDX_92779627994ac79277f070c91e" ON "drive_file" ("userHost") `);
await queryRunner.query(`CREATE INDEX "IDX_37bb9a1b4585f8a3beb24c62d6" ON "drive_file" ("md5") `);
await queryRunner.query(`CREATE INDEX "IDX_a40b8df8c989d7db937ea27cf6" ON "drive_file" ("type") `);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_d85a184c2540d2deba33daf642" ON "drive_file" ("accessKey") `);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_e74022ce9a074b3866f70e0d27" ON "drive_file" ("thumbnailAccessKey") `);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_c55b2b7c284d9fef98026fc88e" ON "drive_file" ("webpublicAccessKey") `);
await queryRunner.query(`CREATE INDEX "IDX_e5848eac4940934e23dbc17581" ON "drive_file" ("uri") `);
await queryRunner.query(`CREATE INDEX "IDX_bb90d1956dafc4068c28aa7560" ON "drive_file" ("folderId") `);
await queryRunner.query(`CREATE TABLE "user" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "updatedAt" TIMESTAMP WITH TIME ZONE, "lastFetchedAt" TIMESTAMP WITH TIME ZONE, "username" character varying(128) NOT NULL, "usernameLower" character varying(128) NOT NULL, "name" character varying(128), "followersCount" integer NOT NULL DEFAULT 0, "followingCount" integer NOT NULL DEFAULT 0, "notesCount" integer NOT NULL DEFAULT 0, "avatarId" character varying(32), "bannerId" character varying(32), "tags" character varying(128) array NOT NULL DEFAULT '{}'::varchar[], "avatarUrl" character varying(512), "bannerUrl" character varying(512), "avatarColor" character varying(32), "bannerColor" character varying(32), "isSuspended" boolean NOT NULL DEFAULT false, "isSilenced" boolean NOT NULL DEFAULT false, "isLocked" boolean NOT NULL DEFAULT false, "isBot" boolean NOT NULL DEFAULT false, "isCat" boolean NOT NULL DEFAULT false, "isAdmin" boolean NOT NULL DEFAULT false, "isModerator" boolean NOT NULL DEFAULT false, "isVerified" boolean NOT NULL DEFAULT false, "emojis" character varying(128) array NOT NULL DEFAULT '{}'::varchar[], "host" character varying(128), "inbox" character varying(512), "sharedInbox" character varying(512), "featured" character varying(512), "uri" character varying(512), "token" character(16), CONSTRAINT "UQ_a854e557b1b14814750c7c7b0c9" UNIQUE ("token"), CONSTRAINT "REL_58f5c71eaab331645112cf8cfa" UNIQUE ("avatarId"), CONSTRAINT "REL_afc64b53f8db3707ceb34eb28e" UNIQUE ("bannerId"), CONSTRAINT "PK_cace4a159ff9f2512dd42373760" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE INDEX "IDX_e11e649824a45d8ed01d597fd9" ON "user" ("createdAt") `);
await queryRunner.query(`CREATE INDEX "IDX_80ca6e6ef65fb9ef34ea8c90f4" ON "user" ("updatedAt") `);
await queryRunner.query(`CREATE INDEX "IDX_a27b942a0d6dcff90e3ee9b5e8" ON "user" ("usernameLower") `);
await queryRunner.query(`CREATE INDEX "IDX_fa99d777623947a5b05f394cae" ON "user" ("tags") `);
await queryRunner.query(`CREATE INDEX "IDX_3252a5df8d5bbd16b281f7799e" ON "user" ("host") `);
await queryRunner.query(`CREATE INDEX "IDX_be623adaa4c566baf5d29ce0c8" ON "user" ("uri") `);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_a854e557b1b14814750c7c7b0c" ON "user" ("token") `);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_5deb01ae162d1d70b80d064c27" ON "user" ("usernameLower", "host") `);
await queryRunner.query(`CREATE TABLE "app" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32), "secret" character varying(64) NOT NULL, "name" character varying(128) NOT NULL, "description" character varying(512) NOT NULL, "permission" character varying(64) array NOT NULL, "callbackUrl" character varying(512), CONSTRAINT "PK_9478629fc093d229df09e560aea" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE INDEX "IDX_048a757923ed8b157e9895da53" ON "app" ("createdAt") `);
await queryRunner.query(`CREATE INDEX "IDX_3f5b0899ef90527a3462d7c2cb" ON "app" ("userId") `);
await queryRunner.query(`CREATE INDEX "IDX_f49922d511d666848f250663c4" ON "app" ("secret") `);
await queryRunner.query(`CREATE TABLE "access_token" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "token" character varying(128) NOT NULL, "hash" character varying(128) NOT NULL, "userId" character varying(32) NOT NULL, "appId" character varying(32) NOT NULL, CONSTRAINT "PK_f20f028607b2603deabd8182d12" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE INDEX "IDX_70ba8f6af34bc924fc9e12adb8" ON "access_token" ("token") `);
await queryRunner.query(`CREATE INDEX "IDX_64c327441248bae40f7d92f34f" ON "access_token" ("hash") `);
await queryRunner.query(`CREATE INDEX "IDX_9949557d0e1b2c19e5344c171e" ON "access_token" ("userId") `);
await queryRunner.query(`CREATE TYPE "note_visibility_enum" AS ENUM('public', 'home', 'followers', 'specified')`);
await queryRunner.query(`CREATE TABLE "note" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "replyId" character varying(32), "renoteId" character varying(32), "text" text, "name" character varying(256), "cw" character varying(512), "appId" character varying(32), "userId" character varying(32) NOT NULL, "viaMobile" boolean NOT NULL DEFAULT false, "localOnly" boolean NOT NULL DEFAULT false, "renoteCount" smallint NOT NULL DEFAULT 0, "repliesCount" smallint NOT NULL DEFAULT 0, "reactions" jsonb NOT NULL DEFAULT '{}', "visibility" "note_visibility_enum" NOT NULL, "uri" character varying(512), "score" integer NOT NULL DEFAULT 0, "fileIds" character varying(32) array NOT NULL DEFAULT '{}'::varchar[], "attachedFileTypes" character varying(256) array NOT NULL DEFAULT '{}'::varchar[], "visibleUserIds" character varying(32) array NOT NULL DEFAULT '{}'::varchar[], "mentions" character varying(32) array NOT NULL DEFAULT '{}'::varchar[], "mentionedRemoteUsers" text NOT NULL DEFAULT '[]', "emojis" character varying(128) array NOT NULL DEFAULT '{}'::varchar[], "tags" character varying(128) array NOT NULL DEFAULT '{}'::varchar[], "hasPoll" boolean NOT NULL DEFAULT false, "geo" jsonb DEFAULT null, "userHost" character varying(128), "replyUserId" character varying(32), "replyUserHost" character varying(128), "renoteUserId" character varying(32), "renoteUserHost" character varying(128), CONSTRAINT "PK_96d0c172a4fba276b1bbed43058" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE INDEX "IDX_e7c0567f5261063592f022e9b5" ON "note" ("createdAt") `);
await queryRunner.query(`CREATE INDEX "IDX_17cb3553c700a4985dff5a30ff" ON "note" ("replyId") `);
await queryRunner.query(`CREATE INDEX "IDX_52ccc804d7c69037d558bac4c9" ON "note" ("renoteId") `);
await queryRunner.query(`CREATE INDEX "IDX_5b87d9d19127bd5d92026017a7" ON "note" ("userId") `);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_153536c67d05e9adb24e99fc2b" ON "note" ("uri") `);
await queryRunner.query(`CREATE INDEX "IDX_51c063b6a133a9cb87145450f5" ON "note" ("fileIds") `);
await queryRunner.query(`CREATE INDEX "IDX_25dfc71b0369b003a4cd434d0b" ON "note" ("attachedFileTypes") `);
await queryRunner.query(`CREATE INDEX "IDX_796a8c03959361f97dc2be1d5c" ON "note" ("visibleUserIds") `);
await queryRunner.query(`CREATE INDEX "IDX_54ebcb6d27222913b908d56fd8" ON "note" ("mentions") `);
await queryRunner.query(`CREATE INDEX "IDX_88937d94d7443d9a99a76fa5c0" ON "note" ("tags") `);
await queryRunner.query(`CREATE INDEX "IDX_7125a826ab192eb27e11d358a5" ON "note" ("userHost") `);
await queryRunner.query(`CREATE TABLE "poll_vote" ("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, "choice" integer NOT NULL, CONSTRAINT "PK_fd002d371201c472490ba89c6a0" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE INDEX "IDX_0fb627e1c2f753262a74f0562d" ON "poll_vote" ("createdAt") `);
await queryRunner.query(`CREATE INDEX "IDX_66d2bd2ee31d14bcc23069a89f" ON "poll_vote" ("userId") `);
await queryRunner.query(`CREATE INDEX "IDX_aecfbd5ef60374918e63ee95fa" ON "poll_vote" ("noteId") `);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_50bd7164c5b78f1f4a42c4d21f" ON "poll_vote" ("userId", "noteId", "choice") `);
await queryRunner.query(`CREATE TABLE "note_reaction" ("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, "reaction" character varying(128) NOT NULL, CONSTRAINT "PK_767ec729b108799b587a3fcc9cf" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE INDEX "IDX_01f4581f114e0ebd2bbb876f0b" ON "note_reaction" ("createdAt") `);
await queryRunner.query(`CREATE INDEX "IDX_13761f64257f40c5636d0ff95e" ON "note_reaction" ("userId") `);
await queryRunner.query(`CREATE INDEX "IDX_45145e4953780f3cd5656f0ea6" ON "note_reaction" ("noteId") `);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_ad0c221b25672daf2df320a817" ON "note_reaction" ("userId", "noteId") `);
await queryRunner.query(`CREATE TABLE "note_watching" ("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, "noteUserId" character varying(32) NOT NULL, CONSTRAINT "PK_49286fdb23725945a74aa27d757" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE INDEX "IDX_318cdf42a9cfc11f479bd802bb" ON "note_watching" ("createdAt") `);
await queryRunner.query(`CREATE INDEX "IDX_b0134ec406e8d09a540f818288" ON "note_watching" ("userId") `);
await queryRunner.query(`CREATE INDEX "IDX_03e7028ab8388a3f5e3ce2a861" ON "note_watching" ("noteId") `);
await queryRunner.query(`CREATE INDEX "IDX_44499765eec6b5489d72c4253b" ON "note_watching" ("noteUserId") `);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_a42c93c69989ce1d09959df4cf" ON "note_watching" ("userId", "noteId") `);
await queryRunner.query(`CREATE TABLE "note_unread" ("id" character varying(32) NOT NULL, "userId" character varying(32) NOT NULL, "noteId" character varying(32) NOT NULL, "noteUserId" character varying(32) NOT NULL, "isSpecified" boolean NOT NULL, CONSTRAINT "PK_1904eda61a784f57e6e51fa9c1f" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE INDEX "IDX_56b0166d34ddae49d8ef7610bb" ON "note_unread" ("userId") `);
await queryRunner.query(`CREATE INDEX "IDX_e637cba4dc4410218c4251260e" ON "note_unread" ("noteId") `);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_d908433a4953cc13216cd9c274" ON "note_unread" ("userId", "noteId") `);
await queryRunner.query(`CREATE TABLE "notification" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "notifieeId" character varying(32) NOT NULL, "notifierId" character varying(32) NOT NULL, "type" character varying(32) NOT NULL, "isRead" boolean NOT NULL DEFAULT false, "noteId" character varying(32), "reaction" character varying(128), "choice" integer, CONSTRAINT "PK_705b6c7cdf9b2c2ff7ac7872cb7" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE INDEX "IDX_b11a5e627c41d4dc3170f1d370" ON "notification" ("createdAt") `);
await queryRunner.query(`CREATE INDEX "IDX_3c601b70a1066d2c8b517094cb" ON "notification" ("notifieeId") `);
await queryRunner.query(`CREATE TABLE "meta" ("id" character varying(32) NOT NULL, "name" character varying(128), "description" character varying(1024), "maintainerName" character varying(128), "maintainerEmail" character varying(128), "announcements" jsonb NOT NULL DEFAULT '[]', "disableRegistration" boolean NOT NULL DEFAULT false, "disableLocalTimeline" boolean NOT NULL DEFAULT false, "disableGlobalTimeline" boolean NOT NULL DEFAULT false, "enableEmojiReaction" boolean NOT NULL DEFAULT true, "useStarForReactionFallback" boolean NOT NULL DEFAULT false, "langs" character varying(64) array NOT NULL DEFAULT '{}'::varchar[], "hiddenTags" character varying(256) array NOT NULL DEFAULT '{}'::varchar[], "blockedHosts" character varying(256) array NOT NULL DEFAULT '{}'::varchar[], "mascotImageUrl" character varying(512) DEFAULT '/assets/ai.png', "bannerUrl" character varying(512), "errorImageUrl" character varying(512) DEFAULT 'https://xn--931a.moe/aiart/yubitun.png', "iconUrl" character varying(512), "cacheRemoteFiles" boolean NOT NULL DEFAULT true, "proxyAccount" character varying(128), "enableRecaptcha" boolean NOT NULL DEFAULT false, "recaptchaSiteKey" character varying(64), "recaptchaSecretKey" character varying(64), "localDriveCapacityMb" integer NOT NULL DEFAULT 1024, "remoteDriveCapacityMb" integer NOT NULL DEFAULT 32, "maxNoteTextLength" integer NOT NULL DEFAULT 500, "summalyProxy" character varying(128), "enableEmail" boolean NOT NULL DEFAULT false, "email" character varying(128), "smtpSecure" boolean NOT NULL DEFAULT false, "smtpHost" character varying(128), "smtpPort" integer, "smtpUser" character varying(128), "smtpPass" character varying(128), "enableServiceWorker" boolean NOT NULL DEFAULT false, "swPublicKey" character varying(128), "swPrivateKey" character varying(128), "enableTwitterIntegration" boolean NOT NULL DEFAULT false, "twitterConsumerKey" character varying(128), "twitterConsumerSecret" character varying(128), "enableGithubIntegration" boolean NOT NULL DEFAULT false, "githubClientId" character varying(128), "githubClientSecret" character varying(128), "enableDiscordIntegration" boolean NOT NULL DEFAULT false, "discordClientId" character varying(128), "discordClientSecret" character varying(128), CONSTRAINT "PK_c4c17a6c2bd7651338b60fc590b" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE TABLE "following" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "followeeId" character varying(32) NOT NULL, "followerId" character varying(32) NOT NULL, "followerHost" character varying(128), "followerInbox" character varying(512), "followerSharedInbox" character varying(512), "followeeHost" character varying(128), "followeeInbox" character varying(512), "followeeSharedInbox" character varying(512), CONSTRAINT "PK_c76c6e044bdf76ecf8bfb82a645" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE INDEX "IDX_582f8fab771a9040a12961f3e7" ON "following" ("createdAt") `);
await queryRunner.query(`CREATE INDEX "IDX_24e0042143a18157b234df186c" ON "following" ("followeeId") `);
await queryRunner.query(`CREATE INDEX "IDX_6516c5a6f3c015b4eed39978be" ON "following" ("followerId") `);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_307be5f1d1252e0388662acb96" ON "following" ("followerId", "followeeId") `);
await queryRunner.query(`CREATE TABLE "instance" ("id" character varying(32) NOT NULL, "caughtAt" TIMESTAMP WITH TIME ZONE NOT NULL, "host" character varying(128) NOT NULL, "system" character varying(64), "usersCount" integer NOT NULL DEFAULT 0, "notesCount" integer NOT NULL DEFAULT 0, "followingCount" integer NOT NULL DEFAULT 0, "followersCount" integer NOT NULL DEFAULT 0, "driveUsage" integer NOT NULL DEFAULT 0, "driveFiles" integer NOT NULL DEFAULT 0, "latestRequestSentAt" TIMESTAMP WITH TIME ZONE, "latestStatus" integer, "latestRequestReceivedAt" TIMESTAMP WITH TIME ZONE, "lastCommunicatedAt" TIMESTAMP WITH TIME ZONE NOT NULL, "isNotResponding" boolean NOT NULL DEFAULT false, "isMarkedAsClosed" boolean NOT NULL DEFAULT false, CONSTRAINT "PK_eaf60e4a0c399c9935413e06474" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE INDEX "IDX_2cd3b2a6b4cf0b910b260afe08" ON "instance" ("caughtAt") `);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_8d5afc98982185799b160e10eb" ON "instance" ("host") `);
await queryRunner.query(`CREATE TABLE "muting" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "muteeId" character varying(32) NOT NULL, "muterId" character varying(32) NOT NULL, CONSTRAINT "PK_2e92d06c8b5c602eeb27ca9ba48" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE INDEX "IDX_f86d57fbca33c7a4e6897490cc" ON "muting" ("createdAt") `);
await queryRunner.query(`CREATE INDEX "IDX_ec96b4fed9dae517e0dbbe0675" ON "muting" ("muteeId") `);
await queryRunner.query(`CREATE INDEX "IDX_93060675b4a79a577f31d260c6" ON "muting" ("muterId") `);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_1eb9d9824a630321a29fd3b290" ON "muting" ("muterId", "muteeId") `);
await queryRunner.query(`CREATE TABLE "sw_subscription" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "endpoint" character varying(512) NOT NULL, "auth" character varying(256) NOT NULL, "publickey" character varying(128) NOT NULL, CONSTRAINT "PK_e8f763631530051b95eb6279b91" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE INDEX "IDX_97754ca6f2baff9b4abb7f853d" ON "sw_subscription" ("userId") `);
await queryRunner.query(`CREATE TABLE "blocking" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "blockeeId" character varying(32) NOT NULL, "blockerId" character varying(32) NOT NULL, CONSTRAINT "PK_e5d9a541cc1965ee7e048ea09dd" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE INDEX "IDX_b9a354f7941c1e779f3b33aea6" ON "blocking" ("createdAt") `);
await queryRunner.query(`CREATE INDEX "IDX_2cd4a2743a99671308f5417759" ON "blocking" ("blockeeId") `);
await queryRunner.query(`CREATE INDEX "IDX_0627125f1a8a42c9a1929edb55" ON "blocking" ("blockerId") `);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_98a1bc5cb30dfd159de056549f" ON "blocking" ("blockerId", "blockeeId") `);
await queryRunner.query(`CREATE TABLE "user_list" ("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, CONSTRAINT "PK_87bab75775fd9b1ff822b656402" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE INDEX "IDX_b7fcefbdd1c18dce86687531f9" ON "user_list" ("userId") `);
await queryRunner.query(`CREATE TABLE "user_list_joining" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "userListId" character varying(32) NOT NULL, CONSTRAINT "PK_11abb3768da1c5f8de101c9df45" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE INDEX "IDX_d844bfc6f3f523a05189076efa" ON "user_list_joining" ("userId") `);
await queryRunner.query(`CREATE INDEX "IDX_605472305f26818cc93d1baaa7" ON "user_list_joining" ("userListId") `);
await queryRunner.query(`CREATE TABLE "hashtag" ("id" character varying(32) NOT NULL, "name" character varying(128) NOT NULL, "mentionedUserIds" character varying(32) array NOT NULL, "mentionedUsersCount" integer NOT NULL DEFAULT 0, "mentionedLocalUserIds" character varying(32) array NOT NULL, "mentionedLocalUsersCount" integer NOT NULL DEFAULT 0, "mentionedRemoteUserIds" character varying(32) array NOT NULL, "mentionedRemoteUsersCount" integer NOT NULL DEFAULT 0, "attachedUserIds" character varying(32) array NOT NULL, "attachedUsersCount" integer NOT NULL DEFAULT 0, "attachedLocalUserIds" character varying(32) array NOT NULL, "attachedLocalUsersCount" integer NOT NULL DEFAULT 0, "attachedRemoteUserIds" character varying(32) array NOT NULL, "attachedRemoteUsersCount" integer NOT NULL DEFAULT 0, CONSTRAINT "PK_cb36eb8af8412bfa978f1165d78" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_347fec870eafea7b26c8a73bac" ON "hashtag" ("name") `);
await queryRunner.query(`CREATE INDEX "IDX_2710a55f826ee236ea1a62698f" ON "hashtag" ("mentionedUsersCount") `);
await queryRunner.query(`CREATE INDEX "IDX_0e206cec573f1edff4a3062923" ON "hashtag" ("mentionedLocalUsersCount") `);
await queryRunner.query(`CREATE INDEX "IDX_4c02d38a976c3ae132228c6fce" ON "hashtag" ("mentionedRemoteUsersCount") `);
await queryRunner.query(`CREATE INDEX "IDX_d57f9030cd3af7f63ffb1c267c" ON "hashtag" ("attachedUsersCount") `);
await queryRunner.query(`CREATE INDEX "IDX_0c44bf4f680964145f2a68a341" ON "hashtag" ("attachedLocalUsersCount") `);
await queryRunner.query(`CREATE INDEX "IDX_0b03cbcd7e6a7ce068efa8ecc2" ON "hashtag" ("attachedRemoteUsersCount") `);
await queryRunner.query(`CREATE TABLE "note_favorite" ("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_af0da35a60b9fa4463a62082b36" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE INDEX "IDX_47f4b1892f5d6ba8efb3057d81" ON "note_favorite" ("userId") `);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_0f4fb9ad355f3effff221ef245" ON "note_favorite" ("userId", "noteId") `);
await queryRunner.query(`CREATE TABLE "abuse_user_report" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "reporterId" character varying(32) NOT NULL, "comment" character varying(512) NOT NULL, CONSTRAINT "PK_87873f5f5cc5c321a1306b2d18c" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE INDEX "IDX_db2098070b2b5a523c58181f74" ON "abuse_user_report" ("createdAt") `);
await queryRunner.query(`CREATE INDEX "IDX_d049123c413e68ca52abe73420" ON "abuse_user_report" ("userId") `);
await queryRunner.query(`CREATE INDEX "IDX_04cc96756f89d0b7f9473e8cdf" ON "abuse_user_report" ("reporterId") `);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_5cd442c3b2e74fdd99dae20243" ON "abuse_user_report" ("userId", "reporterId") `);
await queryRunner.query(`CREATE TABLE "registration_ticket" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "code" character varying(64) NOT NULL, CONSTRAINT "PK_f11696b6fafcf3662d4292734f8" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_0ff69e8dfa9fe31bb4a4660f59" ON "registration_ticket" ("code") `);
await queryRunner.query(`CREATE TABLE "messaging_message" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "recipientId" character varying(32) NOT NULL, "text" character varying(4096), "isRead" boolean NOT NULL DEFAULT false, "fileId" character varying(32), CONSTRAINT "PK_db398fd79dc95d0eb8c30456eaa" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE INDEX "IDX_e21cd3646e52ef9c94aaf17c2e" ON "messaging_message" ("createdAt") `);
await queryRunner.query(`CREATE INDEX "IDX_5377c307783fce2b6d352e1203" ON "messaging_message" ("userId") `);
await queryRunner.query(`CREATE INDEX "IDX_cac14a4e3944454a5ce7daa514" ON "messaging_message" ("recipientId") `);
await queryRunner.query(`CREATE TABLE "signin" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "ip" character varying(128) NOT NULL, "headers" jsonb NOT NULL, "success" boolean NOT NULL, CONSTRAINT "PK_9e96ddc025712616fc492b3b588" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE INDEX "IDX_2c308dbdc50d94dc625670055f" ON "signin" ("userId") `);
await queryRunner.query(`CREATE TABLE "auth_session" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "token" character varying(128) NOT NULL, "userId" character varying(32), "appId" character varying(32) NOT NULL, CONSTRAINT "PK_19354ed146424a728c1112a8cbf" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE INDEX "IDX_62cb09e1129f6ec024ef66e183" ON "auth_session" ("token") `);
await queryRunner.query(`CREATE TABLE "follow_request" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "followeeId" character varying(32) NOT NULL, "followerId" character varying(32) NOT NULL, "requestId" character varying(128), "followerHost" character varying(128), "followerInbox" character varying(512), "followerSharedInbox" character varying(512), "followeeHost" character varying(128), "followeeInbox" character varying(512), "followeeSharedInbox" character varying(512), CONSTRAINT "PK_53a9aa3725f7a3deb150b39dbfc" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE INDEX "IDX_12c01c0d1a79f77d9f6c15fadd" ON "follow_request" ("followeeId") `);
await queryRunner.query(`CREATE INDEX "IDX_a7fd92dd6dc519e6fb435dd108" ON "follow_request" ("followerId") `);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_d54a512b822fac7ed52800f6b4" ON "follow_request" ("followerId", "followeeId") `);
await queryRunner.query(`CREATE TABLE "emoji" ("id" character varying(32) NOT NULL, "updatedAt" TIMESTAMP WITH TIME ZONE, "name" character varying(128) NOT NULL, "host" character varying(128), "url" character varying(512) NOT NULL, "uri" character varying(512), "type" character varying(64), "aliases" character varying(128) array NOT NULL DEFAULT '{}'::varchar[], CONSTRAINT "PK_df74ce05e24999ee01ea0bc50a3" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE INDEX "IDX_b37dafc86e9af007e3295c2781" ON "emoji" ("name") `);
await queryRunner.query(`CREATE INDEX "IDX_5900e907bb46516ddf2871327c" ON "emoji" ("host") `);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_4f4d35e1256c84ae3d1f0eab10" ON "emoji" ("name", "host") `);
await queryRunner.query(`CREATE TABLE "reversi_game" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "startedAt" TIMESTAMP WITH TIME ZONE, "user1Id" character varying(32) NOT NULL, "user2Id" character varying(32) NOT NULL, "user1Accepted" boolean NOT NULL DEFAULT false, "user2Accepted" boolean NOT NULL DEFAULT false, "black" integer, "isStarted" boolean NOT NULL DEFAULT false, "isEnded" boolean NOT NULL DEFAULT false, "winnerId" character varying(32), "surrendered" character varying(32), "logs" jsonb NOT NULL DEFAULT '[]', "map" character varying(64) array NOT NULL, "bw" character varying(32) NOT NULL, "isLlotheo" boolean NOT NULL DEFAULT false, "canPutEverywhere" boolean NOT NULL DEFAULT false, "loopedBoard" boolean NOT NULL DEFAULT false, "form1" jsonb DEFAULT null, "form2" jsonb DEFAULT null, "crc32" character varying(32), CONSTRAINT "PK_76b30eeba71b1193ad7c5311c3f" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE INDEX "IDX_b46ec40746efceac604142be1c" ON "reversi_game" ("createdAt") `);
await queryRunner.query(`CREATE TABLE "reversi_matching" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "parentId" character varying(32) NOT NULL, "childId" character varying(32) NOT NULL, CONSTRAINT "PK_880bd0afbab232f21c8b9d146cf" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE INDEX "IDX_b604d92d6c7aec38627f6eaf16" ON "reversi_matching" ("createdAt") `);
await queryRunner.query(`CREATE INDEX "IDX_3b25402709dd9882048c2bbade" ON "reversi_matching" ("parentId") `);
await queryRunner.query(`CREATE INDEX "IDX_e247b23a3c9b45f89ec1299d06" ON "reversi_matching" ("childId") `);
await queryRunner.query(`CREATE TABLE "user_note_pining" ("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_a6a2dad4ae000abce2ea9d9b103" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE INDEX "IDX_bfbc6f79ba4007b4ce5097f08d" ON "user_note_pining" ("userId") `);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_410cd649884b501c02d6e72738" ON "user_note_pining" ("userId", "noteId") `);
await queryRunner.query(`CREATE TYPE "poll_notevisibility_enum" AS ENUM('public', 'home', 'followers', 'specified')`);
await queryRunner.query(`CREATE TABLE "poll" ("noteId" character varying(32) NOT NULL, "expiresAt" TIMESTAMP WITH TIME ZONE, "multiple" boolean NOT NULL, "choices" character varying(128) array NOT NULL DEFAULT '{}'::varchar[], "votes" integer array NOT NULL, "noteVisibility" "poll_notevisibility_enum" NOT NULL, "userId" character varying(32) NOT NULL, "userHost" character varying(128), CONSTRAINT "REL_da851e06d0dfe2ef397d8b1bf1" UNIQUE ("noteId"), CONSTRAINT "PK_da851e06d0dfe2ef397d8b1bf1b" PRIMARY KEY ("noteId"))`);
await queryRunner.query(`CREATE INDEX "IDX_0610ebcfcfb4a18441a9bcdab2" ON "poll" ("userId") `);
await queryRunner.query(`CREATE INDEX "IDX_7fa20a12319c7f6dc3aed98c0a" ON "poll" ("userHost") `);
await queryRunner.query(`CREATE TABLE "user_keypair" ("userId" character varying(32) NOT NULL, "publicKey" character varying(4096) NOT NULL, "privateKey" character varying(4096) NOT NULL, CONSTRAINT "REL_f4853eb41ab722fe05f81cedeb" UNIQUE ("userId"), CONSTRAINT "PK_f4853eb41ab722fe05f81cedeb6" PRIMARY KEY ("userId"))`);
await queryRunner.query(`CREATE TABLE "user_publickey" ("userId" character varying(32) NOT NULL, "keyId" character varying(256) NOT NULL, "keyPem" character varying(4096) NOT NULL, CONSTRAINT "REL_10c146e4b39b443ede016f6736" UNIQUE ("userId"), CONSTRAINT "PK_10c146e4b39b443ede016f6736d" PRIMARY KEY ("userId"))`);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_171e64971c780ebd23fae140bb" ON "user_publickey" ("keyId") `);
await queryRunner.query(`CREATE TABLE "user_profile" ("userId" character varying(32) NOT NULL, "location" character varying(128), "birthday" character(10), "description" character varying(1024), "fields" jsonb NOT NULL DEFAULT '[]', "url" character varying(512), "email" character varying(128), "emailVerifyCode" character varying(128), "emailVerified" boolean NOT NULL DEFAULT false, "twoFactorTempSecret" character varying(128), "twoFactorSecret" character varying(128), "twoFactorEnabled" boolean NOT NULL DEFAULT false, "password" character varying(128), "clientData" jsonb NOT NULL DEFAULT '{}', "autoWatch" boolean NOT NULL DEFAULT false, "autoAcceptFollowed" boolean NOT NULL DEFAULT false, "alwaysMarkNsfw" boolean NOT NULL DEFAULT false, "carefulBot" boolean NOT NULL DEFAULT false, "twitter" boolean NOT NULL DEFAULT false, "twitterAccessToken" character varying(64) DEFAULT null, "twitterAccessTokenSecret" character varying(64) DEFAULT null, "twitterUserId" character varying(64) DEFAULT null, "twitterScreenName" character varying(64) DEFAULT null, "github" boolean NOT NULL DEFAULT false, "githubAccessToken" character varying(64) DEFAULT null, "githubId" integer DEFAULT null, "githubLogin" character varying(64) DEFAULT null, "discord" boolean NOT NULL DEFAULT false, "discordAccessToken" character varying(64) DEFAULT null, "discordRefreshToken" character varying(64) DEFAULT null, "discordExpiresDate" integer DEFAULT null, "discordId" character varying(64) DEFAULT null, "discordUsername" character varying(64) DEFAULT null, "discordDiscriminator" character varying(64) DEFAULT null, "userHost" character varying(128), CONSTRAINT "REL_51cb79b5555effaf7d69ba1cff" UNIQUE ("userId"), CONSTRAINT "PK_51cb79b5555effaf7d69ba1cff9" PRIMARY KEY ("userId"))`);
await queryRunner.query(`CREATE INDEX "IDX_dce530b98e454793dac5ec2f5a" ON "user_profile" ("userHost") `);
await queryRunner.query(`CREATE TYPE "__chart__active_users_span_enum" AS ENUM('hour', 'day')`);
await queryRunner.query(`CREATE TABLE "__chart__active_users" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "group" character varying(128), "span" "__chart__active_users_span_enum" NOT NULL, "unique" jsonb NOT NULL DEFAULT '{}', "___local_count" bigint NOT NULL, "___remote_count" bigint NOT NULL, CONSTRAINT "PK_317237a9f733b970604a11e314f" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE TYPE "__chart__drive_span_enum" AS ENUM('hour', 'day')`);
await queryRunner.query(`CREATE TABLE "__chart__drive" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "group" character varying(128), "span" "__chart__drive_span_enum" NOT NULL, "unique" jsonb NOT NULL DEFAULT '{}', "___local_totalCount" bigint NOT NULL, "___local_totalSize" bigint NOT NULL, "___local_incCount" bigint NOT NULL, "___local_incSize" bigint NOT NULL, "___local_decCount" bigint NOT NULL, "___local_decSize" bigint NOT NULL, "___remote_totalCount" bigint NOT NULL, "___remote_totalSize" bigint NOT NULL, "___remote_incCount" bigint NOT NULL, "___remote_incSize" bigint NOT NULL, "___remote_decCount" bigint NOT NULL, "___remote_decSize" bigint NOT NULL, CONSTRAINT "PK_f96bc548a765cd4b3b354221ce7" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE TYPE "__chart__federation_span_enum" AS ENUM('hour', 'day')`);
await queryRunner.query(`CREATE TABLE "__chart__federation" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "group" character varying(128), "span" "__chart__federation_span_enum" NOT NULL, "unique" jsonb NOT NULL DEFAULT '{}', "___instance_total" bigint NOT NULL, "___instance_inc" bigint NOT NULL, "___instance_dec" bigint NOT NULL, CONSTRAINT "PK_b39dcd31a0fe1a7757e348e85fd" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE TYPE "__chart__hashtag_span_enum" AS ENUM('hour', 'day')`);
await queryRunner.query(`CREATE TABLE "__chart__hashtag" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "group" character varying(128), "span" "__chart__hashtag_span_enum" NOT NULL, "unique" jsonb NOT NULL DEFAULT '{}', "___local_count" bigint NOT NULL, "___remote_count" bigint NOT NULL, CONSTRAINT "PK_c32f1ea2b44a5d2f7881e37f8f9" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE TYPE "__chart__instance_span_enum" AS ENUM('hour', 'day')`);
await queryRunner.query(`CREATE TABLE "__chart__instance" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "group" character varying(128), "span" "__chart__instance_span_enum" NOT NULL, "unique" jsonb NOT NULL DEFAULT '{}', "___requests_failed" bigint NOT NULL, "___requests_succeeded" bigint NOT NULL, "___requests_received" bigint NOT NULL, "___notes_total" bigint NOT NULL, "___notes_inc" bigint NOT NULL, "___notes_dec" bigint NOT NULL, "___notes_diffs_normal" bigint NOT NULL, "___notes_diffs_reply" bigint NOT NULL, "___notes_diffs_renote" bigint NOT NULL, "___users_total" bigint NOT NULL, "___users_inc" bigint NOT NULL, "___users_dec" bigint NOT NULL, "___following_total" bigint NOT NULL, "___following_inc" bigint NOT NULL, "___following_dec" bigint NOT NULL, "___followers_total" bigint NOT NULL, "___followers_inc" bigint NOT NULL, "___followers_dec" bigint NOT NULL, "___drive_totalFiles" bigint NOT NULL, "___drive_totalUsage" bigint NOT NULL, "___drive_incFiles" bigint NOT NULL, "___drive_incUsage" bigint NOT NULL, "___drive_decFiles" bigint NOT NULL, "___drive_decUsage" bigint NOT NULL, CONSTRAINT "PK_1267c67c7c2d47b4903975f2c00" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE TYPE "__chart__network_span_enum" AS ENUM('hour', 'day')`);
await queryRunner.query(`CREATE TABLE "__chart__network" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "group" character varying(128), "span" "__chart__network_span_enum" NOT NULL, "unique" jsonb NOT NULL DEFAULT '{}', "___incomingRequests" bigint NOT NULL, "___outgoingRequests" bigint NOT NULL, "___totalTime" bigint NOT NULL, "___incomingBytes" bigint NOT NULL, "___outgoingBytes" bigint NOT NULL, CONSTRAINT "PK_bc4290c2e27fad14ef0c1ca93f3" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE TYPE "__chart__notes_span_enum" AS ENUM('hour', 'day')`);
await queryRunner.query(`CREATE TABLE "__chart__notes" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "group" character varying(128), "span" "__chart__notes_span_enum" NOT NULL, "unique" jsonb NOT NULL DEFAULT '{}', "___local_total" bigint NOT NULL, "___local_inc" bigint NOT NULL, "___local_dec" bigint NOT NULL, "___local_diffs_normal" bigint NOT NULL, "___local_diffs_reply" bigint NOT NULL, "___local_diffs_renote" bigint NOT NULL, "___remote_total" bigint NOT NULL, "___remote_inc" bigint NOT NULL, "___remote_dec" bigint NOT NULL, "___remote_diffs_normal" bigint NOT NULL, "___remote_diffs_reply" bigint NOT NULL, "___remote_diffs_renote" bigint NOT NULL, CONSTRAINT "PK_0aec823fa85c7f901bdb3863b14" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE TYPE "__chart__per_user_drive_span_enum" AS ENUM('hour', 'day')`);
await queryRunner.query(`CREATE TABLE "__chart__per_user_drive" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "group" character varying(128), "span" "__chart__per_user_drive_span_enum" NOT NULL, "unique" jsonb NOT NULL DEFAULT '{}', "___totalCount" bigint NOT NULL, "___totalSize" bigint NOT NULL, "___incCount" bigint NOT NULL, "___incSize" bigint NOT NULL, "___decCount" bigint NOT NULL, "___decSize" bigint NOT NULL, CONSTRAINT "PK_d0ef23d24d666e1a44a0cd3d208" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE TYPE "__chart__per_user_following_span_enum" AS ENUM('hour', 'day')`);
await queryRunner.query(`CREATE TABLE "__chart__per_user_following" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "group" character varying(128), "span" "__chart__per_user_following_span_enum" NOT NULL, "unique" jsonb NOT NULL DEFAULT '{}', "___local_followings_total" bigint NOT NULL, "___local_followings_inc" bigint NOT NULL, "___local_followings_dec" bigint NOT NULL, "___local_followers_total" bigint NOT NULL, "___local_followers_inc" bigint NOT NULL, "___local_followers_dec" bigint NOT NULL, "___remote_followings_total" bigint NOT NULL, "___remote_followings_inc" bigint NOT NULL, "___remote_followings_dec" bigint NOT NULL, "___remote_followers_total" bigint NOT NULL, "___remote_followers_inc" bigint NOT NULL, "___remote_followers_dec" bigint NOT NULL, CONSTRAINT "PK_85bb1b540363a29c2fec83bd907" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE TYPE "__chart__per_user_notes_span_enum" AS ENUM('hour', 'day')`);
await queryRunner.query(`CREATE TABLE "__chart__per_user_notes" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "group" character varying(128), "span" "__chart__per_user_notes_span_enum" NOT NULL, "unique" jsonb NOT NULL DEFAULT '{}', "___total" bigint NOT NULL, "___inc" bigint NOT NULL, "___dec" bigint NOT NULL, "___diffs_normal" bigint NOT NULL, "___diffs_reply" bigint NOT NULL, "___diffs_renote" bigint NOT NULL, CONSTRAINT "PK_334acf6e915af2f29edc11b8e50" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE TYPE "__chart__per_user_reaction_span_enum" AS ENUM('hour', 'day')`);
await queryRunner.query(`CREATE TABLE "__chart__per_user_reaction" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "group" character varying(128), "span" "__chart__per_user_reaction_span_enum" NOT NULL, "unique" jsonb NOT NULL DEFAULT '{}', "___local_count" bigint NOT NULL, "___remote_count" bigint NOT NULL, CONSTRAINT "PK_984f54dae441e65b633e8d27a7f" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE TYPE "__chart__test_grouped_span_enum" AS ENUM('hour', 'day')`);
await queryRunner.query(`CREATE TABLE "__chart__test_grouped" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "group" character varying(128), "span" "__chart__test_grouped_span_enum" NOT NULL, "unique" jsonb NOT NULL DEFAULT '{}', "___foo_total" bigint NOT NULL, "___foo_inc" bigint NOT NULL, "___foo_dec" bigint NOT NULL, CONSTRAINT "PK_f4a2b175d308695af30d4293272" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE TYPE "__chart__test_unique_span_enum" AS ENUM('hour', 'day')`);
await queryRunner.query(`CREATE TABLE "__chart__test_unique" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "group" character varying(128), "span" "__chart__test_unique_span_enum" NOT NULL, "unique" jsonb NOT NULL DEFAULT '{}', "___foo" bigint NOT NULL, CONSTRAINT "PK_409bac9c97cc612d8500012319d" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE TYPE "__chart__test_span_enum" AS ENUM('hour', 'day')`);
await queryRunner.query(`CREATE TABLE "__chart__test" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "group" character varying(128), "span" "__chart__test_span_enum" NOT NULL, "unique" jsonb NOT NULL DEFAULT '{}', "___foo_total" bigint NOT NULL, "___foo_inc" bigint NOT NULL, "___foo_dec" bigint NOT NULL, CONSTRAINT "PK_b4bc31dffbd1b785276a3ecfc1e" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE TYPE "__chart__users_span_enum" AS ENUM('hour', 'day')`);
await queryRunner.query(`CREATE TABLE "__chart__users" ("id" SERIAL NOT NULL, "date" integer NOT NULL, "group" character varying(128), "span" "__chart__users_span_enum" NOT NULL, "unique" jsonb NOT NULL DEFAULT '{}', "___local_total" bigint NOT NULL, "___local_inc" bigint NOT NULL, "___local_dec" bigint NOT NULL, "___remote_total" bigint NOT NULL, "___remote_inc" bigint NOT NULL, "___remote_dec" bigint NOT NULL, CONSTRAINT "PK_4dfcf2c78d03524b9eb2c99d328" PRIMARY KEY ("id"))`);
await queryRunner.query(`ALTER TABLE "drive_folder" ADD CONSTRAINT "FK_f4fc06e49c0171c85f1c48060d2" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "drive_folder" ADD CONSTRAINT "FK_00ceffb0cdc238b3233294f08f2" FOREIGN KEY ("parentId") REFERENCES "drive_folder"("id") ON DELETE SET NULL ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "drive_file" ADD CONSTRAINT "FK_860fa6f6c7df5bb887249fba22e" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE SET NULL ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "drive_file" ADD CONSTRAINT "FK_bb90d1956dafc4068c28aa7560a" FOREIGN KEY ("folderId") REFERENCES "drive_folder"("id") ON DELETE SET NULL ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "user" ADD CONSTRAINT "FK_58f5c71eaab331645112cf8cfa5" FOREIGN KEY ("avatarId") REFERENCES "drive_file"("id") ON DELETE SET NULL ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "user" ADD CONSTRAINT "FK_afc64b53f8db3707ceb34eb28e2" FOREIGN KEY ("bannerId") REFERENCES "drive_file"("id") ON DELETE SET NULL ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "app" ADD CONSTRAINT "FK_3f5b0899ef90527a3462d7c2cb3" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE SET NULL ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "access_token" ADD CONSTRAINT "FK_9949557d0e1b2c19e5344c171e9" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "access_token" ADD CONSTRAINT "FK_a3ff16c90cc87a82a0b5959e560" FOREIGN KEY ("appId") REFERENCES "app"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "note" ADD CONSTRAINT "FK_17cb3553c700a4985dff5a30ff5" FOREIGN KEY ("replyId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "note" ADD CONSTRAINT "FK_52ccc804d7c69037d558bac4c96" FOREIGN KEY ("renoteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "note" ADD CONSTRAINT "FK_ec5c201576192ba8904c345c5cc" FOREIGN KEY ("appId") REFERENCES "app"("id") ON DELETE SET NULL ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "note" ADD CONSTRAINT "FK_5b87d9d19127bd5d92026017a7b" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "poll_vote" ADD CONSTRAINT "FK_66d2bd2ee31d14bcc23069a89f8" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "poll_vote" ADD CONSTRAINT "FK_aecfbd5ef60374918e63ee95fa7" FOREIGN KEY ("noteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "note_reaction" ADD CONSTRAINT "FK_13761f64257f40c5636d0ff95ee" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "note_reaction" ADD CONSTRAINT "FK_45145e4953780f3cd5656f0ea6a" FOREIGN KEY ("noteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "note_watching" ADD CONSTRAINT "FK_b0134ec406e8d09a540f8182888" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "note_watching" ADD CONSTRAINT "FK_03e7028ab8388a3f5e3ce2a8619" FOREIGN KEY ("noteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "note_unread" ADD CONSTRAINT "FK_56b0166d34ddae49d8ef7610bb9" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "note_unread" ADD CONSTRAINT "FK_e637cba4dc4410218c4251260e4" FOREIGN KEY ("noteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "notification" ADD CONSTRAINT "FK_3c601b70a1066d2c8b517094cb9" FOREIGN KEY ("notifieeId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "notification" ADD CONSTRAINT "FK_3b4e96eec8d36a8bbb9d02aa710" FOREIGN KEY ("notifierId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "notification" ADD CONSTRAINT "FK_769cb6b73a1efe22ddf733ac453" FOREIGN KEY ("noteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "following" ADD CONSTRAINT "FK_24e0042143a18157b234df186c3" FOREIGN KEY ("followeeId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "following" ADD CONSTRAINT "FK_6516c5a6f3c015b4eed39978be5" FOREIGN KEY ("followerId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "muting" ADD CONSTRAINT "FK_ec96b4fed9dae517e0dbbe0675c" FOREIGN KEY ("muteeId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "muting" ADD CONSTRAINT "FK_93060675b4a79a577f31d260c67" FOREIGN KEY ("muterId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "sw_subscription" ADD CONSTRAINT "FK_97754ca6f2baff9b4abb7f853dd" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "blocking" ADD CONSTRAINT "FK_2cd4a2743a99671308f5417759e" FOREIGN KEY ("blockeeId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "blocking" ADD CONSTRAINT "FK_0627125f1a8a42c9a1929edb552" FOREIGN KEY ("blockerId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "user_list" ADD CONSTRAINT "FK_b7fcefbdd1c18dce86687531f99" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "user_list_joining" ADD CONSTRAINT "FK_d844bfc6f3f523a05189076efaa" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "user_list_joining" ADD CONSTRAINT "FK_605472305f26818cc93d1baaa74" FOREIGN KEY ("userListId") REFERENCES "user_list"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "note_favorite" ADD CONSTRAINT "FK_47f4b1892f5d6ba8efb3057d81a" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "note_favorite" ADD CONSTRAINT "FK_0e00498f180193423c992bc4370" FOREIGN KEY ("noteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "abuse_user_report" ADD CONSTRAINT "FK_d049123c413e68ca52abe734203" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "abuse_user_report" ADD CONSTRAINT "FK_04cc96756f89d0b7f9473e8cdf3" FOREIGN KEY ("reporterId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "messaging_message" ADD CONSTRAINT "FK_5377c307783fce2b6d352e1203b" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "messaging_message" ADD CONSTRAINT "FK_cac14a4e3944454a5ce7daa5142" FOREIGN KEY ("recipientId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "messaging_message" ADD CONSTRAINT "FK_535def119223ac05ad3fa9ef64b" FOREIGN KEY ("fileId") REFERENCES "drive_file"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "signin" ADD CONSTRAINT "FK_2c308dbdc50d94dc625670055f7" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "auth_session" ADD CONSTRAINT "FK_c072b729d71697f959bde66ade0" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "auth_session" ADD CONSTRAINT "FK_dbe037d4bddd17b03a1dc778dee" FOREIGN KEY ("appId") REFERENCES "app"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "follow_request" ADD CONSTRAINT "FK_12c01c0d1a79f77d9f6c15fadd2" FOREIGN KEY ("followeeId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "follow_request" ADD CONSTRAINT "FK_a7fd92dd6dc519e6fb435dd108f" FOREIGN KEY ("followerId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "reversi_game" ADD CONSTRAINT "FK_f7467510c60a45ce5aca6292743" FOREIGN KEY ("user1Id") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "reversi_game" ADD CONSTRAINT "FK_6649a4e8c5d5cf32fb03b5da9f6" FOREIGN KEY ("user2Id") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "reversi_matching" ADD CONSTRAINT "FK_3b25402709dd9882048c2bbade0" FOREIGN KEY ("parentId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "reversi_matching" ADD CONSTRAINT "FK_e247b23a3c9b45f89ec1299d066" FOREIGN KEY ("childId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "user_note_pining" ADD CONSTRAINT "FK_bfbc6f79ba4007b4ce5097f08d6" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "user_note_pining" ADD CONSTRAINT "FK_68881008f7c3588ad7ecae471cf" FOREIGN KEY ("noteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "poll" ADD CONSTRAINT "FK_da851e06d0dfe2ef397d8b1bf1b" FOREIGN KEY ("noteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "user_keypair" ADD CONSTRAINT "FK_f4853eb41ab722fe05f81cedeb6" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "user_publickey" ADD CONSTRAINT "FK_10c146e4b39b443ede016f6736d" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "user_profile" ADD CONSTRAINT "FK_51cb79b5555effaf7d69ba1cff9" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
}
public async down(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`ALTER TABLE "user_profile" DROP CONSTRAINT "FK_51cb79b5555effaf7d69ba1cff9"`);
await queryRunner.query(`ALTER TABLE "user_publickey" DROP CONSTRAINT "FK_10c146e4b39b443ede016f6736d"`);
await queryRunner.query(`ALTER TABLE "user_keypair" DROP CONSTRAINT "FK_f4853eb41ab722fe05f81cedeb6"`);
await queryRunner.query(`ALTER TABLE "poll" DROP CONSTRAINT "FK_da851e06d0dfe2ef397d8b1bf1b"`);
await queryRunner.query(`ALTER TABLE "user_note_pining" DROP CONSTRAINT "FK_68881008f7c3588ad7ecae471cf"`);
await queryRunner.query(`ALTER TABLE "user_note_pining" DROP CONSTRAINT "FK_bfbc6f79ba4007b4ce5097f08d6"`);
await queryRunner.query(`ALTER TABLE "reversi_matching" DROP CONSTRAINT "FK_e247b23a3c9b45f89ec1299d066"`);
await queryRunner.query(`ALTER TABLE "reversi_matching" DROP CONSTRAINT "FK_3b25402709dd9882048c2bbade0"`);
await queryRunner.query(`ALTER TABLE "reversi_game" DROP CONSTRAINT "FK_6649a4e8c5d5cf32fb03b5da9f6"`);
await queryRunner.query(`ALTER TABLE "reversi_game" DROP CONSTRAINT "FK_f7467510c60a45ce5aca6292743"`);
await queryRunner.query(`ALTER TABLE "follow_request" DROP CONSTRAINT "FK_a7fd92dd6dc519e6fb435dd108f"`);
await queryRunner.query(`ALTER TABLE "follow_request" DROP CONSTRAINT "FK_12c01c0d1a79f77d9f6c15fadd2"`);
await queryRunner.query(`ALTER TABLE "auth_session" DROP CONSTRAINT "FK_dbe037d4bddd17b03a1dc778dee"`);
await queryRunner.query(`ALTER TABLE "auth_session" DROP CONSTRAINT "FK_c072b729d71697f959bde66ade0"`);
await queryRunner.query(`ALTER TABLE "signin" DROP CONSTRAINT "FK_2c308dbdc50d94dc625670055f7"`);
await queryRunner.query(`ALTER TABLE "messaging_message" DROP CONSTRAINT "FK_535def119223ac05ad3fa9ef64b"`);
await queryRunner.query(`ALTER TABLE "messaging_message" DROP CONSTRAINT "FK_cac14a4e3944454a5ce7daa5142"`);
await queryRunner.query(`ALTER TABLE "messaging_message" DROP CONSTRAINT "FK_5377c307783fce2b6d352e1203b"`);
await queryRunner.query(`ALTER TABLE "abuse_user_report" DROP CONSTRAINT "FK_04cc96756f89d0b7f9473e8cdf3"`);
await queryRunner.query(`ALTER TABLE "abuse_user_report" DROP CONSTRAINT "FK_d049123c413e68ca52abe734203"`);
await queryRunner.query(`ALTER TABLE "note_favorite" DROP CONSTRAINT "FK_0e00498f180193423c992bc4370"`);
await queryRunner.query(`ALTER TABLE "note_favorite" DROP CONSTRAINT "FK_47f4b1892f5d6ba8efb3057d81a"`);
await queryRunner.query(`ALTER TABLE "user_list_joining" DROP CONSTRAINT "FK_605472305f26818cc93d1baaa74"`);
await queryRunner.query(`ALTER TABLE "user_list_joining" DROP CONSTRAINT "FK_d844bfc6f3f523a05189076efaa"`);
await queryRunner.query(`ALTER TABLE "user_list" DROP CONSTRAINT "FK_b7fcefbdd1c18dce86687531f99"`);
await queryRunner.query(`ALTER TABLE "blocking" DROP CONSTRAINT "FK_0627125f1a8a42c9a1929edb552"`);
await queryRunner.query(`ALTER TABLE "blocking" DROP CONSTRAINT "FK_2cd4a2743a99671308f5417759e"`);
await queryRunner.query(`ALTER TABLE "sw_subscription" DROP CONSTRAINT "FK_97754ca6f2baff9b4abb7f853dd"`);
await queryRunner.query(`ALTER TABLE "muting" DROP CONSTRAINT "FK_93060675b4a79a577f31d260c67"`);
await queryRunner.query(`ALTER TABLE "muting" DROP CONSTRAINT "FK_ec96b4fed9dae517e0dbbe0675c"`);
await queryRunner.query(`ALTER TABLE "following" DROP CONSTRAINT "FK_6516c5a6f3c015b4eed39978be5"`);
await queryRunner.query(`ALTER TABLE "following" DROP CONSTRAINT "FK_24e0042143a18157b234df186c3"`);
await queryRunner.query(`ALTER TABLE "notification" DROP CONSTRAINT "FK_769cb6b73a1efe22ddf733ac453"`);
await queryRunner.query(`ALTER TABLE "notification" DROP CONSTRAINT "FK_3b4e96eec8d36a8bbb9d02aa710"`);
await queryRunner.query(`ALTER TABLE "notification" DROP CONSTRAINT "FK_3c601b70a1066d2c8b517094cb9"`);
await queryRunner.query(`ALTER TABLE "note_unread" DROP CONSTRAINT "FK_e637cba4dc4410218c4251260e4"`);
await queryRunner.query(`ALTER TABLE "note_unread" DROP CONSTRAINT "FK_56b0166d34ddae49d8ef7610bb9"`);
await queryRunner.query(`ALTER TABLE "note_watching" DROP CONSTRAINT "FK_03e7028ab8388a3f5e3ce2a8619"`);
await queryRunner.query(`ALTER TABLE "note_watching" DROP CONSTRAINT "FK_b0134ec406e8d09a540f8182888"`);
await queryRunner.query(`ALTER TABLE "note_reaction" DROP CONSTRAINT "FK_45145e4953780f3cd5656f0ea6a"`);
await queryRunner.query(`ALTER TABLE "note_reaction" DROP CONSTRAINT "FK_13761f64257f40c5636d0ff95ee"`);
await queryRunner.query(`ALTER TABLE "poll_vote" DROP CONSTRAINT "FK_aecfbd5ef60374918e63ee95fa7"`);
await queryRunner.query(`ALTER TABLE "poll_vote" DROP CONSTRAINT "FK_66d2bd2ee31d14bcc23069a89f8"`);
await queryRunner.query(`ALTER TABLE "note" DROP CONSTRAINT "FK_5b87d9d19127bd5d92026017a7b"`);
await queryRunner.query(`ALTER TABLE "note" DROP CONSTRAINT "FK_ec5c201576192ba8904c345c5cc"`);
await queryRunner.query(`ALTER TABLE "note" DROP CONSTRAINT "FK_52ccc804d7c69037d558bac4c96"`);
await queryRunner.query(`ALTER TABLE "note" DROP CONSTRAINT "FK_17cb3553c700a4985dff5a30ff5"`);
await queryRunner.query(`ALTER TABLE "access_token" DROP CONSTRAINT "FK_a3ff16c90cc87a82a0b5959e560"`);
await queryRunner.query(`ALTER TABLE "access_token" DROP CONSTRAINT "FK_9949557d0e1b2c19e5344c171e9"`);
await queryRunner.query(`ALTER TABLE "app" DROP CONSTRAINT "FK_3f5b0899ef90527a3462d7c2cb3"`);
await queryRunner.query(`ALTER TABLE "user" DROP CONSTRAINT "FK_afc64b53f8db3707ceb34eb28e2"`);
await queryRunner.query(`ALTER TABLE "user" DROP CONSTRAINT "FK_58f5c71eaab331645112cf8cfa5"`);
await queryRunner.query(`ALTER TABLE "drive_file" DROP CONSTRAINT "FK_bb90d1956dafc4068c28aa7560a"`);
await queryRunner.query(`ALTER TABLE "drive_file" DROP CONSTRAINT "FK_860fa6f6c7df5bb887249fba22e"`);
await queryRunner.query(`ALTER TABLE "drive_folder" DROP CONSTRAINT "FK_00ceffb0cdc238b3233294f08f2"`);
await queryRunner.query(`ALTER TABLE "drive_folder" DROP CONSTRAINT "FK_f4fc06e49c0171c85f1c48060d2"`);
await queryRunner.query(`DROP TABLE "__chart__users"`);
await queryRunner.query(`DROP TYPE "__chart__users_span_enum"`);
await queryRunner.query(`DROP TABLE "__chart__test"`);
await queryRunner.query(`DROP TYPE "__chart__test_span_enum"`);
await queryRunner.query(`DROP TABLE "__chart__test_unique"`);
await queryRunner.query(`DROP TYPE "__chart__test_unique_span_enum"`);
await queryRunner.query(`DROP TABLE "__chart__test_grouped"`);
await queryRunner.query(`DROP TYPE "__chart__test_grouped_span_enum"`);
await queryRunner.query(`DROP TABLE "__chart__per_user_reaction"`);
await queryRunner.query(`DROP TYPE "__chart__per_user_reaction_span_enum"`);
await queryRunner.query(`DROP TABLE "__chart__per_user_notes"`);
await queryRunner.query(`DROP TYPE "__chart__per_user_notes_span_enum"`);
await queryRunner.query(`DROP TABLE "__chart__per_user_following"`);
await queryRunner.query(`DROP TYPE "__chart__per_user_following_span_enum"`);
await queryRunner.query(`DROP TABLE "__chart__per_user_drive"`);
await queryRunner.query(`DROP TYPE "__chart__per_user_drive_span_enum"`);
await queryRunner.query(`DROP TABLE "__chart__notes"`);
await queryRunner.query(`DROP TYPE "__chart__notes_span_enum"`);
await queryRunner.query(`DROP TABLE "__chart__network"`);
await queryRunner.query(`DROP TYPE "__chart__network_span_enum"`);
await queryRunner.query(`DROP TABLE "__chart__instance"`);
await queryRunner.query(`DROP TYPE "__chart__instance_span_enum"`);
await queryRunner.query(`DROP TABLE "__chart__hashtag"`);
await queryRunner.query(`DROP TYPE "__chart__hashtag_span_enum"`);
await queryRunner.query(`DROP TABLE "__chart__federation"`);
await queryRunner.query(`DROP TYPE "__chart__federation_span_enum"`);
await queryRunner.query(`DROP TABLE "__chart__drive"`);
await queryRunner.query(`DROP TYPE "__chart__drive_span_enum"`);
await queryRunner.query(`DROP TABLE "__chart__active_users"`);
await queryRunner.query(`DROP TYPE "__chart__active_users_span_enum"`);
await queryRunner.query(`DROP INDEX "IDX_dce530b98e454793dac5ec2f5a"`);
await queryRunner.query(`DROP TABLE "user_profile"`);
await queryRunner.query(`DROP INDEX "IDX_171e64971c780ebd23fae140bb"`);
await queryRunner.query(`DROP TABLE "user_publickey"`);
await queryRunner.query(`DROP TABLE "user_keypair"`);
await queryRunner.query(`DROP INDEX "IDX_7fa20a12319c7f6dc3aed98c0a"`);
await queryRunner.query(`DROP INDEX "IDX_0610ebcfcfb4a18441a9bcdab2"`);
await queryRunner.query(`DROP TABLE "poll"`);
await queryRunner.query(`DROP TYPE "poll_notevisibility_enum"`);
await queryRunner.query(`DROP INDEX "IDX_410cd649884b501c02d6e72738"`);
await queryRunner.query(`DROP INDEX "IDX_bfbc6f79ba4007b4ce5097f08d"`);
await queryRunner.query(`DROP TABLE "user_note_pining"`);
await queryRunner.query(`DROP INDEX "IDX_e247b23a3c9b45f89ec1299d06"`);
await queryRunner.query(`DROP INDEX "IDX_3b25402709dd9882048c2bbade"`);
await queryRunner.query(`DROP INDEX "IDX_b604d92d6c7aec38627f6eaf16"`);
await queryRunner.query(`DROP TABLE "reversi_matching"`);
await queryRunner.query(`DROP INDEX "IDX_b46ec40746efceac604142be1c"`);
await queryRunner.query(`DROP TABLE "reversi_game"`);
await queryRunner.query(`DROP INDEX "IDX_4f4d35e1256c84ae3d1f0eab10"`);
await queryRunner.query(`DROP INDEX "IDX_5900e907bb46516ddf2871327c"`);
await queryRunner.query(`DROP INDEX "IDX_b37dafc86e9af007e3295c2781"`);
await queryRunner.query(`DROP TABLE "emoji"`);
await queryRunner.query(`DROP INDEX "IDX_d54a512b822fac7ed52800f6b4"`);
await queryRunner.query(`DROP INDEX "IDX_a7fd92dd6dc519e6fb435dd108"`);
await queryRunner.query(`DROP INDEX "IDX_12c01c0d1a79f77d9f6c15fadd"`);
await queryRunner.query(`DROP TABLE "follow_request"`);
await queryRunner.query(`DROP INDEX "IDX_62cb09e1129f6ec024ef66e183"`);
await queryRunner.query(`DROP TABLE "auth_session"`);
await queryRunner.query(`DROP INDEX "IDX_2c308dbdc50d94dc625670055f"`);
await queryRunner.query(`DROP TABLE "signin"`);
await queryRunner.query(`DROP INDEX "IDX_cac14a4e3944454a5ce7daa514"`);
await queryRunner.query(`DROP INDEX "IDX_5377c307783fce2b6d352e1203"`);
await queryRunner.query(`DROP INDEX "IDX_e21cd3646e52ef9c94aaf17c2e"`);
await queryRunner.query(`DROP TABLE "messaging_message"`);
await queryRunner.query(`DROP INDEX "IDX_0ff69e8dfa9fe31bb4a4660f59"`);
await queryRunner.query(`DROP TABLE "registration_ticket"`);
await queryRunner.query(`DROP INDEX "IDX_5cd442c3b2e74fdd99dae20243"`);
await queryRunner.query(`DROP INDEX "IDX_04cc96756f89d0b7f9473e8cdf"`);
await queryRunner.query(`DROP INDEX "IDX_d049123c413e68ca52abe73420"`);
await queryRunner.query(`DROP INDEX "IDX_db2098070b2b5a523c58181f74"`);
await queryRunner.query(`DROP TABLE "abuse_user_report"`);
await queryRunner.query(`DROP INDEX "IDX_0f4fb9ad355f3effff221ef245"`);
await queryRunner.query(`DROP INDEX "IDX_47f4b1892f5d6ba8efb3057d81"`);
await queryRunner.query(`DROP TABLE "note_favorite"`);
await queryRunner.query(`DROP INDEX "IDX_0b03cbcd7e6a7ce068efa8ecc2"`);
await queryRunner.query(`DROP INDEX "IDX_0c44bf4f680964145f2a68a341"`);
await queryRunner.query(`DROP INDEX "IDX_d57f9030cd3af7f63ffb1c267c"`);
await queryRunner.query(`DROP INDEX "IDX_4c02d38a976c3ae132228c6fce"`);
await queryRunner.query(`DROP INDEX "IDX_0e206cec573f1edff4a3062923"`);
await queryRunner.query(`DROP INDEX "IDX_2710a55f826ee236ea1a62698f"`);
await queryRunner.query(`DROP INDEX "IDX_347fec870eafea7b26c8a73bac"`);
await queryRunner.query(`DROP TABLE "hashtag"`);
await queryRunner.query(`DROP INDEX "IDX_605472305f26818cc93d1baaa7"`);
await queryRunner.query(`DROP INDEX "IDX_d844bfc6f3f523a05189076efa"`);
await queryRunner.query(`DROP TABLE "user_list_joining"`);
await queryRunner.query(`DROP INDEX "IDX_b7fcefbdd1c18dce86687531f9"`);
await queryRunner.query(`DROP TABLE "user_list"`);
await queryRunner.query(`DROP INDEX "IDX_98a1bc5cb30dfd159de056549f"`);
await queryRunner.query(`DROP INDEX "IDX_0627125f1a8a42c9a1929edb55"`);
await queryRunner.query(`DROP INDEX "IDX_2cd4a2743a99671308f5417759"`);
await queryRunner.query(`DROP INDEX "IDX_b9a354f7941c1e779f3b33aea6"`);
await queryRunner.query(`DROP TABLE "blocking"`);
await queryRunner.query(`DROP INDEX "IDX_97754ca6f2baff9b4abb7f853d"`);
await queryRunner.query(`DROP TABLE "sw_subscription"`);
await queryRunner.query(`DROP INDEX "IDX_1eb9d9824a630321a29fd3b290"`);
await queryRunner.query(`DROP INDEX "IDX_93060675b4a79a577f31d260c6"`);
await queryRunner.query(`DROP INDEX "IDX_ec96b4fed9dae517e0dbbe0675"`);
await queryRunner.query(`DROP INDEX "IDX_f86d57fbca33c7a4e6897490cc"`);
await queryRunner.query(`DROP TABLE "muting"`);
await queryRunner.query(`DROP INDEX "IDX_8d5afc98982185799b160e10eb"`);
await queryRunner.query(`DROP INDEX "IDX_2cd3b2a6b4cf0b910b260afe08"`);
await queryRunner.query(`DROP TABLE "instance"`);
await queryRunner.query(`DROP INDEX "IDX_307be5f1d1252e0388662acb96"`);
await queryRunner.query(`DROP INDEX "IDX_6516c5a6f3c015b4eed39978be"`);
await queryRunner.query(`DROP INDEX "IDX_24e0042143a18157b234df186c"`);
await queryRunner.query(`DROP INDEX "IDX_582f8fab771a9040a12961f3e7"`);
await queryRunner.query(`DROP TABLE "following"`);
await queryRunner.query(`DROP TABLE "meta"`);
await queryRunner.query(`DROP INDEX "IDX_3c601b70a1066d2c8b517094cb"`);
await queryRunner.query(`DROP INDEX "IDX_b11a5e627c41d4dc3170f1d370"`);
await queryRunner.query(`DROP TABLE "notification"`);
await queryRunner.query(`DROP INDEX "IDX_d908433a4953cc13216cd9c274"`);
await queryRunner.query(`DROP INDEX "IDX_e637cba4dc4410218c4251260e"`);
await queryRunner.query(`DROP INDEX "IDX_56b0166d34ddae49d8ef7610bb"`);
await queryRunner.query(`DROP TABLE "note_unread"`);
await queryRunner.query(`DROP INDEX "IDX_a42c93c69989ce1d09959df4cf"`);
await queryRunner.query(`DROP INDEX "IDX_44499765eec6b5489d72c4253b"`);
await queryRunner.query(`DROP INDEX "IDX_03e7028ab8388a3f5e3ce2a861"`);
await queryRunner.query(`DROP INDEX "IDX_b0134ec406e8d09a540f818288"`);
await queryRunner.query(`DROP INDEX "IDX_318cdf42a9cfc11f479bd802bb"`);
await queryRunner.query(`DROP TABLE "note_watching"`);
await queryRunner.query(`DROP INDEX "IDX_ad0c221b25672daf2df320a817"`);
await queryRunner.query(`DROP INDEX "IDX_45145e4953780f3cd5656f0ea6"`);
await queryRunner.query(`DROP INDEX "IDX_13761f64257f40c5636d0ff95e"`);
await queryRunner.query(`DROP INDEX "IDX_01f4581f114e0ebd2bbb876f0b"`);
await queryRunner.query(`DROP TABLE "note_reaction"`);
await queryRunner.query(`DROP INDEX "IDX_50bd7164c5b78f1f4a42c4d21f"`);
await queryRunner.query(`DROP INDEX "IDX_aecfbd5ef60374918e63ee95fa"`);
await queryRunner.query(`DROP INDEX "IDX_66d2bd2ee31d14bcc23069a89f"`);
await queryRunner.query(`DROP INDEX "IDX_0fb627e1c2f753262a74f0562d"`);
await queryRunner.query(`DROP TABLE "poll_vote"`);
await queryRunner.query(`DROP INDEX "IDX_7125a826ab192eb27e11d358a5"`);
await queryRunner.query(`DROP INDEX "IDX_88937d94d7443d9a99a76fa5c0"`);
await queryRunner.query(`DROP INDEX "IDX_54ebcb6d27222913b908d56fd8"`);
await queryRunner.query(`DROP INDEX "IDX_796a8c03959361f97dc2be1d5c"`);
await queryRunner.query(`DROP INDEX "IDX_25dfc71b0369b003a4cd434d0b"`);
await queryRunner.query(`DROP INDEX "IDX_51c063b6a133a9cb87145450f5"`);
await queryRunner.query(`DROP INDEX "IDX_153536c67d05e9adb24e99fc2b"`);
await queryRunner.query(`DROP INDEX "IDX_5b87d9d19127bd5d92026017a7"`);
await queryRunner.query(`DROP INDEX "IDX_52ccc804d7c69037d558bac4c9"`);
await queryRunner.query(`DROP INDEX "IDX_17cb3553c700a4985dff5a30ff"`);
await queryRunner.query(`DROP INDEX "IDX_e7c0567f5261063592f022e9b5"`);
await queryRunner.query(`DROP TABLE "note"`);
await queryRunner.query(`DROP TYPE "note_visibility_enum"`);
await queryRunner.query(`DROP INDEX "IDX_9949557d0e1b2c19e5344c171e"`);
await queryRunner.query(`DROP INDEX "IDX_64c327441248bae40f7d92f34f"`);
await queryRunner.query(`DROP INDEX "IDX_70ba8f6af34bc924fc9e12adb8"`);
await queryRunner.query(`DROP TABLE "access_token"`);
await queryRunner.query(`DROP INDEX "IDX_f49922d511d666848f250663c4"`);
await queryRunner.query(`DROP INDEX "IDX_3f5b0899ef90527a3462d7c2cb"`);
await queryRunner.query(`DROP INDEX "IDX_048a757923ed8b157e9895da53"`);
await queryRunner.query(`DROP TABLE "app"`);
await queryRunner.query(`DROP INDEX "IDX_5deb01ae162d1d70b80d064c27"`);
await queryRunner.query(`DROP INDEX "IDX_a854e557b1b14814750c7c7b0c"`);
await queryRunner.query(`DROP INDEX "IDX_be623adaa4c566baf5d29ce0c8"`);
await queryRunner.query(`DROP INDEX "IDX_3252a5df8d5bbd16b281f7799e"`);
await queryRunner.query(`DROP INDEX "IDX_fa99d777623947a5b05f394cae"`);
await queryRunner.query(`DROP INDEX "IDX_a27b942a0d6dcff90e3ee9b5e8"`);
await queryRunner.query(`DROP INDEX "IDX_80ca6e6ef65fb9ef34ea8c90f4"`);
await queryRunner.query(`DROP INDEX "IDX_e11e649824a45d8ed01d597fd9"`);
await queryRunner.query(`DROP TABLE "user"`);
await queryRunner.query(`DROP INDEX "IDX_bb90d1956dafc4068c28aa7560"`);
await queryRunner.query(`DROP INDEX "IDX_e5848eac4940934e23dbc17581"`);
await queryRunner.query(`DROP INDEX "IDX_c55b2b7c284d9fef98026fc88e"`);
await queryRunner.query(`DROP INDEX "IDX_e74022ce9a074b3866f70e0d27"`);
await queryRunner.query(`DROP INDEX "IDX_d85a184c2540d2deba33daf642"`);
await queryRunner.query(`DROP INDEX "IDX_a40b8df8c989d7db937ea27cf6"`);
await queryRunner.query(`DROP INDEX "IDX_37bb9a1b4585f8a3beb24c62d6"`);
await queryRunner.query(`DROP INDEX "IDX_92779627994ac79277f070c91e"`);
await queryRunner.query(`DROP INDEX "IDX_860fa6f6c7df5bb887249fba22"`);
await queryRunner.query(`DROP INDEX "IDX_c8dfad3b72196dd1d6b5db168a"`);
await queryRunner.query(`DROP TABLE "drive_file"`);
await queryRunner.query(`DROP INDEX "IDX_00ceffb0cdc238b3233294f08f"`);
await queryRunner.query(`DROP INDEX "IDX_f4fc06e49c0171c85f1c48060d"`);
await queryRunner.query(`DROP INDEX "IDX_02878d441ceae15ce060b73daf"`);
await queryRunner.query(`DROP TABLE "drive_folder"`);
await queryRunner.query(`DROP INDEX "IDX_584b536b49e53ac81beb39a177"`);
await queryRunner.query(`DROP INDEX "IDX_8cb40cfc8f3c28261e6f887b03"`);
await queryRunner.query(`DROP INDEX "IDX_8e4eb51a35d81b64dda28eed0a"`);
await queryRunner.query(`DROP TABLE "log"`);
await queryRunner.query(`DROP TYPE "log_level_enum"`);
}
}

View File

@ -0,0 +1,31 @@
import {MigrationInterface, QueryRunner} from "typeorm";
export class Pages1556348509290 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`CREATE TYPE "page_visibility_enum" AS ENUM('public', 'followers', 'specified')`);
await queryRunner.query(`CREATE TABLE "page" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL, "title" character varying(256) NOT NULL, "name" character varying(256) NOT NULL, "summary" character varying(256), "alignCenter" boolean NOT NULL, "font" character varying(32) NOT NULL, "userId" character varying(32) NOT NULL, "eyeCatchingImageId" character varying(32), "content" jsonb NOT NULL DEFAULT '[]', "variables" jsonb NOT NULL DEFAULT '[]', "visibility" "page_visibility_enum" NOT NULL, "visibleUserIds" character varying(32) array NOT NULL DEFAULT '{}'::varchar[], CONSTRAINT "PK_742f4117e065c5b6ad21b37ba1f" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE INDEX "IDX_fbb4297c927a9b85e9cefa2eb1" ON "page" ("createdAt") `);
await queryRunner.query(`CREATE INDEX "IDX_af639b066dfbca78b01a920f8a" ON "page" ("updatedAt") `);
await queryRunner.query(`CREATE INDEX "IDX_b82c19c08afb292de4600d99e4" ON "page" ("name") `);
await queryRunner.query(`CREATE INDEX "IDX_ae1d917992dd0c9d9bbdad06c4" ON "page" ("userId") `);
await queryRunner.query(`CREATE INDEX "IDX_90148bbc2bf0854428786bfc15" ON "page" ("visibleUserIds") `);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_2133ef8317e4bdb839c0dcbf13" ON "page" ("userId", "name") `);
await queryRunner.query(`ALTER TABLE "page" ADD CONSTRAINT "FK_ae1d917992dd0c9d9bbdad06c4a" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "page" ADD CONSTRAINT "FK_3126dd7c502c9e4d7597ef7ef10" FOREIGN KEY ("eyeCatchingImageId") REFERENCES "drive_file"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
}
public async down(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`ALTER TABLE "page" DROP CONSTRAINT "FK_3126dd7c502c9e4d7597ef7ef10"`);
await queryRunner.query(`ALTER TABLE "page" DROP CONSTRAINT "FK_ae1d917992dd0c9d9bbdad06c4a"`);
await queryRunner.query(`DROP INDEX "IDX_2133ef8317e4bdb839c0dcbf13"`);
await queryRunner.query(`DROP INDEX "IDX_90148bbc2bf0854428786bfc15"`);
await queryRunner.query(`DROP INDEX "IDX_ae1d917992dd0c9d9bbdad06c4"`);
await queryRunner.query(`DROP INDEX "IDX_b82c19c08afb292de4600d99e4"`);
await queryRunner.query(`DROP INDEX "IDX_af639b066dfbca78b01a920f8a"`);
await queryRunner.query(`DROP INDEX "IDX_fbb4297c927a9b85e9cefa2eb1"`);
await queryRunner.query(`DROP TABLE "page"`);
await queryRunner.query(`DROP TYPE "page_visibility_enum"`);
}
}

View File

@ -0,0 +1,16 @@
import {MigrationInterface, QueryRunner} from "typeorm";
export class UserProfile1556746559567 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`ALTER TABLE "user_profile" ALTER COLUMN "githubId" TYPE VARCHAR(64) USING "githubId"::VARCHAR(64)`);
await queryRunner.query(`ALTER TABLE "user_profile" ALTER COLUMN "discordExpiresDate" TYPE VARCHAR(64) USING "discordExpiresDate"::VARCHAR(64)`);
}
public async down(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`UPDATE "user_profile" SET github = FALSE, discord = FALSE`);
await queryRunner.query(`ALTER TABLE "user_profile" ALTER COLUMN "githubId" TYPE INTEGER USING NULL`);
await queryRunner.query(`ALTER TABLE "user_profile" ALTER COLUMN "discordExpiresDate" TYPE INTEGER USING NULL`);
}
}

View File

@ -0,0 +1,13 @@
import {MigrationInterface, QueryRunner} from "typeorm";
export class PinnedUsers1557476068003 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`ALTER TABLE "meta" ADD "pinnedUsers" character varying(256) array NOT NULL DEFAULT '{}'::varchar[]`);
}
public async down(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "pinnedUsers"`);
}
}

View File

@ -0,0 +1,16 @@
import {MigrationInterface, QueryRunner} from "typeorm";
export class AddSomeUrls1557761316509 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`ALTER TABLE "meta" ADD "ToSUrl" character varying(512)`);
await queryRunner.query(`ALTER TABLE "meta" ADD "repositoryUrl" character varying(512) NOT NULL DEFAULT 'https://github.com/syuilo/misskey'`);
await queryRunner.query(`ALTER TABLE "meta" ADD "feedbackUrl" character varying(512) DEFAULT 'https://github.com/syuilo/misskey/issues/new'`);
}
public async down(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "feedbackUrl"`);
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "repositoryUrl"`);
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "ToSUrl"`);
}
}

View File

@ -0,0 +1,31 @@
import {MigrationInterface, QueryRunner} from "typeorm";
export class ObjectStorageSetting1557932705754 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`ALTER TABLE "meta" ADD "useObjectStorage" boolean NOT NULL DEFAULT false`);
await queryRunner.query(`ALTER TABLE "meta" ADD "objectStorageBucket" character varying(512)`);
await queryRunner.query(`ALTER TABLE "meta" ADD "objectStoragePrefix" character varying(512)`);
await queryRunner.query(`ALTER TABLE "meta" ADD "objectStorageBaseUrl" character varying(512)`);
await queryRunner.query(`ALTER TABLE "meta" ADD "objectStorageEndpoint" character varying(512)`);
await queryRunner.query(`ALTER TABLE "meta" ADD "objectStorageRegion" character varying(512)`);
await queryRunner.query(`ALTER TABLE "meta" ADD "objectStorageAccessKey" character varying(512)`);
await queryRunner.query(`ALTER TABLE "meta" ADD "objectStorageSecretKey" character varying(512)`);
await queryRunner.query(`ALTER TABLE "meta" ADD "objectStoragePort" integer`);
await queryRunner.query(`ALTER TABLE "meta" ADD "objectStorageUseSSL" boolean NOT NULL DEFAULT true`);
}
public async down(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "objectStorageUseSSL"`);
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "objectStoragePort"`);
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "objectStorageSecretKey"`);
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "objectStorageAccessKey"`);
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "objectStorageRegion"`);
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "objectStorageEndpoint"`);
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "objectStorageBaseUrl"`);
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "objectStoragePrefix"`);
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "objectStorageBucket"`);
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "useObjectStorage"`);
}
}

View File

@ -0,0 +1,23 @@
import {MigrationInterface, QueryRunner} from "typeorm";
export class PageLike1558072954435 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`CREATE TABLE "page_like" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "pageId" character varying(32) NOT NULL, CONSTRAINT "PK_813f034843af992d3ae0f43c64c" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE INDEX "IDX_0e61efab7f88dbb79c9166dbb4" ON "page_like" ("userId") `);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_4ce6fb9c70529b4c8ac46c9bfa" ON "page_like" ("userId", "pageId") `);
await queryRunner.query(`ALTER TABLE "page" ADD "likedCount" integer NOT NULL DEFAULT 0`);
await queryRunner.query(`ALTER TABLE "page_like" ADD CONSTRAINT "FK_0e61efab7f88dbb79c9166dbb48" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "page_like" ADD CONSTRAINT "FK_cf8782626dced3176038176a847" FOREIGN KEY ("pageId") REFERENCES "page"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
}
public async down(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`ALTER TABLE "page_like" DROP CONSTRAINT "FK_cf8782626dced3176038176a847"`);
await queryRunner.query(`ALTER TABLE "page_like" DROP CONSTRAINT "FK_0e61efab7f88dbb79c9166dbb48"`);
await queryRunner.query(`ALTER TABLE "page" DROP COLUMN "likedCount"`);
await queryRunner.query(`DROP INDEX "IDX_4ce6fb9c70529b4c8ac46c9bfa"`);
await queryRunner.query(`DROP INDEX "IDX_0e61efab7f88dbb79c9166dbb4"`);
await queryRunner.query(`DROP TABLE "page_like"`);
}
}

View File

@ -0,0 +1,41 @@
import {MigrationInterface, QueryRunner} from "typeorm";
export class UserGroup1558103093633 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`CREATE TABLE "user_group" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "name" character varying(256) NOT NULL, "userId" character varying(32) NOT NULL, "isPrivate" boolean NOT NULL DEFAULT false, CONSTRAINT "PK_3c29fba6fe013ec8724378ce7c9" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE INDEX "IDX_20e30aa35180e317e133d75316" ON "user_group" ("createdAt") `);
await queryRunner.query(`CREATE INDEX "IDX_3d6b372788ab01be58853003c9" ON "user_group" ("userId") `);
await queryRunner.query(`CREATE TABLE "user_group_joining" ("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_15f2425885253c5507e1599cfe7" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE INDEX "IDX_f3a1b4bd0c7cabba958a0c0b23" ON "user_group_joining" ("userId") `);
await queryRunner.query(`CREATE INDEX "IDX_67dc758bc0566985d1b3d39986" ON "user_group_joining" ("userGroupId") `);
await queryRunner.query(`ALTER TABLE "messaging_message" ADD "groupId" character varying(32)`);
await queryRunner.query(`ALTER TABLE "messaging_message" ADD "reads" character varying(32) array NOT NULL DEFAULT '{}'::varchar[]`);
await queryRunner.query(`ALTER TABLE "messaging_message" ALTER COLUMN "recipientId" DROP NOT NULL`);
await queryRunner.query(`COMMENT ON COLUMN "messaging_message"."recipientId" IS 'The recipient user ID.'`);
await queryRunner.query(`CREATE INDEX "IDX_2c4be03b446884f9e9c502135b" ON "messaging_message" ("groupId") `);
await queryRunner.query(`ALTER TABLE "messaging_message" ADD CONSTRAINT "FK_2c4be03b446884f9e9c502135be" FOREIGN KEY ("groupId") REFERENCES "user_group"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "user_group" ADD CONSTRAINT "FK_3d6b372788ab01be58853003c93" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "user_group_joining" ADD CONSTRAINT "FK_f3a1b4bd0c7cabba958a0c0b231" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "user_group_joining" ADD CONSTRAINT "FK_67dc758bc0566985d1b3d399865" FOREIGN KEY ("userGroupId") REFERENCES "user_group"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
}
public async down(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`ALTER TABLE "user_group_joining" DROP CONSTRAINT "FK_67dc758bc0566985d1b3d399865"`);
await queryRunner.query(`ALTER TABLE "user_group_joining" DROP CONSTRAINT "FK_f3a1b4bd0c7cabba958a0c0b231"`);
await queryRunner.query(`ALTER TABLE "user_group" DROP CONSTRAINT "FK_3d6b372788ab01be58853003c93"`);
await queryRunner.query(`ALTER TABLE "messaging_message" DROP CONSTRAINT "FK_2c4be03b446884f9e9c502135be"`);
await queryRunner.query(`DROP INDEX "IDX_2c4be03b446884f9e9c502135b"`);
await queryRunner.query(`COMMENT ON COLUMN "messaging_message"."recipientId" IS ''`);
await queryRunner.query(`ALTER TABLE "messaging_message" ALTER COLUMN "recipientId" SET NOT NULL`);
await queryRunner.query(`ALTER TABLE "messaging_message" DROP COLUMN "reads"`);
await queryRunner.query(`ALTER TABLE "messaging_message" DROP COLUMN "groupId"`);
await queryRunner.query(`DROP INDEX "IDX_67dc758bc0566985d1b3d39986"`);
await queryRunner.query(`DROP INDEX "IDX_f3a1b4bd0c7cabba958a0c0b23"`);
await queryRunner.query(`DROP TABLE "user_group_joining"`);
await queryRunner.query(`DROP INDEX "IDX_3d6b372788ab01be58853003c9"`);
await queryRunner.query(`DROP INDEX "IDX_20e30aa35180e317e133d75316"`);
await queryRunner.query(`DROP TABLE "user_group"`);
}
}

View File

@ -0,0 +1,25 @@
import {MigrationInterface, QueryRunner} from "typeorm";
export class UserGroupInvite1558257926829 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`CREATE TABLE "user_group_invite" ("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_3893884af0d3a5f4d01e7921a97" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE INDEX "IDX_1039988afa3bf991185b277fe0" ON "user_group_invite" ("userId") `);
await queryRunner.query(`CREATE INDEX "IDX_e10924607d058004304611a436" ON "user_group_invite" ("userGroupId") `);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_78787741f9010886796f2320a4" ON "user_group_invite" ("userId", "userGroupId") `);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_d9ecaed8c6dc43f3592c229282" ON "user_group_joining" ("userId", "userGroupId") `);
await queryRunner.query(`ALTER TABLE "user_group_invite" ADD CONSTRAINT "FK_1039988afa3bf991185b277fe03" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "user_group_invite" ADD CONSTRAINT "FK_e10924607d058004304611a436a" FOREIGN KEY ("userGroupId") REFERENCES "user_group"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
}
public async down(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`ALTER TABLE "user_group_invite" DROP CONSTRAINT "FK_e10924607d058004304611a436a"`);
await queryRunner.query(`ALTER TABLE "user_group_invite" DROP CONSTRAINT "FK_1039988afa3bf991185b277fe03"`);
await queryRunner.query(`DROP INDEX "IDX_d9ecaed8c6dc43f3592c229282"`);
await queryRunner.query(`DROP INDEX "IDX_78787741f9010886796f2320a4"`);
await queryRunner.query(`DROP INDEX "IDX_e10924607d058004304611a436"`);
await queryRunner.query(`DROP INDEX "IDX_1039988afa3bf991185b277fe0"`);
await queryRunner.query(`DROP TABLE "user_group_invite"`);
}
}

View File

@ -0,0 +1,13 @@
import {MigrationInterface, QueryRunner} from "typeorm";
export class UserListJoining1558266512381 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_90f7da835e4c10aca6853621e1" ON "user_list_joining" ("userId", "userListId") `);
}
public async down(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`DROP INDEX "IDX_90f7da835e4c10aca6853621e1"`);
}
}

View File

@ -0,0 +1,29 @@
import {MigrationInterface, QueryRunner} from "typeorm";
export class webauthn1561706992953 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`CREATE TABLE "attestation_challenge" ("id" character varying(32) NOT NULL, "userId" character varying(32) NOT NULL, "challenge" character varying(64) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "registrationChallenge" boolean NOT NULL DEFAULT false, CONSTRAINT "PK_d0ba6786e093f1bcb497572a6b5" PRIMARY KEY ("id", "userId"))`);
await queryRunner.query(`CREATE INDEX "IDX_f1a461a618fa1755692d0e0d59" ON "attestation_challenge" ("userId") `);
await queryRunner.query(`CREATE INDEX "IDX_47efb914aed1f72dd39a306c7b" ON "attestation_challenge" ("challenge") `);
await queryRunner.query(`CREATE TABLE "user_security_key" ("id" character varying NOT NULL, "userId" character varying(32) NOT NULL, "publicKey" character varying NOT NULL, "lastUsed" TIMESTAMP WITH TIME ZONE NOT NULL, "name" character varying(30) NOT NULL, CONSTRAINT "PK_3e508571121ab39c5f85d10c166" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE INDEX "IDX_ff9ca3b5f3ee3d0681367a9b44" ON "user_security_key" ("userId") `);
await queryRunner.query(`CREATE INDEX "IDX_0d7718e562dcedd0aa5cf2c9f7" ON "user_security_key" ("publicKey") `);
await queryRunner.query(`ALTER TABLE "user_profile" ADD "securityKeysAvailable" boolean NOT NULL DEFAULT false`);
await queryRunner.query(`ALTER TABLE "attestation_challenge" ADD CONSTRAINT "FK_f1a461a618fa1755692d0e0d592" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "user_security_key" ADD CONSTRAINT "FK_ff9ca3b5f3ee3d0681367a9b447" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
}
public async down(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`ALTER TABLE "user_security_key" DROP CONSTRAINT "FK_ff9ca3b5f3ee3d0681367a9b447"`);
await queryRunner.query(`ALTER TABLE "attestation_challenge" DROP CONSTRAINT "FK_f1a461a618fa1755692d0e0d592"`);
await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "securityKeysAvailable"`);
await queryRunner.query(`DROP INDEX "IDX_0d7718e562dcedd0aa5cf2c9f7"`);
await queryRunner.query(`DROP INDEX "IDX_ff9ca3b5f3ee3d0681367a9b44"`);
await queryRunner.query(`DROP TABLE "user_security_key"`);
await queryRunner.query(`DROP INDEX "IDX_47efb914aed1f72dd39a306c7b"`);
await queryRunner.query(`DROP INDEX "IDX_f1a461a618fa1755692d0e0d59"`);
await queryRunner.query(`DROP TABLE "attestation_challenge"`);
}
}

View File

@ -0,0 +1,201 @@
import {MigrationInterface, QueryRunner} from "typeorm";
export class ChartIndexes1561873850023 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`CREATE INDEX "IDX_0ad37b7ef50f4ddc84363d7ccc" ON "__chart__active_users" ("date") `);
await queryRunner.query(`CREATE INDEX "IDX_15e91a03aeeac9dbccdf43fc06" ON "__chart__active_users" ("span") `);
await queryRunner.query(`CREATE INDEX "IDX_00ed5f86db1f7efafb1978bf21" ON "__chart__active_users" ("group") `);
await queryRunner.query(`CREATE INDEX "IDX_20f57cc8f142c131340ee16742" ON "__chart__active_users" ("span", "date") `);
await queryRunner.query(`CREATE INDEX "IDX_9a3ed15a30ab7e3a37702e6e08" ON "__chart__active_users" ("date", "group") `);
await queryRunner.query(`CREATE INDEX "IDX_c26e2c1cbb6e911e0554b27416" ON "__chart__active_users" ("span", "date", "group") `);
await queryRunner.query(`CREATE INDEX "IDX_13565815f618a1ff53886c5b28" ON "__chart__drive" ("date") `);
await queryRunner.query(`CREATE INDEX "IDX_3fa0d0f17ca72e3dc80999a032" ON "__chart__drive" ("span") `);
await queryRunner.query(`CREATE INDEX "IDX_7a170f67425e62a8fabb76c872" ON "__chart__drive" ("group") `);
await queryRunner.query(`CREATE INDEX "IDX_6e1df243476e20cbf86572ecc0" ON "__chart__drive" ("span", "date") `);
await queryRunner.query(`CREATE INDEX "IDX_3313d7288855ec105b5bbf6c21" ON "__chart__drive" ("date", "group") `);
await queryRunner.query(`CREATE INDEX "IDX_06690fc959f1c9fdaf21928222" ON "__chart__drive" ("span", "date", "group") `);
await queryRunner.query(`CREATE INDEX "IDX_36cb699c49580d4e6c2e6159f9" ON "__chart__federation" ("date") `);
await queryRunner.query(`CREATE INDEX "IDX_e447064455928cf627590ef527" ON "__chart__federation" ("span") `);
await queryRunner.query(`CREATE INDEX "IDX_76e87c7bfc5d925fcbba405d84" ON "__chart__federation" ("group") `);
await queryRunner.query(`CREATE INDEX "IDX_2d416e6af791a82e338c79d480" ON "__chart__federation" ("span", "date") `);
await queryRunner.query(`CREATE INDEX "IDX_dd907becf76104e4b656659e6b" ON "__chart__federation" ("date", "group") `);
await queryRunner.query(`CREATE INDEX "IDX_e9cd07672b37d8966cf3709283" ON "__chart__federation" ("span", "date", "group") `);
await queryRunner.query(`CREATE INDEX "IDX_07747a1038c05f532a718fe1de" ON "__chart__hashtag" ("date") `);
await queryRunner.query(`CREATE INDEX "IDX_fcc181fb8283009c61cc4083ef" ON "__chart__hashtag" ("span") `);
await queryRunner.query(`CREATE INDEX "IDX_99a7d2faaef84a6f728d714ad6" ON "__chart__hashtag" ("group") `);
await queryRunner.query(`CREATE INDEX "IDX_49975586f50ed7b800fdd88fbd" ON "__chart__hashtag" ("span", "date") `);
await queryRunner.query(`CREATE INDEX "IDX_25a97c02003338124b2b75fdbc" ON "__chart__hashtag" ("date", "group") `);
await queryRunner.query(`CREATE INDEX "IDX_6d6f156ceefc6bc5f273a0e370" ON "__chart__hashtag" ("span", "date", "group") `);
await queryRunner.query(`CREATE INDEX "IDX_6b8f34a1a64b06014b6fb66824" ON "__chart__instance" ("date") `);
await queryRunner.query(`CREATE INDEX "IDX_c12f0af4a66cdd30c2287ce8aa" ON "__chart__instance" ("span") `);
await queryRunner.query(`CREATE INDEX "IDX_da8a46ba84ca1d8bb5a29bfb63" ON "__chart__instance" ("group") `);
await queryRunner.query(`CREATE INDEX "IDX_d0a4f79af5a97b08f37b547197" ON "__chart__instance" ("span", "date") `);
await queryRunner.query(`CREATE INDEX "IDX_39ee857ab2f23493037c6b6631" ON "__chart__instance" ("date", "group") `);
await queryRunner.query(`CREATE INDEX "IDX_f5448d9633cff74208d850aabe" ON "__chart__instance" ("span", "date", "group") `);
await queryRunner.query(`CREATE INDEX "IDX_a1efd3e0048a5f2793a47360dc" ON "__chart__network" ("date") `);
await queryRunner.query(`CREATE INDEX "IDX_f8dd01baeded2ffa833e0a610a" ON "__chart__network" ("span") `);
await queryRunner.query(`CREATE INDEX "IDX_7b5da130992ec9df96712d4290" ON "__chart__network" ("group") `);
await queryRunner.query(`CREATE INDEX "IDX_08fac0eb3b11f04c200c0b40dd" ON "__chart__network" ("span", "date") `);
await queryRunner.query(`CREATE INDEX "IDX_0a905b992fecd2b5c3fb98759e" ON "__chart__network" ("date", "group") `);
await queryRunner.query(`CREATE INDEX "IDX_9ff6944f01acb756fdc92d7563" ON "__chart__network" ("span", "date", "group") `);
await queryRunner.query(`CREATE INDEX "IDX_42eb716a37d381cdf566192b2b" ON "__chart__notes" ("date") `);
await queryRunner.query(`CREATE INDEX "IDX_e69096589f11e3baa98ddd64d0" ON "__chart__notes" ("span") `);
await queryRunner.query(`CREATE INDEX "IDX_7036f2957151588b813185c794" ON "__chart__notes" ("group") `);
await queryRunner.query(`CREATE INDEX "IDX_0c9a159c5082cbeef3ca6706b5" ON "__chart__notes" ("span", "date") `);
await queryRunner.query(`CREATE INDEX "IDX_f09d543e3acb16c5976bdb31fa" ON "__chart__notes" ("date", "group") `);
await queryRunner.query(`CREATE INDEX "IDX_924fc196c80ca24bae01dd37e4" ON "__chart__notes" ("span", "date", "group") `);
await queryRunner.query(`CREATE INDEX "IDX_5f86db6492274e07c1a3cdf286" ON "__chart__per_user_drive" ("date") `);
await queryRunner.query(`CREATE INDEX "IDX_328f259961e60c4fa0bfcf55ca" ON "__chart__per_user_drive" ("span") `);
await queryRunner.query(`CREATE INDEX "IDX_e496ca8096d28f6b9b509264dc" ON "__chart__per_user_drive" ("group") `);
await queryRunner.query(`CREATE INDEX "IDX_42ea9381f0fda8dfe0fa1c8b53" ON "__chart__per_user_drive" ("span", "date") `);
await queryRunner.query(`CREATE INDEX "IDX_30bf67687f483ace115c5ca642" ON "__chart__per_user_drive" ("date", "group") `);
await queryRunner.query(`CREATE INDEX "IDX_f2aeafde2ae6fbad38e857631b" ON "__chart__per_user_drive" ("span", "date", "group") `);
await queryRunner.query(`CREATE INDEX "IDX_7af07790712aa3438ff6773f3b" ON "__chart__per_user_following" ("date") `);
await queryRunner.query(`CREATE INDEX "IDX_f92dd6d03f8d994f29987f6214" ON "__chart__per_user_following" ("span") `);
await queryRunner.query(`CREATE INDEX "IDX_4b3593098b6edc9c5afe36b18b" ON "__chart__per_user_following" ("group") `);
await queryRunner.query(`CREATE INDEX "IDX_57b5458d0d3d6d1e7f13d4e57f" ON "__chart__per_user_following" ("span", "date") `);
await queryRunner.query(`CREATE INDEX "IDX_b77d4dd9562c3a899d9a286fcd" ON "__chart__per_user_following" ("date", "group") `);
await queryRunner.query(`CREATE INDEX "IDX_4db3b84c7be0d3464714f3e0b1" ON "__chart__per_user_following" ("span", "date", "group") `);
await queryRunner.query(`CREATE INDEX "IDX_84234bd1abb873f07329681c83" ON "__chart__per_user_notes" ("date") `);
await queryRunner.query(`CREATE INDEX "IDX_8d2cbbc8114d90d19b44d626b6" ON "__chart__per_user_notes" ("span") `);
await queryRunner.query(`CREATE INDEX "IDX_55bf20f366979f2436de99206b" ON "__chart__per_user_notes" ("group") `);
await queryRunner.query(`CREATE INDEX "IDX_046feeb12e9ef5f783f409866a" ON "__chart__per_user_notes" ("span", "date") `);
await queryRunner.query(`CREATE INDEX "IDX_5048e9daccbbbc6d567bb142d3" ON "__chart__per_user_notes" ("date", "group") `);
await queryRunner.query(`CREATE INDEX "IDX_f68a5ab958f9f5fa17a32ac23b" ON "__chart__per_user_notes" ("span", "date", "group") `);
await queryRunner.query(`CREATE INDEX "IDX_f7bf4c62059764c2c2bb40fdab" ON "__chart__per_user_reaction" ("date") `);
await queryRunner.query(`CREATE INDEX "IDX_65633a106bce43fc7c5c30a5c7" ON "__chart__per_user_reaction" ("span") `);
await queryRunner.query(`CREATE INDEX "IDX_8cf3156fd7a6b15c43459c6e3b" ON "__chart__per_user_reaction" ("group") `);
await queryRunner.query(`CREATE INDEX "IDX_edeb73c09c3143a81bcb34d569" ON "__chart__per_user_reaction" ("span", "date") `);
await queryRunner.query(`CREATE INDEX "IDX_229a41ad465f9205f1f5703291" ON "__chart__per_user_reaction" ("date", "group") `);
await queryRunner.query(`CREATE INDEX "IDX_e316f01a6d24eb31db27f88262" ON "__chart__per_user_reaction" ("span", "date", "group") `);
await queryRunner.query(`CREATE INDEX "IDX_0c641990ecf47d2545df4edb75" ON "__chart__test_grouped" ("date") `);
await queryRunner.query(`CREATE INDEX "IDX_2be7ec6cebddc14dc11e206686" ON "__chart__test_grouped" ("span") `);
await queryRunner.query(`CREATE INDEX "IDX_234dff3c0b56a6150b95431ab9" ON "__chart__test_grouped" ("group") `);
await queryRunner.query(`CREATE INDEX "IDX_a5133470f4825902e170328ca5" ON "__chart__test_grouped" ("span", "date") `);
await queryRunner.query(`CREATE INDEX "IDX_b14489029e4b3aaf4bba5fb524" ON "__chart__test_grouped" ("date", "group") `);
await queryRunner.query(`CREATE INDEX "IDX_84e661abb7bd1e51b690d4b017" ON "__chart__test_grouped" ("span", "date", "group") `);
await queryRunner.query(`CREATE INDEX "IDX_437bab3c6061d90f6bb65fd2cc" ON "__chart__test_unique" ("date") `);
await queryRunner.query(`CREATE INDEX "IDX_5c73bf61da4f6e6f15bae88ed1" ON "__chart__test_unique" ("span") `);
await queryRunner.query(`CREATE INDEX "IDX_bbfa573a8181018851ed0b6357" ON "__chart__test_unique" ("group") `);
await queryRunner.query(`CREATE INDEX "IDX_d70c86baedc68326be11f9c0ce" ON "__chart__test_unique" ("span", "date") `);
await queryRunner.query(`CREATE INDEX "IDX_a0cd75442dd10d0643a17c4a49" ON "__chart__test_unique" ("date", "group") `);
await queryRunner.query(`CREATE INDEX "IDX_66e1e1ecd2f29e57778af35b59" ON "__chart__test_unique" ("span", "date", "group") `);
await queryRunner.query(`CREATE INDEX "IDX_b070a906db04b44c67c6c2144d" ON "__chart__test" ("date") `);
await queryRunner.query(`CREATE INDEX "IDX_92255988735563f0fe4aba1f05" ON "__chart__test" ("span") `);
await queryRunner.query(`CREATE INDEX "IDX_d41cce6aee1a50bfc062038f9b" ON "__chart__test" ("group") `);
await queryRunner.query(`CREATE INDEX "IDX_c5870993e25c3d5771f91f5003" ON "__chart__test" ("span", "date") `);
await queryRunner.query(`CREATE INDEX "IDX_a319e5dbf47e8a17497623beae" ON "__chart__test" ("date", "group") `);
await queryRunner.query(`CREATE INDEX "IDX_f170de677ea75ad4533de2723e" ON "__chart__test" ("span", "date", "group") `);
await queryRunner.query(`CREATE INDEX "IDX_845254b3eaf708ae8a6cac3026" ON "__chart__users" ("date") `);
await queryRunner.query(`CREATE INDEX "IDX_7c184198ecf66a8d3ecb253ab3" ON "__chart__users" ("span") `);
await queryRunner.query(`CREATE INDEX "IDX_ed9b95919c672a13008e9487ee" ON "__chart__users" ("group") `);
await queryRunner.query(`CREATE INDEX "IDX_f091abb24193d50c653c6b77fc" ON "__chart__users" ("span", "date") `);
await queryRunner.query(`CREATE INDEX "IDX_337e9599f278bd7537fe30876f" ON "__chart__users" ("date", "group") `);
await queryRunner.query(`CREATE INDEX "IDX_a770a57c70e668cc61590c9161" ON "__chart__users" ("span", "date", "group") `);
}
public async down(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`DROP INDEX "IDX_a770a57c70e668cc61590c9161"`);
await queryRunner.query(`DROP INDEX "IDX_337e9599f278bd7537fe30876f"`);
await queryRunner.query(`DROP INDEX "IDX_f091abb24193d50c653c6b77fc"`);
await queryRunner.query(`DROP INDEX "IDX_ed9b95919c672a13008e9487ee"`);
await queryRunner.query(`DROP INDEX "IDX_7c184198ecf66a8d3ecb253ab3"`);
await queryRunner.query(`DROP INDEX "IDX_845254b3eaf708ae8a6cac3026"`);
await queryRunner.query(`DROP INDEX "IDX_f170de677ea75ad4533de2723e"`);
await queryRunner.query(`DROP INDEX "IDX_a319e5dbf47e8a17497623beae"`);
await queryRunner.query(`DROP INDEX "IDX_c5870993e25c3d5771f91f5003"`);
await queryRunner.query(`DROP INDEX "IDX_d41cce6aee1a50bfc062038f9b"`);
await queryRunner.query(`DROP INDEX "IDX_92255988735563f0fe4aba1f05"`);
await queryRunner.query(`DROP INDEX "IDX_b070a906db04b44c67c6c2144d"`);
await queryRunner.query(`DROP INDEX "IDX_66e1e1ecd2f29e57778af35b59"`);
await queryRunner.query(`DROP INDEX "IDX_a0cd75442dd10d0643a17c4a49"`);
await queryRunner.query(`DROP INDEX "IDX_d70c86baedc68326be11f9c0ce"`);
await queryRunner.query(`DROP INDEX "IDX_bbfa573a8181018851ed0b6357"`);
await queryRunner.query(`DROP INDEX "IDX_5c73bf61da4f6e6f15bae88ed1"`);
await queryRunner.query(`DROP INDEX "IDX_437bab3c6061d90f6bb65fd2cc"`);
await queryRunner.query(`DROP INDEX "IDX_84e661abb7bd1e51b690d4b017"`);
await queryRunner.query(`DROP INDEX "IDX_b14489029e4b3aaf4bba5fb524"`);
await queryRunner.query(`DROP INDEX "IDX_a5133470f4825902e170328ca5"`);
await queryRunner.query(`DROP INDEX "IDX_234dff3c0b56a6150b95431ab9"`);
await queryRunner.query(`DROP INDEX "IDX_2be7ec6cebddc14dc11e206686"`);
await queryRunner.query(`DROP INDEX "IDX_0c641990ecf47d2545df4edb75"`);
await queryRunner.query(`DROP INDEX "IDX_e316f01a6d24eb31db27f88262"`);
await queryRunner.query(`DROP INDEX "IDX_229a41ad465f9205f1f5703291"`);
await queryRunner.query(`DROP INDEX "IDX_edeb73c09c3143a81bcb34d569"`);
await queryRunner.query(`DROP INDEX "IDX_8cf3156fd7a6b15c43459c6e3b"`);
await queryRunner.query(`DROP INDEX "IDX_65633a106bce43fc7c5c30a5c7"`);
await queryRunner.query(`DROP INDEX "IDX_f7bf4c62059764c2c2bb40fdab"`);
await queryRunner.query(`DROP INDEX "IDX_f68a5ab958f9f5fa17a32ac23b"`);
await queryRunner.query(`DROP INDEX "IDX_5048e9daccbbbc6d567bb142d3"`);
await queryRunner.query(`DROP INDEX "IDX_046feeb12e9ef5f783f409866a"`);
await queryRunner.query(`DROP INDEX "IDX_55bf20f366979f2436de99206b"`);
await queryRunner.query(`DROP INDEX "IDX_8d2cbbc8114d90d19b44d626b6"`);
await queryRunner.query(`DROP INDEX "IDX_84234bd1abb873f07329681c83"`);
await queryRunner.query(`DROP INDEX "IDX_4db3b84c7be0d3464714f3e0b1"`);
await queryRunner.query(`DROP INDEX "IDX_b77d4dd9562c3a899d9a286fcd"`);
await queryRunner.query(`DROP INDEX "IDX_57b5458d0d3d6d1e7f13d4e57f"`);
await queryRunner.query(`DROP INDEX "IDX_4b3593098b6edc9c5afe36b18b"`);
await queryRunner.query(`DROP INDEX "IDX_f92dd6d03f8d994f29987f6214"`);
await queryRunner.query(`DROP INDEX "IDX_7af07790712aa3438ff6773f3b"`);
await queryRunner.query(`DROP INDEX "IDX_f2aeafde2ae6fbad38e857631b"`);
await queryRunner.query(`DROP INDEX "IDX_30bf67687f483ace115c5ca642"`);
await queryRunner.query(`DROP INDEX "IDX_42ea9381f0fda8dfe0fa1c8b53"`);
await queryRunner.query(`DROP INDEX "IDX_e496ca8096d28f6b9b509264dc"`);
await queryRunner.query(`DROP INDEX "IDX_328f259961e60c4fa0bfcf55ca"`);
await queryRunner.query(`DROP INDEX "IDX_5f86db6492274e07c1a3cdf286"`);
await queryRunner.query(`DROP INDEX "IDX_924fc196c80ca24bae01dd37e4"`);
await queryRunner.query(`DROP INDEX "IDX_f09d543e3acb16c5976bdb31fa"`);
await queryRunner.query(`DROP INDEX "IDX_0c9a159c5082cbeef3ca6706b5"`);
await queryRunner.query(`DROP INDEX "IDX_7036f2957151588b813185c794"`);
await queryRunner.query(`DROP INDEX "IDX_e69096589f11e3baa98ddd64d0"`);
await queryRunner.query(`DROP INDEX "IDX_42eb716a37d381cdf566192b2b"`);
await queryRunner.query(`DROP INDEX "IDX_9ff6944f01acb756fdc92d7563"`);
await queryRunner.query(`DROP INDEX "IDX_0a905b992fecd2b5c3fb98759e"`);
await queryRunner.query(`DROP INDEX "IDX_08fac0eb3b11f04c200c0b40dd"`);
await queryRunner.query(`DROP INDEX "IDX_7b5da130992ec9df96712d4290"`);
await queryRunner.query(`DROP INDEX "IDX_f8dd01baeded2ffa833e0a610a"`);
await queryRunner.query(`DROP INDEX "IDX_a1efd3e0048a5f2793a47360dc"`);
await queryRunner.query(`DROP INDEX "IDX_f5448d9633cff74208d850aabe"`);
await queryRunner.query(`DROP INDEX "IDX_39ee857ab2f23493037c6b6631"`);
await queryRunner.query(`DROP INDEX "IDX_d0a4f79af5a97b08f37b547197"`);
await queryRunner.query(`DROP INDEX "IDX_da8a46ba84ca1d8bb5a29bfb63"`);
await queryRunner.query(`DROP INDEX "IDX_c12f0af4a66cdd30c2287ce8aa"`);
await queryRunner.query(`DROP INDEX "IDX_6b8f34a1a64b06014b6fb66824"`);
await queryRunner.query(`DROP INDEX "IDX_6d6f156ceefc6bc5f273a0e370"`);
await queryRunner.query(`DROP INDEX "IDX_25a97c02003338124b2b75fdbc"`);
await queryRunner.query(`DROP INDEX "IDX_49975586f50ed7b800fdd88fbd"`);
await queryRunner.query(`DROP INDEX "IDX_99a7d2faaef84a6f728d714ad6"`);
await queryRunner.query(`DROP INDEX "IDX_fcc181fb8283009c61cc4083ef"`);
await queryRunner.query(`DROP INDEX "IDX_07747a1038c05f532a718fe1de"`);
await queryRunner.query(`DROP INDEX "IDX_e9cd07672b37d8966cf3709283"`);
await queryRunner.query(`DROP INDEX "IDX_dd907becf76104e4b656659e6b"`);
await queryRunner.query(`DROP INDEX "IDX_2d416e6af791a82e338c79d480"`);
await queryRunner.query(`DROP INDEX "IDX_76e87c7bfc5d925fcbba405d84"`);
await queryRunner.query(`DROP INDEX "IDX_e447064455928cf627590ef527"`);
await queryRunner.query(`DROP INDEX "IDX_36cb699c49580d4e6c2e6159f9"`);
await queryRunner.query(`DROP INDEX "IDX_06690fc959f1c9fdaf21928222"`);
await queryRunner.query(`DROP INDEX "IDX_3313d7288855ec105b5bbf6c21"`);
await queryRunner.query(`DROP INDEX "IDX_6e1df243476e20cbf86572ecc0"`);
await queryRunner.query(`DROP INDEX "IDX_7a170f67425e62a8fabb76c872"`);
await queryRunner.query(`DROP INDEX "IDX_3fa0d0f17ca72e3dc80999a032"`);
await queryRunner.query(`DROP INDEX "IDX_13565815f618a1ff53886c5b28"`);
await queryRunner.query(`DROP INDEX "IDX_c26e2c1cbb6e911e0554b27416"`);
await queryRunner.query(`DROP INDEX "IDX_9a3ed15a30ab7e3a37702e6e08"`);
await queryRunner.query(`DROP INDEX "IDX_20f57cc8f142c131340ee16742"`);
await queryRunner.query(`DROP INDEX "IDX_00ed5f86db1f7efafb1978bf21"`);
await queryRunner.query(`DROP INDEX "IDX_15e91a03aeeac9dbccdf43fc06"`);
await queryRunner.query(`DROP INDEX "IDX_0ad37b7ef50f4ddc84363d7ccc"`);
await queryRunner.query(`DROP INDEX "IDX_90148bbc2bf0854428786bfc15"`);
await queryRunner.query(`DROP INDEX "IDX_88937d94d7443d9a99a76fa5c0"`);
await queryRunner.query(`DROP INDEX "IDX_54ebcb6d27222913b908d56fd8"`);
await queryRunner.query(`DROP INDEX "IDX_796a8c03959361f97dc2be1d5c"`);
await queryRunner.query(`DROP INDEX "IDX_25dfc71b0369b003a4cd434d0b"`);
await queryRunner.query(`DROP INDEX "IDX_51c063b6a133a9cb87145450f5"`);
await queryRunner.query(`DROP INDEX "IDX_fa99d777623947a5b05f394cae"`);
await queryRunner.query(`DROP INDEX "IDX_315c779174fe8247ab324f036e"`);
await queryRunner.query(`DROP INDEX "IDX_c5d46cbfda48b1c33ed852e21b"`);
await queryRunner.query(`DROP INDEX "IDX_8cb40cfc8f3c28261e6f887b03"`);
}
}

View File

@ -0,0 +1,13 @@
import {MigrationInterface, QueryRunner} from "typeorm";
export class PasswordLessLogin1562422242907 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`ALTER TABLE "user_profile" ADD COLUMN "usePasswordLessLogin" boolean DEFAULT false NOT NULL`);
}
public async down(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "usePasswordLessLogin"`);
}
}

View File

@ -0,0 +1,17 @@
import {MigrationInterface, QueryRunner} from "typeorm";
export class PinnedPage1562444565093 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`ALTER TABLE "user_profile" ADD "pinnedPageId" character varying(32)`);
await queryRunner.query(`ALTER TABLE "user_profile" ADD CONSTRAINT "UQ_6dc44f1ceb65b1e72bacef2ca27" UNIQUE ("pinnedPageId")`);
await queryRunner.query(`ALTER TABLE "user_profile" ADD CONSTRAINT "FK_6dc44f1ceb65b1e72bacef2ca27" FOREIGN KEY ("pinnedPageId") REFERENCES "page"("id") ON DELETE SET NULL ON UPDATE NO ACTION`);
}
public async down(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`ALTER TABLE "user_profile" DROP CONSTRAINT "FK_6dc44f1ceb65b1e72bacef2ca27"`);
await queryRunner.query(`ALTER TABLE "user_profile" DROP CONSTRAINT "UQ_6dc44f1ceb65b1e72bacef2ca27"`);
await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "pinnedPageId"`);
}
}

View File

@ -0,0 +1,13 @@
import {MigrationInterface, QueryRunner} from "typeorm";
export class PageTitleHideOption1562448332510 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`ALTER TABLE "page" ADD "hideTitleWhenPinned" boolean NOT NULL DEFAULT false`);
}
public async down(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`ALTER TABLE "page" DROP COLUMN "hideTitleWhenPinned"`);
}
}

View File

@ -0,0 +1,17 @@
import {MigrationInterface, QueryRunner} from "typeorm";
export class ModerationLog1562869971568 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`CREATE TABLE "moderation_log" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "type" character varying(128) NOT NULL, "info" jsonb NOT NULL, CONSTRAINT "PK_d0adca6ecfd068db83e4526cc26" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE INDEX "IDX_a08ad074601d204e0f69da9a95" ON "moderation_log" ("userId") `);
await queryRunner.query(`ALTER TABLE "moderation_log" ADD CONSTRAINT "FK_a08ad074601d204e0f69da9a954" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
}
public async down(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`ALTER TABLE "moderation_log" DROP CONSTRAINT "FK_a08ad074601d204e0f69da9a954"`);
await queryRunner.query(`DROP INDEX "IDX_a08ad074601d204e0f69da9a95"`);
await queryRunner.query(`DROP TABLE "moderation_log"`);
}
}

View File

@ -0,0 +1,13 @@
import {MigrationInterface, QueryRunner} from "typeorm";
export class UsedUsername1563757595828 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`CREATE TABLE "used_username" ("username" character varying(128) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, CONSTRAINT "PK_78fd79d2d24c6ac2f4cc9a31a5d" PRIMARY KEY ("username"))`);
}
public async down(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`DROP TABLE "used_username"`);
}
}

View File

@ -0,0 +1,13 @@
import {MigrationInterface, QueryRunner} from "typeorm";
export class room1565634203341 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`ALTER TABLE "user_profile" ADD "room" jsonb NOT NULL DEFAULT '{}'`);
}
public async down(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "room"`);
}
}

17
ormconfig.js Normal file
View File

@ -0,0 +1,17 @@
const config = require('./built/config').default;
const entities = require('./built/db/postgre').entities;
module.exports = {
type: 'postgres',
host: config.db.host,
port: config.db.port,
username: config.db.user,
password: config.db.pass,
database: config.db.db,
extra: config.db.extra,
entities: entities,
migrations: ['migration/*.ts'],
cli: {
migrationsDir: 'migration'
}
};

View File

@ -1,7 +1,7 @@
{
"name": "misskey",
"author": "syuilo <i@syuilo.com>",
"version": "11.0.2",
"version": "11.31.0",
"codename": "daybreak",
"repository": {
"type": "git",
@ -11,7 +11,10 @@
"private": true,
"scripts": {
"start": "node ./index.js",
"init": "node ./built/init.js",
"init": "npm run migrate",
"ormconfig": "node ./built/ormconfig.js",
"migrate": "ts-node ./node_modules/typeorm/cli.js migration:run",
"migrateandstart": "npm run migrate && npm run start",
"build": "webpack && gulp build",
"webpack": "webpack",
"watch": "webpack --watch",
@ -22,110 +25,115 @@
"test": "gulp test",
"format": "gulp format"
},
"resolutions": {
"gulp-cssnano/cssnano/postcss-svgo/svgo/js-yaml": "^3.13.1",
"lodash": "^4.17.13"
},
"dependencies": {
"@fortawesome/fontawesome-svg-core": "1.2.15",
"@fortawesome/free-brands-svg-icons": "5.7.2",
"@fortawesome/free-regular-svg-icons": "5.7.2",
"@fortawesome/free-solid-svg-icons": "5.7.2",
"@fortawesome/vue-fontawesome": "0.1.5",
"@koa/cors": "2.2.3",
"@prezzemolo/rap": "0.1.2",
"@prezzemolo/zip": "0.0.3",
"@elastic/elasticsearch": "7.3.0",
"@fortawesome/fontawesome-svg-core": "1.2.19",
"@fortawesome/free-brands-svg-icons": "5.9.0",
"@fortawesome/free-regular-svg-icons": "5.9.0",
"@fortawesome/free-solid-svg-icons": "5.9.0",
"@fortawesome/vue-fontawesome": "0.1.6",
"@koa/cors": "3.0.0",
"@types/bcryptjs": "2.4.2",
"@types/bull": "3.5.11",
"@types/bull": "3.5.15",
"@types/cbor": "2.0.0",
"@types/dateformat": "3.0.0",
"@types/deep-equal": "1.0.1",
"@types/double-ended-queue": "2.1.0",
"@types/elasticsearch": "5.0.32",
"@types/file-type": "10.9.1",
"@types/double-ended-queue": "2.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/gulp-uglify": "3.0.6",
"@types/gulp-util": "3.0.34",
"@types/is-root": "1.0.0",
"@types/is-url": "1.2.28",
"@types/js-yaml": "3.12.1",
"@types/jsdom": "12.2.3",
"@types/jsdom": "12.2.4",
"@types/katex": "0.10.1",
"@types/koa": "2.0.48",
"@types/koa": "2.0.49",
"@types/koa-bodyparser": "5.0.2",
"@types/koa-compress": "2.0.9",
"@types/koa-cors": "0.0.0",
"@types/koa-favicon": "2.0.19",
"@types/koa-logger": "3.1.1",
"@types/koa-mount": "3.0.1",
"@types/koa-mount": "4.0.0",
"@types/koa-multer": "1.0.0",
"@types/koa-router": "7.0.40",
"@types/koa-router": "7.0.42",
"@types/koa-send": "4.1.2",
"@types/koa-views": "2.0.3",
"@types/koa__cors": "2.2.3",
"@types/lolex": "3.1.1",
"@types/minio": "7.0.1",
"@types/mocha": "5.2.6",
"@types/mongodb": "3.1.22",
"@types/monk": "6.0.0",
"@types/node": "11.13.4",
"@types/nodemailer": "4.6.7",
"@types/nprogress": "0.0.29",
"@types/mocha": "5.2.7",
"@types/node": "12.0.10",
"@types/nodemailer": "6.2.0",
"@types/nprogress": "0.2.0",
"@types/oauth": "0.9.1",
"@types/parse5": "5.0.0",
"@types/parsimmon": "1.10.0",
"@types/portscanner": "2.1.0",
"@types/pug": "2.0.4",
"@types/qrcode": "1.3.2",
"@types/qrcode": "1.3.3",
"@types/random-seed": "0.3.3",
"@types/ratelimiter": "2.1.28",
"@types/redis": "2.8.12",
"@types/redis": "2.8.13",
"@types/rename": "1.0.1",
"@types/request": "2.48.1",
"@types/request-promise-native": "1.0.15",
"@types/request": "2.48.2",
"@types/request-promise-native": "1.0.16",
"@types/request-stats": "3.0.0",
"@types/rimraf": "2.0.2",
"@types/sharp": "0.22.1",
"@types/showdown": "1.9.2",
"@types/seedrandom": "2.4.28",
"@types/sharp": "0.22.2",
"@types/showdown": "1.9.3",
"@types/speakeasy": "2.0.4",
"@types/systeminformation": "3.23.1",
"@types/tinycolor2": "1.4.1",
"@types/tinycolor2": "1.4.2",
"@types/tmp": "0.1.0",
"@types/uuid": "3.4.4",
"@types/uuid": "3.4.5",
"@types/web-push": "3.3.0",
"@types/webpack": "4.4.27",
"@types/webpack": "4.4.34",
"@types/webpack-stream": "3.2.10",
"@types/websocket": "0.0.40",
"@types/ws": "6.0.1",
"animejs": "3.0.1",
"apexcharts": "3.6.7",
"@typescript-eslint/parser": "1.11.0",
"agentkeepalive": "4.0.2",
"animejs": "3.1.0",
"apexcharts": "3.8.5",
"autobind-decorator": "2.4.0",
"autosize": "4.0.2",
"autwh": "0.1.0",
"aws-sdk": "2.520.0",
"bcryptjs": "2.4.3",
"bootstrap": "4.3.1",
"bootstrap-vue": "2.0.0-rc.13",
"bull": "3.7.0",
"bull": "3.10.0",
"cafy": "15.1.1",
"cbor": "4.3.0",
"chai": "4.2.0",
"chalk": "2.4.2",
"cli-highlight": "2.1.0",
"cli-highlight": "2.1.1",
"commander": "2.20.0",
"content-disposition": "0.5.3",
"crc-32": "1.2.0",
"css-loader": "2.1.1",
"css-loader": "3.2.0",
"cssnano": "4.1.10",
"dateformat": "3.0.3",
"deep-equal": "1.0.1",
"diskusage": "1.0.0",
"diskusage": "1.1.3",
"double-ended-queue": "2.1.0-0",
"elasticsearch": "15.4.1",
"emojilib": "2.4.0",
"eslint": "5.16.0",
"eslint-plugin-vue": "5.2.2",
"eventemitter3": "3.1.0",
"feed": "2.0.4",
"file-type": "10.11.0",
"eslint": "6.1.0",
"eslint-plugin-vue": "5.2.3",
"eventemitter3": "4.0.0",
"feed": "3.0.0",
"file-type": "12.2.0",
"fluent-ffmpeg": "2.1.2",
"fuckadblock": "3.2.1",
"gulp": "4.0.0",
"gulp": "4.0.2",
"gulp-cssnano": "2.1.3",
"gulp-imagemin": "5.0.3",
"gulp-imagemin": "6.1.0",
"gulp-mocha": "6.0.0",
"gulp-rename": "1.4.0",
"gulp-replace": "1.0.0",
@ -138,20 +146,22 @@
"hard-source-webpack-plugin": "0.13.1",
"html-minifier": "4.0.0",
"http-signature": "1.2.0",
"insert-text-at-cursor": "0.2.0",
"is-root": "2.0.0",
"is-svg": "4.1.0",
"https-proxy-agent": "2.2.2",
"insert-text-at-cursor": "0.3.0",
"is-root": "2.1.0",
"is-svg": "4.2.0",
"js-yaml": "3.13.1",
"jsdom": "14.0.0",
"jsdom": "15.1.1",
"json5": "2.1.0",
"json5-loader": "2.0.0",
"katex": "0.10.1",
"koa": "2.7.0",
"json5-loader": "3.0.0",
"jsrsasign": "8.0.12",
"katex": "0.11.0",
"koa": "2.8.1",
"koa-bodyparser": "4.2.1",
"koa-compress": "3.0.0",
"koa-favicon": "2.0.1",
"koa-json-body": "5.3.0",
"koa-logger": "3.2.0",
"koa-logger": "3.2.1",
"koa-mount": "4.0.0",
"koa-multer": "1.0.2",
"koa-router": "7.4.0",
@ -160,38 +170,35 @@
"koa-views": "6.2.0",
"langmap": "0.0.16",
"loader-utils": "1.2.3",
"lolex": "3.1.0",
"lolex": "4.2.0",
"lookup-dns-cache": "2.1.0",
"minio": "7.0.5",
"mocha": "6.1.3",
"mocha": "6.2.0",
"moji": "0.5.1",
"moment": "2.24.0",
"mongodb": "3.2.3",
"monk": "6.0.6",
"ms": "2.1.1",
"nested-property": "0.0.7",
"node-fetch": "2.3.0",
"nodemailer": "6.1.0",
"ms": "2.1.2",
"nested-property": "1.0.1",
"node-fetch": "2.6.0",
"nodemailer": "6.3.0",
"nprogress": "0.2.0",
"object-assign-deep": "0.4.0",
"os-utils": "0.0.14",
"parse5": "5.1.0",
"parsimmon": "1.12.0",
"pg": "7.9.0",
"parsimmon": "1.13.0",
"pg": "7.12.1",
"portscanner": "2.2.0",
"postcss-loader": "3.0.0",
"prismjs": "1.16.0",
"prismjs": "1.17.1",
"progress-bar-webpack-plugin": "1.12.1",
"promise-any": "0.2.0",
"promise-limit": "2.7.0",
"promise-sequential": "1.1.1",
"pug": "2.0.3",
"pug": "2.0.4",
"punycode": "2.1.1",
"qrcode": "1.3.3",
"pureimage": "0.1.6",
"qrcode": "1.4.1",
"random-seed": "0.3.0",
"randomcolor": "0.5.4",
"ratelimiter": "3.3.0",
"ratelimiter": "3.3.1",
"recaptcha-promise": "0.1.3",
"reconnecting-websocket": "4.1.10",
"reconnecting-websocket": "4.2.0",
"redis": "2.8.0",
"reflect-metadata": "0.1.13",
"rename": "1.0.4",
@ -202,59 +209,63 @@
"rimraf": "2.6.3",
"rndstr": "1.0.0",
"s-age": "1.1.2",
"sharp": "0.22.0",
"seedrandom": "3.0.3",
"sharp": "0.23.0",
"showdown": "1.9.0",
"showdown-highlightjs-extension": "0.1.2",
"speakeasy": "2.0.0",
"stringz": "1.0.0",
"stringz": "2.0.0",
"style-loader": "0.23.1",
"stylus": "0.54.5",
"stylus": "0.54.7",
"stylus-loader": "3.0.2",
"summaly": "2.2.0",
"systeminformation": "4.1.4",
"summaly": "2.3.1",
"syslog-pro": "1.0.0",
"systeminformation": "4.14.8",
"syuilo-password-strength": "0.0.1",
"terser-webpack-plugin": "1.2.3",
"terser-webpack-plugin": "1.4.1",
"textarea-caret": "3.1.0",
"three": "0.108.0",
"tinycolor2": "1.4.1",
"tmp": "0.1.0",
"ts-loader": "5.3.3",
"ts-node": "7.0.1",
"tslint": "5.15.0",
"tslint": "5.18.0",
"tslint-sonarts": "1.9.0",
"typeorm": "0.2.16-rc.1",
"typescript": "3.3.3333",
"typescript-eslint-parser": "22.0.0",
"typeorm": "0.2.18",
"typescript": "3.5.3",
"uglify-es": "3.3.9",
"ulid": "2.3.0",
"url-loader": "1.1.2",
"uuid": "3.3.2",
"url-loader": "2.1.0",
"uuid": "3.3.3",
"v-animate-css": "0.0.3",
"v-debounce": "0.1.2",
"video-thumbnail-generator": "1.1.3",
"vue": "2.6.10",
"vue-color": "2.7.0",
"vue-content-loading": "1.6.0",
"vue-cropperjs": "3.0.0",
"vue-i18n": "8.10.0",
"vue-js-modal": "1.3.28",
"vue-json-pretty": "1.6.0",
"vue-loader": "15.7.0",
"vue-cropperjs": "4.0.0",
"vue-i18n": "8.14.0",
"vue-js-modal": "1.3.31",
"vue-json-pretty": "1.6.1",
"vue-loader": "15.7.1",
"vue-marquee-text-component": "1.1.1",
"vue-prism-component": "1.1.1",
"vue-router": "3.0.4",
"vue-router": "3.1.2",
"vue-sequential-entrance": "1.1.3",
"vue-style-loader": "4.1.2",
"vue-svg-inline-loader": "1.2.15",
"vue-svg-inline-loader": "1.2.17",
"vue-template-compiler": "2.6.10",
"vuedraggable": "2.20.0",
"vuedraggable": "2.23.0",
"vuewordcloud": "18.7.11",
"vuex": "3.1.0",
"vuex": "3.1.1",
"vuex-persistedstate": "2.5.4",
"web-push": "3.3.3",
"webpack": "4.30.0",
"webpack-cli": "3.3.0",
"websocket": "1.0.28",
"ws": "6.2.1",
"web-push": "3.3.5",
"webpack": "4.39.3",
"webpack-cli": "3.3.7",
"websocket": "1.0.29",
"ws": "7.1.2",
"xev": "2.0.1"
},
"devDependencies": {
"@types/fluent-ffmpeg": "2.1.10"
}
}

803
src/@types/jsrsasign.d.ts vendored Normal file
View File

@ -0,0 +1,803 @@
// Attention: Partial Type Definition
declare module 'jsrsasign' {
//// HELPER TYPES
/**
* Attention: The value might be changed by the function.
*/
type Mutable<T> = T;
/**
* Deprecated: The function might be deleted in future release.
*/
type Deprecated<T> = T;
//// COMMON TYPES
/**
* byte number
*/
type ByteNumber = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255;
/**
* hexadecimal string /[0-9A-F]/
*/
type HexString = string;
/**
* binary string /[01]/
*/
type BinString = string;
/**
* base64 string /[A-Za-z0-9+/]=+/
*/
type Base64String = string;
/**
* base64 URL encoded string /[A-Za-z0-9_-]/
*/
type Base64URLString = string;
/**
* time value (ex. "151231235959Z")
*/
type TimeValue = string;
/**
* OID string (ex. '1.2.3.4.567')
*/
type OID = string;
/**
* OID name
*/
type OIDName = string;
/**
* PEM formatted string
*/
type PEM = string;
//// ASN1 TYPES
class ASN1Object {
public isModified: boolean;
public hTLV: ASN1TLV;
public hT: ASN1T;
public hL: ASN1L;
public hV: ASN1V;
public getLengthHexFromValue(): HexString;
public getEncodedHex(): ASN1TLV;
public getValueHex(): ASN1V;
public getFreshValueHex(): ASN1V;
}
class DERAbstractStructured extends ASN1Object {
constructor(params?: Partial<Record<'array', ASN1Object[]>>);
public setByASN1ObjectArray(asn1ObjectArray: ASN1Object[]): void;
public appendASN1Object(asn1Object: ASN1Object): void;
}
class DERSequence extends DERAbstractStructured {
constructor(params?: Partial<Record<'array', ASN1Object[]>>);
public getFreshValueHex(): ASN1V;
}
//// ASN1HEX TYPES
/**
* ASN.1 DER encoded data (hexadecimal string)
*/
type ASN1S = HexString;
/**
* index of something
*/
type Idx<T extends { [idx: string]: unknown } | { [idx: number]: unknown }> = ASN1S extends { [idx: string]: unknown } ? string : ASN1S extends { [idx: number]: unknown } ? number : never;
/**
* byte length of something
*/
type ByteLength<T extends { length: unknown }> = T['length'];
/**
* ASN.1 L(length) (hexadecimal string)
*/
type ASN1L = HexString;
/**
* ASN.1 T(tag) (hexadecimal string)
*/
type ASN1T = HexString;
/**
* ASN.1 V(value) (hexadecimal string)
*/
type ASN1V = HexString;
/**
* ASN.1 TLV (hexadecimal string)
*/
type ASN1TLV = HexString;
/**
* ASN.1 object string
*/
type ASN1ObjectString = string;
/**
* nth
*/
type Nth = number;
/**
* ASN.1 DER encoded OID value (hexadecimal string)
*/
type ASN1OIDV = HexString;
class ASN1HEX {
public static getLblen(s: ASN1S, idx: Idx<ASN1S>): ByteLength<ASN1L>;
public static getL(s: ASN1S, idx: Idx<ASN1S>): ASN1L;
public static getVblen(s: ASN1S, idx: Idx<ASN1S>): ByteLength<ASN1V>;
public static getVidx(s: ASN1S, idx: Idx<ASN1S>): Idx<ASN1V>;
public static getV(s: ASN1S, idx: Idx<ASN1S>): ASN1V;
public static getTLV(s: ASN1S, idx: Idx<ASN1S>): ASN1TLV;
public static getNextSiblingIdx(s: ASN1S, idx: Idx<ASN1S>): Idx<ASN1ObjectString>;
public static getChildIdx(h: ASN1S, pos: Idx<ASN1S>): Idx<ASN1ObjectString>[];
public static getNthChildIdx(h: ASN1S, idx: Idx<ASN1S>, nth: Nth): Idx<ASN1ObjectString>;
public static getIdxbyList(h: ASN1S, currentIndex: Idx<ASN1ObjectString>, nthList: Mutable<Nth[]>, checkingTag?: string): Idx<Mutable<Nth[]>>;
public static getTLVbyList(h: ASN1S, currentIndex: Idx<ASN1ObjectString>, nthList: Mutable<Nth[]>, checkingTag?: string): ASN1TLV;
public static getVbyList(h: ASN1S, currentIndex: Idx<ASN1ObjectString>, nthList: Mutable<Nth[]>, checkingTag?: string, removeUnusedbits?: boolean): ASN1V;
public static hextooidstr(hex: ASN1OIDV): OID;
public static dump(hexOrObj: ASN1S | ASN1Object, flags?: Record<string, unknown>, idx?: Idx<ASN1S>, indent?: string): string;
public static isASN1HEX(hex: string): hex is HexString;
public static oidname(oidDotOrHex: OID | ASN1OIDV): OIDName;
}
//// BIG INTEGER TYPES (PARTIAL)
class BigInteger {
constructor(a: null);
constructor(a: number, b: SecureRandom);
constructor(a: number, b: number, c: SecureRandom);
constructor(a: unknown);
constructor(a: string, b: number);
public am(i: number, x: number, w: number, j: number, c: number, n: number): number;
public DB: number;
public DM: number;
public DV: number;
public FV: number;
public F1: number;
public F2: number;
protected copyTo(r: Mutable<BigInteger>): void;
protected fromInt(x: number): void;
protected fromString(s: string, b: number): void;
protected clamp(): void;
public toString(b: number): string;
public negate(): BigInteger;
public abs(): BigInteger;
public compareTo(a: BigInteger): number;
public bitLength(): number;
protected dlShiftTo(n: number, r: Mutable<BigInteger>): void;
protected drShiftTo(n: number, r: Mutable<BigInteger>): void;
protected lShiftTo(n: number, r: Mutable<BigInteger>): void;
protected rShiftTo(n: number, r: Mutable<BigInteger>): void;
protected subTo(a: BigInteger, r: Mutable<BigInteger>): void;
protected multiplyTo(a: BigInteger, r: Mutable<BigInteger>): void;
protected squareTo(r: Mutable<BigInteger>): void;
protected divRemTo(m: BigInteger, q: Mutable<BigInteger>, r: Mutable<BigInteger>): void;
public mod(a: BigInteger): BigInteger;
protected invDigit(): number;
protected isEven(): boolean;
protected exp(e: number, z: Classic | Montgomery): BigInteger;
public modPowInt(e: number, m: BigInteger): BigInteger;
public static ZERO: BigInteger;
public static ONE: BigInteger;
}
class Classic {
constructor(m: BigInteger);
public convert(x: BigInteger): BigInteger;
public revert(x: BigInteger): BigInteger;
public reduce(x: Mutable<BigInteger>): void;
public mulTo(x: BigInteger, r: Mutable<BigInteger>): void;
public sqrTo(x: BigInteger, y: BigInteger, r: Mutable<BigInteger>): void;
}
class Montgomery {
constructor(m: BigInteger);
public convert(x: BigInteger): BigInteger;
public revert(x: BigInteger): BigInteger;
public reduce(x: Mutable<BigInteger>): void;
public mulTo(x: BigInteger, r: Mutable<BigInteger>): void;
public sqrTo(x: BigInteger, y: BigInteger, r: Mutable<BigInteger>): void;
}
//// KEYUTIL TYPES
type DecryptAES = (dataHex: HexString, keyHex: HexString, ivHex: HexString) => HexString;
type Decrypt3DES = (dataHex: HexString, keyHex: HexString, ivHex: HexString) => HexString;
type DecryptDES = (dataHex: HexString, keyHex: HexString, ivHex: HexString) => HexString;
type EncryptAES = (dataHex: HexString, keyHex: HexString, ivHex: HexString) => HexString;
type Encrypt3DES = (dataHex: HexString, keyHex: HexString, ivHex: HexString) => HexString;
type EncryptDES = (dataHex: HexString, keyHex: HexString, ivHex: HexString) => HexString;
type AlgList = {
'AES-256-CBC': { 'proc': DecryptAES; 'eproc': EncryptAES; keylen: 32; ivlen: 16; };
'AES-192-CBC': { 'proc': DecryptAES; 'eproc': EncryptAES; keylen: 24; ivlen: 16; };
'AES-128-CBC': { 'proc': DecryptAES; 'eproc': EncryptAES; keylen: 16; ivlen: 16; };
'DES-EDE3-CBC': { 'proc': Decrypt3DES; 'eproc': Encrypt3DES; keylen: 24; ivlen: 8; };
'DES-CBC': { 'proc': DecryptDES; 'eproc': EncryptDES; keylen: 8; ivlen: 8; };
};
type AlgName = keyof AlgList;
type PEMHeadAlgName = 'RSA' | 'EC' | 'DSA';
type GetKeyRSAParam = RSAKey | {
n: BigInteger;
e: number;
} | Record<'n' | 'e', HexString> | Record<'n' | 'e', HexString> & Record<'d' | 'p' | 'q' | 'dp' | 'dq' | 'co', HexString | null> | {
n: BigInteger;
e: number;
d: BigInteger;
} | {
kty: 'RSA';
} & Record<'n' | 'e', Base64URLString> | {
kty: 'RSA';
} & Record<'n' | 'e' | 'd' | 'p' | 'q' | 'dp' | 'dq' | 'qi', Base64URLString> | {
kty: 'RSA';
} & Record<'n' | 'e' | 'd', Base64URLString>;
type GetKeyECDSAParam = KJUR.crypto.ECDSA | {
curve: KJUR.crypto.CurveName;
xy: HexString;
} | {
curve: KJUR.crypto.CurveName;
d: HexString;
} | {
kty: 'EC';
crv: KJUR.crypto.CurveName;
x: Base64URLString;
y: Base64URLString;
} | {
kty: 'EC';
crv: KJUR.crypto.CurveName;
x: Base64URLString;
y: Base64URLString;
d: Base64URLString;
};
type GetKeyDSAParam = KJUR.crypto.DSA | Record<'p' | 'q' | 'g', BigInteger> & Record<'y', BigInteger | null> | Record<'p' | 'q' | 'g' | 'x', BigInteger> & Record<'y', BigInteger | null>;
type GetKeyParam = GetKeyRSAParam | GetKeyECDSAParam | GetKeyDSAParam | string;
class KEYUTIL {
public version: '1.0.0';
public parsePKCS5PEM(sPKCS5PEM: PEM): Partial<Record<'type' | 's', string>> & (Record<'cipher' | 'ivsalt', string> | Record<'cipher' | 'ivsalt', undefined>);
public getKeyAndUnusedIvByPasscodeAndIvsalt(algName: AlgName, passcode: string, ivsaltHex: HexString): Record<'keyhex' | 'ivhex', HexString>;
public decryptKeyB64(privateKeyB64: Base64String, sharedKeyAlgName: AlgName, sharedKeyHex: HexString, ivsaltHex: HexString): Base64String;
public getDecryptedKeyHex(sEncryptedPEM: PEM, passcode: string): HexString;
public getEncryptedPKCS5PEMFromPrvKeyHex(pemHeadAlg: PEMHeadAlgName, hPrvKey: string, passcode: string, sharedKeyAlgName?: AlgName | null, ivsaltHex?: HexString | null): PEM;
public parseHexOfEncryptedPKCS8(sHEX: HexString): {
ciphertext: ASN1V;
encryptionSchemeAlg: 'TripleDES';
encryptionSchemeIV: ASN1V;
pbkdf2Salt: ASN1V;
pbkdf2Iter: number;
};
public getPBKDF2KeyHexFromParam(info: ReturnType<this['parseHexOfEncryptedPKCS8']>, passcode: string): HexString;
private _getPlainPKCS8HexFromEncryptedPKCS8PEM(pkcs8PEM: PEM, passcode: string): HexString;
public getKeyFromEncryptedPKCS8PEM(prvKeyHex: HexString): ReturnType<this['getKeyFromPlainPrivatePKCS8Hex']>;
public parsePlainPrivatePKCS8Hex(pkcs8PrvHex: HexString): {
algparam: ASN1V | null;
algoid: ASN1V;
keyidx: Idx<ASN1V>;
};
public getKeyFromPlainPrivatePKCS8PEM(prvKeyHex: HexString): ReturnType<this['getKeyFromPlainPrivatePKCS8Hex']>;
public getKeyFromPlainPrivatePKCS8Hex(prvKeyHex: HexString): RSAKey | KJUR.crypto.DSA | KJUR.crypto.ECDSA;
private _getKeyFromPublicPKCS8Hex(h: HexString): RSAKey | KJUR.crypto.DSA | KJUR.crypto.ECDSA;
public parsePublicRawRSAKeyHex(pubRawRSAHex: HexString): Record<'n' | 'e', ASN1V>;
public parsePublicPKCS8Hex(pkcs8PubHex: HexString): {
algparam: ASN1V | Record<'p' | 'q' | 'g', ASN1V> | null;
algoid: ASN1V;
key: ASN1V;
};
public static getKey(param: GetKeyRSAParam): RSAKey;
public static getKey(param: GetKeyECDSAParam): KJUR.crypto.ECDSA;
public static getKey(param: GetKeyDSAParam): KJUR.crypto.DSA;
public static getKey(param: string, passcode?: string, hextype?: string): RSAKey | KJUR.crypto.ECDSA | KJUR.crypto.DSA;
public static generateKeypair(alg: 'RSA', keylen: number): Record<'prvKeyObj' | 'pubKeyObj', RSAKey>;
public static generateKeypair(alg: 'EC', curve: KJUR.crypto.CurveName): Record<'prvKeyObj' | 'pubKeyObj', KJUR.crypto.ECDSA>;
public static getPEM(keyObjOrHex: RSAKey | KJUR.crypto.ECDSA | KJUR.crypto.DSA, formatType?: 'PKCS1PRV' | 'PKCS5PRV' | 'PKCS8PRV', passwd?: string, encAlg?: 'DES-CBC' | 'DES-EDE3-CBC' | 'AES-128-CBC' | 'AES-192-CBC' | 'AES-256-CBC', hexType?: string, ivsaltHex?: HexString): object; // To Do
public static getKeyFromCSRPEM(csrPEM: PEM): RSAKey | KJUR.crypto.ECDSA | KJUR.crypto.DSA;
public static getKeyFromCSRHex(csrHex: HexString): RSAKey | KJUR.crypto.ECDSA | KJUR.crypto.DSA;
public static parseCSRHex(csrHex: HexString): Record<'p8pubkeyhex', ASN1TLV>;
public static getJWKFromKey(keyObj: RSAKey): {
kty: 'RSA';
} & Record<'n' | 'e' | 'd' | 'p' | 'q' | 'dp' | 'dq' | 'qi', Base64URLString> | {
kty: 'RSA';
} & Record<'n' | 'e', Base64URLString>;
public static getJWKFromKey(keyObj: KJUR.crypto.ECDSA): {
kty: 'EC';
crv: KJUR.crypto.CurveName;
x: Base64URLString;
y: Base64URLString;
d: Base64URLString;
} | {
kty: 'EC';
crv: KJUR.crypto.CurveName;
x: Base64URLString;
y: Base64URLString;
};
}
//// KJUR NAMESPACE (PARTIAL)
namespace KJUR {
namespace crypto {
type CurveName = 'secp128r1' | 'secp160k1' | 'secp160r1' | 'secp192k1' | 'secp192r1' | 'secp224r1' | 'secp256k1' | 'secp256r1' | 'secp384r1' | 'secp521r1';
class DSA {
public p: BigInteger | null;
public q: BigInteger | null;
public g: BigInteger | null;
public y: BigInteger | null;
public x: BigInteger | null;
public type: 'DSA';
public isPrivate: boolean;
public isPublic: boolean;
public setPrivate(p: BigInteger, q: BigInteger, g: BigInteger, y: BigInteger | null, x: BigInteger): void;
public setPrivateHex(hP: HexString, hQ: HexString, hG: HexString, hY: HexString | null, hX: HexString): void;
public setPublic(p: BigInteger, q: BigInteger, g: BigInteger, y: BigInteger): void;
public setPublicHex(hP: HexString, hQ: HexString, hG: HexString, hY: HexString): void;
public signWithMessageHash(sHashHex: HexString): HexString;
public verifyWithMessageHash(sHashHex: HexString, hSigVal: HexString): boolean;
public parseASN1Signature(hSigVal: HexString): [BigInteger, BigInteger];
public readPKCS5PrvKeyHex(h: HexString): void;
public readPKCS8PrvKeyHex(h: HexString): void;
public readPKCS8PubKeyHex(h: HexString): void;
public readCertPubKeyHex(h: HexString, nthPKI: number): void;
}
class ECDSA {
constructor(params?: {
curve?: CurveName;
prv?: HexString;
pub?: HexString;
});
public p: BigInteger | null;
public q: BigInteger | null;
public g: BigInteger | null;
public y: BigInteger | null;
public x: BigInteger | null;
public type: 'EC';
public isPrivate: boolean;
public isPublic: boolean;
public getBigRandom(limit: BigInteger): BigInteger;
public setNamedCurve(curveName: CurveName): void;
public setPrivateKeyHex(prvKeyHex: HexString): void;
public setPublicKeyHex(pubKeyHex: HexString): void;
public getPublicKeyXYHex(): Record<'x' | 'y', HexString>;
public getShortNISTPCurveName(): 'P-256' | 'P-384' | null;
public generateKeyPairHex(): Record<'ecprvhex' | 'ecpubhex', HexString>;
public signWithMessageHash(hashHex: HexString): HexString;
public signHex(hashHex: HexString, privHex: HexString): HexString;
public verifyWithMessageHash(sHashHex: HexString, hSigVal: HexString): boolean;
public parseASN1Signature(hSigVal: HexString): [BigInteger, BigInteger];
public readPKCS5PrvKeyHex(h: HexString): void;
public readPKCS8PrvKeyHex(h: HexString): void;
public readPKCS8PubKeyHex(h: HexString): void;
public readCertPubKeyHex(h: HexString, nthPKI: number): void;
public static parseSigHex(sigHex: HexString): Record<'r' | 's', BigInteger>;
public static parseSigHexInHexRS(sigHex: HexString): Record<'r' | 's', ASN1V>;
public static asn1SigToConcatSig(asn1Sig: HexString): HexString;
public static concatSigToASN1Sig(concatSig: HexString): ASN1TLV;
public static hexRSSigToASN1Sig(hR: HexString, hS: HexString): ASN1TLV;
public static biRSSigToASN1Sig(biR: BigInteger, biS: BigInteger): ASN1TLV;
public static getName(s: CurveName | HexString): 'secp256r1' | 'secp256k1' | 'secp384r1' | null;
}
class Signature {
constructor(params?: ({
alg: string;
prov?: string;
} | {}) & ({
psssaltlen: number;
} | {}) & ({
prvkeypem: PEM;
prvkeypas?: never;
} | {}));
private _setAlgNames(): void;
private _zeroPaddingOfSignature(hex: HexString, bitLength: number): HexString;
public setAlgAndProvider(alg: string, prov: string): void;
public init(key: GetKeyParam, pass?: string): void;
public updateString(str: string): void;
public updateHex(hex: HexString): void;
public sign(): HexString;
public signString(str: string): HexString;
public signHex(hex: HexString): HexString;
public verify(hSigVal: string): boolean | 0;
}
}
}
//// RSAKEY TYPES
class RSAKey {
public n: BigInteger | null;
public e: number;
public d: BigInteger | null;
public p: BigInteger | null;
public q: BigInteger | null;
public dmp1: BigInteger | null;
public dmq1: BigInteger | null;
public coeff: BigInteger | null;
public type: 'RSA';
public isPrivate?: boolean;
public isPublic?: boolean;
//// RSA PUBLIC
protected doPublic(x: BigInteger): BigInteger;
public setPublic(N: BigInteger, E: number): void;
public setPublic(N: HexString, E: HexString): void;
public encrypt(text: string): HexString | null;
public encryptOAEP(text: string, hash?: string, hashLen?: number): HexString | null;
public encryptOAEP(text: string, hash?: (s: string) => string, hashLen?: number): HexString | null;
//// RSA PRIVATE
protected doPrivate(x: BigInteger): BigInteger;
public setPrivate(N: BigInteger, E: number, D: BigInteger): void;
public setPrivate(N: HexString, E: HexString, D: HexString): void;
public setPrivateEx(N: HexString, E: HexString, D?: HexString | null, P?: HexString | null, Q?: HexString | null, DP?: HexString | null, DQ?: HexString | null, C?: HexString | null): void;
public generate(B: number, E: HexString): void;
public decrypt(ctext: HexString): string;
public decryptOAEP(ctext: HexString, hash?: string, hashLen?: number): string | null;
public encryptOAEP(ctext: HexString, hash?: (s: string) => string, hashLen?: number): string | null;
//// RSA PEM
public getPosArrayOfChildrenFromHex(hPrivateKey: PEM): Idx<ASN1ObjectString>[];
public getHexValueArrayOfChildrenFromHex(hPrivateKey: PEM): Idx<ASN1ObjectString>[];
public readPrivateKeyFromPEMString(keyPEM: PEM): void;
public readPKCS5PrvKeyHex(h: HexString): void;
public readPKCS8PrvKeyHex(h: HexString): void;
public readPKCS5PubKeyHex(h: HexString): void;
public readPKCS8PubKeyHex(h: HexString): void;
public readCertPubKeyHex(h: HexString, nthPKI: Nth): void;
//// RSA SIGN
public sign(s: string, hashAlg: string): HexString;
public signWithMessageHash(sHashHex: HexString, hashAlg: string): HexString;
public signPSS(s: string, hashAlg: string, sLen: number): HexString;
public signWithMessageHashPSS(hHash: HexString, hashAlg: string, sLen: number): HexString;
public verify(sMsg: string, hSig: HexString): boolean | 0;
public verifyWithMessageHash(sHashHex: HexString, hSig: HexString): boolean | 0;
public verifyPSS(sMsg: string, hSig: HexString, hashAlg: string, sLen: number): boolean;
public verifyWithMessageHashPSS(hHash: HexString, hSig: HexString, hashAlg: string, sLen: number): boolean;
public static SALT_LEN_HLEN: -1;
public static SALT_LEN_MAX: -2;
public static SALT_LEN_RECOVER: -2;
}
/// RNG TYPES
class SecureRandom {
public nextBytes(ba: Mutable<ByteNumber[]>): void;
}
//// X509 TYPES
type ExtInfo = {
critical: boolean;
oid: OID;
vidx: Idx<ASN1V>;
};
type ExtAIAInfo = Record<'ocsp' | 'caissuer', string>;
type ExtCertificatePolicy = {
id: OIDName;
} & Partial<{
cps: string;
} | {
unotice: string;
}>;
class X509 {
public hex: HexString | null;
public version: number;
public foffset: number;
public aExtInfo: null;
public getVersion(): number;
public getSerialNumberHex(): ASN1V;
public getSignatureAlgorithmField(): OIDName;
public getIssuerHex(): ASN1TLV;
public getIssuerString(): HexString;
public getSubjectHex(): ASN1TLV;
public getSubjectString(): HexString;
public getNotBefore(): TimeValue;
public getNotAfter(): TimeValue;
public getPublicKeyHex(): ASN1TLV;
public getPublicKeyIdx(): Idx<Mutable<Nth[]>>;
public getPublicKeyContentIdx(): Idx<Mutable<Nth[]>>;
public getPublicKey(): RSAKey | KJUR.crypto.ECDSA | KJUR.crypto.DSA;
public getSignatureAlgorithmName(): OIDName;
public getSignatureValueHex(): ASN1V;
public verifySignature(pubKey: GetKeyParam): boolean | 0;
public parseExt(): void;
public getExtInfo(oidOrName: OID | string): ExtInfo | undefined;
public getExtBasicConstraints(): ExtInfo | {} | {
cA: true;
pathLen?: number;
};
public getExtKeyUsageBin(): BinString;
public getExtKeyUsageString(): string;
public getExtSubjectKeyIdentifier(): ASN1V | undefined;
public getExtAuthorityKeyIdentifier(): {
kid: ASN1V;
} | undefined;
public getExtExtKeyUsageName(): OIDName[] | undefined;
public getExtSubjectAltName(): Deprecated<string[]>;
public getExtSubjectAltName2(): ['MAIL' | 'DNS' | 'DN' | 'URI' | 'IP', string][] | undefined;
public getExtCRLDistributionPointsURI(): string[] | undefined;
public getExtAIAInfo(): ExtAIAInfo | undefined;
public getExtCertificatePolicies(): ExtCertificatePolicy[] | undefined;
public readCertPEM(sCertPEM: PEM): void;
public readCertHex(sCertHex: HexString): void;
public getInfo(): string;
public static hex2dn(hex: HexString, idx?: Idx<HexString>): string;
public static hex2rdn(hex: HexString, idx?: Idx<HexString>): string;
public static hex2attrTypeValue(hex: HexString, idx?: Idx<HexString>): string;
public static getPublicKeyFromCertPEM(sCertPEM: PEM): RSAKey | KJUR.crypto.ECDSA | KJUR.crypto.DSA;
public static getPublicKeyInfoPropOfCertPEM(sCertPEM: PEM): {
algparam: ASN1V | null;
leyhex: ASN1V;
algoid: ASN1V;
};
}
}

View File

@ -1,17 +1,9 @@
declare module 'lookup-dns-cache' {
type IPv4 = 4;
import { LookupOneOptions, LookupAllOptions, LookupOptions, LookupAddress } from 'dns';
type IPv6 = 6;
type Family = IPv4 | IPv6 | undefined;
interface IRunOptions {
family?: Family;
all?: boolean;
}
type RunCallback = (error: Error | null, address?: string | string[], family?: Family) => void;
export function lookup(hostname: string, options: IRunOptions | Family, callback: RunCallback): {} | undefined;
export function lookup(hostname: string, callback: RunCallback): {} | undefined;
function lookup(hostname: string, family: number, callback: (err: NodeJS.ErrnoException | null, address: string, family: number) => void): void;
function lookup(hostname: string, options: LookupOneOptions, callback: (err: NodeJS.ErrnoException | null, address: string, family: number) => void): void;
function lookup(hostname: string, options: LookupAllOptions, callback: (err: NodeJS.ErrnoException | null, addresses: LookupAddress[]) => void): void;
function lookup(hostname: string, options: LookupOptions, callback: (err: NodeJS.ErrnoException | null, address: string | LookupAddress[], family: number) => void): void;
function lookup(hostname: string, callback: (err: NodeJS.ErrnoException | null, address: string, family: number) => void): void;
}

View File

@ -1,7 +0,0 @@
declare module 'promise-any' {
function promiseAny<T>(iterable: Iterable<T | PromiseLike<T>>): Promise<T>;
namespace promiseAny {} // Hack
export = promiseAny;
}

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, and @acid-chicken.');
console.log(' Misskey is maintained by @syuilo, @AyaMorisawa, @mei23, @acid-chicken, and @rinsuki.');
console.log(chalk.keyword('orange')(' If you like Misskey, please donate to support development. https://www.patreon.com/syuilo'));
console.log('');
@ -50,7 +50,7 @@ export async function masterMain() {
// initialize app
config = await init();
if (config.port == null) {
if (config.port == null || Number.isNaN(config.port)) {
bootLogger.error('The port is not configured. Please configure port.', null, true);
process.exit(1);
}
@ -79,6 +79,7 @@ export async function masterMain() {
require('../daemons/server-stats').default();
require('../daemons/notes-stats').default();
require('../daemons/queue-stats').default();
require('../daemons/janitor').default();
}
bootLogger.succ(`Now listening on port ${config.port} on ${config.url}`, null, true);
@ -158,7 +159,7 @@ async function init(): Promise<Config> {
return config;
}
async function spawnWorkers(limit: number = Infinity) {
async function spawnWorkers(limit: number = 1) {
const workers = Math.min(limit, os.cpus().length);
bootLogger.info(`Starting ${workers} worker${workers === 1 ? '' : 's'}...`);
await Promise.all([...Array(workers)].map(spawnWorker));

View File

@ -19,7 +19,8 @@ init(launch => {
mode: 'history',
base: '/admin/',
routes: [
{ path: '/', component: Index },
{ path: '/:page', component: Index },
{ path: '/', redirect: '/dashboard' },
{ path: '*', component: NotFound }
]
});

View File

@ -1,7 +1,7 @@
<template>
<div>
<ui-card>
<template #title><fa icon="broadcast-tower"/> {{ $t('announcements') }}</template>
<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>
@ -9,13 +9,16 @@
<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="plus"/> {{ $t('add') }}</ui-button>
<ui-button @click="add"><fa :icon="faPlus"/> {{ $t('add') }}</ui-button>
</section>
</ui-card>
</div>
@ -24,12 +27,14 @@
<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
};
},
@ -43,7 +48,8 @@ export default Vue.extend({
add() {
this.announcements.unshift({
title: '',
text: ''
text: '',
image: null
});
},

View File

@ -124,7 +124,7 @@ export default Vue.extend({
this.connection = this.$root.stream.useSharedConnection('serverStats');
this.updateStats();
this.clock = setInterval(this.updateStats, 1000);
this.clock = setInterval(this.updateStats, 3000);
this.$root.getMeta().then(meta => {
this.meta = meta;

View File

@ -0,0 +1,61 @@
<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

@ -14,6 +14,10 @@
<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>
@ -227,6 +231,29 @@ export default Vue.extend({
});
});
},
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>
@ -242,7 +269,7 @@ export default Vue.extend({
> div:nth-child(1)
> .thumbnail
display block
display flex
width 64px
height 64px
background-size cover

View File

@ -54,7 +54,6 @@
<span>{{ $t('latest-request-received-at') }}</span>
<template #prefix><fa :icon="faInbox"/></template>
</ui-input>
<ui-switch v-model="instance.isBlocked" @change="updateInstance()">{{ $t('block') }}</ui-switch>
<ui-switch v-model="instance.isMarkedAsClosed" @change="updateInstance()">{{ $t('marked-as-closed') }}</ui-switch>
<details>
<summary>{{ $t('charts') }}</summary>
@ -79,6 +78,10 @@
</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>
@ -130,7 +133,7 @@
<span>{{ $t('status') }}</span>
</header>
<div v-for="instance in instances" :style="{ opacity: instance.isNotResponding ? 0.5 : 1 }">
<a @click.prevent="showInstance(instance.host)" target="_blank" :href="`https://${instance.host}`" :style="{ textDecoration: instance.isMarkedAsClosed ? 'line-through' : 'none' }">{{ instance.host }}</a>
<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>
@ -142,6 +145,16 @@
<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>
@ -149,7 +162,7 @@
import Vue from 'vue';
import i18n from '../../i18n';
import { faPaperPlane } from '@fortawesome/free-regular-svg-icons';
import { faGlobe, faTerminal, faSearch, faMinusCircle, faServer, faCrosshairs, faEnvelopeOpenText, faUsers, faCaretDown, faCaretUp, faTrafficLight, faInbox } from '@fortawesome/free-solid-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';
@ -176,7 +189,8 @@ export default Vue.extend({
chartSrc: 'requests',
chartSpan: 'hour',
chartInstance: null,
faGlobe, faTerminal, faSearch, faMinusCircle, faServer, faCrosshairs, faEnvelopeOpenText, faUsers, faCaretDown, faCaretUp, faPaperPlane, faTrafficLight, faInbox
blockedHosts: '',
faTrashAlt, faBan, faGlobe, faTerminal, faSearch, faMinusCircle, faServer, faCrosshairs, faEnvelopeOpenText, faUsers, faCaretDown, faCaretUp, faPaperPlane, faTrafficLight, faInbox
};
},
@ -246,6 +260,10 @@ export default Vue.extend({
mounted() {
this.fetchInstances();
this.$root.getMeta().then(meta => {
this.blockedHosts = meta.blockedHosts.join('\n');
});
},
beforeDestroy() {
@ -293,6 +311,17 @@ export default Vue.extend({
});
},
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,
@ -477,6 +506,22 @@ export default Vue.extend({
}]
};
},
saveBlockedHosts() {
this.$root.api('admin/update-meta', {
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>

View File

@ -1,41 +0,0 @@
<template>
<div>
<ui-card>
<template #title>{{ $t('hided-tags') }}</template>
<section>
<textarea class="jdnqwkzlnxcfftthoybjxrebyolvoucw" v-model="hiddenTags"></textarea>
<ui-button @click="save">{{ $t('save') }}</ui-button>
</section>
</ui-card>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import i18n from '../../i18n';
export default Vue.extend({
i18n: i18n('admin/views/hashtags.vue'),
data() {
return {
hiddenTags: '',
};
},
created() {
this.$root.getMeta().then(meta => {
this.hiddenTags = meta.hiddenTags.join('\n');
});
},
methods: {
save() {
this.$root.api('admin/update-meta', {
hiddenTags: this.hiddenTags.split('\n')
}).then(() => {
//this.$root.os.apis.dialog({ text: `Saved` });
}).catch(e => {
//this.$root.os.apis.dialog({ text: `Failed ${e}` });
});
}
}
});
</script>

View File

@ -18,18 +18,18 @@
<p class="name"><mk-user-name :user="$store.state.i"/></p>
</div>
<ul>
<li @click="nav('dashboard')" :class="{ active: page == 'dashboard' }"><fa icon="home" fixed-width/>{{ $t('dashboard') }}</li>
<li @click="nav('instance')" :class="{ active: page == 'instance' }"><fa icon="cog" fixed-width/>{{ $t('instance') }}</li>
<li @click="nav('queue')" :class="{ active: page == 'queue' }"><fa :icon="faTasks" fixed-width/>{{ $t('queue') }}</li>
<li @click="nav('logs')" :class="{ active: page == 'logs' }"><fa :icon="faStream" fixed-width/>{{ $t('logs') }}</li>
<li @click="nav('moderators')" :class="{ active: page == 'moderators' }"><fa :icon="faHeadset" fixed-width/>{{ $t('moderators') }}</li>
<li @click="nav('users')" :class="{ active: page == 'users' }"><fa icon="users" fixed-width/>{{ $t('users') }}</li>
<li @click="nav('drive')" :class="{ active: page == 'drive' }"><fa icon="cloud" fixed-width/>{{ $t('@.drive') }}</li>
<li @click="nav('federation')" :class="{ active: page == 'federation' }"><fa :icon="faGlobe" fixed-width/>{{ $t('federation') }}</li>
<li @click="nav('emoji')" :class="{ active: page == 'emoji' }"><fa :icon="faGrin" fixed-width/>{{ $t('emoji') }}</li>
<li @click="nav('announcements')" :class="{ active: page == 'announcements' }"><fa icon="broadcast-tower" fixed-width/>{{ $t('announcements') }}</li>
<li @click="nav('hashtags')" :class="{ active: page == 'hashtags' }"><fa icon="hashtag" fixed-width/>{{ $t('hashtags') }}</li>
<li @click="nav('abuse')" :class="{ active: page == 'abuse' }"><fa :icon="faExclamationCircle" fixed-width/>{{ $t('abuse') }}</li>
<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>
@ -44,11 +44,11 @@
<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 == 'hashtags'"><x-hashtags/></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>
@ -61,20 +61,20 @@
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 XModerators from "./moderators.vue";
import XEmoji from "./emoji.vue";
import XAnnouncements from "./announcements.vue";
import XHashtags from "./hashtags.vue";
import XUsers from "./users.vue";
import XDrive from "./drive.vue";
import XAbuse from "./abuse.vue";
import XFederation from "./federation.vue";
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 } from '@fortawesome/free-solid-svg-icons';
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
@ -88,10 +88,10 @@ export default Vue.extend({
XInstance,
XQueue,
XLogs,
XDb,
XModerators,
XEmoji,
XAnnouncements,
XHashtags,
XUsers,
XDrive,
XAbuse,
@ -102,7 +102,6 @@ export default Vue.extend({
},
data() {
return {
page: 'dashboard',
version,
isMobile,
navOpend: !isMobile,
@ -112,12 +111,13 @@ export default Vue.extend({
faGlobe,
faExclamationCircle,
faTasks,
faStream
faStream,
faDatabase,
};
},
methods: {
nav(page: string) {
this.page = page;
computed: {
page() {
return this.$route.params.page;
}
}
});
@ -239,11 +239,10 @@ export default Vue.extend({
list-style none
font-size 15px
> li
> li > a
display block
padding 10px 16px
margin 0
cursor pointer
user-select none
color #eee
transition margin-left 0.2s ease

View File

@ -2,132 +2,243 @@
<div>
<ui-card>
<template #title><fa icon="cog"/> {{ $t('instance') }}</template>
<section class="fit-top fit-bottom">
<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="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="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="disableRegistration">{{ $t('disable-registration') }}</ui-switch>
<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 class="fit-bottom">
<header><fa icon="cloud"/> {{ $t('drive-config') }}</header>
<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>
</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 class="fit-bottom">
<header><fa :icon="faShieldAlt"/> {{ $t('recaptcha-config') }}</header>
<ui-switch v-model="enableRecaptcha">{{ $t('enable-recaptcha') }}</ui-switch>
<ui-info>{{ $t('recaptcha-info') }}</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>
</section>
<section>
<header><fa :icon="faGhost"/> {{ $t('proxy-account-config') }}</header>
<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>
<header><fa :icon="farEnvelope"/> {{ $t('email-config') }}</header>
<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>
<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" :withPasswordToggle="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>
<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>
<header><fa :icon="faBolt"/> {{ $t('serviceworker-config') }}</header>
<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>
<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 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>
<header>summaly Proxy</header>
<ui-input v-model="summalyProxy">URL</ui-input>
</section>
<section>
<ui-button @click="updateMeta">{{ $t('save') }}</ui-button>
<ui-button @click="updateMeta"><fa :icon="faSave"/> {{ $t('save') }}</ui-button>
</section>
</ui-card>
<ui-card>
<template #title>{{ $t('invite') }}</template>
<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="invite">{{ $t('invite') }}</ui-button>
<p v-if="inviteCode">Code: <code>{{ inviteCode }}</code></p>
<ui-button @click="updateMeta"><fa :icon="faSave"/> {{ $t('save') }}</ui-button>
</section>
</ui-card>
<ui-card>
<template #title><fa :icon="['fab', 'twitter']"/> {{ $t('twitter-integration-config') }}</template>
<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>
<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>
<ui-button @click="updateMeta">{{ $t('save') }}</ui-button>
<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>
</ui-card>
<ui-card>
<template #title><fa :icon="['fab', 'github']"/> {{ $t('github-integration-config') }}</template>
<section>
<header><fa :icon="['fab', 'github']"/> {{ $t('github-integration-config') }}</header>
<ui-switch v-model="enableGithubIntegration">{{ $t('enable-github-integration') }}</ui-switch>
<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>
<ui-button @click="updateMeta">{{ $t('save') }}</ui-button>
<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>
<ui-card>
<template #title><fa :icon="['fab', 'discord']"/> {{ $t('discord-integration-config') }}</template>
<section>
<ui-switch v-model="enableDiscordIntegration">{{ $t('enable-discord-integration') }}</ui-switch>
<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>
<ui-button @click="updateMeta">{{ $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>
@ -136,8 +247,8 @@ import Vue from 'vue';
import i18n from '../../i18n';
import { url, host } from '../../config';
import { toUnicode } from 'punycode';
import { faHeadset, faShieldAlt, faGhost, faUserPlus, faBolt } from '@fortawesome/free-solid-svg-icons';
import { faEnvelope as farEnvelope } from '@fortawesome/free-regular-svg-icons';
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'),
@ -148,6 +259,9 @@ export default Vue.extend({
host: toUnicode(host),
maintainerName: null,
maintainerEmail: null,
ToSUrl: null,
repositoryUrl: "https://github.com/syuilo/misskey",
feedbackUrl: null,
disableRegistration: false,
disableLocalTimeline: false,
disableGlobalTimeline: false,
@ -177,7 +291,6 @@ export default Vue.extend({
discordClientId: null,
discordClientSecret: null,
proxyAccount: null,
inviteCode: null,
summalyProxy: null,
enableEmail: false,
email: null,
@ -190,14 +303,29 @@ export default Vue.extend({
enableServiceWorker: false,
swPublicKey: null,
swPrivateKey: null,
faHeadset, faShieldAlt, faGhost, faUserPlus, farEnvelope, faBolt
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().then(meta => {
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;
@ -239,13 +367,74 @@ export default Vue.extend({
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.inviteCode = x.code;
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',
@ -258,6 +447,9 @@ export default Vue.extend({
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,
@ -297,7 +489,19 @@ export default Vue.extend({
smtpPass: this.smtpAuth ? this.smtpPass : '',
enableServiceWorker: this.enableServiceWorker,
swPublicKey: this.swPublicKey,
swPrivateKey: this.swPrivateKey
swPrivateKey: this.swPrivateKey,
pinnedUsers: this.pinnedUsers.split('\n'),
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',

View File

@ -26,6 +26,8 @@
</details>
</code>
</div>
<ui-button @click="deleteAll()">{{ $t('delete-all') }}</ui-button>
</section>
</ui-card>
</div>
@ -78,6 +80,15 @@ export default Vue.extend({
}).then(logs => {
this.logs = logs.reverse();
});
},
deleteAll() {
this.$root.api('admin/delete-logs').then(() => {
this.$root.dialog({
type: 'success',
splash: true
});
});
}
}
});

View File

@ -12,6 +12,31 @@
</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>
@ -26,10 +51,17 @@ export default Vue.extend({
data() {
return {
username: '',
changing: false
changing: false,
logs: [],
untilLogId: null,
existMoreLogs: false
};
},
created() {
this.fetchLogs();
},
methods: {
async add() {
this.changing = true;
@ -74,6 +106,22 @@ export default Vue.extend({
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

@ -0,0 +1,181 @@
<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>

View File

@ -2,59 +2,27 @@
<div>
<ui-card>
<template #title><fa :icon="faChartBar"/> {{ $t('title') }}</template>
<section class="wptihjuy">
<header><fa :icon="faPaperPlane"/> Deliver</header>
<ui-info warn v-if="latestStats && latestStats.deliver.waiting > 0">The queue is jammed.</ui-info>
<ui-horizon-group inputs v-if="latestStats" class="fit-bottom">
<ui-input :value="latestStats.deliver.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.deliver.active | number" type="text" readonly>
<span>Active</span>
<template #prefix><fa :icon="farPlayCircle"/></template>
<template #suffix>jobs</template>
</ui-input>
<ui-input :value="latestStats.deliver.waiting | number" type="text" readonly>
<span>Waiting</span>
<template #prefix><fa :icon="faStopCircle"/></template>
<template #suffix>jobs</template>
</ui-input>
<ui-input :value="latestStats.deliver.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="deliverChart" class="chart"></div>
<section>
<header><fa :icon="faPaperPlane"/> {{ $t('domains.deliver') }}</header>
<x-chart v-if="connection" :connection="connection" :limit="chartLimit" type="deliver"/>
</section>
<section class="wptihjuy">
<header><fa :icon="faInbox"/> Inbox</header>
<ui-info warn v-if="latestStats && latestStats.inbox.waiting > 0">The queue is jammed.</ui-info>
<ui-horizon-group inputs v-if="latestStats" class="fit-bottom">
<ui-input :value="latestStats.inbox.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.inbox.active | number" type="text" readonly>
<span>Active</span>
<template #prefix><fa :icon="farPlayCircle"/></template>
<template #suffix>jobs</template>
</ui-input>
<ui-input :value="latestStats.inbox.waiting | number" type="text" readonly>
<span>Waiting</span>
<template #prefix><fa :icon="faStopCircle"/></template>
<template #suffix>jobs</template>
</ui-input>
<ui-input :value="latestStats.inbox.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="inboxChart" class="chart"></div>
<section>
<header><fa :icon="faInbox"/> {{ $t('domains.inbox') }}</header>
<x-chart v-if="connection" :connection="connection" :limit="chartLimit" type="inbox"/>
</section>
<section>
<details>
<summary>{{ $t('other-queues') }}</summary>
<section>
<header><fa :icon="faDatabase"/> {{ $t('domains.db') }}</header>
<x-chart v-if="connection" :connection="connection" :limit="chartLimit" type="db"/>
</section>
<ui-hr/>
<section>
<header><fa :icon="faCloud"/> {{ $t('domains.objectStorage') }}</header>
<x-chart v-if="connection" :connection="connection" :limit="chartLimit" type="objectStorage"/>
</section>
</details>
</section>
<section>
<ui-button @click="removeAllJobs">{{ $t('remove-all-jobs') }}</ui-button>
@ -69,9 +37,13 @@
<template #label>{{ $t('queue') }}</template>
<option value="deliver">{{ $t('domains.deliver') }}</option>
<option value="inbox">{{ $t('domains.inbox') }}</option>
<option value="db">{{ $t('domains.db') }}</option>
<option value="objectStorage">{{ $t('domains.objectStorage') }}</option>
</ui-select>
<ui-select v-model="state">
<template #label>{{ $t('state') }}</template>
<option value="active">{{ $t('states.active') }}</option>
<option value="waiting">{{ $t('states.waiting') }}</option>
<option value="delayed">{{ $t('states.delayed') }}</option>
</ui-select>
</ui-horizon-group>
@ -94,74 +66,31 @@
<script lang="ts">
import Vue from 'vue';
import { faTasks, faInbox, faDatabase, faCloud } from '@fortawesome/free-solid-svg-icons';
import { faPaperPlane, faChartBar } from '@fortawesome/free-regular-svg-icons';
import i18n from '../../i18n';
import ApexCharts from 'apexcharts';
import * as tinycolor from 'tinycolor2';
import { faTasks, faInbox, faStopwatch, faPlayCircle as fasPlayCircle } from '@fortawesome/free-solid-svg-icons';
import { faPaperPlane, faStopCircle, faPlayCircle as farPlayCircle, faChartBar } from '@fortawesome/free-regular-svg-icons';
const limit = 200;
import XChart from './queue.chart.vue';
export default Vue.extend({
i18n: i18n('admin/views/queue.vue'),
components: {
XChart
},
data() {
return {
stats: [],
deliverChart: null,
inboxChart: null,
connection: null,
chartLimit: 200,
jobs: [],
jobsLimit: 50,
domain: 'deliver',
state: 'delayed',
faTasks, faPaperPlane, faInbox, faStopwatch, faStopCircle, farPlayCircle, fasPlayCircle, faChartBar
faTasks, faPaperPlane, faInbox, faChartBar, faDatabase, faCloud
};
},
computed: {
latestStats(): any {
return this.stats[this.stats.length - 1];
}
},
watch: {
stats(stats) {
this.inboxChart.updateSeries([{
name: 'Process',
type: 'area',
data: stats.map((x, i) => ({ x: i, y: x.inbox.activeSincePrevTick }))
}, {
name: 'Active',
type: 'area',
data: stats.map((x, i) => ({ x: i, y: x.inbox.active }))
}, {
name: 'Waiting',
type: 'line',
data: stats.map((x, i) => ({ x: i, y: x.inbox.waiting }))
}, {
name: 'Delayed',
type: 'line',
data: stats.map((x, i) => ({ x: i, y: x.inbox.delayed }))
}]);
this.deliverChart.updateSeries([{
name: 'Process',
type: 'area',
data: stats.map((x, i) => ({ x: i, y: x.deliver.activeSincePrevTick }))
}, {
name: 'Active',
type: 'area',
data: stats.map((x, i) => ({ x: i, y: x.deliver.active }))
}, {
name: 'Waiting',
type: 'line',
data: stats.map((x, i) => ({ x: i, y: x.deliver.waiting }))
}, {
name: 'Delayed',
type: 'line',
data: stats.map((x, i) => ({ x: i, y: x.deliver.delayed }))
}]);
},
domain() {
this.jobs = [];
this.fetchJobs();
@ -176,83 +105,14 @@ export default Vue.extend({
mounted() {
this.fetchJobs();
const chartOpts = id => ({
chart: {
id,
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.inboxChart = new ApexCharts(this.$refs.inboxChart, chartOpts('a'));
this.deliverChart = new ApexCharts(this.$refs.deliverChart, chartOpts('b'));
this.inboxChart.render();
this.deliverChart.render();
const connection = this.$root.stream.useSharedConnection('queueStats');
connection.on('stats', this.onStats);
connection.on('statsLog', this.onStatsLog);
connection.send('requestLog', {
this.connection = this.$root.stream.useSharedConnection('queueStats');
this.connection.send('requestLog', {
id: Math.random().toString().substr(2, 8),
length: limit
length: this.chartLimit
});
this.$once('hook:beforeDestroy', () => {
connection.dispose();
this.inboxChart.destroy();
this.deliverChart.destroy();
this.connection.dispose();
});
},
@ -274,17 +134,6 @@ export default Vue.extend({
});
},
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);
}
},
fetchJobs() {
this.$root.api('admin/queue/jobs', {
domain: this.domain,
@ -299,11 +148,6 @@ export default Vue.extend({
</script>
<style lang="stylus" scoped>
.wptihjuy
> .chart
min-height 200px !important
margin 0 -8px
.xvvuvgsv
> b
margin-right 16px

View File

@ -5,13 +5,12 @@
<mk-avatar class="avatar" :user="user" :disable-link="true"/>
</a>
</div>
<div>
<div @click="click(user.id)">
<header>
<b><mk-user-name :user="user"/></b>
<span class="username">@{{ user | acct }}</span>
<span class="is-admin" v-if="user.isAdmin">admin</span>
<span class="is-moderator" v-if="user.isModerator">moderator</span>
<span class="is-verified" v-if="user.isVerified" :title="$t('@.verified-user')"><fa icon="star"/></span>
<span class="is-silenced" v-if="user.isSilenced" :title="$t('@.silenced-user')"><fa :icon="faMicrophoneSlash"/></span>
<span class="is-suspended" v-if="user.isSuspended" :title="$t('@.suspended-user')"><fa :icon="faSnowflake"/></span>
</header>
@ -33,7 +32,7 @@ import { faSnowflake } from '@fortawesome/free-regular-svg-icons';
export default Vue.extend({
i18n: i18n('admin/views/users.vue'),
props: ['user'],
props: ['user', 'click'],
data() {
return {
faSnowflake, faMicrophoneSlash
@ -45,7 +44,7 @@ export default Vue.extend({
<style lang="stylus" scoped>
.kofvwchc
display flex
padding 16px 0
padding 16px
border-top solid 1px var(--faceDivider)
> div:first-child
@ -56,6 +55,7 @@ export default Vue.extend({
> div:last-child
flex 1
cursor pointer
padding-left 16px
@media (max-width 500px)
@ -77,9 +77,19 @@ export default Vue.extend({
background var(--noteHeaderAdminBg)
color var(--noteHeaderAdminFg)
> .is-verified
> .is-silenced
> .is-suspended
margin 0 0 0 .5em
color #4dabf7
&:hover
color var(--primaryForeground)
background var(--primary)
text-decoration none
border-radius 3px
&:active
color var(--primaryForeground)
background var(--primaryDarken10)
border-radius 3px
</style>

View File

@ -8,14 +8,11 @@
</ui-input>
<ui-button @click="showUser"><fa :icon="faSearch"/> {{ $t('lookup') }}</ui-button>
<div class="user" v-if="user">
<x-user :user='user'/>
<div ref="user" class="user" v-if="user" :key="user.id">
<x-user :user="user"/>
<div class="actions">
<ui-button v-if="user.host != null" @click="updateRemoteUser"><fa :icon="faSync"/> {{ $t('update-remote-user') }}</ui-button>
<ui-button @click="resetPassword"><fa :icon="faKey"/> {{ $t('reset-password') }}</ui-button>
<ui-horizon-group>
<ui-button @click="verifyUser" :disabled="verifying"><fa :icon="faCertificate"/> {{ $t('verify') }}</ui-button>
<ui-button @click="unverifyUser" :disabled="unverifying">{{ $t('unverify') }}</ui-button>
</ui-horizon-group>
<ui-horizon-group>
<ui-button @click="silenceUser"><fa :icon="faMicrophoneSlash"/> {{ $t('make-silence') }}</ui-button>
<ui-button @click="unsilenceUser">{{ $t('unmake-silence') }}</ui-button>
@ -24,7 +21,7 @@
<ui-button @click="suspendUser" :disabled="suspending"><fa :icon="faSnowflake"/> {{ $t('suspend') }}</ui-button>
<ui-button @click="unsuspendUser" :disabled="unsuspending">{{ $t('unsuspend') }}</ui-button>
</ui-horizon-group>
<ui-button v-if="user.host != null" @click="updateRemoteUser"><fa :icon="faSync"/> {{ $t('update-remote-user') }}</ui-button>
<ui-button @click="deleteAllFiles"><fa :icon="faTrashAlt"/> {{ $t('delete-all-files') }}</ui-button>
<ui-textarea v-if="user" :value="user | json5" readonly tall style="margin-top:16px;"></ui-textarea>
</div>
</div>
@ -47,7 +44,6 @@
<option value="all">{{ $t('users.state.all') }}</option>
<option value="admin">{{ $t('users.state.admin') }}</option>
<option value="moderator">{{ $t('users.state.moderator') }}</option>
<option value="verified">{{ $t('users.state.verified') }}</option>
<option value="silenced">{{ $t('users.state.silenced') }}</option>
<option value="suspended">{{ $t('users.state.suspended') }}</option>
</ui-select>
@ -58,8 +54,16 @@
<option value="remote">{{ $t('users.origin.remote') }}</option>
</ui-select>
</ui-horizon-group>
<ui-horizon-group searchboxes>
<ui-input v-model="searchUsername" type="text" spellcheck="false" @input="fetchUsers(true)">
<span>{{ $t('username') }}</span>
</ui-input>
<ui-input v-model="searchHost" type="text" spellcheck="false" @input="fetchUsers(true)" :disabled="origin === 'local'">
<span>{{ $t('host') }}</span>
</ui-input>
</ui-horizon-group>
<sequential-entrance animation="entranceFromTop" delay="25">
<x-user v-for="user in users" :user='user' :key="user.id"/>
<x-user v-for="user in users" :key="user.id" :user='user' :click="showUserOnClick"/>
</sequential-entrance>
<ui-button v-if="existMore" @click="fetchUsers">{{ $t('@.load-more') }}</ui-button>
</section>
@ -71,8 +75,8 @@
import Vue from 'vue';
import i18n from '../../i18n';
import parseAcct from "../../../../misc/acct/parse";
import { faCertificate, faUsers, faTerminal, faSearch, faKey, faSync, faMicrophoneSlash } from '@fortawesome/free-solid-svg-icons';
import { faSnowflake } from '@fortawesome/free-regular-svg-icons';
import { faUsers, faTerminal, faSearch, faKey, faSync, faMicrophoneSlash } from '@fortawesome/free-solid-svg-icons';
import { faSnowflake, faTrashAlt } from '@fortawesome/free-regular-svg-icons';
import XUser from './users.user.vue';
export default Vue.extend({
@ -84,18 +88,18 @@ export default Vue.extend({
return {
user: null,
target: null,
verifying: false,
unverifying: false,
suspending: false,
unsuspending: false,
sort: '+createdAt',
state: 'all',
origin: 'local',
searchUsername: '',
searchHost: '',
limit: 10,
offset: 0,
users: [],
existMore: false,
faTerminal, faCertificate, faUsers, faSnowflake, faSearch, faKey, faSync, faMicrophoneSlash
faTerminal, faUsers, faSnowflake, faSearch, faKey, faSync, faMicrophoneSlash, faTrashAlt
};
},
@ -113,6 +117,7 @@ export default Vue.extend({
},
origin() {
if (this.origin === 'local') this.searchHost = '';
this.users = [];
this.offset = 0;
this.fetchUsers();
@ -163,6 +168,15 @@ export default Vue.extend({
this.target = '';
},
async showUserOnClick(userId: string) {
this.$root.api('admin/show-user', { userId: userId }).then(info => {
this.user = info;
this.$nextTick(() => {
this.$refs.user.scrollIntoView();
});
});
},
/** 処理対象ユーザーの情報を更新する */
async refreshUser() {
this.$root.api('admin/show-user', { userId: this.user.id }).then(info => {
@ -181,57 +195,9 @@ export default Vue.extend({
});
},
async verifyUser() {
if (!await this.getConfirmed(this.$t('verify-confirm'))) return;
this.verifying = true;
const process = async () => {
await this.$root.api('admin/verify-user', { userId: this.user.id });
this.$root.dialog({
type: 'success',
text: this.$t('verified')
});
};
await process().catch(e => {
this.$root.dialog({
type: 'error',
text: e.toString()
});
});
this.verifying = false;
this.refreshUser();
},
async unverifyUser() {
if (!await this.getConfirmed(this.$t('unverify-confirm'))) return;
this.unverifying = true;
const process = async () => {
await this.$root.api('admin/unverify-user', { userId: this.user.id });
this.$root.dialog({
type: 'success',
text: this.$t('unverified')
});
};
await process().catch(e => {
this.$root.dialog({
type: 'error',
text: e.toString()
});
});
this.unverifying = false;
this.refreshUser();
},
async silenceUser() {
if (!await this.getConfirmed(this.$t('silence-confirm'))) return;
const process = async () => {
await this.$root.api('admin/silence-user', { userId: this.user.id });
this.$root.dialog({
@ -251,6 +217,8 @@ export default Vue.extend({
},
async unsilenceUser() {
if (!await this.getConfirmed(this.$t('unsilence-confirm'))) return;
const process = async () => {
await this.$root.api('admin/unsilence-user', { userId: this.user.id });
this.$root.dialog({
@ -330,6 +298,25 @@ export default Vue.extend({
this.refreshUser();
},
async deleteAllFiles() {
if (!await this.getConfirmed(this.$t('delete-all-files-confirm'))) return;
const process = async () => {
await this.$root.api('admin/delete-all-files-of-a-user', { userId: this.user.id });
this.$root.dialog({
type: 'success',
splash: true
});
};
await process().catch(e => {
this.$root.dialog({
type: 'error',
text: e.toString()
});
});
},
async getConfirmed(text: string): Promise<Boolean> {
const confirm = await this.$root.dialog({
type: 'warning',
@ -341,13 +328,16 @@ export default Vue.extend({
return !confirm.canceled;
},
fetchUsers() {
fetchUsers(truncate?: boolean) {
if (truncate) this.offset = 0;
this.$root.api('admin/show-users', {
state: this.state,
origin: this.origin,
sort: this.sort,
offset: this.offset,
limit: this.limit + 1
limit: this.limit + 1,
username: this.searchUsername,
hostname: this.searchHost
}).then(users => {
if (users.length == this.limit + 1) {
users.pop();
@ -355,7 +345,7 @@ export default Vue.extend({
} else {
this.existMore = false;
}
this.users = this.users.concat(users);
this.users = truncate ? users : this.users.concat(users);
this.offset += this.limit;
});
}

View File

@ -34,7 +34,7 @@ body
.peg
display block
position absolute
right 0px
right 0
width 100px
height 100%
box-shadow 0 0 10px var(--primary), 0 0 5px var(--primary)

View File

@ -1,7 +1,7 @@
<template>
<div class="form">
<header>
<h1 v-html="$t('share-access', { name: app.name })"></h1>
<h1 v-html="$t('share-access', { name })"></h1>
<img :src="app.iconUrl"/>
</header>
<div class="app">
@ -34,6 +34,11 @@ export default Vue.extend({
i18n: i18n('auth/views/form.vue'),
props: ['session'],
computed: {
name(): string {
const el = document.createElement('div');
el.textContent = this.app.name
return el.innerHTML;
},
app(): any {
return this.session.app;
}

View File

@ -98,7 +98,7 @@ export default Vue.extend({
margin 0 auto
text-align center
background #fff
box-shadow 0px 4px 16px rgba(#000, 0.2)
box-shadow 0 4px 16px rgba(#000, 0.2)
> .fetching
margin 0

View File

@ -41,7 +41,6 @@
if (`${url.pathname}/`.startsWith('/dev/')) app = 'dev';
if (`${url.pathname}/`.startsWith('/auth/')) app = 'auth';
if (`${url.pathname}/`.startsWith('/admin/')) app = 'admin';
if (`${url.pathname}/`.startsWith('/test/')) app = 'test';
//#endregion
// Script version
@ -85,7 +84,14 @@
// Detect the user agent
const ua = navigator.userAgent.toLowerCase();
const isMobile = /mobile|iphone|ipad|android/.test(ua);
let isMobile = /mobile|iphone|ipad|android/.test(ua) || window.innerWidth < 576;
if (settings && settings.device.appTypeForce) {
if (settings.device.appTypeForce === 'mobile') {
isMobile = true;
} else if (settings.device.appTypeForce === 'desktop') {
isMobile = false;
}
}
// Get the <head> element
const head = document.getElementsByTagName('head')[0];

View File

@ -60,9 +60,9 @@ export default function <T extends object>(data: {
save() {
if (this.platform == 'deck') {
this.$store.commit('device/updateDeckColumn', this.column);
this.$store.commit('updateDeckColumn', this.column);
} else {
this.$store.commit('device/updateWidget', this.widget);
this.$store.commit('updateWidget', this.widget);
}
}
}

View File

@ -52,7 +52,7 @@ function match(e: KeyboardEvent, patterns: action['patterns']): boolean {
pattern.ctrl == e.ctrlKey &&
pattern.shift == e.shiftKey &&
pattern.alt == e.altKey &&
e.metaKey == false
!e.metaKey
);
}

View File

@ -0,0 +1,5 @@
export function hexifyAB(buffer) {
return Array.from(new Uint8Array(buffer))
.map(item => item.toString(16).padStart(2, 0))
.join('');
}

View File

@ -0,0 +1,48 @@
export function collectPageVars(content) {
const pageVars = [];
const collect = (xs: any[]) => {
for (const x of xs) {
if (x.type === 'textInput') {
pageVars.push({
name: x.name,
type: 'string',
value: x.default || ''
});
} else if (x.type === 'textareaInput') {
pageVars.push({
name: x.name,
type: 'string',
value: x.default || ''
});
} else if (x.type === 'numberInput') {
pageVars.push({
name: x.name,
type: 'number',
value: x.default || 0
});
} else if (x.type === 'switch') {
pageVars.push({
name: x.name,
type: 'boolean',
value: x.default || false
});
} else if (x.type === 'counter') {
pageVars.push({
name: x.name,
type: 'number',
value: 0
});
} else if (x.type === 'radioButton') {
pageVars.push({
name: x.name,
type: 'string',
value: x.default || ''
});
} else if (x.children) {
collect(x.children);
}
}
};
collect(content);
return pageVars;
}

View File

@ -0,0 +1,31 @@
import parseAcct from '../../../../misc/acct/parse';
import { host as localHost } from '../../config';
export async function genSearchQuery(v: any, q: string) {
let host: string;
let userId: string;
if (q.split(' ').some(x => x.startsWith('@'))) {
for (const at of q.split(' ').filter(x => x.startsWith('@')).map(x => x.substr(1))) {
if (at.includes('.')) {
if (at === localHost || at === '.') {
host = null;
} else {
host = at;
}
} else {
const user = await v.$root.api('users/show', parseAcct(at)).catch(x => null);
if (user) {
userId = user.id;
} else {
// todo: show error
}
}
}
}
return {
query: q.split(' ').filter(x => !x.startsWith('/') && !x.startsWith('@')).join(' '),
host: host,
userId: userId
};
}

View File

@ -4,7 +4,8 @@ const faces = [
'🐡( \'-\' 🐡 )フグパンチ!!!!',
'✌️(´・_・`)✌️',
'(。><。)',
'(Δ・x・Δ)'
'(Δ・x・Δ)',
'(コ`・ヘ・´ケ)'
];
export default () => faces[Math.floor(Math.random() * faces.length)];

View File

@ -3,6 +3,8 @@ import { sum, unique } from '../../../../prelude/array';
import shouldMuteNote from './should-mute-note';
import MkNoteMenu from '../views/components/note-menu.vue';
import MkReactionPicker from '../views/components/reaction-picker.vue';
import pleaseLogin from './please-login';
import i18n from '../../i18n';
function focus(el, fn) {
const target = fn(el);
@ -20,10 +22,13 @@ type Opts = {
};
export default (opts: Opts = {}) => ({
i18n: i18n(),
data() {
return {
showContent: false,
hideThisNote: false
hideThisNote: false,
openingMenu: false
};
},
@ -83,9 +88,19 @@ export default (opts: Opts = {}) => ({
if (this.appearNote.text) {
const ast = parse(this.appearNote.text);
// TODO: 再帰的にURL要素がないか調べる
return unique(ast
const urls = unique(ast
.filter(t => ((t.node.type == 'url' || t.node.type == 'link') && t.node.props.url && !t.node.props.silent))
.map(t => t.node.props.url));
// unique without hash
// [ http://a/#1, http://a/#2, http://b/#3 ] => [ http://a/#1, http://b/#3 ]
const removeHash = x => x.replace(/#[^#]*$/, '');
return urls.reduce((array, url) => {
const removed = removeHash(url);
if (!array.map(x => removeHash(x)).includes(removed)) array.push(url);
return array;
}, []);
} else {
return null;
}
@ -98,6 +113,7 @@ export default (opts: Opts = {}) => ({
methods: {
reply(viaKeyboard = false) {
pleaseLogin(this.$root);
this.$root.$post({
reply: this.appearNote,
animation: !viaKeyboard,
@ -108,6 +124,7 @@ export default (opts: Opts = {}) => ({
},
renote(viaKeyboard = false) {
pleaseLogin(this.$root);
this.$root.$post({
renote: this.appearNote,
animation: !viaKeyboard,
@ -124,6 +141,7 @@ export default (opts: Opts = {}) => ({
},
react(viaKeyboard = false) {
pleaseLogin(this.$root);
this.blur();
this.$root.new(MkReactionPicker, {
source: this.$refs.reactButton,
@ -134,7 +152,7 @@ export default (opts: Opts = {}) => ({
},
reactDirectly(reaction) {
(this.$root.api('notes/reactions/create', {
this.$root.api('notes/reactions/create', {
noteId: this.appearNote.id,
reaction: reaction
});
@ -149,6 +167,7 @@ export default (opts: Opts = {}) => ({
},
favorite() {
pleaseLogin(this.$root);
this.$root.api('notes/favorites/create', {
noteId: this.appearNote.id
}).then(() => {
@ -160,17 +179,30 @@ export default (opts: Opts = {}) => ({
},
del() {
this.$root.api('notes/delete', {
noteId: this.appearNote.id
this.$root.dialog({
type: 'warning',
text: this.$t('@.delete-confirm'),
showCancelButton: true
}).then(({ canceled }) => {
if (canceled) return;
this.$root.api('notes/delete', {
noteId: this.appearNote.id
});
});
},
menu(viaKeyboard = false) {
if (this.openingMenu) return;
this.openingMenu = true;
this.$root.new(MkNoteMenu, {
source: this.$refs.menuButton,
note: this.appearNote,
animation: !viaKeyboard
}).$once('closed', this.focus);
}).$once('closed', () => {
this.openingMenu = false;
this.focus();
});
},
toggleShowContent() {

View File

@ -137,7 +137,6 @@ export default prop => ({
Vue.set(this.$_ns_target, 'deletedAt', body.deletedAt);
Vue.set(this.$_ns_target, 'renote', null);
this.$_ns_target.text = null;
this.$_ns_target.tags = [];
this.$_ns_target.fileIds = [];
this.$_ns_target.poll = null;
this.$_ns_target.geo = null;
@ -145,8 +144,6 @@ export default prop => ({
break;
}
}
this.$emit(`update:${prop}`, this.$_ns_note_);
},
}
});

View File

@ -0,0 +1,189 @@
import Vue from 'vue';
export default (opts) => ({
data() {
return {
items: [],
queue: [],
offset: 0,
fetching: true,
moreFetching: false,
inited: false,
more: false
};
},
computed: {
empty(): boolean {
return this.items.length == 0 && !this.fetching && this.inited;
},
error(): boolean {
return !this.fetching && !this.inited;
}
},
watch: {
queue(x) {
if (opts.onQueueChanged) opts.onQueueChanged(this, x);
},
pagination() {
this.init();
}
},
created() {
opts.displayLimit = opts.displayLimit || 30;
this.init();
},
mounted() {
if (opts.captureWindowScroll) {
this.isScrollTop = () => {
return window.scrollY <= 8;
};
window.addEventListener('scroll', this.onScroll, { passive: true });
} else if (opts.isContainer) {
this.isScrollTop = () => {
return this.$el.scrollTop <= 8;
};
this.$el.addEventListener('scroll', this.onScroll, { passive: true });
}
},
beforeDestroy() {
if (opts.captureWindowScroll) {
window.removeEventListener('scroll', this.onScroll);
} else if (opts.isContainer) {
this.$el.removeEventListener('scroll', this.onScroll);
}
},
methods: {
updateItem(i, item) {
Vue.set((this as any).items, i, item);
},
reload() {
this.queue = [];
this.items = [];
this.init();
},
async init() {
this.fetching = true;
if (opts.beforeInit) opts.beforeInit(this);
let params = typeof this.pagination.params === 'function' ? this.pagination.params(true) : this.pagination.params;
if (params && params.then) params = await params;
await this.$root.api(this.pagination.endpoint, {
limit: (this.pagination.limit || 10) + 1,
...params
}).then(x => {
if (x.length == (this.pagination.limit || 10) + 1) {
x.pop();
this.items = x;
this.more = true;
} else {
this.items = x;
this.more = false;
}
this.offset = x.length;
this.inited = true;
this.fetching = false;
if (opts.onInited) opts.onInited(this);
}, e => {
this.fetching = false;
if (opts.onInited) opts.onInited(this);
});
},
async fetchMore() {
if (!this.more || this.moreFetching || this.items.length === 0) return;
this.moreFetching = true;
let params = typeof this.pagination.params === 'function' ? this.pagination.params(false) : this.pagination.params;
if (params && params.then) params = await params;
await this.$root.api(this.pagination.endpoint, {
limit: (this.pagination.limit || 10) + 1,
...(this.pagination.endpoint === 'notes/search' ? {
offset: this.offset,
} : {
untilId: this.items[this.items.length - 1].id,
}),
...params
}).then(x => {
if (x.length == (this.pagination.limit || 10) + 1) {
x.pop();
this.items = this.items.concat(x);
this.more = true;
} else {
this.items = this.items.concat(x);
this.more = false;
}
this.offset += x.length;
this.moreFetching = false;
}, e => {
this.moreFetching = false;
});
},
prepend(item, silent = false) {
if (opts.onPrepend) {
const cancel = opts.onPrepend(this, item, silent);
if (cancel) return;
}
if (this.isScrollTop == null || this.isScrollTop()) {
// Prepend the item
this.items.unshift(item);
// オーバーフローしたら古い投稿は捨てる
if (this.items.length >= opts.displayLimit) {
this.items = this.items.slice(0, opts.displayLimit);
this.more = true;
}
} else {
this.queue.push(item);
}
},
append(item) {
this.items.push(item);
},
releaseQueue() {
for (const n of this.queue) {
this.prepend(n, true);
}
this.queue = [];
},
onScroll() {
if (this.isScrollTop()) {
this.onTop();
}
if (this.$store.state.settings.fetchOnScroll) {
// 親要素が display none だったら弾く
// https://github.com/syuilo/misskey/issues/1569
// http://d.hatena.ne.jp/favril/20091105/1257403319
if (this.$el.offsetHeight == 0) return;
const bottomPosition = opts.isContainer ? this.$el.scrollHeight : document.body.offsetHeight;
const currentBottomPosition = opts.isContainer ? this.$el.scrollTop + this.$el.clientHeight : window.scrollY + window.innerHeight;
if (currentBottomPosition > (bottomPosition - 8)) this.onBottom();
}
},
onTop() {
this.releaseQueue();
},
onBottom() {
this.fetchMore();
}
}
});

View File

@ -0,0 +1,10 @@
export default ($root: any) => {
if ($root.$store.getters.isSignedIn) return;
$root.dialog({
title: $root.$t('@.signin-required'),
text: null
});
throw new Error('signin required');
};

View File

@ -0,0 +1,531 @@
import insertTextAtCursor from 'insert-text-at-cursor';
import { length } from 'stringz';
import { toASCII } from 'punycode';
import MkVisibilityChooser from '../views/components/visibility-chooser.vue';
import getFace from './get-face';
import { parse } from '../../../../mfm/parse';
import { host, url } from '../../config';
import i18n from '../../i18n';
import { erase, unique } from '../../../../prelude/array';
import extractMentions from '../../../../misc/extract-mentions';
import { formatTimeString } from '../../../../misc/format-time-string';
export default (opts) => ({
i18n: i18n(),
components: {
XPostFormAttaches: () => import('../views/components/post-form-attaches.vue').then(m => m.default),
XPollEditor: () => import('../views/components/poll-editor.vue').then(m => m.default)
},
props: {
reply: {
type: Object,
required: false
},
renote: {
type: Object,
required: false
},
mention: {
type: Object,
required: false
},
initialText: {
type: String,
required: false
},
initialNote: {
type: Object,
required: false
},
instant: {
type: Boolean,
required: false,
default: false
}
},
data() {
return {
posting: false,
text: '',
files: [],
uploadings: [],
poll: false,
pollChoices: [],
pollMultiple: false,
pollExpiration: [],
useCw: false,
cw: null,
geo: null,
visibility: 'public',
visibleUsers: [],
localOnly: false,
autocomplete: null,
draghover: false,
quoteId: null,
recentHashtags: JSON.parse(localStorage.getItem('hashtags') || '[]'),
maxNoteTextLength: 1000
};
},
computed: {
draftId(): string {
return this.renote
? `renote:${this.renote.id}`
: this.reply
? `reply:${this.reply.id}`
: 'note';
},
placeholder(): string {
const xs = [
this.$t('@.note-placeholders.a'),
this.$t('@.note-placeholders.b'),
this.$t('@.note-placeholders.c'),
this.$t('@.note-placeholders.d'),
this.$t('@.note-placeholders.e'),
this.$t('@.note-placeholders.f')
];
const x = xs[Math.floor(Math.random() * xs.length)];
return this.renote
? opts.mobile ? this.$t('@.post-form.option-quote-placeholder') : this.$t('@.post-form.quote-placeholder')
: this.reply
? this.$t('@.post-form.reply-placeholder')
: x;
},
submitText(): string {
return this.renote
? this.$t('@.post-form.renote')
: this.reply
? this.$t('@.post-form.reply')
: this.$t('@.post-form.submit');
},
canPost(): boolean {
return !this.posting &&
(1 <= this.text.length || 1 <= this.files.length || this.poll || this.renote) &&
(length(this.text.trim()) <= this.maxNoteTextLength) &&
(!this.poll || this.pollChoices.length >= 2);
}
},
created() {
this.$root.getMeta().then(meta => {
this.maxNoteTextLength = meta.maxNoteTextLength;
});
},
mounted() {
if (this.initialText) {
this.text = this.initialText;
}
if (this.mention) {
this.text = this.mention.host ? `@${this.mention.username}@${toASCII(this.mention.host)}` : `@${this.mention.username}`;
this.text += ' ';
}
if (this.reply && this.reply.user.host != null) {
this.text = `@${this.reply.user.username}@${toASCII(this.reply.user.host)} `;
}
if (this.reply && this.reply.text != null) {
const ast = parse(this.reply.text);
for (const x of extractMentions(ast)) {
const mention = x.host ? `@${x.username}@${toASCII(x.host)}` : `@${x.username}`;
// 自分は除外
if (this.$store.state.i.username == x.username && x.host == null) continue;
if (this.$store.state.i.username == x.username && x.host == host) continue;
// 重複は除外
if (this.text.indexOf(`${mention} `) != -1) continue;
this.text += `${mention} `;
}
}
// デフォルト公開範囲
this.applyVisibility(this.$store.state.settings.rememberNoteVisibility ? (this.$store.state.device.visibility || this.$store.state.settings.defaultNoteVisibility) : this.$store.state.settings.defaultNoteVisibility);
if (this.reply && this.reply.localOnly) {
this.localOnly = true;
}
// 公開以外へのリプライ時は元の公開範囲を引き継ぐ
if (this.reply && ['home', 'followers', 'specified'].includes(this.reply.visibility)) {
this.visibility = this.reply.visibility;
if (this.reply.visibility === 'specified') {
this.$root.api('users/show', {
userIds: this.reply.visibleUserIds.filter(uid => uid !== this.$store.state.i.id && uid !== this.reply.userId)
}).then(users => {
this.visibleUsers.push(...users);
});
if (this.reply.userId !== this.$store.state.i.id) {
this.$root.api('users/show', { userId: this.reply.userId }).then(user => {
this.visibleUsers.push(user);
});
}
}
}
// keep cw when reply
if (this.$store.state.settings.keepCw && this.reply && this.reply.cw) {
this.useCw = true;
this.cw = this.reply.cw;
}
this.focus();
this.$nextTick(() => {
this.focus();
});
this.$nextTick(() => {
// 書きかけの投稿を復元
if (!this.instant && !this.mention) {
const draft = JSON.parse(localStorage.getItem('drafts') || '{}')[this.draftId];
if (draft) {
this.text = draft.data.text;
this.files = (draft.data.files || []).filter(e => e);
if (draft.data.poll) {
this.poll = true;
this.$nextTick(() => {
(this.$refs.poll as any).set(draft.data.poll);
});
}
this.$emit('change-attached-files', this.files);
}
}
// 削除して編集
if (this.initialNote) {
const init = this.initialNote;
this.text = init.text ? init.text : '';
this.files = init.files;
this.cw = init.cw;
this.useCw = init.cw != null;
if (init.poll) {
this.poll = true;
this.$nextTick(() => {
(this.$refs.poll as any).set({
choices: init.poll.choices.map(c => c.text),
multiple: init.poll.multiple
});
});
}
// hack 位置情報投稿が動くようになったら適用する
this.geo = null;
this.visibility = init.visibility;
this.localOnly = init.localOnly;
this.quoteId = init.renote ? init.renote.id : null;
}
this.$nextTick(() => this.watch());
});
},
methods: {
watch() {
this.$watch('text', () => this.saveDraft());
this.$watch('poll', () => this.saveDraft());
this.$watch('files', () => this.saveDraft());
},
trimmedLength(text: string) {
return length(text.trim());
},
addTag(tag: string) {
insertTextAtCursor(this.$refs.text, ` #${tag} `);
},
focus() {
(this.$refs.text as any).focus();
},
chooseFile() {
(this.$refs.file as any).click();
},
chooseFileFromDrive() {
this.$chooseDriveFile({
multiple: true
}).then(files => {
for (const x of files) this.attachMedia(x);
});
},
attachMedia(driveFile) {
this.files.push(driveFile);
this.$emit('change-attached-files', this.files);
},
detachMedia(id) {
this.files = this.files.filter(x => x.id != id);
this.$emit('change-attached-files', this.files);
},
onChangeFile() {
for (const x of Array.from((this.$refs.file as any).files)) this.upload(x);
},
upload(file: File, name?: string) {
(this.$refs.uploader as any).upload(file, this.$store.state.settings.uploadFolder, name);
},
onChangeUploadings(uploads) {
this.$emit('change-uploadings', uploads);
},
onPollUpdate() {
const got = this.$refs.poll.get();
this.pollChoices = got.choices;
this.pollMultiple = got.multiple;
this.pollExpiration = [got.expiration, got.expiresAt || got.expiredAfter];
this.saveDraft();
},
setGeo() {
if (navigator.geolocation == null) {
this.$root.dialog({
type: 'warning',
text: this.$t('@.post-form.geolocation-alert')
});
return;
}
navigator.geolocation.getCurrentPosition(pos => {
this.geo = pos.coords;
this.$emit('geo-attached', this.geo);
}, err => {
this.$root.dialog({
type: 'error',
title: this.$t('@.post-form.error'),
text: err.message
});
}, {
enableHighAccuracy: true
});
},
removeGeo() {
this.geo = null;
this.$emit('geo-dettached');
},
setVisibility() {
const w = this.$root.new(MkVisibilityChooser, {
source: this.$refs.visibilityButton,
currentVisibility: this.localOnly ? `local-${this.visibility}` : this.visibility
});
w.$once('chosen', v => {
this.applyVisibility(v);
});
},
applyVisibility(v: string) {
const m = v.match(/^local-(.+)/);
if (m) {
this.localOnly = true;
this.visibility = m[1];
} else {
this.localOnly = false;
this.visibility = v;
}
},
addVisibleUser() {
this.$root.dialog({
title: this.$t('@.post-form.enter-username'),
user: true
}).then(({ canceled, result: user }) => {
if (canceled) return;
this.visibleUsers.push(user);
});
},
removeVisibleUser(user) {
this.visibleUsers = erase(user, this.visibleUsers);
},
clear() {
this.text = '';
this.files = [];
this.poll = false;
this.quoteId = null;
this.$emit('change-attached-files', this.files);
},
onKeydown(e) {
if ((e.which == 10 || e.which == 13) && (e.ctrlKey || e.metaKey) && this.canPost) this.post();
},
async onPaste(e: ClipboardEvent) {
for (const { item, i } of Array.from(e.clipboardData.items).map((item, i) => ({item, i}))) {
if (item.kind == 'file') {
const file = item.getAsFile();
const lio = file.name.lastIndexOf('.');
const ext = lio >= 0 ? file.name.slice(lio) : '';
const formatted = `${formatTimeString(new Date(file.lastModified), this.$store.state.settings.pastedFileName).replace(/{{number}}/g, `${i + 1}`)}${ext}`;
const name = this.$store.state.settings.pasteDialog
? await this.$root.dialog({
title: this.$t('@.post-form.enter-file-name'),
input: {
default: formatted
},
allowEmpty: false
}).then(({ canceled, result }) => canceled ? false : result)
: formatted;
if (name) this.upload(file, name);
}
}
const paste = e.clipboardData.getData('text');
if (!this.renote && !this.quoteId && paste.startsWith(url + '/notes/')) {
e.preventDefault();
this.$root.dialog({
type: 'info',
text: this.$t('@.post-form.quote-question'),
showCancelButton: true
}).then(({ canceled }) => {
if (canceled) {
insertTextAtCursor(this.$refs.text, paste);
return;
}
this.quoteId = paste.substr(url.length).match(/^\/notes\/(.+?)\/?$/)[1];
});
}
},
onDragover(e) {
const isFile = e.dataTransfer.items[0].kind == 'file';
const isDriveFile = e.dataTransfer.types[0] == 'mk_drive_file';
if (isFile || isDriveFile) {
e.preventDefault();
this.draghover = true;
e.dataTransfer.dropEffect = e.dataTransfer.effectAllowed == 'all' ? 'copy' : 'move';
}
},
onDragenter(e) {
this.draghover = true;
},
onDragleave(e) {
this.draghover = false;
},
onDrop(e): void {
this.draghover = false;
// ファイルだったら
if (e.dataTransfer.files.length > 0) {
e.preventDefault();
for (const x of Array.from(e.dataTransfer.files)) this.upload(x);
return;
}
//#region ドライブのファイル
const driveFile = e.dataTransfer.getData('mk_drive_file');
if (driveFile != null && driveFile != '') {
const file = JSON.parse(driveFile);
this.files.push(file);
this.$emit('change-attached-files', this.files);
e.preventDefault();
}
//#endregion
},
async emoji() {
const Picker = await import('../../desktop/views/components/emoji-picker-dialog.vue').then(m => m.default);
const button = this.$refs.emoji;
const rect = button.getBoundingClientRect();
const vm = this.$root.new(Picker, {
x: button.offsetWidth + rect.left + window.pageXOffset,
y: rect.top + window.pageYOffset
});
vm.$once('chosen', emoji => {
insertTextAtCursor(this.$refs.text, emoji);
});
},
saveDraft() {
if (this.instant) return;
const data = JSON.parse(localStorage.getItem('drafts') || '{}');
data[this.draftId] = {
updatedAt: new Date(),
data: {
text: this.text,
files: this.files,
poll: this.poll && this.$refs.poll ? (this.$refs.poll as any).get() : undefined
}
};
localStorage.setItem('drafts', JSON.stringify(data));
},
deleteDraft() {
const data = JSON.parse(localStorage.getItem('drafts') || '{}');
delete data[this.draftId];
localStorage.setItem('drafts', JSON.stringify(data));
},
kao() {
this.text += getFace();
},
post() {
this.posting = true;
const viaMobile = opts.mobile && !this.$store.state.settings.disableViaMobile;
this.$root.api('notes/create', {
text: this.text == '' ? undefined : this.text,
fileIds: this.files.length > 0 ? this.files.map(f => f.id) : undefined,
replyId: this.reply ? this.reply.id : undefined,
renoteId: this.renote ? this.renote.id : this.quoteId ? this.quoteId : undefined,
poll: this.poll ? (this.$refs.poll as any).get() : undefined,
cw: this.useCw ? this.cw || '' : undefined,
visibility: this.visibility,
visibleUserIds: this.visibility == 'specified' ? this.visibleUsers.map(u => u.id) : undefined,
localOnly: this.localOnly,
geo: this.geo ? {
coordinates: [this.geo.longitude, this.geo.latitude],
altitude: this.geo.altitude,
accuracy: this.geo.accuracy,
altitudeAccuracy: this.geo.altitudeAccuracy,
heading: isNaN(this.geo.heading) ? null : this.geo.heading,
speed: this.geo.speed,
} : null,
viaMobile: viaMobile
}).then(data => {
this.clear();
this.deleteDraft();
this.$emit('posted');
if (opts.onSuccess) opts.onSuccess(this);
}).catch(err => {
if (opts.onSuccess) opts.onFailure(this);
}).then(() => {
this.posting = false;
});
if (this.text && this.text != '') {
const hashtags = parse(this.text).filter(x => x.node.type === 'hashtag').map(x => x.node.props.hashtag);
const history = JSON.parse(localStorage.getItem('hashtags') || '[]') as string[];
localStorage.setItem('hashtags', JSON.stringify(unique(hashtags.concat(history))));
}
},
}
});

View File

@ -0,0 +1,21 @@
export type RoomInfo = {
roomType: string;
carpetColor: string;
furnitures: Furniture[];
};
export type Furniture = {
id: string; // 同じ家具が複数ある場合にそれぞれを識別するためのIDであり、家具IDではない
type: string; // こっちが家具ID(chairとか)
position: {
x: number;
y: number;
z: number;
};
rotation: {
x: number;
y: number;
z: number;
};
props?: Record<string, any>;
};

View File

@ -0,0 +1,397 @@
// 家具メタデータ
// 家具にはユーザーが設定できるプロパティを設定可能です:
//
// props: {
// <propname>: <proptype>
// }
//
// proptype一覧:
// * image ... 画像選択ダイアログを出し、その画像のURLが格納されます
// * color ... 色選択コントロールを出し、選択された色が格納されます
// 家具にカスタムテクスチャを適用できるようにするには、textureプロパティに以下の追加の情報を含めます:
// 便宜上そのUVのどの部分にカスタムテクスチャを貼り合わせるかのエリアをテクスチャエリアと呼びます。
// UVは1024*1024だと仮定します。
//
// <key>: {
// prop: <プロパティ名>,
// uv: {
// x: <テクスチャエリアX座標>,
// y: <テクスチャエリアY座標>,
// width: <テクスチャエリアの幅>,
// height: <テクスチャエリアの高さ>,
// },
// }
//
// <key>には、カスタムテクスチャを適用したいメッシュ名を指定します
// <プロパティ名>には、カスタムテクスチャとして使用する画像を格納するプロパティ(前述)名を指定します
// 家具にカスタムカラーを適用できるようにするには、colorプロパティに以下の追加の情報を含めます:
//
// <key>: <プロパティ名>
//
// <key>には、カスタムカラーを適用したいマテリアル名を指定します
// <プロパティ名>には、カスタムカラーとして使用する色を格納するプロパティ(前述)名を指定します
[
{
id: "milk",
place: "floor"
},
{
id: "bed",
place: "floor"
},
{
id: "low-table",
place: "floor",
props: {
color: 'color'
},
color: {
Table: 'color'
}
},
{
id: "desk",
place: "floor",
props: {
color: 'color'
},
color: {
Board: 'color'
}
},
{
id: "chair",
place: "floor",
props: {
color: 'color'
},
color: {
Chair: 'color'
}
},
{
id: "chair2",
place: "floor",
props: {
color1: 'color',
color2: 'color'
},
color: {
Cushion: 'color1',
Leg: 'color2'
}
},
{
id: "fan",
place: "wall"
},
{
id: "pc",
place: "floor"
},
{
id: "plant",
place: "floor"
},
{
id: "plant2",
place: "floor"
},
{
id: "eraser",
place: "floor"
},
{
id: "pencil",
place: "floor"
},
{
id: "pudding",
place: "floor"
},
{
id: "cardboard-box",
place: "floor"
},
{
id: "cardboard-box2",
place: "floor"
},
{
id: "cardboard-box3",
place: "floor"
},
{
id: "book",
place: "floor",
props: {
color: 'color'
},
color: {
Cover: 'color'
}
},
{
id: "book2",
place: "floor"
},
{
id: "piano",
place: "floor"
},
{
id: "facial-tissue",
place: "floor"
},
{
id: "server",
place: "floor"
},
{
id: "moon",
place: "floor"
},
{
id: "corkboard",
place: "wall"
},
{
id: "mousepad",
place: "floor",
props: {
color: 'color'
},
color: {
Pad: 'color'
}
},
{
id: "monitor",
place: "floor",
props: {
screen: 'image'
},
texture: {
Screen: {
prop: 'screen',
uv: {
x: 0,
y: 434,
width: 1024,
height: 588,
},
},
},
},
{
id: "tv",
place: "floor",
props: {
screen: 'image'
},
texture: {
Screen: {
prop: 'screen',
uv: {
x: 0,
y: 434,
width: 1024,
height: 588,
},
},
},
},
{
id: "keyboard",
place: "floor"
},
{
id: "carpet-stripe",
place: "floor",
props: {
color1: 'color',
color2: 'color'
},
color: {
CarpetAreaA: 'color1',
CarpetAreaB: 'color2'
},
},
{
id: "mat",
place: "floor",
props: {
color: 'color'
},
color: {
Mat: 'color'
}
},
{
id: "color-box",
place: "floor",
props: {
color: 'color'
},
color: {
main: 'color'
}
},
{
id: "wall-clock",
place: "wall"
},
{
id: "cube",
place: "floor",
props: {
color: 'color'
},
color: {
Cube: 'color'
}
},
{
id: "photoframe",
place: "wall",
props: {
photo: 'image',
color: 'color'
},
texture: {
Photo: {
prop: 'photo',
uv: {
x: 0,
y: 342,
width: 1024,
height: 683,
},
},
},
color: {
Frame: 'color'
}
},
{
id: "pinguin",
place: "floor",
props: {
body: 'color',
belly: 'color'
},
color: {
Body: 'body',
Belly: 'belly',
}
},
{
id: "rubik-cube",
place: "floor",
},
{
id: "poster-h",
place: "wall",
props: {
picture: 'image'
},
texture: {
Poster: {
prop: 'picture',
uv: {
x: 0,
y: 277,
width: 1024,
height: 745,
},
},
},
},
{
id: "poster-v",
place: "wall",
props: {
picture: 'image'
},
texture: {
Poster: {
prop: 'picture',
uv: {
x: 0,
y: 0,
width: 745,
height: 1024,
},
},
},
},
{
id: "sofa",
place: "floor",
props: {
color: 'color'
},
color: {
Sofa: 'color'
}
},
{
id: "spiral",
place: "floor",
props: {
color: 'color'
},
color: {
Step: 'color'
}
},
{
id: "bin",
place: "floor",
props: {
color: 'color'
},
color: {
Bin: 'color'
}
},
{
id: "cup-noodle",
place: "floor"
},
{
id: "holo-display",
place: "floor",
props: {
image: 'image'
},
texture: {
Image_Front: {
prop: 'image',
uv: {
x: 0,
y: 0,
width: 1024,
height: 1024,
},
},
Image_Back: {
prop: 'image',
uv: {
x: 0,
y: 0,
width: 1024,
height: 1024,
},
},
},
},
{
id: 'energy-drink',
place: "floor",
}
]

View File

@ -0,0 +1,776 @@
import autobind from 'autobind-decorator';
import { v4 as uuid } from 'uuid';
import * as THREE from 'three';
import { GLTFLoader, GLTF } from 'three/examples/jsm/loaders/GLTFLoader';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js';
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js';
import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass.js';
import { BloomPass } from 'three/examples/jsm/postprocessing/BloomPass.js';
import { FXAAShader } from 'three/examples/jsm/shaders/FXAAShader.js';
import { TransformControls } from 'three/examples/jsm/controls/TransformControls.js';
import { Furniture, RoomInfo } from './furniture';
import { query as urlQuery } from '../../../../../prelude/url';
const furnitureDefs = require('./furnitures.json5');
THREE.ImageUtils.crossOrigin = '';
type Options = {
graphicsQuality: Room['graphicsQuality'];
onChangeSelect: Room['onChangeSelect'];
useOrthographicCamera: boolean;
};
/**
* MisskeyRoom Core Engine
*/
export class Room {
private clock: THREE.Clock;
private scene: THREE.Scene;
private renderer: THREE.WebGLRenderer;
private camera: THREE.PerspectiveCamera | THREE.OrthographicCamera;
private controls: OrbitControls;
private composer: EffectComposer;
private mixers: THREE.AnimationMixer[] = [];
private furnitureControl: TransformControls;
private roomInfo: RoomInfo;
private graphicsQuality: 'cheep' | 'low' | 'medium' | 'high' | 'ultra';
private roomObj: THREE.Object3D;
private objects: THREE.Object3D[] = [];
private selectedObject: THREE.Object3D = null;
private onChangeSelect: Function;
private isTransformMode = false;
private renderFrameRequestId: number;
private get canvas(): HTMLCanvasElement {
return this.renderer.domElement;
}
private get furnitures(): Furniture[] {
return this.roomInfo.furnitures;
}
private set furnitures(furnitures: Furniture[]) {
this.roomInfo.furnitures = furnitures;
}
private get enableShadow() {
return this.graphicsQuality != 'cheep';
}
private get usePostFXs() {
return this.graphicsQuality !== 'cheep' && this.graphicsQuality !== 'low';
}
private get shadowQuality() {
return (
this.graphicsQuality === 'ultra' ? 16384 :
this.graphicsQuality === 'high' ? 8192 :
this.graphicsQuality === 'medium' ? 4096 :
this.graphicsQuality === 'low' ? 1024 :
0); // cheep
}
constructor(user, isMyRoom, roomInfo: RoomInfo, container, options: Options) {
this.roomInfo = roomInfo;
this.graphicsQuality = options.graphicsQuality;
this.onChangeSelect = options.onChangeSelect;
this.clock = new THREE.Clock(true);
//#region Init a scene
this.scene = new THREE.Scene();
const width = window.innerWidth;
const height = window.innerHeight;
//#region Init a renderer
this.renderer = new THREE.WebGLRenderer({
antialias: false,
stencil: false,
alpha: false,
powerPreference:
this.graphicsQuality === 'ultra' ? 'high-performance' :
this.graphicsQuality === 'high' ? 'high-performance' :
this.graphicsQuality === 'medium' ? 'default' :
this.graphicsQuality === 'low' ? 'low-power' :
'low-power' // cheep
});
this.renderer.setPixelRatio(window.devicePixelRatio);
this.renderer.setSize(width, height);
this.renderer.autoClear = false;
this.renderer.setClearColor(new THREE.Color(0x051f2d));
this.renderer.shadowMap.enabled = this.enableShadow;
this.renderer.shadowMap.type =
this.graphicsQuality === 'ultra' ? THREE.PCFSoftShadowMap :
this.graphicsQuality === 'high' ? THREE.PCFSoftShadowMap :
this.graphicsQuality === 'medium' ? THREE.PCFShadowMap :
this.graphicsQuality === 'low' ? THREE.BasicShadowMap :
THREE.BasicShadowMap; // cheep
container.appendChild(this.canvas);
//#endregion
//#region Init a camera
this.camera = options.useOrthographicCamera
? new THREE.OrthographicCamera(
width / - 2, width / 2, height / 2, height / - 2, -10, 10)
: new THREE.PerspectiveCamera(45, width / height);
if (options.useOrthographicCamera) {
this.camera.position.x = 2;
this.camera.position.y = 2;
this.camera.position.z = 2;
this.camera.zoom = 100;
this.camera.updateProjectionMatrix();
} else {
this.camera.position.x = 5;
this.camera.position.y = 2;
this.camera.position.z = 5;
}
this.scene.add(this.camera);
//#endregion
//#region AmbientLight
const ambientLight = new THREE.AmbientLight(0xffffff, 1);
this.scene.add(ambientLight);
//#endregion
if (this.graphicsQuality !== 'cheep') {
//#region Room light
const roomLight = new THREE.SpotLight(0xffffff, 0.1);
roomLight.position.set(0, 8, 0);
roomLight.castShadow = this.enableShadow;
roomLight.shadow.bias = -0.0001;
roomLight.shadow.mapSize.width = this.shadowQuality;
roomLight.shadow.mapSize.height = this.shadowQuality;
roomLight.shadow.camera.near = 0.1;
roomLight.shadow.camera.far = 9;
roomLight.shadow.camera.fov = 45;
this.scene.add(roomLight);
//#endregion
}
//#region Out light
const outLight1 = new THREE.SpotLight(0xffffff, 0.4);
outLight1.position.set(9, 3, -2);
outLight1.castShadow = this.enableShadow;
outLight1.shadow.bias = -0.001; // アクネ、アーチファクト対策 その代わりピーターパンが発生する可能性がある
outLight1.shadow.mapSize.width = this.shadowQuality;
outLight1.shadow.mapSize.height = this.shadowQuality;
outLight1.shadow.camera.near = 6;
outLight1.shadow.camera.far = 15;
outLight1.shadow.camera.fov = 45;
this.scene.add(outLight1);
const outLight2 = new THREE.SpotLight(0xffffff, 0.2);
outLight2.position.set(-2, 3, 9);
outLight2.castShadow = false;
outLight2.shadow.bias = -0.001; // アクネ、アーチファクト対策 その代わりピーターパンが発生する可能性がある
outLight2.shadow.camera.near = 6;
outLight2.shadow.camera.far = 15;
outLight2.shadow.camera.fov = 45;
this.scene.add(outLight2);
//#endregion
//#region Init a controller
this.controls = new OrbitControls(this.camera, this.canvas);
this.controls.target.set(0, 1, 0);
this.controls.enableZoom = true;
this.controls.enablePan = isMyRoom;
this.controls.minPolarAngle = 0;
this.controls.maxPolarAngle = Math.PI / 2;
this.controls.minAzimuthAngle = 0;
this.controls.maxAzimuthAngle = Math.PI / 2;
this.controls.enableDamping = true;
this.controls.dampingFactor = 0.2;
this.controls.mouseButtons.LEFT = 1;
this.controls.mouseButtons.MIDDLE = 2;
this.controls.mouseButtons.RIGHT = 0;
//#endregion
//#region POST FXs
if (!this.usePostFXs) {
this.composer = null;
} else {
const renderTarget = new THREE.WebGLRenderTarget(width, height, {
minFilter: THREE.LinearFilter,
magFilter: THREE.LinearFilter,
format: THREE.RGBFormat,
stencilBuffer: false,
});
const fxaa = new ShaderPass(FXAAShader);
fxaa.uniforms['resolution'].value = new THREE.Vector2(1 / width, 1 / height);
fxaa.renderToScreen = true;
this.composer = new EffectComposer(this.renderer, renderTarget);
this.composer.addPass(new RenderPass(this.scene, this.camera));
if (this.graphicsQuality === 'ultra') {
this.composer.addPass(new BloomPass(0.25, 30, 128.0, 512));
}
this.composer.addPass(fxaa);
}
//#endregion
//#endregion
//#region Label
//#region Avatar
const avatarUrl = `/proxy/?${urlQuery({ url: user.avatarUrl })}`;
const textureLoader = new THREE.TextureLoader();
textureLoader.crossOrigin = 'anonymous';
const iconTexture = textureLoader.load(avatarUrl);
iconTexture.wrapS = THREE.RepeatWrapping;
iconTexture.wrapT = THREE.RepeatWrapping;
iconTexture.anisotropy = 16;
const avatarMaterial = new THREE.MeshBasicMaterial({
map: iconTexture,
side: THREE.DoubleSide,
alphaTest: 0.5
});
const iconGeometry = new THREE.PlaneGeometry(1, 1);
const avatarObject = new THREE.Mesh(iconGeometry, avatarMaterial);
avatarObject.position.set(-3, 2.5, 2);
avatarObject.rotation.y = Math.PI / 2;
avatarObject.castShadow = false;
this.scene.add(avatarObject);
//#endregion
//#region Username
const name = user.username;
new THREE.FontLoader().load('/assets/fonts/helvetiker_regular.typeface.json', font => {
const nameGeometry = new THREE.TextGeometry(name, {
size: 0.5,
height: 0,
curveSegments: 8,
font: font,
bevelThickness: 0,
bevelSize: 0,
bevelEnabled: false
});
const nameMaterial = new THREE.MeshLambertMaterial({
color: 0xffffff
});
const nameObject = new THREE.Mesh(nameGeometry, nameMaterial);
nameObject.position.set(-3, 2.25, 1.25);
nameObject.rotation.y = Math.PI / 2;
nameObject.castShadow = false;
this.scene.add(nameObject);
});
//#endregion
//#endregion
//#region Interaction
if (isMyRoom) {
this.furnitureControl = new TransformControls(this.camera, this.canvas);
this.scene.add(this.furnitureControl);
// Hover highlight
this.canvas.onmousemove = this.onmousemove;
// Click
this.canvas.onmousedown = this.onmousedown;
}
//#endregion
//#region Init room
this.loadRoom();
//#endregion
//#region Load furnitures
for (const furniture of this.furnitures) {
this.loadFurniture(furniture).then(obj => {
this.scene.add(obj.scene);
this.objects.push(obj.scene);
});
}
//#endregion
// Start render
if (this.usePostFXs) {
this.renderWithPostFXs();
} else {
this.renderWithoutPostFXs();
}
}
@autobind
private renderWithoutPostFXs() {
this.renderFrameRequestId =
window.requestAnimationFrame(this.renderWithoutPostFXs);
// Update animations
const clock = this.clock.getDelta();
for (const mixer of this.mixers) {
mixer.update(clock);
}
this.controls.update();
this.renderer.render(this.scene, this.camera);
}
@autobind
private renderWithPostFXs() {
this.renderFrameRequestId =
window.requestAnimationFrame(this.renderWithPostFXs);
// Update animations
const clock = this.clock.getDelta();
for (const mixer of this.mixers) {
mixer.update(clock);
}
this.controls.update();
this.renderer.clear();
this.composer.render();
}
@autobind
private loadRoom() {
const type = this.roomInfo.roomType;
new GLTFLoader().load(`/assets/room/rooms/${type}/${type}.glb`, gltf => {
gltf.scene.traverse(child => {
if (!(child instanceof THREE.Mesh)) return;
child.receiveShadow = this.enableShadow;
child.material = new THREE.MeshLambertMaterial({
color: (child.material as THREE.MeshStandardMaterial).color,
map: (child.material as THREE.MeshStandardMaterial).map,
name: (child.material as THREE.MeshStandardMaterial).name,
});
// 異方性フィルタリング
if ((child.material as THREE.MeshLambertMaterial).map && this.graphicsQuality !== 'cheep') {
(child.material as THREE.MeshLambertMaterial).map.minFilter = THREE.LinearMipMapLinearFilter;
(child.material as THREE.MeshLambertMaterial).map.magFilter = THREE.LinearMipMapLinearFilter;
(child.material as THREE.MeshLambertMaterial).map.anisotropy = 8;
}
});
gltf.scene.position.set(0, 0, 0);
this.scene.add(gltf.scene);
this.roomObj = gltf.scene;
if (this.roomInfo.roomType === 'default') {
this.applyCarpetColor();
}
});
}
@autobind
private loadFurniture(furniture: Furniture) {
const def = furnitureDefs.find(d => d.id === furniture.type);
return new Promise<GLTF>((res, rej) => {
const loader = new GLTFLoader();
loader.load(`/assets/room/furnitures/${furniture.type}/${furniture.type}.glb`, gltf => {
const model = gltf.scene;
// Load animation
if (gltf.animations.length > 0) {
const mixer = new THREE.AnimationMixer(model);
this.mixers.push(mixer);
for (const clip of gltf.animations) {
mixer.clipAction(clip).play();
}
}
model.name = furniture.id;
model.position.x = furniture.position.x;
model.position.y = furniture.position.y;
model.position.z = furniture.position.z;
model.rotation.x = furniture.rotation.x;
model.rotation.y = furniture.rotation.y;
model.rotation.z = furniture.rotation.z;
model.traverse(child => {
if (!(child instanceof THREE.Mesh)) return;
child.castShadow = this.enableShadow;
child.receiveShadow = this.enableShadow;
(child.material as THREE.MeshStandardMaterial).metalness = 0;
// 異方性フィルタリング
if ((child.material as THREE.MeshStandardMaterial).map && this.graphicsQuality !== 'cheep') {
(child.material as THREE.MeshStandardMaterial).map.minFilter = THREE.LinearMipMapLinearFilter;
(child.material as THREE.MeshStandardMaterial).map.magFilter = THREE.LinearMipMapLinearFilter;
(child.material as THREE.MeshStandardMaterial).map.anisotropy = 8;
}
});
if (def.color) { // カスタムカラー
this.applyCustomColor(model);
}
if (def.texture) { // カスタムテクスチャ
this.applyCustomTexture(model);
}
res(gltf);
}, null, rej);
});
}
@autobind
private applyCarpetColor() {
this.roomObj.traverse(child => {
if (!(child instanceof THREE.Mesh)) return;
if (child.material &&
(child.material as THREE.MeshStandardMaterial).name &&
(child.material as THREE.MeshStandardMaterial).name === 'Carpet'
) {
const colorHex = parseInt(this.roomInfo.carpetColor.substr(1), 16);
(child.material as THREE.MeshStandardMaterial).color.setHex(colorHex);
}
});
}
@autobind
private applyCustomColor(model: THREE.Object3D) {
const furniture = this.furnitures.find(furniture => furniture.id === model.name);
const def = furnitureDefs.find(d => d.id === furniture.type);
if (def.color == null) return;
model.traverse(child => {
if (!(child instanceof THREE.Mesh)) return;
for (const t of Object.keys(def.color)) {
if (!child.material ||
!(child.material as THREE.MeshStandardMaterial).name ||
(child.material as THREE.MeshStandardMaterial).name !== t
) continue;
const prop = def.color[t];
const val = furniture.props ? furniture.props[prop] : undefined;
if (val == null) continue;
const colorHex = parseInt(val.substr(1), 16);
(child.material as THREE.MeshStandardMaterial).color.setHex(colorHex);
}
});
}
@autobind
private applyCustomTexture(model: THREE.Object3D) {
const furniture = this.furnitures.find(furniture => furniture.id === model.name);
const def = furnitureDefs.find(d => d.id === furniture.type);
if (def.texture == null) return;
model.traverse(child => {
if (!(child instanceof THREE.Mesh)) return;
for (const t of Object.keys(def.texture)) {
if (child.name !== t) continue;
const prop = def.texture[t].prop;
const val = furniture.props ? furniture.props[prop] : undefined;
if (val == null) continue;
const canvas = document.createElement('canvas');
canvas.height = 1024;
canvas.width = 1024;
child.material = new THREE.MeshLambertMaterial({
emissive: 0x111111,
side: THREE.DoubleSide,
alphaTest: 0.5,
});
const img = new Image();
img.crossOrigin = 'anonymous';
img.onload = () => {
const uvInfo = def.texture[t].uv;
const ctx = canvas.getContext('2d');
ctx.drawImage(img,
0, 0, img.width, img.height,
uvInfo.x, uvInfo.y, uvInfo.width, uvInfo.height);
const texture = new THREE.Texture(canvas);
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
texture.anisotropy = 16;
texture.flipY = false;
(child.material as THREE.MeshLambertMaterial).map = texture;
(child.material as THREE.MeshLambertMaterial).needsUpdate = true;
(child.material as THREE.MeshLambertMaterial).map.needsUpdate = true;
};
img.src = val;
}
});
}
@autobind
private onmousemove(ev: MouseEvent) {
if (this.isTransformMode) return;
const rect = (ev.target as HTMLElement).getBoundingClientRect();
const x = (((ev.clientX * window.devicePixelRatio) - rect.left) / this.canvas.width) * 2 - 1;
const y = -(((ev.clientY * window.devicePixelRatio) - rect.top) / this.canvas.height) * 2 + 1;
const pos = new THREE.Vector2(x, y);
this.camera.updateMatrixWorld();
const raycaster = new THREE.Raycaster();
raycaster.setFromCamera(pos, this.camera);
const intersects = raycaster.intersectObjects(this.objects, true);
for (const object of this.objects) {
if (this.isSelectedObject(object)) continue;
object.traverse(child => {
if (child instanceof THREE.Mesh) {
(child.material as THREE.MeshStandardMaterial).emissive.setHex(0x000000);
}
});
}
if (intersects.length > 0) {
const intersected = this.getRoot(intersects[0].object);
if (this.isSelectedObject(intersected)) return;
intersected.traverse(child => {
if (child instanceof THREE.Mesh) {
(child.material as THREE.MeshStandardMaterial).emissive.setHex(0x191919);
}
});
}
}
@autobind
private onmousedown(ev: MouseEvent) {
if (this.isTransformMode) return;
if (ev.target !== this.canvas || ev.button !== 0) return;
const rect = (ev.target as HTMLElement).getBoundingClientRect();
const x = (((ev.clientX * window.devicePixelRatio) - rect.left) / this.canvas.width) * 2 - 1;
const y = -(((ev.clientY * window.devicePixelRatio) - rect.top) / this.canvas.height) * 2 + 1;
const pos = new THREE.Vector2(x, y);
this.camera.updateMatrixWorld();
const raycaster = new THREE.Raycaster();
raycaster.setFromCamera(pos, this.camera);
const intersects = raycaster.intersectObjects(this.objects, true);
for (const object of this.objects) {
object.traverse(child => {
if (child instanceof THREE.Mesh) {
(child.material as THREE.MeshStandardMaterial).emissive.setHex(0x000000);
}
});
}
if (intersects.length > 0) {
const selectedObj = this.getRoot(intersects[0].object);
this.selectFurniture(selectedObj);
} else {
this.selectedObject = null;
this.onChangeSelect(null);
}
}
@autobind
private getRoot(obj: THREE.Object3D): THREE.Object3D {
let found = false;
let x = obj.parent;
while (!found) {
if (x.parent.parent == null) {
found = true;
} else {
x = x.parent;
}
}
return x;
}
@autobind
private isSelectedObject(obj: THREE.Object3D): boolean {
if (this.selectedObject == null) {
return false;
} else {
return obj.name === this.selectedObject.name;
}
}
@autobind
private selectFurniture(obj: THREE.Object3D) {
this.selectedObject = obj;
this.onChangeSelect(obj);
obj.traverse(child => {
if (child instanceof THREE.Mesh) {
(child.material as THREE.MeshStandardMaterial).emissive.setHex(0xff0000);
}
});
}
/**
* 家具の移動/回転モードにします
* @param type 移動か回転か
*/
@autobind
public enterTransformMode(type: 'translate' | 'rotate') {
this.isTransformMode = true;
this.furnitureControl.setMode(type);
this.furnitureControl.attach(this.selectedObject);
}
/**
* 家具の移動/回転モードを終了します
*/
@autobind
public exitTransformMode() {
this.isTransformMode = false;
this.furnitureControl.detach();
}
/**
* 家具プロパティを更新します
* @param key プロパティ名
* @param value 値
*/
@autobind
public updateProp(key: string, value: any) {
const furniture = this.furnitures.find(furniture => furniture.id === this.selectedObject.name);
if (furniture.props == null) furniture.props = {};
furniture.props[key] = value;
this.applyCustomColor(this.selectedObject);
this.applyCustomTexture(this.selectedObject);
}
/**
* 部屋に家具を追加します
* @param type 家具の種類
*/
@autobind
public addFurniture(type: string) {
const furniture = {
id: uuid(),
type: type,
position: {
x: 0,
y: 0,
z: 0,
},
rotation: {
x: 0,
y: 0,
z: 0,
},
};
this.furnitures.push(furniture);
this.loadFurniture(furniture).then(obj => {
this.scene.add(obj.scene);
this.objects.push(obj.scene);
});
}
/**
* 現在選択されている家具を部屋から削除します
*/
@autobind
public removeFurniture() {
this.exitTransformMode();
const obj = this.selectedObject;
this.scene.remove(obj);
this.objects = this.objects.filter(object => object.name !== obj.name);
this.furnitures = this.furnitures.filter(furniture => furniture.id !== obj.name);
this.selectedObject = null;
this.onChangeSelect(null);
}
/**
* 全ての家具を部屋から削除します
*/
@autobind
public removeAllFurnitures() {
this.exitTransformMode();
for (const obj of this.objects) {
this.scene.remove(obj);
}
this.objects = [];
this.furnitures = [];
this.selectedObject = null;
this.onChangeSelect(null);
}
/**
* 部屋の床の色を変更します
* @param color 色
*/
@autobind
public updateCarpetColor(color: string) {
this.roomInfo.carpetColor = color;
this.applyCarpetColor();
}
/**
* 部屋の種類を変更します
* @param type 種類
*/
@autobind
public changeRoomType(type: string) {
this.roomInfo.roomType = type;
this.scene.remove(this.roomObj);
this.loadRoom();
}
/**
* 部屋データを取得します
*/
@autobind
public getRoomInfo() {
for (const obj of this.objects) {
const furniture = this.furnitures.find(f => f.id === obj.name);
furniture.position.x = obj.position.x;
furniture.position.y = obj.position.y;
furniture.position.z = obj.position.z;
furniture.rotation.x = obj.rotation.x;
furniture.rotation.y = obj.rotation.y;
furniture.rotation.z = obj.rotation.z;
}
return this.roomInfo;
}
/**
* 選択されている家具を取得します
*/
@autobind
public getSelectedObject() {
return this.selectedObject;
}
@autobind
public findFurnitureById(id: string) {
return this.furnitures.find(furniture => furniture.id === id);
}
/**
* レンダリングを終了します
*/
@autobind
public destroy() {
// Stop render loop
window.cancelAnimationFrame(this.renderFrameRequestId);
this.controls.dispose();
this.scene.dispose();
}
}

View File

@ -0,0 +1,64 @@
import { faHistory } from '@fortawesome/free-solid-svg-icons';
export async function search(v: any, q: string) {
q = q.trim();
if (q.startsWith('@') && !q.includes(' ')) {
v.$router.push(`/${q}`);
return;
}
if (q.startsWith('#')) {
v.$router.push(`/tags/${encodeURIComponent(q.substr(1))}`);
return;
}
// like 2018/03/12
if (/^[0-9]{4}\/[0-9]{2}\/[0-9]{2}/.test(q.replace(/-/g, '/'))) {
const date = new Date(q.replace(/-/g, '/'));
// 日付しか指定されてない場合、例えば 2018/03/12 ならユーザーは
// 2018/03/12 のコンテンツを「含む」結果になることを期待するはずなので
// 23時間59分進める(そのままだと 2018/03/12 00:00:00 「まで」の
// 結果になってしまい、2018/03/12 のコンテンツは含まれない)
if (q.replace(/-/g, '/').match(/^[0-9]{4}\/[0-9]{2}\/[0-9]{2}$/)) {
date.setHours(23, 59, 59, 999);
}
v.$root.$emit('warp', date);
v.$root.dialog({
icon: faHistory,
splash: true,
});
return;
}
if (q.startsWith('https://')) {
const dialog = v.$root.dialog({
type: 'waiting',
text: v.$t('@.fetching-as-ap-object'),
showOkButton: false,
showCancelButton: false,
cancelableByBgClick: false
});
try {
const res = await v.$root.api('ap/show', {
uri: q
});
dialog.close();
if (res.type == 'User') {
v.$router.push(`/@${res.object.username}@${res.object.host}`);
} else if (res.type == 'Note') {
v.$router.push(`/notes/${res.object.id}`);
}
} catch (e) {
dialog.close();
// TODO: Show error
}
return;
}
v.$router.push(`/search?q=${encodeURIComponent(q)}`);
}

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