Compare commits

...

291 Commits

Author SHA1 Message Date
86b0dfdd33 2.29.0 2018-06-07 06:16:11 +09:00
ab04f2fce0 ✌️ 2018-06-07 06:15:57 +09:00
be9f836b21 やった 2018-06-07 06:13:57 +09:00
818bc96aab 2.28.0 2018-06-07 05:15:05 +09:00
14d12c21f2 nanka iroiro 2018-06-07 05:14:37 +09:00
2053a041e5 Fix 2018-06-07 04:33:39 +09:00
0534a0a41e ✌️ 2018-06-07 04:31:49 +09:00
0ac5fdab49 2.27.3 2018-06-07 02:07:00 +09:00
39099909bf Fix firefox 2018-06-07 02:06:32 +09:00
999ce8e366 Improve scroll performance 2018-06-07 01:52:03 +09:00
8678e30cc8 2.27.2 2018-06-07 01:45:04 +09:00
8a59e9d9c8 Merge pull request #1677 from syuilo/l10n_master
New Crowdin translations
2018-06-07 01:44:26 +09:00
dddace9d6a New translations ja.yml (English) 2018-06-07 01:42:12 +09:00
388cb7db3a ✌️ 2018-06-07 01:41:05 +09:00
46b74b3e1c New translations ja.yml (Portuguese) 2018-06-07 01:22:17 +09:00
d53e80c88a New translations ja.yml (Korean) 2018-06-07 01:22:14 +09:00
d8a8f36676 New translations ja.yml (Polish) 2018-06-07 01:22:12 +09:00
dafdbbf552 New translations ja.yml (Chinese Simplified) 2018-06-07 01:22:10 +09:00
52bc52293b New translations ja.yml (Italian) 2018-06-07 01:22:08 +09:00
0733aefb64 New translations ja.yml (Russian) 2018-06-07 01:22:06 +09:00
aac6dec5da New translations ja.yml (English) 2018-06-07 01:22:03 +09:00
d44c59ea3e New translations ja.yml (Spanish) 2018-06-07 01:22:01 +09:00
9b3c3881c4 New translations ja.yml (German) 2018-06-07 01:21:59 +09:00
cdd722dca0 New translations ja.yml (French) 2018-06-07 01:21:57 +09:00
9ad7a80496 i18n 2018-06-07 01:17:29 +09:00
b85597b15d Fix glitch 2018-06-07 01:00:38 +09:00
ebb98d975b ✌️ 2018-06-07 00:53:31 +09:00
c1b320710b 2.27.1 2018-06-06 19:37:15 +09:00
1201794bef Revert "fix: validate post's text with Ctrl+Enter on PC."
This reverts commit fac6868305.
2018-06-06 19:34:25 +09:00
dc58c9bd2f 2.27.0 2018-06-06 19:24:34 +09:00
9787da7240 Merge branch 'master' of https://github.com/syuilo/misskey 2018-06-06 19:22:48 +09:00
b0f989dbac Deckにウィジェットを置けるように 2018-06-06 19:22:45 +09:00
a0ec6b8ea7 Merge pull request #1678 from 2vg/patch-2
fix: validate post's text with Ctrl+Enter on PC.
2018-06-06 09:50:17 +09:00
fac6868305 fix: validate post's text with Ctrl+Enter on PC. 2018-06-06 09:46:33 +09:00
ed8fa59639 Update README.md 2018-06-06 05:39:05 +09:00
e8edda01a9 2.26.2 2018-06-06 05:29:45 +09:00
380a369eca oops 2018-06-06 05:29:31 +09:00
781fffee42 2.26.1 2018-06-06 05:18:46 +09:00
69b5de3346 wip 2018-06-06 05:18:08 +09:00
0d8c83f27c wip 2018-06-06 04:00:48 +09:00
8ca58de2ba wip 2018-06-06 03:12:06 +09:00
d8cd24fab0 wip 2018-06-06 03:03:56 +09:00
f918081168 wip 2018-06-06 02:48:26 +09:00
f88fb9bc1d wip 2018-06-06 01:54:36 +09:00
062fbd7d27 wip 2018-06-06 01:54:24 +09:00
6b6af008d0 New translations ja.yml (Portuguese) 2018-06-05 23:23:22 +09:00
4d35def548 New translations ja.yml (Korean) 2018-06-05 23:23:20 +09:00
b369d6bd5c New translations ja.yml (Polish) 2018-06-05 23:23:17 +09:00
63dfe2726c New translations ja.yml (Chinese Simplified) 2018-06-05 23:23:15 +09:00
1002d29cc2 New translations ja.yml (Italian) 2018-06-05 23:23:13 +09:00
868240666a New translations ja.yml (Russian) 2018-06-05 23:23:11 +09:00
02a88fdc9c New translations ja.yml (English) 2018-06-05 23:23:08 +09:00
bc4adf7107 New translations ja.yml (Spanish) 2018-06-05 23:23:06 +09:00
bd67785802 New translations ja.yml (German) 2018-06-05 23:23:03 +09:00
68c90e8ebe New translations ja.yml (French) 2018-06-05 23:23:01 +09:00
64519a9fd4 2.26.0 2018-06-05 23:22:37 +09:00
d21da0211c Merge pull request #1676 from syuilo/deck
Deck (wip)
2018-06-05 23:21:53 +09:00
2e919b788f wip 2018-06-05 23:19:04 +09:00
2d2056f2bd Merge pull request #1675 from 2vg/patch-1
fix: validate post's text on mobile client.
2018-06-05 23:03:26 +09:00
334dabc1de fix: validate post's text on mobile client. 2018-06-05 23:00:03 +09:00
dfa2c951d6 wip 2018-06-05 22:54:03 +09:00
e28d1c7569 wip 2018-06-05 21:44:02 +09:00
9ce0f96de3 wip 2018-06-05 21:36:21 +09:00
a408b19bbe Update README.md 2018-06-05 15:09:21 +09:00
f9a17b8021 Merge pull request #1674 from syuilo/l10n_master
New Crowdin translations
2018-06-04 23:22:34 +09:00
5eeb200913 New translations ja.yml (English) 2018-06-04 20:07:56 +09:00
f87981eeee 2.25.2 2018-06-04 19:59:07 +09:00
761ae807db Fix bug 2018-06-03 19:53:57 +09:00
643a0e6b13 New translations ja.yml (Portuguese) 2018-06-03 19:41:36 +09:00
e7e5f76e9e New translations ja.yml (Korean) 2018-06-03 19:41:34 +09:00
247acd81a9 New translations ja.yml (Polish) 2018-06-03 19:41:32 +09:00
a2457a6ac4 New translations ja.yml (Chinese Simplified) 2018-06-03 19:41:30 +09:00
af7a320493 New translations ja.yml (Italian) 2018-06-03 19:41:28 +09:00
4dd8b7e85d New translations ja.yml (Russian) 2018-06-03 19:41:26 +09:00
3a4392af40 New translations ja.yml (English) 2018-06-03 19:41:23 +09:00
44f70f0009 New translations ja.yml (Spanish) 2018-06-03 19:41:20 +09:00
238c4cf181 New translations ja.yml (German) 2018-06-03 19:41:18 +09:00
9171c49d85 New translations ja.yml (French) 2018-06-03 19:41:16 +09:00
5e967e24ff ✌️ 2018-06-03 19:39:02 +09:00
70ac07d60e 🎨 2018-06-03 07:34:34 +09:00
81ee670dc2 New translations ja.yml (Polish) 2018-06-03 05:32:01 +09:00
faf215685b New translations ja.yml (Polish) 2018-06-03 05:21:18 +09:00
255c07d1ab 2.25.1 2018-06-03 04:51:58 +09:00
83e9711274 New translations ja.yml (English) 2018-06-02 23:02:02 +09:00
0aa9201770 2.25.0 2018-06-02 19:23:17 +09:00
534e43f72d Fix bug 2018-06-02 19:19:58 +09:00
8f50080647 Merge pull request #1673 from syuilo/l10n_master
New Crowdin translations
2018-06-02 17:05:18 +09:00
cdc70875e5 New translations ja.yml (English) 2018-06-02 16:51:10 +09:00
e6962d6fab New translations ja.yml (English) 2018-06-02 16:41:22 +09:00
3703563939 New translations ja.yml (Portuguese) 2018-06-02 16:31:39 +09:00
e81b145735 New translations ja.yml (Korean) 2018-06-02 16:31:37 +09:00
7f4145ee56 New translations ja.yml (Polish) 2018-06-02 16:31:35 +09:00
3967cf40b3 New translations ja.yml (Chinese Simplified) 2018-06-02 16:31:33 +09:00
84b0d56c4c New translations ja.yml (Italian) 2018-06-02 16:31:32 +09:00
e081d8d4ca New translations ja.yml (Russian) 2018-06-02 16:31:30 +09:00
b6ad7149d8 New translations ja.yml (English) 2018-06-02 16:31:28 +09:00
0f36f60cb4 New translations ja.yml (Spanish) 2018-06-02 16:31:26 +09:00
1284eef9e2 New translations ja.yml (German) 2018-06-02 16:31:24 +09:00
dec264ee6a New translations ja.yml (French) 2018-06-02 16:31:22 +09:00
e25e1d88d6 Merge pull request #1671 from syuilo/locked-account
Locked account
2018-06-02 16:28:08 +09:00
60a7f7f146 wip 2018-06-02 16:27:24 +09:00
897f7a031d wip 2018-06-02 16:13:32 +09:00
4feff8835c wip 2018-06-02 16:01:32 +09:00
8dfd892b71 wip 2018-06-02 15:51:43 +09:00
9e8cfd76c8 wip 2018-06-02 13:40:28 +09:00
a6a4bb6599 wip 2018-06-02 13:36:29 +09:00
5ca8a0d886 wip 2018-06-02 13:34:53 +09:00
6840496791 wip 2018-06-02 13:14:54 +09:00
0128831649 wip 2018-06-02 13:11:28 +09:00
56fa24e401 wip 2018-06-02 12:58:56 +09:00
e011870a60 Merge pull request #1672 from Angristan/patch-1
Update build docs
2018-06-02 03:54:10 +09:00
8d78ee08c1 Cover multiple cases 2018-06-01 20:52:47 +02:00
2752319e50 Update build docs
Fix #1474
2018-06-01 20:24:30 +02:00
a26c19cbd2 wip 2018-06-02 00:51:20 +09:00
f14571dc42 wip 2018-06-02 00:38:31 +09:00
484d17f53f wip 2018-06-02 00:15:17 +09:00
924119651a Merge branch 'master' into locked-account 2018-06-01 23:37:19 +09:00
c6d49dacbc Merge pull request #1670 from syuilo/l10n_master
New Crowdin translations
2018-06-01 23:36:22 +09:00
0be790fa31 wip 2018-06-01 21:55:27 +09:00
b7f6eb8290 New translations ja.yml (English) 2018-06-01 16:29:25 +09:00
f1bda0b2e1 New translations ja.yml (English) 2018-06-01 16:12:22 +09:00
bae44b4708 wip 2018-06-01 01:12:02 +09:00
35115607bc wip 2018-06-01 00:42:37 +09:00
51255bb446 wip 2018-05-31 22:56:02 +09:00
bd758a156e wip 2018-05-31 18:34:15 +09:00
51929fb607 typo 2018-05-31 18:11:28 +09:00
9599a31239 wip 2018-05-31 18:08:47 +09:00
9fdb125960 Merge pull request #1668 from syuilo/l10n_master
New Crowdin translations
2018-05-31 17:38:49 +09:00
534c0a6001 New translations ja.yml (English) 2018-05-31 17:31:23 +09:00
58bfcfda91 New translations ja.yml (English) 2018-05-31 17:21:36 +09:00
8d0802f05d New translations ja.yml (English) 2018-05-31 17:12:41 +09:00
5cd8c5d229 New translations ja.yml (English) 2018-05-31 17:02:48 +09:00
fa3c4436d9 New translations ja.yml (English) 2018-05-31 16:52:27 +09:00
d32d95918c 🎨 2018-05-31 16:44:11 +09:00
34899757d5 New translations ja.yml (English) 2018-05-31 16:41:32 +09:00
111dbdcd7f Fix 2018-05-31 16:38:05 +09:00
0c38509f1c New translations ja.yml (Polish) 2018-05-31 04:21:47 +09:00
652aa1f69b New translations ja.yml (German) 2018-05-31 00:33:22 +09:00
dc380c38da New translations ja.yml (German) 2018-05-31 00:23:33 +09:00
8555e04f50 New translations ja.yml (German) 2018-05-31 00:13:36 +09:00
c23bbf81f1 2.24.3 2018-05-30 23:08:26 +09:00
7dd7de8ff6 Update endpoints.ts 2018-05-30 23:05:24 +09:00
2ca8bafde3 Merge pull request #1664 from syuilo/l10n_master
New Crowdin translations
2018-05-30 22:08:38 +09:00
79f6c3f1ca New translations ja.yml (Portuguese) 2018-05-30 21:23:17 +09:00
fce0b315cf New translations ja.yml (Korean) 2018-05-30 21:23:14 +09:00
56c7a8f2e4 New translations ja.yml (Polish) 2018-05-30 21:23:10 +09:00
5ef2f157f2 New translations ja.yml (Chinese Simplified) 2018-05-30 21:23:08 +09:00
738afbe475 New translations ja.yml (Italian) 2018-05-30 21:23:06 +09:00
791a81a4c7 New translations ja.yml (Russian) 2018-05-30 21:23:03 +09:00
aa82d7a2c9 New translations ja.yml (English) 2018-05-30 21:23:01 +09:00
f57d2e54d2 New translations ja.yml (Spanish) 2018-05-30 21:22:58 +09:00
fea1a2e51b New translations ja.yml (German) 2018-05-30 21:22:55 +09:00
bda5347f1e New translations ja.yml (French) 2018-05-30 21:22:53 +09:00
98d9c37922 Merge pull request #1665 from m4sk1n/patch-1
fix typo
2018-05-30 21:21:59 +09:00
e3bde41a25 New translations ja.yml (Polish) 2018-05-30 21:14:46 +09:00
5fb2f7749d fix typo 2018-05-30 12:13:51 +00:00
a56bdf2372 New translations ja.yml (Polish) 2018-05-30 21:05:48 +09:00
9d991df32f New translations ja.yml (English) 2018-05-30 21:05:45 +09:00
c4a3f89d1c New translations ja.yml (English) 2018-05-30 20:51:48 +09:00
ea223bab51 Fix bug 2018-05-30 18:13:20 +09:00
dd94392317 2.24.2 2018-05-30 05:02:56 +09:00
baa2845916 Merge pull request #1663 from syuilo/l10n_master
New Crowdin translations
2018-05-30 05:02:17 +09:00
97ae4ea13e New translations ja.yml (English) 2018-05-30 05:00:58 +09:00
d1c5f0c70f New translations ja.yml (Portuguese) 2018-05-30 04:51:38 +09:00
95bff3005f New translations ja.yml (Korean) 2018-05-30 04:51:36 +09:00
c0b06496b1 New translations ja.yml (Polish) 2018-05-30 04:51:34 +09:00
2105e1f259 New translations ja.yml (Chinese Simplified) 2018-05-30 04:51:32 +09:00
e546414c2f New translations ja.yml (Italian) 2018-05-30 04:51:30 +09:00
1f4660a930 New translations ja.yml (Russian) 2018-05-30 04:51:28 +09:00
a2165c2e01 New translations ja.yml (English) 2018-05-30 04:51:26 +09:00
1af920739f New translations ja.yml (Spanish) 2018-05-30 04:51:24 +09:00
868e8228f0 New translations ja.yml (German) 2018-05-30 04:51:22 +09:00
2bbc74560d New translations ja.yml (French) 2018-05-30 04:51:20 +09:00
5d2caa456d 🎨 2018-05-30 04:46:50 +09:00
9069a99a15 wip 2018-05-30 04:45:27 +09:00
fa56a44d85 🎨 2018-05-30 04:07:23 +09:00
248acaee75 2.24.1 2018-05-30 00:16:03 +09:00
ef75f12abe Fix bug 2018-05-30 00:15:32 +09:00
854814c226 2.24.0 2018-05-29 23:57:25 +09:00
b6a322f447 Merge branch 'master' of https://github.com/syuilo/misskey 2018-05-29 23:56:52 +09:00
161b9602f4 Fix bug 2018-05-29 23:56:44 +09:00
62669bff07 Merge pull request #1662 from syuilo/l10n_master
New Crowdin translations
2018-05-29 23:55:19 +09:00
02bd299714 New translations ja.yml (English) 2018-05-29 23:52:22 +09:00
f71dabfbfa New translations ja.yml (Portuguese) 2018-05-29 23:45:17 +09:00
8d31cedafc New translations ja.yml (Korean) 2018-05-29 23:45:11 +09:00
a88d6c1c47 New translations ja.yml (Polish) 2018-05-29 23:45:09 +09:00
d35a13fc0b New translations ja.yml (Chinese Simplified) 2018-05-29 23:45:05 +09:00
8e4029c1cd New translations ja.yml (Italian) 2018-05-29 23:44:59 +09:00
9a9f852540 New translations ja.yml (Russian) 2018-05-29 23:44:57 +09:00
c66497a4de New translations ja.yml (English) 2018-05-29 23:44:55 +09:00
1f9ecbf0be New translations ja.yml (Spanish) 2018-05-29 23:44:53 +09:00
423a6f7013 New translations ja.yml (German) 2018-05-29 23:44:51 +09:00
ef0ca38362 New translations ja.yml (French) 2018-05-29 23:44:48 +09:00
ae9bfd69b0 Add analog clock widget 2018-05-29 23:13:39 +09:00
3d231c3456 Fix 2018-05-29 22:56:05 +09:00
95d0d0047a 時計をSVG化 2018-05-29 22:43:03 +09:00
d05aee19f2 2.23.2 2018-05-29 21:46:30 +09:00
125765faa6 Fix bug 2018-05-29 21:46:02 +09:00
70c0b1d8c0 🎨 2018-05-29 19:13:49 +09:00
72e8660ae3 🎨 2018-05-29 19:03:03 +09:00
2127bf32c2 2.23.1 2018-05-29 17:11:48 +09:00
2b9acc239e Fix bug 2018-05-29 17:10:59 +09:00
47a6188097 2.23.0 2018-05-29 15:43:24 +09:00
8abce1469a Merge pull request #1661 from syuilo/l10n_master
New Crowdin translations
2018-05-29 15:43:01 +09:00
8a2bee2136 New translations ja.yml (Portuguese) 2018-05-29 15:42:20 +09:00
e7a532f0cc New translations ja.yml (Korean) 2018-05-29 15:42:17 +09:00
2cb1678577 New translations ja.yml (Polish) 2018-05-29 15:42:15 +09:00
d249bc6575 New translations ja.yml (Chinese Simplified) 2018-05-29 15:42:13 +09:00
e409b45873 New translations ja.yml (Italian) 2018-05-29 15:42:10 +09:00
f2d26c1909 New translations ja.yml (Russian) 2018-05-29 15:42:08 +09:00
898e3d7138 New translations ja.yml (English) 2018-05-29 15:42:06 +09:00
78cc0f7b6f New translations ja.yml (Spanish) 2018-05-29 15:42:04 +09:00
b14ca6a464 New translations ja.yml (German) 2018-05-29 15:42:02 +09:00
4691c1259a New translations ja.yml (French) 2018-05-29 15:42:00 +09:00
69f07cb015 Fix bug 2018-05-29 15:41:49 +09:00
a426f4c7bd nanka iroiro 2018-05-29 15:38:48 +09:00
3430a2d093 New translations ja.yml (English) 2018-05-29 15:31:19 +09:00
4ecc8c799d 🎨 2018-05-29 15:21:03 +09:00
fa02a58fc4 New translations ja.yml (Portuguese) 2018-05-29 14:51:25 +09:00
2905d172b8 New translations ja.yml (Korean) 2018-05-29 14:51:23 +09:00
5f6e5e4c8b New translations ja.yml (Polish) 2018-05-29 14:51:21 +09:00
d68c2a0170 New translations ja.yml (Chinese Simplified) 2018-05-29 14:51:19 +09:00
76c7ad5e24 New translations ja.yml (Italian) 2018-05-29 14:51:17 +09:00
1cf65a0145 New translations ja.yml (Russian) 2018-05-29 14:51:16 +09:00
0c8602f1d5 New translations ja.yml (English) 2018-05-29 14:51:14 +09:00
2dc4990804 New translations ja.yml (Spanish) 2018-05-29 14:51:12 +09:00
47ecd2e900 New translations ja.yml (German) 2018-05-29 14:51:10 +09:00
01d8e9cf4e New translations ja.yml (French) 2018-05-29 14:51:08 +09:00
da52f980c4 ✌️ 2018-05-29 14:42:29 +09:00
366b7ef946 🎨 2018-05-29 14:22:15 +09:00
0e7c0fd528 2.22.3 2018-05-29 13:22:29 +09:00
fb28b238cf Add workaround for Safari bug 2018-05-29 13:21:38 +09:00
b375bbc75c 2.22.2 2018-05-29 11:53:59 +09:00
74ebd6e4a0 Merge branch 'master' of https://github.com/syuilo/misskey 2018-05-29 11:53:35 +09:00
72f2b92d4f ✌️ 2018-05-29 11:53:28 +09:00
178eeec041 Merge pull request #1660 from syuilo/l10n_master
New Crowdin translations
2018-05-29 11:53:03 +09:00
7ff950b5e3 New translations ja.yml (English) 2018-05-29 11:50:50 +09:00
11409b723e 🎨 2018-05-29 11:45:01 +09:00
a59c8b4f57 New translations ja.yml (Portuguese) 2018-05-29 11:41:13 +09:00
690e273257 New translations ja.yml (Korean) 2018-05-29 11:41:11 +09:00
0133a1ba97 New translations ja.yml (Polish) 2018-05-29 11:41:09 +09:00
809b0e67a6 New translations ja.yml (Chinese Simplified) 2018-05-29 11:41:08 +09:00
a702271efd New translations ja.yml (Italian) 2018-05-29 11:41:06 +09:00
ec4f8ddd3e New translations ja.yml (Russian) 2018-05-29 11:41:04 +09:00
839f66c82f New translations ja.yml (English) 2018-05-29 11:41:02 +09:00
9ae2775452 New translations ja.yml (Spanish) 2018-05-29 11:41:00 +09:00
c9818358ee New translations ja.yml (German) 2018-05-29 11:40:58 +09:00
6e3a88ffcb New translations ja.yml (French) 2018-05-29 11:40:56 +09:00
4c54d68fad Darken 2018-05-29 11:38:24 +09:00
c351ba7820 Fix 2018-05-29 11:36:45 +09:00
3c2d72f611 Fix bug 2018-05-29 11:32:55 +09:00
f557407589 Fix bug 2018-05-29 11:29:02 +09:00
a0a4ce4dd9 Fix bug 2018-05-29 11:25:28 +09:00
281971f4a4 2.22.1 2018-05-29 02:37:31 +09:00
12b13e974c 🎨 2018-05-29 02:36:57 +09:00
9d27fa7eaa Fix bug 2018-05-29 02:31:32 +09:00
9f1385b03a 2.22.0 2018-05-29 02:26:13 +09:00
8c019a6d0b Merge pull request #1659 from syuilo/l10n_master
New Crowdin translations
2018-05-29 02:24:14 +09:00
87faf5942c New translations ja.yml (English) 2018-05-29 02:22:44 +09:00
8c9977c136 🎨 2018-05-29 02:20:40 +09:00
1ffa66af4f New translations ja.yml (English) 2018-05-29 02:13:39 +09:00
3d5d2de80b New translations ja.yml (Portuguese) 2018-05-29 02:03:19 +09:00
12c313235e New translations ja.yml (Korean) 2018-05-29 02:03:16 +09:00
c63acba0a5 New translations ja.yml (Polish) 2018-05-29 02:03:14 +09:00
5aaf8e6308 New translations ja.yml (Chinese Simplified) 2018-05-29 02:03:12 +09:00
f7d6d41a90 New translations ja.yml (Italian) 2018-05-29 02:03:10 +09:00
0d79a41527 New translations ja.yml (Russian) 2018-05-29 02:03:08 +09:00
fef8c14586 New translations ja.yml (English) 2018-05-29 02:03:06 +09:00
1bfd4cfc34 New translations ja.yml (Spanish) 2018-05-29 02:03:04 +09:00
a8e48e06a1 New translations ja.yml (German) 2018-05-29 02:03:02 +09:00
d59dd7e44a New translations ja.yml (French) 2018-05-29 02:03:00 +09:00
e5431648fd ✌️ 2018-05-29 02:00:45 +09:00
2ddbca4641 Fix bug 2018-05-29 01:55:32 +09:00
d944827f3d New translations ja.yml (Portuguese) 2018-05-29 01:52:43 +09:00
bd01d81d1d New translations ja.yml (Korean) 2018-05-29 01:52:41 +09:00
9d52bd9ae8 New translations ja.yml (Polish) 2018-05-29 01:52:39 +09:00
4f782ac219 New translations ja.yml (Chinese Simplified) 2018-05-29 01:52:37 +09:00
77377ba63f New translations ja.yml (Italian) 2018-05-29 01:52:35 +09:00
6afb985121 New translations ja.yml (Russian) 2018-05-29 01:52:33 +09:00
47fb538311 New translations ja.yml (English) 2018-05-29 01:52:31 +09:00
5644a2ff0b New translations ja.yml (Spanish) 2018-05-29 01:52:29 +09:00
c87aeb6cc4 New translations ja.yml (German) 2018-05-29 01:52:27 +09:00
37ce882337 New translations ja.yml (French) 2018-05-29 01:52:24 +09:00
afc2efee1b ✌️ 2018-05-29 01:50:01 +09:00
8f79f862b9 🍕 2018-05-29 01:44:15 +09:00
016386b350 ✌️ 2018-05-29 01:25:54 +09:00
ab16fb3a3f #1634 2018-05-29 01:22:39 +09:00
973b1e42ef typo 2018-05-29 00:38:07 +09:00
bd1f3a2f01 #1579 2018-05-29 00:36:52 +09:00
5d82443389 2.21.1 2018-05-28 22:00:29 +09:00
43eb8bd99b notes/local-timeline と notes/global-timeline のサインインを不要に 2018-05-28 21:59:57 +09:00
165 changed files with 5849 additions and 1744 deletions

View File

