Compare commits

...

325 Commits

Author SHA1 Message Date
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
d040dc19bc Merge branch 'develop' 2019-04-15 12:23:20 +09:00
a38ae4a402 11.0.2 2019-04-15 12:23:03 +09:00
772063aade Refactor 2019-04-15 12:20:48 +09:00
31c26354c5 Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2019-04-15 12:11:58 +09:00
64b331c5b2 Update read.ts 2019-04-15 12:11:32 +09:00
94f8a145ec Better permisson Fix #2341 (#4611)
* Better permisson Fix #2341

* add kinds.ts

* test

* fix

* v11

* fix
2019-04-15 12:10:40 +09:00
b357afa30a Clean up 2019-04-15 12:04:23 +09:00
fee0437493 Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2019-04-15 12:03:04 +09:00
663b8864c1 Fix bug 2019-04-15 12:03:00 +09:00
c6eafdde30 Fix bug 2019-04-15 11:59:25 +09:00
f32ff95256 New Crowdin translations (#4685)
* New translations ja-JP.yml (German)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Korean)

* 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 (Czech)
2019-04-15 11:33:08 +09:00
0452b75c3e Fix #4688 (#4689) 2019-04-15 11:32:53 +09:00
97efd23ec8 Update README.md [AUTOGEN] (#4691) 2019-04-15 11:31:32 +09:00
ea3e311528 簡易的なパーミッションの後方互換 (#4687) 2019-04-15 03:48:54 +09:00
0565454419 callbackUrlをappのレスポンスに追加 (#4686) 2019-04-15 03:39:31 +09:00
35c79c2f29 Fix bug 2019-04-15 03:20:14 +09:00
e6089aec48 Update README.md 2019-04-15 02:45:16 +09:00
dd3f7834c3 Merge branch 'develop' 2019-04-15 01:06:57 +09:00
f8cf18d880 11.0.1 2019-04-15 01:06:36 +09:00
2ac7e242b6 Fix test 2019-04-15 01:03:57 +09:00
d8b604a94f Update CHANGELOG.md 2019-04-14 23:18:01 +09:00
a1f7b00981 Clean up 2019-04-14 22:54:33 +09:00
b7ee42198c New translations ja-JP.yml (German) (#4683) 2019-04-14 22:40:35 +09:00
d66e4b7ff9 Merge branch 'develop' 2019-04-14 20:38:55 +09:00
7f9789cf65 11.0.0 2019-04-14 20:36:13 +09:00
b41c18e033 New translations ja-JP.yml (English) (#4681) 2019-04-14 20:31:15 +09:00
3c73a7ec6d inc/dec score 2019-04-14 20:28:57 +09:00
182c09d952 Update note.ts 2019-04-14 20:26:47 +09:00
9fb86aed04 Clean up 2019-04-14 18:18:20 +09:00
b8f7b13b05 11.0.0-beta.16 2019-04-14 17:44:16 +09:00
1ee1d5b6d1 Update and clean dependencies 🚀 2019-04-14 17:40:30 +09:00
154c38c314 Fix URL 2019-04-14 17:23:11 +09:00
3c0626752a 11.0.0-beta.15 2019-04-14 17:21:59 +09:00
511ef77fb7 Update CHANGELOG.md 2019-04-14 17:21:37 +09:00
4df3ede500 New Crowdin translations (#4641)
* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Polish)

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

* New translations ja-JP.yml (Spanish)

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

* New translations ja-JP.yml (Czech)

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

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

* New translations ja-JP.yml (English)

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

* New translations ja-JP.yml (French)

* 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 (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 (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)
2019-04-14 17:19:52 +09:00
e83c080af8 Update README.md [AUTOGEN] (#4678) 2019-04-14 17:18:55 +09:00
054220db70 リファクタリング (#4587)
* Use I cap

* Avoid _

* Use default value instead of optional boolean

* Bye useless variable

* Bye verbose try-catch
2019-04-14 17:18:17 +09:00
97bff010a8 Update README.md [AUTOGEN] (#4665) 2019-04-14 17:12:49 +09:00
487a3079cd Improve post form attaches; Fix #4673, Resolve #2327, Resolve #2145 [v11] (#4674)
* improve post form attaches

* Fix

* chain

* 右クリックでも反応するように
2019-04-14 17:12:04 +09:00
2d5158c680 Fix bug 2019-04-14 16:06:04 +09:00
837be06b72 Update docker-compose.yml 2019-04-14 12:05:12 +09:00
7e0d8dd4d7 11.0.0-beta.14 2019-04-14 12:00:49 +09:00
146fb23d7d Fix bug 2019-04-14 11:59:23 +09:00
61455ffe29 Fix bug 2019-04-14 11:58:10 +09:00
c267baafdc Fix bug 2019-04-14 11:56:37 +09:00
42248a306a Better error handling 2019-04-14 11:53:47 +09:00
694ec7ebe1 Fix bug 2019-04-14 11:50:31 +09:00
e3b3f8fac1 Better error handling 2019-04-14 04:17:24 +09:00
b390363b25 Update CHANGELOG.md 2019-04-14 02:44:49 +09:00
f6f8cdbcf2 11.0.0-beta.13 2019-04-14 02:36:21 +09:00
f46f53b8a3 Refactor 2019-04-14 02:36:00 +09:00
a2fcae4383 Fix bug 2019-04-14 02:33:50 +09:00
483f043768 11.0.0-beta.12 2019-04-14 02:24:27 +09:00
f8e0f4f21f Fix bug 2019-04-14 02:21:57 +09:00
9c3613e96d Improve error handling 2019-04-14 02:19:59 +09:00
d9cacdc86d Update meid.ts 2019-04-14 01:47:46 +09:00
aa3d2deeaa Add meid 2019-04-14 01:40:29 +09:00
e64912545a Update id generation methods 2019-04-14 01:08:26 +09:00
b247be80cc 11.0.0-beta.11 2019-04-13 20:02:47 +09:00
343f2f1f33 Fix bug 2019-04-13 20:02:31 +09:00
2d590df900 Clean up 2019-04-13 20:01:32 +09:00
ba56b2b9fd Update CHANGELOG.md 2019-04-13 19:40:03 +09:00
bf472b0c5e refactor 2019-04-13 19:36:57 +09:00
f7961f34c5 Update CHANGELOG.md 2019-04-13 19:23:32 +09:00
e369031a28 Redis必須に 2019-04-13 19:19:32 +09:00
186d7bbfd9 Fix bug 2019-04-13 19:08:41 +09:00
60a11f8da5 11.0.0-beta.10 2019-04-13 18:58:48 +09:00
1181fcdceb Fix bug 2019-04-13 18:58:29 +09:00
8cb9852058 リプライ先をエラー時に無視すると本来は投票なのに投票じゃないと扱われおかしくなるのでエラーにするように 2019-04-13 18:45:07 +09:00
53d46d1cbe Fix error 2019-04-13 18:23:32 +09:00
275e1c8de9 Refactor 2019-04-13 18:17:27 +09:00
d46eca4c87 Refactor 2019-04-13 18:14:32 +09:00
2927fb1597 11.0.0-beta.9 2019-04-13 17:27:17 +09:00
8c72e011d2 Fix bug 2019-04-13 17:26:38 +09:00
69662e24c3 Fix bug 2019-04-13 17:24:56 +09:00
96099ffe98 11.0.0-beta.8 2019-04-13 16:55:13 +09:00
ae16b45c11 Fix bug 2019-04-13 16:54:21 +09:00
cfee87d3ef 11.0.0-beta.7 2019-04-13 15:18:27 +09:00
5fcf5bc635 Fix bug 2019-04-13 15:18:12 +09:00
14bcb813cc Update migrate.ts 2019-04-13 15:09:16 +09:00
6af19794b6 11.0.0-beta.6 2019-04-13 15:03:56 +09:00
8316186695 Clean packed responses 2019-04-13 15:02:15 +09:00
85d3023cd5 Clean packed responses 2019-04-13 14:55:59 +09:00
78414dee29 Add note 2019-04-13 14:45:51 +09:00
084135141f typo 2019-04-13 14:37:45 +09:00
467a21f028 Update CONTRIBUTING.md 2019-04-13 14:36:35 +09:00
6e284c44d6 Update CONTRIBUTING.md 2019-04-13 14:34:34 +09:00
daf9a449e8 Update CONTRIBUTING.md 2019-04-13 14:31:05 +09:00
960268fd33 typo 2019-04-13 14:17:50 +09:00
8c331da315 Fix bug 2019-04-13 14:11:15 +09:00
b0d626d862 Update CONTRIBUTING.md 2019-04-13 14:04:29 +09:00
a51fbd7316 Suppress errors 2019-04-13 04:00:02 +09:00
063f372f3c 11.0.0-beta.5 2019-04-13 01:53:00 +09:00
987168b863 strictNullChecks (#4666)
* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip
2019-04-13 01:43:22 +09:00
4ee40c3345 Fix bug 2019-04-12 14:24:56 +09:00
654daff7ce Better error handling 2019-04-12 13:07:56 +09:00
64e10e9619 11.0.0-beta.4 2019-04-12 02:25:56 +09:00
b89cffe98d Fix bug 2019-04-12 02:22:22 +09:00
bd76ba702f 🎨 2019-04-12 02:15:22 +09:00
5d52e9ce6b 11.0.0-beta.3 2019-04-12 01:56:48 +09:00
3c29027ca3 Clean up 2019-04-12 01:54:28 +09:00
2ff3069d23 トランザクションを使うようにしたり 2019-04-12 01:52:25 +09:00
4198246351 トランザクションを使用してアンケートレコードの挿入に失敗した場合に投稿レコードの挿入もなかったことにするように 2019-04-12 01:30:10 +09:00
2b6389b4dc Fix bug 2019-04-12 01:03:40 +09:00
d7df75ae6c Clean up 2019-04-12 01:01:25 +09:00
11c30eccb3 非正規化カラムを削除
非正規化するほどの情報じゃない
2019-04-12 00:42:39 +09:00
ab8c6515b8 Fix error log 2019-04-12 00:33:26 +09:00
d4ad36fa41 Update migrate.ts 2019-04-11 22:49:12 +09:00
4d688be3df Update migrate.ts 2019-04-11 22:44:04 +09:00
d2b75f3501 Update migrate.ts 2019-04-11 19:42:35 +09:00
46b78cb4ff Increase url column length 2019-04-11 19:03:49 +09:00
5d6e0d0f37 Update migrate.ts 2019-04-11 16:15:27 +09:00
e19d0a37bb Update migrate.ts 2019-04-11 16:09:33 +09:00
dea3e2132e Update migrate.ts 2019-04-11 15:53:15 +09:00
91c1ceefbd Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2019-04-11 12:59:16 +09:00
5c50989970 Fix bug 2019-04-11 12:59:09 +09:00
2a7e3b9c51 Fix: AP actor Service のサポートが不完全 (v11) (#4662) 2019-04-11 03:09:12 +09:00
ab302df0ae Update CHANGELOG.md 2019-04-11 00:18:37 +09:00
21e5809993 Clean up 2019-04-10 23:57:39 +09:00
c58afc67e8 Update migrate.ts 2019-04-10 20:13:14 +09:00
8e344f2deb 11.0.0-beta.2 2019-04-10 20:08:19 +09:00
c28f4ffb3f Clean up 2019-04-10 20:07:36 +09:00
2a40240310 Fix bug 2019-04-10 18:35:51 +09:00
0e9fba9287 11.0.0-beta.1 2019-04-10 18:25:16 +09:00
2e3dd2a30a Fix bug 2019-04-10 18:13:33 +09:00
dda5f6559d Fix bug 2019-04-10 18:10:09 +09:00
4152e59638 Fix bug 2019-04-10 18:05:39 +09:00
9d5a92bce6 11.0.0-alpha.10 2019-04-10 15:08:05 +09:00
30172b92e6 WebFingerリクエストで Proxy, Keep-Alive などをサポート #4658
Co-Authored-By: MeiMei <mei23@users.noreply.github.com>
2019-04-10 15:07:21 +09:00
8468a9d4c7 11.0.0-alpha.9 2019-04-10 15:04:33 +09:00
626cfb61ac テーブル分割 2019-04-10 15:04:27 +09:00
9603f3fa4f Delete get-user-summary.ts 2019-04-10 14:58:45 +09:00
619a1b9e53 Fix bug 2019-04-10 14:10:00 +09:00
62e76ad588 11.0.0-alpha.8 2019-04-10 01:00:00 +09:00
236d72685d More puny 2019-04-10 00:59:41 +09:00
72a5f7b1e2 Fix bug 2019-04-10 00:40:10 +09:00
d1c16a90b4 11.0.0-alpha.7 2019-04-10 00:01:10 +09:00
33a9783ae5 ドメインは常にPunycodeで保存するように 2019-04-09 23:59:32 +09:00
4d64fd665e Update update.ts 2019-04-09 23:40:55 +09:00
96443384fe 11.0.0-alpha.6 2019-04-09 23:35:34 +09:00
69939f1edb :) 2019-04-09 23:31:41 +09:00
e3c0058942 Refactor 2019-04-09 23:29:48 +09:00
3dc2361654 Update migrate.ts 2019-04-09 23:12:11 +09:00
ec2f709018 Update migrate.ts 2019-04-09 23:09:57 +09:00
ea06665c51 isRemote --> isLink 2019-04-09 23:07:08 +09:00
83b7010d6a 10.100.0 2019-04-09 21:13:52 +09:00
71654cbe47 Fix #4636 2019-04-09 21:11:05 +09:00
e8f96e848a Merge branch 'v10' of https://github.com/syuilo/misskey into v10 2019-04-09 21:10:36 +09:00
251abf21d4 Update .gitignore 2019-04-09 21:10:18 +09:00
d103427932 Fix non media thumbnails (#4380) 2019-04-09 21:07:46 +09:00
74a4bd704c Update migrate.ts 2019-04-09 21:05:49 +09:00
c62f3e0e45 11.0.0-alpha.5 2019-04-09 20:51:23 +09:00
a56a969433 Update dependencies 🚀 2019-04-09 20:49:56 +09:00
1016f94bbb Fix bug 2019-04-09 20:47:31 +09:00
e98cce9aee Update migrate.ts 2019-04-09 19:20:10 +09:00
d4bdb5d327 Update migrate.ts 2019-04-09 19:14:18 +09:00
db4378415e Update migrate.ts 2019-04-09 19:02:09 +09:00
9b594880c8 Restore crypto_key to migration 2019-04-09 19:02:02 +09:00
d44fc3db2f Update migrate.ts 2019-04-09 18:45:21 +09:00
5133b0a0c0 Update migrate.ts 2019-04-09 18:41:53 +09:00
815469304f typo 2019-04-09 18:37:14 +09:00
c651921c79 Fix bug 2019-04-09 18:36:43 +09:00
d18c835221 Update migrate.ts 2019-04-09 18:35:07 +09:00
e38335077e Update user.ts 2019-04-09 12:36:01 +09:00
34c150cf73 Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2019-04-09 12:31:48 +09:00
24cb3ba091 Update migrate.ts 2019-04-09 12:31:45 +09:00
c07eaef2d1 Update note.ts 2019-04-09 12:25:19 +09:00
5df708ac9f Delete mark-admin.js 2019-04-09 04:09:34 +09:00
38ffbe95e9 Update migrate.ts 2019-04-09 01:42:07 +09:00
8bec4042fc Update migrate.ts 2019-04-09 01:31:54 +09:00
ee7ef89dfb Fix bug 2019-04-09 01:31:48 +09:00
54a5246061 Update migrate.ts 2019-04-09 01:03:58 +09:00
fa6eae2937 Update migrate.ts 2019-04-08 23:24:44 +09:00
795be20ee1 Clean up 2019-04-08 23:06:05 +09:00
87d3a06dcd revert rename 2019-04-08 23:05:41 +09:00
8b5c917195 Update CHANGELOG.md 2019-04-08 22:23:33 +09:00
c7da0e59ff Update CHANGELOG.md 2019-04-08 21:46:11 +09:00
eb14acbe0c Doc: Update installing command (#4655)
Replace the "Checkout to Latest Release" command.
Current setup document will checkout latest alpha version.
Because grep command in the document does not exclude alpha version tags.
2019-04-08 21:40:13 +09:00
56860a6bef wip migration 2019-04-08 20:33:42 +09:00
735687be21 update token generation 2019-04-08 20:29:52 +09:00
592cdfa910 ユーザーリストでフォローボタンを表示するように (#4654) 2019-04-08 20:18:42 +09:00
f2ad1a0406 Fix: 投稿ウィジットでローカルのみの公開範囲で投稿できない (#4653) 2019-04-08 20:16:00 +09:00
fab0cc51b3 Fix 2019-04-08 19:56:42 +09:00
3a26acbdb2 ユーザーリストでフォローボタンを表示するように (#4603) 2019-04-08 17:20:16 +09:00
8d0c31bcda 11.0.0-alpha.4 2019-04-08 17:07:50 +09:00
0b99293d4c Fix bug 2019-04-08 17:04:37 +09:00
802153ff9b Fix bug 2019-04-08 16:49:05 +09:00
ec73e2d237 11.0.0-alpha.3 2019-04-08 16:43:51 +09:00
c32b020535 Update ja-JP.yml 2019-04-08 16:43:27 +09:00
c4441804e2 Fix bug 2019-04-08 16:41:41 +09:00
6c9d80d4e8 Fix bug 2019-04-08 16:39:02 +09:00
a231f8d26c Fix bug 2019-04-08 16:34:45 +09:00
82af9320c0 Fix: TLを遡った時に抜けがある時がある (v10) (#4629)
* Update the cursor when the timeline is updated

* fix releaseQueue
2019-04-08 15:18:44 +09:00
fceebf7388 Fix #4562 (#4563) 2019-04-08 15:17:39 +09:00
08da258b63 Update README.md 2019-04-08 15:11:03 +09:00
5994926440 11.0.0-alpha.2 2019-04-08 14:51:36 +09:00
30f2da4215 Fix bug 2019-04-08 14:41:23 +09:00
1a2229f886 Improve instance chart 2019-04-08 14:29:17 +09:00
1e166490d9 [Client] Better pagination
Fix #4628
Close #4629
2019-04-08 14:17:44 +09:00
1c57e6f80a i18n 2019-04-08 13:55:09 +09:00
a6537a8748 Fix: 投稿ウィジットでローカルのみの公開範囲で投稿できない (#4647) 2019-04-08 13:31:42 +09:00
842b75977b Update README.md [AUTOGEN] (#4652) 2019-04-08 04:21:37 +09:00
9b3dccf60c Update README.md [AUTOGEN] (#4649) 2019-04-08 04:20:53 +09:00
2d533e0cd8 Update CHANGELOG.md 2019-04-08 03:52:46 +09:00
9e1925c808 11.0.0-alpha.1 2019-04-08 03:48:26 +09:00
142d59be85 Fix bug 2019-04-08 03:35:02 +09:00
d9a5e06b5b Fix bug 2019-04-08 02:27:06 +09:00
b6889e9ac6 Fix bug 2019-04-08 00:46:01 +09:00
dc82203e9b Fix bug 2019-04-08 00:24:01 +09:00
6a30d32e7d Fix bug 2019-04-07 23:31:58 +09:00
d9780606b3 Refactor 2019-04-07 23:06:07 +09:00
fffa32df48 Fix bug 2019-04-07 23:05:57 +09:00
cad49892d3 Fix avgColor format 2019-04-07 22:57:30 +09:00
f0a29721c9 Use PostgreSQL instead of MongoDB (#4572)
* wip

* Update note.ts

* Update timeline.ts

* Update core.ts

* wip

* Update generate-visibility-query.ts

* wip

* wip

* wip

* wip

* wip

* Update global-timeline.ts

* wip

* wip

* wip

* Update vote.ts

* wip

* wip

* Update create.ts

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* Update files.ts

* wip

* wip

* Update CONTRIBUTING.md

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* Update read-notification.ts

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* Update cancel.ts

* wip

* wip

* wip

* Update show.ts

* wip

* wip

* Update gen-id.ts

* Update create.ts

* Update id.ts

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* Docker: Update files about Docker (#4599)

* Docker: Use cache if files used by `yarn install` was not updated

This patch reduces the number of times to installing node_modules.
For example, `yarn install` step will be skipped when only ".config/default.yml" is updated.

* Docker: Migrate MongoDB to Postgresql

Misskey uses Postgresql as a database instead of Mongodb since version 11.

* Docker: Uncomment about data persistence

This patch will save a lot of databases.

* wip

* wip

* wip

* Update activitypub.ts

* wip

* wip

* wip

* Update logs.ts

* wip

* Update drive-file.ts

* Update register.ts

* wip

* wip

* Update mentions.ts

* wip

* wip

* wip

* Update recommendation.ts

* wip

* Update index.ts

* wip

* Update recommendation.ts

* Doc: Update docker.ja.md and docker.en.md (#1) (#4608)

Update how to set up misskey.

* wip

* ✌️

* wip

* Update note.ts

* Update postgre.ts

* wip

* wip

* wip

* wip

* Update add-file.ts

* wip

* wip

* wip

* Clean up

* Update logs.ts

* wip

* 🍕

* wip

* Ad notes

* wip

* Update api-visibility.ts

* Update note.ts

* Update add-file.ts

* tests

* tests

* Update postgre.ts

* Update utils.ts

* wip

* wip

* Refactor

* wip

* Refactor

* wip

* wip

* Update show-users.ts

* Update update-instance.ts

* wip

* Update feed.ts

* Update outbox.ts

* Update outbox.ts

* Update user.ts

* wip

* Update list.ts

* Update update-hashtag.ts

* wip

* Update update-hashtag.ts

* Refactor

* Update update.ts

* wip

* wip

* ✌️

* clean up

* docs

* Update push.ts

* wip

* Update api.ts

* wip

* ✌️

* Update make-pagination-query.ts

* ✌️

* Delete hashtags.ts

* Update instances.ts

* Update instances.ts

* Update create.ts

* Update search.ts

* Update reversi-game.ts

* Update signup.ts

* Update user.ts

* id

* Update example.yml

* 🎨

* objectid

* fix

* reversi

* reversi

* Fix bug of chart engine

* Add test of chart engine

* Improve test

* Better testing

* Improve chart engine

* Refactor

* Add test of chart engine

* Refactor

* Add chart test

* Fix bug

* コミットし忘れ

* Refactoring

* ✌️

* Add tests

* Add test

* Extarct note tests

* Refactor

* 存在しないユーザーにメンションできなくなっていた問題を修正

* Fix bug

* Update update-meta.ts

* Fix bug

* Update mention.vue

* Fix bug

* Update meta.ts

* Update CONTRIBUTING.md

* Fix bug

* Fix bug

* Fix bug

* Clean up

* Clean up

* Update notification.ts

* Clean up

* Add mute tests

* Add test

* Refactor

* Add test

* Fix test

* Refactor

* Refactor

* Add tests

* Update utils.ts

* Update utils.ts

* Fix test

* Update package.json

* Update update.ts

* Update manifest.ts

* Fix bug

* Fix bug

* Add test

* 🎨

* Update endpoint permissions

* Updaye permisison

* Update person.ts

#4299

* データベースと同期しないように

* Fix bug

* Fix bug

* Update reversi-game.ts

* Use a feature of Node v11.7.0 to extract a public key (#4644)

* wip

* wip

* ✌️

* Refactoring

#1540

* test

* test

* test

* test

* test

* test

* test

* Fix bug

* Fix test

* 🍣

* wip

* #4471

* Add test for #4335

* Refactor

* Fix test

* Add tests

* 🕓

* Fix bug

* Add test

* Add test

* rename

* Fix bug
2019-04-07 21:50:36 +09:00
13caf37991 Update README.md [AUTOGEN] (#4639) 2019-04-06 12:47:02 +09:00
705 changed files with 16500 additions and 16060 deletions

View File

@ -5,12 +5,6 @@ executors:
working_directory: /tmp/workspace working_directory: /tmp/workspace
docker: docker:
- image: misskey/ci:latest - image: misskey/ci:latest
- image: circleci/mongo:latest
with-redis:
working_directory: /tmp/workspace
docker:
- image: misskey/ci:latest
- image: circleci/mongo:latest
- image: circleci/redis:latest - image: circleci/redis:latest
docker: docker:
working_directory: /tmp/workspace working_directory: /tmp/workspace
@ -62,22 +56,10 @@ jobs:
executor: executor:
type: string type: string
default: "default" default: "default"
without_redis:
type: boolean
default: false
executor: <<parameters.executor>> executor: <<parameters.executor>>
steps: steps:
- attach_workspace: - attach_workspace:
at: /tmp/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: - run:
name: Test name: Test
command: | command: |
@ -140,32 +122,14 @@ workflows:
branches: branches:
only: master only: master
- test: - test:
name: manual-test-with-redis name: manual-test
executor: with-redis
requires: requires:
- manual-build - manual-build
filters: filters:
branches: branches:
ignore: master ignore: master
- test: - test:
name: auto-test-without-redis name: auto-test
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
requires: requires:
- auto-build - auto-build
filters: filters:

View File

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

View File

@ -1,8 +1,16 @@
#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# Misskey configuration
#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# ┌─────┐
#───┘ URL └─────────────────────────────────────────────────────
# Final accessible URL seen by a user. # Final accessible URL seen by a user.
url: https://example.tld/ url: https://example.tld/
# ┌───────────────────────┐
#───┘ Port and TLS settings └───────────────────────────────────
### Port and TLS settings ######################################
# #
# Misskey supports two deployment options for public. # Misskey supports two deployment options for public.
# #
@ -30,28 +38,51 @@ url: https://example.tld/
# You need to set Certificate in 'https' section. # You need to set Certificate in 'https' section.
# To use option 1, uncomment below line. # To use option 1, uncomment below line.
# port: 3000 # A port that your Misskey server should listen. #port: 3000 # A port that your Misskey server should listen.
# To use option 2, uncomment below lines. # To use option 2, uncomment below lines.
# port: 443 #port: 443
#
# https: #https:
# # path for certification # # path for certification
# key: /etc/letsencrypt/live/example.tld/privkey.pem # key: /etc/letsencrypt/live/example.tld/privkey.pem
# cert: /etc/letsencrypt/live/example.tld/fullchain.pem # cert: /etc/letsencrypt/live/example.tld/fullchain.pem
################################################################ # ┌──────────────────────────┐
#───┘ PostgreSQL configuration └────────────────────────────────
db:
mongodb:
host: localhost host: localhost
port: 27017 port: 5432
# Database name
db: misskey db: misskey
# Auth
user: example-misskey-user user: example-misskey-user
pass: example-misskey-pass pass: example-misskey-pass
# ┌─────────────────────┐
#───┘ Redis configuration └─────────────────────────────────────
redis:
host: localhost
port: 6379
#pass: example-pass
# ┌─────────────────────────────┐
#───┘ Elasticsearch configuration └─────────────────────────────
#elasticsearch:
# host: localhost
# port: 9200
# pass: null
# ┌────────────────────────────────────┐
#───┘ File storage (Drive) configuration └──────────────────────
drive: drive:
storage: 'db' storage: 'fs'
# OR # OR
@ -88,26 +119,28 @@ drive:
# accessKey: XXX # accessKey: XXX
# secretKey: YYY # secretKey: YYY
# ┌───────────────┐
#───┘ ID generation └───────────────────────────────────────────
# You can select the ID generation method.
# You don't usually need to change this setting, but you can
# change it according to your preferences.
# Available methods:
# aid ... Short, Millisecond accuracy
# meid ... Similar to ObjectID, Millisecond accuracy
# ulid ... Millisecond accuracy
# objectid ... This is left for backward compatibility
id: 'aid'
# ┌─────────────────────┐
#───┘ Other configuration └─────────────────────────────────────
# If enabled: # If enabled:
# The first account created is automatically marked as Admin. # The first account created is automatically marked as Admin.
autoAdmin: true autoAdmin: true
#
# Below settings are optional
#
# Redis
#redis:
# host: localhost
# port: 6379
# pass: example-pass
# Elasticsearch
#elasticsearch:
# host: localhost
# port: 9200
# pass: null
# Whether disable HSTS # Whether disable HSTS
#disableHsts: true #disableHsts: true

View File

@ -1,13 +0,0 @@
var user = {
user: 'example-misskey-user',
pwd: 'example-misskey-pass',
roles: [
{
role: 'readWrite',
db: 'misskey'
}
]
};
db.createUser(user);

6
.dockerignore Executable file → Normal file
View File

@ -5,8 +5,8 @@
.vscode .vscode
Dockerfile Dockerfile
build/ build/
db/
docker-compose.yml docker-compose.yml
node_modules/
mongo/
redis/
elasticsearch/ elasticsearch/
node_modules/
redis/

5
.gitignore vendored
View File

@ -8,14 +8,15 @@
built built
/data /data
/.cache-loader /.cache-loader
/db
/elasticsearch
npm-debug.log npm-debug.log
*.pem *.pem
run.bat run.bat
api-docs.json api-docs.json
*.log *.log
/redis /redis
/mongo
/elasticsearch
*.code-workspace *.code-workspace
yarn.lock yarn.lock
.DS_Store .DS_Store
/files

View File

@ -5,6 +5,174 @@ If you encounter any problems with updating, please try the following:
1. `npm run clean` or `npm run cleanall` 1. `npm run clean` or `npm run cleanall`
2. Retry update (Don't forget `npm i`) 2. Retry update (Don't forget `npm i`)
How to migrate to v11 from v10
------------------------------
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. `npm i`
5. `npm run build`
6. `npm run init`
7. `npm run migrate`
8. master ブランチに戻す
9. enjoy
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
* アプリが作成できない問題を修正
* 「ハイライト」が表示されない問題を修正
* リモートの投稿に添付されている画像が小さい問題を修正
* モバイル版でリストの名前が表示されない問題を修正
* APIドキュメントにパーミッション一覧を追加
11.0.1 (2019/04/15)
-------------------
### Improvements
* 不要な依存関係を削除
11.0.0 daybreak (2019/04/14)
----------------------------
### Improvements
* **データベースがMongoDBからPostgreSQLに変更されました**
* **Redisが必須に**
* アカウントを完全に削除できるように
* 投稿フォームで添付ファイルの閲覧注意を確認/設定できるように
* ミュート/ブロック時にそのユーザーの投稿のウォッチをすべて解除するように
### Fixes
* フォロー申請数が実際より1すくなくなる問題を修正
* リストからアカウント削除したユーザーを削除できない問題を修正
* リストTLでフォローしていないユーザーの非公開投稿が流れる問題を修正
* リストTLでダイレクト投稿が流れない問題を修正
* ミュートしているユーザーの投稿がタイムラインに流れてくることがある問題を修正
### APIの破壊的変更
* v10時点で deprecated だったパラメータなどを削除
* ユーザーリストの title が name に
* リバーシの対局の`settings`プロパティがなくなり、その中にあったプロパティがすべて上の階層に
* 例えば`game.settings.map`は`game.map`になる
### 既知の問題
* ユーザー認証無しでのアプリが作成できない
* 依存ライブラリの問題と思わるため、対応が難しい
### Migration
coming soon...
10.100.0
----------
* ユーザーリストでフォローボタンを表示するように
* ドライブのファイルのサムネイルを修正
* 投稿ウィジットでローカルのみの公開範囲で投稿できない問題を修正
* TLを遡った時に抜けがある時がある問題を修正
* ユーザータイムラインが投稿日時順ではなくなっているのを修正
* 10.99.0 でチャートのレンダリングがおかしい問題を修正
10.99.0 10.99.0
---------- ----------
* manifest.json にインスタンス名を反映させるように * manifest.json にインスタンス名を反映させるように

View File

@ -46,10 +46,40 @@ Convert な(na) to にゃ(nya)
Revert Nyaize Revert Nyaize
## Code style ## Code style
### Use semicolon ### セミコロンを省略しない
To avoid ASI Hazard ASI Hazardを避けるためでもある
### 中括弧を省略しない
Bad:
``` ts
if (foo)
bar;
else
baz;
```
Good:
``` ts
if (foo) {
bar;
} else {
baz;
}
```
ただし**`if`が一行**の時だけは省略しても良い
Good:
``` ts
if (foo) bar;
```
### `export default`を使わない
インテリセンスと相性が悪かったりするため
参考:
* https://gfx.hatenablog.com/entry/2017/11/24/135343
* https://basarat.gitbooks.io/typescript/docs/tips/defaultIsBad.html
### Don't use `export default`
Bad: Bad:
``` ts ``` ts
export default function(foo: string): string { export default function(foo: string): string {
@ -75,3 +105,95 @@ src ... Source code
test ... Test code test ... Test code
``` ```
## Notes
### placeholder
SQLをクエリビルダで組み立てる際、使用するプレースホルダは重複してはならない
例えば
``` ts
query.andWhere(new Brackets(qb => {
for (const type of ps.fileType) {
qb.orWhere(`:type = ANY(note.attachedFileTypes)`, { type: type });
}
}));
```
と書くと、ループ中で`type`というプレースホルダが複数回使われてしまいおかしくなる
だから次のようにする必要がある
```ts
query.andWhere(new Brackets(qb => {
for (const type of ps.fileType) {
const i = ps.fileType.indexOf(type);
qb.orWhere(`:type${i} = ANY(note.attachedFileTypes)`, { [`type${i}`]: type });
}
}));
```
### `null` in SQL
SQLを発行する際、パラメータが`null`になる可能性のある場合はSQL文を出し分けなければならない
例えば
``` ts
query.where('file.folderId = :folderId', { folderId: ps.folderId });
```
という処理で、`ps.folderId`が`null`だと結果的に`file.folderId = null`のようなクエリが発行されてしまい、これは正しいSQLではないので期待した結果が得られない
だから次のようにする必要がある
``` ts
if (ps.folderId) {
query.where('file.folderId = :folderId', { folderId: ps.folderId });
} else {
query.where('file.folderId IS NULL');
}
```
### `[]` in SQL
SQLを発行する際、`IN`のパラメータが`[]`(空の配列)になる可能性のある場合はSQL文を出し分けなければならない
例えば
``` ts
const users = await Users.find({
id: In(userIds)
});
```
という処理で、`userIds`が`[]`だと結果的に`user.id IN ()`のようなクエリが発行されてしまい、これは正しいSQLではないので期待した結果が得られない
だから次のようにする必要がある
``` ts
const users = userIds.length > 0 ? await Users.find({
id: In(userIds)
}) : [];
```
### 配列のインデックス in SQL
SQLでは配列のインデックスは**1始まり**。
`[a, b, c]`の `a`にアクセスしたいなら`[0]`ではなく`[1]`と書く
### `undefined`にご用心
MongoDBの時とは違い、findOneでレコードを取得する時に対象レコードが存在しない場合 **`undefined`** が返ってくるので注意。
MongoDBは`null`で返してきてたので、その感覚で`if (x === null)`とか書くとバグる。代わりに`if (x == null)`と書いてください
### 簡素な`undefined`チェック
データベースからレコードを取得するときに、プログラムの流れ的に(ほぼ)絶対`undefined`にはならない場合でも、`undefined`チェックしないとTypeScriptに怒られます。
でもいちいち複数行を費やして、発生するはずのない`undefined`をチェックするのも面倒なので、`ensure`というユーティリティ関数を用意しています。
例えば、
``` ts
const user = await Users.findOne(userId);
// この時点で user の型は User | undefined
if (user == null) {
throw 'missing user';
}
// この時点で user の型は User
```
という処理を`ensure`を使うと
``` ts
const user = await Users.findOne(userId).then(ensure);
// この時点で user の型は User
```
という風に書けます。
もちろん`ensure`内部でエラーを握りつぶすようなことはしておらず、万が一`undefined`だった場合はPromiseがRejectされ後続の処理は実行されません。
``` ts
const user = await Users.findOne(userId).then(ensure);
// 万が一 Users.findOne の結果が undefined だったら、ensure でエラーが発生するので
// この行に到達することは無い
// なので、.then(ensure) は
// if (user == null) {
// throw 'missing user';
// }
// の糖衣構文のような扱いです
```

View File

@ -21,11 +21,11 @@ RUN apk add --no-cache \
pkgconfig \ pkgconfig \
python \ python \
zlib-dev zlib-dev
RUN npm i -g yarn
COPY package.json ./
RUN npm i
COPY . ./ COPY . ./
RUN yarn install RUN npm run build
RUN yarn build
FROM base AS runner FROM base AS runner

View File

@ -1,4 +1,4 @@
<a href="https://ai.misskey.xyz/"><img src="https://github.com/syuilo/misskey/blob/develop/assets/ai-orig.png?raw=true" align="right" height="320px"/></a> <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.xyz/)
================================================================ ================================================================
@ -59,7 +59,7 @@ Organize and store your files! Want to post a picture you have already uploaded?
--- ---
...and more! Experience Misskey with your own eyes at [misskey.xyz](https://misskey.xyz) or join one of the [other instances](https://joinmisskey.github.io/) that are available. ...and more! Experience Misskey with your own eyes at [misskey.io](https://misskey.io/) or join one of the [other instances](https://joinmisskey.github.io/) that are available.
Screen shots Screen shots
---------------------------------------------------------------- ----------------------------------------------------------------
@ -101,29 +101,31 @@ Please see the [Contribution Guide](./CONTRIBUTING.md).
---------------------------------------------------------------- ----------------------------------------------------------------
<!-- PATREON_START --> <!-- PATREON_START -->
<table><tr> <table><tr>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/5888816/36da0f7c15954df0ab13f9abdf227f66/1?token-time=2145916800&token-hash=HGkZJ7s4bSaQVoOJ5q30mTWHTxDLiw1LuyaogKPLy24%3D" alt="Hiroshi Seki" width="100"></td> <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/1?token-time=2145916800&token-hash=WeuDzzz24cRXJogyIkU-mxARqkdyms-rcZKbO-GpGjw%3D" alt="weep" 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://c8.patreon.com/2/200/12059069" alt="naga_rus" 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/12913507/f7181eacafe8469a93033d85f5969c29/4?token-time=2145916800&token-hash=vZdDTTF-ahiKBjjgppS2ev4rkD8H7TTKkXXoxsucs6Y%3D" alt="Melilot" 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> <td><img src="https://c8.patreon.com/2/200/16869916" alt="見当かなみ" width="100"></td>
</tr><tr> </tr><tr>
<td><a href="https://www.patreon.com/rane_hs">Hiroshi Seki</a></td> <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/weepjp">weep</a></td>
<td><a href="https://www.patreon.com/user?u=12059069">naga_rus</a></td> <td><a href="https://www.patreon.com/user?u=13099460">ne_moni</a></td>
<td><a href="https://www.patreon.com/user?u=12913507">Melilot</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> <td><a href="https://www.patreon.com/user?u=16869916">見当かなみ</a></td>
</tr></table> </tr></table>
<table><tr> <table><tr>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/12021162/963128bb8d14476dbd8407943db8f31a/1?token-time=2145916800&token-hash=1FlxS9MEgmNGH_RHUVHbO5hIXB5I1z0lvA33CTvYvjA%3D" alt="gutfuckllc" width="100"></td> <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/11357794/923ce94cd8c44ba788ee931907881839/1?token-time=2145916800&token-hash=0xgcpqvFDqRcV_YIEhcPNVH7gs9sLg_BBnTJXCkN4ao%3D" alt="mydarkstar" 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/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://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?token-time=2145916800&token-hash=2PsbFNw0tnubZzgSXD01R6hIgncfiElG7H7HX2Y3dyo%3D" alt="nemu" 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://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?token-time=2145916800&token-hash=9JtETp0X8gI280Ne1E8bxn6j4Lw5o2k4mJkICx97V_k%3D" alt="YUKIMOCHI" 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://c8.patreon.com/2/200/17463605" alt="Sampot" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/17880724/311738c8a48f4a6b9443c2445a75adde/1?token-time=2145916800&token-hash=95p8VdGX45E8BitZR_eOcDlqCjumjzNLBPQJrJdeCpI%3D" alt="takimura" width="100"></td> <td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/19356899/496b4681d33b4520bd7688e0fd19c04d/1.jpeg?token-time=2145916800&token-hash=3aMtpAjhwf01G3Uf8iIKYL8FUXXgxV7NvoQLne7lAKE%3D" alt="Ryosuke Yamamoto" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/17195955/be45e5e14c3e48b2bee0456c84e19df4/4?token-time=2145916800&token-hash=SbdZeN5SmsuT9stD6v0jN1z0hftg0FmRiCTxysU0Ihw%3D" alt="Damillora" 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>
</tr><tr> </tr><tr>
<td><a href="https://www.patreon.com/gutfuckllc">gutfuckllc</a></td> <td><a href="https://www.patreon.com/gutfuckllc">gutfuckllc</a></td>
<td><a href="https://www.patreon.com/mydarkstar">mydarkstar</a></td> <td><a href="https://www.patreon.com/mydarkstar">mydarkstar</a></td>
@ -133,19 +135,22 @@ Please see the [Contribution Guide](./CONTRIBUTING.md).
<td><a href="https://www.patreon.com/user?u=17866454">sikyosyounin</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/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=17463605">Sampot</a></td>
<td><a href="https://www.patreon.com/takimura">takimura</a></td> <td><a href="https://www.patreon.com/user?u=19356899">Ryosuke Yamamoto</a></td>
<td><a href="https://www.patreon.com/damillora">Damillora</a></td> <td><a href="https://www.patreon.com/user?u=13737140">Satsuki Yanagi</a></td>
</tr></table> </tr></table>
<table><tr> <table><tr>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/16900731/935a10339daa4ede8e555903a0707060/1?token-time=2145916800&token-hash=3CrpqH-XtKs_NoIlSsTyVs8wCzP1WFCsG2xwps1IJq0%3D" alt="Atsuko Tominaga" 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/4389829/9f709180ac714651a70f74a82f3ffdb9/3?token-time=2145916800&token-hash=-iJszBqgYBhsM5qMdA1knf9wvprhEfESzKfR2oh7mIA%3D" alt="natalie" width="100"></td> <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/13034746/c711c7f58e204ecfbc2fd646bc8a4eee/1?token-time=2145916800&token-hash=5T8XcaAf9Zyzfg3QubR06s_kJZkArVEM2dwObrBVAU4%3D" alt="Hiratake" width="100"></td> <td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/16900731/83884b38afc74d4cbe83c30a13b10edd/1.png?token-time=2145916800&token-hash=R5Tog8RWg0rguRoCIoir3lThokrdPvs8Utfikhc0nhY%3D" alt="Atsuko Tominaga" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/18072312/98e894d960314fa7bc236a72a39488fe/1?token-time=2145916800&token-hash=D6QK3fPyqiYKJfOzc-QqaSSairUrWdjld-ewp2waj6s%3D" alt="Hekovic" 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/4503830/ccf2cc867ea64de0b524bb2e24b9a1cb/1?token-time=2145916800&token-hash=Ksk_2l3gjPDbnzMUOCSW1E-hdPJsNs2tSR4_RAakRK8%3D" alt="dansup" 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/619786/32cf01444db24e578cd1982c197f6fc6/1?token-time=2145916800&token-hash=CXe9AqlZy9AsYfiWd3OBYVOzvODoN47Litz0Tu4BFpU%3D" alt="Gargron" width="100"></td> <td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/18072312/98e894d960314fa7bc236a72a39488fe/1.jpe?token-time=2145916800&token-hash=qA8j97lIZNc-74AuZ0p4F3ms6sKPeKjtNt2vEuwpsyo%3D" alt="Hekovic" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/5731881/4b6038e6cda34c04b83a5fcce3806a93/1?token-time=2145916800&token-hash=xhR1n6NAAyEb-IUXLD6_dshkFa3mefU5ZZuk1L8qKTs%3D" alt="Nokotaro Takeda" width="100"></td> <td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/4503830/ccf2cc867ea64de0b524bb2e24b9a1cb/1.jpeg?token-time=2145916800&token-hash=L55UhJ0rcuNAH3w_ryeeGN4hC6taoOixyAhraEi0bzw%3D" alt="dansup" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/12531784/93a45137841849329ba692da92ac7c60/1?token-time=2145916800&token-hash=uR-48MQ0A4j0irQSrCAQZJ-sJUSs_Fkihlg3-l59b7c%3D" alt="Takashi Shibuya" 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>
</tr><tr> </tr><tr>
<td><a href="https://www.patreon.com/takimura">takimura</a></td>
<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=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/user?u=4389829">natalie</a></td>
<td><a href="https://www.patreon.com/hiratake">Hiratake</a></td> <td><a href="https://www.patreon.com/hiratake">Hiratake</a></td>
@ -153,10 +158,14 @@ Please see the [Contribution Guide](./CONTRIBUTING.md).
<td><a href="https://www.patreon.com/dansup">dansup</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/mastodon">Gargron</a></td>
<td><a href="https://www.patreon.com/takenoko">Nokotaro Takeda</a></td> <td><a href="https://www.patreon.com/takenoko">Nokotaro Takeda</a></td>
</tr></table>
<table><tr>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/12531784/93a45137841849329ba692da92ac7c60/1.jpeg?token-time=2145916800&token-hash=vGe7wXGqmA8Q7m-kDNb6fyGdwk-Dxk4F-ut8ZZu51RM%3D" alt="Takashi Shibuya" width="100"></td>
</tr><tr>
<td><a href="https://www.patreon.com/user?u=12531784">Takashi Shibuya</a></td> <td><a href="https://www.patreon.com/user?u=12531784">Takashi Shibuya</a></td>
</tr></table> </tr></table>
**Last updated:** Fri, 05 Apr 2019 09:39:06 UTC **Last updated:** Thu, 18 Apr 2019 23:38:06 UTC
<!-- PATREON_END --> <!-- PATREON_END -->
:four_leaf_clover: Copyright :four_leaf_clover: Copyright

View File

@ -1,9 +0,0 @@
{
'targets': [
{
'target_name': 'crypto_key',
'sources': ['src/crypto_key.cc'],
'include_dirs': ['<!(node -e "require(\'nan\')")']
}
]
}

View File

@ -1,23 +0,0 @@
const mongo = require('mongodb');
const User = require('../built/models/user').default;
const args = process.argv.slice(2);
const user = args[0];
const q = user.startsWith('@') ? {
username: user.split('@')[1],
host: user.split('@')[2] || null
} : { _id: new mongo.ObjectID(user) };
console.log(`Mark as admin ${user}...`);
User.update(q, {
$set: {
isAdmin: true
}
}).then(() => {
console.log(`Done ${user}`);
}, e => {
console.error(e);
});

View File

@ -1,57 +0,0 @@
// for Node.js interpret
const chalk = require('chalk');
const sequential = require('promise-sequential');
const { default: User } = require('../../built/models/user');
const { default: DriveFile } = require('../../built/models/drive-file');
async function main() {
const promiseGens = [];
const count = await DriveFile.count({});
let prev;
for (let i = 0; i < count; i++) {
promiseGens.push(() => {
const promise = new Promise(async (res, rej) => {
const file = await DriveFile.findOne(prev ? {
_id: { $gt: prev._id }
} : {}, {
sort: {
_id: 1
}
});
prev = file;
const user = await User.findOne({ _id: file.metadata.userId });
DriveFile.update({
_id: file._id
}, {
$set: {
'metadata._user': {
host: user.host
}
}
}).then(() => {
res([i, file]);
}).catch(rej);
});
promise.then(([i, file]) => {
console.log(chalk`{gray ${i}} {green done: {bold ${file._id}} ${file.filename}}`);
});
return promise;
});
}
return await sequential(promiseGens);
}
main().then(() => {
console.log('ALL DONE');
}).catch(console.error);

View File

@ -1,71 +0,0 @@
// for Node.js interpret
const chalk = require('chalk');
const sequential = require('promise-sequential');
const { default: User } = require('../../built/models/user');
const { default: DriveFile } = require('../../built/models/drive-file');
async function main() {
const promiseGens = [];
const count = await User.count({});
let prev;
for (let i = 0; i < count; i++) {
promiseGens.push(() => {
const promise = new Promise(async (res, rej) => {
const user = await User.findOne(prev ? {
_id: { $gt: prev._id }
} : {}, {
sort: {
_id: 1
}
});
prev = user;
const set = {};
if (user.avatarId != null) {
const file = await DriveFile.findOne({ _id: user.avatarId });
if (file && file.metadata.properties.avgColor) {
set.avatarColor = file.metadata.properties.avgColor;
}
}
if (user.bannerId != null) {
const file = await DriveFile.findOne({ _id: user.bannerId });
if (file && file.metadata.properties.avgColor) {
set.bannerColor = file.metadata.properties.avgColor;
}
}
if (Object.keys(set).length === 0) return res([i, user]);
User.update({
_id: user._id
}, {
$set: set
}).then(() => {
res([i, user]);
}).catch(rej);
});
promise.then(([i, user]) => {
console.log(chalk`{gray ${i}} {green done: {bold ${user._id}} @${user.username}}`);
});
return promise;
});
}
return await sequential(promiseGens);
}
main().then(() => {
console.log('ALL DONE');
}).catch(console.error);

View File

@ -1,9 +0,0 @@
const { default: DriveFile } = require('../../built/models/drive-file');
DriveFile.update({}, {
$rename: {
'metadata.isMetaOnly': 'metadata.withoutChunks'
}
}, {
multi: true
});

View File

@ -1,134 +0,0 @@
const { default: Stats } = require('../../built/models/stats');
const { default: User } = require('../../built/models/user');
const { default: Note } = require('../../built/models/note');
const { default: DriveFile } = require('../../built/models/drive-file');
const now = new Date();
const y = now.getFullYear();
const m = now.getMonth();
const d = now.getDate();
const today = new Date(y, m, d);
async function main() {
const localUsersCount = await User.count({
host: null
});
const remoteUsersCount = await User.count({
host: { $ne: null }
});
const localNotesCount = await Note.count({
'_user.host': null
});
const remoteNotesCount = await Note.count({
'_user.host': { $ne: null }
});
const localDriveFilesCount = await DriveFile.count({
'metadata._user.host': null
});
const remoteDriveFilesCount = await DriveFile.count({
'metadata._user.host': { $ne: null }
});
const localDriveFilesSize = await DriveFile
.aggregate([{
$match: {
'metadata._user.host': null,
'metadata.deletedAt': { $exists: false }
}
}, {
$project: {
length: true
}
}, {
$group: {
_id: null,
usage: { $sum: '$length' }
}
}])
.then(aggregates => {
if (aggregates.length > 0) {
return aggregates[0].usage;
}
return 0;
});
const remoteDriveFilesSize = await DriveFile
.aggregate([{
$match: {
'metadata._user.host': { $ne: null },
'metadata.deletedAt': { $exists: false }
}
}, {
$project: {
length: true
}
}, {
$group: {
_id: null,
usage: { $sum: '$length' }
}
}])
.then(aggregates => {
if (aggregates.length > 0) {
return aggregates[0].usage;
}
return 0;
});
await Stats.insert({
date: today,
users: {
local: {
total: localUsersCount,
diff: 0
},
remote: {
total: remoteUsersCount,
diff: 0
}
},
notes: {
local: {
total: localNotesCount,
diff: 0,
diffs: {
normal: 0,
reply: 0,
renote: 0
}
},
remote: {
total: remoteNotesCount,
diff: 0,
diffs: {
normal: 0,
reply: 0,
renote: 0
}
}
},
drive: {
local: {
totalCount: localDriveFilesCount,
totalSize: localDriveFilesSize,
diffCount: 0,
diffSize: 0
},
remote: {
totalCount: remoteDriveFilesCount,
totalSize: remoteDriveFilesSize,
diffCount: 0,
diffSize: 0
}
}
});
console.log('done');
}
main();

View File

@ -1,144 +0,0 @@
const { default: Stats } = require('../../built/models/stats');
const { default: User } = require('../../built/models/user');
const { default: Note } = require('../../built/models/note');
const { default: DriveFile } = require('../../built/models/drive-file');
const now = new Date();
const y = now.getFullYear();
const m = now.getMonth();
const d = now.getDate();
const h = now.getHours();
const date = new Date(y, m, d, h);
async function main() {
await Stats.update({}, {
$set: {
span: 'day'
}
}, {
multi: true
});
const localUsersCount = await User.count({
host: null
});
const remoteUsersCount = await User.count({
host: { $ne: null }
});
const localNotesCount = await Note.count({
'_user.host': null
});
const remoteNotesCount = await Note.count({
'_user.host': { $ne: null }
});
const localDriveFilesCount = await DriveFile.count({
'metadata._user.host': null
});
const remoteDriveFilesCount = await DriveFile.count({
'metadata._user.host': { $ne: null }
});
const localDriveFilesSize = await DriveFile
.aggregate([{
$match: {
'metadata._user.host': null,
'metadata.deletedAt': { $exists: false }
}
}, {
$project: {
length: true
}
}, {
$group: {
_id: null,
usage: { $sum: '$length' }
}
}])
.then(aggregates => {
if (aggregates.length > 0) {
return aggregates[0].usage;
}
return 0;
});
const remoteDriveFilesSize = await DriveFile
.aggregate([{
$match: {
'metadata._user.host': { $ne: null },
'metadata.deletedAt': { $exists: false }
}
}, {
$project: {
length: true
}
}, {
$group: {
_id: null,
usage: { $sum: '$length' }
}
}])
.then(aggregates => {
if (aggregates.length > 0) {
return aggregates[0].usage;
}
return 0;
});
await Stats.insert({
date: date,
span: 'hour',
users: {
local: {
total: localUsersCount,
diff: 0
},
remote: {
total: remoteUsersCount,
diff: 0
}
},
notes: {
local: {
total: localNotesCount,
diff: 0,
diffs: {
normal: 0,
reply: 0,
renote: 0
}
},
remote: {
total: remoteNotesCount,
diff: 0,
diffs: {
normal: 0,
reply: 0,
renote: 0
}
}
},
drive: {
local: {
totalCount: localDriveFilesCount,
totalSize: localDriveFilesSize,
diffCount: 0,
diffSize: 0
},
remote: {
totalCount: remoteDriveFilesCount,
totalSize: remoteDriveFilesSize,
diffCount: 0,
diffSize: 0
}
}
});
console.log('done');
}
main();

View File

@ -5,8 +5,8 @@ services:
build: . build: .
restart: always restart: always
links: links:
- mongo - db
# - redis - redis
# - es # - es
ports: ports:
- "127.0.0.1:3000:3000" - "127.0.0.1:3000:3000"
@ -14,26 +14,23 @@ services:
- internal_network - internal_network
- external_network - external_network
# redis: redis:
# restart: always
# image: redis:4.0-alpine
# networks:
# - internal_network
### Uncomment to enable Redis persistance
## volumes:
## - ./redis:/data
mongo:
restart: always restart: always
image: mongo:4.1 image: redis:4.0-alpine
networks: networks:
- internal_network - internal_network
environment:
MONGO_INITDB_DATABASE: "misskey"
volumes: volumes:
- ./.config/mongo_initdb.js:/docker-entrypoint-initdb.d/mongo_initdb.js:ro - ./redis:/data
### Uncomment to enable MongoDB persistance
# - ./mongo:/data db:
restart: always
image: postgres:11.2-alpine
networks:
- internal_network
env_file:
- .config/docker.env
volumes:
- ./db:/var/lib/postgresql/data
# es: # es:
# restart: always # restart: always
@ -42,9 +39,8 @@ services:
# - "ES_JAVA_OPTS=-Xms512m -Xmx512m" # - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
# networks: # networks:
# - internal_network # - internal_network
#### Uncomment to enable ES persistence # volumes:
## volumes: # - ./elasticsearch:/usr/share/elasticsearch/data
## - ./elasticsearch:/usr/share/elasticsearch/data
networks: networks:
internal_network: internal_network:

View File

@ -1,22 +0,0 @@
Comment faire une sauvegarde de votre Misskey ?
==========================
Assurez-vous d'avoir installé **mongodb-tools**.
---
Dans votre terminal :
``` shell
$ mongodump --archive=db-backup -u <VotreNomdUtilisateur> -p <VotreMotDePasse>
```
Pour plus de détails, merci de consulter [la documentation de mongodump](https://docs.mongodb.com/manual/reference/program/mongodump/).
Restauration
-------
``` shell
$ mongorestore --archive=db-backup
```
Pour plus de détails, merci de consulter [la documentation de mongorestore](https://docs.mongodb.com/manual/reference/program/mongorestore/).

View File

@ -1,22 +0,0 @@
How to backup your Misskey
==========================
Make sure **mongodb-tools** installed.
---
In your shell:
``` shell
$ mongodump --archive=db-backup -u <YourUserName> -p <YourPassword>
```
For details, please see [mongodump docs](https://docs.mongodb.com/manual/reference/program/mongodump/).
Restore
-------
``` shell
$ mongorestore --archive=db-backup
```
For details, please see [mongorestore docs](https://docs.mongodb.com/manual/reference/program/mongorestore/).

View File

@ -9,15 +9,51 @@ This guide describes how to install and setup Misskey with Docker.
*1.* Download Misskey *1.* Download Misskey
---------------------------------------------------------------- ----------------------------------------------------------------
1. `git clone -b master git://github.com/syuilo/misskey.git` Clone Misskey repository's master branch. 1. Clone Misskey repository's master branch.
2. `cd misskey` Move to misskey directory.
3. `git checkout $(git tag -l | grep -v 'rc[0-9]*$' | sort -V | tail -n 1)` Checkout to the [latest release](https://github.com/syuilo/misskey/releases/latest) tag. `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 *2.* Configure Misskey
---------------------------------------------------------------- ----------------------------------------------------------------
1. `cp .config/example.yml .config/default.yml` Copy the `.config/example.yml` and rename it to `default.yml`.
2. `cp .config/mongo_initdb_example.js .config/mongo_initdb.js` Copy the `.config/mongo_initdb_example.js` and rename it to `mongo_initdb.js`. Create configuration files with following:
3. Edit `default.yml` and `mongo_initdb.js`.
```bash
cd .config
cp example.yml default.yml
cp docker_example.env docker.env
```
### `default.yml`
Edit this file the same as non-Docker environment.
However hostname of Postgresql, Redis and Elasticsearch are not `localhost`, they are set in `docker-compose.yml`.
The following is default hostname:
| Service | Hostname |
|---------------|----------|
| Postgresql | `db` |
| Redis | `redis` |
| Elasticsearch | `es` |
### `docker.env`
Configure Postgresql in this file.
The minimum required settings are:
| name | Description |
|---------------------|---------------|
| `POSTGRES_PASSWORD` | Password |
| `POSTGRES_USER` | Username |
| `POSTGRES_DB` | Database name |
*3.* Configure Docker *3.* Configure Docker
---------------------------------------------------------------- ----------------------------------------------------------------
@ -29,7 +65,13 @@ Build misskey with the following:
`docker-compose build` `docker-compose build`
*5.* That is it. *5.* Init DB
----------------------------------------------------------------
``` shell
docker-compose run --rm web npm run init
```
*6.* That is it.
---------------------------------------------------------------- ----------------------------------------------------------------
Well done! Now you have an environment to run Misskey. Well done! Now you have an environment to run Misskey.
@ -37,9 +79,9 @@ Well done! Now you have an environment to run Misskey.
Just `docker-compose up -d`. GLHF! Just `docker-compose up -d`. GLHF!
### How to update your Misskey server to the latest version ### How to update your Misskey server to the latest version
1. `git fetch` 1. `git stash`
2. `git stash` 2. `git checkout master`
3. `git checkout $(git tag -l | grep -v 'rc[0-9]*$' | sort -V | tail -n 1)` 3. `git pull`
4. `git stash pop` 4. `git stash pop`
5. `docker-compose build` 5. `docker-compose build`
6. Check [ChangeLog](../CHANGELOG.md) for migration information 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.* 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. 1. 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 -v 'rc[0-9]*$' | sort -V | tail -n 1)` Checkout sur le tag de la [dernière version](https://github.com/syuilo/misskey/releases/latest). `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 *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! Utilisez la commande `docker-compose up -d`. GLHF!
### How to update your Misskey server to the latest version ### How to update your Misskey server to the latest version
1. `git fetch` 1. `git stash`
2. `git stash` 2. `git checkout master`
3. `git checkout $(git tag -l | grep -v 'rc[0-9]*$' | sort -V | tail -n 1)` 3. `git pull`
4. `git stash pop` 4. `git stash pop`
5. `docker-compose build` 5. `docker-compose build`
6. Consultez le [ChangeLog](../CHANGELOG.md) pour avoir les éventuelles informations de migration 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) ### Configuration d'ElasticSearch (pour la fonction de recherche)
*1.* Préparation de l'environnement *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 1. 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)
`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 *2.* Après lancement du docker-compose, initialisation de la base ElasticSearch
---------------------------------------------------------------- ----------------------------------------------------------------
1. `docker-compose -it web /bin/sh` Connexion dans le conteneur web 1. 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 `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` 4. `exit`
---------------------------------------------------------------- ----------------------------------------------------------------

View File

@ -9,15 +9,51 @@ Dockerを使ったMisskey構築方法
*1.* Misskeyのダウンロード *1.* Misskeyのダウンロード
---------------------------------------------------------------- ----------------------------------------------------------------
1. `git clone -b master git://github.com/syuilo/misskey.git` masterブランチからMisskeyレポジトリをクローン 1. masterブランチからMisskeyレポジトリをクローン
2. `cd misskey` misskeyディレクトリに移動
3. `git checkout $(git tag -l | grep -v 'rc[0-9]*$' | sort -V | tail -n 1)` [最新のリリース](https://github.com/syuilo/misskey/releases/latest)を確認
*2.* 設定ファイルを作成する `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.* 設定ファイルの作成と編集
---------------------------------------------------------------- ----------------------------------------------------------------
1. `cp .config/example.yml .config/default.yml` `.config/example.yml`をコピーし名前を`default.yml`にする
2. `cp .config/mongo_initdb_example.js .config/mongo_initdb.js` `.config/mongo_initdb_example.js`をコピーし名前を`mongo_initdb.js`にする 下記コマンドで設定ファイルを作成してください。
3. `default.yml``mongo_initdb.js`を編集する
```bash
cd .config
cp example.yml default.yml
cp docker_example.env docker.env
```
### `default.yml`の編集
非Docker環境と同じ様に編集してください。
ただし、Postgresql、RedisとElasticsearchのホストは`localhost`ではなく、`docker-compose.yml`で設定されたサービス名になっています。
標準設定では次の通りです。
| サービス | ホスト名 |
|---------------|---------|
| Postgresql |`db` |
| Redis |`redis` |
| Elasticsearch |`es` |
### `docker.env`の編集
このファイルはPostgresqlの設定を記述します。
最低限記述する必要がある設定は次の通りです。
| 設定 | 内容 |
|---------------------|--------------|
| `POSTGRES_PASSWORD` | パスワード |
| `POSTGRES_USER` | ユーザー名 |
| `POSTGRES_DB` | データベース名 |
*3.* Dockerの設定 *3.* Dockerの設定
---------------------------------------------------------------- ----------------------------------------------------------------
@ -29,7 +65,13 @@ Dockerを使ったMisskey構築方法
`docker-compose build` `docker-compose build`
*5.* 以上です! *5.* データベースを初期化
----------------------------------------------------------------
``` shell
docker-compose run --rm web npm run init
```
*6.* 以上です!
---------------------------------------------------------------- ----------------------------------------------------------------
お疲れ様でした。これでMisskeyを動かす準備は整いました。 お疲れ様でした。これでMisskeyを動かす準備は整いました。
@ -37,9 +79,9 @@ Dockerを使ったMisskey構築方法
`docker-compose up -d`するだけです。GLHF! `docker-compose up -d`するだけです。GLHF!
### Misskeyを最新バージョンにアップデートする方法: ### Misskeyを最新バージョンにアップデートする方法:
1. `git fetch` 1. `git stash`
2. `git stash` 2. `git checkout master`
3. `git checkout $(git tag -l | grep -v 'rc[0-9]*$' | sort -V | tail -n 1)` 3. `git pull`
4. `git stash pop` 4. `git stash pop`
5. `docker-compose build` 5. `docker-compose build`
6. [ChangeLog](../CHANGELOG.md)でマイグレーション情報を確認する 6. [ChangeLog](../CHANGELOG.md)でマイグレーション情報を確認する

View File

@ -22,37 +22,45 @@ adduser --disabled-password --disabled-login misskey
Please install and setup these softwares: Please install and setup these softwares:
#### Dependencies :package: #### Dependencies :package:
* **[Node.js](https://nodejs.org/en/)** >= 10.0.0 * **[Node.js](https://nodejs.org/en/)** >= 11.7.0
* **[MongoDB](https://www.mongodb.com/)** >= 3.6 * **[PostgreSQL](https://www.postgresql.org/)** >= 10
* **[Redis](https://redis.io/)**
##### Optional ##### Optional
* [Redis](https://redis.io/)
* Redis is optional, but we strongly recommended to install it
* [Elasticsearch](https://www.elastic.co/) - required to enable the search feature * [Elasticsearch](https://www.elastic.co/) - required to enable the search feature
* [FFmpeg](https://www.ffmpeg.org/) * [FFmpeg](https://www.ffmpeg.org/)
*3.* Setup MongoDB *3.* Install Misskey
---------------------------------------------------------------- ----------------------------------------------------------------
As root: 1. Connect to misskey user.
1. `mongo` Go to the mongo shell
2. `use misskey` Use the misskey database
3. `db.createUser( { user: "misskey", pwd: "<password>", roles: [ { role: "readWrite", db: "misskey" } ] } )` Create the misskey user.
4. `exit` You're done!
*4.* Install Misskey `su - 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 -v 'rc[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.
*5.* Configure 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.
`npm install`
*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` 2. Edit `default.yml`
*6.* Build Misskey *5.* Build Misskey
---------------------------------------------------------------- ----------------------------------------------------------------
Build misskey with the following: Build misskey with the following:
@ -68,6 +76,12 @@ If you're still encountering errors about some modules, use node-gyp:
3. `node-gyp build` 3. `node-gyp build`
4. `NODE_ENV=production npm run build` 4. `NODE_ENV=production npm run build`
*6.* Init DB
----------------------------------------------------------------
``` shell
npm run init
```
*7.* That is it. *7.* That is it.
---------------------------------------------------------------- ----------------------------------------------------------------
Well done! Now, you have an environment that run to Misskey. Well done! Now, you have an environment that run to Misskey.
@ -77,37 +91,45 @@ Just `NODE_ENV=production npm start`. GLHF!
### Launch with systemd ### 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: 2. Edit it, and paste this and save:
``` ```
[Unit] [Unit]
Description=Misskey daemon Description=Misskey daemon
[Service] [Service]
Type=simple Type=simple
User=misskey User=misskey
ExecStart=/usr/bin/npm start ExecStart=/usr/bin/npm start
WorkingDirectory=/home/misskey/misskey WorkingDirectory=/home/misskey/misskey
Environment="NODE_ENV=production" Environment="NODE_ENV=production"
TimeoutSec=60 TimeoutSec=60
StandardOutput=syslog StandardOutput=syslog
StandardError=syslog StandardError=syslog
SyslogIdentifier=misskey SyslogIdentifier=misskey
Restart=always Restart=always
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target
``` ```
3. `systemctl daemon-reload ; systemctl enable misskey` Reload systemd and enable the misskey service. 3. Reload systemd and enable the misskey service.
4. `systemctl start misskey` Start 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`. You can check if the service is running with `systemctl status misskey`.
### How to update your Misskey server to the latest version ### How to update your Misskey server to the latest version
1. `git fetch` 1. `git checkout master`
2. `git checkout $(git tag -l | grep -v 'rc[0-9]*$' | sort -V | tail -n 1)` 2. `git pull`
3. `npm install` 3. `npm install`
4. `NODE_ENV=production npm run build` 4. `NODE_ENV=production npm run build`
5. Check [ChangeLog](../CHANGELOG.md) for migration information 5. Check [ChangeLog](../CHANGELOG.md) for migration information

View File

@ -22,37 +22,45 @@ adduser --disabled-password --disabled-login misskey
Installez les paquets suivants : Installez les paquets suivants :
#### Dépendences :package: #### Dépendences :package:
* **[Node.js](https://nodejs.org/en/)** >= 10.0.0 * **[Node.js](https://nodejs.org/en/)** >= 11.7.0
* **[MongoDB](https://www.mongodb.com/)** >= 3.6 * **[PostgreSQL](https://www.postgresql.org/)** >= 10
* **[Redis](https://redis.io/)**
##### Optionnels ##### Optionnels
* [Redis](https://redis.io/)
* Redis est optionnel mais nous vous recommandons vivement de l'installer
* [Elasticsearch](https://www.elastic.co/) - requis pour pouvoir activer la fonctionnalité de recherche * [Elasticsearch](https://www.elastic.co/) - requis pour pouvoir activer la fonctionnalité de recherche
* [FFmpeg](https://www.ffmpeg.org/) * [FFmpeg](https://www.ffmpeg.org/)
*3.* Paramètrage de MongoDB *3.* Installation de Misskey
---------------------------------------------------------------- ----------------------------------------------------------------
En root : 1. Basculez vers l'utilisateur misskey.
1. `mongo` Ouvrez le shell mongo
2. `use misskey` Utilisez la base de données misskey
3. `db.createUser( { user: "misskey", pwd: "<password>", roles: [ { role: "readWrite", db: "misskey" } ] } )` Créez l'utilisateur misskey.
4. `exit` Vous avez terminé !
*4.* Installation de Misskey `su - 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 -v 'rc[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.
*5.* Création du fichier de configuration 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.
`npm 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` 2. Editez le fichier `default.yml`
*6.* Construction de Misskey *5.* Construction de Misskey
---------------------------------------------------------------- ----------------------------------------------------------------
Construisez Misskey comme ceci : Construisez Misskey comme ceci :
@ -68,7 +76,7 @@ Si vous rencontrez des erreurs concernant certains modules, utilisez node-gyp:
3. `node-gyp build` 3. `node-gyp build`
4. `NODE_ENV=production npm run build` 4. `NODE_ENV=production npm run build`
*7.* C'est tout. *6.* C'est tout.
---------------------------------------------------------------- ----------------------------------------------------------------
Excellent ! Maintenant, vous avez un environnement prêt pour lancer Misskey Excellent ! Maintenant, vous avez un environnement prêt pour lancer Misskey
@ -77,37 +85,45 @@ Lancez tout simplement `NODE_ENV=production npm start`. Bonne chance et amusez-v
### Démarrage avec systemd ### 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 : 2. Editez-le puis copiez et coller ceci dans le fichier :
``` ```
[Unit] [Unit]
Description=Misskey daemon Description=Misskey daemon
[Service] [Service]
Type=simple Type=simple
User=misskey User=misskey
ExecStart=/usr/bin/npm start ExecStart=/usr/bin/npm start
WorkingDirectory=/home/misskey/misskey WorkingDirectory=/home/misskey/misskey
Environment="NODE_ENV=production" Environment="NODE_ENV=production"
TimeoutSec=60 TimeoutSec=60
StandardOutput=syslog StandardOutput=syslog
StandardError=syslog StandardError=syslog
SyslogIdentifier=misskey SyslogIdentifier=misskey
Restart=always Restart=always
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target
``` ```
3. `systemctl daemon-reload ; systemctl enable misskey` Redémarre systemd et active le service misskey. 3. Redémarre systemd et active le service misskey.
4. `systemctl start misskey` Démarre 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`. 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 ### Méthode de mise à jour vers la plus récente version de Misskey
1. `git fetch` 1. `git checkout master`
2. `git checkout $(git tag -l | grep -v 'rc[0-9]*$' | sort -V | tail -n 1)` 2. `git pull`
3. `npm install` 3. `npm install`
4. `NODE_ENV=production npm run build` 4. `NODE_ENV=production npm run build`
5. Consultez [ChangeLog](../CHANGELOG.md) pour les information de migration. 5. Consultez [ChangeLog](../CHANGELOG.md) pour les information de migration.

View File

@ -22,44 +22,46 @@ adduser --disabled-password --disabled-login misskey
これらのソフトウェアをインストール・設定してください: これらのソフトウェアをインストール・設定してください:
#### 依存関係 :package: #### 依存関係 :package:
* **[Node.js](https://nodejs.org/en/)** (10.0.0以上) * **[Node.js](https://nodejs.org/en/)** (11.7.0以上)
* **[MongoDB](https://www.mongodb.com/)** (3.6以上) * **[PostgreSQL](https://www.postgresql.org/)** (10以上)
* **[Redis](https://redis.io/)**
##### オプション ##### オプション
* [Redis](https://redis.io/)
* Redisはオプションですが、インストールすることを強く推奨します。
* インストールしなくていいのは、あなたのインスタンスが自分専用のときだけとお考えください。
* 具体的には、Redisをインストールしないと、次の事が出来なくなります:
* Misskeyプロセスを複数起動しての負荷分散
* レートリミット
* ジョブキュー
* Twitter連携
* [Elasticsearch](https://www.elastic.co/) * [Elasticsearch](https://www.elastic.co/)
* 検索機能を有効にするためにはインストールが必要です。 * 検索機能を有効にするためにはインストールが必要です。
* [FFmpeg](https://www.ffmpeg.org/) * [FFmpeg](https://www.ffmpeg.org/)
*3.* MongoDBの設定 *3.* Misskeyのインストール
---------------------------------------------------------------- ----------------------------------------------------------------
ルートで: 1. misskeyユーザーを使用
1. `mongo` mongoシェルを起動
2. `use misskey` misskeyデータベースを使用
3. `db.createUser( { user: "misskey", pwd: "<password>", roles: [ { role: "readWrite", db: "misskey" } ] } )` misskeyユーザーを作成
4. `exit` mongoシェルを終了
*4.* Misskeyのインストール `su - 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 -v 'rc[0-9]*$' | sort -V | tail -n 1)` [最新のリリース](https://github.com/syuilo/misskey/releases/latest)を確認
5. `npm install` Misskeyの依存パッケージをインストール
*5.* 設定ファイルを作成する 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の依存パッケージをインストール
`npm 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` を編集する。 2. `default.yml` を編集する。
*6.* Misskeyのビルド *5.* Misskeyのビルド
---------------------------------------------------------------- ----------------------------------------------------------------
次のコマンドでMisskeyをビルドしてください: 次のコマンドでMisskeyをビルドしてください:
@ -74,6 +76,12 @@ Debianをお使いであれば、`build-essential`パッケージをインスト
3. `node-gyp build` 3. `node-gyp build`
4. `NODE_ENV=production npm run build` 4. `NODE_ENV=production npm run build`
*6.* データベースを初期化
----------------------------------------------------------------
``` shell
npm run init
```
*7.* 以上です! *7.* 以上です!
---------------------------------------------------------------- ----------------------------------------------------------------
お疲れ様でした。これでMisskeyを動かす準備は整いました。 お疲れ様でした。これでMisskeyを動かす準備は整いました。
@ -82,38 +90,47 @@ Debianをお使いであれば、`build-essential`パッケージをインスト
`NODE_ENV=production npm start`するだけです。GLHF! `NODE_ENV=production npm start`するだけです。GLHF!
### systemdを用いた起動 ### systemdを用いた起動
1. systemdサービスのファイルを作成: `/etc/systemd/system/misskey.service` 1. systemdサービスのファイルを作成
`/etc/systemd/system/misskey.service`
2. エディタで開き、以下のコードを貼り付けて保存: 2. エディタで開き、以下のコードを貼り付けて保存:
``` ```
[Unit] [Unit]
Description=Misskey daemon Description=Misskey daemon
[Service] [Service]
Type=simple Type=simple
User=misskey User=misskey
ExecStart=/usr/bin/npm start ExecStart=/usr/bin/npm start
WorkingDirectory=/home/misskey/misskey WorkingDirectory=/home/misskey/misskey
Environment="NODE_ENV=production" Environment="NODE_ENV=production"
TimeoutSec=60 TimeoutSec=60
StandardOutput=syslog StandardOutput=syslog
StandardError=syslog StandardError=syslog
SyslogIdentifier=misskey SyslogIdentifier=misskey
Restart=always Restart=always
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target
``` ```
CentOSで1024以下のポートを使用してMisskeyを使用する場合は`ExecStart=/usr/bin/sudo /usr/bin/npm start`に変更する必要があります。
3. `systemctl daemon-reload ; systemctl enable misskey` systemdを再読み込みしmisskeyサービスを有効化 CentOSで1024以下のポートを使用してMisskeyを使用する場合は`ExecStart=/usr/bin/sudo /usr/bin/npm start`に変更する必要があります。
4. `systemctl start misskey` misskeyサービスの起動
3. systemdを再読み込みしmisskeyサービスを有効化
`systemctl daemon-reload ; systemctl enable misskey`
4. misskeyサービスの起動
`systemctl start misskey`
`systemctl status misskey`と入力すると、サービスの状態を調べることができます。 `systemctl status misskey`と入力すると、サービスの状態を調べることができます。
### Misskeyを最新バージョンにアップデートする方法: ### Misskeyを最新バージョンにアップデートする方法:
1. `git fetch` 1. `git checkout master`
2. `git checkout $(git tag -l | grep -v 'rc[0-9]*$' | sort -V | tail -n 1)` 2. `git pull`
3. `npm install` 3. `npm install`
4. `NODE_ENV=production npm run build` 4. `NODE_ENV=production npm run build`
5. [ChangeLog](../CHANGELOG.md)でマイグレーション情報を確認する 5. [ChangeLog](../CHANGELOG.md)でマイグレーション情報を確認する

View File

@ -49,7 +49,6 @@ gulp.task('build:copy:views', () =>
gulp.task('build:copy', gulp.parallel('build:copy:views', () => gulp.task('build:copy', gulp.parallel('build:copy:views', () =>
gulp.src([ gulp.src([
'./build/Release/crypto_key.node',
'./src/const.json', './src/const.json',
'./src/server/web/views/**/*', './src/server/web/views/**/*',
'./src/**/assets/**/*', './src/**/assets/**/*',
@ -120,7 +119,7 @@ gulp.task('copy:client', () =>
]) ])
.pipe(isProduction ? (imagemin as any)() : gutil.noop()) .pipe(isProduction ? (imagemin as any)() : gutil.noop())
.pipe(rename(path => { .pipe(rename(path => {
path.dirname = path.dirname.replace('assets', '.'); path.dirname = path.dirname!.replace('assets', '.');
})) }))
.pipe(gulp.dest('./built/client/assets/')) .pipe(gulp.dest('./built/client/assets/'))
); );

View File

@ -1 +1 @@
require('./built'); require('./built').default();

View File

@ -20,7 +20,7 @@ common:
outro: "Podívejte se na unikátní vlastnosti Misskey vlastníma očima! Pokud si myslíte, že tato instance není pro vás, zkuste jiné instance, neboť Misskey je decentralizovaná sociální síť, takže můžete snadno najít své přátele. Hodně štěstí a zábavy!" outro: "Podívejte se na unikátní vlastnosti Misskey vlastníma očima! Pokud si myslíte, že tato instance není pro vás, zkuste jiné instance, neboť Misskey je decentralizovaná sociální síť, takže můžete snadno najít své přátele. Hodně štěstí a zábavy!"
adblock: adblock:
detected: "Prosím vypněte svůj blokovač reklam" detected: "Prosím vypněte svůj blokovač reklam"
warning: "<strong>Misskey nepoužívá reklamy</strong>, některé vlastnosti však mohou být nedostupné nebo mohou způsobovat chyby, pokud máte povolený blokovač reklam." warning: "Některé vlastnosti mohou být nedostupné nebo mohou způsobovat chyby, pokud máte povolený blokovač reklam. <strong>Misskey nepoužívá reklamy</strong>."
application-authorization: "Autorizované aplikace" application-authorization: "Autorizované aplikace"
close: "Zavřít" close: "Zavřít"
do-not-copy-paste: "Prosím nezadávejte ani nevkládejte sem kód. Váš účet může být kompromitován." do-not-copy-paste: "Prosím nezadávejte ani nevkládejte sem kód. Váš účet může být kompromitován."
@ -69,6 +69,15 @@ common:
following: "Sledovaní" following: "Sledovaní"
followers: "Sledující" followers: "Sledující"
favorites: "Oblíbené" favorites: "Oblíbené"
permissions:
"read:account": "Zobrazit informace o účtu"
"read:drive": "Prohlížet Disk"
"write:drive": "Pracovat s Diskem"
"read:favorites": "Prohlížet oblíbené"
"read:messaging": "Prohlížet konverzaci"
"write:messaging": "Pracovat s konverzaci"
"read:mutes": "Prohlížet ztlumené"
"write:votes": "Hlasovat"
empty-timeline-info: empty-timeline-info:
follow-users-to-make-your-timeline: "Poznámky sledujících se zobrazí ve vaší časové ose" follow-users-to-make-your-timeline: "Poznámky sledujících se zobrazí ve vaší časové ose"
explore: "Najít uživatele" explore: "Najít uživatele"
@ -227,6 +236,7 @@ common:
cancel: "Zrušit" cancel: "Zrušit"
update-available-title: "Aktualizace k dispozici" 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." 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" verified-user: "Ověřené účty"
hide-password: "Skrýt heslo" hide-password: "Skrýt heslo"
show-password: "Zobrazit heslo" show-password: "Zobrazit heslo"
@ -281,12 +291,6 @@ common:
auth/views/form.vue: auth/views/form.vue:
share-access: "Chcete dovolit aplikaci <i>{name}</i> přístup k vašemu účtu?" share-access: "Chcete dovolit aplikaci <i>{name}</i> přístup k vašemu účtu?"
permission-ask: "Tato aplikace vyžaduje následující oprávnění:" permission-ask: "Tato aplikace vyžaduje následující oprávnění:"
account-read: "Zobrazit informace účtu"
note-write: "Odeslat."
following-write: "Sledovat a přestat sledovat"
drive-read: "Přečíst váš Disk"
notification-read: "Sledovat oznámení."
notification-write: "Zpravovat notifikace."
cancel: "Zrušit" cancel: "Zrušit"
accept: "Povolit přístup" accept: "Povolit přístup"
auth/views/index.vue: auth/views/index.vue:
@ -302,6 +306,7 @@ common/views/pages/explore.vue:
popular-tags: "Populární tagy" popular-tags: "Populární tagy"
federated: "Z fedivesmíru" federated: "Z fedivesmíru"
explore: "Prozkoumat {host}" explore: "Prozkoumat {host}"
users-info: "Aktuálně je zde registrováno {users} uživatelů"
common/views/components/url-preview.vue: common/views/components/url-preview.vue:
enable-player: "Otevřít v přehrávači" enable-player: "Otevřít v přehrávači"
disable-player: "Zavřít přehrávač" disable-player: "Zavřít přehrávač"
@ -354,19 +359,23 @@ common/views/components/connect-failed.troubleshooter.vue:
no-network-desc: "Ujistěte se že jste připojeni k Internetu." no-network-desc: "Ujistěte se že jste připojeni k Internetu."
no-internet: "Nejste 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-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"
common/views/components/media-banner.vue: common/views/components/media-banner.vue:
click-to-show: "Klikněte pro zobrazení" click-to-show: "Klikněte pro zobrazení"
common/views/components/theme.vue: common/views/components/theme.vue:
light-theme: "Šablona pro použití ve světlém vzhledu" light-theme: "Motiv pro použití ve světlém vzhledu"
dark-theme: "Šablona pro použití v tmavém vzhledu" dark-theme: "Motiv pro použití v tmavém vzhledu"
light-themes: "Světlý vzhled" light-themes: "Světlý vzhled"
dark-themes: "Tmavý vzhled" dark-themes: "Tmavý vzhled"
install-a-theme: "Nainstalovat šablonu" install-a-theme: "Nainstalovat motiv"
theme-code: "Kód šablony" theme-code: "Kód motivu"
install: "Nainstalovat" install: "Nainstalovat"
installed: "\"{}\" byl nainstalován" installed: "\"{}\" byl nainstalován"
create-a-theme: "Vytvořit motiv" create-a-theme: "Vytvořit motiv"
save-created-theme: "Uložit motiv"
base-theme: "Základní vzhled" base-theme: "Základní vzhled"
base-theme-light: "Světlý"
base-theme-dark: "Tmavý"
find-more-theme: "Najít další vzhledy" find-more-theme: "Najít další vzhledy"
theme-name: "Jméno vzhledu" theme-name: "Jméno vzhledu"
preview-created-theme: "Náhled" preview-created-theme: "Náhled"
@ -435,6 +444,7 @@ common/views/components/user-menu.vue:
unblock: "Odblokovat" unblock: "Odblokovat"
push-to-list: "Přidat do seznamu" push-to-list: "Přidat do seznamu"
select-list: "Vyberte seznam" select-list: "Vyberte seznam"
report-abuse: "Nahlásit spam"
report-abuse-reported: "Problém byl nahlášen administrátorovi. Děkujeme za Vaší kooperaci." report-abuse-reported: "Problém byl nahlášen administrátorovi. Děkujeme za Vaší kooperaci."
silence: "Ztlumit" silence: "Ztlumit"
suspend: "Zmrazit" suspend: "Zmrazit"
@ -793,8 +803,6 @@ desktop/views/components/settings.tags.vue:
title: "Tagy" title: "Tagy"
add: "Přidat" add: "Přidat"
save: "Uložit" save: "Uložit"
desktop/views/components/taskmanager.vue:
title: "Správce úloh"
desktop/views/components/timeline.vue: desktop/views/components/timeline.vue:
home: "Domů" home: "Domů"
local: "Lokální" local: "Lokální"
@ -839,7 +847,7 @@ admin/views/index.vue:
emoji: "Emoji" emoji: "Emoji"
moderators: "Moderátoři" moderators: "Moderátoři"
users: "Uživatelé" users: "Uživatelé"
federation: "Federovaná" federation: "Z fedivesmíru"
announcements: "Oznámení" announcements: "Oznámení"
hashtags: "Hashtagy" hashtags: "Hashtagy"
queue: "Fronta úloh" queue: "Fronta úloh"
@ -851,7 +859,7 @@ admin/views/dashboard.vue:
drive: "Disk" drive: "Disk"
instances: "Instance" instances: "Instance"
this-instance: "Tato instance" this-instance: "Tato instance"
federated: "Federovaná" federated: "Z fedivesmíru"
admin/views/abuse.vue: admin/views/abuse.vue:
details: "Popis" details: "Popis"
remove-report: "Odstranit" remove-report: "Odstranit"
@ -1006,7 +1014,7 @@ admin/views/federation.vue:
status: "Status" status: "Status"
latest-request-received-at: "Poslední požadavek přijat" latest-request-received-at: "Poslední požadavek přijat"
block: "Blokován" block: "Blokován"
instances: "Federovaná" instances: "Z fedivesmíru"
states: states:
all: "Všechny" all: "Všechny"
blocked: "Blokován" blocked: "Blokován"
@ -1112,7 +1120,7 @@ mobile/views/components/post-form.vue:
reply: "Odpovědět" reply: "Odpovědět"
renote: "Renotovat" renote: "Renotovat"
reply-placeholder: "Odpovědět na tento příspěvěk" reply-placeholder: "Odpovědět na tento příspěvěk"
location-alert: "Vaše zařízení nepodporuje lokační službu" geolocation-alert: "Vaše zařízení nepodporuje lokační službu"
error: "Chyba" error: "Chyba"
username-prompt: "Zadejte uživatelské jméno" username-prompt: "Zadejte uživatelské jméno"
mobile/views/components/sub-note-content.vue: mobile/views/components/sub-note-content.vue:
@ -1183,11 +1191,3 @@ deck/deck.user-column.vue:
activity: "Aktivita" activity: "Aktivita"
dev/views/new-app.vue: dev/views/new-app.vue:
app-name-desc: "Jméno vaší aplikace" app-name-desc: "Jméno vaší aplikace"
app-desc: "Stručný popis nebo představení vaší aplikace."
account-read: "Zobrazit informace účtu"
note-write: "Odeslat."
reaction-write: "Přidat nebo odebrat reakce."
following-write: "Sledovat a přestat sledovat"
drive-read: "Přečíst váš Disk"
notification-read: "Sledovat oznámení."
notification-write: "Zpravovat notifikace."

View File

@ -7,6 +7,7 @@ common:
about: "Danke, dass Du Misskey gefunden hast. Misskey ist eine <b>dezentralisierte Microblogging-Plattform</b>, welche auf der ganzen Welt verteilt ist. Da es innerhalb es Fediversums existiert (ein Universum, in dem verschiedene Soziale Netzwerke organisiert sind), ist es unmittelbar mit anderen sozialen Netzwerken verbunden. Warum nimmst du dir nicht einmal eine Auszeit von dem Trubel der Stadt und tauchst in das neue Internet hinein?" about: "Danke, dass Du Misskey gefunden hast. Misskey ist eine <b>dezentralisierte Microblogging-Plattform</b>, welche auf der ganzen Welt verteilt ist. Da es innerhalb es Fediversums existiert (ein Universum, in dem verschiedene Soziale Netzwerke organisiert sind), ist es unmittelbar mit anderen sozialen Netzwerken verbunden. Warum nimmst du dir nicht einmal eine Auszeit von dem Trubel der Stadt und tauchst in das neue Internet hinein?"
intro: intro:
title: "Was ist Misskey?" title: "Was ist Misskey?"
about: "Misskey ist eine Quelloffene, <b>dezentralisierte microblogging Software</b>. Es bietet eine erweiterbare Benutzeroberfläche, verschiedenste Möglichkeiten auf Beiträge zu reagieren, kostenlosen Datenspeicher, und andere fortschrittliche Funktionen. Zusätzlich ist Misskey dazu in der Lage, sich mittels des Fediverse mit beliebig vielen anderen ActivityPub-kompatiblen Diensten zu verbinden. Wenn du zum Beispiel einen Betrag mit Misskey abschickst, wird dieser auch für Nutzer von Mastodon oder Pleroma sichtbar sein. So ähnlich wie eine Radioübertragung zwischen Planeten."
features: "Funktionen" features: "Funktionen"
rich-contents: "Notizen" rich-contents: "Notizen"
reaction: "Reaktionen" reaction: "Reaktionen"
@ -19,6 +20,13 @@ common:
load-more: "Mehr laden" load-more: "Mehr laden"
enter-password: "Bitte Passwort eingeben" enter-password: "Bitte Passwort eingeben"
2fa: "Zwei-Faktor-Authentifizierung" 2fa: "Zwei-Faktor-Authentifizierung"
customize-home: "Layout Anpassen"
featured-notes: "Hervorgehobene Beiträge"
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?"
got-it: "Verstanden!" got-it: "Verstanden!"
customization-tips: customization-tips:
title: "Anpassung-Tipps" title: "Anpassung-Tipps"
@ -26,6 +34,7 @@ common:
notification: notification:
file-uploaded: "Datei hochgeladen!" file-uploaded: "Datei hochgeladen!"
message-from: "Nachricht von {}:" message-from: "Nachricht von {}:"
reversi-invited: "Zu einem Spiel eingeladen"
reversi-invited-by: "Eingeladen von {}:" reversi-invited-by: "Eingeladen von {}:"
notified-by: "Benachrichtigt von {}:" notified-by: "Benachrichtigt von {}:"
reply-from: "Antwort von {}:" reply-from: "Antwort von {}:"
@ -46,7 +55,24 @@ common:
drive: "Drive" drive: "Drive"
messaging: "Unterhaltungen" messaging: "Unterhaltungen"
home: "Home" home: "Home"
favorites: "Diese Notiz favorisieren" deck: "Stapel"
timeline: "Zeitleiste"
explore: "Entdecken"
following: "Folgt"
followers: "Folgende"
favorites: "Diesen Beitrag favorisieren"
permissions:
"read:account": "Accountinformationen anzeigen."
"write:account": "Accountinformationen bearbeiten."
"read:drive": "Dateien anzeigen"
"write:drive": "Dateien bearbeiten"
"read:favorites": "Favoriten anzeigen"
"read:messaging": "Unterhaltung anzeigen"
"write:messaging": "Unterhaltung 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"
weekday-short: weekday-short:
sunday: "So" sunday: "So"
monday: "Mo" monday: "Mo"
@ -77,11 +103,11 @@ common:
note-visibility: note-visibility:
public: "Öffentlich" public: "Öffentlich"
home: "Startseite" home: "Startseite"
home-desc: "Nur auf die Startseite posten" home-desc: "Auf die Startseite posten"
followers: "Abonnenten" followers: "Abonnenten"
followers-desc: "Nur für diejenigen sichtbar, die dir folgen" followers-desc: "Nur für diejenigen sichtbar, die dir folgen"
specified: "Direkt" specified: "Direkt"
specified-desc: "Nur für bestimmte Benutzer posten" specified-desc: "Nur für bestimmte Benutzer sichtbar"
local-public: "Öffentlich (nur lokal)" local-public: "Öffentlich (nur lokal)"
local-home: "Home (nur lokal)" local-home: "Home (nur lokal)"
local-followers: "Follower (nur lokal)" local-followers: "Follower (nur lokal)"
@ -91,11 +117,34 @@ common:
c: "Was geht dir durch den Kopf?" c: "Was geht dir durch den Kopf?"
d: "Willst du etwas sagen?" d: "Willst du etwas sagen?"
e: "Schreib hier etwas!" e: "Schreib hier etwas!"
f: "Warte darauf, das du schreibst." f: "Warte darauf, das du schreibst..."
settings: "Einstellungen"
_settings: _settings:
profile: "Dein Profil" profile: "Dein Profil"
notification: "Benachrichtigungen" notification: "Benachrichtigungen"
apps: "Anwendungen"
tags: "Hashtags"
mute-and-block: "Stummschalten/Blocken"
blocking: "Blocken"
security: "Sicherheit"
signin: "Login-Verlauf"
password: "Passwort" password: "Passwort"
other: "Mehr"
appearance: "Designs"
behavior: "Verhalten"
fetch-on-scroll: "Unendliches laden beim scrollen"
fetch-on-scroll-desc: "Wenn beim scrollen das Ende erreicht wird, lädt die Anwendung automatisch neue Inhalte nach."
note-visibility: "Sichtbarkeit von Beiträgen"
default-note-visibility: "Die Standardsichtbarkeit"
remember-note-visibility: "Erinnerung an Sichtbarkeit von Beiträgen"
web-search-engine: "Web-Suchmaschine"
web-search-engine-desc: "Beispiel: https://www.google.de/search?q={{query}}"
keep-cw: "Inhaltswarnung beibehalten"
keep-cw-desc: "Wenn auf einen Beitrag geantwortet wird, wird die Inhaltswarnung des Originalbeitrags übernommen."
i-like-sushi: "Ich bevorzuge Sushi anstelle von Pudding"
show-reversi-board-labels: "Zeige Reihen- und Spaltenbeschreibungen in Reversi an"
use-avatar-reversi-stones: "Avatar als Stein in Reversi anzeigen"
disable-animated-mfm: "Animierten Text in Beiträgen deaktivieren"
search: "Suche" search: "Suche"
delete: "Löschen" delete: "Löschen"
loading: "Laden" loading: "Laden"
@ -103,7 +152,7 @@ common:
update-available: "Eine neue Version von Misskey ist verfügbar ({newer}, aktuell ist {current}). Lade die Seite neu um die aktuelle Version zu laden" 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." my-token-regenerated: "Dein Token wurde generiert. Du wirst jetzt abgemeldet."
verified-user: "Verifizierter Benutzer" verified-user: "Verifizierter Benutzer"
do-not-use-in-production: "Dies ist eine Entwicklungsversion. Nicht in einer Produktionsumgebung verwenden." do-not-use-in-production: "Dies ist eine Entwicklungsversion. Nicht in einer Produktivumgebung verwenden."
error: error:
retry: "Erneut versuchen" retry: "Erneut versuchen"
reversi: reversi:
@ -117,7 +166,7 @@ common:
analog-clock: "Analoge Uhr" analog-clock: "Analoge Uhr"
profile: "Profil" profile: "Profil"
calendar: "Kalender" calendar: "Kalender"
timemachine: "Kalender (Zeitmaschiene)" timemachine: "Kalender (Zeitmaschine)"
activity: "Aktivitäten" activity: "Aktivitäten"
rss: "RSS Leser" rss: "RSS Leser"
memo: "Notizen" memo: "Notizen"
@ -128,7 +177,7 @@ common:
notifications: "Benachrichtigungen" notifications: "Benachrichtigungen"
users: "Empfohlene Benutzer" users: "Empfohlene Benutzer"
polls: "Umfrage" polls: "Umfrage"
post-form: "Beitragsform" post-form: "\"Neuer Beitrag\"-Formular"
server: "Server-Info" server: "Server-Info"
nav: "Navigation" nav: "Navigation"
tips: "Tipps" tips: "Tipps"
@ -138,13 +187,6 @@ common:
auth/views/form.vue: auth/views/form.vue:
share-access: "Erlaubst Du <i>{name}</i> auf deinen Account zuzugreifen?" share-access: "Erlaubst Du <i>{name}</i> auf deinen Account zuzugreifen?"
permission-ask: "Diese Applikation benötigt folgende Berechtigungen:" permission-ask: "Diese Applikation benötigt folgende Berechtigungen:"
account-read: "Accountinformationen anzeigen."
account-write: "Accountinformationen bearbeiten."
note-write: "Senden."
like-write: "Auf Beiträge reagieren."
following-write: "Folgen oder entfolgen."
notification-read: "Siehe deine Benachrichtigungen."
notification-write: "Benachrichtigungen verwalten."
cancel: "Abbrechen" cancel: "Abbrechen"
accept: "Zugriff erlauben." accept: "Zugriff erlauben."
auth/views/index.vue: auth/views/index.vue:
@ -185,7 +227,7 @@ common/views/components/games/reversi/reversi.room.vue:
ready: "Bereit" ready: "Bereit"
common/views/components/connect-failed.vue: common/views/components/connect-failed.vue:
title: "Verbindung zum Server ist fehlgeschlagen" title: "Verbindung zum Server ist fehlgeschlagen"
description: "Es gibt entweder ein Problem mit deiner Internetverbindung, der Server ist nicht erreichbar oder wird gerade gewartet. Bitte versuche es später noch einmal." description: "Entweder gibt es ein Problem mit deiner Internetverbindung oder der Server ist zur Zeit nicht erreichbar oder wird gewartet. Bitte versuche es später noch einmal."
thanks: "Vielen Dank für das nutzen von Misskey." thanks: "Vielen Dank für das nutzen von Misskey."
troubleshoot: "Problembehandlung" troubleshoot: "Problembehandlung"
common/views/components/connect-failed.troubleshooter.vue: common/views/components/connect-failed.troubleshooter.vue:
@ -202,8 +244,8 @@ common/views/components/connect-failed.troubleshooter.vue:
no-internet: "Keine Internetverbindung" no-internet: "Keine Internetverbindung"
no-internet-desc: "Bitte vergewissere dich, dass du mit dem Internet verbunden bist." no-internet-desc: "Bitte vergewissere dich, dass du mit dem Internet verbunden bist."
no-server: "Verbindung mit dem Server nicht möglich" no-server: "Verbindung mit dem Server nicht möglich"
no-server-desc: "Die Internetverbindung scheint in Ordnung zu sein, aber eine Verbindung mit dem Misskey Server konnte nicht hergestellt werden. Möglicherweise ist dieser zur Zeit offline oder in der Wartung, bitte versuche es später noch einmal." no-server-desc: "Die Internetverbindung scheint in Ordnung zu sein, aber eine Verbindung mit dem Misskey-Server konnte nicht hergestellt werden. Möglicherweise ist dieser zur Zeit offline oder wird gewartet. Bitte versuche es später noch einmal."
success: "Erfolgreich mit dem Misskey Server verbunden" success: "Erfolgreich mit dem Misskey-Server verbunden"
success-desc: "Die Verbindung scheint zu funktionieren. Bitte lade die Seite neu." success-desc: "Die Verbindung scheint zu funktionieren. Bitte lade die Seite neu."
flush: "Cache leeren" flush: "Cache leeren"
set-version: "Version angeben" set-version: "Version angeben"
@ -230,6 +272,7 @@ common/views/components/theme.vue:
invalid-theme: "Thema ist ungültig" invalid-theme: "Thema ist ungültig"
already-installed: "Thema ist bereits installiert" already-installed: "Thema ist bereits installiert"
author: "Autor" author: "Autor"
desc: "Beschreibung"
export: "Exportieren" export: "Exportieren"
import: "Importieren" import: "Importieren"
common/views/components/cw-button.vue: common/views/components/cw-button.vue:
@ -257,15 +300,15 @@ common/views/components/nav.vue:
status: "Status" status: "Status"
wiki: "Wiki" wiki: "Wiki"
donors: "Spender" donors: "Spender"
repository: "Projektarchiv" repository: "Quellcode"
develop: "Entwickler" develop: "Entwickler"
feedback: "Feedback" feedback: "Feedback"
common/views/components/note-menu.vue: common/views/components/note-menu.vue:
favorite: "Diese Notiz favorisieren" favorite: "Diesen Beitrag favorisieren"
unfavorite: "Aus Favoriten entfernen" unfavorite: "Aus Favoriten entfernen"
pin: "An die Profilseite pinnen" pin: "An die Profilseite pinnen"
delete: "Löschen" delete: "Löschen"
delete-confirm: "Diesen Post löschen?" delete-confirm: "Diesen Beitrag löschen?"
remote: "Auf Quelle anzeigen" remote: "Auf Quelle anzeigen"
common/views/components/poll.vue: common/views/components/poll.vue:
vote-to: "Stimme für '{}'" vote-to: "Stimme für '{}'"
@ -302,8 +345,8 @@ common/views/components/signup.vue:
password: "Passwort" password: "Passwort"
password-placeholder: "Wir empfehlen mindestens 8 Zeichen" password-placeholder: "Wir empfehlen mindestens 8 Zeichen"
weak-password: "Schwaches Passwort" weak-password: "Schwaches Passwort"
normal-password: "Faires Passwort" normal-password: "Normales Passwort"
strong-password: "Schwaches Passwort" strong-password: "Starkes Passwort"
retype: "Wiederholen" retype: "Wiederholen"
retype-placeholder: "Bitte das Passwort erneut eingeben" retype-placeholder: "Bitte das Passwort erneut eingeben"
password-matched: "OK" password-matched: "OK"
@ -325,16 +368,17 @@ common/views/components/uploader.vue:
common/views/components/visibility-chooser.vue: common/views/components/visibility-chooser.vue:
public: "Öffentlich" public: "Öffentlich"
home: "Home" home: "Home"
home-desc: "Nur auf die Startseite posten" home-desc: "Auf die Startseite posten"
followers: "Folgende" followers: "Folgende"
followers-desc: "Nur für diejenigen sichtbar, die dir folgen" followers-desc: "Nur für diejenigen sichtbar, die dir folgen"
specified: "Direkt" specified: "Direkt"
specified-desc: "Poste nur für bestimmte Benutzer" specified-desc: "Nur für bestimmte Benutzer sichtbar"
local-public: "Öffentlich (nur lokal)" local-public: "Öffentlich (nur lokal)"
local-home: "Home (nur lokal)" local-home: "Home (nur lokal)"
local-followers: "Follower (nur lokal)" local-followers: "Follower (nur lokal)"
common/views/components/profile-editor.vue: common/views/components/profile-editor.vue:
title: "Dein Profil" title: "Dein Profil"
name: "Name"
avatar: "Avatar" avatar: "Avatar"
banner: "Banner" banner: "Banner"
save: "Speichern" save: "Speichern"
@ -406,8 +450,8 @@ desktop/views/components/drive.file.vue:
copied: "Kopieren erfolgreich" copied: "Kopieren erfolgreich"
copied-url-to-clipboard: "URL wurde in die Zwischenablage kopiert" copied-url-to-clipboard: "URL wurde in die Zwischenablage kopiert"
desktop/views/components/drive.folder.vue: desktop/views/components/drive.folder.vue:
unable-to-process: "Der Vorgang konnte nicht beendet werden" unable-to-process: "Der Vorgang konnte nicht abgeschlossen werden"
circular-reference-detected: "Das Zielverzeichnis ist ein Unterverzeichnis des Verzeichnisses welches du verschieben möchtest" circular-reference-detected: "Das Zielverzeichnis ist innerhalb des Verzeichnisses, dass du verschieben möchtest"
unhandled-error: "Unbekannter Fehler" unhandled-error: "Unbekannter Fehler"
contextmenu: contextmenu:
move-to-this-folder: "Verschiebe in diesen Ordner" move-to-this-folder: "Verschiebe in diesen Ordner"
@ -422,7 +466,7 @@ desktop/views/components/drive.vue:
empty-drive-description: "Du kannst rechts klicken und \"Datei hochladen\" auswählen oder eine Datei per Drag and Drop auf das Fenster ziehen." empty-drive-description: "Du kannst rechts klicken und \"Datei hochladen\" auswählen oder eine Datei per Drag and Drop auf das Fenster ziehen."
empty-folder: "Dieser Ordner ist leer" empty-folder: "Dieser Ordner ist leer"
unable-to-process: "Der Vorgang konnte nicht beendet werden" unable-to-process: "Der Vorgang konnte nicht beendet werden"
circular-reference-detected: "Das Zielverzeichnis ist ein Unterverzeichnis des Verzeichnisses welches du verschieben möchtest" circular-reference-detected: "Das Zielverzeichnis ist innerhalb des Verzeichnisses, dass du verschieben möchtest"
unhandled-error: "Unbekannter Fehler" unhandled-error: "Unbekannter Fehler"
url-upload: "Von einer URL hochladen" url-upload: "Von einer URL hochladen"
url-of-file: "URL der Datei, welche du hochladen möchtest" url-of-file: "URL der Datei, welche du hochladen möchtest"
@ -446,15 +490,15 @@ desktop/views/input-dialog.vue:
cancel: "Abbrechen" cancel: "Abbrechen"
ok: "OK" ok: "OK"
desktop/views/components/note-detail.vue: desktop/views/components/note-detail.vue:
private: "Dieser Post ist privat" private: "Dieser Beitrag ist privat"
deleted: "Dieser Beitrag wurde entfernt" deleted: "Dieser Beitrag wurde entfernt"
location: "Ort" location: "Ort"
renote: "Anmerkung" renote: "Anmerkung"
add-reaction: "Reaktion hinzufügen" add-reaction: "Reaktion hinzufügen"
desktop/views/components/note.vue: desktop/views/components/note.vue:
reply: "Antworten" reply: "Antworten"
renote: "Anmerkung" renote: "Anmerken"
private: "Dieser Post ist privat" private: "Dieser Beitrag ist privat"
deleted: "Dieser Beitrag wurde entfernt" deleted: "Dieser Beitrag wurde entfernt"
desktop/views/components/notes.vue: desktop/views/components/notes.vue:
error: "Laden fehlgeschlagen." error: "Laden fehlgeschlagen."
@ -466,9 +510,9 @@ desktop/views/components/post-form.vue:
hide-contents: "Inhalt verstecken" hide-contents: "Inhalt verstecken"
reply-placeholder: "Antworte auf diese Anmerkung..." reply-placeholder: "Antworte auf diese Anmerkung..."
quote-placeholder: "Zitiere diese Anmerkung..." quote-placeholder: "Zitiere diese Anmerkung..."
submit: "Beitragsform" submit: "Abschicken"
reply: "Antworten" reply: "Antworten"
renote: "Anmerkung" renote: "Anmerken"
posted: "Gepostet!" posted: "Gepostet!"
replied: "Geantwortet!" replied: "Geantwortet!"
reposted: "Weitergesagt!" reposted: "Weitergesagt!"
@ -478,14 +522,13 @@ desktop/views/components/post-form.vue:
posting: "Posting" posting: "Posting"
attach-media-from-local: "Medien von deinem PC hinzufügen" attach-media-from-local: "Medien von deinem PC hinzufügen"
attach-media-from-drive: "Medien von deinem Speicher hinzufügen" attach-media-from-drive: "Medien von deinem Speicher hinzufügen"
attach-cancel: "Hinzufügen abbrechen"
create-poll: "Eine Abstimmung erstellen" create-poll: "Eine Abstimmung erstellen"
text-remain: "{} Zeichen verbleibend" text-remain: "{} Zeichen verbleibend"
visibility: "Sichtbarkeit" visibility: "Sichtbarkeit"
error: "Fehler" error: "Fehler"
enter-username: "Bitte gib einen Benutzernamen ein..." enter-username: "Bitte gib einen Benutzernamen ein..."
desktop/views/components/post-form-window.vue: desktop/views/components/post-form-window.vue:
note: "Neue Notiz" note: "Neuer Beitrag"
reply: "Antworten" reply: "Antworten"
attaches: "{} Medien hinzugefügt" attaches: "{} Medien hinzugefügt"
uploading-media: "Lade {} Medien hoch" uploading-media: "Lade {} Medien hoch"
@ -499,7 +542,7 @@ desktop/views/components/renote-form.vue:
success: "Weitergesagt!" success: "Weitergesagt!"
failure: "Weitersagen fehlgeschlagen" failure: "Weitersagen fehlgeschlagen"
desktop/views/components/renote-form-window.vue: desktop/views/components/renote-form-window.vue:
title: "Bist du dir sicher, dass du das reposten willst?" title: "Bist du dir sicher, dass du das weitersagen willst?"
desktop/views/components/settings.2fa.vue: desktop/views/components/settings.2fa.vue:
url: "https://www.google.de/intl/de/landing/2step/" url: "https://www.google.de/intl/de/landing/2step/"
register: "Ein Gerät registrieren" register: "Ein Gerät registrieren"
@ -511,6 +554,7 @@ desktop/views/components/settings.2fa.vue:
common/views/components/api-settings.vue: common/views/components/api-settings.vue:
enter-password: "Bitte Passwort eingeben" enter-password: "Bitte Passwort eingeben"
console: console:
parameter: "Parameter"
send: "Senden" send: "Senden"
common/views/components/drive-settings.vue: common/views/components/drive-settings.vue:
in-use: "benutzt" in-use: "benutzt"
@ -518,14 +562,12 @@ common/views/components/drive-settings.vue:
common/views/components/mute-and-block.vue: common/views/components/mute-and-block.vue:
save: "Speichern" save: "Speichern"
desktop/views/components/sub-note-content.vue: desktop/views/components/sub-note-content.vue:
private: "Dieser Post ist privat" private: "Dieser Beitrag ist privat"
deleted: "Dieser Beitrag wurde entfernt" deleted: "Dieser Beitrag wurde entfernt"
poll: "Umfrage" poll: "Umfrage"
desktop/views/components/settings.tags.vue: desktop/views/components/settings.tags.vue:
add: "Hinzufügen" add: "Hinzufügen"
save: "Speichern" save: "Speichern"
desktop/views/components/taskmanager.vue:
title: "Taskmanager"
desktop/views/components/timeline.vue: desktop/views/components/timeline.vue:
home: "Home" home: "Home"
local: "Lokal" local: "Lokal"
@ -610,22 +652,22 @@ mobile/views/components/drive.file-detail.vue:
download: "Download" download: "Download"
rename: "Umbenennen" rename: "Umbenennen"
mobile/views/components/note.vue: mobile/views/components/note.vue:
private: "Dieser Post ist privat" private: "Dieser Beitrag ist privat"
deleted: "Dieser Beitrag wurde entfernt" deleted: "Dieser Beitrag wurde entfernt"
location: "Ort" location: "Ort"
mobile/views/components/note-detail.vue: mobile/views/components/note-detail.vue:
reply: "Antworten" reply: "Antworten"
private: "Dieser Post ist privat" private: "Dieser Beitrag ist privat"
deleted: "Dieser Beitrag wurde entfernt" deleted: "Dieser Beitrag wurde entfernt"
location: "Ort" location: "Ort"
mobile/views/components/notifications.vue: mobile/views/components/notifications.vue:
empty: "Keine Benachrichtigungen" empty: "Keine Benachrichtigungen"
mobile/views/components/post-form.vue: mobile/views/components/post-form.vue:
reply: "Antworten" reply: "Antworten"
renote: "Anmerkung" renote: "Anmerken"
reply-placeholder: "Antworte auf diese Anmerkung..." reply-placeholder: "Antworte auf diese Anmerkung..."
mobile/views/components/sub-note-content.vue: mobile/views/components/sub-note-content.vue:
private: "Dieser Post ist privat" private: "Dieser Beitrag ist privat"
deleted: "Dieser Beitrag wurde entfernt" deleted: "Dieser Beitrag wurde entfernt"
poll: "Umfrage" poll: "Umfrage"
mobile/views/components/ui.nav.vue: mobile/views/components/ui.nav.vue:
@ -642,7 +684,7 @@ mobile/views/pages/home.vue:
global: "Global" global: "Global"
mobile/views/pages/widgets.vue: mobile/views/pages/widgets.vue:
add-widget: "Hinzufügen" add-widget: "Hinzufügen"
customization-tips: "Anpassung-Tipps" customization-tips: "Anpassungs-Tipps"
mobile/views/pages/widgets/activity.vue: mobile/views/pages/widgets/activity.vue:
activity: "Aktivität" activity: "Aktivität"
mobile/views/pages/note.vue: mobile/views/pages/note.vue:
@ -663,11 +705,47 @@ deck:
list: "Listen" list: "Listen"
rename: "Umbenennen" rename: "Umbenennen"
deck/deck.user-column.vue: deck/deck.user-column.vue:
following: "Folgen"
followers: "Folgende"
images: "Bilder"
activity: "Aktivität" activity: "Aktivität"
timeline: "Zeitleiste"
pinned-notes: "Angeheftete Beiträge"
docs:
edit-this-page-on-github: "Hast Du einen Fehler gefunden oder Lust, diese Dokumentation zu verbessern?"
edit-this-page-on-github-link: "Seite auf GitHub bearbeiten!"
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:
manage-apps: "Anwendungen verwalten"
create-app: "Anwendung erstellen"
app-missing: "Keine Anwendungen"
dev/views/new-app.vue: dev/views/new-app.vue:
account-read: "Accountinformationen anzeigen." create-app: "Erstelle Anwendung"
account-write: "Accountinformationen bearbeiten." app-name: "Name der Anwendung"
note-write: "Senden." app-name-desc: "Der Name der Anwendung"
following-write: "Folgen oder entfolgen." app-overview: "Beschreibung der Anwendung"
notification-read: "Siehe deine Benachrichtigungen." callback-url: "Callback-URL (optional)"
notification-write: "Benachrichtigungen verwalten." 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."

View File

@ -69,6 +69,22 @@ common:
following: "Following" following: "Following"
followers: "Followers" followers: "Followers"
favorites: "Favorites" favorites: "Favorites"
permissions:
"read:account": "View account information"
"write:account": "Update your account information"
"read:blocks": "View Blocks"
"write:blocks": "Work with Blocks"
"read:drive": "Browse the Drive"
"write:drive": "Work with the Drive"
"read:favorites": "View Favorites"
"write:favorites": "Work with Favorites"
"read:following": "View Follower info"
"write:following": "Work with Follow info"
"read:messaging": "View Messaging"
"write:messaging": "Work with Messaging"
"read:mutes": "View Muted"
"write:mutes": "Work with Muted"
"write:votes": "Vote"
empty-timeline-info: empty-timeline-info:
follow-users-to-make-your-timeline: "Following users will show their posts in your timeline." follow-users-to-make-your-timeline: "Following users will show their posts in your timeline."
explore: "Find users" explore: "Find users"
@ -276,21 +292,13 @@ common:
nav: "Navigation" nav: "Navigation"
tips: "Tips" tips: "Tips"
hashtags: "Hashtags" hashtags: "Hashtags"
queue: "Queue"
dev: "Failed to create the application. Please try again." dev: "Failed to create the application. Please try again."
ai-chan-kawaii: "Ai-chan kawaii!" ai-chan-kawaii: "Ai-chan kawaii!"
you: "You" you: "You"
auth/views/form.vue: auth/views/form.vue:
share-access: "Would you allow <i>{name}</i> to access your account?" share-access: "Would you allow <i>{name}</i> to access your account?"
permission-ask: "This application requires the following permissions:" permission-ask: "This application requires the following permissions:"
account-read: "View account information."
account-write: "Modify account information."
note-write: "Post."
like-write: "Express yourself about this post."
following-write: "Follow and unfollow."
drive-read: "Read your drive."
drive-write: "Upload/delete files in your drive."
notification-read: "Read your notifications."
notification-write: "Manage your notifications."
cancel: "Cancel" cancel: "Cancel"
accept: "Allow access." accept: "Allow access."
auth/views/index.vue: auth/views/index.vue:
@ -877,7 +885,6 @@ desktop/views/components/post-form.vue:
posting: "Posting" posting: "Posting"
attach-media-from-local: "Attach media from your device" attach-media-from-local: "Attach media from your device"
attach-media-from-drive: "Attach media from your Drive" attach-media-from-drive: "Attach media from your Drive"
attach-cancel: "Cancel attachment"
insert-a-kao: "v('ω')v" insert-a-kao: "v('ω')v"
create-poll: "Create a poll" create-poll: "Create a poll"
text-remain: "{} characters remaining" text-remain: "{} characters remaining"
@ -970,6 +977,10 @@ common/views/components/password-settings.vue:
not-match: "The new passwords do not match" not-match: "The new passwords do not match"
changed: "Password changed" changed: "Password changed"
failed: "Failed to change password" failed: "Failed to change password"
common/views/components/post-form-attaches.vue:
attach-cancel: "Remove Attachment"
mark-as-sensitive: "Mark as 'sensitive'"
unmark-as-sensitive: "Unmark as 'sensitive'"
desktop/views/components/sub-note-content.vue: desktop/views/components/sub-note-content.vue:
private: "This post is private" private: "This post is private"
deleted: "This post has been deleted" deleted: "This post has been deleted"
@ -980,8 +991,6 @@ desktop/views/components/settings.tags.vue:
query: "Query (optional)" query: "Query (optional)"
add: "Add" add: "Add"
save: "Save" save: "Save"
desktop/views/components/taskmanager.vue:
title: "Task Manager"
desktop/views/components/timeline.vue: desktop/views/components/timeline.vue:
home: "Home" home: "Home"
local: "Local" local: "Local"
@ -1115,11 +1124,6 @@ admin/views/instance.vue:
save: "Save" save: "Save"
saved: "Saved" saved: "Saved"
user-recommendation-config: "Recommended users" user-recommendation-config: "Recommended users"
enable-external-user-recommendation: "Enable external user recommendations"
external-user-recommendation-engine: "Engine"
external-user-recommendation-engine-desc: "Example: https://vinayaka.distsn.org/cgi-bin/vinayaka-user-match-misskey-api.cgi?{{host}}+{{user}}+{{limit}}+{{offset}}"
external-user-recommendation-timeout: "Timeout"
external-user-recommendation-timeout-desc: "Number of milliseconds (ex. 300,000)"
email-config: "Email server settings" email-config: "Email server settings"
email-config-info: "Used to confirm email and password reset etc." email-config-info: "Used to confirm email and password reset etc."
enable-email: "Enable email delivery" enable-email: "Enable email delivery"
@ -1470,7 +1474,7 @@ mobile/views/components/post-form.vue:
quote-placeholder: "Quote this post... (optional)" quote-placeholder: "Quote this post... (optional)"
reply-placeholder: "Reply to this note..." reply-placeholder: "Reply to this note..."
cw-placeholder: "Comments for the post (optional)" cw-placeholder: "Comments for the post (optional)"
location-alert: "Your device does not provide location services" geolocation-alert: "Your device does not provide location services."
error: "Error" error: "Error"
username-prompt: "Enter user name" username-prompt: "Enter user name"
mobile/views/components/sub-note-content.vue: mobile/views/components/sub-note-content.vue:
@ -1623,21 +1627,9 @@ dev/views/new-app.vue:
create-app: "Creating application" create-app: "Creating application"
app-name: "Application name" app-name: "Application name"
app-name-desc: "The name of your app" app-name-desc: "The name of your app"
app-name-ex: "ex) Misskey for iOS"
app-overview: "Application summary" app-overview: "Application summary"
app-desc: "A brief description or introduction of your app."
app-desc-ex: "ex) Misskey iOS client."
callback-url: "The callback URL (optional)" callback-url: "The callback URL (optional)"
callback-url-desc: "The URL to redirect to after the user is authenticated via the authentication form." callback-url-desc: "The URL to redirect to after the user is authenticated via the authentication form."
authority: "Permissions" authority: "Permissions"
authority-desc: "Only the functions requested here can be accessed via the API." authority-desc: "Only the functions requested here can be accessed via the API."
authority-warning: "You can change it even after creating the application, but if you give different permissions, all user keys associated at that time will be invalidated." authority-warning: "You can change it even after creating the application, but if you give different permissions, all user keys associated at that time will be invalidated."
account-read: "View account information."
account-write: "Modify account information."
note-write: "Post."
reaction-write: "Add or remove reactions."
following-write: "Follow and unfollow."
drive-read: "Read the drive."
drive-write: "Upload/delete files in the drive."
notification-read: "Read your notifications."
notification-write: "Manage your notifications."

View File

@ -20,8 +20,15 @@ common:
application-authorization: "Autorizaciones de la aplicación." application-authorization: "Autorizaciones de la aplicación."
close: "Cerrar" close: "Cerrar"
do-not-copy-paste: "Por favor no copies código aquí. Tu cuenta puede resultar comprometida." 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" enter-password: "Escribe una contraseña"
2fa: "Autenticación de dos factores" 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"
got-it: "¡Listo!" got-it: "¡Listo!"
customization-tips: customization-tips:
title: "Consejos de personalización" title: "Consejos de personalización"
@ -50,8 +57,22 @@ common:
drive: "Drive" drive: "Drive"
messaging: "Conversación" messaging: "Conversación"
home: "Inicio" home: "Inicio"
deck: "Deck"
timeline: "Timeline"
explore: "Explorar"
following: "Siguiendo" following: "Siguiendo"
followers: "Seguidores"
favorites: "Me gusta esta nota" 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:messaging": "Ver conversación"
"read:notifications": "Ver notificaciones"
"write:votes": "Vota"
weekday-short: weekday-short:
sunday: "domingo" sunday: "domingo"
monday: "lunes" monday: "lunes"
@ -97,12 +118,24 @@ common:
d: "¿Quieres decir algo?" d: "¿Quieres decir algo?"
e: "¡Escribe aquí!" e: "¡Escribe aquí!"
f: "Esperando a que escribas algo..." f: "Esperando a que escribas algo..."
settings: "Configuración"
_settings: _settings:
profile: "Tu perfil" profile: "Tu perfil"
notification: "Notificaciones" notification: "Notificaciones"
apps: "Aplicaciones"
tags: "Etiquetas" tags: "Etiquetas"
mute-and-block: "Silenciar/Bloquear"
blocking: "Bloquear" blocking: "Bloquear"
security: "Seguridad"
password: "Contraseña" 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}}"
use-os-default-emojis: "Usar los emoticonos estándar del sistema operativo" use-os-default-emojis: "Usar los emoticonos estándar del sistema operativo"
line-width: "Grosor de línea" line-width: "Grosor de línea"
line-width-thick: "Grosor" line-width-thick: "Grosor"
@ -128,6 +161,19 @@ common:
contrasted-acct: "Añadir contraste al nombre de usuario" contrasted-acct: "Añadir contraste al nombre de usuario"
wallpaper: "Fondo de pantalla" wallpaper: "Fondo de pantalla"
choose-wallpaper: "Escoge un fondo de pantalla" choose-wallpaper: "Escoge un fondo de pantalla"
delete-wallpaper: "Quitar fondo de pantalla"
show-clock-on-header: "Muestra el reloj en la parte superior derecha"
timeline: "Timeline"
sound: "Sonido"
enable-sounds: "Habilitar sonido"
volume: "Volúmen"
test: "Prueba"
version: "Versión"
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" navbar-position-left: "Izquierda"
search: "Buscar" search: "Buscar"
delete: "eliminar" delete: "eliminar"
@ -169,15 +215,6 @@ common:
you: "Tú" you: "Tú"
auth/views/form.vue: auth/views/form.vue:
permission-ask: "La aplicación requiere los siguientes permisos:" permission-ask: "La aplicación requiere los siguientes permisos:"
account-read: "Viendo información de la cuenta:"
account-write: "Modificar información de la cuenta:"
note-write: "Publicación."
like-write: "Para reaccionar a las publicaciones."
following-write: "Seguir o dejar de seguir"
drive-read: "Leer tu unidad."
drive-write: "Cargar o borrar archivos de tu unidad."
notification-read: "Leer tus notificaciones."
notification-write: "Administrar tus notificaciones."
cancel: "Cancelar" cancel: "Cancelar"
accept: "Garantizar acceso." accept: "Garantizar acceso."
auth/views/index.vue: auth/views/index.vue:
@ -631,7 +668,6 @@ desktop/views/components/post-form.vue:
posting: "Publicando" posting: "Publicando"
attach-media-from-local: "Agregar medios de tu dispositivo" attach-media-from-local: "Agregar medios de tu dispositivo"
attach-media-from-drive: "Adjunta multimedia desde tu Disco" attach-media-from-drive: "Adjunta multimedia desde tu Disco"
attach-cancel: "Quitar el archivo adjunto"
create-poll: "Crea una encuesta" create-poll: "Crea una encuesta"
text-remain: "quedan {} caracteres" text-remain: "quedan {} caracteres"
recent-tags: "Reciente" recent-tags: "Reciente"
@ -697,6 +733,9 @@ common/views/components/mute-and-block.vue:
mute: "Silenciar" mute: "Silenciar"
block: "Bloquear" block: "Bloquear"
save: "Guardar" save: "Guardar"
common/views/components/post-form-attaches.vue:
mark-as-sensitive: "Marcar como 'sensible'"
unmark-as-sensitive: "Desmarcar como 'sensible'"
desktop/views/components/sub-note-content.vue: desktop/views/components/sub-note-content.vue:
private: "Esta publicación es privada" private: "Esta publicación es privada"
deleted: "Esta publicación ha sido removida" deleted: "Esta publicación ha sido removida"
@ -708,7 +747,6 @@ desktop/views/components/settings.tags.vue:
desktop/views/components/timeline.vue: desktop/views/components/timeline.vue:
home: "Inicio" home: "Inicio"
local: "Local" local: "Local"
hybrid: "Social"
global: "Global" global: "Global"
list: "Listas" list: "Listas"
hashtag: "Hashtags" hashtag: "Hashtags"
@ -768,7 +806,6 @@ admin/views/instance.vue:
recaptcha-secret-key: "clave secreta reCAPTCHA" recaptcha-secret-key: "clave secreta reCAPTCHA"
invite: "Invitar" invite: "Invitar"
save: "Guardar" save: "Guardar"
external-user-recommendation-timeout: "Tiempo de espera"
email: "Correo electrónico" email: "Correo electrónico"
smtp-host: "Host SMTP" smtp-host: "Host SMTP"
smtp-port: "Puerto SMTP" smtp-port: "Puerto SMTP"
@ -878,6 +915,7 @@ mobile/views/components/post-form.vue:
reply: "Responder" reply: "Responder"
renote: "Republicar" renote: "Republicar"
reply-placeholder: "Responder a esta nota..." reply-placeholder: "Responder a esta nota..."
geolocation-alert: "Tu dispositivo no tiene soporte de geolocalización."
mobile/views/components/sub-note-content.vue: mobile/views/components/sub-note-content.vue:
private: "Esta publicación es privada" private: "Esta publicación es privada"
deleted: "Esta publicación ha sido removida" deleted: "Esta publicación ha sido removida"
@ -898,7 +936,6 @@ mobile/views/pages/user-lists.vue:
mobile/views/pages/home.vue: mobile/views/pages/home.vue:
home: "Inicio" home: "Inicio"
local: "Local" local: "Local"
hybrid: "Social"
global: "Global" global: "Global"
mobile/views/pages/widgets.vue: mobile/views/pages/widgets.vue:
dashboard: "Panel de control" dashboard: "Panel de control"
@ -921,7 +958,6 @@ mobile/views/pages/user/home.photos.vue:
deck: deck:
home: "Inicio" home: "Inicio"
local: "Local" local: "Local"
hybrid: "Social"
hashtag: "Etiquetas" hashtag: "Etiquetas"
global: "Global" global: "Global"
notifications: "Notificaciones" notifications: "Notificaciones"
@ -929,12 +965,3 @@ deck:
rename: "Renombrar" rename: "Renombrar"
deck/deck.user-column.vue: deck/deck.user-column.vue:
activity: "Actividad" activity: "Actividad"
dev/views/new-app.vue:
account-read: "Viendo información de la cuenta:"
account-write: "Modificar información de la cuenta:"
note-write: "Publicación."
following-write: "Seguir o dejar de seguir"
drive-read: "Leer tu unidad."
drive-write: "Cargar o borrar archivos de tu unidad."
notification-read: "Leer tus notificaciones."
notification-write: "Administrar tus notificaciones."

View File

@ -67,6 +67,12 @@ common:
following: "Suit" following: "Suit"
followers: "Abonné·e·s" followers: "Abonné·e·s"
favorites: "Mettre cette note en favoris" favorites: "Mettre cette note en favoris"
permissions:
"read:account": "Afficher les informations du compte"
"write:account": "Mettre à jour les informations de votre compte"
"read:drive": "Parcourir le Drive"
"write:drive": "Écrire sur le Drive"
"write:votes": "Vote"
empty-timeline-info: empty-timeline-info:
follow-users-to-make-your-timeline: "Les utilisateurs suivants afficheront leurs publications sur votre fil." follow-users-to-make-your-timeline: "Les utilisateurs suivants afficheront leurs publications sur votre fil."
explore: "Trouver des utilisateurs" explore: "Trouver des utilisateurs"
@ -121,6 +127,7 @@ common:
notification: "Notifications" notification: "Notifications"
apps: "Applications" apps: "Applications"
tags: "Hashtags" tags: "Hashtags"
mute-and-block: "Silencer / Bloquer"
blocking: "En cours blocage" blocking: "En cours blocage"
security: "Sécurité" security: "Sécurité"
signin: "Historique des connexions" signin: "Historique des connexions"
@ -134,6 +141,16 @@ common:
remember-note-visibility: "Se souvenir du mode de visibilité de la publication" remember-note-visibility: "Se souvenir du mode de visibilité de la publication"
web-search-engine: "Moteur de recherche Web" web-search-engine: "Moteur de recherche Web"
web-search-engine-desc: "Exemple: https://www.google.com/?#q={{query}}" web-search-engine-desc: "Exemple: https://www.google.com/?#q={{query}}"
keep-cw: "Maintenir l'avertissement de contenu"
i-like-sushi: "Je préfère les sushis plutôt que le pudding"
show-reversi-board-labels: "Afficher les étiquettes des lignes et colonnes dans Reversi"
use-avatar-reversi-stones: "Utiliser lavatar comme pion dans Reversi"
disable-animated-mfm: "Désactiver les textes animés dans les publications"
disable-showing-animated-images: "Désactiver l'animation des images"
suggest-recent-hashtags: "Afficher les hashtags populaires dans le champs de saisie"
always-show-nsfw: "Toujours afficher les contenus sensibles"
always-mark-nsfw: "Toujours marquer les notes ayant des médias comme sensibles"
show-full-acct: "Afficher ladresse complète de lutilisateur"
show-via: "Afficher via" show-via: "Afficher via"
reduce-motion: "Réduire les animations dans linterface utilisateur" reduce-motion: "Réduire les animations dans linterface utilisateur"
this-setting-is-this-device-only: "Uniquement sur cet appareil" this-setting-is-this-device-only: "Uniquement sur cet appareil"
@ -143,25 +160,69 @@ common:
line-width-normal: "Normale" line-width-normal: "Normale"
line-width-thick: "Épaisse" line-width-thick: "Épaisse"
font-size: "Taille du texte" font-size: "Taille du texte"
font-size-x-small: "Très petit"
font-size-small: "Petite"
font-size-medium: "Normale" font-size-medium: "Normale"
font-size-large: "Grande"
font-size-x-large: "Large" font-size-x-large: "Large"
deck-column-align: "Alignement des colonnes du Deck"
deck-column-align-center: "Centrer" deck-column-align-center: "Centrer"
deck-column-align-left: "À gauche" deck-column-align-left: "À gauche"
deck-column-align-flexible: "Flexible" deck-column-align-flexible: "Flexible"
deck-column-width: "Largeur des colonnes du Deck" deck-column-width: "Largeur des colonnes du Deck"
deck-column-width-narrow: "Étroite"
deck-column-width-narrower: "Légèrement étroite"
deck-column-width-normal: "Normale" deck-column-width-normal: "Normale"
deck-column-width-wider: "Légèrement large"
deck-column-width-wide: "Large"
use-shadow: "Utiliser les ombres dans l'interface utilisateur"
rounded-corners: "Coins arrondis de l'interface utilisateur"
circle-icons: "Utiliser des icônes circulaires"
contrasted-acct: "Ajouter du contraste au nom de lutilisateur"
wallpaper: "Image du fond d'écran"
choose-wallpaper: "Sélectionner un fond d'écran"
delete-wallpaper: "Supprimer le fond d'écran"
post-form-on-timeline: "Afficher le champs de saisie en haut du fil"
show-clock-on-header: "Afficher l'horloge sur le coté supérieur droit"
timeline: "Fil dactualité" timeline: "Fil dactualité"
show-my-renotes: "Afficher mes republications dans le fil"
remain-deleted-note: "Continuer à afficher les notes supprimées"
sound: "Son"
enable-sounds: "Activer les sons"
enable-sounds-desc: "Jouer un son lorsque vous recevez un message/publication. Ce paramètre est sauvegardé dans le navigateur."
volume: "Volume"
test: "Test"
update: "Mise à jour de Misskey"
version: "Version actuelle :"
latest-version: "Dernière version :"
update-checking: "Recherche de mises à jour"
do-update: "Rechercher des mises à jour"
update-settings: "Paramètres avancés"
no-updates: "Aucune mise à jour disponible"
no-updates-desc: "Votre Misskey est à jour."
update-available: "Nouvelle version disponible !"
update-available-desc: "Les mises à jour seront appliquées une fois la page est rechargée."
advanced-settings: "Paramètres avancés"
debug-mode: "Activer le mode débogage"
debug-mode-desc: "Ce paramètre est stocké dans le navigateur."
navbar-position: "Position de la barre de navigation"
navbar-position-top: "en haut" navbar-position-top: "en haut"
navbar-position-left: "À gauche" navbar-position-left: "À gauche"
navbar-position-right: "à droite" navbar-position-right: "à droite"
i-am-under-limited-internet: "J'ai un accès Internet limité"
post-style: "Style d'affichage des notes"
post-style-standard: "Standard" post-style-standard: "Standard"
post-style-smart: "Intelligent" post-style-smart: "Intelligent"
notification-position: "Afficher les notifications" notification-position: "Afficher les notifications"
notification-position-bottom: "en bas" notification-position-bottom: "en bas"
notification-position-top: "en haut" notification-position-top: "en haut"
disable-via-mobile: "Enlever la mention publié via 'mobile'"
load-raw-images: "Afficher les photos jointes dans leur qualité originale"
load-remote-media: "Afficher les médias depuis le serveur distant"
search: "Recherche" search: "Recherche"
delete: "Supprimer" delete: "Supprimer"
loading: "Chargement en cours…" loading: "Chargement en cours…"
ok: "Confirmer"
cancel: "Quitter" cancel: "Quitter"
update-available-title: "Mise à jour disponible" update-available-title: "Mise à jour disponible"
update-available: "Une nouvelle version de Misskey est disponible ({newer}, version actuelle: {current}). Veuillez recharger la page pour appliquer la mise à jour." update-available: "Une nouvelle version de Misskey est disponible ({newer}, version actuelle: {current}). Veuillez recharger la page pour appliquer la mise à jour."
@ -176,7 +237,7 @@ common:
view-on-remote: " Consulter le profil complet" view-on-remote: " Consulter le profil complet"
renoted-by: "Renoté par {user}" renoted-by: "Renoté par {user}"
no-notes: "Sans aucune note" no-notes: "Sans aucune note"
turn-on-darkmode: "Basculer vers le mode nuit" turn-on-darkmode: "Mode nuit"
turn-off-darkmode: "Mode jour" turn-off-darkmode: "Mode jour"
error: error:
title: "Une erreur est survenue" title: "Une erreur est survenue"
@ -214,21 +275,13 @@ common:
nav: "Navigation" nav: "Navigation"
tips: "Conseils" tips: "Conseils"
hashtags: "Hashtags" hashtags: "Hashtags"
queue: "File d'attente"
dev: "Échec lors de la création de lapplication. Veuillez réessayer." dev: "Échec lors de la création de lapplication. Veuillez réessayer."
ai-chan-kawaii: "Ai-Chan est mignonne !" ai-chan-kawaii: "Ai-Chan est mignonne !"
you: "Vous" you: "Vous"
auth/views/form.vue: auth/views/form.vue:
share-access: "Désirez-vous autoriser <i>{name}</i> à avoir accès à votre compte?" share-access: "Désirez-vous autoriser <i>{name}</i> à avoir accès à votre compte?"
permission-ask: "Cette application nécessite les autorisations suivantes :" permission-ask: "Cette application nécessite les autorisations suivantes :"
account-read: "Afficher les informations du compte."
account-write: "Modifications des informations du compte."
note-write: "Publier."
like-write: "Réagir aux publications."
following-write: "Suivre des comptes et se désabonner."
drive-read: "Lire votre Drive"
drive-write: "Téléverser/supprimer des fichiers dans votre Drive."
notification-read: "Lire vos notifications."
notification-write: "Gérer vos notifications."
cancel: "Annuler" cancel: "Annuler"
accept: "Autoriser laccès" accept: "Autoriser laccès"
auth/views/index.vue: auth/views/index.vue:
@ -250,6 +303,8 @@ common/views/pages/explore.vue:
federated: "Du Fédiverse" federated: "Du Fédiverse"
explore: "Explorer {host}" explore: "Explorer {host}"
users-info: "Actuellement, {users} utilisateurs se sont inscrit ici" users-info: "Actuellement, {users} utilisateurs se sont inscrit ici"
common/views/components/url-preview.vue:
disable-player: "Fermer le lecteur"
common/views/components/user-list.vue: common/views/components/user-list.vue:
no-users: "Il n'y a aucun utilisateur" no-users: "Il n'y a aucun utilisateur"
common/views/components/games/reversi/reversi.vue: common/views/components/games/reversi/reversi.vue:
@ -424,19 +479,32 @@ common/views/components/user-menu.vue:
common/views/components/poll.vue: common/views/components/poll.vue:
vote-to: "Voter pour '{}'" vote-to: "Voter pour '{}'"
vote-count: "{} votes" vote-count: "{} votes"
total-votes: "{} Total des votes"
vote: "Vote" vote: "Vote"
show-result: "Montrer les résultats" show-result: "Montrer les résultats"
voted: "Voté" voted: "Voté"
closed: "Terminé"
remaining-days: "{d} jours, {h} heures restantes"
remaining-hours: "{h} heures et {m} minutes restantes"
remaining-minutes: "{m} minutes et {s} secondes restantes"
remaining-seconds: "{s} secondes restantes"
common/views/components/poll-editor.vue: common/views/components/poll-editor.vue:
no-only-one-choice: "Vous devez saisir au moins deux choix." no-only-one-choice: "Vous devez saisir au moins deux choix."
choice-n: "Choix {}" choice-n: "Choix {}"
remove: "Supprimer ce choix" remove: "Supprimer ce choix"
add: "+ Ajouter un choix" add: "+ Ajouter un choix"
destroy: "Annuler ce sondage" destroy: "Annuler ce sondage"
expiration: "Valide jusqu'à"
infinite: "Illimité"
at: "Choisir une date et une durée"
no-more: "Vous ne pouvez pas en ajouter davantage"
deadline-date: "Date déchéance"
deadline-time: "Durée"
interval: "Durée" interval: "Durée"
unit: "Unité" unit: "Unité"
second: "secondes" second: "secondes"
minute: "Minutes" minute: "Minutes"
hour: "Heures"
day: "D" day: "D"
common/views/components/reaction-picker.vue: common/views/components/reaction-picker.vue:
choose-reaction: "Choisissez votre réaction" choose-reaction: "Choisissez votre réaction"
@ -568,6 +636,7 @@ common/views/components/profile-editor.vue:
email-not-verified: "Adresse de courriel nest pas confirmée. Veuillez vérifier votre boite de réception." email-not-verified: "Adresse de courriel nest pas confirmée. Veuillez vérifier votre boite de réception."
export: "Exporter" export: "Exporter"
import: "Importer" import: "Importer"
export-and-import: "Exportation et importation"
export-targets: export-targets:
all-notes: "Toutes les notes publiées" all-notes: "Toutes les notes publiées"
following-list: "Liste des abonnements" following-list: "Liste des abonnements"
@ -793,7 +862,6 @@ desktop/views/components/post-form.vue:
posting: "Publication …" posting: "Publication …"
attach-media-from-local: "Joindre un média depuis votre appareil" attach-media-from-local: "Joindre un média depuis votre appareil"
attach-media-from-drive: "Joindre un média depuis votre Drive" attach-media-from-drive: "Joindre un média depuis votre Drive"
attach-cancel: "Annuler le fichier attaché"
insert-a-kao: "v('ω')v" insert-a-kao: "v('ω')v"
create-poll: "Créer un sondage" create-poll: "Créer un sondage"
text-remain: "{} caractères restants" text-remain: "{} caractères restants"
@ -886,6 +954,9 @@ common/views/components/password-settings.vue:
not-match: "Les nouveaux mots de passe ne sont pas identiques" not-match: "Les nouveaux mots de passe ne sont pas identiques"
changed: "Mot de passe modifié avec succès" changed: "Mot de passe modifié avec succès"
failed: "Échec lors de la modification du mot de passe" failed: "Échec lors de la modification du mot de passe"
common/views/components/post-form-attaches.vue:
mark-as-sensitive: "Marquer comme sensible"
unmark-as-sensitive: "Ne pas marquer comme sensible"
desktop/views/components/sub-note-content.vue: desktop/views/components/sub-note-content.vue:
private: "cette publication est privée" private: "cette publication est privée"
deleted: "cette publication a été supprimée" deleted: "cette publication a été supprimée"
@ -896,8 +967,6 @@ desktop/views/components/settings.tags.vue:
query: "Requête (optionnelle)" query: "Requête (optionnelle)"
add: "Ajouter" add: "Ajouter"
save: "Enregistrer" save: "Enregistrer"
desktop/views/components/taskmanager.vue:
title: "Gestionnaire de tâches"
desktop/views/components/timeline.vue: desktop/views/components/timeline.vue:
home: "Accueil" home: "Accueil"
local: "Local" local: "Local"
@ -958,6 +1027,7 @@ admin/views/index.vue:
hashtags: "Hashtags" hashtags: "Hashtags"
abuse: "Abus" abuse: "Abus"
queue: "File dattente" queue: "File dattente"
logs: "Journaux"
back-to-misskey: "Retour vers Misskey" back-to-misskey: "Retour vers Misskey"
admin/views/dashboard.vue: admin/views/dashboard.vue:
dashboard: "Tableau de bord" dashboard: "Tableau de bord"
@ -1026,11 +1096,6 @@ admin/views/instance.vue:
save: "Sauvegarder" save: "Sauvegarder"
saved: "Enregistré" saved: "Enregistré"
user-recommendation-config: "Utilisateurs" user-recommendation-config: "Utilisateurs"
enable-external-user-recommendation: "Activer la recommandation des utilisateurs distants"
external-user-recommendation-engine: "Moteur"
external-user-recommendation-engine-desc: "Exemple: https://vinayaka.distsn.org/cgi-bin/vinayaka-user-match-misskey-api.cgi?{{host}}+{{user}}+{{limit}}+{{offset}}"
external-user-recommendation-timeout: "Délai dexpiration"
external-user-recommendation-timeout-desc: "En millisecondes (par exemple : 300000)"
email-config: "Paramètres du serveur de messagerie" email-config: "Paramètres du serveur de messagerie"
email-config-info: "Utilisé pour confirmer votre adresse de courrier électronique et la réinitialisation de votre mot de passe." email-config-info: "Utilisé pour confirmer votre adresse de courrier électronique et la réinitialisation de votre mot de passe."
enable-email: "Activation de la distribution du courrier" enable-email: "Activation de la distribution du courrier"
@ -1199,6 +1264,7 @@ admin/views/federation.vue:
marked-as-closed: "Marquées comme fermées" marked-as-closed: "Marquées comme fermées"
lookup: "Recherche" lookup: "Recherche"
instances: "Fédérées" instances: "Fédérées"
instance-not-registered: "Linstance na pas encore été découverte"
sort: "Trier par" sort: "Trier par"
sorts: sorts:
caughtAtAsc: "Date dinscription (Ascendant)" caughtAtAsc: "Date dinscription (Ascendant)"
@ -1206,6 +1272,7 @@ admin/views/federation.vue:
lastCommunicatedAtAsc: "La date et l'heure des interactions plus anciennes" lastCommunicatedAtAsc: "La date et l'heure des interactions plus anciennes"
lastCommunicatedAtDesc: "La date et l'heure des nouvelles interactions" lastCommunicatedAtDesc: "La date et l'heure des nouvelles interactions"
notesDesc: "Description des notes" notesDesc: "Description des notes"
usersAsc: "Peu d'abonnés"
followingAsc: "Les moins suivies" followingAsc: "Les moins suivies"
followingDesc: "Ayant le plus d'abonné·e·s" followingDesc: "Ayant le plus d'abonné·e·s"
followersAsc: "Ayant le moins d'abonné·e·s" followersAsc: "Ayant le moins d'abonné·e·s"
@ -1369,7 +1436,7 @@ mobile/views/components/post-form.vue:
quote-placeholder: "Citer ce billet ... (Facultatif)" quote-placeholder: "Citer ce billet ... (Facultatif)"
reply-placeholder: "Répondre à cette note" reply-placeholder: "Répondre à cette note"
cw-placeholder: "Commenter le contenu (optionnel)" cw-placeholder: "Commenter le contenu (optionnel)"
location-alert: "Votre appareil ne prend pas en charge les services de localisation" geolocation-alert: "Votre appareil ne prend pas en charge les services de localisation"
error: "Erreur" error: "Erreur"
username-prompt: "Saisir un nom d'utilisateur" username-prompt: "Saisir un nom d'utilisateur"
mobile/views/components/sub-note-content.vue: mobile/views/components/sub-note-content.vue:
@ -1521,21 +1588,9 @@ dev/views/new-app.vue:
create-app: "Création dune application" create-app: "Création dune application"
app-name: "Nom de lapplication" app-name: "Nom de lapplication"
app-name-desc: "Le nom de votre application" app-name-desc: "Le nom de votre application"
app-name-ex: "p. ex. Misskey pour iOS"
app-overview: "Description courte de lapplication" app-overview: "Description courte de lapplication"
app-desc: "Brève description introductive à votre application."
app-desc-ex: "p. ex) Misskey pour iOS"
callback-url: "LUrl de callback (facultatif)" callback-url: "LUrl de callback (facultatif)"
callback-url-desc: "Vous pouvez définir lURL de redirection lorsque lutilisateur sest authentifié via formulaire dauthentification." callback-url-desc: "Vous pouvez définir lURL de redirection lorsque lutilisateur sest authentifié via formulaire dauthentification."
authority: "Autorisations " authority: "Autorisations "
authority-desc: "Sont accessibles via lAPI, uniquement les fonctionnalités demandées ici." authority-desc: "Sont accessibles via lAPI, uniquement les fonctionnalités demandées ici."
authority-warning: "Vous pouvez le changer même après avoir créé l'application, mais si vous attribuez une nouvelle permission, toutes les clés utilisateur associées seront dès lors invalides." authority-warning: "Vous pouvez le changer même après avoir créé l'application, mais si vous attribuez une nouvelle permission, toutes les clés utilisateur associées seront dès lors invalides."
account-read: "Afficher les informations du compte"
account-write: "Modifications des informations du compte"
note-write: "Publications."
reaction-write: "Ajout et suppression de réactions."
following-write: "Sabonner et se désabonner."
drive-read: "Lecture du Drive."
drive-write: "Téléversement/suppression des fichiers de votre Lecteur."
notification-read: "Lire vos notifications."
notification-write: "Gestion de vos notifications."

View File

@ -35,6 +35,7 @@ common:
signup: "新規登録" signup: "新規登録"
signout: "ログアウト" signout: "ログアウト"
reload-to-apply-the-setting: "この設定を反映するにはページをリロードする必要があります。今すぐリロードしますか?" reload-to-apply-the-setting: "この設定を反映するにはページをリロードする必要があります。今すぐリロードしますか?"
fetching-as-ap-object: "連合に照会中"
got-it: "わかった" got-it: "わかった"
customization-tips: customization-tips:
@ -73,6 +74,28 @@ common:
followers: "フォロワー" followers: "フォロワー"
favorites: "お気に入り" favorites: "お気に入り"
permissions:
"read:account": "アカウントの情報を見る"
"write:account": "アカウントの情報を変更する"
"read:blocks": "ブロックを見る"
"write:blocks": "ブロックを操作する"
"read:drive": "ドライブを見る"
"write:drive": "ドライブを操作する"
"read:favorites": "お気に入りを見る"
"write:favorites": "お気に入りを操作する"
"read:following": "フォローの情報を見る"
"write:following": "フォロー・フォロー解除する"
"read:messaging": "トークを見る"
"write:messaging": "トークを操作する"
"read:mutes": "ミュートを見る"
"write:mutes": "ミュートを操作する"
"write:notes": "投稿を作成・削除する"
"read:notifications": "通知を見る"
"write:notifications": "通知を操作する"
"read:reactions": "リアクションを見る"
"write:reactions": "リアクションを操作する"
"write:votes": "投票する"
empty-timeline-info: empty-timeline-info:
follow-users-to-make-your-timeline: "ユーザーをフォローすると投稿がタイムラインに表示されます。" follow-users-to-make-your-timeline: "ユーザーをフォローすると投稿がタイムラインに表示されます。"
explore: "ユーザーを探索する" explore: "ユーザーを探索する"
@ -291,6 +314,7 @@ common:
nav: "ナビゲーション" nav: "ナビゲーション"
tips: "ヒント" tips: "ヒント"
hashtags: "ハッシュタグ" hashtags: "ハッシュタグ"
queue: "キュー"
dev: "アプリの作成に失敗しました。再度お試しください。" dev: "アプリの作成に失敗しました。再度お試しください。"
ai-chan-kawaii: "藍ちゃかわいい" ai-chan-kawaii: "藍ちゃかわいい"
@ -299,15 +323,6 @@ common:
auth/views/form.vue: auth/views/form.vue:
share-access: "<i>{name}</i>があなたのアカウントにアクセスすることを許可しますか?" share-access: "<i>{name}</i>があなたのアカウントにアクセスすることを許可しますか?"
permission-ask: "このアプリは次の権限を要求しています:" permission-ask: "このアプリは次の権限を要求しています:"
account-read: "アカウントの情報を見る。"
account-write: "アカウントの情報を操作する。"
note-write: "投稿する。"
like-write: "いいねしたりいいね解除する。"
following-write: "フォローしたりフォロー解除する。"
drive-read: "ドライブを見る。"
drive-write: "ドライブを操作する。"
notification-read: "通知を見る。"
notification-write: "通知を操作する。"
cancel: "キャンセル" cancel: "キャンセル"
accept: "アクセスを許可" accept: "アクセスを許可"
@ -513,8 +528,12 @@ common/views/components/user-menu.vue:
mention: "メンション" mention: "メンション"
mute: "ミュート" mute: "ミュート"
unmute: "ミュート解除" unmute: "ミュート解除"
mute-confirm: "このユーザーをミュートしますか?"
unmute-confirm: "このユーザーをミュート解除しますか?"
block: "ブロック" block: "ブロック"
unblock: "ブロック解除" unblock: "ブロック解除"
block-confirm: "このユーザーをブロックしますか?"
unblock-confirm: "このユーザーをブロック解除しますか?"
push-to-list: "リストに追加" push-to-list: "リストに追加"
select-list: "リストを選択してください" select-list: "リストを選択してください"
report-abuse: "スパムを報告" report-abuse: "スパムを報告"
@ -522,8 +541,12 @@ common/views/components/user-menu.vue:
report-abuse-reported: "管理者に報告されました。ご協力ありがとうございました。" report-abuse-reported: "管理者に報告されました。ご協力ありがとうございました。"
silence: "サイレンス" silence: "サイレンス"
unsilence: "サイレンス解除" unsilence: "サイレンス解除"
silence-confirm: "このユーザーをサイレンスしますか?"
unsilence-confirm: "このユーザーをサイレンス解除しますか?"
suspend: "凍結" suspend: "凍結"
unsuspend: "凍結解除" unsuspend: "凍結解除"
suspend-confirm: "このユーザーを凍結しますか?"
unsuspend-confirm: "このユーザーを凍結解除しますか?"
common/views/components/poll.vue: common/views/components/poll.vue:
vote-to: "「{}」に投票する" vote-to: "「{}」に投票する"
@ -725,6 +748,10 @@ common/views/components/user-list-editor.vue:
delete-are-you-sure: "リスト「$1」を削除しますか" delete-are-you-sure: "リスト「$1」を削除しますか"
deleted: "削除しました" deleted: "削除しました"
common/views/components/user-lists.vue:
create-list: "リストを作成"
list-name: "リスト名"
common/views/widgets/broadcast.vue: common/views/widgets/broadcast.vue:
fetching: "確認中" fetching: "確認中"
no-broadcasts: "お知らせはありません" no-broadcasts: "お知らせはありません"
@ -967,7 +994,6 @@ desktop/views/components/post-form.vue:
posting: "投稿中" posting: "投稿中"
attach-media-from-local: "PCからメディアを添付" attach-media-from-local: "PCからメディアを添付"
attach-media-from-drive: "ドライブからメディアを添付" attach-media-from-drive: "ドライブからメディアを添付"
attach-cancel: "添付取り消し"
insert-a-kao: "v('ω')v" insert-a-kao: "v('ω')v"
create-poll: "アンケートを作成" create-poll: "アンケートを作成"
text-remain: "残り{}文字" text-remain: "残り{}文字"
@ -1073,6 +1099,11 @@ common/views/components/password-settings.vue:
changed: "パスワードを変更しました" changed: "パスワードを変更しました"
failed: "パスワード変更に失敗しました" failed: "パスワード変更に失敗しました"
common/views/components/post-form-attaches.vue:
attach-cancel: "添付取り消し"
mark-as-sensitive: "閲覧注意に設定"
unmark-as-sensitive: "閲覧注意を解除"
desktop/views/components/sub-note-content.vue: desktop/views/components/sub-note-content.vue:
private: "この投稿は非公開です" private: "この投稿は非公開です"
deleted: "この投稿は削除されました" deleted: "この投稿は削除されました"
@ -1085,9 +1116,6 @@ desktop/views/components/settings.tags.vue:
add: "追加" add: "追加"
save: "保存" save: "保存"
desktop/views/components/taskmanager.vue:
title: "タスクマネージャ"
desktop/views/components/timeline.vue: desktop/views/components/timeline.vue:
home: "ホーム" home: "ホーム"
local: "ローカル" local: "ローカル"
@ -1130,8 +1158,6 @@ desktop/views/components/received-follow-requests-window.vue:
desktop/views/components/user-lists-window.vue: desktop/views/components/user-lists-window.vue:
title: "リスト" title: "リスト"
create-list: "リストを作成"
list-name: "リスト名"
desktop/views/components/user-preview.vue: desktop/views/components/user-preview.vue:
notes: "投稿" notes: "投稿"
@ -1238,11 +1264,6 @@ admin/views/instance.vue:
save: "保存" save: "保存"
saved: "保存しました" saved: "保存しました"
user-recommendation-config: "おすすめユーザー" user-recommendation-config: "おすすめユーザー"
enable-external-user-recommendation: "外部ユーザーレコメンデーションを有効にする"
external-user-recommendation-engine: "エンジン"
external-user-recommendation-engine-desc: "例: https://vinayaka.distsn.org/cgi-bin/vinayaka-user-match-misskey-api.cgi?{{host}}+{{user}}+{{limit}}+{{offset}}"
external-user-recommendation-timeout: "タイムアウト"
external-user-recommendation-timeout-desc: "ミリ秒単位 (例: 300000)"
email-config: "メールサーバーの設定" email-config: "メールサーバーの設定"
email-config-info: "メールアドレス確認やパスワードリセットの際に使われます。" email-config-info: "メールアドレス確認やパスワードリセットの際に使われます。"
enable-email: "メール配信を有効にする" enable-email: "メール配信を有効にする"
@ -1326,7 +1347,9 @@ admin/views/users.vue:
unsuspend-confirm: "凍結を解除しますか?" unsuspend-confirm: "凍結を解除しますか?"
unsuspended: "凍結を解除しました" unsuspended: "凍結を解除しました"
make-silence: "サイレンス" make-silence: "サイレンス"
silence-confirm: "サイレンスしますか?"
unmake-silence: "サイレンスの解除" unmake-silence: "サイレンスの解除"
unsilence-confirm: "サイレンスを解除しますか?"
verify: "公式アカウントにする" verify: "公式アカウントにする"
verify-confirm: "公式アカウントにしますか?" verify-confirm: "公式アカウントにしますか?"
verified: "公式アカウントにしました" verified: "公式アカウントにしました"
@ -1540,6 +1563,7 @@ desktop/views/widgets/polls.vue:
desktop/views/widgets/post-form.vue: desktop/views/widgets/post-form.vue:
title: "投稿" title: "投稿"
note: "投稿" note: "投稿"
something-happened: "何らかの事情で投稿できませんでした。"
desktop/views/widgets/profile.vue: desktop/views/widgets/profile.vue:
update-banner: "クリックでバナー編集" update-banner: "クリックでバナー編集"
@ -1562,12 +1586,11 @@ mobile/views/components/drive.vue:
file-count: "ファイル" file-count: "ファイル"
nothing-in-drive: "ドライブには何もありません" nothing-in-drive: "ドライブには何もありません"
folder-is-empty: "このフォルダは空です" folder-is-empty: "このフォルダは空です"
prompt: "何をしますか?(数字を入力してください): <1 → ファイルをアップロード | 2 → ファイルをURLでアップロード | 3 → フォルダ作成 | 4 → このフォルダ名を変更 | 5 → このフォルダを移動 | 6 → このフォルダを削除>"
deletion-alert: "ごめんなさい!フォルダの削除は未実装です...。"
folder-name: "フォルダー名" folder-name: "フォルダー名"
here-is-root: "現在いる場所はルートで、フォルダではありません。" here-is-root: "現在いる場所はルートで、フォルダではありません。"
url-prompt: "アップロードしたいファイルのURL" url-prompt: "アップロードしたいファイルのURL"
uploading: "アップロードをリクエストしました。アップロードが完了するまで時間がかかる場合があります。" uploading: "アップロードをリクエストしました。アップロードが完了するまで時間がかかる場合があります。"
folder-name-cannot-empty: "フォルダ名を空白にすることはできません。"
mobile/views/components/drive-file-chooser.vue: mobile/views/components/drive-file-chooser.vue:
select-file: "ファイルを選択" select-file: "ファイルを選択"
@ -1632,7 +1655,7 @@ mobile/views/components/post-form.vue:
quote-placeholder: "この投稿を引用... (オプション)" quote-placeholder: "この投稿を引用... (オプション)"
reply-placeholder: "この投稿への返信..." reply-placeholder: "この投稿への返信..."
cw-placeholder: "内容への注釈 (オプション)" cw-placeholder: "内容への注釈 (オプション)"
location-alert: "お使いの端末は位置情報に対応していません" geolocation-alert: "お使いの端末は位置情報に対応していません"
error: "エラー" error: "エラー"
username-prompt: "ユーザー名を入力してください" username-prompt: "ユーザー名を入力してください"
@ -1657,9 +1680,17 @@ mobile/views/components/ui.nav.vue:
admin: "管理" admin: "管理"
about: "Misskeyについて" about: "Misskeyについて"
mobile/views/pages/drive.vue:
contextmenu:
upload: "ファイルをアップロード"
url-upload: "ファイルをURLでアップロード"
create-folder: "フォルダーを作成"
rename-folder: "フォルダー名を変更"
move-folder: "このフォルダを移動"
delete-folder: "このフォルダを削除"
mobile/views/pages/user-lists.vue: mobile/views/pages/user-lists.vue:
title: "リスト" title: "リスト"
enter-list-name: "リスト名を入力してください"
mobile/views/pages/signup.vue: mobile/views/pages/signup.vue:
lets-start: "📦 始めましょう" lets-start: "📦 始めましょう"
@ -1811,24 +1842,18 @@ dev/views/apps.vue:
app-missing: "アプリなし" app-missing: "アプリなし"
dev/views/new-app.vue: dev/views/new-app.vue:
new-app: "新しいアプリケーション"
new-app-info: "アプリケーションはAPIからでも作成できます。 (app/create)"
create-app: "アプリケーションの作成" create-app: "アプリケーションの作成"
app-name: "アプリケーション名" app-name: "アプリケーション名"
app-name-placeholder: "ex) Misskey for iOS"
app-name-desc: "あなたのアプリの名称。" app-name-desc: "あなたのアプリの名称。"
app-name-ex: "ex) Misskey for iOS"
app-overview: "アプリの概要" app-overview: "アプリの概要"
app-desc: "あなたのアプリの簡単な説明や紹介。" app-overview-placeholder: " ex) Misskey iOSクライアント。"
app-desc-ex: "ex) Misskey iOSクライアント。" app-overview-desc: "あなたのアプリの簡単な説明や紹介。"
callback-url: "コールバックURL (オプション)" callback-url: "コールバックURL (オプション)"
callback-url-placeholder: "ex) https://your.app.example.com/callback.php"
callback-url-desc: "ユーザーが認証フォームで認証した際にリダイレクトするURLを設定できます。" callback-url-desc: "ユーザーが認証フォームで認証した際にリダイレクトするURLを設定できます。"
authority: "権限" authority: "権限"
authority-desc: "ここで要求した機能だけがAPIからアクセスできます。" authority-desc: "ここで要求した機能だけがAPIからアクセスできます。"
authority-warning: "アプリ作成後も変更できますが、新たな権限を付与する場合、その時点で関連付けられているユーザーキーはすべて無効になります。" authority-warning: "アプリ作成後も変更できますが、新たな権限を付与する場合、その時点で関連付けられているユーザーキーはすべて無効になります。"
account-read: "アカウントの情報を見る。"
account-write: "アカウントの情報を操作する。"
note-write: "投稿する。"
reaction-write: "リアクションしたりリアクションをキャンセルする。"
following-write: "フォローしたりフォロー解除する。"
drive-read: "ドライブを見る。"
drive-write: "ドライブを操作する。"
notification-read: "通知を見る。"
notification-write: "通知を操作する。"

View File

@ -60,6 +60,8 @@ common:
following: "フォローしとる" following: "フォローしとる"
followers: "フォロワー" followers: "フォロワー"
favorites: "お気に入り" favorites: "お気に入り"
permissions:
"write:votes": "投票するで"
weekday-short: weekday-short:
sunday: "日" sunday: "日"
monday: "月" monday: "月"
@ -166,15 +168,6 @@ common:
auth/views/form.vue: auth/views/form.vue:
share-access: "あんたのアカウントに<i>{name}</i>がアクセスしようとしてるで?ええか?" share-access: "あんたのアカウントに<i>{name}</i>がアクセスしようとしてるで?ええか?"
permission-ask: "このアプリは次の権限を要求してんで:" permission-ask: "このアプリは次の権限を要求してんで:"
account-read: "アカウントの情報を見させてもらうで。"
account-write: "アカウントの情報を操作させてもらうで。"
note-write: "投稿させてもらうで。"
like-write: "いいねしたりいいね解除させてもらうで。"
following-write: "フォローしたりフォロー解除させてもらうで。"
drive-read: "ドライブを見させてもらうで。"
drive-write: "ドライブを操作させてもらうで。"
notification-read: "通知を見させてもらうで。"
notification-write: "通知を操作させてもらうで。"
cancel: "やめとくわ" cancel: "やめとくわ"
accept: "アクセスを許可や!" accept: "アクセスを許可や!"
auth/views/index.vue: auth/views/index.vue:
@ -688,7 +681,6 @@ desktop/views/components/post-form.vue:
posting: "投稿中" posting: "投稿中"
attach-media-from-local: "PCからメディア持ってくる" attach-media-from-local: "PCからメディア持ってくる"
attach-media-from-drive: "ドライブからメディア持ってくる" attach-media-from-drive: "ドライブからメディア持ってくる"
attach-cancel: "くっつけるのやめよか"
create-poll: "アンケートを作成" create-poll: "アンケートを作成"
text-remain: "残り{}文字" text-remain: "残り{}文字"
recent-tags: "最近のタグ" recent-tags: "最近のタグ"
@ -779,6 +771,9 @@ common/views/components/password-settings.vue:
enter-new-password-again: "もっぺん入れてや" enter-new-password-again: "もっぺん入れてや"
not-match: "パスワードがおうとらん" not-match: "パスワードがおうとらん"
changed: "パスワード変えたわ" changed: "パスワード変えたわ"
common/views/components/post-form-attaches.vue:
mark-as-sensitive: "見たらあかん感じにしとく"
unmark-as-sensitive: "やっぱ見せたるわ"
desktop/views/components/sub-note-content.vue: desktop/views/components/sub-note-content.vue:
private: "この投稿は見せられへんわ" private: "この投稿は見せられへんわ"
deleted: "この投稿なんか無くなってもうたわ" deleted: "この投稿なんか無くなってもうたわ"
@ -787,12 +782,9 @@ desktop/views/components/sub-note-content.vue:
desktop/views/components/settings.tags.vue: desktop/views/components/settings.tags.vue:
add: "増やす" add: "増やす"
save: "保存" save: "保存"
desktop/views/components/taskmanager.vue:
title: "タスクマネージャ"
desktop/views/components/timeline.vue: desktop/views/components/timeline.vue:
home: "ホーム" home: "ホーム"
local: "ローカル" local: "ローカル"
hybrid: "ソーシャル"
global: "グローバル" global: "グローバル"
mentions: "あんた宛て" mentions: "あんた宛て"
messages: "ダイレクト投稿" messages: "ダイレクト投稿"
@ -908,11 +900,6 @@ admin/views/instance.vue:
save: "保存" save: "保存"
saved: "保存したで!" saved: "保存したで!"
user-recommendation-config: "このユーザーええで" user-recommendation-config: "このユーザーええで"
enable-external-user-recommendation: "外部ユーザーレコメンデーションを使えるようにする"
external-user-recommendation-engine: "エンジン"
external-user-recommendation-engine-desc: "例: https://vinayaka.distsn.org/cgi-bin/vinayaka-user-match-misskey-api.cgi?{{host}}+{{user}}+{{limit}}+{{offset}}"
external-user-recommendation-timeout: "タイムアウト"
external-user-recommendation-timeout-desc: "ミリ秒単位 (例: 300000)"
email-config: "メールサーバーの設定" email-config: "メールサーバーの設定"
email-config-info: "メールアドレス確認やパスワードリセットの際に使うで。" email-config-info: "メールアドレス確認やパスワードリセットの際に使うで。"
enable-email: "メール配信を有効にする" enable-email: "メール配信を有効にする"
@ -1141,7 +1128,7 @@ mobile/views/components/post-form.vue:
quote-placeholder: "この投稿を持ってくる(オプション)" quote-placeholder: "この投稿を持ってくる(オプション)"
reply-placeholder: "この投稿への返信..." reply-placeholder: "この投稿への返信..."
cw-placeholder: "内容への注釈 (オプション)" cw-placeholder: "内容への注釈 (オプション)"
location-alert: "あんさんのつことる端末は位置情報に対応しとらんみたいやわ、知らんけど。" geolocation-alert: "あんさんのつことる端末は位置情報に対応しとらんみたいやわ、知らんけど。"
error: "エラー" error: "エラー"
username-prompt: "ユーザー名を入力してや" username-prompt: "ユーザー名を入力してや"
mobile/views/components/sub-note-content.vue: mobile/views/components/sub-note-content.vue:
@ -1174,7 +1161,6 @@ mobile/views/pages/following.vue:
mobile/views/pages/home.vue: mobile/views/pages/home.vue:
home: "ホーム" home: "ホーム"
local: "ローカル" local: "ローカル"
hybrid: "ソーシャル"
global: "グローバル" global: "グローバル"
mentions: "あんた宛て" mentions: "あんた宛て"
messages: "ダイレクト投稿" messages: "ダイレクト投稿"
@ -1229,7 +1215,6 @@ deck:
widgets: "ウィジェット" widgets: "ウィジェット"
home: "ホーム" home: "ホーム"
local: "ローカル" local: "ローカル"
hybrid: "ソーシャル"
hashtag: "ハッシュタグ" hashtag: "ハッシュタグ"
global: "グローバル" global: "グローバル"
mentions: "あんた宛て" mentions: "あんた宛て"
@ -1289,21 +1274,9 @@ dev/views/new-app.vue:
create-app: "アプリケーション作る" create-app: "アプリケーション作る"
app-name: "アプリケーションの名前" app-name: "アプリケーションの名前"
app-name-desc: "あんたのアプリの名前。" app-name-desc: "あんたのアプリの名前。"
app-name-ex: "ex) 関西ミスキー保安協会"
app-overview: "このアプリどんなん?" app-overview: "このアプリどんなん?"
app-desc: "あんたのアプリどんなんか教えて"
app-desc-ex: "ex) 関西人なら誰でも口ずさめるこのCMがついにMisskeyへ。"
callback-url: "コールバックURL (無くてもええで)" callback-url: "コールバックURL (無くてもええで)"
callback-url-desc: "ユーザーが認証フォームで認証した後どこに連れてくかを設定できるで" callback-url-desc: "ユーザーが認証フォームで認証した後どこに連れてくかを設定できるで"
authority: "権限" authority: "権限"
authority-desc: "ここにチェックした機能しかAPIからアクセスできひんから気ぃつけてな" authority-desc: "ここにチェックした機能しかAPIからアクセスできひんから気ぃつけてな"
authority-warning: "アプリ作った後でも変えれるけど、新しいやつ追加したらそん時関連付いてるユーザーキーは全部ほかされるで。" authority-warning: "アプリ作った後でも変えれるけど、新しいやつ追加したらそん時関連付いてるユーザーキーは全部ほかされるで。"
account-read: "アカウントの情報見せて"
account-write: "アカウントの情報いじらせて"
note-write: "投稿させて"
reaction-write: "リアクションしたりそれをキャンセルさせて"
following-write: "フォローとかフォロー解除させて"
drive-read: "ドライブ見せて"
drive-write: "ドライブいじらせて"
notification-read: "通知見せて"
notification-write: "通知いじらせて"

View File

@ -69,6 +69,12 @@ common:
following: "팔로우 중" following: "팔로우 중"
followers: "팔로워" followers: "팔로워"
favorites: "즐겨찾기" favorites: "즐겨찾기"
permissions:
"read:account": "계정 정보 보기"
"write:account": "계정 정보 변경"
"read:drive": "드라이브 보기"
"write:drive": "드라이브 수정"
"write:votes": "투표하기"
empty-timeline-info: empty-timeline-info:
follow-users-to-make-your-timeline: "사용자를 팔로우하면 글이 타임라인에 표시됩니다." follow-users-to-make-your-timeline: "사용자를 팔로우하면 글이 타임라인에 표시됩니다."
explore: "사용자 탐색" explore: "사용자 탐색"
@ -276,21 +282,13 @@ common:
nav: "내비게이션" nav: "내비게이션"
tips: "팁" tips: "팁"
hashtags: "해시태그" hashtags: "해시태그"
queue: "큐"
dev: "앱을 만드는 데 실패했습니다. 다시 시도하시기 바랍니다." dev: "앱을 만드는 데 실패했습니다. 다시 시도하시기 바랍니다."
ai-chan-kawaii: "아이쨩 귀여워" ai-chan-kawaii: "아이쨩 귀여워"
you: "당신" you: "당신"
auth/views/form.vue: auth/views/form.vue:
share-access: "<i>{name}</i>가 당신의 계정에 엑세스하도록 허용하시겠습니까?" share-access: "<i>{name}</i>가 당신의 계정에 엑세스하도록 허용하시겠습니까?"
permission-ask: "이 앱은 다음의 권한을 요청합니다:" permission-ask: "이 앱은 다음의 권한을 요청합니다:"
account-read: "계정 정보 보기."
account-write: "계정 정보의 수정."
note-write: "게시하기."
like-write: "좋아요 하거나 좋아요 해제하기."
following-write: "팔로우하거나 팔로우를 취소하기."
drive-read: "드라이브 보기."
drive-write: "드라이브의 수정."
notification-read: "알림 읽기."
notification-write: "알림 수정하기."
cancel: "취소" cancel: "취소"
accept: "접근 권한 허용" accept: "접근 권한 허용"
auth/views/index.vue: auth/views/index.vue:
@ -877,7 +875,6 @@ desktop/views/components/post-form.vue:
posting: "게시중" posting: "게시중"
attach-media-from-local: "PC에서 미디어 첨부" attach-media-from-local: "PC에서 미디어 첨부"
attach-media-from-drive: "드라이브에서 미디어 첨부" attach-media-from-drive: "드라이브에서 미디어 첨부"
attach-cancel: "첨부 취소"
insert-a-kao: "v('ω')v" insert-a-kao: "v('ω')v"
create-poll: "투표 만들기" create-poll: "투표 만들기"
text-remain: "{}문자 남음" text-remain: "{}문자 남음"
@ -970,6 +967,10 @@ common/views/components/password-settings.vue:
not-match: "새 비밀번호가 일치하지 않습니다" not-match: "새 비밀번호가 일치하지 않습니다"
changed: "비밀번호를 변경하였습니다" changed: "비밀번호를 변경하였습니다"
failed: "비밀번호 변경을 실패하였습니다." failed: "비밀번호 변경을 실패하였습니다."
common/views/components/post-form-attaches.vue:
attach-cancel: "첨부 취소"
mark-as-sensitive: "열람주의로 설정"
unmark-as-sensitive: "열람주의 해제"
desktop/views/components/sub-note-content.vue: desktop/views/components/sub-note-content.vue:
private: "이 글은 비공개입니다" private: "이 글은 비공개입니다"
deleted: "이 글은 삭제되었습니다" deleted: "이 글은 삭제되었습니다"
@ -980,8 +981,6 @@ desktop/views/components/settings.tags.vue:
query: "쿼리 (생략 가능)" query: "쿼리 (생략 가능)"
add: "추가" add: "추가"
save: "저장" save: "저장"
desktop/views/components/taskmanager.vue:
title: "작업 관리자"
desktop/views/components/timeline.vue: desktop/views/components/timeline.vue:
home: "홈" home: "홈"
local: "로컬" local: "로컬"
@ -1115,11 +1114,6 @@ admin/views/instance.vue:
save: "저장" save: "저장"
saved: "저장하였습니다" saved: "저장하였습니다"
user-recommendation-config: "추천 사용자" user-recommendation-config: "추천 사용자"
enable-external-user-recommendation: "외부 사용자 추천 활성화"
external-user-recommendation-engine: "엔진"
external-user-recommendation-engine-desc: "예: https://vinayaka.distsn.org/cgi-bin/vinayaka-user-match-misskey-api.cgi?{{host}}+{{user}}+{{limit}}+{{offset}}"
external-user-recommendation-timeout: "타임 아웃"
external-user-recommendation-timeout-desc: "밀리초 (예: 300000)"
email-config: "메일 서버 설정" email-config: "메일 서버 설정"
email-config-info: "메일 주소 확인 혹은 비밀번호 재설정에 사용 됩니다." email-config-info: "메일 주소 확인 혹은 비밀번호 재설정에 사용 됩니다."
enable-email: "메일 발신 활성화" enable-email: "메일 발신 활성화"
@ -1470,7 +1464,7 @@ mobile/views/components/post-form.vue:
quote-placeholder: "이 글을 인용... (선택적)" quote-placeholder: "이 글을 인용... (선택적)"
reply-placeholder: "이 글에 답글..." reply-placeholder: "이 글에 답글..."
cw-placeholder: "내용 주석 (선택적)" cw-placeholder: "내용 주석 (선택적)"
location-alert: "사용하시는 장치가 위치정보 기능에 대응하지 않습니다" geolocation-alert: "사용하시는 장치가 위치정보 기능에 대응하지 않습니다"
error: "오류" error: "오류"
username-prompt: "사용자명을 입력하여 주십시오" username-prompt: "사용자명을 입력하여 주십시오"
mobile/views/components/sub-note-content.vue: mobile/views/components/sub-note-content.vue:
@ -1623,21 +1617,9 @@ dev/views/new-app.vue:
create-app: "어플리케이션 생성" create-app: "어플리케이션 생성"
app-name: "어플리케이션 이름" app-name: "어플리케이션 이름"
app-name-desc: "앱의 이름." app-name-desc: "앱의 이름."
app-name-ex: "ex) Misskey for iOS"
app-overview: "앱 개요" app-overview: "앱 개요"
app-desc: "어플리케이션에 대한 간단한 설명."
app-desc-ex: "ex) Misskey iOS 클라이언트."
callback-url: "콜백 URL (옵션)" callback-url: "콜백 URL (옵션)"
callback-url-desc: "사용자가 인증 폼에서 인증한 뒤 리다이렉트할 URL을 설정합니다." callback-url-desc: "사용자가 인증 폼에서 인증한 뒤 리다이렉트할 URL을 설정합니다."
authority: "권한" authority: "권한"
authority-desc: "이곳에서 요청한 권한에 한정하여 API로 액세스할 수 있습니다." authority-desc: "이곳에서 요청한 권한에 한정하여 API로 액세스할 수 있습니다."
authority-warning: "앱을 생성한 뒤에도 변경할 수 있지만, 새로운 권한을 설정하는 경우 그 시점부터 예전에 발급받았던 유저 키는 모두 무효화됩니다." authority-warning: "앱을 생성한 뒤에도 변경할 수 있지만, 새로운 권한을 설정하는 경우 그 시점부터 예전에 발급받았던 유저 키는 모두 무효화됩니다."
account-read: "계정 정보 보기."
account-write: "계정 정보 편집."
note-write: "글 쓰기."
reaction-write: "리액션을 하거나 리액션을 취소할 수 있음."
following-write: "팔로우하거나 팔로우 해제하기."
drive-read: "드라이브 보기."
drive-write: "드라이브를 조작."
notification-read: "알림 보기."
notification-write: "알림 조작."

View File

@ -23,6 +23,8 @@ common:
timeline: "Tijdlijn" timeline: "Tijdlijn"
followers: "Volgers" followers: "Volgers"
favorites: "Deze notitie toevoegen aan favorieten" favorites: "Deze notitie toevoegen aan favorieten"
permissions:
"write:votes": "Stemmen"
weekday-short: weekday-short:
sunday: "Z" sunday: "Z"
monday: "M" monday: "M"
@ -334,7 +336,6 @@ desktop/views/components/post-form.vue:
posting: "Bezig met plaatsen" posting: "Bezig met plaatsen"
attach-media-from-local: "Media bijvoegen van je computer" attach-media-from-local: "Media bijvoegen van je computer"
attach-media-from-drive: "Media bijvoegen uit je Drive" attach-media-from-drive: "Media bijvoegen uit je Drive"
attach-cancel: "Bijlage annuleren"
create-poll: "Peiling creëren" create-poll: "Peiling creëren"
text-remain: "{} resterende tekens" text-remain: "{} resterende tekens"
desktop/views/components/post-form-window.vue: desktop/views/components/post-form-window.vue:
@ -384,8 +385,6 @@ desktop/views/components/sub-note-content.vue:
poll: "Peilingen" poll: "Peilingen"
desktop/views/components/settings.tags.vue: desktop/views/components/settings.tags.vue:
add: "Toevoegen" add: "Toevoegen"
desktop/views/components/taskmanager.vue:
title: "Taakbeheer"
desktop/views/components/timeline.vue: desktop/views/components/timeline.vue:
home: "Startpagina" home: "Startpagina"
local: "Lokaal" local: "Lokaal"

View File

@ -37,6 +37,8 @@ common:
home: "Hjem" home: "Hjem"
followers: "Følgere" followers: "Følgere"
favorites: "Merket som favoritt" favorites: "Merket som favoritt"
permissions:
"write:votes": "Stem"
weekday-short: weekday-short:
sunday: "S" sunday: "S"
monday: "M" monday: "M"

View File

@ -23,6 +23,7 @@ common:
enter-password: "Wprowadź Hasło" enter-password: "Wprowadź Hasło"
2fa: "Uwierzytelnienie dwuetapowe" 2fa: "Uwierzytelnienie dwuetapowe"
customize-home: "Dostosuj stronę główną" customize-home: "Dostosuj stronę główną"
featured-notes: "Wyróżnienia"
dark-mode: "Tryb ciemny" dark-mode: "Tryb ciemny"
signin: "Zaloguj się" signin: "Zaloguj się"
signup: "Rejestracja" signup: "Rejestracja"
@ -61,6 +62,9 @@ common:
following: "Śledzisz" following: "Śledzisz"
followers: "Śledzący" followers: "Śledzący"
favorites: "Moje ulubione" favorites: "Moje ulubione"
permissions:
"read:drive": "Wyświetl dysk"
"write:votes": "Zagłosuj"
empty-timeline-info: empty-timeline-info:
explore: "Poznaj" explore: "Poznaj"
weekday-short: weekday-short:
@ -201,15 +205,6 @@ common:
you: "Ty" you: "Ty"
auth/views/form.vue: auth/views/form.vue:
permission-ask: "Ta aplikacja wymaga następujących uprawnień:" permission-ask: "Ta aplikacja wymaga następujących uprawnień:"
account-read: "Wyświetlanie informacji o koncie:"
account-write: "Modyfikowanie informacji o koncie:"
note-write: "Publikacja."
like-write: "Reagowanie na wpisy."
following-write: "Śledzenie i cofanie śledzenia."
drive-read: "Odczytywanie Twojego dysku."
drive-write: "Wysyłanie i usuwanie plików na Twoim dysku."
notification-read: "Odczytywanie Twoich powiadomień."
notification-write: "Zarządzanie Twoimi powiadomieniami."
cancel: "Anuluj" cancel: "Anuluj"
accept: "Przyznaj dostęp." accept: "Przyznaj dostęp."
auth/views/index.vue: auth/views/index.vue:
@ -715,7 +710,6 @@ desktop/views/components/post-form.vue:
posting: "Wysyłanie" posting: "Wysyłanie"
attach-media-from-local: "Załącz zawartość multimedialną z komputera" attach-media-from-local: "Załącz zawartość multimedialną z komputera"
attach-media-from-drive: "Załącz zawartość multimedialną z dysku" attach-media-from-drive: "Załącz zawartość multimedialną z dysku"
attach-cancel: "Usuń załącznik"
insert-a-kao: "v('ω')v" insert-a-kao: "v('ω')v"
create-poll: "Utwórz ankietę" create-poll: "Utwórz ankietę"
text-remain: "pozostałe znaki: {}" text-remain: "pozostałe znaki: {}"
@ -795,6 +789,9 @@ common/views/components/password-settings.vue:
enter-current-password: "Wprowadź obecne hasło" enter-current-password: "Wprowadź obecne hasło"
enter-new-password: "Wprowadź nowe hasło" enter-new-password: "Wprowadź nowe hasło"
enter-new-password-again: "Wprowadź ponownie nowe hasło" enter-new-password-again: "Wprowadź ponownie nowe hasło"
common/views/components/post-form-attaches.vue:
mark-as-sensitive: "Oznacz jako zawartość wrażliwą"
unmark-as-sensitive: "Cofnij oznaczenie jako zawartość wrażliwą"
desktop/views/components/sub-note-content.vue: desktop/views/components/sub-note-content.vue:
private: "ten wpis jest prywatny" private: "ten wpis jest prywatny"
deleted: "ten wpis został usunięty" deleted: "ten wpis został usunięty"
@ -805,12 +802,9 @@ desktop/views/components/settings.tags.vue:
query: "Zapytanie (opcjonalne)" query: "Zapytanie (opcjonalne)"
add: "Dodaj" add: "Dodaj"
save: "Zapisz" save: "Zapisz"
desktop/views/components/taskmanager.vue:
title: "Menedżer zadań"
desktop/views/components/timeline.vue: desktop/views/components/timeline.vue:
home: "Strona główna" home: "Strona główna"
local: "Lokalne" local: "Lokalne"
hybrid: "Społeczność"
global: "Globalne" global: "Globalne"
mentions: "Wspomnienia" mentions: "Wspomnienia"
messages: "Bezpośrednie wpisy" messages: "Bezpośrednie wpisy"
@ -882,8 +876,6 @@ admin/views/instance.vue:
save: "Zapisz" save: "Zapisz"
saved: "Zapisano" saved: "Zapisano"
user-recommendation-config: "Polecani użytkownicy" user-recommendation-config: "Polecani użytkownicy"
external-user-recommendation-engine: "Silnik"
external-user-recommendation-engine-desc: "Np: https://vinayaka.distsn.org/cgi-bin/vinayaka-user-match-misskey-api.cgi?{{host}}+{{user}}+{{limit}}+{{offset}}"
email: "Adres e-mail" email: "Adres e-mail"
admin/views/charts.vue: admin/views/charts.vue:
notes: "Wpisy" notes: "Wpisy"
@ -1091,7 +1083,7 @@ mobile/views/components/post-form.vue:
quote-placeholder: "Zacytuj ten wpis… (nieobowiązkowe)" quote-placeholder: "Zacytuj ten wpis… (nieobowiązkowe)"
reply-placeholder: "Odpowiedź na ten wpis…" reply-placeholder: "Odpowiedź na ten wpis…"
cw-placeholder: "Treść ostrzeżenia (opcjonalnie)" cw-placeholder: "Treść ostrzeżenia (opcjonalnie)"
location-alert: "Twoje urządzenie nie pozwala na przekazywanie informacji o lokalizacji" geolocation-alert: "Twoje urządzenie nie obsługuje geolokalizacji."
error: "Błąd" error: "Błąd"
username-prompt: "Wprowadź nazwę użytkownika" username-prompt: "Wprowadź nazwę użytkownika"
mobile/views/components/sub-note-content.vue: mobile/views/components/sub-note-content.vue:
@ -1119,7 +1111,6 @@ mobile/views/pages/signup.vue:
mobile/views/pages/home.vue: mobile/views/pages/home.vue:
home: "Strona główna" home: "Strona główna"
local: "Lokalne" local: "Lokalne"
hybrid: "Społeczność"
global: "Globalne" global: "Globalne"
mentions: "Wspomnienia" mentions: "Wspomnienia"
messages: "Bezpośrednie wpisy" messages: "Bezpośrednie wpisy"
@ -1169,7 +1160,6 @@ deck:
widgets: "Widżety" widgets: "Widżety"
home: "Strona główna" home: "Strona główna"
local: "Lokalne" local: "Lokalne"
hybrid: "Społeczność"
hashtag: "Hashtag" hashtag: "Hashtag"
global: "Globalne" global: "Globalne"
mentions: "Wspomnienia" mentions: "Wspomnienia"
@ -1224,11 +1214,3 @@ dev/views/apps.vue:
dev/views/new-app.vue: dev/views/new-app.vue:
app-name: "Nazwa Aplikacji" app-name: "Nazwa Aplikacji"
authority: "Uprawnienia" authority: "Uprawnienia"
account-read: "Wyświetlanie informacji o koncie:"
account-write: "Modyfikowanie informacji o koncie:"
note-write: "Publikacja."
following-write: "Śledzenie i cofanie śledzenia."
drive-read: "Odczytywanie Twojego dysku."
drive-write: "Wysyłanie i usuwanie plików na Twoim dysku."
notification-read: "Odczytywanie Twoich powiadomień."
notification-write: "Zarządzanie Twoimi powiadomieniami."

View File

@ -119,9 +119,6 @@ common:
you: "Você" you: "Você"
auth/views/form.vue: auth/views/form.vue:
permission-ask: "Este aplicativo precisa das seguintes permissões:" permission-ask: "Este aplicativo precisa das seguintes permissões:"
account-read: "Ver informações da conta."
account-write: "Modificar informações da conta."
note-write: "Publicar"
cancel: "Cancelar" cancel: "Cancelar"
accept: "Permitir acesso" accept: "Permitir acesso"
auth/views/index.vue: auth/views/index.vue:
@ -292,7 +289,3 @@ docs:
description: "Descrição" description: "Descrição"
dev/views/index.vue: dev/views/index.vue:
manage-apps: "Gerenciar aplicativos" manage-apps: "Gerenciar aplicativos"
dev/views/new-app.vue:
account-read: "Ver informações da conta."
account-write: "Modificar informações da conta."
note-write: "Publicar"

View File

@ -69,6 +69,27 @@ common:
following: "正在关注" following: "正在关注"
followers: "关注者" followers: "关注者"
favorites: "最爱" favorites: "最爱"
permissions:
"read:account": "查看账户信息"
"write:account": "更改我的帐户信息"
"read:blocks": "查看黑名单"
"write:blocks": "编辑黑名单"
"read:drive": "查看网盘"
"write:drive": "管理网盘文件"
"read:favorites": "查看收藏夹"
"write:favorites": "编辑收藏夹"
"read:following": "查看关注信息"
"write:following": "关注/取消关注"
"read:messaging": "查看对话"
"write:messaging": "对话操作"
"read:mutes": "查看屏蔽列表"
"write:mutes": "编辑屏蔽列表"
"write:notes": "创建或删除帖子"
"read:notifications": "查看通知"
"write:notifications": "管理通知"
"read:reactions": "查看回应"
"write:reactions": "回应操作"
"write:votes": "投票"
empty-timeline-info: empty-timeline-info:
follow-users-to-make-your-timeline: "关注其他用户时,帖子将显示在时间线中。" follow-users-to-make-your-timeline: "关注其他用户时,帖子将显示在时间线中。"
explore: "查找用户" explore: "查找用户"
@ -124,7 +145,7 @@ common:
apps: "应用程序" apps: "应用程序"
tags: "标签" tags: "标签"
mute-and-block: "屏蔽/拉黑" mute-and-block: "屏蔽/拉黑"
blocking: "屏蔽" blocking: "拉黑"
security: "安全性" security: "安全性"
signin: "登录历史" signin: "登录历史"
password: "密码" password: "密码"
@ -276,21 +297,13 @@ common:
nav: "导航" nav: "导航"
tips: "提示" tips: "提示"
hashtags: "标签" hashtags: "标签"
queue: "队列"
dev: "构建应用程序失败,请再试一次。" dev: "构建应用程序失败,请再试一次。"
ai-chan-kawaii: "小蓝真可爱" ai-chan-kawaii: "小蓝真可爱"
you: "您" you: "您"
auth/views/form.vue: auth/views/form.vue:
share-access: "您要允许<i>{name}</i>来访问您的账户吗?" share-access: "您要允许<i>{name}</i>来访问您的账户吗?"
permission-ask: "这个应用程序需要以下权限:" permission-ask: "这个应用程序需要以下权限:"
account-read: "查看账户信息"
account-write: "修改账户信息"
note-write: "投稿。"
like-write: "点赞或取消赞。"
following-write: "关注或取消关注。"
drive-read: "查看您的网盘"
drive-write: "管理网盘文件。"
notification-read: "查看通知。"
notification-write: "管理通知。"
cancel: "取消" cancel: "取消"
accept: "允许访问。" accept: "允许访问。"
auth/views/index.vue: auth/views/index.vue:
@ -877,7 +890,6 @@ desktop/views/components/post-form.vue:
posting: "发送中" posting: "发送中"
attach-media-from-local: "从设备中添加媒体文件" attach-media-from-local: "从设备中添加媒体文件"
attach-media-from-drive: "从网盘中添加媒体文件" attach-media-from-drive: "从网盘中添加媒体文件"
attach-cancel: "删除附件"
insert-a-kao: "v('ω')v" insert-a-kao: "v('ω')v"
create-poll: "创建一个投票" create-poll: "创建一个投票"
text-remain: "还剩{}字" text-remain: "还剩{}字"
@ -970,6 +982,10 @@ common/views/components/password-settings.vue:
not-match: "新密码不匹配" not-match: "新密码不匹配"
changed: "密码已更改" changed: "密码已更改"
failed: "更改密码失败" failed: "更改密码失败"
common/views/components/post-form-attaches.vue:
attach-cancel: "删除附件"
mark-as-sensitive: "标记为“敏感”"
unmark-as-sensitive: "取消标记为“敏感”"
desktop/views/components/sub-note-content.vue: desktop/views/components/sub-note-content.vue:
private: "这个帖子是私密的" private: "这个帖子是私密的"
deleted: "帖子已删除" deleted: "帖子已删除"
@ -980,8 +996,6 @@ desktop/views/components/settings.tags.vue:
query: "查询 (可选)" query: "查询 (可选)"
add: "添加" add: "添加"
save: "保存" save: "保存"
desktop/views/components/taskmanager.vue:
title: "任务管理器"
desktop/views/components/timeline.vue: desktop/views/components/timeline.vue:
home: "首页" home: "首页"
local: "本地" local: "本地"
@ -1115,11 +1129,6 @@ admin/views/instance.vue:
save: "保存" save: "保存"
saved: "保存完毕" saved: "保存完毕"
user-recommendation-config: "推荐用户" user-recommendation-config: "推荐用户"
enable-external-user-recommendation: "启用外部用户推荐"
external-user-recommendation-engine: "引擎"
external-user-recommendation-engine-desc: "例如: https://vinayaka.distsn.org/cgi-bin/vinayaka-user-match-misskey-api.cgi?{{host}}+{{user}}+{{limit}}+{{offset}}"
external-user-recommendation-timeout: "超时"
external-user-recommendation-timeout-desc: "单位为毫秒 (例如300000)"
email-config: "电子邮件服务器设置" email-config: "电子邮件服务器设置"
email-config-info: "用于确认电子邮件和密码重置等。" email-config-info: "用于确认电子邮件和密码重置等。"
enable-email: "启用电子邮件送递" enable-email: "启用电子邮件送递"
@ -1394,6 +1403,7 @@ desktop/views/widgets/polls.vue:
desktop/views/widgets/post-form.vue: desktop/views/widgets/post-form.vue:
title: "帖子" title: "帖子"
note: "帖子" note: "帖子"
something-happened: "由于某种原因无法发帖。"
desktop/views/widgets/profile.vue: desktop/views/widgets/profile.vue:
update-banner: "点击来剪辑背景" update-banner: "点击来剪辑背景"
update-avatar: "点击来剪辑头像" update-avatar: "点击来剪辑头像"
@ -1470,7 +1480,7 @@ mobile/views/components/post-form.vue:
quote-placeholder: "引用这个帖子t... (可选)" quote-placeholder: "引用这个帖子t... (可选)"
reply-placeholder: "回复这个帖子" reply-placeholder: "回复这个帖子"
cw-placeholder: "评论帖子(可选)" cw-placeholder: "评论帖子(可选)"
location-alert: "您的设备不提供位服务" geolocation-alert: "您的设备不提供位服务"
error: "错误" error: "错误"
username-prompt: "请输入用户名" username-prompt: "请输入用户名"
mobile/views/components/sub-note-content.vue: mobile/views/components/sub-note-content.vue:
@ -1503,7 +1513,7 @@ mobile/views/pages/following.vue:
mobile/views/pages/home.vue: mobile/views/pages/home.vue:
home: "首页" home: "首页"
local: "Local" local: "Local"
hybrid: "Social" hybrid: "社交"
global: "Global" global: "Global"
mentions: "Mentions" mentions: "Mentions"
messages: "直接发布" messages: "直接发布"
@ -1559,7 +1569,7 @@ deck:
widgets: "小部件" widgets: "小部件"
home: "首页" home: "首页"
local: "Local" local: "Local"
hybrid: "Social" hybrid: "社交"
hashtag: "标签" hashtag: "标签"
global: "Global" global: "Global"
mentions: "Mentions" mentions: "Mentions"
@ -1620,24 +1630,18 @@ dev/views/apps.vue:
create-app: "创建应用" create-app: "创建应用"
app-missing: "没有应用" app-missing: "没有应用"
dev/views/new-app.vue: dev/views/new-app.vue:
new-app: "新应用"
new-app-info: "可以从 API 中创建应用。 (app/create)"
create-app: "正在创建应用" create-app: "正在创建应用"
app-name: "应用名称" app-name: "应用名称"
app-name-placeholder: "ex) iOS版Misskey"
app-name-desc: "您应用的名称" app-name-desc: "您应用的名称"
app-name-ex: "ex) iOS版本的Misskey"
app-overview: "应用摘要" app-overview: "应用摘要"
app-desc: "您的应用的简要说明或介绍。" app-overview-placeholder: " ex) iOS版Misskey客户端."
app-desc-ex: "ex) iOS版Misskey客户端." app-overview-desc: "您的应用的简要说明或介绍。"
callback-url: "回应URL (optional)" callback-url: "回应URL (optional)"
callback-url-placeholder: "ex) https://your.app.example.com/callback.php"
callback-url-desc: "通过身份验证表单对用户进行身份验证后重定向到的URL。" callback-url-desc: "通过身份验证表单对用户进行身份验证后重定向到的URL。"
authority: "权限" authority: "权限"
authority-desc: "只能通过API访问此处请求的功能。" authority-desc: "只能通过API访问此处请求的功能。"
authority-warning: "您可以在创建应用程序后对其进行更改,但如果您授予不同的权限,则当时关联的所有用户密钥都将失效。" authority-warning: "您可以在创建应用程序后对其进行更改,但如果您授予不同的权限,则当时关联的所有用户密钥都将失效。"
account-read: "查看账户信息"
account-write: "修改账户信息"
note-write: "投稿。"
reaction-write: "添加或删除回应。"
following-write: "关注和不关注"
drive-read: "查看网盘"
drive-write: "管理网盘文件。"
notification-read: "阅读您的通知"
notification-write: "管理通知"

View File

@ -1,8 +1,8 @@
{ {
"name": "misskey", "name": "misskey",
"author": "syuilo <i@syuilo.com>", "author": "syuilo <i@syuilo.com>",
"version": "10.99.0", "version": "11.2.1",
"codename": "nighthike", "codename": "daybreak",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/syuilo/misskey.git" "url": "https://github.com/syuilo/misskey.git"
@ -11,7 +11,7 @@
"private": true, "private": true,
"scripts": { "scripts": {
"start": "node ./index.js", "start": "node ./index.js",
"debug": "DEBUG=misskey:* node ./index.js", "init": "node ./built/init.js",
"build": "webpack && gulp build", "build": "webpack && gulp build",
"webpack": "webpack", "webpack": "webpack",
"watch": "webpack --watch", "watch": "webpack --watch",
@ -32,14 +32,13 @@
"@prezzemolo/rap": "0.1.2", "@prezzemolo/rap": "0.1.2",
"@prezzemolo/zip": "0.0.3", "@prezzemolo/zip": "0.0.3",
"@types/bcryptjs": "2.4.2", "@types/bcryptjs": "2.4.2",
"@types/bull": "3.5.8", "@types/bull": "3.5.11",
"@types/chai-http": "3.0.5",
"@types/dateformat": "3.0.0", "@types/dateformat": "3.0.0",
"@types/deep-equal": "1.0.1", "@types/deep-equal": "1.0.1",
"@types/double-ended-queue": "2.1.0", "@types/double-ended-queue": "2.1.0",
"@types/elasticsearch": "5.0.30", "@types/elasticsearch": "5.0.32",
"@types/file-type": "10.6.0", "@types/file-type": "10.9.1",
"@types/gulp": "4.0.5", "@types/gulp": "4.0.6",
"@types/gulp-mocha": "0.0.32", "@types/gulp-mocha": "0.0.32",
"@types/gulp-rename": "0.0.33", "@types/gulp-rename": "0.0.33",
"@types/gulp-replace": "0.0.31", "@types/gulp-replace": "0.0.31",
@ -47,66 +46,65 @@
"@types/gulp-util": "3.0.34", "@types/gulp-util": "3.0.34",
"@types/is-root": "1.0.0", "@types/is-root": "1.0.0",
"@types/is-url": "1.2.28", "@types/is-url": "1.2.28",
"@types/js-yaml": "3.12.0", "@types/js-yaml": "3.12.1",
"@types/jsdom": "12.2.3", "@types/jsdom": "12.2.3",
"@types/katex": "0.10.1", "@types/katex": "0.10.1",
"@types/koa": "2.0.48", "@types/koa": "2.0.48",
"@types/koa-bodyparser": "5.0.2", "@types/koa-bodyparser": "5.0.2",
"@types/koa-compress": "2.0.8", "@types/koa-compress": "2.0.9",
"@types/koa-cors": "0.0.0", "@types/koa-cors": "0.0.0",
"@types/koa-favicon": "2.0.19", "@types/koa-favicon": "2.0.19",
"@types/koa-logger": "3.1.1", "@types/koa-logger": "3.1.1",
"@types/koa-mount": "3.0.1", "@types/koa-mount": "3.0.1",
"@types/koa-multer": "1.0.0", "@types/koa-multer": "1.0.0",
"@types/koa-router": "7.0.40", "@types/koa-router": "7.0.40",
"@types/koa-send": "4.1.1", "@types/koa-send": "4.1.2",
"@types/koa-views": "2.0.3", "@types/koa-views": "2.0.3",
"@types/koa__cors": "2.2.3", "@types/koa__cors": "2.2.3",
"@types/lolex": "3.1.1",
"@types/minio": "7.0.1", "@types/minio": "7.0.1",
"@types/mkdirp": "0.5.2", "@types/mocha": "5.2.6",
"@types/mocha": "5.2.5", "@types/node": "11.13.4",
"@types/mongodb": "3.1.20", "@types/nodemailer": "4.6.7",
"@types/node": "11.10.4",
"@types/nodemailer": "4.6.6",
"@types/nprogress": "0.0.29", "@types/nprogress": "0.0.29",
"@types/oauth": "0.9.1", "@types/oauth": "0.9.1",
"@types/parse5": "5.0.0", "@types/parse5": "5.0.0",
"@types/parsimmon": "1.10.0", "@types/parsimmon": "1.10.0",
"@types/portscanner": "2.1.0", "@types/portscanner": "2.1.0",
"@types/pug": "2.0.4", "@types/pug": "2.0.4",
"@types/qrcode": "1.3.0", "@types/qrcode": "1.3.2",
"@types/random-seed": "0.3.3",
"@types/ratelimiter": "2.1.28", "@types/ratelimiter": "2.1.28",
"@types/redis": "2.8.10", "@types/redis": "2.8.12",
"@types/rename": "1.0.1", "@types/rename": "1.0.1",
"@types/request": "2.48.1", "@types/request": "2.48.1",
"@types/request-promise-native": "1.0.15", "@types/request-promise-native": "1.0.15",
"@types/request-stats": "3.0.0", "@types/request-stats": "3.0.0",
"@types/rimraf": "2.0.2", "@types/rimraf": "2.0.2",
"@types/seedrandom": "2.4.27", "@types/sharp": "0.22.1",
"@types/sharp": "0.21.2",
"@types/showdown": "1.9.2", "@types/showdown": "1.9.2",
"@types/speakeasy": "2.0.4", "@types/speakeasy": "2.0.4",
"@types/systeminformation": "3.23.1", "@types/systeminformation": "3.23.1",
"@types/tinycolor2": "1.4.1", "@types/tinycolor2": "1.4.1",
"@types/tmp": "0.0.33", "@types/tmp": "0.1.0",
"@types/uuid": "3.4.4", "@types/uuid": "3.4.4",
"@types/web-push": "3.3.0", "@types/web-push": "3.3.0",
"@types/webpack": "4.4.24", "@types/webpack": "4.4.27",
"@types/webpack-stream": "3.2.10", "@types/webpack-stream": "3.2.10",
"@types/websocket": "0.0.40", "@types/websocket": "0.0.40",
"@types/ws": "6.0.1", "@types/ws": "6.0.1",
"animejs": "3.0.1", "animejs": "3.0.1",
"apexcharts": "3.6.5", "apexcharts": "3.6.7",
"autobind-decorator": "2.4.0", "autobind-decorator": "2.4.0",
"autosize": "4.0.2", "autosize": "4.0.2",
"autwh": "0.1.0", "autwh": "0.1.0",
"bcryptjs": "2.4.3", "bcryptjs": "2.4.3",
"bootstrap-vue": "2.0.0-rc.13", "bootstrap-vue": "2.0.0-rc.13",
"bull": "3.7.0", "bull": "3.7.0",
"cafy": "15.1.0", "cafy": "15.1.1",
"chai": "4.2.0", "chai": "4.2.0",
"chai-http": "4.2.1",
"chalk": "2.4.2", "chalk": "2.4.2",
"cli-highlight": "2.1.0",
"commander": "2.20.0", "commander": "2.20.0",
"content-disposition": "0.5.3", "content-disposition": "0.5.3",
"crc-32": "1.2.0", "crc-32": "1.2.0",
@ -114,17 +112,15 @@
"cssnano": "4.1.10", "cssnano": "4.1.10",
"dateformat": "3.0.3", "dateformat": "3.0.3",
"deep-equal": "1.0.1", "deep-equal": "1.0.1",
"deepcopy": "0.6.3",
"diskusage": "1.0.0", "diskusage": "1.0.0",
"double-ended-queue": "2.1.0-0", "double-ended-queue": "2.1.0-0",
"elasticsearch": "15.4.1", "elasticsearch": "15.4.1",
"emojilib": "2.4.0", "emojilib": "2.4.0",
"escape-regexp": "0.0.1", "eslint": "5.16.0",
"eslint": "5.15.1",
"eslint-plugin-vue": "5.2.2", "eslint-plugin-vue": "5.2.2",
"eventemitter3": "3.1.0", "eventemitter3": "3.1.0",
"feed": "2.0.4", "feed": "2.0.4",
"file-type": "10.10.0", "file-type": "10.11.0",
"fuckadblock": "3.2.1", "fuckadblock": "3.2.1",
"gulp": "4.0.0", "gulp": "4.0.0",
"gulp-cssnano": "2.1.3", "gulp-cssnano": "2.1.3",
@ -135,19 +131,19 @@
"gulp-sourcemaps": "2.6.5", "gulp-sourcemaps": "2.6.5",
"gulp-stylus": "2.7.0", "gulp-stylus": "2.7.0",
"gulp-tslint": "8.1.4", "gulp-tslint": "8.1.4",
"gulp-typescript": "5.0.0", "gulp-typescript": "5.0.1",
"gulp-uglify": "3.0.2", "gulp-uglify": "3.0.2",
"gulp-util": "3.0.8", "gulp-util": "3.0.8",
"hard-source-webpack-plugin": "0.13.1", "hard-source-webpack-plugin": "0.13.1",
"html-minifier": "3.5.21", "html-minifier": "4.0.0",
"http-signature": "1.2.0", "http-signature": "1.2.0",
"insert-text-at-cursor": "0.1.2", "insert-text-at-cursor": "0.2.0",
"is-root": "2.0.0", "is-root": "2.0.0",
"is-svg": "4.0.0", "is-svg": "4.1.0",
"js-yaml": "3.13.0", "js-yaml": "3.13.1",
"jsdom": "14.0.0", "jsdom": "14.0.0",
"json5": "2.1.0", "json5": "2.1.0",
"json5-loader": "1.0.1", "json5-loader": "2.0.0",
"katex": "0.10.1", "katex": "0.10.1",
"koa": "2.7.0", "koa": "2.7.0",
"koa-bodyparser": "4.2.1", "koa-bodyparser": "4.2.1",
@ -163,23 +159,22 @@
"koa-views": "6.2.0", "koa-views": "6.2.0",
"langmap": "0.0.16", "langmap": "0.0.16",
"loader-utils": "1.2.3", "loader-utils": "1.2.3",
"lolex": "3.1.0",
"lookup-dns-cache": "2.1.0", "lookup-dns-cache": "2.1.0",
"minio": "7.0.5", "minio": "7.0.5",
"mkdirp": "0.5.1", "mocha": "6.1.3",
"mocha": "5.2.0",
"moji": "0.5.1", "moji": "0.5.1",
"moment": "2.24.0", "moment": "2.24.0",
"mongodb": "3.2.2",
"monk": "6.0.6",
"ms": "2.1.1", "ms": "2.1.1",
"nan": "2.12.1",
"nested-property": "0.0.7", "nested-property": "0.0.7",
"nodemailer": "5.1.1", "node-fetch": "2.3.0",
"nodemailer": "6.1.0",
"nprogress": "0.2.0", "nprogress": "0.2.0",
"object-assign-deep": "0.4.0", "object-assign-deep": "0.4.0",
"os-utils": "0.0.14", "os-utils": "0.0.14",
"parse5": "5.1.0", "parse5": "5.1.0",
"parsimmon": "1.12.0", "parsimmon": "1.12.0",
"pg": "7.9.0",
"portscanner": "2.2.0", "portscanner": "2.2.0",
"postcss-loader": "3.0.0", "postcss-loader": "3.0.0",
"prismjs": "1.16.0", "prismjs": "1.16.0",
@ -189,20 +184,23 @@
"promise-sequential": "1.1.1", "promise-sequential": "1.1.1",
"pug": "2.0.3", "pug": "2.0.3",
"punycode": "2.1.1", "punycode": "2.1.1",
"pureimage": "0.1.6",
"qrcode": "1.3.3", "qrcode": "1.3.3",
"random-seed": "0.3.0",
"randomcolor": "0.5.4", "randomcolor": "0.5.4",
"ratelimiter": "3.3.0", "ratelimiter": "3.3.0",
"recaptcha-promise": "0.1.3", "recaptcha-promise": "0.1.3",
"reconnecting-websocket": "4.1.10", "reconnecting-websocket": "4.1.10",
"redis": "2.8.0", "redis": "2.8.0",
"reflect-metadata": "0.1.13",
"rename": "1.0.4", "rename": "1.0.4",
"request": "2.88.0", "request": "2.88.0",
"request-promise-native": "1.0.7", "request-promise-native": "1.0.7",
"request-stats": "3.0.0", "request-stats": "3.0.0",
"require-all": "3.0.0",
"rimraf": "2.6.3", "rimraf": "2.6.3",
"rndstr": "1.0.0", "rndstr": "1.0.0",
"s-age": "1.1.2", "s-age": "1.1.2",
"seedrandom": "2.4.4",
"sharp": "0.22.0", "sharp": "0.22.0",
"showdown": "1.9.0", "showdown": "1.9.0",
"showdown-highlightjs-extension": "0.1.2", "showdown-highlightjs-extension": "0.1.2",
@ -212,19 +210,21 @@
"stylus": "0.54.5", "stylus": "0.54.5",
"stylus-loader": "3.0.2", "stylus-loader": "3.0.2",
"summaly": "2.2.0", "summaly": "2.2.0",
"systeminformation": "4.0.16", "systeminformation": "4.1.4",
"syuilo-password-strength": "0.0.1", "syuilo-password-strength": "0.0.1",
"terser-webpack-plugin": "1.2.3", "terser-webpack-plugin": "1.2.3",
"textarea-caret": "3.1.0", "textarea-caret": "3.1.0",
"tinycolor2": "1.4.1", "tinycolor2": "1.4.1",
"tmp": "0.0.33", "tmp": "0.1.0",
"ts-loader": "5.3.3", "ts-loader": "5.3.3",
"ts-node": "8.0.3", "ts-node": "7.0.1",
"tslint": "5.13.1", "tslint": "5.15.0",
"tslint-sonarts": "1.9.0", "tslint-sonarts": "1.9.0",
"typeorm": "0.2.16-rc.1",
"typescript": "3.3.3333", "typescript": "3.3.3333",
"typescript-eslint-parser": "22.0.0", "typescript-eslint-parser": "22.0.0",
"uglify-es": "3.3.9", "uglify-es": "3.3.9",
"ulid": "2.3.0",
"url-loader": "1.1.2", "url-loader": "1.1.2",
"uuid": "3.3.2", "uuid": "3.3.2",
"v-animate-css": "0.0.3", "v-animate-css": "0.0.3",
@ -232,7 +232,7 @@
"video-thumbnail-generator": "1.1.3", "video-thumbnail-generator": "1.1.3",
"vue": "2.6.10", "vue": "2.6.10",
"vue-color": "2.7.0", "vue-color": "2.7.0",
"vue-content-loading": "1.5.3", "vue-content-loading": "1.6.0",
"vue-cropperjs": "3.0.0", "vue-cropperjs": "3.0.0",
"vue-i18n": "8.10.0", "vue-i18n": "8.10.0",
"vue-js-modal": "1.3.28", "vue-js-modal": "1.3.28",
@ -240,7 +240,7 @@
"vue-loader": "15.7.0", "vue-loader": "15.7.0",
"vue-marquee-text-component": "1.1.1", "vue-marquee-text-component": "1.1.1",
"vue-prism-component": "1.1.1", "vue-prism-component": "1.1.1",
"vue-router": "3.0.2", "vue-router": "3.0.4",
"vue-sequential-entrance": "1.1.3", "vue-sequential-entrance": "1.1.3",
"vue-style-loader": "4.1.2", "vue-style-loader": "4.1.2",
"vue-svg-inline-loader": "1.2.15", "vue-svg-inline-loader": "1.2.15",
@ -250,9 +250,8 @@
"vuex": "3.1.0", "vuex": "3.1.0",
"vuex-persistedstate": "2.5.4", "vuex-persistedstate": "2.5.4",
"web-push": "3.3.3", "web-push": "3.3.3",
"webfinger.js": "2.7.0", "webpack": "4.30.0",
"webpack": "4.28.4", "webpack-cli": "3.3.0",
"webpack-cli": "3.2.3",
"websocket": "1.0.28", "websocket": "1.0.28",
"ws": "6.2.1", "ws": "6.2.1",
"xev": "2.0.1" "xev": "2.0.1"

View File

@ -1,19 +0,0 @@
declare module 'deepcopy' {
type DeepcopyCustomizerValueType = 'Object';
type DeepcopyCustomizer<T> = (
value: T,
valueType: DeepcopyCustomizerValueType) => T;
interface IDeepcopyOptions<T> {
customizer: DeepcopyCustomizer<T>;
}
function deepcopy<T>(
value: T,
options?: IDeepcopyOptions<T> | DeepcopyCustomizer<T>): T;
namespace deepcopy {} // Hack
export = deepcopy;
}

View File

@ -1,7 +0,0 @@
declare module 'escape-regexp' {
function escapeRegExp(str: string): string;
namespace escapeRegExp {} // Hack
export = escapeRegExp;
}

View File

@ -1,65 +0,0 @@
declare module 'webfinger.js' {
interface IWebFingerConstructorConfig {
tls_only?: boolean;
webfist_fallback?: boolean;
uri_fallback?: boolean;
request_timeout?: number;
}
type JRDProperties = { [type: string]: string };
interface IJRDLink {
rel: string;
type?: string;
href?: string;
template?: string;
titles?: { [lang: string]: string };
properties?: JRDProperties;
}
interface IJRD {
subject?: string;
expires?: Date;
aliases?: string[];
properties?: JRDProperties;
links?: IJRDLink[];
}
interface IIDXLinks {
'avatar': IJRDLink[];
'remotestorage': IJRDLink[];
'blog': IJRDLink[];
'vcard': IJRDLink[];
'updates': IJRDLink[];
'share': IJRDLink[];
'profile': IJRDLink[];
'webfist': IJRDLink[];
'camlistore': IJRDLink[];
[type: string]: IJRDLink[];
}
interface IIDXProperties {
'name': string;
[type: string]: string;
}
interface IIDX {
links: IIDXLinks;
properties: IIDXProperties;
}
interface ILookupCallbackResult {
object: IJRD;
json: string;
idx: IIDX;
}
type LookupCallback = (err: Error | string, result?: ILookupCallbackResult) => void;
export class WebFinger {
constructor(config?: IWebFingerConstructorConfig);
public lookup(address: string, cb: LookupCallback): NodeJS.Timeout;
public lookupLink(address: string, rel: string, cb: IJRDLink): void;
}
}

View File

@ -15,5 +15,8 @@ program
.parse(process.argv); .parse(process.argv);
if (process.env.MK_ONLY_QUEUE) program.onlyQueue = true; if (process.env.MK_ONLY_QUEUE) program.onlyQueue = true;
if (process.env.NODE_ENV === 'test') program.disableClustering = true;
if (process.env.NODE_ENV === 'test') program.quiet = true;
if (process.env.NODE_ENV === 'test') program.noDaemons = true;
export { program }; export { program };

77
src/boot/index.ts Normal file
View File

@ -0,0 +1,77 @@
import * as cluster from 'cluster';
import chalk from 'chalk';
import Xev from 'xev';
import Logger from '../services/logger';
import { program } from '../argv';
// for typeorm
import 'reflect-metadata';
import { masterMain } from './master';
import { workerMain } from './worker';
const logger = new Logger('core', 'cyan');
const clusterLogger = logger.createSubLogger('cluster', 'orange', false);
const ev = new Xev();
/**
* Init process
*/
export default async function() {
process.title = `Misskey (${cluster.isMaster ? 'master' : 'worker'})`;
if (cluster.isMaster || program.disableClustering) {
await masterMain();
if (cluster.isMaster) {
ev.mount();
}
}
if (cluster.isWorker || program.disableClustering) {
await workerMain();
}
// ユニットテスト時にMisskeyが子プロセスで起動された時のため
// それ以外のときは process.send は使えないので弾く
if (process.send) {
process.send('ok');
}
}
//#region Events
// Listen new workers
cluster.on('fork', worker => {
clusterLogger.debug(`Process forked: [${worker.id}]`);
});
// Listen online workers
cluster.on('online', worker => {
clusterLogger.debug(`Process is now online: [${worker.id}]`);
});
// Listen for dying workers
cluster.on('exit', worker => {
// Replace the dead worker,
// we're not sentimental
clusterLogger.error(chalk.red(`[${worker.id}] died :(`));
cluster.fork();
});
// Display detail of unhandled promise rejection
if (!program.quiet) {
process.on('unhandledRejection', console.dir);
}
// Display detail of uncaught exception
process.on('uncaughtException', err => {
logger.error(err);
});
// Dying away...
process.on('exit', code => {
logger.info(`The process is going to exit with code ${code}`);
});
//#endregion

176
src/boot/master.ts Normal file
View File

@ -0,0 +1,176 @@
import * as os from 'os';
import * as cluster from 'cluster';
import chalk from 'chalk';
import * as portscanner from 'portscanner';
import * as isRoot from 'is-root';
import Logger from '../services/logger';
import loadConfig from '../config/load';
import { Config } from '../config/types';
import { lessThan } from '../prelude/array';
import * as pkg from '../../package.json';
import { program } from '../argv';
import { showMachineInfo } from '../misc/show-machine-info';
import { initDb } from '../db/postgre';
const logger = new Logger('core', 'cyan');
const bootLogger = logger.createSubLogger('boot', 'magenta', false);
function greet() {
if (!program.quiet) {
//#region Misskey logo
const v = `v${pkg.version}`;
console.log(' _____ _ _ ');
console.log(' | |_|___ ___| |_ ___ _ _ ');
console.log(' | | | | |_ -|_ -| \'_| -_| | |');
console.log(' |_|_|_|_|___|___|_,_|___|_ |');
console.log(' ' + chalk.gray(v) + (' |___|\n'.substr(v.length)));
//#endregion
console.log(' Misskey is maintained by @syuilo, @AyaMorisawa, @mei23, and @acid-chicken.');
console.log(chalk.keyword('orange')(' If you like Misskey, please donate to support development. https://www.patreon.com/syuilo'));
console.log('');
console.log(chalk`< ${os.hostname()} {gray (PID: ${process.pid.toString()})} >`);
}
bootLogger.info('Welcome to Misskey!');
bootLogger.info(`Misskey v${pkg.version}`, null, true);
}
/**
* Init master process
*/
export async function masterMain() {
greet();
let config!: Config;
try {
// initialize app
config = await init();
if (config.port == null) {
bootLogger.error('The port is not configured. Please configure port.', null, true);
process.exit(1);
}
if (process.platform === 'linux' && isWellKnownPort(config.port) && !isRoot()) {
bootLogger.error('You need root privileges to listen on well-known port on Linux', null, true);
process.exit(1);
}
if (!await isPortAvailable(config.port)) {
bootLogger.error(`Port ${config.port} is already in use`, null, true);
process.exit(1);
}
} catch (e) {
bootLogger.error('Fatal error occurred during initialization', null, true);
process.exit(1);
}
bootLogger.succ('Misskey initialized');
if (!program.disableClustering) {
await spawnWorkers(config.clusterLimit);
}
if (!program.noDaemons) {
require('../daemons/server-stats').default();
require('../daemons/notes-stats').default();
require('../daemons/queue-stats').default();
}
bootLogger.succ(`Now listening on port ${config.port} on ${config.url}`, null, true);
}
const runningNodejsVersion = process.version.slice(1).split('.').map(x => parseInt(x, 10));
const requiredNodejsVersion = [11, 7, 0];
const satisfyNodejsVersion = !lessThan(runningNodejsVersion, requiredNodejsVersion);
function isWellKnownPort(port: number): boolean {
return port < 1024;
}
async function isPortAvailable(port: number): Promise<boolean> {
return await portscanner.checkPortStatus(port, '127.0.0.1') === 'closed';
}
function showEnvironment(): void {
const env = process.env.NODE_ENV;
const logger = bootLogger.createSubLogger('env');
logger.info(typeof env == 'undefined' ? 'NODE_ENV is not set' : `NODE_ENV: ${env}`);
if (env !== 'production') {
logger.warn('The environment is not in production mode.');
logger.warn('DO NOT USE FOR PRODUCTION PURPOSE!', null, true);
}
logger.info(`You ${isRoot() ? '' : 'do not '}have root privileges`);
}
/**
* Init app
*/
async function init(): Promise<Config> {
showEnvironment();
const nodejsLogger = bootLogger.createSubLogger('nodejs');
nodejsLogger.info(`Version ${runningNodejsVersion.join('.')}`);
if (!satisfyNodejsVersion) {
nodejsLogger.error(`Node.js version is less than ${requiredNodejsVersion.join('.')}. Please upgrade it.`, null, true);
process.exit(1);
}
await showMachineInfo(bootLogger);
const configLogger = bootLogger.createSubLogger('config');
let config;
try {
config = loadConfig();
} catch (exception) {
if (typeof exception === 'string') {
configLogger.error(exception);
process.exit(1);
}
if (exception.code === 'ENOENT') {
configLogger.error('Configuration file not found', null, true);
process.exit(1);
}
throw exception;
}
configLogger.succ('Loaded');
// Try to connect to DB
try {
bootLogger.info('Connecting database...');
await initDb();
} catch (e) {
bootLogger.error('Cannot connect to database', null, true);
bootLogger.error(e);
process.exit(1);
}
return config;
}
async function spawnWorkers(limit: number = Infinity) {
const workers = Math.min(limit, os.cpus().length);
bootLogger.info(`Starting ${workers} worker${workers === 1 ? '' : 's'}...`);
await Promise.all([...Array(workers)].map(spawnWorker));
bootLogger.succ('All workers started');
}
function spawnWorker(): Promise<void> {
return new Promise(res => {
const worker = cluster.fork();
worker.on('message', message => {
if (message !== 'ready') return;
res();
});
});
}

20
src/boot/worker.ts Normal file
View File

@ -0,0 +1,20 @@
import * as cluster from 'cluster';
import { initDb } from '../db/postgre';
/**
* Init worker process
*/
export async function workerMain() {
await initDb();
// start server
await require('../server').default();
// start job queue
require('../queue').default();
if (cluster.isWorker) {
// Send a 'ready' message to parent process
process.send!('ready');
}
}

View File

@ -38,7 +38,7 @@
<div class="kidvdlkg" v-for="file in files"> <div class="kidvdlkg" v-for="file in files">
<div @click="file._open = !file._open"> <div @click="file._open = !file._open">
<div> <div>
<div class="thumbnail" :style="thumbnail(file)"></div> <x-file-thumbnail class="thumbnail" :file="file" fit="contain" @click="showFileMenu(file)"/>
</div> </div>
<div> <div>
<header> <header>
@ -48,7 +48,7 @@
<div> <div>
<div> <div>
<span style="margin-right:16px;">{{ file.type }}</span> <span style="margin-right:16px;">{{ file.type }}</span>
<span>{{ file.datasize | bytes }}</span> <span>{{ file.size | bytes }}</span>
</div> </div>
<div><mk-time :time="file.createdAt" mode="detail"/></div> <div><mk-time :time="file.createdAt" mode="detail"/></div>
</div> </div>
@ -75,10 +75,15 @@ import Vue from 'vue';
import i18n from '../../i18n'; import i18n from '../../i18n';
import { faCloud, faTerminal, faSearch } from '@fortawesome/free-solid-svg-icons'; import { faCloud, faTerminal, faSearch } from '@fortawesome/free-solid-svg-icons';
import { faTrashAlt, faEye, faEyeSlash } from '@fortawesome/free-regular-svg-icons'; import { faTrashAlt, faEye, faEyeSlash } from '@fortawesome/free-regular-svg-icons';
import XFileThumbnail from '../../common/views/components/drive-file-thumbnail.vue';
export default Vue.extend({ export default Vue.extend({
i18n: i18n('admin/views/drive.vue'), i18n: i18n('admin/views/drive.vue'),
components: {
XFileThumbnail
},
data() { data() {
return { return {
file: null, file: null,
@ -151,13 +156,6 @@ export default Vue.extend({
}); });
}, },
thumbnail(file: any): any {
return {
'background-color': file.properties.avgColor && file.properties.avgColor.length == 3 ? `rgb(${file.properties.avgColor.join(',')})` : 'transparent',
'background-image': `url(${file.thumbnailUrl})`
};
},
async del(file: any) { async del(file: any) {
const process = async () => { const process = async () => {
await this.$root.api('drive/files/delete', { fileId: file.id }); await this.$root.api('drive/files/delete', { fileId: file.id });
@ -179,9 +177,9 @@ export default Vue.extend({
this.$root.api('drive/files/update', { this.$root.api('drive/files/update', {
fileId: file.id, fileId: file.id,
isSensitive: !file.isSensitive isSensitive: !file.isSensitive
}); }).then(() => {
file.isSensitive = !file.isSensitive; file.isSensitive = !file.isSensitive;
});
}, },
async show() { async show() {
@ -244,7 +242,7 @@ export default Vue.extend({
> div:nth-child(1) > div:nth-child(1)
> .thumbnail > .thumbnail
display block display flex
width 64px width 64px
height 64px height 64px
background-size cover background-size cover

View File

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

View File

@ -77,12 +77,6 @@
<header>summaly Proxy</header> <header>summaly Proxy</header>
<ui-input v-model="summalyProxy">URL</ui-input> <ui-input v-model="summalyProxy">URL</ui-input>
</section> </section>
<section>
<header><fa :icon="faUserPlus"/> {{ $t('user-recommendation-config') }}</header>
<ui-switch v-model="enableExternalUserRecommendation">{{ $t('enable-external-user-recommendation') }}</ui-switch>
<ui-input v-model="externalUserRecommendationEngine" :disabled="!enableExternalUserRecommendation">{{ $t('external-user-recommendation-engine') }}<template #desc>{{ $t('external-user-recommendation-engine-desc') }}</template></ui-input>
<ui-input v-model="externalUserRecommendationTimeout" type="number" :disabled="!enableExternalUserRecommendation">{{ $t('external-user-recommendation-timeout') }}<template #suffix>ms</template><template #desc>{{ $t('external-user-recommendation-timeout-desc') }}</template></ui-input>
</section>
<section> <section>
<ui-button @click="updateMeta">{{ $t('save') }}</ui-button> <ui-button @click="updateMeta">{{ $t('save') }}</ui-button>
</section> </section>
@ -184,9 +178,6 @@ export default Vue.extend({
discordClientSecret: null, discordClientSecret: null,
proxyAccount: null, proxyAccount: null,
inviteCode: null, inviteCode: null,
enableExternalUserRecommendation: false,
externalUserRecommendationEngine: null,
externalUserRecommendationTimeout: null,
summalyProxy: null, summalyProxy: null,
enableEmail: false, enableEmail: false,
email: null, email: null,
@ -204,9 +195,9 @@ export default Vue.extend({
}, },
created() { created() {
this.$root.getMeta().then(meta => { this.$root.getMeta(true).then(meta => {
this.maintainerName = meta.maintainer.name; this.maintainerName = meta.maintainerName;
this.maintainerEmail = meta.maintainer.email; this.maintainerEmail = meta.maintainerEmail;
this.disableRegistration = meta.disableRegistration; this.disableRegistration = meta.disableRegistration;
this.disableLocalTimeline = meta.disableLocalTimeline; this.disableLocalTimeline = meta.disableLocalTimeline;
this.disableGlobalTimeline = meta.disableGlobalTimeline; this.disableGlobalTimeline = meta.disableGlobalTimeline;
@ -236,9 +227,6 @@ export default Vue.extend({
this.enableDiscordIntegration = meta.enableDiscordIntegration; this.enableDiscordIntegration = meta.enableDiscordIntegration;
this.discordClientId = meta.discordClientId; this.discordClientId = meta.discordClientId;
this.discordClientSecret = meta.discordClientSecret; this.discordClientSecret = meta.discordClientSecret;
this.enableExternalUserRecommendation = meta.enableExternalUserRecommendation;
this.externalUserRecommendationEngine = meta.externalUserRecommendationEngine;
this.externalUserRecommendationTimeout = meta.externalUserRecommendationTimeout;
this.summalyProxy = meta.summalyProxy; this.summalyProxy = meta.summalyProxy;
this.enableEmail = meta.enableEmail; this.enableEmail = meta.enableEmail;
this.email = meta.email; this.email = meta.email;
@ -299,9 +287,6 @@ export default Vue.extend({
enableDiscordIntegration: this.enableDiscordIntegration, enableDiscordIntegration: this.enableDiscordIntegration,
discordClientId: this.discordClientId, discordClientId: this.discordClientId,
discordClientSecret: this.discordClientSecret, discordClientSecret: this.discordClientSecret,
enableExternalUserRecommendation: this.enableExternalUserRecommendation,
externalUserRecommendationEngine: this.externalUserRecommendationEngine,
externalUserRecommendationTimeout: parseInt(this.externalUserRecommendationTimeout, 10),
summalyProxy: this.summalyProxy, summalyProxy: this.summalyProxy,
enableEmail: this.enableEmail, enableEmail: this.enableEmail,
email: this.email, email: this.email,

View File

@ -19,7 +19,7 @@
</ui-horizon-group> </ui-horizon-group>
<div class="nqjzuvev"> <div class="nqjzuvev">
<code v-for="log in logs" :key="log._id" :class="log.level"> <code v-for="log in logs" :key="log.id" :class="log.level">
<details> <details>
<summary><mk-time :time="log.createdAt"/> [{{ log.domain.join('.') }}] {{ log.message }}</summary> <summary><mk-time :time="log.createdAt"/> [{{ log.domain.join('.') }}] {{ log.message }}</summary>
<vue-json-pretty v-if="log.data" :data="log.data"></vue-json-pretty> <vue-json-pretty v-if="log.data" :data="log.data"></vue-json-pretty>

View File

@ -165,7 +165,7 @@ export default Vue.extend({
/** 処理対象ユーザーの情報を更新する */ /** 処理対象ユーザーの情報を更新する */
async refreshUser() { async refreshUser() {
this.$root.api('admin/show-user', { userId: this.user._id }).then(info => { this.$root.api('admin/show-user', { userId: this.user.id }).then(info => {
this.user = info; this.user = info;
}); });
}, },
@ -173,7 +173,7 @@ export default Vue.extend({
async resetPassword() { async resetPassword() {
if (!await this.getConfirmed(this.$t('reset-password-confirm'))) return; if (!await this.getConfirmed(this.$t('reset-password-confirm'))) return;
this.$root.api('admin/reset-password', { userId: this.user._id }).then(res => { this.$root.api('admin/reset-password', { userId: this.user.id }).then(res => {
this.$root.dialog({ this.$root.dialog({
type: 'success', type: 'success',
text: this.$t('password-updated', { password: res.password }) text: this.$t('password-updated', { password: res.password })
@ -187,7 +187,7 @@ export default Vue.extend({
this.verifying = true; this.verifying = true;
const process = async () => { const process = async () => {
await this.$root.api('admin/verify-user', { userId: this.user._id }); await this.$root.api('admin/verify-user', { userId: this.user.id });
this.$root.dialog({ this.$root.dialog({
type: 'success', type: 'success',
text: this.$t('verified') text: this.$t('verified')
@ -212,7 +212,7 @@ export default Vue.extend({
this.unverifying = true; this.unverifying = true;
const process = async () => { const process = async () => {
await this.$root.api('admin/unverify-user', { userId: this.user._id }); await this.$root.api('admin/unverify-user', { userId: this.user.id });
this.$root.dialog({ this.$root.dialog({
type: 'success', type: 'success',
text: this.$t('unverified') text: this.$t('unverified')
@ -232,8 +232,10 @@ export default Vue.extend({
}, },
async silenceUser() { async silenceUser() {
if (!await this.getConfirmed(this.$t('silence-confirm'))) return;
const process = async () => { const process = async () => {
await this.$root.api('admin/silence-user', { userId: this.user._id }); await this.$root.api('admin/silence-user', { userId: this.user.id });
this.$root.dialog({ this.$root.dialog({
type: 'success', type: 'success',
splash: true splash: true
@ -251,8 +253,10 @@ export default Vue.extend({
}, },
async unsilenceUser() { async unsilenceUser() {
if (!await this.getConfirmed(this.$t('unsilence-confirm'))) return;
const process = async () => { const process = async () => {
await this.$root.api('admin/unsilence-user', { userId: this.user._id }); await this.$root.api('admin/unsilence-user', { userId: this.user.id });
this.$root.dialog({ this.$root.dialog({
type: 'success', type: 'success',
splash: true splash: true
@ -275,7 +279,7 @@ export default Vue.extend({
this.suspending = true; this.suspending = true;
const process = async () => { const process = async () => {
await this.$root.api('admin/suspend-user', { userId: this.user._id }); await this.$root.api('admin/suspend-user', { userId: this.user.id });
this.$root.dialog({ this.$root.dialog({
type: 'success', type: 'success',
text: this.$t('suspended') text: this.$t('suspended')
@ -300,7 +304,7 @@ export default Vue.extend({
this.unsuspending = true; this.unsuspending = true;
const process = async () => { const process = async () => {
await this.$root.api('admin/unsuspend-user', { userId: this.user._id }); await this.$root.api('admin/unsuspend-user', { userId: this.user.id });
this.$root.dialog({ this.$root.dialog({
type: 'success', type: 'success',
text: this.$t('unsuspended') text: this.$t('unsuspended')
@ -320,7 +324,7 @@ export default Vue.extend({
}, },
async updateRemoteUser() { async updateRemoteUser() {
this.$root.api('admin/update-remote-user', { userId: this.user._id }).then(res => { this.$root.api('admin/update-remote-user', { userId: this.user.id }).then(res => {
this.$root.dialog({ this.$root.dialog({
type: 'success', type: 'success',
text: this.$t('remote-user-updated') text: this.$t('remote-user-updated')

View File

@ -14,15 +14,7 @@
<h2>{{ $t('permission-ask') }}</h2> <h2>{{ $t('permission-ask') }}</h2>
<ul> <ul>
<template v-for="p in app.permission"> <template v-for="p in app.permission">
<li v-if="p == 'account-read'">{{ $t('account-read') }}</li> <li :key="p">{{ $t(`@.permissions.${p}`) }}</li>
<li v-if="p == 'account-write'">{{ $t('account-write') }}</li>
<li v-if="p == 'note-write'">{{ $t('note-write') }}</li>
<li v-if="p == 'like-write'">{{ $t('like-write') }}</li>
<li v-if="p == 'following-write'">{{ $t('following-write') }}</li>
<li v-if="p == 'drive-read'">{{ $t('drive-read') }}</li>
<li v-if="p == 'drive-write'">{{ $t('drive-write') }}</li>
<li v-if="p == 'notification-read'">{{ $t('notification-read') }}</li>
<li v-if="p == 'notification-write'">{{ $t('notification-write') }}</li>
</template> </template>
</ul> </ul>
</section> </section>

View File

@ -45,15 +45,9 @@ export default function <T extends object>(data: {
this.$watch('props', () => { this.$watch('props', () => {
this.mergeProps(); this.mergeProps();
}); });
this.bakeProps();
}, },
methods: { methods: {
bakeProps() {
this.bakedOldProps = JSON.stringify(this.props);
},
mergeProps() { mergeProps() {
if (data.props) { if (data.props) {
const defaultProps = data.props(); const defaultProps = data.props();
@ -65,17 +59,10 @@ export default function <T extends object>(data: {
}, },
save() { save() {
if (this.bakedOldProps == JSON.stringify(this.props)) return;
this.bakeProps();
if (this.platform == 'deck') { if (this.platform == 'deck') {
this.$store.commit('device/updateDeckColumn', this.column); this.$store.commit('device/updateDeckColumn', this.column);
} else { } else {
this.$root.api('i/update_widget', { this.$store.commit('device/updateWidget', this.widget);
id: this.id,
data: this.props
});
} }
} }
} }

View File

@ -70,8 +70,8 @@ export default (opts: Opts = {}) => ({
}, },
reactionsCount(): number { reactionsCount(): number {
return this.appearNote.reactionCounts return this.appearNote.reactions
? sum(Object.values(this.appearNote.reactionCounts)) ? sum(Object.values(this.appearNote.reactions))
: 0; : 0;
}, },
@ -134,7 +134,7 @@ export default (opts: Opts = {}) => ({
}, },
reactDirectly(reaction) { reactDirectly(reaction) {
(this.$root.api('notes/reactions/create', { this.$root.api('notes/reactions/create', {
noteId: this.appearNote.id, noteId: this.appearNote.id,
reaction: reaction reaction: reaction
}); });

View File

@ -87,16 +87,16 @@ export default prop => ({
case 'reacted': { case 'reacted': {
const reaction = body.reaction; const reaction = body.reaction;
if (this.$_ns_target.reactionCounts == null) { if (this.$_ns_target.reactions == null) {
Vue.set(this.$_ns_target, 'reactionCounts', {}); Vue.set(this.$_ns_target, 'reactions', {});
} }
if (this.$_ns_target.reactionCounts[reaction] == null) { if (this.$_ns_target.reactions[reaction] == null) {
Vue.set(this.$_ns_target.reactionCounts, reaction, 0); Vue.set(this.$_ns_target.reactions, reaction, 0);
} }
// Increment the count // Increment the count
this.$_ns_target.reactionCounts[reaction]++; this.$_ns_target.reactions[reaction]++;
if (body.userId == this.$store.state.i.id) { if (body.userId == this.$store.state.i.id) {
Vue.set(this.$_ns_target, 'myReaction', reaction); Vue.set(this.$_ns_target, 'myReaction', reaction);
@ -107,16 +107,16 @@ export default prop => ({
case 'unreacted': { case 'unreacted': {
const reaction = body.reaction; const reaction = body.reaction;
if (this.$_ns_target.reactionCounts == null) { if (this.$_ns_target.reactions == null) {
return; return;
} }
if (this.$_ns_target.reactionCounts[reaction] == null) { if (this.$_ns_target.reactions[reaction] == null) {
return; return;
} }
// Decrement the count // Decrement the count
if (this.$_ns_target.reactionCounts[reaction] > 0) this.$_ns_target.reactionCounts[reaction]--; if (this.$_ns_target.reactions[reaction] > 0) this.$_ns_target.reactions[reaction]--;
if (body.userId == this.$store.state.i.id) { if (body.userId == this.$store.state.i.id) {
Vue.set(this.$_ns_target, 'myReaction', null); Vue.set(this.$_ns_target, 'myReaction', null);
@ -125,9 +125,11 @@ export default prop => ({
} }
case 'pollVoted': { case 'pollVoted': {
if (body.userId == this.$store.state.i.id) return;
const choice = body.choice; const choice = body.choice;
this.$_ns_target.poll.choices.find(c => c.id === choice).votes++; this.$_ns_target.poll.choices[choice].votes++;
if (body.userId == this.$store.state.i.id) {
Vue.set(this.$_ns_target.poll.choices[choice], 'isVoted', true);
}
break; break;
} }
@ -135,7 +137,6 @@ export default prop => ({
Vue.set(this.$_ns_target, 'deletedAt', body.deletedAt); Vue.set(this.$_ns_target, 'deletedAt', body.deletedAt);
Vue.set(this.$_ns_target, 'renote', null); Vue.set(this.$_ns_target, 'renote', null);
this.$_ns_target.text = null; this.$_ns_target.text = null;
this.$_ns_target.tags = [];
this.$_ns_target.fileIds = []; this.$_ns_target.fileIds = [];
this.$_ns_target.poll = null; this.$_ns_target.poll = null;
this.$_ns_target.geo = null; this.$_ns_target.geo = null;

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('@')) {
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)}`);
}

View File

@ -55,11 +55,7 @@ export default Vue.extend({
}, },
icon(): any { icon(): any {
return { return {
backgroundColor: this.lightmode backgroundColor: this.user.avatarColor,
? `rgb(${this.user.avatarColor.slice(0, 3).join(',')})`
: this.user.avatarColor && this.user.avatarColor.length == 3
? `rgb(${this.user.avatarColor.join(',')})`
: null,
backgroundImage: this.lightmode ? null : `url(${this.url})`, backgroundImage: this.lightmode ? null : `url(${this.url})`,
borderRadius: this.$store.state.settings.circleIcons ? '100%' : null borderRadius: this.$store.state.settings.circleIcons ? '100%' : null
}; };
@ -67,7 +63,7 @@ export default Vue.extend({
}, },
mounted() { mounted() {
if (this.user.avatarColor) { if (this.user.avatarColor) {
this.$el.style.color = `rgb(${this.user.avatarColor.slice(0, 3).join(',')})`; this.$el.style.color = this.user.avatarColor;
} }
}, },
methods: { methods: {

View File

@ -6,7 +6,17 @@
<mk-signin/> <mk-signin/>
</template> </template>
<template v-else> <template v-else>
<div class="icon" v-if="!input && !select && !user" :class="type"><fa :icon="icon"/></div> <div class="icon" v-if="icon">
<fa :icon="icon"/>
</div>
<div class="icon" v-else-if="!input && !select && !user" :class="type">
<fa icon="check" v-if="type === 'success'"/>
<fa :icon="faTimesCircle" v-if="type === 'error'"/>
<fa icon="exclamation-triangle" v-if="type === 'warning'"/>
<fa icon="info-circle" v-if="type === 'info'"/>
<fa :icon="faQuestionCircle" v-if="type === 'question'"/>
<fa icon="spinner" pulse v-if="type === 'waiting'"/>
</div>
<header v-if="title" v-html="title"></header> <header v-if="title" v-html="title"></header>
<div class="body" v-if="text" v-html="text"></div> <div class="body" v-if="text" v-html="text"></div>
<ui-input v-if="input" v-model="inputValue" autofocus :type="input.type || 'text'" :placeholder="input.placeholder" @keydown="onInputKeydown"></ui-input> <ui-input v-if="input" v-model="inputValue" autofocus :type="input.type || 'text'" :placeholder="input.placeholder" @keydown="onInputKeydown"></ui-input>
@ -14,8 +24,8 @@
<ui-select v-if="select" v-model="selectedValue" autofocus> <ui-select v-if="select" v-model="selectedValue" autofocus>
<option v-for="item in select.items" :value="item.value">{{ item.text }}</option> <option v-for="item in select.items" :value="item.value">{{ item.text }}</option>
</ui-select> </ui-select>
<ui-horizon-group no-grow class="buttons fit-bottom" v-if="!splash"> <ui-horizon-group no-grow class="buttons fit-bottom" v-if="!splash && (showOkButton || showCancelButton)">
<ui-button @click="ok" primary :autofocus="!input && !select && !user">{{ (showCancelButton || input || select || user) ? $t('@.ok') : $t('@.got-it') }}</ui-button> <ui-button @click="ok" v-if="showOkButton" primary :autofocus="!input && !select && !user">{{ (showCancelButton || input || select || user) ? $t('@.ok') : $t('@.got-it') }}</ui-button>
<ui-button @click="cancel" v-if="showCancelButton || input || select || user">{{ $t('@.cancel') }}</ui-button> <ui-button @click="cancel" v-if="showCancelButton || input || select || user">{{ $t('@.cancel') }}</ui-button>
</ui-horizon-group> </ui-horizon-group>
</template> </template>
@ -55,10 +65,21 @@ export default Vue.extend({
user: { user: {
required: false required: false
}, },
icon: {
required: false
},
showOkButton: {
type: Boolean,
default: true
},
showCancelButton: { showCancelButton: {
type: Boolean, type: Boolean,
default: false default: false
}, },
cancelableByBgClick: {
type: Boolean,
default: true
},
splash: { splash: {
type: Boolean, type: Boolean,
default: false default: false
@ -69,22 +90,11 @@ export default Vue.extend({
return { return {
inputValue: this.input && this.input.default ? this.input.default : null, inputValue: this.input && this.input.default ? this.input.default : null,
userInputValue: null, userInputValue: null,
selectedValue: null selectedValue: null,
faTimesCircle, faQuestionCircle
}; };
}, },
computed: {
icon(): any {
switch (this.type) {
case 'success': return 'check';
case 'error': return faTimesCircle;
case 'warning': return 'exclamation-triangle';
case 'info': return 'info-circle';
case 'question': return faQuestionCircle;
}
}
},
mounted() { mounted() {
this.$nextTick(() => { this.$nextTick(() => {
(this.$refs.bg as any).style.pointerEvents = 'auto'; (this.$refs.bg as any).style.pointerEvents = 'auto';
@ -113,6 +123,8 @@ export default Vue.extend({
methods: { methods: {
async ok() { async ok() {
if (!this.showOkButton) return;
if (this.user) { if (this.user) {
const user = await this.$root.api('users/show', parseAcct(this.userInputValue)); const user = await this.$root.api('users/show', parseAcct(this.userInputValue));
if (user) { if (user) {
@ -156,7 +168,9 @@ export default Vue.extend({
}, },
onBgClick() { onBgClick() {
if (this.cancelableByBgClick) {
this.cancel(); this.cancel();
}
}, },
onInputKeydown(e) { onInputKeydown(e) {
@ -183,9 +197,6 @@ export default Vue.extend({
height 100% height 100%
&.splash &.splash
&, *
pointer-events none !important
> .main > .main
min-width 0 min-width 0
width initial width initial
@ -243,7 +254,7 @@ export default Vue.extend({
margin-top 8px margin-top 8px
> .body > .body
margin 16px 0 margin 16px 0 0 0
> .buttons > .buttons
margin-top 16px margin-top 16px

View File

@ -105,15 +105,11 @@ export default Vue.extend({
}, },
isThumbnailAvailable(): boolean { isThumbnailAvailable(): boolean {
return this.file.thumbnailUrl return this.file.thumbnailUrl
? this.file.thumbnailUrl.endsWith('?thumbnail')
? (this.is === 'image' || this.is === 'video') ? (this.is === 'image' || this.is === 'video')
: true
: false; : false;
}, },
background(): string { background(): string {
return this.file.properties.avgColor && this.file.properties.avgColor.length == 3 return this.file.properties.avgColor || 'transparent';
? `rgb(${this.file.properties.avgColor.join(',')})`
: 'transparent';
} }
}, },
mounted() { mounted() {
@ -122,10 +118,10 @@ export default Vue.extend({
}, },
methods: { methods: {
onThumbnailLoaded() { onThumbnailLoaded() {
if (this.file.properties.avgColor && this.file.properties.avgColor.length == 3) { if (this.file.properties.avgColor) {
anime({ anime({
targets: this.$refs.thumbnail, targets: this.$refs.thumbnail,
backgroundColor: `rgba(${this.file.properties.avgColor.join(',')}, 0)`, backgroundColor: 'transparent', // TODO fade
duration: 100, duration: 100,
easing: 'linear' easing: 'linear'
}); });

View File

@ -24,11 +24,11 @@
<div class="board"> <div class="board">
<div class="labels-x" v-if="this.$store.state.settings.games.reversi.showBoardLabels"> <div class="labels-x" v-if="this.$store.state.settings.games.reversi.showBoardLabels">
<span v-for="i in game.settings.map[0].length">{{ String.fromCharCode(64 + i) }}</span> <span v-for="i in game.map[0].length">{{ String.fromCharCode(64 + i) }}</span>
</div> </div>
<div class="flex"> <div class="flex">
<div class="labels-y" v-if="this.$store.state.settings.games.reversi.showBoardLabels"> <div class="labels-y" v-if="this.$store.state.settings.games.reversi.showBoardLabels">
<div v-for="i in game.settings.map.length">{{ i }}</div> <div v-for="i in game.map.length">{{ i }}</div>
</div> </div>
<div class="cells" :style="cellsStyle"> <div class="cells" :style="cellsStyle">
<div v-for="(stone, i) in o.board" <div v-for="(stone, i) in o.board"
@ -46,11 +46,11 @@
</div> </div>
</div> </div>
<div class="labels-y" v-if="this.$store.state.settings.games.reversi.showBoardLabels"> <div class="labels-y" v-if="this.$store.state.settings.games.reversi.showBoardLabels">
<div v-for="i in game.settings.map.length">{{ i }}</div> <div v-for="i in game.map.length">{{ i }}</div>
</div> </div>
</div> </div>
<div class="labels-x" v-if="this.$store.state.settings.games.reversi.showBoardLabels"> <div class="labels-x" v-if="this.$store.state.settings.games.reversi.showBoardLabels">
<span v-for="i in game.settings.map[0].length">{{ String.fromCharCode(64 + i) }}</span> <span v-for="i in game.map[0].length">{{ String.fromCharCode(64 + i) }}</span>
</div> </div>
</div> </div>
@ -71,9 +71,9 @@
</div> </div>
<div class="info"> <div class="info">
<p v-if="game.settings.isLlotheo">{{ $t('is-llotheo') }}</p> <p v-if="game.isLlotheo">{{ $t('is-llotheo') }}</p>
<p v-if="game.settings.loopedBoard">{{ $t('looped-map') }}</p> <p v-if="game.loopedBoard">{{ $t('looped-map') }}</p>
<p v-if="game.settings.canPutEverywhere">{{ $t('can-put-everywhere') }}</p> <p v-if="game.canPutEverywhere">{{ $t('can-put-everywhere') }}</p>
</div> </div>
</div> </div>
</template> </template>
@ -160,8 +160,8 @@ export default Vue.extend({
cellsStyle(): any { cellsStyle(): any {
return { return {
'grid-template-rows': `repeat(${this.game.settings.map.length}, 1fr)`, 'grid-template-rows': `repeat(${this.game.map.length}, 1fr)`,
'grid-template-columns': `repeat(${this.game.settings.map[0].length}, 1fr)` 'grid-template-columns': `repeat(${this.game.map[0].length}, 1fr)`
}; };
} }
}, },
@ -169,10 +169,10 @@ export default Vue.extend({
watch: { watch: {
logPos(v) { logPos(v) {
if (!this.game.isEnded) return; if (!this.game.isEnded) return;
this.o = new Reversi(this.game.settings.map, { this.o = new Reversi(this.game.map, {
isLlotheo: this.game.settings.isLlotheo, isLlotheo: this.game.isLlotheo,
canPutEverywhere: this.game.settings.canPutEverywhere, canPutEverywhere: this.game.canPutEverywhere,
loopedBoard: this.game.settings.loopedBoard loopedBoard: this.game.loopedBoard
}); });
for (const log of this.logs.slice(0, v)) { for (const log of this.logs.slice(0, v)) {
this.o.put(log.color, log.pos); this.o.put(log.color, log.pos);
@ -184,10 +184,10 @@ export default Vue.extend({
created() { created() {
this.game = this.initGame; this.game = this.initGame;
this.o = new Reversi(this.game.settings.map, { this.o = new Reversi(this.game.map, {
isLlotheo: this.game.settings.isLlotheo, isLlotheo: this.game.isLlotheo,
canPutEverywhere: this.game.settings.canPutEverywhere, canPutEverywhere: this.game.canPutEverywhere,
loopedBoard: this.game.settings.loopedBoard loopedBoard: this.game.loopedBoard
}); });
for (const log of this.game.logs) { for (const log of this.game.logs) {
@ -286,10 +286,10 @@ export default Vue.extend({
onRescue(game) { onRescue(game) {
this.game = game; this.game = game;
this.o = new Reversi(this.game.settings.map, { this.o = new Reversi(this.game.map, {
isLlotheo: this.game.settings.isLlotheo, isLlotheo: this.game.isLlotheo,
canPutEverywhere: this.game.settings.canPutEverywhere, canPutEverywhere: this.game.canPutEverywhere,
loopedBoard: this.game.settings.loopedBoard loopedBoard: this.game.loopedBoard
}); });
for (const log of this.game.logs) { for (const log of this.game.logs) {

View File

@ -17,9 +17,9 @@
</header> </header>
<div> <div>
<div class="random" v-if="game.settings.map == null"><fa icon="dice"/></div> <div class="random" v-if="game.map == null"><fa icon="dice"/></div>
<div class="board" v-else :style="{ 'grid-template-rows': `repeat(${ game.settings.map.length }, 1fr)`, 'grid-template-columns': `repeat(${ game.settings.map[0].length }, 1fr)` }"> <div class="board" v-else :style="{ 'grid-template-rows': `repeat(${ game.map.length }, 1fr)`, 'grid-template-columns': `repeat(${ game.map[0].length }, 1fr)` }">
<div v-for="(x, i) in game.settings.map.join('')" <div v-for="(x, i) in game.map.join('')"
:data-none="x == ' '" :data-none="x == ' '"
@click="onPixelClick(i, x)"> @click="onPixelClick(i, x)">
<fa v-if="x == 'b'" :icon="fasCircle"/> <fa v-if="x == 'b'" :icon="fasCircle"/>
@ -35,9 +35,9 @@
</header> </header>
<div> <div>
<form-radio v-model="game.settings.bw" value="random" @change="updateSettings">{{ $t('random') }}</form-radio> <form-radio v-model="game.bw" value="random" @change="updateSettings('bw')">{{ $t('random') }}</form-radio>
<form-radio v-model="game.settings.bw" :value="1" @change="updateSettings">{{ this.$t('black-is').split('{}')[0] }}<b><mk-user-name :user="game.user1"/></b>{{ this.$t('black-is').split('{}')[1] }}</form-radio> <form-radio v-model="game.bw" :value="1" @change="updateSettings('bw')">{{ this.$t('black-is').split('{}')[0] }}<b><mk-user-name :user="game.user1"/></b>{{ this.$t('black-is').split('{}')[1] }}</form-radio>
<form-radio v-model="game.settings.bw" :value="2" @change="updateSettings">{{ this.$t('black-is').split('{}')[0] }}<b><mk-user-name :user="game.user2"/></b>{{ this.$t('black-is').split('{}')[1] }}</form-radio> <form-radio v-model="game.bw" :value="2" @change="updateSettings('bw')">{{ this.$t('black-is').split('{}')[0] }}<b><mk-user-name :user="game.user2"/></b>{{ this.$t('black-is').split('{}')[1] }}</form-radio>
</div> </div>
</div> </div>
@ -47,9 +47,9 @@
</header> </header>
<div> <div>
<ui-switch v-model="game.settings.isLlotheo" @change="updateSettings">{{ $t('is-llotheo') }}</ui-switch> <ui-switch v-model="game.isLlotheo" @change="updateSettings('isLlotheo')">{{ $t('is-llotheo') }}</ui-switch>
<ui-switch v-model="game.settings.loopedBoard" @change="updateSettings">{{ $t('looped-map') }}</ui-switch> <ui-switch v-model="game.loopedBoard" @change="updateSettings('loopedBoard')">{{ $t('looped-map') }}</ui-switch>
<ui-switch v-model="game.settings.canPutEverywhere" @change="updateSettings">{{ $t('can-put-everywhere') }}</ui-switch> <ui-switch v-model="game.canPutEverywhere" @change="updateSettings('canPutEverywhere')">{{ $t('can-put-everywhere') }}</ui-switch>
</div> </div>
</div> </div>
@ -159,8 +159,8 @@ export default Vue.extend({
this.connection.on('initForm', this.onInitForm); this.connection.on('initForm', this.onInitForm);
this.connection.on('message', this.onMessage); this.connection.on('message', this.onMessage);
if (this.game.user1Id != this.$store.state.i.id && this.game.settings.form1) this.form = this.game.settings.form1; if (this.game.user1Id != this.$store.state.i.id && this.game.form1) this.form = this.game.form1;
if (this.game.user2Id != this.$store.state.i.id && this.game.settings.form2) this.form = this.game.settings.form2; if (this.game.user2Id != this.$store.state.i.id && this.game.form2) this.form = this.game.form2;
}, },
beforeDestroy() { beforeDestroy() {
@ -189,18 +189,19 @@ export default Vue.extend({
this.$forceUpdate(); this.$forceUpdate();
}, },
updateSettings() { updateSettings(key: string) {
this.connection.send('updateSettings', { this.connection.send('updateSettings', {
settings: this.game.settings key: key,
value: this.game[key]
}); });
}, },
onUpdateSettings(settings) { onUpdateSettings({ key, value }) {
this.game.settings = settings; this.game[key] = value;
if (this.game.settings.map == null) { if (this.game.map == null) {
this.mapName = null; this.mapName = null;
} else { } else {
const found = Object.values(maps).find(x => x.data.join('') == this.game.settings.map.join('')); const found = Object.values(maps).find(x => x.data.join('') == this.game.map.join(''));
this.mapName = found ? found.name : '-Custom-'; this.mapName = found ? found.name : '-Custom-';
} }
}, },
@ -224,27 +225,27 @@ export default Vue.extend({
onMapChange() { onMapChange() {
if (this.mapName == null) { if (this.mapName == null) {
this.game.settings.map = null; this.game.map = null;
} else { } else {
this.game.settings.map = Object.values(maps).find(x => x.name == this.mapName).data; this.game.map = Object.values(maps).find(x => x.name == this.mapName).data;
} }
this.$forceUpdate(); this.$forceUpdate();
this.updateSettings(); this.updateSettings();
}, },
onPixelClick(pos, pixel) { onPixelClick(pos, pixel) {
const x = pos % this.game.settings.map[0].length; const x = pos % this.game.map[0].length;
const y = Math.floor(pos / this.game.settings.map[0].length); const y = Math.floor(pos / this.game.map[0].length);
const newPixel = const newPixel =
pixel == ' ' ? '-' : pixel == ' ' ? '-' :
pixel == '-' ? 'b' : pixel == '-' ? 'b' :
pixel == 'b' ? 'w' : pixel == 'b' ? 'w' :
' '; ' ';
const line = this.game.settings.map[y].split(''); const line = this.game.map[y].split('');
line[x] = newPixel; line[x] = newPixel;
this.$set(this.game.settings.map, y, line.join('')); this.$set(this.game.map, y, line.join(''));
this.$forceUpdate(); this.$forceUpdate();
this.updateSettings(); this.updateSettings('map');
} }
} }
}); });

View File

@ -106,7 +106,7 @@ export default Vue.extend({
async nav(game, actualNav = true) { async nav(game, actualNav = true) {
if (this.selfNav) { if (this.selfNav) {
// 受け取ったゲーム情報が省略されたものなら完全な情報を取得する // 受け取ったゲーム情報が省略されたものなら完全な情報を取得する
if (game != null && (game.settings == null || game.settings.map == null)) { if (game != null && game.map == null) {
game = await this.$root.api('games/reversi/games/show', { game = await this.$root.api('games/reversi/games/show', {
gameId: game.id gameId: game.id
}); });

View File

@ -2,7 +2,7 @@
<div class="nhasjydimbopojusarffqjyktglcuxjy" v-if="meta"> <div class="nhasjydimbopojusarffqjyktglcuxjy" v-if="meta">
<div class="banner" :style="{ backgroundImage: meta.bannerUrl ? `url(${meta.bannerUrl})` : null }"></div> <div class="banner" :style="{ backgroundImage: meta.bannerUrl ? `url(${meta.bannerUrl})` : null }"></div>
<h1>{{ meta.name }}</h1> <h1>{{ meta.name || 'Misskey' }}</h1>
<p v-html="meta.description || this.$t('@.about')"></p> <p v-html="meta.description || this.$t('@.about')"></p>
<router-link to="/">{{ $t('start') }}</router-link> <router-link to="/">{{ $t('start') }}</router-link>
</div> </div>

View File

@ -52,7 +52,7 @@ export default Vue.extend({
} }
return { return {
'background-color': this.image.properties.avgColor && this.image.properties.avgColor.length == 3 ? `rgb(${this.image.properties.avgColor.join(',')})` : 'transparent', 'background-color': this.image.properties.avgColor || 'transparent',
'background-image': url 'background-image': url
}; };
} }

View File

@ -33,10 +33,12 @@ export default Vue.extend({
}, },
computed: { computed: {
canonical(): string { canonical(): string {
return `@${this.username}@${toUnicode(this.host)}`; return this.host === localHost ? `@${this.username}` : `@${this.username}@${toUnicode(this.host)}`;
}, },
isMe(): boolean { isMe(): boolean {
return this.$store.getters.isSignedIn && this.canonical.toLowerCase() === `@${this.$store.state.i.username}@${toUnicode(localHost)}`.toLowerCase(); return this.$store.getters.isSignedIn && (
`@${this.username}@${toUnicode(this.host)}` === `@${this.$store.state.i.username}@${toUnicode(localHost)}`.toLowerCase()
);
} }
}, },
methods: { methods: {

View File

@ -85,7 +85,10 @@ export default Vue.extend({
} }
} else { } else {
if (items[0].kind == 'file') { if (items[0].kind == 'file') {
alert(this.$t('only-one-file-attached')); this.$root.dialog({
type: 'error',
text: this.$t('only-one-file-attached')
});
} }
} }
}, },
@ -107,7 +110,10 @@ export default Vue.extend({
return; return;
} else if (e.dataTransfer.files.length > 1) { } else if (e.dataTransfer.files.length > 1) {
e.preventDefault(); e.preventDefault();
alert(this.$t('only-one-file-attached')); this.$root.dialog({
type: 'error',
text: this.$t('only-one-file-attached')
});
return; return;
} }

View File

@ -11,7 +11,7 @@
<div class="file" v-if="message.file"> <div class="file" v-if="message.file">
<a :href="message.file.url" target="_blank" :title="message.file.name"> <a :href="message.file.url" target="_blank" :title="message.file.name">
<img v-if="message.file.type.split('/')[0] == 'image'" :src="message.file.url" :alt="message.file.name" <img v-if="message.file.type.split('/')[0] == 'image'" :src="message.file.url" :alt="message.file.name"
:style="{ backgroundColor: message.file.properties.avgColor && message.file.properties.avgColor.length == 3 ? `rgb(${message.file.properties.avgColor.join(',')})` : 'transparent' }"/> :style="{ backgroundColor: message.file.properties.avgColor || 'transparent' }"/>
<p v-else>{{ message.file.name }}</p> <p v-else>{{ message.file.name }}</p>
</a> </a>
</div> </div>

View File

@ -6,7 +6,7 @@
<div class="body"> <div class="body">
<p class="init" v-if="init"><fa icon="spinner .spin"/>{{ $t('@.loading') }}</p> <p class="init" v-if="init"><fa icon="spinner .spin"/>{{ $t('@.loading') }}</p>
<p class="empty" v-if="!init && messages.length == 0"><fa icon="info-circle"/>{{ $t('empty') }}</p> <p class="empty" v-if="!init && messages.length == 0"><fa icon="info-circle"/>{{ $t('empty') }}</p>
<p class="no-history" v-if="!init && messages.length > 0 && !existMoreMessages"><fa icon="flag"/>{{ $t('no-history') }}</p> <p class="no-history" v-if="!init && messages.length > 0 && !existMoreMessages"><fa :icon="faFlag"/>{{ $t('no-history') }}</p>
<button class="more" :class="{ fetching: fetchingMoreMessages }" v-if="existMoreMessages" @click="fetchMoreMessages" :disabled="fetchingMoreMessages"> <button class="more" :class="{ fetching: fetchingMoreMessages }" v-if="existMoreMessages" @click="fetchMoreMessages" :disabled="fetchingMoreMessages">
<template v-if="fetchingMoreMessages"><fa icon="spinner" pulse fixed-width/></template>{{ fetchingMoreMessages ? $t('@.loading') : $t('@.load-more') }} <template v-if="fetchingMoreMessages"><fa icon="spinner" pulse fixed-width/></template>{{ fetchingMoreMessages ? $t('@.loading') : $t('@.load-more') }}
</button> </button>
@ -35,6 +35,7 @@ import XMessage from './messaging-room.message.vue';
import XForm from './messaging-room.form.vue'; import XForm from './messaging-room.form.vue';
import { url } from '../../../config'; import { url } from '../../../config';
import { faArrowCircleDown } from '@fortawesome/free-solid-svg-icons'; import { faArrowCircleDown } from '@fortawesome/free-solid-svg-icons';
import { faFlag } from '@fortawesome/free-regular-svg-icons';
export default Vue.extend({ export default Vue.extend({
i18n: i18n('common/views/components/messaging-room.vue'), i18n: i18n('common/views/components/messaging-room.vue'),
@ -54,7 +55,7 @@ export default Vue.extend({
connection: null, connection: null,
showIndicator: false, showIndicator: false,
timer: null, timer: null,
faArrowCircleDown faArrowCircleDown, faFlag
}; };
}, },
@ -125,7 +126,10 @@ export default Vue.extend({
this.form.upload(e.dataTransfer.files[0]); this.form.upload(e.dataTransfer.files[0]);
return; return;
} else if (e.dataTransfer.files.length > 1) { } else if (e.dataTransfer.files.length > 1) {
alert(this.$t('only-one-file-attached')); this.$root.dialog({
type: 'error',
text: this.$t('only-one-file-attached')
});
return; return;
} }

View File

@ -1,7 +1,7 @@
<template> <template>
<div class="mk-poll" :data-done="closed || isVoted"> <div class="mk-poll" :data-done="closed || isVoted">
<ul> <ul>
<li v-for="choice in poll.choices" :key="choice.id" @click="vote(choice.id)" :class="{ voted: choice.voted }" :title="!closed && !isVoted ? $t('vote-to').replace('{}', choice.text) : ''"> <li v-for="(choice, i) in poll.choices" :key="i" @click="vote(i)" :class="{ voted: choice.voted }" :title="!closed && !isVoted ? $t('vote-to').replace('{}', choice.text) : ''">
<div class="backdrop" :style="{ 'width': `${showResult ? (choice.votes / total * 100) : 0}%` }"></div> <div class="backdrop" :style="{ 'width': `${showResult ? (choice.votes / total * 100) : 0}%` }"></div>
<span> <span>
<template v-if="choice.isVoted"><fa icon="check"/></template> <template v-if="choice.isVoted"><fa icon="check"/></template>
@ -82,12 +82,6 @@ export default Vue.extend({
noteId: this.note.id, noteId: this.note.id,
choice: id choice: id
}).then(() => { }).then(() => {
for (const c of this.poll.choices) {
if (c.id == id) {
c.votes++;
Vue.set(c, 'isVoted', true);
}
}
if (!this.showResult) this.showResult = !this.poll.multiple; if (!this.showResult) this.showResult = !this.poll.multiple;
}); });
} }

View File

@ -0,0 +1,139 @@
<template>
<div class="skeikyzd" v-show="files.length != 0">
<x-draggable class="files" :list="files" animation="150">
<div v-for="file in files" :key="file.id" @click="showFileMenu(file, $event)" @contextmenu.prevent="showFileMenu(file, $event)">
<x-file-thumbnail :data-id="file.id" class="thumbnail" :file="file" fit="cover"/>
<img class="remove" @click.stop="detachMedia(file.id)" src="/assets/desktop/remove.png" :title="$t('attach-cancel')" alt=""/>
<div class="sensitive" v-if="file.isSensitive">
<fa class="icon" :icon="faExclamationTriangle"/>
</div>
</div>
</x-draggable>
<p class="remain">{{ 4 - files.length }}/4</p>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import i18n from '../../../i18n';
import * as XDraggable from 'vuedraggable';
import XMenu from '../../../common/views/components/menu.vue';
import { faTimesCircle, faEye, faEyeSlash } from '@fortawesome/free-regular-svg-icons';
import { faExclamationTriangle } from '@fortawesome/free-solid-svg-icons';
import XFileThumbnail from './drive-file-thumbnail.vue'
export default Vue.extend({
i18n: i18n('common/views/components/post-form-attaches.vue'),
components: {
XDraggable,
XFileThumbnail
},
props: {
files: {
type: Array,
required: true
},
detachMediaFn: {
type: Object,
required: false
}
},
data() {
return {
faExclamationTriangle
};
},
methods: {
detachMedia(id) {
if (this.detachMediaFn) this.detachMediaFn(id)
else if (this.$parent.detachMedia) this.$parent.detachMedia(id)
},
toggleSensitive(file) {
this.$root.api('drive/files/update', {
fileId: file.id,
isSensitive: !file.isSensitive
}).then(() => {
file.isSensitive = !file.isSensitive;
});
},
showFileMenu(file, ev: MouseEvent) {
this.$root.new(XMenu, {
items: [{
type: 'item',
text: file.isSensitive ? this.$t('unmark-as-sensitive') : this.$t('mark-as-sensitive'),
icon: file.isSensitive ? faEyeSlash : faEye,
action: () => { this.toggleSensitive(file) }
}, {
type: 'item',
text: this.$t('attach-cancel'),
icon: faTimesCircle,
action: () => { this.detachMedia(file.id) }
}],
source: ev.currentTarget || ev.target
});
}
}
});
</script>
<style lang="stylus" scoped>
.skeikyzd
padding 4px
> .files
display flex
flex-wrap wrap
> div
width 64px
height 64px
margin 4px
cursor move
&:hover > .remove
display block
> .thumbnail
width 100%
height 100%
z-index 1
color var(--text)
> .remove
display none
position absolute
top -6px
right -6px
width 16px
height 16px
cursor pointer
z-index 1000
> .sensitive
display flex
position absolute
width 64px
height 64px
top 0
left 0
z-index 2
background rgba(17, 17, 17, .7)
color #fff
> .icon
margin auto
> .remain
display block
position absolute
top 8px
right 8px
margin 0
padding 0
color var(--primaryAlpha04)
</style>

View File

@ -20,7 +20,7 @@ export default Vue.extend({
}, },
computed: { computed: {
reactions(): any { reactions(): any {
return this.note.reactionCounts; return this.note.reactions;
}, },
isMe(): boolean { isMe(): boolean {
return this.$store.getters.isSignedIn && this.$store.state.i.id === this.note.userId; return this.$store.getters.isSignedIn && this.$store.state.i.id === this.note.userId;

View File

@ -14,7 +14,7 @@
<section> <section>
<header><fa icon="terminal"/> {{ $t('console.title') }}</header> <header><fa icon="terminal"/> {{ $t('console.title') }}</header>
<ui-input v-model="endpoint"> <ui-input v-model="endpoint" :datalist="endpoints">
<span>{{ $t('console.endpoint') }}</span> <span>{{ $t('console.endpoint') }}</span>
</ui-input> </ui-input>
<ui-textarea v-model="body"> <ui-textarea v-model="body">
@ -39,15 +39,23 @@ import * as JSON5 from 'json5';
export default Vue.extend({ export default Vue.extend({
i18n: i18n('common/views/components/api-settings.vue'), i18n: i18n('common/views/components/api-settings.vue'),
data() { data() {
return { return {
endpoint: '', endpoint: '',
body: '{}', body: '{}',
res: null, res: null,
sending: false sending: false,
endpoints: []
}; };
}, },
created() {
this.$root.api('endpoints').then(endpoints => {
this.endpoints = endpoints;
});
},
methods: { methods: {
regenerateToken() { regenerateToken() {
this.$root.dialog({ this.$root.dialog({

View File

@ -2,7 +2,7 @@
<ui-card> <ui-card>
<template #title><fa :icon="['far', 'bell']"/> {{ $t('title') }}</template> <template #title><fa :icon="['far', 'bell']"/> {{ $t('title') }}</template>
<section> <section>
<ui-switch v-model="$store.state.i.settings.autoWatch" @change="onChangeAutoWatch"> <ui-switch v-model="$store.state.i.autoWatch" @change="onChangeAutoWatch">
{{ $t('auto-watch') }}<template #desc>{{ $t('auto-watch-desc') }}</template> {{ $t('auto-watch') }}<template #desc>{{ $t('auto-watch-desc') }}</template>
</ui-switch> </ui-switch>
<section> <section>

View File

@ -84,7 +84,7 @@
<ui-info v-else warn>{{ $t('email-not-verified') }}</ui-info> <ui-info v-else warn>{{ $t('email-not-verified') }}</ui-info>
</template> </template>
<ui-input v-model="email" type="email"><span>{{ $t('email-address') }}</span></ui-input> <ui-input v-model="email" type="email"><span>{{ $t('email-address') }}</span></ui-input>
<ui-button @click="updateEmail()"><fa :icon="faSave"/> {{ $t('save') }}</ui-button> <ui-button @click="updateEmail()" :disabled="email === $store.state.i.email"><fa :icon="faSave"/> {{ $t('save') }}</ui-button>
</div> </div>
</section> </section>
@ -158,14 +158,14 @@ export default Vue.extend({
computed: { computed: {
alwaysMarkNsfw: { alwaysMarkNsfw: {
get() { return this.$store.state.i.settings.alwaysMarkNsfw; }, get() { return this.$store.state.i.alwaysMarkNsfw; },
set(value) { this.$root.api('i/update', { alwaysMarkNsfw: value }); } set(value) { this.$root.api('i/update', { alwaysMarkNsfw: value }); }
}, },
bannerStyle(): any { bannerStyle(): any {
if (this.$store.state.i.bannerUrl == null) return {}; if (this.$store.state.i.bannerUrl == null) return {};
return { return {
backgroundColor: this.$store.state.i.bannerColor && this.$store.state.i.bannerColor.length == 3 ? `rgb(${ this.$store.state.i.bannerColor.join(',') })` : null, backgroundColor: this.$store.state.i.bannerColor,
backgroundImage: `url(${ this.$store.state.i.bannerUrl })` backgroundImage: `url(${ this.$store.state.i.bannerUrl })`
}; };
}, },
@ -178,10 +178,10 @@ export default Vue.extend({
this.email = this.$store.state.i.email; this.email = this.$store.state.i.email;
this.name = this.$store.state.i.name; this.name = this.$store.state.i.name;
this.username = this.$store.state.i.username; this.username = this.$store.state.i.username;
this.location = this.$store.state.i.profile.location; this.location = this.$store.state.i.location;
this.description = this.$store.state.i.description; this.description = this.$store.state.i.description;
this.lang = this.$store.state.i.lang; this.lang = this.$store.state.i.lang;
this.birthday = this.$store.state.i.profile.birthday; this.birthday = this.$store.state.i.birthday;
this.avatarId = this.$store.state.i.avatarId; this.avatarId = this.$store.state.i.avatarId;
this.bannerId = this.$store.state.i.bannerId; this.bannerId = this.$store.state.i.bannerId;
this.isCat = this.$store.state.i.isCat; this.isCat = this.$store.state.i.isCat;

View File

@ -525,15 +525,11 @@ export default Vue.extend({
this.$chooseDriveFile({ this.$chooseDriveFile({
multiple: false multiple: false
}).then(file => { }).then(file => {
this.$root.api('i/update', { this.$store.dispatch('settings/set', { key: 'wallpaper', value: file.url });
wallpaperId: file.id
});
}); });
}, },
deleteWallpaper() { deleteWallpaper() {
this.$root.api('i/update', { this.$store.dispatch('settings/set', { key: 'wallpaper', value: null });
wallpaperId: null
});
}, },
checkForUpdate() { checkForUpdate() {
this.checkingForUpdate = true; this.checkingForUpdate = true;
@ -542,8 +538,8 @@ export default Vue.extend({
this.latestVersion = newer; this.latestVersion = newer;
if (newer == null) { if (newer == null) {
this.$root.dialog({ this.$root.dialog({
title: this.$t('no-updates'), title: this.$t('@._settings.no-updates'),
text: this.$t('no-updates-desc') text: this.$t('@._settings.no-updates-desc')
}); });
} else { } else {
this.$root.dialog({ this.$root.dialog({

View File

@ -130,20 +130,6 @@ import * as tinycolor from 'tinycolor2';
import * as JSON5 from 'json5'; import * as JSON5 from 'json5';
import { faMoon, faSun } from '@fortawesome/free-regular-svg-icons'; import { faMoon, faSun } from '@fortawesome/free-regular-svg-icons';
// 後方互換性のため
function convertOldThemedefinition(t) {
const t2 = {
id: t.meta.id,
name: t.meta.name,
author: t.meta.author,
base: t.meta.base,
vars: t.meta.vars,
props: t
};
delete t2.props.meta;
return t2;
}
export default Vue.extend({ export default Vue.extend({
i18n: i18n('common/views/components/theme.vue'), i18n: i18n('common/views/components/theme.vue'),
components: { components: {
@ -231,20 +217,6 @@ export default Vue.extend({
} }
}, },
beforeCreate() {
// migrate old theme definitions
// 後方互換性のため
this.$store.commit('device/set', {
key: 'themes', value: this.$store.state.device.themes.map(t => {
if (t.id == null) {
return convertOldThemedefinition(t);
} else {
return t;
}
})
});
},
methods: { methods: {
install(code) { install(code) {
let theme; let theme;
@ -259,11 +231,6 @@ export default Vue.extend({
return; return;
} }
// 後方互換性のため
if (theme.id == null && theme.meta != null) {
theme = convertOldThemedefinition(theme);
}
if (theme.id == null) { if (theme.id == null) {
this.$root.dialog({ this.$root.dialog({
type: 'error', type: 'error',

View File

@ -79,7 +79,10 @@ export default Vue.extend({
localStorage.setItem('i', res.i); localStorage.setItem('i', res.i);
location.reload(); location.reload();
}).catch(() => { }).catch(() => {
alert(this.$t('login-failed')); this.$root.dialog({
type: 'error',
text: this.$t('login-failed')
});
this.signing = false; this.signing = false;
}); });
} }

View File

@ -4,7 +4,7 @@
<ui-input v-if="meta.disableRegistration" v-model="invitationCode" type="text" :autocomplete="Math.random()" spellcheck="false" required styl="fill"> <ui-input v-if="meta.disableRegistration" v-model="invitationCode" type="text" :autocomplete="Math.random()" spellcheck="false" required styl="fill">
<span>{{ $t('invitation-code') }}</span> <span>{{ $t('invitation-code') }}</span>
<template #prefix><fa icon="id-card-alt"/></template> <template #prefix><fa icon="id-card-alt"/></template>
<template #desc v-html="this.$t('invitation-info').replace('{}', 'mailto:' + meta.maintainer.email)"></template> <template #desc v-html="this.$t('invitation-info').replace('{}', 'mailto:' + meta.maintainerEmail)"></template>
</ui-input> </ui-input>
<ui-input v-model="username" type="text" pattern="^[a-zA-Z0-9_]{1,20}$" :autocomplete="Math.random()" spellcheck="false" required @input="onChangeUsername" styl="fill"> <ui-input v-model="username" type="text" pattern="^[a-zA-Z0-9_]{1,20}$" :autocomplete="Math.random()" spellcheck="false" required @input="onChangeUsername" styl="fill">
<span>{{ $t('username') }}</span> <span>{{ $t('username') }}</span>
@ -153,7 +153,10 @@ export default Vue.extend({
location.href = '/'; location.href = '/';
}); });
}).catch(() => { }).catch(() => {
alert(this.$t('some-error')); this.$root.dialog({
type: 'error',
text: this.$t('some-error')
});
if (this.meta.enableRecaptcha) { if (this.meta.enableRecaptcha) {
(window as any).grecaptcha.reset(); (window as any).grecaptcha.reset();

View File

@ -23,6 +23,7 @@
@focus="focused = true" @focus="focused = true"
@blur="focused = false" @blur="focused = false"
@keydown="$emit('keydown', $event)" @keydown="$emit('keydown', $event)"
:list="id"
> >
<input v-else ref="input" <input v-else ref="input"
:type="type" :type="type"
@ -37,7 +38,11 @@
@focus="focused = true" @focus="focused = true"
@blur="focused = false" @blur="focused = false"
@keydown="$emit('keydown', $event)" @keydown="$emit('keydown', $event)"
:list="id"
> >
<datalist :id="id" v-if="datalist">
<option v-for="data in datalist" :value="data"/>
</datalist>
</template> </template>
<template v-else> <template v-else>
<input ref="input" <input ref="input"
@ -130,6 +135,10 @@ export default Vue.extend({
required: false, required: false,
default: false default: false
}, },
datalist: {
type: Array,
required: false,
},
inline: { inline: {
type: Boolean, type: Boolean,
required: false, required: false,
@ -147,7 +156,8 @@ export default Vue.extend({
return { return {
v: this.value, v: this.value,
focused: false, focused: false,
passwordStrength: '' passwordStrength: '',
id: Math.random().toString()
}; };
}, },
computed: { computed: {

View File

@ -1,7 +1,7 @@
<template> <template>
<div class="cudqjmnl"> <div class="cudqjmnl">
<ui-card> <ui-card>
<template #title><fa :icon="faList"/> {{ list.title }}</template> <template #title><fa :icon="faList"/> {{ list.name }}</template>
<section> <section>
<ui-button @click="rename"><fa :icon="faICursor"/> {{ $t('rename') }}</ui-button> <ui-button @click="rename"><fa :icon="faICursor"/> {{ $t('rename') }}</ui-button>
@ -75,7 +75,7 @@ export default Vue.extend({
this.$root.dialog({ this.$root.dialog({
title: this.$t('rename'), title: this.$t('rename'),
input: { input: {
default: this.list.title default: this.list.name
} }
}).then(({ canceled, result: title }) => { }).then(({ canceled, result: title }) => {
if (canceled) return; if (canceled) return;
@ -89,7 +89,7 @@ export default Vue.extend({
del() { del() {
this.$root.dialog({ this.$root.dialog({
type: 'warning', type: 'warning',
text: this.$t('delete-are-you-sure').replace('$1', this.list.title), text: this.$t('delete-are-you-sure').replace('$1', this.list.name),
showCancelButton: true showCancelButton: true
}).then(({ canceled }) => { }).then(({ canceled }) => {
if (canceled) return; if (canceled) return;

View File

@ -8,7 +8,7 @@
<div class="no-users" v-if="inited && us.length == 0"> <div class="no-users" v-if="inited && us.length == 0">
<p>{{ $t('no-users') }}</p> <p>{{ $t('no-users') }}</p>
</div> </div>
<div class="user" v-for="user in us"> <div class="user" v-for="user in us" :key="user.id">
<mk-avatar class="avatar" :user="user"/> <mk-avatar class="avatar" :user="user"/>
<div class="body" v-if="!iconOnly"> <div class="body" v-if="!iconOnly">
<div class="name"> <div class="name">
@ -18,6 +18,7 @@
<div class="description" v-if="user.description" :title="user.description"> <div class="description" v-if="user.description" :title="user.description">
<mfm :text="user.description" :is-note="false" :author="user" :i="$store.state.i" :custom-emojis="user.emojis" :should-break="false" :plain-text="true"/> <mfm :text="user.description" :is-note="false" :author="user" :i="$store.state.i" :custom-emojis="user.emojis" :should-break="false" :plain-text="true"/>
</div> </div>
<mk-follow-button class="follow-button" v-if="$store.getters.isSignedIn && user.id != $store.state.i.id" :user="user" mini/>
</div> </div>
</div> </div>
<button class="more" :class="{ fetching: fetchingMoreUsers }" v-if="cursor != null" @click="fetchMoreUsers()" :disabled="fetchingMoreUsers"> <button class="more" :class="{ fetching: fetchingMoreUsers }" v-if="cursor != null" @click="fetchMoreUsers()" :disabled="fetchingMoreUsers">
@ -50,7 +51,7 @@ export default Vue.extend({
fetchingMoreUsers: false, fetchingMoreUsers: false,
us: [], us: [],
inited: false, inited: false,
cursor: null more: false
}; };
}, },
@ -160,6 +161,12 @@ export default Vue.extend({
text-overflow ellipsis text-overflow ellipsis
opacity 0.7 opacity 0.7
font-size 14px font-size 14px
padding-right 40px
> .follow-button
position absolute
top 8px
right 0px
> .more > .more
display block display block

View File

@ -0,0 +1,95 @@
<template>
<div class="xkxvokkjlptzyewouewmceqcxhpgzprp">
<button class="ui" @click="add">{{ $t('create-list') }}</button>
<a v-for="list in lists" :key="list.id" @click="choice(list)">{{ list.name }}</a>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import i18n from '../../../i18n';
export default Vue.extend({
i18n: i18n('common/views/components/user-lists.vue'),
data() {
return {
fetching: true,
lists: []
};
},
mounted() {
this.$root.api('users/lists/list').then(lists => {
this.fetching = false;
this.lists = lists;
});
},
methods: {
add() {
this.$root.dialog({
title: this.$t('list-name'),
input: true
}).then(async ({ canceled, result: title }) => {
if (canceled) return;
const list = await this.$root.api('users/lists/create', {
title
});
this.lists.push(list)
this.$emit('choosen', list);
});
},
choice(list) {
this.$emit('choosen', list);
}
}
});
</script>
<style lang="stylus" scoped>
.xkxvokkjlptzyewouewmceqcxhpgzprp
padding 16px
background: var(--bg)
> button
display block
margin-bottom 16px
color var(--primaryForeground)
background var(--primary)
width 100%
border-radius 38px
user-select none
cursor pointer
padding 0 16px
min-width 100px
line-height 38px
font-size 14px
font-weight 700
&:hover
background var(--primaryLighten10)
&:active
background var(--primaryDarken10)
a
display block
margin 8px 0
padding 8px
color var(--text)
background var(--face)
box-shadow 0 2px 16px var(--reversiListItemShadow)
border-radius 6px
cursor pointer
line-height 32px
*
pointer-events none
user-select none
&:hover
box-shadow 0 0 0 100px inset rgba(0, 0, 0, 0.05)
&:active
box-shadow 0 0 0 100px inset rgba(0, 0, 0, 0.1)
</style>

View File

@ -73,7 +73,7 @@ export default Vue.extend({
title: t, title: t,
select: { select: {
items: lists.map(list => ({ items: lists.map(list => ({
value: list.id, text: list.title value: list.id, text: list.name
})) }))
}, },
showCancelButton: true showCancelButton: true
@ -89,8 +89,10 @@ export default Vue.extend({
}); });
}, },
toggleMute() { async toggleMute() {
if (this.user.isMuted) { if (this.user.isMuted) {
if (!await this.getConfirmed(this.$t('unmute-confirm'))) return;
this.$root.api('mute/delete', { this.$root.api('mute/delete', {
userId: this.user.id userId: this.user.id
}).then(() => { }).then(() => {
@ -102,6 +104,8 @@ export default Vue.extend({
}); });
}); });
} else { } else {
if (!await this.getConfirmed(this.$t('mute-confirm'))) return;
this.$root.api('mute/create', { this.$root.api('mute/create', {
userId: this.user.id userId: this.user.id
}).then(() => { }).then(() => {
@ -115,8 +119,10 @@ export default Vue.extend({
} }
}, },
toggleBlock() { async toggleBlock() {
if (this.user.isBlocking) { if (this.user.isBlocking) {
if (!await this.getConfirmed(this.$t('unblock-confirm'))) return;
this.$root.api('blocking/delete', { this.$root.api('blocking/delete', {
userId: this.user.id userId: this.user.id
}).then(() => { }).then(() => {
@ -128,6 +134,8 @@ export default Vue.extend({
}); });
}); });
} else { } else {
if (!await this.getConfirmed(this.$t('block-confirm'))) return;
this.$root.api('blocking/create', { this.$root.api('blocking/create', {
userId: this.user.id userId: this.user.id
}).then(() => { }).then(() => {
@ -164,7 +172,9 @@ export default Vue.extend({
}); });
}, },
toggleSilence() { async toggleSilence() {
if (!await this.getConfirmed(this.$t(this.user.isSilenced ? 'unsilence-confirm' : 'silence-confirm'))) return;
this.$root.api(this.user.isSilenced ? 'admin/unsilence-user' : 'admin/silence-user', { this.$root.api(this.user.isSilenced ? 'admin/unsilence-user' : 'admin/silence-user', {
userId: this.user.id userId: this.user.id
}).then(() => { }).then(() => {
@ -181,7 +191,9 @@ export default Vue.extend({
}); });
}, },
toggleSuspend() { async toggleSuspend() {
if (!await this.getConfirmed(this.$t(this.user.isSuspended ? 'unsuspend-confirm' : 'suspend-confirm'))) return;
this.$root.api(this.user.isSuspended ? 'admin/unsuspend-user' : 'admin/suspend-user', { this.$root.api(this.user.isSuspended ? 'admin/unsuspend-user' : 'admin/suspend-user', {
userId: this.user.id userId: this.user.id
}).then(() => { }).then(() => {
@ -196,7 +208,18 @@ export default Vue.extend({
text: e text: e
}); });
}); });
} },
async getConfirmed(text: string): Promise<Boolean> {
const confirm = await this.$root.dialog({
type: 'warning',
showCancelButton: true,
title: 'confirm',
text,
});
return !confirm.canceled;
},
} }
}); });
</script> </script>

View File

@ -28,12 +28,12 @@ export default Vue.extend({
notes.pop(); notes.pop();
return { return {
notes: notes, notes: notes,
cursor: notes[notes.length - 1].id more: true
}; };
} else { } else {
return { return {
notes: notes, notes: notes,
cursor: null more: false
}; };
} }
}) })

View File

@ -37,12 +37,12 @@ export default Vue.extend({
notes.pop(); notes.pop();
return { return {
notes: notes, notes: notes,
cursor: notes[notes.length - 1].id more: true
}; };
} else { } else {
return { return {
notes: notes, notes: notes,
cursor: null more: false
}; };
} }
}) })

View File

@ -28,7 +28,7 @@ export default Vue.extend({
data() { data() {
return { return {
connection: null, connection: null,
makePromise: cursor => this.$root.api('notes/search_by_tag', { makePromise: cursor => this.$root.api('notes/search-by-tag', {
limit: fetchLimit + 1, limit: fetchLimit + 1,
untilId: cursor ? cursor : undefined, untilId: cursor ? cursor : undefined,
withFiles: this.mediaOnly, withFiles: this.mediaOnly,
@ -41,12 +41,12 @@ export default Vue.extend({
notes.pop(); notes.pop();
return { return {
notes: notes, notes: notes,
cursor: notes[notes.length - 1].id more: true
}; };
} else { } else {
return { return {
notes: notes, notes: notes,
cursor: null more: false
}; };
} }
}) })

View File

@ -41,12 +41,12 @@ export default Vue.extend({
notes.pop(); notes.pop();
return { return {
notes: notes, notes: notes,
cursor: notes[notes.length - 1].id more: true
}; };
} else { } else {
return { return {
notes: notes, notes: notes,
cursor: null more: false
}; };
} }
}) })

View File

@ -27,12 +27,12 @@ export default Vue.extend({
notes.pop(); notes.pop();
return { return {
notes: notes, notes: notes,
cursor: notes[notes.length - 1].id more: true
}; };
} else { } else {
return { return {
notes: notes, notes: notes,
cursor: null more: false
}; };
} }
}) })

View File

@ -26,8 +26,8 @@
</template> </template>
</component> </component>
<footer v-if="cursor != null"> <footer v-if="more">
<button @click="more" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }"> <button @click="fetchMore()" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }">
<template v-if="!moreFetching">{{ $t('@.load-more') }}</template> <template v-if="!moreFetching">{{ $t('@.load-more') }}</template>
<template v-if="moreFetching"><fa icon="spinner" pulse fixed-width/></template> <template v-if="moreFetching"><fa icon="spinner" pulse fixed-width/></template>
</button> </button>
@ -61,7 +61,7 @@ export default Vue.extend({
fetching: true, fetching: true,
moreFetching: false, moreFetching: false,
inited: false, inited: false,
cursor: null more: false
}; };
}, },
@ -119,7 +119,7 @@ export default Vue.extend({
this.notes = x; this.notes = x;
} else { } else {
this.notes = x.notes; this.notes = x.notes;
this.cursor = x.cursor; this.more = x.more;
} }
this.inited = true; this.inited = true;
this.fetching = false; this.fetching = false;
@ -129,12 +129,12 @@ export default Vue.extend({
}); });
}, },
more() { fetchMore() {
if (this.cursor == null || this.moreFetching) return; if (!this.more || this.moreFetching) return;
this.moreFetching = true; this.moreFetching = true;
this.makePromise(this.cursor).then(x => { this.makePromise(this.notes[this.notes.length - 1].id).then(x => {
this.notes = this.notes.concat(x.notes); this.notes = this.notes.concat(x.notes);
this.cursor = x.cursor; this.more = x.more;
this.moreFetching = false; this.moreFetching = false;
}, e => { }, e => {
this.moreFetching = false; this.moreFetching = false;
@ -157,6 +157,7 @@ export default Vue.extend({
// オーバーフローしたら古い投稿は捨てる // オーバーフローしたら古い投稿は捨てる
if (this.notes.length >= displayLimit) { if (this.notes.length >= displayLimit) {
this.notes = this.notes.slice(0, displayLimit); this.notes = this.notes.slice(0, displayLimit);
this.more = true;
} }
} else { } else {
this.queue.push(note); this.queue.push(note);
@ -165,6 +166,7 @@ export default Vue.extend({
append(note) { append(note) {
this.notes.push(note); this.notes.push(note);
this.cursor = this.notes[this.notes.length - 1].id
}, },
releaseQueue() { releaseQueue() {
@ -179,7 +181,7 @@ export default Vue.extend({
}, },
onBottom() { onBottom() {
this.more(); this.fetchMore();
} }
} }
}); });

View File

@ -62,7 +62,7 @@
</div> </div>
</div> </div>
<div class="notification poll_vote" v-if="notification.type == 'poll_vote'"> <div class="notification pollVote" v-if="notification.type == 'pollVote'">
<mk-avatar class="avatar" :user="notification.user"/> <mk-avatar class="avatar" :user="notification.user"/>
<div> <div>
<header> <header>

View File

@ -39,7 +39,7 @@ export default Vue.extend({
} else { } else {
return { return {
notes: notes, notes: notes,
cursor: null more: false
}; };
} }
}) })

View File

@ -82,7 +82,7 @@ export default Vue.extend({
case 'local': return this.$t('@deck.local'); case 'local': return this.$t('@deck.local');
case 'hybrid': return this.$t('@deck.hybrid'); case 'hybrid': return this.$t('@deck.hybrid');
case 'global': return this.$t('@deck.global'); case 'global': return this.$t('@deck.global');
case 'list': return this.column.list.title; case 'list': return this.column.list.name;
case 'hashtag': return this.$store.state.settings.tagTimelines.find(x => x.id == this.column.tagTlId).title; case 'hashtag': return this.$store.state.settings.tagTimelines.find(x => x.id == this.column.tagTlId).title;
} }
} }

View File

@ -85,12 +85,12 @@ export default Vue.extend({
notes.pop(); notes.pop();
return { return {
notes: notes, notes: notes,
cursor: notes[notes.length - 1].id more: true
}; };
} else { } else {
return { return {
notes: notes, notes: notes,
cursor: null more: false
}; };
} }
}); });

View File

@ -85,7 +85,7 @@ export default Vue.extend({
this.makePromise = cursor => this.$root.api('users/notes', { this.makePromise = cursor => this.$root.api('users/notes', {
userId: this.user.id, userId: this.user.id,
limit: fetchLimit + 1, limit: fetchLimit + 1,
untilId: cursor ? cursor : undefined, untilDate: cursor ? cursor : new Date().getTime() + 1000 * 86400 * 365,
withFiles: this.withFiles, withFiles: this.withFiles,
includeMyRenotes: this.$store.state.settings.showMyRenotes, includeMyRenotes: this.$store.state.settings.showMyRenotes,
includeRenotedMyNotes: this.$store.state.settings.showRenotedMyNotes, includeRenotedMyNotes: this.$store.state.settings.showRenotedMyNotes,
@ -95,12 +95,12 @@ export default Vue.extend({
notes.pop(); notes.pop();
return { return {
notes: notes, notes: notes,
cursor: notes[notes.length - 1].id more: true
}; };
} else { } else {
return { return {
notes: notes, notes: notes,
cursor: null more: false
}; };
} }
}); });
@ -118,7 +118,6 @@ export default Vue.extend({
fileType: image, fileType: image,
excludeNsfw: !this.$store.state.device.alwaysShowNsfw, excludeNsfw: !this.$store.state.device.alwaysShowNsfw,
limit: 9, limit: 9,
untilDate: new Date().getTime() + 1000 * 86400 * 365
}).then(notes => { }).then(notes => {
for (const note of notes) { for (const note of notes) {
for (const file of note.files) { for (const file of note.files) {

View File

@ -8,7 +8,7 @@
<div class="is-remote" v-if="user.host != null"> <div class="is-remote" v-if="user.host != null">
<details> <details>
<summary><fa icon="exclamation-triangle"/> {{ $t('@.is-remote-user') }}</summary> <summary><fa icon="exclamation-triangle"/> {{ $t('@.is-remote-user') }}</summary>
<a :href="user.url || user.uri" target="_blank">{{ $t('@.view-on-remote') }}</a> <a :href="user.url" target="_blank">{{ $t('@.view-on-remote') }}</a>
</details> </details>
</div> </div>
<header :style="bannerStyle"> <header :style="bannerStyle">
@ -88,7 +88,7 @@ export default Vue.extend({
if (this.user == null) return {}; if (this.user == null) return {};
if (this.user.bannerUrl == null) return {}; if (this.user.bannerUrl == null) return {};
return { return {
backgroundColor: this.user.bannerColor && this.user.bannerColor.length == 3 ? `rgb(${ this.user.bannerColor.join(',') })` : null, backgroundColor: this.user.bannerColor,
backgroundImage: `url(${ this.user.bannerUrl })` backgroundImage: `url(${ this.user.bannerUrl })`
}; };
}, },

View File

@ -106,16 +106,6 @@ export default Vue.extend({
value: deck value: deck
}); });
} }
// 互換性のため
if (this.$store.state.device.deck != null && this.$store.state.device.deck.layout == null) {
this.$store.commit('device/set', {
key: 'deck',
value: Object.assign({}, this.$store.state.device.deck, {
layout: this.$store.state.device.deck.columns.map(c => [c.id])
})
});
}
}, },
mounted() { mounted() {
@ -199,7 +189,7 @@ export default Vue.extend({
title: this.$t('@deck.select-list'), title: this.$t('@deck.select-list'),
select: { select: {
items: lists.map(list => ({ items: lists.map(list => ({
value: list.id, text: list.title value: list.id, text: list.name
})) }))
}, },
showCancelButton: true showCancelButton: true

View File

@ -21,7 +21,7 @@
<option value="users">{{ $t('@.widgets.users') }}</option> <option value="users">{{ $t('@.widgets.users') }}</option>
<option value="polls">{{ $t('@.widgets.polls') }}</option> <option value="polls">{{ $t('@.widgets.polls') }}</option>
<option value="post-form">{{ $t('@.widgets.post-form') }}</option> <option value="post-form">{{ $t('@.widgets.post-form') }}</option>
<option value="messaging">{{ $t('@.widgets.messaging') }}</option> <option value="messaging">{{ $t('@.messaging') }}</option>
<option value="memo">{{ $t('@.widgets.memo') }}</option> <option value="memo">{{ $t('@.widgets.memo') }}</option>
<option value="hashtags">{{ $t('@.widgets.hashtags') }}</option> <option value="hashtags">{{ $t('@.widgets.hashtags') }}</option>
<option value="posts-monitor">{{ $t('@.widgets.posts-monitor') }}</option> <option value="posts-monitor">{{ $t('@.widgets.posts-monitor') }}</option>
@ -33,7 +33,7 @@
</header> </header>
<x-draggable <x-draggable
:list="column.widgets" :list="column.widgets"
:options="{ animation: 150 }" animation="150"
@sort="onWidgetSort" @sort="onWidgetSort"
> >
<div v-for="widget in column.widgets" class="customize-container" :key="widget.id" @contextmenu.stop.prevent="widgetFunc(widget.id)"> <div v-for="widget in column.widgets" class="customize-container" :key="widget.id" @contextmenu.stop.prevent="widgetFunc(widget.id)">

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