Compare commits

...

235 Commits

Author SHA1 Message Date
0500600cdd Merge branch 'develop' 2019-06-25 01:27:51 +09:00
6b897e562a 11.23.1 2019-06-25 01:27:33 +09:00
f74bc309b1 Fix bug 2019-06-25 01:24:01 +09:00
bc83963ac7 English nyaize 2019-06-24 22:20:13 +09:00
94715e6153 Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2019-06-23 16:12:37 +09:00
31a5247b9c 🎨 2019-06-23 16:12:11 +09:00
ac9f77752d New translations ja-JP.yml (Chinese Simplified) (#5081) 2019-06-23 01:53:21 +09:00
73ac2632c2 Merge branch 'develop' 2019-06-23 00:22:33 +09:00
20f11a6701 11.23.0 2019-06-23 00:21:58 +09:00
9bdc67c1f6 New Crowdin translations (#5065)
* New translations ja-JP.yml (Chinese Simplified)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Korean)

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

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Korean)

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

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Russian)

* New translations ja-JP.yml (Russian)

* New translations ja-JP.yml (Russian)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Korean)

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

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

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Czech)

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

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Dutch)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Norwegian)

* New translations ja-JP.yml (Spanish)

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

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

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

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

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Korean)

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

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Korean)

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

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Czech)

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

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

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

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (French)

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

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Norwegian)

* New translations ja-JP.yml (Spanish)

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

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (French)

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

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Norwegian)

* New translations ja-JP.yml (Spanish)

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

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (French)

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

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (Dutch)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Norwegian)

* New translations ja-JP.yml (Portuguese)

* New translations ja-JP.yml (Spanish)

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

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

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

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

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

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

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Polish)

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

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (English)

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

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

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

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

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

* New translations ja-JP.yml (Korean)

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

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (English)

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

* Update CONTRIBUTING.md

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

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (French)

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

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Spanish)

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

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Korean)

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

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (French)

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

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

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (Dutch)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Norwegian)

* New translations ja-JP.yml (Portuguese)

* New translations ja-JP.yml (Russian)

* New translations ja-JP.yml (Spanish)

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

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (French)

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

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (Dutch)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Norwegian)

* New translations ja-JP.yml (Spanish)

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

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

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

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

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

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (French)

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

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (Dutch)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Norwegian)

* New translations ja-JP.yml (Spanish)

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

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (French)

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

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Norwegian)

* New translations ja-JP.yml (Portuguese)

* New translations ja-JP.yml (Spanish)

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

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Danish)

* New translations ja-JP.yml (Korean)

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

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

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (French)

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

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Spanish)

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

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (French)

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

* New translations ja-JP.yml (Czech)

* New translations ja-JP.yml (Korean)

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

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

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

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

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

* New translations ja-JP.yml (Chinese Simplified)
2019-05-16 13:11:56 +09:00
62cbb92154 Fix #4930 2019-05-16 12:59:09 +09:00
155da0c6a3 Avoid roma-ji naming 2019-04-10 20:30:00 +09:00
303 changed files with 9406 additions and 5045 deletions

View File

@ -62,6 +62,13 @@ db:
user: example-misskey-user user: example-misskey-user
pass: example-misskey-pass pass: example-misskey-pass
# Whether disable Caching queries
#disableCache: true
# Extra Connection options
#extra:
# ssl: true
# ┌─────────────────────┐ # ┌─────────────────────┐
#───┘ Redis configuration └───────────────────────────────────── #───┘ Redis configuration └─────────────────────────────────────

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

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

19
.gitignore vendored
View File

@ -1,11 +1,23 @@
# Visual Studio Code
/.vscode
# Intelij-IDEA
/.idea
# Node.js
/node_modules
# yarn
yarn.lock
# config
/.config/* /.config/*
!/.config/example.yml !/.config/example.yml
!/.config/mongo_initdb_example.js !/.config/mongo_initdb_example.js
/.vscode
/node_modules # misskey
/build /build
/built /built
built
/data /data
/.cache-loader /.cache-loader
/db /db
@ -17,7 +29,6 @@ api-docs.json
*.log *.log
/redis /redis
*.code-workspace *.code-workspace
yarn.lock
.DS_Store .DS_Store
/files /files
ormconfig.json ormconfig.json

View File

@ -17,42 +17,187 @@ npm i -g ts-node
npm run migrate npm run migrate
``` ```
How to migrate to v11 from v10 11.23.1 (2019/06/25)
------------------------------ --------------------
### 移行の注意点 ### 🐛Fixes
**以下のデータは引き継がれません** * クライアントの設定がリセットされることがある問題を修正
* 通知
* リモートの投稿
* リバーシの対局
### 手順 11.23.0 (2019/06/23)
1. v11をインストールしたい場所に syuilo/misskey をクローン --------------------
2. config を設定する ### ✨Improvements
* PostgreSQL(`db`)の設定とは別に、v10からMongoDBの設定をコピペしてくる(例は下にあります) * ホーム/デッキのカスタマイズ情報を複数のデバイスで同期できるように
* `id`の設定を`meid`または`objectid`にする * ホーム/デッキのカスタマイズ情報の複数プリセット切り替え
* サーバー情報にRedisのバージョンを追加
* ServiceWorker有効化
* MisskeyPagesでリストの要素数を取得する関数を追加
* URLプレビューでハッシュだけ違うプレビューカードは表示しないように
* URLプレビューをユーザーロケールで出し分けるように
* リモートの凍結されたアカウントからのアクティビティはすべて無視するように
``` yml ### 🐛Fixes
db: * フォロー解除してもフォローボタンがフォロー中のままになる問題を修正
host: localhost
port: 5432
db: misskey
user: x
pass: x
mongodb: 11.22.0 (2019/06/18)
user: x --------------------
pass: x ### ✨Improvements
host: localhost * 管理画面でデータベースの各テーブルのレコード数やサイズを確認できるように
port: 27017 * サーバー情報にPostgreSQLのバージョンを追加
db: misskey
``` ### 🐛Fixes
3. migration ブランチに切り替え * リモートファイルのダウンロードに失敗することがある問題を修正
4. `npm i` * アンケートの期間を日時指定で選択すると日時がUTCになってしまう問題を修正
5. `npm run build` * MFMのパースを修正
6. `npm run init`
7. `npm run migrate` 11.21.0 (2019/06/16)
8. master ブランチに戻す --------------------
9. enjoy ### ✨Improvements
* Unicode 12.0 の絵文字に対応
* 閉鎖しているホストにはAP deliverしないように
* image以外はproxyしないように
### 🐛Fixes
* サムネイル生成でエラーになるとファイルのアップロードに失敗する問題を修正
* オートコンプリートにアニメーション停止が効かない問題を修正
11.20.4 (2019/06/13)
--------------------
### 🐛Fixes
* 検索結果がループする問題を修正
* 設定でPostgreSQLのクエリー結果のキャッシュを無効できるように
* 「投稿内の動きのあるテキストを無効にする」だけ反応しない問題を修正
* 特定の操作のデータベースのパフォーマンス調整
11.20.3 (2019/06/10)
--------------------
### 🐛Fixes
* 絵文字サジェストが動作しなくなっていた問題を修正
11.20.2 (2019/06/10)
--------------------
### 🐛Fixes
* Redisにパスワードを設定している場合接続できない問題を修正
* i18n
* など
11.20.1 (2019/06/07)
--------------------
### 🐛Fixes
* リモートファイルのキャッシュをすべて削除するときの動作を修正
* ストリームのハッシュタグチャンネルが死んでいる問題を修正
* Pagesから他の同一インスタンス内のPagesのページへのリンクができない問題を修正
* /api/notes/create 公開範囲private を渡すとタイムアウトする問題を修正
* パスワードの確認が完了しなくてもユーザー登録できる問題を修正
* 依存関係の更新
* i18n
11.20.0 (2019/05/27)
--------------------
### ✨Improvements
* 管理画面からリモートファイルのキャッシュをすべて削除できるように
* 投稿フォームに投稿のURLをペーストしようとすると引用RNにできるように
* モバイル版の投稿フォームにファイルをドロップできるように
* モバイル版でも投稿の下書き自動保存ができるように
* リモートファイルのキャッシュが期限切れになったときにサムネイルが無くならないように
* ジョブキュー管理画面を強化
### 🐛Fixes
* 投稿内のローカルなURLプレビューをクリックしたとき not found になることがある問題を修正
* デスクトップでユーザーページに遷移するときページが再度読み込みされることがある問題を修正
* フォロー申請自動承認オプションが常にオフで表示される問題を修正
* ポートを設定せずに起動したときに適切なエラーメッセージが表示されない問題を修正
* i18n
11.19.1 (2019/05/26)
--------------------
### 🐛Fixes
* タグページを遷移してもタイムラインが変わらない問題を修正
* インスタンス名を空にしてもMisskeyロゴが表示されない問題を修正
* 投稿内のローカルなURLをクリックしたとき not found になることがある問題を修正
* npm run init がプロセス終了しない問題を修正
11.19.0 (2019/05/25)
--------------------
### ✨Improvements
* グループのオーナーを変えられるように
* PagesでURLプレビューを表示するように
* サーバーログを削除できるように
* リンク先が同じインスタンスの投稿内のURLをクリックしたときは新しいタブで開かないように
* PostgreSQLの接続オプションを設定ファイルで設定できるように
* いくつかのAPIでのパフォーマンスを向上
* ユーザビリティの向上
* デザインの調整
### 🐛Fixes
* デッキでユーザーページを遷移したときに前のユーザーのタイムラインが残り続ける問題を修正
* デッキでフォロー申請が見れない問題を修正
* グループ情報が更新できない問題を修正
* Firefoxでトークの下が隠れてしまう問題を修正
* トーク履歴がないと履歴が読み込み中のままになる問題を修正
* 通知で長い名前のユーザーがいると横スクロールが発生する問題を修正
* iOSでの選択ダイアログの動作を修正
11.18.1 (2019/05/21)
--------------------
### 🐛Fixes
* 11.18.0からフォロー/フォロワーのもっと読み込む機能が作動していない問題を修正
* iOSで投稿フォームに自動フォーカスしない問題を修正
* ダークモードでグループ名がみにくい問題を修正
* ハッシュタグタイムラインを読み込んだ時にプログレスバーが残り続ける問題を修正
* ユーザビリティの修正
11.18.0 (2019/05/21)
--------------------
### ✨Improvements
* デザインの調整
### 🐛Fixes
* 投稿の削除が連合しない問題を修正
11.17.1 (2019/05/20)
--------------------
### 🐛Fixes
* トークの通知インジケーターが点灯し続ける問題を修正
* ユーザーグループの読み込みでエラーになることがある問題を修正
11.17.0 (2019/05/19)
--------------------
### 注意
このアップデートを適用した後、プロセスを起動(もしくは再起動)する前に[マイグレーション](#migration)の手順を実行してください
### ✨Improvements
* ユーザーグループを招待制に
### 🐛Fixes
* フォロー申請が表示されない問題を修正
* トークの通知インジケーターが点灯し続ける問題を修正
* 自分を自分のグループから削除できる問題を修正
* 新しいタブでグループトークを開くことができない問題を修正
11.16.1 (2019/05/19)
--------------------
### 🐛Fixes
* Dockerで起動できない問題を修正
11.16.0 (2019/05/19)
--------------------
### 注意
このアップデートを適用した後、プロセスを起動(もしくは再起動)する前に[マイグレーション](#migration)の手順を実行してください
### ✨Improvements
* ユーザーグループ機能を追加
* ページに「いいね」できるように
* UIの改善
### 🐛Fixes
* トークを読み込むときに最大数指定できなかった問題を修正
11.15.0 (2019/05/16)
--------------------
### ✨Improvements
* 管理画面でreCAPTCHAのプレビューを表示するように
### 🐛Fixes
* オブジェクトストレージのリージョンの設定が反映されない問題を修正
11.14.0 (2019/05/16) 11.14.0 (2019/05/16)
-------------------- --------------------
@ -413,7 +558,40 @@ mongodb:
* 依存ライブラリの問題と思わるため、対応が難しい * 依存ライブラリの問題と思わるため、対応が難しい
### Migration ### Migration
coming soon... #### 移行の注意点
**以下のデータは引き継がれません**
* 通知
* リモートの投稿
* リバーシの対局
#### 手順
1. v11をインストールしたい場所に syuilo/misskey をクローン
2. config を設定する
* PostgreSQL(`db`)の設定とは別に、v10からMongoDBの設定をコピペしてくる(例は下にあります)
* `id`の設定を`meid`または`objectid`にする
``` yml
db:
host: localhost
port: 5432
db: misskey
user: x
pass: x
mongodb:
user: x
pass: x
host: localhost
port: 27017
db: misskey
```
3. migration ブランチに切り替え
4. `npm i`
5. `npm run build`
6. `npm run init`
7. `npm run migrate`
8. master ブランチに戻す
9. enjoy
10.100.0 10.100.0
---------- ----------

View File

@ -3,11 +3,17 @@
## Issues ## Issues
Feature suggestions and bug reports are filed in https://github.com/syuilo/misskey/issues . Feature suggestions and bug reports are filed in https://github.com/syuilo/misskey/issues .
Before creating a new issue, please search existing issues to avoid duplication.
If you find the existing issue, please add your reaction or comment to the issue. * Please search existing issues to avoid duplication. If your issue is already filed, please add your reaction or comment to the existing one.
* If you have multiple independent issues, please submit them separately.
## Localization (l10n) ## Localization (l10n)
Please use [Crowdin](https://crowdin.com/project/misskey) for localization. Misskey uses [Crowdin](https://crowdin.com/project/misskey) for localization management.
You can improve our translations with your Crowdin account.
Changes you make in Crowdin will be merged into develop branch.
If you can't find the language you want to contribute with, please open an issue.
![Crowdin](https://d322cqt584bo4o.cloudfront.net/misskey/localized.svg) ![Crowdin](https://d322cqt584bo4o.cloudfront.net/misskey/localized.svg)
@ -15,16 +21,16 @@ Please use [Crowdin](https://crowdin.com/project/misskey) for localization.
Misskey uses [vue-i18n](https://github.com/kazupon/vue-i18n). Misskey uses [vue-i18n](https://github.com/kazupon/vue-i18n).
## Documentation ## Documentation
* Documents for contributors are located in `/docs`. * Documents for contributors are located in [`/docs`](/docs).
* Documents for instance admins are located in `/docs`. * Documents for instance admins are located in [`/docs`](/docs).
* Documents for end users are located in `src/docs`. * Documents for end users are located in [`/src/docs`](/src/docs).
## Test ## Test
* Test codes are located in `/test`. * Test codes are located in [`/test`](/test).
## Continuous integration ## Continuous integration
Misskey uses CircleCI for automated test. Misskey uses CircleCI for automated test.
Configuration files are located in `/.circleci`. Configuration files are located in [`/.circleci`](/.circleci).
## Glossary ## Glossary
### AP ### AP
@ -128,6 +134,20 @@ query.andWhere(new Brackets(qb => {
})); }));
``` ```
### Not `null` in TypeORM
```ts
const foo = await Foos.findOne({
bar: Not(null)
});
```
のようなクエリ(`bar`が`null`ではない)は期待通りに動作しない。
次のようにします:
```ts
const foo = await Foos.findOne({
bar: Not(IsNull())
});
```
### `null` in SQL ### `null` in SQL
SQLを発行する際、パラメータが`null`になる可能性のある場合はSQL文を出し分けなければならない SQLを発行する際、パラメータが`null`になる可能性のある場合はSQL文を出し分けなければならない
例えば 例えば

View File

@ -39,4 +39,4 @@ COPY --from=builder /misskey/node_modules ./node_modules
COPY --from=builder /misskey/built ./built COPY --from=builder /misskey/built ./built
COPY . ./ COPY . ./
CMD ["npm", "start"] CMD ["npm", "run", "migrateandstart"]

View File

@ -106,22 +106,24 @@ Please see the [Contribution Guide](./CONTRIBUTING.md).
<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/5888816/36da0f7c15954df0ab13f9abdf227f66/1.jpeg?token-time=2145916800&token-hash=at8QpJXJ8C0zINY_NmoMKv-MhXVoUK-YzTgaJPJzJYU%3D" alt="Hiroshi Seki" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/12190916/fb7fa7983c14425f890369535b1506a4/3.png?token-time=2145916800&token-hash=oH_i7gJjNT7Ot6j9JiVwy7ZJIBqACVnzLqlz4YrDAZA%3D" alt="weepjp" width="100"></td> <td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/12190916/fb7fa7983c14425f890369535b1506a4/3.png?token-time=2145916800&token-hash=oH_i7gJjNT7Ot6j9JiVwy7ZJIBqACVnzLqlz4YrDAZA%3D" alt="weepjp" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/19045173/cb91c0f345c24d4ebfd05f19906d5e26/1.png?token-time=2145916800&token-hash=o_zKBytJs_AxHwSYw_5R8eD0eSJe3RoTR3kR3Q0syN0%3D" alt="kiritan" width="100"></td> <td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/19045173/cb91c0f345c24d4ebfd05f19906d5e26/1.png?token-time=2145916800&token-hash=o_zKBytJs_AxHwSYw_5R8eD0eSJe3RoTR3kR3Q0syN0%3D" alt="kiritan" width="100"></td>
<td><img src="https://c8.patreon.com/2/200/776209" alt="Denshi" width="100"></td>
<td><img src="https://c8.patreon.com/2/200/557245" alt="mkatze" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/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/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.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/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://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/5670915/ee175f0bfb6347ffa4ea101a8c097bff/1.jpg?token-time=2145916800&token-hash=mPLM9CA-riFHx-myr3bLZJuH2xBRHA9se5VbHhLIOuA%3D" alt="osapon" width="100"></td>
<td><img src="https://c8.patreon.com/2/200/16869916" alt="見当かなみ" width="100"></td>
</tr><tr> </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">weepjp</a></td> <td><a href="https://www.patreon.com/weepjp">weepjp</a></td>
<td><a href="https://www.patreon.com/user?u=19045173">kiritan</a></td> <td><a href="https://www.patreon.com/user?u=19045173">kiritan</a></td>
<td><a href="https://www.patreon.com/user?u=776209">Denshi</a></td>
<td><a href="https://www.patreon.com/user?u=557245">mkatze</a></td>
<td><a href="https://www.patreon.com/user?u=13099460">ne_moni</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/osapon">osapon</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://c8.patreon.com/2/200/16869916" alt="見当かなみ" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/18899730/6a22797f68254034a854d69ea2445fc8/1.png?token-time=2145916800&token-hash=b_uj57yxo5VzkSOUS7oXE_762dyOTB_oxzbO6lFNG3k%3D" alt="YuzuRyo61" width="100"></td> <td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/18899730/6a22797f68254034a854d69ea2445fc8/1.png?token-time=2145916800&token-hash=b_uj57yxo5VzkSOUS7oXE_762dyOTB_oxzbO6lFNG3k%3D" alt="YuzuRyo61" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/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.png?token-time=2145916800&token-hash=9nEQje_eMvUjq9a7L3uBqW-MQbS-rRMaMgd7UYVoFNM%3D" alt="mydarkstar" width="100"></td> <td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/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://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://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>
@ -130,8 +132,8 @@ Please see the [Contribution Guide](./CONTRIBUTING.md).
<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/19356899/496b4681d33b4520bd7688e0fd19c04d/2.jpeg?token-time=2145916800&token-hash=_sTj3dUBOhn9qwiJ7F19Qd-yWWfUqJC_0jG1h0agEqQ%3D" alt="sheeta.s" width="100"></td> <td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/19356899/496b4681d33b4520bd7688e0fd19c04d/2.jpeg?token-time=2145916800&token-hash=_sTj3dUBOhn9qwiJ7F19Qd-yWWfUqJC_0jG1h0agEqQ%3D" alt="sheeta.s" width="100"></td>
</tr><tr> </tr><tr>
<td><a href="https://www.patreon.com/user?u=16869916">見当かなみ</a></td>
<td><a href="https://www.patreon.com/Yuzulia">YuzuRyo61</a></td> <td><a href="https://www.patreon.com/Yuzulia">YuzuRyo61</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>
<td><a href="https://www.patreon.com/user?u=12718187">Peter G.</a></td> <td><a href="https://www.patreon.com/user?u=12718187">Peter G.</a></td>
<td><a href="https://www.patreon.com/user?u=13039004">nemu</a></td> <td><a href="https://www.patreon.com/user?u=13039004">nemu</a></td>
@ -150,7 +152,7 @@ Please see the [Contribution Guide](./CONTRIBUTING.md).
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/5923936/2a743cbfbff946c2af3f09026047c0da/2.png?token-time=2145916800&token-hash=h6yphW1qnM0n_NOWaf8qtszMRLXEwIxfk5beu4RxdT0%3D" alt="noellabo" width="100"></td> <td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/5923936/2a743cbfbff946c2af3f09026047c0da/2.png?token-time=2145916800&token-hash=h6yphW1qnM0n_NOWaf8qtszMRLXEwIxfk5beu4RxdT0%3D" alt="noellabo" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/2384390/5681180e1efb46a8b28e0e8d4c8b9037/1.jpg?token-time=2145916800&token-hash=SJcMy-Q1BcS940-LFUVOMfR7-5SgrzsEQGhYb3yowFk%3D" alt="CG" width="100"></td> <td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/2384390/5681180e1efb46a8b28e0e8d4c8b9037/1.jpg?token-time=2145916800&token-hash=SJcMy-Q1BcS940-LFUVOMfR7-5SgrzsEQGhYb3yowFk%3D" alt="CG" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/18072312/98e894d960314fa7bc236a72a39488fe/1.jpe?token-time=2145916800&token-hash=qA8j97lIZNc-74AuZ0p4F3ms6sKPeKjtNt2vEuwpsyo%3D" alt="Hekovic" width="100"></td> <td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/18072312/98e894d960314fa7bc236a72a39488fe/1.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/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/10789744/97175095d8f04c0f86225ff47cb98d40/1.jpeg?token-time=2145916800&token-hash=l4AoMR7Nj7K4yAHrkrk2hAoggPkbSPm12m1nmbe9Pb8%3D" alt="Naoki Hirayama" width="100"></td>
</tr><tr> </tr><tr>
<td><a href="https://www.patreon.com/user?u=13737140">Satsuki Yanagi</a></td> <td><a href="https://www.patreon.com/user?u=13737140">Satsuki Yanagi</a></td>
<td><a href="https://www.patreon.com/takimura">takimura</a></td> <td><a href="https://www.patreon.com/takimura">takimura</a></td>
@ -161,19 +163,21 @@ Please see the [Contribution Guide](./CONTRIBUTING.md).
<td><a href="https://www.patreon.com/noellabo">noellabo</a></td> <td><a href="https://www.patreon.com/noellabo">noellabo</a></td>
<td><a href="https://www.patreon.com/Corset">CG</a></td> <td><a href="https://www.patreon.com/Corset">CG</a></td>
<td><a href="https://www.patreon.com/hekovic">Hekovic</a></td> <td><a href="https://www.patreon.com/hekovic">Hekovic</a></td>
<td><a href="https://www.patreon.com/dansup">dansup</a></td> <td><a href="https://www.patreon.com/spinlock">Naoki Hirayama</a></td>
</tr></table> </tr></table>
<table><tr> <table><tr>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/4503830/ccf2cc867ea64de0b524bb2e24b9a1cb/1.jpeg?token-time=2145916800&token-hash=L55UhJ0rcuNAH3w_ryeeGN4hC6taoOixyAhraEi0bzw%3D" alt="dansup" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/619786/32cf01444db24e578cd1982c197f6fc6/1.jpeg?token-time=2145916800&token-hash=d8jBQLMOHD87KtXs5C9fk1o58DMF73pQ-dYH3uZJPBE%3D" alt="Gargron" width="100"></td> <td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/619786/32cf01444db24e578cd1982c197f6fc6/1.jpeg?token-time=2145916800&token-hash=d8jBQLMOHD87KtXs5C9fk1o58DMF73pQ-dYH3uZJPBE%3D" alt="Gargron" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/5731881/4b6038e6cda34c04b83a5fcce3806a93/1.png?token-time=2145916800&token-hash=hBayGfOmQH3kRMdNnDe4oCZD_9fsJWSt29xXR3KRMVk%3D" alt="Nokotaro Takeda" width="100"></td> <td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/5731881/4b6038e6cda34c04b83a5fcce3806a93/1.png?token-time=2145916800&token-hash=hBayGfOmQH3kRMdNnDe4oCZD_9fsJWSt29xXR3KRMVk%3D" alt="Nokotaro Takeda" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/12531784/93a45137841849329ba692da92ac7c60/1.jpeg?token-time=2145916800&token-hash=vGe7wXGqmA8Q7m-kDNb6fyGdwk-Dxk4F-ut8ZZu51RM%3D" alt="Takashi Shibuya" width="100"></td> <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> </tr><tr>
<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>
<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:** Mon, 13 May 2019 06:13:06 UTC **Last updated:** Tue, 11 Jun 2019 01:46:06 UTC
<!-- PATREON_END --> <!-- PATREON_END -->
:four_leaf_clover: Copyright :four_leaf_clover: Copyright

View File

@ -93,6 +93,25 @@ common:
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"
post-form:
attach-location-information: "Přidat informace o lokaci"
hide-contents: "Schovat obsah"
reply-placeholder: "Odpovědět na tento příspěvek"
quote-placeholder: "Citovat tento příspěvek"
submit: "Odeslat"
reply: "Odpovědět"
renote: "Renotovat"
attach-media-from-local: "Uplodovat soubor z vašeho zařízení"
insert-a-kao: "v('ω')v"
create-poll: "Vytvořit anketu"
text-remain: "zbývá ještě {} znaků"
recent-tags: "Nejnovější"
visibility: "Viditelnost"
geolocation-alert: "Vaše zařízení nedalo k dispozici lokaci"
error: "Chyba"
enter-username: "Zadejte své uživatelské jméno"
add-visible-user: "Přidat uživatele"
username-prompt: "Zadejte své uživatelské jméno"
weekday-short: weekday-short:
sunday: "Ne" sunday: "Ne"
monday: "Po" monday: "Po"
@ -251,6 +270,7 @@ common:
my-token-regenerated: "Váš token byl regenerován, proto budete odhlášen/a." my-token-regenerated: "Váš token byl regenerován, proto budete odhlášen/a."
hide-password: "Skrýt heslo" hide-password: "Skrýt heslo"
show-password: "Zobrazit heslo" show-password: "Zobrazit heslo"
enter-username: "Zadejte své uživatelské jméno"
do-not-use-in-production: "Tohle je vývojářský build. Nepoužívejte v produkci." do-not-use-in-production: "Tohle je vývojářský build. Nepoužívejte v produkci."
user-suspended: "Tomuto uživateli byl pozastaven účet." user-suspended: "Tomuto uživateli byl pozastaven účet."
is-remote-user: "Informace o tomto uživateli nemusí být kompletní." is-remote-user: "Informace o tomto uživateli nemusí být kompletní."
@ -307,7 +327,10 @@ auth/views/form.vue:
accept: "Povolit přístup" accept: "Povolit přístup"
auth/views/index.vue: auth/views/index.vue:
loading: "Načítám..." loading: "Načítám..."
denied-paragraph: "Tato aplikace nebude mít přístup k Vašemu účtu."
already-authorized: "Tato aplikace byla již autorizována." already-authorized: "Tato aplikace byla již autorizována."
callback-url: "Zpátky do aplikace."
please-go-back: "Prosím vraťte se zpátky do aplikace."
error: "Taková relace neexistuje." error: "Taková relace neexistuje."
sign-in: "Prosím přihlaste se." sign-in: "Prosím přihlaste se."
common/views/pages/explore.vue: common/views/pages/explore.vue:
@ -357,23 +380,30 @@ common/views/components/games/reversi/reversi.room.vue:
waiting-for-both: "Připravuji" waiting-for-both: "Připravuji"
cancel: "Zrušit" cancel: "Zrušit"
ready: "Připraveno" ready: "Připraveno"
cancel-ready: "Pokračovat v přípravě"
common/views/components/connect-failed.vue: common/views/components/connect-failed.vue:
title: "Nelze se připojit k serveru" title: "Nelze se připojit k serveru"
description: "Nastal problém s Vaším připojením k internetu, nebo server není dostupný nebo zrovna probíhá údržba. Prosím {zkuste to znova} za pár minut." description: "Nastal problém s Vaším připojením k internetu, nebo server není dostupný nebo zrovna probíhá údržba. Prosím {zkuste to znova} za pár minut."
thanks: "Děkujeme že jste použili Misskey." thanks: "Děkujeme že jste použili Misskey."
common/views/components/connect-failed.troubleshooter.vue: common/views/components/connect-failed.troubleshooter.vue:
title: "Poradce při potížích"
network: "Síťové připojení" network: "Síťové připojení"
checking-network: "Prověřit síťové připojení" checking-network: "Prověřit síťové připojení"
internet: "Připojení k internetu" internet: "Připojení k internetu"
checking-internet: "Ověřuji připojení k internetu." checking-internet: "Ověřuji připojení k internetu."
server: "Připojení k serveru" server: "Připojení k serveru"
checking-server: "Spojuji se se serverem"
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" no-server: "Nelze se připojit k serveru Misskey"
success: "Úspěšně se podařilo spojit s Misskey serverem"
flush: "Vyčistit mezipaměť"
common/views/components/media-banner.vue: common/views/components/media-banner.vue:
sensitive: "Choulostivý obsah"
click-to-show: "Klikněte pro zobrazení" click-to-show: "Klikněte pro zobrazení"
common/views/components/theme.vue: common/views/components/theme.vue:
theme: "Vzhled"
light-theme: "Motiv pro použití ve světlém vzhledu" light-theme: "Motiv pro použití ve světlém vzhledu"
dark-theme: "Motiv 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"
@ -384,6 +414,7 @@ common/views/components/theme.vue:
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" save-created-theme: "Uložit motiv"
primary-color: "Základní barva"
text-color: "Barva textu" text-color: "Barva textu"
base-theme: "Základní vzhled" base-theme: "Základní vzhled"
base-theme-light: "Světlý" base-theme-light: "Světlý"
@ -391,8 +422,10 @@ common/views/components/theme.vue:
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"
invalid-theme: "Vzhled není validní"
already-installed: "Tento vzhled je již nainstalován." already-installed: "Tento vzhled je již nainstalován."
saved: "Uloženo" saved: "Uloženo"
manage-themes: "Správa vzhledů"
builtin-themes: "Standardní vzhledy" builtin-themes: "Standardní vzhledy"
my-themes: "Moje vzhledy" my-themes: "Moje vzhledy"
installed-themes: "Nainstalované vzhledy" installed-themes: "Nainstalované vzhledy"
@ -403,6 +436,7 @@ common/views/components/theme.vue:
desc: "Popis" desc: "Popis"
export: "Exportovat" export: "Exportovat"
import: "Importovat" import: "Importovat"
import-by-code: "nebo zkopírujte kód"
theme-name-required: "Jméno vzhledu je povinné" theme-name-required: "Jméno vzhledu je povinné"
common/views/components/cw-button.vue: common/views/components/cw-button.vue:
hide: "Skrýt" hide: "Skrýt"
@ -414,14 +448,12 @@ common/views/components/messaging.vue:
search-user: "Najít uživatele" search-user: "Najít uživatele"
you: "Vy" you: "Vy"
no-history: "Žádná historie" no-history: "Žádná historie"
user: "Uživatel"
common/views/components/messaging-room.vue: common/views/components/messaging-room.vue:
empty: "Žádné zprávy"
new-message: "Máte novou zprávu" new-message: "Máte novou zprávu"
only-one-file-attached: "Jenom JEDEN soubor může být přiložen ke zprávě."
common/views/components/messaging-room.form.vue: common/views/components/messaging-room.form.vue:
send: "Odeslat" send: "Odeslat"
attach-from-local: "Přiložit soubory z Vašeho zařízení" attach-from-local: "Přiložit soubory z Vašeho zařízení"
only-one-file-attached: "Jenom JEDEN soubor může být přiložen ke zprávě."
common/views/components/messaging-room.message.vue: common/views/components/messaging-room.message.vue:
is-read: "Přečtené" is-read: "Přečtené"
deleted: "Tato zpráva byla odstraněna" deleted: "Tato zpráva byla odstraněna"
@ -477,10 +509,13 @@ common/views/components/poll-editor.vue:
remove: "Odstranit tuto možnost" remove: "Odstranit tuto možnost"
add: "+ Přidat možnost" add: "+ Přidat možnost"
destroy: "Zahodit dotazník" destroy: "Zahodit dotazník"
multiple: "Více odpovědí je povoleno"
expiration: "Termín" expiration: "Termín"
infinite: "Nekonečne" infinite: "Nekonečne"
at: "Výběr data a času" at: "Výběr data a času"
no-more: "Více už přidat nemůžete"
deadline-date: "Termín ukončení" deadline-date: "Termín ukončení"
deadline-time: "Doba trvání"
interval: "Trvání" interval: "Trvání"
second: "Sekunda" second: "Sekunda"
minute: "Minuta" minute: "Minuta"
@ -488,6 +523,7 @@ common/views/components/poll-editor.vue:
day: "Ne" day: "Ne"
common/views/components/reaction-picker.vue: common/views/components/reaction-picker.vue:
choose-reaction: "Vyberte svoji reakci" choose-reaction: "Vyberte svoji reakci"
input-reaction-placeholder: "nebo vložte Emoji"
common/views/components/emoji-picker.vue: common/views/components/emoji-picker.vue:
custom-emoji: "Emoji" custom-emoji: "Emoji"
people: "Lidé" people: "Lidé"
@ -501,6 +537,7 @@ common/views/components/emoji-picker.vue:
common/views/components/signin.vue: common/views/components/signin.vue:
username: "Přezdívka" username: "Přezdívka"
password: "Heslo" password: "Heslo"
token: "Token"
signing-in: "Přihlašování..." signing-in: "Přihlašování..."
or: "Nebo" or: "Nebo"
signin-with-twitter: "Přihlásit se pomocí účtu Twitter" signin-with-twitter: "Přihlásit se pomocí účtu Twitter"
@ -528,6 +565,7 @@ common/views/components/signup.vue:
password-matched: "OK" password-matched: "OK"
password-not-matched: "Neshodují se" password-not-matched: "Neshodují se"
recaptcha: "Potvrzení" recaptcha: "Potvrzení"
tos: "Podmínky užívání"
create: "Vytvořit účet" create: "Vytvořit účet"
some-error: "Pokus o vytvoření účtu selhal. Prosím zkuste to znovu." some-error: "Pokus o vytvoření účtu selhal. Prosím zkuste to znovu."
common/views/components/special-message.vue: common/views/components/special-message.vue:
@ -566,6 +604,7 @@ common/views/components/visibility-chooser.vue:
home: "Domů" home: "Domů"
specified-desc: "Poslat pouze zmíněným uživatelům" specified-desc: "Poslat pouze zmíněným uživatelům"
local-public: "Veřejná (pouze místní)" local-public: "Veřejná (pouze místní)"
local-public-desc: "Nepublikovat na vzdálených serverech"
local-home: "Domovská (pouze místní)" local-home: "Domovská (pouze místní)"
local-followers: "Pro sledující (pouze místní)" local-followers: "Pro sledující (pouze místní)"
common/views/components/trends.vue: common/views/components/trends.vue:
@ -575,6 +614,8 @@ common/views/components/language-settings.vue:
title: "Zobrazit jazyky" title: "Zobrazit jazyky"
pick-language: "Zvolte jazyk" pick-language: "Zvolte jazyk"
recommended: "Doporučené" recommended: "Doporučené"
auto: "Automaticky"
specify-language: "Vyberte jazyk"
info: "Pro aktivování změn musíte znovu načíst stránky." info: "Pro aktivování změn musíte znovu načíst stránky."
common/views/components/profile-editor.vue: common/views/components/profile-editor.vue:
title: "Profil" title: "Profil"
@ -601,6 +642,7 @@ common/views/components/profile-editor.vue:
email-not-verified: "Váš email není potvrzen. Prosím zkontrolujte si svou schránku." email-not-verified: "Váš email není potvrzen. Prosím zkontrolujte si svou schránku."
export: "Exportovat" export: "Exportovat"
import: "Importovat" import: "Importovat"
export-and-import: "Import / Export"
export-targets: export-targets:
following-list: "Seznam sledujících" following-list: "Seznam sledujících"
mute-list: "Seznam ztlumených uživatelů" mute-list: "Seznam ztlumených uživatelů"
@ -617,10 +659,34 @@ common/views/components/user-list-editor.vue:
remove-user: "Odebrat z tohoto seznamu" remove-user: "Odebrat z tohoto seznamu"
delete-are-you-sure: "Smazat seznam \"$1\"?" delete-are-you-sure: "Smazat seznam \"$1\"?"
deleted: "Smazáno" deleted: "Smazáno"
add-user: "Přidat uživatele"
common/views/components/user-group-editor.vue:
users: "Členové"
rename: "Přejmenovat skupinu"
delete: "Odstranit skupinu"
transfer: "Přesunout skupinu"
transfer-are-you-sure: "Jste si jistí že chcete přidat @$2 do skupiny: $1?"
transferred: "Skupina přesunuta"
remove-user: "Odebrat uživatele z této skupiny"
delete-are-you-sure: "Jste si jistí že chcete smazat skupinu \"$1\"?"
deleted: "Smazáno"
invite: "Pozvat"
invited: "Pozvánka byla úspěšně odeslána"
common/views/components/user-lists.vue: common/views/components/user-lists.vue:
user-lists: "Seznamy"
create-list: "Vytvořit seznam"
list-name: "Název seznamu" list-name: "Název seznamu"
common/views/components/user-groups.vue:
user-groups: "Skupiny"
create-group: "Vytvořit skupinu"
group-name: "Název skupiny"
owned-groups: "Moje skupiny"
invites: "Pozvat"
reject-invite: "Odmítnout"
common/views/widgets/broadcast.vue: common/views/widgets/broadcast.vue:
fetching: "Načítám" fetching: "Načítám"
no-broadcasts: "Žádná nová oznámení"
have-a-nice-day: "Přejeme Vám příjemný den!"
next: "Další" next: "Další"
common/views/widgets/calendar.vue: common/views/widgets/calendar.vue:
year: "Rok {}" year: "Rok {}"
@ -647,6 +713,12 @@ common/views/widgets/slideshow.vue:
no-image: "V této složce nebyly nalezeny žádné fotky." no-image: "V této složce nebyly nalezeny žádné fotky."
common/views/pages/not-found.vue: common/views/pages/not-found.vue:
page-not-found: "Stránka nenalezena" page-not-found: "Stránka nenalezena"
common/views/pages/follow.vue:
following: "Sledování"
follow: "Sledovat"
common/views/pages/follow-requests.vue:
accept: "Přijmout"
reject: "Odmítnout"
desktop: desktop:
banner: "Baner" banner: "Baner"
avatar-crop-title: "Vyberte část, která se zobrazí jako avatar" avatar-crop-title: "Vyberte část, která se zobrazí jako avatar"
@ -749,27 +821,11 @@ desktop/views/components/notes.vue:
error: "Načítání selhalo." error: "Načítání selhalo."
retry: "Opakovat" retry: "Opakovat"
desktop/views/components/post-form.vue: desktop/views/components/post-form.vue:
add-visible-user: "+Přidat uživatele"
attach-location-information: "Přidat informace o lokaci"
hide-contents: "Schovat obsah"
reply-placeholder: "Odpovědět na tento příspěvěk"
quote-placeholder: "Citovat tento příspěvek"
submit: "Příspěvek"
reply: "Odpovědět"
renote: "Renotovat"
posted: "Odesláno!" posted: "Odesláno!"
replied: "Odpověděno!" replied: "Odpověděno!"
reposted: "Renotováno!" reposted: "Renotováno!"
note-failed: "Nepodařilo se přidat příspěvek" note-failed: "Nepodařilo se přidat příspěvek"
renote-failed: "Renotování neuspělo" renote-failed: "Renotování neuspělo"
insert-a-kao: "v('ω')v"
create-poll: "Vytvořit anketu"
text-remain: "{0} znaků zbývá"
recent-tags: "Nejnovější"
visibility: "Viditelnost"
geolocation-alert: "Vaše zařízení nepodporuje lokační službu"
error: "Chyba"
enter-username: "Zadejte své uživatelské jméno..."
desktop/views/components/post-form-window.vue: desktop/views/components/post-form-window.vue:
note: "Nový příspěvek" note: "Nový příspěvek"
reply: "Odpovědět" reply: "Odpovědět"
@ -788,6 +844,7 @@ desktop/views/components/renote-form-window.vue:
desktop/views/components/settings.2fa.vue: desktop/views/components/settings.2fa.vue:
detail: "Více…" detail: "Více…"
url: "https://www.google.cz/landing/2step/" url: "https://www.google.cz/landing/2step/"
token: "Token"
common/views/components/media-image.vue: common/views/components/media-image.vue:
click-to-show: "Klikněte pro zobrazení" click-to-show: "Klikněte pro zobrazení"
common/views/components/api-settings.vue: common/views/components/api-settings.vue:
@ -844,6 +901,7 @@ desktop/views/components/ui.header.vue:
desktop/views/components/ui.header.account.vue: desktop/views/components/ui.header.account.vue:
profile: "Váš profil" profile: "Váš profil"
lists: "Seznamy" lists: "Seznamy"
groups: "Skupiny"
admin: "Administrace" admin: "Administrace"
desktop/views/components/ui.header.nav.vue: desktop/views/components/ui.header.nav.vue:
game: "Hry" game: "Hry"
@ -853,11 +911,6 @@ desktop/views/components/ui.header.post.vue:
post: "Nový příspěvek" post: "Nový příspěvek"
desktop/views/components/ui.header.search.vue: desktop/views/components/ui.header.search.vue:
placeholder: "Vyhledávání" placeholder: "Vyhledávání"
desktop/views/components/received-follow-requests-window.vue:
accept: "Přijmout"
reject: "Odmítnout"
desktop/views/components/user-lists-window.vue:
title: "Seznamy uživatelů"
desktop/views/components/user-preview.vue: desktop/views/components/user-preview.vue:
notes: "Příspěvky" notes: "Příspěvky"
desktop/views/components/users-list.vue: desktop/views/components/users-list.vue:
@ -873,7 +926,6 @@ admin/views/index.vue:
users: "Uživatelé" users: "Uživatelé"
federation: "Z fedivesmíru" federation: "Z fedivesmíru"
announcements: "Oznámení" announcements: "Oznámení"
hashtags: "Hashtagy"
queue: "Fronta úloh" queue: "Fronta úloh"
logs: "Logy" logs: "Logy"
back-to-misskey: "Zpět na Misskey" back-to-misskey: "Zpět na Misskey"
@ -884,6 +936,11 @@ admin/views/dashboard.vue:
instances: "Instance" instances: "Instance"
this-instance: "Tato instance" this-instance: "Tato instance"
federated: "Z fedivesmíru" federated: "Z fedivesmíru"
admin/views/logs.vue:
logs: "Logy"
levels:
info: "Informace"
error: "Chyba"
admin/views/abuse.vue: admin/views/abuse.vue:
details: "Popis" details: "Popis"
remove-report: "Odstranit" remove-report: "Odstranit"
@ -898,12 +955,12 @@ admin/views/instance.vue:
maintainer-config: "Informace o administrátorovi" maintainer-config: "Informace o administrátorovi"
maintainer-name: "Jméno administrátora" maintainer-name: "Jméno administrátora"
maintainer-email: "Kontakt na administrátora" maintainer-email: "Kontakt na administrátora"
object-storage-endpoint: "Endpoint"
mb: "V megabajtech" mb: "V megabajtech"
recaptcha-config: "nastavení služby reCAPTCHA" recaptcha-config: "nastavení služby reCAPTCHA"
recaptcha-info: "reCAPTCHA token je povinný. Můžete jej získat na https://www.google.com/recaptcha/intro/" recaptcha-info: "reCAPTCHA token je povinný. Můžete jej získat na https://www.google.com/recaptcha/intro/"
enable-recaptcha: "povolit reCAPTCHA" enable-recaptcha: "povolit reCAPTCHA"
recaptcha-site-key: "reCAPTCHA klíč stránky (site key)" recaptcha-preview: "Náhled"
recaptcha-secret-key: "reCAPTCHA tajný klíč"
twitter-integration-config: "Nastavení spojení s Twitterem" twitter-integration-config: "Nastavení spojení s Twitterem"
twitter-integration-info: "The callback URL is set on {url}." twitter-integration-info: "The callback URL is set on {url}."
enable-twitter-integration: "Povolit připojení k Twitteru" enable-twitter-integration: "Povolit připojení k Twitteru"
@ -1026,6 +1083,7 @@ admin/views/federation.vue:
host: "Hostitel" host: "Hostitel"
notes: "Poznámky" notes: "Poznámky"
users: "Uživatelé" users: "Uživatelé"
following: "Sledování"
caught-at: "Vytvořeno" caught-at: "Vytvořeno"
status: "Status" status: "Status"
latest-request-received-at: "Poslední požadavek přijat" latest-request-received-at: "Poslední požadavek přijat"
@ -1045,6 +1103,7 @@ admin/views/federation.vue:
hour: "za hodinu" hour: "za hodinu"
day: "za den" day: "za den"
blocked-hosts: "Blokován" blocked-hosts: "Blokován"
save: "Uložit"
desktop/views/pages/welcome.vue: desktop/views/pages/welcome.vue:
about: "O Misskey" about: "O Misskey"
timeline: "Časová osa" timeline: "Časová osa"
@ -1083,6 +1142,8 @@ desktop/views/pages/user/user.photos.vue:
no-photos: "Žádné obrázky" no-photos: "Žádné obrázky"
desktop/views/pages/user/user.header.vue: desktop/views/pages/user/user.header.vue:
posts: "Poznámky" posts: "Poznámky"
following: "Sledovaní"
followers: "Sledující"
month: "Po" month: "Po"
day: "Ne" day: "Ne"
desktop/views/widgets/notifications.vue: desktop/views/widgets/notifications.vue:
@ -1111,6 +1172,7 @@ mobile/views/components/drive.file-detail.vue:
mobile/views/components/media-video.vue: mobile/views/components/media-video.vue:
click-to-show: "Klikněte pro zobrazení" click-to-show: "Klikněte pro zobrazení"
common/views/components/follow-button.vue: common/views/components/follow-button.vue:
following: "Sledování"
follow-processing: "Zpracovávám" follow-processing: "Zpracovávám"
mobile/views/components/note.vue: mobile/views/components/note.vue:
private: "Tento příspěvek je soukromý" private: "Tento příspěvek je soukromý"
@ -1130,15 +1192,6 @@ mobile/views/components/note-sub.vue:
admin: "admin" admin: "admin"
bot: "bot" bot: "bot"
cat: "kočka" cat: "kočka"
mobile/views/components/post-form.vue:
add-visible-user: "Přidat uživatele"
submit: "Příspěvek"
reply: "Odpovědět"
renote: "Renotovat"
reply-placeholder: "Odpovědět na tento příspěvěk"
geolocation-alert: "Vaše zařízení nepodporuje lokační službu"
error: "Chyba"
username-prompt: "Zadejte uživatelské jméno"
mobile/views/components/sub-note-content.vue: mobile/views/components/sub-note-content.vue:
private: "Tento příspěvek je soukromý" private: "Tento příspěvek je soukromý"
deleted: "Tento příspěvek byl odstraněn" deleted: "Tento příspěvek byl odstraněn"
@ -1151,6 +1204,7 @@ mobile/views/components/ui.nav.vue:
notifications: "Oznámení" notifications: "Oznámení"
search: "Vyhledávání" search: "Vyhledávání"
user-lists: "Seznamy" user-lists: "Seznamy"
user-groups: "Skupiny"
widgets: "Widgety" widgets: "Widgety"
game: "Hry" game: "Hry"
admin: "Administrace" admin: "Administrace"
@ -1159,8 +1213,6 @@ mobile/views/pages/drive.vue:
contextmenu: contextmenu:
upload: "Nahrát soubor" upload: "Nahrát soubor"
create-folder: "Vytvořit složku" create-folder: "Vytvořit složku"
mobile/views/pages/user-lists.vue:
title: "Seznamy"
mobile/views/pages/signup.vue: mobile/views/pages/signup.vue:
lets-start: "Váš účet je připraven! 📦" lets-start: "Váš účet je připraven! 📦"
mobile/views/pages/home.vue: mobile/views/pages/home.vue:
@ -1177,9 +1229,6 @@ mobile/views/pages/widgets/activity.vue:
activity: "Aktivita" activity: "Aktivita"
mobile/views/pages/share.vue: mobile/views/pages/share.vue:
share-with: "Sdílet na {name}" share-with: "Sdílet na {name}"
mobile/views/pages/received-follow-requests.vue:
accept: "Přijmout"
reject: "Odmítnout"
mobile/views/pages/note.vue: mobile/views/pages/note.vue:
prev: "Předchozí příspěvěk" prev: "Předchozí příspěvěk"
next: "Následující příspěvek" next: "Následující příspěvek"
@ -1212,6 +1261,7 @@ deck/deck.user-column.vue:
dev/views/new-app.vue: dev/views/new-app.vue:
app-name-desc: "Jméno vaší aplikace" app-name-desc: "Jméno vaší aplikace"
pages: pages:
like: "Lajk"
title: "Titulek" title: "Titulek"
blocks: blocks:
post: "Formulář pro psaní" post: "Formulář pro psaní"
@ -1248,5 +1298,7 @@ pages:
arg2: "Seznamy" arg2: "Seznamy"
_pick: _pick:
arg1: "Seznamy" arg1: "Seznamy"
_listLen:
arg1: "Seznamy"
types: types:
array: "Seznamy" array: "Seznamy"

1880
locales/da-DK.yml Normal file

File diff suppressed because it is too large Load Diff

View File

@ -10,26 +10,35 @@ common:
about: "Misskey ist eine Quelloffene, <b>dezentralisierte microblogging Software</b>. Es bietet eine erweiterbare Benutzeroberfläche, verschiedenste Möglichkeiten auf Beiträge zu reagieren, kostenlosen Datenspeicher, und andere fortschrittliche Funktionen. Zusätzlich ist Misskey dazu in der Lage, sich mittels des Fediverse mit beliebig vielen anderen ActivityPub-kompatiblen Diensten zu verbinden. Wenn du zum Beispiel einen Betrag mit Misskey abschickst, wird dieser auch für Nutzer von Mastodon oder Pleroma sichtbar sein. So ähnlich wie eine Radioübertragung zwischen Planeten." 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"
rich-contents-desc: "Poste einfach deine Ideen, Interessen und alles, was du teilen möchtest. Gestalte deine Nachrichten, teile deine Lieblingsbilder, sende Dateien und Videos und erstelle Umfragen das und mehr kann Misskey!"
reaction: "Reaktionen" reaction: "Reaktionen"
reaction-desc: "Der einfachste Weg, deine Gefühle mit anderen zu teilen. Mit Misskey kannst du auf verschiedenste Arten auf Beiträge reagieren, statt nur zu „liken“."
ui: "Benutzeroberfläche" ui: "Benutzeroberfläche"
ui-desc: "Geschmäcker sind verschieden. Deswegen ist Misskeys Oberfläche hochanpassbar und modular. Mache die Startseite zu deiner Startseite, indem du das Layout deiner Timeline änderst und mit Widgets staffierst."
drive: "Drive" drive: "Drive"
drive-desc: "Du willst ein hochgeladenes Foto nochmal posten? Deine Dateien benennen und in Ordnern sortieren? Misskeys Drive ist der beste Ort dafür. Damit wird das Teilen zum Kinderspiel!"
outro: "Probiere Misskey aus und entdecke Misskeys einzigartige Funktionen. Wenn dir diese Instanz nicht zusagt, nimm einfach eine andere. Dank Misskeys dezentralem System kannst du dich überall mit deinen Freunden verbinden. Also dann, GLHF!"
adblock: adblock:
detected: "Bitte deaktiviere den Werbeblocker." detected: "Bitte deaktiviere den Werbeblocker."
warning: "<strong>Misskey hat keine Werbung.</strong> Allerdings können Werbeblocker für unerwartete Probleme und fehlende Funktionen sorgen."
application-authorization: "Autorisierte Anwendungen" application-authorization: "Autorisierte Anwendungen"
close: "Schließen" close: "Schließen"
do-not-copy-paste: "Bitte keinen Code einfügen. Ihr Account könnte gefährdet werden."
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" customize-home: "Layout Anpassen"
featured-notes: "Hervorgehobene Beiträge" featured-notes: "Beliebt"
dark-mode: "Dunkler Modus" dark-mode: "Dunkler Modus"
signin: "Einloggen" signin: "Einloggen"
signup: "Registrieren" signup: "Registrieren"
signout: "Ausloggen" signout: "Ausloggen"
reload-to-apply-the-setting: "Die Seite muss zum Übernehmen dieser Einstellung aktualisiert werden. Soll die Seite jetzt neu geladen werden?" reload-to-apply-the-setting: "Die Seite muss zum Übernehmen dieser Einstellung aktualisiert werden. Soll die Seite jetzt neu geladen werden?"
fetching-as-ap-object: "Hole Daten…"
got-it: "Verstanden!" got-it: "Verstanden!"
customization-tips: customization-tips:
title: "Anpassung-Tipps" title: "Anpassung-Tipps"
paragraph: "<p>Du kannst deine Startseite anpassen, indem du Widgets hinzufügst und verschiebst.</p><p><strong>Klicke <strong>rechts</strong></strong> auf ein Widget, um dessen Aussehen zu verändern.</p><p>Um ein Widget zu löschen, klicke und ziehe es auf den <strong>Papierkorb</strong> am Kopfende der Seite.</p><p>Wenn du fertig bist, drücke auf den Beenden-Knopf oben rechts.</p>"
gotit: "Verstanden!" gotit: "Verstanden!"
notification: notification:
file-uploaded: "Datei hochgeladen!" file-uploaded: "Datei hochgeladen!"
@ -56,25 +65,41 @@ common:
pages: "Seite" pages: "Seite"
messaging: "Unterhaltungen" messaging: "Unterhaltungen"
home: "Home" home: "Home"
deck: "Stapel" deck: "Deck"
timeline: "Zeitleiste" timeline: "Zeitleiste"
explore: "Entdecken" explore: "Entdecken"
following: "Folgt" following: "Folgt"
followers: "Folgende" followers: "Folgende"
favorites: "Diesen Beitrag favorisieren" favorites: "Favoriten"
permissions: permissions:
"read:account": "Accountinformationen anzeigen." "read:account": "Accountinformationen anzeigen."
"write:account": "Accountinformationen bearbeiten." "write:account": "Accountinformationen bearbeiten."
"read:blocks": "Blöcke anzeigen" "read:blocks": "Blöcke anzeigen"
"write:blocks": "Auf Sperrungen zugreifen"
"read:drive": "Dateien anzeigen" "read:drive": "Dateien anzeigen"
"write:drive": "Dateien bearbeiten" "write:drive": "Dateien bearbeiten"
"read:favorites": "Favoriten anzeigen" "read:favorites": "Favoriten anzeigen"
"write:favorites": "Auf Favoriten zugreifen"
"read:following": "Follower-Daten lesen"
"write:following": "Folgestatus bearbeiten"
"read:messaging": "Unterhaltung anzeigen" "read:messaging": "Unterhaltung anzeigen"
"write:messaging": "Unterhaltung bearbeiten" "write:messaging": "Unterhaltung bearbeiten"
"read:mutes": "Stummschaltungen lesen"
"write:mutes": "Stummschaltungen bearbeiten"
"write:notes": "Beiträge löschen und verfassen"
"read:notifications": "Benachrichtigungen lesen"
"write:notifications": "Benachrichtigungen bearbeiten"
"read:reactions": "Reaktionen sehen"
"write:reactions": "Reaktionen hinzufügen und bearbeiten"
"write:votes": "Abstimmen" "write:votes": "Abstimmen"
empty-timeline-info: empty-timeline-info:
follow-users-to-make-your-timeline: "Beiträge von Benutzern, denen du folgst, werden in der Zeitleiste angezeigt." follow-users-to-make-your-timeline: "Beiträge von Benutzern, denen du folgst, werden in der Zeitleiste angezeigt."
explore: "Benutzer finden" explore: "Benutzer finden"
post-form:
reply: "Antworten"
renote: "Anmerkung"
enter-username: "Bitte gib einen Benutzernamen ein"
username-prompt: "Bitte gib einen Benutzernamen ein"
weekday-short: weekday-short:
sunday: "So" sunday: "So"
monday: "Mo" monday: "Mo"
@ -147,22 +172,116 @@ common:
show-reversi-board-labels: "Zeige Reihen- und Spaltenbeschreibungen in Reversi an" show-reversi-board-labels: "Zeige Reihen- und Spaltenbeschreibungen in Reversi an"
use-avatar-reversi-stones: "Avatar als Stein in Reversi anzeigen" use-avatar-reversi-stones: "Avatar als Stein in Reversi anzeigen"
disable-animated-mfm: "Animierten Text in Beiträgen deaktivieren" disable-animated-mfm: "Animierten Text in Beiträgen deaktivieren"
disable-showing-animated-images: "Animierte Grafiken deaktivieren"
suggest-recent-hashtags: "Beim Verfassen von Beiträgen letzte Hashtags anzeigen"
always-show-nsfw: "Sensible Inhalte (NSFW) immer anzeigen"
always-mark-nsfw: "Meine Anhänge immer als NSFW markieren"
show-full-acct: "Servername bei Benutzernamen immer anzeigen"
show-via: "„via“ anzeigen"
reduce-motion: "Animationen der Benutzeroberfläche reduzieren"
this-setting-is-this-device-only: "Nur auf diesem Gerät"
use-os-default-emojis: "Betriebssystem-Emojis nutzen"
line-width: "Linienstärke"
line-width-thin: "Dünn"
line-width-normal: "Normal"
line-width-thick: "Dick"
font-size: "Schriftgröße"
font-size-x-small: "Sehr klein"
font-size-small: "Klein"
font-size-medium: "Normal"
font-size-large: "Groß"
font-size-x-large: "Sehr groß"
deck-column-align: "Spaltenaufteilung der Deck-Ansicht"
deck-column-align-center: "Mitte"
deck-column-align-left: "Links"
deck-column-align-flexible: "Flexibel"
deck-column-width: "Spaltenbreite des Decks"
deck-column-width-narrow: "Sehr eng"
deck-column-width-narrower: "Eng"
deck-column-width-normal: "Normal"
deck-column-width-wider: "Breit"
deck-column-width-wide: "Sehr breit"
use-shadow: "Nutze Schatten"
rounded-corners: "Abgerundete Ecken"
circle-icons: "Kreisförmige Icons"
contrasted-acct: "Nutzernamen kontrastreicher darstellen"
wallpaper: "Hintergrund"
choose-wallpaper: "Hintergrund auswählen"
delete-wallpaper: "Hintergrund entfernen"
post-form-on-timeline: "Beitragsformular über Timeline anzeigen"
show-clock-on-header: "Uhr am oberen rechten Rand anzeigen"
show-reply-target: "Zeige bei einer Antwort die ursprüngliche Nachricht"
timeline: "Timeline"
show-my-renotes: "Zeige eigene Renotes in der Timeline"
show-renoted-my-notes: "Zeige Renotes deiner Posts in der Timeline"
show-local-renotes: "Zeige Renotes lokaler Posts in der Timeline"
remain-deleted-note: "Gelöschte Beiträge weiterhin anzeigen"
sound: "Töne"
enable-sounds: "Töne aktivieren"
enable-sounds-desc: "Spiel einen Ton ab beim Erhalten eines Beitrags bzw. einer Nachricht. Diese Einstellung wird im Browser gespeichert."
volume: "Lautstärke"
test: "Test"
update: "Misskey-Update"
version: "Version:"
latest-version: "Neuste Version:"
update-checking: "Suche nach Updates"
do-update: "Nach Updates suchen"
update-settings: "Erweiterte Einstellungen"
no-updates: "Kein Update verfügbar"
no-updates-desc: "Misskey ist aktuell."
update-available: "Eine neue Version ist verfügbar!"
update-available-desc: "Änderungen werden beim Neuladen der Seite angewendet."
advanced-settings: "Erweiterte Einstellungen"
debug-mode: "Debug-Modus einschalten"
debug-mode-desc: "Diese Einstellung wird im Browser gespeichert."
navbar-position: "Postion der Navigationsleiste"
navbar-position-top: "Oben"
navbar-position-left: "Links"
navbar-position-right: "Rechts"
i-am-under-limited-internet: "Ich möchte Datenvolumen sparen"
post-style: "Beitrags-Anzeigestil"
post-style-standard: "Standard"
post-style-smart: "Smart"
notification-position: "Benachrichtigungen anzeigen"
notification-position-bottom: "Unten"
notification-position-top: "Oben"
disable-via-mobile: "Beitrag nicht als „vom Handy“ markieren"
load-raw-images: "Anhänge in voller Größe laden"
load-remote-media: "Zeige Inhalte von fremden Servern"
search: "Suche" search: "Suche"
delete: "Löschen" delete: "Löschen"
loading: "Laden" loading: "Laden"
ok: "Okay"
cancel: "Abbrechen"
update-available-title: "Aktualisierung verfügbar" update-available-title: "Aktualisierung verfügbar"
update-available: "Eine neue Version von Misskey ist verfügbar ({newer}, aktuell ist {current}). Lade die Seite neu um die aktuelle Version zu laden" 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."
hide-password: "Passwort verbergen"
show-password: "Passwort zeigen"
enter-username: "Kontonamen eingeben"
do-not-use-in-production: "Dies ist eine Entwicklungsversion. Nicht in einer Produktivumgebung verwenden." do-not-use-in-production: "Dies ist eine Entwicklungsversion. Nicht in einer Produktivumgebung verwenden."
user-suspended: "Dieser Nutzer wurde gesperrt."
is-remote-user: "Diese Nutzerinformationen können unvollständig sein."
is-remote-post: "Dies ist ein entfernter Post."
view-on-remote: "Vollständige Infos auf Ursprungsserver anzeigen"
renoted-by: "Renote von {user}"
no-notes: "Keine Beiträge"
turn-on-darkmode: "Dunkles Design"
turn-off-darkmode: "Helles Design"
error: error:
title: "Allgemeiner Fehler"
retry: "Erneut versuchen" retry: "Erneut versuchen"
reversi: reversi:
drawn: "Unentschieden" drawn: "Unentschieden"
my-turn: "Du bist am Zug" my-turn: "Du bist am Zug"
opponent-turn: "Dein Gegner ist an der Reihe" opponent-turn: "Dein Gegner ist an der Reihe"
turn-of: "{name}s Zug"
past-turn-of: "Zug von {name}"
won: "{name} hat gewonnen"
black: "Schwarz" black: "Schwarz"
white: "Weiß" white: "Weiß"
total: "Gesamt" total: "Gesamt"
this-turn: "{count}. Zug"
widgets: widgets:
analog-clock: "Analoge Uhr" analog-clock: "Analoge Uhr"
profile: "Profil" profile: "Profil"
@ -173,8 +292,10 @@ common:
memo: "Notizen" memo: "Notizen"
trends: "Trends" trends: "Trends"
photo-stream: "Bilder" photo-stream: "Bilder"
posts-monitor: "Beitrags-Aktivität"
slideshow: "Diashow" slideshow: "Diashow"
version: "Version" version: "Version"
broadcast: "Ankündigungen"
notifications: "Benachrichtigungen" notifications: "Benachrichtigungen"
users: "Empfohlene Benutzer" users: "Empfohlene Benutzer"
polls: "Umfrage" polls: "Umfrage"
@ -183,7 +304,9 @@ common:
nav: "Navigation" nav: "Navigation"
tips: "Tipps" tips: "Tipps"
hashtags: "Hashtags" hashtags: "Hashtags"
queue: "Warteschlange"
dev: "Fehler beim Erstellen der Applikation. Bitte versuche es erneut." dev: "Fehler beim Erstellen der Applikation. Bitte versuche es erneut."
ai-chan-kawaii: "Ai-chan kawaii!"
you: "Du" you: "Du"
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?"
@ -193,17 +316,37 @@ auth/views/form.vue:
auth/views/index.vue: auth/views/index.vue:
loading: "Lädt" loading: "Lädt"
denied: "Autorisierung der Anwendung wurde verweigert." denied: "Autorisierung der Anwendung wurde verweigert."
denied-paragraph: "Diese App kann nicht auf deinen Account zugreifen."
already-authorized: "Diese Anwendung ist bereits autorisiert." already-authorized: "Diese Anwendung ist bereits autorisiert."
allowed: "Autorisierung der Anwendung wurde erlaubt." allowed: "Autorisierung der Anwendung wurde erlaubt."
callback-url: "Zur App zurückkehren"
please-go-back: "Bitte gehe zurück zur Anwendung." please-go-back: "Bitte gehe zurück zur Anwendung."
error: "Sitzung ist nicht vorhanden." error: "Sitzung ist nicht vorhanden."
sign-in: "Bitte melde dich an." sign-in: "Bitte melde dich an."
common/views/pages/explore.vue:
pinned-users: "Vorgeschlagen"
popular-users: "Beliebt"
recently-updated-users: "Kürzlich aktiv"
recently-registered-users: "Neue Benutzer"
popular-tags: "Beliebte Tags"
federated: "Aus dem Fediverse"
explore: "{host} erkunden"
users-info: "Momentan sind {users} Nutzer hier registriert"
common/views/components/url-preview.vue:
enable-player: "Player öffnen"
disable-player: "Player schließen"
common/views/components/user-list.vue:
no-users: "Keine Benutzer"
common/views/components/games/reversi/reversi.vue: common/views/components/games/reversi/reversi.vue:
matching: matching:
waiting-for: "Warten auf {}" waiting-for: "Warten auf {}"
cancel: "Abbrechen" cancel: "Abbrechen"
common/views/components/games/reversi/reversi.game.vue: common/views/components/games/reversi/reversi.game.vue:
surrender: "Aufgeben" surrender: "Aufgeben"
surrendered: "durch Aufgabe"
is-llotheo: "Der niedrigere gewinnt (Llotheo)"
looped-map: "Spielbrettenden verbinden"
can-put-everywhere: "Setzen ist überall erlaubt"
common/views/components/games/reversi/reversi.index.vue: common/views/components/games/reversi/reversi.index.vue:
title: "Misskey Reversi" title: "Misskey Reversi"
sub-title: "Spiele Reversi mit deinen Freunden!" sub-title: "Spiele Reversi mit deinen Freunden!"
@ -221,7 +364,14 @@ common/views/components/games/reversi/reversi.room.vue:
black-or-white: "Schwarz/Weiß" black-or-white: "Schwarz/Weiß"
black-is: "Schwarz ist {}" black-is: "Schwarz ist {}"
rules: "Regeln" rules: "Regeln"
is-llotheo: "Der niedrigere gewinnt (Llotheo)"
looped-map: "Spielbrettenden verbinden"
can-put-everywhere: "Setzen ist überall erlaubt"
settings-of-the-bot: "Bot-Einstellungen"
this-game-is-started-soon: "Spiel beginnt gleich"
waiting-for-other: "Warte auf den Gegner" waiting-for-other: "Warte auf den Gegner"
waiting-for-me: "Warten, bis du bereit bist"
waiting-for-both: "Vorbereiten…"
cancel: "Abbrechen" cancel: "Abbrechen"
ready: "Bereit" ready: "Bereit"
common/views/components/connect-failed.vue: common/views/components/connect-failed.vue:
@ -252,10 +402,13 @@ common/views/components/media-banner.vue:
sensitive: "Dieser Inhalt ist NSFW" sensitive: "Dieser Inhalt ist NSFW"
click-to-show: "Klicke zum den Inhalt anzusehen" click-to-show: "Klicke zum den Inhalt anzusehen"
common/views/components/theme.vue: common/views/components/theme.vue:
theme: "Design"
light-theme: "Thema" light-theme: "Thema"
dark-theme: "Thema während des Nachtmodus" dark-theme: "Thema während des Nachtmodus"
light-themes: "Helles Thema" light-themes: "Helles Thema"
dark-themes: "Dunkles Thema" dark-themes: "Dunkles Thema"
install-a-theme: "Design wird installiert"
theme-code: "Design-Quelltext"
install: "Anwenden" install: "Anwenden"
installed: "\"{}\" wurde installiert" installed: "\"{}\" wurde installiert"
create-a-theme: "Thema erstellen" create-a-theme: "Thema erstellen"
@ -266,24 +419,39 @@ common/views/components/theme.vue:
base-theme: "Basisthema" base-theme: "Basisthema"
base-theme-light: "Hell" base-theme-light: "Hell"
base-theme-dark: "Dunkel" base-theme-dark: "Dunkel"
find-more-theme: "Mehr Designs finden"
theme-name: "Name des Themas" theme-name: "Name des Themas"
preview-created-theme: "Vorschau" preview-created-theme: "Vorschau"
invalid-theme: "Thema ist ungültig" invalid-theme: "Thema ist ungültig"
already-installed: "Thema ist bereits installiert" already-installed: "Thema ist bereits installiert"
saved: "Gespeichert"
manage-themes: "Designs verwalten"
builtin-themes: "Standard-Designs"
my-themes: "Meine Designs"
installed-themes: "Installierte Designs"
select-theme: "Design wählen"
uninstall: "Deinstallieren"
uninstalled: "„{}“ wurde deinstalliert"
author: "Autor" author: "Autor"
desc: "Beschreibung" desc: "Beschreibung"
export: "Exportieren" export: "Exportieren"
import: "Importieren" import: "Importieren"
import-by-code: "oder Quelltext einfügen"
theme-name-required: "Design-Name ist erforderlich"
common/views/components/cw-button.vue: common/views/components/cw-button.vue:
hide: "Ausblenden"
show: "Mehr"
chars: "{count} Zeichen"
files: "{count} Dateien"
poll: "Umfrage" poll: "Umfrage"
common/views/components/messaging.vue: common/views/components/messaging.vue:
search-user: "Einen Nutzer suchen" search-user: "Einen Nutzer suchen"
you: "Du" you: "Du"
no-history: "Keine Chronik" no-history: "Keine Chronik"
user: "Benutzer"
group: "Gruppen"
common/views/components/messaging-room.vue: common/views/components/messaging-room.vue:
empty: "Keine Unterhaltungen"
no-history: "Keine weitere Chronik vorhanden" no-history: "Keine weitere Chronik vorhanden"
resize-form: "Ziehen um die Größe zu verändern"
new-message: "Neue Nachricht" new-message: "Neue Nachricht"
common/views/components/messaging-room.form.vue: common/views/components/messaging-room.form.vue:
input-message-here: "Nachricht hier eingeben" input-message-here: "Nachricht hier eingeben"
@ -303,12 +471,28 @@ common/views/components/nav.vue:
develop: "Entwickler" develop: "Entwickler"
feedback: "Feedback" feedback: "Feedback"
common/views/components/note-menu.vue: common/views/components/note-menu.vue:
mention: "Erwähnungen"
detail: "Details"
copy-content: "Inhalt kopieren"
copy-link: "Link kopieren"
favorite: "Diesen Beitrag favorisieren" favorite: "Diesen Beitrag favorisieren"
unfavorite: "Aus Favoriten entfernen" unfavorite: "Aus Favoriten entfernen"
watch: "Beobachten"
unwatch: "Nicht mehr beobachten"
pin: "An die Profilseite pinnen" pin: "An die Profilseite pinnen"
unpin: "Lösen"
delete: "Löschen" delete: "Löschen"
delete-confirm: "Diesen Beitrag löschen?" delete-confirm: "Diesen Beitrag löschen?"
remote: "Auf Quelle anzeigen" remote: "Auf Quelle anzeigen"
common/views/components/user-menu.vue:
mention: "Erwähnungen"
mute: "Stummschalten"
unmute: "Stummschaltung aufheben"
mute-confirm: "Bist du sicher, dass du diesen Nutzer stummschalten möchtest?"
unmute-confirm: "Stummschaltung für diesen Nutzer aufheben?"
block: "Sperren"
unblock: "Sperrung aufheben"
block-confirm: "Diesen Nutzer wirklich sperren?"
common/views/components/poll.vue: common/views/components/poll.vue:
vote-to: "Stimme für '{}'" vote-to: "Stimme für '{}'"
vote-count: "{} Stimmen" vote-count: "{} Stimmen"
@ -386,6 +570,14 @@ common/views/components/profile-editor.vue:
export-targets: export-targets:
user-lists: "Listen" user-lists: "Listen"
enter-password: "Bitte Passwort eingeben" enter-password: "Bitte Passwort eingeben"
common/views/components/user-group-editor.vue:
invite: "Einladen"
common/views/components/user-lists.vue:
user-lists: "Listen"
common/views/components/user-groups.vue:
user-groups: "Gruppen"
owned-groups: "Meine Gruppen"
invites: "Einladen"
common/views/widgets/broadcast.vue: common/views/widgets/broadcast.vue:
fetching: "Laden" fetching: "Laden"
no-broadcasts: "Keine Broadcasts" no-broadcasts: "Keine Broadcasts"
@ -395,6 +587,7 @@ common/views/widgets/photo-stream.vue:
title: "Fotostream" title: "Fotostream"
no-photos: "Keine Fotos" no-photos: "Keine Fotos"
common/views/widgets/posts-monitor.vue: common/views/widgets/posts-monitor.vue:
title: "Beitrags-Aktivität"
toggle: "Sicht umschalten" toggle: "Sicht umschalten"
common/views/widgets/server.vue: common/views/widgets/server.vue:
title: "Serverinformationen" title: "Serverinformationen"
@ -482,7 +675,7 @@ desktop/views/components/followers.vue:
desktop/views/components/following.vue: desktop/views/components/following.vue:
empty: "Du folgst niemanden" empty: "Du folgst niemanden"
desktop/views/components/home.vue: desktop/views/components/home.vue:
done: "Verbunden" done: "Beenden"
add-widget: "Widget hinzufügen:" add-widget: "Widget hinzufügen:"
add: "Hinzufügen" add: "Hinzufügen"
desktop/views/input-dialog.vue: desktop/views/input-dialog.vue:
@ -496,7 +689,8 @@ desktop/views/components/note-detail.vue:
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: "Anmerken" renote: "Anmerkung"
detail: "Details"
private: "Dieser Beitrag 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:
@ -505,27 +699,12 @@ desktop/views/components/notes.vue:
desktop/views/components/notifications.vue: desktop/views/components/notifications.vue:
empty: "Keine Benachrichtigungen" empty: "Keine Benachrichtigungen"
desktop/views/components/post-form.vue: desktop/views/components/post-form.vue:
add-visible-user: "+Nutzer hinzufügen"
hide-contents: "Inhalt verstecken"
reply-placeholder: "Antworte auf diese Anmerkung..."
quote-placeholder: "Zitiere diese Anmerkung..."
submit: "Abschicken"
reply: "Antworten"
renote: "Anmerken"
posted: "Gepostet!" posted: "Gepostet!"
replied: "Geantwortet!" replied: "Geantwortet!"
reposted: "Weitergesagt!" reposted: "Weitergesagt!"
note-failed: "Anmerkung fehlgeschlagen" note-failed: "Anmerkung fehlgeschlagen"
reply-failed: "Antwort fehlgeschlagen" reply-failed: "Antwort fehlgeschlagen"
renote-failed: "Anmerkung fehlgeschlagen" renote-failed: "Anmerkung fehlgeschlagen"
posting: "Posting"
attach-media-from-local: "Medien von deinem PC hinzufügen"
attach-media-from-drive: "Medien von deinem Speicher hinzufügen"
create-poll: "Eine Abstimmung erstellen"
text-remain: "{} Zeichen verbleibend"
visibility: "Sichtbarkeit"
error: "Fehler"
enter-username: "Bitte gib einen Benutzernamen ein..."
desktop/views/components/post-form-window.vue: desktop/views/components/post-form-window.vue:
note: "Neuer Beitrag" note: "Neuer Beitrag"
reply: "Antworten" reply: "Antworten"
@ -575,6 +754,7 @@ desktop/views/components/timeline.vue:
desktop/views/components/ui.header.account.vue: desktop/views/components/ui.header.account.vue:
profile: "Dein Profil" profile: "Dein Profil"
lists: "Listen" lists: "Listen"
groups: "Gruppen"
desktop/views/components/ui.header.nav.vue: desktop/views/components/ui.header.nav.vue:
game: "Spielen" game: "Spielen"
desktop/views/components/ui.header.notifications.vue: desktop/views/components/ui.header.notifications.vue:
@ -583,17 +763,18 @@ desktop/views/components/ui.header.post.vue:
post: "Einen neuen Post erstellen" post: "Einen neuen Post erstellen"
desktop/views/components/ui.header.search.vue: desktop/views/components/ui.header.search.vue:
placeholder: "Suchen" placeholder: "Suchen"
desktop/views/components/user-lists-window.vue:
title: "Listen"
desktop/views/components/users-list.vue: desktop/views/components/users-list.vue:
fetching: "Lade…" fetching: "Lade…"
admin/views/dashboard.vue: admin/views/dashboard.vue:
drive: "Drive" drive: "Drive"
admin/views/abuse.vue: admin/views/abuse.vue:
details: "Details"
remove-report: "Löschen" remove-report: "Löschen"
admin/views/instance.vue: admin/views/instance.vue:
recaptcha-preview: "Vorschau"
invite: "Einladen" invite: "Einladen"
save: "Speichern" save: "Speichern"
saved: "Gespeichert"
admin/views/charts.vue: admin/views/charts.vue:
drive: "Drive" drive: "Drive"
admin/views/drive.vue: admin/views/drive.vue:
@ -613,8 +794,10 @@ admin/views/announcements.vue:
save: "Speichern" save: "Speichern"
remove: "Löschen" remove: "Löschen"
add: "Hinzufügen" add: "Hinzufügen"
saved: "Gespeichert"
admin/views/federation.vue: admin/views/federation.vue:
status: "Status" status: "Status"
save: "Speichern"
desktop/views/pages/note.vue: desktop/views/pages/note.vue:
prev: "Vorheriger Kommentar" prev: "Vorheriger Kommentar"
next: "Nächster Kommentar" next: "Nächster Kommentar"
@ -659,10 +842,6 @@ mobile/views/components/note-detail.vue:
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:
reply: "Antworten"
renote: "Anmerken"
reply-placeholder: "Antworte auf diese Anmerkung..."
mobile/views/components/sub-note-content.vue: mobile/views/components/sub-note-content.vue:
private: "Dieser Beitrag ist privat" private: "Dieser Beitrag ist privat"
deleted: "Dieser Beitrag wurde entfernt" deleted: "Dieser Beitrag wurde entfernt"
@ -671,14 +850,13 @@ mobile/views/components/ui.nav.vue:
notifications: "Benachrichtigungen" notifications: "Benachrichtigungen"
search: "Suchen" search: "Suchen"
user-lists: "Listen" user-lists: "Listen"
user-groups: "Gruppen"
game: "Spielen" game: "Spielen"
about: "Über" about: "Über"
mobile/views/pages/drive.vue: mobile/views/pages/drive.vue:
contextmenu: contextmenu:
upload: "Eine Datei hochladen" upload: "Eine Datei hochladen"
create-folder: "Ein Verzeichnis erstellen" create-folder: "Ein Verzeichnis erstellen"
mobile/views/pages/user-lists.vue:
title: "Listen"
mobile/views/pages/home.vue: mobile/views/pages/home.vue:
home: "Home" home: "Home"
local: "Lokal" local: "Lokal"
@ -732,6 +910,7 @@ dev/views/new-app.vue:
authority-desc: "Nur die hier eingetragenen Berechtigungen, werden per API zur Verfügung stehen." 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." authority-warning: "Dies kann auch nach dem erstellen der Anwendung geändert werden, allerdings werden dann alle bisher generierten Token ungültig."
pages: pages:
like: "Gefällt mir"
blocks: blocks:
post: "\"Neuer Beitrag\"-Formular" post: "\"Neuer Beitrag\"-Formular"
script: script:
@ -750,5 +929,7 @@ pages:
arg2: "Listen" arg2: "Listen"
_pick: _pick:
arg1: "Listen" arg1: "Listen"
_listLen:
arg1: "Listen"
types: types:
array: "Listen" array: "Listen"

View File

@ -95,6 +95,33 @@ common:
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"
post-form:
attach-location-information: "Attach location information"
hide-contents: "Hide contents"
reply-placeholder: "Reply to this post..."
quote-placeholder: "Quote this Post..."
option-quote-placeholder: "Quote this post... (optional)"
quote-attached: "Quoted"
quote-question: "Do you want to append a quote?"
submit: "Post"
reply: "Reply"
renote: "Renote"
posting: "Posting"
attach-media-from-local: "Attach media from your device"
attach-media-from-drive: "Attach media from your Drive"
insert-a-kao: "v('ω')v"
create-poll: "Create a poll"
text-remain: "{} characters remaining"
recent-tags: "Recent"
local-only-message: "This post will only be published locally"
click-to-tagging: "Click to tagging"
visibility: "Visibility"
geolocation-alert: "Your device does not provide location services"
error: "Error"
enter-username: "Please enter username"
add-visible-user: "Add a user"
cw-placeholder: "Comments for the post (optional)"
username-prompt: "Please enter username"
weekday-short: weekday-short:
sunday: "S" sunday: "S"
monday: "M" monday: "M"
@ -243,6 +270,9 @@ common:
disable-via-mobile: "Don't mark the post as 'from mobile'" disable-via-mobile: "Don't mark the post as 'from mobile'"
load-raw-images: "Show attached images in original quality" load-raw-images: "Show attached images in original quality"
load-remote-media: "Show media from a remote server" load-remote-media: "Show media from a remote server"
sync: "Sync"
home-profile: "Home profile"
deck-profile: "Deck profile"
search: "Search" search: "Search"
delete: "Delete" delete: "Delete"
loading: "Loading" loading: "Loading"
@ -253,6 +283,7 @@ common:
my-token-regenerated: "Your token has been regenerated, so you will be signed out." my-token-regenerated: "Your token has been regenerated, so you will be signed out."
hide-password: "Hide Password" hide-password: "Hide Password"
show-password: "Show Password" show-password: "Show Password"
enter-username: "Please enter username"
do-not-use-in-production: "This is a development build. Do not use in production." do-not-use-in-production: "This is a development build. Do not use in production."
user-suspended: "This user has been suspended." user-suspended: "This user has been suspended."
is-remote-user: "The information about this user may not be entirely complete." is-remote-user: "The information about this user may not be entirely complete."
@ -318,7 +349,7 @@ auth/views/index.vue:
error: "Session does not exist." error: "Session does not exist."
sign-in: "Please sign in." sign-in: "Please sign in."
common/views/pages/explore.vue: common/views/pages/explore.vue:
pinned-users: "Higlighted users" pinned-users: "Pinned users"
popular-users: "Popular users" popular-users: "Popular users"
recently-updated-users: "Recently active users" recently-updated-users: "Recently active users"
recently-registered-users: "Users who joined recently" recently-registered-users: "Users who joined recently"
@ -448,18 +479,23 @@ common/views/components/messaging.vue:
search-user: "Find a user" search-user: "Find a user"
you: "You" you: "You"
no-history: "Without history" no-history: "Without history"
user: "User"
group: "Group"
start-with-user: "Start chatting with a user"
start-with-group: "Start a group and chat"
select-group: "Select a group"
common/views/components/messaging-room.vue: common/views/components/messaging-room.vue:
empty: "No conversations" not-talked-user: "You have not talked to this user yet"
not-talked-group: "There is no conversation in this group"
no-history: "There is no further history" no-history: "There is no further history"
resize-form: "Drag to resize"
new-message: "New message" new-message: "New message"
only-one-file-attached: "Only ONE file can be attached to a message." only-one-file-attached: "You can only attach one file to a message"
common/views/components/messaging-room.form.vue: common/views/components/messaging-room.form.vue:
input-message-here: "Enter message here" input-message-here: "Enter message here"
send: "Send" send: "Send"
attach-from-local: "Attach files from your device" attach-from-local: "Attach files from your device"
attach-from-drive: "Attach files from your Drive" attach-from-drive: "Attach files from your Drive"
only-one-file-attached: "Only one file can be attached to the message." only-one-file-attached: "You can only attach one file to a message"
common/views/components/messaging-room.message.vue: common/views/components/messaging-room.message.vue:
is-read: "Read" is-read: "Read"
deleted: "This message has been deleted" deleted: "This message has been deleted"
@ -472,6 +508,7 @@ common/views/components/nav.vue:
repository: "Repository" repository: "Repository"
develop: "Developers" develop: "Developers"
feedback: "Feedback" feedback: "Feedback"
tos: "Terms Of Service"
common/views/components/note-menu.vue: common/views/components/note-menu.vue:
mention: "Mention" mention: "Mention"
detail: "Details" detail: "Details"
@ -543,6 +580,7 @@ common/views/components/poll-editor.vue:
day: "S" day: "S"
common/views/components/reaction-picker.vue: common/views/components/reaction-picker.vue:
choose-reaction: "Send a reaction" choose-reaction: "Send a reaction"
input-reaction-placeholder: "or input Emoji"
common/views/components/emoji-picker.vue: common/views/components/emoji-picker.vue:
custom-emoji: "Custom Emoji" custom-emoji: "Custom Emoji"
people: "People" people: "People"
@ -584,6 +622,8 @@ common/views/components/signup.vue:
password-matched: "OK" password-matched: "OK"
password-not-matched: "Doesn't match" password-not-matched: "Doesn't match"
recaptcha: "Verification" recaptcha: "Verification"
agree-to: "Accept {0}."
tos: "Terms Of Service"
create: "Create an Account" create: "Create an Account"
some-error: "An attempt at account creation has failed for some reason. Please try again." some-error: "An attempt at account creation has failed for some reason. Please try again."
common/views/components/special-message.vue: common/views/components/special-message.vue:
@ -691,9 +731,32 @@ common/views/components/user-list-editor.vue:
remove-user: "Remove from this list" remove-user: "Remove from this list"
delete-are-you-sure: "Delete list \"$1\"?" delete-are-you-sure: "Delete list \"$1\"?"
deleted: "Deleted successfully" deleted: "Deleted successfully"
add-user: "Add a user"
common/views/components/user-group-editor.vue:
users: "Members"
rename: "Rename group"
delete: "Delete group"
transfer: "transfer group"
transfer-are-you-sure: "Are you sure you want to add @$2 to the group $1?"
transferred: "Group transferred"
remove-user: "Remove a user from this group"
delete-are-you-sure: "Are you sure to delete group \"$1\"?"
deleted: "Deleted"
invite: "Invite"
invited: "The invitation was successfully sent"
common/views/components/user-lists.vue: common/views/components/user-lists.vue:
user-lists: "Lists"
create-list: "Create a list" create-list: "Create a list"
list-name: "List name" list-name: "List name"
common/views/components/user-groups.vue:
user-groups: "Groups"
create-group: "Create a group"
group-name: "Group name"
owned-groups: "My groups"
joined-groups: "Membership in groups"
invites: "Invite"
accept-invite: "Join"
reject-invite: "Decline"
common/views/widgets/broadcast.vue: common/views/widgets/broadcast.vue:
fetching: "Checking" fetching: "Checking"
no-broadcasts: "No announcements" no-broadcasts: "No announcements"
@ -755,6 +818,10 @@ common/views/pages/follow.vue:
request-pending: "Pending follow request" request-pending: "Pending follow request"
follow-processing: "Processing follow" follow-processing: "Processing follow"
follow-request: "Follow request" follow-request: "Follow request"
common/views/pages/follow-requests.vue:
received-follow-requests: "Follow requests"
accept: "Accept"
reject: "Reject"
desktop: desktop:
banner-crop-title: "Crop the part that appears as a banner" banner-crop-title: "Crop the part that appears as a banner"
banner: "Banner" banner: "Banner"
@ -771,7 +838,7 @@ desktop/views/components/activity.chart.vue:
total: "Black ... Total" total: "Black ... Total"
notes: "Blue ... Notes" notes: "Blue ... Notes"
replies: "Red ... Replies" replies: "Red ... Replies"
renotes: "Green ... Repost" renotes: "Green ... Renotes"
desktop/views/components/activity.vue: desktop/views/components/activity.vue:
title: "Activity" title: "Activity"
toggle: "Toggle views" toggle: "Toggle views"
@ -868,7 +935,7 @@ desktop/views/components/note-detail.vue:
private: "Post is private" private: "Post is private"
deleted: "Post has been removed" deleted: "Post has been removed"
location: "Location" location: "Location"
renote: "Repost" renote: "Renote"
add-reaction: "Add a reaction" add-reaction: "Add a reaction"
undo-reaction: "Reverse reaction" undo-reaction: "Reverse reaction"
desktop/views/components/note.vue: desktop/views/components/note.vue:
@ -885,34 +952,12 @@ desktop/views/components/notes.vue:
desktop/views/components/notifications.vue: desktop/views/components/notifications.vue:
empty: "No notifications!" empty: "No notifications!"
desktop/views/components/post-form.vue: desktop/views/components/post-form.vue:
add-visible-user: "+Add a user"
attach-location-information: "Attach location information"
hide-contents: "Hide contents"
reply-placeholder: "Reply to this post..."
quote-placeholder: "Quote this Post..."
submit: "Post"
reply: "Reply"
renote: "Repost"
posted: "Posted!" posted: "Posted!"
replied: "Replied!" replied: "Replied!"
reposted: "Reposted!" reposted: "Renoted!"
note-failed: "Failed to post" note-failed: "Failed to post"
reply-failed: "Failed to reply" reply-failed: "Failed to reply"
renote-failed: "Failed to Renote" renote-failed: "Failed to Renote"
posting: "Posting"
attach-media-from-local: "Attach media from your device"
attach-media-from-drive: "Attach media from your Drive"
insert-a-kao: "v('ω')v"
create-poll: "Create a poll"
text-remain: "{} characters remaining"
recent-tags: "Recent"
local-only-message: "This post will only be published locally"
click-to-tagging: "Click to tagging"
visibility: "Visibility"
geolocation-alert: "Your device does not provide location services."
error: "Error"
enter-username: "Please enter a username..."
annotations: "Annotations for the post (optional)"
desktop/views/components/post-form-window.vue: desktop/views/components/post-form-window.vue:
note: "New Post" note: "New Post"
reply: "Reply" reply: "Reply"
@ -923,13 +968,13 @@ desktop/views/components/progress-dialog.vue:
desktop/views/components/renote-form.vue: desktop/views/components/renote-form.vue:
quote: "Quote..." quote: "Quote..."
cancel: "Cancel" cancel: "Cancel"
renote: "Repost" renote: "Renote"
renote-home: "Renote (Home)" renote-home: "Renote (Home)"
reposting: "Renoting..." reposting: "Renoting..."
success: "Reposted!" success: "Renoted!"
failure: "Failed to Repost" failure: "Failed to Renote"
desktop/views/components/renote-form-window.vue: desktop/views/components/renote-form-window.vue:
title: "Do you want to Renote it?" title: "Do you want to renote it?"
desktop/views/pages/user-following-or-followers.vue: desktop/views/pages/user-following-or-followers.vue:
following: "{user}'s following" following: "{user}'s following"
followers: "{user}'s follower" followers: "{user}'s follower"
@ -1026,6 +1071,7 @@ desktop/views/components/ui.header.vue:
desktop/views/components/ui.header.account.vue: desktop/views/components/ui.header.account.vue:
profile: "Your profile" profile: "Your profile"
lists: "Lists" lists: "Lists"
groups: "Groups"
follow-requests: "Follow requests" follow-requests: "Follow requests"
admin: "Admin" admin: "Admin"
desktop/views/components/ui.header.nav.vue: desktop/views/components/ui.header.nav.vue:
@ -1036,12 +1082,6 @@ desktop/views/components/ui.header.post.vue:
post: "Compose new Post" post: "Compose new Post"
desktop/views/components/ui.header.search.vue: desktop/views/components/ui.header.search.vue:
placeholder: "Search" placeholder: "Search"
desktop/views/components/received-follow-requests-window.vue:
title: "Follow requests"
accept: "Accept"
reject: "Reject"
desktop/views/components/user-lists-window.vue:
title: "User lists"
desktop/views/components/user-preview.vue: desktop/views/components/user-preview.vue:
notes: "Posts" notes: "Posts"
following: "Following" following: "Following"
@ -1063,11 +1103,13 @@ admin/views/index.vue:
users: "Users" users: "Users"
federation: "Federation" federation: "Federation"
announcements: "Announcements" announcements: "Announcements"
hashtags: "Hashtags"
abuse: "Abuse" abuse: "Abuse"
queue: "Job Queue" queue: "Job Queue"
logs: "Logs" logs: "Logs"
db: "Database"
back-to-misskey: "Back to Misskey" back-to-misskey: "Back to Misskey"
admin/views/db.vue:
tables: "Tables"
admin/views/dashboard.vue: admin/views/dashboard.vue:
dashboard: "Dashboard" dashboard: "Dashboard"
accounts: "Accounts" accounts: "Accounts"
@ -1079,6 +1121,32 @@ admin/views/dashboard.vue:
admin/views/queue.vue: admin/views/queue.vue:
title: "Queue" title: "Queue"
remove-all-jobs: "Clear all queued jobs" remove-all-jobs: "Clear all queued jobs"
jobs: "Jobs"
queue: "Queue"
domains:
deliver: "Delivers"
inbox: "Received"
db: "Database"
objectStorage: "Object Storage"
state: "Sort"
states:
active: "Running"
delayed: "Scheduled"
waiting: "Queued"
result-is-truncated: "Result is truncated"
other-queues: "Other queues"
admin/views/logs.vue:
logs: "Logs"
domain: "Domain"
level: "Level"
levels:
all: "All"
info: "Information"
success: "Success"
warning: "Warning"
error: "Error"
debug: "Debug"
delete-all: "Remove All"
admin/views/abuse.vue: admin/views/abuse.vue:
title: "Abuse" title: "Abuse"
target: "Target" target: "Target"
@ -1090,14 +1158,34 @@ admin/views/instance.vue:
instance-name: "Instance name" instance-name: "Instance name"
instance-description: "Instance description" instance-description: "Instance description"
host: "Host" host: "Host"
icon-url: "URL of the icon"
logo-url: "URL of the logo"
banner-url: "Banner image URL" banner-url: "Banner image URL"
error-image-url: "Error image URL" error-image-url: "Error image URL"
languages: "Language of this instance" languages: "Language of this instance"
languages-desc: "You can add more than one, separated by spaces." languages-desc: "You can add more than one, separated by spaces."
tos-url: "Terms of Service URL"
repository-url: "Repository URL"
feedback-url: "URL for feedback"
maintainer-config: "Administrator information" maintainer-config: "Administrator information"
maintainer-name: "Administrator name" maintainer-name: "Administrator name"
maintainer-email: "Contact Administrator" maintainer-email: "Contact Administrator"
advanced-config: "Other settings"
note-and-tl: "Notes and timelines"
drive-config: "Drive settings" drive-config: "Drive settings"
use-object-storage: "Use Object Storage"
object-storage-base-url: "URL"
object-storage-bucket: "Bucket Name"
object-storage-prefix: "Prefix"
object-storage-endpoint: "Endpoint"
object-storage-region: "Region"
object-storage-port: "Port"
object-storage-access-key: "Access Key"
object-storage-secret-key: "Secret Key"
object-storage-use-ssl: "Use SSL"
object-storage-s3-info: "If you are going to use Amazon S3 as Object Storage, Please refer {0} to configure 'Endpoint' and 'Region'."
object-storage-s3-info-here: "here"
object-storage-gcs-info: "If you are going to use Google Cloud Storage as Object Storage, Set the 'Endpoint' as storage.googleapis.com, and keep the 'Region' is blank."
cache-remote-files: "Cache remote files" cache-remote-files: "Cache remote files"
cache-remote-files-desc: "Without this parameter, all remote files are linked to their host server directly. This will be an effective solution to save your server storage, however make remote files invisible to users who set direct-link disabled, since no thumbnail will be generated, increase traffic. It is recommended that this parameter set enabled." cache-remote-files-desc: "Without this parameter, all remote files are linked to their host server directly. This will be an effective solution to save your server storage, however make remote files invisible to users who set direct-link disabled, since no thumbnail will be generated, increase traffic. It is recommended that this parameter set enabled."
local-drive-capacity-mb: "Volume of Drive per user" local-drive-capacity-mb: "Volume of Drive per user"
@ -1105,9 +1193,14 @@ admin/views/instance.vue:
mb: "In megabytes" mb: "In megabytes"
recaptcha-config: "the reCAPTCHA settings" recaptcha-config: "the reCAPTCHA settings"
recaptcha-info: "reCAPTCHA token is required. Please get it on https://www.google.com/recaptcha/intro/" recaptcha-info: "reCAPTCHA token is required. Please get it on https://www.google.com/recaptcha/intro/"
recaptcha-info2: "v3 is not supported. Please use v2."
enable-recaptcha: "enable reCAPTCHA" enable-recaptcha: "enable reCAPTCHA"
recaptcha-site-key: "reCAPTCHA site key" recaptcha-site-key: "Site key"
recaptcha-secret-key: "reCAPTCHA secret key" recaptcha-secret-key: "Secret Key"
recaptcha-preview: "Preview"
hidden-tags: "Hidden hashtags"
hidden-tags-info: "List up the hashtags delimited by line breaks that you want exclude from statistics."
external-service-integration-config: "Connect an external service"
twitter-integration-config: "Settings of connecting to Twitter" twitter-integration-config: "Settings of connecting to Twitter"
twitter-integration-info: "The callback URL is set on {url}." twitter-integration-info: "The callback URL is set on {url}."
enable-twitter-integration: "Enable connection to Twitter" enable-twitter-integration: "Enable connection to Twitter"
@ -1138,7 +1231,8 @@ admin/views/instance.vue:
invite: "Invite" invite: "Invite"
save: "Save" save: "Save"
saved: "Saved" saved: "Saved"
pinned-users: "Higlighted user" pinned-users: "Pinned user"
pinned-users-info: "List up the users delimited by line breaks that you want to show as 'Pinned Users'."
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"
@ -1204,6 +1298,9 @@ admin/views/drive.vue:
unmark-as-sensitive: "Unmark as 'sensitive'" unmark-as-sensitive: "Unmark as 'sensitive'"
marked-as-sensitive: "Set a sensitive content notice" marked-as-sensitive: "Set a sensitive content notice"
unmarked-as-sensitive: "Remove the sensitive content notice" unmarked-as-sensitive: "Remove the sensitive content notice"
clean-remote-files: "Clear the remote files cache"
clean-remote-files-are-you-sure: "Are you sure you want to remove all cached files from remote?"
clean-up: "Clean up"
admin/views/users.vue: admin/views/users.vue:
operation: "Operations" operation: "Operations"
username-or-userid: "Username or user ID" username-or-userid: "Username or user ID"
@ -1224,6 +1321,8 @@ admin/views/users.vue:
unsilence-confirm: "Are you certain that you want to stop silencing this user?" unsilence-confirm: "Are you certain that you want to stop silencing this user?"
update-remote-user: "Update information about remote user" update-remote-user: "Update information about remote user"
remote-user-updated: "The information regarding the remote user has been updated." remote-user-updated: "The information regarding the remote user has been updated."
delete-all-files: "Delete all files"
delete-all-files-confirm: "Are you sure that you want to delete all files?"
users: users:
title: "Users" title: "Users"
sort: sort:
@ -1299,6 +1398,7 @@ admin/views/federation.vue:
latest-request-received-at: "Last request received at" latest-request-received-at: "Last request received at"
remove-all-following: "Withold all followers" remove-all-following: "Withold all followers"
remove-all-following-info: "Unfollow all accounts from {host}. Please run this if the instance no longer exists." remove-all-following-info: "Unfollow all accounts from {host}. Please run this if the instance no longer exists."
delete-all-files: "Remove all files"
block: "Block" block: "Block"
marked-as-closed: "Marked as closed" marked-as-closed: "Marked as closed"
lookup: "Look up" lookup: "Look up"
@ -1346,6 +1446,8 @@ admin/views/federation.vue:
hour: "Hourly" hour: "Hourly"
day: "Daily" day: "Daily"
blocked-hosts: "Blocking" blocked-hosts: "Blocking"
blocked-hosts-info: "List up the hosts delimited by line breaks that you want to block."
save: "Save"
desktop/views/pages/welcome.vue: desktop/views/pages/welcome.vue:
about: "More details..." about: "More details..."
timeline: "Timeline" timeline: "Timeline"
@ -1477,17 +1579,6 @@ mobile/views/components/note-sub.vue:
cat: "cat" cat: "cat"
mobile/views/components/notifications.vue: mobile/views/components/notifications.vue:
empty: "No notifications" empty: "No notifications"
mobile/views/components/post-form.vue:
add-visible-user: "Add a user"
submit: "Post"
reply: "Reply"
renote: "Renote"
quote-placeholder: "Quote this post... (optional)"
reply-placeholder: "Reply to this note..."
cw-placeholder: "Comments for the post (optional)"
geolocation-alert: "Your device does not provide location services."
error: "Error"
username-prompt: "Enter user name"
mobile/views/components/sub-note-content.vue: mobile/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"
@ -1502,6 +1593,7 @@ mobile/views/components/ui.nav.vue:
follow-requests: "Follow requests" follow-requests: "Follow requests"
search: "Search" search: "Search"
user-lists: "Lists" user-lists: "Lists"
user-groups: "Groups"
widgets: "Widgets" widgets: "Widgets"
game: "Games" game: "Games"
admin: "Admin" admin: "Admin"
@ -1514,8 +1606,6 @@ mobile/views/pages/drive.vue:
rename-folder: "Rename folder" rename-folder: "Rename folder"
move-folder: "Move this folder" move-folder: "Move this folder"
delete-folder: "Delete this folder" delete-folder: "Delete this folder"
mobile/views/pages/user-lists.vue:
title: "Lists"
mobile/views/pages/signup.vue: mobile/views/pages/signup.vue:
lets-start: "Your account is now ready! 📦" lets-start: "Your account is now ready! 📦"
mobile/views/pages/followers.vue: mobile/views/pages/followers.vue:
@ -1540,10 +1630,6 @@ mobile/views/pages/widgets/activity.vue:
activity: "Activity" activity: "Activity"
mobile/views/pages/share.vue: mobile/views/pages/share.vue:
share-with: "Share on {name}" share-with: "Share on {name}"
mobile/views/pages/received-follow-requests.vue:
title: "Follow requests"
accept: "Accept"
reject: "Reject"
mobile/views/pages/note.vue: mobile/views/pages/note.vue:
title: "Post" title: "Post"
prev: "Previous note" prev: "Previous note"
@ -1649,9 +1735,17 @@ pages:
edit-this-page: "Edit this page" edit-this-page: "Edit this page"
view-source: "View Source" view-source: "View Source"
view-page: "View page" view-page: "View page"
like: "Like"
unlike: "Unlike"
liked-pages: "Favorite pages"
my-pages: "My pages"
inspector: "Inspector" inspector: "Inspector"
content: "Page block" content: "Page block"
variables: "Variables" variables: "Variables"
variables-info: "You can make your page more dynamic by using variables. If you write down <b>{ variable name }</b> in the text, you can embed the value of the variable there. For example, if the source text is <b>Hello { thing } world!</b> and the value of variable 'thing' is <b> ai </b>, that text becomes to <b>Hello ai world!</b>."
variables-info2: "Because the evaluation(=calculating) of variables are performed from top to bottom, the variable cannot refer another variable which exists on later line. For example, when defining three variables <b>A</b>, <b>B</b> and <b>C</b>, variable <b>C</b> <i>can</i> refer the variable <b>A</b> and <b>B</b> in its expression, but variable <b>A</b> <i>cannot</i> refer the variable <b>B</b> or <b>C</b> in its expression."
variables-info3: "If you want to get some input from the user, place a 'User Input' block on the page and set the variable name as which you want to store that input in 'variable name' (variables are created automatically). You can use that variable to perform actions in response to user's input."
variables-info4: "Function allows make your processing logic as group in a reusable way. To create a function, create a variable of type 'Function'. A function can have a slot (Argument) whose value is available as a variable in the function. There are also functions that take functions as arguments in the AiScript standard (called the higher-order function.). In addition to the predefined functions, you can also set them in the slots of such higher-order functions on the fly."
more-details: "Description" more-details: "Description"
title: "Title" title: "Title"
url: "Page URL" url: "Page URL"
@ -1749,6 +1843,7 @@ pages:
strReverse: "Flip text" strReverse: "Flip text"
_strReverse: _strReverse:
arg1: "Text" arg1: "Text"
join: "Text Concatenation"
_join: _join:
arg1: "Lists" arg1: "Lists"
arg2: "Separator" arg2: "Separator"
@ -1768,7 +1863,8 @@ pages:
_divide: _divide:
arg1: "A" arg1: "A"
arg2: "B" arg2: "B"
_remind: mod: "÷ Remaindering"
_mod:
arg1: "A" arg1: "A"
arg2: "B" arg2: "B"
eq: "A and B are equal" eq: "A and B are equal"
@ -1831,21 +1927,28 @@ pages:
dailyRandomPick: "Choose at random from the list (Daily for each user)" dailyRandomPick: "Choose at random from the list (Daily for each user)"
_dailyRandomPick: _dailyRandomPick:
arg1: "Lists" arg1: "Lists"
seedRandom: "Random (Seed)"
_seedRandom: _seedRandom:
arg1: "Seed" arg1: "Seed"
arg2: "Probability" arg2: "Probability"
seedRannum: "Random number (Seed)"
_seedRannum: _seedRannum:
arg1: "Seed" arg1: "Seed"
arg2: "Minimum" arg2: "Minimum"
arg3: "Maximum" arg3: "Maximum"
seedRandomPick: "Randomly selected from list (Seed)"
_seedRandomPick: _seedRandomPick:
arg1: "Seed" arg1: "Seed"
arg2: "Lists" arg2: "Lists"
DRPWPM: "Randomly selected from weighted list (Daily updated per user)"
_DRPWPM: _DRPWPM:
arg1: "List of text" arg1: "List of text"
pick: "Select from list"
_pick: _pick:
arg1: "Lists" arg1: "Lists"
arg2: "Position" arg2: "Position"
_listLen:
arg1: "Lists"
number: "Number" number: "Number"
stringToNumber: "Text to number" stringToNumber: "Text to number"
_stringToNumber: _stringToNumber:
@ -1860,8 +1963,13 @@ pages:
fn: "Function" fn: "Function"
_fn: _fn:
slots: "Slots" slots: "Slots"
slots-info: "Please delimit each slot with a line break"
arg1: "Output" arg1: "Output"
for: "Repeat" for: "Repeat"
_for:
arg1: "Count"
arg2: "Action"
typeError: "Slot {slot} accepts \"{expect}\" type, but It actually contains \"{actual}\" type!"
thereIsEmptySlot: "Slot {slot} is empty!" thereIsEmptySlot: "Slot {slot} is empty!"
types: types:
string: "Text" string: "Text"

View File

@ -80,6 +80,11 @@ common:
"read:notifications": "Ver notificaciones" "read:notifications": "Ver notificaciones"
"read:reactions": "Ver reacciones" "read:reactions": "Ver reacciones"
"write:votes": "Vota" "write:votes": "Vota"
post-form:
reply: "Responder"
renote: "Volver a publicar"
enter-username: "Ingresar nombre de usuario"
username-prompt: "Ingresar nombre de usuario"
weekday-short: weekday-short:
sunday: "domingo" sunday: "domingo"
monday: "lunes" monday: "lunes"
@ -202,6 +207,7 @@ common:
my-token-regenerated: "Tu token se ha regenerado vas a ser desconectado." my-token-regenerated: "Tu token se ha regenerado vas a ser desconectado."
hide-password: "Ocultar contraseña" hide-password: "Ocultar contraseña"
show-password: "Mostrar contraseña" show-password: "Mostrar contraseña"
enter-username: "Ingresar nombre de usuario"
do-not-use-in-production: "Esto está en desarrollo, no usarlo para producción." do-not-use-in-production: "Esto está en desarrollo, no usarlo para producción."
user-suspended: "Este usuario ha sido suspendido" user-suspended: "Este usuario ha sido suspendido"
is-remote-user: "La información sobre este usuario puede no estar completa" is-remote-user: "La información sobre este usuario puede no estar completa"
@ -395,17 +401,13 @@ common/views/components/messaging.vue:
you: "Tu" you: "Tu"
no-history: "Sin historial" no-history: "Sin historial"
common/views/components/messaging-room.vue: common/views/components/messaging-room.vue:
empty: "Sin conversaciones"
no-history: "El historial se ha acabado" no-history: "El historial se ha acabado"
resize-form: "Arrastra para redimensionar"
new-message: "Nuevo mensaje" new-message: "Nuevo mensaje"
only-one-file-attached: "Un único archivo se puede conectar al mensaje"
common/views/components/messaging-room.form.vue: common/views/components/messaging-room.form.vue:
input-message-here: "Escribe el mensaje aquí" input-message-here: "Escribe el mensaje aquí"
send: "Enviar" send: "Enviar"
attach-from-local: "Adjunta ficheros desde tu PC" attach-from-local: "Adjunta ficheros desde tu PC"
attach-from-drive: "Adjunta ficheros desde tu disco" attach-from-drive: "Adjunta ficheros desde tu disco"
only-one-file-attached: "Un único archivo se puede conectar al mensaje"
common/views/components/messaging-room.message.vue: common/views/components/messaging-room.message.vue:
is-read: "Leer" is-read: "Leer"
deleted: "El mensaje se ha borrado" deleted: "El mensaje se ha borrado"
@ -587,8 +589,13 @@ common/views/components/user-list-editor.vue:
rename: "Cambiar el nombre de la lista" rename: "Cambiar el nombre de la lista"
delete: "Eliminar lista" delete: "Eliminar lista"
remove-user: "Eliminar de la lista" remove-user: "Eliminar de la lista"
common/views/components/user-group-editor.vue:
invite: "Invitar"
common/views/components/user-lists.vue: common/views/components/user-lists.vue:
user-lists: "Listas"
list-name: "Nombre de lista" list-name: "Nombre de lista"
common/views/components/user-groups.vue:
invites: "Invitar"
common/views/widgets/broadcast.vue: common/views/widgets/broadcast.vue:
fetching: "Recuperando" fetching: "Recuperando"
no-broadcasts: "Sin emisión" no-broadcasts: "Sin emisión"
@ -647,6 +654,8 @@ common/views/pages/follow.vue:
request-pending: "Solicitud pendiente" request-pending: "Solicitud pendiente"
follow-processing: "Solicitud en proceso" follow-processing: "Solicitud en proceso"
follow-request: "Solicitar suscripción" follow-request: "Solicitar suscripción"
common/views/pages/follow-requests.vue:
received-follow-requests: "Solicitudes de seguimiento"
desktop: desktop:
banner-crop-title: "Corta la parte que aparece como un banner" banner-crop-title: "Corta la parte que aparece como un banner"
banner: "Banner" banner: "Banner"
@ -763,7 +772,7 @@ desktop/views/components/note-detail.vue:
add-reaction: "Agregar una reacción" add-reaction: "Agregar una reacción"
desktop/views/components/note.vue: desktop/views/components/note.vue:
reply: "Responder" reply: "Responder"
renote: "Republicar" renote: "Volver a publicar"
add-reaction: "Reacción" add-reaction: "Reacción"
detail: "Detalles" detail: "Detalles"
private: "Esta publicación es privada" private: "Esta publicación es privada"
@ -774,32 +783,12 @@ desktop/views/components/notes.vue:
desktop/views/components/notifications.vue: desktop/views/components/notifications.vue:
empty: "No hay notificaciones" empty: "No hay notificaciones"
desktop/views/components/post-form.vue: desktop/views/components/post-form.vue:
add-visible-user: "+Agregar usuario"
attach-location-information: "Agregar localización"
hide-contents: "Esconder contenidos"
reply-placeholder: "Responder a esta nota..."
quote-placeholder: "Citar esta nota..."
submit: "Publicar"
reply: "Responder"
renote: "Republicar"
posted: "¡Publicado!" posted: "¡Publicado!"
replied: "¡Respondido!" replied: "¡Respondido!"
reposted: "¡Republicado!" reposted: "¡Republicado!"
note-failed: "Error al publicar nota" note-failed: "Error al publicar nota"
reply-failed: "Error al responder" reply-failed: "Error al responder"
renote-failed: "Error al republicar" renote-failed: "Error al republicar"
posting: "Publicando"
attach-media-from-local: "Agregar medios de tu dispositivo"
attach-media-from-drive: "Adjunta multimedia desde tu Disco"
create-poll: "Crea una encuesta"
text-remain: "quedan {} caracteres"
recent-tags: "Reciente"
click-to-tagging: "Click para etiquetar"
visibility: "Visibilidad"
geolocation-alert: "Tu dispositivo no tiene soporte de geolocalización."
error: "Error"
enter-username: "Por favor escribe un nombre de usuario..."
annotations: "Anotaciones a la publicación (opcional)"
desktop/views/components/post-form-window.vue: desktop/views/components/post-form-window.vue:
note: "Nota nueva" note: "Nota nueva"
reply: "Responder" reply: "Responder"
@ -890,12 +879,6 @@ desktop/views/components/ui.header.post.vue:
post: "Crear una publicación" post: "Crear una publicación"
desktop/views/components/ui.header.search.vue: desktop/views/components/ui.header.search.vue:
placeholder: "Buscar" placeholder: "Buscar"
desktop/views/components/received-follow-requests-window.vue:
title: "Solicitudes de seguidores"
accept: "Aceptar"
reject: "Rechazar"
desktop/views/components/user-lists-window.vue:
title: "Listas de usuario"
desktop/views/components/user-preview.vue: desktop/views/components/user-preview.vue:
notes: "Publicaciones" notes: "Publicaciones"
following: "Sigue" following: "Sigue"
@ -910,7 +893,6 @@ admin/views/index.vue:
moderators: "Moderadores" moderators: "Moderadores"
users: "Usuarios" users: "Usuarios"
federation: "Federado" federation: "Federado"
hashtags: "Hashtags"
queue: "Cola de trabajos" queue: "Cola de trabajos"
logs: "Registros" logs: "Registros"
back-to-misskey: "Volver a Misskey" back-to-misskey: "Volver a Misskey"
@ -925,6 +907,9 @@ admin/views/dashboard.vue:
admin/views/queue.vue: admin/views/queue.vue:
title: "Cola" title: "Cola"
remove-all-jobs: "Limpiar todos los trabajos pendientes" remove-all-jobs: "Limpiar todos los trabajos pendientes"
queue: "Cola"
admin/views/logs.vue:
logs: "Registros"
admin/views/abuse.vue: admin/views/abuse.vue:
title: "Abuso" title: "Abuso"
target: "Destinatario" target: "Destinatario"
@ -945,7 +930,7 @@ admin/views/instance.vue:
maintainer-email: "Contactar con el administrador" maintainer-email: "Contactar con el administrador"
drive-config: "Ajustes del Drive" drive-config: "Ajustes del Drive"
cache-remote-files: "Mantener en cache los archivos remotos" cache-remote-files: "Mantener en cache los archivos remotos"
recaptcha-secret-key: "clave secreta reCAPTCHA" recaptcha-preview: "Vista previa"
invite: "Invitar" invite: "Invitar"
save: "Guardar" save: "Guardar"
saved: "Guardado" saved: "Guardado"
@ -1004,6 +989,7 @@ admin/views/federation.vue:
hour: "Por hora" hour: "Por hora"
day: "Por día" day: "Por día"
blocked-hosts: "Bloquear" blocked-hosts: "Bloquear"
save: "Guardar"
desktop/views/pages/selectdrive.vue: desktop/views/pages/selectdrive.vue:
cancel: "Cancelar" cancel: "Cancelar"
desktop/views/pages/user-list.users.vue: desktop/views/pages/user-list.users.vue:
@ -1056,11 +1042,6 @@ mobile/views/components/note-detail.vue:
location: "Localización" location: "Localización"
mobile/views/components/notifications.vue: mobile/views/components/notifications.vue:
empty: "No hay notificaciones" empty: "No hay notificaciones"
mobile/views/components/post-form.vue:
reply: "Responder"
renote: "Republicar"
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"
@ -1080,8 +1061,6 @@ mobile/views/pages/drive.vue:
contextmenu: contextmenu:
upload: "Subir fichero" upload: "Subir fichero"
create-folder: "Crear una carpeta" create-folder: "Crear una carpeta"
mobile/views/pages/user-lists.vue:
title: "Listas"
mobile/views/pages/home.vue: mobile/views/pages/home.vue:
home: "Inicio" home: "Inicio"
local: "Local" local: "Local"
@ -1092,10 +1071,6 @@ mobile/views/pages/widgets.vue:
customization-tips: "Consejos de personalización" customization-tips: "Consejos de personalización"
mobile/views/pages/widgets/activity.vue: mobile/views/pages/widgets/activity.vue:
activity: "Actividad" activity: "Actividad"
mobile/views/pages/received-follow-requests.vue:
title: "Solicitudes de seguimiento"
accept: "Aceptar"
reject: "Rechazar"
mobile/views/pages/games/reversi.vue: mobile/views/pages/games/reversi.vue:
reversi: "Reversi" reversi: "Reversi"
mobile/views/pages/search.vue: mobile/views/pages/search.vue:
@ -1115,6 +1090,7 @@ deck:
deck/deck.user-column.vue: deck/deck.user-column.vue:
activity: "Actividad" activity: "Actividad"
pages: pages:
like: "Me gusta"
blocks: blocks:
post: "Formulario" post: "Formulario"
script: script:
@ -1133,5 +1109,7 @@ pages:
arg2: "Listas" arg2: "Listas"
_pick: _pick:
arg1: "Listas" arg1: "Listas"
_listLen:
arg1: "Listas"
types: types:
array: "Listas" array: "Listas"

View File

@ -12,7 +12,7 @@ common:
rich-contents: "Notes" rich-contents: "Notes"
rich-contents-desc: "Partagez vos idées, les événements et les sujets qui vous tiennent à cœur ainsi que tout autre chose que vous souhaitez partager avec les autres. Si vous le désirez, vous pouvez décorer vos messages en utilisant une syntaxe différente ou en y joignant des sondages et des fichiers, tels que les photos ou les vidéos que vous aimez." rich-contents-desc: "Partagez vos idées, les événements et les sujets qui vous tiennent à cœur ainsi que tout autre chose que vous souhaitez partager avec les autres. Si vous le désirez, vous pouvez décorer vos messages en utilisant une syntaxe différente ou en y joignant des sondages et des fichiers, tels que les photos ou les vidéos que vous aimez."
reaction: "Réactions" reaction: "Réactions"
reaction-desc: "Une manière simple d'exprimer vos émotions. Misskey peut attacher diverses réactions aux publications des autres utilisateurs. Si vous essayez les réactions sur Misskey, vous ne pourrez plus retourner sur une autre plateforme de réseaux sociaux n'offrant que des « J'aime »." reaction-desc: "Une manière simple d'exprimer vos émotions. Misskey peut attacher diverses réactions aux publications des autres utilisateur·rice·s. Si vous essayez les réactions sur Misskey, vous ne pourrez plus retourner sur une autre plateforme de réseaux sociaux n'offrant que des « J'aime »."
ui: "Interface" ui: "Interface"
ui-desc: "Aucune interface graphique ne peut plaire à tout le monde. Par conséquent, Misskey possède une interface utilisateur hautement personnalisable selon vos goûts. Vous pouvez rendre votre page d'accueil originale en modifiant la mise en page de votre fil et en déplaçant les widgets que vous pouvez facilement ajuster pour vous approprier cet espace." ui-desc: "Aucune interface graphique ne peut plaire à tout le monde. Par conséquent, Misskey possède une interface utilisateur hautement personnalisable selon vos goûts. Vous pouvez rendre votre page d'accueil originale en modifiant la mise en page de votre fil et en déplaçant les widgets que vous pouvez facilement ajuster pour vous approprier cet espace."
drive: "Drive" drive: "Drive"
@ -68,7 +68,7 @@ common:
explore: "Découvrir" explore: "Découvrir"
following: "Suit" following: "Suit"
followers: "Abonné·e·s" followers: "Abonné·e·s"
favorites: "Mettre cette note en favoris" favorites: "Favorites"
permissions: permissions:
"read:account": "Afficher les informations du compte" "read:account": "Afficher les informations du compte"
"write:account": "Mettre à jour les informations de votre compte" "write:account": "Mettre à jour les informations de votre compte"
@ -78,7 +78,10 @@ common:
"write:drive": "Écrire sur le Drive" "write:drive": "Écrire sur le Drive"
"read:favorites": "Afficher les favoris" "read:favorites": "Afficher les favoris"
"write:favorites": "Écrire des favoris" "write:favorites": "Écrire des favoris"
"read:following": "Voir les informations de l'abonné"
"read:messaging": "Lire les conversations"
"write:messaging": "Utiliser la messagerie" "write:messaging": "Utiliser la messagerie"
"read:mutes": "Voir les comptes masqués"
"write:notes": "Créer ou supprimer des publications" "write:notes": "Créer ou supprimer des publications"
"read:notifications": "Afficher les notifications" "read:notifications": "Afficher les notifications"
"write:notifications": "Gérer vos notifications" "write:notifications": "Gérer vos notifications"
@ -86,8 +89,34 @@ common:
"write:reactions": "Gérer vos réactions" "write:reactions": "Gérer vos réactions"
"write:votes": "Vote" "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 utilisateur·rice·s suivant·e·s afficheront leurs publications sur votre fil."
explore: "Trouver des utilisateurs" explore: "Trouver des utilisateur·rice·s"
post-form:
attach-location-information: "Joindre des informations de localisation"
hide-contents: "Masquer les contenus"
reply-placeholder: "Répondre à cette note …"
quote-placeholder: "Citer cette note …"
option-quote-placeholder: "Citer ce billet ... (Facultatif)"
quote-attached: "Cité"
submit: "Publication"
reply: "Répondre"
renote: "Republier"
posting: "Publication …"
attach-media-from-local: "Joindre un média depuis votre appareil"
attach-media-from-drive: "Joindre un média depuis votre Drive"
insert-a-kao: "v('ω')v"
create-poll: "Créer un sondage"
text-remain: "{} caractères restants"
recent-tags: "Récent"
local-only-message: "Ce message sera publié uniquement sur le fil local"
click-to-tagging: "Cliquer pour taguer"
visibility: "Visibilité"
geolocation-alert: "Votre appareil ne prend pas en charge les services de localisation"
error: "Erreur"
enter-username: "Saisir un nom d'utilisateur"
add-visible-user: "Ajouter un utilisateur"
cw-placeholder: "Commenter le contenu (optionnel)"
username-prompt: "Saisir un nom d'utilisateur"
weekday-short: weekday-short:
sunday: "D" sunday: "D"
monday: "L" monday: "L"
@ -119,13 +148,13 @@ common:
public: "Public" public: "Public"
home: "Principal" home: "Principal"
home-desc: "Publier sur le fil principal uniquement" home-desc: "Publier sur le fil principal uniquement"
followers: "Abonnés" followers: "Abonné·e·s"
followers-desc: "Publier à vos abonnés uniquement" followers-desc: "Publier à vos abonné·e·s uniquement"
specified: "Direct" specified: "Direct"
specified-desc: "Publier uniquement aux utilisateurs mentionnés" specified-desc: "Publier uniquement aux utilisateur·rice·s mentionné·e·s"
local-public: "Local (Public)" local-public: "Local (Public)"
local-home: "Accueil (local uniquement)" local-home: "Accueil (local uniquement)"
local-followers: "Local (Abonnés)" local-followers: "Abonné·e·s (Local uniquement)"
note-placeholders: note-placeholders:
a: "Que faites-vous maintenant ?" a: "Que faites-vous maintenant ?"
b: "Quoi de neuf ?" b: "Quoi de neuf ?"
@ -155,6 +184,7 @@ common:
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" keep-cw: "Maintenir l'avertissement de contenu"
keep-cw-desc: "Lorsque vous répondez à un message, le même avertissement de contenu est reprit par défaut dans la réponse, le même que celui qui a été défini dans le message original."
i-like-sushi: "Je préfère les sushis plutôt que le pudding" 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" show-reversi-board-labels: "Afficher les étiquettes des lignes et colonnes dans Reversi"
use-avatar-reversi-stones: "Utiliser lavatar comme pion dans Reversi" use-avatar-reversi-stones: "Utiliser lavatar comme pion dans Reversi"
@ -197,9 +227,11 @@ common:
delete-wallpaper: "Supprimer le fond d'écran" delete-wallpaper: "Supprimer le fond d'écran"
post-form-on-timeline: "Afficher le champs de saisie en haut du fil" 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" show-clock-on-header: "Afficher l'horloge sur le coté supérieur droit"
show-reply-target: "Afficher les réponses"
timeline: "Fil dactualité" timeline: "Fil dactualité"
show-my-renotes: "Afficher mes republications dans le fil" show-my-renotes: "Afficher mes republications dans le fil"
show-renoted-my-notes: "Afficher les partages de mes propres notes sur le fil" show-renoted-my-notes: "Afficher les partages de mes propres notes sur le fil"
show-local-renotes: "Afficher les partages locaux sur les fils"
remain-deleted-note: "Continuer à afficher les notes supprimées" remain-deleted-note: "Continuer à afficher les notes supprimées"
sound: "Son" sound: "Son"
enable-sounds: "Activer les sons" enable-sounds: "Activer les sons"
@ -233,6 +265,7 @@ common:
disable-via-mobile: "Enlever la mention publié via 'mobile'" disable-via-mobile: "Enlever la mention publié via 'mobile'"
load-raw-images: "Afficher les photos jointes dans leur qualité originale" load-raw-images: "Afficher les photos jointes dans leur qualité originale"
load-remote-media: "Afficher les médias depuis le serveur distant" load-remote-media: "Afficher les médias depuis le serveur distant"
sync: "Synchroniser"
search: "Recherche" search: "Recherche"
delete: "Supprimer" delete: "Supprimer"
loading: "Chargement en cours…" loading: "Chargement en cours…"
@ -243,6 +276,7 @@ common:
my-token-regenerated: "Votre jeton vient dêtre généré, vous allez maintenant être déconnecté." my-token-regenerated: "Votre jeton vient dêtre généré, vous allez maintenant être déconnecté."
hide-password: "Masquer le mot de passe" hide-password: "Masquer le mot de passe"
show-password: "Afficher le mot de passe" show-password: "Afficher le mot de passe"
enter-username: "Saisir un nom d'utilisateur"
do-not-use-in-production: "Il sagit dune version de développement. Ne pas utiliser dans un environnement de production." do-not-use-in-production: "Il sagit dune version de développement. Ne pas utiliser dans un environnement de production."
user-suspended: "Cet·te utilisateur·trice a été suspendu·e" user-suspended: "Cet·te utilisateur·trice a été suspendu·e"
is-remote-user: "Les informations à propos de ce compte peuvent être incomplètes." is-remote-user: "Les informations à propos de ce compte peuvent être incomplètes."
@ -281,7 +315,7 @@ common:
version: "Version" version: "Version"
broadcast: "Diffusion" broadcast: "Diffusion"
notifications: "Notifications" notifications: "Notifications"
users: "Utilisateurs recommandés" users: "Utilisateur·rice·s recommandé·e·s"
polls: "Sondages" polls: "Sondages"
post-form: "Champs de publication" post-form: "Champs de publication"
server: "Infos sur le serveur" server: "Infos sur le serveur"
@ -308,13 +342,14 @@ auth/views/index.vue:
error: "La session nexiste pas." error: "La session nexiste pas."
sign-in: "Veuillez vous connecter" sign-in: "Veuillez vous connecter"
common/views/pages/explore.vue: common/views/pages/explore.vue:
popular-users: "Utilisateurs populaires" pinned-users: "Utilisateur·rice·s épinglé·e·s"
recently-updated-users: "Utilisateurs actifs récemment" popular-users: "Utilisateur·rice·s populaires"
recently-updated-users: "Utilisateur·rice·s actif·ve·s récemment"
recently-registered-users: "Les nouveaux inscrits" recently-registered-users: "Les nouveaux inscrits"
popular-tags: "Mots-clés populaires" popular-tags: "Mots-clés populaires"
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} utilisateur·rice·s se sont inscrit ici"
common/views/components/url-preview.vue: common/views/components/url-preview.vue:
enable-player: "Activer la lecture" enable-player: "Activer la lecture"
disable-player: "Fermer le lecteur" disable-player: "Fermer le lecteur"
@ -436,18 +471,23 @@ common/views/components/messaging.vue:
search-user: "Trouver un utilisateur" search-user: "Trouver un utilisateur"
you: "Vous" you: "Vous"
no-history: "Pas d'historique" no-history: "Pas d'historique"
user: "Utilisateur·rice·s"
group: "Groupe"
start-with-user: "Initier une discussion avec un·e utilisateur·rice"
start-with-group: "Démarrer un groupe et converser"
select-group: "Sélectionner un groupe"
common/views/components/messaging-room.vue: common/views/components/messaging-room.vue:
empty: "Pas de conversations" not-talked-user: "Vous n'avez pas encore discuté avec cet·te utilisateur·rice"
not-talked-group: "Il n y a aucune conversation dans ce groupe"
no-history: "Aucun historique" no-history: "Aucun historique"
resize-form: "Faites glisser pour redimensionner"
new-message: "Nouveau message" new-message: "Nouveau message"
only-one-file-attached: "Un seul fichier peut être joint au message" only-one-file-attached: "Vous ne pouvez joindre qu'un seul fichier au message"
common/views/components/messaging-room.form.vue: common/views/components/messaging-room.form.vue:
input-message-here: "Tapez ici votre message" input-message-here: "Tapez ici votre message"
send: "Envoyer" send: "Envoyer"
attach-from-local: "Joindre un fichier depuis votre ordinateur" attach-from-local: "Joindre un fichier depuis votre ordinateur"
attach-from-drive: "Joindre un fichier depuis votre Drive" attach-from-drive: "Joindre un fichier depuis votre Drive"
only-one-file-attached: "Un seul fichier uniquement peut être joint au message" only-one-file-attached: "Vous ne pouvez joindre qu'un seul fichier au message"
common/views/components/messaging-room.message.vue: common/views/components/messaging-room.message.vue:
is-read: "Lu" is-read: "Lu"
deleted: "Ce message a été supprimé" deleted: "Ce message a été supprimé"
@ -526,6 +566,7 @@ common/views/components/poll-editor.vue:
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"
input-reaction-placeholder: "ou insérez un émoji"
common/views/components/emoji-picker.vue: common/views/components/emoji-picker.vue:
custom-emoji: "Émoji personnalisé" custom-emoji: "Émoji personnalisé"
people: "Personnes" people: "Personnes"
@ -567,6 +608,7 @@ common/views/components/signup.vue:
password-matched: "OK" password-matched: "OK"
password-not-matched: "Les mots de passe ne correspondent pas." password-not-matched: "Les mots de passe ne correspondent pas."
recaptcha: "Vérifier" recaptcha: "Vérifier"
agree-to: "Accepter {0}."
tos: "Conditions d'utilisation" tos: "Conditions d'utilisation"
create: "Créer un compte" create: "Créer un compte"
some-error: "La création du compte a échoué. Veuillez réessayer." some-error: "La création du compte a échoué. Veuillez réessayer."
@ -612,13 +654,13 @@ common/views/components/visibility-chooser.vue:
followers: "Abonné·e·s" followers: "Abonné·e·s"
followers-desc: "Publier à vos abonné·e·s uniquement" followers-desc: "Publier à vos abonné·e·s uniquement"
specified: "Direct" specified: "Direct"
specified-desc: "Publier uniquement aux utilisateurs mentionnés" specified-desc: "Publier uniquement aux utilisateur·rice·s mentionné·e·s"
local-public: "Local (Public)" local-public: "Local (Public)"
local-public-desc: "Ne pas publier pour les distants" local-public-desc: "Ne pas publier pour les distants"
local-home: "Accueil (local uniquement)" local-home: "Accueil (local uniquement)"
local-followers: "Local (Abonnés)" local-followers: "Abonné·e·s (Local uniquement)"
common/views/components/trends.vue: common/views/components/trends.vue:
count: "{} utilisateurs mentionnés" count: "{} utilisateur·rice·s mentionné·e·s"
empty: "Aucune tendance" empty: "Aucune tendance"
common/views/components/language-settings.vue: common/views/components/language-settings.vue:
title: "Langue " title: "Langue "
@ -675,9 +717,31 @@ common/views/components/user-list-editor.vue:
remove-user: "Retirer de cette liste" remove-user: "Retirer de cette liste"
delete-are-you-sure: "Voulez-vous vraiment supprimer la liste « $1 » ?" delete-are-you-sure: "Voulez-vous vraiment supprimer la liste « $1 » ?"
deleted: "Supprimé" deleted: "Supprimé"
add-user: "Ajouter un utilisateur"
common/views/components/user-group-editor.vue:
users: "Membres"
rename: "Renommer le groupe"
delete: "Supprimer le groupe"
transfer: "Transférer de groupe"
transferred: "Groupe transféré"
remove-user: "Enlever un utilisateur de ce groupe"
delete-are-you-sure: "Désirez-vous vraiment supprimer le groupe $1 ?"
deleted: "Supprimé"
invite: "Inviter"
invited: "Invitation envoyée avec succès"
common/views/components/user-lists.vue: common/views/components/user-lists.vue:
user-lists: "Listes"
create-list: "Créer une liste" create-list: "Créer une liste"
list-name: "Nom de la liste" list-name: "Nom de la liste"
common/views/components/user-groups.vue:
user-groups: "Groupe"
create-group: "Créer un groupe"
group-name: "Nom du groupe"
owned-groups: "Mes groupes"
joined-groups: "Membre dans les groupes"
invites: "Inviter"
accept-invite: "Participer"
reject-invite: "Refuser"
common/views/widgets/broadcast.vue: common/views/widgets/broadcast.vue:
fetching: "Récupération" fetching: "Récupération"
no-broadcasts: "Aucune annonce" no-broadcasts: "Aucune annonce"
@ -738,6 +802,10 @@ common/views/pages/follow.vue:
request-pending: "Demande dabonnement en attente" request-pending: "Demande dabonnement en attente"
follow-processing: "Demande en attente" follow-processing: "Demande en attente"
follow-request: "Demande dabonnement" follow-request: "Demande dabonnement"
common/views/pages/follow-requests.vue:
received-follow-requests: "Demandes dabonnement"
accept: "Accepter"
reject: "Refuser"
desktop: desktop:
banner-crop-title: "Découpez la partie qui apparaîtra comme bannière" banner-crop-title: "Découpez la partie qui apparaîtra comme bannière"
banner: "Bannière" banner: "Bannière"
@ -831,7 +899,7 @@ desktop/views/components/media-video.vue:
sensitive: "Le contenu est NSFW" sensitive: "Le contenu est NSFW"
click-to-show: "Cliquer pour afficher" click-to-show: "Cliquer pour afficher"
desktop/views/components/followers-window.vue: desktop/views/components/followers-window.vue:
followers: "{} abonné·e·s" followers: "Abonné·e·s de {}"
desktop/views/components/followers.vue: desktop/views/components/followers.vue:
empty: "Il semble que vous navez pas encore dabonné·e·s." empty: "Il semble que vous navez pas encore dabonné·e·s."
desktop/views/components/following-window.vue: desktop/views/components/following-window.vue:
@ -868,34 +936,12 @@ desktop/views/components/notes.vue:
desktop/views/components/notifications.vue: desktop/views/components/notifications.vue:
empty: "Aucune de notification !" empty: "Aucune de notification !"
desktop/views/components/post-form.vue: desktop/views/components/post-form.vue:
add-visible-user: "+Ajouter un·e utilisateur·rice"
attach-location-information: "Attacher des informations de localisation"
hide-contents: "Masquer les contenus"
reply-placeholder: "Répondre à cette note …"
quote-placeholder: "Citer cette note …"
submit: "Publier"
reply: "Répondre"
renote: "Republier"
posted: "Publié !" posted: "Publié !"
replied: "Répondu !" replied: "Répondu !"
reposted: "Reposté !" reposted: "Reposté !"
note-failed: "La note à échoué" note-failed: "La note à échoué"
reply-failed: "La réponse a échoué" reply-failed: "La réponse a échoué"
renote-failed: "Échec lors de la republication" renote-failed: "Échec lors de la republication"
posting: "Publication …"
attach-media-from-local: "Joindre un média depuis votre appareil"
attach-media-from-drive: "Joindre un média depuis votre Drive"
insert-a-kao: "v('ω')v"
create-poll: "Créer un sondage"
text-remain: "{} caractères restants"
recent-tags: "Récent"
local-only-message: "Ce message sera publié uniquement sur le fil local"
click-to-tagging: "Cliquer pour taguer"
visibility: "Visibilité"
geolocation-alert: "Votre appareil ne prend pas en charge les services de localisation"
error: "Erreur"
enter-username: "Saisir un nom d'utilisateur …"
annotations: "Commenter le contenu (optionnel)"
desktop/views/components/post-form-window.vue: desktop/views/components/post-form-window.vue:
note: "Nouvelle note" note: "Nouvelle note"
reply: "Répondre" reply: "Répondre"
@ -1009,6 +1055,7 @@ desktop/views/components/ui.header.vue:
desktop/views/components/ui.header.account.vue: desktop/views/components/ui.header.account.vue:
profile: "Votre profil" profile: "Votre profil"
lists: "Listes" lists: "Listes"
groups: "Groupes"
follow-requests: "Demandes dabonnement" follow-requests: "Demandes dabonnement"
admin: "Admin" admin: "Admin"
desktop/views/components/ui.header.nav.vue: desktop/views/components/ui.header.nav.vue:
@ -1019,12 +1066,6 @@ desktop/views/components/ui.header.post.vue:
post: "Rédiger une nouvelle publication" post: "Rédiger une nouvelle publication"
desktop/views/components/ui.header.search.vue: desktop/views/components/ui.header.search.vue:
placeholder: "Chercher" placeholder: "Chercher"
desktop/views/components/received-follow-requests-window.vue:
title: "Demandes dabonnement"
accept: "Accepter"
reject: "Refuser"
desktop/views/components/user-lists-window.vue:
title: "Listes de l'utilisateur"
desktop/views/components/user-preview.vue: desktop/views/components/user-preview.vue:
notes: "Publications" notes: "Publications"
following: "Abonné à" following: "Abonné à"
@ -1043,14 +1084,16 @@ admin/views/index.vue:
instance: "Instance" instance: "Instance"
emoji: "Émoji" emoji: "Émoji"
moderators: "Modérateurs" moderators: "Modérateurs"
users: "Utilisateurs" users: "Utilisateur·rice·s"
federation: "Fédération" federation: "Fédération"
announcements: "Annonces" announcements: "Annonces"
hashtags: "Hashtags"
abuse: "Abus" abuse: "Abus"
queue: "File dattente" queue: "File dattente"
logs: "Journaux" logs: "Journaux"
db: "Base de données"
back-to-misskey: "Retour vers Misskey" back-to-misskey: "Retour vers Misskey"
admin/views/db.vue:
tables: "Tables"
admin/views/dashboard.vue: admin/views/dashboard.vue:
dashboard: "Tableau de bord" dashboard: "Tableau de bord"
accounts: "Comptes" accounts: "Comptes"
@ -1062,6 +1105,30 @@ admin/views/dashboard.vue:
admin/views/queue.vue: admin/views/queue.vue:
title: "File d'attente" title: "File d'attente"
remove-all-jobs: "Enlever toutes les tâches en attente" remove-all-jobs: "Enlever toutes les tâches en attente"
jobs: "Tâches"
queue: "File d'attente"
domains:
deliver: "Délivrées"
inbox: "Reçues"
db: "Base de données"
state: "État"
states:
active: "en cours"
delayed: "Programmé"
waiting: "En file d'attente"
other-queues: "Autres files dattente"
admin/views/logs.vue:
logs: "Journaux"
domain: "Domaine"
level: "Niveau"
levels:
all: "Tous"
info: "Informations"
success: "Succès"
warning: "Avertissement"
error: "Erreur"
debug: "Débogage"
delete-all: "Effacer tout"
admin/views/abuse.vue: admin/views/abuse.vue:
title: "Abus" title: "Abus"
target: "Cible" target: "Cible"
@ -1073,23 +1140,42 @@ admin/views/instance.vue:
instance-name: "Nom de linstance" instance-name: "Nom de linstance"
instance-description: "Description de linstance" instance-description: "Description de linstance"
host: "Hôte" host: "Hôte"
icon-url: "URL de l'icône"
logo-url: "URL do logo"
banner-url: "URL de limage de la bannière" banner-url: "URL de limage de la bannière"
error-image-url: "URL de limage derreur" error-image-url: "URL de limage derreur"
languages: "Langue de linstance" languages: "Langue de linstance"
languages-desc: "Vous pouvez en définir plus dune, séparées par des espaces." languages-desc: "Vous pouvez en définir plus dune, séparées par des espaces."
tos-url: "URL des conditions d'utilisation"
repository-url: "URL du dépôt"
maintainer-config: "Informations de ladministrateur" maintainer-config: "Informations de ladministrateur"
maintainer-name: "Nom de ladministrateur" maintainer-name: "Nom de ladministrateur"
maintainer-email: "Contact administratif" maintainer-email: "Contact administratif"
advanced-config: "Autres réglages"
note-and-tl: "Notes et fils"
drive-config: "Paramètres du lecteur" drive-config: "Paramètres du lecteur"
object-storage-base-url: "URL"
object-storage-prefix: "Préfixe"
object-storage-endpoint: "Point de terminaison"
object-storage-region: "Région"
object-storage-port: "Port"
object-storage-access-key: "Clé d'accès"
object-storage-secret-key: "Clé secrète"
object-storage-use-ssl: "Utiliser SSL"
object-storage-s3-info-here: "ici"
cache-remote-files: "Mettre en cache des fichiers distants" cache-remote-files: "Mettre en cache des fichiers distants"
local-drive-capacity-mb: "Volume du lecteur par utilisateur" local-drive-capacity-mb: "Volume du lecteur par utilisateur"
remote-drive-capacity-mb: "Volume du lecteur par utilisateur distant" remote-drive-capacity-mb: "Volume du lecteur par utilisateur distant"
mb: "en mégaoctets" mb: "en mégaoctets"
recaptcha-config: "Paramètres de reCAPTCHA" recaptcha-config: "Paramètres de reCAPTCHA"
recaptcha-info: "Si activé, un jeton reCAPTCHA est requis. Vous pouvez en obtenir un sur https://www.google.com/recaptcha/intro/" recaptcha-info: "Si activé, un jeton reCAPTCHA est requis. Vous pouvez en obtenir un sur https://www.google.com/recaptcha/intro/"
recaptcha-info2: "v3 n'est pas supportée. Veuillez utiliser v2."
enable-recaptcha: "Activation de reCAPTCHA" enable-recaptcha: "Activation de reCAPTCHA"
recaptcha-site-key: "Clé reCAPTCHA du site" recaptcha-site-key: "Clé du site"
recaptcha-secret-key: "Clé secrète reCAPTCHA" recaptcha-secret-key: "Clé secrète"
recaptcha-preview: "Prévisualisation"
hidden-tags: "Tags cachés"
external-service-integration-config: "Services connectés"
twitter-integration-config: "Paramètres de connexion à Twitter" twitter-integration-config: "Paramètres de connexion à Twitter"
twitter-integration-info: "L'URL de callback est {url}." twitter-integration-info: "L'URL de callback est {url}."
enable-twitter-integration: "Activer la connexion à Twitter" enable-twitter-integration: "Activer la connexion à Twitter"
@ -1114,9 +1200,12 @@ admin/views/instance.vue:
disable-local-timeline: "Désactiver le fil local" disable-local-timeline: "Désactiver le fil local"
disable-global-timeline: "Désactiver le fil global" disable-global-timeline: "Désactiver le fil global"
disabling-timelines-info: "Même si vous désactivez ces fils, l'administrateur et les modérateurs peuvent continuer à les utiliser." disabling-timelines-info: "Même si vous désactivez ces fils, l'administrateur et les modérateurs peuvent continuer à les utiliser."
enable-emoji-reaction: "Activer les pictogrammes dans les réactions"
use-star-for-reaction-fallback: "Utiliser une étoile si une réaction est inconnue"
invite: "Inviter" invite: "Inviter"
save: "Sauvegarder" save: "Sauvegarder"
saved: "Enregistré" saved: "Enregistré"
pinned-users: "Utilisateur·rice épinglé·e"
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"
@ -1140,7 +1229,7 @@ admin/views/charts.vue:
per-hour: "par heure" per-hour: "par heure"
federation: "Fédération" federation: "Fédération"
notes: "Publications" notes: "Publications"
users: "Utilisateurs" users: "Utilisateur·rice·s"
drive: "Lecteur" drive: "Lecteur"
network: "Réseau" network: "Réseau"
charts: charts:
@ -1150,8 +1239,8 @@ admin/views/charts.vue:
local-notes: "Nombre des publications : augmentation/diminution (Local)" local-notes: "Nombre des publications : augmentation/diminution (Local)"
remote-notes: "Nombre de publications : augmentation/diminution (distants)" remote-notes: "Nombre de publications : augmentation/diminution (distants)"
notes-total: "Total des notes" notes-total: "Total des notes"
users: "Nombre dutilisateurs : augmentation/diminution" users: "Nombre dutilisateur·rice·s : augmentation/diminution"
users-total: "Nombre total des utilisateurs" users-total: "Nombre total des utilisateur·rice·s"
active-users: "Utilisateur·rice·s actif·ve·s" active-users: "Utilisateur·rice·s actif·ve·s"
drive: "Capacité utilisée comme stockage : augmentation/diminution" drive: "Capacité utilisée comme stockage : augmentation/diminution"
drive-total: "Utilisation totale du lecteur" drive-total: "Utilisation totale du lecteur"
@ -1182,6 +1271,8 @@ admin/views/drive.vue:
unmark-as-sensitive: "Ne pas marquer comme sensible" unmark-as-sensitive: "Ne pas marquer comme sensible"
marked-as-sensitive: "Marqué comme sensible" marked-as-sensitive: "Marqué comme sensible"
unmarked-as-sensitive: "Marqué comme non sensible" unmarked-as-sensitive: "Marqué comme non sensible"
clean-remote-files: "Nettoyer le cache des fichiers distants"
clean-up: "Nettoyage"
admin/views/users.vue: admin/views/users.vue:
operation: "Actions" operation: "Actions"
username-or-userid: "Nom dutilisateur·rice ou ID utilisateur" username-or-userid: "Nom dutilisateur·rice ou ID utilisateur"
@ -1201,8 +1292,9 @@ admin/views/users.vue:
unmake-silence: "Enlever la sourdine" unmake-silence: "Enlever la sourdine"
update-remote-user: "Mettre à jour les informations de lutilisateur·rice distant·e" update-remote-user: "Mettre à jour les informations de lutilisateur·rice distant·e"
remote-user-updated: "Les informations de lutilisateur·rice distant·e ont étés mis à jour" remote-user-updated: "Les informations de lutilisateur·rice distant·e ont étés mis à jour"
delete-all-files: "Supprimer tous les fichiers"
users: users:
title: "Utilisateurs" title: "Utilisateur·rice·s"
sort: sort:
title: "Trier par" title: "Trier par"
createdAtAsc: "Date dinscription (Ascendant)" createdAtAsc: "Date dinscription (Ascendant)"
@ -1275,6 +1367,7 @@ admin/views/federation.vue:
latest-request-sent-at: "Dernière requête envoyée" latest-request-sent-at: "Dernière requête envoyée"
latest-request-received-at: "Dernière requête reçue" latest-request-received-at: "Dernière requête reçue"
remove-all-following-info: "Se désabonner de tous les comptes de {host}. Exécutez cette commande si l'instance n'existe plus." remove-all-following-info: "Se désabonner de tous les comptes de {host}. Exécutez cette commande si l'instance n'existe plus."
delete-all-files: "Supprimer tous les fichiers"
block: "Bloquer" block: "Bloquer"
marked-as-closed: "Marquées comme fermées" marked-as-closed: "Marquées comme fermées"
lookup: "Recherche" lookup: "Recherche"
@ -1287,7 +1380,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" usersAsc: "Peu d'abonné·e·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"
@ -1302,7 +1395,7 @@ admin/views/federation.vue:
charts: "Graphs" charts: "Graphs"
chart-srcs: chart-srcs:
requests: "Requêtes" requests: "Requêtes"
users: "Nombre dutilisateurs·trices : augmentation/diminution" users: "Nombre dutilisateur·trice·s : augmentation/diminution"
users-total: "Nombre total des utilisateur·rice·s" users-total: "Nombre total des utilisateur·rice·s"
notes: "Augmentation/diminution du nombre des notes" notes: "Augmentation/diminution du nombre des notes"
notes-total: "Nombre total des notes" notes-total: "Nombre total des notes"
@ -1314,6 +1407,7 @@ admin/views/federation.vue:
hour: "Par heure" hour: "Par heure"
day: "Par jour" day: "Par jour"
blocked-hosts: "En cours blocage" blocked-hosts: "En cours blocage"
save: "Enregistrer"
desktop/views/pages/welcome.vue: desktop/views/pages/welcome.vue:
about: "à propos" about: "à propos"
timeline: "Fil dactualité" timeline: "Fil dactualité"
@ -1343,7 +1437,7 @@ desktop/views/pages/user-list.users.vue:
desktop/views/pages/user/user.followers-you-know.vue: desktop/views/pages/user/user.followers-you-know.vue:
title: "Abonné·e·s que vous connaissez" title: "Abonné·e·s que vous connaissez"
loading: "Chargement en cours" loading: "Chargement en cours"
no-users: "Aucun abonné connu" no-users: "Aucun·e abonné·e connu·e"
desktop/views/pages/user/user.friends.vue: desktop/views/pages/user/user.friends.vue:
title: "Mentions fréquentes" title: "Mentions fréquentes"
loading: "Chargement en cours" loading: "Chargement en cours"
@ -1396,8 +1490,10 @@ mobile/views/components/drive.vue:
nothing-in-drive: "Rien" nothing-in-drive: "Rien"
folder-is-empty: "Ce dossier est vide" folder-is-empty: "Ce dossier est vide"
folder-name: "Nom du dossier" folder-name: "Nom du dossier"
here-is-root: "Actuellement, vous êtes dans la racine et non pas dans un dossier."
url-prompt: "URL du fichier que vous souhaitez téléverser" url-prompt: "URL du fichier que vous souhaitez téléverser"
uploading: "Envoi demandé. Le téléversement pourrait prendre un certain temps avant de s'achever." uploading: "Envoi demandé. Le téléversement pourrait prendre un certain temps avant de s'achever."
folder-name-cannot-empty: "Le nom du dossier ne peut être laissé vide."
mobile/views/components/drive-file-chooser.vue: mobile/views/components/drive-file-chooser.vue:
select-file: "Choisissez un fichier" select-file: "Choisissez un fichier"
mobile/views/components/drive-folder-chooser.vue: mobile/views/components/drive-folder-chooser.vue:
@ -1417,7 +1513,7 @@ mobile/views/components/media-video.vue:
sensitive: "Le contenu est NSFW" sensitive: "Le contenu est NSFW"
click-to-show: "Cliquer pour afficher" click-to-show: "Cliquer pour afficher"
common/views/components/follow-button.vue: common/views/components/follow-button.vue:
following: "Abonné" following: "Abonné·e"
follow: " Suivre" follow: " Suivre"
request-pending: "Demande en attente" request-pending: "Demande en attente"
follow-processing: "En cours dabonnement" follow-processing: "En cours dabonnement"
@ -1442,17 +1538,6 @@ mobile/views/components/note-sub.vue:
cat: "chat" cat: "chat"
mobile/views/components/notifications.vue: mobile/views/components/notifications.vue:
empty: "Aucune de notification !" empty: "Aucune de notification !"
mobile/views/components/post-form.vue:
add-visible-user: "Ajouter un·e utilisateur·rice"
submit: "Publier"
reply: "Répondre"
renote: "Republier"
quote-placeholder: "Citer ce billet ... (Facultatif)"
reply-placeholder: "Répondre à cette note"
cw-placeholder: "Commenter le contenu (optionnel)"
geolocation-alert: "Votre appareil ne prend pas en charge les services de localisation"
error: "Erreur"
username-prompt: "Saisir un nom d'utilisateur"
mobile/views/components/sub-note-content.vue: mobile/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"
@ -1467,6 +1552,7 @@ mobile/views/components/ui.nav.vue:
follow-requests: "Demandes dabonnement" follow-requests: "Demandes dabonnement"
search: "Rechercher" search: "Rechercher"
user-lists: "Listes" user-lists: "Listes"
user-groups: "Groupe"
widgets: "Modules" widgets: "Modules"
game: "Jeux" game: "Jeux"
admin: "Admin" admin: "Admin"
@ -1474,16 +1560,17 @@ mobile/views/components/ui.nav.vue:
mobile/views/pages/drive.vue: mobile/views/pages/drive.vue:
contextmenu: contextmenu:
upload: "Téléverser un fichier" upload: "Téléverser un fichier"
url-upload: "Transférer un fichier depuis une URL"
create-folder: "Créer un dossier" create-folder: "Créer un dossier"
rename-folder: "Renommer le dossier" rename-folder: "Renommer le dossier"
mobile/views/pages/user-lists.vue: move-folder: "Déplacer ce dossier"
title: "Listes" delete-folder: "Supprimer ce dossier"
mobile/views/pages/signup.vue: mobile/views/pages/signup.vue:
lets-start: "Votre compte est prêt ! 📦" lets-start: "Votre compte est prêt ! 📦"
mobile/views/pages/followers.vue: mobile/views/pages/followers.vue:
followers-of: "Abonnés de {name}" followers-of: "Abonné·e·s de {name}"
mobile/views/pages/following.vue: mobile/views/pages/following.vue:
following-of: "Abonnés de {name}" following-of: "Abonné·e·s de {name}"
mobile/views/pages/home.vue: mobile/views/pages/home.vue:
home: "Accueil" home: "Accueil"
local: "Local" local: "Local"
@ -1501,10 +1588,6 @@ mobile/views/pages/widgets/activity.vue:
activity: "Activité" activity: "Activité"
mobile/views/pages/share.vue: mobile/views/pages/share.vue:
share-with: "Partager avec {name}" share-with: "Partager avec {name}"
mobile/views/pages/received-follow-requests.vue:
title: "Demandes dabonnement"
accept: "Accepter"
reject: "Refuser"
mobile/views/pages/note.vue: mobile/views/pages/note.vue:
title: "Publication" title: "Publication"
prev: "Note précédente" prev: "Note précédente"
@ -1557,7 +1640,7 @@ deck:
remove: "Supprimer la colonne" remove: "Supprimer la colonne"
add-column: "Ajouter une colonne" add-column: "Ajouter une colonne"
rename: "Renommer" rename: "Renommer"
stack-left: "Vers la gauche" stack-left: "Empiler à gauche"
pop-right: "Vers la droite" pop-right: "Vers la droite"
disabled-timeline: disabled-timeline:
title: "Le fil été désactivé" title: "Le fil été désactivé"
@ -1569,7 +1652,7 @@ deck/deck.user-column.vue:
follows-you: "Vous suit" follows-you: "Vous suit"
posts: "Notes" posts: "Notes"
following: "Suit" following: "Suit"
followers: "Abonnés" followers: "Abonné·e·s"
images: "Images" images: "Images"
activity: "Activité" activity: "Activité"
timeline: "Fil dactualité" timeline: "Fil dactualité"
@ -1584,22 +1667,35 @@ dev/views/apps.vue:
create-app: "Créer une app" create-app: "Créer une app"
app-missing: "Aucune application" app-missing: "Aucune application"
dev/views/new-app.vue: dev/views/new-app.vue:
new-app: "Nouvelle application"
new-app-info: "Vous pouvez aussi créer une application avec l'API. (app/create)"
create-app: "Création dune application" create-app: "Création dune application"
app-name: "Nom de lapplication" app-name: "Nom de lapplication"
app-name-placeholder: "p. ex. Misskey pour iOS"
app-name-desc: "Le nom de votre application" app-name-desc: "Le nom de votre application"
app-overview: "Description courte de lapplication" app-overview: "Description courte de lapplication"
app-overview-placeholder: "p. ex. Misskey pour iOS"
app-overview-desc: "Brève description introductive à votre application."
callback-url: "LUrl de callback (facultatif)" callback-url: "LUrl de callback (facultatif)"
callback-url-placeholder: "p. ex. https://votre.app.example.com/callback.php"
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."
pages: pages:
new-page: "Créer une page"
edit-page: "Modifier une page"
read-page: "Voir la source"
page-created: "Page a été créée !" page-created: "Page a été créée !"
page-updated: "A mis à jour la page"
are-you-sure-delete: "Confirmez-vous la suppression de cette page ?" are-you-sure-delete: "Confirmez-vous la suppression de cette page ?"
page-deleted: "La page a bien été supprimée." page-deleted: "La page a bien été supprimée."
edit-this-page: "Éditer cette page" edit-this-page: "Éditer cette page"
view-source: "Afficher la source" view-source: "Afficher la source"
view-page: "Afficher la page" view-page: "Afficher la page"
like: "Bien"
liked-pages: "Pages favorites"
my-pages: "Mes pages"
inspector: "Inspecteur" inspector: "Inspecteur"
content: "Bloc de page" content: "Bloc de page"
variables: "Variables" variables: "Variables"
@ -1611,12 +1707,16 @@ pages:
font: "Police de caractères" font: "Police de caractères"
fontSerif: "Serif" fontSerif: "Serif"
fontSansSerif: "Sans Serif" fontSansSerif: "Sans Serif"
set-eye-catching-image: "Définir une image attirante"
remove-eye-catching-image: "Supprimer une image attirante"
choose-block: "Ajouter un bloc" choose-block: "Ajouter un bloc"
select-type: "Choisir un type" select-type: "Choisir un type"
enter-variable-name: "Veuillez choisir un nom de variable" enter-variable-name: "Veuillez choisir un nom de variable"
the-variable-name-is-already-used: "Cette variable est déjà utilisée" the-variable-name-is-already-used: "Cette variable est déjà utilisée"
content-blocks: "Contenu du cadre" content-blocks: "Contenu du cadre"
input-blocks: "Entrée"
special-blocks: "Spécial" special-blocks: "Spécial"
post-from-post-form: "Publier ce contenu"
posted-from-post-form: "Publié !" posted-from-post-form: "Publié !"
blocks: blocks:
text: "Texte" text: "Texte"
@ -1653,11 +1753,15 @@ pages:
_counter: _counter:
name: "Nom de la variable" name: "Nom de la variable"
text: "Titre" text: "Titre"
inc: "Augmenter le chiffre"
_button: _button:
text: "Titre" text: "Titre"
action: "L'opération lorsque le bouton sera pressé"
_action: _action:
dialog: "Afficher une fenêtre de dialogue"
_dialog: _dialog:
content: "Contenu" content: "Contenu"
resetRandom: "Réinitialiser le nombre aléatoire"
script: script:
categories: categories:
flow: "Contrôle" flow: "Contrôle"
@ -1667,9 +1771,11 @@ pages:
random: "Aléatoire" random: "Aléatoire"
value: "Valeur" value: "Valeur"
fn: "Fonction" fn: "Fonction"
text: "Actions texte"
list: "Listes" list: "Listes"
blocks: blocks:
text: "Texte" text: "Texte"
textList: "Liste de texte"
strLen: "Longueur du texte" strLen: "Longueur du texte"
_strLen: _strLen:
arg1: "Texte" arg1: "Texte"
@ -1702,7 +1808,7 @@ pages:
_divide: _divide:
arg1: "A" arg1: "A"
arg2: "B" arg2: "B"
_remind: _mod:
arg1: "A" arg1: "A"
arg2: "B" arg2: "B"
eq: "A et B sont équivalents" eq: "A et B sont équivalents"
@ -1713,36 +1819,74 @@ pages:
_notEq: _notEq:
arg1: "A" arg1: "A"
arg2: "B" arg2: "B"
and: "A et B"
_and: _and:
arg1: "A" arg1: "A"
arg2: "B" arg2: "B"
or: "A ou B"
_or: _or:
arg1: "A" arg1: "A"
arg2: "B" arg2: "B"
lt: "A est plus petit que B"
_lt: _lt:
arg1: "A" arg1: "A"
arg2: "B" arg2: "B"
gt: "A est supérieur à B"
_gt: _gt:
arg1: "A" arg1: "A"
arg2: "B" arg2: "B"
ltEq: "A est plus petit ou égal à B"
_ltEq: _ltEq:
arg1: "A" arg1: "A"
arg2: "B" arg2: "B"
gtEq: "A est supérieur ou égal à B"
_gtEq: _gtEq:
arg1: "A" arg1: "A"
arg2: "B" arg2: "B"
_if:
arg1: "Si"
arg2: "donc"
arg3: "sinon"
not: "négation"
_not:
arg1: "négation"
random: "Aléatoire" random: "Aléatoire"
_random:
arg1: "Probabilité"
rannum: "Nombre aléatoire"
_rannum:
arg1: "Minimum"
arg2: "Maximum"
randomPick: "Choisir aléatoirement depuis la liste"
_randomPick: _randomPick:
arg1: "Listes" arg1: "Listes"
_dailyRandom:
arg1: "Probabilité"
_dailyRannum:
arg1: "Minimum"
arg2: "Maximum"
_dailyRandomPick: _dailyRandomPick:
arg1: "Listes" arg1: "Listes"
_seedRandom:
arg2: "Probabilité"
_seedRannum:
arg2: "Min"
arg3: "Max"
_seedRandomPick: _seedRandomPick:
arg2: "Listes" arg2: "Listes"
_DRPWPM:
arg1: "Liste de texte"
pick: "Sélectionner dans la liste"
_pick: _pick:
arg1: "Listes" arg1: "Listes"
arg2: "Position"
_listLen:
arg1: "Listes"
number: "Numérique" number: "Numérique"
stringToNumber: "Chaîne en chiffres"
_stringToNumber: _stringToNumber:
arg1: "Texte" arg1: "Texte"
numberToString: "Chiffres en chaîne"
_numberToString: _numberToString:
arg1: "Numérique" arg1: "Numérique"
_splitStrByLine: _splitStrByLine:
@ -1750,11 +1894,19 @@ pages:
ref: "Variables" ref: "Variables"
fn: "Fonction" fn: "Fonction"
_fn: _fn:
slots: "Emplacement"
arg1: "Sortie" arg1: "Sortie"
for: "Répéter" for: "Répéter"
_for:
arg1: "Compter"
arg2: "Action"
thereIsEmptySlot: "Slot {slot} est vide !"
types: types:
string: "Texte" string: "Texte"
number: "Numérique" number: "Numérique"
boolean: "Marqueur"
array: "Listes" array: "Listes"
stringArray: "Liste de texte" stringArray: "Liste de texte"
emptySlot: "Slot vide"
enviromentVariables: "Variables d'environnement" enviromentVariables: "Variables d'environnement"
pageVariables: "Élément de page"

View File

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

View File

@ -101,6 +101,34 @@ common:
follow-users-to-make-your-timeline: "ユーザーをフォローすると投稿がタイムラインに表示されます。" follow-users-to-make-your-timeline: "ユーザーをフォローすると投稿がタイムラインに表示されます。"
explore: "ユーザーを探索する" explore: "ユーザーを探索する"
post-form:
attach-location-information: "位置情報を添付する"
hide-contents: "内容を隠す"
reply-placeholder: "この投稿への返信..."
quote-placeholder: "この投稿を引用..."
option-quote-placeholder: "この投稿を引用... (オプション)"
quote-attached: "引用付き"
quote-question: "引用として添付しますか?"
submit: "投稿"
reply: "返信"
renote: "Renote"
posting: "投稿中"
attach-media-from-local: "PCからメディアを添付"
attach-media-from-drive: "ドライブからメディアを添付"
insert-a-kao: "v('ω')v"
create-poll: "アンケートを作成"
text-remain: "残り{}文字"
recent-tags: "最近"
local-only-message: "この投稿はローカルにのみ公開されます"
click-to-tagging: "クリックでタグ付け"
visibility: "公開範囲"
geolocation-alert: "お使いの端末は位置情報に対応していません"
error: "エラー"
enter-username: "ユーザー名を入力してください"
add-visible-user: "ユーザーを追加"
cw-placeholder: "内容への注釈 (オプション)"
username-prompt: "ユーザー名を入力してください"
weekday-short: weekday-short:
sunday: "日" sunday: "日"
monday: "月" monday: "月"
@ -254,6 +282,9 @@ common:
disable-via-mobile: "「モバイルからの投稿」フラグを付けない" disable-via-mobile: "「モバイルからの投稿」フラグを付けない"
load-raw-images: "添付された画像を高画質で表示する" load-raw-images: "添付された画像を高画質で表示する"
load-remote-media: "リモートサーバーのメディアを表示する" load-remote-media: "リモートサーバーのメディアを表示する"
sync: "同期"
home-profile: "ホームのプロファイル"
deck-profile: "デッキのプロファイル"
search: "検索" search: "検索"
delete: "削除" delete: "削除"
@ -265,6 +296,7 @@ common:
my-token-regenerated: "あなたのトークンが更新されたのでサインアウトします。" my-token-regenerated: "あなたのトークンが更新されたのでサインアウトします。"
hide-password: "パスワードを隠す" hide-password: "パスワードを隠す"
show-password: "パスワードを表示する" show-password: "パスワードを表示する"
enter-username: "ユーザー名を入力してください"
do-not-use-in-production: "これは開発ビルドです。本番環境で使用しないでください。" do-not-use-in-production: "これは開発ビルドです。本番環境で使用しないでください。"
user-suspended: "このユーザーは凍結されています。" user-suspended: "このユーザーは凍結されています。"
@ -480,20 +512,25 @@ common/views/components/messaging.vue:
search-user: "ユーザーを探す" search-user: "ユーザーを探す"
you: "あなた" you: "あなた"
no-history: "履歴はありません" no-history: "履歴はありません"
user: "ユーザー"
group: "グループ"
start-with-user: "ユーザーとトークを開始"
start-with-group: "グループとトークを開始"
select-group: "グループを選択してください"
common/views/components/messaging-room.vue: common/views/components/messaging-room.vue:
empty: "このユーザーと話したことはありません" not-talked-user: "このユーザーとの会話はありません"
not-talked-group: "このグループでの会話はありません"
no-history: "これより過去の履歴はありません" no-history: "これより過去の履歴はありません"
resize-form: "ドラッグしてフォームの広さを調整"
new-message: "新しいメッセージがあります" new-message: "新しいメッセージがあります"
only-one-file-attached: "メッセージに添付できるのはひとつのファイルのみです" only-one-file-attached: "メッセージに添付できるファイルはひとつです"
common/views/components/messaging-room.form.vue: common/views/components/messaging-room.form.vue:
input-message-here: "ここにメッセージを入力" input-message-here: "ここにメッセージを入力"
send: "送信" send: "送信"
attach-from-local: "PCからファイルを添付する" attach-from-local: "PCからファイルを添付する"
attach-from-drive: "ドライブからファイルを添付する" attach-from-drive: "ドライブからファイルを添付する"
only-one-file-attached: "メッセージに添付できるのはひとつのファイルのみです" only-one-file-attached: "メッセージに添付できるファイルはひとつです"
common/views/components/messaging-room.message.vue: common/views/components/messaging-room.message.vue:
is-read: "既読" is-read: "既読"
@ -585,6 +622,7 @@ common/views/components/poll-editor.vue:
common/views/components/reaction-picker.vue: common/views/components/reaction-picker.vue:
choose-reaction: "リアクションを選択" choose-reaction: "リアクションを選択"
input-reaction-placeholder: "または絵文字を入力"
common/views/components/emoji-picker.vue: common/views/components/emoji-picker.vue:
custom-emoji: "カスタム絵文字" custom-emoji: "カスタム絵文字"
@ -750,11 +788,36 @@ common/views/components/user-list-editor.vue:
remove-user: "このリストから削除" remove-user: "このリストから削除"
delete-are-you-sure: "リスト「$1」を削除しますか" delete-are-you-sure: "リスト「$1」を削除しますか"
deleted: "削除しました" deleted: "削除しました"
add-user: "ユーザーを追加"
common/views/components/user-group-editor.vue:
users: "メンバー"
rename: "グループ名を変更"
delete: "グループを削除"
transfer: "グループを譲渡"
transfer-are-you-sure: "グループ「$1」を「@$2」さんに譲渡しますか"
transferred: "グループを譲渡しました"
remove-user: "このグループから削除"
delete-are-you-sure: "グループ「$1」を削除しますか"
deleted: "削除しました"
invite: "招待"
invited: "招待を送信しました"
common/views/components/user-lists.vue: common/views/components/user-lists.vue:
user-lists: "リスト"
create-list: "リストを作成" create-list: "リストを作成"
list-name: "リスト名" list-name: "リスト名"
common/views/components/user-groups.vue:
user-groups: "グループ"
create-group: "グループを作成"
group-name: "グループ名"
owned-groups: "自分のグループ"
joined-groups: "参加しているグループ"
invites: "招待"
accept-invite: "参加"
reject-invite: "拒否"
common/views/widgets/broadcast.vue: common/views/widgets/broadcast.vue:
fetching: "確認中" fetching: "確認中"
no-broadcasts: "お知らせはありません" no-broadcasts: "お知らせはありません"
@ -827,6 +890,11 @@ common/views/pages/follow.vue:
follow-processing: "フォロー処理中" follow-processing: "フォロー処理中"
follow-request: "フォロー申請" follow-request: "フォロー申請"
common/views/pages/follow-requests.vue:
received-follow-requests: "フォロー申請"
accept: "承認"
reject: "拒否"
desktop: desktop:
banner-crop-title: "バナーとして表示する部分を選択" banner-crop-title: "バナーとして表示する部分を選択"
banner: "バナー" banner: "バナー"
@ -980,34 +1048,12 @@ desktop/views/components/notifications.vue:
empty: "ありません!" empty: "ありません!"
desktop/views/components/post-form.vue: desktop/views/components/post-form.vue:
add-visible-user: "+ユーザーを追加"
attach-location-information: "位置情報を添付する"
hide-contents: "内容を隠す"
reply-placeholder: "この投稿への返信..."
quote-placeholder: "この投稿を引用..."
submit: "投稿"
reply: "返信"
renote: "Renote"
posted: "投稿しました!" posted: "投稿しました!"
replied: "返信しました!" replied: "返信しました!"
reposted: "Renoteしました" reposted: "Renoteしました"
note-failed: "投稿に失敗しました" note-failed: "投稿に失敗しました"
reply-failed: "返信に失敗しました" reply-failed: "返信に失敗しました"
renote-failed: "Renoteに失敗しました" renote-failed: "Renoteに失敗しました"
posting: "投稿中"
attach-media-from-local: "PCからメディアを添付"
attach-media-from-drive: "ドライブからメディアを添付"
insert-a-kao: "v('ω')v"
create-poll: "アンケートを作成"
text-remain: "残り{}文字"
recent-tags: "最近"
local-only-message: "この投稿はローカルにのみ公開されます"
click-to-tagging: "クリックでタグ付け"
visibility: "公開範囲"
geolocation-alert: "お使いの端末は位置情報に対応していません"
error: "エラー"
enter-username: "ユーザー名を入力してください"
annotations: "内容への注釈 (オプション)"
desktop/views/components/post-form-window.vue: desktop/views/components/post-form-window.vue:
note: "新規投稿" note: "新規投稿"
@ -1139,6 +1185,7 @@ desktop/views/components/ui.header.vue:
desktop/views/components/ui.header.account.vue: desktop/views/components/ui.header.account.vue:
profile: "プロフィール" profile: "プロフィール"
lists: "リスト" lists: "リスト"
groups: "グループ"
follow-requests: "フォロー申請" follow-requests: "フォロー申請"
admin: "管理" admin: "管理"
@ -1154,14 +1201,6 @@ desktop/views/components/ui.header.post.vue:
desktop/views/components/ui.header.search.vue: desktop/views/components/ui.header.search.vue:
placeholder: "検索" placeholder: "検索"
desktop/views/components/received-follow-requests-window.vue:
title: "フォロー申請"
accept: "承認"
reject: "拒否"
desktop/views/components/user-lists-window.vue:
title: "リスト"
desktop/views/components/user-preview.vue: desktop/views/components/user-preview.vue:
notes: "投稿" notes: "投稿"
following: "フォロー" following: "フォロー"
@ -1190,8 +1229,12 @@ admin/views/index.vue:
abuse: "スパム報告" abuse: "スパム報告"
queue: "ジョブキュー" queue: "ジョブキュー"
logs: "ログ" logs: "ログ"
db: "データベース"
back-to-misskey: "Misskeyに戻る" back-to-misskey: "Misskeyに戻る"
admin/views/db.vue:
tables: "テーブル"
admin/views/dashboard.vue: admin/views/dashboard.vue:
dashboard: "ダッシュボード" dashboard: "ダッシュボード"
accounts: "アカウント" accounts: "アカウント"
@ -1204,6 +1247,33 @@ admin/views/dashboard.vue:
admin/views/queue.vue: admin/views/queue.vue:
title: "キュー" title: "キュー"
remove-all-jobs: "すべてのジョブをクリア" remove-all-jobs: "すべてのジョブをクリア"
jobs: "ジョブ"
queue: "キュー"
domains:
deliver: "配送"
inbox: "受信"
db: "データベース"
objectStorage: "オブジェクトストレージ"
state: "状態"
states:
active: "処理中"
delayed: "予約済み"
waiting: "順番待ち"
result-is-truncated: "結果は省略されています"
other-queues: "その他のキュー"
admin/views/logs.vue:
logs: "ログ"
domain: "ドメイン"
level: "レベル"
levels:
all: "全て"
info: "情報"
success: "成功"
warning: "警告"
error: "エラー"
debug: "デバッグ"
delete-all: "全て削除"
admin/views/abuse.vue: admin/views/abuse.vue:
title: "スパム報告" title: "スパム報告"
@ -1252,9 +1322,11 @@ admin/views/instance.vue:
mb: "メガバイト単位" mb: "メガバイト単位"
recaptcha-config: "reCAPTCHAの設定" recaptcha-config: "reCAPTCHAの設定"
recaptcha-info: "reCAPTCHAを有効にする場合、reCAPTCHAトークンを取得する必要があります。https://www.google.com/recaptcha/intro/ にアクセスしてトークンを取得してください。" recaptcha-info: "reCAPTCHAを有効にする場合、reCAPTCHAトークンを取得する必要があります。https://www.google.com/recaptcha/intro/ にアクセスしてトークンを取得してください。"
recaptcha-info2: "v3は非対応です。v2を使用してください。"
enable-recaptcha: "reCAPTCHAを有効にする" enable-recaptcha: "reCAPTCHAを有効にする"
recaptcha-site-key: "reCAPTCHA site key" recaptcha-site-key: "サイトキー"
recaptcha-secret-key: "reCAPTCHA secret key" recaptcha-secret-key: "シークレットキー"
recaptcha-preview: "プレビュー"
hidden-tags: "非表示ハッシュタグ" hidden-tags: "非表示ハッシュタグ"
hidden-tags-info: "集計から除外するハッシュタグを改行で区切って記述します。" hidden-tags-info: "集計から除外するハッシュタグを改行で区切って記述します。"
external-service-integration-config: "外部サービス連携" external-service-integration-config: "外部サービス連携"
@ -1357,6 +1429,9 @@ admin/views/drive.vue:
unmark-as-sensitive: "閲覧注意を解除" unmark-as-sensitive: "閲覧注意を解除"
marked-as-sensitive: "閲覧注意に設定しました" marked-as-sensitive: "閲覧注意に設定しました"
unmarked-as-sensitive: "閲覧注意を解除しました" unmarked-as-sensitive: "閲覧注意を解除しました"
clean-remote-files: "リモートファイルのキャッシュを削除"
clean-remote-files-are-you-sure: "すべてのリモートファイルのキャッシュを削除してもよろしいですか?"
clean-up: "クリーンアップ"
admin/views/users.vue: admin/views/users.vue:
operation: "操作" operation: "操作"
@ -1509,6 +1584,7 @@ admin/views/federation.vue:
day: "1日ごと" day: "1日ごと"
blocked-hosts: "ブロック" blocked-hosts: "ブロック"
blocked-hosts-info: "ブロックしたいホストを改行で区切って記述します。" blocked-hosts-info: "ブロックしたいホストを改行で区切って記述します。"
save: "保存"
desktop/views/pages/welcome.vue: desktop/views/pages/welcome.vue:
about: "詳しく..." about: "詳しく..."
@ -1671,18 +1747,6 @@ mobile/views/components/note-sub.vue:
mobile/views/components/notifications.vue: mobile/views/components/notifications.vue:
empty: "ありません!" empty: "ありません!"
mobile/views/components/post-form.vue:
add-visible-user: "ユーザーを追加"
submit: "投稿"
reply: "返信"
renote: "Renote"
quote-placeholder: "この投稿を引用... (オプション)"
reply-placeholder: "この投稿への返信..."
cw-placeholder: "内容への注釈 (オプション)"
geolocation-alert: "お使いの端末は位置情報に対応していません"
error: "エラー"
username-prompt: "ユーザー名を入力してください"
mobile/views/components/sub-note-content.vue: mobile/views/components/sub-note-content.vue:
private: "この投稿は非公開です" private: "この投稿は非公開です"
deleted: "この投稿は削除されました" deleted: "この投稿は削除されました"
@ -1699,6 +1763,7 @@ mobile/views/components/ui.nav.vue:
follow-requests: "フォロー申請" follow-requests: "フォロー申請"
search: "検索" search: "検索"
user-lists: "リスト" user-lists: "リスト"
user-groups: "グループ"
widgets: "ウィジェット" widgets: "ウィジェット"
game: "ゲーム" game: "ゲーム"
admin: "管理" admin: "管理"
@ -1713,9 +1778,6 @@ mobile/views/pages/drive.vue:
move-folder: "このフォルダを移動" move-folder: "このフォルダを移動"
delete-folder: "このフォルダを削除" delete-folder: "このフォルダを削除"
mobile/views/pages/user-lists.vue:
title: "リスト"
mobile/views/pages/signup.vue: mobile/views/pages/signup.vue:
lets-start: "📦 始めましょう" lets-start: "📦 始めましょう"
@ -1748,11 +1810,6 @@ mobile/views/pages/widgets/activity.vue:
mobile/views/pages/share.vue: mobile/views/pages/share.vue:
share-with: "{name}で共有" share-with: "{name}で共有"
mobile/views/pages/received-follow-requests.vue:
title: "フォロー申請"
accept: "承認"
reject: "拒否"
mobile/views/pages/note.vue: mobile/views/pages/note.vue:
title: "投稿" title: "投稿"
prev: "前の投稿" prev: "前の投稿"
@ -1873,6 +1930,10 @@ pages:
edit-this-page: "このページを編集" edit-this-page: "このページを編集"
view-source: "ソースを表示" view-source: "ソースを表示"
view-page: "ページを見る" view-page: "ページを見る"
like: "いいね"
unlike: "いいね解除"
liked-pages: "いいねしたページ"
my-pages: "自分のページ"
inspector: "インスペクター" inspector: "インスペクター"
content: "ページブロック" content: "ページブロック"
variables: "変数" variables: "変数"
@ -2006,8 +2067,8 @@ pages:
_divide: _divide:
arg1: "A" arg1: "A"
arg2: "B" arg2: "B"
remind: "÷ 割った余り" mod: "÷ 割った余り"
_remind: _mod:
arg1: "A" arg1: "A"
arg2: "B" arg2: "B"
eq: "AとBが同じ" eq: "AとBが同じ"
@ -2090,6 +2151,9 @@ pages:
_pick: _pick:
arg1: "リスト" arg1: "リスト"
arg2: "位置" arg2: "位置"
listLen: "リストの長さを取得"
_listLen:
arg1: "リスト"
number: "数値" number: "数値"
stringToNumber: "テキストを数値に" stringToNumber: "テキストを数値に"
_stringToNumber: _stringToNumber:

View File

@ -62,6 +62,14 @@ common:
favorites: "お気に入り" favorites: "お気に入り"
permissions: permissions:
"write:votes": "投票するで" "write:votes": "投票するで"
post-form:
submit: "投稿"
reply: "返す"
renote: "Renote"
error: "エラー"
enter-username: "ユーザー名を入力してや"
add-visible-user: "ユーザー増やす"
username-prompt: "ユーザー名を入力してや"
weekday-short: weekday-short:
sunday: "日" sunday: "日"
monday: "月" monday: "月"
@ -121,6 +129,7 @@ common:
update-available-title: "更新があんで" update-available-title: "更新があんで"
update-available: "Misskeyの新しいバージョンがあんで({newer}。現在{current}をつこてるわ)。ページを再度読み込みしたると更新が適用されるわ。" update-available: "Misskeyの新しいバージョンがあんで({newer}。現在{current}をつこてるわ)。ページを再度読み込みしたると更新が適用されるわ。"
my-token-regenerated: "あんさんのトークンが更新されたらしいわ。すまんがとりあえずサインアウトすんで。" my-token-regenerated: "あんさんのトークンが更新されたらしいわ。すまんがとりあえずサインアウトすんで。"
enter-username: "ユーザー名を入力してや"
do-not-use-in-production: "開発ビルドや。本番環境で使わんといて!知らんで!" do-not-use-in-production: "開発ビルドや。本番環境で使わんといて!知らんで!"
is-remote-post: "この投稿情報はコピーです。" is-remote-post: "この投稿情報はコピーです。"
view-on-remote: "ちゃんとした情報見せてや!" view-on-remote: "ちゃんとした情報見せてや!"
@ -294,18 +303,15 @@ common/views/components/messaging.vue:
search-user: "ユーザーを探す" search-user: "ユーザーを探す"
you: "あんさん" you: "あんさん"
no-history: "履歴はあらへんで" no-history: "履歴はあらへんで"
user: "ユーザー"
common/views/components/messaging-room.vue: common/views/components/messaging-room.vue:
empty: "このユーザーと話したことはあらへんで"
no-history: "これより過去の履歴はあらへんで" no-history: "これより過去の履歴はあらへんで"
resize-form: "ドラッグしてフォームの広さを調整"
new-message: "新しいメッセージがあるで" new-message: "新しいメッセージがあるで"
only-one-file-attached: "メッセージに添付できんのはひとつのファイルのみやで"
common/views/components/messaging-room.form.vue: common/views/components/messaging-room.form.vue:
input-message-here: "ここにメッセージ書いてや" input-message-here: "ここにメッセージ書いてや"
send: "送信" send: "送信"
attach-from-local: "PCからファイルを添付する" attach-from-local: "PCからファイルを添付する"
attach-from-drive: "ドライブからファイルを添付する" attach-from-drive: "ドライブからファイルを添付する"
only-one-file-attached: "メッセージに添付できんのはひとつのファイルのみやで"
common/views/components/messaging-room.message.vue: common/views/components/messaging-room.message.vue:
is-read: "既読" is-read: "既読"
deleted: "このメッセージは削除されたわ" deleted: "このメッセージは削除されたわ"
@ -476,8 +482,14 @@ common/views/components/profile-editor.vue:
enter-password: "パスワードを入れてや" enter-password: "パスワードを入れてや"
common/views/components/user-list-editor.vue: common/views/components/user-list-editor.vue:
users: "ユーザー" users: "ユーザー"
add-user: "ユーザー増やす"
common/views/components/user-group-editor.vue:
invite: "招待"
common/views/components/user-lists.vue: common/views/components/user-lists.vue:
user-lists: "リスト"
list-name: "リスト名" list-name: "リスト名"
common/views/components/user-groups.vue:
invites: "招待"
common/views/widgets/broadcast.vue: common/views/widgets/broadcast.vue:
fetching: "見てみるわ…" fetching: "見てみるわ…"
no-broadcasts: "お知らせはあらへんで" no-broadcasts: "お知らせはあらへんで"
@ -536,6 +548,8 @@ common/views/pages/follow.vue:
request-pending: "フォローの許し待っとる" request-pending: "フォローの許し待っとる"
follow-processing: "今フォロー処理やっとる‥" follow-processing: "今フォロー処理やっとる‥"
follow-request: "フォロー許してくれや!言うてみる" follow-request: "フォロー許してくれや!言うてみる"
common/views/pages/follow-requests.vue:
received-follow-requests: "フォロー許してくれや!言うてみる"
desktop: desktop:
banner-crop-title: "どこバナーとして出す?" banner-crop-title: "どこバナーとして出す?"
banner: "バナー" banner: "バナー"
@ -664,33 +678,12 @@ desktop/views/components/notes.vue:
desktop/views/components/notifications.vue: desktop/views/components/notifications.vue:
empty: "あらへん!" empty: "あらへん!"
desktop/views/components/post-form.vue: desktop/views/components/post-form.vue:
add-visible-user: "+ユーザー増やす"
attach-location-information: "いる場所くっつけるで"
hide-contents: "内容を隠す"
reply-placeholder: "この投稿への返信..."
quote-placeholder: "この投稿を引用..."
submit: "投稿"
reply: "返信"
renote: "Renote"
posted: "投稿したで!" posted: "投稿したで!"
replied: "返信したで!" replied: "返信したで!"
reposted: "Renoteしたで" reposted: "Renoteしたで"
note-failed: "投稿に失敗したで" note-failed: "投稿に失敗したで"
reply-failed: "返信に失敗したで" reply-failed: "返信に失敗したで"
renote-failed: "Renoteでけへん" renote-failed: "Renoteでけへん"
posting: "投稿中"
attach-media-from-local: "PCからメディア持ってくる"
attach-media-from-drive: "ドライブからメディア持ってくる"
create-poll: "アンケートを作成"
text-remain: "残り{}文字"
recent-tags: "最近のタグ"
local-only-message: "この投稿はローカルだけ公開されるで"
click-to-tagging: "クリックでタグ付け"
visibility: "公開範囲"
geolocation-alert: "あんさんのつことる端末は位置情報に対応しとらんみたいやわ、知らんけど。"
error: "エラー"
enter-username: "ユーザー名を入力してや"
annotations: "もっと教えてな(別にええけど)"
desktop/views/components/post-form-window.vue: desktop/views/components/post-form-window.vue:
note: "新規投稿" note: "新規投稿"
reply: "返す" reply: "返す"
@ -809,12 +802,6 @@ desktop/views/components/ui.header.post.vue:
post: "新規投稿" post: "新規投稿"
desktop/views/components/ui.header.search.vue: desktop/views/components/ui.header.search.vue:
placeholder: "検索" placeholder: "検索"
desktop/views/components/received-follow-requests-window.vue:
title: "フォロー許してくれや!言うてみる"
accept: "許す"
reject: "許さん"
desktop/views/components/user-lists-window.vue:
title: "リスト"
desktop/views/components/user-preview.vue: desktop/views/components/user-preview.vue:
notes: "投稿" notes: "投稿"
following: "フォロー" following: "フォロー"
@ -836,7 +823,6 @@ admin/views/index.vue:
users: "ユーザー" users: "ユーザー"
federation: "連合" federation: "連合"
announcements: "知っといてや" announcements: "知っといてや"
hashtags: "ハッシュタグ"
back-to-misskey: "Misskeyに戻る" back-to-misskey: "Misskeyに戻る"
admin/views/dashboard.vue: admin/views/dashboard.vue:
dashboard: "ダッシュボード" dashboard: "ダッシュボード"
@ -846,6 +832,10 @@ admin/views/dashboard.vue:
instances: "インスタンス" instances: "インスタンス"
this-instance: "ワイのインスタンス" this-instance: "ワイのインスタンス"
federated: "連合" federated: "連合"
admin/views/logs.vue:
levels:
info: "情報"
error: "エラー"
admin/views/abuse.vue: admin/views/abuse.vue:
details: "もっと" details: "もっと"
remove-report: "削除" remove-report: "削除"
@ -861,6 +851,7 @@ admin/views/instance.vue:
maintainer-name: "管理者名" maintainer-name: "管理者名"
maintainer-email: "管理者の連絡先" maintainer-email: "管理者の連絡先"
drive-config: "ドライブの設定" drive-config: "ドライブの設定"
object-storage-endpoint: "エンドポイント"
cache-remote-files: "リモートのファイルをキャッシュする" cache-remote-files: "リモートのファイルをキャッシュする"
cache-remote-files-desc: "この設定を無効にすると、リモートファイルをこっちで保管せずに直接リンク張るようになるで。サーバーのストレージは軽くやろうけど、プライバシー設定で直リンクを向こうにしとるユーザーはファイルが見れへんし、サムネイルが無いから通信量が増えたりするから、普通はオンにしといてな。" cache-remote-files-desc: "この設定を無効にすると、リモートファイルをこっちで保管せずに直接リンク張るようになるで。サーバーのストレージは軽くやろうけど、プライバシー設定で直リンクを向こうにしとるユーザーはファイルが見れへんし、サムネイルが無いから通信量が増えたりするから、普通はオンにしといてな。"
local-drive-capacity-mb: "ローカルユーザーひとりあたりのドライブ容量" local-drive-capacity-mb: "ローカルユーザーひとりあたりのドライブ容量"
@ -869,8 +860,7 @@ admin/views/instance.vue:
recaptcha-config: "reCAPTCHAの設定" recaptcha-config: "reCAPTCHAの設定"
recaptcha-info: "reCAPTCHAを有効にするにはreCAPTCHAトークンが要るで。https://www.google.com/recaptcha/intro/ にアクセスしてトークンを取得してな。" recaptcha-info: "reCAPTCHAを有効にするにはreCAPTCHAトークンが要るで。https://www.google.com/recaptcha/intro/ にアクセスしてトークンを取得してな。"
enable-recaptcha: "reCAPTCHAを有効にする" enable-recaptcha: "reCAPTCHAを有効にする"
recaptcha-site-key: "reCAPTCHA site key" recaptcha-preview: "試してみる"
recaptcha-secret-key: "reCAPTCHA secret key"
twitter-integration-config: "Twitter連携の設定" twitter-integration-config: "Twitter連携の設定"
twitter-integration-info: "コールバックURLは {url} に設定してや。" twitter-integration-info: "コールバックURLは {url} に設定してや。"
enable-twitter-integration: "Twitter連携を有効にする" enable-twitter-integration: "Twitter連携を有効にする"
@ -992,6 +982,7 @@ admin/views/federation.vue:
hour: "1時間ごと" hour: "1時間ごと"
day: "1日ごと" day: "1日ごと"
blocked-hosts: "ブロック" blocked-hosts: "ブロック"
save: "保存"
desktop/views/pages/welcome.vue: desktop/views/pages/welcome.vue:
about: "もうちょい……" about: "もうちょい……"
timeline: "タイムライン" timeline: "タイムライン"
@ -1115,17 +1106,6 @@ mobile/views/components/note-sub.vue:
cat: "cat" cat: "cat"
mobile/views/components/notifications.vue: mobile/views/components/notifications.vue:
empty: "あらへん!" empty: "あらへん!"
mobile/views/components/post-form.vue:
add-visible-user: "ユーザー増やす"
submit: "投稿"
reply: "返す"
renote: "Renote"
quote-placeholder: "この投稿を持ってくる(オプション)"
reply-placeholder: "この投稿への返信..."
cw-placeholder: "内容への注釈 (オプション)"
geolocation-alert: "あんさんのつことる端末は位置情報に対応しとらんみたいやわ、知らんけど。"
error: "エラー"
username-prompt: "ユーザー名を入力してや"
mobile/views/components/sub-note-content.vue: mobile/views/components/sub-note-content.vue:
private: "この投稿は見せられへんわ" private: "この投稿は見せられへんわ"
deleted: "この投稿なんか無くなってもうたわ" deleted: "この投稿なんか無くなってもうたわ"
@ -1148,8 +1128,6 @@ mobile/views/pages/drive.vue:
contextmenu: contextmenu:
upload: "ファイル上げる" upload: "ファイル上げる"
create-folder: "フォルダー作る" create-folder: "フォルダー作る"
mobile/views/pages/user-lists.vue:
title: "リスト"
mobile/views/pages/signup.vue: mobile/views/pages/signup.vue:
lets-start: "📦 始めようや" lets-start: "📦 始めようや"
mobile/views/pages/followers.vue: mobile/views/pages/followers.vue:
@ -1172,10 +1150,6 @@ mobile/views/pages/widgets/activity.vue:
activity: "やっとること" activity: "やっとること"
mobile/views/pages/share.vue: mobile/views/pages/share.vue:
share-with: "{name}で共有" share-with: "{name}で共有"
mobile/views/pages/received-follow-requests.vue:
title: "フォロー許してくれや!"
accept: "許す"
reject: "許さん"
mobile/views/pages/note.vue: mobile/views/pages/note.vue:
title: "投稿" title: "投稿"
prev: "前のやつ" prev: "前のやつ"
@ -1260,6 +1234,7 @@ dev/views/new-app.vue:
authority-desc: "ここにチェックした機能しかAPIからアクセスできひんから気ぃつけてな" authority-desc: "ここにチェックした機能しかAPIからアクセスできひんから気ぃつけてな"
authority-warning: "アプリ作った後でも変えれるけど、新しいやつ追加したらそん時関連付いてるユーザーキーは全部ほかされるで。" authority-warning: "アプリ作った後でも変えれるけど、新しいやつ追加したらそん時関連付いてるユーザーキーは全部ほかされるで。"
pages: pages:
like: "ええやん"
blocks: blocks:
image: "画像" image: "画像"
post: "投稿フォーム" post: "投稿フォーム"
@ -1279,5 +1254,7 @@ pages:
arg2: "リスト" arg2: "リスト"
_pick: _pick:
arg1: "リスト" arg1: "リスト"
_listLen:
arg1: "リスト"
types: types:
array: "リスト" array: "リスト"

View File

@ -4,7 +4,7 @@ meta:
common: common:
misskey: "연합우주의 ⭐" misskey: "연합우주의 ⭐"
about-title: "연합우주의 ⭐." about-title: "연합우주의 ⭐."
about: "Misskey를 찾아주셔서 감사합니다. Misskey는 지구에서 태어난 <b>분산 마이크로 블로그 SNS </b> 입니다. Fediverse(다양한 SNS로 구성되는 우주)에 존재하 다른 SNS와 상호 연결되어 있습니다. 잠시 도시의 번잡함에서 벗어나 새로운 인터넷에 다이브 해 보지 않겠습니까." about: "Misskey를 발견해주셔서 감사합니다! Misskey는 지구에서 태어난 <b>분산 마이크로 블로그 SNS</b> 입니다. Fediverse (다양한 SNS가 함께하는 우주)에 존재하고 있어서, 다른 SNS와 서로 연결되어 있습니다. 번잡한 도시에서 벗어나 새로운 인터넷에 빠져보지 않으시겠어요?"
intro: intro:
title: "Misskey란?" title: "Misskey란?"
about: "Misskey는 오픈소스 <b>분산형 마이크로블로그 SNS</b>입니다. 다양하고 폭넓게 커스터마이징할 수 있는 UI, 글에 대한 리액션, 파일을 관리할 수 있는 드라이브 등의 선진적인 기능을 갖추고 있습니다. 더하여 Fediverse라고 부르는 네트워크에 연결할 수 있어 다른 SNS와도 주고받을 수 있습니다. 예를 들자면, 당신이 무언가를 게시하면, 해당 게시물은 Misskey 뿐만 아니라 다른 SNS에도 전해집니다. 살짝 어떤 행성에서 다른 행성으로 전파를 발신하고 있는 모습을 상상해주세요." about: "Misskey는 오픈소스 <b>분산형 마이크로블로그 SNS</b>입니다. 다양하고 폭넓게 커스터마이징할 수 있는 UI, 글에 대한 리액션, 파일을 관리할 수 있는 드라이브 등의 선진적인 기능을 갖추고 있습니다. 더하여 Fediverse라고 부르는 네트워크에 연결할 수 있어 다른 SNS와도 주고받을 수 있습니다. 예를 들자면, 당신이 무언가를 게시하면, 해당 게시물은 Misskey 뿐만 아니라 다른 SNS에도 전해집니다. 살짝 어떤 행성에서 다른 행성으로 전파를 발신하고 있는 모습을 상상해주세요."
@ -20,7 +20,7 @@ common:
outro: "이외에도 Misskey에만 있는 기능이 아직도 더 있으니 부디 여러분 자신의 눈으로 확인해보시기 바랍니다. Misskey는 분산형 SNS라서 이 인스턴스가 마음에 들지 않으신다면 다른 인스턴스를 시도해보실 수도 있습니다. 그럼, GLHF!" outro: "이외에도 Misskey에만 있는 기능이 아직도 더 있으니 부디 여러분 자신의 눈으로 확인해보시기 바랍니다. Misskey는 분산형 SNS라서 이 인스턴스가 마음에 들지 않으신다면 다른 인스턴스를 시도해보실 수도 있습니다. 그럼, GLHF!"
adblock: adblock:
detected: "광고 차단기를 해제하십시오" detected: "광고 차단기를 해제하십시오"
warning: "<strong>Misskey는 광고를 게재하지 않습니다</strong>. 그러나 광고 차단 기능을 사용할 경우 일부 기능을 사용할 수 없게 될 가능성이나 결함이 발생하는 경우가 있습니다." warning: "<strong>Misskey는 광고를 게재하지 않습니다</strong>. 하지만 광고 차단 기능을 사용할 경우 일부 기능을 사용할 수 없거나 문제가 발생할 수 있습니다."
application-authorization: "앱 연계" application-authorization: "앱 연계"
close: "닫기" close: "닫기"
do-not-copy-paste: "여기에 코드를 입력하거나 붙여넣지 마십시오. 계정이 무단으로 사용될 수 있습니다." do-not-copy-paste: "여기에 코드를 입력하거나 붙여넣지 마십시오. 계정이 무단으로 사용될 수 있습니다."
@ -42,7 +42,7 @@ common:
gotit: "Got it!" gotit: "Got it!"
notification: notification:
file-uploaded: "파일이 업로드되었습니다" file-uploaded: "파일이 업로드되었습니다"
message-from: "{}님으로부터 메시지:" message-from: "{}님 메시지:"
reversi-invited: "게임 초대가 있습니다" reversi-invited: "게임 초대가 있습니다"
reversi-invited-by: "{}님으로부터" reversi-invited-by: "{}님으로부터"
notified-by: "{}님으로부터" notified-by: "{}님으로부터"
@ -51,7 +51,7 @@ common:
time: time:
unknown: "알 수 없는 시간" unknown: "알 수 없는 시간"
future: "미래" future: "미래"
just_now: "방금" just_now: "방금"
seconds_ago: "{}초 전" seconds_ago: "{}초 전"
minutes_ago: "{}분 전" minutes_ago: "{}분 전"
hours_ago: "{}시간 전" hours_ago: "{}시간 전"
@ -67,19 +67,19 @@ common:
home: "홈" home: "홈"
deck: "덱" deck: "덱"
timeline: "타임라인" timeline: "타임라인"
explore: "발견" explore: "발견하기"
following: "팔로우 중" following: "팔로우 중"
followers: "팔로워" followers: "팔로워"
favorites: "즐겨찾기" favorites: "즐겨찾기"
permissions: permissions:
"read:account": "계정 정보 보기" "read:account": "계정 정보를 볼 수 있습니다."
"write:account": "계정 정보 변경" "write:account": "계정 정보 변경할 수 있습니다."
"read:blocks": "차단 보기" "read:blocks": "차단 목록을 볼 수 있습니다."
"write:blocks": "차단 수정" "write:blocks": "차단 목록을 조작할 수 있습니다."
"read:drive": "드라이브 보기" "read:drive": "드라이브의 파일들을 볼 수 있습니다."
"write:drive": "드라이브 수정" "write:drive": "드라이브의 파일들을 조작할 수 있습니다."
"read:favorites": "즐겨찾기 보기" "read:favorites": "즐겨찾기 목록을 볼 수 있습니다."
"write:favorites": "즐겨찾기 수정" "write:favorites": "즐겨찾기 목록을 조작할 수 있습니다."
"read:following": "팔로우 정보 보기" "read:following": "팔로우 정보 보기"
"write:following": "팔로잉, 팔로우 수정" "write:following": "팔로잉, 팔로우 수정"
"read:messaging": "대화 보기" "read:messaging": "대화 보기"
@ -95,6 +95,33 @@ common:
empty-timeline-info: empty-timeline-info:
follow-users-to-make-your-timeline: "사용자를 팔로우하면 글이 타임라인에 표시됩니다." follow-users-to-make-your-timeline: "사용자를 팔로우하면 글이 타임라인에 표시됩니다."
explore: "사용자 탐색" explore: "사용자 탐색"
post-form:
attach-location-information: "위치 정보를 첨부합니다"
hide-contents: "내용 숨기기"
reply-placeholder: "이 글에 답글..."
quote-placeholder: "이 글을 인용..."
option-quote-placeholder: "이 글을 인용... (옵션)"
quote-attached: "인용함"
quote-question: "인용해서 작성하시겠습니까?"
submit: "글쓰기"
reply: "답글 달기"
renote: "리노트"
posting: "게시중"
attach-media-from-local: "PC에서 미디어 첨부"
attach-media-from-drive: "드라이브에서 미디어 첨부"
insert-a-kao: "v('ω')v"
create-poll: "투표 만들기"
text-remain: "{}문자 남음"
recent-tags: "최근"
local-only-message: "이 글은 로컬에만 공개되어 있습니다"
click-to-tagging: "클릭하여 태그 넣기"
visibility: "공개 범위"
geolocation-alert: "사용 중이신 장치에서는 위치 정보를 사용할 수 없습니다"
error: "오류"
enter-username: "사용자명을 입력해주세요"
add-visible-user: "사용자 추가"
cw-placeholder: "내용에 대한 주석 (옵션)"
username-prompt: "사용자명을 입력해주세요"
weekday-short: weekday-short:
sunday: "일" sunday: "일"
monday: "월" monday: "월"
@ -243,6 +270,9 @@ common:
disable-via-mobile: "작성하는 글에 \"모바일에서 작성함\" 을 붙이지 않음" disable-via-mobile: "작성하는 글에 \"모바일에서 작성함\" 을 붙이지 않음"
load-raw-images: "첨부 이미지를 고품질로 표시" load-raw-images: "첨부 이미지를 고품질로 표시"
load-remote-media: "원격 서버의 미디어를 표시" load-remote-media: "원격 서버의 미디어를 표시"
sync: "동기화"
home-profile: "홈 프로필"
deck-profile: "덱 프로필"
search: "검색" search: "검색"
delete: "삭제" delete: "삭제"
loading: "로드 중" loading: "로드 중"
@ -253,12 +283,13 @@ common:
my-token-regenerated: "당신의 토큰이 업데이트되었으므로 로그아웃합니다." my-token-regenerated: "당신의 토큰이 업데이트되었으므로 로그아웃합니다."
hide-password: "비밀번호 숨기기" hide-password: "비밀번호 숨기기"
show-password: "비밀번호 표시" show-password: "비밀번호 표시"
enter-username: "사용자명을 입력해주세요"
do-not-use-in-production: "이것은 개발 빌드입니다. 프로덕션 환경에서 사용하지 마십시오." do-not-use-in-production: "이것은 개발 빌드입니다. 프로덕션 환경에서 사용하지 마십시오."
user-suspended: "이 사용자는 정지된 상태입니다." user-suspended: "이 사용자는 정지된 상태입니다."
is-remote-user: "이 사용자 정보는 정확하지 않을 수 있습니다." is-remote-user: "이 사용자 정보는 정확하지 않을 수 있습니다."
is-remote-post: "이 글 정보는 복사본입니다." is-remote-post: "이 글 정보는 복사본입니다."
view-on-remote: "정확한 정보 보기" view-on-remote: "정확한 정보 보기"
renoted-by: "{user}이(가) 리노트" renoted-by: "{user}이 리노트"
no-notes: "글이 없습니다" no-notes: "글이 없습니다"
turn-on-darkmode: "어둠에 삼켜져라" turn-on-darkmode: "어둠에 삼켜져라"
turn-off-darkmode: "빛이 있으라" turn-off-darkmode: "빛이 있으라"
@ -448,18 +479,23 @@ common/views/components/messaging.vue:
search-user: "사용자 찾기" search-user: "사용자 찾기"
you: "당신" you: "당신"
no-history: "기록이 없습니다" no-history: "기록이 없습니다"
user: "사용자"
group: "그룹"
start-with-user: "사용자와 대화 시작"
start-with-group: "그룹과 대화 시작"
select-group: "그룹을 선택하여 주십시오"
common/views/components/messaging-room.vue: common/views/components/messaging-room.vue:
empty: "이 사용자와 대화한 적이 없습니다" not-talked-user: "이 사용자와 대화 없습니다"
not-talked-group: "이 그룹과의 대화가 없습니다"
no-history: "이것보다 과거의 기록이 없습니다" no-history: "이것보다 과거의 기록이 없습니다"
resize-form: "드래그하여 폼의 크기 조절"
new-message: "새 메시지가 있습니다" new-message: "새 메시지가 있습니다"
only-one-file-attached: "메시지에는 하나의 파일만 첨부할 수 있습니다" only-one-file-attached: "메시지에 첨부할 수 있는 파일은 하나까지입니다"
common/views/components/messaging-room.form.vue: common/views/components/messaging-room.form.vue:
input-message-here: "여기에 메시지를 입력하세요" input-message-here: "여기에 메시지를 입력하세요"
send: "전송" send: "전송"
attach-from-local: "PC에서 파일 첨부" attach-from-local: "PC에서 파일 첨부"
attach-from-drive: "드라이브에서 파일 첨부" attach-from-drive: "드라이브에서 파일 첨부"
only-one-file-attached: "메시지에는 하나의 파일만 첨부할 수 있습니다" only-one-file-attached: "메시지에 첨부할 수 있는 파일은 하나까지입니다"
common/views/components/messaging-room.message.vue: common/views/components/messaging-room.message.vue:
is-read: "읽음" is-read: "읽음"
deleted: "이 메시지는 삭제되었습니다" deleted: "이 메시지는 삭제되었습니다"
@ -544,6 +580,7 @@ common/views/components/poll-editor.vue:
day: "일" day: "일"
common/views/components/reaction-picker.vue: common/views/components/reaction-picker.vue:
choose-reaction: "리액션 선택" choose-reaction: "리액션 선택"
input-reaction-placeholder: "또는 이모지 입력"
common/views/components/emoji-picker.vue: common/views/components/emoji-picker.vue:
custom-emoji: "커스텀 이모지" custom-emoji: "커스텀 이모지"
people: "사람들" people: "사람들"
@ -585,6 +622,7 @@ common/views/components/signup.vue:
password-matched: "확인되었습니다" password-matched: "확인되었습니다"
password-not-matched: "일치하지 않습니다" password-not-matched: "일치하지 않습니다"
recaptcha: "자동 가입 방지" recaptcha: "자동 가입 방지"
agree-to: "{0}에 동의합니다."
tos: "이용 약관" tos: "이용 약관"
create: "계정 만들기" create: "계정 만들기"
some-error: "알 수 없는 이유로 계정 만들기에 실패했습니다. 다시 한번 시도해 주세요." some-error: "알 수 없는 이유로 계정 만들기에 실패했습니다. 다시 한번 시도해 주세요."
@ -693,9 +731,32 @@ common/views/components/user-list-editor.vue:
remove-user: "이 리스트에서 제거" remove-user: "이 리스트에서 제거"
delete-are-you-sure: "리스트 \"$1\"을 삭제하시겠습니까?" delete-are-you-sure: "리스트 \"$1\"을 삭제하시겠습니까?"
deleted: "삭제하였습니다" deleted: "삭제하였습니다"
add-user: "사용자 추가"
common/views/components/user-group-editor.vue:
users: "멤버"
rename: "그룹명을 변경"
delete: "그룹을 삭제"
transfer: "그룹을 양도"
transfer-are-you-sure: "그룹 「$1」을 「@$2」 님에게 양도하시겠습니까?"
transferred: "그룹을 양도하였습니다"
remove-user: "이 그룹에서 삭제"
delete-are-you-sure: "그룹 「$1」을 삭제하시겠습니까?"
deleted: "삭제하였습니다"
invite: "초대"
invited: "초대를 보냈습니다"
common/views/components/user-lists.vue: common/views/components/user-lists.vue:
user-lists: "리스트"
create-list: "리스트 만들기" create-list: "리스트 만들기"
list-name: "리스트 이름" list-name: "리스트 이름"
common/views/components/user-groups.vue:
user-groups: "그룹"
create-group: "그룹 만들기"
group-name: "그룹명"
owned-groups: "자신의 그룹"
joined-groups: "참여중인 그룹"
invites: "초대"
accept-invite: "참여"
reject-invite: "거부"
common/views/widgets/broadcast.vue: common/views/widgets/broadcast.vue:
fetching: "확인중" fetching: "확인중"
no-broadcasts: "공지사항이 없습니다" no-broadcasts: "공지사항이 없습니다"
@ -757,6 +818,10 @@ common/views/pages/follow.vue:
request-pending: "팔로우 허가 대기중" request-pending: "팔로우 허가 대기중"
follow-processing: "팔로우 처리중" follow-processing: "팔로우 처리중"
follow-request: "팔로우 요청" follow-request: "팔로우 요청"
common/views/pages/follow-requests.vue:
received-follow-requests: "팔로우 요청"
accept: "승인"
reject: "거부"
desktop: desktop:
banner-crop-title: "배너로 표시할 부분을 선택" banner-crop-title: "배너로 표시할 부분을 선택"
banner: "배너" banner: "배너"
@ -887,34 +952,12 @@ desktop/views/components/notes.vue:
desktop/views/components/notifications.vue: desktop/views/components/notifications.vue:
empty: "비었습니다!" empty: "비었습니다!"
desktop/views/components/post-form.vue: desktop/views/components/post-form.vue:
add-visible-user: "+사용자 추가"
attach-location-information: "위치정보를 첨부하기"
hide-contents: "내용 숨기기"
reply-placeholder: "이 글에 답글..."
quote-placeholder: "이 글을 인용..."
submit: "글쓰기"
reply: "답글 달기"
renote: "리노트"
posted: "게시하였습니다!" posted: "게시하였습니다!"
replied: "답글을 달았습니다!" replied: "답글을 달았습니다!"
reposted: "리노트 하였습니다!" reposted: "리노트 하였습니다!"
note-failed: "게시에 실패하였습니다" note-failed: "게시에 실패하였습니다"
reply-failed: "답글을 달지 못했습니다" reply-failed: "답글을 달지 못했습니다"
renote-failed: "리노트에 실패하였습니다" renote-failed: "리노트에 실패하였습니다"
posting: "게시중"
attach-media-from-local: "PC에서 미디어 첨부"
attach-media-from-drive: "드라이브에서 미디어 첨부"
insert-a-kao: "v('ω')v"
create-poll: "투표 만들기"
text-remain: "{}문자 남음"
recent-tags: "최근"
local-only-message: "이 글은 로컬에만 공개되어 있습니다"
click-to-tagging: "클릭하여 태그 넣기"
visibility: "공개설정"
geolocation-alert: "사용하시는 장치가 위치정보 기능에 대응하지 않습니다"
error: "오류"
enter-username: "사용자명을 입력해주세요"
annotations: "내용 주석 (선택적)"
desktop/views/components/post-form-window.vue: desktop/views/components/post-form-window.vue:
note: "새 글" note: "새 글"
reply: "답글 달기" reply: "답글 달기"
@ -1028,6 +1071,7 @@ desktop/views/components/ui.header.vue:
desktop/views/components/ui.header.account.vue: desktop/views/components/ui.header.account.vue:
profile: "프로필" profile: "프로필"
lists: "리스트" lists: "리스트"
groups: "그룹"
follow-requests: "팔로우 요청" follow-requests: "팔로우 요청"
admin: "관리" admin: "관리"
desktop/views/components/ui.header.nav.vue: desktop/views/components/ui.header.nav.vue:
@ -1038,12 +1082,6 @@ desktop/views/components/ui.header.post.vue:
post: "새 글" post: "새 글"
desktop/views/components/ui.header.search.vue: desktop/views/components/ui.header.search.vue:
placeholder: "검색" placeholder: "검색"
desktop/views/components/received-follow-requests-window.vue:
title: "팔로우 요청"
accept: "승인"
reject: "거부"
desktop/views/components/user-lists-window.vue:
title: "리스트"
desktop/views/components/user-preview.vue: desktop/views/components/user-preview.vue:
notes: "글" notes: "글"
following: "팔로잉" following: "팔로잉"
@ -1065,11 +1103,13 @@ admin/views/index.vue:
users: "사용자" users: "사용자"
federation: "연합" federation: "연합"
announcements: "공지사항" announcements: "공지사항"
hashtags: "해시태그"
abuse: "스팸 신고" abuse: "스팸 신고"
queue: "작업 대기열" queue: "작업 대기열"
logs: "로그" logs: "로그"
db: "데이터베이스"
back-to-misskey: "Misskey로 돌아가기" back-to-misskey: "Misskey로 돌아가기"
admin/views/db.vue:
tables: "테이블"
admin/views/dashboard.vue: admin/views/dashboard.vue:
dashboard: "대시보드" dashboard: "대시보드"
accounts: "계정" accounts: "계정"
@ -1081,6 +1121,32 @@ admin/views/dashboard.vue:
admin/views/queue.vue: admin/views/queue.vue:
title: "큐" title: "큐"
remove-all-jobs: "모든 작업 제거" remove-all-jobs: "모든 작업 제거"
jobs: "작업"
queue: "큐"
domains:
deliver: "전송"
inbox: "수신"
db: "데이터베이스"
objectStorage: "오브젝트 스토리지"
state: "상태"
states:
active: "처리중"
delayed: "지연됨"
waiting: "대기열에 있음"
result-is-truncated: "결과는 생략되었습니다"
other-queues: "기타 큐"
admin/views/logs.vue:
logs: "로그"
domain: "도메인"
level: "수준"
levels:
all: "전체"
info: "정보"
success: "성공"
warning: "경고"
error: "오류"
debug: "디버그"
delete-all: "모두 삭제"
admin/views/abuse.vue: admin/views/abuse.vue:
title: "스팸 신고" title: "스팸 신고"
target: "대상" target: "대상"
@ -1104,7 +1170,22 @@ admin/views/instance.vue:
maintainer-config: "관리자 정보" maintainer-config: "관리자 정보"
maintainer-name: "관리자 이름" maintainer-name: "관리자 이름"
maintainer-email: "관리자 연락처" maintainer-email: "관리자 연락처"
advanced-config: "그 외 설정"
note-and-tl: "글과 타임라인"
drive-config: "드라이브 설정" drive-config: "드라이브 설정"
use-object-storage: "오브젝트 스토리지를 사용"
object-storage-base-url: "URL"
object-storage-bucket: "버킷 이름"
object-storage-prefix: "프리픽스"
object-storage-endpoint: "엔드포인트"
object-storage-region: "리전"
object-storage-port: "포트"
object-storage-access-key: "액세스 키"
object-storage-secret-key: "시크릿 키"
object-storage-use-ssl: "SSL 사용"
object-storage-s3-info: "Amazon S3를 오브젝트 스토리지로 사용하는 경우의 「엔드포인트」와 「리전」의 설정값에 대해서는 {0}을 확인하여 주십시오."
object-storage-s3-info-here: "이곳"
object-storage-gcs-info: "Google Cloud Storage를 오브젝트 스토리지로 사용하는 경우, 「엔드포인트」는 storage.googleapis.com 으로 설정하고, 「리전」 란은 비웁니다."
cache-remote-files: "원격 파일을 캐시" cache-remote-files: "원격 파일을 캐시"
cache-remote-files-desc: "이 설정을 해지하면 원격 파일을 캐시하지 않고 해당 파일을 직접 링크하게 됩니다. 그에 따라 서버의 저장 공간을 절약할 수 있지만, 프라이버시 설정에서 직접 링크를 무효로 설정한 사용자에게는 파일이 보이지 않거나, 썸네일이 생성되지 않기 때문에 통신량이 증가합니다. 일반적으로 이 설정을 ON으로 두는 것을 추천합니다." cache-remote-files-desc: "이 설정을 해지하면 원격 파일을 캐시하지 않고 해당 파일을 직접 링크하게 됩니다. 그에 따라 서버의 저장 공간을 절약할 수 있지만, 프라이버시 설정에서 직접 링크를 무효로 설정한 사용자에게는 파일이 보이지 않거나, 썸네일이 생성되지 않기 때문에 통신량이 증가합니다. 일반적으로 이 설정을 ON으로 두는 것을 추천합니다."
local-drive-capacity-mb: "로컬 사용자 한 명당 드라이브 용량" local-drive-capacity-mb: "로컬 사용자 한 명당 드라이브 용량"
@ -1112,9 +1193,14 @@ admin/views/instance.vue:
mb: "메가바이트 단위" mb: "메가바이트 단위"
recaptcha-config: "reCAPCHA 설정" recaptcha-config: "reCAPCHA 설정"
recaptcha-info: "reCAPCHA를 사용하도록 설정하는 경우 reCAPCHA 토큰을 확보해야 합니다. https://www.google.com/recaptcha/intro/ 에 접속하여 토큰을 가져와주십시오." recaptcha-info: "reCAPCHA를 사용하도록 설정하는 경우 reCAPCHA 토큰을 확보해야 합니다. https://www.google.com/recaptcha/intro/ 에 접속하여 토큰을 가져와주십시오."
recaptcha-info2: "v3는지원하지 않습니다. v2를 사용하여 주십시오."
enable-recaptcha: "reCAPCHA 활성화" enable-recaptcha: "reCAPCHA 활성화"
recaptcha-site-key: "reCAPTCHA site key" recaptcha-site-key: "사이트 키"
recaptcha-secret-key: "reCAPTCHA secret key" recaptcha-secret-key: "시크릿 키"
recaptcha-preview: "미리보기"
hidden-tags: "숨긴 해시태그"
hidden-tags-info: "집계에서 제외할 해시태그를 줄 바꿈으로 구분하여 기술합니다."
external-service-integration-config: "외부 서비스 연계"
twitter-integration-config: "Twitter 연동 설정" twitter-integration-config: "Twitter 연동 설정"
twitter-integration-info: "콜백 URL은 {url} 로 설정됩니다." twitter-integration-info: "콜백 URL은 {url} 로 설정됩니다."
enable-twitter-integration: "트위터 연동 활성화" enable-twitter-integration: "트위터 연동 활성화"
@ -1146,6 +1232,7 @@ admin/views/instance.vue:
save: "저장" save: "저장"
saved: "저장하였습니다" saved: "저장하였습니다"
pinned-users: "고정된 사용자" pinned-users: "고정된 사용자"
pinned-users-info: "고정해두고 싶은 사용자를 줄바꿈으로 구분하여 기술합니다."
email-config: "메일 서버 설정" email-config: "메일 서버 설정"
email-config-info: "메일 주소 확인 혹은 비밀번호 재설정에 사용 됩니다." email-config-info: "메일 주소 확인 혹은 비밀번호 재설정에 사용 됩니다."
enable-email: "메일 발신 활성화" enable-email: "메일 발신 활성화"
@ -1211,6 +1298,9 @@ admin/views/drive.vue:
unmark-as-sensitive: "열람주의 해제" unmark-as-sensitive: "열람주의 해제"
marked-as-sensitive: "열람주의로 설정하였습니다" marked-as-sensitive: "열람주의로 설정하였습니다"
unmarked-as-sensitive: "열람주의를 제거하였습니다" unmarked-as-sensitive: "열람주의를 제거하였습니다"
clean-remote-files: "리모트 파일 캐시를 삭제"
clean-remote-files-are-you-sure: "정말 모든 리모트 파일의 캐시를 삭제하시겠습니까?"
clean-up: "청소"
admin/views/users.vue: admin/views/users.vue:
operation: "작업" operation: "작업"
username-or-userid: "사용자명 혹은 사용자 ID" username-or-userid: "사용자명 혹은 사용자 ID"
@ -1231,6 +1321,8 @@ admin/views/users.vue:
unsilence-confirm: "침묵 해제하시겠습니까?" unsilence-confirm: "침묵 해제하시겠습니까?"
update-remote-user: "원격 사용자 정보 갱신" update-remote-user: "원격 사용자 정보 갱신"
remote-user-updated: "원격 사용자 정보를 갱신하였습니다" remote-user-updated: "원격 사용자 정보를 갱신하였습니다"
delete-all-files: "모든 파일 삭제"
delete-all-files-confirm: "모든 파일을 삭제하시겠습니까?"
users: users:
title: "사용자" title: "사용자"
sort: sort:
@ -1306,6 +1398,7 @@ admin/views/federation.vue:
latest-request-received-at: "마지막으로 요청을 받은 시간" latest-request-received-at: "마지막으로 요청을 받은 시간"
remove-all-following: "모든 팔로잉 해제" remove-all-following: "모든 팔로잉 해제"
remove-all-following-info: "{host}(으)로부터 모든 팔로잉을 해제합니다. 해당 인스턴스가 더 이상 존재하지 않게 된 경우 등에 실행하십시오." remove-all-following-info: "{host}(으)로부터 모든 팔로잉을 해제합니다. 해당 인스턴스가 더 이상 존재하지 않게 된 경우 등에 실행하십시오."
delete-all-files: "파일을 모두 삭제"
block: "차단" block: "차단"
marked-as-closed: "폐쇄된 것으로 표시" marked-as-closed: "폐쇄된 것으로 표시"
lookup: "조회" lookup: "조회"
@ -1353,6 +1446,8 @@ admin/views/federation.vue:
hour: "1시간마다" hour: "1시간마다"
day: "1일마다" day: "1일마다"
blocked-hosts: "차단" blocked-hosts: "차단"
blocked-hosts-info: "차단할 호스트를 줄바꿈으로 구분하여 기술합니다."
save: "저장"
desktop/views/pages/welcome.vue: desktop/views/pages/welcome.vue:
about: "자세히..." about: "자세히..."
timeline: "타임라인" timeline: "타임라인"
@ -1484,17 +1579,6 @@ mobile/views/components/note-sub.vue:
cat: "cat" cat: "cat"
mobile/views/components/notifications.vue: mobile/views/components/notifications.vue:
empty: "없습니다!" empty: "없습니다!"
mobile/views/components/post-form.vue:
add-visible-user: "사용자 추가"
submit: "글쓰기"
reply: "답글 달기"
renote: "리노트"
quote-placeholder: "이 글을 인용... (선택적)"
reply-placeholder: "이 글에 답글..."
cw-placeholder: "내용 주석 (선택적)"
geolocation-alert: "사용하시는 장치가 위치정보 기능에 대응하지 않습니다"
error: "오류"
username-prompt: "사용자명을 입력하여 주십시오"
mobile/views/components/sub-note-content.vue: mobile/views/components/sub-note-content.vue:
private: "이 글은 비공개입니다" private: "이 글은 비공개입니다"
deleted: "이 글은 삭제되었습니다" deleted: "이 글은 삭제되었습니다"
@ -1509,6 +1593,7 @@ mobile/views/components/ui.nav.vue:
follow-requests: "팔로우 요청" follow-requests: "팔로우 요청"
search: "검색" search: "검색"
user-lists: "리스트" user-lists: "리스트"
user-groups: "그룹"
widgets: "위젯" widgets: "위젯"
game: "게임" game: "게임"
admin: "관리" admin: "관리"
@ -1521,8 +1606,6 @@ mobile/views/pages/drive.vue:
rename-folder: "폴더 이름 바꾸기" rename-folder: "폴더 이름 바꾸기"
move-folder: "이 폴더를 이동" move-folder: "이 폴더를 이동"
delete-folder: "이 폴더를 삭제" delete-folder: "이 폴더를 삭제"
mobile/views/pages/user-lists.vue:
title: "리스트"
mobile/views/pages/signup.vue: mobile/views/pages/signup.vue:
lets-start: "📦 이제 시작해도 됩니다" lets-start: "📦 이제 시작해도 됩니다"
mobile/views/pages/followers.vue: mobile/views/pages/followers.vue:
@ -1547,10 +1630,6 @@ mobile/views/pages/widgets/activity.vue:
activity: "활동" activity: "활동"
mobile/views/pages/share.vue: mobile/views/pages/share.vue:
share-with: "{name}(으)로 공유" share-with: "{name}(으)로 공유"
mobile/views/pages/received-follow-requests.vue:
title: "팔로우 요청"
accept: "승인"
reject: "거부"
mobile/views/pages/note.vue: mobile/views/pages/note.vue:
title: "글" title: "글"
prev: "이전 글" prev: "이전 글"
@ -1656,9 +1735,17 @@ pages:
edit-this-page: "이 페이지를 편집" edit-this-page: "이 페이지를 편집"
view-source: "소스 보기" view-source: "소스 보기"
view-page: "페이지 보기" view-page: "페이지 보기"
like: "좋아요"
unlike: "좋아요 해제"
liked-pages: "좋아요한 페이지"
my-pages: "내 페이지"
inspector: "인스펙터" inspector: "인스펙터"
content: "페이지 블록" content: "페이지 블록"
variables: "변수" variables: "변수"
variables-info: "변수를 사용하면 동적인 페이지를 만들 수 있습니다. 텍스트에 <b>{ 변수명 }</b>을 적으면 그 위치에 변수의 값을 집어넣습니다. 예를 들자면 <b>Hello { thing } world!</b> 라는 텍스트가 있을 때, 변수(thing)의 값이 <b>ai</b>인 경우 텍스트는 <b>Hello ai world!</b>가 됩니다."
variables-info2: "변수의 평가(값을 산출해내는 것)는 위에서부터 아래로 진행되므로 어떤 변수의 내부에서 자신보다 아래에 있는 변수를 참조할 수는 없습니다. 예를 들자면 위에서부터 <b>A, B, C</b>의 3개의 변수가 정의되어 있을 때, <b>C</b>의 내부에 <b>A</b>나 <b>B</b>를 참조할 수는 있지만, <b>A</b>의 내부에서 <b>B</b>나 <b>C</b>를 참조할 수는 없습니다."
variables-info3: "사용자로부터 입력을 받으려면, 페이지에 「사용자 입력」 블록을 삽입하고 「변수명」에 입력받은 값을 저장하고 싶은 변수명을 설정합니다 (변수는 자동으로 생성됩니다). 그 변수를 사용하여 사용자 입력에 따라 동작할 수 있습니다."
variables-info4: "함수를 사용하면 반복되는 작업을 손쉽게 처리할 수 있습니다. 함수를 만드시려면 「함수」 타입의 변수를 만듭니다. 함수에서 슬롯(인수)를 받도록 설정하면, 함수를 사용할 때 슬롯에 입력된 값을 함수 안에서 변수로써 이용할 수 있게 됩니다. 또한, AiScript 표준에는 함수를 인수로 받는 함수(고차함수)도 존재합니다. 함수를 미리 정의하는 것 외에, 이와 같은 고차함수를 즉석으로 설정할 수 있습니다."
more-details: "자세한 설명" more-details: "자세한 설명"
title: "제목" title: "제목"
url: "페이지 URL" url: "페이지 URL"
@ -1739,6 +1826,8 @@ pages:
text: "텍스트" text: "텍스트"
multiLineText: "텍스트 (여러줄)" multiLineText: "텍스트 (여러줄)"
textList: "텍스트 목록" textList: "텍스트 목록"
_textList:
info: "각각을 줄 바꿈으로 구분해주십시오"
strLen: "텍스트의 길이" strLen: "텍스트의 길이"
_strLen: _strLen:
arg1: "텍스트" arg1: "텍스트"
@ -1774,8 +1863,8 @@ pages:
_divide: _divide:
arg1: "A" arg1: "A"
arg2: "B" arg2: "B"
remind: "÷ 나눈 나머지" mod: "÷ 나눈 나머지"
_remind: _mod:
arg1: "A" arg1: "A"
arg2: "B" arg2: "B"
eq: "A와 B가 동일" eq: "A와 B가 동일"
@ -1828,40 +1917,59 @@ pages:
randomPick: "목록에서 임의로 선택" randomPick: "목록에서 임의로 선택"
_randomPick: _randomPick:
arg1: "리스트" arg1: "리스트"
dailyRandom: "랜덤 (하루동안 결과 유지)"
_dailyRandom: _dailyRandom:
arg1: "확률" arg1: "확률"
dailyRannum: "난수 (하루동안 결과 유지)"
_dailyRannum: _dailyRannum:
arg1: "최소" arg1: "최소"
arg2: "최대" arg2: "최대"
dailyRandomPick: "목록에서 임의로 선택 (하루동안 결과 유지)"
_dailyRandomPick: _dailyRandomPick:
arg1: "리스트" arg1: "리스트"
seedRandom: "무작위 (시드)"
_seedRandom: _seedRandom:
arg1: "시드" arg1: "시드"
arg2: "확률" arg2: "확률"
seedRannum: "난수 (시드)"
_seedRannum: _seedRannum:
arg1: "시드" arg1: "시드"
arg2: "최소" arg2: "최소"
arg3: "최대" arg3: "최대"
seedRandomPick: "목록에서 무작위로 선택 (시드)"
_seedRandomPick: _seedRandomPick:
arg1: "시드" arg1: "시드"
arg2: "리스트" arg2: "리스트"
DRPWPM: "확률형 목록에서 임의로 선택 (하루동안 결과 유지)"
_DRPWPM: _DRPWPM:
arg1: "텍스트 목록" arg1: "텍스트 목록"
pick: "목록에서 선택"
_pick: _pick:
arg1: "리스트" arg1: "리스트"
arg2: "위치"
_listLen:
arg1: "리스트"
number: "수치" number: "수치"
stringToNumber: "텍스트를 수치로" stringToNumber: "텍스트를 수치로"
_stringToNumber: _stringToNumber:
arg1: "텍스트" arg1: "텍스트"
numberToString: "수치를 텍스트로"
_numberToString: _numberToString:
arg1: "수치" arg1: "수치"
splitStrByLine: "텍스트를 행 단위로 분할"
_splitStrByLine: _splitStrByLine:
arg1: "텍스트" arg1: "텍스트"
ref: "변수" ref: "변수"
fn: "함수" fn: "함수"
_fn: _fn:
slots: "슬롯" slots: "슬롯"
slots-info: "각 슬롯을 줄 바꿈으로 구분하여 주십시오"
arg1: "출력" arg1: "출력"
for: "반복"
_for:
arg1: "횟수"
arg2: "처리"
typeError: "슬롯 {slot}은 \"{expect}\"를 사용할 수 있지만 \"{actual}이 들어있습니다!"
thereIsEmptySlot: "슬롯 {slot}이(가) 비었습니다!" thereIsEmptySlot: "슬롯 {slot}이(가) 비었습니다!"
types: types:
string: "텍스트" string: "텍스트"

View File

@ -25,6 +25,10 @@ common:
favorites: "Deze notitie toevoegen aan favorieten" favorites: "Deze notitie toevoegen aan favorieten"
permissions: permissions:
"write:votes": "Stemmen" "write:votes": "Stemmen"
post-form:
submit: "Bericht"
reply: "Beantwoorden"
add-visible-user: "Gebruiker toevoegen"
weekday-short: weekday-short:
sunday: "Z" sunday: "Z"
monday: "M" monday: "M"
@ -104,10 +108,9 @@ common/views/components/messaging.vue:
search-user: "Gebruiker zoeken" search-user: "Gebruiker zoeken"
you: "Jij" you: "Jij"
no-history: "Geen geschiedenis" no-history: "Geen geschiedenis"
user: "Gebruiker"
common/views/components/messaging-room.vue: common/views/components/messaging-room.vue:
empty: "Geen gesprekken"
no-history: "Er is geen verdere geschiedenis" no-history: "Er is geen verdere geschiedenis"
resize-form: "Versleep om grootte te wijzigen"
new-message: "Nieuw bericht" new-message: "Nieuw bericht"
common/views/components/messaging-room.form.vue: common/views/components/messaging-room.form.vue:
input-message-here: "Voer hier je bericht in" input-message-here: "Voer hier je bericht in"
@ -202,6 +205,9 @@ common/views/components/profile-editor.vue:
enter-password: "Voer het wachtwoord in" enter-password: "Voer het wachtwoord in"
common/views/components/user-list-editor.vue: common/views/components/user-list-editor.vue:
users: "Gebruiker" users: "Gebruiker"
add-user: "Gebruiker toevoegen"
common/views/components/user-lists.vue:
user-lists: "Lijsten"
common/views/widgets/broadcast.vue: common/views/widgets/broadcast.vue:
fetching: "Bezig met ophalen" fetching: "Bezig met ophalen"
no-broadcasts: "Geen uitzendingen" no-broadcasts: "Geen uitzendingen"
@ -323,21 +329,12 @@ desktop/views/components/notes.vue:
desktop/views/components/notifications.vue: desktop/views/components/notifications.vue:
empty: "Geen meldingen" empty: "Geen meldingen"
desktop/views/components/post-form.vue: desktop/views/components/post-form.vue:
reply-placeholder: "Deze notitie beantwoorden..."
quote-placeholder: "Deze notitie citeren..."
submit: "Bericht"
reply: "Beantwoorden"
posted: "Geplaatst!" posted: "Geplaatst!"
replied: "Beantwoord!" replied: "Beantwoord!"
reposted: "Hergeplaatst!" reposted: "Hergeplaatst!"
note-failed: "Noteren mislukt" note-failed: "Noteren mislukt"
reply-failed: "Beantwoorden mislukt" reply-failed: "Beantwoorden mislukt"
renote-failed: "Renote mislukt" renote-failed: "Renote mislukt"
posting: "Bezig met plaatsen"
attach-media-from-local: "Media bijvoegen van je computer"
attach-media-from-drive: "Media bijvoegen uit je Drive"
create-poll: "Peiling creëren"
text-remain: "{} resterende tekens"
desktop/views/components/post-form-window.vue: desktop/views/components/post-form-window.vue:
note: "Nieuwe notitie" note: "Nieuwe notitie"
reply: "Beantwoorden" reply: "Beantwoorden"
@ -401,8 +398,6 @@ desktop/views/components/ui.header.post.vue:
post: "Nieuw bericht opstellen" post: "Nieuw bericht opstellen"
desktop/views/components/ui.header.search.vue: desktop/views/components/ui.header.search.vue:
placeholder: "Zoeken" placeholder: "Zoeken"
desktop/views/components/user-lists-window.vue:
title: "Lijsten"
desktop/views/components/user-preview.vue: desktop/views/components/user-preview.vue:
notes: "Berichten" notes: "Berichten"
following: "Volgend" following: "Volgend"
@ -538,11 +533,6 @@ mobile/views/components/note-detail.vue:
location: "Locatie" location: "Locatie"
mobile/views/components/notifications.vue: mobile/views/components/notifications.vue:
empty: "Geen meldingen" empty: "Geen meldingen"
mobile/views/components/post-form.vue:
add-visible-user: "Gebruiker toevoegen"
submit: "Plaatsen"
reply: "Antwoord"
reply-placeholder: "Deze notitie beantwoorden..."
mobile/views/components/sub-note-content.vue: mobile/views/components/sub-note-content.vue:
private: "(dit bericht is privé)" private: "(dit bericht is privé)"
media-count: "{} media" media-count: "{} media"
@ -558,8 +548,6 @@ mobile/views/pages/drive.vue:
contextmenu: contextmenu:
upload: "Bestand uploaden" upload: "Bestand uploaden"
create-folder: "Map creëren" create-folder: "Map creëren"
mobile/views/pages/user-lists.vue:
title: "Lijsten"
mobile/views/pages/home.vue: mobile/views/pages/home.vue:
home: "Startpagina" home: "Startpagina"
local: "Lokaal" local: "Lokaal"
@ -618,6 +606,7 @@ docs:
edit-this-page-on-github: "Heb je een fout ontdekt of wil je bijdragen aan de documentatie? " edit-this-page-on-github: "Heb je een fout ontdekt of wil je bijdragen aan de documentatie? "
edit-this-page-on-github-link: "Bewerk deze pagina op GitHub!" edit-this-page-on-github-link: "Bewerk deze pagina op GitHub!"
pages: pages:
like: "Leuk"
blocks: blocks:
image: "Afbeeldingen" image: "Afbeeldingen"
script: script:
@ -634,5 +623,7 @@ pages:
arg2: "Lijsten" arg2: "Lijsten"
_pick: _pick:
arg1: "Lijsten" arg1: "Lijsten"
_listLen:
arg1: "Lijsten"
types: types:
array: "Lijsten" array: "Lijsten"

View File

@ -39,6 +39,10 @@ common:
favorites: "Merket som favoritt" favorites: "Merket som favoritt"
permissions: permissions:
"write:votes": "Stem" "write:votes": "Stem"
post-form:
submit: "Innlegg"
reply: "Svar"
error: "Feil"
weekday-short: weekday-short:
sunday: "S" sunday: "S"
monday: "M" monday: "M"
@ -130,6 +134,7 @@ common/views/components/cw-button.vue:
hide: "Skjul" hide: "Skjul"
common/views/components/messaging.vue: common/views/components/messaging.vue:
you: "Du" you: "Du"
user: "Bruker"
common/views/components/messaging-room.form.vue: common/views/components/messaging-room.form.vue:
send: "Send" send: "Send"
common/views/components/messaging-room.message.vue: common/views/components/messaging-room.message.vue:
@ -192,8 +197,13 @@ common/views/components/profile-editor.vue:
user-lists: "Lister" user-lists: "Lister"
common/views/components/user-list-editor.vue: common/views/components/user-list-editor.vue:
users: "Bruker" users: "Bruker"
common/views/components/user-group-editor.vue:
invite: "Inviter"
common/views/components/user-lists.vue: common/views/components/user-lists.vue:
user-lists: "Lister"
list-name: "Liste navn" list-name: "Liste navn"
common/views/components/user-groups.vue:
invites: "Inviter"
common/views/widgets/broadcast.vue: common/views/widgets/broadcast.vue:
fetching: "Henter" fetching: "Henter"
next: "Neste" next: "Neste"
@ -255,13 +265,6 @@ desktop/views/components/note.vue:
detail: "Detaljer" detail: "Detaljer"
desktop/views/components/notes.vue: desktop/views/components/notes.vue:
retry: "Prøv på nytt" retry: "Prøv på nytt"
desktop/views/components/post-form.vue:
submit: "Send"
reply: "Svar"
posting: "Publiserer"
recent-tags: "Nylig"
visibility: "Synlighet"
error: "Feil"
desktop/views/components/post-form-window.vue: desktop/views/components/post-form-window.vue:
note: "Nytt innlegg" note: "Nytt innlegg"
reply: "Svar" reply: "Svar"
@ -307,11 +310,6 @@ desktop/views/components/ui.header.post.vue:
post: "Skriv nytt innlegg" post: "Skriv nytt innlegg"
desktop/views/components/ui.header.search.vue: desktop/views/components/ui.header.search.vue:
placeholder: "Søk" placeholder: "Søk"
desktop/views/components/received-follow-requests-window.vue:
accept: "Godta"
reject: "Avslå"
desktop/views/components/user-lists-window.vue:
title: "Brukerlister"
desktop/views/components/user-preview.vue: desktop/views/components/user-preview.vue:
notes: "Innlegg" notes: "Innlegg"
following: "Følger" following: "Følger"
@ -327,6 +325,10 @@ admin/views/index.vue:
admin/views/dashboard.vue: admin/views/dashboard.vue:
notes: "Innlegg" notes: "Innlegg"
drive: "Disk" drive: "Disk"
admin/views/logs.vue:
levels:
info: "Informasjon"
error: "Feil"
admin/views/abuse.vue: admin/views/abuse.vue:
details: "Detaljer" details: "Detaljer"
remove-report: "Slett" remove-report: "Slett"
@ -365,6 +367,7 @@ admin/views/federation.vue:
status: "Status" status: "Status"
states: states:
all: "Alle" all: "Alle"
save: "Lagre"
desktop/views/pages/welcome.vue: desktop/views/pages/welcome.vue:
announcements: "Kunngjøringer" announcements: "Kunngjøringer"
info: "Informasjon" info: "Informasjon"
@ -436,10 +439,6 @@ mobile/views/components/note-sub.vue:
admin: "admin" admin: "admin"
bot: "bot" bot: "bot"
cat: "katt" cat: "katt"
mobile/views/components/post-form.vue:
submit: "Send"
reply: "Svar"
error: "Feil"
mobile/views/components/ui.header.vue: mobile/views/components/ui.header.vue:
adjective: "Mr." adjective: "Mr."
mobile/views/components/ui.nav.vue: mobile/views/components/ui.nav.vue:
@ -448,17 +447,12 @@ mobile/views/components/ui.nav.vue:
user-lists: "Lister" user-lists: "Lister"
game: "Spill" game: "Spill"
admin: "Admin" admin: "Admin"
mobile/views/pages/user-lists.vue:
title: "Lister"
mobile/views/pages/home.vue: mobile/views/pages/home.vue:
home: "Hjem" home: "Hjem"
local: "Lokalt" local: "Lokalt"
global: "Globalt" global: "Globalt"
mobile/views/pages/widgets.vue: mobile/views/pages/widgets.vue:
add-widget: "Legg til" add-widget: "Legg til"
mobile/views/pages/received-follow-requests.vue:
accept: "Godta"
reject: "Avslå"
mobile/views/pages/note.vue: mobile/views/pages/note.vue:
title: "Innlegg" title: "Innlegg"
prev: "Forrige innlegg" prev: "Forrige innlegg"
@ -490,6 +484,7 @@ deck/deck.user-column.vue:
followers: "Følgere" followers: "Følgere"
images: "Bilder" images: "Bilder"
pages: pages:
like: "Lik"
blocks: blocks:
image: "Bilder" image: "Bilder"
script: script:
@ -508,5 +503,7 @@ pages:
arg2: "Lister" arg2: "Lister"
_pick: _pick:
arg1: "Lister" arg1: "Lister"
_listLen:
arg1: "Lister"
types: types:
array: "Lister" array: "Lister"

View File

@ -68,6 +68,24 @@ common:
"write:votes": "Zagłosuj" "write:votes": "Zagłosuj"
empty-timeline-info: empty-timeline-info:
explore: "Poznaj" explore: "Poznaj"
post-form:
hide-contents: "Ukryj zawartość"
reply-placeholder: "Odpowiedź na ten wpis…"
quote-placeholder: "Zacytuj ten wpis…"
submit: "Wpis"
reply: "Odpowiedz"
renote: "Udostępnij"
posting: "Wysyłanie"
attach-media-from-local: "Załącz zawartość multimedialną z komputera"
attach-media-from-drive: "Załącz zawartość multimedialną z dysku"
create-poll: "Utwórz ankietę"
text-remain: "pozostałe znaki: {}"
recent-tags: "Ostatnie"
visibility: "Widoczność"
error: "Błąd"
enter-username: "Wprowadź nazwę użytkownika"
add-visible-user: "Dodaj użytkownika"
username-prompt: "Wprowadź nazwę użytkownika"
weekday-short: weekday-short:
sunday: "N" sunday: "N"
monday: "Pn" monday: "Pn"
@ -168,6 +186,7 @@ common:
my-token-regenerated: "Twój token został wygenerowany. Zostaniesz wylogowany." my-token-regenerated: "Twój token został wygenerowany. Zostaniesz wylogowany."
hide-password: "Ukryj hasło" hide-password: "Ukryj hasło"
show-password: "Pokaż hasło" show-password: "Pokaż hasło"
enter-username: "Wprowadź nazwę użytkownika"
view-on-remote: "Dla dopełnienia, zobacz to zdalnie." view-on-remote: "Dla dopełnienia, zobacz to zdalnie."
renoted-by: "{user} udostępnił(a)" renoted-by: "{user} udostępnił(a)"
error: error:
@ -217,6 +236,9 @@ auth/views/index.vue:
please-go-back: "Wróć do aplikacji." please-go-back: "Wróć do aplikacji."
error: "Sesja nie istnieje." error: "Sesja nie istnieje."
sign-in: "Proszę zalogować się." sign-in: "Proszę zalogować się."
common/views/pages/explore.vue:
popular-users: "Popularni użytkownicy"
popular-tags: "Popularne tagi"
common/views/components/games/reversi/reversi.vue: common/views/components/games/reversi/reversi.vue:
matching: matching:
waiting-for: "Oczekiwanie na {}" waiting-for: "Oczekiwanie na {}"
@ -323,18 +345,15 @@ common/views/components/messaging.vue:
search-user: "Znajdź użytkownika" search-user: "Znajdź użytkownika"
you: "Ty" you: "Ty"
no-history: "Brak historii" no-history: "Brak historii"
user: "Użytkownicy"
common/views/components/messaging-room.vue: common/views/components/messaging-room.vue:
empty: "Brak konwersacji"
no-history: "Brak dalszej historii" no-history: "Brak dalszej historii"
resize-form: "Przeciągnij aby zmienić rozmiar"
new-message: "Nowa wiadomość" new-message: "Nowa wiadomość"
only-one-file-attached: "Tylko JEDEN plik może zostać dołączony do wiadomości"
common/views/components/messaging-room.form.vue: common/views/components/messaging-room.form.vue:
input-message-here: "Wprowadź wiadomość tutaj" input-message-here: "Wprowadź wiadomość tutaj"
send: "Wyślij" send: "Wyślij"
attach-from-local: "Załącz pliki z komputera" attach-from-local: "Załącz pliki z komputera"
attach-from-drive: "Załącz pliki z dysku" attach-from-drive: "Załącz pliki z dysku"
only-one-file-attached: "Tylko jeden plik może zostać dołączony do wiadomości"
common/views/components/messaging-room.message.vue: common/views/components/messaging-room.message.vue:
is-read: "Przeczytano" is-read: "Przeczytano"
deleted: "Wiadomość została usunięta" deleted: "Wiadomość została usunięta"
@ -511,8 +530,15 @@ common/views/components/user-list-editor.vue:
remove-user: "Usuń z tej listy" remove-user: "Usuń z tej listy"
delete-are-you-sure: "Usunąć listę \"$1\"?" delete-are-you-sure: "Usunąć listę \"$1\"?"
deleted: "Usunięto" deleted: "Usunięto"
add-user: "Dodaj użytkownika"
common/views/components/user-group-editor.vue:
deleted: "Usunięto"
invite: "Zaproś"
common/views/components/user-lists.vue: common/views/components/user-lists.vue:
user-lists: "Listy"
list-name: "Nazwa listy" list-name: "Nazwa listy"
common/views/components/user-groups.vue:
invites: "Zaproś"
common/views/widgets/broadcast.vue: common/views/widgets/broadcast.vue:
fetching: "Sprawdzanie" fetching: "Sprawdzanie"
no-broadcasts: "Brak transmisji" no-broadcasts: "Brak transmisji"
@ -568,6 +594,8 @@ common/views/pages/follow.vue:
request-pending: "Oczekiwanie na pozwolenie" request-pending: "Oczekiwanie na pozwolenie"
follow-processing: "Przetwarzanie śledzenia" follow-processing: "Przetwarzanie śledzenia"
follow-request: "Poproś o śledzenie" follow-request: "Poproś o śledzenie"
common/views/pages/follow-requests.vue:
received-follow-requests: "Prośby o śledzenie"
desktop: desktop:
banner: "Baner" banner: "Baner"
uploading-banner: "Wysyłanie baneru" uploading-banner: "Wysyłanie baneru"
@ -694,33 +722,12 @@ desktop/views/components/notes.vue:
desktop/views/components/notifications.vue: desktop/views/components/notifications.vue:
empty: "Brak powiadomień" empty: "Brak powiadomień"
desktop/views/components/post-form.vue: desktop/views/components/post-form.vue:
add-visible-user: "+Dodaj użytkownika"
attach-location-information: "Załącz informacje o lokalizacji"
hide-contents: "Ukryj zawartość"
reply-placeholder: "Odpowiedz na ten wpis…"
quote-placeholder: "Zacytuj ten wpis…"
submit: "Wyślij"
reply: "Odpowiedz"
renote: "Udostępnienie"
posted: "Opublikowano!" posted: "Opublikowano!"
replied: "Odpowiedziano!" replied: "Odpowiedziano!"
reposted: "Udostępniono!" reposted: "Udostępniono!"
note-failed: "Nie udało się wysłać" note-failed: "Nie udało się wysłać"
reply-failed: "Nie udało się odpowiedzieć" reply-failed: "Nie udało się odpowiedzieć"
renote-failed: "Nie udało się udostępnić" renote-failed: "Nie udało się udostępnić"
posting: "Wysyłanie"
attach-media-from-local: "Załącz zawartość multimedialną z komputera"
attach-media-from-drive: "Załącz zawartość multimedialną z dysku"
insert-a-kao: "v('ω')v"
create-poll: "Utwórz ankietę"
text-remain: "pozostałe znaki: {}"
recent-tags: "Ostatnie"
click-to-tagging: "Naciśnij aby oznaczyć"
visibility: "Widoczność"
geolocation-alert: "Twoje urządzenie nie obsługuje geolokalizacji."
error: "Bład"
enter-username: "Wprowadź nazwę użytkownika…"
annotations: "Treść ostrzeżenia (opcjonalnie)"
desktop/views/components/post-form-window.vue: desktop/views/components/post-form-window.vue:
note: "Nowy wpis" note: "Nowy wpis"
reply: "Odpowiedz" reply: "Odpowiedz"
@ -829,12 +836,6 @@ desktop/views/components/ui.header.post.vue:
post: "Utwórz nowy wpis" post: "Utwórz nowy wpis"
desktop/views/components/ui.header.search.vue: desktop/views/components/ui.header.search.vue:
placeholder: "Szukaj" placeholder: "Szukaj"
desktop/views/components/received-follow-requests-window.vue:
title: "Prośby o śledzenie"
accept: "Zatwierdź"
reject: "Odmów"
desktop/views/components/user-lists-window.vue:
title: "Listy"
desktop/views/components/user-preview.vue: desktop/views/components/user-preview.vue:
notes: "Wpisy" notes: "Wpisy"
following: "Śledzeni" following: "Śledzeni"
@ -855,18 +856,22 @@ admin/views/index.vue:
moderators: "Moderatorzy" moderators: "Moderatorzy"
users: "Użytkownicy" users: "Użytkownicy"
announcements: "Ogłoszenia" announcements: "Ogłoszenia"
hashtags: "Hashtagi"
admin/views/dashboard.vue: admin/views/dashboard.vue:
dashboard: "Kokpit" dashboard: "Kokpit"
accounts: "Konta" accounts: "Konta"
notes: "Wpisy" notes: "Wpisy"
drive: "Dysk" drive: "Dysk"
instances: "Instancja" instances: "Instancja"
admin/views/logs.vue:
levels:
info: "Informacje"
error: "Błąd"
admin/views/abuse.vue: admin/views/abuse.vue:
details: "Szczegóły" details: "Szczegóły"
remove-report: "Usuń" remove-report: "Usuń"
admin/views/instance.vue: admin/views/instance.vue:
instance: "Instancja" instance: "Instancja"
recaptcha-preview: "Pokaż podgląd"
github-integration-client-id: "Client ID" github-integration-client-id: "Client ID"
github-integration-client-secret: "Client Secret" github-integration-client-secret: "Client Secret"
discord-integration-client-id: "Client ID" discord-integration-client-id: "Client ID"
@ -949,6 +954,7 @@ admin/views/federation.vue:
chart-srcs: chart-srcs:
requests: "Żądania" requests: "Żądania"
blocked-hosts: "Zablokuj" blocked-hosts: "Zablokuj"
save: "Zapisz"
desktop/views/pages/welcome.vue: desktop/views/pages/welcome.vue:
about: "O Misskey" about: "O Misskey"
timeline: "Oś czasu" timeline: "Oś czasu"
@ -1071,17 +1077,6 @@ mobile/views/components/note-sub.vue:
cat: "kot" cat: "kot"
mobile/views/components/notifications.vue: mobile/views/components/notifications.vue:
empty: "Brak powiadomień" empty: "Brak powiadomień"
mobile/views/components/post-form.vue:
add-visible-user: "Dodaj użytkownika"
submit: "Wyślij"
reply: "Odpowiedz"
renote: "Udostępnij"
quote-placeholder: "Zacytuj ten wpis… (nieobowiązkowe)"
reply-placeholder: "Odpowiedź na ten wpis…"
cw-placeholder: "Treść ostrzeżenia (opcjonalnie)"
geolocation-alert: "Twoje urządzenie nie obsługuje geolokalizacji."
error: "Błąd"
username-prompt: "Wprowadź nazwę użytkownika"
mobile/views/components/sub-note-content.vue: mobile/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"
@ -1103,8 +1098,6 @@ mobile/views/pages/drive.vue:
contextmenu: contextmenu:
upload: "Wyślij plik" upload: "Wyślij plik"
create-folder: "Utwórz katalog" create-folder: "Utwórz katalog"
mobile/views/pages/user-lists.vue:
title: "Listy"
mobile/views/pages/signup.vue: mobile/views/pages/signup.vue:
lets-start: "Rozpocznijmy! 📦" lets-start: "Rozpocznijmy! 📦"
mobile/views/pages/home.vue: mobile/views/pages/home.vue:
@ -1119,10 +1112,6 @@ mobile/views/pages/widgets.vue:
customization-tips: "Wskazówki o dostosowywaniu" customization-tips: "Wskazówki o dostosowywaniu"
mobile/views/pages/widgets/activity.vue: mobile/views/pages/widgets/activity.vue:
activity: "Aktywność" activity: "Aktywność"
mobile/views/pages/received-follow-requests.vue:
title: "Prośby o śledzenie"
accept: "Zatwierdź"
reject: "Odmów"
mobile/views/pages/note.vue: mobile/views/pages/note.vue:
title: "Wpis" title: "Wpis"
prev: "Poprzedni wpis" prev: "Poprzedni wpis"
@ -1197,6 +1186,7 @@ dev/views/new-app.vue:
app-name: "Nazwa Aplikacji" app-name: "Nazwa Aplikacji"
authority: "Uprawnienia" authority: "Uprawnienia"
pages: pages:
like: "Lubię"
title: "Tytuł" title: "Tytuł"
blocks: blocks:
image: "Zdjęcia" image: "Zdjęcia"
@ -1229,5 +1219,7 @@ pages:
arg2: "Listy" arg2: "Listy"
_pick: _pick:
arg1: "Listy" arg1: "Listy"
_listLen:
arg1: "Listy"
types: types:
array: "Listy" array: "Listy"

View File

@ -45,6 +45,9 @@ common:
trash: "Lixo" trash: "Lixo"
timeline: "Linha do tempo" timeline: "Linha do tempo"
followers: "Seguidores" followers: "Seguidores"
post-form:
enter-username: "Digite o nome de usuário."
username-prompt: "Digite o nome de usuário."
weekday-short: weekday-short:
sunday: "Dom" sunday: "Dom"
monday: "Seg" monday: "Seg"
@ -89,6 +92,7 @@ common:
update-available-title: "Atualização disponível" update-available-title: "Atualização disponível"
update-available: "Uma nova versão de Misskey está disponível ({newer}). A versão atual é {current}. Recarregue a página para atualizar." update-available: "Uma nova versão de Misskey está disponível ({newer}). A versão atual é {current}. Recarregue a página para atualizar."
my-token-regenerated: "Seu token foi recriado, portanto você foi deslogado." my-token-regenerated: "Seu token foi recriado, portanto você foi deslogado."
enter-username: "Digite o nome de usuário."
reversi: reversi:
drawn: "Empatado" drawn: "Empatado"
my-turn: "Seu turno" my-turn: "Seu turno"
@ -160,6 +164,10 @@ common/views/components/profile-editor.vue:
name: "Nome" name: "Nome"
export-targets: export-targets:
following-list: "Seguindo" following-list: "Seguindo"
common/views/components/user-group-editor.vue:
invite: "Convidar"
common/views/components/user-groups.vue:
invites: "Convidar"
common/views/widgets/posts-monitor.vue: common/views/widgets/posts-monitor.vue:
title: "Gráfico de publicações" title: "Gráfico de publicações"
common/views/widgets/memo.vue: common/views/widgets/memo.vue:
@ -270,6 +278,7 @@ docs:
dev/views/index.vue: dev/views/index.vue:
manage-apps: "Gerenciar aplicativos" manage-apps: "Gerenciar aplicativos"
pages: pages:
like: "Curtir"
blocks: blocks:
image: "Imagens" image: "Imagens"
post: "Formulário de publicação" post: "Formulário de publicação"

View File

@ -26,6 +26,13 @@ common:
do-not-copy-paste: "Пожалуйста, не вводите и не вставляйте сюда код. Аккаунту может угрожать опасность." do-not-copy-paste: "Пожалуйста, не вводите и не вставляйте сюда код. Аккаунту может угрожать опасность."
load-more: "Загрузить больше" load-more: "Загрузить больше"
enter-password: "Пожалуйста, введите ваш пароль" enter-password: "Пожалуйста, введите ваш пароль"
2fa: "Двухфакторная аутентификация"
customize-home: "Настройка домашней страницы"
dark-mode: "Тёмная тема"
signin: "Войти"
signup: "Регистрация"
signout: "Выйти"
reload-to-apply-the-setting: "Вам необходимо перезагрузить страницу, чтобы применить настройки. Вы хотите перезагрузить сейчас?"
customization-tips: customization-tips:
title: "Советы по настройке" title: "Советы по настройке"
gotit: "Понятно!" gotit: "Понятно!"
@ -51,7 +58,14 @@ common:
month-and-day: "{day}.{month}" month-and-day: "{day}.{month}"
trash: "Мусорное ведро" trash: "Мусорное ведро"
drive: "Drive" drive: "Drive"
pages: "Страницы"
messaging: "Чат" messaging: "Чат"
timeline: "Лента"
followers: "Подписчики"
favorites: "Избранное"
post-form:
reply: "Ответить"
create-poll: "Создать опрос"
weekday-short: weekday-short:
sunday: "Вс" sunday: "Вс"
monday: "Пн" monday: "Пн"
@ -147,6 +161,7 @@ mobile/views/components/sub-note-content.vue:
mobile/views/pages/widgets.vue: mobile/views/pages/widgets.vue:
customization-tips: "Советы по настройке" customization-tips: "Советы по настройке"
pages: pages:
like: "Нравится"
script: script:
categories: categories:
random: "Случайно" random: "Случайно"

View File

@ -95,6 +95,33 @@ common:
empty-timeline-info: empty-timeline-info:
follow-users-to-make-your-timeline: "关注其他用户时,帖子将显示在时间线中。" follow-users-to-make-your-timeline: "关注其他用户时,帖子将显示在时间线中。"
explore: "查找用户" explore: "查找用户"
post-form:
attach-location-information: "添加位置信息"
hide-contents: "隐藏内容"
reply-placeholder: "回复此贴..."
quote-placeholder: "引用此帖…"
option-quote-placeholder: "引用此帖…(可选)"
quote-attached: "已引用"
quote-question: "是否将其作为引用附上?"
submit: "帖子"
reply: "回复"
renote: "转推"
posting: "发送中"
attach-media-from-local: "从PC中添加媒体文件"
attach-media-from-drive: "从网盘中添加媒体文件"
insert-a-kao: "v('ω')v"
create-poll: "创建一个投票"
text-remain: "还剩{}个字符"
recent-tags: "最近"
local-only-message: "这篇文章只会在本地发布"
click-to-tagging: "点击添加标签"
visibility: "可见性"
geolocation-alert: "您的设备不支持定位服务"
error: "错误"
enter-username: "输入用户名"
add-visible-user: "添加用户"
cw-placeholder: "评论帖子(可选)"
username-prompt: "输入用户名"
weekday-short: weekday-short:
sunday: "日" sunday: "日"
monday: "一" monday: "一"
@ -145,7 +172,7 @@ common:
profile: "个人资料" profile: "个人资料"
notification: "通知" notification: "通知"
apps: "应用程序" apps: "应用程序"
tags: "标签" tags: "哈希标签"
mute-and-block: "屏蔽/拉黑" mute-and-block: "屏蔽/拉黑"
blocking: "拉黑" blocking: "拉黑"
security: "安全性" security: "安全性"
@ -168,7 +195,7 @@ common:
use-avatar-reversi-stones: "用头像作为黑白棋的棋子" use-avatar-reversi-stones: "用头像作为黑白棋的棋子"
disable-animated-mfm: "在帖子中禁用动画文本" disable-animated-mfm: "在帖子中禁用动画文本"
disable-showing-animated-images: "不播放动画" disable-showing-animated-images: "不播放动画"
suggest-recent-hashtags: "在帖子表单上显示最近流行的主题标签" suggest-recent-hashtags: "在帖子表单上显示最近流行的哈希标签"
always-show-nsfw: "总是显示 NSFW 的内容" always-show-nsfw: "总是显示 NSFW 的内容"
always-mark-nsfw: "总是用 NSFW 来标记附件" always-mark-nsfw: "总是用 NSFW 来标记附件"
show-full-acct: "不要从用户名中忽略主机名" show-full-acct: "不要从用户名中忽略主机名"
@ -243,6 +270,9 @@ common:
disable-via-mobile: "不要将帖子标记为“来自手机”" disable-via-mobile: "不要将帖子标记为“来自手机”"
load-raw-images: "以原始质量显示附加图像" load-raw-images: "以原始质量显示附加图像"
load-remote-media: "显示来自远程服务器的媒体" load-remote-media: "显示来自远程服务器的媒体"
sync: "同步"
home-profile: "定制首页数据"
deck-profile: "定制Deck数据"
search: "搜索" search: "搜索"
delete: "删除" delete: "删除"
loading: "正在加载中" loading: "正在加载中"
@ -253,6 +283,7 @@ common:
my-token-regenerated: "您的 Token 已被重置, 您将自动登出。" my-token-regenerated: "您的 Token 已被重置, 您将自动登出。"
hide-password: "隐藏密码" hide-password: "隐藏密码"
show-password: "显示密码" show-password: "显示密码"
enter-username: "输入用户名"
do-not-use-in-production: "这是一个开发者测试版. 请勿在生产环境中使用." do-not-use-in-production: "这是一个开发者测试版. 请勿在生产环境中使用."
user-suspended: "该用户已被冻结。" user-suspended: "该用户已被冻结。"
is-remote-user: "此用户信息可能不准确。" is-remote-user: "此用户信息可能不准确。"
@ -297,7 +328,7 @@ common:
server: "服务器信息" server: "服务器信息"
nav: "导航" nav: "导航"
tips: "提示" tips: "提示"
hashtags: "标签" hashtags: "哈希标签"
queue: "队列" queue: "队列"
dev: "构建应用程序失败,请再试一次。" dev: "构建应用程序失败,请再试一次。"
ai-chan-kawaii: "小蓝真可爱" ai-chan-kawaii: "小蓝真可爱"
@ -448,18 +479,23 @@ common/views/components/messaging.vue:
search-user: "查找用户" search-user: "查找用户"
you: "您" you: "您"
no-history: "没有历史记录" no-history: "没有历史记录"
user: "用户"
group: "群组"
start-with-user: "开始用户聊天"
start-with-group: "开始群组聊天"
select-group: "请选择群组"
common/views/components/messaging-room.vue: common/views/components/messaging-room.vue:
empty: "没有对话" not-talked-user: "没有用户的会话记录"
not-talked-group: "没有群组的会话记录"
no-history: "没有更多的历史记录" no-history: "没有更多的历史记录"
resize-form: "拖动以调整大小"
new-message: "新信息" new-message: "新信息"
only-one-file-attached: "只一个附件可以附加到消息中。" only-one-file-attached: "只能添加一个附件"
common/views/components/messaging-room.form.vue: common/views/components/messaging-room.form.vue:
input-message-here: "在此键入信息" input-message-here: "在此键入信息"
send: "发送" send: "发送"
attach-from-local: "从电脑中添加文件" attach-from-local: "从电脑中添加文件"
attach-from-drive: "从网盘中添加文件" attach-from-drive: "从网盘中添加文件"
only-one-file-attached: "在信息中只允许添加一个附件" only-one-file-attached: "只能添加一个附件"
common/views/components/messaging-room.message.vue: common/views/components/messaging-room.message.vue:
is-read: "已读" is-read: "已读"
deleted: "此消息已被删除" deleted: "此消息已被删除"
@ -469,9 +505,10 @@ common/views/components/nav.vue:
status: "状态" status: "状态"
wiki: "维基百科" wiki: "维基百科"
donors: "捐赠者" donors: "捐赠者"
repository: "码库" repository: "码库"
develop: "开发人员" develop: "开发人员"
feedback: "反馈" feedback: "反馈"
tos: "服务条款"
common/views/components/note-menu.vue: common/views/components/note-menu.vue:
mention: "提到" mention: "提到"
detail: "详细信息" detail: "详细信息"
@ -543,6 +580,7 @@ common/views/components/poll-editor.vue:
day: "日" day: "日"
common/views/components/reaction-picker.vue: common/views/components/reaction-picker.vue:
choose-reaction: "选择回应" choose-reaction: "选择回应"
input-reaction-placeholder: "表情符号输入"
common/views/components/emoji-picker.vue: common/views/components/emoji-picker.vue:
custom-emoji: "自定义表情符号" custom-emoji: "自定义表情符号"
people: "人" people: "人"
@ -584,6 +622,8 @@ common/views/components/signup.vue:
password-matched: "确认" password-matched: "确认"
password-not-matched: "密码不一致" password-not-matched: "密码不一致"
recaptcha: "验证" recaptcha: "验证"
agree-to: "同意{0}"
tos: "服务条款"
create: "创建一个账户" create: "创建一个账户"
some-error: "由于某种原因,创建帐户失败。请再试一次。" some-error: "由于某种原因,创建帐户失败。请再试一次。"
common/views/components/special-message.vue: common/views/components/special-message.vue:
@ -691,9 +731,32 @@ common/views/components/user-list-editor.vue:
remove-user: "从此列表中删除" remove-user: "从此列表中删除"
delete-are-you-sure: "删除列表“$1”" delete-are-you-sure: "删除列表“$1”"
deleted: "已删除" deleted: "已删除"
add-user: "添加用户"
common/views/components/user-group-editor.vue:
users: "成员"
rename: "更改群组名"
delete: "删除群组"
transfer: "群组转让"
transfer-are-you-sure: "将群组「$1」转让给「@$2」吗"
transferred: "群组已转让"
remove-user: "从本群组中删除"
delete-are-you-sure: "确定要删除「$1」组"
deleted: "已删除"
invite: "邀请"
invited: "邀请已发送"
common/views/components/user-lists.vue: common/views/components/user-lists.vue:
user-lists: "列表"
create-list: "创建列表" create-list: "创建列表"
list-name: "列表名称" list-name: "列表名称"
common/views/components/user-groups.vue:
user-groups: "群组"
create-group: "创建群组"
group-name: "群组名"
owned-groups: "我的群组"
joined-groups: "加入群组"
invites: "邀请"
accept-invite: "加入"
reject-invite: "拒绝"
common/views/widgets/broadcast.vue: common/views/widgets/broadcast.vue:
fetching: "确认中" fetching: "确认中"
no-broadcasts: "没有公告" no-broadcasts: "没有公告"
@ -713,7 +776,7 @@ common/views/widgets/posts-monitor.vue:
title: "投稿表格" title: "投稿表格"
toggle: "切换视图" toggle: "切换视图"
common/views/widgets/hashtags.vue: common/views/widgets/hashtags.vue:
title: "标签" title: "哈希标签"
common/views/widgets/server.vue: common/views/widgets/server.vue:
title: "服务器信息" title: "服务器信息"
toggle: "切换显示" toggle: "切换显示"
@ -755,6 +818,10 @@ common/views/pages/follow.vue:
request-pending: "发送关注申请" request-pending: "发送关注申请"
follow-processing: "申请处理中" follow-processing: "申请处理中"
follow-request: "关注请求" follow-request: "关注请求"
common/views/pages/follow-requests.vue:
received-follow-requests: "关注申请"
accept: "接受"
reject: "拒绝"
desktop: desktop:
banner-crop-title: "裁剪显示为背景的部分" banner-crop-title: "裁剪显示为背景的部分"
banner: "背景" banner: "背景"
@ -795,7 +862,7 @@ desktop/views/components/crop-window.vue:
cancel: "取消" cancel: "取消"
ok: "确定" ok: "确定"
desktop/views/components/drive-window.vue: desktop/views/components/drive-window.vue:
used: "使用" used: "使用"
desktop/views/components/drive.file.vue: desktop/views/components/drive.file.vue:
avatar: "头像" avatar: "头像"
banner: "背景" banner: "背景"
@ -885,34 +952,12 @@ desktop/views/components/notes.vue:
desktop/views/components/notifications.vue: desktop/views/components/notifications.vue:
empty: "没有通知哦!" empty: "没有通知哦!"
desktop/views/components/post-form.vue: desktop/views/components/post-form.vue:
add-visible-user: "+添加用户"
attach-location-information: "添加位置信息"
hide-contents: "隐藏内容"
reply-placeholder: "回复这个帖子"
quote-placeholder: "引用这个帖子…"
submit: "投稿"
reply: "回复"
renote: "转推"
posted: "已发送投稿!" posted: "已发送投稿!"
replied: "已回复!" replied: "已回复!"
reposted: "已转推!" reposted: "已转推!"
note-failed: "发帖失败" note-failed: "发帖失败"
reply-failed: "回复失败" reply-failed: "回复失败"
renote-failed: "转推失败" renote-failed: "转推失败"
posting: "发送中"
attach-media-from-local: "从设备中添加媒体文件"
attach-media-from-drive: "从网盘中添加媒体文件"
insert-a-kao: "v('ω')v"
create-poll: "创建一个投票"
text-remain: "还剩{}字"
recent-tags: "最近"
local-only-message: "这篇文章只会在本地发表"
click-to-tagging: "点击添加标签"
visibility: "可见性"
geolocation-alert: "您的设备不提供位置服务"
error: "错误"
enter-username: "请填写一个用户名"
annotations: "注释帖子(可选)"
desktop/views/components/post-form-window.vue: desktop/views/components/post-form-window.vue:
note: "新建帖子" note: "新建帖子"
reply: "回复" reply: "回复"
@ -974,7 +1019,7 @@ desktop/views/components/settings.apps.vue:
no-apps: "没有已连接的应用程序" no-apps: "没有已连接的应用程序"
common/views/components/drive-settings.vue: common/views/components/drive-settings.vue:
max: "容量" max: "容量"
in-use: "正在使用" in-use: "使用"
stats: "统计" stats: "统计"
common/views/components/mute-and-block.vue: common/views/components/mute-and-block.vue:
mute-and-block: "屏蔽/拉黑" mute-and-block: "屏蔽/拉黑"
@ -1016,8 +1061,8 @@ desktop/views/components/timeline.vue:
mentions: "提到的" mentions: "提到的"
messages: "直接发布" messages: "直接发布"
list: "列表" list: "列表"
hashtag: "标签" hashtag: "哈希标签"
add-tag-timeline: "添加标签" add-tag-timeline: "添加哈希标签"
add-list: "添加列表" add-list: "添加列表"
list-name: "列表名称" list-name: "列表名称"
desktop/views/components/ui.header.vue: desktop/views/components/ui.header.vue:
@ -1026,6 +1071,7 @@ desktop/views/components/ui.header.vue:
desktop/views/components/ui.header.account.vue: desktop/views/components/ui.header.account.vue:
profile: "个人资料" profile: "个人资料"
lists: "列表" lists: "列表"
groups: "群组"
follow-requests: "关注申请" follow-requests: "关注申请"
admin: "管理" admin: "管理"
desktop/views/components/ui.header.nav.vue: desktop/views/components/ui.header.nav.vue:
@ -1036,12 +1082,6 @@ desktop/views/components/ui.header.post.vue:
post: "撰写新帖子" post: "撰写新帖子"
desktop/views/components/ui.header.search.vue: desktop/views/components/ui.header.search.vue:
placeholder: "搜索" placeholder: "搜索"
desktop/views/components/received-follow-requests-window.vue:
title: "关注申请"
accept: "接收"
reject: "拒绝"
desktop/views/components/user-lists-window.vue:
title: "用户列表"
desktop/views/components/user-preview.vue: desktop/views/components/user-preview.vue:
notes: "帖子" notes: "帖子"
following: "关注中" following: "关注中"
@ -1063,11 +1103,13 @@ admin/views/index.vue:
users: "用户" users: "用户"
federation: "联合" federation: "联合"
announcements: "公告" announcements: "公告"
hashtags: "标签"
abuse: "举报垃圾信息" abuse: "举报垃圾信息"
queue: "作业队列" queue: "作业队列"
logs: "登录" logs: "登录"
db: "数据库"
back-to-misskey: "返回 Misskey" back-to-misskey: "返回 Misskey"
admin/views/db.vue:
tables: "表格"
admin/views/dashboard.vue: admin/views/dashboard.vue:
dashboard: "Dashboard" dashboard: "Dashboard"
accounts: "账户" accounts: "账户"
@ -1079,6 +1121,32 @@ admin/views/dashboard.vue:
admin/views/queue.vue: admin/views/queue.vue:
title: "队列" title: "队列"
remove-all-jobs: "清除所有作业" remove-all-jobs: "清除所有作业"
jobs: "任务"
queue: "队列"
domains:
deliver: "交付"
inbox: "收件箱"
db: "数据库"
objectStorage: "对象存储"
state: "状态"
states:
active: "处理中"
delayed: "已预订"
waiting: "队列等待中"
result-is-truncated: "结果已省略"
other-queues: "其他队列"
admin/views/logs.vue:
logs: "登录"
domain: "域"
level: "级别"
levels:
all: "所有"
info: "信息"
success: "成功"
warning: "警告"
error: "错误"
debug: "调试"
delete-all: "全部删除"
admin/views/abuse.vue: admin/views/abuse.vue:
title: "举报垃圾信息" title: "举报垃圾信息"
target: "目标" target: "目标"
@ -1090,14 +1158,34 @@ admin/views/instance.vue:
instance-name: "实例名称" instance-name: "实例名称"
instance-description: "实例介绍" instance-description: "实例介绍"
host: "主机名" host: "主机名"
icon-url: "图标URL"
logo-url: "Logo URL"
banner-url: "背景图片地址" banner-url: "背景图片地址"
error-image-url: "无效的图像URL" error-image-url: "无效的图像URL"
languages: "实例语言" languages: "实例语言"
languages-desc: "您可以添加多个,以空格分隔。" languages-desc: "您可以添加多个,以空格分隔。"
tos-url: "服务条款URL"
repository-url: "源码库URL"
feedback-url: "反馈URL"
maintainer-config: "管理员信息" maintainer-config: "管理员信息"
maintainer-name: "管理员名称" maintainer-name: "管理员名称"
maintainer-email: "联系管理员" maintainer-email: "联系管理员"
advanced-config: "其他设置"
note-and-tl: "帖子和时间线"
drive-config: "网盘设置" drive-config: "网盘设置"
use-object-storage: "使用对象存储"
object-storage-base-url: "URL"
object-storage-bucket: "存储空间名"
object-storage-prefix: "前缀"
object-storage-endpoint: "端点"
object-storage-region: "区域"
object-storage-port: "端口"
object-storage-access-key: "访问密钥"
object-storage-secret-key: "密钥"
object-storage-use-ssl: "使用 SSL"
object-storage-s3-info: "使用Amazon S3作为对象存储时请确认{0}相关“终端”和“区域”的设置。"
object-storage-s3-info-here: "这里"
object-storage-gcs-info: "将Google Cloud Storage用作对象存储时请将“终端”设置为storage.googleapis.com并将“区域”留空。"
cache-remote-files: "远程文件缓存" cache-remote-files: "远程文件缓存"
cache-remote-files-desc: "如果没有此参数,则所有远程文件都将直接链接到其主机服务器。 这将是保存服务器存储的有效解决方案,但是对于设置禁用直接链接的用户而言,远程文件不可见,因为不会生成缩略图,从而增加流量。 建议启用此参数集。" cache-remote-files-desc: "如果没有此参数,则所有远程文件都将直接链接到其主机服务器。 这将是保存服务器存储的有效解决方案,但是对于设置禁用直接链接的用户而言,远程文件不可见,因为不会生成缩略图,从而增加流量。 建议启用此参数集。"
local-drive-capacity-mb: "每个用户的网盘空间" local-drive-capacity-mb: "每个用户的网盘空间"
@ -1105,9 +1193,14 @@ admin/views/instance.vue:
mb: "以兆字节(Mbps)为单位" mb: "以兆字节(Mbps)为单位"
recaptcha-config: "reCAPTCHA设置" recaptcha-config: "reCAPTCHA设置"
recaptcha-info: "reCAPTCHA token是必要的. 请从 https://www.google.com/recaptcha/intro/ 获取。\n请注意, 该功能在中国大陆不可用。" recaptcha-info: "reCAPTCHA token是必要的. 请从 https://www.google.com/recaptcha/intro/ 获取。\n请注意, 该功能在中国大陆不可用。"
recaptcha-info2: "不支持v3。请使用v2。"
enable-recaptcha: "启用 reCAPTCHA\n(请注意, 此功能在中国大陆不可用. 如果启用, 可能导致无法正常使用登录或注册等功能)" enable-recaptcha: "启用 reCAPTCHA\n(请注意, 此功能在中国大陆不可用. 如果启用, 可能导致无法正常使用登录或注册等功能)"
recaptcha-site-key: "reCAPTCHA site key" recaptcha-site-key: "网站密钥"
recaptcha-secret-key: "reCAPTCHA secret key" recaptcha-secret-key: "密钥"
recaptcha-preview: "预览"
hidden-tags: "隐藏哈希标签"
hidden-tags-info: "使用换行符分隔要从集合中排除的哈希标签。"
external-service-integration-config: "连接外部服务"
twitter-integration-config: "连接到Twitter的设置" twitter-integration-config: "连接到Twitter的设置"
twitter-integration-info: "设置返回的URL{url}。" twitter-integration-info: "设置返回的URL{url}。"
enable-twitter-integration: "启用连接到Twitter" enable-twitter-integration: "启用连接到Twitter"
@ -1139,6 +1232,7 @@ admin/views/instance.vue:
save: "保存" save: "保存"
saved: "保存完毕" saved: "保存完毕"
pinned-users: "置顶用户" pinned-users: "置顶用户"
pinned-users-info: "描述您要置顶的用户,以换行符分隔。"
email-config: "电子邮件服务器设置" email-config: "电子邮件服务器设置"
email-config-info: "用于确认电子邮件和密码重置等。" email-config-info: "用于确认电子邮件和密码重置等。"
enable-email: "启用电子邮件送递" enable-email: "启用电子邮件送递"
@ -1204,6 +1298,9 @@ admin/views/drive.vue:
unmark-as-sensitive: "取消标记为“敏感”" unmark-as-sensitive: "取消标记为“敏感”"
marked-as-sensitive: "标记为“敏感”" marked-as-sensitive: "标记为“敏感”"
unmarked-as-sensitive: "取消标记为“敏感”" unmarked-as-sensitive: "取消标记为“敏感”"
clean-remote-files: "删除远程文件缓存"
clean-remote-files-are-you-sure: "确定要删除所有远程文件缓存吗?"
clean-up: "清除缓存"
admin/views/users.vue: admin/views/users.vue:
operation: "操作" operation: "操作"
username-or-userid: "用户名或用户ID" username-or-userid: "用户名或用户ID"
@ -1224,6 +1321,8 @@ admin/views/users.vue:
unsilence-confirm: "解除屏蔽?" unsilence-confirm: "解除屏蔽?"
update-remote-user: "更新远程用户信息" update-remote-user: "更新远程用户信息"
remote-user-updated: "远程用户信息已更新" remote-user-updated: "远程用户信息已更新"
delete-all-files: "删除所有文件"
delete-all-files-confirm: "删除所有文件吗?"
users: users:
title: "用户" title: "用户"
sort: sort:
@ -1299,6 +1398,7 @@ admin/views/federation.vue:
latest-request-received-at: "上次收到的请求" latest-request-received-at: "上次收到的请求"
remove-all-following: "取消所有关注" remove-all-following: "取消所有关注"
remove-all-following-info: "取消{host}的所有关注者。当实例不存在时执行。" remove-all-following-info: "取消{host}的所有关注者。当实例不存在时执行。"
delete-all-files: "删除所有文件"
block: "拉黑" block: "拉黑"
marked-as-closed: "标记为已关闭" marked-as-closed: "标记为已关闭"
lookup: "查询" lookup: "查询"
@ -1346,6 +1446,8 @@ admin/views/federation.vue:
hour: "每小时" hour: "每小时"
day: "每天" day: "每天"
blocked-hosts: "拉黑" blocked-hosts: "拉黑"
blocked-hosts-info: "描述您要阻止的主机,以换行符分隔。"
save: "保存"
desktop/views/pages/welcome.vue: desktop/views/pages/welcome.vue:
about: "更多信息..." about: "更多信息..."
timeline: "时间线" timeline: "时间线"
@ -1367,7 +1469,7 @@ desktop/views/pages/search.vue:
not-available: "在此实例的设置中关闭搜索功能。" not-available: "在此实例的设置中关闭搜索功能。"
not-found: "没有找到“{q}”的帖子" not-found: "没有找到“{q}”的帖子"
desktop/views/pages/tag.vue: desktop/views/pages/tag.vue:
no-posts-found: "没有找到带有主题标签“{q}”的帖子" no-posts-found: "没有找到带有哈希标签“{q}”的帖子"
desktop/views/pages/user-list.users.vue: desktop/views/pages/user-list.users.vue:
users: "用户" users: "用户"
add-user: "添加用户" add-user: "添加用户"
@ -1422,7 +1524,7 @@ desktop/views/widgets/users.vue:
refresh: "更多" refresh: "更多"
no-one: "不是!" no-one: "不是!"
mobile/views/components/drive.vue: mobile/views/components/drive.vue:
used: "使用" used: "使用"
folder-count: "文件夹" folder-count: "文件夹"
count-separator: "" count-separator: ""
file-count: "文件" file-count: "文件"
@ -1443,7 +1545,7 @@ mobile/views/components/drive.file-detail.vue:
download: "下载" download: "下载"
rename: "重命名" rename: "重命名"
move: "移动" move: "移动"
hash: "Hash (md5)" hash: "哈希(md5)"
exif: "EXIF" exif: "EXIF"
nsfw: "阅读注意" nsfw: "阅读注意"
mark-as-sensitive: "标记为“敏感”" mark-as-sensitive: "标记为“敏感”"
@ -1477,17 +1579,6 @@ mobile/views/components/note-sub.vue:
cat: "cat" cat: "cat"
mobile/views/components/notifications.vue: mobile/views/components/notifications.vue:
empty: "没有通知哦!" empty: "没有通知哦!"
mobile/views/components/post-form.vue:
add-visible-user: "添加用户"
submit: "帖子"
reply: "回复"
renote: "转推"
quote-placeholder: "引用这个帖子t... (可选)"
reply-placeholder: "回复这个帖子"
cw-placeholder: "评论帖子(可选)"
geolocation-alert: "您的设备不提供位置服务"
error: "错误"
username-prompt: "请输入用户名"
mobile/views/components/sub-note-content.vue: mobile/views/components/sub-note-content.vue:
private: "私密帖子" private: "私密帖子"
deleted: "帖子已删除" deleted: "帖子已删除"
@ -1502,6 +1593,7 @@ mobile/views/components/ui.nav.vue:
follow-requests: "关注申请" follow-requests: "关注申请"
search: "搜索" search: "搜索"
user-lists: "列表" user-lists: "列表"
user-groups: "群组"
widgets: "小部件" widgets: "小部件"
game: "游戏" game: "游戏"
admin: "管理" admin: "管理"
@ -1514,8 +1606,6 @@ mobile/views/pages/drive.vue:
rename-folder: "重命名文件夹" rename-folder: "重命名文件夹"
move-folder: "移动此文件夹" move-folder: "移动此文件夹"
delete-folder: "删除此文件夹" delete-folder: "删除此文件夹"
mobile/views/pages/user-lists.vue:
title: "列表"
mobile/views/pages/signup.vue: mobile/views/pages/signup.vue:
lets-start: "您的账户现已准备就绪! 📦" lets-start: "您的账户现已准备就绪! 📦"
mobile/views/pages/followers.vue: mobile/views/pages/followers.vue:
@ -1530,7 +1620,7 @@ mobile/views/pages/home.vue:
mentions: "Mentions" mentions: "Mentions"
messages: "直接发布" messages: "直接发布"
mobile/views/pages/tag.vue: mobile/views/pages/tag.vue:
no-posts-found: "没有找到带有主题标签“{q}”的帖子" no-posts-found: "没有找到带有哈希标签“{q}”的帖子"
mobile/views/pages/widgets.vue: mobile/views/pages/widgets.vue:
dashboard: "仪表盘" dashboard: "仪表盘"
widgets-hints: "您可以添加/删除/重新排列小部件。 要移动小部件,请拖动“三”。 点击“×”删除小部件。 某些小部件可以通过点击来更改显示。" widgets-hints: "您可以添加/删除/重新排列小部件。 要移动小部件,请拖动“三”。 点击“×”删除小部件。 某些小部件可以通过点击来更改显示。"
@ -1540,10 +1630,6 @@ mobile/views/pages/widgets/activity.vue:
activity: "活动" activity: "活动"
mobile/views/pages/share.vue: mobile/views/pages/share.vue:
share-with: "共享{name}" share-with: "共享{name}"
mobile/views/pages/received-follow-requests.vue:
title: "关注申请"
accept: "批准"
reject: "拒绝"
mobile/views/pages/note.vue: mobile/views/pages/note.vue:
title: "帖文" title: "帖文"
prev: "上一个帖子" prev: "上一个帖子"
@ -1582,7 +1668,7 @@ deck:
home: "首页" home: "首页"
local: "Local" local: "Local"
hybrid: "社交" hybrid: "社交"
hashtag: "标签" hashtag: "哈希标签"
global: "Global" global: "Global"
mentions: "Mentions" mentions: "Mentions"
direct: "直接发布" direct: "直接发布"
@ -1649,6 +1735,10 @@ pages:
edit-this-page: "编辑此页面" edit-this-page: "编辑此页面"
view-source: "查看源代码" view-source: "查看源代码"
view-page: "查看页面" view-page: "查看页面"
like: "赞"
unlike: "取消赞"
liked-pages: "喜欢的页面"
my-pages: "个人页面"
inspector: "检查器" inspector: "检查器"
content: "页面内容" content: "页面内容"
variables: "变量" variables: "变量"
@ -1773,8 +1863,8 @@ pages:
_divide: _divide:
arg1: "A" arg1: "A"
arg2: "B" arg2: "B"
remind: "÷ 取模" mod: "÷ 取模"
_remind: _mod:
arg1: "A" arg1: "A"
arg2: "B" arg2: "B"
eq: "A和B相等" eq: "A和B相等"
@ -1857,6 +1947,9 @@ pages:
_pick: _pick:
arg1: "列表" arg1: "列表"
arg2: "位置" arg2: "位置"
listLen: "获取列表长度"
_listLen:
arg1: "列表"
number: "数值" number: "数值"
stringToNumber: "文本到数字" stringToNumber: "文本到数字"
_stringToNumber: _stringToNumber:

View File

@ -86,3 +86,5 @@ admin/views/dashboard.vue:
drive: "雲端硬碟" drive: "雲端硬碟"
admin/views/charts.vue: admin/views/charts.vue:
drive: "雲端硬碟" drive: "雲端硬碟"
pages:
like: "贊"

View File

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

View File

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

View File

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

View File

@ -0,0 +1,25 @@
import {MigrationInterface, QueryRunner} from "typeorm";
export class UserGroupInvite1558257926829 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`CREATE TABLE "user_group_invite" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "userGroupId" character varying(32) NOT NULL, CONSTRAINT "PK_3893884af0d3a5f4d01e7921a97" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE INDEX "IDX_1039988afa3bf991185b277fe0" ON "user_group_invite" ("userId") `);
await queryRunner.query(`CREATE INDEX "IDX_e10924607d058004304611a436" ON "user_group_invite" ("userGroupId") `);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_78787741f9010886796f2320a4" ON "user_group_invite" ("userId", "userGroupId") `);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_d9ecaed8c6dc43f3592c229282" ON "user_group_joining" ("userId", "userGroupId") `);
await queryRunner.query(`ALTER TABLE "user_group_invite" ADD CONSTRAINT "FK_1039988afa3bf991185b277fe03" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "user_group_invite" ADD CONSTRAINT "FK_e10924607d058004304611a436a" FOREIGN KEY ("userGroupId") REFERENCES "user_group"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
}
public async down(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`ALTER TABLE "user_group_invite" DROP CONSTRAINT "FK_e10924607d058004304611a436a"`);
await queryRunner.query(`ALTER TABLE "user_group_invite" DROP CONSTRAINT "FK_1039988afa3bf991185b277fe03"`);
await queryRunner.query(`DROP INDEX "IDX_d9ecaed8c6dc43f3592c229282"`);
await queryRunner.query(`DROP INDEX "IDX_78787741f9010886796f2320a4"`);
await queryRunner.query(`DROP INDEX "IDX_e10924607d058004304611a436"`);
await queryRunner.query(`DROP INDEX "IDX_1039988afa3bf991185b277fe0"`);
await queryRunner.query(`DROP TABLE "user_group_invite"`);
}
}

View File

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

View File

@ -1,7 +1,7 @@
{ {
"name": "misskey", "name": "misskey",
"author": "syuilo <i@syuilo.com>", "author": "syuilo <i@syuilo.com>",
"version": "11.14.0", "version": "11.23.1",
"codename": "daybreak", "codename": "daybreak",
"repository": { "repository": {
"type": "git", "type": "git",
@ -14,6 +14,7 @@
"init": "node ./built/init.js", "init": "node ./built/init.js",
"ormconfig": "node ./built/ormconfig.js", "ormconfig": "node ./built/ormconfig.js",
"migrate": "npm run ormconfig && ts-node ./node_modules/typeorm/cli.js migration:run", "migrate": "npm run ormconfig && ts-node ./node_modules/typeorm/cli.js migration:run",
"migrateandstart": "npm run migrate && npm run start",
"build": "webpack && gulp build", "build": "webpack && gulp build",
"webpack": "webpack", "webpack": "webpack",
"watch": "webpack --watch", "watch": "webpack --watch",
@ -24,6 +25,10 @@
"test": "gulp test", "test": "gulp test",
"format": "gulp format" "format": "gulp format"
}, },
"resolutions": {
"gulp-cssnano/cssnano/postcss-svgo/svgo/js-yaml": "^3.13.1",
"video-thumbnail-generator/lodash": "^4.17.11"
},
"dependencies": { "dependencies": {
"@elastic/elasticsearch": "7.0.0-rc.2", "@elastic/elasticsearch": "7.0.0-rc.2",
"@fortawesome/fontawesome-svg-core": "1.2.15", "@fortawesome/fontawesome-svg-core": "1.2.15",
@ -32,13 +37,11 @@
"@fortawesome/free-solid-svg-icons": "5.7.2", "@fortawesome/free-solid-svg-icons": "5.7.2",
"@fortawesome/vue-fontawesome": "0.1.5", "@fortawesome/vue-fontawesome": "0.1.5",
"@koa/cors": "2.2.3", "@koa/cors": "2.2.3",
"@prezzemolo/zip": "0.0.3",
"@types/bcryptjs": "2.4.2", "@types/bcryptjs": "2.4.2",
"@types/bull": "3.5.11", "@types/bull": "3.5.11",
"@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/file-type": "10.9.1",
"@types/gulp": "4.0.6", "@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",
@ -96,17 +99,17 @@
"@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.11", "apexcharts": "3.8.0",
"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.9.1", "bull": "3.10.0",
"cafy": "15.1.1", "cafy": "15.1.1",
"chai": "4.2.0", "chai": "4.2.0",
"chalk": "2.4.2", "chalk": "2.4.2",
"cli-highlight": "2.1.0", "cli-highlight": "2.1.1",
"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",
@ -140,12 +143,12 @@
"http-signature": "1.2.0", "http-signature": "1.2.0",
"insert-text-at-cursor": "0.2.0", "insert-text-at-cursor": "0.2.0",
"is-root": "2.1.0", "is-root": "2.1.0",
"is-svg": "4.1.0", "is-svg": "4.2.0",
"js-yaml": "3.13.1", "js-yaml": "3.13.1",
"jsdom": "15.1.0", "jsdom": "15.1.1",
"json5": "2.1.0", "json5": "2.1.0",
"json5-loader": "2.0.0", "json5-loader": "2.0.0",
"katex": "0.10.1", "katex": "0.10.2",
"koa": "2.7.0", "koa": "2.7.0",
"koa-bodyparser": "4.2.1", "koa-bodyparser": "4.2.1",
"koa-compress": "3.0.0", "koa-compress": "3.0.0",
@ -162,14 +165,14 @@
"loader-utils": "1.2.3", "loader-utils": "1.2.3",
"lolex": "3.1.0", "lolex": "3.1.0",
"lookup-dns-cache": "2.1.0", "lookup-dns-cache": "2.1.0",
"minio": "7.0.8", "minio": "7.0.10",
"mocha": "6.1.4", "mocha": "6.1.4",
"moji": "0.5.1", "moji": "0.5.1",
"moment": "2.24.0", "moment": "2.24.0",
"ms": "2.1.1", "ms": "2.1.2",
"nested-property": "0.0.7", "nested-property": "0.0.7",
"node-fetch": "2.5.0", "node-fetch": "2.6.0",
"nodemailer": "6.1.1", "nodemailer": "6.2.1",
"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",
@ -211,10 +214,10 @@
"style-loader": "0.23.1", "style-loader": "0.23.1",
"stylus": "0.54.5", "stylus": "0.54.5",
"stylus-loader": "3.0.2", "stylus-loader": "3.0.2",
"summaly": "2.2.0", "summaly": "2.3.0",
"systeminformation": "4.1.6", "systeminformation": "4.11.1",
"syuilo-password-strength": "0.0.1", "syuilo-password-strength": "0.0.1",
"terser-webpack-plugin": "1.2.3", "terser-webpack-plugin": "1.3.0",
"textarea-caret": "3.1.0", "textarea-caret": "3.1.0",
"tinycolor2": "1.4.1", "tinycolor2": "1.4.1",
"tmp": "0.1.0", "tmp": "0.1.0",
@ -247,13 +250,13 @@
"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",
"vue-template-compiler": "2.6.10", "vue-template-compiler": "2.6.10",
"vuedraggable": "2.20.0", "vuedraggable": "2.21.0",
"vuewordcloud": "18.7.11", "vuewordcloud": "18.7.11",
"vuex": "3.1.1", "vuex": "3.1.1",
"vuex-persistedstate": "2.5.4", "vuex-persistedstate": "2.5.4",
"web-push": "3.3.4", "web-push": "3.3.5",
"webpack": "4.31.0", "webpack": "4.34.0",
"webpack-cli": "3.3.2", "webpack-cli": "3.3.4",
"websocket": "1.0.28", "websocket": "1.0.28",
"ws": "7.0.0", "ws": "7.0.0",
"xev": "2.0.1" "xev": "2.0.1"

View File

@ -50,7 +50,7 @@ export async function masterMain() {
// initialize app // initialize app
config = await init(); config = await init();
if (config.port == null) { if (config.port == null || Number.isNaN(config.port)) {
bootLogger.error('The port is not configured. Please configure port.', null, true); bootLogger.error('The port is not configured. Please configure port.', null, true);
process.exit(1); process.exit(1);
} }

View File

@ -1,7 +1,7 @@
<template> <template>
<div> <div>
<ui-card> <ui-card>
<template #title><fa icon="broadcast-tower"/> {{ $t('announcements') }}</template> <template #title><fa :icon="faBroadcastTower"/> {{ $t('announcements') }}</template>
<section v-for="(announcement, i) in announcements" class="fit-top"> <section v-for="(announcement, i) in announcements" class="fit-top">
<ui-input v-model="announcement.title" @change="save"> <ui-input v-model="announcement.title" @change="save">
<span>{{ $t('title') }}</span> <span>{{ $t('title') }}</span>
@ -18,7 +18,7 @@
</ui-horizon-group> </ui-horizon-group>
</section> </section>
<section> <section>
<ui-button @click="add"><fa icon="plus"/> {{ $t('add') }}</ui-button> <ui-button @click="add"><fa :icon="faPlus"/> {{ $t('add') }}</ui-button>
</section> </section>
</ui-card> </ui-card>
</div> </div>
@ -27,12 +27,14 @@
<script lang="ts"> <script lang="ts">
import Vue from 'vue'; import Vue from 'vue';
import i18n from '../../i18n'; import i18n from '../../i18n';
import { faBroadcastTower, faPlus } from '@fortawesome/free-solid-svg-icons';
export default Vue.extend({ export default Vue.extend({
i18n: i18n('admin/views/announcements.vue'), i18n: i18n('admin/views/announcements.vue'),
data() { data() {
return { return {
announcements: [], announcements: [],
faBroadcastTower, faPlus
}; };
}, },

View File

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

View File

@ -0,0 +1,39 @@
<template>
<div>
<ui-card>
<template #title><fa :icon="faDatabase"/> {{ $t('tables') }}</template>
<section v-if="tables">
<div v-for="table in Object.keys(tables)"><b>{{ table }}</b> {{ tables[table].count | number }} {{ tables[table].size | bytes }}</div>
</section>
</ui-card>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import i18n from '../../i18n';
import { faDatabase } from '@fortawesome/free-solid-svg-icons';
export default Vue.extend({
i18n: i18n('admin/views/db.vue'),
data() {
return {
tables: null,
faDatabase
};
},
mounted() {
this.fetch();
},
methods: {
fetch() {
this.$root.api('admin/get-table-stats').then(tables => {
this.tables = tables;
});
},
}
});
</script>

View File

@ -14,6 +14,10 @@
<ui-button @click="show()"><fa :icon="faSearch"/> {{ $t('lookup') }}</ui-button> <ui-button @click="show()"><fa :icon="faSearch"/> {{ $t('lookup') }}</ui-button>
<ui-textarea v-if="file" :value="file | json5" readonly tall style="margin-top:16px;"></ui-textarea> <ui-textarea v-if="file" :value="file | json5" readonly tall style="margin-top:16px;"></ui-textarea>
</section> </section>
<section>
<ui-button @click="cleanUp()"><fa :icon="faTrashAlt"/> {{ $t('clean-up') }}</ui-button>
<ui-button @click="cleanRemoteFiles()"><fa :icon="faTrashAlt"/> {{ $t('clean-remote-files') }}</ui-button>
</section>
</ui-card> </ui-card>
<ui-card> <ui-card>
@ -227,6 +231,29 @@ export default Vue.extend({
}); });
}); });
}, },
cleanRemoteFiles() {
this.$root.dialog({
type: 'warning',
text: this.$t('clean-remote-files-are-you-sure'),
showCancelButton: true
}).then(({ canceled }) => {
if (canceled) return;
this.$root.api('admin/drive/clean-remote-files');
this.$root.dialog({
type: 'success',
splash: true
});
});
},
cleanUp() {
this.$root.api('admin/drive/cleanup');
this.$root.dialog({
type: 'success',
splash: true
});
}
} }
}); });
</script> </script>

View File

@ -22,6 +22,7 @@
<li @click="nav('instance')" :class="{ active: page == 'instance' }"><fa icon="cog" fixed-width/>{{ $t('instance') }}</li> <li @click="nav('instance')" :class="{ active: page == 'instance' }"><fa icon="cog" fixed-width/>{{ $t('instance') }}</li>
<li @click="nav('queue')" :class="{ active: page == 'queue' }"><fa :icon="faTasks" fixed-width/>{{ $t('queue') }}</li> <li @click="nav('queue')" :class="{ active: page == 'queue' }"><fa :icon="faTasks" fixed-width/>{{ $t('queue') }}</li>
<li @click="nav('logs')" :class="{ active: page == 'logs' }"><fa :icon="faStream" fixed-width/>{{ $t('logs') }}</li> <li @click="nav('logs')" :class="{ active: page == 'logs' }"><fa :icon="faStream" fixed-width/>{{ $t('logs') }}</li>
<li @click="nav('db')" :class="{ active: page == 'db' }"><fa :icon="faDatabase" fixed-width/>{{ $t('db') }}</li>
<li @click="nav('moderators')" :class="{ active: page == 'moderators' }"><fa :icon="faHeadset" fixed-width/>{{ $t('moderators') }}</li> <li @click="nav('moderators')" :class="{ active: page == 'moderators' }"><fa :icon="faHeadset" fixed-width/>{{ $t('moderators') }}</li>
<li @click="nav('users')" :class="{ active: page == 'users' }"><fa icon="users" fixed-width/>{{ $t('users') }}</li> <li @click="nav('users')" :class="{ active: page == 'users' }"><fa icon="users" fixed-width/>{{ $t('users') }}</li>
<li @click="nav('drive')" :class="{ active: page == 'drive' }"><fa icon="cloud" fixed-width/>{{ $t('@.drive') }}</li> <li @click="nav('drive')" :class="{ active: page == 'drive' }"><fa icon="cloud" fixed-width/>{{ $t('@.drive') }}</li>
@ -43,6 +44,7 @@
<div v-if="page == 'instance'"><x-instance/></div> <div v-if="page == 'instance'"><x-instance/></div>
<div v-if="page == 'queue'"><x-queue/></div> <div v-if="page == 'queue'"><x-queue/></div>
<div v-if="page == 'logs'"><x-logs/></div> <div v-if="page == 'logs'"><x-logs/></div>
<div v-if="page == 'db'"><x-db/></div>
<div v-if="page == 'moderators'"><x-moderators/></div> <div v-if="page == 'moderators'"><x-moderators/></div>
<div v-if="page == 'users'"><x-users/></div> <div v-if="page == 'users'"><x-users/></div>
<div v-if="page == 'emoji'"><x-emoji/></div> <div v-if="page == 'emoji'"><x-emoji/></div>
@ -59,19 +61,20 @@
import Vue from 'vue'; import Vue from 'vue';
import i18n from '../../i18n'; import i18n from '../../i18n';
import { version } from '../../config'; import { version } from '../../config';
import XDashboard from "./dashboard.vue"; import XDashboard from './dashboard.vue';
import XInstance from "./instance.vue"; import XInstance from './instance.vue';
import XQueue from "./queue.vue"; import XQueue from './queue.vue';
import XLogs from "./logs.vue"; import XLogs from './logs.vue';
import XModerators from "./moderators.vue"; import XDb from './db.vue';
import XEmoji from "./emoji.vue"; import XModerators from './moderators.vue';
import XAnnouncements from "./announcements.vue"; import XEmoji from './emoji.vue';
import XUsers from "./users.vue"; import XAnnouncements from './announcements.vue';
import XDrive from "./drive.vue"; import XUsers from './users.vue';
import XAbuse from "./abuse.vue"; import XDrive from './drive.vue';
import XFederation from "./federation.vue"; import XAbuse from './abuse.vue';
import XFederation from './federation.vue';
import { faHeadset, faArrowLeft, faGlobe, faExclamationCircle, faTasks, faStream } from '@fortawesome/free-solid-svg-icons'; import { faHeadset, faArrowLeft, faGlobe, faExclamationCircle, faTasks, faStream, faDatabase } from '@fortawesome/free-solid-svg-icons';
import { faGrin } from '@fortawesome/free-regular-svg-icons'; import { faGrin } from '@fortawesome/free-regular-svg-icons';
// Detect the user agent // Detect the user agent
@ -85,6 +88,7 @@ export default Vue.extend({
XInstance, XInstance,
XQueue, XQueue,
XLogs, XLogs,
XDb,
XModerators, XModerators,
XEmoji, XEmoji,
XAnnouncements, XAnnouncements,
@ -108,7 +112,8 @@ export default Vue.extend({
faGlobe, faGlobe,
faExclamationCircle, faExclamationCircle,
faTasks, faTasks,
faStream faStream,
faDatabase,
}; };
}, },
methods: { methods: {

View File

@ -9,11 +9,11 @@
<ui-input v-model="iconUrl"><template #icon><fa icon="link"/></template>{{ $t('icon-url') }}</ui-input> <ui-input v-model="iconUrl"><template #icon><fa icon="link"/></template>{{ $t('icon-url') }}</ui-input>
<ui-input v-model="mascotImageUrl"><template #icon><fa icon="link"/></template>{{ $t('logo-url') }}</ui-input> <ui-input v-model="mascotImageUrl"><template #icon><fa icon="link"/></template>{{ $t('logo-url') }}</ui-input>
<ui-input v-model="bannerUrl"><template #icon><fa icon="link"/></template>{{ $t('banner-url') }}</ui-input> <ui-input v-model="bannerUrl"><template #icon><fa icon="link"/></template>{{ $t('banner-url') }}</ui-input>
<ui-input v-model="errorImageUrl"><template #icon><fa icon="link"/></template>{{ $t('error-image-url') }}</ui-input>
<ui-input v-model="ToSUrl"><template #icon><fa icon="link"/></template>{{ $t('tos-url') }}</ui-input> <ui-input v-model="ToSUrl"><template #icon><fa icon="link"/></template>{{ $t('tos-url') }}</ui-input>
<ui-input v-model="languages"><template #icon><fa icon="language"/></template>{{ $t('languages') }}<template #desc>{{ $t('languages-desc') }}</template></ui-input>
<details> <details>
<summary>{{ $t('advanced-config') }}</summary> <summary>{{ $t('advanced-config') }}</summary>
<ui-input v-model="errorImageUrl"><template #icon><fa icon="link"/></template>{{ $t('error-image-url') }}</ui-input>
<ui-input v-model="languages"><template #icon><fa icon="language"/></template>{{ $t('languages') }}<template #desc>{{ $t('languages-desc') }}</template></ui-input>
<ui-input v-model="repositoryUrl"><template #icon><fa icon="link"/></template>{{ $t('repository-url') }}</ui-input> <ui-input v-model="repositoryUrl"><template #icon><fa icon="link"/></template>{{ $t('repository-url') }}</ui-input>
<ui-input v-model="feedbackUrl"><template #icon><fa icon="link"/></template>{{ $t('feedback-url') }}</ui-input> <ui-input v-model="feedbackUrl"><template #icon><fa icon="link"/></template>{{ $t('feedback-url') }}</ui-input>
</details> </details>
@ -159,12 +159,17 @@
<ui-switch v-model="enableRecaptcha">{{ $t('enable-recaptcha') }}</ui-switch> <ui-switch v-model="enableRecaptcha">{{ $t('enable-recaptcha') }}</ui-switch>
<template v-if="enableRecaptcha"> <template v-if="enableRecaptcha">
<ui-info>{{ $t('recaptcha-info') }}</ui-info> <ui-info>{{ $t('recaptcha-info') }}</ui-info>
<ui-info warn>{{ $t('recaptcha-info2') }}</ui-info>
<ui-horizon-group inputs> <ui-horizon-group inputs>
<ui-input v-model="recaptchaSiteKey" :disabled="!enableRecaptcha"><template #icon><fa icon="key"/></template>{{ $t('recaptcha-site-key') }}</ui-input> <ui-input v-model="recaptchaSiteKey" :disabled="!enableRecaptcha"><template #icon><fa icon="key"/></template>{{ $t('recaptcha-site-key') }}</ui-input>
<ui-input v-model="recaptchaSecretKey" :disabled="!enableRecaptcha"><template #icon><fa icon="key"/></template>{{ $t('recaptcha-secret-key') }}</ui-input> <ui-input v-model="recaptchaSecretKey" :disabled="!enableRecaptcha"><template #icon><fa icon="key"/></template>{{ $t('recaptcha-secret-key') }}</ui-input>
</ui-horizon-group> </ui-horizon-group>
</template> </template>
</section> </section>
<section v-if="enableRecaptcha && recaptchaSiteKey">
<header>{{ $t('recaptcha-preview') }}</header>
<div ref="recaptcha" style="margin: 16px 0 0 0;" :key="recaptchaSiteKey"></div>
</section>
<section> <section>
<ui-button @click="updateMeta"><fa :icon="faSave"/> {{ $t('save') }}</ui-button> <ui-button @click="updateMeta"><fa :icon="faSave"/> {{ $t('save') }}</ui-button>
</section> </section>
@ -376,6 +381,34 @@ export default Vue.extend({
}); });
}, },
mounted() {
const renderRecaptchaPreview = () => {
if (!(window as any).grecaptcha) return;
if (!this.$refs.recaptcha) return;
if (!this.recaptchaSiteKey) return;
(window as any).grecaptcha.render(this.$refs.recaptcha, {
sitekey: this.recaptchaSiteKey
});
};
window.onRecaotchaLoad = () => {
renderRecaptchaPreview();
};
const head = document.getElementsByTagName('head')[0];
const script = document.createElement('script');
script.setAttribute('src', 'https://www.google.com/recaptcha/api.js?onload=onRecaotchaLoad');
head.appendChild(script);
this.$watch('enableRecaptcha', () => {
renderRecaptchaPreview();
});
this.$watch('recaptchaSiteKey', () => {
renderRecaptchaPreview();
});
},
methods: { methods: {
invite() { invite() {
this.$root.api('admin/invite').then(x => { this.$root.api('admin/invite').then(x => {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -83,9 +83,19 @@ export default (opts: Opts = {}) => ({
if (this.appearNote.text) { if (this.appearNote.text) {
const ast = parse(this.appearNote.text); const ast = parse(this.appearNote.text);
// TODO: 再帰的にURL要素がないか調べる // TODO: 再帰的にURL要素がないか調べる
return unique(ast const urls = unique(ast
.filter(t => ((t.node.type == 'url' || t.node.type == 'link') && t.node.props.url && !t.node.props.silent)) .filter(t => ((t.node.type == 'url' || t.node.type == 'link') && t.node.props.url && !t.node.props.silent))
.map(t => t.node.props.url)); .map(t => t.node.props.url));
// unique without hash
// [ http://a/#1, http://a/#2, http://b/#3 ] => [ http://a/#1, http://b/#3 ]
const removeHash = x => x.replace(/#[^#]*$/, '');
return urls.reduce((array, url) => {
const removed = removeHash(url);
if (!array.map(x => removeHash(x)).includes(removed)) array.push(url);
return array;
}, []);
} else { } else {
return null; return null;
} }

View File

@ -144,8 +144,6 @@ export default prop => ({
break; break;
} }
} }
this.$emit(`update:${prop}`, this.$_ns_note_);
}, },
} }
}); });

View File

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

View File

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

View File

@ -16,7 +16,7 @@
</ol> </ol>
<ol class="emojis" ref="suggests" v-if="emojis.length > 0"> <ol class="emojis" ref="suggests" v-if="emojis.length > 0">
<li v-for="emoji in emojis" @click="complete(type, emoji.emoji)" @keydown="onKeydown" tabindex="-1"> <li v-for="emoji in emojis" @click="complete(type, emoji.emoji)" @keydown="onKeydown" tabindex="-1">
<span class="emoji" v-if="emoji.isCustomEmoji"><img :src="emoji.url" :alt="emoji.emoji"/></span> <span class="emoji" v-if="emoji.isCustomEmoji"><img :src="$store.state.device.disableShowingAnimatedImages ? getStaticImageUrl(emoji.url) : emoji.url" :alt="emoji.emoji"/></span>
<span class="emoji" v-else-if="!useOsDefaultEmojis"><img :src="emoji.url" :alt="emoji.emoji"/></span> <span class="emoji" v-else-if="!useOsDefaultEmojis"><img :src="emoji.url" :alt="emoji.emoji"/></span>
<span class="emoji" v-else>{{ emoji.emoji }}</span> <span class="emoji" v-else>{{ emoji.emoji }}</span>
<span class="name" v-html="emoji.name.replace(q, `<b>${q}</b>`)"></span> <span class="name" v-html="emoji.name.replace(q, `<b>${q}</b>`)"></span>
@ -31,6 +31,7 @@ import Vue from 'vue';
import * as emojilib from 'emojilib'; import * as emojilib from 'emojilib';
import contains from '../../../common/scripts/contains'; import contains from '../../../common/scripts/contains';
import { twemojiBase } from '../../../../../misc/twemoji-base'; import { twemojiBase } from '../../../../../misc/twemoji-base';
import { getStaticImageUrl } from '../../../common/scripts/get-static-image-url';
type EmojiDef = { type EmojiDef = {
emoji: string; emoji: string;
@ -78,6 +79,7 @@ export default Vue.extend({
data() { data() {
return { return {
getStaticImageUrl,
fetching: true, fetching: true,
users: [], users: [],
hashtags: [], hashtags: [],

View File

@ -0,0 +1,27 @@
<template>
<div>
<mk-avatar v-for="user in us" :user="user" :key="user.id" style="width:32px;height:32px;"/>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
export default Vue.extend({
props: {
userIds: {
required: true
},
},
data() {
return {
us: []
};
},
async created() {
this.us = await this.$root.api('users/show', {
userIds: this.userIds
});
}
});
</script>

View File

@ -18,6 +18,7 @@
<fa icon="spinner" pulse v-if="type === 'waiting'"/> <fa icon="spinner" pulse v-if="type === 'waiting'"/>
</div> </div>
<header v-if="title" v-html="title"></header> <header v-if="title" v-html="title"></header>
<header v-if="title == null && user">{{ $t('@.enter-username') }}</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>
<ui-input v-if="user" v-model="userInputValue" autofocus @keydown="onInputKeydown"><template #prefix>@</template></ui-input> <ui-input v-if="user" v-model="userInputValue" autofocus @keydown="onInputKeydown"><template #prefix>@</template></ui-input>
@ -97,7 +98,7 @@ 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: this.select ? this.select.items ? this.select.items[0].value : this.select.groupedItems[0].items[0].value : null,
faTimesCircle, faQuestionCircle faTimesCircle, faQuestionCircle
}; };
}, },

View File

@ -19,7 +19,6 @@ export default Vue.extend({
}); });
</script> </script>
<style lang="stylus" scoped> <style lang="stylus" scoped>
.a .a
display block display block

View File

@ -23,11 +23,11 @@
</div> </div>
<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="$store.state.settings.gamesReversiShowBoardLabels">
<span v-for="i in game.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="$store.state.settings.gamesReversiShowBoardLabels">
<div v-for="i in game.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">
@ -35,7 +35,7 @@
:class="{ empty: stone == null, none: o.map[i] == 'null', isEnded: game.isEnded, myTurn: !game.isEnded && isMyTurn, can: turnUser ? o.canPut(turnUser.id == blackUser.id, i) : null, prev: o.prevPos == i }" :class="{ empty: stone == null, none: o.map[i] == 'null', isEnded: game.isEnded, myTurn: !game.isEnded && isMyTurn, can: turnUser ? o.canPut(turnUser.id == blackUser.id, i) : null, prev: o.prevPos == i }"
@click="set(i)" @click="set(i)"
:title="`${String.fromCharCode(65 + o.transformPosToXy(i)[0])}${o.transformPosToXy(i)[1] + 1}`"> :title="`${String.fromCharCode(65 + o.transformPosToXy(i)[0])}${o.transformPosToXy(i)[1] + 1}`">
<template v-if="$store.state.settings.games.reversi.useAvatarStones"> <template v-if="$store.state.settings.gamesReversiUseAvatarStones">
<img v-if="stone === true" :src="blackUser.avatarUrl" alt="black"> <img v-if="stone === true" :src="blackUser.avatarUrl" alt="black">
<img v-if="stone === false" :src="whiteUser.avatarUrl" alt="white"> <img v-if="stone === false" :src="whiteUser.avatarUrl" alt="white">
</template> </template>
@ -45,11 +45,11 @@
</template> </template>
</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.gamesReversiShowBoardLabels">
<div v-for="i in game.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.gamesReversiShowBoardLabels">
<span v-for="i in game.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>

View File

@ -21,7 +21,6 @@ import avatar from './avatar.vue';
import nav from './nav.vue'; import nav from './nav.vue';
import misskeyFlavoredMarkdown from './misskey-flavored-markdown.vue'; import misskeyFlavoredMarkdown from './misskey-flavored-markdown.vue';
import poll from './poll.vue'; import poll from './poll.vue';
import pollEditor from './poll-editor.vue';
import reactionIcon from './reaction-icon.vue'; import reactionIcon from './reaction-icon.vue';
import reactionsViewer from './reactions-viewer.vue'; import reactionsViewer from './reactions-viewer.vue';
import time from './time.vue'; import time from './time.vue';
@ -44,6 +43,9 @@ import uiSwitch from './ui/switch.vue';
import uiRadio from './ui/radio.vue'; import uiRadio from './ui/radio.vue';
import uiSelect from './ui/select.vue'; import uiSelect from './ui/select.vue';
import uiInfo from './ui/info.vue'; import uiInfo from './ui/info.vue';
import uiMargin from './ui/margin.vue';
import uiHr from './ui/hr.vue';
import uiPagination from './ui/pagination.vue';
import formButton from './ui/form/button.vue'; import formButton from './ui/form/button.vue';
import formRadio from './ui/form/radio.vue'; import formRadio from './ui/form/radio.vue';
@ -68,7 +70,6 @@ Vue.component('mk-acct', acct);
Vue.component('mk-avatar', avatar); Vue.component('mk-avatar', avatar);
Vue.component('mk-nav', nav); Vue.component('mk-nav', nav);
Vue.component('mk-poll', poll); Vue.component('mk-poll', poll);
Vue.component('mk-poll-editor', pollEditor);
Vue.component('mk-reaction-icon', reactionIcon); Vue.component('mk-reaction-icon', reactionIcon);
Vue.component('mk-reactions-viewer', reactionsViewer); Vue.component('mk-reactions-viewer', reactionsViewer);
Vue.component('mk-time', time); Vue.component('mk-time', time);
@ -91,5 +92,8 @@ Vue.component('ui-switch', uiSwitch);
Vue.component('ui-radio', uiRadio); Vue.component('ui-radio', uiRadio);
Vue.component('ui-select', uiSelect); Vue.component('ui-select', uiSelect);
Vue.component('ui-info', uiInfo); Vue.component('ui-info', uiInfo);
Vue.component('ui-margin', uiMargin);
Vue.component('ui-hr', uiHr);
Vue.component('ui-pagination', uiPagination);
Vue.component('form-button', formButton); Vue.component('form-button', formButton);
Vue.component('form-radio', formRadio); Vue.component('form-radio', formRadio);

View File

@ -1,7 +1,7 @@
<template> <template>
<div class="onchrpzrvnoruiaenfcqvccjfuupzzwv" :class="{ isMobile: $root.isMobile }"> <div class="onchrpzrvnoruiaenfcqvccjfuupzzwv" :class="{ isMobile: $root.isMobile }">
<div class="backdrop" ref="backdrop" @click="close"></div> <div class="backdrop" ref="backdrop" @click="close"></div>
<div class="popover" :class="{ hukidasi }" ref="popover"> <div class="popover" :class="{ bubble }" ref="popover">
<template v-for="item, i in items"> <template v-for="item, i in items">
<div v-if="item === null"></div> <div v-if="item === null"></div>
<button v-if="item" @click="clicked(item.action)" :tabindex="i"> <button v-if="item" @click="clicked(item.action)" :tabindex="i">
@ -28,7 +28,7 @@ export default Vue.extend({
}, },
data() { data() {
return { return {
hukidasi: !this.$root.isMobile bubble: !this.$root.isMobile
}; };
}, },
mounted() { mounted() {
@ -56,12 +56,12 @@ export default Vue.extend({
if (left + width - window.pageXOffset > window.innerWidth) { if (left + width - window.pageXOffset > window.innerWidth) {
left = window.innerWidth - width + window.pageXOffset; left = window.innerWidth - width + window.pageXOffset;
this.hukidasi = false; this.bubble = false;
} }
if (top + height - window.pageYOffset > window.innerHeight) { if (top + height - window.pageYOffset > window.innerHeight) {
top = window.innerHeight - height + window.pageYOffset; top = window.innerHeight - height + window.pageYOffset;
this.hukidasi = false; this.bubble = false;
} }
if (top < 0) { if (top < 0) {
@ -150,7 +150,7 @@ export default Vue.extend({
$balloon-size = 16px $balloon-size = 16px
&.hukidasi &.bubble
margin-top $balloon-size margin-top $balloon-size
transform-origin center -($balloon-size) transform-origin center -($balloon-size)

View File

@ -33,7 +33,16 @@ import * as autosize from 'autosize';
export default Vue.extend({ export default Vue.extend({
i18n: i18n('common/views/components/messaging-room.form.vue'), i18n: i18n('common/views/components/messaging-room.form.vue'),
props: ['user'], props: {
user: {
type: Object,
requird: false,
},
group: {
type: Object,
requird: false,
},
},
data() { data() {
return { return {
text: null, text: null,
@ -43,7 +52,7 @@ export default Vue.extend({
}, },
computed: { computed: {
draftId(): string { draftId(): string {
return this.user.id; return this.user ? 'user:' + this.user.id : 'group:' + this.group.id;
}, },
canSend(): boolean { canSend(): boolean {
return (this.text != null && this.text != '') || this.file != null; return (this.text != null && this.text != '') || this.file != null;
@ -159,7 +168,8 @@ export default Vue.extend({
send() { send() {
this.sending = true; this.sending = true;
this.$root.api('messaging/messages/create', { this.$root.api('messaging/messages/create', {
userId: this.user.id, userId: this.user ? this.user.id : undefined,
groupId: this.group ? this.group.id : undefined,
text: this.text ? this.text : undefined, text: this.text ? this.text : undefined,
fileId: this.file ? this.file.id : undefined fileId: this.file ? this.file.id : undefined
}).then(message => { }).then(message => {

View File

@ -23,7 +23,12 @@
<div></div> <div></div>
<mk-url-preview v-for="url in urls" :url="url" :key="url"/> <mk-url-preview v-for="url in urls" :url="url" :key="url"/>
<footer> <footer>
<span class="read" v-if="isMe && message.isRead">{{ $t('is-read') }}</span> <template v-if="isGroup">
<span class="read" v-if="message.reads.length > 0">{{ $t('is-read') }} {{ message.reads.length }}</span>
</template>
<template v-else>
<span class="read" v-if="isMe && message.isRead">{{ $t('is-read') }}</span>
</template>
<mk-time :time="message.createdAt"/> <mk-time :time="message.createdAt"/>
<template v-if="message.is_edited"><fa icon="pencil-alt"/></template> <template v-if="message.is_edited"><fa icon="pencil-alt"/></template>
</footer> </footer>
@ -42,6 +47,9 @@ export default Vue.extend({
props: { props: {
message: { message: {
required: true required: true
},
isGroup: {
required: false
} }
}, },
computed: { computed: {

View File

@ -4,14 +4,14 @@
@drop.prevent.stop="onDrop" @drop.prevent.stop="onDrop"
> >
<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" pulse fixed-width/>{{ $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"/>{{ user ? $t('not-talked-user') : $t('not-talked-group') }}</p>
<p class="no-history" v-if="!init && messages.length > 0 && !existMoreMessages"><fa :icon="faFlag"/>{{ $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>
<template v-for="(message, i) in _messages"> <template v-for="(message, i) in _messages">
<x-message :message="message" :key="message.id"/> <x-message :message="message" :key="message.id" :is-group="group != null"/>
<p class="date" v-if="i != messages.length - 1 && message._date != _messages[i + 1]._date"> <p class="date" v-if="i != messages.length - 1 && message._date != _messages[i + 1]._date">
<span>{{ _messages[i + 1]._datetext }}</span> <span>{{ _messages[i + 1]._datetext }}</span>
</p> </p>
@ -23,7 +23,7 @@
<button @click="onIndicatorClick"><i><fa :icon="faArrowCircleDown"/></i>{{ $t('new-message') }}</button> <button @click="onIndicatorClick"><i><fa :icon="faArrowCircleDown"/></i>{{ $t('new-message') }}</button>
</div> </div>
</transition> </transition>
<x-form :user="user" ref="form"/> <x-form :user="user" :group="group" ref="form"/>
</footer> </footer>
</div> </div>
</template> </template>
@ -34,17 +34,30 @@ import i18n from '../../../i18n';
import XMessage from './messaging-room.message.vue'; 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, faFlag } 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'),
components: { components: {
XMessage, XMessage,
XForm XForm
}, },
props: ['user', 'isNaked'], props: {
user: {
type: Object,
requird: false,
},
group: {
type: Object,
requird: false,
},
isNaked: {
type: Boolean,
requird: false,
},
},
data() { data() {
return { return {
@ -76,7 +89,10 @@ export default Vue.extend({
}, },
mounted() { mounted() {
this.connection = this.$root.stream.connectToChannel('messaging', { otherparty: this.user.id }); this.connection = this.$root.stream.connectToChannel('messaging', {
otherparty: this.user ? this.user.id : undefined,
group: this.group ? this.group.id : undefined,
});
this.connection.on('message', this.onMessage); this.connection.on('message', this.onMessage);
this.connection.on('read', this.onRead); this.connection.on('read', this.onRead);
@ -147,7 +163,8 @@ export default Vue.extend({
const max = this.existMoreMessages ? 20 : 10; const max = this.existMoreMessages ? 20 : 10;
this.$root.api('messaging/messages', { this.$root.api('messaging/messages', {
userId: this.user.id, userId: this.user ? this.user.id : undefined,
groupId: this.group ? this.group.id : undefined,
limit: max + 1, limit: max + 1,
untilId: this.existMoreMessages ? this.messages[0].id : undefined untilId: this.existMoreMessages ? this.messages[0].id : undefined
}).then(messages => { }).then(messages => {
@ -199,12 +216,21 @@ export default Vue.extend({
} }
}, },
onRead(ids) { onRead(x) {
if (!Array.isArray(ids)) ids = [ids]; if (this.user) {
for (const id of ids) { if (!Array.isArray(x)) x = [x];
if (this.messages.some(x => x.id == id)) { for (const id of x) {
const exist = this.messages.map(x => x.id).indexOf(id); if (this.messages.some(x => x.id == id)) {
this.messages[exist].isRead = true; const exist = this.messages.map(x => x.id).indexOf(id);
this.messages[exist].isRead = true;
}
}
} else if (this.group) {
for (const id of x.ids) {
if (this.messages.some(x => x.id == id)) {
const exist = this.messages.map(x => x.id).indexOf(id);
this.messages[exist].reads.push(x.userId);
}
} }
} }
}, },
@ -274,17 +300,13 @@ export default Vue.extend({
<style lang="stylus" scoped> <style lang="stylus" scoped>
.mk-messaging-room .mk-messaging-room
display flex
flex 1
flex-direction column
height 100%
background var(--messagingRoomBg) background var(--messagingRoomBg)
> .body > .body
width 100% width 100%
max-width 600px max-width 600px
margin 0 auto margin 0 auto
flex 1 min-height calc(100% - 103px)
> .init, > .init,
> .empty > .empty

View File

@ -21,36 +21,43 @@
</div> </div>
</div> </div>
<div class="history" v-if="messages.length > 0"> <div class="history" v-if="messages.length > 0">
<template> <a v-for="message in messages"
<a v-for="message in messages" class="user"
class="user" :href="message.groupId ? `/i/messaging/group/${message.groupId}` : `/i/messaging/${getAcct(isMe(message) ? message.recipient : message.user)}`"
:href="`/i/messaging/${getAcct(isMe(message) ? message.recipient : message.user)}`" :data-is-me="isMe(message)"
:data-is-me="isMe(message)" :data-is-read="message.groupId ? message.reads.includes($store.state.i.id) : message.isRead"
:data-is-read="message.isRead" @click.prevent="message.groupId ? navigateGroup(message.group) : navigate(isMe(message) ? message.recipient : message.user)"
@click.prevent="navigate(isMe(message) ? message.recipient : message.user)" :key="message.id"
:key="message.id" >
> <div>
<div> <mk-avatar class="avatar" :user="message.groupId ? message.user : isMe(message) ? message.recipient : message.user"/>
<mk-avatar class="avatar" :user="isMe(message) ? message.recipient : message.user"/> <header v-if="message.groupId">
<header> <span class="name">{{ message.group.name }}</span>
<span class="name"><mk-user-name :user="isMe(message) ? message.recipient : message.user"/></span> <mk-time :time="message.createdAt"/>
<span class="username">@{{ isMe(message) ? message.recipient : message.user | acct }}</span> </header>
<mk-time :time="message.createdAt"/> <header v-else>
</header> <span class="name"><mk-user-name :user="isMe(message) ? message.recipient : message.user"/></span>
<div class="body"> <span class="username">@{{ isMe(message) ? message.recipient : message.user | acct }}</span>
<p class="text"><span class="me" v-if="isMe(message)">{{ $t('you') }}:</span>{{ message.text }}</p> <mk-time :time="message.createdAt"/>
</div> </header>
<div class="body">
<p class="text"><span class="me" v-if="isMe(message)">{{ $t('you') }}:</span>{{ message.text }}</p>
</div> </div>
</a> </div>
</template> </a>
</div> </div>
<p class="no-history" v-if="!fetching && messages.length == 0">{{ $t('no-history') }}</p> <p class="no-history" v-if="!fetching && messages.length == 0">{{ $t('no-history') }}</p>
<p class="fetching" v-if="fetching"><fa icon="spinner" pulse fixed-width/>{{ $t('@.loading') }}<mk-ellipsis/></p> <p class="fetching" v-if="fetching"><fa icon="spinner" pulse fixed-width/>{{ $t('@.loading') }}<mk-ellipsis/></p>
<ui-margin>
<ui-button @click="startUser()"><fa :icon="faUser"/> {{ $t('start-with-user') }}</ui-button>
<ui-button @click="startGroup()"><fa :icon="faUsers"/> {{ $t('start-with-group') }}</ui-button>
</ui-margin>
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import Vue from 'vue'; import Vue from 'vue';
import { faUser, faUsers } from '@fortawesome/free-solid-svg-icons';
import i18n from '../../../i18n'; import i18n from '../../../i18n';
import getAcct from '../../../../../misc/acct/render'; import getAcct from '../../../../../misc/acct/render';
@ -73,7 +80,8 @@ export default Vue.extend({
messages: [], messages: [],
q: null, q: null,
result: [], result: [],
connection: null connection: null,
faUser, faUsers
}; };
}, },
mounted() { mounted() {
@ -82,9 +90,13 @@ export default Vue.extend({
this.connection.on('message', this.onMessage); this.connection.on('message', this.onMessage);
this.connection.on('read', this.onRead); this.connection.on('read', this.onRead);
this.$root.api('messaging/history').then(messages => { this.$root.api('messaging/history', { group: false }).then(userMessages => {
this.messages = messages; this.$root.api('messaging/history', { group: true }).then(groupMessages => {
this.fetching = false; const messages = userMessages.concat(groupMessages);
messages.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());
this.messages = messages;
this.fetching = false;
});
}); });
}, },
beforeDestroy() { beforeDestroy() {
@ -96,16 +108,27 @@ export default Vue.extend({
return message.userId == this.$store.state.i.id; return message.userId == this.$store.state.i.id;
}, },
onMessage(message) { onMessage(message) {
this.messages = this.messages.filter(m => !( if (message.recipientId) {
(m.recipientId == message.recipientId && m.userId == message.userId) || this.messages = this.messages.filter(m => !(
(m.recipientId == message.userId && m.userId == message.recipientId))); (m.recipientId == message.recipientId && m.userId == message.userId) ||
(m.recipientId == message.userId && m.userId == message.recipientId)));
this.messages.unshift(message); this.messages.unshift(message);
} else if (message.groupId) {
this.messages = this.messages.filter(m => m.groupId !== message.groupId);
this.messages.unshift(message);
}
}, },
onRead(ids) { onRead(ids) {
for (const id of ids) { for (const id of ids) {
const found = this.messages.find(m => m.id == id); const found = this.messages.find(m => m.id == id);
if (found) found.isRead = true; if (found) {
if (found.recipientId) {
found.isRead = true;
} else if (found.groupId) {
found.reads.push(this.$store.state.i.id);
}
}
} }
}, },
search() { search() {
@ -125,6 +148,9 @@ export default Vue.extend({
navigate(user) { navigate(user) {
this.$emit('navigate', user); this.$emit('navigate', user);
}, },
navigateGroup(group) {
this.$emit('navigateGroup', group);
},
onSearchKeydown(e) { onSearchKeydown(e) {
switch (e.which) { switch (e.which) {
case 9: // [TAB] case 9: // [TAB]
@ -161,6 +187,31 @@ export default Vue.extend({
(list.childNodes[i].nextElementSibling || list.childNodes[0]).focus(); (list.childNodes[i].nextElementSibling || list.childNodes[0]).focus();
break; break;
} }
},
async startUser() {
const { result: user } = await this.$root.dialog({
user: {
local: true
}
});
if (user == null) return;
this.navigate(user);
},
async startGroup() {
const groups1 = await this.$root.api('users/groups/owned');
const groups2 = await this.$root.api('users/groups/joined');
const { canceled, result: group } = await this.$root.dialog({
type: null,
title: this.$t('select-group'),
select: {
items: groups1.concat(groups2).map(group => ({
value: group, text: group.name
}))
},
showCancelButton: true
});
if (canceled) return;
this.navigateGroup(group);
} }
} }
}); });
@ -311,7 +362,6 @@ export default Vue.extend({
color rgba(#000, 0.3) color rgba(#000, 0.3)
> .history > .history
> a > a
display block display block
text-decoration none text-decoration none

View File

@ -175,7 +175,6 @@ export default Vue.component('misskey-flavored-markdown', {
props: { props: {
url: token.node.props.url, url: token.node.props.url,
rel: 'nofollow noopener', rel: 'nofollow noopener',
target: '_blank'
}, },
attrs: { attrs: {
style: 'color:var(--mfmUrl);' style: 'color:var(--mfmUrl);'

View File

@ -1,5 +1,5 @@
<template> <template>
<router-link :to="`/@${page.user.username}/pages/${page.name}`" class="vhpxefrj" tabindex="-1" :class="{ shadow: $store.state.device.useShadow, round: $store.state.device.roundedCorners }"> <router-link :to="`/@${page.user.username}/pages/${page.name}`" class="vhpxefrj" tabindex="-1">
<div class="thumbnail" v-if="page.eyeCatchingImage" :style="`background-image: url('${page.eyeCatchingImage.thumbnailUrl}')`"></div> <div class="thumbnail" v-if="page.eyeCatchingImage" :style="`background-image: url('${page.eyeCatchingImage.thumbnailUrl}')`"></div>
<article> <article>
<header> <header>
@ -32,16 +32,13 @@ export default Vue.extend({
display block display block
overflow hidden overflow hidden
width 100% width 100%
background var(--face) border solid var(--lineWidth) var(--urlPreviewBorder)
border-radius 4px
overflow hidden
&.round &:hover
border-radius 8px text-decoration none
border-color var(--urlPreviewBorderHover)
&.shadow
box-shadow 0 4px 16px rgba(#000, 0.1)
@media (min-width 500px)
box-shadow 0 8px 32px rgba(#000, 0.1)
> .thumbnail > .thumbnail
position absolute position absolute

View File

@ -1,5 +1,5 @@
<template> <template>
<div class="mk-poll-editor"> <div class="zmdxowus">
<p class="caution" v-if="choices.length < 2"> <p class="caution" v-if="choices.length < 2">
<fa icon="exclamation-triangle"/>{{ $t('no-only-one-choice') }} <fa icon="exclamation-triangle"/>{{ $t('no-only-one-choice') }}
</p> </p>
@ -89,9 +89,7 @@ export default Vue.extend({
get() { get() {
const at = () => { const at = () => {
const [date] = moment(this.atDate).toISOString().split('T'); return moment(`${this.atDate} ${this.atTime}`).valueOf();
const [hour, minute] = this.atTime.split(':');
return moment(`${date}T${hour}:${minute}Z`).valueOf();
}; };
const after = () => { const after = () => {
@ -134,7 +132,7 @@ export default Vue.extend({
</script> </script>
<style lang="stylus" scoped> <style lang="stylus" scoped>
.mk-poll-editor .zmdxowus
padding 8px padding 8px
> .caution > .caution

View File

@ -16,7 +16,7 @@
<button @click="react('pudding')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="10" :title="$t('@.reactions.pudding')" v-particle><mk-reaction-icon reaction="pudding"/></button> <button @click="react('pudding')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="10" :title="$t('@.reactions.pudding')" v-particle><mk-reaction-icon reaction="pudding"/></button>
</div> </div>
<div v-if="enableEmojiReaction" class="text"> <div v-if="enableEmojiReaction" class="text">
<input v-model="text" placeholder="または絵文字を入力" @keyup.enter="reactText" @input="tryReactText" v-autocomplete="{ model: 'text' }"> <input v-model="text" :placeholder="$t('input-reaction-placeholder')" @keyup.enter="reactText" @input="tryReactText" v-autocomplete="{ model: 'text' }">
</div> </div>
</div> </div>
</div> </div>

View File

@ -131,6 +131,13 @@
</section> </section>
</section> </section>
<section>
<header>{{ $t('@._settings.sync') }}</header>
<ui-input v-if="$root.isMobile" v-model="mobileHomeProfile" :datalist="Object.keys($store.state.settings.mobileHomeProfiles)">{{ $t('@._settings.home-profile') }}</ui-input>
<ui-input v-else v-model="homeProfile" :datalist="Object.keys($store.state.settings.homeProfiles)">{{ $t('@._settings.home-profile') }}</ui-input>
<ui-input v-model="deckProfile" :datalist="Object.keys($store.state.settings.deckProfiles)">{{ $t('@._settings.deck-profile') }}</ui-input>
</section>
<section> <section>
<header>{{ $t('@._settings.web-search-engine') }}</header> <header>{{ $t('@._settings.web-search-engine') }}</header>
<ui-input v-model="webSearchEngine">{{ $t('@._settings.web-search-engine') }}<template #desc>{{ $t('@._settings.web-search-engine-desc') }}</template></ui-input> <ui-input v-model="webSearchEngine">{{ $t('@._settings.web-search-engine') }}<template #desc>{{ $t('@._settings.web-search-engine-desc') }}</template></ui-input>
@ -472,13 +479,13 @@ export default Vue.extend({
}, },
games_reversi_showBoardLabels: { games_reversi_showBoardLabels: {
get() { return this.$store.state.settings.games.reversi.showBoardLabels; }, get() { return this.$store.state.settings.gamesReversiShowBoardLabels; },
set(value) { this.$store.dispatch('settings/set', { key: 'games.reversi.showBoardLabels', value }); } set(value) { this.$store.dispatch('settings/set', { key: 'gamesReversiShowBoardLabels', value }); }
}, },
games_reversi_useAvatarStones: { games_reversi_useAvatarStones: {
get() { return this.$store.state.settings.games.reversi.useAvatarStones; }, get() { return this.$store.state.settings.gamesReversiUseAvatarStones; },
set(value) { this.$store.dispatch('settings/set', { key: 'games.reversi.useAvatarStones', value }); } set(value) { this.$store.dispatch('settings/set', { key: 'gamesReversiUseAvatarStones', value }); }
}, },
disableAnimatedMfm: { disableAnimatedMfm: {
@ -500,6 +507,21 @@ export default Vue.extend({
get() { return this.$store.state.device.mobileNotificationPosition; }, get() { return this.$store.state.device.mobileNotificationPosition; },
set(value) { this.$store.commit('device/set', { key: 'mobileNotificationPosition', value }); } set(value) { this.$store.commit('device/set', { key: 'mobileNotificationPosition', value }); }
}, },
homeProfile: {
get() { return this.$store.state.device.homeProfile; },
set(value) { this.$store.commit('device/set', { key: 'homeProfile', value }); }
},
mobileHomeProfile: {
get() { return this.$store.state.device.mobileHomeProfile; },
set(value) { this.$store.commit('device/set', { key: 'mobileHomeProfile', value }); }
},
deckProfile: {
get() { return this.$store.state.device.deckProfile; },
set(value) { this.$store.commit('device/set', { key: 'deckProfile', value }); }
},
}, },
created() { created() {
this.$root.getMeta().then(meta => { this.$root.getMeta().then(meta => {

View File

@ -43,7 +43,7 @@
</i18n> </i18n>
</ui-switch> </ui-switch>
<div v-if="meta.enableRecaptcha" class="g-recaptcha" :data-sitekey="meta.recaptchaSiteKey" style="margin: 16px 0;"></div> <div v-if="meta.enableRecaptcha" class="g-recaptcha" :data-sitekey="meta.recaptchaSiteKey" style="margin: 16px 0;"></div>
<ui-button type="submit" :disabled="!(meta.ToSUrl ? ToSAgreement : true)">{{ $t('create') }}</ui-button> <ui-button type="submit" :disabled="!(meta.ToSUrl ? ToSAgreement : true) || passwordRetypeState == 'not-match'">{{ $t('create') }}</ui-button>
</template> </template>
</form> </form>
</template> </template>

View File

@ -113,7 +113,7 @@ export default Vue.extend({
padding 8px 10px padding 8px 10px
text-align center text-align center
font-weight normal font-weight normal
font-size 16px font-size 14px
line-height 24px line-height 24px
border none border none
outline none outline none

View File

@ -0,0 +1,15 @@
<template>
<div class="evrzpitu"></div>
</template>
<script lang="ts">
import Vue from 'vue';
export default Vue.extend({});
</script>
<style lang="stylus" scoped>
.evrzpitu
margin 16px 0
border-bottom solid var(--lineWidth) var(--faceDivider)
</style>

View File

@ -210,17 +210,25 @@ export default Vue.extend({
} }
this.$nextTick(() => { this.$nextTick(() => {
if (this.$refs.prefix) { // このコンポーネントが作成された時、非表示状態である場合がある
this.$refs.label.style.left = (this.$refs.prefix.offsetLeft + this.$refs.prefix.offsetWidth) + 'px'; // 非表示状態だと要素の幅などは0になってしまうので、定期的に計算する
if (this.$refs.prefix.offsetWidth) { const clock = setInterval(() => {
this.$refs.input.style.paddingLeft = this.$refs.prefix.offsetWidth + 'px'; if (this.$refs.prefix) {
this.$refs.label.style.left = (this.$refs.prefix.offsetLeft + this.$refs.prefix.offsetWidth) + 'px';
if (this.$refs.prefix.offsetWidth) {
this.$refs.input.style.paddingLeft = this.$refs.prefix.offsetWidth + 'px';
}
} }
} if (this.$refs.suffix) {
if (this.$refs.suffix) { if (this.$refs.suffix.offsetWidth) {
if (this.$refs.suffix.offsetWidth) { this.$refs.input.style.paddingRight = this.$refs.suffix.offsetWidth + 'px';
this.$refs.input.style.paddingRight = this.$refs.suffix.offsetWidth + 'px'; }
} }
} }, 100);
this.$once('hook:beforeDestroy', () => {
clearInterval(clock);
});
}); });
this.$on('keydown', (e: KeyboardEvent) => { this.$on('keydown', (e: KeyboardEvent) => {

View File

@ -0,0 +1,16 @@
<template>
<div class="zdcrxcne">
<slot></slot>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
export default Vue.extend({});
</script>
<style lang="stylus" scoped>
.zdcrxcne
margin 16px
</style>

View File

@ -0,0 +1,36 @@
<template>
<div class="mwermpua" v-if="!fetching">
<sequential-entrance animation="entranceFromTop" delay="25">
<slot :items="items"></slot>
</sequential-entrance>
<div class="more" v-if="more">
<ui-button @click="fetchMore()">{{ $t('@.load-more') }}</ui-button>
</div>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import paging from '../../../scripts/paging';
export default Vue.extend({
mixins: [
paging({
captureWindowScroll: false,
}),
],
props: {
pagination: {
required: true
},
},
});
</script>
<style lang="stylus" scoped>
.mwermpua
> .more
margin-top 16px
</style>

View File

@ -9,7 +9,7 @@
</blockquote> </blockquote>
</div> </div>
<div v-else class="mk-url-preview"> <div v-else class="mk-url-preview">
<a :class="{ mini: narrow, compact }" :href="url" rel="nofollow noopener" target="_blank" :title="url" v-if="!fetching"> <component :is="hasRoute ? 'router-link' : 'a'" :class="{ mini: narrow, compact }" :[attr]="hasRoute ? url.substr(local.length) : url" rel="nofollow noopener" :target="target" :title="url" v-if="!fetching">
<div class="thumbnail" v-if="thumbnail" :style="`background-image: url('${thumbnail}')`"> <div class="thumbnail" v-if="thumbnail" :style="`background-image: url('${thumbnail}')`">
<button v-if="!playerEnabled && player.url" @click.prevent="playerEnabled = true" :title="$t('enable-player')"><fa :icon="['far', 'play-circle']"/></button> <button v-if="!playerEnabled && player.url" @click.prevent="playerEnabled = true" :title="$t('enable-player')"><fa :icon="['far', 'play-circle']"/></button>
</div> </div>
@ -23,17 +23,18 @@
<p :title="sitename">{{ sitename }}</p> <p :title="sitename">{{ sitename }}</p>
</footer> </footer>
</article> </article>
</a> </component>
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import Vue from 'vue'; import Vue from 'vue';
import i18n from '../../../i18n'; import i18n from '../../../i18n';
import { url as misskeyUrl } from '../../../config'; import { url as local, lang } from '../../../config';
export default Vue.extend({ export default Vue.extend({
i18n: i18n('common/views/components/url-preview.vue'), i18n: i18n('common/views/components/url-preview.vue'),
props: { props: {
url: { url: {
type: String, type: String,
@ -60,7 +61,13 @@ export default Vue.extend({
}, },
data() { data() {
const isSelf = this.url.startsWith(local);
const hasRoute =
this.url.substr(local.length).startsWith('/@') ||
this.url.substr(local.length).startsWith('/notes/') ||
this.url.substr(local.length).startsWith('/pages/');
return { return {
local,
fetching: true, fetching: true,
title: null, title: null,
description: null, description: null,
@ -74,15 +81,18 @@ export default Vue.extend({
}, },
tweetUrl: null, tweetUrl: null,
playerEnabled: false, playerEnabled: false,
misskeyUrl, self: isSelf,
hasRoute: hasRoute,
attr: hasRoute ? 'to' : 'href',
target: hasRoute ? null : '_blank'
}; };
}, },
created() { created() {
const url = new URL(this.url); const requestUrl = new URL(this.url);
if (this.detail && url.hostname == 'twitter.com' && /^\/.+\/status(es)?\/\d+/.test(url.pathname)) { if (this.detail && requestUrl.hostname == 'twitter.com' && /^\/.+\/status(es)?\/\d+/.test(requestUrl.pathname)) {
this.tweetUrl = url; this.tweetUrl = requestUrl;
const twttr = (window as any).twttr || {}; const twttr = (window as any).twttr || {};
const loadTweet = () => twttr.widgets.load(this.$refs.tweet); const loadTweet = () => twttr.widgets.load(this.$refs.tweet);
@ -103,10 +113,15 @@ export default Vue.extend({
return; return;
} }
if (url.hostname === 'music.youtube.com') if (requestUrl.hostname === 'music.youtube.com') {
url.hostname = 'youtube.com'; requestUrl.hostname = 'youtube.com';
}
fetch(`/url?url=${encodeURIComponent(this.url)}`).then(res => { const requestLang = (lang || 'ja-JP').replace('ja-KS', 'ja-JP');
requestUrl.hash = '';
fetch(`/url?url=${encodeURIComponent(requestUrl.href)}&lang=${requestLang}`).then(res => {
res.json().then(info => { res.json().then(info => {
if (info.url == null) return; if (info.url == null) return;
this.title = info.title; this.title = info.title;

View File

@ -1,29 +1,42 @@
<template> <template>
<a class="mk-url" :href="url" :rel="rel" :target="target"> <component :is="hasRoute ? 'router-link' : 'a'" class="mk-url" :[attr]="hasRoute ? url.substr(local.length) : url" :rel="rel" :target="target">
<span class="schema">{{ schema }}//</span> <template v-if="!self">
<span class="hostname">{{ hostname }}</span> <span class="schema">{{ schema }}//</span>
<span class="port" v-if="port != ''">:{{ port }}</span> <span class="hostname">{{ hostname }}</span>
<span class="pathname" v-if="pathname != ''">{{ pathname }}</span> <span class="port" v-if="port != ''">:{{ port }}</span>
</template>
<span class="pathname" v-if="pathname != ''">{{ self ? pathname.substr(1) : pathname }}</span>
<span class="query">{{ query }}</span> <span class="query">{{ query }}</span>
<span class="hash">{{ hash }}</span> <span class="hash">{{ hash }}</span>
<fa icon="external-link-square-alt"/> <fa icon="external-link-square-alt" v-if="target === '_blank'"/>
</a> </component>
</template> </template>
<script lang="ts"> <script lang="ts">
import Vue from 'vue'; import Vue from 'vue';
import { toUnicode as decodePunycode } from 'punycode'; import { toUnicode as decodePunycode } from 'punycode';
import { url as local } from '../../../config';
export default Vue.extend({ export default Vue.extend({
props: ['url', 'rel', 'target'], props: ['url', 'rel'],
data() { data() {
const isSelf = this.url.startsWith(local);
const hasRoute = isSelf && (
this.url.substr(local.length).startsWith('/@') ||
this.url.substr(local.length).startsWith('/notes/') ||
this.url.substr(local.length).startsWith('/pages/'));
return { return {
local,
schema: null, schema: null,
hostname: null, hostname: null,
port: null, port: null,
pathname: null, pathname: null,
query: null, query: null,
hash: null hash: null,
self: isSelf,
hasRoute: hasRoute,
attr: hasRoute ? 'to' : 'href',
target: hasRoute ? null : '_blank'
}; };
}, },
created() { created() {

View File

@ -2,13 +2,13 @@
<ui-container :body-togglable="true"> <ui-container :body-togglable="true">
<template #header><slot></slot></template> <template #header><slot></slot></template>
<mk-error v-if="!fetching && !inited" @retry="init()"/> <mk-error v-if="error" @retry="init()"/>
<div class="efvhhmdq" :class="{ iconOnly }" v-size="[{ lt: 500, class: 'narrow' }]"> <div class="efvhhmdq" :class="{ iconOnly }" v-size="[{ lt: 500, class: 'narrow' }]">
<div class="no-users" v-if="inited && us.length == 0"> <div class="no-users" v-if="empty">
<p>{{ $t('no-users') }}</p> <p>{{ $t('no-users') }}</p>
</div> </div>
<div class="user" v-for="user in us" :key="user.id"> <div class="user" v-for="user in users" :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">
@ -21,8 +21,8 @@
<mk-follow-button class="follow-button" v-if="$store.getters.isSignedIn && user.id != $store.state.i.id" :user="user" mini/> <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: moreFetching }" v-if="more" @click="fetchMore()" :disabled="moreFetching">
<template v-if="fetchingMoreUsers"><fa icon="spinner" pulse fixed-width/></template>{{ fetchingMoreUsers ? $t('@.loading') : $t('@.load-more') }} <template v-if="moreFetching"><fa icon="spinner" pulse fixed-width/></template>{{ moreFetching ? $t('@.loading') : $t('@.load-more') }}
</button> </button>
</div> </div>
</ui-container> </ui-container>
@ -31,60 +31,31 @@
<script lang="ts"> <script lang="ts">
import Vue from 'vue'; import Vue from 'vue';
import i18n from '../../../i18n'; import i18n from '../../../i18n';
import paging from '../../../common/scripts/paging';
export default Vue.extend({ export default Vue.extend({
i18n: i18n('common/views/components/user-list.vue'), i18n: i18n('common/views/components/user-list.vue'),
mixins: [
paging({}),
],
props: { props: {
makePromise: { pagination: {
required: true required: true
}, },
extract: {
required: false
},
iconOnly: { iconOnly: {
type: Boolean, type: Boolean,
default: false default: false
} }
}, },
data() { computed: {
return { users() {
fetching: true, return this.extract ? this.extract(this.items) : this.items;
fetchingMoreUsers: false,
us: [],
inited: false,
more: false
};
},
created() {
this.init();
},
methods: {
async init() {
this.fetching = true;
await (this.makePromise()).then(x => {
if (Array.isArray(x)) {
this.us = x;
} else {
this.us = x.users;
this.cursor = x.cursor;
}
this.inited = true;
this.fetching = false;
}, e => {
this.fetching = false;
});
},
async fetchMoreUsers() {
this.fetchingMoreUsers = true;
await (this.makePromise(this.cursor)).then(x => {
this.us = this.us.concat(x.users);
this.cursor = x.cursor;
this.fetchingMoreUsers = false;
}, e => {
this.fetchingMoreUsers = false;
});
} }
} }
}); });

View File

@ -1,95 +0,0 @@
<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: name }) => {
if (canceled) return;
const list = await this.$root.api('users/lists/create', {
name
});
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

@ -0,0 +1,45 @@
<template>
<x-column>
<template #header>
<fa v-if="icon" :icon="icon"/>{{ title }}
</template>
<div>
<component :is="component" @init="init" v-bind="$attrs"/>
</div>
</x-column>
</template>
<script lang="ts">
import Vue from 'vue';
import XColumn from './deck.column.vue';
export default Vue.extend({
components: {
XColumn,
},
props: {
component: {
required: true
}
},
data() {
return {
title: null,
icon: null,
};
},
mounted() {
},
methods: {
init(v) {
this.title = v.title;
this.icon = v.icon;
}
}
});
</script>

View File

@ -146,7 +146,8 @@ export default Vue.extend({
toggleActive() { toggleActive() {
if (!this.isStacked) return; if (!this.isStacked) return;
const vms = this.$store.state.device.deck.layout.find(ids => ids.indexOf(this.column.id) != -1).map(id => this.getColumnVm(id)); const deck = this.$store.state.device.deckProfile ? this.$store.state.settings.deckProfiles[this.$store.state.device.deckProfile] : this.$store.state.device.deck;
const vms = deck.layout.find(ids => ids.indexOf(this.column.id) != -1).map(id => this.getColumnVm(id));
if (this.active && countIf(vm => vm.$el.classList.contains('active'), vms) == 1) return; if (this.active && countIf(vm => vm.$el.classList.contains('active'), vms) == 1) return;
this.active = !this.active; this.active = !this.active;
}, },
@ -179,50 +180,50 @@ export default Vue.extend({
} }
}).then(({ canceled, result: name }) => { }).then(({ canceled, result: name }) => {
if (canceled) return; if (canceled) return;
this.$store.commit('device/renameDeckColumn', { id: this.column.id, name }); this.$store.commit('renameDeckColumn', { id: this.column.id, name });
}); });
} }
}, null, { }, null, {
icon: 'arrow-left', icon: 'arrow-left',
text: this.$t('swap-left'), text: this.$t('swap-left'),
action: () => { action: () => {
this.$store.commit('device/swapLeftDeckColumn', this.column.id); this.$store.commit('swapLeftDeckColumn', this.column.id);
} }
}, { }, {
icon: 'arrow-right', icon: 'arrow-right',
text: this.$t('swap-right'), text: this.$t('swap-right'),
action: () => { action: () => {
this.$store.commit('device/swapRightDeckColumn', this.column.id); this.$store.commit('swapRightDeckColumn', this.column.id);
} }
}, this.isStacked ? { }, this.isStacked ? {
icon: faArrowUp, icon: faArrowUp,
text: this.$t('swap-up'), text: this.$t('swap-up'),
action: () => { action: () => {
this.$store.commit('device/swapUpDeckColumn', this.column.id); this.$store.commit('swapUpDeckColumn', this.column.id);
} }
} : undefined, this.isStacked ? { } : undefined, this.isStacked ? {
icon: faArrowDown, icon: faArrowDown,
text: this.$t('swap-down'), text: this.$t('swap-down'),
action: () => { action: () => {
this.$store.commit('device/swapDownDeckColumn', this.column.id); this.$store.commit('swapDownDeckColumn', this.column.id);
} }
} : undefined, null, { } : undefined, null, {
icon: ['far', 'window-restore'], icon: ['far', 'window-restore'],
text: this.$t('stack-left'), text: this.$t('stack-left'),
action: () => { action: () => {
this.$store.commit('device/stackLeftDeckColumn', this.column.id); this.$store.commit('stackLeftDeckColumn', this.column.id);
} }
}, this.isStacked ? { }, this.isStacked ? {
icon: faWindowMaximize, icon: faWindowMaximize,
text: this.$t('pop-right'), text: this.$t('pop-right'),
action: () => { action: () => {
this.$store.commit('device/popRightDeckColumn', this.column.id); this.$store.commit('popRightDeckColumn', this.column.id);
} }
} : undefined, null, { } : undefined, null, {
icon: ['far', 'trash-alt'], icon: ['far', 'trash-alt'],
text: this.$t('remove'), text: this.$t('remove'),
action: () => { action: () => {
this.$store.commit('device/removeDeckColumn', this.column.id); this.$store.commit('removeDeckColumn', this.column.id);
} }
}]; }];
@ -306,7 +307,7 @@ export default Vue.extend({
const id = e.dataTransfer.getData('mk-deck-column'); const id = e.dataTransfer.getData('mk-deck-column');
if (id != null && id != '') { if (id != null && id != '') {
this.$store.commit('device/swapDeckColumn', { this.$store.commit('swapDeckColumn', {
a: this.column.id, a: this.column.id,
b: id b: id
}); });

View File

@ -2,7 +2,7 @@
<x-column :name="name" :column="column" :is-stacked="isStacked"> <x-column :name="name" :column="column" :is-stacked="isStacked">
<template #header><fa :icon="['far', 'envelope']"/>{{ name }}</template> <template #header><fa :icon="['far', 'envelope']"/>{{ name }}</template>
<x-direct/> <x-notes ref="timeline" :pagination="pagination" @inited="() => $emit('loaded')"/>
</x-column> </x-column>
</template> </template>
@ -10,13 +10,14 @@
import Vue from 'vue'; import Vue from 'vue';
import i18n from '../../../i18n'; import i18n from '../../../i18n';
import XColumn from './deck.column.vue'; import XColumn from './deck.column.vue';
import XDirect from './deck.direct.vue'; import XNotes from './deck.notes.vue';
export default Vue.extend({ export default Vue.extend({
i18n: i18n(), i18n: i18n(),
components: { components: {
XColumn, XColumn,
XDirect XNotes
}, },
props: { props: {
@ -30,6 +31,22 @@ export default Vue.extend({
} }
}, },
data() {
return {
connection: null,
pagination: {
endpoint: 'notes/mentions',
limit: 10,
params: {
includeMyRenotes: this.$store.state.settings.showMyRenotes,
includeRenotedMyNotes: this.$store.state.settings.showRenotedMyNotes,
includeLocalRenotes: this.$store.state.settings.showLocalRenotes,
visibility: 'specified'
}
}
};
},
computed: { computed: {
name(): string { name(): string {
if (this.column.name) return this.column.name; if (this.column.name) return this.column.name;
@ -37,9 +54,25 @@ export default Vue.extend({
} }
}, },
mounted() {
this.connection = this.$root.stream.useSharedConnection('main');
this.connection.on('mention', this.onNote);
},
beforeDestroy() {
this.connection.dispose();
},
methods: { methods: {
onNote(note) {
// Prepend a note
if (note.visibility == 'specified') {
(this.$refs.timeline as any).prepend(note);
}
},
focus() { focus() {
this.$refs.tl.focus(); this.$refs.timeline.focus();
} }
} }
}); });

View File

@ -1,65 +0,0 @@
<template>
<x-notes ref="timeline" :make-promise="makePromise" @inited="() => $emit('loaded')"/>
</template>
<script lang="ts">
import Vue from 'vue';
import XNotes from './deck.notes.vue';
const fetchLimit = 10;
export default Vue.extend({
components: {
XNotes
},
data() {
return {
connection: null,
makePromise: cursor => this.$root.api('notes/mentions', {
limit: fetchLimit + 1,
untilId: cursor ? cursor : undefined,
includeMyRenotes: this.$store.state.settings.showMyRenotes,
includeRenotedMyNotes: this.$store.state.settings.showRenotedMyNotes,
includeLocalRenotes: this.$store.state.settings.showLocalRenotes,
visibility: 'specified'
}).then(notes => {
if (notes.length == fetchLimit + 1) {
notes.pop();
return {
notes: notes,
more: true
};
} else {
return {
notes: notes,
more: false
};
}
})
};
},
mounted() {
this.connection = this.$root.stream.useSharedConnection('main');
this.connection.on('mention', this.onNote);
},
beforeDestroy() {
this.connection.dispose();
},
methods: {
onNote(note) {
// Prepend a note
if (note.visibility == 'specified') {
(this.$refs.timeline as any).prepend(note);
}
},
focus() {
this.$refs.timeline.focus();
}
}
});
</script>

View File

@ -1,34 +0,0 @@
<template>
<x-column>
<template #header>
<fa :icon="faHashtag"/>{{ $t('@.explore') }}
</template>
<div>
<x-explore v-bind="$attrs"/>
</div>
</x-column>
</template>
<script lang="ts">
import Vue from 'vue';
import i18n from '../../../i18n';
import XColumn from './deck.column.vue';
import XExplore from '../../../common/views/pages/explore.vue';
import { faHashtag } from '@fortawesome/free-solid-svg-icons';
export default Vue.extend({
i18n: i18n(),
components: {
XColumn,
XExplore,
},
data() {
return {
faHashtag
};
}
});
</script>

View File

@ -1,58 +0,0 @@
<template>
<x-column>
<template #header>
<fa :icon="['fa', 'star']"/>{{ $t('@.favorites') }}
</template>
<div>
<x-notes ref="timeline" :make-promise="makePromise" @inited="() => $emit('loaded')"/>
</div>
</x-column>
</template>
<script lang="ts">
import Vue from 'vue';
import i18n from '../../../i18n';
import XColumn from './deck.column.vue';
import XNotes from './deck.notes.vue';
const fetchLimit = 10;
export default Vue.extend({
i18n: i18n(),
components: {
XColumn,
XNotes,
},
data() {
return {
makePromise: cursor => this.$root.api('i/favorites', {
limit: fetchLimit + 1,
untilId: cursor ? cursor : undefined,
}).then(notes => {
notes = notes.map(x => x.note);
if (notes.length == fetchLimit + 1) {
notes.pop();
return {
notes: notes,
more: true
};
} else {
return {
notes: notes,
more: false
};
}
})
};
},
methods: {
focus() {
this.$refs.timeline.focus();
}
}
});
</script>

View File

@ -1,46 +0,0 @@
<template>
<x-column>
<template #header>
<fa :icon="faNewspaper"/>{{ $t('@.featured-notes') }}
</template>
<div>
<x-notes ref="timeline" :make-promise="makePromise" @inited="() => $emit('loaded')"/>
</div>
</x-column>
</template>
<script lang="ts">
import Vue from 'vue';
import i18n from '../../../i18n';
import XColumn from './deck.column.vue';
import XNotes from './deck.notes.vue';
import { faNewspaper } from '@fortawesome/free-solid-svg-icons';
export default Vue.extend({
i18n: i18n(),
components: {
XColumn,
XNotes,
},
data() {
return {
faNewspaper,
makePromise: cursor => this.$root.api('notes/featured', {
limit: 30,
}).then(notes => {
notes.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());
return notes;
})
};
},
methods: {
focus() {
this.$refs.timeline.focus();
}
}
});
</script>

View File

@ -1,13 +1,11 @@
<template> <template>
<x-notes ref="timeline" :make-promise="makePromise" @inited="() => $emit('loaded')"/> <x-notes ref="timeline" :pagination="pagination" @inited="() => $emit('loaded')"/>
</template> </template>
<script lang="ts"> <script lang="ts">
import Vue from 'vue'; import Vue from 'vue';
import XNotes from './deck.notes.vue'; import XNotes from './deck.notes.vue';
const fetchLimit = 10;
export default Vue.extend({ export default Vue.extend({
components: { components: {
XNotes XNotes
@ -28,28 +26,18 @@ export default Vue.extend({
data() { data() {
return { return {
connection: null, connection: null,
makePromise: cursor => this.$root.api('notes/search-by-tag', { pagination: {
limit: fetchLimit + 1, endpoint: 'notes/search-by-tag',
untilId: cursor ? cursor : undefined, limit: 10,
withFiles: this.mediaOnly, params: init => ({
includeMyRenotes: this.$store.state.settings.showMyRenotes, untilDate: init ? undefined : (this.date ? this.date.getTime() : undefined),
includeRenotedMyNotes: this.$store.state.settings.showRenotedMyNotes, withFiles: this.mediaOnly,
includeLocalRenotes: this.$store.state.settings.showLocalRenotes, includeMyRenotes: this.$store.state.settings.showMyRenotes,
query: this.tagTl.query includeRenotedMyNotes: this.$store.state.settings.showRenotedMyNotes,
}).then(notes => { includeLocalRenotes: this.$store.state.settings.showLocalRenotes,
if (notes.length == fetchLimit + 1) { query: this.tagTl.query
notes.pop(); })
return { }
notes: notes,
more: true
};
} else {
return {
notes: notes,
more: false
};
}
})
}; };
}, },

View File

@ -1,13 +1,11 @@
<template> <template>
<x-notes ref="timeline" :make-promise="makePromise" @inited="() => $emit('loaded')"/> <x-notes ref="timeline" :pagination="pagination" @inited="() => $emit('loaded')"/>
</template> </template>
<script lang="ts"> <script lang="ts">
import Vue from 'vue'; import Vue from 'vue';
import XNotes from './deck.notes.vue'; import XNotes from './deck.notes.vue';
const fetchLimit = 10;
export default Vue.extend({ export default Vue.extend({
components: { components: {
XNotes XNotes
@ -28,28 +26,18 @@ export default Vue.extend({
data() { data() {
return { return {
connection: null, connection: null,
makePromise: cursor => this.$root.api('notes/user-list-timeline', { pagination: {
listId: this.list.id, endpoint: 'notes/user-list-timeline',
limit: fetchLimit + 1, limit: 10,
untilId: cursor ? cursor : undefined, params: init => ({
withFiles: this.mediaOnly, listId: this.list.id,
includeMyRenotes: this.$store.state.settings.showMyRenotes, untilDate: init ? undefined : (this.date ? this.date.getTime() : undefined),
includeRenotedMyNotes: this.$store.state.settings.showRenotedMyNotes, withFiles: this.mediaOnly,
includeLocalRenotes: this.$store.state.settings.showLocalRenotes includeMyRenotes: this.$store.state.settings.showMyRenotes,
}).then(notes => { includeRenotedMyNotes: this.$store.state.settings.showRenotedMyNotes,
if (notes.length == fetchLimit + 1) { includeLocalRenotes: this.$store.state.settings.showLocalRenotes
notes.pop(); })
return { }
notes: notes,
more: true
};
} else {
return {
notes: notes,
more: false
};
}
})
}; };
}, },

View File

@ -2,7 +2,7 @@
<x-column :name="name" :column="column" :is-stacked="isStacked"> <x-column :name="name" :column="column" :is-stacked="isStacked">
<template #header><fa icon="at"/>{{ name }}</template> <template #header><fa icon="at"/>{{ name }}</template>
<x-mentions ref="tl"/> <x-notes ref="timeline" :pagination="pagination" @inited="() => $emit('loaded')"/>
</x-column> </x-column>
</template> </template>
@ -10,13 +10,14 @@
import Vue from 'vue'; import Vue from 'vue';
import i18n from '../../../i18n'; import i18n from '../../../i18n';
import XColumn from './deck.column.vue'; import XColumn from './deck.column.vue';
import XMentions from './deck.mentions.vue'; import XNotes from './deck.notes.vue';
export default Vue.extend({ export default Vue.extend({
i18n: i18n(), i18n: i18n(),
components: { components: {
XColumn, XColumn,
XMentions XNotes
}, },
props: { props: {
@ -30,6 +31,22 @@ export default Vue.extend({
} }
}, },
data() {
return {
connection: null,
pagination: {
endpoint: 'notes/mentions',
limit: 10,
params: init => ({
untilDate: init ? undefined : (this.date ? this.date.getTime() : undefined),
includeMyRenotes: this.$store.state.settings.showMyRenotes,
includeRenotedMyNotes: this.$store.state.settings.showRenotedMyNotes,
includeLocalRenotes: this.$store.state.settings.showLocalRenotes
})
}
};
},
computed: { computed: {
name(): string { name(): string {
if (this.column.name) return this.column.name; if (this.column.name) return this.column.name;
@ -37,9 +54,22 @@ export default Vue.extend({
} }
}, },
mounted() {
this.connection = this.$root.stream.useSharedConnection('main');
this.connection.on('mention', this.onNote);
},
beforeDestroy() {
this.connection.dispose();
},
methods: { methods: {
onNote(note) {
(this.$refs.timeline as any).prepend(note);
},
focus() { focus() {
this.$refs.tl.focus(); this.$refs.timeline.focus();
} }
} }
}); });

View File

@ -1,61 +0,0 @@
<template>
<x-notes ref="timeline" :make-promise="makePromise" @inited="() => $emit('loaded')"/>
</template>
<script lang="ts">
import Vue from 'vue';
import XNotes from './deck.notes.vue';
const fetchLimit = 10;
export default Vue.extend({
components: {
XNotes
},
data() {
return {
connection: null,
makePromise: cursor => this.$root.api('notes/mentions', {
limit: fetchLimit + 1,
untilId: cursor ? cursor : undefined,
includeMyRenotes: this.$store.state.settings.showMyRenotes,
includeRenotedMyNotes: this.$store.state.settings.showRenotedMyNotes,
includeLocalRenotes: this.$store.state.settings.showLocalRenotes
}).then(notes => {
if (notes.length == fetchLimit + 1) {
notes.pop();
return {
notes: notes,
more: true
};
} else {
return {
notes: notes,
more: false
};
}
})
};
},
mounted() {
this.connection = this.$root.stream.useSharedConnection('main');
this.connection.on('mention', this.onNote);
},
beforeDestroy() {
this.connection.dispose();
},
methods: {
onNote(note) {
(this.$refs.timeline as any).prepend(note);
},
focus() {
this.$refs.timeline.focus();
}
}
});
</script>

View File

@ -1,8 +1,8 @@
<template> <template>
<div class="eamppglmnmimdhrlzhplwpvyeaqmmhxu"> <div class="eamppglmnmimdhrlzhplwpvyeaqmmhxu">
<div class="empty" v-if="notes.length == 0 && !fetching && inited">{{ $t('@.no-notes') }}</div> <div class="empty" v-if="empty">{{ $t('@.no-notes') }}</div>
<mk-error v-if="!fetching && !inited" @retry="init()"/> <mk-error v-if="error" @retry="init()"/>
<div class="placeholder" v-if="fetching"> <div class="placeholder" v-if="fetching">
<template v-for="i in 10"> <template v-for="i in 10">
@ -16,7 +16,6 @@
<mk-note <mk-note
:note="note" :note="note"
:key="note.id" :key="note.id"
@update:note="onNoteUpdated(i, $event)"
:compact="true" :compact="true"
/> />
<p class="date" :key="note.id + '_date'" v-if="i != notes.length - 1 && note._date != _notes[i + 1]._date"> <p class="date" :key="note.id + '_date'" v-if="i != notes.length - 1 && note._date != _notes[i + 1]._date">
@ -39,33 +38,47 @@
import Vue from 'vue'; import Vue from 'vue';
import i18n from '../../../i18n'; import i18n from '../../../i18n';
import shouldMuteNote from '../../../common/scripts/should-mute-note'; import shouldMuteNote from '../../../common/scripts/should-mute-note';
import paging from '../../../common/scripts/paging';
const displayLimit = 20;
export default Vue.extend({ export default Vue.extend({
i18n: i18n(), i18n: i18n(),
inject: ['column', 'isScrollTop', 'count'], inject: ['column', 'isScrollTop', 'count'],
mixins: [
paging({
limit: 20,
onQueueChanged: (self, q) => {
self.count(q.length);
},
onPrepend: (self, note, silent) => {
// 弾く
if (shouldMuteNote(self.$store.state.i, self.$store.state.settings, note)) return false;
// タブが非表示またはスクロール位置が最上部ではないならタイトルで通知
if (document.hidden || !self.isScrollTop()) {
self.$store.commit('pushBehindNote', note);
}
}
}),
],
props: { props: {
makePromise: { pagination: {
required: true required: true
},
extract: {
required: false
} }
}, },
data() {
return {
rootEl: null,
notes: [],
queue: [],
fetching: true,
moreFetching: false,
inited: false,
more: false
};
},
computed: { computed: {
notes() {
return this.extract ? this.extract(this.items) : this.items;
},
_notes(): any[] { _notes(): any[] {
return (this.notes as any).map(note => { return (this.notes as any).map(note => {
const date = new Date(note.createdAt).getDate(); const date = new Date(note.createdAt).getDate();
@ -77,15 +90,6 @@ export default Vue.extend({
} }
}, },
watch: {
queue(q) {
this.count(q.length);
},
makePromise() {
this.init();
}
},
created() { created() {
this.column.$on('top', this.onTop); this.column.$on('top', this.onTop);
this.column.$on('bottom', this.onBottom); this.column.$on('bottom', this.onBottom);
@ -101,88 +105,6 @@ export default Vue.extend({
focus() { focus() {
(this.$refs.notes as any).children[0].focus ? (this.$refs.notes as any).children[0].focus() : (this.$refs.notes as any).$el.children[0].focus(); (this.$refs.notes as any).children[0].focus ? (this.$refs.notes as any).children[0].focus() : (this.$refs.notes as any).$el.children[0].focus();
}, },
onNoteUpdated(i, note) {
Vue.set((this as any).notes, i, note);
},
reload() {
this.init();
},
async init() {
this.queue = [];
this.notes = [];
this.fetching = true;
await (this.makePromise()).then(x => {
if (Array.isArray(x)) {
this.notes = x;
} else {
this.notes = x.notes;
this.more = x.more;
}
this.inited = true;
this.fetching = false;
this.$emit('inited');
}, e => {
this.fetching = false;
});
},
async fetchMore() {
if (!this.more || this.moreFetching) return;
this.moreFetching = true;
await (this.makePromise(this.notes[this.notes.length - 1].id)).then(x => {
this.notes = this.notes.concat(x.notes);
this.more = x.more;
this.moreFetching = false;
}, e => {
this.moreFetching = false;
});
},
prepend(note, silent = false) {
// 弾く
if (shouldMuteNote(this.$store.state.i, this.$store.state.settings, note)) return;
// タブが非表示ならタイトルで通知
if (document.hidden) {
this.$store.commit('pushBehindNote', note);
}
if (this.isScrollTop()) {
// Prepend the note
this.notes.unshift(note);
// オーバーフローしたら古い投稿は捨てる
if (this.notes.length >= displayLimit) {
this.notes = this.notes.slice(0, displayLimit);
this.more = true;
}
} else {
this.queue.push(note);
}
},
append(note) {
this.notes.push(note);
this.cursor = this.notes[this.notes.length - 1].id
},
releaseQueue() {
for (const n of this.queue) {
this.prepend(n, true);
}
this.queue = [];
},
onTop() {
this.releaseQueue();
},
onBottom() {
this.fetchMore();
}
} }
}); });
</script> </script>

View File

@ -4,8 +4,8 @@
<mk-avatar class="avatar" :user="notification.user"/> <mk-avatar class="avatar" :user="notification.user"/>
<div> <div>
<header> <header>
<mk-reaction-icon :reaction="notification.reaction"/> <mk-reaction-icon :reaction="notification.reaction" class="icon"/>
<router-link :to="notification.user | userPage"> <router-link :to="notification.user | userPage" class="name">
<mk-user-name :user="notification.user"/> <mk-user-name :user="notification.user"/>
</router-link> </router-link>
<mk-time :time="notification.createdAt"/> <mk-time :time="notification.createdAt"/>
@ -22,8 +22,8 @@
<mk-avatar class="avatar" :user="notification.user"/> <mk-avatar class="avatar" :user="notification.user"/>
<div> <div>
<header> <header>
<fa icon="retweet"/> <fa icon="retweet" class="icon"/>
<router-link :to="notification.user | userPage"> <router-link :to="notification.user | userPage" class="name">
<mk-user-name :user="notification.user"/> <mk-user-name :user="notification.user"/>
</router-link> </router-link>
<mk-time :time="notification.createdAt"/> <mk-time :time="notification.createdAt"/>
@ -40,8 +40,8 @@
<mk-avatar class="avatar" :user="notification.user"/> <mk-avatar class="avatar" :user="notification.user"/>
<div> <div>
<header> <header>
<fa icon="user-plus"/> <fa icon="user-plus" class="icon"/>
<router-link :to="notification.user | userPage"> <router-link :to="notification.user | userPage" class="name">
<mk-user-name :user="notification.user"/> <mk-user-name :user="notification.user"/>
</router-link> </router-link>
<mk-time :time="notification.createdAt"/> <mk-time :time="notification.createdAt"/>
@ -53,9 +53,9 @@
<mk-avatar class="avatar" :user="notification.user"/> <mk-avatar class="avatar" :user="notification.user"/>
<div> <div>
<header> <header>
<fa icon="user-clock"/> <fa icon="user-clock" class="icon"/>
<router-link :to="notification.user | userPage"> <router-link :to="notification.user | userPage">
<mk-user-name :user="notification.user"/> <mk-user-name :user="notification.user" class="name"/>
</router-link> </router-link>
<mk-time :time="notification.createdAt"/> <mk-time :time="notification.createdAt"/>
</header> </header>
@ -66,9 +66,9 @@
<mk-avatar class="avatar" :user="notification.user"/> <mk-avatar class="avatar" :user="notification.user"/>
<div> <div>
<header> <header>
<fa icon="chart-pie"/> <fa icon="chart-pie" class="icon"/>
<router-link :to="notification.user | userPage"> <router-link :to="notification.user | userPage">
<mk-user-name :user="notification.user"/> <mk-user-name :user="notification.user" class="name"/>
</router-link> </router-link>
<mk-time :time="notification.createdAt"/> <mk-time :time="notification.createdAt"/>
</header> </header>
@ -81,15 +81,15 @@
</div> </div>
<template v-if="notification.type == 'quote'"> <template v-if="notification.type == 'quote'">
<mk-note :note="notification.note" @update:note="onNoteUpdated"/> <mk-note :note="notification.note"/>
</template> </template>
<template v-if="notification.type == 'reply'"> <template v-if="notification.type == 'reply'">
<mk-note :note="notification.note" @update:note="onNoteUpdated"/> <mk-note :note="notification.note"/>
</template> </template>
<template v-if="notification.type == 'mention'"> <template v-if="notification.type == 'mention'">
<mk-note :note="notification.note" @update:note="onNoteUpdated"/> <mk-note :note="notification.note"/>
</template> </template>
</div> </div>
</template> </template>
@ -105,17 +105,6 @@ export default Vue.extend({
getNoteSummary getNoteSummary
}; };
}, },
methods: {
onNoteUpdated(note) {
switch (this.notification.type) {
case 'quote':
case 'reply':
case 'mention':
Vue.set(this.notification, 'note', note);
break;
}
}
}
}); });
</script> </script>
@ -148,9 +137,13 @@ export default Vue.extend({
align-items baseline align-items baseline
white-space nowrap white-space nowrap
[data-icon], .mk-reaction-icon > .icon
margin-right 4px margin-right 4px
> .name
overflow hidden
text-overflow ellipsis
> .mk-time > .mk-time
margin-left auto margin-left auto
color var(--noteHeaderInfo) color var(--noteHeaderInfo)

View File

@ -10,16 +10,17 @@
<component :is="!$store.state.device.reduceMotion ? 'transition-group' : 'div'" name="mk-notifications" class="transition notifications" tag="div"> <component :is="!$store.state.device.reduceMotion ? 'transition-group' : 'div'" name="mk-notifications" class="transition notifications" tag="div">
<template v-for="(notification, i) in _notifications"> <template v-for="(notification, i) in _notifications">
<x-notification class="notification" :notification="notification" :key="notification.id"/> <x-notification class="notification" :notification="notification" :key="notification.id"/>
<p class="date" v-if="i != notifications.length - 1 && notification._date != _notifications[i + 1]._date" :key="notification.id + '-time'"> <p class="date" v-if="i != items.length - 1 && notification._date != _notifications[i + 1]._date" :key="notification.id + '-time'">
<span><fa icon="angle-up"/>{{ notification._datetext }}</span> <span><fa icon="angle-up"/>{{ notification._datetext }}</span>
<span><fa icon="angle-down"/>{{ _notifications[i + 1]._datetext }}</span> <span><fa icon="angle-down"/>{{ _notifications[i + 1]._datetext }}</span>
</p> </p>
</template> </template>
</component> </component>
<button class="more" :class="{ fetching: fetchingMoreNotifications }" v-if="moreNotifications" @click="fetchMoreNotifications" :disabled="fetchingMoreNotifications"> <button class="more" :class="{ fetching: moreFetching }" v-if="more" @click="fetchMore" :disabled="moreFetching">
<template v-if="fetchingMoreNotifications"><fa icon="spinner" pulse fixed-width/></template>{{ fetchingMoreNotifications ? this.$t('@.loading') : this.$t('@.load-more') }} <template v-if="moreFetching"><fa icon="spinner" pulse fixed-width/></template>{{ moreFetching ? this.$t('@.loading') : this.$t('@.load-more') }}
</button> </button>
<p class="empty" v-if="notifications.length == 0 && !fetching">{{ $t('empty') }}</p> <p class="empty" v-if="empty">{{ $t('empty') }}</p>
<mk-error v-if="error" @retry="init()"/>
</div> </div>
</template> </template>
@ -27,31 +28,38 @@
import Vue from 'vue'; import Vue from 'vue';
import i18n from '../../../i18n'; import i18n from '../../../i18n';
import XNotification from './deck.notification.vue'; import XNotification from './deck.notification.vue';
import paging from '../../../common/scripts/paging';
const displayLimit = 20;
export default Vue.extend({ export default Vue.extend({
i18n: i18n(), i18n: i18n(),
components: { components: {
XNotification XNotification
}, },
inject: ['column', 'isScrollTop', 'count'], inject: ['column', 'isScrollTop', 'count'],
mixins: [
paging({
onQueueChanged: (self, q) => {
self.count(q.length);
},
}),
],
data() { data() {
return { return {
fetching: true, connection: null,
fetchingMoreNotifications: false, pagination: {
notifications: [], endpoint: 'i/notifications',
queue: [], limit: 20,
moreNotifications: false, }
connection: null
}; };
}, },
computed: { computed: {
_notifications(): any[] { _notifications(): any[] {
return (this.notifications as any).map(notification => { return (this.items as any).map(notification => {
const date = new Date(notification.createdAt).getDate(); const date = new Date(notification.createdAt).getDate();
const month = new Date(notification.createdAt).getMonth() + 1; const month = new Date(notification.createdAt).getMonth() + 1;
notification._date = date; notification._date = date;
@ -61,33 +69,12 @@ export default Vue.extend({
} }
}, },
watch: {
queue(q) {
this.count(q.length);
}
},
mounted() { mounted() {
this.connection = this.$root.stream.useSharedConnection('main'); this.connection = this.$root.stream.useSharedConnection('main');
this.connection.on('notification', this.onNotification); this.connection.on('notification', this.onNotification);
this.column.$on('top', this.onTop); this.column.$on('top', this.onTop);
this.column.$on('bottom', this.onBottom); this.column.$on('bottom', this.onBottom);
const max = 10;
this.$root.api('i/notifications', {
limit: max + 1
}).then(notifications => {
if (notifications.length == max + 1) {
this.moreNotifications = true;
notifications.pop();
}
this.notifications = notifications;
this.fetching = false;
});
}, },
beforeDestroy() { beforeDestroy() {
@ -98,26 +85,6 @@ export default Vue.extend({
}, },
methods: { methods: {
fetchMoreNotifications() {
this.fetchingMoreNotifications = true;
const max = 20;
this.$root.api('i/notifications', {
limit: max + 1,
untilId: this.notifications[this.notifications.length - 1].id
}).then(notifications => {
if (notifications.length == max + 1) {
this.moreNotifications = true;
notifications.pop();
} else {
this.moreNotifications = false;
}
this.notifications = this.notifications.concat(notifications);
this.fetchingMoreNotifications = false;
});
},
onNotification(notification) { onNotification(notification) {
// TODO: ユーザーが画面を見てないと思われるとき(ブラウザやタブがアクティブじゃないなど)は送信しない // TODO: ユーザーが画面を見てないと思われるとき(ブラウザやタブがアクティブじゃないなど)は送信しない
this.$root.stream.send('readNotification', { this.$root.stream.send('readNotification', {
@ -126,35 +93,6 @@ export default Vue.extend({
this.prepend(notification); this.prepend(notification);
}, },
prepend(notification) {
if (this.isScrollTop()) {
// Prepend the notification
this.notifications.unshift(notification);
// オーバーフローしたら古い通知は捨てる
if (this.notifications.length >= displayLimit) {
this.notifications = this.notifications.slice(0, displayLimit);
}
} else {
this.queue.push(notification);
}
},
releaseQueue() {
for (const n of this.queue) {
this.prepend(n);
}
this.queue = [];
},
onTop() {
this.releaseQueue();
},
onBottom() {
this.fetchMoreNotifications();
}
} }
}); });
</script> </script>

View File

@ -5,7 +5,7 @@
</template> </template>
<div> <div>
<x-notes ref="timeline" :make-promise="makePromise" @inited="() => $emit('loaded')"/> <x-notes ref="timeline" :pagination="pagination" @inited="() => $emit('loaded')"/>
</div> </div>
</x-column> </x-column>
</template> </template>
@ -16,8 +16,6 @@ import XColumn from './deck.column.vue';
import XNotes from './deck.notes.vue'; import XNotes from './deck.notes.vue';
import { genSearchQuery } from '../../../common/scripts/gen-search-query'; import { genSearchQuery } from '../../../common/scripts/gen-search-query';
const limit = 20;
export default Vue.extend({ export default Vue.extend({
components: { components: {
XColumn, XColumn,
@ -26,24 +24,11 @@ export default Vue.extend({
data() { data() {
return { return {
makePromise: async cursor => this.$root.api('notes/search', { pagination: {
limit: limit + 1, endpoint: 'notes/search',
offset: cursor ? cursor : undefined, limit: 20,
...(await genSearchQuery(this, this.q)) params: () => genSearchQuery(this, this.q)
}).then(notes => { }
if (notes.length == limit + 1) {
notes.pop();
return {
notes: notes,
cursor: cursor ? cursor + limit : limit
};
} else {
return {
notes: notes,
more: false
};
}
})
}; };
}, },

View File

@ -90,7 +90,7 @@ export default Vue.extend({
methods: { methods: {
onChangeSettings(v) { onChangeSettings(v) {
this.$store.commit('device/updateDeckColumn', this.column); this.$store.commit('updateDeckColumn', this.column);
}, },
focus() { focus() {

View File

@ -6,7 +6,7 @@
</p> </p>
<p class="desc">{{ $t('disabled-timeline.description') }}</p> <p class="desc">{{ $t('disabled-timeline.description') }}</p>
</div> </div>
<x-notes v-else ref="timeline" :make-promise="makePromise" @inited="() => $emit('loaded')"/> <x-notes v-else ref="timeline" :pagination="pagination" @inited="() => $emit('loaded')"/>
</template> </template>
<script lang="ts"> <script lang="ts">
@ -15,8 +15,6 @@ import XNotes from './deck.notes.vue';
import { faMinusCircle } from '@fortawesome/free-solid-svg-icons'; import { faMinusCircle } from '@fortawesome/free-solid-svg-icons';
import i18n from '../../../i18n'; import i18n from '../../../i18n';
const fetchLimit = 10;
export default Vue.extend({ export default Vue.extend({
i18n: i18n('deck'), i18n: i18n('deck'),
@ -42,7 +40,7 @@ export default Vue.extend({
connection: null, connection: null,
disabled: false, disabled: false,
faMinusCircle, faMinusCircle,
makePromise: null pagination: null
}; };
}, },
@ -73,27 +71,17 @@ export default Vue.extend({
}, },
created() { created() {
this.makePromise = cursor => this.$root.api(this.endpoint, { this.pagination = {
limit: fetchLimit + 1, endpoint: this.endpoint,
untilId: cursor ? cursor : undefined, limit: 10,
withFiles: this.mediaOnly, params: init => ({
includeMyRenotes: this.$store.state.settings.showMyRenotes, untilDate: init ? undefined : (this.date ? this.date.getTime() : undefined),
includeRenotedMyNotes: this.$store.state.settings.showRenotedMyNotes, withFiles: this.mediaOnly,
includeLocalRenotes: this.$store.state.settings.showLocalRenotes includeMyRenotes: this.$store.state.settings.showMyRenotes,
}).then(notes => { includeRenotedMyNotes: this.$store.state.settings.showRenotedMyNotes,
if (notes.length == fetchLimit + 1) { includeLocalRenotes: this.$store.state.settings.showLocalRenotes
notes.pop(); })
return { };
notes: notes,
more: true
};
} else {
return {
notes: notes,
more: false
};
}
});
}, },
mounted() { mounted() {

View File

@ -30,7 +30,7 @@
<ui-container> <ui-container>
<template #header><fa :icon="['far', 'comment-alt']"/> {{ $t('timeline') }}</template> <template #header><fa :icon="['far', 'comment-alt']"/> {{ $t('timeline') }}</template>
<div> <div>
<x-notes ref="timeline" :make-promise="makePromise" @inited="() => $emit('loaded')"/> <x-notes ref="timeline" :pagination="pagination" @inited="() => $emit('loaded')" :key="user.id"/>
</div> </div>
</ui-container> </ui-container>
</div> </div>
@ -43,8 +43,6 @@ import XNotes from './deck.notes.vue';
import { concat } from '../../../../../prelude/array'; import { concat } from '../../../../../prelude/array';
import ApexCharts from 'apexcharts'; import ApexCharts from 'apexcharts';
const fetchLimit = 10;
export default Vue.extend({ export default Vue.extend({
i18n: i18n('deck/deck.user-column.vue'), i18n: i18n('deck/deck.user-column.vue'),
@ -63,49 +61,38 @@ export default Vue.extend({
return { return {
withFiles: false, withFiles: false,
images: [], images: [],
makePromise: null,
chart: null as ApexCharts chart: null as ApexCharts
}; };
}, },
computed: {
pagination() {
return {
endpoint: 'users/notes',
limit: 10,
params: init => ({
userId: this.user.id,
untilDate: init ? undefined : (this.date ? this.date.getTime() : undefined),
withFiles: this.withFiles,
includeMyRenotes: this.$store.state.settings.showMyRenotes,
includeRenotedMyNotes: this.$store.state.settings.showRenotedMyNotes,
includeLocalRenotes: this.$store.state.settings.showLocalRenotes
})
}
}
},
watch: { watch: {
user() { user() {
this.fetch(); this.fetch();
this.genPromiseMaker();
} }
}, },
created() { created() {
this.fetch(); this.fetch();
this.genPromiseMaker();
}, },
methods: { methods: {
genPromiseMaker() {
this.makePromise = cursor => this.$root.api('users/notes', {
userId: this.user.id,
limit: fetchLimit + 1,
untilDate: cursor ? cursor : new Date().getTime() + 1000 * 86400 * 365,
withFiles: this.withFiles,
includeMyRenotes: this.$store.state.settings.showMyRenotes,
includeRenotedMyNotes: this.$store.state.settings.showRenotedMyNotes,
includeLocalRenotes: this.$store.state.settings.showLocalRenotes
}).then(notes => {
if (notes.length == fetchLimit + 1) {
notes.pop();
return {
notes: notes,
more: true
};
} else {
return {
notes: notes,
more: false
};
}
});
},
fetch() { fetch() {
const image = [ const image = [
'image/jpeg', 'image/jpeg',

View File

@ -25,20 +25,25 @@ import * as uuid from 'uuid';
export default Vue.extend({ export default Vue.extend({
i18n: i18n('deck'), i18n: i18n('deck'),
components: { components: {
XColumnCore XColumnCore
}, },
computed: { computed: {
deck() {
return this.$store.getters.deck;
},
columns(): any[] { columns(): any[] {
if (this.$store.state.device.deck == null) return []; if (this.deck == null) return [];
return this.$store.state.device.deck.columns; return this.deck.columns;
}, },
layout(): any[] { layout(): any[] {
if (this.$store.state.device.deck == null) return []; if (this.deck == null) return [];
if (this.$store.state.device.deck.layout == null) return this.$store.state.device.deck.columns.map(c => [c.id]); if (this.deck.layout == null) return this.deck.columns.map(c => [c.id]);
return this.$store.state.device.deck.layout; return this.deck.layout;
}, },
style(): any { style(): any {
@ -75,7 +80,7 @@ export default Vue.extend({
}, },
created() { created() {
if (this.$store.state.device.deck == null) { if (this.deck == null) {
const deck = { const deck = {
columns: [/*{ columns: [/*{
type: 'widgets', type: 'widgets',
@ -101,10 +106,7 @@ export default Vue.extend({
deck.layout = deck.columns.map(c => [c.id]); deck.layout = deck.columns.map(c => [c.id]);
this.$store.commit('device/set', { this.$store.commit('setDeck', deck);
key: 'deck',
value: deck
});
} }
}, },
@ -129,7 +131,7 @@ export default Vue.extend({
icon: 'home', icon: 'home',
text: this.$t('@deck.home'), text: this.$t('@deck.home'),
action: () => { action: () => {
this.$store.commit('device/addDeckColumn', { this.$store.commit('addDeckColumn', {
id: uuid(), id: uuid(),
type: 'home' type: 'home'
}); });
@ -138,7 +140,7 @@ export default Vue.extend({
icon: ['far', 'comments'], icon: ['far', 'comments'],
text: this.$t('@deck.local'), text: this.$t('@deck.local'),
action: () => { action: () => {
this.$store.commit('device/addDeckColumn', { this.$store.commit('addDeckColumn', {
id: uuid(), id: uuid(),
type: 'local' type: 'local'
}); });
@ -147,7 +149,7 @@ export default Vue.extend({
icon: 'share-alt', icon: 'share-alt',
text: this.$t('@deck.hybrid'), text: this.$t('@deck.hybrid'),
action: () => { action: () => {
this.$store.commit('device/addDeckColumn', { this.$store.commit('addDeckColumn', {
id: uuid(), id: uuid(),
type: 'hybrid' type: 'hybrid'
}); });
@ -156,7 +158,7 @@ export default Vue.extend({
icon: 'globe', icon: 'globe',
text: this.$t('@deck.global'), text: this.$t('@deck.global'),
action: () => { action: () => {
this.$store.commit('device/addDeckColumn', { this.$store.commit('addDeckColumn', {
id: uuid(), id: uuid(),
type: 'global' type: 'global'
}); });
@ -165,7 +167,7 @@ export default Vue.extend({
icon: 'at', icon: 'at',
text: this.$t('@deck.mentions'), text: this.$t('@deck.mentions'),
action: () => { action: () => {
this.$store.commit('device/addDeckColumn', { this.$store.commit('addDeckColumn', {
id: uuid(), id: uuid(),
type: 'mentions' type: 'mentions'
}); });
@ -174,7 +176,7 @@ export default Vue.extend({
icon: ['far', 'envelope'], icon: ['far', 'envelope'],
text: this.$t('@deck.direct'), text: this.$t('@deck.direct'),
action: () => { action: () => {
this.$store.commit('device/addDeckColumn', { this.$store.commit('addDeckColumn', {
id: uuid(), id: uuid(),
type: 'direct' type: 'direct'
}); });
@ -195,7 +197,7 @@ export default Vue.extend({
showCancelButton: true showCancelButton: true
}); });
if (canceled) return; if (canceled) return;
this.$store.commit('device/addDeckColumn', { this.$store.commit('addDeckColumn', {
id: uuid(), id: uuid(),
type: 'list', type: 'list',
list: lists.find(l => l.id === listId) list: lists.find(l => l.id === listId)
@ -210,7 +212,7 @@ export default Vue.extend({
input: true input: true
}).then(({ canceled, result: title }) => { }).then(({ canceled, result: title }) => {
if (canceled) return; if (canceled) return;
this.$store.commit('device/addDeckColumn', { this.$store.commit('addDeckColumn', {
id: uuid(), id: uuid(),
type: 'hashtag', type: 'hashtag',
tagTlId: this.$store.state.settings.tagTimelines.find(x => x.title == title).id tagTlId: this.$store.state.settings.tagTimelines.find(x => x.title == title).id
@ -221,7 +223,7 @@ export default Vue.extend({
icon: ['far', 'bell'], icon: ['far', 'bell'],
text: this.$t('@deck.notifications'), text: this.$t('@deck.notifications'),
action: () => { action: () => {
this.$store.commit('device/addDeckColumn', { this.$store.commit('addDeckColumn', {
id: uuid(), id: uuid(),
type: 'notifications' type: 'notifications'
}); });
@ -230,7 +232,7 @@ export default Vue.extend({
icon: 'calculator', icon: 'calculator',
text: this.$t('@deck.widgets'), text: this.$t('@deck.widgets'),
action: () => { action: () => {
this.$store.commit('device/addDeckColumn', { this.$store.commit('addDeckColumn', {
id: uuid(), id: uuid(),
type: 'widgets', type: 'widgets',
widgets: [] widgets: []

View File

@ -110,7 +110,7 @@ export default Vue.extend({
}, },
addWidget() { addWidget() {
this.$store.commit('device/addDeckWidget', { this.$store.commit('addDeckWidget', {
id: this.column.id, id: this.column.id,
widget: { widget: {
name: this.widgetAdderSelected, name: this.widgetAdderSelected,
@ -123,14 +123,14 @@ export default Vue.extend({
}, },
removeWidget(widget) { removeWidget(widget) {
this.$store.commit('device/removeDeckWidget', { this.$store.commit('removeDeckWidget', {
id: this.column.id, id: this.column.id,
widget widget
}); });
}, },
saveWidgets() { saveWidgets() {
this.$store.commit('device/updateDeckColumn', this.column); this.$store.commit('updateDeckColumn', this.column);
} }
} }
}); });

View File

@ -18,24 +18,24 @@
</div> </div>
</ui-container> </ui-container>
<mk-user-list v-if="tag != null" :make-promise="tagUsers" :key="`${tag}-local`"> <mk-user-list v-if="tag != null" :pagination="tagUsers" :key="`${tag}-local`">
<fa :icon="faHashtag" fixed-width/>{{ tag }} <fa :icon="faHashtag" fixed-width/>{{ tag }}
</mk-user-list> </mk-user-list>
<mk-user-list v-if="tag != null" :make-promise="tagRemoteUsers" :key="`${tag}-remote`"> <mk-user-list v-if="tag != null" :pagination="tagRemoteUsers" :key="`${tag}-remote`">
<fa :icon="faHashtag" fixed-width/>{{ tag }} ({{ $t('federated') }}) <fa :icon="faHashtag" fixed-width/>{{ tag }} ({{ $t('federated') }})
</mk-user-list> </mk-user-list>
<template v-if="tag == null"> <template v-if="tag == null">
<mk-user-list :make-promise="pinnedUsers"> <mk-user-list :pagination="pinnedUsers">
<fa :icon="faBookmark" fixed-width/>{{ $t('pinned-users') }} <fa :icon="faBookmark" fixed-width/>{{ $t('pinned-users') }}
</mk-user-list> </mk-user-list>
<mk-user-list :make-promise="popularUsers"> <mk-user-list :pagination="popularUsers">
<fa :icon="faChartLine" fixed-width/>{{ $t('popular-users') }} <fa :icon="faChartLine" fixed-width/>{{ $t('popular-users') }}
</mk-user-list> </mk-user-list>
<mk-user-list :make-promise="recentlyUpdatedUsers"> <mk-user-list :pagination="recentlyUpdatedUsers">
<fa :icon="faCommentAlt" fixed-width/>{{ $t('recently-updated-users') }} <fa :icon="faCommentAlt" fixed-width/>{{ $t('recently-updated-users') }}
</mk-user-list> </mk-user-list>
<mk-user-list :make-promise="recentlyRegisteredUsers"> <mk-user-list :pagination="recentlyRegisteredUsers">
<fa :icon="faPlus" fixed-width/>{{ $t('recently-registered-users') }} <fa :icon="faPlus" fixed-width/>{{ $t('recently-registered-users') }}
</mk-user-list> </mk-user-list>
</template> </template>
@ -60,24 +60,21 @@ export default Vue.extend({
data() { data() {
return { return {
pinnedUsers: () => this.$root.api('pinned-users'), pinnedUsers: { endpoint: 'pinned-users' },
popularUsers: () => this.$root.api('users', { popularUsers: { endpoint: 'users', limit: 10, params: {
state: 'alive', state: 'alive',
origin: 'local', origin: 'local',
sort: '+follower', sort: '+follower',
limit: 10 } },
}), recentlyUpdatedUsers: { endpoint: 'users', limit: 10, params: {
recentlyUpdatedUsers: () => this.$root.api('users', {
origin: 'local', origin: 'local',
sort: '+updatedAt', sort: '+updatedAt',
limit: 10 } },
}), recentlyRegisteredUsers: { endpoint: 'users', limit: 10, params: {
recentlyRegisteredUsers: () => this.$root.api('users', {
origin: 'local', origin: 'local',
state: 'alive', state: 'alive',
sort: '+createdAt', sort: '+createdAt',
limit: 10 } },
}),
tagsLocal: [], tagsLocal: [],
tagsRemote: [], tagsRemote: [],
stats: null, stats: null,
@ -88,24 +85,30 @@ export default Vue.extend({
}, },
computed: { computed: {
tagUsers(): () => Promise<any> { tagUsers(): any {
return () => this.$root.api('hashtags/users', { return {
tag: this.tag, endpoint: 'hashtags/users',
state: 'alive', limit: 30,
origin: 'local', params: {
sort: '+follower', tag: this.tag,
limit: 30 state: 'alive',
}); origin: 'local',
sort: '+follower',
}
};
}, },
tagRemoteUsers(): () => Promise<any> { tagRemoteUsers(): any {
return () => this.$root.api('hashtags/users', { return {
tag: this.tag, endpoint: 'hashtags/users',
state: 'alive', limit: 30,
origin: 'remote', params: {
sort: '+follower', tag: this.tag,
limit: 30 state: 'alive',
}); origin: 'remote',
sort: '+follower',
}
};
}, },
}, },
@ -116,6 +119,10 @@ export default Vue.extend({
}, },
created() { created() {
this.$emit('init', {
title: this.$t('@.explore'),
icon: faHashtag
});
this.$root.api('hashtags/list', { this.$root.api('hashtags/list', {
sort: '+attachedLocalUsers', sort: '+attachedLocalUsers',
attachedToLocalUserOnly: true, attachedToLocalUserOnly: true,

View File

@ -0,0 +1,44 @@
<template>
<div>
<component :is="notesComponent" :pagination="pagination" :extract="items => items.map(item => item.note)"/>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import { faStar } from '@fortawesome/free-solid-svg-icons';
import i18n from '../../../i18n';
//import Progress from '../../../common/scripts/loading';
export default Vue.extend({
i18n: i18n(),
props: {
platform: {
type: String,
required: true
}
},
data() {
return {
pagination: {
endpoint: 'i/favorites',
limit: 10,
},
notesComponent:
this.platform === 'desktop' ? () => import('../../../desktop/views/components/detail-notes.vue').then(m => m.default) :
this.platform === 'mobile' ? () => import('../../../mobile/views/components/detail-notes.vue').then(m => m.default) :
this.platform === 'deck' ? () => import('../deck/deck.notes.vue').then(m => m.default) : null
};
},
created() {
this.$emit('init', {
title: this.$t('@.favorites'),
icon: faStar
});
},
});
</script>

View File

@ -0,0 +1,44 @@
<template>
<div>
<component :is="notesComponent" :pagination="pagination"/>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import { faNewspaper } from '@fortawesome/free-solid-svg-icons';
import i18n from '../../../i18n';
//import Progress from '../../../common/scripts/loading';
export default Vue.extend({
i18n: i18n(),
props: {
platform: {
type: String,
required: true
}
},
data() {
return {
pagination: {
endpoint: 'notes/featured',
limit: 29,
},
notesComponent:
this.platform === 'desktop' ? () => import('../../../desktop/views/components/detail-notes.vue').then(m => m.default) :
this.platform === 'mobile' ? () => import('../../../mobile/views/components/detail-notes.vue').then(m => m.default) :
this.platform === 'deck' ? () => import('../deck/deck.notes.vue').then(m => m.default) : null
};
},
created() {
this.$emit('init', {
title: this.$t('@.featured-notes'),
icon: faNewspaper
});
},
});
</script>

View File

@ -0,0 +1,74 @@
<template>
<div>
<ui-container :body-togglable="true">
<template #header>{{ $t('received-follow-requests') }}</template>
<div v-if="!fetching">
<sequential-entrance animation="entranceFromTop" delay="25" tag="div">
<div v-for="req in requests" class="mcbzkkaw">
<router-link :key="req.id" :to="req.follower | userPage">
<mk-user-name :user="req.follower"/>
</router-link>
<span>
<a @click="accept(req.follower)">{{ $t('accept') }}</a>|<a @click="reject(req.follower)">{{ $t('reject') }}</a>
</span>
</div>
</sequential-entrance>
</div>
</ui-container>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import i18n from '../../../i18n';
import Progress from '../../scripts/loading';
import { faUserClock } from '@fortawesome/free-solid-svg-icons';
export default Vue.extend({
i18n: i18n('common/views/pages/follow-requests.vue'),
data() {
return {
fetching: true,
requests: []
};
},
created() {
this.$emit('init', {
title: this.$t('received-follow-requests'),
icon: faUserClock
});
},
mounted() {
Progress.start();
this.$root.api('following/requests/list').then(requests => {
this.fetching = false;
this.requests = requests;
Progress.done();
});
},
methods: {
accept(user) {
this.$root.api('following/requests/accept', { userId: user.id }).then(() => {
this.requests = this.requests.filter(r => r.follower.id != user.id);
});
},
reject(user) {
this.$root.api('following/requests/reject', { userId: user.id }).then(() => {
this.requests = this.requests.filter(r => r.follower.id != user.id);
});
}
}
});
</script>
<style lang="stylus" scoped>
.mcbzkkaw
display flex
padding 16px
border solid 1px var(--faceDivider)
border-radius 4px
> span
margin 0 0 0 auto
</style>

View File

@ -1,7 +1,5 @@
<template> <template>
<div> <mk-user-list :pagination="pagination" :extract="items => items.map(item => item.follower)">{{ $t('@.followers') }}</mk-user-list>
<mk-user-list :make-promise="makePromise">{{ $t('@.followers') }}</mk-user-list>
</div>
</template> </template>
<script lang="ts"> <script lang="ts">
@ -9,31 +7,18 @@ import Vue from 'vue';
import parseAcct from '../../../../../misc/acct/parse'; import parseAcct from '../../../../../misc/acct/parse';
import i18n from '../../../i18n'; import i18n from '../../../i18n';
const fetchLimit = 30;
export default Vue.extend({ export default Vue.extend({
i18n: i18n(), i18n: i18n(),
data() { data() {
return { return {
makePromise: cursor => this.$root.api('users/followers', { pagination: {
...parseAcct(this.$route.params.user), endpoint: 'users/followers',
limit: fetchLimit + 1, limit: 30,
untilId: cursor ? cursor : undefined, params: {
}).then(followings => { ...parseAcct(this.$route.params.user),
if (followings.length == fetchLimit + 1) {
followings.pop();
return {
users: followings.map(following => following.follower),
cursor: followings[followings.length - 1].id
};
} else {
return {
users: followings.map(following => following.follower),
more: false
};
} }
}), },
}; };
}, },
}); });

View File

@ -1,7 +1,5 @@
<template> <template>
<div> <mk-user-list :pagination="pagination" :extract="items => items.map(item => item.followee)">{{ $t('@.following') }}</mk-user-list>
<mk-user-list :make-promise="makePromise">{{ $t('@.following') }}</mk-user-list>
</div>
</template> </template>
<script lang="ts"> <script lang="ts">
@ -9,31 +7,18 @@ import Vue from 'vue';
import parseAcct from '../../../../../misc/acct/parse'; import parseAcct from '../../../../../misc/acct/parse';
import i18n from '../../../i18n'; import i18n from '../../../i18n';
const fetchLimit = 30;
export default Vue.extend({ export default Vue.extend({
i18n: i18n(), i18n: i18n(),
data() { data() {
return { return {
makePromise: cursor => this.$root.api('users/following', { pagination: {
...parseAcct(this.$route.params.user), endpoint: 'users/following',
limit: fetchLimit + 1, limit: 30,
untilId: cursor ? cursor : undefined, params: {
}).then(followings => { ...parseAcct(this.$route.params.user),
if (followings.length == fetchLimit + 1) {
followings.pop();
return {
users: followings.map(following => following.followee),
cursor: followings[followings.length - 1].id
};
} else {
return {
users: followings.map(following => following.followee),
more: false
};
} }
}), },
}; };
}, },
}); });

View File

@ -5,7 +5,7 @@
<section style="padding: 0 16px 0 16px;"> <section style="padding: 0 16px 0 16px;">
<ui-input v-model="value.name"><template #prefix><fa :icon="faMagic"/></template><span>{{ $t('blocks._counter.name') }}</span></ui-input> <ui-input v-model="value.name"><template #prefix><fa :icon="faMagic"/></template><span>{{ $t('blocks._counter.name') }}</span></ui-input>
<ui-input v-model="value.text"><span>{{ $t('blocks._counter.text') }}</span></ui-input> <ui-input v-model="value.text"><span>{{ $t('blocks._counter.text') }}</span></ui-input>
<ui-input v-model="value.inc" type="number"><span>{{ $t('blocks._counter.increment') }}</span></ui-input> <ui-input v-model="value.inc" type="number"><span>{{ $t('blocks._counter.inc') }}</span></ui-input>
</section> </section>
</x-container> </x-container>
</template> </template>

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