@ -20,9 +20,10 @@ ultimately sophisticated new type of mini-blog based SNS.
----------------------------------------------------------------
* Reactions
* User lists
* Cusromizable column view (known as MisskeyDeck)
* Private messages
* Mute
* Real time contents
* Streaming
* ActivityPub compatible
and more! You can see it with your own eyes at [misskey.xyz](https://misskey.xyz).

View File

@ -69,7 +69,7 @@
inkscape:cx="232.39583"
inkscape:cy="251.50613"
inkscape:document-units="px"
inkscape:current-layer="layer1"
inkscape:current-layer="g4502"
showgrid="true"
units="px"
inkscape:snap-bbox="true"
@ -79,7 +79,7 @@
inkscape:snap-center="true"
inkscape:snap-page="true"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-height="1027"
inkscape:window-x="-8"
inkscape:window-y="1072"
inkscape:window-maximized="1"
@ -111,7 +111,7 @@
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
@ -124,25 +124,19 @@
id="g4502"
transform="matrix(1.096096,0,0,1.096096,-2.960633,-44.023579)">
<g
style="fill:#2fa1bb;fill-opacity:0.94117647"
style="fill:#000000;fill-opacity:1"
transform="translate(-1.3333333e-6,-1.3439941e-6)"
id="g5125">
<g
transform="matrix(0.91391326,0,0,0.91391326,7.9719907,17.595761)"
id="text4489"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:141.03404236px;line-height:476.69509888px;font-family:'OTADESIGN Rounded';-inkscape-font-specification:'OTADESIGN Rounded';letter-spacing:0px;word-spacing:0px;fill:#2fa1bb;fill-opacity:0.94117647;stroke:none;stroke-width:0.28950602px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:141.03404236px;line-height:476.69509888px;font-family:'OTADESIGN Rounded';-inkscape-font-specification:'OTADESIGN Rounded';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.28950602px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
aria-label="Mi">
<path
sodipodi:nodetypes="zccssscssccscczzzccsccsscscsccz"
inkscape:connector-curvature="0"
id="path5210"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:'OTADESIGN Rounded';-inkscape-font-specification:'OTADESIGN Rounded';fill:#2fa1bb;fill-opacity:0.94117647;stroke-width:0.28950602px"
d="m 75.196381,231.17126 c -5.855419,0.0202 -10.885068,-3.50766 -13.2572,-7.61584 -1.266603,-1.79454 -3.772419,-2.43291 -3.807919,0 v 11.2332 c 0,4.51309 -1.645397,8.41504 -4.936191,11.70583 -3.196772,3.19677 -7.098714,4.79516 -11.705826,4.79516 -4.513089,0 -8.415031,-1.59839 -11.705825,-4.79516 -3.196772,-3.29079 -4.795158,-7.19274 -4.795158,-11.70583 v -61.7729 c 0,-3.47884 0.987238,-6.6286 2.961715,-9.44928 2.068499,-2.91471 4.701135,-4.9362 7.897906,-6.06447 1.786431,-0.65816 3.666885,-0.98724 5.641362,-0.98724 5.077225,0 9.308247,1.97448 12.693064,5.92343 1.786431,1.97448 2.820681,3.00873 3.102749,3.10275 0,0 13.408119,16.21319 13.78421,16.49526 0.376091,0.28206 1.480789,2.43848 4.127113,2.43848 2.646324,0 3.89218,-2.15642 4.26827,-2.43848 0.376091,-0.28207 13.784088,-16.49526 13.784088,-16.49526 0.09402,0.094 1.081261,-0.94022 2.961715,-3.10275 3.478837,-3.94895 7.756866,-5.92343 12.834096,-5.92343 1.88045,0 3.76091,0.32908 5.64136,0.98724 3.19677,1.12827 5.7824,3.14976 7.75688,6.06447 2.06849,2.82068 3.10274,5.97044 3.10274,9.44928 v 61.7729 c 0,4.51309 -1.6454,8.41504 -4.93619,11.70583 -3.19677,3.19677 -7.09871,4.79516 -11.70582,4.79516 -4.51309,0 -8.41504,-1.59839 -11.705828,-4.79516 -3.196772,-3.29079 -4.795158,-7.19274 -4.795158,-11.70583 v -11.2332 c -0.277898,-3.06563 -2.987588,-1.13379 -3.948953,0 -2.538613,4.70114 -7.401781,7.59567 -13.2572,7.61584 z" />
<path
inkscape:connector-curvature="0"
id="path5212"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:'OTADESIGN Rounded';-inkscape-font-specification:'OTADESIGN Rounded';fill:#2fa1bb;fill-opacity:0.94117647;stroke-width:0.28950602px"
d="m 145.83461,185.00361 q -5.92343,0 -10.15445,-4.08999 -4.08999,-4.23102 -4.08999,-10.15445 0,-5.92343 4.08999,-10.01342 4.23102,-4.23102 10.15445,-4.23102 5.92343,0 10.15445,4.23102 4.23102,4.08999 4.23102,10.01342 0,5.92343 -4.23102,10.15445 -4.23102,4.08999 -10.15445,4.08999 z m 0.14103,2.82068 q 5.92343,0 10.01342,4.23102 4.23102,4.23102 4.23102,10.15445 v 34.83541 q 0,5.92343 -4.23102,10.15445 -4.08999,4.08999 -10.01342,4.08999 -5.92343,0 -10.15445,-4.08999 -4.23102,-4.23102 -4.23102,-10.15445 v -34.83541 q 0,-5.92343 4.23102,-10.15445 4.23102,-4.23102 10.15445,-4.23102 z" />
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:'OTADESIGN Rounded';-inkscape-font-specification:'OTADESIGN Rounded';fill:#000000;fill-opacity:1;stroke-width:1.09609616px"
d="M 62.474609 76.585938 C 54.999059 76.585938 47.878825 77.832365 41.115234 80.324219 C 29.011968 84.595952 19.044417 92.249798 11.212891 103.28516 C 3.7373405 113.96451 0 125.88934 0 139.06055 L 0 372.93945 C 0 390.02642 6.0510264 404.79858 18.154297 417.25781 C 30.613543 429.36108 45.387643 435.41406 62.474609 435.41406 C 79.917556 435.41406 94.689698 429.36108 106.79297 417.25781 C 119.25222 404.79858 125.48242 390.02642 125.48242 372.93945 L 125.48242 330.4082 C 125.61683 321.19698 135.10492 323.61391 139.90039 330.4082 C 148.8815 345.96215 167.92265 359.32062 190.0918 359.24414 C 212.26095 359.16778 230.67374 348.20715 240.28516 330.4082 C 243.92497 326.11557 254.18418 318.80145 255.23633 330.4082 L 255.23633 372.93945 C 255.23633 390.02642 261.28735 404.79858 273.39062 417.25781 C 285.84985 429.36108 300.62397 435.41406 317.71094 435.41406 C 335.15388 435.41406 349.92603 429.36108 362.0293 417.25781 C 374.48853 404.79858 380.71875 390.02642 380.71875 372.93945 L 380.71875 139.06055 C 380.71875 125.88934 376.80415 113.96451 368.97266 103.28516 C 361.49709 92.249798 351.70678 84.595952 339.60352 80.324219 C 332.48396 77.832365 325.3637 76.585938 318.24414 76.585938 C 299.02128 76.585938 282.82549 84.062587 269.6543 99.013672 C 262.53473 107.20121 258.79542 111.11761 258.43945 110.76172 C 258.43945 110.76172 207.67587 172.14495 206.25195 173.21289 C 204.82804 174.2808 200.11102 182.44531 190.0918 182.44531 C 180.07257 182.44531 175.89071 174.2808 174.4668 173.21289 C 173.04288 172.14495 122.2793 110.76172 122.2793 110.76172 C 121.21136 110.40575 117.29484 106.48923 110.53125 99.013672 C 97.716024 84.062587 81.697447 76.585938 62.474609 76.585938 z M 457.53516 76.585938 C 442.58406 76.585937 429.7692 81.926117 419.08984 92.605469 C 408.76646 102.92885 403.60547 115.56648 403.60547 130.51758 C 403.60547 145.46868 408.76646 158.28354 419.08984 168.96289 C 429.7692 179.28627 442.58406 184.44922 457.53516 184.44922 C 472.48625 184.44922 485.30112 179.28627 495.98047 168.96289 C 506.65982 158.28354 512 145.46868 512 130.51758 C 512 115.56648 506.65982 102.92885 495.98047 92.605469 C 485.30112 81.926117 472.48625 76.585938 457.53516 76.585938 z M 458.06836 195.12695 C 443.11726 195.12695 430.3024 200.46713 419.62305 211.14648 C 408.94369 221.82584 403.60547 234.6407 403.60547 249.5918 L 403.60547 381.48242 C 403.60547 396.43352 408.94369 409.24838 419.62305 419.92773 C 430.3024 430.25112 443.11726 435.41406 458.06836 435.41406 C 473.01946 435.41406 485.65709 430.25112 495.98047 419.92773 C 506.65982 409.24838 512 396.43352 512 381.48242 L 512 249.5918 C 512 234.6407 506.65982 221.82584 495.98047 211.14648 C 485.65709 200.46713 473.01946 195.12695 458.06836 195.12695 z "
transform="matrix(0.26412464,0,0,0.26412464,24.988264,136.28626)"
id="path5210" />
</g>
</g>
</g>

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

View File

@ -3,16 +3,21 @@ const User = require('../built/models/user').default;
const args = process.argv.slice(2);
const userId = new mongo.ObjectID(args[0]);
const user = args[0];
console.log(`Suspending ${userId}...`);
const q = user.startsWith('@') ? {
username: user.split('@')[1],
host: user.split('@')[2] || null
} : { _id: new mongo.ObjectID(user) };
User.update({ _id: userId }, {
console.log(`Suspending ${user}...`);
User.update(q, {
$set: {
isSuspended: true
}
}).then(() => {
console.log(`Suspended ${userId}`);
console.log(`Suspended ${user}`);
}, e => {
console.error(e);
});

View File

@ -47,7 +47,14 @@ You need to generate config file via `npm run config` command.
*5.* Build Misskey
----------------------------------------------------------------
We need to use `node-gyp` to build the `crypto` module.
Build misskey with the following:
`npm run build`
If you're on Debian, you will need to install the `build-essential` package.
If you're still encountering errors about some modules, use node-gyp:
1. `npm install -g node-gyp`
2. `node-gyp configure`

View File

@ -35,32 +35,51 @@ common:
angry: "Wütend"
confused: "Verwirrt"
pudding: "Pudding"
note-placeholders:
a: "Was machst du gerade?"
b: "Was ist so passiert?"
c: "Was geht dir durch den Kopf?"
d: "Willst du etwas sagen?"
e: "Schreib hier etwas!"
f: "Warte darauf, das du schreibst."
delete: "Löschen"
loading: "Laden"
ok: "OK"
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."
widgets:
profile: "プロフィール"
calendar: "カレンダー"
timemachine: "カレンダー(タイムマシン)"
activity: "アクティビティ"
rss: "RSSリーダー"
memo: "メモ"
trends: "トレンド"
photo-stream: "フォトストリーム"
slideshow: "スライドショー"
version: "バージョン"
analog-clock: "Analoge Uhr"
profile: "Profil"
calendar: "Kalender"
timemachine: "Kalender (Zeitmaschiene)"
activity: "Aktivitäten"
rss: "RSS Leser"
memo: "Notizen"
trends: "Trends"
photo-stream: "Bilder"
slideshow: "Diashow"
version: "Version"
broadcast: "ブロードキャスト"
notifications: "通知"
users: "おすすめユーザー"
polls: "投票"
notifications: "Benachrichtigungen"
users: "Empfohlene Benutzer"
polls: "Umfragen"
post-form: "投稿フォーム"
messaging: "メッセージ"
server: "サーバー情報"
donation: "寄付のお願い"
nav: "ナビゲーション"
tips: "ヒント"
messaging: "Nachrichten"
server: "Server-Info"
donation: "Spenden"
nav: "Navigation"
tips: "Tipps"
deck:
widgets: "ウィジェット"
home: "ホーム"
local: "ローカル"
global: "グローバル"
notifications: "通知"
list: "リスト"
swap-left: "左に移動"
swap-right: "右に移動"
remove: "カラムを削除"
add-column: "カラムを追加"
common/views/components/connect-failed.vue:
title: "Verbindung zum Server ist fehlgeschlagen"
description: "Es gibt entweder ein Problem mit deiner Internetverbindung, der Server ist nicht erreichbar oder wird gerade gewartet. Bitte versuche es später noch einmal."
@ -115,8 +134,8 @@ common/views/components/nav.vue:
common/views/components/note-menu.vue:
favorite: "Diese Anmerkung favorisieren"
pin: "An die Profilseite pinnen"
delete: "削除"
delete-confirm: "この投稿を削除しますか?"
delete: "Löschen"
delete-confirm: "Diesen Post löschen?"
remote: "Auf Quelle anzeigen"
common/views/components/poll.vue:
vote-to: "Stimme für '{}'"
@ -177,14 +196,14 @@ common/views/components/twitter-setting.vue:
common/views/components/uploader.vue:
waiting: "Warten"
common/views/components/visibility-chooser.vue:
public: "公開"
home: "ホーム"
public: "Öffentlich"
home: "Home"
home-desc: "ホームタイムラインにのみ公開"
followers: "フォロワー"
followers-desc: "自分のフォロワーにのみ公開"
specified: "ダイレクト"
specified-desc: "指定したユーザーにのみ公開"
private: "非公開"
followers: "Folgende"
followers-desc: "Nur für diejenigen sichtbar, die dir folgen"
specified: "Direkt"
specified-desc: "Poste nur für bestimmte Benutzer"
private: "Privat"
common/views/widgets/broadcast.vue:
fetching: "Laden"
no-broadcasts: "Keine Broadcasts"
@ -200,9 +219,9 @@ common/views/widgets/server.vue:
title: "Serverinformationen"
toggle: "Sicht umschalten"
common/views/widgets/memo.vue:
title: "メモ"
memo: "ここに書いて!"
save: "保存"
title: "Notizen"
memo: "Schreib hier!"
save: "Speichern"
desktop/views/components/activity.chart.vue:
total: "Schwarz ... komplett"
notes: "Blau ... Hinweise"
@ -241,29 +260,29 @@ desktop/views/components/drive.file.vue:
copy-url: "URL kopieren"
download: "Download"
else-files: "その他..."
set-as-avatar: "アイコンに設定"
set-as-banner: "バナーに設定"
open-in-app: "アプリで開く"
add-app: "アプリを追加"
rename-file: "ファイル名の変更"
input-new-file-name: "新しいファイル名を入力してください"
copied: "コピー完了"
copied-url-to-clipboard: "URLをクリップボードにコピーしました"
set-as-avatar: "Als Avatar festlegen"
set-as-banner: "Setze als Banner"
open-in-app: "In der App öffnen"
add-app: "App hinzufügen"
rename-file: "Datei umbennen"
input-new-file-name: "Geben Sie den neuen Dateinamen an"
copied: "Kopieren erfolgreich"
copied-url-to-clipboard: "URL wurde in die Zwischenablage kopiert"
desktop/views/components/drive.folder.vue:
unable-to-process: "操作を完了できません"
circular-reference-detected: "移動先のフォルダーは、移動するフォルダーのサブフォルダーです。"
unhandled-error: "不明なエラー"
unable-to-process: "Der Vorgang konnte nicht beendet werden"
circular-reference-detected: "Das Zielverzeichnis ist ein Unterverzeichnis des Verzeichnisses welches du verschieben möchtest"
unhandled-error: "Unbekannter Fehler"
contextmenu:
move-to-this-folder: "このフォルダへ移動"
show-in-new-window: "新しいウィンドウで表示"
rename: "名前を変更"
rename-folder: "フォルダ名の変更"
input-new-folder-name: "新しいフォルダ名を入力してください"
move-to-this-folder: "Verschiebe in diesen Ordner"
show-in-new-window: "In einem neuen Fenster anzeigen"
rename: "Umbenennen"
rename-folder: "Ordner umbenennen"
input-new-folder-name: "Namen für neuen Ordner eingeben"
desktop/views/components/drive.nav-folder.vue:
drive: "ドライブ"
drive: "Laufwerk"
desktop/views/components/drive.vue:
search: "検索"
load-more: "もっと読み込む"
search: "Suchen"
load-more: "Mehr laden"
empty-draghover: "Herzlich Willkommen!"
empty-drive: "Dein Speicher ist leer"
empty-drive-description: "Du kannst rechts klicken und \"Datei hochladen\" auswählen oder eine Datei per Drag and Drop auf das Fenster ziehen."
@ -282,12 +301,14 @@ desktop/views/components/drive.vue:
upload: "Eine Datei hochladen"
url-upload: "Von einer URL hochladen"
desktop/views/components/follow-button.vue:
unfollow: "フォロー解除"
follow: "フォローする"
following: "フォロー"
follow: "フォロー"
request-pending: "フォロー許可待ち"
follow-request: "フォロー申請"
desktop/views/components/followers-window.vue:
followers: "{} のフォロワー"
desktop/views/components/followers.vue:
empty: "フォロワーはいないようです。"
empty: "Dir scheint niemand zu folgen."
desktop/views/components/following-window.vue:
following: "{} のフォロー"
desktop/views/components/following.vue:
@ -319,9 +340,6 @@ desktop/views/components/note-detail.vue:
location: "Ort"
renote: "Anmerkung"
add-reaction: "Reaktion hinzufügen"
desktop/views/components/note-detail.sub.vue:
private: "この投稿は非公開です"
deleted: "この投稿は削除されました"
desktop/views/components/notes.note.vue:
reposted-by: "Auch geteilt von"
reply: "Antworten"
@ -337,10 +355,9 @@ desktop/views/components/notifications.vue:
more: "Mehr"
empty: "Keine Benachrichtigungen"
desktop/views/components/post-form.vue:
note-placeholder: "Was ist bei dir los?"
reply-placeholder: "Antworte auf diese Anmerkung..."
quote-placeholder: "Zitiere diese Anmerkung..."
note: "Post"
submit: "投稿"
reply: "Antworten"
renote: "Anmerkung"
posted: "Gepostet!"
@ -472,7 +489,7 @@ desktop/views/components/settings.api.vue:
regenerate-token: "トークンを再生成"
token: "Token:"
enter-password: "パスワードを入力してください"
desktop/views/components/settings.app.vue:
desktop/views/components/settings.apps.vue:
no-apps: "連携しているアプリケーションはありません"
desktop/views/components/settings.mute.vue:
no-users: "ミュートしているユーザーはいません"
@ -510,12 +527,14 @@ desktop/views/components/ui.header.account.vue:
drive: "Speicher"
favorites: "Favoriten"
lists: "Listen"
follow-requests: "フォロー申請"
customize: "Anpassen"
settings: "Einstellungen"
signout: "Ausloggen"
dark: "Verdunkeln"
desktop/views/components/ui.header.nav.vue:
home: "Home"
deck: "デッキ"
messaging: "Nachrichten"
game: "Spielen"
desktop/views/components/ui.header.notifications.vue:
@ -524,7 +543,12 @@ desktop/views/components/ui.header.post.vue:
post: "Einen neuen Post erstellen"
desktop/views/components/ui.header.search.vue:
placeholder: "Suchen"
desktop/views/components/received-follow-requests-window.vue:
title: "フォロー申請"
accept: "承認"
reject: "拒否"
desktop/views/components/user-lists-window.vue:
title: "リスト"
create-list: "リストを作成"
desktop/views/components/user-preview.vue:
notes: "投稿"
@ -609,7 +633,6 @@ desktop/views/widgets/polls.vue:
desktop/views/widgets/post-form.vue:
title: "投稿"
note: "投稿"
placeholder: "いまどうしてる?"
desktop/views/widgets/profile.vue:
update-banner: "クリックでバナー編集"
update-avatar: "クリックでアバター編集"
@ -650,8 +673,10 @@ mobile/views/components/drive.file-detail.vue:
hash: "ハッシュ (md5)"
exif: "EXIF"
mobile/views/components/follow-button.vue:
following: "フォロー中"
follow: "フォロー"
unfollow: "フォロー解除"
request-pending: "フォロー許可待ち"
follow-request: "フォロー申請"
mobile/views/components/friends-maker.vue:
title: "気になるユーザーをフォロー"
empty: "おすすめのユーザーは見つかりませんでした。"
@ -691,9 +716,8 @@ mobile/views/components/post-form.vue:
submit: "投稿"
reply: "返信"
renote: "Renote"
renote-placeholder: "この投稿を引用... (オプション)"
quote-placeholder: "この投稿を引用... (オプション)"
reply-placeholder: "この投稿への返信..."
note-placeholder: "いまどうしてる?"
cw-placeholder: "内容への注釈 (オプション)"
location-alert: "お使いの端末は位置情報に対応していません"
error: "エラー"
@ -707,11 +731,17 @@ mobile/views/components/timeline.vue:
empty: "投稿がありません"
load-more: "もっと"
mobile/views/components/ui.nav.vue:
home: "ホーム"
timeline: "タイムライン"
notifications: "通知"
messaging: "メッセージ"
follow-requests: "フォロー申請"
search: "検索"
drive: "ドライブ"
favorites: "お気に入り"
user-lists: "リスト"
widgets: "ウィジェット"
game: "ゲーム"
darkmode: "ダークモード"
settings: "設定"
about: "Misskeyについて"
mobile/views/components/user-timeline.vue:
@ -722,8 +752,14 @@ mobile/views/components/users-list.vue:
all: "すべて"
known: "知り合い"
load-more: "もっと"
mobile/views/pages/favorites.vue:
title: "お気に入り"
mobile/views/pages/user-lists.vue:
title: "リスト"
enter-list-name: "リスト名を入力してください"
mobile/views/pages/drive.vue:
drive: "ドライブ"
more: "もっと見る"
mobile/views/pages/followers.vue:
followers-of: "{}のフォロワー"
mobile/views/pages/following.vue:
@ -736,6 +772,10 @@ mobile/views/pages/messaging.vue:
messaging: "メッセージ"
mobile/views/pages/messaging-room.vue:
messaging: "メッセージ"
mobile/views/pages/received-follow-requests.vue:
title: "フォロー申請"
accept: "承認"
reject: "拒否"
mobile/views/pages/note.vue:
title: "投稿"
prev: "前の投稿"

View File

@ -5,7 +5,7 @@ meta:
common:
misskey: "A planet of fediverse"
about-title: "A ⭐ of fediverse."
about: "Misskeyを見つけていただき、ありがとうございます。Misskeyは、地球で生まれた<b>分散マイクロブログSNS</b>です。Fediverse(様々なSNSで構成される宇宙)の中に存在するため、他のSNSと相互に繋がっています。暫し都会の喧騒から離れて、新しいインターネットにダイブしてみませんか。"
about: "Thanks for finding Misskey. Misskey is a <b>decentralized microblogging platform</b> born on Earth. Since it exists within Fediverse (a universe where various social media platforms are organized) it is mutually linked with other social media platforms. Why don't you take a short break from the hustle and bustle of the city, and dive into a new Internet?"
time:
unknown: "unknown"
future: "future"
@ -35,12 +35,20 @@ common:
angry: "Angry"
confused: "Confused"
pudding: "Pudding"
note-placeholders:
a: "What are you doing?"
b: "What's happening?"
c: "Whats on your mind?"
d: "Do you want to say something?"
e: "Write here!"
f: "Waiting for your writing."
delete: "Delete"
loading: "Loading"
ok: "OK"
update-available: "A new version of Misskey is now available({newer}, current is {current}). Reload the page to apply the update."
my-token-regenerated: "Your token has been generated. You will now get logged out."
update-available: "A new version of Misskey is now available({newer}, the current version is {current}). Reload the page to apply updates."
my-token-regenerated: "Your token has been renewed so you will be signed out."
widgets:
analog-clock: "Analog clock"
profile: "Profile"
calendar: "Calendar"
timemachine: "Calendar (Time Machine)"
@ -61,9 +69,20 @@ common:
donation: "Donation"
nav: "Navigation"
tips: "Tips"
deck:
widgets: "Widgets"
home: "Home"
local: "Local"
global: "Global"
notifications: "Notifications"
list: "List"
swap-left: "Move Left"
swap-right: "Move Right"
remove: "Remove"
add-column: "Add a column"
common/views/components/connect-failed.vue:
title: "Unable to connect to the server"
description: "There is a problem either with your internet connection, or the server may be down or under maintenance. Please {try again} later."
description: "There is a problem either with your Internet connection, or the server may be down or under maintenance. Please {try again} later."
thanks: "Thank you for using Misskey."
troubleshoot: "Troubleshoot"
common/views/components/connect-failed.troubleshooter.vue:
@ -71,12 +90,12 @@ common/views/components/connect-failed.troubleshooter.vue:
network: "Network connection"
checking-network: "Checking network connection"
internet: "Internet connection"
checking-internet: "Checking internet connection"
checking-internet: "Checking Internet connection"
server: "Server connection"
checking-server: "Checking server connection"
finding: "Finding a problem"
no-network: "There is no Network connection"
no-network-desc: "Please make sure you are connected to the Network."
finding: "Searching for issues"
no-network: "No connection"
no-network-desc: "Please make sure you are connected to the network."
no-internet: "There is no Internet connection"
no-internet-desc: "Please make sure you are connected to the Internet."
no-server: "Unable to connect to the Misskey server"
@ -86,19 +105,19 @@ common/views/components/connect-failed.troubleshooter.vue:
flush: "Clean cache"
set-version: "Specify version"
common/views/components/messaging.vue:
search-user: "Find an user"
search-user: "Find a user"
you: "You"
no-history: "No history"
common/views/components/messaging-room.vue:
empty: "No conversations"
more: "More"
empty: "You haven't messaged this user"
more: "Read more"
no-history: "There is no more history"
resize-form: "Drag to resize"
new-message: "New message"
common/views/components/messaging-room.form.vue:
input-message-here: "Enter message here"
send: "Send"
attach-from-local: "Attach files from your pc"
attach-from-local: "Attach files from your PC"
attach-from-drive: "Attach files from your Drive"
common/views/components/messaging-room.message.vue:
is-read: "Read"
@ -130,7 +149,7 @@ common/views/components/poll-editor.vue:
choice-n: "Choice {}"
remove: "Remove this choice"
add: "+ Add a choice"
destroy: "Destroy this poll"
destroy: "Cancel this poll"
common/views/components/reaction-picker.vue:
choose-reaction: "Choose a reaction"
common/views/components/signin.vue:
@ -150,10 +169,10 @@ common/views/components/signup.vue:
too-long: "Please enter up to 20 characters."
password: "Password"
password-placeholder: "We recommend more than 8 characters."
weak-password: "Weak"
normal-password: "So so"
strong-password: "Strong"
retype: "Type again"
weak-password: "Weak password"
normal-password: "Fair password"
strong-password: "Strong password"
retype: "Re-enter"
retype-placeholder: "Confirm your password"
password-matched: "OK"
password-not-matched: "Doesn't match"
@ -170,9 +189,9 @@ common/views/components/stream-indicator.vue:
common/views/components/twitter-setting.vue:
description: "If you connect your Twitter account to your Misskey account, you will be able to see your Twitter account information on your profile and you can sign-in using Twitter."
connected-to: "You are connected to this Twitter account"
detail: "Detail..."
detail: "Details..."
reconnect: "Reconnect"
connect: "Link your twitter account"
connect: "Link your Twitter account"
disconnect: "Disconnect"
common/views/components/uploader.vue:
waiting: "Waiting"
@ -192,7 +211,7 @@ common/views/widgets/broadcast.vue:
next: "Next"
common/views/widgets/donation.vue:
title: "Donation"
text: "To keep Misskey up and running we spend money for our domain name, servers and so on.. We don't get any money from it, and we would really appreciate it if you could donate. If you're interested contact {}. Thank you for your contribution!"
text: "To keep Misskey up and running we spend money for our domain name, servers and so on. Since we don't get money from advertisements, we count on donations from all of you. If you're interested contact {}. Thank you for your contribution!"
common/views/widgets/photo-stream.vue:
title: "Photostream"
no-photos: "No photos"
@ -215,7 +234,7 @@ desktop/views/components/calendar.vue:
title: "{1} / {2}"
prev: "Previous month"
next: "Next month"
go: "Click to naviguate"
go: "Click to navigate"
desktop/views/components/choose-file-from-drive-window.vue:
choose-file: "Choosing files"
upload: "Upload files from your PC"
@ -282,19 +301,21 @@ desktop/views/components/drive.vue:
upload: "Upload a file"
url-upload: "Upload from a URL"
desktop/views/components/follow-button.vue:
unfollow: "Unfollow"
following: "Following"
follow: "Follow"
request-pending: "フォロー許可待ち"
follow-request: "Follow request"
desktop/views/components/followers-window.vue:
followers: "Followers of {}"
followers: "{}'s followers"
desktop/views/components/followers.vue:
empty: "Seems that you dont have any followers."
empty: "Seems like you dont have any followers."
desktop/views/components/following-window.vue:
following: "Following of {}"
following: "Following {}"
desktop/views/components/following.vue:
empty: "You dont follow anyone."
desktop/views/components/friends-maker.vue:
title: "Recommended users:"
empty: "Similar users werent found."
empty: "Couldn't find any recommended users."
fetching: "Loading…"
refresh: "More"
close: "Close"
@ -315,19 +336,16 @@ desktop/views/components/note-detail.vue:
more: "Load more conversations"
private: "this post is private"
deleted: "this post has been deleted"
reposted-by: "Renoted by {}"
reposted-by: "Reposted by {}"
location: "Location"
renote: "Renote"
renote: "Repost"
add-reaction: "Add a reaction"
desktop/views/components/note-detail.sub.vue:
private: "this post is private"
deleted: "this post has been deleted"
desktop/views/components/notes.note.vue:
reposted-by: "Reposted by {}"
reply: "Reply"
renote: "Renote"
renote: "Repost"
add-reaction: "Add a reaction"
detail: "Show detail"
detail: "Show details"
private: "this post is private"
deleted: "this post has been deleted"
desktop/views/components/notes.vue:
@ -337,25 +355,24 @@ desktop/views/components/notifications.vue:
more: "More"
empty: "No notifications"
desktop/views/components/post-form.vue:
note-placeholder: "What's happening?"
reply-placeholder: "Reply to this note..."
quote-placeholder: "Quote this note..."
note: "Post"
submit: "Post"
reply: "Reply"
renote: "Renote"
renote: "Repost"
posted: "Posted!"
replied: "Replied!"
reposted: "Reposted!"
note-failed: "Failed to note"
reply-failed: "Failed to reply"
renote-failed: "Failed to renote"
renote-failed: "Failed to repost"
posting: "Posting"
attach-media-from-local: "Attach media from your pc"
attach-media-from-local: "Attach media from your PC"
attach-media-from-drive: "Attach media from your Drive"
attach-cancel: "Cancel attachment"
insert-a-kao: "v(‘ω’)v"
create-poll: "Create a poll"
text-remain: "{} chars remaining"
text-remain: "{} characters remaining"
desktop/views/components/post-form-window.vue:
note: "New note"
reply: "Reply"
@ -366,12 +383,12 @@ desktop/views/components/progress-dialog.vue:
desktop/views/components/renote-form.vue:
quote: "Quote..."
cancel: "Cancel"
renote: "Renote"
renote: "Repost"
reposting: "Reposting..."
success: "Reposted!"
failure: "Failed to Renote"
failure: "Repost failed"
desktop/views/components/renote-form-window.vue:
title: "Are you sure you want to renote this note?"
title: "Are you sure you want to repost this?"
desktop/views/components/settings-window.vue:
settings: "Settings"
desktop/views/components/settings.vue:
@ -401,22 +418,22 @@ desktop/views/components/settings.vue:
gradient-window-header: "Use gradients on window headers"
post-form-on-timeline: "Display post form at the top of the timeline"
show-reply-target: "Display reply target"
show-my-renotes: "Show my renote in the timeline"
show-renoted-my-notes: "Show renoted my post in the timeline"
show-my-renotes: "Show my reposts in the timeline"
show-renoted-my-notes: "Show my posts that have been shared in the timeline"
show-maps: "Show the map"
show-maps-desc: "Show the map of the location attached to the post."
show-maps-desc: "Automatically show the map of the location attached to the post."
sound: "Sound"
enable-sounds: "Enable sound"
enable-sounds-desc: "Play a sound when you received a post/message. This setting is stored in the browser."
enable-sounds-desc: "Play a sound when you receive a post/message. This setting is stored in the browser."
volume: "Volume"
test: "Test"
mobile: "Mobile"
disable-via-mobile: "Not mark the post as 'from mobile'"
disable-via-mobile: "Don't mark the post as 'from mobile'"
language: "Language"
pick-language: "Select a language"
recommended: "Recommended"
auto: "Auto"
specify-language: "Specify the language"
specify-language: "Specify language"
language-desc: "You need to reload the page for the changes to take effect."
cache: "Cache"
clean-cache: "Cleanup"
@ -434,11 +451,11 @@ desktop/views/components/settings.vue:
do-update: "Check for update"
update-settings: "Advanced settings"
prevent-update: "Postpone updates (not recommended)"
prevent-update-desc: "You may reflect updates even if you select this setting. This setting is valid only this device."
prevent-update-desc: "Even if you turn this setting on updates may apply. This setting is valid only for this device."
no-updates: "No updates available"
no-updates-desc: "Your Misskey is up to date."
update-available: "New version is available!"
update-available-desc: "To reload the page and updates are applied."
update-available-desc: "The updates will apply if you reload the page again."
advanced-settings: "Advanced"
debug-mode: "Enable the debug mode"
debug-mode-desc: "This setting is stored in the browser."
@ -472,8 +489,8 @@ desktop/views/components/settings.api.vue:
regenerate-token: "Regenerate the token"
token: "Token:"
enter-password: "Please enter the password"
desktop/views/components/settings.app.vue:
no-apps: "No authorized apps"
desktop/views/components/settings.apps.vue:
no-apps: "No linked applications"
desktop/views/components/settings.mute.vue:
no-users: "No muted users"
desktop/views/components/settings.password.vue:
@ -510,12 +527,14 @@ desktop/views/components/ui.header.account.vue:
drive: "Drive"
favorites: "Favorites"
lists: "Lists"
follow-requests: "Follow requests"
customize: "Customize"
settings: "Settings"
signout: "Sign out"
dark: "Fall in dark"
desktop/views/components/ui.header.nav.vue:
home: "Home"
deck: "Deck"
messaging: "Messages"
game: "Play Othello"
desktop/views/components/ui.header.notifications.vue:
@ -524,7 +543,12 @@ desktop/views/components/ui.header.post.vue:
post: "Compose new Post"
desktop/views/components/ui.header.search.vue:
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"
create-list: "Create list"
desktop/views/components/user-preview.vue:
notes: "Posts"
@ -609,7 +633,6 @@ desktop/views/widgets/polls.vue:
desktop/views/widgets/post-form.vue:
title: "Post"
note: "Post"
placeholder: "What's happening?"
desktop/views/widgets/profile.vue:
update-banner: "Click to edit your banner"
update-avatar: "Click to edit your avatar"
@ -630,13 +653,13 @@ mobile/views/components/drive.vue:
load-more: "Load more"
nothing-in-drive: "Nothing"
folder-is-empty: "This folder is empty"
prompt: "何をしますか?(数字を入力してください): <1 → ファイルをアップロード | 2 → ファイルをURLでアップロード | 3 → フォルダ作成 | 4 → このフォルダ名を変更 | 5 → このフォルダを移動 | 6 → このフォルダを削除>"
prompt: "What do you want to do? (Please enter a number): <1 → Upload a file | 2 → Upload a file from a URL | 3 → Create a folder | 4 → Change this folder's name | 5 → Move this folder | 6 → Delete this folder>"
deletion-alert: "Sorry! Deleting a folder is not yet implemented."
folder-name: "Folder name"
root-rename-alert: "現在いる場所はルートで、フォルダではないため名前の変更はできません。名前を変更したいフォルダに移動してからやってください。"
root-move-alert: "現在いる場所はルートで、フォルダではないため移動はできません。移動したいフォルダに移動してからやってください。"
root-rename-alert: "You're in the root; it can't be renamed because it's not a folder. Navigate to a folder you want to rename and try again."
root-move-alert: "You're in the root; it can't be moved because it's not a folder. Navigate to a folder you want to move and try again."
url-prompt: "URL of file you want to upload"
uploading: "アップロードをリクエストしました。アップロードが完了するまで時間がかかる場合があります。"
uploading: "Upload requested. It may take some time for the upload to complete."
mobile/views/components/drive-file-detail.vue:
rename: "Rename"
mobile/views/components/drive-file-chooser.vue:
@ -650,8 +673,10 @@ mobile/views/components/drive.file-detail.vue:
hash: "Hash (md5)"
exif: "EXIF"
mobile/views/components/follow-button.vue:
following: "Following"
follow: "Follow"
unfollow: "Unfollow"
request-pending: "フォロー許可待ち"
follow-request: "Follow request"
mobile/views/components/friends-maker.vue:
title: "Let's follow users"
empty: "Featured user was not found."
@ -659,7 +684,7 @@ mobile/views/components/friends-maker.vue:
refresh: "See more"
close: "Close"
mobile/views/components/note.vue:
reposted-by: "Renoted by {}"
reposted-by: "Reposted by {}"
more: "See more"
less: "Hide"
private: "this post is private"
@ -668,7 +693,7 @@ mobile/views/components/note.vue:
mobile/views/components/note-detail.vue:
reply: "Reply"
reaction: "Reaction"
reposted-by: "Renoted by {}"
reposted-by: "Reposted by {}"
private: "this post is private"
deleted: "this post has been deleted"
location: "Location"
@ -690,12 +715,11 @@ mobile/views/components/post-form.vue:
add-visible-user: "Add a user"
submit: "Post"
reply: "Reply"
renote: "Renote"
renote-placeholder: "Quote this post. (optional)"
renote: "Repost"
quote-placeholder: "Quote this post... (optional)"
reply-placeholder: "Reply to this note..."
note-placeholder: "What's happening?"
cw-placeholder: "内容への注釈 (オプション)"
location-alert: "お使いの端末は位置情報に対応していません"
cw-placeholder: "Comments about content (optional)"
location-alert: "Your device does not support location services"
error: "Error"
username-prompt: "Enter user name"
mobile/views/components/sub-note-content.vue:
@ -707,11 +731,17 @@ mobile/views/components/timeline.vue:
empty: "No notes"
load-more: "More"
mobile/views/components/ui.nav.vue:
home: "Home"
timeline: "Timeline"
notifications: "Notifications"
messaging: "Messages"
follow-requests: "Follow requests"
search: "Search"
drive: "Drive"
favorites: "Favorites"
user-lists: "Lists"
widgets: "Widgets"
game: "Games"
darkmode: "Dark mode"
settings: "Settings"
about: "About Misskey"
mobile/views/components/user-timeline.vue:
@ -722,8 +752,14 @@ mobile/views/components/users-list.vue:
all: "All"
known: "You know"
load-more: "More"
mobile/views/pages/favorites.vue:
title: "Favorites"
mobile/views/pages/user-lists.vue:
title: "Lists"
enter-list-name: "Enter list name"
mobile/views/pages/drive.vue:
drive: "Drive"
more: "Load more"
mobile/views/pages/followers.vue:
followers-of: "Followers of {}"
mobile/views/pages/following.vue:
@ -736,6 +772,10 @@ mobile/views/pages/messaging.vue:
messaging: "Messaging"
mobile/views/pages/messaging-room.vue:
messaging: "Messaging"
mobile/views/pages/received-follow-requests.vue:
title: "Follow requests"
accept: "Accept"
reject: "Reject"
mobile/views/pages/note.vue:
title: "Post"
prev: "Previous note"
@ -775,8 +815,8 @@ mobile/views/pages/settings.vue:
circle-icons: "Use circle icons"
timeline: "Timeline"
show-reply-target: "Show reply target"
show-my-renotes: "Show my renotes"
show-renoted-my-notes: "Show renoted my notes"
show-my-renotes: "Show my reposts"
show-renoted-my-notes: "Show my reposted posts"
post-style: "Post design"
post-style-standard: "Standard"
post-style-smart: "Smart"

View File

@ -35,12 +35,20 @@ common:
angry: "おこ"
confused: "こまこまのこまり"
pudding: "Pudding"
note-placeholders:
a: "今どうしてる?"
b: "何かありましたか?"
c: "何をお考えですか?"
d: "言いたいことは?"
e: "ここに書いてください"
f: "あなたが書くのを待っています..."
delete: "削除"
loading: "読み込み中"
ok: "わかった"
update-available: "Misskeyの新しいバージョンがあります({newer}。現在{current}を利用中)。ページを再度読み込みすると更新が適用されます。"
my-token-regenerated: "あなたのトークンが更新されたのでサインアウトします。"
widgets:
analog-clock: "アナログ時計"
profile: "プロフィール"
calendar: "カレンダー"
timemachine: "カレンダー(タイムマシン)"
@ -61,6 +69,17 @@ common:
donation: "寄付のお願い"
nav: "ナビゲーション"
tips: "ヒント"
deck:
widgets: "ウィジェット"
home: "ホーム"
local: "ローカル"
global: "グローバル"
notifications: "通知"
list: "リスト"
swap-left: "左に移動"
swap-right: "右に移動"
remove: "カラムを削除"
add-column: "カラムを追加"
common/views/components/connect-failed.vue:
title: "サーバーに接続できません"
description: "インターネット回線に問題があるか、サーバーがダウンまたはメンテナンスしている可能性があります。しばらくしてから{再度お試し}ください。"
@ -282,8 +301,10 @@ desktop/views/components/drive.vue:
upload: "ファイルをアップロード"
url-upload: "URLからアップロード"
desktop/views/components/follow-button.vue:
unfollow: "フォロー解除"
follow: "フォローする"
following: "フォロー"
follow: "フォロー"
request-pending: "フォロー許可待ち"
follow-request: "フォロー申請"
desktop/views/components/followers-window.vue:
followers: "{} のフォロワー"
desktop/views/components/followers.vue:
@ -319,9 +340,6 @@ desktop/views/components/note-detail.vue:
location: "位置情報"
renote: "Renote"
add-reaction: "リアクション"
desktop/views/components/note-detail.sub.vue:
private: "この投稿は非公開です"
deleted: "この投稿は削除されました"
desktop/views/components/notes.note.vue:
reposted-by: "{}がRenote"
reply: "返信"
@ -337,10 +355,9 @@ desktop/views/components/notifications.vue:
more: "もっと見る"
empty: "ありません!"
desktop/views/components/post-form.vue:
note-placeholder: "いまどうしてる?"
reply-placeholder: "この投稿への返信..."
quote-placeholder: "この投稿を引用..."
note: "投稿"
submit: "投稿"
reply: "返信"
renote: "Renote"
posted: "投稿しました!"
@ -472,7 +489,7 @@ desktop/views/components/settings.api.vue:
regenerate-token: "トークンを再生成"
token: "Token:"
enter-password: "パスワードを入力してください"
desktop/views/components/settings.app.vue:
desktop/views/components/settings.apps.vue:
no-apps: "連携しているアプリケーションはありません"
desktop/views/components/settings.mute.vue:
no-users: "ミュートしているユーザーはいません"
@ -510,12 +527,14 @@ desktop/views/components/ui.header.account.vue:
drive: "ドライブ"
favorites: "お気に入り"
lists: "リスト"
follow-requests: "フォロー申請"
customize: "カスタマイズ"
settings: "設定"
signout: "サインアウト"
dark: "闇に飲まれる"
desktop/views/components/ui.header.nav.vue:
home: "ホーム"
deck: "デッキ"
messaging: "メッセージ"
game: "ゲーム"
desktop/views/components/ui.header.notifications.vue:
@ -524,7 +543,12 @@ desktop/views/components/ui.header.post.vue:
post: "新規投稿"
desktop/views/components/ui.header.search.vue:
placeholder: "検索"
desktop/views/components/received-follow-requests-window.vue:
title: "フォロー申請"
accept: "承認"
reject: "拒否"
desktop/views/components/user-lists-window.vue:
title: "リスト"
create-list: "リストを作成"
desktop/views/components/user-preview.vue:
notes: "投稿"
@ -609,7 +633,6 @@ desktop/views/widgets/polls.vue:
desktop/views/widgets/post-form.vue:
title: "投稿"
note: "投稿"
placeholder: "いまどうしてる?"
desktop/views/widgets/profile.vue:
update-banner: "クリックでバナー編集"
update-avatar: "クリックでアバター編集"
@ -650,8 +673,10 @@ mobile/views/components/drive.file-detail.vue:
hash: "ハッシュ (md5)"
exif: "EXIF"
mobile/views/components/follow-button.vue:
following: "フォロー中"
follow: "フォロー"
unfollow: "フォロー解除"
request-pending: "フォロー許可待ち"
follow-request: "フォロー申請"
mobile/views/components/friends-maker.vue:
title: "気になるユーザーをフォロー"
empty: "おすすめのユーザーは見つかりませんでした。"
@ -691,9 +716,8 @@ mobile/views/components/post-form.vue:
submit: "投稿"
reply: "返信"
renote: "Renote"
renote-placeholder: "この投稿を引用... (オプション)"
quote-placeholder: "この投稿を引用... (オプション)"
reply-placeholder: "この投稿への返信..."
note-placeholder: "いまどうしてる?"
cw-placeholder: "内容への注釈 (オプション)"
location-alert: "お使いの端末は位置情報に対応していません"
error: "エラー"
@ -707,11 +731,17 @@ mobile/views/components/timeline.vue:
empty: "投稿がありません"
load-more: "もっと"
mobile/views/components/ui.nav.vue:
home: "ホーム"
timeline: "タイムライン"
notifications: "通知"
messaging: "メッセージ"
follow-requests: "フォロー申請"
search: "検索"
drive: "ドライブ"
favorites: "お気に入り"
user-lists: "リスト"
widgets: "ウィジェット"
game: "ゲーム"
darkmode: "ダークモード"
settings: "設定"
about: "Misskeyについて"
mobile/views/components/user-timeline.vue:
@ -722,8 +752,14 @@ mobile/views/components/users-list.vue:
all: "すべて"
known: "知り合い"
load-more: "もっと"
mobile/views/pages/favorites.vue:
title: "お気に入り"
mobile/views/pages/user-lists.vue:
title: "リスト"
enter-list-name: "リスト名を入力してください"
mobile/views/pages/drive.vue:
drive: "ドライブ"
more: "もっと見る"
mobile/views/pages/followers.vue:
followers-of: "{}のフォロワー"
mobile/views/pages/following.vue:
@ -736,6 +772,10 @@ mobile/views/pages/messaging.vue:
messaging: "メッセージ"
mobile/views/pages/messaging-room.vue:
messaging: "メッセージ"
mobile/views/pages/received-follow-requests.vue:
title: "フォロー申請"
accept: "承認"
reject: "拒否"
mobile/views/pages/note.vue:
title: "投稿"
prev: "前の投稿"

View File

@ -35,12 +35,20 @@ common:
angry: "En Colère"
confused: "Confus"
pudding: "Pudding"
note-placeholders:
a: "今どうしてる?"
b: "何かありましたか?"
c: "何をお考えですか?"
d: "言いたいことは?"
e: "ここに書いてください"
f: "あなたが書くのを待っています..."
delete: "Supprimer"
loading: "Chargement"
ok: "OK"
update-available: "Une nouvelle version de Misskey est disponible({newer}, version actuelle: {current}). Recharger la page pour appliquer la mise à jour."
my-token-regenerated: "Votre token vient d'être généré, vous allez maintenant être déconnecté."
widgets:
analog-clock: "アナログ時計"
profile: "プロフィール"
calendar: "カレンダー"
timemachine: "カレンダー(タイムマシン)"
@ -61,6 +69,17 @@ common:
donation: "寄付のお願い"
nav: "ナビゲーション"
tips: "ヒント"
deck:
widgets: "ウィジェット"
home: "ホーム"
local: "ローカル"
global: "グローバル"
notifications: "通知"
list: "リスト"
swap-left: "左に移動"
swap-right: "右に移動"
remove: "カラムを削除"
add-column: "カラムを追加"
common/views/components/connect-failed.vue:
title: "Impossible de se connecter au server."
description: "Il y a soit un problème avec votre connexion internet, soit le serveur est hors-ligne ou en maintenance. Veuillez {ressayer} plus tard."
@ -282,8 +301,10 @@ desktop/views/components/drive.vue:
upload: "Uploader un fichier"
url-upload: "Uploader d'un URL"
desktop/views/components/follow-button.vue:
unfollow: "フォロー解除"
follow: "フォローする"
following: "フォロー"
follow: "フォロー"
request-pending: "フォロー許可待ち"
follow-request: "フォロー申請"
desktop/views/components/followers-window.vue:
followers: "{} のフォロワー"
desktop/views/components/followers.vue:
@ -319,9 +340,6 @@ desktop/views/components/note-detail.vue:
location: "位置情報"
renote: "Renote"
add-reaction: "リアクション"
desktop/views/components/note-detail.sub.vue:
private: "この投稿は非公開です"
deleted: "この投稿は削除されました"
desktop/views/components/notes.note.vue:
reposted-by: "Reposté par {}"
reply: "Répondre"
@ -337,10 +355,9 @@ desktop/views/components/notifications.vue:
more: "Plus"
empty: "Pas de notifications"
desktop/views/components/post-form.vue:
note-placeholder: "Qu'est-ce qui se passe?"
reply-placeholder: "Répondre à cette note"
quote-placeholder: "Citer cette note"
note: "Poster"
submit: "投稿"
reply: "Répondre"
renote: "Renote"
posted: "Posté!"
@ -472,8 +489,8 @@ desktop/views/components/settings.api.vue:
regenerate-token: "Regenerer le token"
token: "Token:"
enter-password: "Veuillez entrer le mot de passe"
desktop/views/components/settings.app.vue:
no-apps: "Aucune application authorisée"
desktop/views/components/settings.apps.vue:
no-apps: "連携しているアプリケーションはありません"
desktop/views/components/settings.mute.vue:
no-users: "Aucun utilisateurs mis en sourdine"
desktop/views/components/settings.password.vue:
@ -510,12 +527,14 @@ desktop/views/components/ui.header.account.vue:
drive: "Drive"
favorites: "Favorites"
lists: "リスト"
follow-requests: "フォロー申請"
customize: "Modifications"
settings: "Réglages"
signout: "Déconnexion"
dark: "Fall in dark"
desktop/views/components/ui.header.nav.vue:
home: "Accueil"
deck: "デッキ"
messaging: "Messages"
game: "Jeux"
desktop/views/components/ui.header.notifications.vue:
@ -524,7 +543,12 @@ desktop/views/components/ui.header.post.vue:
post: "Composer un nouveau post"
desktop/views/components/ui.header.search.vue:
placeholder: "Chercher"
desktop/views/components/received-follow-requests-window.vue:
title: "フォロー申請"
accept: "承認"
reject: "拒否"
desktop/views/components/user-lists-window.vue:
title: "リスト"
create-list: "リストを作成"
desktop/views/components/user-preview.vue:
notes: "投稿"
@ -609,7 +633,6 @@ desktop/views/widgets/polls.vue:
desktop/views/widgets/post-form.vue:
title: "Post"
note: "Post"
placeholder: "Qu'est-ce qu'il se passe?"
desktop/views/widgets/profile.vue:
update-banner: "クリックでバナー編集"
update-avatar: "クリックでアバター編集"
@ -650,8 +673,10 @@ mobile/views/components/drive.file-detail.vue:
hash: "Hash (md5)"
exif: "EXIF"
mobile/views/components/follow-button.vue:
following: "フォロー中"
follow: "Suivre"
unfollow: "Ne plus suivre"
request-pending: "フォロー許可待ち"
follow-request: "フォロー申請"
mobile/views/components/friends-maker.vue:
title: "気になるユーザーをフォロー"
empty: "おすすめのユーザーは見つかりませんでした。"
@ -691,9 +716,8 @@ mobile/views/components/post-form.vue:
submit: "Poster"
reply: "返信"
renote: "Renote"
renote-placeholder: "この投稿を引用... (オプション)"
quote-placeholder: "この投稿を引用... (オプション)"
reply-placeholder: "Répondre à cette note"
note-placeholder: "Qu'est-ce qu'il se passe?"
cw-placeholder: "内容への注釈 (オプション)"
location-alert: "お使いの端末は位置情報に対応していません"
error: "エラー"
@ -707,11 +731,17 @@ mobile/views/components/timeline.vue:
empty: "Pas de notes"
load-more: "Afficher plus"
mobile/views/components/ui.nav.vue:
home: "Accueil"
timeline: "タイムライン"
notifications: "Notifications"
messaging: "Messages"
follow-requests: "フォロー申請"
search: "Rechercher"
drive: "Drive"
favorites: "お気に入り"
user-lists: "リスト"
widgets: "ウィジェット"
game: "ゲーム"
darkmode: "ダークモード"
settings: "Réglages"
about: "À propose de Misskey"
mobile/views/components/user-timeline.vue:
@ -722,8 +752,14 @@ mobile/views/components/users-list.vue:
all: "Tout"
known: "Vous connaissez"
load-more: "Afficher plus"
mobile/views/pages/favorites.vue:
title: "お気に入り"
mobile/views/pages/user-lists.vue:
title: "リスト"
enter-list-name: "リスト名を入力してください"
mobile/views/pages/drive.vue:
drive: "Drive"
more: "もっと見る"
mobile/views/pages/followers.vue:
followers-of: "Abonnés de {}"
mobile/views/pages/following.vue:
@ -736,6 +772,10 @@ mobile/views/pages/messaging.vue:
messaging: "Messagerie"
mobile/views/pages/messaging-room.vue:
messaging: "Messagerie"
mobile/views/pages/received-follow-requests.vue:
title: "フォロー申請"
accept: "承認"
reject: "拒否"
mobile/views/pages/note.vue:
title: "Post"
prev: "Note précedante"

View File

@ -35,12 +35,20 @@ common:
angry: "おこ"
confused: "こまこまのこまり"
pudding: "Pudding"
note-placeholders:
a: "今どうしてる?"
b: "何かありましたか?"
c: "何をお考えですか?"
d: "言いたいことは?"
e: "ここに書いてください"
f: "あなたが書くのを待っています..."
delete: "削除"
loading: "読み込み中"
ok: "わかった"
update-available: "Misskeyの新しいバージョンがあります({newer}。現在{current}を利用中)。ページを再度読み込みすると更新が適用されます。"
my-token-regenerated: "あなたのトークンが更新されたのでサインアウトします。"
widgets:
analog-clock: "アナログ時計"
profile: "プロフィール"
calendar: "カレンダー"
timemachine: "カレンダー(タイムマシン)"
@ -61,6 +69,17 @@ common:
donation: "寄付のお願い"
nav: "ナビゲーション"
tips: "ヒント"
deck:
widgets: "ウィジェット"
home: "ホーム"
local: "ローカル"
global: "グローバル"
notifications: "通知"
list: "リスト"
swap-left: "左に移動"
swap-right: "右に移動"
remove: "カラムを削除"
add-column: "カラムを追加"
common/views/components/connect-failed.vue:
title: "サーバーに接続できません"
description: "インターネット回線に問題があるか、サーバーがダウンまたはメンテナンスしている可能性があります。しばらくしてから{再度お試し}ください。"
@ -282,8 +301,10 @@ desktop/views/components/drive.vue:
upload: "ファイルをアップロード"
url-upload: "URLからアップロード"
desktop/views/components/follow-button.vue:
unfollow: "フォロー解除"
follow: "フォローする"
following: "フォロー"
follow: "フォロー"
request-pending: "フォロー許可待ち"
follow-request: "フォロー申請"
desktop/views/components/followers-window.vue:
followers: "{} のフォロワー"
desktop/views/components/followers.vue:
@ -319,9 +340,6 @@ desktop/views/components/note-detail.vue:
location: "位置情報"
renote: "Renote"
add-reaction: "リアクション"
desktop/views/components/note-detail.sub.vue:
private: "この投稿は非公開です"
deleted: "この投稿は削除されました"
desktop/views/components/notes.note.vue:
reposted-by: "{}がRenote"
reply: "返信"
@ -337,10 +355,9 @@ desktop/views/components/notifications.vue:
more: "もっと見る"
empty: "ありません!"
desktop/views/components/post-form.vue:
note-placeholder: "いまどうしてる?"
reply-placeholder: "この投稿への返信..."
quote-placeholder: "この投稿を引用..."
note: "投稿"
submit: "投稿"
reply: "返信"
renote: "Renote"
posted: "投稿しました!"
@ -472,7 +489,7 @@ desktop/views/components/settings.api.vue:
regenerate-token: "トークンを再生成"
token: "Token:"
enter-password: "パスワードを入力してください"
desktop/views/components/settings.app.vue:
desktop/views/components/settings.apps.vue:
no-apps: "連携しているアプリケーションはありません"
desktop/views/components/settings.mute.vue:
no-users: "ミュートしているユーザーはいません"
@ -510,12 +527,14 @@ desktop/views/components/ui.header.account.vue:
drive: "ドライブ"
favorites: "お気に入り"
lists: "リスト"
follow-requests: "フォロー申請"
customize: "カスタマイズ"
settings: "設定"
signout: "サインアウト"
dark: "闇に飲まれる"
desktop/views/components/ui.header.nav.vue:
home: "ホーム"
deck: "デッキ"
messaging: "メッセージ"
game: "ゲーム"
desktop/views/components/ui.header.notifications.vue:
@ -524,7 +543,12 @@ desktop/views/components/ui.header.post.vue:
post: "新規投稿"
desktop/views/components/ui.header.search.vue:
placeholder: "検索"
desktop/views/components/received-follow-requests-window.vue:
title: "フォロー申請"
accept: "承認"
reject: "拒否"
desktop/views/components/user-lists-window.vue:
title: "リスト"
create-list: "リストを作成"
desktop/views/components/user-preview.vue:
notes: "投稿"
@ -609,7 +633,6 @@ desktop/views/widgets/polls.vue:
desktop/views/widgets/post-form.vue:
title: "投稿"
note: "投稿"
placeholder: "いまどうしてる?"
desktop/views/widgets/profile.vue:
update-banner: "クリックでバナー編集"
update-avatar: "クリックでアバター編集"
@ -650,8 +673,10 @@ mobile/views/components/drive.file-detail.vue:
hash: "ハッシュ (md5)"
exif: "EXIF"
mobile/views/components/follow-button.vue:
following: "フォロー中"
follow: "フォロー"
unfollow: "フォロー解除"
request-pending: "フォロー許可待ち"
follow-request: "フォロー申請"
mobile/views/components/friends-maker.vue:
title: "気になるユーザーをフォロー"
empty: "おすすめのユーザーは見つかりませんでした。"
@ -691,9 +716,8 @@ mobile/views/components/post-form.vue:
submit: "投稿"
reply: "返信"
renote: "Renote"
renote-placeholder: "この投稿を引用... (オプション)"
quote-placeholder: "この投稿を引用... (オプション)"
reply-placeholder: "この投稿への返信..."
note-placeholder: "いまどうしてる?"
cw-placeholder: "内容への注釈 (オプション)"
location-alert: "お使いの端末は位置情報に対応していません"
error: "エラー"
@ -707,11 +731,17 @@ mobile/views/components/timeline.vue:
empty: "投稿がありません"
load-more: "もっと"
mobile/views/components/ui.nav.vue:
home: "ホーム"
timeline: "タイムライン"
notifications: "通知"
messaging: "メッセージ"
follow-requests: "フォロー申請"
search: "検索"
drive: "ドライブ"
favorites: "お気に入り"
user-lists: "リスト"
widgets: "ウィジェット"
game: "ゲーム"
darkmode: "ダークモード"
settings: "設定"
about: "Misskeyについて"
mobile/views/components/user-timeline.vue:
@ -722,8 +752,14 @@ mobile/views/components/users-list.vue:
all: "すべて"
known: "知り合い"
load-more: "もっと"
mobile/views/pages/favorites.vue:
title: "お気に入り"
mobile/views/pages/user-lists.vue:
title: "リスト"
enter-list-name: "リスト名を入力してください"
mobile/views/pages/drive.vue:
drive: "ドライブ"
more: "もっと見る"
mobile/views/pages/followers.vue:
followers-of: "{}のフォロワー"
mobile/views/pages/following.vue:
@ -736,6 +772,10 @@ mobile/views/pages/messaging.vue:
messaging: "メッセージ"
mobile/views/pages/messaging-room.vue:
messaging: "メッセージ"
mobile/views/pages/received-follow-requests.vue:
title: "フォロー申請"
accept: "承認"
reject: "拒否"
mobile/views/pages/note.vue:
title: "投稿"
prev: "前の投稿"

View File

@ -39,6 +39,14 @@ common:
confused: "こまこまのこまり"
pudding: "Pudding"
note-placeholders:
a: "今どうしてる?"
b: "何かありましたか?"
c: "何をお考えですか?"
d: "言いたいことは?"
e: "ここに書いてください"
f: "あなたが書くのを待っています..."
delete: "削除"
loading: "読み込み中"
ok: "わかった"
@ -46,6 +54,7 @@ common:
my-token-regenerated: "あなたのトークンが更新されたのでサインアウトします。"
widgets:
analog-clock: "アナログ時計"
profile: "プロフィール"
calendar: "カレンダー"
timemachine: "カレンダー(タイムマシン)"
@ -67,6 +76,19 @@ common:
nav: "ナビゲーション"
tips: "ヒント"
deck:
widgets: "ウィジェット"
home: "ホーム"
local: "ローカル"
global: "グローバル"
notifications: "通知"
list: "リスト"
swap-left: "左に移動"
swap-right: "右に移動"
remove: "カラムを削除"
add-column: "カラムを追加"
rename: "名前を変更"
common/views/components/connect-failed.vue:
title: "サーバーに接続できません"
description: "インターネット回線に問題があるか、サーバーがダウンまたはメンテナンスしている可能性があります。しばらくしてから{再度お試し}ください。"
@ -322,8 +344,10 @@ desktop/views/components/drive.vue:
url-upload: "URLからアップロード"
desktop/views/components/follow-button.vue:
unfollow: "フォロー解除"
follow: "フォローする"
following: "フォロー"
follow: "フォロー"
request-pending: "フォロー許可待ち"
follow-request: "フォロー申請"
desktop/views/components/followers-window.vue:
followers: "{} のフォロワー"
@ -371,10 +395,6 @@ desktop/views/components/note-detail.vue:
renote: "Renote"
add-reaction: "リアクション"
desktop/views/components/note-detail.sub.vue:
private: "この投稿は非公開です"
deleted: "この投稿は削除されました"
desktop/views/components/notes.note.vue:
reposted-by: "{}がRenote"
reply: "返信"
@ -393,10 +413,9 @@ desktop/views/components/notifications.vue:
empty: "ありません!"
desktop/views/components/post-form.vue:
note-placeholder: "いまどうしてる?"
reply-placeholder: "この投稿への返信..."
quote-placeholder: "この投稿を引用..."
note: "投稿"
submit: "投稿"
reply: "返信"
renote: "Renote"
posted: "投稿しました!"
@ -547,7 +566,7 @@ desktop/views/components/settings.api.vue:
token: "Token:"
enter-password: "パスワードを入力してください"
desktop/views/components/settings.app.vue:
desktop/views/components/settings.apps.vue:
no-apps: "連携しているアプリケーションはありません"
desktop/views/components/settings.mute.vue:
@ -592,6 +611,7 @@ desktop/views/components/ui.header.account.vue:
drive: "ドライブ"
favorites: "お気に入り"
lists: "リスト"
follow-requests: "フォロー申請"
customize: "カスタマイズ"
settings: "設定"
signout: "サインアウト"
@ -599,6 +619,7 @@ desktop/views/components/ui.header.account.vue:
desktop/views/components/ui.header.nav.vue:
home: "ホーム"
deck: "デッキ"
messaging: "メッセージ"
game: "ゲーム"
@ -611,7 +632,13 @@ desktop/views/components/ui.header.post.vue:
desktop/views/components/ui.header.search.vue:
placeholder: "検索"
desktop/views/components/received-follow-requests-window.vue:
title: "フォロー申請"
accept: "承認"
reject: "拒否"
desktop/views/components/user-lists-window.vue:
title: "リスト"
create-list: "リストを作成"
desktop/views/components/user-preview.vue:
@ -718,7 +745,6 @@ desktop/views/widgets/polls.vue:
desktop/views/widgets/post-form.vue:
title: "投稿"
note: "投稿"
placeholder: "いまどうしてる?"
desktop/views/widgets/profile.vue:
update-banner: "クリックでバナー編集"
@ -768,8 +794,10 @@ mobile/views/components/drive.file-detail.vue:
exif: "EXIF"
mobile/views/components/follow-button.vue:
following: "フォロー中"
follow: "フォロー"
unfollow: "フォロー解除"
request-pending: "フォロー許可待ち"
follow-request: "フォロー申請"
mobile/views/components/friends-maker.vue:
title: "気になるユーザーをフォロー"
@ -817,9 +845,8 @@ mobile/views/components/post-form.vue:
submit: "投稿"
reply: "返信"
renote: "Renote"
renote-placeholder: "この投稿を引用... (オプション)"
quote-placeholder: "この投稿を引用... (オプション)"
reply-placeholder: "この投稿への返信..."
note-placeholder: "いまどうしてる?"
cw-placeholder: "内容への注釈 (オプション)"
location-alert: "お使いの端末は位置情報に対応していません"
error: "エラー"
@ -836,11 +863,17 @@ mobile/views/components/timeline.vue:
load-more: "もっと"
mobile/views/components/ui.nav.vue:
home: "ホーム"
timeline: "タイムライン"
notifications: "通知"
messaging: "メッセージ"
follow-requests: "フォロー申請"
search: "検索"
drive: "ドライブ"
favorites: "お気に入り"
user-lists: "リスト"
widgets: "ウィジェット"
game: "ゲーム"
darkmode: "ダークモード"
settings: "設定"
about: "Misskeyについて"
@ -854,8 +887,16 @@ mobile/views/components/users-list.vue:
known: "知り合い"
load-more: "もっと"
mobile/views/pages/favorites.vue:
title: "お気に入り"
mobile/views/pages/user-lists.vue:
title: "リスト"
enter-list-name: "リスト名を入力してください"
mobile/views/pages/drive.vue:
drive: "ドライブ"
more: "もっと見る"
mobile/views/pages/followers.vue:
followers-of: "{}のフォロワー"
@ -874,6 +915,11 @@ mobile/views/pages/messaging.vue:
mobile/views/pages/messaging-room.vue:
messaging: "メッセージ"
mobile/views/pages/received-follow-requests.vue:
title: "フォロー申請"
accept: "承認"
reject: "拒否"
mobile/views/pages/note.vue:
title: "投稿"
prev: "前の投稿"

View File

@ -35,12 +35,20 @@ common:
angry: "おこ"
confused: "こまこまのこまり"
pudding: "Pudding"
note-placeholders:
a: "今どうしてる?"
b: "何かありましたか?"
c: "何をお考えですか?"
d: "言いたいことは?"
e: "ここに書いてください"
f: "あなたが書くのを待っています..."
delete: "削除"
loading: "読み込み中"
ok: "わかった"
update-available: "Misskeyの新しいバージョンがあります({newer}。現在{current}を利用中)。ページを再度読み込みすると更新が適用されます。"
my-token-regenerated: "あなたのトークンが更新されたのでサインアウトします。"
widgets:
analog-clock: "アナログ時計"
profile: "プロフィール"
calendar: "カレンダー"
timemachine: "カレンダー(タイムマシン)"
@ -61,6 +69,17 @@ common:
donation: "寄付のお願い"
nav: "ナビゲーション"
tips: "ヒント"
deck:
widgets: "ウィジェット"
home: "ホーム"
local: "ローカル"
global: "グローバル"
notifications: "通知"
list: "リスト"
swap-left: "左に移動"
swap-right: "右に移動"
remove: "カラムを削除"
add-column: "カラムを追加"
common/views/components/connect-failed.vue:
title: "サーバーに接続できません"
description: "インターネット回線に問題があるか、サーバーがダウンまたはメンテナンスしている可能性があります。しばらくしてから{再度お試し}ください。"
@ -282,8 +301,10 @@ desktop/views/components/drive.vue:
upload: "ファイルをアップロード"
url-upload: "URLからアップロード"
desktop/views/components/follow-button.vue:
unfollow: "フォロー解除"
follow: "フォローする"
following: "フォロー"
follow: "フォロー"
request-pending: "フォロー許可待ち"
follow-request: "フォロー申請"
desktop/views/components/followers-window.vue:
followers: "{} のフォロワー"
desktop/views/components/followers.vue:
@ -319,9 +340,6 @@ desktop/views/components/note-detail.vue:
location: "位置情報"
renote: "Renote"
add-reaction: "リアクション"
desktop/views/components/note-detail.sub.vue:
private: "この投稿は非公開です"
deleted: "この投稿は削除されました"
desktop/views/components/notes.note.vue:
reposted-by: "{}がRenote"
reply: "返信"
@ -337,10 +355,9 @@ desktop/views/components/notifications.vue:
more: "もっと見る"
empty: "ありません!"
desktop/views/components/post-form.vue:
note-placeholder: "いまどうしてる?"
reply-placeholder: "この投稿への返信..."
quote-placeholder: "この投稿を引用..."
note: "投稿"
submit: "投稿"
reply: "返信"
renote: "Renote"
posted: "投稿しました!"
@ -472,7 +489,7 @@ desktop/views/components/settings.api.vue:
regenerate-token: "トークンを再生成"
token: "Token:"
enter-password: "パスワードを入力してください"
desktop/views/components/settings.app.vue:
desktop/views/components/settings.apps.vue:
no-apps: "連携しているアプリケーションはありません"
desktop/views/components/settings.mute.vue:
no-users: "ミュートしているユーザーはいません"
@ -510,12 +527,14 @@ desktop/views/components/ui.header.account.vue:
drive: "ドライブ"
favorites: "お気に入り"
lists: "リスト"
follow-requests: "フォロー申請"
customize: "カスタマイズ"
settings: "設定"
signout: "サインアウト"
dark: "闇に飲まれる"
desktop/views/components/ui.header.nav.vue:
home: "ホーム"
deck: "デッキ"
messaging: "メッセージ"
game: "ゲーム"
desktop/views/components/ui.header.notifications.vue:
@ -524,7 +543,12 @@ desktop/views/components/ui.header.post.vue:
post: "新規投稿"
desktop/views/components/ui.header.search.vue:
placeholder: "検索"
desktop/views/components/received-follow-requests-window.vue:
title: "フォロー申請"
accept: "承認"
reject: "拒否"
desktop/views/components/user-lists-window.vue:
title: "リスト"
create-list: "リストを作成"
desktop/views/components/user-preview.vue:
notes: "投稿"
@ -609,7 +633,6 @@ desktop/views/widgets/polls.vue:
desktop/views/widgets/post-form.vue:
title: "投稿"
note: "投稿"
placeholder: "いまどうしてる?"
desktop/views/widgets/profile.vue:
update-banner: "クリックでバナー編集"
update-avatar: "クリックでアバター編集"
@ -650,8 +673,10 @@ mobile/views/components/drive.file-detail.vue:
hash: "ハッシュ (md5)"
exif: "EXIF"
mobile/views/components/follow-button.vue:
following: "フォロー中"
follow: "フォロー"
unfollow: "フォロー解除"
request-pending: "フォロー許可待ち"
follow-request: "フォロー申請"
mobile/views/components/friends-maker.vue:
title: "気になるユーザーをフォロー"
empty: "おすすめのユーザーは見つかりませんでした。"
@ -691,9 +716,8 @@ mobile/views/components/post-form.vue:
submit: "投稿"
reply: "返信"
renote: "Renote"
renote-placeholder: "この投稿を引用... (オプション)"
quote-placeholder: "この投稿を引用... (オプション)"
reply-placeholder: "この投稿への返信..."
note-placeholder: "いまどうしてる?"
cw-placeholder: "内容への注釈 (オプション)"
location-alert: "お使いの端末は位置情報に対応していません"
error: "エラー"
@ -707,11 +731,17 @@ mobile/views/components/timeline.vue:
empty: "投稿がありません"
load-more: "もっと"
mobile/views/components/ui.nav.vue:
home: "ホーム"
timeline: "タイムライン"
notifications: "通知"
messaging: "メッセージ"
follow-requests: "フォロー申請"
search: "検索"
drive: "ドライブ"
favorites: "お気に入り"
user-lists: "リスト"
widgets: "ウィジェット"
game: "ゲーム"
darkmode: "ダークモード"
settings: "設定"
about: "Misskeyについて"
mobile/views/components/user-timeline.vue:
@ -722,8 +752,14 @@ mobile/views/components/users-list.vue:
all: "すべて"
known: "知り合い"
load-more: "もっと"
mobile/views/pages/favorites.vue:
title: "お気に入り"
mobile/views/pages/user-lists.vue:
title: "リスト"
enter-list-name: "リスト名を入力してください"
mobile/views/pages/drive.vue:
drive: "ドライブ"
more: "もっと見る"
mobile/views/pages/followers.vue:
followers-of: "{}のフォロワー"
mobile/views/pages/following.vue:
@ -736,6 +772,10 @@ mobile/views/pages/messaging.vue:
messaging: "メッセージ"
mobile/views/pages/messaging-room.vue:
messaging: "メッセージ"
mobile/views/pages/received-follow-requests.vue:
title: "フォロー申請"
accept: "承認"
reject: "拒否"
mobile/views/pages/note.vue:
title: "投稿"
prev: "前の投稿"

View File

@ -3,8 +3,8 @@ meta:
lang: "język polski"
divider: ""
common:
misskey: "A planet of fediverse"
about-title: "A ⭐ of fediverse."
misskey: "Planeta Fediwersum"
about-title: "⭐ Fediwersum"
about: "Misskeyを見つけていただき、ありがとうございます。Misskeyは、地球で生まれた<b>分散マイクロブログSNS</b>です。Fediverse(様々なSNSで構成される宇宙)の中に存在するため、他のSNSと相互に繋がっています。暫し都会の喧騒から離れて、新しいインターネットにダイブしてみませんか。"
time:
unknown: "nieznany"
@ -35,12 +35,20 @@ common:
angry: "Wściekły"
confused: "Zmieszany"
pudding: "Pudding"
note-placeholders:
a: "Co robisz?"
b: "Co się wydarzyło?"
c: "Co Ci chodzi po głowie?"
d: "Czy masz coś do powiedzenia?"
e: "Napisz coś tutaj!"
f: "Czekamy, aż coś napiszesz."
delete: "Usuń"
loading: "Ładowanie"
ok: "OK"
update-available: "Nowa wersja Misskey jest dostępna ({newer}, obecna to {current}). Odśwież stronę, aby zastosować aktualizację."
my-token-regenerated: "Twój token został wygenerowany. Zostaniesz wylogowany."
widgets:
analog-clock: "Zegar analogowy"
profile: "Profil"
calendar: "Kalendarz"
timemachine: "Kalendarz (wehikuł czasu)"
@ -61,6 +69,17 @@ common:
donation: "Dotacje"
nav: "Nawigacja"
tips: "Wskazówki"
deck:
widgets: "ウィジェット"
home: "ホーム"
local: "ローカル"
global: "グローバル"
notifications: "通知"
list: "リスト"
swap-left: "左に移動"
swap-right: "右に移動"
remove: "カラムを削除"
add-column: "カラムを追加"
common/views/components/connect-failed.vue:
title: "Nie udało się połączyć z serwerem"
description: "Wystąpił problem z Twoim połączeniem z Internetem, lub z serwerem. {Spróbuj ponownie} wkrótce."
@ -282,8 +301,10 @@ desktop/views/components/drive.vue:
upload: "Wyślij plik"
url-upload: "Wyślij z adresu URL"
desktop/views/components/follow-button.vue:
unfollow: "Przestań śledzić"
following: "フォロー中"
follow: "Śledź"
request-pending: "Oczekiwanie na pozwolenie"
follow-request: "Poproś o śledzenie"
desktop/views/components/followers-window.vue:
followers: "Śledzący"
desktop/views/components/followers.vue:
@ -319,9 +340,6 @@ desktop/views/components/note-detail.vue:
location: "Informacje o lokalizacji"
renote: "Udostępnienie"
add-reaction: "Dodaj reakcję"
desktop/views/components/note-detail.sub.vue:
private: "ten wpis jest prywatny"
deleted: "ten wpis został usunięty"
desktop/views/components/notes.note.vue:
reposted-by: "Udostępniono przez {}"
reply: "Odpowiedz"
@ -337,10 +355,9 @@ desktop/views/components/notifications.vue:
more: "Więcej"
empty: "Brak powiadomień"
desktop/views/components/post-form.vue:
note-placeholder: "Co się dzieje?"
reply-placeholder: "Odpowiedz na ten wpis…"
quote-placeholder: "Zacytuj ten wpis…"
note: "Wyślij"
submit: "Wyślij"
reply: "Odpowiedz"
renote: "Udostępnienie"
posted: "Opublikowano!"
@ -423,7 +440,7 @@ desktop/views/components/settings.vue:
cache-warn: "Pamięć podręczna informacji o koncie/wpisów/odpowiedzi/wiadomości/ustawień przechowywanych w przeglądarce zostanie usunięta. Będziesz musiał odświeżyć stronę po wyczyszczeniu."
cache-cleared: "Wyczyszczono pamięć podręczną"
cache-cleared-desc: "Proszę odświeżyć stronę."
auto-watch: "投稿の自動ウォッチ"
auto-watch: "Automatycznie nasłuchuj"
auto-watch-desc: "Otrzymuj natychmiastowo informacje o wpisach/odpowiedziach/reakcjach."
about: "O Misskey"
operator: "Administrator instancji"
@ -466,13 +483,13 @@ desktop/views/components/settings.2fa.vue:
failed: "Nie udało się skonfigurować uwierzytelniania dwuetapowego, upewnij się że wprowadziłeś prawidłowy token."
info: "Od teraz, wprowadzaj token wyświetlany na urządzeniu przy każdym logowaniu do Misskey."
desktop/views/components/settings.api.vue:
intro: "APIを利用するには、上記のトークンを「i」というキーでパラメータに付加してリクエストします。"
intro: "Aby uzyskać dostęp do API, ustaw ten token jako klucz 'i' parametrów żądań."
caution: "Nie pokazuj tego tokenu osobom trzecim (nie wprowadzaj go nigdzie indziej), aby konto nie trafiło w niepowołane ręce."
regeneration-of-token: "W przypadku wycieku tokenu, możesz wygenerować nowy."
regenerate-token: "Wygeneruj nowy token"
token: "Token:"
enter-password: "Wprowadź hasło"
desktop/views/components/settings.app.vue:
desktop/views/components/settings.apps.vue:
no-apps: "Brak zautoryzowanych aplikacji"
desktop/views/components/settings.mute.vue:
no-users: "Brak wyciszonych użytkowników"
@ -510,12 +527,14 @@ desktop/views/components/ui.header.account.vue:
drive: "Dysk"
favorites: "Ulubione"
lists: "Listy"
follow-requests: "Prośby o śledzenie"
customize: "Dostosuj"
settings: "Ustawienia"
signout: "Wyloguj się"
dark: "Sprowadź ciemność"
desktop/views/components/ui.header.nav.vue:
home: "Strona główna"
deck: "デッキ"
messaging: "Wiadomości"
game: "Gra"
desktop/views/components/ui.header.notifications.vue:
@ -524,7 +543,12 @@ desktop/views/components/ui.header.post.vue:
post: "Utwórz nowy wpis"
desktop/views/components/ui.header.search.vue:
placeholder: "Szukaj"
desktop/views/components/received-follow-requests-window.vue:
title: "Poproś o śledzenie"
accept: "Zatwierdź"
reject: "Odmów"
desktop/views/components/user-lists-window.vue:
title: "Listy"
create-list: "Utwórz listę"
desktop/views/components/user-preview.vue:
notes: "Wpisy"
@ -541,8 +565,8 @@ desktop/views/components/window.vue:
popout: "Pop-out"
close: "Zamknij"
desktop/views/pages/welcome.vue:
about: "詳しく..."
gotit: "わかった"
about: "O Misskey"
gotit: "Rozumiem!"
signin: "Zaloguj się"
signup: "Zarejestruj się"
signin-button: "Zaloguj się"
@ -609,7 +633,6 @@ desktop/views/widgets/polls.vue:
desktop/views/widgets/post-form.vue:
title: "Wpis"
note: "Wpis"
placeholder: "Co się dzieje?"
desktop/views/widgets/profile.vue:
update-banner: "Naciśnij, aby zmienić baner"
update-avatar: "Naciśnij, aby zmienić awatar"
@ -650,8 +673,10 @@ mobile/views/components/drive.file-detail.vue:
hash: "Hash (md5)"
exif: "EXIF"
mobile/views/components/follow-button.vue:
following: "フォロー中"
follow: "Śledź"
unfollow: "Przestań śledzić"
request-pending: "Oczekiwanie na pozwolenie"
follow-request: "Poproś o śledzenie"
mobile/views/components/friends-maker.vue:
title: "Zacznij śledzić ludzi takich jak Ty"
empty: "Nie znaleziono podobnych użytkowników."
@ -691,9 +716,8 @@ mobile/views/components/post-form.vue:
submit: "Wyślij"
reply: "Odpowiedz"
renote: "Udostępnij"
renote-placeholder: "Zacytuj wpis… (nieobowiązkowe)"
quote-placeholder: "Zacytuj ten wpis… (nieobowiązkowe)"
reply-placeholder: "Odpowiedź na ten wpis…"
note-placeholder: "Co się dzieje?"
cw-placeholder: "Treść ostrzeżenia (opcjonalnie)"
location-alert: "Twoje urządzenie nie pozwala na przekazywanie informacji o lokalizacji"
error: "Błąd"
@ -707,11 +731,17 @@ mobile/views/components/timeline.vue:
empty: "Brak wpisów"
load-more: "Więcej"
mobile/views/components/ui.nav.vue:
home: "Strona główna"
timeline: "Oś czasu"
notifications: "Powiadomienia"
messaging: "Wiadomości"
follow-requests: "Prośby o śledzenie"
search: "Szukaj"
drive: "Dysk"
favorites: "Ulubione"
user-lists: "Listy"
widgets: "Widżety"
game: "Gry"
darkmode: "Tryb ciemny"
settings: "Ustawienia"
about: "O Misskey"
mobile/views/components/user-timeline.vue:
@ -722,8 +752,14 @@ mobile/views/components/users-list.vue:
all: "Wszyscy"
known: "Znasz"
load-more: "Więcej"
mobile/views/pages/favorites.vue:
title: "Ulubione"
mobile/views/pages/user-lists.vue:
title: "Listy"
enter-list-name: "Wprowadź nazwę listy"
mobile/views/pages/drive.vue:
drive: "Dysk"
more: "Załaduj więcej"
mobile/views/pages/followers.vue:
followers-of: "Śledzący {}"
mobile/views/pages/following.vue:
@ -736,6 +772,10 @@ mobile/views/pages/messaging.vue:
messaging: "Wiadomości"
mobile/views/pages/messaging-room.vue:
messaging: "Wiadomości"
mobile/views/pages/received-follow-requests.vue:
title: "Prośby o śledzenie"
accept: "Zatwierdź"
reject: "Odmów"
mobile/views/pages/note.vue:
title: "Wpis"
prev: "Poprzedni wpis"
@ -779,7 +819,7 @@ mobile/views/pages/settings.vue:
show-renoted-my-notes: "Pokazuj udostępnienia moich wpisów"
post-style: "Styl wpisów"
post-style-standard: "Standardowy"
post-style-smart: "スマート"
post-style-smart: "Inteligentny"
behavior: "Zachowanie"
fetch-on-scroll: "Automatycznie ładuj po przeciągnięciu w dół"
disable-via-mobile: "Nie oznaczaj wpisów jako „wysłane z telefonu”"

View File

@ -35,12 +35,20 @@ common:
angry: "おこ"
confused: "こまこまのこまり"
pudding: "Pudding"
note-placeholders:
a: "今どうしてる?"
b: "何かありましたか?"
c: "何をお考えですか?"
d: "言いたいことは?"
e: "ここに書いてください"
f: "あなたが書くのを待っています..."
delete: "削除"
loading: "読み込み中"
ok: "わかった"
update-available: "Misskeyの新しいバージョンがあります({newer}。現在{current}を利用中)。ページを再度読み込みすると更新が適用されます。"
my-token-regenerated: "あなたのトークンが更新されたのでサインアウトします。"
widgets:
analog-clock: "アナログ時計"
profile: "プロフィール"
calendar: "カレンダー"
timemachine: "カレンダー(タイムマシン)"
@ -61,6 +69,17 @@ common:
donation: "寄付のお願い"
nav: "ナビゲーション"
tips: "ヒント"
deck:
widgets: "ウィジェット"
home: "ホーム"
local: "ローカル"
global: "グローバル"
notifications: "通知"
list: "リスト"
swap-left: "左に移動"
swap-right: "右に移動"
remove: "カラムを削除"
add-column: "カラムを追加"
common/views/components/connect-failed.vue:
title: "サーバーに接続できません"
description: "インターネット回線に問題があるか、サーバーがダウンまたはメンテナンスしている可能性があります。しばらくしてから{再度お試し}ください。"
@ -282,8 +301,10 @@ desktop/views/components/drive.vue:
upload: "ファイルをアップロード"
url-upload: "URLからアップロード"
desktop/views/components/follow-button.vue:
unfollow: "フォロー解除"
follow: "フォローする"
following: "フォロー"
follow: "フォロー"
request-pending: "フォロー許可待ち"
follow-request: "フォロー申請"
desktop/views/components/followers-window.vue:
followers: "{} のフォロワー"
desktop/views/components/followers.vue:
@ -319,9 +340,6 @@ desktop/views/components/note-detail.vue:
location: "位置情報"
renote: "Renote"
add-reaction: "リアクション"
desktop/views/components/note-detail.sub.vue:
private: "この投稿は非公開です"
deleted: "この投稿は削除されました"
desktop/views/components/notes.note.vue:
reposted-by: "{}がRenote"
reply: "返信"
@ -337,10 +355,9 @@ desktop/views/components/notifications.vue:
more: "もっと見る"
empty: "ありません!"
desktop/views/components/post-form.vue:
note-placeholder: "いまどうしてる?"
reply-placeholder: "この投稿への返信..."
quote-placeholder: "この投稿を引用..."
note: "投稿"
submit: "投稿"
reply: "返信"
renote: "Renote"
posted: "投稿しました!"
@ -472,7 +489,7 @@ desktop/views/components/settings.api.vue:
regenerate-token: "トークンを再生成"
token: "Token:"
enter-password: "パスワードを入力してください"
desktop/views/components/settings.app.vue:
desktop/views/components/settings.apps.vue:
no-apps: "連携しているアプリケーションはありません"
desktop/views/components/settings.mute.vue:
no-users: "ミュートしているユーザーはいません"
@ -510,12 +527,14 @@ desktop/views/components/ui.header.account.vue:
drive: "ドライブ"
favorites: "お気に入り"
lists: "リスト"
follow-requests: "フォロー申請"
customize: "カスタマイズ"
settings: "設定"
signout: "サインアウト"
dark: "闇に飲まれる"
desktop/views/components/ui.header.nav.vue:
home: "ホーム"
deck: "デッキ"
messaging: "メッセージ"
game: "ゲーム"
desktop/views/components/ui.header.notifications.vue:
@ -524,7 +543,12 @@ desktop/views/components/ui.header.post.vue:
post: "新規投稿"
desktop/views/components/ui.header.search.vue:
placeholder: "検索"
desktop/views/components/received-follow-requests-window.vue:
title: "フォロー申請"
accept: "承認"
reject: "拒否"
desktop/views/components/user-lists-window.vue:
title: "リスト"
create-list: "リストを作成"
desktop/views/components/user-preview.vue:
notes: "投稿"
@ -609,7 +633,6 @@ desktop/views/widgets/polls.vue:
desktop/views/widgets/post-form.vue:
title: "投稿"
note: "投稿"
placeholder: "いまどうしてる?"
desktop/views/widgets/profile.vue:
update-banner: "クリックでバナー編集"
update-avatar: "クリックでアバター編集"
@ -650,8 +673,10 @@ mobile/views/components/drive.file-detail.vue:
hash: "ハッシュ (md5)"
exif: "EXIF"
mobile/views/components/follow-button.vue:
following: "フォロー中"
follow: "フォロー"
unfollow: "フォロー解除"
request-pending: "フォロー許可待ち"
follow-request: "フォロー申請"
mobile/views/components/friends-maker.vue:
title: "気になるユーザーをフォロー"
empty: "おすすめのユーザーは見つかりませんでした。"
@ -691,9 +716,8 @@ mobile/views/components/post-form.vue:
submit: "投稿"
reply: "返信"
renote: "Renote"
renote-placeholder: "この投稿を引用... (オプション)"
quote-placeholder: "この投稿を引用... (オプション)"
reply-placeholder: "この投稿への返信..."
note-placeholder: "いまどうしてる?"
cw-placeholder: "内容への注釈 (オプション)"
location-alert: "お使いの端末は位置情報に対応していません"
error: "エラー"
@ -707,11 +731,17 @@ mobile/views/components/timeline.vue:
empty: "投稿がありません"
load-more: "もっと"
mobile/views/components/ui.nav.vue:
home: "ホーム"
timeline: "タイムライン"
notifications: "通知"
messaging: "メッセージ"
follow-requests: "フォロー申請"
search: "検索"
drive: "ドライブ"
favorites: "お気に入り"
user-lists: "リスト"
widgets: "ウィジェット"
game: "ゲーム"
darkmode: "ダークモード"
settings: "設定"
about: "Misskeyについて"
mobile/views/components/user-timeline.vue:
@ -722,8 +752,14 @@ mobile/views/components/users-list.vue:
all: "すべて"
known: "知り合い"
load-more: "もっと"
mobile/views/pages/favorites.vue:
title: "お気に入り"
mobile/views/pages/user-lists.vue:
title: "リスト"
enter-list-name: "リスト名を入力してください"
mobile/views/pages/drive.vue:
drive: "ドライブ"
more: "もっと見る"
mobile/views/pages/followers.vue:
followers-of: "{}のフォロワー"
mobile/views/pages/following.vue:
@ -736,6 +772,10 @@ mobile/views/pages/messaging.vue:
messaging: "メッセージ"
mobile/views/pages/messaging-room.vue:
messaging: "メッセージ"
mobile/views/pages/received-follow-requests.vue:
title: "フォロー申請"
accept: "承認"
reject: "拒否"
mobile/views/pages/note.vue:
title: "投稿"
prev: "前の投稿"

View File

@ -35,12 +35,20 @@ common:
angry: "おこ"
confused: "こまこまのこまり"
pudding: "Pudding"
note-placeholders:
a: "今どうしてる?"
b: "何かありましたか?"
c: "何をお考えですか?"
d: "言いたいことは?"
e: "ここに書いてください"
f: "あなたが書くのを待っています..."
delete: "削除"
loading: "読み込み中"
ok: "わかった"
update-available: "Misskeyの新しいバージョンがあります({newer}。現在{current}を利用中)。ページを再度読み込みすると更新が適用されます。"
my-token-regenerated: "あなたのトークンが更新されたのでサインアウトします。"
widgets:
analog-clock: "アナログ時計"
profile: "プロフィール"
calendar: "カレンダー"
timemachine: "カレンダー(タイムマシン)"
@ -61,6 +69,17 @@ common:
donation: "寄付のお願い"
nav: "ナビゲーション"
tips: "ヒント"
deck:
widgets: "ウィジェット"
home: "ホーム"
local: "ローカル"
global: "グローバル"
notifications: "通知"
list: "リスト"
swap-left: "左に移動"
swap-right: "右に移動"
remove: "カラムを削除"
add-column: "カラムを追加"
common/views/components/connect-failed.vue:
title: "サーバーに接続できません"
description: "インターネット回線に問題があるか、サーバーがダウンまたはメンテナンスしている可能性があります。しばらくしてから{再度お試し}ください。"
@ -282,8 +301,10 @@ desktop/views/components/drive.vue:
upload: "ファイルをアップロード"
url-upload: "URLからアップロード"
desktop/views/components/follow-button.vue:
unfollow: "フォロー解除"
follow: "フォローする"
following: "フォロー"
follow: "フォロー"
request-pending: "フォロー許可待ち"
follow-request: "フォロー申請"
desktop/views/components/followers-window.vue:
followers: "{} のフォロワー"
desktop/views/components/followers.vue:
@ -319,9 +340,6 @@ desktop/views/components/note-detail.vue:
location: "位置情報"
renote: "Renote"
add-reaction: "リアクション"
desktop/views/components/note-detail.sub.vue:
private: "この投稿は非公開です"
deleted: "この投稿は削除されました"
desktop/views/components/notes.note.vue:
reposted-by: "{}がRenote"
reply: "返信"
@ -337,10 +355,9 @@ desktop/views/components/notifications.vue:
more: "もっと見る"
empty: "ありません!"
desktop/views/components/post-form.vue:
note-placeholder: "いまどうしてる?"
reply-placeholder: "この投稿への返信..."
quote-placeholder: "この投稿を引用..."
note: "投稿"
submit: "投稿"
reply: "返信"
renote: "Renote"
posted: "投稿しました!"
@ -472,7 +489,7 @@ desktop/views/components/settings.api.vue:
regenerate-token: "トークンを再生成"
token: "Token:"
enter-password: "パスワードを入力してください"
desktop/views/components/settings.app.vue:
desktop/views/components/settings.apps.vue:
no-apps: "連携しているアプリケーションはありません"
desktop/views/components/settings.mute.vue:
no-users: "ミュートしているユーザーはいません"
@ -510,12 +527,14 @@ desktop/views/components/ui.header.account.vue:
drive: "ドライブ"
favorites: "お気に入り"
lists: "リスト"
follow-requests: "フォロー申請"
customize: "カスタマイズ"
settings: "設定"
signout: "サインアウト"
dark: "闇に飲まれる"
desktop/views/components/ui.header.nav.vue:
home: "ホーム"
deck: "デッキ"
messaging: "メッセージ"
game: "ゲーム"
desktop/views/components/ui.header.notifications.vue:
@ -524,7 +543,12 @@ desktop/views/components/ui.header.post.vue:
post: "新規投稿"
desktop/views/components/ui.header.search.vue:
placeholder: "検索"
desktop/views/components/received-follow-requests-window.vue:
title: "フォロー申請"
accept: "承認"
reject: "拒否"
desktop/views/components/user-lists-window.vue:
title: "リスト"
create-list: "リストを作成"
desktop/views/components/user-preview.vue:
notes: "投稿"
@ -609,7 +633,6 @@ desktop/views/widgets/polls.vue:
desktop/views/widgets/post-form.vue:
title: "投稿"
note: "投稿"
placeholder: "いまどうしてる?"
desktop/views/widgets/profile.vue:
update-banner: "クリックでバナー編集"
update-avatar: "クリックでアバター編集"
@ -650,8 +673,10 @@ mobile/views/components/drive.file-detail.vue:
hash: "ハッシュ (md5)"
exif: "EXIF"
mobile/views/components/follow-button.vue:
following: "フォロー中"
follow: "フォロー"
unfollow: "フォロー解除"
request-pending: "フォロー許可待ち"
follow-request: "フォロー申請"
mobile/views/components/friends-maker.vue:
title: "気になるユーザーをフォロー"
empty: "おすすめのユーザーは見つかりませんでした。"
@ -691,9 +716,8 @@ mobile/views/components/post-form.vue:
submit: "投稿"
reply: "返信"
renote: "Renote"
renote-placeholder: "この投稿を引用... (オプション)"
quote-placeholder: "この投稿を引用... (オプション)"
reply-placeholder: "この投稿への返信..."
note-placeholder: "いまどうしてる?"
cw-placeholder: "内容への注釈 (オプション)"
location-alert: "お使いの端末は位置情報に対応していません"
error: "エラー"
@ -707,11 +731,17 @@ mobile/views/components/timeline.vue:
empty: "投稿がありません"
load-more: "もっと"
mobile/views/components/ui.nav.vue:
home: "ホーム"
timeline: "タイムライン"
notifications: "通知"
messaging: "メッセージ"
follow-requests: "フォロー申請"
search: "検索"
drive: "ドライブ"
favorites: "お気に入り"
user-lists: "リスト"
widgets: "ウィジェット"
game: "ゲーム"
darkmode: "ダークモード"
settings: "設定"
about: "Misskeyについて"
mobile/views/components/user-timeline.vue:
@ -722,8 +752,14 @@ mobile/views/components/users-list.vue:
all: "すべて"
known: "知り合い"
load-more: "もっと"
mobile/views/pages/favorites.vue:
title: "お気に入り"
mobile/views/pages/user-lists.vue:
title: "リスト"
enter-list-name: "リスト名を入力してください"
mobile/views/pages/drive.vue:
drive: "ドライブ"
more: "もっと見る"
mobile/views/pages/followers.vue:
followers-of: "{}のフォロワー"
mobile/views/pages/following.vue:
@ -736,6 +772,10 @@ mobile/views/pages/messaging.vue:
messaging: "メッセージ"
mobile/views/pages/messaging-room.vue:
messaging: "メッセージ"
mobile/views/pages/received-follow-requests.vue:
title: "フォロー申請"
accept: "承認"
reject: "拒否"
mobile/views/pages/note.vue:
title: "投稿"
prev: "前の投稿"

View File

@ -35,12 +35,20 @@ common:
angry: "おこ"
confused: "こまこまのこまり"
pudding: "Pudding"
note-placeholders:
a: "今どうしてる?"
b: "何かありましたか?"
c: "何をお考えですか?"
d: "言いたいことは?"
e: "ここに書いてください"
f: "あなたが書くのを待っています..."
delete: "削除"
loading: "読み込み中"
ok: "わかった"
update-available: "Misskeyの新しいバージョンがあります({newer}。現在{current}を利用中)。ページを再度読み込みすると更新が適用されます。"
my-token-regenerated: "あなたのトークンが更新されたのでサインアウトします。"
widgets:
analog-clock: "アナログ時計"
profile: "プロフィール"
calendar: "カレンダー"
timemachine: "カレンダー(タイムマシン)"
@ -61,6 +69,17 @@ common:
donation: "寄付のお願い"
nav: "ナビゲーション"
tips: "ヒント"
deck:
widgets: "ウィジェット"
home: "ホーム"
local: "ローカル"
global: "グローバル"
notifications: "通知"
list: "リスト"
swap-left: "左に移動"
swap-right: "右に移動"
remove: "カラムを削除"
add-column: "カラムを追加"
common/views/components/connect-failed.vue:
title: "サーバーに接続できません"
description: "インターネット回線に問題があるか、サーバーがダウンまたはメンテナンスしている可能性があります。しばらくしてから{再度お試し}ください。"
@ -282,8 +301,10 @@ desktop/views/components/drive.vue:
upload: "ファイルをアップロード"
url-upload: "URLからアップロード"
desktop/views/components/follow-button.vue:
unfollow: "フォロー解除"
follow: "フォローする"
following: "フォロー"
follow: "フォロー"
request-pending: "フォロー許可待ち"
follow-request: "フォロー申請"
desktop/views/components/followers-window.vue:
followers: "{} のフォロワー"
desktop/views/components/followers.vue:
@ -319,9 +340,6 @@ desktop/views/components/note-detail.vue:
location: "位置情報"
renote: "Renote"
add-reaction: "リアクション"
desktop/views/components/note-detail.sub.vue:
private: "この投稿は非公開です"
deleted: "この投稿は削除されました"
desktop/views/components/notes.note.vue:
reposted-by: "{}がRenote"
reply: "返信"
@ -337,10 +355,9 @@ desktop/views/components/notifications.vue:
more: "もっと見る"
empty: "ありません!"
desktop/views/components/post-form.vue:
note-placeholder: "いまどうしてる?"
reply-placeholder: "この投稿への返信..."
quote-placeholder: "この投稿を引用..."
note: "投稿"
submit: "投稿"
reply: "返信"
renote: "Renote"
posted: "投稿しました!"
@ -472,7 +489,7 @@ desktop/views/components/settings.api.vue:
regenerate-token: "トークンを再生成"
token: "Token:"
enter-password: "パスワードを入力してください"
desktop/views/components/settings.app.vue:
desktop/views/components/settings.apps.vue:
no-apps: "連携しているアプリケーションはありません"
desktop/views/components/settings.mute.vue:
no-users: "ミュートしているユーザーはいません"
@ -510,12 +527,14 @@ desktop/views/components/ui.header.account.vue:
drive: "ドライブ"
favorites: "お気に入り"
lists: "リスト"
follow-requests: "フォロー申請"
customize: "カスタマイズ"
settings: "設定"
signout: "サインアウト"
dark: "闇に飲まれる"
desktop/views/components/ui.header.nav.vue:
home: "ホーム"
deck: "デッキ"
messaging: "メッセージ"
game: "ゲーム"
desktop/views/components/ui.header.notifications.vue:
@ -524,7 +543,12 @@ desktop/views/components/ui.header.post.vue:
post: "新規投稿"
desktop/views/components/ui.header.search.vue:
placeholder: "検索"
desktop/views/components/received-follow-requests-window.vue:
title: "フォロー申請"
accept: "承認"
reject: "拒否"
desktop/views/components/user-lists-window.vue:
title: "リスト"
create-list: "リストを作成"
desktop/views/components/user-preview.vue:
notes: "投稿"
@ -609,7 +633,6 @@ desktop/views/widgets/polls.vue:
desktop/views/widgets/post-form.vue:
title: "投稿"
note: "投稿"
placeholder: "いまどうしてる?"
desktop/views/widgets/profile.vue:
update-banner: "クリックでバナー編集"
update-avatar: "クリックでアバター編集"
@ -650,8 +673,10 @@ mobile/views/components/drive.file-detail.vue:
hash: "ハッシュ (md5)"
exif: "EXIF"
mobile/views/components/follow-button.vue:
following: "フォロー中"
follow: "フォロー"
unfollow: "フォロー解除"
request-pending: "フォロー許可待ち"
follow-request: "フォロー申請"
mobile/views/components/friends-maker.vue:
title: "気になるユーザーをフォロー"
empty: "おすすめのユーザーは見つかりませんでした。"
@ -691,9 +716,8 @@ mobile/views/components/post-form.vue:
submit: "投稿"
reply: "返信"
renote: "Renote"
renote-placeholder: "この投稿を引用... (オプション)"
quote-placeholder: "この投稿を引用... (オプション)"
reply-placeholder: "この投稿への返信..."
note-placeholder: "いまどうしてる?"
cw-placeholder: "内容への注釈 (オプション)"
location-alert: "お使いの端末は位置情報に対応していません"
error: "エラー"
@ -707,11 +731,17 @@ mobile/views/components/timeline.vue:
empty: "投稿がありません"
load-more: "もっと"
mobile/views/components/ui.nav.vue:
home: "ホーム"
timeline: "タイムライン"
notifications: "通知"
messaging: "メッセージ"
follow-requests: "フォロー申請"
search: "検索"
drive: "ドライブ"
favorites: "お気に入り"
user-lists: "リスト"
widgets: "ウィジェット"
game: "ゲーム"
darkmode: "ダークモード"
settings: "設定"
about: "Misskeyについて"
mobile/views/components/user-timeline.vue:
@ -722,8 +752,14 @@ mobile/views/components/users-list.vue:
all: "すべて"
known: "知り合い"
load-more: "もっと"
mobile/views/pages/favorites.vue:
title: "お気に入り"
mobile/views/pages/user-lists.vue:
title: "リスト"
enter-list-name: "リスト名を入力してください"
mobile/views/pages/drive.vue:
drive: "ドライブ"
more: "もっと見る"
mobile/views/pages/followers.vue:
followers-of: "{}のフォロワー"
mobile/views/pages/following.vue:
@ -736,6 +772,10 @@ mobile/views/pages/messaging.vue:
messaging: "メッセージ"
mobile/views/pages/messaging-room.vue:
messaging: "メッセージ"
mobile/views/pages/received-follow-requests.vue:
title: "フォロー申請"
accept: "承認"
reject: "拒否"
mobile/views/pages/note.vue:
title: "投稿"
prev: "前の投稿"

View File

@ -1,8 +1,8 @@
{
"name": "misskey",
"author": "syuilo <i@syuilo.com>",
"version": "2.21.0",
"clientVersion": "1.0.5903",
"version": "2.29.0",
"clientVersion": "1.0.6195",
"codename": "nighthike",
"main": "./built/index.js",
"private": true,

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!-- Generator: Gravit.io --><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="isolation:isolate" viewBox="0 0 512 512" width="512" height="512"><defs><clipPath id="_clipPath_P6eAE2OaBltOJ3gHGVajfqsOnfv4xIns"><rect width="512" height="512"/></clipPath></defs><g clip-path="url(#_clipPath_P6eAE2OaBltOJ3gHGVajfqsOnfv4xIns)"><clipPath id="_clipPath_P6q7MZAUp3XpQhVgs2GuAbegX9v4gkom"><rect x="0" y="0" width="512" height="512" transform="matrix(1,0,0,1,0,0)" fill="rgb(255,255,255)"/></clipPath><g clip-path="url(#_clipPath_P6q7MZAUp3XpQhVgs2GuAbegX9v4gkom)"><g id="Group"><g id="g4502"><g id="g5125"><g id="text4489"><path d=" M 190.093 359.243 C 167.923 359.32 148.881 345.963 139.9 330.409 C 135.104 323.615 125.617 321.198 125.482 330.409 L 125.482 372.939 C 125.482 390.026 119.253 404.799 106.794 417.258 C 94.69 429.362 79.917 435.413 62.474 435.413 C 45.387 435.413 30.614 429.362 18.155 417.258 C 6.052 404.799 0 390.026 0 372.939 L 0 139.061 C 0 125.89 3.738 113.965 11.213 103.285 C 19.045 92.25 29.012 84.596 41.116 80.325 C 47.879 77.833 54.999 76.587 62.474 76.587 C 81.697 76.587 97.716 84.062 110.531 99.013 C 117.295 106.489 121.211 110.405 122.279 110.761 C 122.279 110.761 173.043 172.145 174.467 173.213 C 175.891 174.281 180.073 182.446 190.093 182.446 C 200.112 182.446 204.829 174.281 206.253 173.213 C 207.676 172.145 258.44 110.761 258.44 110.761 C 258.796 111.117 262.534 107.201 269.654 99.013 C 282.825 84.062 299.022 76.587 318.245 76.587 C 325.364 76.587 332.484 77.833 339.603 80.325 C 351.707 84.596 361.496 92.25 368.972 103.285 C 376.803 113.965 380.719 125.89 380.719 139.061 L 380.719 372.939 C 380.719 390.026 374.489 404.799 362.03 417.258 C 349.927 429.362 335.154 435.413 317.711 435.413 C 300.624 435.413 285.851 429.362 273.391 417.258 C 261.288 404.799 255.237 390.026 255.237 372.939 L 255.237 330.409 C 254.184 318.802 243.925 326.116 240.285 330.409 C 230.674 348.208 212.262 359.167 190.093 359.243 Z M 457.535 184.448 Q 435.109 184.448 419.09 168.963 Q 403.605 152.944 403.605 130.518 Q 403.605 108.091 419.09 92.606 Q 435.109 76.587 457.535 76.587 Q 479.962 76.587 495.981 92.606 Q 512 108.091 512 130.518 Q 512 152.944 495.981 168.963 Q 479.962 184.448 457.535 184.448 Z M 458.069 195.128 Q 480.496 195.128 495.981 211.147 Q 512 227.166 512 249.592 L 512 381.482 Q 512 403.909 495.981 419.928 Q 480.496 435.413 458.069 435.413 Q 435.643 435.413 419.624 419.928 Q 403.605 403.909 403.605 381.482 L 403.605 249.592 Q 403.605 227.166 419.624 211.147 Q 435.643 195.128 458.069 195.128 Z " fill-rule="evenodd" fill="rgb(157,157,157)"/></g></g></g></g></g></g></svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
y="0px" width="1024px" height="512px" viewBox="0 256 1024 512" enable-background="new 0 256 1024 512" xml:space="preserve">
<polyline opacity="0.5" fill="none" stroke="#000000" stroke-width="34" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="
896.5,608.5 800.5,416.5 704.5,608.5 608.5,416.5 512.5,608.5 416.5,416.5 320.5,608.5 224.5,416.5 128.5,608.5 "/>
</svg>

Before

Width:  |  Height:  |  Size: 646 B

View File

@ -20,6 +20,7 @@ init(launch => {
// Init router
const router = new VueRouter({
mode: 'history',
base: '/auth/',
routes: [
{ path: '/:token', component: Index },
]

View File

@ -3,6 +3,7 @@
<main v-if="$store.getters.isSignedIn">
<p class="fetching" v-if="fetching">読み込み中<mk-ellipsis/></p>
<x-form
class="form"
ref="form"
v-if="state == 'waiting'"
:session="session"
@ -26,7 +27,7 @@
<h1>サインインしてください</h1>
<mk-signin/>
</main>
<footer><img src="/assets/auth/logo.svg" alt="Misskey"/></footer>
<footer><img src="/assets/auth/icon.svg" alt="Misskey"/></footer>
</div>
</template>
@ -51,7 +52,7 @@ export default Vue.extend({
}
},
mounted() {
if (!this.$root.$data.$store.getters.isSignedIn) return;
if (!this.$store.getters.isSignedIn) return;
// Fetch session
(this as any).api('auth/session/show', {
@ -62,7 +63,7 @@ export default Vue.extend({
// 既に連携していた場合
if (this.session.app.isAuthorized) {
this.$root.$data.os.api('auth/accept', {
(this as any).api('auth/accept', {
token: this.session.token
}).then(() => {
this.accepted();
@ -72,6 +73,7 @@ export default Vue.extend({
}
}).catch(error => {
this.state = 'fetch-session-error';
this.fetching = false;
});
},
methods: {
@ -101,7 +103,7 @@ export default Vue.extend({
padding 32px
color #555
> div
> div:not(.form)
padding 64px
> h1
@ -142,8 +144,8 @@ export default Vue.extend({
> footer
> img
display block
width 64px
height 64px
margin 0 auto
width 32px
height 32px
margin 16px auto
</style>

View File

@ -32,9 +32,9 @@
//#region Detect app name
let app = null;
if (url.pathname == '/docs') app = 'docs';
if (url.pathname == '/dev') app = 'dev';
if (url.pathname == '/auth') app = 'auth';
if (url.pathname == '/docs' || url.pathname.startsWith('/docs/')) app = 'docs';
if (url.pathname == '/dev' || url.pathname.startsWith('/dev/')) app = 'dev';
if (url.pathname == '/auth' || url.pathname.startsWith('/auth/')) app = 'auth';
//#endregion
//#region Detect the user language

View File

@ -9,9 +9,9 @@ export default function<T extends object>(data: {
widget: {
type: Object
},
isMobile: {
type: Boolean,
default: false
platform: {
type: String,
required: true
},
isCustomizeMode: {
type: Boolean,
@ -66,17 +66,10 @@ export default function<T extends object>(data: {
this.bakeProps();
if (this.isMobile) {
(this as any).api('i/update_mobile_home', {
id: this.id,
data: this.props
});
} else {
(this as any).api('i/update_home', {
id: this.id,
data: this.props
});
}
(this as any).api('i/update_widget', {
id: this.id,
data: this.props
});
}
}
});

View File

@ -1,5 +1,3 @@
import * as merge from 'object-assign-deep';
import Stream from './stream';
import StreamManager from './stream-manager';
import MiOS from '../../../mios';
@ -20,7 +18,7 @@ export class HomeStream extends Stream {
}, 1000 * 60);
// 自分の情報が更新されたとき
this.on('i_updated', i => {
this.on('meUpdated', i => {
if (os.debug) {
console.log('I updated:', i);
}
@ -28,6 +26,30 @@ export class HomeStream extends Stream {
os.store.dispatch('mergeMe', i);
});
this.on('read_all_notifications', () => {
os.store.dispatch('mergeMe', {
hasUnreadNotification: false
});
});
this.on('unread_notification', () => {
os.store.dispatch('mergeMe', {
hasUnreadNotification: true
});
});
this.on('read_all_messaging_messages', () => {
os.store.dispatch('mergeMe', {
hasUnreadMessagingMessage: false
});
});
this.on('unread_messaging_message', () => {
os.store.dispatch('mergeMe', {
hasUnreadMessagingMessage: true
});
});
this.on('clientSettingUpdated', x => {
os.store.commit('settings/set', {
key: x.key,
@ -36,25 +58,18 @@ export class HomeStream extends Stream {
});
this.on('home_updated', x => {
if (x.home) {
os.store.commit('settings/setHome', x.home);
} else {
os.store.commit('settings/setHomeWidget', {
id: x.id,
data: x.data
});
}
os.store.commit('settings/setHome', x);
});
this.on('mobile_home_updated', x => {
if (x.home) {
os.store.commit('settings/setMobileHome', x.home);
} else {
os.store.commit('settings/setMobileHomeWidget', {
id: x.id,
data: x.data
});
}
os.store.commit('settings/setMobileHome', x);
});
this.on('widgetUpdated', x => {
os.store.commit('settings/setWidget', {
id: x.id,
data: x.data
});
});
// トークンが再生成されたとき

View File

@ -0,0 +1,127 @@
<template>
<svg class="mk-analog-clock" viewBox="0 0 10 10" preserveAspectRatio="none">
<circle v-for="angle, i in graduations"
:cx="5 + (Math.sin(angle) * (5 - graduationsPadding))"
:cy="5 - (Math.cos(angle) * (5 - graduationsPadding))"
:r="i % 5 == 0 ? 0.125 : 0.05"
:fill="i % 5 == 0 ? majorGraduationColor : minorGraduationColor"/>
<line
:x1="5 - (Math.sin(sAngle) * (sHandLengthRatio * handsTailLength))"
:y1="5 + (Math.cos(sAngle) * (sHandLengthRatio * handsTailLength))"
:x2="5 + (Math.sin(sAngle) * ((sHandLengthRatio * 5) - handsPadding))"
:y2="5 - (Math.cos(sAngle) * ((sHandLengthRatio * 5) - handsPadding))"
:stroke="sHandColor"
stroke-width="0.05"/>
<line
:x1="5 - (Math.sin(mAngle) * (mHandLengthRatio * handsTailLength))"
:y1="5 + (Math.cos(mAngle) * (mHandLengthRatio * handsTailLength))"
:x2="5 + (Math.sin(mAngle) * ((mHandLengthRatio * 5) - handsPadding))"
:y2="5 - (Math.cos(mAngle) * ((mHandLengthRatio * 5) - handsPadding))"
:stroke="mHandColor"
stroke-width="0.1"/>
<line
:x1="5 - (Math.sin(hAngle) * (hHandLengthRatio * handsTailLength))"
:y1="5 + (Math.cos(hAngle) * (hHandLengthRatio * handsTailLength))"
:x2="5 + (Math.sin(hAngle) * ((hHandLengthRatio * 5) - handsPadding))"
:y2="5 - (Math.cos(hAngle) * ((hHandLengthRatio * 5) - handsPadding))"
:stroke="hHandColor"
stroke-width="0.1"/>
</svg>
</template>
<script lang="ts">
import Vue from 'vue';
import { themeColor } from '../../../config';
export default Vue.extend({
props: {
dark: {
type: Boolean,
default: false
}
},
data() {
return {
now: new Date(),
clock: null,
graduationsPadding: 0.5,
handsPadding: 1,
handsTailLength: 0.7,
hHandLengthRatio: 0.75,
mHandLengthRatio: 1,
sHandLengthRatio: 1
};
},
computed: {
majorGraduationColor(): string {
return this.dark ? 'rgba(255, 255, 255, 0.3)' : 'rgba(0, 0, 0, 0.3)';
},
minorGraduationColor(): string {
return this.dark ? 'rgba(255, 255, 255, 0.2)' : 'rgba(0, 0, 0, 0.2)';
},
sHandColor(): string {
return this.dark ? 'rgba(255, 255, 255, 0.5)' : 'rgba(0, 0, 0, 0.3)';
},
mHandColor(): string {
return this.dark ? '#fff' : '#777';
},
hHandColor(): string {
return themeColor;
},
s(): number {
return this.now.getSeconds();
},
m(): number {
return this.now.getMinutes();
},
h(): number {
return this.now.getHours();
},
hAngle(): number {
return Math.PI * (this.h % 12 + this.m / 60) / 6;
},
mAngle(): number {
return Math.PI * (this.m + this.s / 60) / 30;
},
sAngle(): number {
return Math.PI * this.s / 30;
},
graduations(): any {
const angles = [];
for (let i = 0; i < 60; i++) {
const angle = Math.PI * i / 30;
angles.push(angle);
}
return angles;
}
},
mounted() {
this.clock = setInterval(this.tick, 1000);
},
beforeDestroy() {
clearInterval(this.clock);
},
methods: {
tick() {
this.now = new Date();
}
}
});
</script>
<style lang="stylus" scoped>
.mk-analog-clock
display block
</style>

View File

@ -1,5 +1,7 @@
import Vue from 'vue';
import analogClock from './analog-clock.vue';
import menu from './menu.vue';
import signin from './signin.vue';
import signup from './signup.vue';
import forkit from './forkit.vue';
@ -27,6 +29,8 @@ import Switch from './switch.vue';
import Othello from './othello.vue';
import welcomeTimeline from './welcome-timeline.vue';
Vue.component('mk-analog-clock', analogClock);
Vue.component('mk-menu', menu);
Vue.component('mk-signin', signin);
Vue.component('mk-signup', signup);
Vue.component('mk-forkit', forkit);

View File

@ -1,9 +1,11 @@
<template>
<div class="mk-media-list" :data-count="mediaList.length">
<template v-for="media in mediaList">
<mk-media-video :video="media" :key="media.id" v-if="media.type.startsWith('video')" :inline-playable="mediaList.length === 1"/>
<mk-media-image :image="media" :key="media.id" v-else :raw="raw"/>
</template>
<div class="mk-media-list">
<div :data-count="mediaList.length" ref="grid">
<template v-for="media in mediaList">
<mk-media-video :video="media" :key="media.id" v-if="media.type.startsWith('video')" :inline-playable="mediaList.length === 1"/>
<mk-media-image :image="media" :key="media.id" v-else :raw="raw"/>
</template>
</div>
</div>
</template>
@ -18,47 +20,60 @@ export default Vue.extend({
raw: {
default: false
}
},
mounted() {
// for Safari bug
this.$refs.grid.style.height = this.$refs.grid.clientHeight ? `${this.$refs.grid.clientHeight}px` : '128px';
}
});
</script>
<style lang="stylus" scoped>
.mk-media-list
display grid
grid-gap 4px
height 256px
width 100%
@media (max-width 500px)
height 192px
&:before
content ''
display block
padding-top 56.25% // 16:9
> div
position absolute
top 0
right 0
bottom 0
left 0
display grid
grid-gap 4px
&[data-count="1"]
grid-template-rows 1fr
&[data-count="2"]
grid-template-columns 1fr 1fr
grid-template-rows 1fr
&[data-count="3"]
grid-template-columns 1fr 0.5fr
grid-template-rows 1fr 1fr
:nth-child(1)
grid-row 1 / 3
:nth-child(3)
grid-column 2 / 3
grid-row 2 / 3
&[data-count="4"]
grid-template-columns 1fr 1fr
grid-template-rows 1fr 1fr
&[data-count="1"]
grid-template-rows 1fr
&[data-count="2"]
grid-template-columns 1fr 1fr
grid-template-rows 1fr
&[data-count="3"]
grid-template-columns 1fr 0.5fr
grid-template-rows 1fr 1fr
:nth-child(1)
grid-row 1 / 3
:nth-child(3)
grid-column 1 / 2
grid-row 1 / 2
:nth-child(2)
grid-column 2 / 3
grid-row 2/3
&[data-count="4"]
grid-template-columns 1fr 1fr
grid-template-rows 1fr 1fr
:nth-child(1)
grid-column 1 / 2
grid-row 1 / 2
:nth-child(2)
grid-column 2 / 3
grid-row 1 / 2
:nth-child(3)
grid-column 1 / 2
grid-row 2 / 3
:nth-child(4)
grid-column 2 / 3
grid-row 2 / 3
grid-row 1 / 2
:nth-child(3)
grid-column 1 / 2
grid-row 2 / 3
:nth-child(4)
grid-column 2 / 3
grid-row 2 / 3
</style>

View File

@ -0,0 +1,161 @@
<template>
<div class="mk-menu">
<div class="backdrop" ref="backdrop" @click="close"></div>
<div class="popover" :class="{ compact }" ref="popover">
<template v-for="item in items">
<div v-if="item == null"></div>
<button v-else @click="clicked(item.onClick)" v-html="item.content"></button>
</template>
</div>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import * as anime from 'animejs';
export default Vue.extend({
props: ['source', 'compact', 'items'],
mounted() {
this.$nextTick(() => {
const popover = this.$refs.popover as any;
const rect = this.source.getBoundingClientRect();
const width = popover.offsetWidth;
const height = popover.offsetHeight;
if (this.compact) {
const x = rect.left + window.pageXOffset + (this.source.offsetWidth / 2);
const y = rect.top + window.pageYOffset + (this.source.offsetHeight / 2);
popover.style.left = (x - (width / 2)) + 'px';
popover.style.top = (y - (height / 2)) + 'px';
} else {
const x = rect.left + window.pageXOffset + (this.source.offsetWidth / 2);
const y = rect.top + window.pageYOffset + this.source.offsetHeight;
popover.style.left = (x - (width / 2)) + 'px';
popover.style.top = y + 'px';
}
anime({
targets: this.$refs.backdrop,
opacity: 1,
duration: 100,
easing: 'linear'
});
anime({
targets: this.$refs.popover,
opacity: 1,
scale: [0.5, 1],
duration: 500
});
});
},
methods: {
clicked(fn) {
fn();
this.close();
},
close() {
(this.$refs.backdrop as any).style.pointerEvents = 'none';
anime({
targets: this.$refs.backdrop,
opacity: 0,
duration: 200,
easing: 'linear'
});
(this.$refs.popover as any).style.pointerEvents = 'none';
anime({
targets: this.$refs.popover,
opacity: 0,
scale: 0.5,
duration: 200,
easing: 'easeInBack',
complete: () => {
this.$emit('closed');
this.$destroy();
}
});
}
}
});
</script>
<style lang="stylus" scoped>
@import '~const.styl'
$border-color = rgba(27, 31, 35, 0.15)
.mk-menu
position initial
> .backdrop
position fixed
top 0
left 0
z-index 10000
width 100%
height 100%
background rgba(#000, 0.1)
opacity 0
> .popover
position absolute
z-index 10001
padding 8px 0
background #fff
border 1px solid $border-color
border-radius 4px
box-shadow 0 3px 12px rgba(27, 31, 35, 0.15)
transform scale(0.5)
opacity 0
$balloon-size = 16px
&:not(.compact)
margin-top $balloon-size
transform-origin center -($balloon-size)
&:before
content ""
display block
position absolute
top -($balloon-size * 2)
left s('calc(50% - %s)', $balloon-size)
border-top solid $balloon-size transparent
border-left solid $balloon-size transparent
border-right solid $balloon-size transparent
border-bottom solid $balloon-size $border-color
&:after
content ""
display block
position absolute
top -($balloon-size * 2) + 1.5px
left s('calc(50% - %s)', $balloon-size)
border-top solid $balloon-size transparent
border-left solid $balloon-size transparent
border-right solid $balloon-size transparent
border-bottom solid $balloon-size #fff
> button
display block
padding 8px 16px
width 100%
&:hover
color $theme-color-foreground
background $theme-color
text-decoration none
&:active
color $theme-color-foreground
background darken($theme-color, 10%)
> div
margin 8px 0
height 1px
background #eee
</style>

View File

@ -1,55 +1,41 @@
<template>
<div class="mk-note-menu">
<div class="backdrop" ref="backdrop" @click="close"></div>
<div class="popover" :class="{ compact }" ref="popover">
<button @click="favorite">%i18n:@favorite%</button>
<button v-if="note.userId == $store.state.i.id" @click="pin">%i18n:@pin%</button>
<button v-if="note.userId == $store.state.i.id" @click="del">%i18n:@delete%</button>
<a v-if="note.uri" :href="note.uri" target="_blank">%i18n:@remote%</a>
</div>
<div class="mk-note-menu" style="position:initial">
<mk-menu ref="menu" :source="source" :compact="compact" :items="items" @closed="$destroy"/>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import * as anime from 'animejs';
export default Vue.extend({
props: ['note', 'source', 'compact'],
mounted() {
this.$nextTick(() => {
const popover = this.$refs.popover as any;
const rect = this.source.getBoundingClientRect();
const width = popover.offsetWidth;
const height = popover.offsetHeight;
if (this.compact) {
const x = rect.left + window.pageXOffset + (this.source.offsetWidth / 2);
const y = rect.top + window.pageYOffset + (this.source.offsetHeight / 2);
popover.style.left = (x - (width / 2)) + 'px';
popover.style.top = (y - (height / 2)) + 'px';
} else {
const x = rect.left + window.pageXOffset + (this.source.offsetWidth / 2);
const y = rect.top + window.pageYOffset + this.source.offsetHeight;
popover.style.left = (x - (width / 2)) + 'px';
popover.style.top = y + 'px';
computed: {
items() {
const items = [];
items.push({
content: '%i18n:@favorite%',
onClick: this.favorite
});
if (this.note.userId == this.$store.state.i.id) {
items.push({
content: '%i18n:@pin%',
onClick: this.pin
});
items.push({
content: '%i18n:@delete%',
onClick: this.del
});
}
anime({
targets: this.$refs.backdrop,
opacity: 1,
duration: 100,
easing: 'linear'
});
anime({
targets: this.$refs.popover,
opacity: 1,
scale: [0.5, 1],
duration: 500
});
});
if (this.note.uri) {
items.push({
content: '%i18n:@remote%',
onClick: () => {
window.open(this.note.uri, '_blank');
}
});
}
return items;
}
},
methods: {
pin() {
@ -78,98 +64,8 @@ export default Vue.extend({
},
close() {
(this.$refs.backdrop as any).style.pointerEvents = 'none';
anime({
targets: this.$refs.backdrop,
opacity: 0,
duration: 200,
easing: 'linear'
});
(this.$refs.popover as any).style.pointerEvents = 'none';
anime({
targets: this.$refs.popover,
opacity: 0,
scale: 0.5,
duration: 200,
easing: 'easeInBack',
complete: () => this.$destroy()
});
this.$refs.menu.close();
}
}
});
</script>
<style lang="stylus" scoped>
@import '~const.styl'
$border-color = rgba(27, 31, 35, 0.15)
.mk-note-menu
position initial
> .backdrop
position fixed
top 0
left 0
z-index 10000
width 100%
height 100%
background rgba(#000, 0.1)
opacity 0
> .popover
position absolute
z-index 10001
padding 8px 0
background #fff
border 1px solid $border-color
border-radius 4px
box-shadow 0 3px 12px rgba(27, 31, 35, 0.15)
transform scale(0.5)
opacity 0
$balloon-size = 16px
&:not(.compact)
margin-top $balloon-size
transform-origin center -($balloon-size)
&:before
content ""
display block
position absolute
top -($balloon-size * 2)
left s('calc(50% - %s)', $balloon-size)
border-top solid $balloon-size transparent
border-left solid $balloon-size transparent
border-right solid $balloon-size transparent
border-bottom solid $balloon-size $border-color
&:after
content ""
display block
position absolute
top -($balloon-size * 2) + 1.5px
left s('calc(50% - %s)', $balloon-size)
border-top solid $balloon-size transparent
border-left solid $balloon-size transparent
border-right solid $balloon-size transparent
border-bottom solid $balloon-size #fff
> button
> a
display block
padding 8px 16px
width 100%
&:hover
color $theme-color-foreground
background $theme-color
text-decoration none
&:active
color $theme-color-foreground
background darken($theme-color, 10%)
</style>

View File

@ -0,0 +1,41 @@
<template>
<div class="mkw-analog-clock">
<mk-widget-container :naked="props.naked" :show-header="false">
<div class="mkw-analog-clock--body">
<mk-analog-clock :dark="$store.state.device.darkmode"/>
</div>
</mk-widget-container>
</div>
</template>
<script lang="ts">
import define from '../../../common/define-widget';
export default define({
name: 'analog-clock',
props: () => ({
naked: false
})
}).extend({
methods: {
func() {
this.props.naked = !this.props.naked;
this.save();
}
}
});
</script>
<style lang="stylus" scoped>
@import '~const.styl'
root(isDark)
.mkw-analog-clock--body
padding 8px
.mkw-analog-clock[data-darkmode]
root(true)
.mkw-analog-clock:not([data-darkmode])
root(false)
</style>

View File

@ -2,7 +2,7 @@
<div class="mkw-broadcast"
:data-found="broadcasts.length != 0"
:data-melt="props.design == 1"
:data-mobile="isMobile"
:data-mobile="platform == 'mobile'"
>
<div class="icon">
<svg height="32" version="1.1" viewBox="0 0 32 32" width="32">

View File

@ -1,5 +1,5 @@
<template>
<div class="mkw-calendar" :data-special="special" :data-mobile="isMobile">
<div class="mkw-calendar" :data-special="special" :data-mobile="platform == 'mobile'">
<mk-widget-container :naked="props.design == 1" :show-header="false">
<div class="mkw-calendar--body">
<div class="calendar" :data-is-holiday="isHoliday">
@ -67,7 +67,7 @@ export default define({
},
methods: {
func() {
if (this.isMobile) return;
if (this.platform == 'mobile') return;
if (this.props.design == 2) {
this.props.design = 0;
} else {

View File

@ -1,5 +1,5 @@
<template>
<div class="mkw-donation" :data-mobile="isMobile">
<div class="mkw-donation" :data-mobile="platform == 'mobile'">
<article>
<h1>%fa:heart%%i18n:@title%</h1>
<p>

View File

@ -1,5 +1,6 @@
import Vue from 'vue';
import wAnalogClock from './analog-clock.vue';
import wVersion from './version.vue';
import wRss from './rss.vue';
import wServer from './server.vue';
@ -12,6 +13,7 @@ import wTips from './tips.vue';
import wDonation from './donation.vue';
import wNav from './nav.vue';
Vue.component('mkw-analog-clock', wAnalogClock);
Vue.component('mkw-nav', wNav);
Vue.component('mkw-calendar', wCalendar);
Vue.component('mkw-photo-stream', wPhotoStream);

View File

@ -73,6 +73,7 @@ root(isDark)
background isDark ? #282c37 : #fff
border none
border-bottom solid 1px isDark ? #1c2023 : #eee
border-radius 0
> button
display block

View File

@ -4,7 +4,7 @@
<template slot="header">%fa:rss-square%RSS</template>
<button slot="func" title="設定" @click="setting">%fa:cog%</button>
<div class="mkw-rss--body" :data-mobile="isMobile">
<div class="mkw-rss--body" :data-mobile="platform == 'mobile'">
<p class="fetching" v-if="fetching">%fa:spinner .pulse .fw%%i18n:common.loading%<mk-ellipsis/></p>
<div class="feed" v-else>
<a v-for="item in items" :href="item.link" target="_blank">{{ item.title }}</a>

View File

@ -1,5 +1,5 @@
<template>
<div class="mkw-slideshow" :data-mobile="isMobile">
<div class="mkw-slideshow" :data-mobile="platform == 'mobile'">
<div @click="choose">
<p v-if="props.folder === undefined">
<template v-if="isCustomizeMode">フォルダを指定するにはカスタマイズモードを終了してください</template>

View File

@ -6,7 +6,7 @@ export default (os: OS) => opts => {
const o = opts || {};
if (o.renote) {
const vm = os.new(RenoteFormWindow, {
renote: o.renote
note: o.renote
});
document.body.appendChild(vm.$el);
} else {

View File

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

After

Width:  |  Height:  |  Size: 7.0 KiB

View File

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

After

Width:  |  Height:  |  Size: 7.0 KiB

View File

@ -1,25 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="レイヤー_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
y="0px" width="256px" height="256px" viewBox="0 0 256 256" enable-background="new 0 0 256 256" xml:space="preserve">
<circle fill="#FFFFFF" cx="128" cy="153.6" r="19.201"/>
<circle fill="#FFFFFF" cx="51.2" cy="153.6" r="19.2"/>
<circle fill="#FFFFFF" cx="204.8" cy="153.6" r="19.2"/>
<polyline fill="none" stroke="#FFFFFF" stroke-width="16" stroke-linejoin="round" stroke-miterlimit="10" points="51.2,153.6
89.601,102.4 128,153.6 166.4,102.4 204.799,153.6 "/>
<circle fill="#FFFFFF" cx="89.6" cy="102.4" r="19.2"/>
<circle fill="#FFFFFF" cx="166.4" cy="102.4" r="19.199"/>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1021 B

View File

@ -1,25 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="レイヤー_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
y="0px" width="256px" height="256px" viewBox="0 0 256 256" enable-background="new 0 0 256 256" xml:space="preserve">
<circle cx="128" cy="153.6" r="19.201"/>
<circle cx="51.2" cy="153.6" r="19.2"/>
<circle cx="204.8" cy="153.6" r="19.2"/>
<polyline fill="none" stroke="#000000" stroke-width="16" stroke-linejoin="round" stroke-miterlimit="10" points="51.2,153.6
89.601,102.4 128,153.6 166.4,102.4 204.799,153.6 "/>
<circle cx="89.6" cy="102.4" r="19.2"/>
<circle cx="166.4" cy="102.4" r="19.199"/>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 946 B

View File

@ -23,6 +23,7 @@ import updateAvatar from './api/update-avatar';
import updateBanner from './api/update-banner';
import MkIndex from './views/pages/index.vue';
import MkDeck from './views/pages/deck/deck.vue';
import MkUser from './views/pages/user/user.vue';
import MkFavorites from './views/pages/favorites.vue';
import MkSelectDrive from './views/pages/selectdrive.vue';
@ -50,6 +51,7 @@ init(async (launch) => {
mode: 'history',
routes: [
{ path: '/', name: 'index', component: MkIndex },
{ path: '/deck', name: 'deck', component: MkDeck },
{ path: '/i/customize-home', component: MkHomeCustomize },
{ path: '/i/favorites', component: MkFavorites },
{ path: '/i/messaging/:user', component: MkMessagingRoom },

View File

@ -6,44 +6,27 @@
*::input-placeholder
color #D8CBC5
*
&:focus
outline none
&::scrollbar
width 5px
background transparent
&:horizontal
height 5px
&::scrollbar-button
width 0
height 0
background rgba(0, 0, 0, 0.2)
&::scrollbar-piece
background transparent
&:start
background transparent
&::scrollbar-thumb
background rgba(0, 0, 0, 0.2)
&:hover
background rgba(0, 0, 0, 0.4)
&:active
background $theme-color
&::scrollbar-corner
background rgba(0, 0, 0, 0.2)
*:focus
outline none
html
height 100%
background #f7f7f7
&, *
&::-webkit-scrollbar
width 6px
height 6px
&::-webkit-scrollbar-thumb
background rgba(0, 0, 0, 0.2)
&:hover
background rgba(0, 0, 0, 0.4)
&:active
background $theme-color
&[data-darkmode]
background #191B22
@ -51,10 +34,6 @@ html
&::-webkit-scrollbar-track
background-color #282C37
&::-webkit-scrollbar
width 6px
height 6px
&::-webkit-scrollbar-thumb
background-color #454954
@ -63,8 +42,3 @@ html
&:active
background-color $theme-color
body
display flex
flex-direction column
min-height 100%

View File

@ -1,108 +0,0 @@
<template>
<canvas class="mk-analog-clock" ref="canvas" width="256" height="256"></canvas>
</template>
<script lang="ts">
import Vue from 'vue';
import { themeColor } from '../../../config';
const Vec2 = function(this: any, x, y) {
this.x = x;
this.y = y;
};
export default Vue.extend({
data() {
return {
clock: null
};
},
mounted() {
this.tick();
this.clock = setInterval(this.tick, 1000);
},
beforeDestroy() {
clearInterval(this.clock);
},
methods: {
tick() {
const canv = this.$refs.canvas as any;
const now = new Date();
const s = now.getSeconds();
const m = now.getMinutes();
const h = now.getHours();
const ctx = canv.getContext('2d');
const canvW = canv.width;
const canvH = canv.height;
ctx.clearRect(0, 0, canvW, canvH);
{ // 背景
const center = Math.min((canvW / 2), (canvH / 2));
const lineStart = center * 0.90;
const shortLineEnd = center * 0.87;
const longLineEnd = center * 0.84;
for (let i = 0; i < 60; i++) {
const angle = Math.PI * i / 30;
const uv = new Vec2(Math.sin(angle), -Math.cos(angle));
ctx.beginPath();
ctx.lineWidth = 1;
ctx.moveTo((canvW / 2) + uv.x * lineStart, (canvH / 2) + uv.y * lineStart);
if (i % 5 == 0) {
ctx.strokeStyle = 'rgba(255, 255, 255, 0.2)';
ctx.lineTo((canvW / 2) + uv.x * longLineEnd, (canvH / 2) + uv.y * longLineEnd);
} else {
ctx.strokeStyle = 'rgba(255, 255, 255, 0.1)';
ctx.lineTo((canvW / 2) + uv.x * shortLineEnd, (canvH / 2) + uv.y * shortLineEnd);
}
ctx.stroke();
}
}
{ // 分
const angle = Math.PI * (m + s / 60) / 30;
const length = Math.min(canvW, canvH) / 2.6;
const uv = new Vec2(Math.sin(angle), -Math.cos(angle));
ctx.beginPath();
ctx.strokeStyle = '#ffffff';
ctx.lineWidth = 2;
ctx.moveTo(canvW / 2 - uv.x * length / 5, canvH / 2 - uv.y * length / 5);
ctx.lineTo(canvW / 2 + uv.x * length, canvH / 2 + uv.y * length);
ctx.stroke();
}
{ // 時
const angle = Math.PI * (h % 12 + m / 60) / 6;
const length = Math.min(canvW, canvH) / 4;
const uv = new Vec2(Math.sin(angle), -Math.cos(angle));
ctx.beginPath();
ctx.strokeStyle = themeColor;
ctx.lineWidth = 2;
ctx.moveTo(canvW / 2 - uv.x * length / 5, canvH / 2 - uv.y * length / 5);
ctx.lineTo(canvW / 2 + uv.x * length, canvH / 2 + uv.y * length);
ctx.stroke();
}
{ // 秒
const angle = Math.PI * s / 30;
const length = Math.min(canvW, canvH) / 2.6;
const uv = new Vec2(Math.sin(angle), -Math.cos(angle));
ctx.beginPath();
ctx.strokeStyle = 'rgba(255, 255, 255, 0.5)';
ctx.lineWidth = 1;
ctx.moveTo(canvW / 2 - uv.x * length / 5, canvH / 2 - uv.y * length / 5);
ctx.lineTo(canvW / 2 + uv.x * length, canvH / 2 + uv.y * length);
ctx.stroke();
}
}
}
});
</script>
<style lang="stylus" scoped>
.mk-analog-clock
display block
width 256px
height 256px
</style>

View File

@ -62,7 +62,7 @@ export default Vue.extend({
onContextmenu(e) {
this.isContextmenuShowing = true;
contextmenu(e, [{
contextmenu((this as any).os)(e, [{
type: 'item',
text: '%i18n:@contextmenu.rename%',
icon: '%fa:i-cursor%',

View File

@ -52,7 +52,7 @@ export default Vue.extend({
onContextmenu(e) {
this.isContextmenuShowing = true;
contextmenu(e, [{
contextmenu((this as any).os)(e, [{
type: 'item',
text: '%i18n:@contextmenu.move-to-this-folder%',
icon: '%fa:arrow-right%',

View File

@ -136,7 +136,7 @@ export default Vue.extend({
},
methods: {
onContextmenu(e) {
contextmenu(e, [{
contextmenu((this as any).os)(e, [{
type: 'item',
text: '%i18n:@contextmenu.create-folder%',
icon: '%fa:R folder%',

View File

@ -1,19 +1,16 @@
<template>
<button class="mk-follow-button"
:class="{ wait, follow: !user.isFollowing, unfollow: user.isFollowing, big: size == 'big' }"
:class="{ wait, active: u.isFollowing || u.hasPendingFollowRequestFromYou, big: size == 'big' }"
@click="onClick"
:disabled="wait"
:title="user.isFollowing ? '%i18n:@unfollow%' : '%i18n:@follow%'"
>
<template v-if="!wait && user.isFollowing">
<template v-if="size == 'compact'">%fa:minus%</template>
<template v-if="size == 'big'">%fa:minus%%i18n:@unfollow%</template>
<template v-if="!wait">
<template v-if="u.hasPendingFollowRequestFromYou">%fa:hourglass-half%<template v-if="size == 'big'"> %i18n:@request-pending%</template></template>
<template v-else-if="u.isFollowing">%fa:minus%<template v-if="size == 'big'"> %i18n:@following%</template></template>
<template v-else-if="!u.isFollowing && u.isLocked">%fa:plus%<template v-if="size == 'big'"> %i18n:@follow-request%</template></template>
<template v-else-if="!u.isFollowing && !u.isLocked">%fa:plus%<template v-if="size == 'big'"> %i18n:@follow%</template></template>
</template>
<template v-if="!wait && !user.isFollowing">
<template v-if="size == 'compact'">%fa:plus%</template>
<template v-if="size == 'big'">%fa:plus%%i18n:@follow%</template>
</template>
<template v-if="wait">%fa:spinner .pulse .fw%</template>
<template v-else>%fa:spinner .pulse .fw%</template>
</button>
</template>
@ -34,6 +31,7 @@ export default Vue.extend({
data() {
return {
u: this.user,
wait: false,
connection: null,
connectionId: null
@ -56,39 +54,44 @@ export default Vue.extend({
methods: {
onFollow(user) {
if (user.id == this.user.id) {
if (user.id == this.u.id) {
this.user.isFollowing = user.isFollowing;
}
},
onUnfollow(user) {
if (user.id == this.user.id) {
if (user.id == this.u.id) {
this.user.isFollowing = user.isFollowing;
}
},
onClick() {
async onClick() {
this.wait = true;
if (this.user.isFollowing) {
(this as any).api('following/delete', {
userId: this.user.id
}).then(() => {
this.user.isFollowing = false;
}).catch(err => {
console.error(err);
}).then(() => {
this.wait = false;
});
} else {
(this as any).api('following/create', {
userId: this.user.id
}).then(() => {
this.user.isFollowing = true;
}).catch(err => {
console.error(err);
}).then(() => {
this.wait = false;
});
try {
if (this.u.isFollowing) {
this.u = await (this as any).api('following/delete', {
userId: this.u.id
});
} else {
if (this.u.isLocked && this.u.hasPendingFollowRequestFromYou) {
this.u = await (this as any).api('following/requests/cancel', {
userId: this.u.id
});
} else if (this.u.isLocked) {
this.u = await (this as any).api('following/create', {
userId: this.u.id
});
} else {
this.u = await (this as any).api('following/create', {
userId: this.user.id
});
}
}
} catch (e) {
console.error(e);
} finally {
this.wait = false;
}
}
}
@ -124,7 +127,7 @@ root(isDark)
border 2px solid rgba($theme-color, 0.3)
border-radius 8px
&.follow
&:not(.active)
color isDark ? #fff : #888
background isDark ? linear-gradient(to bottom, #313543 0%, #282c37 100%) : linear-gradient(to bottom, #ffffff 0%, #f5f5f5 100%)
border solid 1px isDark ? #1c2023 : #e2e2e2
@ -137,7 +140,7 @@ root(isDark)
background isDark ? #22262f : #ececec
border-color isDark ? #151a1d : #dcdcdc
&.unfollow
&.active
color $theme-color-foreground
background linear-gradient(to bottom, lighten($theme-color, 25%) 0%, lighten($theme-color, 10%) 100%)
border solid 1px lighten($theme-color, 15%)
@ -162,9 +165,6 @@ root(isDark)
height 38px
line-height 38px
i
margin-right 8px
.mk-follow-button[data-darkmode]
root(true)

View File

@ -7,6 +7,7 @@
<p>%i18n:@add-widget%</p>
<select v-model="widgetAdderSelected">
<option value="profile">%i18n:common.widgets.profile%</option>
<option value="analog-clock">%i18n:common.widgets.analog-clock%</option>
<option value="calendar">%i18n:common.widgets.calendar%</option>
<option value="timemachine">%i18n:common.widgets.timemachine%</option>
<option value="activity">%i18n:common.widgets.activity%</option>
@ -46,7 +47,7 @@
:key="place"
>
<div v-for="widget in widgets[place]" class="customize-container" :key="widget.id" @contextmenu.stop.prevent="onWidgetContextmenu(widget.id)">
<component :is="`mkw-${widget.name}`" :widget="widget" :ref="widget.id" :is-customize-mode="true"/>
<component :is="`mkw-${widget.name}`" :widget="widget" :ref="widget.id" :is-customize-mode="true" platform="desktop"/>
</div>
</x-draggable>
<div class="main">
@ -59,12 +60,11 @@
</template>
<template v-else>
<div v-for="place in ['left', 'right']" :class="place">
<component v-for="widget in widgets[place]" :is="`mkw-${widget.name}`" :key="widget.id" :ref="widget.id" :widget="widget" @chosen="warp"/>
<component v-for="widget in widgets[place]" :is="`mkw-${widget.name}`" :key="widget.id" :ref="widget.id" :widget="widget" @chosen="warp" platform="desktop"/>
</div>
<div class="main">
<mk-post-form v-if="$store.state.settings.showPostFormOnTopOfTl"/>
<mk-timeline ref="tl" @loaded="onTlLoaded" v-if="mode == 'timeline'"/>
<mk-mentions @loaded="onTlLoaded" v-if="mode == 'mentions'"/>
<mk-post-form class="form" v-if="$store.state.settings.showPostFormOnTopOfTl"/>
<mk-timeline class="tl" cref="tl" @loaded="onTlLoaded" v-if="mode == 'timeline'"/>
</div>
</template>
</div>
@ -76,6 +76,50 @@ import Vue from 'vue';
import * as XDraggable from 'vuedraggable';
import * as uuid from 'uuid';
const defaultDesktopHomeWidgets = {
left: [
'profile',
'calendar',
'activity',
'rss',
'trends',
'photo-stream',
'version'
],
right: [
'broadcast',
'notifications',
'users',
'polls',
'server',
'donation',
'nav',
'tips'
]
};
//#region Construct home data
const _defaultDesktopHomeWidgets = [];
defaultDesktopHomeWidgets.left.forEach(widget => {
_defaultDesktopHomeWidgets.push({
name: widget,
id: uuid(),
place: 'left',
data: {}
});
});
defaultDesktopHomeWidgets.right.forEach(widget => {
_defaultDesktopHomeWidgets.push({
name: widget,
id: uuid(),
place: 'right',
data: {}
});
});
//#endregion
export default Vue.extend({
components: {
XDraggable
@ -103,7 +147,7 @@ export default Vue.extend({
computed: {
home(): any[] {
return this.$store.state.settings.home;
return this.$store.state.settings.home || [];
},
left(): any[] {
return this.home.filter(w => w.place == 'left');
@ -119,6 +163,16 @@ export default Vue.extend({
}
},
created() {
if (this.$store.state.settings.home == null) {
this.api('i/update_home', {
home: _defaultDesktopHomeWidgets
}).then(() => {
this.$store.commit('settings/setHome', _defaultDesktopHomeWidgets);
});
}
},
mounted() {
this.connection = (this as any).os.stream.getConnection();
this.connectionId = (this as any).os.stream.use();
@ -298,11 +352,18 @@ root(isDark)
width calc(100% - 275px * 2)
order 2
.mk-post-form
> .form
margin-bottom 16px
border solid 1px rgba(#000, 0.075)
border-radius 4px
@media (max-width 700px)
padding 0
> .tl
border none
border-radius 0
> *:not(.main)
width 275px
padding 16px 0 16px 0

View File

@ -9,7 +9,6 @@ import subNoteContent from './sub-note-content.vue';
import window from './window.vue';
import noteFormWindow from './post-form-window.vue';
import renoteFormWindow from './renote-form-window.vue';
import analogClock from './analog-clock.vue';
import ellipsisIcon from './ellipsis-icon.vue';
import mediaImage from './media-image.vue';
import mediaImageDialog from './media-image-dialog.vue';
@ -40,7 +39,6 @@ Vue.component('mk-sub-note-content', subNoteContent);
Vue.component('mk-window', window);
Vue.component('mk-post-form-window', noteFormWindow);
Vue.component('mk-renote-form-window', renoteFormWindow);
Vue.component('mk-analog-clock', analogClock);
Vue.component('mk-ellipsis-icon', ellipsisIcon);
Vue.component('mk-media-image', mediaImage);
Vue.component('mk-media-image-dialog', mediaImageDialog);

View File

@ -1,124 +0,0 @@
<template>
<div class="sub" :title="title">
<mk-avatar class="avatar" :user="note.user"/>
<div class="main">
<header>
<div class="left">
<router-link class="name" :to="note.user | userPage" v-user-preview="note.userId">{{ note.user | userName }}</router-link>
<span class="username"><mk-acct :user="note.user"/></span>
</div>
<div class="right">
<router-link class="time" :to="note | notePage">
<mk-time :time="note.createdAt"/>
</router-link>
</div>
</header>
<div class="body">
<div class="text">
<span v-if="note.isHidden" style="opacity: 0.5">%i18n:@private%</span>
<span v-if="note.deletedAt" style="opacity: 0.5">%i18n:@deleted%</span>
<mk-note-html v-if="note.text" :text="note.text" :i="$store.state.i"/>
</div>
<div class="media" v-if="note.mediaIds.length > 0">
<mk-media-list :media-list="note.media"/>
</div>
</div>
</div>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import dateStringify from '../../../common/scripts/date-stringify';
export default Vue.extend({
props: ['note'],
computed: {
title(): string {
return dateStringify(this.note.createdAt);
}
}
});
</script>
<style lang="stylus" scoped>
root(isDark)
margin 0
padding 20px 32px
background isDark ? #21242d : #fdfdfd
&:after
content ""
display block
clear both
&:hover
> .main > footer > button
color #888
> .avatar
display block
float left
margin 0 16px 0 0
width 44px
height 44px
border-radius 4px
> .main
float left
width calc(100% - 60px)
> header
margin-bottom 4px
white-space nowrap
&:after
content ""
display block
clear both
> .left
float left
> .name
display inline
margin 0
padding 0
color isDark ? #fff : #777
font-size 1em
font-weight 700
text-align left
text-decoration none
&:hover
text-decoration underline
> .username
text-align left
margin 0 0 0 8px
color isDark ? #606984 : #ccc
> .right
float right
> .time
font-size 0.9em
color isDark ? #606984 : #c0c0c0
> .body
> .text
cursor default
display block
margin 0
padding 0
overflow-wrap break-word
font-size 1em
color isDark ? #959ba7 : #717171
.sub[data-darkmode]
root(true)
.sub:not([data-darkmode])
root(false)
</style>

View File

@ -89,7 +89,7 @@ import MkPostFormWindow from './post-form-window.vue';
import MkRenoteFormWindow from './renote-form-window.vue';
import MkNoteMenu from '../../../common/views/components/note-menu.vue';
import MkReactionPicker from '../../../common/views/components/reaction-picker.vue';
import XSub from './note-detail.sub.vue';
import XSub from './notes.note.sub.vue';
export default Vue.extend({
components: {
@ -218,8 +218,6 @@ export default Vue.extend({
@import '~const.styl'
root(isDark)
margin 0 auto
padding 0
overflow hidden
text-align left
background isDark ? #282C37 : #fff

View File

@ -5,9 +5,18 @@
<header>
<router-link class="name" :to="note.user | userPage" v-user-preview="note.userId">{{ note.user | userName }}</router-link>
<span class="username"><mk-acct :user="note.user"/></span>
<router-link class="time" :to="note | notePage">
<mk-time :time="note.createdAt"/>
</router-link>
<div class="info">
<span class="mobile" v-if="note.viaMobile">%fa:mobile-alt%</span>
<router-link class="created-at" :to="note | notePage">
<mk-time :time="note.createdAt"/>
</router-link>
<span class="visibility" v-if="note.visibility != 'public'">
<template v-if="note.visibility == 'home'">%fa:home%</template>
<template v-if="note.visibility == 'followers'">%fa:unlock%</template>
<template v-if="note.visibility == 'specified'">%fa:envelope%</template>
<template v-if="note.visibility == 'private'">%fa:lock%</template>
</span>
</div>
</header>
<div class="body">
<mk-sub-note-content class="text" :note="note"/>
@ -32,24 +41,20 @@ export default Vue.extend({
<style lang="stylus" scoped>
root(isDark)
display flex
font-size 0.9em
&:after
content ""
display block
clear both
> .avatar
flex-shrink 0
display block
float left
margin 0 12px 0 0
width 48px
height 48px
border-radius 8px
> .main
float left
width calc(100% - 60px)
flex 1
min-width 0
> header
display flex
@ -75,9 +80,18 @@ root(isDark)
text-overflow ellipsis
color isDark ? #606984 : #d1d8da
> .time
> .info
margin-left auto
color isDark ? #606984 : #b2b8bb
font-size 0.9em
> *
color isDark ? #606984 : #b2b8bb
> .mobile
margin-right 6px
> .visibility
margin-left 6px
> .body

View File

@ -44,27 +44,23 @@ export default Vue.extend({
<style lang="stylus" scoped>
root(isDark)
display flex
margin 0
padding 16px 32px
font-size 0.9em
background isDark ? #21242d : #fcfcfc
&:after
content ""
display block
clear both
> .avatar
flex-shrink 0
display block
float left
margin 0 12px 0 0
width 48px
height 48px
border-radius 8px
> .main
float left
width calc(100% - 60px)
flex 1
min-width 0
> header
display flex
@ -119,8 +115,6 @@ root(isDark)
margin-left 6px
> .body
max-height 128px
overflow hidden
> .text
cursor default

View File

@ -387,20 +387,16 @@ root(isDark)
padding-top 8px
> article
display flex
padding 28px 32px 18px 32px
&:after
content ""
display block
clear both
&:hover
> .main > footer > button
color isDark ? #707b97 : #888
> .avatar
flex-shrink 0
display block
float left
margin 0 16px 10px 0
width 58px
height 58px
@ -410,8 +406,8 @@ root(isDark)
//top 74px
> .main
float left
width calc(100% - 74px)
flex 1
min-width 0
> header
display flex
@ -467,7 +463,7 @@ root(isDark)
> .app
margin-right 8px
padding-right 8px
border-right solid 1px #eaeaea
border-right solid 1px isDark ? #1c2023 : #eaeaea
> .visibility
margin-left 8px
@ -556,7 +552,7 @@ root(isDark)
padding 2px 8px 2px 16px
font-size 90%
color #8d969e
background #edf0f3
background isDark ? #313543 : #edf0f3
border-radius 4px
&:before
@ -569,7 +565,7 @@ root(isDark)
width 8px
height 8px
margin auto 0
background #fff
background isDark ? #282c37 : #fff
border-radius 100%
&:hover

View File

@ -74,7 +74,7 @@ export default Vue.extend({
mounted() {
document.addEventListener('visibilitychange', this.onVisibilitychange, false);
window.addEventListener('scroll', this.onScroll);
window.addEventListener('scroll', this.onScroll, { passive: true });
},
beforeDestroy() {

View File

@ -5,6 +5,7 @@
<template v-for="(notification, i) in _notifications">
<div class="notification" :class="notification.type" :key="notification.id">
<mk-time :time="notification.createdAt"/>
<template v-if="notification.type == 'reaction'">
<mk-avatar class="avatar" :user="notification.user"/>
<div class="text">
@ -17,6 +18,7 @@
</router-link>
</div>
</template>
<template v-if="notification.type == 'renote'">
<mk-avatar class="avatar" :user="notification.note.user"/>
<div class="text">
@ -28,6 +30,7 @@
</router-link>
</div>
</template>
<template v-if="notification.type == 'quote'">
<mk-avatar class="avatar" :user="notification.note.user"/>
<div class="text">
@ -37,6 +40,7 @@
<router-link class="note-preview" :to="notification.note | notePage">{{ getNoteSummary(notification.note) }}</router-link>
</div>
</template>
<template v-if="notification.type == 'follow'">
<mk-avatar class="avatar" :user="notification.user"/>
<div class="text">
@ -45,6 +49,16 @@
</p>
</div>
</template>
<template v-if="notification.type == 'receiveFollowRequest'">
<mk-avatar class="avatar" :user="notification.user"/>
<div class="text">
<p>%fa:user-clock%
<router-link :to="notification.user | userPage" v-user-preview="notification.user.id">{{ notification.user | userName }}</router-link>
</p>
</div>
</template>
<template v-if="notification.type == 'reply'">
<mk-avatar class="avatar" :user="notification.note.user"/>
<div class="text">
@ -54,6 +68,7 @@
<router-link class="note-preview" :to="notification.note | notePage">{{ getNoteSummary(notification.note) }}</router-link>
</div>
</template>
<template v-if="notification.type == 'mention'">
<mk-avatar class="avatar" :user="notification.note.user"/>
<div class="text">
@ -63,6 +78,7 @@
<a class="note-preview" :href="notification.note | notePage">{{ getNoteSummary(notification.note) }}</a>
</div>
</template>
<template v-if="notification.type == 'poll_vote'">
<mk-avatar class="avatar" :user="notification.user"/>
<div class="text">
@ -73,6 +89,7 @@
</div>
</template>
</div>
<p class="date" v-if="i != notifications.length - 1 && notification._date != _notifications[i + 1]._date" :key="notification.id + '-time'">
<span>%fa:angle-up%{{ notification._datetext }}</span>
<span>%fa:angle-down%{{ _notifications[i + 1]._datetext }}</span>
@ -189,7 +206,7 @@ root(isDark)
margin 0
padding 16px
overflow-wrap break-word
font-size 0.9em
font-size 12px
border-bottom solid 1px isDark ? #1c2023 : rgba(#000, 0.05)
&:last-child
@ -251,6 +268,10 @@ root(isDark)
.text p i
color #53c7ce
&.receiveFollowRequest
.text p i
color #888
&.reply, &.mention
.text p i
color #555

View File

@ -1,21 +1,23 @@
<template>
<mk-window ref="window" is-modal @closed="$destroy">
<span slot="header">
<span :class="$style.icon" v-if="geo">%fa:map-marker-alt%</span>
<mk-window class="mk-post-form-window" ref="window" is-modal @closed="$destroy">
<span slot="header" class="mk-post-form-window--header">
<span class="icon" v-if="geo">%fa:map-marker-alt%</span>
<span v-if="!reply">%i18n:@note%</span>
<span v-if="reply">%i18n:@reply%</span>
<span :class="$style.count" v-if="media.length != 0">{{ '%i18n:@attaches%'.replace('{}', media.length) }}</span>
<span :class="$style.count" v-if="uploadings.length != 0">{{ '%i18n:@uploading-media%'.replace('{}', uploadings.length) }}<mk-ellipsis/></span>
<span class="count" v-if="media.length != 0">{{ '%i18n:@attaches%'.replace('{}', media.length) }}</span>
<span class="count" v-if="uploadings.length != 0">{{ '%i18n:@uploading-media%'.replace('{}', uploadings.length) }}<mk-ellipsis/></span>
</span>
<mk-note-preview v-if="reply" :class="$style.notePreview" :note="reply"/>
<mk-post-form ref="form"
:reply="reply"
@posted="onPosted"
@change-uploadings="onChangeUploadings"
@change-attached-media="onChangeMedia"
@geo-attached="onGeoAttached"
@geo-dettached="onGeoDettached"/>
<div class="mk-post-form-window--body">
<mk-note-preview v-if="reply" class="notePreview" :note="reply"/>
<mk-post-form ref="form"
:reply="reply"
@posted="onPosted"
@change-uploadings="onChangeUploadings"
@change-attached-media="onChangeMedia"
@geo-attached="onGeoAttached"
@geo-dettached="onGeoDettached"/>
</div>
</mk-window>
</template>
@ -56,21 +58,33 @@ export default Vue.extend({
});
</script>
<style lang="stylus" module>
.icon
margin-right 8px
<style lang="stylus" scoped>
root(isDark)
.mk-post-form-window--header
.icon
margin-right 8px
.count
margin-left 8px
opacity 0.8
.count
margin-left 8px
opacity 0.8
&:before
content '('
&:before
content '('
&:after
content ')'
&:after
content ')'
.notePreview
margin 16px 22px 0 22px
.mk-post-form-window--body
.notePreview
if isDark
margin 16px 22px 0 22px
else
margin 16px 22px
.mk-post-form-window[data-darkmode]
root(true)
.mk-post-form-window:not([data-darkmode])
root(false)
</style>

View File

@ -86,11 +86,21 @@ export default Vue.extend({
},
placeholder(): string {
const xs = [
'%i18n:common.note-placeholders.a%',
'%i18n:common.note-placeholders.b%',
'%i18n:common.note-placeholders.c%',
'%i18n:common.note-placeholders.d%',
'%i18n:common.note-placeholders.e%',
'%i18n:common.note-placeholders.f%'
];
const x = xs[Math.floor(Math.random() * xs.length)];
return this.renote
? '%i18n:@quote-placeholder%'
: this.reply
? '%i18n:@reply-placeholder%'
: '%i18n:@note-placeholder%';
: x;
},
submitText(): string {
@ -98,7 +108,7 @@ export default Vue.extend({
? '%i18n:@renote%'
: this.reply
? '%i18n:@reply%'
: '%i18n:@note%';
: '%i18n:@submit%';
},
canPost(): boolean {

View File

@ -0,0 +1,72 @@
<template>
<mk-window ref="window" is-modal width="450px" height="500px" @closed="$destroy">
<span slot="header">%fa:envelope R% %i18n:@title%</span>
<div class="slpqaxdoxhvglersgjukmvizkqbmbokc" :data-darkmode="$store.state.device.darkmode">
<div v-for="req in requests">
<router-link :key="req.id" :to="req.follower | userPage">{{ req.follower | userName }}</router-link>
<span>
<a @click="accept(req.follower)">%i18n:@accept%</a>|<a @click="reject(req.follower)">%i18n:@reject%</a>
</span>
</div>
</div>
</mk-window>
</template>
<script lang="ts">
import Vue from 'vue';
export default Vue.extend({
data() {
return {
fetching: true,
requests: []
};
},
mounted() {
(this as any).api('following/requests/list').then(requests => {
this.fetching = false;
this.requests = requests;
});
},
methods: {
accept(user) {
(this as any).api('following/requests/accept', { userId: user.id }).then(() => {
this.requests = this.requests.filter(r => r.follower.id != user.id);
});
},
reject(user) {
(this as any).api('following/requests/reject', { userId: user.id }).then(() => {
this.requests = this.requests.filter(r => r.follower.id != user.id);
});
},
close() {
(this as any).$refs.window.close();
}
}
});
</script>
<style lang="stylus" scoped>
root(isDark)
padding 16px
> button
margin-bottom 16px
> div
display flex
padding 16px
border solid 1px isDark ? #1c2023 : #eee
border-radius 4px
> span
margin 0 0 0 auto
.slpqaxdoxhvglersgjukmvizkqbmbokc[data-darkmode]
root(true)
.slpqaxdoxhvglersgjukmvizkqbmbokc:not([data-darkmode])
root(false)
</style>

View File

@ -23,7 +23,11 @@
</label>
<button class="ui primary" @click="save">%i18n:@save%</button>
<section>
<h2>その他</h2>
<h2>%i18n:@locked-account%</h2>
<mk-switch v-model="$store.state.i.isLocked" @change="onChangeIsLocked" text="%i18n:@is-locked%"/>
</section>
<section>
<h2>%i18n:@other%</h2>
<mk-switch v-model="$store.state.i.isBot" @change="onChangeIsBot" text="%i18n:@is-bot%"/>
<mk-switch v-model="$store.state.i.isCat" @change="onChangeIsCat" text="%i18n:@is-cat%"/>
</section>
@ -62,6 +66,11 @@ export default Vue.extend({
(this as any).apis.notify('プロフィールを更新しました');
});
},
onChangeIsLocked() {
(this as any).api('i/update', {
isLocked: this.$store.state.i.isLocked
});
},
onChangeIsBot() {
(this as any).api('i/update', {
isBot: this.$store.state.i.isBot

View File

@ -40,6 +40,8 @@
<button class="ui button" @click="customizeHome" style="margin-bottom: 16px">%i18n:@customize%</button>
</div>
<div class="div">
<button class="ui" @click="updateWallpaper">%i18n:@choose-wallpaper%</button>
<button class="ui" @click="deleteWallpaper">%i18n:@delete-wallpaper%</button>
<mk-switch v-model="darkmode" text="%i18n:@dark-mode%"/>
<mk-switch v-model="$store.state.settings.circleIcons" @change="onChangeCircleIcons" text="%i18n:@circle-icons%"/>
<mk-switch v-model="$store.state.settings.gradientWindowHeader" @change="onChangeGradientWindowHeader" text="%i18n:@gradient-window-header%"/>
@ -293,6 +295,20 @@ export default Vue.extend({
this.$router.push('/i/customize-home');
this.$emit('done');
},
updateWallpaper() {
(this as any).apis.chooseDriveFile({
multiple: false
}).then(file => {
(this as any).api('i/update', {
wallpaperId: file.id
});
});
},
deleteWallpaper() {
(this as any).api('i/update', {
wallpaperId: null
});
},
onChangeFetchOnScroll(v) {
this.$store.dispatch('settings/set', {
key: 'fetchOnScroll',

View File

@ -5,7 +5,7 @@
<span v-if="note.deletedAt" style="opacity: 0.5">%i18n:@deleted%</span>
<a class="reply" v-if="note.replyId">%fa:reply%</a>
<mk-note-html v-if="note.text" :text="note.text" :i="$store.state.i"/>
<a class="rp" v-if="note.renoteId" :href="`/note:${note.renoteId}`">RP: ...</a>
<a class="rp" v-if="note.renoteId" :href="`/notes/${note.renoteId}`">RP: ...</a>
</div>
<details v-if="note.media.length > 0">
<summary>({{ '%i18n:@media-count%'.replace('{}', note.media.length) }})</summary>

View File

@ -36,7 +36,7 @@ export default Vue.extend({
</script>
<style lang="stylus" scoped>
.mk-ui-notification
root(isDark)
display block
position fixed
z-index 10000
@ -46,10 +46,10 @@ export default Vue.extend({
margin 0 auto
padding 128px 0 0 0
width 500px
color rgba(#000, 0.6)
background rgba(#fff, 0.9)
color rgba(isDark ? #fff : #000, 0.6)
background rgba(isDark ? #282C37 : #fff, 0.9)
border-radius 0 0 8px 8px
box-shadow 0 2px 4px rgba(#000, 0.2)
box-shadow 0 2px 4px rgba(#000, isDark ? 0.4 : 0.2)
transform translateY(-64px)
opacity 0
@ -58,4 +58,10 @@ export default Vue.extend({
line-height 64px
text-align center
.mk-ui-notification[data-darkmode]
root(true)
.mk-ui-notification:not([data-darkmode])
root(false)
</style>

View File

@ -19,6 +19,9 @@
<li @click="list">
<p>%fa:list%<span>%i18n:@lists%</span>%fa:angle-right%</p>
</li>
<li @click="followRequests" v-if="$store.state.i.isLocked">
<p>%fa:envelope R%<span>%i18n:@follow-requests%<i v-if="$store.state.i.pendingReceivedFollowRequestsCount">{{ $store.state.i.pendingReceivedFollowRequestsCount }}</i></span>%fa:angle-right%</p>
</li>
</ul>
<ul>
<li>
@ -46,6 +49,7 @@
<script lang="ts">
import Vue from 'vue';
import MkUserListsWindow from './user-lists-window.vue';
import MkFollowRequestsWindow from './received-follow-requests-window.vue';
import MkSettingsWindow from './settings-window.vue';
import MkDriveWindow from './drive-window.vue';
import contains from '../../../common/scripts/contains';
@ -91,6 +95,10 @@ export default Vue.extend({
this.$router.push(`i/lists/${ list.id }`);
});
},
followRequests() {
this.close();
(this as any).os.new(MkFollowRequestsWindow);
},
settings() {
this.close();
(this as any).os.new(MkSettingsWindow);
@ -225,6 +233,16 @@ root(isDark)
> span:first-child
padding-left 22px
> span:nth-child(2)
> i
margin-left 4px
padding 2px 8px
font-size 90%
font-style normal
background $theme-color
color $theme-color-foreground
border-radius 8px
> [data-fa]:first-child
margin-right 6px
width 16px

View File

@ -8,7 +8,7 @@
</time>
</div>
<div class="content">
<mk-analog-clock/>
<mk-analog-clock :dark="true"/>
</div>
</div>
</template>

View File

@ -8,11 +8,17 @@
<p>%i18n:@home%</p>
</router-link>
</li>
<li class="deck" :class="{ active: $route.name == 'deck' }">
<router-link to="/deck">
%fa:columns%
<p>%i18n:@deck% <small>(beta)</small></p>
</router-link>
</li>
<li class="messaging">
<a @click="messaging">
%fa:comments%
<p>%i18n:@messaging%</p>
<template v-if="hasUnreadMessagingMessages">%fa:circle%</template>
<template v-if="hasUnreadMessagingMessage">%fa:circle%</template>
</a>
</li>
<li class="game">
@ -35,48 +41,33 @@ import MkGameWindow from './game-window.vue';
export default Vue.extend({
data() {
return {
hasUnreadMessagingMessages: false,
hasGameInvitations: false,
connection: null,
connectionId: null
};
},
computed: {
hasUnreadMessagingMessage(): boolean {
return this.$store.getters.isSignedIn && this.$store.state.i.hasUnreadMessagingMessage;
}
},
mounted() {
if (this.$store.getters.isSignedIn) {
this.connection = (this as any).os.stream.getConnection();
this.connectionId = (this as any).os.stream.use();
this.connection.on('read_all_messaging_messages', this.onReadAllMessagingMessages);
this.connection.on('unread_messaging_message', this.onUnreadMessagingMessage);
this.connection.on('othello_invited', this.onOthelloInvited);
this.connection.on('othello_no_invites', this.onOthelloNoInvites);
// Fetch count of unread messaging messages
(this as any).api('messaging/unread').then(res => {
if (res.count > 0) {
this.hasUnreadMessagingMessages = true;
}
});
}
},
beforeDestroy() {
if (this.$store.getters.isSignedIn) {
this.connection.off('read_all_messaging_messages', this.onReadAllMessagingMessages);
this.connection.off('unread_messaging_message', this.onUnreadMessagingMessage);
this.connection.off('othello_invited', this.onOthelloInvited);
this.connection.off('othello_no_invites', this.onOthelloNoInvites);
(this as any).os.stream.dispose(this.connectionId);
}
},
methods: {
onUnreadMessagingMessage() {
this.hasUnreadMessagingMessages = true;
},
onReadAllMessagingMessages() {
this.hasUnreadMessagingMessages = false;
},
onOthelloInvited() {
this.hasGameInvitations = true;
},

View File

@ -1,7 +1,7 @@
<template>
<div class="notifications">
<button :data-active="isOpen" @click="toggle" title="%i18n:@title%">
%fa:R bell%<template v-if="hasUnreadNotifications">%fa:circle%</template>
%fa:R bell%<template v-if="hasUnreadNotification">%fa:circle%</template>
</button>
<div class="pop" v-if="isOpen">
<mk-notifications/>
@ -16,44 +16,15 @@ import contains from '../../../common/scripts/contains';
export default Vue.extend({
data() {
return {
isOpen: false,
hasUnreadNotifications: false,
connection: null,
connectionId: null
isOpen: false
};
},
mounted() {
if (this.$store.getters.isSignedIn) {
this.connection = (this as any).os.stream.getConnection();
this.connectionId = (this as any).os.stream.use();
this.connection.on('read_all_notifications', this.onReadAllNotifications);
this.connection.on('unread_notification', this.onUnreadNotification);
// Fetch count of unread notifications
(this as any).api('notifications/get_unread_count').then(res => {
if (res.count > 0) {
this.hasUnreadNotifications = true;
}
});
}
},
beforeDestroy() {
if (this.$store.getters.isSignedIn) {
this.connection.off('read_all_notifications', this.onReadAllNotifications);
this.connection.off('unread_notification', this.onUnreadNotification);
(this as any).os.stream.dispose(this.connectionId);
computed: {
hasUnreadNotification(): boolean {
return this.$store.getters.isSignedIn && this.$store.state.i.hasUnreadNotification;
}
},
methods: {
onReadAllNotifications() {
this.hasUnreadNotifications = false;
},
onUnreadNotification() {
this.hasUnreadNotifications = true;
},
toggle() {
this.isOpen ? this.close() : this.open();
},

View File

@ -150,8 +150,8 @@ root(isDark)
display block
width 100%
height 48px
background-image url(/assets/desktop/header-logo.svg)
background-size 46px
background-image isDark ? url('/assets/desktop/header-icon.dark.svg') : url('/assets/desktop/header-icon.light.svg')
background-size 24px
background-position center
background-repeat no-repeat
opacity 0.3

View File

@ -1,6 +1,6 @@
<template>
<div>
<x-header/>
<div class="mk-ui" :style="style">
<x-header class="header"/>
<div class="content">
<slot></slot>
</div>
@ -16,6 +16,15 @@ export default Vue.extend({
components: {
XHeader
},
computed: {
style(): any {
if (!this.$store.getters.isSignedIn || this.$store.state.i.wallpaperUrl == null) return {};
return {
backgroundColor: this.$store.state.i.wallpaperColor && this.$store.state.i.wallpaperColor.length == 3 ? `rgb(${ this.$store.state.i.wallpaperColor.join(',') })` : null,
backgroundImage: `url(${ this.$store.state.i.wallpaperUrl })`
};
}
},
mounted() {
document.addEventListener('keydown', this.onKeydown);
},
@ -35,3 +44,22 @@ export default Vue.extend({
});
</script>
<style lang="stylus" scoped>
.mk-ui
display flex
flex-direction column
flex 1
background-size cover
background-position center
background-attachment fixed
> .header
@media (max-width 1000px)
display none
> .content
display flex
flex-direction column
flex 1
overflow hidden
</style>

View File

@ -1,8 +1,8 @@
<template>
<mk-window ref="window" is-modal width="450px" height="500px" @closed="$destroy">
<span slot="header">%fa:list% リスト</span>
<span slot="header">%fa:list% %i18n:@title%</span>
<div data-id="6e4caea3-d8f9-4ab7-96de-ab67fe8d5c82" :data-darkmode="$store.state.device.darkmode">
<div class="xkxvokkjlptzyewouewmceqcxhpgzprp" :data-darkmode="$store.state.device.darkmode">
<button class="ui" @click="add">%i18n:@create-list%</button>
<a v-for="list in lists" :key="list.id" @click="choice(list)">{{ list.title }}</a>
</div>
@ -60,10 +60,10 @@ root(isDark)
border solid 1px isDark ? #1c2023 : #eee
border-radius 4px
[data-id="6e4caea3-d8f9-4ab7-96de-ab67fe8d5c82"][data-darkmode]
.xkxvokkjlptzyewouewmceqcxhpgzprp[data-darkmode]
root(true)
[data-id="6e4caea3-d8f9-4ab7-96de-ab67fe8d5c82"]:not([data-darkmode])
.xkxvokkjlptzyewouewmceqcxhpgzprp:not([data-darkmode])
root(false)
</style>

View File

@ -36,7 +36,7 @@ export default Vue.extend({
<style lang="stylus" scoped>
root(isDark)
background isDark ? #282C37 : #fff
border solid 1px rgba(#000, 0.075)
border solid 1px rgba(#000, isDark ? 0.2 : 0.075)
border-radius 6px
overflow hidden

View File

@ -0,0 +1,195 @@
<template>
<div class="dnpfarvgbnfmyzbdquhhzyxcmstpdqzs" :class="{ naked, narrow }">
<header :class="{ indicate }">
<slot name="header"></slot>
<button ref="menu" @click="showMenu">%fa:caret-down%</button>
</header>
<div ref="body">
<slot></slot>
</div>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import Menu from '../../../../common/views/components/menu.vue';
export default Vue.extend({
props: {
id: {
type: String,
required: false
},
name: {
type: String,
required: false
},
menu: {
type: Array,
required: false
},
naked: {
type: Boolean,
required: false,
default: false
},
narrow: {
type: Boolean,
required: false,
default: false
}
},
data() {
return {
indicate: false
};
},
provide() {
return {
column: this,
isScrollTop: this.isScrollTop,
indicate: v => this.indicate = v
};
},
mounted() {
this.$refs.body.addEventListener('scroll', this.onScroll, { passive: true });
},
beforeDestroy() {
this.$refs.body.removeEventListener('scroll', this.onScroll);
},
methods: {
isScrollTop() {
return this.$refs.body.scrollTop == 0;
},
onScroll() {
if (this.isScrollTop()) {
this.$emit('top');
}
if (this.$store.state.settings.fetchOnScroll !== false) {
const current = this.$refs.body.scrollTop + this.$refs.body.clientHeight;
if (current > this.$refs.body.scrollHeight - 1) this.$emit('bottom');
}
},
showMenu() {
const items = [{
content: '%fa:pencil-alt% %i18n:common.deck.rename%',
onClick: () => {
(this as any).apis.input({
title: '%i18n:common.deck.rename%',
default: this.name,
allowEmpty: false
}).then(name => {
this.$store.dispatch('settings/renameDeckColumn', { id: this.id, name });
});
}
}, null, {
content: '%fa:arrow-left% %i18n:common.deck.swap-left%',
onClick: () => {
this.$store.dispatch('settings/swapLeftDeckColumn', this.id);
}
}, {
content: '%fa:arrow-right% %i18n:common.deck.swap-right%',
onClick: () => {
this.$store.dispatch('settings/swapRightDeckColumn', this.id);
}
}, null, {
content: '%fa:trash-alt R% %i18n:common.deck.remove%',
onClick: () => {
this.$store.dispatch('settings/removeDeckColumn', this.id);
}
}];
if (this.menu) {
items.unshift(null);
this.menu.reverse().forEach(i => items.unshift(i));
}
this.os.new(Menu, {
source: this.$refs.menu,
compact: false,
items
});
}
}
});
</script>
<style lang="stylus" scoped>
@import '~const.styl'
root(isDark)
$header-height = 42px
flex 1
min-width 330px
max-width 330px
height 100%
background isDark ? #282C37 : #fff
border-radius 6px
box-shadow 0 2px 16px rgba(#000, 0.1)
overflow hidden
&.narrow
min-width 285px
max-width 285px
&.naked
background rgba(#000, isDark ? 0.25 : 0.1)
> header
background transparent
box-shadow none
if !isDark
> button
color #bbb
> header
z-index 1
line-height $header-height
padding 0 16px
font-size 14px
color isDark ? #e3e5e8 : #888
background isDark ? #313543 : #fff
box-shadow 0 1px rgba(#000, 0.15)
&.indicate
box-shadow 0 3px 0 0 $theme-color
> span
[data-fa]
margin-right 8px
> button
position absolute
top 0
right 0
width $header-height
line-height $header-height
color isDark ? #9baec8 : #ccc
&:hover
color isDark ? #b2c1d5 : #aaa
&:active
color isDark ? #b2c1d5 : #999
> div
height "calc(100% - %s)" % $header-height
overflow auto
overflow-x hidden
.dnpfarvgbnfmyzbdquhhzyxcmstpdqzs[data-darkmode]
root(true)
.dnpfarvgbnfmyzbdquhhzyxcmstpdqzs:not([data-darkmode])
root(false)
</style>

View File

@ -0,0 +1,118 @@
<template>
<x-notes ref="timeline" :more="existMore ? more : null"/>
</template>
<script lang="ts">
import Vue from 'vue';
import XNotes from './deck.notes.vue';
import { UserListStream } from '../../../../common/scripts/streaming/user-list';
const fetchLimit = 10;
export default Vue.extend({
components: {
XNotes
},
props: {
list: {
type: Object,
required: true
},
mediaOnly: {
type: Boolean,
required: false,
default: false
}
},
data() {
return {
fetching: true,
moreFetching: false,
existMore: false,
connection: null
};
},
watch: {
mediaOnly() {
this.fetch();
}
},
mounted() {
if (this.connection) this.connection.close();
this.connection = new UserListStream((this as any).os, this.$store.state.i, this.list.id);
this.connection.on('note', this.onNote);
this.connection.on('userAdded', this.onUserAdded);
this.connection.on('userRemoved', this.onUserRemoved);
this.fetch();
},
beforeDestroy() {
this.connection.close();
},
methods: {
fetch() {
this.fetching = true;
(this.$refs.timeline as any).init(() => new Promise((res, rej) => {
(this as any).api('notes/user-list-timeline', {
listId: this.list.id,
limit: fetchLimit + 1,
mediaOnly: this.mediaOnly,
includeMyRenotes: this.$store.state.settings.showMyRenotes,
includeRenotedMyNotes: this.$store.state.settings.showRenotedMyNotes
}).then(notes => {
if (notes.length == fetchLimit + 1) {
notes.pop();
this.existMore = true;
}
res(notes);
this.fetching = false;
this.$emit('loaded');
}, rej);
}));
},
more() {
this.moreFetching = true;
const promise = (this as any).api('notes/user-list-timeline', {
listId: this.list.id,
limit: fetchLimit + 1,
untilId: (this.$refs.timeline as any).tail().id,
mediaOnly: this.mediaOnly,
includeMyRenotes: this.$store.state.settings.showMyRenotes,
includeRenotedMyNotes: this.$store.state.settings.showRenotedMyNotes
});
promise.then(notes => {
if (notes.length == fetchLimit + 1) {
notes.pop();
} else {
this.existMore = false;
}
notes.forEach(n => (this.$refs.timeline as any).append(n));
this.moreFetching = false;
});
return promise;
},
onNote(note) {
if (this.mediaOnly && note.media.length == 0) return;
// Prepend a note
(this.$refs.timeline as any).prepend(note);
},
onUserAdded() {
this.fetch();
},
onUserRemoved() {
this.fetch();
}
}
});
</script>

View File

@ -0,0 +1,153 @@
<template>
<div class="fnlfosztlhtptnongximhlbykxblytcq">
<mk-avatar class="avatar" :user="note.user"/>
<div class="main">
<header>
<router-link class="name" :to="note.user | userPage">{{ note.user | userName }}</router-link>
<span class="is-admin" v-if="note.user.isAdmin">%i18n:@admin%</span>
<span class="is-bot" v-if="note.user.isBot">%i18n:@bot%</span>
<span class="is-cat" v-if="note.user.isCat">%i18n:@cat%</span>
<span class="username"><mk-acct :user="note.user"/></span>
<div class="info">
<span class="mobile" v-if="note.viaMobile">%fa:mobile-alt%</span>
<router-link class="created-at" :to="note | notePage">
<mk-time :time="note.createdAt"/>
</router-link>
<span class="visibility" v-if="note.visibility != 'public'">
<template v-if="note.visibility == 'home'">%fa:home%</template>
<template v-if="note.visibility == 'followers'">%fa:unlock%</template>
<template v-if="note.visibility == 'specified'">%fa:envelope%</template>
<template v-if="note.visibility == 'private'">%fa:lock%</template>
</span>
</div>
</header>
<div class="body">
<mk-sub-note-content class="text" :note="note"/>
</div>
</div>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
export default Vue.extend({
props: {
note: {
type: Object,
required: true
},
// TODO
truncate: {
type: Boolean,
default: true
}
}
});
</script>
<style lang="stylus" scoped>
root(isDark)
display flex
padding 16px
font-size 10px
background isDark ? #21242d : #fcfcfc
&.smart
> .main
width 100%
> header
align-items center
> .avatar
flex-shrink 0
display block
margin 0 8px 0 0
width 38px
height 38px
border-radius 8px
> .main
flex 1
min-width 0
> header
display flex
align-items baseline
margin-bottom 2px
white-space nowrap
> .avatar
flex-shrink 0
margin-right 8px
width 18px
height 18px
border-radius 100%
> .name
display block
margin 0 0.5em 0 0
padding 0
overflow hidden
color isDark ? #fff : #607073
font-size 1em
font-weight 700
text-align left
text-decoration none
text-overflow ellipsis
&:hover
text-decoration underline
> .is-admin
> .is-bot
> .is-cat
align-self center
margin 0 0.5em 0 0
padding 1px 5px
font-size 0.8em
color isDark ? #758188 : #aaa
border solid 1px isDark ? #57616f : #ddd
border-radius 3px
&.is-admin
border-color isDark ? #d42c41 : #f56a7b
color isDark ? #d42c41 : #f56a7b
> .username
text-align left
margin 0
color isDark ? #606984 : #d1d8da
> .info
margin-left auto
font-size 0.9em
> *
color isDark ? #606984 : #b2b8bb
> .mobile
margin-right 6px
> .visibility
margin-left 6px
> .body
> .text
margin 0
padding 0
color isDark ? #959ba7 : #717171
pre
max-height 120px
font-size 80%
.fnlfosztlhtptnongximhlbykxblytcq[data-darkmode]
root(true)
.fnlfosztlhtptnongximhlbykxblytcq:not([data-darkmode])
root(false)
</style>

View File

@ -0,0 +1,513 @@
<template>
<div class="zyjjkidcqjnlegkqebitfviomuqmseqk" :class="{ renote: isRenote }">
<div class="reply-to" v-if="p.reply && (!$store.getters.isSignedIn || $store.state.settings.showReplyTarget)">
<x-sub :note="p.reply"/>
</div>
<div class="renote" v-if="isRenote">
<mk-avatar class="avatar" :user="note.user"/>
%fa:retweet%
<span>{{ '%i18n:@reposted-by%'.substr(0, '%i18n:@reposted-by%'.indexOf('{')) }}</span>
<router-link class="name" :to="note.user | userPage">{{ note.user | userName }}</router-link>
<span>{{ '%i18n:@reposted-by%'.substr('%i18n:@reposted-by%'.indexOf('}') + 1) }}</span>
<mk-time :time="note.createdAt"/>
</div>
<article>
<mk-avatar class="avatar" :user="p.user"/>
<div class="main">
<header>
<router-link class="name" :to="p.user | userPage">{{ p.user | userName }}</router-link>
<span class="is-admin" v-if="p.user.isAdmin">admin</span>
<span class="is-bot" v-if="p.user.isBot">bot</span>
<span class="is-cat" v-if="p.user.isCat">cat</span>
<span class="username"><mk-acct :user="p.user"/></span>
<div class="info">
<span class="mobile" v-if="p.viaMobile">%fa:mobile-alt%</span>
<router-link class="created-at" :to="p | notePage">
<mk-time :time="p.createdAt"/>
</router-link>
<span class="visibility" v-if="p.visibility != 'public'">
<template v-if="p.visibility == 'home'">%fa:home%</template>
<template v-if="p.visibility == 'followers'">%fa:unlock%</template>
<template v-if="p.visibility == 'specified'">%fa:envelope%</template>
<template v-if="p.visibility == 'private'">%fa:lock%</template>
</span>
</div>
</header>
<div class="body">
<p v-if="p.cw != null" class="cw">
<span class="text" v-if="p.cw != ''">{{ p.cw }}</span>
<span class="toggle" @click="showContent = !showContent">{{ showContent ? '%i18n:@less%' : '%i18n:@more%' }}</span>
</p>
<div class="content" v-show="p.cw == null || showContent">
<div class="text">
<span v-if="p.isHidden" style="opacity: 0.5">(%i18n:@private%)</span>
<span v-if="p.deletedAt" style="opacity: 0.5">(%i18n:@deleted%)</span>
<a class="reply" v-if="p.reply">%fa:reply%</a>
<mk-note-html v-if="p.text && !canHideText(p)" :text="p.text" :i="$store.state.i"/>
<a class="rp" v-if="p.renote != null">RP:</a>
</div>
<div class="media" v-if="p.media.length > 0">
<mk-media-list :media-list="p.media"/>
</div>
<mk-poll v-if="p.poll" :note="p" ref="pollViewer"/>
<div class="tags" v-if="p.tags && p.tags.length > 0">
<router-link v-for="tag in p.tags" :key="tag" :to="`/search?q=#${tag}`">{{ tag }}</router-link>
</div>
<a class="location" v-if="p.geo" :href="`http://maps.google.com/maps?q=${p.geo.coordinates[1]},${p.geo.coordinates[0]}`" target="_blank">%fa:map-marker-alt% %i18n:@location%</a>
<div class="renote" v-if="p.renote">
<mk-note-preview :note="p.renote"/>
</div>
</div>
<span class="app" v-if="p.app">via <b>{{ p.app.name }}</b></span>
</div>
<footer>
<mk-reactions-viewer :note="p" ref="reactionsViewer"/>
<button @click="reply">
<template v-if="p.reply">%fa:reply-all%</template>
<template v-else>%fa:reply%</template>
</button>
<button @click="renote" title="Renote">%fa:retweet%</button>
<button :class="{ reacted: p.myReaction != null }" @click="react" ref="reactButton">%fa:plus%</button>
<button class="menu" @click="menu" ref="menuButton">%fa:ellipsis-h%</button>
</footer>
</div>
</article>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import parse from '../../../../../../text/parse';
import canHideText from '../../../../common/scripts/can-hide-text';
import MkNoteMenu from '../../../../common/views/components/note-menu.vue';
import MkReactionPicker from '../../../../common/views/components/reaction-picker.vue';
import XSub from './deck.note.sub.vue';
export default Vue.extend({
components: {
XSub
},
props: ['note'],
data() {
return {
showContent: false,
connection: null,
connectionId: null
};
},
computed: {
isRenote(): boolean {
return (this.note.renote &&
this.note.text == null &&
this.note.mediaIds.length == 0 &&
this.note.poll == null);
},
p(): any {
return this.isRenote ? this.note.renote : this.note;
},
urls(): string[] {
if (this.p.text) {
const ast = parse(this.p.text);
return ast
.filter(t => (t.type == 'url' || t.type == 'link') && !t.silent)
.map(t => t.url);
} else {
return null;
}
}
},
created() {
if (this.$store.getters.isSignedIn) {
this.connection = (this as any).os.stream.getConnection();
this.connectionId = (this as any).os.stream.use();
}
},
mounted() {
this.capture(true);
if (this.$store.getters.isSignedIn) {
this.connection.on('_connected_', this.onStreamConnected);
}
},
beforeDestroy() {
this.decapture(true);
if (this.$store.getters.isSignedIn) {
this.connection.off('_connected_', this.onStreamConnected);
(this as any).os.stream.dispose(this.connectionId);
}
},
methods: {
canHideText,
capture(withHandler = false) {
if (this.$store.getters.isSignedIn) {
this.connection.send({
type: 'capture',
id: this.p.id
});
if (withHandler) this.connection.on('note-updated', this.onStreamNoteUpdated);
}
},
decapture(withHandler = false) {
if (this.$store.getters.isSignedIn) {
this.connection.send({
type: 'decapture',
id: this.p.id
});
if (withHandler) this.connection.off('note-updated', this.onStreamNoteUpdated);
}
},
onStreamConnected() {
this.capture();
},
onStreamNoteUpdated(data) {
const note = data.note;
if (note.id == this.note.id) {
this.$emit('update:note', note);
} else if (note.id == this.note.renoteId) {
this.note.renote = note;
}
},
reply() {
(this as any).apis.post({
reply: this.p
});
},
renote() {
(this as any).apis.post({
renote: this.p
});
},
react() {
(this as any).os.new(MkReactionPicker, {
source: this.$refs.reactButton,
note: this.p,
compact: true
});
},
menu() {
(this as any).os.new(MkNoteMenu, {
source: this.$refs.menuButton,
note: this.p,
compact: true
});
}
}
});
</script>
<style lang="stylus" scoped>
@import '~const.styl'
root(isDark)
font-size 12px
border-bottom solid 1px isDark ? #1c2023 : #eaeaea
&:last-of-type
border-bottom none
&.smart
> article
> .main
> header
align-items center
margin-bottom 4px
> .renote
display flex
align-items center
padding 8px 16px
line-height 28px
white-space pre
color #9dbb00
background isDark ? linear-gradient(to bottom, #314027 0%, #282c37 100%) : linear-gradient(to bottom, #edfde2 0%, #fff 100%)
.avatar
flex-shrink 0
display inline-block
width 20px
height 20px
margin 0 8px 0 0
border-radius 6px
[data-fa]
margin-right 4px
> span
flex-shrink 0
&:last-of-type
margin-right 8px
.name
overflow hidden
flex-shrink 1
text-overflow ellipsis
white-space nowrap
font-weight bold
> .mk-time
display block
margin-left auto
flex-shrink 0
font-size 0.9em
& + article
padding-top 8px
> article
display flex
padding 16px 16px 9px
> .avatar
flex-shrink 0
display block
margin 0 10px 8px 0
width 42px
height 42px
border-radius 6px
//position -webkit-sticky
//position sticky
//top 62px
> .main
flex 1
min-width 0
> header
display flex
align-items baseline
white-space nowrap
> .avatar
flex-shrink 0
margin-right 8px
width 20px
height 20px
border-radius 100%
> .name
display block
margin 0 0.5em 0 0
padding 0
overflow hidden
color isDark ? #fff : #627079
font-weight bold
text-decoration none
text-overflow ellipsis
> .is-admin
> .is-bot
> .is-cat
align-self center
margin 0 0.5em 0 0
padding 1px 6px
font-size 0.8em
color isDark ? #758188 : #aaa
border solid 1px isDark ? #57616f : #ddd
border-radius 3px
&.is-admin
border-color isDark ? #d42c41 : #f56a7b
color isDark ? #d42c41 : #f56a7b
> .username
margin 0 0.5em 0 0
overflow hidden
text-overflow ellipsis
color isDark ? #606984 : #ccc
> .info
margin-left auto
font-size 0.9em
> *
color isDark ? #606984 : #c0c0c0
> .mobile
margin-right 6px
> .visibility
margin-left 6px
> .body
> .cw
cursor default
display block
margin 0
padding 0
overflow-wrap break-word
color isDark ? #fff : #717171
> .text
margin-right 8px
> .toggle
display inline-block
padding 4px 8px
font-size 0.7em
color isDark ? #393f4f : #fff
background isDark ? #687390 : #b1b9c1
border-radius 2px
cursor pointer
user-select none
&:hover
background isDark ? #707b97 : #bbc4ce
> .content
> .text
display block
margin 0
padding 0
overflow-wrap break-word
color isDark ? #fff : #717171
>>> .title
display block
margin-bottom 4px
padding 4px
font-size 90%
text-align center
background isDark ? #2f3944 : #eef1f3
border-radius 4px
>>> .code
margin 8px 0
>>> .quote
margin 8px
padding 6px 12px
color isDark ? #6f808e : #aaa
border-left solid 3px isDark ? #637182 : #eee
> .reply
margin-right 8px
color isDark ? #99abbf : #717171
> .rp
margin-left 4px
font-style oblique
color #a0bf46
[data-is-me]:after
content "you"
padding 0 4px
margin-left 4px
font-size 80%
color $theme-color-foreground
background $theme-color
border-radius 4px
.mk-url-preview
margin-top 8px
> .tags
margin 4px 0 0 0
> *
display inline-block
margin 0 8px 0 0
padding 2px 8px 2px 16px
font-size 90%
color #8d969e
background isDark ? #313543 : #edf0f3
border-radius 4px
&:before
content ""
display block
position absolute
top 0
bottom 0
left 4px
width 8px
height 8px
margin auto 0
background isDark ? #282c37 : #fff
border-radius 100%
> .media
> img
display block
max-width 100%
> .location
margin 4px 0
font-size 12px
color #ccc
> .map
width 100%
height 200px
&:empty
display none
> .mk-poll
font-size 80%
> .renote
margin 8px 0
> .mk-note-preview
padding 16px
border dashed 1px isDark ? #4e945e : #c0dac6
border-radius 8px
> .app
font-size 12px
color #ccc
> footer
> button
margin 0
padding 8px
background transparent
border none
box-shadow none
font-size 1em
color isDark ? #606984 : #ddd
cursor pointer
&:not(:last-child)
margin-right 28px
&:hover
color isDark ? #9198af : #666
> .count
display inline
margin 0 0 0 8px
color #999
&.reacted
color $theme-color
.zyjjkidcqjnlegkqebitfviomuqmseqk[data-darkmode]
root(true)
.zyjjkidcqjnlegkqebitfviomuqmseqk:not([data-darkmode])
root(false)
</style>

View File

@ -0,0 +1,236 @@
<template>
<div class="eamppglmnmimdhrlzhplwpvyeaqmmhxu">
<slot name="empty" v-if="notes.length == 0 && !fetching && requestInitPromise == null"></slot>
<div v-if="!fetching && requestInitPromise != null">
<p>%i18n:@error%</p>
<button @click="resolveInitPromise">%i18n:@retry%</button>
</div>
<transition-group name="mk-notes" class="transition">
<template v-for="(note, i) in _notes">
<x-note :note="note" :key="note.id" @update:note="onNoteUpdated(i, $event)"/>
<p class="date" :key="note.id + '_date'" v-if="i != notes.length - 1 && note._date != _notes[i + 1]._date">
<span>%fa:angle-up%{{ note._datetext }}</span>
<span>%fa:angle-down%{{ _notes[i + 1]._datetext }}</span>
</p>
</template>
</transition-group>
<footer v-if="more">
<button @click="loadMore" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }">
<template v-if="!moreFetching">%i18n:@load-more%</template>
<template v-if="moreFetching">%fa:spinner .pulse .fw%</template>
</button>
</footer>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import { url } from '../../../config';
import getNoteSummary from '../../../../../renderers/get-note-summary';
import XNote from './deck.note.vue';
const displayLimit = 30;
export default Vue.extend({
components: {
XNote
},
inject: ['column', 'isScrollTop', 'indicate'],
props: {
more: {
type: Function,
required: false
}
},
data() {
return {
rootEl: null,
requestInitPromise: null as () => Promise<any[]>,
notes: [],
queue: [],
unreadCount: 0,
fetching: true,
moreFetching: false
};
},
computed: {
_notes(): any[] {
return (this.notes as any).map(note => {
const date = new Date(note.createdAt).getDate();
const month = new Date(note.createdAt).getMonth() + 1;
note._date = date;
note._datetext = `${month}${date}`;
return note;
});
}
},
created() {
this.column.$on('top', this.onTop);
this.column.$on('bottom', this.onBottom);
},
beforeDestroy() {
this.column.$off('top', this.onTop);
this.column.$off('bottom', this.onBottom);
},
methods: {
focus() {
(this.$el as any).children[0].focus();
},
onNoteUpdated(i, note) {
Vue.set((this as any).notes, i, note);
},
init(promiseGenerator: () => Promise<any[]>) {
this.requestInitPromise = promiseGenerator;
this.resolveInitPromise();
},
resolveInitPromise() {
this.queue = [];
this.notes = [];
this.fetching = true;
const promise = this.requestInitPromise();
promise.then(notes => {
this.notes = notes;
this.requestInitPromise = null;
this.fetching = false;
}, e => {
this.fetching = false;
});
},
prepend(note, silent = false) {
//#region 弾く
const isMyNote = note.userId == this.$store.state.i.id;
const isPureRenote = note.renoteId != null && note.text == null && note.mediaIds.length == 0 && note.poll == null;
if (this.$store.state.settings.showMyRenotes === false) {
if (isMyNote && isPureRenote) {
return;
}
}
if (this.$store.state.settings.showRenotedMyNotes === false) {
if (isPureRenote && (note.renote.userId == this.$store.state.i.id)) {
return;
}
}
//#endregion
if (this.isScrollTop()) {
// Prepend the note
this.notes.unshift(note);
// オーバーフローしたら古い投稿は捨てる
if (this.notes.length >= displayLimit) {
this.notes = this.notes.slice(0, displayLimit);
}
} else {
this.queue.push(note);
this.indicate(true);
}
},
append(note) {
this.notes.push(note);
},
tail() {
return this.notes[this.notes.length - 1];
},
releaseQueue() {
this.queue.forEach(n => this.prepend(n, true));
this.queue = [];
this.indicate(false);
},
async loadMore() {
if (this.more == null) return;
if (this.moreFetching) return;
this.moreFetching = true;
await this.more();
this.moreFetching = false;
},
onTop() {
this.releaseQueue();
},
onBottom() {
this.loadMore();
}
}
});
</script>
<style lang="stylus" scoped>
@import '~const.styl'
root(isDark)
.transition
.mk-notes-enter
.mk-notes-leave-to
opacity 0
transform translateY(-30px)
> *
transition transform .3s ease, opacity .3s ease
> .date
display block
margin 0
line-height 32px
font-size 14px
text-align center
color isDark ? #666b79 : #aaa
background isDark ? #242731 : #fdfdfd
border-bottom solid 1px isDark ? #1c2023 : #eaeaea
span
margin 0 16px
[data-fa]
margin-right 8px
> footer
> button
display block
margin 0
padding 16px
width 100%
text-align center
color #ccc
background isDark ? #282C37 : #fff
border-top solid 1px isDark ? #1c2023 : #eaeaea
border-bottom-left-radius 6px
border-bottom-right-radius 6px
&:hover
background isDark ? #2e3440 : #f5f5f5
&:active
background isDark ? #21242b : #eee
.eamppglmnmimdhrlzhplwpvyeaqmmhxu[data-darkmode]
root(true)
.eamppglmnmimdhrlzhplwpvyeaqmmhxu:not([data-darkmode])
root(false)
</style>

View File

@ -0,0 +1,179 @@
<template>
<div class="dsfykdcjpuwfvpefwufddclpjhzktmpw">
<div class="notification reaction" v-if="notification.type == 'reaction'">
<mk-avatar class="avatar" :user="notification.user"/>
<div>
<header>
<mk-reaction-icon :reaction="notification.reaction"/>
<router-link :to="notification.user | userPage">{{ notification.user | userName }}</router-link>
<mk-time :time="notification.createdAt"/>
</header>
<router-link class="note-ref" :to="notification.note | notePage">
%fa:quote-left%{{ getNoteSummary(notification.note) }}
%fa:quote-right%
</router-link>
</div>
</div>
<div class="notification renote" v-if="notification.type == 'renote'">
<mk-avatar class="avatar" :user="notification.user"/>
<div>
<header>
%fa:retweet%
<router-link :to="notification.user | userPage">{{ notification.user | userName }}</router-link>
<mk-time :time="notification.createdAt"/>
</header>
<router-link class="note-ref" :to="notification.note | notePage">
%fa:quote-left%{{ getNoteSummary(notification.note.renote) }}%fa:quote-right%
</router-link>
</div>
</div>
<div class="notification follow" v-if="notification.type == 'follow'">
<mk-avatar class="avatar" :user="notification.user"/>
<div>
<header>
%fa:user-plus%
<router-link :to="notification.user | userPage">{{ notification.user | userName }}</router-link>
<mk-time :time="notification.createdAt"/>
</header>
</div>
</div>
<div class="notification followRequest" v-if="notification.type == 'receiveFollowRequest'">
<mk-avatar class="avatar" :user="notification.user"/>
<div>
<header>
%fa:user-clock%
<router-link :to="notification.user | userPage">{{ notification.user | userName }}</router-link>
<mk-time :time="notification.createdAt"/>
</header>
</div>
</div>
<div class="notification poll_vote" v-if="notification.type == 'poll_vote'">
<mk-avatar class="avatar" :user="notification.user"/>
<div>
<header>
%fa:chart-pie%
<router-link :to="notification.user | userPage">{{ notification.user | userName }}</router-link>
<mk-time :time="notification.createdAt"/>
</header>
<router-link class="note-ref" :to="notification.note | notePage">
%fa:quote-left%{{ getNoteSummary(notification.note) }}%fa:quote-right%
</router-link>
</div>
</div>
<template v-if="notification.type == 'quote'">
<x-note :note="notification.note" @update:note="onNoteUpdated"/>
</template>
<template v-if="notification.type == 'reply'">
<x-note :note="notification.note" @update:note="onNoteUpdated"/>
</template>
<template v-if="notification.type == 'mention'">
<x-note :note="notification.note" @update:note="onNoteUpdated"/>
</template>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import getNoteSummary from '../../../../../../renderers/get-note-summary';
import XNote from './deck.note.vue';
export default Vue.extend({
components: {
XNote
},
props: ['notification'],
data() {
return {
getNoteSummary
};
},
methods: {
onNoteUpdated(note) {
switch (this.notification.type) {
case 'quote':
case 'reply':
case 'mention':
Vue.set(this.notification, 'note', note);
break;
}
}
}
});
</script>
<style lang="stylus" scoped>
root(isDark)
> .notification
padding 16px
font-size 12px
overflow-wrap break-word
&:after
content ""
display block
clear both
> .avatar
display block
float left
width 36px
height 36px
border-radius 6px
> div
float right
width calc(100% - 36px)
padding-left 8px
> header
display flex
align-items baseline
white-space nowrap
i, .mk-reaction-icon
margin-right 4px
> .mk-time
margin-left auto
color isDark ? #606984 : #c0c0c0
font-size 0.9em
> .note-preview
color isDark ? #fff : #717171
> .note-ref
color isDark ? #fff : #717171
[data-fa]
font-size 1em
font-weight normal
font-style normal
display inline-block
margin-right 3px
&.renote
> div > header i
color #77B255
&.follow
> div > header i
color #53c7ce
&.receiveFollowRequest
> div > header i
color #888
.dsfykdcjpuwfvpefwufddclpjhzktmpw[data-darkmode]
root(true)
.dsfykdcjpuwfvpefwufddclpjhzktmpw:not([data-darkmode])
root(false)
</style>

View File

@ -0,0 +1,36 @@
<template>
<div>
<x-column :id="column.id" :name="name">
<span slot="header">%fa:bell R%{{ name }}</span>
<x-notifications/>
</x-column>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import XColumn from './deck.column.vue';
import XNotifications from './deck.notifications.vue';
export default Vue.extend({
components: {
XColumn,
XNotifications
},
props: {
column: {
type: Object,
required: true
}
},
computed: {
name(): string {
if (this.column.name) return this.column.name;
return '%i18n:common.deck.notifications%';
}
},
});
</script>

View File

@ -0,0 +1,179 @@
<template>
<div class="oxynyeqmfvracxnglgulyqfgqxnxmehl">
<transition-group name="mk-notifications" class="transition notifications">
<template v-for="(notification, i) in _notifications">
<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'">
<span>%fa:angle-up%{{ notification._datetext }}</span>
<span>%fa:angle-down%{{ _notifications[i + 1]._datetext }}</span>
</p>
</template>
</transition-group>
<button class="more" :class="{ fetching: fetchingMoreNotifications }" v-if="moreNotifications" @click="fetchMoreNotifications" :disabled="fetchingMoreNotifications">
<template v-if="fetchingMoreNotifications">%fa:spinner .pulse .fw%</template>{{ fetchingMoreNotifications ? '%i18n:common.loading%' : '%i18n:@more%' }}
</button>
<p class="empty" v-if="notifications.length == 0 && !fetching">%i18n:@empty%</p>
<p class="loading" v-if="fetching">%fa:spinner .pulse .fw%%i18n:common.loading%<mk-ellipsis/></p>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import XNotification from './deck.notification.vue';
export default Vue.extend({
components: {
XNotification
},
data() {
return {
fetching: true,
fetchingMoreNotifications: false,
notifications: [],
moreNotifications: false,
connection: null,
connectionId: null
};
},
computed: {
_notifications(): any[] {
return (this.notifications as any).map(notification => {
const date = new Date(notification.createdAt).getDate();
const month = new Date(notification.createdAt).getMonth() + 1;
notification._date = date;
notification._datetext = `${month}${date}`;
return notification;
});
}
},
mounted() {
this.connection = (this as any).os.stream.getConnection();
this.connectionId = (this as any).os.stream.use();
this.connection.on('notification', this.onNotification);
const max = 10;
(this as any).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() {
this.connection.off('notification', this.onNotification);
(this as any).os.stream.dispose(this.connectionId);
},
methods: {
fetchMoreNotifications() {
this.fetchingMoreNotifications = true;
const max = 30;
(this as any).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) {
// TODO: ユーザーが画面を見てないと思われるとき(ブラウザやタブがアクティブじゃないなど)は送信しない
this.connection.send({
type: 'read_notification',
id: notification.id
});
this.notifications.unshift(notification);
}
}
});
</script>
<style lang="stylus" scoped>
root(isDark)
.transition
.mk-notifications-enter
.mk-notifications-leave-to
opacity 0
transform translateY(-30px)
> *
transition transform .3s ease, opacity .3s ease
> .notifications
> .notification:not(:last-child)
border-bottom solid 1px isDark ? #1c2023 : #eaeaea
> .date
display block
margin 0
line-height 32px
text-align center
font-size 0.8em
color isDark ? #666b79 : #aaa
background isDark ? #242731 : #fdfdfd
border-bottom solid 1px isDark ? #1c2023 : #eaeaea
span
margin 0 16px
i
margin-right 8px
> .more
display block
width 100%
padding 16px
color #555
border-top solid 1px rgba(#000, 0.05)
&:hover
background rgba(#000, 0.025)
&:active
background rgba(#000, 0.05)
&.fetching
cursor wait
> [data-fa]
margin-right 4px
> .empty
margin 0
padding 16px
text-align center
color #aaa
> .loading
margin 0
padding 16px
text-align center
color #aaa
> [data-fa]
margin-right 4px
.oxynyeqmfvracxnglgulyqfgqxnxmehl[data-darkmode]
root(true)
.oxynyeqmfvracxnglgulyqfgqxnxmehl:not([data-darkmode])
root(false)
</style>

View File

@ -0,0 +1,73 @@
<template>
<div>
<x-column :id="column.id" :menu="menu" :name="name">
<span slot="header">
<template v-if="column.type == 'home'">%fa:home%</template>
<template v-if="column.type == 'local'">%fa:R comments%</template>
<template v-if="column.type == 'global'">%fa:globe%</template>
<template v-if="column.type == 'list'">%fa:list%</template>
<span>{{ name }}</span>
</span>
<div class="editor" v-if="edit">
<mk-switch v-model="column.isMediaOnly" @change="onChangeSettings" text="%i18n:@is-media-only%"/>
<mk-switch v-model="column.isMediaView" @change="onChangeSettings" text="%i18n:@is-media-view%"/>
</div>
<x-list-tl v-if="column.type == 'list'" :list="column.list" :media-only="column.isMediaOnly"/>
<x-tl v-else :src="column.type" :media-only="column.isMediaOnly"/>
</x-column>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import XColumn from './deck.column.vue';
import XTl from './deck.tl.vue';
import XListTl from './deck.list-tl.vue';
export default Vue.extend({
components: {
XColumn,
XTl,
XListTl
},
props: {
column: {
type: Object,
required: true
}
},
data() {
return {
edit: false,
menu: [{
content: '%fa:cog% %i18n:@edit%',
onClick: () => {
this.edit = !this.edit;
}
}]
}
},
computed: {
name(): string {
if (this.column.name) return this.column.name;
switch (this.column.type) {
case 'home': return '%i18n:common.deck.home%';
case 'local': return '%i18n:common.deck.local%';
case 'global': return '%i18n:common.deck.global%';
case 'list': return this.column.list.title;
}
}
},
methods: {
onChangeSettings(v) {
this.$store.dispatch('settings/saveDeck');
}
}
});
</script>

View File

@ -0,0 +1,147 @@
<template>
<x-notes ref="timeline" :more="existMore ? more : null"/>
</template>
<script lang="ts">
import Vue from 'vue';
import XNotes from './deck.notes.vue';
const fetchLimit = 10;
export default Vue.extend({
components: {
XNotes
},
props: {
src: {
type: String,
required: false,
default: 'home'
},
mediaOnly: {
type: Boolean,
required: false,
default: false
}
},
data() {
return {
fetching: true,
moreFetching: false,
existMore: false,
connection: null,
connectionId: null
};
},
watch: {
mediaOnly() {
this.fetch();
}
},
computed: {
stream(): any {
return this.src == 'home'
? (this as any).os.stream
: this.src == 'local'
? (this as any).os.streams.localTimelineStream
: (this as any).os.streams.globalTimelineStream;
},
endpoint(): string {
return this.src == 'home'
? 'notes/timeline'
: this.src == 'local'
? 'notes/local-timeline'
: 'notes/global-timeline';
}
},
mounted() {
this.connection = this.stream.getConnection();
this.connectionId = this.stream.use();
this.connection.on('note', this.onNote);
if (this.src == 'home') {
this.connection.on('follow', this.onChangeFollowing);
this.connection.on('unfollow', this.onChangeFollowing);
}
this.fetch();
},
beforeDestroy() {
this.connection.off('note', this.onNote);
if (this.src == 'home') {
this.connection.off('follow', this.onChangeFollowing);
this.connection.off('unfollow', this.onChangeFollowing);
}
this.stream.dispose(this.connectionId);
},
methods: {
fetch() {
this.fetching = true;
(this.$refs.timeline as any).init(() => new Promise((res, rej) => {
(this as any).api(this.endpoint, {
limit: fetchLimit + 1,
mediaOnly: this.mediaOnly,
includeMyRenotes: this.$store.state.settings.showMyRenotes,
includeRenotedMyNotes: this.$store.state.settings.showRenotedMyNotes
}).then(notes => {
if (notes.length == fetchLimit + 1) {
notes.pop();
this.existMore = true;
}
res(notes);
this.fetching = false;
this.$emit('loaded');
}, rej);
}));
},
more() {
this.moreFetching = true;
const promise = (this as any).api(this.endpoint, {
limit: fetchLimit + 1,
mediaOnly: this.mediaOnly,
untilId: (this.$refs.timeline as any).tail().id,
includeMyRenotes: this.$store.state.settings.showMyRenotes,
includeRenotedMyNotes: this.$store.state.settings.showRenotedMyNotes
});
promise.then(notes => {
if (notes.length == fetchLimit + 1) {
notes.pop();
} else {
this.existMore = false;
}
notes.forEach(n => (this.$refs.timeline as any).append(n));
this.moreFetching = false;
});
return promise;
},
onNote(note) {
if (this.mediaOnly && note.media.length == 0) return;
// Prepend a note
(this.$refs.timeline as any).prepend(note);
},
onChangeFollowing() {
this.fetch();
},
focus() {
(this.$refs.timeline as any).focus();
}
}
});
</script>

View File

@ -0,0 +1,185 @@
<template>
<mk-ui :class="$style.root">
<div class="qlvquzbjribqcaozciifydkngcwtyzje" :data-darkmode="$store.state.device.darkmode">
<template v-for="column in columns">
<x-widgets-column v-if="column.type == 'widgets'" :key="column.id" :column="column"/>
<x-notifications-column v-if="column.type == 'notifications'" :key="column.id" :column="column"/>
<x-tl-column v-if="column.type == 'home'" :key="column.id" :column="column"/>
<x-tl-column v-if="column.type == 'local'" :key="column.id" :column="column"/>
<x-tl-column v-if="column.type == 'global'" :key="column.id" :column="column"/>
<x-tl-column v-if="column.type == 'list'" :key="column.id" :column="column"/>
</template>
<button ref="add" @click="add" title="%i18n:common.deck.add-column%">%fa:plus%</button>
</div>
</mk-ui>
</template>
<script lang="ts">
import Vue from 'vue';
import XTlColumn from './deck.tl-column.vue';
import XNotificationsColumn from './deck.notifications-column.vue';
import XWidgetsColumn from './deck.widgets-column.vue';
import Menu from '../../../../common/views/components/menu.vue';
import MkUserListsWindow from '../../components/user-lists-window.vue';
import * as uuid from 'uuid';
export default Vue.extend({
components: {
XTlColumn,
XNotificationsColumn,
XWidgetsColumn
},
computed: {
columns() {
if (this.$store.state.settings.deck == null) return [];
return this.$store.state.settings.deck.columns;
}
},
created() {
if (this.$store.state.settings.deck == null) {
const deck = {
columns: [/*{
type: 'widgets',
widgets: []
}, */{
id: uuid(),
type: 'home'
}, {
id: uuid(),
type: 'notifications'
}, {
id: uuid(),
type: 'local'
}, {
id: uuid(),
type: 'global'
}]
};
this.$store.dispatch('settings/set', {
key: 'deck',
value: deck
});
}
},
mounted() {
document.documentElement.style.overflow = 'hidden';
},
beforeDestroy() {
document.documentElement.style.overflow = 'auto';
},
methods: {
add() {
this.os.new(Menu, {
source: this.$refs.add,
compact: true,
items: [{
content: '%i18n:common.deck.home%',
onClick: () => {
this.$store.dispatch('settings/addDeckColumn', {
id: uuid(),
type: 'home'
});
}
}, {
content: '%i18n:common.deck.local%',
onClick: () => {
this.$store.dispatch('settings/addDeckColumn', {
id: uuid(),
type: 'local'
});
}
}, {
content: '%i18n:common.deck.global%',
onClick: () => {
this.$store.dispatch('settings/addDeckColumn', {
id: uuid(),
type: 'global'
});
}
}, {
content: '%i18n:common.deck.list%',
onClick: () => {
const w = (this as any).os.new(MkUserListsWindow);
w.$once('choosen', list => {
this.$store.dispatch('settings/addDeckColumn', {
id: uuid(),
type: 'list',
list: list
});
w.close();
});
}
}, {
content: '%i18n:common.deck.notifications%',
onClick: () => {
this.$store.dispatch('settings/addDeckColumn', {
id: uuid(),
type: 'notifications'
});
}
}, {
content: '%i18n:common.deck.widgets%',
onClick: () => {
this.$store.dispatch('settings/addDeckColumn', {
id: uuid(),
type: 'widgets',
widgets: []
});
}
}]
});
}
}
});
</script>
<style lang="stylus" module>
.root
height 100vh
</style>
<style lang="stylus" scoped>
@import '~const.styl'
root(isDark)
display flex
flex 1
padding 16px 0 16px 16px
overflow auto
> div
margin-right 8px
&:last-of-type
margin-right 0
> *
&:first-child
margin-left auto
&:last-child
margin-right auto
> button
padding 0 16px
color isDark ? #93a0a5 : #888
&:hover
color isDark ? #b8c5ca : #777
&:active
color isDark ? #fff : #555
.qlvquzbjribqcaozciifydkngcwtyzje[data-darkmode]
root(true)
.qlvquzbjribqcaozciifydkngcwtyzje:not([data-darkmode])
root(false)
</style>

View File

@ -0,0 +1,159 @@
<template>
<div class="wtdtxvecapixsepjtcupubtsmometobz">
<x-column :id="column.id" :menu="menu" :naked="true" :narrow="true" :name="name">
<span slot="header">%fa:calculator%{{ name }}</span>
<div class="gqpwvtwtprsbmnssnbicggtwqhmylhnq">
<template v-if="edit">
<header>
<select v-model="widgetAdderSelected">
<option value="profile">%i18n:common.widgets.profile%</option>
<option value="analog-clock">%i18n:common.widgets.analog-clock%</option>
<option value="calendar">%i18n:common.widgets.calendar%</option>
<option value="timemachine">%i18n:common.widgets.timemachine%</option>
<option value="activity">%i18n:common.widgets.activity%</option>
<option value="rss">%i18n:common.widgets.rss%</option>
<option value="trends">%i18n:common.widgets.trends%</option>
<option value="photo-stream">%i18n:common.widgets.photo-stream%</option>
<option value="slideshow">%i18n:common.widgets.slideshow%</option>
<option value="version">%i18n:common.widgets.version%</option>
<option value="broadcast">%i18n:common.widgets.broadcast%</option>
<option value="notifications">%i18n:common.widgets.notifications%</option>
<option value="users">%i18n:common.widgets.users%</option>
<option value="polls">%i18n:common.widgets.polls%</option>
<option value="post-form">%i18n:common.widgets.post-form%</option>
<option value="messaging">%i18n:common.widgets.messaging%</option>
<option value="memo">%i18n:common.widgets.memo%</option>
<option value="server">%i18n:common.widgets.server%</option>
<option value="donation">%i18n:common.widgets.donation%</option>
<option value="nav">%i18n:common.widgets.nav%</option>
<option value="tips">%i18n:common.widgets.tips%</option>
</select>
<button @click="addWidget">%i18n:@add%</button>
</header>
<x-draggable
:list="column.widgets"
:options="{ handle: '.handle', animation: 150 }"
@sort="onWidgetSort"
>
<div v-for="widget in column.widgets" class="customize-container" :key="widget.id">
<header>
<span class="handle">%fa:bars%</span>{{ widget.name }}<button class="remove" @click="removeWidget(widget)">%fa:times%</button>
</header>
<div @click="widgetFunc(widget.id)">
<component :is="`mkw-${widget.name}`" :widget="widget" :ref="widget.id" :is-customize-mode="true" platform="deck"/>
</div>
</div>
</x-draggable>
</template>
<template v-else>
<component class="widget" v-for="widget in column.widgets" :is="`mkw-${widget.name}`" :key="widget.id" :ref="widget.id" :widget="widget" platform="deck"/>
</template>
</div>
</x-column>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import XColumn from './deck.column.vue';
import * as XDraggable from 'vuedraggable';
import * as uuid from 'uuid';
export default Vue.extend({
components: {
XColumn,
XDraggable
},
props: {
column: {
type: Object,
required: true
}
},
data() {
return {
edit: false,
menu: null,
widgetAdderSelected: null
}
},
computed: {
name(): string {
if (this.column.name) return this.column.name;
return '%i18n:common.deck.widgets%';
}
},
created() {
this.menu = [{
content: '%fa:cog% %i18n:@edit%',
onClick: () => {
this.edit = !this.edit;
}
}];
},
methods: {
widgetFunc(id) {
const w = this.$refs[id][0];
if (w.func) w.func();
},
onWidgetSort() {
this.saveWidgets();
},
addWidget() {
this.$store.dispatch('settings/addDeckWidget', {
id: this.column.id,
widget: {
name: this.widgetAdderSelected,
id: uuid(),
data: {}
}
});
},
removeWidget(widget) {
this.$store.dispatch('settings/removeDeckWidget', {
id: this.column.id,
widget
});
},
saveWidgets() {
this.$store.dispatch('settings/saveDeck');
}
}
});
</script>
<style lang="stylus" scoped>
@import '~const.styl'
root(isDark)
.gqpwvtwtprsbmnssnbicggtwqhmylhnq
.widget, .customize-container
margin 8px
&:first-of-type
margin-top 0
.customize-container
background #fff
> header
color isDark ? #fff : #000
.wtdtxvecapixsepjtcupubtsmometobz[data-darkmode]
root(true)
.wtdtxvecapixsepjtcupubtsmometobz:not([data-darkmode])
root(false)
</style>

View File

@ -2,7 +2,7 @@
<mk-ui>
<main v-if="!fetching">
<template v-for="favorite in favorites">
<mk-note-detail :note="favorite.note" :key="favorite.note.id"/>
<mk-note-detail class="post" :note="favorite.note" :key="favorite.note.id"/>
</template>
<a v-if="existMore" @click="more">%i18n:@more%</a>
</main>
@ -70,4 +70,7 @@ main
margin 0 auto
padding 16px
max-width 700px
> .post
margin-bottom 16px
</style>

View File

@ -46,7 +46,7 @@ export default Vue.extend({
},
mounted() {
document.addEventListener('keydown', this.onDocumentKeydown);
window.addEventListener('scroll', this.onScroll);
window.addEventListener('scroll', this.onScroll, { passive: true });
this.fetch();
},

View File

@ -37,7 +37,7 @@ export default Vue.extend({
mounted() {
if (this.user.bannerUrl) {
window.addEventListener('load', this.onScroll);
window.addEventListener('scroll', this.onScroll);
window.addEventListener('scroll', this.onScroll, { passive: true });
window.addEventListener('resize', this.onScroll);
}
},

View File

@ -12,7 +12,7 @@
</article>
</main>
<main v-else class="index">
<img :src="$store.state.device.darkmode ? 'assets/title-dark.svg' : 'assets/title.svg'" alt="Misskey">
<img :src="$store.state.device.darkmode ? 'assets/title.dark.svg' : 'assets/title.light.svg'" alt="Misskey">
<p class="desc"><b>%i18n:common.misskey%</b> - <span @click="about = true">%i18n:@about%</span></p>
<p class="account">
<button class="signup" @click="signup">%i18n:@signup-button%</button>
@ -80,10 +80,10 @@ export default Vue.extend({
<style lang="stylus" scoped>
@import '~const.styl'
@import url(https://fonts.googleapis.com/earlyaccess/notosansjp.css);
root(isDark)
display flex
flex-direction column
flex 1
min-height 100vh
background-image isDark ? url('/assets/welcome-bg.dark.svg') : url('/assets/welcome-bg.light.svg')
background-size cover
background-position center
@ -103,6 +103,7 @@ root(isDark)
text-align center
&.about
font-family 'Noto Sans JP'
color isDark ? #fff : #627574
> article
@ -114,7 +115,7 @@ root(isDark)
> h1
margin 0
font-variant small-caps
font-weight 900
> p
margin 20px 0

View File

@ -3,7 +3,7 @@
<template v-if="props.design == 0">
<p class="title">%fa:pencil-alt%%i18n:@title%</p>
</template>
<textarea :disabled="posting" v-model="text" @keydown="onKeydown" placeholder="%i18n:@placeholder%"></textarea>
<textarea :disabled="posting" v-model="text" @keydown="onKeydown" :placeholder="placeholder"></textarea>
<button @click="post" :disabled="posting">%i18n:@note%</button>
</div>
</template>
@ -22,6 +22,19 @@ export default define({
text: ''
};
},
computed: {
placeholder(): string {
const xs = [
'%i18n:common.note-placeholders.a%',
'%i18n:common.note-placeholders.b%',
'%i18n:common.note-placeholders.c%',
'%i18n:common.note-placeholders.d%',
'%i18n:common.note-placeholders.e%',
'%i18n:common.note-placeholders.f%'
];
return xs[Math.floor(Math.random() * xs.length)];
}
},
methods: {
func() {
if (this.props.design == 1) {

View File

@ -73,12 +73,12 @@ export default class MiOS extends EventEmitter {
public app: Vue;
public new(vm, props) {
const w = new vm({
const x = new vm({
parent: this.app,
propsData: props
}).$mount();
document.body.appendChild(w.$el);
return w;
document.body.appendChild(x.$el);
return x;
}
/**

View File

@ -32,10 +32,14 @@ import MkNotifications from './views/pages/notifications.vue';
import MkWidgets from './views/pages/widgets.vue';
import MkMessaging from './views/pages/messaging.vue';
import MkMessagingRoom from './views/pages/messaging-room.vue';
import MkReceivedFollowRequests from './views/pages/received-follow-requests.vue';
import MkNote from './views/pages/note.vue';
import MkSearch from './views/pages/search.vue';
import MkFollowers from './views/pages/followers.vue';
import MkFollowing from './views/pages/following.vue';
import MkFavorites from './views/pages/favorites.vue';
import MkUserLists from './views/pages/user-lists.vue';
import MkUserList from './views/pages/user-list.vue';
import MkSettings from './views/pages/settings.vue';
import MkOthello from './views/pages/othello.vue';
@ -72,6 +76,10 @@ init((launch) => {
{ path: '/signup', name: 'signup', component: MkSignup },
{ path: '/i/settings', name: 'settings', component: MkSettings },
{ path: '/i/notifications', name: 'notifications', component: MkNotifications },
{ path: '/i/favorites', name: 'favorites', component: MkFavorites },
{ path: '/i/lists', name: 'user-lists', component: MkUserLists },
{ path: '/i/lists/:list', name: 'user-list', component: MkUserList },
{ path: '/i/received-follow-requests', name: 'received-follow-requests', component: MkReceivedFollowRequests },
{ path: '/i/widgets', name: 'widgets', component: MkWidgets },
{ path: '/i/messaging', name: 'messaging', component: MkMessaging },
{ path: '/i/messaging/:user', component: MkMessagingRoom },

View File

@ -1,13 +1,16 @@
<template>
<button class="mk-follow-button"
:class="{ wait: wait, follow: !user.isFollowing, unfollow: user.isFollowing }"
:class="{ wait: wait, active: u.isFollowing || u.hasPendingFollowRequestFromYou }"
@click="onClick"
:disabled="wait"
>
<template v-if="!wait && user.isFollowing">%fa:minus%</template>
<template v-if="!wait && !user.isFollowing">%fa:plus%</template>
<template v-if="wait">%fa:spinner .pulse .fw%</template>
{{ user.isFollowing ? '%i18n:@unfollow%' : '%i18n:@follow%' }}
<template v-if="!wait">
<template v-if="u.hasPendingFollowRequestFromYou">%fa:hourglass-half% %i18n:@request-pending%</template>
<template v-else-if="u.isFollowing">%fa:minus% %i18n:@following%</template>
<template v-else-if="!u.isFollowing && u.isLocked">%fa:plus% %i18n:@follow-request%</template>
<template v-else-if="!u.isFollowing && !u.isLocked">%fa:plus% %i18n:@follow%</template>
</template>
<template v-else>%fa:spinner .pulse .fw%</template>
</button>
</template>
@ -22,6 +25,7 @@ export default Vue.extend({
},
data() {
return {
u: this.user,
wait: false,
connection: null,
connectionId: null
@ -42,39 +46,44 @@ export default Vue.extend({
methods: {
onFollow(user) {
if (user.id == this.user.id) {
this.user.isFollowing = user.isFollowing;
if (user.id == this.u.id) {
this.u.isFollowing = user.isFollowing;
}
},
onUnfollow(user) {
if (user.id == this.user.id) {
this.user.isFollowing = user.isFollowing;
if (user.id == this.u.id) {
this.u.isFollowing = user.isFollowing;
}
},
onClick() {
async onClick() {
this.wait = true;
if (this.user.isFollowing) {
(this as any).api('following/delete', {
userId: this.user.id
}).then(() => {
this.user.isFollowing = false;
}).catch(err => {
console.error(err);
}).then(() => {
this.wait = false;
});
} else {
(this as any).api('following/create', {
userId: this.user.id
}).then(() => {
this.user.isFollowing = true;
}).catch(err => {
console.error(err);
}).then(() => {
this.wait = false;
});
try {
if (this.u.isFollowing) {
this.u = await (this as any).api('following/delete', {
userId: this.u.id
});
} else {
if (this.u.isLocked && this.u.hasPendingFollowRequestFromYou) {
this.u = await (this as any).api('following/requests/cancel', {
userId: this.u.id
});
} else if (this.u.isLocked) {
this.u = await (this as any).api('following/create', {
userId: this.u.id
});
} else {
this.u = await (this as any).api('following/create', {
userId: this.user.id
});
}
}
} catch (e) {
console.error(e);
} finally {
this.wait = false;
}
}
}
@ -90,34 +99,39 @@ export default Vue.extend({
cursor pointer
padding 0 16px
margin 0
height inherit
font-size 16px
min-width 150px
line-height 36px
font-size 14px
font-weight bold
color $theme-color
background transparent
outline none
border solid 1px $theme-color
border-radius 4px
border-radius 36px
*
pointer-events none
&:hover
background rgba($theme-color, 0.1)
&.follow
color $theme-color
background transparent
&:active
background rgba($theme-color, 0.2)
&:hover
background rgba($theme-color, 0.1)
&:active
background rgba($theme-color, 0.2)
&.unfollow
&.active
color $theme-color-foreground
background $theme-color
&:hover
background lighten($theme-color, 10%)
border-color lighten($theme-color, 10%)
&:active
background darken($theme-color, 10%)
border-color darken($theme-color, 10%)
&.wait
cursor wait !important
opacity 0.7
> [data-fa]
margin-right 4px
*
pointer-events none
</style>

View File

@ -1,101 +0,0 @@
<template>
<div class="root sub">
<mk-avatar class="avatar" :user="note.user"/>
<div class="main">
<header>
<router-link class="name" :to="note.user | userPage">{{ note.user | userName }}</router-link>
<span class="username"><mk-acct :user="note.user"/></span>
<router-link class="time" :to="note | notePage">
<mk-time :time="note.createdAt"/>
</router-link>
</header>
<div class="body">
<mk-sub-note-content class="text" :note="note"/>
</div>
</div>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
export default Vue.extend({
props: ['note']
});
</script>
<style lang="stylus" scoped>
root(isDark)
padding 8px
font-size 0.9em
background isDark ? #21242d : #fdfdfd
@media (min-width 500px)
padding 12px
@media (min-width 600px)
padding 24px 32px
&:after
content ""
display block
clear both
> .avatar
display block
float left
margin 0 12px 0 0
width 48px
height 48px
border-radius 8px
> .main
float left
width calc(100% - 60px)
> header
display flex
align-items baseline
margin-bottom 4px
white-space nowrap
> .name
display block
margin 0 .5em 0 0
padding 0
overflow hidden
color isDark ? #fff : #607073
font-size 1em
font-weight 700
text-align left
text-decoration none
text-overflow ellipsis
&:hover
text-decoration underline
> .username
text-align left
margin 0 .5em 0 0
color isDark ? #606984 : #d1d8da
> .time
margin-left auto
color isDark ? #606984 : #b2b8bb
> .body
> .text
cursor default
margin 0
padding 0
font-size 1.1em
color isDark ? #959ba7 : #717171
.root.sub[data-darkmode]
root(true)
.root.sub:not([data-darkmode])
root(false)
</style>

View File

@ -87,7 +87,7 @@ import parse from '../../../../../text/parse';
import MkNoteMenu from '../../../common/views/components/note-menu.vue';
import MkReactionPicker from '../../../common/views/components/reaction-picker.vue';
import XSub from './note-detail.sub.vue';
import XSub from './note.sub.vue';
export default Vue.extend({
components: {
@ -172,7 +172,7 @@ export default Vue.extend({
},
methods: {
fetchContext() {
fetchConversation() {
this.conversationFetching = true;
// Fetch conversation
@ -216,8 +216,6 @@ export default Vue.extend({
root(isDark)
overflow hidden
margin 0 auto
padding 0
width 100%
text-align left
background isDark ? #282C37 : #fff

View File

@ -9,9 +9,18 @@
<span class="is-bot" v-if="note.user.isBot">%i18n:@bot%</span>
<span class="is-cat" v-if="note.user.isCat">%i18n:@cat%</span>
<span class="username"><mk-acct :user="note.user"/></span>
<router-link class="time" :to="note | notePage">
<mk-time :time="note.createdAt"/>
</router-link>
<div class="info">
<span class="mobile" v-if="note.viaMobile">%fa:mobile-alt%</span>
<router-link class="created-at" :to="note | notePage">
<mk-time :time="note.createdAt"/>
</router-link>
<span class="visibility" v-if="note.visibility != 'public'">
<template v-if="note.visibility == 'home'">%fa:home%</template>
<template v-if="note.visibility == 'followers'">%fa:unlock%</template>
<template v-if="note.visibility == 'specified'">%fa:envelope%</template>
<template v-if="note.visibility == 'private'">%fa:lock%</template>
</span>
</div>
</header>
<div class="body">
<mk-sub-note-content class="text" :note="note"/>
@ -30,14 +39,16 @@ export default Vue.extend({
<style lang="stylus" scoped>
root(isDark)
display flex
margin 0
padding 0
font-size 0.9em
font-size 10px
&:after
content ""
display block
clear both
@media (min-width 350px)
font-size 12px
@media (min-width 500px)
font-size 14px
&.smart
> .main
@ -47,24 +58,26 @@ root(isDark)
align-items center
> .avatar
flex-shrink 0
display block
float left
margin 0 12px 0 0
width 48px
height 48px
margin 0 10px 0 0
width 40px
height 40px
border-radius 8px
@media (max-width 500px)
@media (min-width 350px)
margin 0 10px 0 0
width 44px
height 44px
> .main
float left
width calc(100% - 60px)
@media (min-width 500px)
margin 0 12px 0 0
width 48px
height 48px
@media (max-width 500px)
width calc(100% - 54px)
> .main
flex 1
min-width 0
> header
display flex
@ -97,7 +110,7 @@ root(isDark)
align-self center
margin 0 0.5em 0 0
padding 1px 6px
font-size 10px
font-size 0.8em
color isDark ? #758188 : #aaa
border solid 1px isDark ? #57616f : #ddd
border-radius 3px
@ -112,9 +125,18 @@ root(isDark)
text-overflow ellipsis
color isDark ? #606984 : #d1d8da
> .time
> .info
margin-left auto
color isDark ? #606984 : #b2b8bb
font-size 0.9em
> *
color isDark ? #606984 : #b2b8bb
> .mobile
margin-right 6px
> .visibility
margin-left 6px
> .body

View File

@ -33,16 +33,33 @@
import Vue from 'vue';
export default Vue.extend({
props: ['note']
props: {
note: {
type: Object,
required: true
},
// TODO
truncate: {
type: Boolean,
default: true
}
}
});
</script>
<style lang="stylus" scoped>
root(isDark)
display flex
padding 16px
font-size 0.9em
font-size 10px
background isDark ? #21242d : #fcfcfc
@media (min-width 350px)
font-size 12px
@media (min-width 500px)
font-size 14px
@media (min-width 600px)
padding 24px 32px
@ -53,30 +70,27 @@ root(isDark)
> header
align-items center
&:after
content ""
display block
clear both
> .avatar
flex-shrink 0
display block
float left
margin 0 10px 0 0
width 42px
height 42px
margin 0 8px 0 0
width 38px
height 38px
border-radius 8px
@media (min-width 350px)
margin-right 10px
width 42px
height 42px
@media (min-width 500px)
margin-right 14px
width 50px
height 50px
> .main
float left
width calc(100% - 52px)
@media (min-width 500px)
width calc(100% - 64px)
flex 1
min-width 0
> header
display flex
@ -112,7 +126,7 @@ root(isDark)
align-self center
margin 0 0.5em 0 0
padding 1px 5px
font-size 10px
font-size 0.8em
color isDark ? #758188 : #aaa
border solid 1px isDark ? #57616f : #ddd
border-radius 3px
@ -140,11 +154,8 @@ root(isDark)
margin-left 6px
> .body
max-height 128px
overflow hidden
> .text
cursor default
margin 0
padding 0
color isDark ? #959ba7 : #717171

View File

@ -269,8 +269,6 @@ root(isDark)
&.smart
> article
> .main
width 100%
> header
align-items center
margin-bottom 4px
@ -328,27 +326,28 @@ root(isDark)
padding-top 8px
> article
display flex
padding 16px 16px 9px
@media (min-width 600px)
padding 32px 32px 22px
&:after
content ""
display block
clear both
> .avatar
flex-shrink 0
display block
float left
margin 0 10px 8px 0
width 48px
height 48px
width 42px
height 42px
border-radius 6px
//position -webkit-sticky
//position sticky
//top 62px
@media (min-width 350px)
width 48px
height 48px
border-radius 6px
@media (min-width 500px)
margin-right 16px
width 58px
@ -356,11 +355,8 @@ root(isDark)
border-radius 8px
> .main
float left
width calc(100% - 58px)
@media (min-width 500px)
width calc(100% - 74px)
flex 1
min-width 0
> header
display flex
@ -393,7 +389,7 @@ root(isDark)
align-self center
margin 0 0.5em 0 0
padding 1px 6px
font-size 12px
font-size 0.8em
color isDark ? #758188 : #aaa
border solid 1px isDark ? #57616f : #ddd
border-radius 3px
@ -422,6 +418,8 @@ root(isDark)
margin-left 6px
> .body
@media (min-width 700px)
font-size 1.1em
> .cw
cursor default
@ -504,7 +502,7 @@ root(isDark)
padding 2px 8px 2px 16px
font-size 90%
color #8d969e
background #edf0f3
background isDark ? #313543 : #edf0f3
border-radius 4px
&:before
@ -517,7 +515,7 @@ root(isDark)
width 8px
height 8px
margin auto 0
background #fff
background isDark ? #282c37 : #fff
border-radius 100%
> .media

View File

@ -81,7 +81,7 @@ export default Vue.extend({
mounted() {
document.addEventListener('visibilitychange', this.onVisibilitychange, false);
window.addEventListener('scroll', this.onScroll);
window.addEventListener('scroll', this.onScroll, { passive: true });
},
beforeDestroy() {

View File

@ -1,7 +1,7 @@
<template>
<div class="mk-notification-preview" :class="notification.type">
<template v-if="notification.type == 'reaction'">
<img class="avatar" :src="`${notification.user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
<mk-avatar class="avatar" :user="notification.user"/>
<div class="text">
<p><mk-reaction-icon :reaction="notification.reaction"/>{{ notification.user | userName }}</p>
<p class="note-ref">%fa:quote-left%{{ getNoteSummary(notification.note) }}%fa:quote-right%</p>
@ -9,7 +9,7 @@
</template>
<template v-if="notification.type == 'renote'">
<img class="avatar" :src="`${notification.note.user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
<mk-avatar class="avatar" :user="notification.note.user"/>
<div class="text">
<p>%fa:retweet%{{ notification.note.user | userName }}</p>
<p class="note-ref">%fa:quote-left%{{ getNoteSummary(notification.note.renote) }}%fa:quote-right%</p>
@ -17,7 +17,7 @@
</template>
<template v-if="notification.type == 'quote'">
<img class="avatar" :src="`${notification.note.user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
<mk-avatar class="avatar" :user="notification.note.user"/>
<div class="text">
<p>%fa:quote-left%{{ notification.note.user | userName }}</p>
<p class="note-preview">{{ getNoteSummary(notification.note) }}</p>
@ -25,14 +25,21 @@
</template>
<template v-if="notification.type == 'follow'">
<img class="avatar" :src="`${notification.user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
<mk-avatar class="avatar" :user="notification.user"/>
<div class="text">
<p>%fa:user-plus%{{ notification.user | userName }}</p>
</div>
</template>
<template v-if="notification.type == 'receiveFollowRequest'">
<mk-avatar class="avatar" :user="notification.user"/>
<div class="text">
<p>%fa:user-clock%{{ notification.user | userName }}</p>
</div>
</template>
<template v-if="notification.type == 'reply'">
<img class="avatar" :src="`${notification.note.user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
<mk-avatar class="avatar" :user="notification.note.user"/>
<div class="text">
<p>%fa:reply%{{ notification.note.user | userName }}</p>
<p class="note-preview">{{ getNoteSummary(notification.note) }}</p>
@ -40,7 +47,7 @@
</template>
<template v-if="notification.type == 'mention'">
<img class="avatar" :src="`${notification.note.user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
<mk-avatar class="avatar" :user="notification.note.user"/>
<div class="text">
<p>%fa:at%{{ notification.note.user | userName }}</p>
<p class="note-preview">{{ getNoteSummary(notification.note) }}</p>
@ -48,7 +55,7 @@
</template>
<template v-if="notification.type == 'poll_vote'">
<img class="avatar" :src="`${notification.user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
<mk-avatar class="avatar" :user="notification.user"/>
<div class="text">
<p>%fa:chart-pie%{{ notification.user | userName }}</p>
<p class="note-ref">%fa:quote-left%{{ getNoteSummary(notification.note) }}%fa:quote-right%</p>
@ -83,16 +90,14 @@ export default Vue.extend({
display block
clear both
img
> .avatar
display block
float left
min-width 36px
min-height 36px
max-width 36px
max-height 36px
width 36px
height 36px
border-radius 6px
.text
> .text
float right
width calc(100% - 36px)
padding-left 8px
@ -120,6 +125,10 @@ export default Vue.extend({
.text p i
color #53c7ce
&.receiveFollowRequest
.text p i
color #888
&.reply, &.mention
.text p i
color #fff

View File

@ -40,6 +40,17 @@
</div>
</div>
<div class="notification followRequest" v-if="notification.type == 'receiveFollowRequest'">
<mk-avatar class="avatar" :user="notification.user"/>
<div>
<header>
%fa:user-clock%
<router-link :to="notification.user | userPage">{{ notification.user | userName }}</router-link>
<mk-time :time="notification.createdAt"/>
</header>
</div>
</div>
<div class="notification poll_vote" v-if="notification.type == 'poll_vote'">
<mk-avatar class="avatar" :user="notification.user"/>
<div>
@ -55,15 +66,15 @@
</div>
<template v-if="notification.type == 'quote'">
<mk-note :note="notification.note"/>
<mk-note :note="notification.note" @update:note="onNoteUpdated"/>
</template>
<template v-if="notification.type == 'reply'">
<mk-note :note="notification.note"/>
<mk-note :note="notification.note" @update:note="onNoteUpdated"/>
</template>
<template v-if="notification.type == 'mention'">
<mk-note :note="notification.note"/>
<mk-note :note="notification.note" @update:note="onNoteUpdated"/>
</template>
</div>
</template>
@ -78,6 +89,17 @@ export default Vue.extend({
return {
getNoteSummary
};
},
methods: {
onNoteUpdated(note) {
switch (this.notification.type) {
case 'quote':
case 'reply':
case 'mention':
Vue.set(this.notification, 'note', note);
break;
}
}
}
});
</script>
@ -156,6 +178,10 @@ root(isDark)
> div > header i
color #53c7ce
&.receiveFollowRequest
> div > header i
color #888
.mk-notification[data-darkmode]
root(true)

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