Compare commits

...

259 Commits

Author SHA1 Message Date
47c45d48b1 4.13.0 2018-06-24 15:56:18 +09:00
cdd9585cb8 🎨 2018-06-24 15:55:41 +09:00
db60188847 Fix bug 2018-06-24 15:51:03 +09:00
21a2e5f415 4.12.0 2018-06-24 13:23:57 +09:00
2377c9b4cb Merge pull request #1773 from syuilo/l10n_master
New Crowdin translations
2018-06-24 13:22:57 +09:00
296f6b1553 New translations ja.yml (English) 2018-06-24 13:20:48 +09:00
e15643ca46 Better reversi labels 2018-06-24 13:18:22 +09:00
9632ba40cc New translations ja.yml (Portuguese) 2018-06-24 13:11:11 +09:00
a2cdeeb6c7 New translations ja.yml (Korean) 2018-06-24 13:11:10 +09:00
a23857ce3c New translations ja.yml (Polish) 2018-06-24 13:11:08 +09:00
78677b3aa7 New translations ja.yml (Chinese Simplified) 2018-06-24 13:11:06 +09:00
7dd264953f New translations ja.yml (Italian) 2018-06-24 13:11:04 +09:00
17af9c3ab6 New translations ja.yml (Russian) 2018-06-24 13:11:02 +09:00
4b49f8fbb8 New translations ja.yml (English) 2018-06-24 13:11:00 +09:00
e253225c66 New translations ja.yml (Spanish) 2018-06-24 13:10:58 +09:00
6abb6f90f6 New translations ja.yml (German) 2018-06-24 13:10:56 +09:00
9fb2743a38 New translations ja.yml (French) 2018-06-24 13:10:55 +09:00
17792716a7 4.11.0 2018-06-24 13:09:22 +09:00
ae7282358e Merge branch 'master' of https://github.com/syuilo/misskey 2018-06-24 13:08:50 +09:00
abc082f7c0 リモートフォローフォームを実装するなど 2018-06-24 13:08:48 +09:00
bf1163ae84 Merge pull request #1772 from syuilo/greenkeeper/ws-5.2.1
Update ws to the latest version 🚀
2018-06-24 03:19:48 +09:00
be74ca472a fix(package): update ws to version 5.2.1 2018-06-23 17:55:11 +00:00
31b472fa47 4.10.0 2018-06-23 23:19:15 +09:00
b502627494 Fix nado 2018-06-23 23:18:39 +09:00
a8017369d0 4.9.0 2018-06-23 23:04:49 +09:00
3f0b5e4318 ✌️ 2018-06-23 23:03:25 +09:00
aea8f93e02 Merge branch 'master' of https://github.com/syuilo/misskey 2018-06-23 22:55:57 +09:00
874411990b ✌️ 2018-06-23 22:55:32 +09:00
780268f70e Merge pull request #1771 from syuilo/patch-1
Use capital letters for othello label
2018-06-23 22:50:53 +09:00
3a8a374e87 Use capital letters for othello label 2018-06-23 22:25:22 +09:00
488f36d491 i18n 2018-06-23 21:56:47 +09:00
4d48b0be99 Fix type 2018-06-23 21:48:36 +09:00
44f3888c24 スペイン語を追加 2018-06-23 19:57:23 +09:00
a76fb4c173 i18n 2018-06-23 19:35:19 +09:00
e4aa003157 MFM: Improve search syntax 2018-06-23 19:31:28 +09:00
247f334334 Fix 2018-06-23 19:18:14 +09:00
509cdae832 Fix bug 2018-06-23 19:16:50 +09:00
5ff59b3339 4.8.0 2018-06-23 17:00:28 +09:00
2b1a785f24 きゃー 2018-06-23 16:58:54 +09:00
2c0b137848 リバーシのラベルを表示できるように 2018-06-23 16:55:52 +09:00
ef68e633cf Merge pull request #1768 from syuilo/greenkeeper/eslint-5.0.0
Update eslint to the latest version 🚀
2018-06-23 12:11:49 +09:00
e9e63ba950 Merge pull request #1767 from syuilo/greenkeeper/hard-source-webpack-plugin-0.9.0
Update hard-source-webpack-plugin to the latest version 🚀
2018-06-23 12:11:31 +09:00
3fd6167e71 Merge pull request #1766 from syuilo/greenkeeper/@types/node-10.3.5
Update @types/node to the latest version 🚀
2018-06-23 12:11:15 +09:00
6b0573ded1 Merge pull request #1769 from syuilo/greenkeeper/ts-node-7.0.0
fix(package): update ts-node to version 7.0.0
2018-06-23 12:11:08 +09:00
328dc80324 4.7.1 2018-06-23 12:09:58 +09:00
24d8617f81 Fix bug 2018-06-23 12:09:09 +09:00
e2c3d4f2fb fix(package): update eslint to version 5.0.0 2018-06-23 02:46:37 +00:00
60229d73c9 fix(package): update hard-source-webpack-plugin to version 0.9.0 2018-06-23 02:35:38 +00:00
40235463bc Fix 2018-06-23 11:30:18 +09:00
c6cbadc514 fix(package): update @types/node to version 10.3.5 2018-06-23 00:27:09 +00:00
3c3c67a34c fix(package): update ts-node to version 7.0.0
Closes #1765
2018-06-22 19:17:54 +00:00
72eedd2ff9 Merge pull request #1764 from syuilo/greenkeeper/ratelimiter-3.1.0
Update ratelimiter to the latest version 🚀
2018-06-22 23:06:04 +09:00
a7e9d5a60b fix(package): update ratelimiter to version 3.1.0 2018-06-22 13:55:39 +00:00
c3d081b700 Merge pull request #1763 from tamaina/better-note-header
change flex-shrink of .username to 2147483647
2018-06-22 21:00:19 +09:00
57f62c919c change flex-shrink of .username to 2147483647 2018-06-22 20:55:19 +09:00
19bdd4fa2a 4.7.0 2018-06-22 18:51:41 +09:00
9d8391583f ✌️ 2018-06-22 18:47:23 +09:00
6037b0acc5 非ログイン時のトップにトレンドを表示するように 2018-06-22 18:32:21 +09:00
09c5efc161 ✌️ 2018-06-22 18:03:08 +09:00
16c2aefe7b Clean up: Remove the unused file 2018-06-22 17:55:58 +09:00
06cfa207fc ✌️ 2018-06-22 17:51:36 +09:00
0be8bbc19f Update README.md 2018-06-22 17:49:21 +09:00
bad85375de Merge pull request #1760 from syuilo/greenkeeper/@types/koa-router-7.0.30
Update @types/koa-router to the latest version 🚀
2018-06-22 17:48:41 +09:00
6c11a7a6c4 Merge pull request #1762 from tamaina/Improve-UI
trifling style changes
2018-06-22 13:39:19 +09:00
6f38c6f339 $theme-color 2018-06-22 13:37:46 +09:00
fb1d727db9 trifling style changes
投稿のタグのマージンと色の最適化
ユーザーページの修正(幅が伸びる、profileの色)
ウェルカムページの修正(ダークモード時)
2018-06-22 13:20:27 +09:00
d98d286dc4 Merge pull request #1761 from tamaina/better-note-header
Fix #1759 (Improve note-header)
2018-06-22 12:26:37 +09:00
1be279dbaa revert ✌️ d6ef92 2018-06-22 11:15:11 +09:00
90e6feeb4c fix(package): update @types/koa-router to version 7.0.30 2018-06-22 01:51:01 +00:00
f1f9f235c7 Update README.md 2018-06-22 02:13:16 +09:00
eb3f938281 Merge pull request #1759 from tamaina/better-note-header
Improve note-header
2018-06-21 21:21:14 +09:00
d6ef923134 ✌️ 2018-06-21 21:19:54 +09:00
5b01577810 Improve note-header 2018-06-21 19:59:33 +09:00
2a111d472a Merge pull request #1758 from syuilo/l10n_master
New Crowdin translations
2018-06-21 14:49:17 +09:00
a8809e89b9 New translations ja.yml (English) 2018-06-21 14:10:53 +09:00
1ab9a49d01 New translations ja.yml (English) 2018-06-21 14:00:53 +09:00
f92c116564 4.6.0 2018-06-21 11:39:54 +09:00
b54539b647 Fix bug 2018-06-21 11:37:18 +09:00
87fc6522fb Improve ServiceWorker notification 2018-06-21 11:35:28 +09:00
b0408d1d6e Merge pull request #1757 from syuilo/greenkeeper/@types/webpack-4.4.2
Update @types/webpack to the latest version 🚀
2018-06-21 09:53:45 +09:00
39779ca8d5 fix(package): update @types/webpack to version 4.4.2 2018-06-21 00:50:02 +00:00
8c34f7559d Merge pull request #1756 from syuilo/greenkeeper/@types/mocha-5.2.3
Update @types/mocha to the latest version 🚀
2018-06-21 09:42:39 +09:00
740c7c2476 Merge pull request #1754 from syuilo/greenkeeper/@types/koa-bodyparser-5.0.0
Update @types/koa-bodyparser to the latest version 🚀
2018-06-21 09:39:22 +09:00
abd43dd471 Merge pull request #1755 from syuilo/greenkeeper/@types/koa-router-7.0.29
Update @types/koa-router to the latest version 🚀
2018-06-21 09:39:11 +09:00
c24b5410bc fix(package): update @types/mocha to version 5.2.3 2018-06-21 00:38:08 +00:00
cde7d0f463 fix(package): update @types/koa-router to version 7.0.29 2018-06-21 00:29:15 +00:00
54548c3ed0 fix(package): update @types/koa-bodyparser to version 5.0.0 2018-06-21 00:21:18 +00:00
221d1edf0f Merge pull request #1753 from syuilo/l10n_master
New Crowdin translations
2018-06-21 08:54:59 +09:00
02e75f9539 Merge pull request #1752 from syuilo/greenkeeper/web-push-3.3.2
Update web-push to the latest version 🚀
2018-06-21 08:54:46 +09:00
6bed2ff106 Merge pull request #1751 from syuilo/greenkeeper/ts-node-6.1.2
Update ts-node to the latest version 🚀
2018-06-21 08:54:36 +09:00
f3e1e4d1da New translations ja.yml (Polish) 2018-06-21 07:21:29 +09:00
370f6384d9 fix(package): update web-push to version 3.3.2 2018-06-20 21:58:40 +00:00
0105587d04 fix(package): update ts-node to version 6.1.2 2018-06-20 20:49:11 +00:00
e327970ab9 Merge pull request #1750 from syuilo/l10n_master
New Crowdin translations
2018-06-21 02:26:14 +09:00
9e247f39ff New translations ja.yml (English) 2018-06-21 02:20:19 +09:00
09f3a10b46 4.5.0 2018-06-21 02:14:26 +09:00
c3679a84e5 ✌️ 2018-06-21 02:12:20 +09:00
75f8d5e7d9 ✌️ 2018-06-21 02:03:25 +09:00
6ba4fa50b9 New translations ja.yml (Portuguese) 2018-06-21 02:01:46 +09:00
f5e130f2a6 New translations ja.yml (Korean) 2018-06-21 02:01:44 +09:00
cd5dcd87b0 New translations ja.yml (Polish) 2018-06-21 02:01:41 +09:00
54f319af0e New translations ja.yml (Chinese Simplified) 2018-06-21 02:01:38 +09:00
96949059cf New translations ja.yml (Italian) 2018-06-21 02:01:36 +09:00
763368db99 New translations ja.yml (Russian) 2018-06-21 02:01:34 +09:00
f622ea654f New translations ja.yml (English) 2018-06-21 02:01:32 +09:00
70c4e6c287 New translations ja.yml (Spanish) 2018-06-21 02:01:30 +09:00
d7692e875a New translations ja.yml (German) 2018-06-21 02:01:28 +09:00
0a94010668 New translations ja.yml (French) 2018-06-21 02:01:26 +09:00
50bd1d9a5d 更新ダイアログをHTMLで描画 2018-06-21 01:58:47 +09:00
d45121a93b New translations ja.yml (Portuguese) 2018-06-21 01:51:30 +09:00
a55e3fb225 New translations ja.yml (Korean) 2018-06-21 01:51:28 +09:00
426b2f5858 New translations ja.yml (Polish) 2018-06-21 01:51:26 +09:00
3d10b5e538 New translations ja.yml (Chinese Simplified) 2018-06-21 01:51:24 +09:00
b639599620 New translations ja.yml (Italian) 2018-06-21 01:51:22 +09:00
63c51c6ee0 New translations ja.yml (Russian) 2018-06-21 01:51:19 +09:00
f39934c274 New translations ja.yml (English) 2018-06-21 01:51:17 +09:00
adec1643bf New translations ja.yml (Spanish) 2018-06-21 01:51:15 +09:00
229ea7d3ab New translations ja.yml (German) 2018-06-21 01:51:13 +09:00
03899f042d New translations ja.yml (French) 2018-06-21 01:51:09 +09:00
46d7cee639 🎨 2018-06-21 01:46:35 +09:00
eb0c378138 Merge branch 'master' of https://github.com/syuilo/misskey 2018-06-21 01:22:06 +09:00
79d1bf30a4 リモートユーザーのHTMLで表現されたプロフィールをMFMに変換するように 2018-06-21 01:21:57 +09:00
5786434f37 Update README.md 2018-06-20 22:40:02 +09:00
3633d7ada1 Disable transitions to avoid memory leak 2018-06-20 22:28:08 +09:00
b95d4aed11 Merge pull request #1749 from syuilo/greenkeeper/initial
Update dependencies to enable Greenkeeper 🌴
2018-06-20 20:28:15 +09:00
c2f599a33c Merge branch 'master' into greenkeeper/initial 2018-06-20 20:28:02 +09:00
89361cfce4 4.4.0 2018-06-20 20:08:36 +09:00
278a6c504a ✌️ 2018-06-20 20:04:28 +09:00
e140ddf7be Merge branch 'master' of https://github.com/syuilo/misskey 2018-06-20 20:02:11 +09:00
f00ba4e704 Prevent update those packages 2018-06-20 20:02:03 +09:00
8128656a9e docs(readme): add Greenkeeper badge 2018-06-20 10:59:57 +00:00
f2f7a6de6b chore(package): update dependencies 2018-06-20 10:59:54 +00:00
8651d81b73 Merge pull request #1748 from syuilo/l10n_master
New Crowdin translations
2018-06-20 19:58:47 +09:00
2458255e22 nanka iroiro 2018-06-20 19:55:34 +09:00
ea12c6e2c0 New translations ja.yml (Polish) 2018-06-20 04:31:22 +09:00
2e22bd2ecf Update manifest.json 2018-06-19 19:07:39 +09:00
777cb0033e Merge pull request #1745 from syuilo/l10n_master
New Crowdin translations
2018-06-19 08:08:23 +09:00
127c126ef5 4.3.1 2018-06-19 08:03:39 +09:00
01ff8d171a Fix bug 2018-06-19 08:03:00 +09:00
457c23fffa New translations ja.yml (English) 2018-06-19 08:00:54 +09:00
b07911ec68 Fix 2018-06-19 07:56:26 +09:00
fb211d59a8 Merge branch 'master' into l10n_master 2018-06-19 07:53:32 +09:00
4e586d35a9 New translations ja.yml (Polish) 2018-06-18 20:23:37 +09:00
52f2461fe6 New translations ja.yml (Portuguese) 2018-06-18 17:32:21 +09:00
ac7dab8b6e New translations ja.yml (Korean) 2018-06-18 17:32:19 +09:00
5e171c2ad1 New translations ja.yml (Polish) 2018-06-18 17:32:17 +09:00
b4a139515c New translations ja.yml (Chinese Simplified) 2018-06-18 17:32:15 +09:00
30219f6b6f New translations ja.yml (Italian) 2018-06-18 17:32:13 +09:00
d19e6bdd03 New translations ja.yml (Russian) 2018-06-18 17:32:11 +09:00
65ce0a5e54 New translations ja.yml (English) 2018-06-18 17:32:09 +09:00
c2659d68dc New translations ja.yml (Spanish) 2018-06-18 17:32:07 +09:00
773c7ba14b New translations ja.yml (German) 2018-06-18 17:32:05 +09:00
93e617f488 New translations ja.yml (French) 2018-06-18 17:32:02 +09:00
f7959c073f 4.3.0 2018-06-18 17:25:45 +09:00
6953970be7 Merge branch 'master' of https://github.com/syuilo/misskey 2018-06-18 17:25:23 +09:00
1496fdaf80 nanka 2018-06-18 17:25:20 +09:00
0fc034b1ac Merge pull request #1743 from Tosuke/patch-1
Replace "size" to "sizes"
2018-06-18 16:48:49 +09:00
c3312c918e replace "size" to "sizes"
やらかした
2018-06-18 16:44:42 +09:00
5a13964ced Fix bug 2018-06-18 16:34:26 +09:00
fe07b1cb7f Merge pull request #1742 from Tosuke/patch-1
Fix path
2018-06-18 15:39:40 +09:00
d805a70508 Fix path 2018-06-18 15:38:58 +09:00
0f0009e0db Clean up 2018-06-18 15:12:29 +09:00
4c4cb2bb17 ✌️ 2018-06-18 15:05:38 +09:00
fe319a529f 4.2.0 2018-06-18 14:54:09 +09:00
91bea1f6c7 ✌️ 2018-06-18 14:52:36 +09:00
01745f7c65 Merge pull request #1706 from syuilo/l10n_master
New Crowdin translations
2018-06-18 14:44:29 +09:00
5d3943ffa8 Merge branch 'master' into l10n_master 2018-06-18 14:43:56 +09:00
e66d7babc5 yatta 2018-06-18 14:28:43 +09:00
80e5645a84 wip 2018-06-18 09:54:53 +09:00
a766faeae9 Merge pull request #1738 from rinsuki/features/ts-noimplicitany-true
[WIP] noImplicitAny: true
2018-06-18 08:42:17 +09:00
4d2d226446 New translations ja.yml (Spanish) 2018-06-18 00:40:45 +09:00
61e83b10c3 New translations ja.yml (Spanish) 2018-06-18 00:30:44 +09:00
ed675f0956 New translations ja.yml (French) 2018-06-17 22:10:47 +09:00
9cce8ab214 New translations ja.yml (French) 2018-06-17 22:00:55 +09:00
daa409cd82 [noImplicitAny: true] src/services/drive 2018-06-17 20:04:19 +09:00
9d65415fdc [noImplicitAny: true] src/services/note 2018-06-17 19:59:02 +09:00
8c40917cc2 [noImplicitAny: true] src/text 2018-06-17 19:55:39 +09:00
871f886702 build:ts success 2018-06-17 19:09:24 +09:00
f19075c50a upgrade font-awesome packages 2018-06-17 17:57:50 +09:00
71da205ab7 fix 2018-06-17 17:45:59 +09:00
a34cc47a11 tsconfig.json noImplicitAny: true 2018-06-17 17:43:54 +09:00
cbddaf1d19 Merge pull request #1735 from rinsuki/fix/minor-fix-201806171721
minor fix
2018-06-17 17:21:50 +09:00
1f1ed2da4c minor fix 2018-06-17 17:21:16 +09:00
8d81bd0dc0 Merge pull request #1732 from rinsuki/fix/1731
Fix #1731
2018-06-17 17:15:31 +09:00
5773a5bfa6 Refactor 2018-06-17 17:15:03 +09:00
7275a48102 Fix #1731 2018-06-17 17:11:05 +09:00
8f84dd610c Use ' 2018-06-17 16:55:55 +09:00
f1f466ed23 Merge pull request #1730 from rinsuki/fix/1729
Fix #1729
2018-06-17 16:51:24 +09:00
0ca5237139 Send servicewroker script 2018-06-17 16:47:37 +09:00
20549bfdf0 Fix #1729 2018-06-17 16:45:01 +09:00
d692bb3c52 Improve user search 2018-06-17 16:40:18 +09:00
44cd1e9223 Merge pull request #1728 from rinsuki/fix/1726
fix #1726
2018-06-17 16:02:21 +09:00
f0fec654ff fix #1726 2018-06-17 15:58:23 +09:00
4e04e5e0c0 Merge pull request #1722 from rinsuki/fix/1700
Fix #1700
2018-06-17 14:30:07 +09:00
4991fb2769 Fix #1700 2018-06-17 14:29:07 +09:00
4d90d554f8 Merge pull request #1721 from rinsuki/activitypub/support-cw
maybe Support CW in ActivityPub
2018-06-17 14:12:50 +09:00
e5468713ac maybe Support CW in ActivityPub 2018-06-17 14:11:31 +09:00
77013f982d Fiox bug 2018-06-17 13:52:52 +09:00
0460cdedd7 inputのsuffixがはみ出す問題を修正 2018-06-17 11:42:23 +09:00
73f5bf69e8 4.1.0 2018-06-17 11:33:24 +09:00
750c0d7df2 Use wildcard 2018-06-17 11:27:20 +09:00
2fcebdd281 cors 2018-06-17 11:23:18 +09:00
e4e65a4cd5 Update CHANGELOG.md 2018-06-17 08:23:46 +09:00
e010ecb03f New translations ja.yml (Portuguese) 2018-06-17 08:21:10 +09:00
fc74db668d New translations ja.yml (Korean) 2018-06-17 08:21:08 +09:00
1bac3418b4 New translations ja.yml (Polish) 2018-06-17 08:21:06 +09:00
53df8c48b7 New translations ja.yml (Chinese Simplified) 2018-06-17 08:21:04 +09:00
92702fe47e New translations ja.yml (Italian) 2018-06-17 08:21:02 +09:00
017c4c12cd New translations ja.yml (Russian) 2018-06-17 08:21:01 +09:00
830d246ba4 New translations ja.yml (English) 2018-06-17 08:20:59 +09:00
6b33afa916 New translations ja.yml (Spanish) 2018-06-17 08:20:57 +09:00
69a3efd534 Update CHANGELOG.md 2018-06-17 08:20:56 +09:00
2d0adb8f4c New translations ja.yml (German) 2018-06-17 08:20:55 +09:00
da9d8cb138 New translations ja.yml (French) 2018-06-17 08:20:53 +09:00
2acaca8582 Update CHANGELOG.md 2018-06-17 08:20:22 +09:00
11cf82c6a4 4.0.0 2018-06-17 08:15:57 +09:00
1ef66c962a reversi 💮 💯 2018-06-17 08:10:54 +09:00
03f20599ba Add missing semicolon 2018-06-17 07:39:51 +09:00
d150b10b3e Update default home widgets 2018-06-17 06:57:50 +09:00
c4f323aae3 Merge pull request #1719 from Tosuke/master
Improve web app manifest(#1716)
2018-06-16 19:53:08 +09:00
8297f8ccd0 Merge branch 'master' of github.com:syuilo/misskey 2018-06-16 19:46:51 +09:00
f336241576 improve web app manifest 2018-06-16 19:45:49 +09:00
f6d9a7e7c3 3.1.1 2018-06-16 19:45:47 +09:00
80d1ee7543 Fix bug 2018-06-16 19:45:29 +09:00
e55a254353 3.1.0 2018-06-16 18:43:25 +09:00
555a0f276c MisskeyShare 2018-06-16 18:42:49 +09:00
cdce7aa5e2 New translations ja.yml (Spanish) 2018-06-16 09:51:05 +09:00
82cea185b2 New translations ja.yml (Spanish) 2018-06-16 09:30:38 +09:00
f92a4bb195 New translations ja.yml (Spanish) 2018-06-16 09:20:56 +09:00
9f4f88df9c New translations ja.yml (Spanish) 2018-06-16 09:10:48 +09:00
e69803cbd1 New translations ja.yml (Spanish) 2018-06-16 09:00:56 +09:00
a9885be09e New translations ja.yml (Spanish) 2018-06-16 05:40:57 +09:00
7b011f4a91 New translations ja.yml (Spanish) 2018-06-16 05:30:45 +09:00
41c404abe6 New translations ja.yml (Spanish) 2018-06-16 05:20:43 +09:00
2089a761cf New translations ja.yml (Spanish) 2018-06-16 05:00:48 +09:00
0ee2df010d New translations ja.yml (Spanish) 2018-06-16 04:50:43 +09:00
466844c016 New translations ja.yml (Spanish) 2018-06-16 04:40:58 +09:00
bbf9a08649 New translations ja.yml (Polish) 2018-06-15 20:11:35 +09:00
c985c66652 New translations ja.yml (Portuguese) 2018-06-15 20:02:34 +09:00
f9dc96320e New translations ja.yml (Korean) 2018-06-15 20:02:32 +09:00
42552789fe New translations ja.yml (Polish) 2018-06-15 20:02:30 +09:00
1a2ffeb0b5 New translations ja.yml (Chinese Simplified) 2018-06-15 20:02:28 +09:00
4f75493249 New translations ja.yml (Italian) 2018-06-15 20:02:25 +09:00
42193695fb New translations ja.yml (Russian) 2018-06-15 20:02:23 +09:00
02af0de21e New translations ja.yml (English) 2018-06-15 20:02:21 +09:00
5f8e10e524 New translations ja.yml (Spanish) 2018-06-15 20:02:19 +09:00
cee93d746c New translations ja.yml (German) 2018-06-15 20:02:17 +09:00
08704a383f New translations ja.yml (French) 2018-06-15 20:02:14 +09:00
acdf7c244f New translations ja.yml (Polish) 2018-06-12 03:15:56 +09:00
a72b6745aa New translations ja.yml (Portuguese) 2018-06-12 02:33:16 +09:00
24086e9023 New translations ja.yml (Korean) 2018-06-12 02:33:14 +09:00
c3d4b5ad38 New translations ja.yml (Polish) 2018-06-12 02:33:12 +09:00
cc618a83e5 New translations ja.yml (Chinese Simplified) 2018-06-12 02:33:08 +09:00
9eaa0b27db New translations ja.yml (Italian) 2018-06-12 02:33:06 +09:00
a8835a679e New translations ja.yml (Russian) 2018-06-12 02:33:00 +09:00
656bc6df84 New translations ja.yml (English) 2018-06-12 02:32:57 +09:00
019aaf7d82 New translations ja.yml (Spanish) 2018-06-12 02:32:55 +09:00
76bafbf398 New translations ja.yml (German) 2018-06-12 02:32:52 +09:00
030bcb99b1 New translations ja.yml (French) 2018-06-12 02:32:47 +09:00
317 changed files with 3135 additions and 4012 deletions

View File

@ -1,6 +1,23 @@
ChangeLog ChangeLog
========= =========
破壊的変更のみ記載。
This document describes breaking changes only.
4.0.0
-----
オセロがリバーシに変更されました。
Othello is now Reversi.
### Migration
MongoDBの、`othelloGames``othelloMatchings`コレクションをそれぞれ`reversiGames``reversiMatchings`にリネームしてください。
You need to rename `othelloGames` and `othelloMatchings` MongoDB collections to `reversiGames` and `reversiMatchings`.
3.0.0 3.0.0
----- -----

View File

@ -5,9 +5,7 @@
[![][travis-badge]][travis-link] [![][travis-badge]][travis-link]
[![][dependencies-badge]][dependencies-link] [![][dependencies-badge]][dependencies-link]
[![][himawari-badge]][himasaku] [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com) [![Greenkeeper badge](https://badges.greenkeeper.io/syuilo/misskey.svg)](https://greenkeeper.io/)
[![][sakurako-badge]][himasaku]
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com)
> Lead Maintainer: [syuilo][syuilo-link] > Lead Maintainer: [syuilo][syuilo-link]
@ -26,7 +24,7 @@ ultimately sophisticated professional microblogging software.
* and widgets! * and widgets!
* Private messages * Private messages
* Mute * Mute
* Streaming * Real-time timelines
* ActivityPub compatible * ActivityPub compatible
and more! You can see it with your own eyes at [misskey.xyz](https://misskey.xyz). and more! You can see it with your own eyes at [misskey.xyz](https://misskey.xyz).
@ -49,9 +47,9 @@ If you want to...
[![Backers][backers-image]][support-url] [![Backers][backers-image]][support-url]
[![Sponsors][sponsors-image]][support-url] [![Sponsors][sponsors-image]][support-url]
| ![][ooo-icon] | | ![][nagarus-icon] | ![][dansup-icon] |
|:-:| |:-:|:-:|
| [ooo][ooo-link] | | [nagarus][nagarus-link] | [dansup][dansup-link] |
:four_leaf_clover: Copyright :four_leaf_clover: Copyright
---------------------------------------------------------------- ----------------------------------------------------------------
@ -67,9 +65,6 @@ Misskey is an open-source software licensed under [GNU AGPLv3](LICENSE).
[travis-badge]: http://img.shields.io/travis/syuilo/misskey/master.svg?style=flat-square [travis-badge]: http://img.shields.io/travis/syuilo/misskey/master.svg?style=flat-square
[dependencies-link]: https://david-dm.org/syuilo/misskey [dependencies-link]: https://david-dm.org/syuilo/misskey
[dependencies-badge]: https://img.shields.io/david/syuilo/misskey.svg?style=flat-square [dependencies-badge]: https://img.shields.io/david/syuilo/misskey.svg?style=flat-square
[himasaku]: https://himasaku.net
[himawari-badge]: https://img.shields.io/badge/%E5%8F%A4%E8%B0%B7-%E5%90%91%E6%97%A5%E8%91%B5-1684c5.svg?style=flat-square
[sakurako-badge]: https://img.shields.io/badge/%E5%A4%A7%E5%AE%A4-%E6%AB%BB%E5%AD%90-efb02a.svg?style=flat-square
[backer-url]: #backers [backer-url]: #backers
[backer-badge]: https://opencollective.com/misskey/backers/badge.svg [backer-badge]: https://opencollective.com/misskey/backers/badge.svg
@ -82,5 +77,8 @@ Misskey is an open-source software licensed under [GNU AGPLv3](LICENSE).
[syuilo-link]: https://syuilo.com [syuilo-link]: https://syuilo.com
[syuilo-icon]: https://avatars2.githubusercontent.com/u/4439005?v=3&s=70 [syuilo-icon]: https://avatars2.githubusercontent.com/u/4439005?v=3&s=70
[ooo-link]: https://www.patreon.com/user/creators?u=11601413 [nagarus-link]: https://www.patreon.com/user/creators?u=11601413
[ooo-icon]: https://c10.patreonusercontent.com/3/eyJ2IjoiMSIsInciOjIwMH0%3D/patreon-media/user/11601413/20cb15f209924302b399b99d3c98b850?token-time=2145916800&token-hash=IO31nK6VZCMWBWU2VAk2c824BX2QZ4DNPKyHHZXS0iw%3D [nagarus-icon]: https://c10.patreonusercontent.com/3/eyJ2IjoiMSIsInciOjIwMH0%3D/patreon-media/user/11601413/20cb15f209924302b399b99d3c98b850?token-time=2145916800&token-hash=IO31nK6VZCMWBWU2VAk2c824BX2QZ4DNPKyHHZXS0iw%3D
[dansup-link]: https://www.patreon.com/dansup
[dansup-icon]: https://c10.patreonusercontent.com/3/eyJ2IjoiMSIsInciOjIwMH0%3D/patreon-media/user/4503830/ccf2cc867ea64de0b524bb2e24b9a1cb?token-time=2145916800&token-hash=opXAM_pnhUTuN1jCA6p_Nn_YsaqohY465YFjWFqMEEE%3D

BIN
assets/icons/128.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
assets/icons/16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 446 B

BIN
assets/icons/192.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

BIN
assets/icons/256.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

BIN
assets/icons/32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 774 B

BIN
assets/icons/64.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -22,8 +22,4 @@ The list of people who have sent donation for Misskey.
--- ---
If your name is missing, please contact us! If your name is missing, please contact us!
If you want to donate to Misskey, please get in touch with [@syuilo][syuilo-link].
[syuilo-link]: https://syuilo.com

View File

@ -1,26 +0,0 @@
# Misskeyにカンパする方法
Misskeyのサポートにご興味をお持ちいただきありがとうございます
Misskeyにカンパをしていただくと、貴方のお名前と好きなURLなどをMisskeyのリポジトリに刻む権利がもらえます。
Misskeyにカンパして開発・運営をサポートするには、次のいくつかの方法があります:
## ConoHaカードを購入する
(本家)Misskeyは、ConoHaというVPSサービスを利用しています。ConoHaカードを購入して、
カードに記載されているクーポンコードを syuilotan@yahoo.co.jp までお送りいただければ、
そのクーポンをチャージしてサーバーの運営費に充てることができます。
ConoHaカードについてはこちらをご覧ください: https://www.conoha.jp/conohacard/
Amazonでも買えます: https://www.amazon.co.jp/dp/B01N9E3416
## Amazonギフトカード
これは間接的な方法です。
## 銀行振込
syuilotan@yahoo.co.jp までお問い合わせください。
## 手渡し
オフ会を行ったときなどに行使できる方法です。
## その他
なにかいいアイデアがあればお教えください。

View File

@ -8,12 +8,12 @@ import * as gutil from 'gulp-util';
import * as ts from 'gulp-typescript'; import * as ts from 'gulp-typescript';
const sourcemaps = require('gulp-sourcemaps'); const sourcemaps = require('gulp-sourcemaps');
import tslint from 'gulp-tslint'; import tslint from 'gulp-tslint';
import cssnano = require('gulp-cssnano'); const cssnano = require('gulp-cssnano');
import * as uglifyComposer from 'gulp-uglify/composer'; import * as uglifyComposer from 'gulp-uglify/composer';
import pug = require('gulp-pug'); import pug = require('gulp-pug');
import * as rimraf from 'rimraf'; import * as rimraf from 'rimraf';
import chalk from 'chalk'; import chalk from 'chalk';
import imagemin = require('gulp-imagemin'); const imagemin = require('gulp-imagemin');
import * as rename from 'gulp-rename'; import * as rename from 'gulp-rename';
import * as mocha from 'gulp-mocha'; import * as mocha from 'gulp-mocha';
import * as replace from 'gulp-replace'; import * as replace from 'gulp-replace';

View File

@ -3,7 +3,7 @@ meta:
lang: "Deutsch" lang: "Deutsch"
divider: "" divider: ""
common: common:
misskey: "A planet of fediverse" misskey: "A of fediverse"
about-title: "A ⭐ of fediverse." about-title: "A ⭐ of fediverse."
about: "Misskeyを見つけていただき、ありがとうございます。Misskeyは、地球で生まれた<b>分散マイクロブログSNS</b>です。Fediverse(様々なSNSで構成される宇宙)の中に存在するため、他のSNSと相互に繋がっています。暫し都会の喧騒から離れて、新しいインターネットにダイブしてみませんか。" about: "Misskeyを見つけていただき、ありがとうございます。Misskeyは、地球で生まれた<b>分散マイクロブログSNS</b>です。Fediverse(様々なSNSで構成される宇宙)の中に存在するため、他のSNSと相互に繋がっています。暫し都会の喧騒から離れて、新しいインターネットにダイブしてみませんか。"
time: time:
@ -42,11 +42,21 @@ common:
d: "Willst du etwas sagen?" d: "Willst du etwas sagen?"
e: "Schreib hier etwas!" e: "Schreib hier etwas!"
f: "Warte darauf, das du schreibst." f: "Warte darauf, das du schreibst."
search: "検索"
delete: "Löschen" delete: "Löschen"
loading: "Laden" loading: "Laden"
ok: "OK" ok: "OK"
update-available-title: "更新があります"
update-available: "Eine neue Version von Misskey ist verfügbar ({newer}, aktuell ist {current}). Lade die Seite neu um die aktuelle Version zu laden" update-available: "Eine neue Version von Misskey ist verfügbar ({newer}, aktuell ist {current}). Lade die Seite neu um die aktuelle Version zu laden"
my-token-regenerated: "Dein Token wurde generiert. Du wirst jetzt abgemeldet." my-token-regenerated: "Dein Token wurde generiert. Du wirst jetzt abgemeldet."
i-like-sushi: "私は(プリンよりむしろ)寿司が好き"
show-reversi-board-labels: "リバーシのボードの行と列のラベルを表示"
reversi:
drawn: "引き分け"
my-turn: "あなたのターンです"
opponent-turn: "相手のターンです"
turn-of: "{}のターンです"
past-turn-of: "{}のターン"
widgets: widgets:
analog-clock: "Analoge Uhr" analog-clock: "Analoge Uhr"
profile: "Profil" profile: "Profil"
@ -228,6 +238,7 @@ common/views/widgets/posts-monitor.vue:
common/views/widgets/hashtags.vue: common/views/widgets/hashtags.vue:
title: "ハッシュタグ" title: "ハッシュタグ"
count: "{}人が投稿" count: "{}人が投稿"
empty: "トレンドなし"
common/views/widgets/server.vue: common/views/widgets/server.vue:
title: "Serverinformationen" title: "Serverinformationen"
toggle: "Sicht umschalten" toggle: "Sicht umschalten"
@ -235,6 +246,12 @@ common/views/widgets/memo.vue:
title: "Notizen" title: "Notizen"
memo: "Schreib hier!" memo: "Schreib hier!"
save: "Speichern" save: "Speichern"
common/views/pages/follow.vue:
signed-in-as: "{}としてサインイン中"
following: "フォロー中"
follow: "フォロー"
request-pending: "フォロー許可待ち"
follow-request: "フォロー申請"
desktop/views/components/activity.chart.vue: desktop/views/components/activity.chart.vue:
total: "Schwarz ... komplett" total: "Schwarz ... komplett"
notes: "Blau ... Hinweise" notes: "Blau ... Hinweise"
@ -333,7 +350,7 @@ desktop/views/components/friends-maker.vue:
refresh: "Mehr" refresh: "Mehr"
close: "Schließen" close: "Schließen"
desktop/views/components/game-window.vue: desktop/views/components/game-window.vue:
game: "Othello" game: "リバーシ"
desktop/views/components/home.vue: desktop/views/components/home.vue:
done: "Verbunden" done: "Verbunden"
add-widget: "Widget hinzufügen:" add-widget: "Widget hinzufügen:"
@ -618,7 +635,7 @@ desktop/views/pages/user/user.friends.vue:
title: "よく話すユーザー" title: "よく話すユーザー"
loading: "読み込み中" loading: "読み込み中"
no-users: "よく話すユーザーはいません" no-users: "よく話すユーザーはいません"
desktop/views/pages/user/user.header.vue: desktop/views/pages/user/user.vue:
is-suspended: "このユーザーは凍結されています。" is-suspended: "このユーザーは凍結されています。"
is-remote: "このユーザーはリモートユーザーです。" is-remote: "このユーザーはリモートユーザーです。"
view-remote: "正確な情報を見る" view-remote: "正確な情報を見る"
@ -636,6 +653,11 @@ desktop/views/pages/user/user.profile.vue:
mute: "ミュートする" mute: "ミュートする"
muted: "ミュートしています" muted: "ミュートしています"
unmute: "ミュート解除" unmute: "ミュート解除"
desktop/views/pages/user/user.header.vue:
posts: "投稿"
following: "フォロー"
followers: "フォロワー"
is-bot: "このアカウントはBotです"
desktop/views/pages/user/user.timeline.vue: desktop/views/pages/user/user.timeline.vue:
default: "投稿" default: "投稿"
with-replies: "投稿と返信" with-replies: "投稿と返信"

View File

@ -3,7 +3,7 @@ meta:
lang: "English" lang: "English"
divider: "" divider: ""
common: common:
misskey: "A planet of fediverse" misskey: "A of fediverse"
about-title: "A ⭐ of fediverse." about-title: "A ⭐ of fediverse."
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?" 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: time:
@ -42,11 +42,21 @@ common:
d: "Do you want to say something?" d: "Do you want to say something?"
e: "Write here!" e: "Write here!"
f: "Waiting for your writing." f: "Waiting for your writing."
search: "Search"
delete: "Delete" delete: "Delete"
loading: "Loading" loading: "Loading"
ok: "OK" ok: "OK"
update-available-title: "Update available"
update-available: "A new version of Misskey is now available({newer}, the current version is {current}). Reload the page to apply updates." 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." my-token-regenerated: "Your token has been renewed so you will be signed out."
i-like-sushi: "I like sushi rather than pudding"
show-reversi-board-labels: "Show row and column labels in Reversi"
reversi:
drawn: "Game Drawn"
my-turn: "あなたのターンです"
opponent-turn: "相手のターンです"
turn-of: "{}のターンです"
past-turn-of: "{}のターン"
widgets: widgets:
analog-clock: "Analog clock" analog-clock: "Analog clock"
profile: "Profile" profile: "Profile"
@ -228,6 +238,7 @@ common/views/widgets/posts-monitor.vue:
common/views/widgets/hashtags.vue: common/views/widgets/hashtags.vue:
title: "Hashtags" title: "Hashtags"
count: "{} users mentioned" count: "{} users mentioned"
empty: "No trend"
common/views/widgets/server.vue: common/views/widgets/server.vue:
title: "Server info" title: "Server info"
toggle: "Toggle views" toggle: "Toggle views"
@ -235,6 +246,12 @@ common/views/widgets/memo.vue:
title: "Sticky note" title: "Sticky note"
memo: "Write here!" memo: "Write here!"
save: "Save" save: "Save"
common/views/pages/follow.vue:
signed-in-as: "Signed in as {}"
following: "Following"
follow: "Follow"
request-pending: "Pending follow request"
follow-request: "Follow request"
desktop/views/components/activity.chart.vue: desktop/views/components/activity.chart.vue:
total: "Black ... Total" total: "Black ... Total"
notes: "Blue ... Notes" notes: "Blue ... Notes"
@ -316,7 +333,7 @@ desktop/views/components/drive.vue:
desktop/views/components/follow-button.vue: desktop/views/components/follow-button.vue:
following: "Following" following: "Following"
follow: "Follow" follow: "Follow"
request-pending: "フォロー許可待ち" request-pending: "Pending follow request"
follow-request: "Follow request" follow-request: "Follow request"
desktop/views/components/followers-window.vue: desktop/views/components/followers-window.vue:
followers: "{}'s followers" followers: "{}'s followers"
@ -333,7 +350,7 @@ desktop/views/components/friends-maker.vue:
refresh: "More" refresh: "More"
close: "Close" close: "Close"
desktop/views/components/game-window.vue: desktop/views/components/game-window.vue:
game: "Othello" game: "Reversi"
desktop/views/components/home.vue: desktop/views/components/home.vue:
done: "Submit" done: "Submit"
add-widget: "Add widget:" add-widget: "Add widget:"
@ -549,7 +566,7 @@ desktop/views/components/ui.header.nav.vue:
home: "Home" home: "Home"
deck: "Deck" deck: "Deck"
messaging: "Messages" messaging: "Messages"
game: "Play Othello" game: "Games"
desktop/views/components/ui.header.notifications.vue: desktop/views/components/ui.header.notifications.vue:
title: "Notifications" title: "Notifications"
desktop/views/components/ui.header.post.vue: desktop/views/components/ui.header.post.vue:
@ -618,7 +635,7 @@ desktop/views/pages/user/user.friends.vue:
title: "Frequently replied" title: "Frequently replied"
loading: "Loading" loading: "Loading"
no-users: "No users" no-users: "No users"
desktop/views/pages/user/user.header.vue: desktop/views/pages/user/user.vue:
is-suspended: "This account has been suspended." is-suspended: "This account has been suspended."
is-remote: "This user is a remote user, so the information is not accurate. " is-remote: "This user is a remote user, so the information is not accurate. "
view-remote: "See accurate information" view-remote: "See accurate information"
@ -636,6 +653,11 @@ desktop/views/pages/user/user.profile.vue:
mute: "Mute" mute: "Mute"
muted: "Muting" muted: "Muting"
unmute: "Unmute" unmute: "Unmute"
desktop/views/pages/user/user.header.vue:
posts: "Posts"
following: "Following"
followers: "Followers"
is-bot: "This account is a bot"
desktop/views/pages/user/user.timeline.vue: desktop/views/pages/user/user.timeline.vue:
default: "Posts" default: "Posts"
with-replies: "Posts and replies" with-replies: "Posts and replies"
@ -695,7 +717,7 @@ mobile/views/components/drive.file-detail.vue:
mobile/views/components/follow-button.vue: mobile/views/components/follow-button.vue:
following: "Following" following: "Following"
follow: "Follow" follow: "Follow"
request-pending: "フォロー許可待ち" request-pending: "Pending follow request"
follow-request: "Follow request" follow-request: "Follow request"
mobile/views/components/friends-maker.vue: mobile/views/components/friends-maker.vue:
title: "Let's follow users" title: "Let's follow users"

View File

@ -1,223 +1,233 @@
--- ---
meta: meta:
lang: "日本語" lang: "Español"
divider: "" divider: ""
common: common:
misskey: "A planet of fediverse" misskey: "Una ⭐️ del fediverso"
about-title: "A ⭐ of fediverse." about-title: "Una ⭐️ del fediverso"
about: "Misskeyを見つけていただき、ありがとうございます。Misskeyは、地球で生まれた<b>分散マイクロブログSNS</b>です。Fediverse(様々なSNSで構成される宇宙)の中に存在するため、他のSNSと相互に繋がっています。暫し都会の喧騒から離れて、新しいインターネットにダイブしてみませんか。" about: "Gracias por encontrae Misskey. Misskey es una <b>plataforma descentralizada de microblogging</b> nacida en la Tierra. Gracias a existir dentro del Fediverso (un universo donde se organizan varias plataformas sociales) se encuentra enlazada mutuamente con otras plataformas sociales. ¿Por què no te tomas un respiro del caos de la ciudad y te sumerges es una nueva manera de entender Internet?"
time: time:
unknown: "なぞのじかん" unknown: "Desconocido"
future: "未来" future: "Futuro"
just_now: "たった今" just_now: "Ahora mismo"
seconds_ago: "{}秒前" seconds_ago: "Hace {}"
minutes_ago: "{}分前" minutes_ago: "Hace {} minuto(s)"
hours_ago: "{}時間前" hours_ago: "Hace {} hora(s)"
days_ago: "{}日前" days_ago: "Hace {} dia(s)"
weeks_ago: "{}週間前" weeks_ago: "Hace {} semana(s)"
months_ago: "{}ヶ月前" months_ago: "Hace {} mes(es)"
years_ago: "{}年前" years_ago: "Hace {} año(s)"
weekday-short: weekday-short:
sunday: "" sunday: "domingo"
monday: "" monday: "lunes"
tuesday: "" tuesday: "martes"
wednesday: "" wednesday: "miércoles"
thursday: "" thursday: "jueves"
friday: "" friday: "viernes"
saturday: "" saturday: "sábado"
reactions: reactions:
like: "いいね" like: "me gusta"
love: "しゅき" love: "amor"
laugh: "" laugh: "risa"
hmm: "ふぅ~む" hmm: "hmm"
surprise: "わお" surprise: "sorpresa"
congrats: "おめでとう" congrats: "felicidades"
angry: "おこ" angry: "enfadado"
confused: "こまこまのこまり" confused: "confundido"
pudding: "Pudding" pudding: "Chafado"
note-placeholders: note-placeholders:
a: "今どうしてる?" a: "¿Qué haces?"
b: "何かありましたか?" b: "¿Qué está pasando?"
c: "何をお考えですか?" c: "¿Qué te pasa por la cabeza?"
d: "言いたいことは?" d: "¿Quieres decir algo?"
e: "ここに書いてください" e: "¡Escribe aquí!"
f: "あなたが書くのを待っています..." f: "Esperando a que escribas algo..."
delete: "削除" search: "検索"
loading: "読み込み中" delete: "eliminar"
ok: "わかった" loading: "cargando"
update-available: "Misskeyの新しいバージョンがあります({newer}。現在{current}を利用中)。ページを再度読み込みすると更新が適用されます。" ok: "OK"
my-token-regenerated: "あなたのトークンが更新されたのでサインアウトします" update-available-title: "更新があります"
update-available: "Hay disponible una nueva versión de Misskey ({newer}, la versión actual es {current}). Refresca la página para aplicar las actualizaciones."
my-token-regenerated: "Tu token se ha regenerado vas a ser desconectado."
i-like-sushi: "私は(プリンよりむしろ)寿司が好き"
show-reversi-board-labels: "リバーシのボードの行と列のラベルを表示"
reversi:
drawn: "引き分け"
my-turn: "あなたのターンです"
opponent-turn: "相手のターンです"
turn-of: "{}のターンです"
past-turn-of: "{}のターン"
widgets: widgets:
analog-clock: "アナログ時計" analog-clock: "Reloj analógico"
profile: "プロフィール" profile: "Perfil"
calendar: "カレンダー" calendar: "Calendario"
timemachine: "カレンダー(タイムマシン)" timemachine: "Calendario (máquina del tiempo)"
activity: "アクティビティ" activity: "Actividad"
rss: "RSSリーダー" rss: "Lector RSS"
memo: "付箋" memo: "Notas adhesivas"
trends: "トレンド" trends: "Tendencias"
photo-stream: "フォトストリーム" photo-stream: "Secuencia de fotos"
posts-monitor: "投稿チャート" posts-monitor: "Gráfico de publicaciones"
slideshow: "スライドショー" slideshow: "Diapositivas"
version: "バージョン" version: "Versión"
broadcast: "ブロードキャスト" broadcast: "Transmisión"
notifications: "通知" notifications: "Notificaciones"
users: "おすすめユーザー" users: "Usuarios destacados"
polls: "アンケート" polls: "Encuestas"
post-form: "投稿フォーム" post-form: "Formulario"
messaging: "メッセージ" messaging: "Mensajes"
server: "サーバー情報" server: "Información del servidor"
donation: "寄付のお願い" donation: "Donaciones"
nav: "ナビゲーション" nav: "Navegación"
tips: "ヒント" tips: "Consejos"
hashtags: "ハッシュタグ" hashtags: "Etiquetas"
deck: deck:
widgets: "ウィジェット" widgets: "Accesorios"
home: "ホーム" home: "Inicio"
local: "ローカル" local: "Local"
global: "グローバル" global: "Global"
notifications: "通知" notifications: "Notificaciones"
list: "リスト" list: "Listado"
swap-left: "左に移動" swap-left: "Desplazar a la izq."
swap-right: "右に移動" swap-right: "Desplazar a la dcha."
swap-up: "上に移動" swap-up: "Desplazar arriba"
swap-down: "下に移動" swap-down: "Desplazar abajo"
remove: "カラムを削除" remove: "Borrar"
add-column: "カラムを追加" add-column: "Añadir columna"
rename: "名前を変更" rename: "Renombrar"
stack-left: "左に重ねる" stack-left: "A la izqda."
pop-right: "右に出す" pop-right: "A la dcha."
common/views/components/connect-failed.vue: common/views/components/connect-failed.vue:
title: "サーバーに接続できません" title: "Imposible conectar al servidor"
description: "インターネット回線に問題があるか、サーバーがダウンまたはメンテナンスしている可能性があります。しばらくしてから{再度お試し}ください。" description: "Hay un problema en tu conexió o puede que el servidor esté caido o en mantenimiento. Por favor {try again} más tarde."
thanks: "いつもMisskeyをご利用いただきありがとうございます。" thanks: "Gracias por usar Misskey."
troubleshoot: "トラブルシュート" troubleshoot: "Problemas más frecuentes"
common/views/components/connect-failed.troubleshooter.vue: common/views/components/connect-failed.troubleshooter.vue:
title: "トラブルシューティング" title: "Resolución de problemas"
network: "ネットワーク接続" network: "Conexión de red"
checking-network: "ネットワーク接続を確認中" checking-network: "Verificar la conexión a la red"
internet: "インターネット接続" internet: "Conexión a Internet"
checking-internet: "インターネット接続を確認中" checking-internet: "Comprobando la conexión a Internet"
server: "サーバー接続" server: "Conexión al servidor"
checking-server: "サーバー接続を確認中" checking-server: "Probando la conexión al servidor"
finding: "問題を調べています" finding: "Buscando cualquier problema"
no-network: "ネットワークに接続されていません" no-network: "Sin conexión"
no-network-desc: "お使いのPCのネットワーク接続が正常か確認してください。" no-network-desc: "Por favor, asegurate que estás conectado a una red"
no-internet: "インターネットに接続されていません" no-internet: "Sin conexión a Internet"
no-internet-desc: "ネットワークには接続されていますが、インターネットには接続されていないようです。お使いのPCのインターネット接続が正常か確認してください。" no-internet-desc: "Por favor, asegurate de estar conectado a Internet."
no-server: "Misskeyのサーバーに接続できません" no-server: "Imposible conectarse al servidor de Misskey"
no-server-desc: "お使いのPCのインターネット接続は正常ですが、Misskeyのサーバーには接続できませんでした。サーバーがダウンまたはメンテナンスしている可能性があるので、しばらくしてから再度御アクセスください。" no-server-desc: "La conexión de red de tu PC es correcta, aún así no puedes conectarte al servidor de Misskey. Es posible que el servidor esté caido o en mantenimiento. Por favor vuelve a intentarlo más tarde."
success: "Misskeyのサーバーに接続できました" success: "Conectado al servidor de Misskey de manera correcta"
success-desc: "正常に接続できるようです。ページを再度読み込みしてください。" success-desc: "Parece que la conexión ha sido posible. Por favor refresca la página."
flush: "キャッシュの削除" flush: "Limpiar la memoria caché"
set-version: "バージョン指定" set-version: "Escoge la versión"
common/views/components/messaging.vue: common/views/components/messaging.vue:
search-user: "ユーザーを探す" search-user: "Encuentra un usuario"
you: "あなた" you: "Tu"
no-history: "履歴はありません" no-history: "Sin historial"
common/views/components/messaging-room.vue: common/views/components/messaging-room.vue:
empty: "このユーザーと話したことはありません" empty: "Sin conversaciones"
more: "もっと読む" more: "Leer más"
no-history: "これより過去の履歴はありません" no-history: "El historial se ha acabado"
resize-form: "ドラッグしてフォームの広さを調整" resize-form: "Arrastra para redimensionar"
new-message: "新しいメッセージがあります" new-message: "Nuevo mensaje"
common/views/components/messaging-room.form.vue: common/views/components/messaging-room.form.vue:
input-message-here: "ここにメッセージを入力" input-message-here: "Escribe el mensaje aquí"
send: "送信" send: "Enviar"
attach-from-local: "PCからファイルを添付する" attach-from-local: "Adjunta ficheros desde tu PC"
attach-from-drive: "ドライブからファイルを添付する" attach-from-drive: "Adjunta ficheros desde tu disco"
common/views/components/messaging-room.message.vue: common/views/components/messaging-room.message.vue:
is-read: "既読" is-read: "Leer"
deleted: "このメッセージは削除されました" deleted: "El mensaje se ha borrado"
common/views/components/nav.vue: common/views/components/nav.vue:
about: "Misskeyについて" about: "Sobre"
stats: "統計" stats: "Estadísticas"
status: "ステータス" status: "Estado"
wiki: "Wiki" wiki: "Wiki"
donors: "ドナー" donors: "Donantes"
repository: "リポジトリ" repository: "Repositorio"
develop: "開発者" develop: "Desarrolladores"
feedback: "フィードバック" feedback: "Opiniones"
common/views/components/note-menu.vue: common/views/components/note-menu.vue:
favorite: "お気に入り" favorite: "Me gusta esta nota"
pin: "ピン留め" pin: "Fijar en el perfil"
delete: "削除" delete: "Borrar"
delete-confirm: "この投稿を削除しますか?" delete-confirm: "¿Seguro que quieres borrar la publicación?"
remote: "投稿元で見る" remote: "Ver el original"
common/views/components/poll.vue: common/views/components/poll.vue:
vote-to: "{}」に投票する" vote-to: "'{}' para votar"
vote-count: "{}" vote-count: "{} votos"
total-users: "{}人が投票" total-users: "{} usuario(s) que ha(n) votado"
vote: "投票する" vote: "Vota"
show-result: "結果を見る" show-result: "Mostrar resultados"
voted: "投票済み" voted: "Votado"
common/views/components/poll-editor.vue: common/views/components/poll-editor.vue:
no-only-one-choice: "アンケートには、選択肢が最低2つ必要です" no-only-one-choice: "Selecciona dos o más opciones."
choice-n: "選択肢{}" choice-n: "{} opcion(es)"
remove: "この選択肢を削除" remove: "Borra la opción"
add: "+選択肢を追加" add: "+ Añade una opción"
destroy: "アンケートを破棄" destroy: "Cancelar la encuesta"
common/views/components/reaction-picker.vue: common/views/components/reaction-picker.vue:
choose-reaction: "リアクションを選択" choose-reaction: "Escoge una reacción"
common/views/components/signin.vue: common/views/components/signin.vue:
username: "ユーザー名" username: "Usuario"
password: "パスワード" password: "Contraseña"
token: "トークン" token: "Identificador"
signing-in: "やってます..." signing-in: "Entrando..."
signin: "サインイン" signin: "Entra"
common/views/components/signup.vue: common/views/components/signup.vue:
username: "ユーザー名" username: "Usuario"
checking: "確認しています..." checking: "Comprobando..."
available: "利用できます" available: "Disponible"
unavailable: "既に利用されています" unavailable: "Utilizado"
error: "通信エラー" error: "Error de conexión"
invalid-format: "a~z、A~Z、0~9、_が使えます" invalid-format: "utiliza letras, números y/o -."
too-short: "1文字以上でお願いします" too-short: "¡Mínimo tienes que introducir un caracter!"
too-long: "20文字以内でお願いします" too-long: "No puedes usar más de 20 caracteres."
password: "パスワード" password: "Contraseña"
password-placeholder: "8文字以上を推奨します" password-placeholder: "Te recomendamos más de 8 caracteres"
weak-password: "弱いパスワード" weak-password: "Contraseña débil"
normal-password: "まあまあのパスワード" normal-password: "No está mal"
strong-password: "強いパスワード" strong-password: "Muy buena contraseña"
retype: "再入力" retype: "Inténtalo otra vez"
retype-placeholder: "確認のため再入力してください" retype-placeholder: "Confirma la contraseña"
password-matched: "確認されました" password-matched: "OK"
password-not-matched: "一致していません" password-not-matched: "Las contraseñas no son las mismas"
recaptcha: "認証" recaptcha: "Verificar"
create: "アカウント作成" create: "Crea una cuenta"
some-error: "何らかの原因によりアカウントの作成に失敗しました。再度お試しください。" some-error: "Por algún motivo no se ha podido crear la cuenta. Por favor inténtalo de nuevo."
common/views/components/special-message.vue: common/views/components/special-message.vue:
new-year: "Happy New Year!" new-year: "¡Feliz Año Nuevo!"
christmas: "Merry Christmas!" christmas: "¡Feliz Navidad!"
common/views/components/stream-indicator.vue: common/views/components/stream-indicator.vue:
connecting: "接続中" connecting: "Conectando"
reconnecting: "再接続中" reconnecting: "Reconectando"
connected: "接続完了" connected: "Conectado"
common/views/components/twitter-setting.vue: common/views/components/twitter-setting.vue:
description: "お使いのTwitterアカウントをお使いのMisskeyアカウントに接続しておくと、プロフィールでTwitterアカウント情報が表示されるようになったり、Twitterを用いた便利なサインインを利用できるようになります。" description: "Si comectas tu cuenta de Twitter con tu cuenta de Misskey podrás ver la información de tu cuemta de Twitter en tu perfil y además podrás entrar usando Twitter."
connected-to: "次のTwitterアカウントに接続されています" connected-to: "Estas comectado con las siguientes cuentas de Twitter"
detail: "詳細..." detail: "Detalles..."
reconnect: "再接続する" reconnect: "Conectar de nuevo"
connect: "Twitterと接続する" connect: "Conectate usando Twitter"
disconnect: "切断する" disconnect: "Desconectado"
common/views/components/uploader.vue: common/views/components/uploader.vue:
waiting: "待機中" waiting: "Un momento"
common/views/components/visibility-chooser.vue: common/views/components/visibility-chooser.vue:
public: "公開" public: "Público"
home: "ホーム" home: "Inicio"
home-desc: "ホームタイムラインにのみ公開" home-desc: "Publica solo en la página de inicio"
followers: "フォロワー" followers: "Seguidores"
followers-desc: "自分のフォロワーにのみ公開" followers-desc: "Piblica solo para tus seguidores"
specified: "ダイレクト" specified: "Directo"
specified-desc: "指定したユーザーにのみ公開" specified-desc: "Publica solo para los seguidores que quieras"
private: "非公開" private: "Privada"
common/views/widgets/broadcast.vue: common/views/widgets/broadcast.vue:
fetching: "確認中" fetching: "Recuperando"
no-broadcasts: "お知らせはありません" no-broadcasts: "Sin emisión"
have-a-nice-day: "良い一日を!" have-a-nice-day: "¡Buenos dias!"
next: "" next: "Siguiente"
common/views/widgets/donation.vue: common/views/widgets/donation.vue:
title: "寄付のお願い" title: "Donaciones"
text: "Misskeyの運営にはドメイン、サーバー等のコストが掛かります。Misskeyは広告を掲載したりしないため、収入を皆様からの寄付に頼っています。もしご興味があれば、{}までご連絡ください。ご協力ありがとうございます。" text: "Misskeyの運営にはドメイン、サーバー等のコストが掛かります。Misskeyは広告を掲載したりしないため、収入を皆様からの寄付に頼っています。もしご興味があれば、{}までご連絡ください。ご協力ありがとうございます。"
common/views/widgets/photo-stream.vue: common/views/widgets/photo-stream.vue:
title: "フォトストリーム" title: "フォトストリーム"
@ -228,6 +238,7 @@ common/views/widgets/posts-monitor.vue:
common/views/widgets/hashtags.vue: common/views/widgets/hashtags.vue:
title: "ハッシュタグ" title: "ハッシュタグ"
count: "{}人が投稿" count: "{}人が投稿"
empty: "トレンドなし"
common/views/widgets/server.vue: common/views/widgets/server.vue:
title: "サーバー情報" title: "サーバー情報"
toggle: "表示を切り替え" toggle: "表示を切り替え"
@ -235,6 +246,12 @@ common/views/widgets/memo.vue:
title: "付箋" title: "付箋"
memo: "ここに書いて!" memo: "ここに書いて!"
save: "保存" save: "保存"
common/views/pages/follow.vue:
signed-in-as: "{}としてサインイン中"
following: "フォロー中"
follow: "フォロー"
request-pending: "フォロー許可待ち"
follow-request: "フォロー申請"
desktop/views/components/activity.chart.vue: desktop/views/components/activity.chart.vue:
total: "Black ... Total" total: "Black ... Total"
notes: "Blue ... Notes" notes: "Blue ... Notes"
@ -257,66 +274,66 @@ desktop/views/components/choose-file-from-drive-window.vue:
desktop/views/components/choose-folder-from-drive-window.vue: desktop/views/components/choose-folder-from-drive-window.vue:
cancel: "キャンセル" cancel: "キャンセル"
ok: "決定" ok: "決定"
choose-prompt: "フォルダを選択" choose-prompt: "Escoge una Carpeta"
desktop/views/components/crop-window.vue: desktop/views/components/crop-window.vue:
skip: "クロップをスキップ" skip: "クロップをスキップ"
cancel: "キャンセル" cancel: "Cancelar"
ok: "決定" ok: "OK"
desktop/views/components/drive-window.vue: desktop/views/components/drive-window.vue:
used: "使用中" used: "usado"
drive: "ドライブ" drive: "Disco"
desktop/views/components/drive.file.vue: desktop/views/components/drive.file.vue:
avatar: "アイコン" avatar: "Avatar"
banner: "バナー" banner: "Banner"
contextmenu: contextmenu:
rename: "名前を変更" rename: "Renombrar"
copy-url: "URLをコピー" copy-url: "Copia la URL"
download: "ダウンロード" download: "Descargar"
else-files: "その他..." else-files: "Otros"
set-as-avatar: "アイコンに設定" set-as-avatar: "Utilizar como avatar"
set-as-banner: "バナーに設定" set-as-banner: "Utilizar como banner"
open-in-app: "アプリで開く" open-in-app: "Abrir en la aplicación"
add-app: "アプリを追加" add-app: "Añadir aplicación"
rename-file: "ファイル名の変更" rename-file: "Renombra el fichero"
input-new-file-name: "新しいファイル名を入力してください" input-new-file-name: "Escribe el nombre nuevo"
copied: "コピー完了" copied: "Copiado"
copied-url-to-clipboard: "URLをクリップボードにコピーしました" copied-url-to-clipboard: "URL copiada al porta papeles"
desktop/views/components/drive.folder.vue: desktop/views/components/drive.folder.vue:
unable-to-process: "操作を完了できません" unable-to-process: "La operación no se puede llevar a cabo"
circular-reference-detected: "移動先のフォルダーは、移動するフォルダーのサブフォルダーです。" circular-reference-detected: "La carpeta de destino es una sub-carpeta de la carpeta que quieres mover."
unhandled-error: "不明なエラー" unhandled-error: "Error desconocido"
contextmenu: contextmenu:
move-to-this-folder: "このフォルダへ移動" move-to-this-folder: "Mover a esta carpeta"
show-in-new-window: "新しいウィンドウで表示" show-in-new-window: "Abrir en una ventana nueva"
rename: "名前を変更" rename: "Renombrar"
rename-folder: "フォルダ名の変更" rename-folder: "Renombrar carpeta"
input-new-folder-name: "新しいフォルダ名を入力してください" input-new-folder-name: "Escribe el nombre nuevo"
desktop/views/components/drive.nav-folder.vue: desktop/views/components/drive.nav-folder.vue:
drive: "ドライブ" drive: "Disco"
desktop/views/components/drive.vue: desktop/views/components/drive.vue:
search: "検索" search: "Buscar"
load-more: "もっと読み込む" load-more: "Cargar más"
empty-draghover: "ドロップですか?いいですよ、ボクはカワイイですからね" empty-draghover: "¡Saluda!"
empty-drive: "ドライブには何もありません。" empty-drive: "Tu disco está vacio"
empty-drive-description: "右クリックして「ファイルをアップロード」を選んだり、ファイルをドラッグ&ドロップすることでもアップロードできます。" empty-drive-description: "También puedes subir archivos seleccionándolos y con el botón derecho selecciona \"Subir fichero\" o puedes arrastrarlo hasta la ventana."
empty-folder: "このフォルダーは空です" empty-folder: "La carpeta está vacia"
unable-to-process: "操作を完了できません" unable-to-process: "La operación no se puede llevar a cabo."
circular-reference-detected: "移動先のフォルダーは、移動するフォルダーのサブフォルダーです。" circular-reference-detected: "La carpeta de destino es una sub-carpeta de la carpeta que quieres mover."
unhandled-error: "不明なエラー" unhandled-error: "Errer desconocido"
url-upload: "URLアップロード" url-upload: "Subir desde una URL"
url-of-file: "アップロードしたいファイルのURL" url-of-file: "URL del fichero que quieres subir"
url-upload-requested: "アップロードをリクエストしました" url-upload-requested: "Subida solicitada"
may-take-time: "アップロードが完了するまで時間がかかる場合があります。" may-take-time: "Subir el fichero puede tardar un tiempo."
create-folder: "フォルダー作成" create-folder: "Crear una carpeta"
folder-name: "フォルダー名" folder-name: "Nombre de la carpeta"
contextmenu: contextmenu:
create-folder: "フォルダーを作成" create-folder: "Crear una carpeta"
upload: "ファイルをアップロード" upload: "Subir fichero"
url-upload: "URLからアップロード" url-upload: "Subir desde una URL"
desktop/views/components/follow-button.vue: desktop/views/components/follow-button.vue:
following: "フォロー中" following: "Siguiendo"
follow: "フォロー" follow: "Sigue"
request-pending: "フォロー許可待ち" request-pending: "Pendiente de aprobación"
follow-request: "フォロー申請" follow-request: "フォロー申請"
desktop/views/components/followers-window.vue: desktop/views/components/followers-window.vue:
followers: "{} のフォロワー" followers: "{} のフォロワー"
@ -333,7 +350,7 @@ desktop/views/components/friends-maker.vue:
refresh: "もっと見る" refresh: "もっと見る"
close: "閉じる" close: "閉じる"
desktop/views/components/game-window.vue: desktop/views/components/game-window.vue:
game: "オセロ" game: "リバーシ"
desktop/views/components/home.vue: desktop/views/components/home.vue:
done: "完了" done: "完了"
add-widget: "ウィジェットを追加:" add-widget: "ウィジェットを追加:"
@ -381,55 +398,55 @@ desktop/views/components/post-form.vue:
renote-failed: "Renoteに失敗しました" renote-failed: "Renoteに失敗しました"
posting: "投稿中" posting: "投稿中"
attach-media-from-local: "PCからメディアを添付" attach-media-from-local: "PCからメディアを添付"
attach-media-from-drive: "ドライブからメディアを添付" attach-media-from-drive: "Adjunta multimedia desde tu Disco"
attach-cancel: "添付取り消し" attach-cancel: "Quitar el archivo adjunto"
insert-a-kao: "v(‘ω’)v" insert-a-kao: "v(‘ω’)v"
create-poll: "アンケートを作成" create-poll: "Crea una encuesta"
text-remain: "残り{}文字" text-remain: "quedan {} caracteres"
desktop/views/components/post-form-window.vue: desktop/views/components/post-form-window.vue:
note: "新規投稿" note: "Nota nueva"
reply: "返信" reply: "Responder"
attaches: "添付: {}メディア" attaches: "{} archivo(s) multimedia adjuntados"
uploading-media: "{}個のメディアをアップロード中" uploading-media: "Subiendo {} archivo(s) multimedia"
desktop/views/components/progress-dialog.vue: desktop/views/components/progress-dialog.vue:
waiting: "待機中" waiting: "Un momento"
desktop/views/components/renote-form.vue: desktop/views/components/renote-form.vue:
quote: "引用する..." quote: "Cita..."
cancel: "キャンセル" cancel: "Cancelar"
renote: "Renote" renote: "Volver a publicar"
reposting: "しています..." reposting: "Publicando de nuevo..."
success: "Renoteしました" success: "¡Publicado!"
failure: "Renoteに失敗しました" failure: "La publicación ha fallado"
desktop/views/components/renote-form-window.vue: desktop/views/components/renote-form-window.vue:
title: "この投稿をRenoteしますか" title: "¿Seguro qué quieres volver a publicarlo?"
desktop/views/components/settings-window.vue: desktop/views/components/settings-window.vue:
settings: "設定" settings: "Configuración"
desktop/views/components/settings.vue: desktop/views/components/settings.vue:
profile: "プロフィール" profile: "Perfil"
notification: "通知" notification: "Notificación"
apps: "アプリ" apps: "Aplicaciones"
mute: "ミュート" mute: "Silenciar"
drive: "ドライブ" drive: "Disco"
security: "セキュリティ" security: "Seguridad"
signin: "サインイン履歴" signin: "Historial de inicios de sesión"
password: "パスワード" password: "Contraseña"
2fa: "二段階認証" 2fa: "Autenticación de Doble-Factor"
other: "その他" other: "Otros"
license: "ライセンス" license: "Licencia"
behaviour: "動作" behaviour: "Acciones"
fetch-on-scroll: "スクロールで自動読み込み" fetch-on-scroll: "Desplazamiento infinito"
fetch-on-scroll-desc: "ページを下までスクロールしたときに自動で追加のコンテンツを読み込みます。" fetch-on-scroll-desc: "Cuando te deslizas al final de la página nuevo contenido se carga automáticamente."
auto-popout: "ウィンドウの自動ポップアウト" auto-popout: "Ventana emergente automática"
auto-popout-desc: "ウィンドウが開かれるとき、ポップアウト(ブラウザ外に切り離す)可能なら自動でポップアウトします。この設定はブラウザに記憶されます。" auto-popout-desc: "Muestra una ventana emergente si es posible. Esta configuración depende del navegador."
advanced: "詳細設定" advanced: "Configuración avanzada"
api-via-stream: "ストリームを経由したAPIリクエスト" api-via-stream: "Solicitar API por medio de un stream"
api-via-stream-desc: "この設定をオンにすると、websocket接続を経由してAPIリクエストが行われます(パフォーマンス向上が期待できます)。オフにすると、ネイティブの fetch APIが利用されます。この設定はこのデバイスのみ有効です。" api-via-stream-desc: "Las peticiones de las API se realizan por conexiones WebSocket en lugar de las tradicionales (para una mejora en el rendimiento). Esta función depende del navegador."
display: "デザインと表示" display: "Diseño y pantalla"
customize: "ホームをカスタマイズ" customize: "Personaliza la página principal"
dark-mode: "ダークモード" dark-mode: "Modo Nocturno"
circle-icons: "円形のアイコンを使用" circle-icons: "Usar iconos circulares"
gradient-window-header: "ウィンドウのタイトルバーにグラデーションを使用" gradient-window-header: "Usar degradados en las cabeceras de las páginas"
post-form-on-timeline: "タイムライン上部に投稿フォームを表示する" post-form-on-timeline: "Mostrar el formulario de las entradas encima de la línea de tiempo"
show-reply-target: "リプライ先を表示する" show-reply-target: "リプライ先を表示する"
show-my-renotes: "自分の行ったRenoteをタイムラインに表示する" show-my-renotes: "自分の行ったRenoteをタイムラインに表示する"
show-renoted-my-notes: "Renoteされた自分の投稿をタイムラインに表示する" show-renoted-my-notes: "Renoteされた自分の投稿をタイムラインに表示する"
@ -618,7 +635,7 @@ desktop/views/pages/user/user.friends.vue:
title: "よく話すユーザー" title: "よく話すユーザー"
loading: "読み込み中" loading: "読み込み中"
no-users: "よく話すユーザーはいません" no-users: "よく話すユーザーはいません"
desktop/views/pages/user/user.header.vue: desktop/views/pages/user/user.vue:
is-suspended: "このユーザーは凍結されています。" is-suspended: "このユーザーは凍結されています。"
is-remote: "このユーザーはリモートユーザーです。" is-remote: "このユーザーはリモートユーザーです。"
view-remote: "正確な情報を見る" view-remote: "正確な情報を見る"
@ -636,6 +653,11 @@ desktop/views/pages/user/user.profile.vue:
mute: "ミュートする" mute: "ミュートする"
muted: "ミュートしています" muted: "ミュートしています"
unmute: "ミュート解除" unmute: "ミュート解除"
desktop/views/pages/user/user.header.vue:
posts: "投稿"
following: "フォロー"
followers: "フォロワー"
is-bot: "このアカウントはBotです"
desktop/views/pages/user/user.timeline.vue: desktop/views/pages/user/user.timeline.vue:
default: "投稿" default: "投稿"
with-replies: "投稿と返信" with-replies: "投稿と返信"

View File

@ -3,20 +3,20 @@ meta:
lang: "Français" lang: "Français"
divider: "" divider: ""
common: common:
misskey: "Une planète du fédiverse" misskey: "A ⭐ of fediverse"
about-title: "Une ⭐ du fédiverse." about-title: "Une ⭐ du fédiverse."
about: "Merci d'avoir découvert Misskey. Misskey est une <b>plateforme de micro-blogging distribuée</b> née sur Terre. Parce qu'il fait partie du Fédiverse (un univers composé de diverses plateformes de réseaux sociaux organisées), il est mutuellement connecté avec d'autres plateformes de réseaux sociaux. Désirez-vous prendre une pause, pendant un instant, loin de l'agitation de la ville et plonger dans un nouvel Internet ?" about: "Merci d'avoir découvert Misskey. Misskey est une <b>plateforme de micro-blogging distribuée</b> née sur Terre. Parce qu'il fait partie du Fédiverse (un univers composé de diverses plateformes de réseaux sociaux organisées), il est mutuellement connecté avec d'autres plateformes de réseaux sociaux. Désirez-vous prendre une pause, pendant un instant, loin de l'agitation de la ville et plonger dans un nouvel Internet ?"
time: time:
unknown: "inconnu" unknown: "inconnu"
future: "future" future: "future"
just_now: "maintenant" just_now: "à l'instant"
seconds_ago: "Il y a {}seconde(s)" seconds_ago: "Il y a {} seconde·s"
minutes_ago: "Il y a {}minute(s)" minutes_ago: "Il y a {} minute·s"
hours_ago: "Il y a {}heure(s)" hours_ago: "Il y a {} heure·s"
days_ago: "Il y a {}jour(s)" days_ago: "Il y a {} jour·s"
weeks_ago: "Il y a{}semaines(s)" weeks_ago: "Il y a {} semaines·s"
months_ago: "Il y a {}mois" months_ago: "Il y a {} mois"
years_ago: "Il y a {}an(s)" years_ago: "Il y a {} an·s"
weekday-short: weekday-short:
sunday: "D" sunday: "D"
monday: "L" monday: "L"
@ -29,24 +29,34 @@ common:
like: "Aime" like: "Aime"
love: "Adore" love: "Adore"
laugh: "Rire" laugh: "Rire"
hmm: "Hmm...?" hmm: "Hmm ... ?"
surprise: "Wow" surprise: "Wow"
congrats: "Félicitations!" congrats: "Félicitations !"
angry: "En Colère" angry: "En colère"
confused: "Confus" confused: "Confus"
pudding: "Pudding" pudding: "Pudding"
note-placeholders: note-placeholders:
a: "Que faîtes vous à cet instant ?" a: "Que faîtes vous maintenant ?"
b: "Quoi de neuf ?" b: "Quoi de neuf ?"
c: "Qu'avez-vous en tête ?" c: "Qu'avez-vous en tête ?"
d: "Voulez-vous exprimer quelque chose ?" d: "Voulez-vous exprimer quelque chose ?"
e: "Écrivez ici" e: "Écrivez ici"
f: "En attente de vos écrits" f: "En attente de vos écrits"
search: "検索"
delete: "Supprimer" delete: "Supprimer"
loading: "Chargement" loading: "Chargement"
ok: "OK" ok: "OK"
update-available: "Une nouvelle version de Misskey est disponible({newer}, version actuelle: {current}). Recharger la page pour appliquer la mise à jour." update-available-title: "更新があります"
update-available: "Une nouvelle version de Misskey est disponible ({newer}, version actuelle: {current}). Veuillez 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é." my-token-regenerated: "Votre token vient d'être généré, vous allez maintenant être déconnecté."
i-like-sushi: "私は(プリンよりむしろ)寿司が好き"
show-reversi-board-labels: "リバーシのボードの行と列のラベルを表示"
reversi:
drawn: "引き分け"
my-turn: "あなたのターンです"
opponent-turn: "相手のターンです"
turn-of: "{}のターンです"
past-turn-of: "{}のターン"
widgets: widgets:
analog-clock: "Horloge analogique" analog-clock: "Horloge analogique"
profile: "Profil" profile: "Profil"
@ -70,7 +80,7 @@ common:
donation: "Dons" donation: "Dons"
nav: "Navigation" nav: "Navigation"
tips: "Conseils" tips: "Conseils"
hashtags: "ハッシュタグ" hashtags: "Étiquettes"
deck: deck:
widgets: "Widgets" widgets: "Widgets"
home: "Accueil" home: "Accueil"
@ -226,8 +236,9 @@ common/views/widgets/posts-monitor.vue:
title: "Graph des publications" title: "Graph des publications"
toggle: "表示を切り替え" toggle: "表示を切り替え"
common/views/widgets/hashtags.vue: common/views/widgets/hashtags.vue:
title: "ハッシュタグ" title: "Étiquettes"
count: "{}人が投稿" count: "{}人が投稿"
empty: "トレンドなし"
common/views/widgets/server.vue: common/views/widgets/server.vue:
title: "Info sur le serveur" title: "Info sur le serveur"
toggle: "Afficher les vues" toggle: "Afficher les vues"
@ -235,6 +246,12 @@ common/views/widgets/memo.vue:
title: "Pense-bête" title: "Pense-bête"
memo: "Écrivez ici !" memo: "Écrivez ici !"
save: "Enregistrer" save: "Enregistrer"
common/views/pages/follow.vue:
signed-in-as: "{}としてサインイン中"
following: "フォロー中"
follow: "フォロー"
request-pending: "フォロー許可待ち"
follow-request: "フォロー申請"
desktop/views/components/activity.chart.vue: desktop/views/components/activity.chart.vue:
total: "Black ... Total" total: "Black ... Total"
notes: "Bleu ... Notes" notes: "Bleu ... Notes"
@ -333,7 +350,7 @@ desktop/views/components/friends-maker.vue:
refresh: "Plus" refresh: "Plus"
close: "Fermer" close: "Fermer"
desktop/views/components/game-window.vue: desktop/views/components/game-window.vue:
game: "Othello" game: "リバーシ"
desktop/views/components/home.vue: desktop/views/components/home.vue:
done: "Envoyer" done: "Envoyer"
add-widget: "Ajouter un widget" add-widget: "Ajouter un widget"
@ -463,7 +480,7 @@ desktop/views/components/settings.vue:
update-checking: "Recherche de mises à jour" update-checking: "Recherche de mises à jour"
do-update: "Rechercher des mises à jour" do-update: "Rechercher des mises à jour"
update-settings: "Paramètres avancés" update-settings: "Paramètres avancés"
prevent-update: "アップデートを延期する(非推奨)" prevent-update: "Reporter les mises à jour (non recommandé)"
prevent-update-desc: "この設定をオンにしてもアップデートが反映される場合があります。この設定はこのデバイスのみ有効です。" prevent-update-desc: "この設定をオンにしてもアップデートが反映される場合があります。この設定はこのデバイスのみ有効です。"
no-updates: "Aucune mise à jour disponible" no-updates: "Aucune mise à jour disponible"
no-updates-desc: "Votre Misskey est à jour." no-updates-desc: "Votre Misskey est à jour."
@ -578,7 +595,7 @@ desktop/views/components/window.vue:
popout: "ポップアウト" popout: "ポップアウト"
close: "Fermer" close: "Fermer"
desktop/views/pages/deck/deck.tl-column.vue: desktop/views/pages/deck/deck.tl-column.vue:
is-media-only: "メディア投稿のみ" is-media-only: "Les publications médias uniquement"
is-media-view: "メディアビュー" is-media-view: "メディアビュー"
desktop/views/pages/deck/deck.note.vue: desktop/views/pages/deck/deck.note.vue:
reposted-by: "Reposté par {}" reposted-by: "Reposté par {}"
@ -618,9 +635,9 @@ desktop/views/pages/user/user.friends.vue:
title: "Personnes qui répondent le plus" title: "Personnes qui répondent le plus"
loading: "Chargement en cours" loading: "Chargement en cours"
no-users: "Pas d'utilisateurs" no-users: "Pas d'utilisateurs"
desktop/views/pages/user/user.header.vue: desktop/views/pages/user/user.vue:
is-suspended: "This account has been suspended." is-suspended: "このユーザーは凍結されています。"
is-remote: "Cet utilisateur n'est pas un utilisateur de Misskey. Certaines informations peuvent être erronées " is-remote: "Cet utilisateur n'est pas un utilisateur de Misskey. Certaines informations peuvent être erronées"
view-remote: "Voir les informations détaillées" view-remote: "Voir les informations détaillées"
desktop/views/pages/user/user.home.vue: desktop/views/pages/user/user.home.vue:
last-used-at: "Last used at" last-used-at: "Last used at"
@ -636,6 +653,11 @@ desktop/views/pages/user/user.profile.vue:
mute: "Mettre en sourdine" mute: "Mettre en sourdine"
muted: "Muting" muted: "Muting"
unmute: "Enlever la sourdine" unmute: "Enlever la sourdine"
desktop/views/pages/user/user.header.vue:
posts: "投稿"
following: "フォロー"
followers: "フォロワー"
is-bot: "このアカウントはBotです"
desktop/views/pages/user/user.timeline.vue: desktop/views/pages/user/user.timeline.vue:
default: "Publications" default: "Publications"
with-replies: "Publications et réponses" with-replies: "Publications et réponses"
@ -678,7 +700,7 @@ mobile/views/components/drive.vue:
folder-name: "Nom du dossier" folder-name: "Nom du dossier"
root-rename-alert: "現在いる場所はルートで、フォルダではないため名前の変更はできません。名前を変更したいフォルダに移動してからやってください。" root-rename-alert: "現在いる場所はルートで、フォルダではないため名前の変更はできません。名前を変更したいフォルダに移動してからやってください。"
root-move-alert: "現在いる場所はルートで、フォルダではないため移動はできません。移動したいフォルダに移動してからやってください。" root-move-alert: "現在いる場所はルートで、フォルダではないため移動はできません。移動したいフォルダに移動してからやってください。"
url-prompt: "アップロードしたいファイルのURL" url-prompt: "URL du fichier que vous souhaitez téléverser"
uploading: "アップロードをリクエストしました。アップロードが完了するまで時間がかかる場合があります。" uploading: "アップロードをリクエストしました。アップロードが完了するまで時間がかかる場合があります。"
mobile/views/components/drive-file-detail.vue: mobile/views/components/drive-file-detail.vue:
rename: "Renommer" rename: "Renommer"
@ -693,9 +715,9 @@ mobile/views/components/drive.file-detail.vue:
hash: "Hash (md5)" hash: "Hash (md5)"
exif: "EXIF" exif: "EXIF"
mobile/views/components/follow-button.vue: mobile/views/components/follow-button.vue:
following: "フォロー中" following: "Abonnements"
follow: "Suivre" follow: "Suivre"
request-pending: "フォロー許可待ち" request-pending: "En attente d'approbation"
follow-request: "Demande d'abonnement" follow-request: "Demande d'abonnement"
mobile/views/components/friends-maker.vue: mobile/views/components/friends-maker.vue:
title: "Abonnez-vous aux utilisateurs" title: "Abonnez-vous aux utilisateurs"
@ -746,7 +768,7 @@ mobile/views/components/sub-note-content.vue:
private: "cette publication est privée" private: "cette publication est privée"
deleted: "cette publication a été supprimée" deleted: "cette publication a été supprimée"
media-count: "{} médias attachés" media-count: "{} médias attachés"
poll: "アンケート" poll: "Sondage"
mobile/views/components/timeline.vue: mobile/views/components/timeline.vue:
empty: "Pas de notes" empty: "Pas de notes"
load-more: "Afficher plus" load-more: "Afficher plus"

View File

@ -5,17 +5,21 @@
import * as fs from 'fs'; import * as fs from 'fs';
import * as yaml from 'js-yaml'; import * as yaml from 'js-yaml';
const loadLang = lang => yaml.safeLoad( export type LangKey = 'de' | 'en' | 'fr' | 'ja' | 'pl' | 'es';
fs.readFileSync(`./locales/${lang}.yml`, 'utf-8')); export type LocaleObject = { [key: string]: any };
const loadLang = (lang: LangKey) => yaml.safeLoad(
fs.readFileSync(`./locales/${lang}.yml`, 'utf-8')) as LocaleObject;
const native = loadLang('ja'); const native = loadLang('ja');
const langs = { const langs: { [key: string]: LocaleObject } = {
'de': loadLang('de'), 'de': loadLang('de'),
'en': loadLang('en'), 'en': loadLang('en'),
'fr': loadLang('fr'), 'fr': loadLang('fr'),
'ja': native, 'ja': native,
'pl': loadLang('pl') 'pl': loadLang('pl'),
'es': loadLang('es')
}; };
Object.entries(langs).map(([, locale]) => { Object.entries(langs).map(([, locale]) => {
@ -23,4 +27,8 @@ Object.entries(langs).map(([, locale]) => {
locale = Object.assign({}, native, locale); locale = Object.assign({}, native, locale);
}); });
export function isAvailableLanguage(lang: string): lang is LangKey {
return lang in langs;
}
export default langs; export default langs;

View File

@ -3,7 +3,7 @@ meta:
lang: "日本語" lang: "日本語"
divider: "" divider: ""
common: common:
misskey: "A planet of fediverse" misskey: "A of fediverse"
about-title: "A ⭐ of fediverse." about-title: "A ⭐ of fediverse."
about: "Misskeyを見つけていただき、ありがとうございます。Misskeyは、地球で生まれた<b>分散マイクロブログSNS</b>です。Fediverse(様々なSNSで構成される宇宙)の中に存在するため、他のSNSと相互に繋がっています。暫し都会の喧騒から離れて、新しいインターネットにダイブしてみませんか。" about: "Misskeyを見つけていただき、ありがとうございます。Misskeyは、地球で生まれた<b>分散マイクロブログSNS</b>です。Fediverse(様々なSNSで構成される宇宙)の中に存在するため、他のSNSと相互に繋がっています。暫し都会の喧騒から離れて、新しいインターネットにダイブしてみませんか。"
time: time:
@ -42,11 +42,21 @@ common:
d: "言いたいことは?" d: "言いたいことは?"
e: "ここに書いてください" e: "ここに書いてください"
f: "あなたが書くのを待っています..." f: "あなたが書くのを待っています..."
search: "検索"
delete: "削除" delete: "削除"
loading: "読み込み中" loading: "読み込み中"
ok: "わかった" ok: "わかった"
update-available-title: "更新があります"
update-available: "Misskeyの新しいバージョンがあります({newer}。現在{current}を利用中)。ページを再度読み込みすると更新が適用されます。" update-available: "Misskeyの新しいバージョンがあります({newer}。現在{current}を利用中)。ページを再度読み込みすると更新が適用されます。"
my-token-regenerated: "あなたのトークンが更新されたのでサインアウトします。" my-token-regenerated: "あなたのトークンが更新されたのでサインアウトします。"
i-like-sushi: "私は(プリンよりむしろ)寿司が好き"
show-reversi-board-labels: "リバーシのボードの行と列のラベルを表示"
reversi:
drawn: "引き分け"
my-turn: "あなたのターンです"
opponent-turn: "相手のターンです"
turn-of: "{}のターンです"
past-turn-of: "{}のターン"
widgets: widgets:
analog-clock: "アナログ時計" analog-clock: "アナログ時計"
profile: "プロフィール" profile: "プロフィール"
@ -228,6 +238,7 @@ common/views/widgets/posts-monitor.vue:
common/views/widgets/hashtags.vue: common/views/widgets/hashtags.vue:
title: "ハッシュタグ" title: "ハッシュタグ"
count: "{}人が投稿" count: "{}人が投稿"
empty: "トレンドなし"
common/views/widgets/server.vue: common/views/widgets/server.vue:
title: "サーバー情報" title: "サーバー情報"
toggle: "表示を切り替え" toggle: "表示を切り替え"
@ -235,6 +246,12 @@ common/views/widgets/memo.vue:
title: "付箋" title: "付箋"
memo: "ここに書いて!" memo: "ここに書いて!"
save: "保存" save: "保存"
common/views/pages/follow.vue:
signed-in-as: "{}としてサインイン中"
following: "フォロー中"
follow: "フォロー"
request-pending: "フォロー許可待ち"
follow-request: "フォロー申請"
desktop/views/components/activity.chart.vue: desktop/views/components/activity.chart.vue:
total: "Black ... Total" total: "Black ... Total"
notes: "Blue ... Notes" notes: "Blue ... Notes"
@ -333,7 +350,7 @@ desktop/views/components/friends-maker.vue:
refresh: "もっと見る" refresh: "もっと見る"
close: "閉じる" close: "閉じる"
desktop/views/components/game-window.vue: desktop/views/components/game-window.vue:
game: "オセロ" game: "リバーシ"
desktop/views/components/home.vue: desktop/views/components/home.vue:
done: "完了" done: "完了"
add-widget: "ウィジェットを追加:" add-widget: "ウィジェットを追加:"
@ -618,7 +635,7 @@ desktop/views/pages/user/user.friends.vue:
title: "よく話すユーザー" title: "よく話すユーザー"
loading: "読み込み中" loading: "読み込み中"
no-users: "よく話すユーザーはいません" no-users: "よく話すユーザーはいません"
desktop/views/pages/user/user.header.vue: desktop/views/pages/user/user.vue:
is-suspended: "このユーザーは凍結されています。" is-suspended: "このユーザーは凍結されています。"
is-remote: "このユーザーはリモートユーザーです。" is-remote: "このユーザーはリモートユーザーです。"
view-remote: "正確な情報を見る" view-remote: "正確な情報を見る"
@ -636,6 +653,11 @@ desktop/views/pages/user/user.profile.vue:
mute: "ミュートする" mute: "ミュートする"
muted: "ミュートしています" muted: "ミュートしています"
unmute: "ミュート解除" unmute: "ミュート解除"
desktop/views/pages/user/user.header.vue:
posts: "投稿"
following: "フォロー"
followers: "フォロワー"
is-bot: "このアカウントはBotです"
desktop/views/pages/user/user.timeline.vue: desktop/views/pages/user/user.timeline.vue:
default: "投稿" default: "投稿"
with-replies: "投稿と返信" with-replies: "投稿と返信"

View File

@ -47,11 +47,22 @@ common:
e: "ここに書いてください" e: "ここに書いてください"
f: "あなたが書くのを待っています..." f: "あなたが書くのを待っています..."
search: "検索"
delete: "削除" delete: "削除"
loading: "読み込み中" loading: "読み込み中"
ok: "わかった" ok: "わかった"
update-available-title: "更新があります"
update-available: "Misskeyの新しいバージョンがあります({newer}。現在{current}を利用中)。ページを再度読み込みすると更新が適用されます。" update-available: "Misskeyの新しいバージョンがあります({newer}。現在{current}を利用中)。ページを再度読み込みすると更新が適用されます。"
my-token-regenerated: "あなたのトークンが更新されたのでサインアウトします。" my-token-regenerated: "あなたのトークンが更新されたのでサインアウトします。"
i-like-sushi: "私は(プリンよりむしろ)寿司が好き"
show-reversi-board-labels: "リバーシのボードの行と列のラベルを表示"
reversi:
drawn: "引き分け"
my-turn: "あなたのターンです"
opponent-turn: "相手のターンです"
turn-of: "{}のターンです"
past-turn-of: "{}のターン"
widgets: widgets:
analog-clock: "アナログ時計" analog-clock: "アナログ時計"
@ -269,6 +280,13 @@ common/views/widgets/memo.vue:
memo: "ここに書いて!" memo: "ここに書いて!"
save: "保存" save: "保存"
common/views/pages/follow.vue:
signed-in-as: "{}としてサインイン中"
following: "フォロー中"
follow: "フォロー"
request-pending: "フォロー許可待ち"
follow-request: "フォロー申請"
desktop/views/components/activity.chart.vue: desktop/views/components/activity.chart.vue:
total: "Black ... Total" total: "Black ... Total"
notes: "Blue ... Notes" notes: "Blue ... Notes"
@ -384,7 +402,7 @@ desktop/views/components/friends-maker.vue:
close: "閉じる" close: "閉じる"
desktop/views/components/game-window.vue: desktop/views/components/game-window.vue:
game: "オセロ" game: "リバーシ"
desktop/views/components/home.vue: desktop/views/components/home.vue:
done: "完了" done: "完了"
@ -726,7 +744,7 @@ desktop/views/pages/user/user.friends.vue:
loading: "読み込み中" loading: "読み込み中"
no-users: "よく話すユーザーはいません" no-users: "よく話すユーザーはいません"
desktop/views/pages/user/user.header.vue: desktop/views/pages/user/user.vue:
is-suspended: "このユーザーは凍結されています。" is-suspended: "このユーザーは凍結されています。"
is-remote: "このユーザーはリモートユーザーです。" is-remote: "このユーザーはリモートユーザーです。"
view-remote: "正確な情報を見る" view-remote: "正確な情報を見る"
@ -748,6 +766,12 @@ desktop/views/pages/user/user.profile.vue:
muted: "ミュートしています" muted: "ミュートしています"
unmute: "ミュート解除" unmute: "ミュート解除"
desktop/views/pages/user/user.header.vue:
posts: "投稿"
following: "フォロー"
followers: "フォロワー"
is-bot: "このアカウントはBotです"
desktop/views/pages/user/user.timeline.vue: desktop/views/pages/user/user.timeline.vue:
default: "投稿" default: "投稿"
with-replies: "投稿と返信" with-replies: "投稿と返信"

View File

@ -3,7 +3,7 @@ meta:
lang: "日本語" lang: "日本語"
divider: "" divider: ""
common: common:
misskey: "A planet of fediverse" misskey: "A of fediverse"
about-title: "A ⭐ of fediverse." about-title: "A ⭐ of fediverse."
about: "Misskeyを見つけていただき、ありがとうございます。Misskeyは、地球で生まれた<b>分散マイクロブログSNS</b>です。Fediverse(様々なSNSで構成される宇宙)の中に存在するため、他のSNSと相互に繋がっています。暫し都会の喧騒から離れて、新しいインターネットにダイブしてみませんか。" about: "Misskeyを見つけていただき、ありがとうございます。Misskeyは、地球で生まれた<b>分散マイクロブログSNS</b>です。Fediverse(様々なSNSで構成される宇宙)の中に存在するため、他のSNSと相互に繋がっています。暫し都会の喧騒から離れて、新しいインターネットにダイブしてみませんか。"
time: time:
@ -42,11 +42,21 @@ common:
d: "言いたいことは?" d: "言いたいことは?"
e: "ここに書いてください" e: "ここに書いてください"
f: "あなたが書くのを待っています..." f: "あなたが書くのを待っています..."
search: "検索"
delete: "削除" delete: "削除"
loading: "読み込み中" loading: "読み込み中"
ok: "わかった" ok: "わかった"
update-available-title: "更新があります"
update-available: "Misskeyの新しいバージョンがあります({newer}。現在{current}を利用中)。ページを再度読み込みすると更新が適用されます。" update-available: "Misskeyの新しいバージョンがあります({newer}。現在{current}を利用中)。ページを再度読み込みすると更新が適用されます。"
my-token-regenerated: "あなたのトークンが更新されたのでサインアウトします。" my-token-regenerated: "あなたのトークンが更新されたのでサインアウトします。"
i-like-sushi: "私は(プリンよりむしろ)寿司が好き"
show-reversi-board-labels: "リバーシのボードの行と列のラベルを表示"
reversi:
drawn: "引き分け"
my-turn: "あなたのターンです"
opponent-turn: "相手のターンです"
turn-of: "{}のターンです"
past-turn-of: "{}のターン"
widgets: widgets:
analog-clock: "アナログ時計" analog-clock: "アナログ時計"
profile: "プロフィール" profile: "プロフィール"
@ -228,6 +238,7 @@ common/views/widgets/posts-monitor.vue:
common/views/widgets/hashtags.vue: common/views/widgets/hashtags.vue:
title: "ハッシュタグ" title: "ハッシュタグ"
count: "{}人が投稿" count: "{}人が投稿"
empty: "トレンドなし"
common/views/widgets/server.vue: common/views/widgets/server.vue:
title: "サーバー情報" title: "サーバー情報"
toggle: "表示を切り替え" toggle: "表示を切り替え"
@ -235,6 +246,12 @@ common/views/widgets/memo.vue:
title: "付箋" title: "付箋"
memo: "ここに書いて!" memo: "ここに書いて!"
save: "保存" save: "保存"
common/views/pages/follow.vue:
signed-in-as: "{}としてサインイン中"
following: "フォロー中"
follow: "フォロー"
request-pending: "フォロー許可待ち"
follow-request: "フォロー申請"
desktop/views/components/activity.chart.vue: desktop/views/components/activity.chart.vue:
total: "Black ... Total" total: "Black ... Total"
notes: "Blue ... Notes" notes: "Blue ... Notes"
@ -333,7 +350,7 @@ desktop/views/components/friends-maker.vue:
refresh: "もっと見る" refresh: "もっと見る"
close: "閉じる" close: "閉じる"
desktop/views/components/game-window.vue: desktop/views/components/game-window.vue:
game: "オセロ" game: "リバーシ"
desktop/views/components/home.vue: desktop/views/components/home.vue:
done: "完了" done: "完了"
add-widget: "ウィジェットを追加:" add-widget: "ウィジェットを追加:"
@ -618,7 +635,7 @@ desktop/views/pages/user/user.friends.vue:
title: "よく話すユーザー" title: "よく話すユーザー"
loading: "読み込み中" loading: "読み込み中"
no-users: "よく話すユーザーはいません" no-users: "よく話すユーザーはいません"
desktop/views/pages/user/user.header.vue: desktop/views/pages/user/user.vue:
is-suspended: "このユーザーは凍結されています。" is-suspended: "このユーザーは凍結されています。"
is-remote: "このユーザーはリモートユーザーです。" is-remote: "このユーザーはリモートユーザーです。"
view-remote: "正確な情報を見る" view-remote: "正確な情報を見る"
@ -636,6 +653,11 @@ desktop/views/pages/user/user.profile.vue:
mute: "ミュートする" mute: "ミュートする"
muted: "ミュートしています" muted: "ミュートしています"
unmute: "ミュート解除" unmute: "ミュート解除"
desktop/views/pages/user/user.header.vue:
posts: "投稿"
following: "フォロー"
followers: "フォロワー"
is-bot: "このアカウントはBotです"
desktop/views/pages/user/user.timeline.vue: desktop/views/pages/user/user.timeline.vue:
default: "投稿" default: "投稿"
with-replies: "投稿と返信" with-replies: "投稿と返信"

View File

@ -3,7 +3,7 @@ meta:
lang: "język polski" lang: "język polski"
divider: "" divider: ""
common: common:
misskey: "Planeta Fediwersum" misskey: " Fediwersum"
about-title: "⭐ Fediwersum" about-title: "⭐ Fediwersum"
about: "Dziękujemy za znalezienie Misskey. Misskey jest <b>zdecentralizowaną platformą mikroblogową</b> powstałą na Ziemi. Ponieważ działa ona w Fediwersum (uniwersum, w którego skład wchodzi wiele sieci społecznościowych), jest ona połączona z innymi platformami społecznościowymi. Spróbujesz odpocząć od zatłoczoneo miasta i zanurzyć się w nowym Internecie?" about: "Dziękujemy za znalezienie Misskey. Misskey jest <b>zdecentralizowaną platformą mikroblogową</b> powstałą na Ziemi. Ponieważ działa ona w Fediwersum (uniwersum, w którego skład wchodzi wiele sieci społecznościowych), jest ona połączona z innymi platformami społecznościowymi. Spróbujesz odpocząć od zatłoczoneo miasta i zanurzyć się w nowym Internecie?"
time: time:
@ -42,11 +42,21 @@ common:
d: "Czy masz coś do powiedzenia?" d: "Czy masz coś do powiedzenia?"
e: "Napisz coś tutaj!" e: "Napisz coś tutaj!"
f: "Czekamy, aż coś napiszesz." f: "Czekamy, aż coś napiszesz."
search: "検索"
delete: "Usuń" delete: "Usuń"
loading: "Ładowanie" loading: "Ładowanie"
ok: "OK" ok: "OK"
update-available-title: "Aktualizacja jest dostępna"
update-available: "Nowa wersja Misskey jest dostępna ({newer}, obecna to {current}). Odśwież stronę, aby zastosować aktualizację." 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." my-token-regenerated: "Twój token został wygenerowany. Zostaniesz wylogowany."
i-like-sushi: "Wolę sushi od puddingu"
show-reversi-board-labels: "リバーシのボードの行と列のラベルを表示"
reversi:
drawn: "引き分け"
my-turn: "あなたのターンです"
opponent-turn: "相手のターンです"
turn-of: "{}のターンです"
past-turn-of: "{}のターン"
widgets: widgets:
analog-clock: "Zegar analogowy" analog-clock: "Zegar analogowy"
profile: "Profil" profile: "Profil"
@ -85,8 +95,8 @@ common:
remove: "Usuń" remove: "Usuń"
add-column: "Dodaj kolumnę" add-column: "Dodaj kolumnę"
rename: "Zmień nazwę" rename: "Zmień nazwę"
stack-left: "左に重ねる" stack-left: "Przypnij do lewej"
pop-right: "右に出す" pop-right: "Odepnij w prawo"
common/views/components/connect-failed.vue: common/views/components/connect-failed.vue:
title: "Nie udało się połączyć z serwerem" 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." description: "Wystąpił problem z Twoim połączeniem z Internetem, lub z serwerem. {Spróbuj ponownie} wkrótce."
@ -228,6 +238,7 @@ common/views/widgets/posts-monitor.vue:
common/views/widgets/hashtags.vue: common/views/widgets/hashtags.vue:
title: "Hashtagi" title: "Hashtagi"
count: "Wspomniany przez {} użytkowników" count: "Wspomniany przez {} użytkowników"
empty: "Brak popularnych hashtagów"
common/views/widgets/server.vue: common/views/widgets/server.vue:
title: "Informacje o serwerze" title: "Informacje o serwerze"
toggle: "Przełącz widok" toggle: "Przełącz widok"
@ -235,6 +246,12 @@ common/views/widgets/memo.vue:
title: "Notatka" title: "Notatka"
memo: "Napisz tutaj!" memo: "Napisz tutaj!"
save: "Zapisz" save: "Zapisz"
common/views/pages/follow.vue:
signed-in-as: "{}としてサインイン中"
following: "フォロー中"
follow: "フォロー"
request-pending: "フォロー許可待ち"
follow-request: "フォロー申請"
desktop/views/components/activity.chart.vue: desktop/views/components/activity.chart.vue:
total: "Czarny … Łącznie" total: "Czarny … Łącznie"
notes: "Niebieski … Wpisy" notes: "Niebieski … Wpisy"
@ -333,7 +350,7 @@ desktop/views/components/friends-maker.vue:
refresh: "Więcej" refresh: "Więcej"
close: "Zamknij" close: "Zamknij"
desktop/views/components/game-window.vue: desktop/views/components/game-window.vue:
game: "Othello" game: "Reversi"
desktop/views/components/home.vue: desktop/views/components/home.vue:
done: "Wyślij" done: "Wyślij"
add-widget: "Dodaj widżet:" add-widget: "Dodaj widżet:"
@ -618,7 +635,7 @@ desktop/views/pages/user/user.friends.vue:
title: "Najbardziej aktywni" title: "Najbardziej aktywni"
loading: "Ładowanie" loading: "Ładowanie"
no-users: "Brak użytkowników" no-users: "Brak użytkowników"
desktop/views/pages/user/user.header.vue: desktop/views/pages/user/user.vue:
is-suspended: "To konto zostało zawieszone." is-suspended: "To konto zostało zawieszone."
is-remote: "To jest użytkownik zdalnej instancji, informacje mogą nie być w pełni dokładne." is-remote: "To jest użytkownik zdalnej instancji, informacje mogą nie być w pełni dokładne."
view-remote: "Wyświetl dokładne informacje" view-remote: "Wyświetl dokładne informacje"
@ -636,6 +653,11 @@ desktop/views/pages/user/user.profile.vue:
mute: "Wycisz" mute: "Wycisz"
muted: "Wyciszyłeś" muted: "Wyciszyłeś"
unmute: "Cofnij wyciszenie" unmute: "Cofnij wyciszenie"
desktop/views/pages/user/user.header.vue:
posts: "投稿"
following: "フォロー"
followers: "フォロワー"
is-bot: "このアカウントはBotです"
desktop/views/pages/user/user.timeline.vue: desktop/views/pages/user/user.timeline.vue:
default: "Wpisy" default: "Wpisy"
with-replies: "Wpisy i odpowiedzi" with-replies: "Wpisy i odpowiedzi"

View File

@ -3,7 +3,7 @@ meta:
lang: "Português" lang: "Português"
divider: "" divider: ""
common: common:
misskey: "A planet of fediverse" misskey: "A of fediverse"
about-title: "A ⭐ of fediverse." about-title: "A ⭐ of fediverse."
about: "Misskeyを見つけていただき、ありがとうございます。Misskeyは、地球で生まれた<b>分散マイクロブログSNS</b>です。Fediverse(様々なSNSで構成される宇宙)の中に存在するため、他のSNSと相互に繋がっています。暫し都会の喧騒から離れて、新しいインターネットにダイブしてみませんか。" about: "Misskeyを見つけていただき、ありがとうございます。Misskeyは、地球で生まれた<b>分散マイクロブログSNS</b>です。Fediverse(様々なSNSで構成される宇宙)の中に存在するため、他のSNSと相互に繋がっています。暫し都会の喧騒から離れて、新しいインターネットにダイブしてみませんか。"
time: time:
@ -42,11 +42,21 @@ common:
d: "言いたいことは?" d: "言いたいことは?"
e: "ここに書いてください" e: "ここに書いてください"
f: "あなたが書くのを待っています..." f: "あなたが書くのを待っています..."
search: "検索"
delete: "削除" delete: "削除"
loading: "読み込み中" loading: "読み込み中"
ok: "わかった" ok: "わかった"
update-available-title: "更新があります"
update-available: "Misskeyの新しいバージョンがあります({newer}。現在{current}を利用中)。ページを再度読み込みすると更新が適用されます。" update-available: "Misskeyの新しいバージョンがあります({newer}。現在{current}を利用中)。ページを再度読み込みすると更新が適用されます。"
my-token-regenerated: "あなたのトークンが更新されたのでサインアウトします。" my-token-regenerated: "あなたのトークンが更新されたのでサインアウトします。"
i-like-sushi: "私は(プリンよりむしろ)寿司が好き"
show-reversi-board-labels: "リバーシのボードの行と列のラベルを表示"
reversi:
drawn: "引き分け"
my-turn: "あなたのターンです"
opponent-turn: "相手のターンです"
turn-of: "{}のターンです"
past-turn-of: "{}のターン"
widgets: widgets:
analog-clock: "アナログ時計" analog-clock: "アナログ時計"
profile: "プロフィール" profile: "プロフィール"
@ -228,6 +238,7 @@ common/views/widgets/posts-monitor.vue:
common/views/widgets/hashtags.vue: common/views/widgets/hashtags.vue:
title: "ハッシュタグ" title: "ハッシュタグ"
count: "{}人が投稿" count: "{}人が投稿"
empty: "トレンドなし"
common/views/widgets/server.vue: common/views/widgets/server.vue:
title: "サーバー情報" title: "サーバー情報"
toggle: "表示を切り替え" toggle: "表示を切り替え"
@ -235,6 +246,12 @@ common/views/widgets/memo.vue:
title: "付箋" title: "付箋"
memo: "ここに書いて!" memo: "ここに書いて!"
save: "保存" save: "保存"
common/views/pages/follow.vue:
signed-in-as: "{}としてサインイン中"
following: "フォロー中"
follow: "フォロー"
request-pending: "フォロー許可待ち"
follow-request: "フォロー申請"
desktop/views/components/activity.chart.vue: desktop/views/components/activity.chart.vue:
total: "Black ... Total" total: "Black ... Total"
notes: "Blue ... Notes" notes: "Blue ... Notes"
@ -333,7 +350,7 @@ desktop/views/components/friends-maker.vue:
refresh: "もっと見る" refresh: "もっと見る"
close: "閉じる" close: "閉じる"
desktop/views/components/game-window.vue: desktop/views/components/game-window.vue:
game: "オセロ" game: "リバーシ"
desktop/views/components/home.vue: desktop/views/components/home.vue:
done: "完了" done: "完了"
add-widget: "ウィジェットを追加:" add-widget: "ウィジェットを追加:"
@ -618,7 +635,7 @@ desktop/views/pages/user/user.friends.vue:
title: "よく話すユーザー" title: "よく話すユーザー"
loading: "読み込み中" loading: "読み込み中"
no-users: "よく話すユーザーはいません" no-users: "よく話すユーザーはいません"
desktop/views/pages/user/user.header.vue: desktop/views/pages/user/user.vue:
is-suspended: "このユーザーは凍結されています。" is-suspended: "このユーザーは凍結されています。"
is-remote: "このユーザーはリモートユーザーです。" is-remote: "このユーザーはリモートユーザーです。"
view-remote: "正確な情報を見る" view-remote: "正確な情報を見る"
@ -636,6 +653,11 @@ desktop/views/pages/user/user.profile.vue:
mute: "ミュートする" mute: "ミュートする"
muted: "ミュートしています" muted: "ミュートしています"
unmute: "ミュート解除" unmute: "ミュート解除"
desktop/views/pages/user/user.header.vue:
posts: "投稿"
following: "フォロー"
followers: "フォロワー"
is-bot: "このアカウントはBotです"
desktop/views/pages/user/user.timeline.vue: desktop/views/pages/user/user.timeline.vue:
default: "投稿" default: "投稿"
with-replies: "投稿と返信" with-replies: "投稿と返信"

View File

@ -3,7 +3,7 @@ meta:
lang: "Русский язык" lang: "Русский язык"
divider: "" divider: ""
common: common:
misskey: "A planet of fediverse" misskey: "A of fediverse"
about-title: "A ⭐ of fediverse." about-title: "A ⭐ of fediverse."
about: "Misskeyを見つけていただき、ありがとうございます。Misskeyは、地球で生まれた<b>分散マイクロブログSNS</b>です。Fediverse(様々なSNSで構成される宇宙)の中に存在するため、他のSNSと相互に繋がっています。暫し都会の喧騒から離れて、新しいインターネットにダイブしてみませんか。" about: "Misskeyを見つけていただき、ありがとうございます。Misskeyは、地球で生まれた<b>分散マイクロブログSNS</b>です。Fediverse(様々なSNSで構成される宇宙)の中に存在するため、他のSNSと相互に繋がっています。暫し都会の喧騒から離れて、新しいインターネットにダイブしてみませんか。"
time: time:
@ -42,11 +42,21 @@ common:
d: "言いたいことは?" d: "言いたいことは?"
e: "ここに書いてください" e: "ここに書いてください"
f: "あなたが書くのを待っています..." f: "あなたが書くのを待っています..."
search: "検索"
delete: "削除" delete: "削除"
loading: "読み込み中" loading: "読み込み中"
ok: "わかった" ok: "わかった"
update-available-title: "更新があります"
update-available: "Misskeyの新しいバージョンがあります({newer}。現在{current}を利用中)。ページを再度読み込みすると更新が適用されます。" update-available: "Misskeyの新しいバージョンがあります({newer}。現在{current}を利用中)。ページを再度読み込みすると更新が適用されます。"
my-token-regenerated: "あなたのトークンが更新されたのでサインアウトします。" my-token-regenerated: "あなたのトークンが更新されたのでサインアウトします。"
i-like-sushi: "私は(プリンよりむしろ)寿司が好き"
show-reversi-board-labels: "リバーシのボードの行と列のラベルを表示"
reversi:
drawn: "引き分け"
my-turn: "あなたのターンです"
opponent-turn: "相手のターンです"
turn-of: "{}のターンです"
past-turn-of: "{}のターン"
widgets: widgets:
analog-clock: "アナログ時計" analog-clock: "アナログ時計"
profile: "プロフィール" profile: "プロフィール"
@ -228,6 +238,7 @@ common/views/widgets/posts-monitor.vue:
common/views/widgets/hashtags.vue: common/views/widgets/hashtags.vue:
title: "ハッシュタグ" title: "ハッシュタグ"
count: "{}人が投稿" count: "{}人が投稿"
empty: "トレンドなし"
common/views/widgets/server.vue: common/views/widgets/server.vue:
title: "サーバー情報" title: "サーバー情報"
toggle: "表示を切り替え" toggle: "表示を切り替え"
@ -235,6 +246,12 @@ common/views/widgets/memo.vue:
title: "付箋" title: "付箋"
memo: "ここに書いて!" memo: "ここに書いて!"
save: "保存" save: "保存"
common/views/pages/follow.vue:
signed-in-as: "{}としてサインイン中"
following: "フォロー中"
follow: "フォロー"
request-pending: "フォロー許可待ち"
follow-request: "フォロー申請"
desktop/views/components/activity.chart.vue: desktop/views/components/activity.chart.vue:
total: "Black ... Total" total: "Black ... Total"
notes: "Blue ... Notes" notes: "Blue ... Notes"
@ -333,7 +350,7 @@ desktop/views/components/friends-maker.vue:
refresh: "もっと見る" refresh: "もっと見る"
close: "閉じる" close: "閉じる"
desktop/views/components/game-window.vue: desktop/views/components/game-window.vue:
game: "オセロ" game: "リバーシ"
desktop/views/components/home.vue: desktop/views/components/home.vue:
done: "完了" done: "完了"
add-widget: "ウィジェットを追加:" add-widget: "ウィジェットを追加:"
@ -618,7 +635,7 @@ desktop/views/pages/user/user.friends.vue:
title: "よく話すユーザー" title: "よく話すユーザー"
loading: "読み込み中" loading: "読み込み中"
no-users: "よく話すユーザーはいません" no-users: "よく話すユーザーはいません"
desktop/views/pages/user/user.header.vue: desktop/views/pages/user/user.vue:
is-suspended: "このユーザーは凍結されています。" is-suspended: "このユーザーは凍結されています。"
is-remote: "このユーザーはリモートユーザーです。" is-remote: "このユーザーはリモートユーザーです。"
view-remote: "正確な情報を見る" view-remote: "正確な情報を見る"
@ -636,6 +653,11 @@ desktop/views/pages/user/user.profile.vue:
mute: "ミュートする" mute: "ミュートする"
muted: "ミュートしています" muted: "ミュートしています"
unmute: "ミュート解除" unmute: "ミュート解除"
desktop/views/pages/user/user.header.vue:
posts: "投稿"
following: "フォロー"
followers: "フォロワー"
is-bot: "このアカウントはBotです"
desktop/views/pages/user/user.timeline.vue: desktop/views/pages/user/user.timeline.vue:
default: "投稿" default: "投稿"
with-replies: "投稿と返信" with-replies: "投稿と返信"

View File

@ -3,7 +3,7 @@ meta:
lang: "中文(简体)" lang: "中文(简体)"
divider: "" divider: ""
common: common:
misskey: "A planet of fediverse" misskey: "A of fediverse"
about-title: "A ⭐ of fediverse." about-title: "A ⭐ of fediverse."
about: "Misskeyを見つけていただき、ありがとうございます。Misskeyは、地球で生まれた<b>分散マイクロブログSNS</b>です。Fediverse(様々なSNSで構成される宇宙)の中に存在するため、他のSNSと相互に繋がっています。暫し都会の喧騒から離れて、新しいインターネットにダイブしてみませんか。" about: "Misskeyを見つけていただき、ありがとうございます。Misskeyは、地球で生まれた<b>分散マイクロブログSNS</b>です。Fediverse(様々なSNSで構成される宇宙)の中に存在するため、他のSNSと相互に繋がっています。暫し都会の喧騒から離れて、新しいインターネットにダイブしてみませんか。"
time: time:
@ -42,11 +42,21 @@ common:
d: "言いたいことは?" d: "言いたいことは?"
e: "ここに書いてください" e: "ここに書いてください"
f: "あなたが書くのを待っています..." f: "あなたが書くのを待っています..."
search: "検索"
delete: "削除" delete: "削除"
loading: "読み込み中" loading: "読み込み中"
ok: "わかった" ok: "わかった"
update-available-title: "更新があります"
update-available: "Misskeyの新しいバージョンがあります({newer}。現在{current}を利用中)。ページを再度読み込みすると更新が適用されます。" update-available: "Misskeyの新しいバージョンがあります({newer}。現在{current}を利用中)。ページを再度読み込みすると更新が適用されます。"
my-token-regenerated: "あなたのトークンが更新されたのでサインアウトします。" my-token-regenerated: "あなたのトークンが更新されたのでサインアウトします。"
i-like-sushi: "私は(プリンよりむしろ)寿司が好き"
show-reversi-board-labels: "リバーシのボードの行と列のラベルを表示"
reversi:
drawn: "引き分け"
my-turn: "あなたのターンです"
opponent-turn: "相手のターンです"
turn-of: "{}のターンです"
past-turn-of: "{}のターン"
widgets: widgets:
analog-clock: "アナログ時計" analog-clock: "アナログ時計"
profile: "プロフィール" profile: "プロフィール"
@ -228,6 +238,7 @@ common/views/widgets/posts-monitor.vue:
common/views/widgets/hashtags.vue: common/views/widgets/hashtags.vue:
title: "ハッシュタグ" title: "ハッシュタグ"
count: "{}人が投稿" count: "{}人が投稿"
empty: "トレンドなし"
common/views/widgets/server.vue: common/views/widgets/server.vue:
title: "サーバー情報" title: "サーバー情報"
toggle: "表示を切り替え" toggle: "表示を切り替え"
@ -235,6 +246,12 @@ common/views/widgets/memo.vue:
title: "付箋" title: "付箋"
memo: "ここに書いて!" memo: "ここに書いて!"
save: "保存" save: "保存"
common/views/pages/follow.vue:
signed-in-as: "{}としてサインイン中"
following: "フォロー中"
follow: "フォロー"
request-pending: "フォロー許可待ち"
follow-request: "フォロー申請"
desktop/views/components/activity.chart.vue: desktop/views/components/activity.chart.vue:
total: "Black ... Total" total: "Black ... Total"
notes: "Blue ... Notes" notes: "Blue ... Notes"
@ -333,7 +350,7 @@ desktop/views/components/friends-maker.vue:
refresh: "もっと見る" refresh: "もっと見る"
close: "閉じる" close: "閉じる"
desktop/views/components/game-window.vue: desktop/views/components/game-window.vue:
game: "オセロ" game: "リバーシ"
desktop/views/components/home.vue: desktop/views/components/home.vue:
done: "完了" done: "完了"
add-widget: "ウィジェットを追加:" add-widget: "ウィジェットを追加:"
@ -618,7 +635,7 @@ desktop/views/pages/user/user.friends.vue:
title: "よく話すユーザー" title: "よく話すユーザー"
loading: "読み込み中" loading: "読み込み中"
no-users: "よく話すユーザーはいません" no-users: "よく話すユーザーはいません"
desktop/views/pages/user/user.header.vue: desktop/views/pages/user/user.vue:
is-suspended: "このユーザーは凍結されています。" is-suspended: "このユーザーは凍結されています。"
is-remote: "このユーザーはリモートユーザーです。" is-remote: "このユーザーはリモートユーザーです。"
view-remote: "正確な情報を見る" view-remote: "正確な情報を見る"
@ -636,6 +653,11 @@ desktop/views/pages/user/user.profile.vue:
mute: "ミュートする" mute: "ミュートする"
muted: "ミュートしています" muted: "ミュートしています"
unmute: "ミュート解除" unmute: "ミュート解除"
desktop/views/pages/user/user.header.vue:
posts: "投稿"
following: "フォロー"
followers: "フォロワー"
is-bot: "このアカウントはBotです"
desktop/views/pages/user/user.timeline.vue: desktop/views/pages/user/user.timeline.vue:
default: "投稿" default: "投稿"
with-replies: "投稿と返信" with-replies: "投稿と返信"

View File

@ -1,8 +1,8 @@
{ {
"name": "misskey", "name": "misskey",
"author": "syuilo <i@syuilo.com>", "author": "syuilo <i@syuilo.com>",
"version": "3.0.1", "version": "4.13.0",
"clientVersion": "1.0.6517", "clientVersion": "1.0.6783",
"codename": "nighthike", "codename": "nighthike",
"main": "./built/index.js", "main": "./built/index.js",
"private": true, "private": true,
@ -23,29 +23,115 @@
"format": "gulp format" "format": "gulp format"
}, },
"dependencies": { "dependencies": {
"@fortawesome/fontawesome": "1.0.1", "@fortawesome/fontawesome": "1.1.8",
"@fortawesome/fontawesome-free-brands": "5.0.2", "@fortawesome/fontawesome-free-brands": "5.0.13",
"@fortawesome/fontawesome-free-regular": "5.0.2", "@fortawesome/fontawesome-free-regular": "5.0.13",
"@fortawesome/fontawesome-free-solid": "5.0.2", "@fortawesome/fontawesome-free-solid": "5.0.13",
"@koa/cors": "2.2.1", "@koa/cors": "2.2.1",
"@prezzemolo/rap": "0.1.2", "@prezzemolo/rap": "0.1.2",
"@prezzemolo/zip": "0.0.3",
"@types/bcryptjs": "2.4.1",
"@types/debug": "0.0.30",
"@types/deep-equal": "1.0.1",
"@types/elasticsearch": "5.0.24",
"@types/file-type": "5.2.1",
"@types/gm": "1.18.0",
"@types/gulp": "3.8.36",
"@types/gulp-htmlmin": "1.3.32",
"@types/gulp-mocha": "0.0.32",
"@types/gulp-rename": "0.0.33",
"@types/gulp-replace": "0.0.31",
"@types/gulp-uglify": "3.0.5",
"@types/gulp-util": "3.0.34",
"@types/inquirer": "0.0.42",
"@types/is-root": "1.0.0",
"@types/is-url": "1.2.28",
"@types/js-yaml": "3.11.1",
"@types/jsdom": "11.0.6",
"@types/koa": "2.0.46",
"@types/koa-bodyparser": "5.0.0",
"@types/koa-compress": "2.0.8",
"@types/koa-favicon": "2.0.19",
"@types/koa-logger": "3.1.0",
"@types/koa-mount": "3.0.1",
"@types/koa-multer": "1.0.0",
"@types/koa-router": "7.0.30",
"@types/koa-send": "4.1.1",
"@types/koa-views": "2.0.3",
"@types/koa__cors": "2.2.2",
"@types/kue": "0.11.9",
"@types/license-checker": "15.0.0",
"@types/mkdirp": "0.5.2",
"@types/mocha": "5.2.3",
"@types/mongodb": "3.0.21",
"@types/ms": "0.7.30",
"@types/node": "10.3.5",
"@types/nopt": "3.0.29",
"@types/parse5": "5.0.0",
"@types/pug": "2.0.4",
"@types/qrcode": "1.2.0",
"@types/ratelimiter": "2.1.28",
"@types/redis": "2.8.6",
"@types/request": "2.47.1",
"@types/request-promise-native": "1.0.15",
"@types/rimraf": "2.0.2",
"@types/seedrandom": "2.4.27",
"@types/single-line-log": "1.1.0",
"@types/speakeasy": "2.0.2",
"@types/tmp": "0.0.33",
"@types/uuid": "3.4.3",
"@types/webpack": "4.4.2",
"@types/webpack-stream": "3.2.10",
"@types/websocket": "0.0.39",
"@types/ws": "5.1.2",
"animejs": "2.2.0",
"autosize": "4.0.2",
"autwh": "0.1.0", "autwh": "0.1.0",
"bcryptjs": "2.4.3", "bcryptjs": "2.4.3",
"bootstrap-vue": "2.0.0-rc.11",
"cafy": "8.0.0", "cafy": "8.0.0",
"chalk": "2.4.1", "chalk": "2.4.1",
"crc-32": "1.2.0", "crc-32": "1.2.0",
"css-loader": "0.28.11",
"debug": "3.1.0", "debug": "3.1.0",
"deep-equal": "1.0.1",
"deepcopy": "0.6.3", "deepcopy": "0.6.3",
"diskusage": "0.2.4", "diskusage": "0.2.4",
"dompurify": "1.0.5",
"elasticsearch": "15.0.0", "elasticsearch": "15.0.0",
"element-ui": "2.4.1",
"emojilib": "2.2.12", "emojilib": "2.2.12",
"escape-regexp": "0.0.1", "escape-regexp": "0.0.1",
"eslint": "5.0.0",
"eslint-plugin-vue": "4.5.0",
"eventemitter3": "3.1.0",
"exif-js": "2.3.0",
"file-loader": "1.1.11",
"file-type": "8.0.0", "file-type": "8.0.0",
"fuckadblock": "3.2.1",
"gm": "1.23.1", "gm": "1.23.1",
"gulp": "3.9.1",
"gulp-cssnano": "2.1.3",
"gulp-htmlmin": "4.0.0",
"gulp-imagemin": "4.1.0",
"gulp-mocha": "6.0.0",
"gulp-pug": "4.0.1",
"gulp-rename": "1.3.0",
"gulp-replace": "1.0.0",
"gulp-sourcemaps": "2.6.4",
"gulp-stylus": "2.7.0",
"gulp-tslint": "8.1.3",
"gulp-typescript": "4.0.2",
"gulp-uglify": "3.0.0",
"gulp-util": "3.0.8",
"hard-source-webpack-plugin": "0.9.0",
"highlight.js": "9.12.0",
"html-minifier": "3.5.16",
"http-signature": "1.2.0", "http-signature": "1.2.0",
"inquirer": "6.0.0",
"is-root": "2.0.0", "is-root": "2.0.0",
"is-url": "1.2.4", "is-url": "1.2.4",
"js-yaml": "3.11.0", "js-yaml": "3.12.0",
"jsdom": "11.11.0", "jsdom": "11.11.0",
"koa": "2.5.1", "koa": "2.5.1",
"koa-bodyparser": "4.2.1", "koa-bodyparser": "4.2.1",
@ -56,166 +142,88 @@
"koa-mount": "3.0.0", "koa-mount": "3.0.0",
"koa-multer": "1.0.2", "koa-multer": "1.0.2",
"koa-router": "7.4.0", "koa-router": "7.4.0",
"koa-send": "4.1.3", "koa-send": "5.0.0",
"koa-slow": "2.1.0", "koa-slow": "2.1.0",
"koa-views": "6.1.4", "koa-views": "6.1.4",
"kue": "0.11.6", "kue": "0.11.6",
"mongodb": "3.0.10", "license-checker": "20.1.0",
"monk": "6.0.6",
"ms": "2.1.1",
"nopt": "4.0.1",
"os-utils": "0.0.14",
"parse5": "5.0.0",
"prominence": "0.2.0",
"promise-sequential": "1.1.1",
"punycode": "2.1.1",
"qrcode": "1.2.0",
"ratelimiter": "3.0.3",
"recaptcha-promise": "0.1.3",
"reconnecting-websocket": "3.2.2",
"redis": "2.8.0",
"request": "2.87.0",
"request-promise-native": "1.0.5",
"rndstr": "1.0.0",
"speakeasy": "2.0.0",
"summaly": "2.0.6",
"tcp-port-used": "0.1.2",
"tmp": "0.0.33",
"uuid": "3.2.1",
"web-push": "3.3.1",
"webfinger.js": "2.6.6",
"websocket": "1.0.26",
"ws": "5.2.0",
"xev": "2.0.1",
"@prezzemolo/zip": "0.0.3",
"@types/bcryptjs": "2.4.1",
"@types/debug": "0.0.30",
"@types/deep-equal": "1.0.1",
"@types/elasticsearch": "5.0.23",
"@types/gm": "1.18.0",
"@types/gulp": "3.8.36",
"@types/gulp-htmlmin": "1.3.32",
"@types/gulp-mocha": "0.0.32",
"@types/gulp-rename": "0.0.33",
"@types/gulp-replace": "0.0.31",
"@types/gulp-uglify": "3.0.5",
"@types/gulp-util": "3.0.34",
"@types/inquirer": "0.0.41",
"@types/is-root": "1.0.0",
"@types/is-url": "1.2.28",
"@types/js-yaml": "3.11.1",
"@types/koa": "2.0.45",
"@types/koa-bodyparser": "4.2.0",
"@types/koa-compress": "2.0.8",
"@types/koa-favicon": "2.0.19",
"@types/koa-logger": "3.1.0",
"@types/koa-mount": "3.0.1",
"@types/koa-multer": "1.0.0",
"@types/koa-router": "7.0.28",
"@types/koa-send": "4.1.1",
"@types/koa-views": "2.0.3",
"@types/koa__cors": "2.2.2",
"@types/kue": "0.11.8",
"@types/license-checker": "15.0.0",
"@types/mkdirp": "0.5.2",
"@types/mocha": "5.2.0",
"@types/mongodb": "3.0.18",
"@types/ms": "0.7.30",
"@types/node": "10.1.2",
"@types/nopt": "3.0.29",
"@types/parse5": "3.0.0",
"@types/pug": "2.0.4",
"@types/qrcode": "0.8.1",
"@types/ratelimiter": "2.1.28",
"@types/redis": "2.8.6",
"@types/request": "2.47.0",
"@types/request-promise-native": "1.0.14",
"@types/rimraf": "2.0.2",
"@types/seedrandom": "2.4.27",
"@types/single-line-log": "1.1.0",
"@types/speakeasy": "2.0.2",
"@types/tmp": "0.0.33",
"@types/uuid": "3.4.3",
"@types/webpack": "4.4.0",
"@types/webpack-stream": "3.2.10",
"@types/websocket": "0.0.39",
"@types/ws": "5.1.1",
"animejs": "2.2.0",
"autosize": "4.0.2",
"bootstrap-vue": "2.0.0-rc.6",
"css-loader": "0.28.11",
"deep-equal": "1.0.1",
"dompurify": "1.0.4",
"element-ui": "2.3.9",
"eslint": "4.19.1",
"eslint-plugin-vue": "4.5.0",
"eventemitter3": "3.1.0",
"exif-js": "2.3.0",
"file-loader": "1.1.11",
"fuckadblock": "3.2.1",
"gulp": "3.9.1",
"gulp-cssnano": "2.1.3",
"gulp-htmlmin": "4.0.0",
"gulp-imagemin": "4.1.0",
"gulp-mocha": "6.0.0",
"gulp-pug": "4.0.1",
"gulp-rename": "1.2.3",
"gulp-replace": "1.0.0",
"gulp-sourcemaps": "2.6.4",
"gulp-stylus": "2.7.0",
"gulp-tslint": "8.1.3",
"gulp-typescript": "4.0.2",
"gulp-uglify": "3.0.0",
"gulp-util": "3.0.8",
"hard-source-webpack-plugin": "0.6.10",
"highlight.js": "9.12.0",
"html-minifier": "3.5.16",
"inquirer": "5.2.0",
"license-checker": "20.0.0",
"loader-utils": "1.1.0", "loader-utils": "1.1.0",
"mecab-async": "0.1.2", "mecab-async": "0.1.2",
"mkdirp": "0.5.1", "mkdirp": "0.5.1",
"mocha": "5.2.0", "mocha": "5.2.0",
"moji": "0.5.1", "moji": "0.5.1",
"mongodb": "3.0.10",
"monk": "6.0.6",
"ms": "2.1.1",
"nan": "2.10.0", "nan": "2.10.0",
"node-sass": "4.9.0", "node-sass": "4.9.0",
"node-sass-json-importer": "3.2.0", "node-sass-json-importer": "3.3.1",
"nopt": "4.0.1",
"nprogress": "0.2.0", "nprogress": "0.2.0",
"object-assign-deep": "0.4.0", "object-assign-deep": "0.4.0",
"on-build-webpack": "0.1.0", "on-build-webpack": "0.1.0",
"os-utils": "0.0.14",
"parse5": "5.0.0",
"progress-bar-webpack-plugin": "1.11.0", "progress-bar-webpack-plugin": "1.11.0",
"prominence": "0.2.0",
"promise-sequential": "1.1.1",
"pug": "2.0.3", "pug": "2.0.3",
"punycode": "2.1.1",
"qrcode": "1.2.0",
"ratelimiter": "3.1.0",
"recaptcha-promise": "0.1.3",
"reconnecting-websocket": "3.2.2",
"redis": "2.8.0",
"request": "2.87.0",
"request-promise-native": "1.0.5",
"rimraf": "2.6.2", "rimraf": "2.6.2",
"rndstr": "1.0.0",
"s-age": "1.1.2", "s-age": "1.1.2",
"sass-loader": "7.0.1", "sass-loader": "7.0.3",
"seedrandom": "2.4.3", "seedrandom": "2.4.3",
"single-line-log": "1.1.2", "single-line-log": "1.1.2",
"speakeasy": "2.0.0",
"style-loader": "0.21.0", "style-loader": "0.21.0",
"stylus": "0.54.5", "stylus": "0.54.5",
"stylus-loader": "3.0.2", "stylus-loader": "3.0.2",
"summaly": "2.0.6",
"swagger-jsdoc": "1.9.7", "swagger-jsdoc": "1.9.7",
"syuilo-password-strength": "0.0.1", "syuilo-password-strength": "0.0.1",
"tcp-port-used": "0.1.2",
"textarea-caret": "3.1.0", "textarea-caret": "3.1.0",
"ts-loader": "4.3.0", "tmp": "0.0.33",
"ts-node": "6.0.4", "ts-loader": "4.4.1",
"ts-node": "7.0.0",
"tslint": "5.10.0", "tslint": "5.10.0",
"typescript": "2.8.3", "typescript": "2.9.2",
"typescript-eslint-parser": "15.0.0", "typescript-eslint-parser": "16.0.0",
"uglify-es": "3.3.9", "uglify-es": "3.3.9",
"url-loader": "1.0.1", "url-loader": "1.0.1",
"uuid": "3.2.1",
"v-animate-css": "0.0.2", "v-animate-css": "0.0.2",
"vue": "2.5.16", "vue": "2.5.16",
"vue-cropperjs": "2.2.0", "vue-cropperjs": "2.2.1",
"vue-js-modal": "1.3.13", "vue-js-modal": "1.3.15",
"vue-json-tree-view": "2.1.4", "vue-json-tree-view": "2.1.4",
"vue-loader": "15.2.1", "vue-loader": "15.2.4",
"vue-router": "3.0.1", "vue-router": "3.0.1",
"vue-template-compiler": "2.5.16", "vue-template-compiler": "2.5.16",
"vuedraggable": "2.16.0", "vuedraggable": "2.16.0",
"vuex": "3.0.1", "vuex": "3.0.1",
"vuex-persistedstate": "^2.5.4", "vuex-persistedstate": "^2.5.4",
"webpack": "4.9.1", "web-push": "3.3.2",
"webpack-cli": "2.1.4" "webfinger.js": "2.6.6",
"webpack": "4.12.0",
"webpack-cli": "3.0.8",
"websocket": "1.0.26",
"ws": "5.2.1",
"xev": "2.0.1"
},
"greenkeeper": {
"ignore": [
"deepcopy",
"cafy",
"@types/gulp"
]
} }
} }

View File

@ -1,4 +1,4 @@
export default acct => { export default (acct: string) => {
const splitted = acct.split('@', 2); const splitted = acct.split('@', 2);
return { username: splitted[0], host: splitted[1] || null }; return { username: splitted[0], host: splitted[1] || null };
}; };

View File

@ -1,3 +1,5 @@
export default user => { import { IUser } from '../models/user';
export default (user: IUser) => {
return user.host === null ? user.username : `${user.username}@${user.host}`; return user.host === null ? user.username : `${user.username}@${user.host}`;
}; };

View File

@ -3,18 +3,18 @@
*/ */
import * as fontawesome from '@fortawesome/fontawesome'; import * as fontawesome from '@fortawesome/fontawesome';
import * as regular from '@fortawesome/fontawesome-free-regular'; import regular from '@fortawesome/fontawesome-free-regular';
import * as solid from '@fortawesome/fontawesome-free-solid'; import solid from '@fortawesome/fontawesome-free-solid';
import * as brands from '@fortawesome/fontawesome-free-brands'; import brands from '@fortawesome/fontawesome-free-brands';
fontawesome.library.add(regular, solid, brands); fontawesome.library.add(regular, solid, brands);
export const pattern = /%fa:(.+?)%/g; export const pattern = /%fa:(.+?)%/g;
export const replacement = (match, key) => { export const replacement = (match: string, key: string) => {
const args = key.split(' '); const args = key.split(' ');
let prefix = 'fas'; let prefix = 'fas';
const classes = []; const classes: string[] = [];
let transform = ''; let transform = '';
let name; let name;
@ -34,12 +34,12 @@ export const replacement = (match, key) => {
} }
}); });
const icon = fontawesome.icon({ prefix, iconName: name }, { const icon = fontawesome.icon({ prefix, iconName: name } as fontawesome.IconLookup, {
classes: classes classes: classes,
transform: fontawesome.parse.transform(transform)
}); });
if (icon) { if (icon) {
icon.transform = fontawesome.parse.transform(transform);
return `<i data-fa class="${name}">${icon.html[0]}</i>`; return `<i data-fa class="${name}">${icon.html[0]}</i>`;
} else { } else {
console.warn(`'${name}' not found in fa`); console.warn(`'${name}' not found in fa`);

View File

@ -2,7 +2,7 @@
* Replace i18n texts * Replace i18n texts
*/ */
import locale from '../../locales'; import locale, { isAvailableLanguage, LocaleObject } from '../../locales';
export default class Replacer { export default class Replacer {
private lang: string; private lang: string;
@ -16,19 +16,19 @@ export default class Replacer {
this.replacement = this.replacement.bind(this); this.replacement = this.replacement.bind(this);
} }
private get(path: string, key: string) { private get(path: string, key: string): string {
const texts = locale[this.lang]; if (!isAvailableLanguage(this.lang)) {
if (texts == null) {
console.warn(`lang '${this.lang}' is not supported`); console.warn(`lang '${this.lang}' is not supported`);
return key; // Fallback return key; // Fallback
} }
const texts = locale[this.lang];
let text = texts; let text = texts;
if (path) { if (path) {
if (text.hasOwnProperty(path)) { if (text.hasOwnProperty(path)) {
text = text[path]; text = text[path] as LocaleObject;
} else { } else {
console.warn(`path '${path}' not found in '${this.lang}'`); console.warn(`path '${path}' not found in '${this.lang}'`);
return key; // Fallback return key; // Fallback
@ -38,7 +38,7 @@ export default class Replacer {
// Check the key existance // Check the key existance
const error = key.split('.').some(k => { const error = key.split('.').some(k => {
if (text.hasOwnProperty(k)) { if (text.hasOwnProperty(k)) {
text = text[k]; text = (text as LocaleObject)[k];
return false; return false;
} else { } else {
return true; return true;
@ -48,12 +48,15 @@ export default class Replacer {
if (error) { if (error) {
console.warn(`key '${key}' not found in '${path}' of '${this.lang}'`); console.warn(`key '${key}' not found in '${path}' of '${this.lang}'`);
return key; // Fallback return key; // Fallback
} else if (typeof text !== 'string') {
console.warn(`key '${key}' is not string in '${path}' of '${this.lang}'`);
return key; // Fallback
} else { } else {
return text; return text;
} }
} }
public replacement(match, key) { public replacement(match: string, key: string) {
let path = null; let path = null;
if (key.indexOf('|') != -1) { if (key.indexOf('|') != -1) {

View File

@ -1,8 +1,8 @@
import * as mongo from 'mongodb'; import * as mongo from 'mongodb';
import { Query } from 'cafy'; import { Query } from 'cafy';
export const isAnId = x => mongo.ObjectID.isValid(x); export const isAnId = (x: any) => mongo.ObjectID.isValid(x);
export const isNotAnId = x => !isAnId(x); export const isNotAnId = (x: any) => !isAnId(x);
/** /**
* ID * ID

View File

@ -1,16 +0,0 @@
export default function(note) {
if (note.text == null) return true;
let txt = note.text;
if (note.media) {
note.media.forEach(file => {
txt = txt.replace(file.url, '');
if (file.src) txt = txt.replace(file.src, '');
});
if (txt == '') return true;
}
return false;
}

View File

@ -23,7 +23,10 @@ export default async function(mios: MiOS, force = false, silent = false) {
} }
if (!silent) { if (!silent) {
alert('%i18n:common.update-available%'.replace('{newer}', newer).replace('{current}', current)); mios.apis.dialog({
title: '%i18n:common.update-available-title%',
text: '%i18n:common.update-available%'.replace('{newer}', newer).replace('{current}', current)
});
} }
return newer; return newer;

View File

@ -20,34 +20,6 @@ export default function(type, data): Notification {
icon: data.url + '?thumbnail&size=64' icon: data.url + '?thumbnail&size=64'
}; };
case 'mention':
return {
title: `${getUserName(data.user)}さんから:`,
body: getNoteSummary(data),
icon: data.user.avatarUrl + '?thumbnail&size=64'
};
case 'reply':
return {
title: `${getUserName(data.user)}さんから返信:`,
body: getNoteSummary(data),
icon: data.user.avatarUrl + '?thumbnail&size=64'
};
case 'quote':
return {
title: `${getUserName(data.user)}さんが引用:`,
body: getNoteSummary(data),
icon: data.user.avatarUrl + '?thumbnail&size=64'
};
case 'reaction':
return {
title: `${getUserName(data.user)}: ${getReactionEmoji(data.reaction)}:`,
body: getNoteSummary(data.note),
icon: data.user.avatarUrl + '?thumbnail&size=64'
};
case 'unread_messaging_message': case 'unread_messaging_message':
return { return {
title: `${getUserName(data.user)}さんからメッセージ:`, title: `${getUserName(data.user)}さんからメッセージ:`,
@ -55,13 +27,47 @@ export default function(type, data): Notification {
icon: data.user.avatarUrl + '?thumbnail&size=64' icon: data.user.avatarUrl + '?thumbnail&size=64'
}; };
case 'othello_invited': case 'reversi_invited':
return { return {
title: '対局への招待があります', title: '対局への招待があります',
body: `${getUserName(data.parent)}さんから`, body: `${getUserName(data.parent)}さんから`,
icon: data.parent.avatarUrl + '?thumbnail&size=64' icon: data.parent.avatarUrl + '?thumbnail&size=64'
}; };
case 'notification':
switch (data.type) {
case 'mention':
return {
title: `${getUserName(data.user)}さんから:`,
body: getNoteSummary(data),
icon: data.user.avatarUrl + '?thumbnail&size=64'
};
case 'reply':
return {
title: `${getUserName(data.user)}さんから返信:`,
body: getNoteSummary(data),
icon: data.user.avatarUrl + '?thumbnail&size=64'
};
case 'quote':
return {
title: `${getUserName(data.user)}さんが引用:`,
body: getNoteSummary(data),
icon: data.user.avatarUrl + '?thumbnail&size=64'
};
case 'reaction':
return {
title: `${getUserName(data.user)}: ${getReactionEmoji(data.reaction)}:`,
body: getNoteSummary(data.note),
icon: data.user.avatarUrl + '?thumbnail&size=64'
};
default:
return null;
}
default: default:
return null; return null;
} }

View File

@ -1,9 +1,9 @@
import Stream from './stream'; import Stream from './stream';
import MiOS from '../../../mios'; import MiOS from '../../../mios';
export class OthelloGameStream extends Stream { export class ReversiGameStream extends Stream {
constructor(os: MiOS, me, game) { constructor(os: MiOS, me, game) {
super(os, 'othello-game', { super(os, 'reversi-game', {
i: me ? me.token : null, i: me ? me.token : null,
game: game.id game: game.id
}); });

View File

@ -2,15 +2,15 @@ import StreamManager from './stream-manager';
import Stream from './stream'; import Stream from './stream';
import MiOS from '../../../mios'; import MiOS from '../../../mios';
export class OthelloStream extends Stream { export class ReversiStream extends Stream {
constructor(os: MiOS, me) { constructor(os: MiOS, me) {
super(os, 'othello', { super(os, 'reversi', {
i: me.token i: me.token
}); });
} }
} }
export class OthelloStreamManager extends StreamManager<OthelloStream> { export class ReversiStreamManager extends StreamManager<ReversiStream> {
private me; private me;
private os: MiOS; private os: MiOS;
@ -23,7 +23,7 @@ export class OthelloStreamManager extends StreamManager<OthelloStream> {
public getConnection() { public getConnection() {
if (this.connection == null) { if (this.connection == null) {
this.connection = new OthelloStream(this.os, this.me); this.connection = new ReversiStream(this.os, this.me);
} }
return this.connection; return this.connection;

View File

@ -1,7 +1,7 @@
<template> <template>
<div class="mk-google"> <div class="mk-google">
<input type="search" v-model="query" :placeholder="q"> <input type="search" v-model="query" :placeholder="q">
<button @click="search">検索</button> <button @click="search">%fa:search% %i18n:common.search%</button>
</div> </div>
</template> </template>

View File

@ -9,7 +9,7 @@ import forkit from './forkit.vue';
import acct from './acct.vue'; import acct from './acct.vue';
import avatar from './avatar.vue'; import avatar from './avatar.vue';
import nav from './nav.vue'; import nav from './nav.vue';
import noteHtml from './note-html'; import misskeyFlavoredMarkdown from './misskey-flavored-markdown';
import poll from './poll.vue'; import poll from './poll.vue';
import pollEditor from './poll-editor.vue'; import pollEditor from './poll-editor.vue';
import reactionIcon from './reaction-icon.vue'; import reactionIcon from './reaction-icon.vue';
@ -27,7 +27,7 @@ import urlPreview from './url-preview.vue';
import twitterSetting from './twitter-setting.vue'; import twitterSetting from './twitter-setting.vue';
import fileTypeIcon from './file-type-icon.vue'; import fileTypeIcon from './file-type-icon.vue';
import Switch from './switch.vue'; import Switch from './switch.vue';
import Othello from './othello.vue'; import Reversi from './reversi.vue';
import welcomeTimeline from './welcome-timeline.vue'; import welcomeTimeline from './welcome-timeline.vue';
import uiInput from './ui/input.vue'; import uiInput from './ui/input.vue';
import uiButton from './ui/button.vue'; import uiButton from './ui/button.vue';
@ -47,7 +47,7 @@ Vue.component('mk-forkit', forkit);
Vue.component('mk-acct', acct); Vue.component('mk-acct', acct);
Vue.component('mk-avatar', avatar); Vue.component('mk-avatar', avatar);
Vue.component('mk-nav', nav); Vue.component('mk-nav', nav);
Vue.component('mk-note-html', noteHtml); Vue.component('misskey-flavored-markdown', misskeyFlavoredMarkdown);
Vue.component('mk-poll', poll); Vue.component('mk-poll', poll);
Vue.component('mk-poll-editor', pollEditor); Vue.component('mk-poll-editor', pollEditor);
Vue.component('mk-reaction-icon', reactionIcon); Vue.component('mk-reaction-icon', reactionIcon);
@ -65,7 +65,7 @@ Vue.component('mk-url-preview', urlPreview);
Vue.component('mk-twitter-setting', twitterSetting); Vue.component('mk-twitter-setting', twitterSetting);
Vue.component('mk-file-type-icon', fileTypeIcon); Vue.component('mk-file-type-icon', fileTypeIcon);
Vue.component('mk-switch', Switch); Vue.component('mk-switch', Switch);
Vue.component('mk-othello', Othello); Vue.component('mk-reversi', Reversi);
Vue.component('mk-welcome-timeline', welcomeTimeline); Vue.component('mk-welcome-timeline', welcomeTimeline);
Vue.component('ui-input', uiInput); Vue.component('ui-input', uiInput);
Vue.component('ui-button', uiButton); Vue.component('ui-button', uiButton);

View File

@ -8,7 +8,7 @@
<img src="/assets/desktop/messaging/delete.png" alt="Delete"/> <img src="/assets/desktop/messaging/delete.png" alt="Delete"/>
</button> </button>
<div class="content" v-if="!message.isDeleted"> <div class="content" v-if="!message.isDeleted">
<mk-note-html class="text" v-if="message.text" ref="text" :text="message.text" :i="$store.state.i"/> <misskey-flavored-markdown class="text" v-if="message.text" ref="text" :text="message.text" :i="$store.state.i"/>
<div class="file" v-if="message.file"> <div class="file" v-if="message.file">
<a :href="message.file.url" target="_blank" :title="message.file.name"> <a :href="message.file.url" target="_blank" :title="message.file.name">
<img v-if="message.file.type.split('/')[0] == 'image'" :src="message.file.url" :alt="message.file.name"/> <img v-if="message.file.type.split('/')[0] == 'image'" :src="message.file.url" :alt="message.file.name"/>
@ -32,7 +32,7 @@
<script lang="ts"> <script lang="ts">
import Vue from 'vue'; import Vue from 'vue';
import parse from '../../../../../text/parse'; import parse from '../../../../../mfm/parse';
export default Vue.extend({ export default Vue.extend({
props: { props: {

View File

@ -1,6 +1,6 @@
import Vue from 'vue'; import Vue from 'vue';
import * as emojilib from 'emojilib'; import * as emojilib from 'emojilib';
import parse from '../../../../../text/parse'; import parse from '../../../../../mfm/parse';
import getAcct from '../../../../../acct/render'; import getAcct from '../../../../../acct/render';
import { url } from '../../../config'; import { url } from '../../../config';
import MkUrl from './url.vue'; import MkUrl from './url.vue';
@ -10,7 +10,7 @@ const flatten = list => list.reduce(
(a, b) => a.concat(Array.isArray(b) ? flatten(b) : b), [] (a, b) => a.concat(Array.isArray(b) ? flatten(b) : b), []
); );
export default Vue.component('mk-note-html', { export default Vue.component('misskey-flavored-markdown', {
props: { props: {
text: { text: {
type: String, type: String,

View File

@ -72,6 +72,7 @@ root(isDark)
> .is-admin > .is-admin
> .is-bot > .is-bot
> .is-cat > .is-cat
flex-shrink 0
align-self center align-self center
margin 0 .5em 0 0 margin 0 .5em 0 0
padding 1px 6px padding 1px 6px
@ -89,6 +90,7 @@ root(isDark)
overflow hidden overflow hidden
text-overflow ellipsis text-overflow ellipsis
color isDark ? #606984 : #ccc color isDark ? #606984 : #ccc
flex-shrink 2147483647
> .info > .info
margin-left auto margin-left auto

View File

@ -8,7 +8,10 @@
<img v-if="reaction == 'congrats'" src="/assets/reactions/congrats.png" alt="%i18n:common.reactions.congrats%"> <img v-if="reaction == 'congrats'" src="/assets/reactions/congrats.png" alt="%i18n:common.reactions.congrats%">
<img v-if="reaction == 'angry'" src="/assets/reactions/angry.png" alt="%i18n:common.reactions.angry%"> <img v-if="reaction == 'angry'" src="/assets/reactions/angry.png" alt="%i18n:common.reactions.angry%">
<img v-if="reaction == 'confused'" src="/assets/reactions/confused.png" alt="%i18n:common.reactions.confused%"> <img v-if="reaction == 'confused'" src="/assets/reactions/confused.png" alt="%i18n:common.reactions.confused%">
<img v-if="reaction == 'pudding'" src="/assets/reactions/pudding.png" alt="%i18n:common.reactions.pudding%"> <template v-if="reaction == 'pudding'">
<img v-if="$store.getters.isSignedIn && $store.state.settings.iLikeSushi" src="/assets/reactions/sushi.png" alt="%i18n:common.reactions.pudding%">
<img v-else src="/assets/reactions/pudding.png" alt="%i18n:common.reactions.pudding%">
</template>
</span> </span>
</template> </template>

View File

@ -3,24 +3,39 @@
<header><b>{{ blackUser.name }}</b>() vs <b>{{ whiteUser.name }}</b>()</header> <header><b>{{ blackUser.name }}</b>() vs <b>{{ whiteUser.name }}</b>()</header>
<div style="overflow: hidden"> <div style="overflow: hidden">
<p class="turn" v-if="!iAmPlayer && !game.isEnded">{{ turnUser.name }}のターンです<mk-ellipsis/></p> <p class="turn" v-if="!iAmPlayer && !game.isEnded">{{ '%i18n:common.reversi.turn-of%'.replace('{}', turnUser.name) }}<mk-ellipsis/></p>
<p class="turn" v-if="logPos != logs.length">{{ turnUser.name }}のターン</p> <p class="turn" v-if="logPos != logs.length">{{ '%i18n:common.reversi.past-turn-of%'.replace('{}', turnUser.name) }}</p>
<p class="turn1" v-if="iAmPlayer && !game.isEnded && !isMyTurn">相手のターンです<mk-ellipsis/></p> <p class="turn1" v-if="iAmPlayer && !game.isEnded && !isMyTurn">%i18n:common.reversi.opponent-turn%<mk-ellipsis/></p>
<p class="turn2" v-if="iAmPlayer && !game.isEnded && isMyTurn" v-animate-css="{ classes: 'tada', iteration: 'infinite' }">あなたのターンです</p> <p class="turn2" v-if="iAmPlayer && !game.isEnded && isMyTurn" v-animate-css="{ classes: 'tada', iteration: 'infinite' }">%i18n:common.reversi.my-turn%</p>
<p class="result" v-if="game.isEnded && logPos == logs.length"> <p class="result" v-if="game.isEnded && logPos == logs.length">
<template v-if="game.winner"><b>{{ game.winner.name }}</b>の勝ち{{ game.settings.isLlotheo ? ' (ロセオ)' : '' }}</template> <template v-if="game.winner"><b>{{ game.winner.name }}</b>の勝ち{{ game.settings.isLlotheo ? ' (ロセオ)' : '' }}</template>
<template v-else>引き分け</template> <template v-else>%i18n:common.reversi.drawn%</template>
</p> </p>
</div> </div>
<div class="board" :style="{ 'grid-template-rows': `repeat(${ game.settings.map.length }, 1fr)`, 'grid-template-columns': `repeat(${ game.settings.map[0].length }, 1fr)` }"> <div class="board">
<div v-for="(stone, i) in o.board" <div class="labels-x" v-if="this.$store.state.settings.reversiBoardLabels">
:class="{ empty: stone == null, none: o.map[i] == 'null', isEnded: game.isEnded, myTurn: !game.isEnded && isMyTurn, can: turnUser ? o.canPut(turnUser.id == blackUser.id, i) : null, prev: o.prevPos == i }" <span v-for="i in game.settings.map[0].length">{{ String.fromCharCode(64 + i) }}</span>
@click="set(i)" </div>
:title="'[' + (o.transformPosToXy(i)[0] + 1) + ', ' + (o.transformPosToXy(i)[1] + 1) + '] (' + i + ')'" <div class="flex">
> <div class="labels-y" v-if="this.$store.state.settings.reversiBoardLabels">
<img v-if="stone === true" :src="`${blackUser.avatarUrl}?thumbnail&size=128`" alt=""> <div v-for="i in game.settings.map.length">{{ i }}</div>
<img v-if="stone === false" :src="`${whiteUser.avatarUrl}?thumbnail&size=128`" alt=""> </div>
<div class="cells" :style="cellsStyle">
<div v-for="(stone, i) in o.board"
:class="{ empty: stone == null, none: o.map[i] == 'null', isEnded: game.isEnded, myTurn: !game.isEnded && isMyTurn, can: turnUser ? o.canPut(turnUser.id == blackUser.id, i) : null, prev: o.prevPos == i }"
@click="set(i)"
:title="`${String.fromCharCode(65 + o.transformPosToXy(i)[0])}${o.transformPosToXy(i)[1] + 1}`">
<img v-if="stone === true" :src="`${blackUser.avatarUrl}?thumbnail&size=128`" alt="">
<img v-if="stone === false" :src="`${whiteUser.avatarUrl}?thumbnail&size=128`" alt="">
</div>
</div>
<div class="labels-y" v-if="this.$store.state.settings.reversiBoardLabels">
<div v-for="i in game.settings.map.length">{{ i }}</div>
</div>
</div>
<div class="labels-x" v-if="this.$store.state.settings.reversiBoardLabels">
<span v-for="i in game.settings.map[0].length">{{ String.fromCharCode(64 + i) }}</span>
</div> </div>
</div> </div>
@ -43,7 +58,7 @@
<script lang="ts"> <script lang="ts">
import Vue from 'vue'; import Vue from 'vue';
import * as CRC32 from 'crc-32'; import * as CRC32 from 'crc-32';
import Othello, { Color } from '../../../../../othello/core'; import Reversi, { Color } from '../../../../../reversi/core';
import { url } from '../../../config'; import { url } from '../../../config';
export default Vue.extend({ export default Vue.extend({
@ -52,7 +67,7 @@ export default Vue.extend({
data() { data() {
return { return {
game: null, game: null,
o: null as Othello, o: null as Reversi,
logs: [], logs: [],
logPos: 0, logPos: 0,
pollingClock: null pollingClock: null
@ -92,13 +107,19 @@ export default Vue.extend({
isMyTurn(): boolean { isMyTurn(): boolean {
if (this.turnUser == null) return null; if (this.turnUser == null) return null;
return this.turnUser.id == this.$store.state.i.id; return this.turnUser.id == this.$store.state.i.id;
},
cellsStyle(): any {
return {
'grid-template-rows': `repeat(${ this.game.settings.map.length }, 1fr)`,
'grid-template-columns': `repeat(${ this.game.settings.map[0].length }, 1fr)`
};
} }
}, },
watch: { watch: {
logPos(v) { logPos(v) {
if (!this.game.isEnded) return; if (!this.game.isEnded) return;
this.o = new Othello(this.game.settings.map, { this.o = new Reversi(this.game.settings.map, {
isLlotheo: this.game.settings.isLlotheo, isLlotheo: this.game.settings.isLlotheo,
canPutEverywhere: this.game.settings.canPutEverywhere, canPutEverywhere: this.game.settings.canPutEverywhere,
loopedBoard: this.game.settings.loopedBoard loopedBoard: this.game.settings.loopedBoard
@ -115,7 +136,7 @@ export default Vue.extend({
created() { created() {
this.game = this.initGame; this.game = this.initGame;
this.o = new Othello(this.game.settings.map, { this.o = new Reversi(this.game.settings.map, {
isLlotheo: this.game.settings.isLlotheo, isLlotheo: this.game.settings.isLlotheo,
canPutEverywhere: this.game.settings.canPutEverywhere, canPutEverywhere: this.game.settings.canPutEverywhere,
loopedBoard: this.game.settings.loopedBoard loopedBoard: this.game.settings.loopedBoard
@ -163,7 +184,7 @@ export default Vue.extend({
// //
if (this.$store.state.device.enableSounds) { if (this.$store.state.device.enableSounds) {
const sound = new Audio(`${url}/assets/othello-put-me.mp3`); const sound = new Audio(`${url}/assets/reversi-put-me.mp3`);
sound.volume = this.$store.state.device.soundVolume; sound.volume = this.$store.state.device.soundVolume;
sound.play(); sound.play();
} }
@ -187,7 +208,7 @@ export default Vue.extend({
// //
if (this.$store.state.device.enableSounds && x.color != this.myColor) { if (this.$store.state.device.enableSounds && x.color != this.myColor) {
const sound = new Audio(`${url}/assets/othello-put-you.mp3`); const sound = new Audio(`${url}/assets/reversi-put-you.mp3`);
sound.volume = this.$store.state.device.soundVolume; sound.volume = this.$store.state.device.soundVolume;
sound.play(); sound.play();
} }
@ -213,7 +234,7 @@ export default Vue.extend({
onRescue(game) { onRescue(game) {
this.game = game; this.game = game;
this.o = new Othello(this.game.settings.map, { this.o = new Reversi(this.game.settings.map, {
isLlotheo: this.game.settings.isLlotheo, isLlotheo: this.game.settings.isLlotheo,
canPutEverywhere: this.game.settings.canPutEverywhere, canPutEverywhere: this.game.settings.canPutEverywhere,
loopedBoard: this.game.settings.loopedBoard loopedBoard: this.game.settings.loopedBoard
@ -244,54 +265,99 @@ export default Vue.extend({
border-bottom dashed 1px #c4cdd4 border-bottom dashed 1px #c4cdd4
> .board > .board
display grid
grid-gap 4px
width 350px width 350px
height 350px height 350px
margin 0 auto margin 0 auto
> div $label-size = 16px
background transparent $gap = 4px
border-radius 6px
overflow hidden
* > .labels-x
pointer-events none height $label-size
user-select none padding 0 $label-size
display flex
&.empty > *
border solid 2px #eee flex 1
display flex
align-items center
justify-content center
font-size 12px
&.empty.can &:first-child
background #eee margin-left -($gap / 2)
&.empty.myTurn &:last-child
border-color #ddd margin-right -($gap / 2)
&.can > .flex
background #eee display flex
cursor pointer
&:hover > .labels-y
border-color darken($theme-color, 10%) width $label-size
background $theme-color display flex
flex-direction column
&:active > *
background darken($theme-color, 10%) flex 1
display flex
align-items center
justify-content center
font-size 12px
&.prev &:first-child
box-shadow 0 0 0 4px rgba($theme-color, 0.7) margin-top -($gap / 2)
&.isEnded &:last-child
border-color #ddd margin-bottom -($gap / 2)
&.none > .cells
border-color transparent !important flex 1
display grid
grid-gap $gap
> img > div
display block background transparent
width 100% border-radius 6px
height 100% overflow hidden
*
pointer-events none
user-select none
&.empty
border solid 2px #eee
&.empty.can
background #eee
&.empty.myTurn
border-color #ddd
&.can
background #eee
cursor pointer
&:hover
border-color darken($theme-color, 10%)
background $theme-color
&:active
background darken($theme-color, 10%)
&.prev
box-shadow 0 0 0 4px rgba($theme-color, 0.7)
&.isEnded
border-color #ddd
&.none
border-color transparent !important
> img
display block
width 100%
height 100%
> .graph > .graph
display grid display grid

View File

@ -7,9 +7,9 @@
<script lang="ts"> <script lang="ts">
import Vue from 'vue'; import Vue from 'vue';
import XGame from './othello.game.vue'; import XGame from './reversi.game.vue';
import XRoom from './othello.room.vue'; import XRoom from './reversi.room.vue';
import { OthelloGameStream } from '../../scripts/streaming/othello-game'; import { ReversiGameStream } from '../../scripts/streaming/reversi-game';
export default Vue.extend({ export default Vue.extend({
components: { components: {
@ -25,7 +25,7 @@ export default Vue.extend({
}, },
created() { created() {
this.g = this.game; this.g = this.game;
this.connection = new OthelloGameStream((this as any).os, this.$store.state.i, this.game); this.connection = new ReversiGameStream((this as any).os, this.$store.state.i, this.game);
this.connection.on('started', this.onStarted); this.connection.on('started', this.onStarted);
}, },
beforeDestroy() { beforeDestroy() {

View File

@ -94,7 +94,7 @@
<script lang="ts"> <script lang="ts">
import Vue from 'vue'; import Vue from 'vue';
import * as maps from '../../../../../othello/maps'; import * as maps from '../../../../../reversi/maps';
export default Vue.extend({ export default Vue.extend({
props: ['game', 'connection'], props: ['game', 'connection'],

View File

@ -1,5 +1,5 @@
<template> <template>
<div class="mk-othello"> <div class="mk-reversi">
<div v-if="game"> <div v-if="game">
<x-gameroom :game="game"/> <x-gameroom :game="game"/>
</div> </div>
@ -10,15 +10,15 @@
</div> </div>
</div> </div>
<div class="index" v-else> <div class="index" v-else>
<h1>Misskey %fa:circle%thell%fa:circle R%</h1> <h1>Misskey Reversi</h1>
<p>他のMisskeyユーザーとオセロで対戦しよう</p> <p>他のMisskeyユーザーとリバーシで対戦しよう</p>
<div class="play"> <div class="play">
<el-button round>フリーマッチ(準備中)</el-button> <el-button round>フリーマッチ(準備中)</el-button>
<el-button type="primary" round @click="match">指名</el-button> <el-button type="primary" round @click="match">指名</el-button>
<details> <details>
<summary>遊び方</summary> <summary>遊び方</summary>
<div> <div>
<p>オセロ相手と交互に石をボードに置いてゆき相手の石を挟んでひっくり返しながら最終的に残った石が多い方が勝ちというボードゲームです</p> <p>リバーシ相手と交互に石をボードに置いてゆき相手の石を挟んでひっくり返しながら最終的に残った石が多い方が勝ちというボードゲームです</p>
<dl> <dl>
<dt><b>フリーマッチ</b></dt> <dt><b>フリーマッチ</b></dt>
<dd>ランダムなユーザーと対戦するモードです</dd> <dd>ランダムなユーザーと対戦するモードです</dd>
@ -39,7 +39,7 @@
</section> </section>
<section v-if="myGames.length > 0"> <section v-if="myGames.length > 0">
<h2>自分の対局</h2> <h2>自分の対局</h2>
<a class="game" v-for="g in myGames" tabindex="-1" @click.prevent="go(g)" :href="`/othello/${g.id}`"> <a class="game" v-for="g in myGames" tabindex="-1" @click.prevent="go(g)" :href="`/reversi/${g.id}`">
<mk-avatar class="avatar" :user="g.user1"/> <mk-avatar class="avatar" :user="g.user1"/>
<mk-avatar class="avatar" :user="g.user2"/> <mk-avatar class="avatar" :user="g.user2"/>
<span><b>{{ g.user1.name }}</b> vs <b>{{ g.user2.name }}</b></span> <span><b>{{ g.user1.name }}</b> vs <b>{{ g.user2.name }}</b></span>
@ -48,7 +48,7 @@
</section> </section>
<section v-if="games.length > 0"> <section v-if="games.length > 0">
<h2>みんなの対局</h2> <h2>みんなの対局</h2>
<a class="game" v-for="g in games" tabindex="-1" @click.prevent="go(g)" :href="`/othello/${g.id}`"> <a class="game" v-for="g in games" tabindex="-1" @click.prevent="go(g)" :href="`/reversi/${g.id}`">
<mk-avatar class="avatar" :user="g.user1"/> <mk-avatar class="avatar" :user="g.user1"/>
<mk-avatar class="avatar" :user="g.user2"/> <mk-avatar class="avatar" :user="g.user2"/>
<span><b>{{ g.user1.name }}</b> vs <b>{{ g.user2.name }}</b></span> <span><b>{{ g.user1.name }}</b> vs <b>{{ g.user2.name }}</b></span>
@ -61,7 +61,7 @@
<script lang="ts"> <script lang="ts">
import Vue from 'vue'; import Vue from 'vue';
import XGameroom from './othello.gameroom.vue'; import XGameroom from './reversi.gameroom.vue';
export default Vue.extend({ export default Vue.extend({
components: { components: {
@ -93,24 +93,24 @@ export default Vue.extend({
} }
}, },
mounted() { mounted() {
this.connection = (this as any).os.streams.othelloStream.getConnection(); this.connection = (this as any).os.streams.reversiStream.getConnection();
this.connectionId = (this as any).os.streams.othelloStream.use(); this.connectionId = (this as any).os.streams.reversiStream.use();
this.connection.on('matched', this.onMatched); this.connection.on('matched', this.onMatched);
this.connection.on('invited', this.onInvited); this.connection.on('invited', this.onInvited);
(this as any).api('othello/games', { (this as any).api('reversi/games', {
my: true my: true
}).then(games => { }).then(games => {
this.myGames = games; this.myGames = games;
}); });
(this as any).api('othello/games').then(games => { (this as any).api('reversi/games').then(games => {
this.games = games; this.games = games;
this.gamesFetching = false; this.gamesFetching = false;
}); });
(this as any).api('othello/invitations').then(invitations => { (this as any).api('reversi/invitations').then(invitations => {
this.invitations = this.invitations.concat(invitations); this.invitations = this.invitations.concat(invitations);
}); });
@ -126,13 +126,13 @@ export default Vue.extend({
beforeDestroy() { beforeDestroy() {
this.connection.off('matched', this.onMatched); this.connection.off('matched', this.onMatched);
this.connection.off('invited', this.onInvited); this.connection.off('invited', this.onInvited);
(this as any).os.streams.othelloStream.dispose(this.connectionId); (this as any).os.streams.reversiStream.dispose(this.connectionId);
clearInterval(this.pingClock); clearInterval(this.pingClock);
}, },
methods: { methods: {
go(game) { go(game) {
(this as any).api('othello/games/show', { (this as any).api('reversi/games/show', {
gameId: game.id gameId: game.id
}).then(game => { }).then(game => {
this.matching = null; this.matching = null;
@ -146,7 +146,7 @@ export default Vue.extend({
(this as any).api('users/show', { (this as any).api('users/show', {
username username
}).then(user => { }).then(user => {
(this as any).api('othello/match', { (this as any).api('reversi/match', {
userId: user.id userId: user.id
}).then(res => { }).then(res => {
if (res == null) { if (res == null) {
@ -160,10 +160,10 @@ export default Vue.extend({
}, },
cancel() { cancel() {
this.matching = null; this.matching = null;
(this as any).api('othello/match/cancel'); (this as any).api('reversi/match/cancel');
}, },
accept(invitation) { accept(invitation) {
(this as any).api('othello/match', { (this as any).api('reversi/match', {
userId: invitation.parent.id userId: invitation.parent.id
}).then(game => { }).then(game => {
if (game) { if (game) {
@ -186,7 +186,7 @@ export default Vue.extend({
<style lang="stylus" scoped> <style lang="stylus" scoped>
@import '~const.styl' @import '~const.styl'
.mk-othello .mk-reversi
color #677f84 color #677f84
background #fff background #fff

View File

@ -289,6 +289,10 @@ root(isDark, fill)
> * > *
display block display block
min-width 16px min-width 16px
max-width 150px
overflow hidden
white-space nowrap
text-overflow ellipsis
> .prefix > .prefix
left 0 left 0

View File

@ -13,7 +13,7 @@
</div> </div>
</header> </header>
<div class="text"> <div class="text">
<mk-note-html v-if="note.text" :text="note.text"/> <misskey-flavored-markdown v-if="note.text" :text="note.text"/>
</div> </div>
</div> </div>
</div> </div>
@ -24,6 +24,13 @@
import Vue from 'vue'; import Vue from 'vue';
export default Vue.extend({ export default Vue.extend({
props: {
max: {
type: Number,
required: false,
default: undefined
}
},
data() { data() {
return { return {
fetching: true, fetching: true,
@ -37,6 +44,7 @@ export default Vue.extend({
fetch(cb?) { fetch(cb?) {
this.fetching = true; this.fetching = true;
(this as any).api('notes', { (this as any).api('notes', {
limit: this.max,
local: true, local: true,
reply: false, reply: false,
renote: false, renote: false,

View File

@ -0,0 +1,215 @@
<template>
<div class="syxhndwprovvuqhmyvveewmbqayniwkv" v-if="!fetching" :data-darkmode="$store.state.device.darkmode">
<div class="signed-in-as" v-html="'%i18n:@signed-in-as%'.replace('{}', '<b>' + myName + '</b>')"></div>
<main>
<div class="banner" :style="bannerStyle"></div>
<mk-avatar class="avatar" :user="user" :disable-preview="true"/>
<div class="body">
<router-link :to="user | userPage" class="name">{{ user | userName }}</router-link>
<span class="username">@{{ user | acct }}</span>
<div class="description">
<misskey-flavored-markdown v-if="user.description" :text="user.description" :i="$store.state.i"/>
</div>
</div>
</main>
<button
:class="{ wait: followWait, active: user.isFollowing || user.hasPendingFollowRequestFromYou }"
@click="onClick"
:disabled="followWait">
<template v-if="!followWait">
<template v-if="user.hasPendingFollowRequestFromYou">%fa:hourglass-half% %i18n:@request-pending%</template>
<template v-else-if="user.isFollowing">%fa:minus% %i18n:@following%</template>
<template v-else-if="!user.isFollowing && user.isLocked">%fa:plus% %i18n:@follow-request%</template>
<template v-else-if="!user.isFollowing && !user.isLocked">%fa:plus% %i18n:@follow%</template>
</template>
<template v-else>%fa:spinner .pulse .fw%</template>
</button>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import parseAcct from '../../../../../acct/parse';
import getUserName from '../../../../../renderers/get-user-name';
import Progress from '../../../common/scripts/loading';
export default Vue.extend({
data() {
return {
fetching: true,
user: null,
followWait: false
};
},
computed: {
myName(): string {
return Vue.filter('userName')(this.$store.state.i);
},
bannerStyle(): any {
if (this.user.bannerUrl == null) return {};
return {
backgroundColor: this.user.bannerColor && this.user.bannerColor.length == 3 ? `rgb(${ this.user.bannerColor.join(',') })` : null,
backgroundImage: `url(${ this.user.bannerUrl })`
};
}
},
created() {
this.fetch();
},
methods: {
fetch() {
const acct = new URL(location.href).searchParams.get('acct');
this.fetching = true;
Progress.start();
(this as any).api('users/show', parseAcct(acct)).then(user => {
this.user = user;
this.fetching = false;
Progress.done();
document.title = getUserName(this.user) + ' | Misskey';
});
},
async onClick() {
this.followWait = true;
try {
if (this.user.isFollowing) {
this.user = await (this as any).api('following/delete', {
userId: this.user.id
});
} else {
if (this.user.isLocked && this.user.hasPendingFollowRequestFromYou) {
this.user = await (this as any).api('following/requests/cancel', {
userId: this.user.id
});
} else if (this.user.isLocked) {
this.user = await (this as any).api('following/create', {
userId: this.user.id
});
} else {
this.user = await (this as any).api('following/create', {
userId: this.user.id
});
}
}
} catch (e) {
console.error(e);
} finally {
this.followWait = false;
}
}
}
});
</script>
<style lang="stylus" scoped>
@import '~const.styl'
root(isDark)
padding 32px
max-width 500px
margin 0 auto
text-align center
color isDark ? #9baec8 : #868c8c
$bg = isDark ? #282C37 : #fff
@media (max-width 400px)
padding 16px
> .signed-in-as
margin-bottom 16px
font-size 14px
color isDark ? #9baec8 : #9daab3
> main
margin-bottom 16px
background $bg
border-radius 8px
box-shadow 0 4px 12px rgba(#000, 0.1)
overflow hidden
> .banner
height 128px
background-position center
background-size cover
> .avatar
display block
margin -50px auto 0 auto
width 100px
height 100px
border-radius 100%
border solid 4px $bg
> .body
padding 4px 32px 32px 32px
@media (max-width 400px)
padding 4px 16px 16px 16px
> .name
font-size 20px
font-weight bold
> .username
display block
opacity 0.7
> .description
margin-top 16px
> button
display block
user-select none
cursor pointer
padding 10px 16px
margin 0
width 100%
min-width 150px
font-size 14px
font-weight bold
color $theme-color
background transparent
outline none
border solid 1px $theme-color
border-radius 36px
&:hover
background rgba($theme-color, 0.1)
&:active
background rgba($theme-color, 0.2)
&.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
*
pointer-events none
.syxhndwprovvuqhmyvveewmbqayniwkv[data-darkmode]
root(true)
.syxhndwprovvuqhmyvveewmbqayniwkv:not([data-darkmode])
root(false)
</style>

View File

@ -6,7 +6,9 @@
<div class="mkw-hashtags--body" :data-mobile="platform == 'mobile'"> <div class="mkw-hashtags--body" :data-mobile="platform == 'mobile'">
<p class="fetching" v-if="fetching">%fa:spinner .pulse .fw%%i18n:common.loading%<mk-ellipsis/></p> <p class="fetching" v-if="fetching">%fa:spinner .pulse .fw%%i18n:common.loading%<mk-ellipsis/></p>
<p class="empty" v-else-if="stats.length == 0">%fa:exclamation-circle%%i18n:@empty%</p> <p class="empty" v-else-if="stats.length == 0">%fa:exclamation-circle%%i18n:@empty%</p>
<transition-group v-else tag="div" name="chart"> <!-- トランジションを有効にするとなぜかメモリリークする -->
<!-- <transition-group v-else tag="div" name="chart"> -->
<div>
<div v-for="stat in stats" :key="stat.tag"> <div v-for="stat in stats" :key="stat.tag">
<div class="tag"> <div class="tag">
<router-link :to="`/tags/${ stat.tag }`" :title="stat.tag">#{{ stat.tag }}</router-link> <router-link :to="`/tags/${ stat.tag }`" :title="stat.tag">#{{ stat.tag }}</router-link>
@ -14,7 +16,8 @@
</div> </div>
<x-chart class="chart" :src="stat.chart"/> <x-chart class="chart" :src="stat.chart"/>
</div> </div>
</transition-group> </div>
<!-- </transition-group> -->
</div> </div>
</mk-widget-container> </mk-widget-container>
</div> </div>

View File

@ -21,7 +21,7 @@ export default (os: OS) => opts => {
res(file); res(file);
}; };
window.open(url + '/selectdrive', window.open(url + `/selectdrive?multiple=${o.multiple}`,
'choose_drive_window', 'choose_drive_window',
'height=500, width=800'); 'height=500, width=800');
} }

View File

@ -34,7 +34,9 @@ import MkMessagingRoom from './views/pages/messaging-room.vue';
import MkNote from './views/pages/note.vue'; import MkNote from './views/pages/note.vue';
import MkSearch from './views/pages/search.vue'; import MkSearch from './views/pages/search.vue';
import MkTag from './views/pages/tag.vue'; import MkTag from './views/pages/tag.vue';
import MkOthello from './views/pages/othello.vue'; import MkReversi from './views/pages/reversi.vue';
import MkShare from './views/pages/share.vue';
import MkFollow from '../common/views/pages/follow.vue';
/** /**
* init * init
@ -62,10 +64,12 @@ init(async (launch) => {
{ path: '/selectdrive', component: MkSelectDrive }, { path: '/selectdrive', component: MkSelectDrive },
{ path: '/search', component: MkSearch }, { path: '/search', component: MkSearch },
{ path: '/tags/:tag', component: MkTag }, { path: '/tags/:tag', component: MkTag },
{ path: '/othello', component: MkOthello }, { path: '/share', component: MkShare },
{ path: '/othello/:game', component: MkOthello }, { path: '/reversi', component: MkReversi },
{ path: '/reversi/:game', component: MkReversi },
{ path: '/@:user', component: MkUser }, { path: '/@:user', component: MkUser },
{ path: '/notes/:note', component: MkNote } { path: '/notes/:note', component: MkNote },
{ path: '/authorize-follow', component: MkFollow }
] ]
}); });
@ -113,6 +117,15 @@ function registerNotifications(stream: HomeStreamManager) {
}); });
function attach(connection) { function attach(connection) {
connection.on('notification', notification => {
const _n = composeNotification('notification', notification);
const n = new Notification(_n.title, {
body: _n.body,
icon: _n.icon
});
setTimeout(n.close.bind(n), 6000);
});
connection.on('drive_file_created', file => { connection.on('drive_file_created', file => {
const _n = composeNotification('drive_file_created', file); const _n = composeNotification('drive_file_created', file);
const n = new Notification(_n.title, { const n = new Notification(_n.title, {
@ -122,33 +135,6 @@ function registerNotifications(stream: HomeStreamManager) {
setTimeout(n.close.bind(n), 5000); setTimeout(n.close.bind(n), 5000);
}); });
connection.on('mention', note => {
const _n = composeNotification('mention', note);
const n = new Notification(_n.title, {
body: _n.body,
icon: _n.icon
});
setTimeout(n.close.bind(n), 6000);
});
connection.on('reply', note => {
const _n = composeNotification('reply', note);
const n = new Notification(_n.title, {
body: _n.body,
icon: _n.icon
});
setTimeout(n.close.bind(n), 6000);
});
connection.on('quote', note => {
const _n = composeNotification('quote', note);
const n = new Notification(_n.title, {
body: _n.body,
icon: _n.icon
});
setTimeout(n.close.bind(n), 6000);
});
connection.on('unread_messaging_message', message => { connection.on('unread_messaging_message', message => {
const _n = composeNotification('unread_messaging_message', message); const _n = composeNotification('unread_messaging_message', message);
const n = new Notification(_n.title, { const n = new Notification(_n.title, {
@ -164,8 +150,8 @@ function registerNotifications(stream: HomeStreamManager) {
setTimeout(n.close.bind(n), 7000); setTimeout(n.close.bind(n), 7000);
}); });
connection.on('othello_invited', matching => { connection.on('reversi_invited', matching => {
const _n = composeNotification('othello_invited', matching); const _n = composeNotification('reversi_invited', matching);
const n = new Notification(_n.title, { const n = new Notification(_n.title, {
body: _n.body, body: _n.body,
icon: _n.icon icon: _n.icon

View File

@ -1,7 +1,7 @@
<template> <template>
<mk-window ref="window" width="500px" height="560px" :popout-url="popout" @closed="$destroy"> <mk-window ref="window" width="500px" height="560px" :popout-url="popout" @closed="$destroy">
<span slot="header" :class="$style.header">%fa:gamepad%%i18n:@game%</span> <span slot="header" :class="$style.header">%fa:gamepad%%i18n:@game%</span>
<mk-othello :class="$style.content" @gamed="g => game = g"/> <mk-reversi :class="$style.content" @gamed="g => game = g"/>
</mk-window> </mk-window>
</template> </template>
@ -18,8 +18,8 @@ export default Vue.extend({
computed: { computed: {
popout(): string { popout(): string {
return this.game return this.game
? `${url}/othello/${this.game.id}` ? `${url}/reversi/${this.game.id}`
: `${url}/othello`; : `${url}/reversi`;
} }
} }
}); });

View File

@ -66,7 +66,7 @@
</div> </div>
<div class="main"> <div class="main">
<mk-post-form class="form" v-if="$store.state.settings.showPostFormOnTopOfTl"/> <mk-post-form class="form" v-if="$store.state.settings.showPostFormOnTopOfTl"/>
<mk-timeline class="tl" cref="tl" @loaded="onTlLoaded" v-if="mode == 'timeline'"/> <mk-timeline class="tl" ref="tl" @loaded="onTlLoaded" v-if="mode == 'timeline'"/>
</div> </div>
</template> </template>
</div> </div>
@ -84,7 +84,7 @@ const defaultDesktopHomeWidgets = {
'calendar', 'calendar',
'activity', 'activity',
'rss', 'rss',
'trends', 'hashtags',
'photo-stream', 'photo-stream',
'version' 'version'
], ],

View File

@ -40,7 +40,7 @@
<div class="text"> <div class="text">
<span v-if="p.isHidden" style="opacity: 0.5">%i18n:@private%</span> <span v-if="p.isHidden" style="opacity: 0.5">%i18n:@private%</span>
<span v-if="p.deletedAt" style="opacity: 0.5">%i18n:@deleted%</span> <span v-if="p.deletedAt" style="opacity: 0.5">%i18n:@deleted%</span>
<mk-note-html v-if="p.text" :text="p.text" :i="$store.state.i"/> <misskey-flavored-markdown v-if="p.text" :text="p.text" :i="$store.state.i"/>
</div> </div>
<div class="media" v-if="p.media.length > 0"> <div class="media" v-if="p.media.length > 0">
<mk-media-list :media-list="p.media" :raw="true"/> <mk-media-list :media-list="p.media" :raw="true"/>
@ -83,7 +83,7 @@
<script lang="ts"> <script lang="ts">
import Vue from 'vue'; import Vue from 'vue';
import dateStringify from '../../../common/scripts/date-stringify'; import dateStringify from '../../../common/scripts/date-stringify';
import parse from '../../../../../text/parse'; import parse from '../../../../../mfm/parse';
import MkPostFormWindow from './post-form-window.vue'; import MkPostFormWindow from './post-form-window.vue';
import MkRenoteFormWindow from './renote-form-window.vue'; import MkRenoteFormWindow from './renote-form-window.vue';

View File

@ -25,7 +25,7 @@
<span v-if="p.isHidden" style="opacity: 0.5">%i18n:@private%</span> <span v-if="p.isHidden" style="opacity: 0.5">%i18n:@private%</span>
<span v-if="p.deletedAt" style="opacity: 0.5">%i18n:@deleted%</span> <span v-if="p.deletedAt" style="opacity: 0.5">%i18n:@deleted%</span>
<a class="reply" v-if="p.reply">%fa:reply%</a> <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" :class="$style.text"/> <misskey-flavored-markdown v-if="p.text" :text="p.text" :i="$store.state.i" :class="$style.text"/>
<a class="rp" v-if="p.renote">RP:</a> <a class="rp" v-if="p.renote">RP:</a>
</div> </div>
<div class="media" v-if="p.media.length > 0"> <div class="media" v-if="p.media.length > 0">
@ -75,8 +75,7 @@
<script lang="ts"> <script lang="ts">
import Vue from 'vue'; import Vue from 'vue';
import dateStringify from '../../../common/scripts/date-stringify'; import dateStringify from '../../../common/scripts/date-stringify';
import canHideText from '../../../common/scripts/can-hide-text'; import parse from '../../../../../mfm/parse';
import parse from '../../../../../text/parse';
import MkPostFormWindow from './post-form-window.vue'; import MkPostFormWindow from './post-form-window.vue';
import MkRenoteFormWindow from './renote-form-window.vue'; import MkRenoteFormWindow from './renote-form-window.vue';
@ -190,8 +189,6 @@ export default Vue.extend({
}, },
methods: { methods: {
canHideText,
capture(withHandler = false) { capture(withHandler = false) {
if (this.$store.getters.isSignedIn) { if (this.$store.getters.isSignedIn) {
this.connection.send({ this.connection.send({
@ -473,10 +470,10 @@ root(isDark)
> * > *
display inline-block display inline-block
margin 0 8px 0 0 margin 0 0 4px 6px
padding 2px 8px 2px 16px padding 2px 8px 2px 16px
font-size 90% font-size 90%
color #8d969e color $theme-color
background isDark ? #313543 : #edf0f3 background isDark ? #313543 : #edf0f3
border-radius 4px border-radius 4px

View File

@ -9,7 +9,9 @@
<button @click="resolveInitPromise">%i18n:@retry%</button> <button @click="resolveInitPromise">%i18n:@retry%</button>
</div> </div>
<transition-group name="mk-notes" class="transition"> <!-- トランジションを有効にするとなぜかメモリリークする -->
<!--<transition-group name="mk-notes" class="transition">-->
<div class="notes">
<template v-for="(note, i) in _notes"> <template v-for="(note, i) in _notes">
<x-note :note="note" :key="note.id" @update:note="onNoteUpdated(i, $event)"/> <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"> <p class="date" :key="note.id + '_date'" v-if="i != notes.length - 1 && note._date != _notes[i + 1]._date">
@ -17,7 +19,8 @@
<span>%fa:angle-down%{{ _notes[i + 1]._datetext }}</span> <span>%fa:angle-down%{{ _notes[i + 1]._datetext }}</span>
</p> </p>
</template> </template>
</transition-group> </div>
<!--</transition-group>-->
<footer v-if="more"> <footer v-if="more">
<button @click="loadMore" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }"> <button @click="loadMore" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }">
@ -221,6 +224,7 @@ root(isDark)
> * > *
transition transform .3s ease, opacity .3s ease transition transform .3s ease, opacity .3s ease
> .notes
> .date > .date
display block display block
margin 0 margin 0

View File

@ -1,7 +1,9 @@
<template> <template>
<div class="mk-notifications"> <div class="mk-notifications">
<div class="notifications" v-if="notifications.length != 0"> <div class="notifications" v-if="notifications.length != 0">
<transition-group name="mk-notifications" class="transition"> <!-- トランジションを有効にするとなぜかメモリリークする -->
<!-- <transition-group name="mk-notifications" class="transition"> -->
<div>
<template v-for="(notification, i) in _notifications"> <template v-for="(notification, i) in _notifications">
<div class="notification" :class="notification.type" :key="notification.id"> <div class="notification" :class="notification.type" :key="notification.id">
<mk-time :time="notification.createdAt"/> <mk-time :time="notification.createdAt"/>
@ -95,7 +97,8 @@
<span>%fa:angle-down%{{ _notifications[i + 1]._datetext }}</span> <span>%fa:angle-down%{{ _notifications[i + 1]._datetext }}</span>
</p> </p>
</template> </template>
</transition-group> </div>
<!-- </transition-group> -->
</div> </div>
<button class="more" :class="{ fetching: fetchingMoreNotifications }" v-if="moreNotifications" @click="fetchMoreNotifications" :disabled="fetchingMoreNotifications"> <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%' }} <template v-if="fetchingMoreNotifications">%fa:spinner .pulse .fw%</template>{{ fetchingMoreNotifications ? '%i18n:common.loading%' : '%i18n:@more%' }}
@ -201,7 +204,7 @@ root(isDark)
transition transform .3s ease, opacity .3s ease transition transform .3s ease, opacity .3s ease
> .notifications > .notifications
> * > div
> .notification > .notification
margin 0 margin 0
padding 16px padding 16px

View File

@ -49,7 +49,7 @@ import Vue from 'vue';
import * as XDraggable from 'vuedraggable'; import * as XDraggable from 'vuedraggable';
import getKao from '../../../common/scripts/get-kao'; import getKao from '../../../common/scripts/get-kao';
import MkVisibilityChooser from '../../../common/views/components/visibility-chooser.vue'; import MkVisibilityChooser from '../../../common/views/components/visibility-chooser.vue';
import parse from '../../../../../text/parse'; import parse from '../../../../../mfm/parse';
import { host } from '../../../config'; import { host } from '../../../config';
export default Vue.extend({ export default Vue.extend({
@ -58,7 +58,25 @@ export default Vue.extend({
MkVisibilityChooser MkVisibilityChooser
}, },
props: ['reply', 'renote'], props: {
reply: {
type: Object,
required: false
},
renote: {
type: Object,
required: false
},
initialText: {
type: String,
required: false
},
instant: {
type: Boolean,
required: false,
default: false
}
},
data() { data() {
return { return {
@ -118,6 +136,10 @@ export default Vue.extend({
}, },
mounted() { mounted() {
if (this.initialText) {
this.text = this.initialText;
}
if (this.reply && this.reply.user.host != null) { if (this.reply && this.reply.user.host != null) {
this.text = `@${this.reply.user.username}@${this.reply.user.host} `; this.text = `@${this.reply.user.username}@${this.reply.user.host} `;
} }
@ -141,17 +163,19 @@ export default Vue.extend({
this.$nextTick(() => { this.$nextTick(() => {
// 書きかけの投稿を復元 // 書きかけの投稿を復元
const draft = JSON.parse(localStorage.getItem('drafts') || '{}')[this.draftId]; if (!this.instant) {
if (draft) { const draft = JSON.parse(localStorage.getItem('drafts') || '{}')[this.draftId];
this.text = draft.data.text; if (draft) {
this.files = draft.data.files; this.text = draft.data.text;
if (draft.data.poll) { this.files = draft.data.files;
this.poll = true; if (draft.data.poll) {
this.$nextTick(() => { this.poll = true;
(this.$refs.poll as any).set(draft.data.poll); this.$nextTick(() => {
}); (this.$refs.poll as any).set(draft.data.poll);
});
}
this.$emit('change-attached-media', this.files);
} }
this.$emit('change-attached-media', this.files);
} }
this.$nextTick(() => this.watch()); this.$nextTick(() => this.watch());
@ -349,6 +373,8 @@ export default Vue.extend({
}, },
saveDraft() { saveDraft() {
if (this.instant) return;
const data = JSON.parse(localStorage.getItem('drafts') || '{}'); const data = JSON.parse(localStorage.getItem('drafts') || '{}');
data[this.draftId] = { data[this.draftId] = {

View File

@ -45,6 +45,7 @@
<mk-switch v-model="darkmode" text="%i18n:@dark-mode%"/> <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.circleIcons" @change="onChangeCircleIcons" text="%i18n:@circle-icons%"/>
<mk-switch v-model="$store.state.settings.gradientWindowHeader" @change="onChangeGradientWindowHeader" text="%i18n:@gradient-window-header%"/> <mk-switch v-model="$store.state.settings.gradientWindowHeader" @change="onChangeGradientWindowHeader" text="%i18n:@gradient-window-header%"/>
<mk-switch v-model="$store.state.settings.iLikeSushi" @change="onChangeILikeSushi" text="%i18n:common.i-like-sushi%"/>
</div> </div>
<mk-switch v-model="$store.state.settings.showPostFormOnTopOfTl" @change="onChangeShowPostFormOnTopOfTl" text="%i18n:@post-form-on-timeline%"/> <mk-switch v-model="$store.state.settings.showPostFormOnTopOfTl" @change="onChangeShowPostFormOnTopOfTl" text="%i18n:@post-form-on-timeline%"/>
<mk-switch v-model="$store.state.settings.showReplyTarget" @change="onChangeShowReplyTarget" text="%i18n:@show-reply-target%"/> <mk-switch v-model="$store.state.settings.showReplyTarget" @change="onChangeShowReplyTarget" text="%i18n:@show-reply-target%"/>
@ -53,6 +54,7 @@
<mk-switch v-model="$store.state.settings.showMaps" @change="onChangeShowMaps" text="%i18n:@show-maps%"> <mk-switch v-model="$store.state.settings.showMaps" @change="onChangeShowMaps" text="%i18n:@show-maps%">
<span>%i18n:@show-maps-desc%</span> <span>%i18n:@show-maps-desc%</span>
</mk-switch> </mk-switch>
<mk-switch v-model="$store.state.settings.reversiBoardLabels" @change="onChangeReversiBoardLabels" text="%i18n:common.show-reversi-board-labels%"/>
</section> </section>
<section class="web" v-show="page == 'web'"> <section class="web" v-show="page == 'web'">
@ -362,6 +364,18 @@ export default Vue.extend({
value: v value: v
}); });
}, },
onChangeILikeSushi(v) {
this.$store.dispatch('settings/set', {
key: 'iLikeSushi',
value: v
});
},
onChangeReversiBoardLabels(v) {
this.$store.dispatch('settings/set', {
key: 'reversiBoardLabels',
value: v
});
},
onChangeGradientWindowHeader(v) { onChangeGradientWindowHeader(v) {
this.$store.dispatch('settings/set', { this.$store.dispatch('settings/set', {
key: 'gradientWindowHeader', key: 'gradientWindowHeader',

View File

@ -4,7 +4,7 @@
<span v-if="note.isHidden" style="opacity: 0.5">%i18n:@private%</span> <span v-if="note.isHidden" style="opacity: 0.5">%i18n:@private%</span>
<span v-if="note.deletedAt" style="opacity: 0.5">%i18n:@deleted%</span> <span v-if="note.deletedAt" style="opacity: 0.5">%i18n:@deleted%</span>
<a class="reply" v-if="note.replyId">%fa:reply%</a> <a class="reply" v-if="note.replyId">%fa:reply%</a>
<mk-note-html v-if="note.text" :text="note.text" :i="$store.state.i"/> <misskey-flavored-markdown v-if="note.text" :text="note.text" :i="$store.state.i"/>
<a class="rp" v-if="note.renoteId" :href="`/notes/${note.renoteId}`">RP: ...</a> <a class="rp" v-if="note.renoteId" :href="`/notes/${note.renoteId}`">RP: ...</a>
</div> </div>
<details v-if="note.media.length > 0"> <details v-if="note.media.length > 0">

View File

@ -56,23 +56,23 @@ export default Vue.extend({
this.connection = (this as any).os.stream.getConnection(); this.connection = (this as any).os.stream.getConnection();
this.connectionId = (this as any).os.stream.use(); this.connectionId = (this as any).os.stream.use();
this.connection.on('othello_invited', this.onOthelloInvited); this.connection.on('reversi_invited', this.onReversiInvited);
this.connection.on('othello_no_invites', this.onOthelloNoInvites); this.connection.on('reversi_no_invites', this.onReversiNoInvites);
} }
}, },
beforeDestroy() { beforeDestroy() {
if (this.$store.getters.isSignedIn) { if (this.$store.getters.isSignedIn) {
this.connection.off('othello_invited', this.onOthelloInvited); this.connection.off('reversi_invited', this.onReversiInvited);
this.connection.off('othello_no_invites', this.onOthelloNoInvites); this.connection.off('reversi_no_invites', this.onReversiNoInvites);
(this as any).os.stream.dispose(this.connectionId); (this as any).os.stream.dispose(this.connectionId);
} }
}, },
methods: { methods: {
onOthelloInvited() { onReversiInvited() {
this.hasGameInvitations = true; this.hasGameInvitations = true;
}, },
onOthelloNoInvites() { onReversiNoInvites() {
this.hasGameInvitations = false; this.hasGameInvitations = false;
}, },

View File

@ -25,7 +25,7 @@
<span v-if="p.isHidden" style="opacity: 0.5">(%i18n:@private%)</span> <span v-if="p.isHidden" style="opacity: 0.5">(%i18n:@private%)</span>
<span v-if="p.deletedAt" style="opacity: 0.5">(%i18n:@deleted%)</span> <span v-if="p.deletedAt" style="opacity: 0.5">(%i18n:@deleted%)</span>
<a class="reply" v-if="p.reply">%fa:reply%</a> <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"/> <misskey-flavored-markdown v-if="p.text" :text="p.text" :i="$store.state.i"/>
<a class="rp" v-if="p.renote != null">RP:</a> <a class="rp" v-if="p.renote != null">RP:</a>
</div> </div>
<div class="media" v-if="p.media.length > 0"> <div class="media" v-if="p.media.length > 0">
@ -67,8 +67,7 @@
<script lang="ts"> <script lang="ts">
import Vue from 'vue'; import Vue from 'vue';
import parse from '../../../../../../text/parse'; import parse from '../../../../../../mfm/parse';
import canHideText from '../../../../common/scripts/can-hide-text';
import MkNoteMenu from '../../../../common/views/components/note-menu.vue'; import MkNoteMenu from '../../../../common/views/components/note-menu.vue';
import MkReactionPicker from '../../../../common/views/components/reaction-picker.vue'; import MkReactionPicker from '../../../../common/views/components/reaction-picker.vue';
@ -148,8 +147,6 @@ export default Vue.extend({
}, },
methods: { methods: {
canHideText,
capture(withHandler = false) { capture(withHandler = false) {
if (this.$store.getters.isSignedIn) { if (this.$store.getters.isSignedIn) {
this.connection.send({ this.connection.send({
@ -381,10 +378,10 @@ root(isDark)
> * > *
display inline-block display inline-block
margin 0 8px 0 0 margin 0 0 4px 6px
padding 2px 8px 2px 16px padding 2px 8px 2px 16px
font-size 90% font-size 90%
color #8d969e color $theme-color
background isDark ? #313543 : #edf0f3 background isDark ? #313543 : #edf0f3
border-radius 4px border-radius 4px

View File

@ -7,7 +7,9 @@
<button @click="resolveInitPromise">%i18n:@retry%</button> <button @click="resolveInitPromise">%i18n:@retry%</button>
</div> </div>
<transition-group name="mk-notes" class="transition"> <!-- トランジションを有効にするとなぜかメモリリークする -->
<!--<transition-group name="mk-notes" class="transition">-->
<div class="notes">
<template v-for="(note, i) in _notes"> <template v-for="(note, i) in _notes">
<x-note :note="note" :key="note.id" @update:note="onNoteUpdated(i, $event)" :media-view="mediaView"/> <x-note :note="note" :key="note.id" @update:note="onNoteUpdated(i, $event)" :media-view="mediaView"/>
<p class="date" :key="note.id + '_date'" v-if="i != notes.length - 1 && note._date != _notes[i + 1]._date"> <p class="date" :key="note.id + '_date'" v-if="i != notes.length - 1 && note._date != _notes[i + 1]._date">
@ -15,7 +17,8 @@
<span>%fa:angle-down%{{ _notes[i + 1]._datetext }}</span> <span>%fa:angle-down%{{ _notes[i + 1]._datetext }}</span>
</p> </p>
</template> </template>
</transition-group> </div>
<!--</transition-group>-->
<footer v-if="more"> <footer v-if="more">
<button @click="loadMore" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }"> <button @click="loadMore" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }">
@ -198,6 +201,7 @@ root(isDark)
> * > *
transition transform .3s ease, opacity .3s ease transition transform .3s ease, opacity .3s ease
> .notes
> .date > .date
display block display block
margin 0 margin 0

View File

@ -1,6 +1,8 @@
<template> <template>
<div class="oxynyeqmfvracxnglgulyqfgqxnxmehl"> <div class="oxynyeqmfvracxnglgulyqfgqxnxmehl">
<transition-group name="mk-notifications" class="transition notifications"> <!-- トランジションを有効にするとなぜかメモリリークする -->
<!--<transition-group name="mk-notifications" class="transition notifications">-->
<div class="notifications">
<template v-for="(notification, i) in _notifications"> <template v-for="(notification, i) in _notifications">
<x-notification class="notification" :notification="notification" :key="notification.id"/> <x-notification class="notification" :notification="notification" :key="notification.id"/>
<p class="date" v-if="i != notifications.length - 1 && notification._date != _notifications[i + 1]._date" :key="notification.id + '-time'"> <p class="date" v-if="i != notifications.length - 1 && notification._date != _notifications[i + 1]._date" :key="notification.id + '-time'">
@ -8,7 +10,8 @@
<span>%fa:angle-down%{{ _notifications[i + 1]._datetext }}</span> <span>%fa:angle-down%{{ _notifications[i + 1]._datetext }}</span>
</p> </p>
</template> </template>
</transition-group> </div>
<!--</transition-group>-->
<button class="more" :class="{ fetching: fetchingMoreNotifications }" v-if="moreNotifications" @click="fetchMoreNotifications" :disabled="fetchingMoreNotifications"> <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%' }} <template v-if="fetchingMoreNotifications">%fa:spinner .pulse .fw%</template>{{ fetchingMoreNotifications ? '%i18n:common.loading%' : '%i18n:@more%' }}
</button> </button>

View File

@ -116,6 +116,8 @@ export default Vue.extend({
data: {} data: {}
} }
}); });
this.widgetAdderSelected = null;
}, },
removeWidget(widget) { removeWidget(widget) {

View File

@ -1,6 +1,6 @@
<template> <template>
<component :is="ui ? 'mk-ui' : 'div'"> <component :is="ui ? 'mk-ui' : 'div'">
<mk-othello v-if="!fetching" :init-game="game" @gamed="onGamed"/> <mk-reversi v-if="!fetching" :init-game="game" @gamed="onGamed"/>
</component> </component>
</template> </template>
@ -33,7 +33,7 @@ export default Vue.extend({
Progress.start(); Progress.start();
this.fetching = true; this.fetching = true;
(this as any).api('othello/games/show', { (this as any).api('reversi/games/show', {
gameId: this.$route.params.game gameId: this.$route.params.game
}).then(game => { }).then(game => {
this.game = game; this.game = game;
@ -43,7 +43,7 @@ export default Vue.extend({
}); });
}, },
onGamed(game) { onGamed(game) {
history.pushState(null, null, '/othello/' + game.id); history.pushState(null, null, '/reversi/' + game.id);
} }
} }
}); });

View File

@ -0,0 +1,58 @@
<template>
<div class="pptjhabgjtt7kwskbfv4y3uml6fpuhmr">
<h1>Misskeyで共有</h1>
<div>
<mk-signin v-if="!$store.getters.isSignedIn"/>
<mk-post-form v-else-if="!posted" :initial-text="text" :instant="true" @posted="posted = true"/>
<p v-if="posted" class="posted">%fa:check%</p>
</div>
<button v-if="posted" class="ui button" @click="close">閉じる</button>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
export default Vue.extend({
data() {
return {
posted: false,
text: new URLSearchParams(location.search).get('text')
};
},
methods: {
close() {
window.close();
}
}
});
</script>
<style lang="stylus" scoped>
.pptjhabgjtt7kwskbfv4y3uml6fpuhmr
padding 16px
> h1
margin 0 0 8px 0
color #555
font-size 20px
text-align center
> div
max-width 500px
margin 0 auto
background #fff
border solid 1px rgba(#000, 0.1)
border-radius 6px
overflow hidden
> .posted
display block
margin 0
padding 64px
text-align center
> button
display block
margin 16px auto
</style>

View File

@ -1,27 +1,37 @@
<template> <template>
<div class="header" :data-is-dark-background="user.bannerUrl != null"> <div class="header" :data-is-dark-background="user.bannerUrl != null">
<div class="is-suspended" v-if="user.isSuspended"><p>%fa:exclamation-triangle% %i18n:@is-suspended%</p></div>
<div class="is-remote" v-if="user.host != null"><p>%fa:exclamation-triangle% %i18n:@is-remote%<a :href="user.url || user.uri" target="_blank">%i18n:@view-remote%</a></p></div>
<div class="banner-container" :style="style"> <div class="banner-container" :style="style">
<div class="banner" ref="banner" :style="style" @click="onBannerClick"></div> <div class="banner" ref="banner" :style="style" @click="onBannerClick"></div>
<div class="fade"></div> <div class="fade"></div>
</div>
<div class="container">
<mk-avatar class="avatar" :user="user" :disable-preview="true"/>
<div class="title"> <div class="title">
<p class="name">{{ user | userName }}</p> <p class="name">{{ user | userName }}</p>
<p class="username"><mk-acct :user="user"/></p> <div>
<p class="location" v-if="user.host === null && user.profile.location">%fa:map-marker%{{ user.profile.location }}</p> <span class="username"><mk-acct :user="user"/></span>
<span v-if="user.isBot" title="%i18n:@is-bot%">%fa:robot%</span>
<span class="location" v-if="user.host === null && user.profile.location">%fa:map-marker% {{ user.profile.location }}</span>
<span class="birthday" v-if="user.host === null && user.profile.birthday">%fa:birthday-cake% {{ user.profile.birthday.replace('-', '').replace('-', '') + '' }} ({{ age }})</span>
</div>
</div>
</div>
<mk-avatar class="avatar" :user="user" :disable-preview="true"/>
<div class="body">
<div class="description">
<misskey-flavored-markdown v-if="user.description" :text="user.description" :i="$store.state.i"/>
</div>
<div class="status">
<span class="notes-count"><b>{{ user.notesCount | number }}</b>%i18n:@posts%</span>
<span class="following clickable" @click="showFollowing"><b>{{ user.followingCount | number }}</b>%i18n:@following%</span>
<span class="followers clickable" @click="showFollowers"><b>{{ user.followersCount | number }}</b>%i18n:@followers%</span>
</div> </div>
<footer>
<router-link :to="user | userPage" :data-active="$parent.page == 'home'">%fa:home%ホーム</router-link>
</footer>
</div> </div>
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import Vue from 'vue'; import Vue from 'vue';
import MkFollowingWindow from '../../components/following-window.vue';
import MkFollowersWindow from '../../components/followers-window.vue';
import * as age from 's-age';
export default Vue.extend({ export default Vue.extend({
props: ['user'], props: ['user'],
@ -32,20 +42,24 @@ export default Vue.extend({
backgroundColor: this.user.bannerColor && this.user.bannerColor.length == 3 ? `rgb(${ this.user.bannerColor.join(',') })` : null, backgroundColor: this.user.bannerColor && this.user.bannerColor.length == 3 ? `rgb(${ this.user.bannerColor.join(',') })` : null,
backgroundImage: `url(${ this.user.bannerUrl })` backgroundImage: `url(${ this.user.bannerUrl })`
}; };
},
age(): number {
return age(this.user.profile.birthday);
} }
}, },
mounted() { mounted() {
if (this.user.bannerUrl) { if (this.user.bannerUrl) {
window.addEventListener('load', this.onScroll); //window.addEventListener('load', this.onScroll);
window.addEventListener('scroll', this.onScroll, { passive: true }); //window.addEventListener('scroll', this.onScroll, { passive: true });
window.addEventListener('resize', this.onScroll); //window.addEventListener('resize', this.onScroll);
} }
}, },
beforeDestroy() { beforeDestroy() {
if (this.user.bannerUrl) { if (this.user.bannerUrl) {
window.removeEventListener('load', this.onScroll); //window.removeEventListener('load', this.onScroll);
window.removeEventListener('scroll', this.onScroll); //window.removeEventListener('scroll', this.onScroll);
window.removeEventListener('resize', this.onScroll); //window.removeEventListener('resize', this.onScroll);
} }
}, },
methods: { methods: {
@ -68,7 +82,19 @@ export default Vue.extend({
(this as any).apis.updateBanner().then(i => { (this as any).apis.updateBanner().then(i => {
this.user.bannerUrl = i.bannerUrl; this.user.bannerUrl = i.bannerUrl;
}); });
} },
showFollowing() {
(this as any).os.new(MkFollowingWindow, {
user: this.user
});
},
showFollowers() {
(this as any).os.new(MkFollowersWindow, {
user: this.user
});
},
} }
}); });
</script> </script>
@ -76,31 +102,11 @@ export default Vue.extend({
<style lang="stylus" scoped> <style lang="stylus" scoped>
@import '~const.styl' @import '~const.styl'
.header root(isDark)
$footer-height = 58px background isDark ? #282C37 : #fff
border 1px solid rgba(#000, 0.075)
border-radius 6px
overflow hidden overflow hidden
background #f7f7f7
box-shadow 0 1px 1px rgba(#000, 0.075)
> .is-suspended
> .is-remote
&.is-suspended
color #570808
background #ffdbdb
&.is-remote
color #573c08
background #fff0db
> p
margin 0 auto
padding 14px 16px
max-width 1200px
font-size 14px
> a
font-weight bold
&[data-is-dark-background] &[data-is-dark-background]
> .banner-container > .banner-container
@ -110,7 +116,6 @@ export default Vue.extend({
> .fade > .fade
background linear-gradient(transparent, rgba(#000, 0.7)) background linear-gradient(transparent, rgba(#000, 0.7))
> .container
> .title > .title
color #fff color #fff
@ -118,7 +123,7 @@ export default Vue.extend({
text-shadow 0 0 8px #000 text-shadow 0 0 8px #000
> .banner-container > .banner-container
height 320px height 250px
overflow hidden overflow hidden
background-size cover background-size cover
background-position center background-position center
@ -136,83 +141,75 @@ export default Vue.extend({
width 100% width 100%
height 78px height 78px
> .container
max-width 1200px
margin 0 auto
> .avatar
display block
position absolute
bottom 16px
left 16px
z-index 2
width 160px
height 160px
border solid 3px #fff
border-radius 8px
box-shadow 1px 1px 3px rgba(#000, 0.2)
> .title > .title
position absolute position absolute
bottom $footer-height bottom 0
left 0 left 0
width 100% width 100%
padding 0 0 8px 195px padding 0 0 8px 154px
color #5e6367 color #5e6367
font-family '游ゴシック', 'YuGothic', 'ヒラギノ角ゴ ProN W3', 'Hiragino Kaku Gothic ProN', 'Meiryo', 'メイリオ', sans-serif
> .name > .name
display block display block
margin 0 margin 0
line-height 40px line-height 32px
font-weight bold font-weight bold
font-size 2em font-size 1.8em
> .username > div
> .location > *
display inline-block
margin-right 16px
line-height 20px
opacity 0.8
&.username
font-weight bold
> .avatar
display block
position absolute
top 170px
left 16px
z-index 2
width 120px
height 120px
box-shadow 1px 1px 3px rgba(#000, 0.2)
> .body
padding 16px 16px 16px 154px
color isDark ? #c5ced6 : #555
> .status
margin-top 16px
padding-top 16px
border-top solid 1px rgba(#000, isDark ? 0.2 : 0.1)
font-size 80%
> *
display inline-block display inline-block
margin 0 16px 0 0 padding-right 16px
line-height 20px margin-right 16px
opacity 0.8
> i &:not(:last-child)
border-right solid 1px rgba(#000, isDark ? 0.2 : 0.1)
&.clickable
cursor pointer
&:hover
color isDark ? #fff : #000
> b
margin-right 4px margin-right 4px
font-size 1rem
font-weight bold
color $theme-color
> footer .header[data-darkmode]
z-index 1 root(true)
height $footer-height
padding-left 195px
> a .header:not([data-darkmode])
display inline-block root(false)
margin 0
padding 0 16px
height $footer-height
line-height $footer-height
color #555
&[data-active]
border-bottom solid 4px $theme-color
> i
margin-right 6px
> button
display block
position absolute
top 0
right 0
margin 8px
padding 0
width $footer-height - 16px
line-height $footer-height - 16px - 2px
font-size 1.2em
color #777
border solid 1px #eee
border-radius 4px
&:hover
color #555
border solid 1px #ddd
</style> </style>

View File

@ -1,103 +0,0 @@
<template>
<div class="home">
<div>
<div ref="left">
<x-profile :user="user"/>
<x-photos :user="user"/>
<x-followers-you-know v-if="$store.getters.isSignedIn && $store.state.i.id != user.id" :user="user"/>
<p v-if="user.host === null">%i18n:@last-used-at%: <b><mk-time :time="user.lastUsedAt"/></b></p>
</div>
</div>
<main>
<mk-note-detail v-if="user.pinnedNote" :note="user.pinnedNote" :compact="true"/>
<x-timeline class="timeline" ref="tl" :user="user"/>
</main>
<div>
<div ref="right">
<mk-calendar @chosen="warp" :start="new Date(user.createdAt)"/>
<mk-activity :user="user"/>
<x-friends :user="user"/>
<div class="nav"><mk-nav/></div>
</div>
</div>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import XTimeline from './user.timeline.vue';
import XProfile from './user.profile.vue';
import XPhotos from './user.photos.vue';
import XFollowersYouKnow from './user.followers-you-know.vue';
import XFriends from './user.friends.vue';
export default Vue.extend({
components: {
XTimeline,
XProfile,
XPhotos,
XFollowersYouKnow,
XFriends
},
props: ['user'],
methods: {
warp(date) {
(this.$refs.tl as any).warp(date);
}
}
});
</script>
<style lang="stylus" scoped>
.home
display flex
justify-content center
margin 0 auto
max-width 1200px
> main
> div > div
> *:not(:last-child)
margin-bottom 16px
> main
padding 16px
width calc(100% - 275px * 2)
> .timeline
border solid 1px rgba(#000, 0.075)
border-radius 6px
> div
width 275px
margin 0
&:first-child > div
padding 16px 0 16px 16px
> p
display block
margin 0
padding 0 12px
text-align center
font-size 0.8em
color #aaa
&:last-child > div
padding 16px 16px 16px 0
> .nav
padding 16px
font-size 12px
color #aaa
background #fff
border solid 1px rgba(#000, 0.075)
border-radius 6px
a
color #999
i
color #ccc
</style>

View File

@ -15,48 +15,17 @@
</button> </button>
<button class="mute ui" @click="list">%fa:list% リストに追加</button> <button class="mute ui" @click="list">%fa:list% リストに追加</button>
</div> </div>
<div class="description" v-if="user.description">{{ user.description }}</div>
<div class="birthday" v-if="user.host === null && user.profile.birthday">
<p>%fa:birthday-cake%{{ user.profile.birthday.replace('-', '年').replace('-', '月') + '日' }} ({{ age }})</p>
</div>
<div class="twitter" v-if="user.host === null && user.twitter">
<p>%fa:B twitter%<a :href="`https://twitter.com/${user.twitter.screenName}`" target="_blank">@{{ user.twitter.screenName }}</a></p>
</div>
<div class="status">
<p class="notes-count">%fa:angle-right%<a>{{ user.notesCount }}</a><b>投稿</b></p>
<p class="following">%fa:angle-right%<a @click="showFollowing">{{ user.followingCount }}</a>人を<b>フォロー</b></p>
<p class="followers">%fa:angle-right%<a @click="showFollowers">{{ user.followersCount }}</a>人の<b>フォロワー</b></p>
</div>
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import Vue from 'vue'; import Vue from 'vue';
import * as age from 's-age';
import MkFollowingWindow from '../../components/following-window.vue';
import MkFollowersWindow from '../../components/followers-window.vue';
import MkUserListsWindow from '../../components/user-lists-window.vue'; import MkUserListsWindow from '../../components/user-lists-window.vue';
export default Vue.extend({ export default Vue.extend({
props: ['user'], props: ['user'],
computed: {
age(): number {
return age(this.user.profile.birthday);
}
},
methods: { methods: {
showFollowing() {
(this as any).os.new(MkFollowingWindow, {
user: this.user
});
},
showFollowers() {
(this as any).os.new(MkFollowersWindow, {
user: this.user
});
},
stalk() { stalk() {
(this as any).api('following/stalk', { (this as any).api('following/stalk', {
userId: this.user.id userId: this.user.id
@ -116,8 +85,8 @@ export default Vue.extend({
</script> </script>
<style lang="stylus" scoped> <style lang="stylus" scoped>
.profile root(isDark)
background #fff background isDark ? #282C37 : #fff
border solid 1px rgba(#000, 0.075) border solid 1px rgba(#000, 0.075)
border-radius 6px border-radius 6px
@ -127,7 +96,7 @@ export default Vue.extend({
> .friend-form > .friend-form
padding 16px padding 16px
text-align center text-align center
border-top solid 1px #eee border-bottom solid 1px isDark ? #21242f : #eee
> .followed > .followed
margin 12px 0 0 0 margin 12px 0 0 0
@ -145,7 +114,7 @@ export default Vue.extend({
> .action-form > .action-form
padding 16px padding 16px
text-align center text-align center
border-top solid 1px #eee border-bottom solid 1px isDark ? #21242f : #eee
> * > *
width 100% width 100%
@ -153,43 +122,10 @@ export default Vue.extend({
&:not(:last-child) &:not(:last-child)
margin-bottom 12px margin-bottom 12px
> .description .profile[data-darkmode]
padding 16px root(true)
color #555
border-top solid 1px #eee
> .birthday .profile:not([data-darkmode])
padding 16px root(false)
color #555
border-top solid 1px #eee
> p
margin 0
> i
margin-right 8px
> .twitter
padding 16px
color #555
border-top solid 1px #eee
> p
margin 0
> i
margin-right 8px
> .status
padding 16px
color #555
border-top solid 1px #eee
> p
margin 8px 0
> i
margin-left 8px
margin-right 8px
</style> </style>

View File

@ -1,9 +1,9 @@
<template> <template>
<div class="timeline"> <div class="oh5y2r7l5lx8j6jj791ykeiwgihheguk">
<header> <header>
<span :data-active="mode == 'default'" @click="mode = 'default'">%i18n:@default%</span> <span :data-active="mode == 'default'" @click="mode = 'default'">%fa:comment-alt R% %i18n:@default%</span>
<span :data-active="mode == 'with-replies'" @click="mode = 'with-replies'">%i18n:@with-replies%</span> <span :data-active="mode == 'with-replies'" @click="mode = 'with-replies'">%fa:comments% %i18n:@with-replies%</span>
<span :data-active="mode == 'with-media'" @click="mode = 'with-media'">%i18n:@with-media%</span> <span :data-active="mode == 'with-media'" @click="mode = 'with-media'">%fa:images% %i18n:@with-media%</span>
</header> </header>
<div class="loading" v-if="fetching"> <div class="loading" v-if="fetching">
<mk-ellipsis-icon/> <mk-ellipsis-icon/>
@ -114,25 +114,44 @@ export default Vue.extend({
<style lang="stylus" scoped> <style lang="stylus" scoped>
@import '~const.styl' @import '~const.styl'
.timeline root(isDark)
background #fff background isDark ? #282C37 : #fff
> header > header
padding 8px 16px padding 0 8px
border-bottom solid 1px #eee z-index 10
background isDark ? #313543 : #fff
border-radius 6px 6px 0 0
box-shadow 0 1px isDark ? rgba(#000, 0.15) : rgba(#000, 0.08)
> span > span
margin-right 16px display inline-block
line-height 27px padding 0 10px
font-size 18px line-height 42px
color #555 font-size 12px
user-select none
&[data-active]
color $theme-color
cursor default
font-weight bold
&:before
content ""
display block
position absolute
bottom 0
left -8px
width calc(100% + 16px)
height 2px
background $theme-color
&:not([data-active]) &:not([data-active])
color $theme-color color isDark ? #9aa2a7 : #6f7477
cursor pointer cursor pointer
&:hover &:hover
text-decoration underline color isDark ? #d9dcde : #525a5f
> .loading > .loading
padding 64px 0 padding 64px 0
@ -151,4 +170,10 @@ export default Vue.extend({
font-size 3em font-size 3em
color #ccc color #ccc
.oh5y2r7l5lx8j6jj791ykeiwgihheguk[data-darkmode]
root(true)
.oh5y2r7l5lx8j6jj791ykeiwgihheguk:not([data-darkmode])
root(false)
</style> </style>

View File

@ -0,0 +1,26 @@
<template>
<div class="adsvaidqfznoartcbplullnejvxjphcn">
<span>%fa:B twitter%<a :href="`https://twitter.com/${user.twitter.screenName}`" target="_blank">@{{ user.twitter.screenName }}</a></span>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
export default Vue.extend({
props: ['user']
});
</script>
<style lang="stylus" scoped>
.adsvaidqfznoartcbplullnejvxjphcn
padding 32px
background #1a94f2
border-radius 6px
color #fff
a
margin-left 8px
color #fff
</style>

View File

@ -1,8 +1,26 @@
<template> <template>
<mk-ui> <mk-ui>
<div class="user" v-if="!fetching"> <div class="xygkxeaeontfaokvqmiblezmhvhostak" v-if="!fetching" :data-darkmode="$store.state.device.darkmode">
<x-header :user="user"/> <div class="is-suspended" v-if="user.isSuspended">%fa:exclamation-triangle% %i18n:@is-suspended%</div>
<x-home v-if="page == 'home'" :user="user"/> <div class="is-remote" v-if="user.host != null">%fa:exclamation-triangle% %i18n:@is-remote%<a :href="user.url || user.uri" target="_blank">%i18n:@view-remote%</a></div>
<main>
<div class="main">
<x-header :user="user"/>
<mk-note-detail v-if="user.pinnedNote" :note="user.pinnedNote" :compact="true"/>
<x-timeline class="timeline" ref="tl" :user="user"/>
</div>
<div class="side">
<x-profile :user="user"/>
<x-twitter :user="user" v-if="user.host === null && user.twitter"/>
<mk-calendar @chosen="warp" :start="new Date(user.createdAt)"/>
<mk-activity :user="user"/>
<x-photos :user="user"/>
<x-friends :user="user"/>
<x-followers-you-know v-if="$store.getters.isSignedIn && $store.state.i.id != user.id" :user="user"/>
<div class="nav"><mk-nav/></div>
<p v-if="user.host === null">%i18n:@last-used-at%: <b><mk-time :time="user.lastUsedAt"/></b></p>
</div>
</main>
</div> </div>
</mk-ui> </mk-ui>
</template> </template>
@ -13,17 +31,22 @@ import parseAcct from '../../../../../../acct/parse';
import getUserName from '../../../../../../renderers/get-user-name'; import getUserName from '../../../../../../renderers/get-user-name';
import Progress from '../../../../common/scripts/loading'; import Progress from '../../../../common/scripts/loading';
import XHeader from './user.header.vue'; import XHeader from './user.header.vue';
import XHome from './user.home.vue'; import XTimeline from './user.timeline.vue';
import XProfile from './user.profile.vue';
import XPhotos from './user.photos.vue';
import XFollowersYouKnow from './user.followers-you-know.vue';
import XFriends from './user.friends.vue';
import XTwitter from './user.twitter.vue';
export default Vue.extend({ export default Vue.extend({
components: { components: {
XHeader, XHeader,
XHome XTimeline,
}, XProfile,
props: { XPhotos,
page: { XFollowersYouKnow,
default: 'home' XFriends,
} XTwitter
}, },
data() { data() {
return { return {
@ -47,8 +70,89 @@ export default Vue.extend({
Progress.done(); Progress.done();
document.title = getUserName(this.user) + ' | Misskey'; document.title = getUserName(this.user) + ' | Misskey';
}); });
},
warp(date) {
(this.$refs.tl as any).warp(date);
} }
} }
}); });
</script> </script>
<style lang="stylus" scoped>
root(isDark)
width 980px
padding 16px
margin 0 auto
> .is-suspended
> .is-remote
margin-bottom 16px
padding 14px 16px
font-size 14px
border-radius 6px
&.is-suspended
color isDark ? #ffb4b4 : #570808
background isDark ? #611d1d : #ffdbdb
border solid 1px isDark ? #d64a4a : #e09696
&.is-remote
color isDark ? #ffbd3e : #573c08
background isDark ? #42321c : #fff0db
border solid 1px isDark ? #90733c : #dcbb7b
> a
font-weight bold
> main
display flex
justify-content center
> .main
> .side
> *:not(:last-child)
margin-bottom 16px
> .main
flex 1
min-width 0 // SEE: http://kudakurage.hatenadiary.com/entry/2016/04/01/232722
margin-right 16px
> .timeline
border 1px solid rgba(#000, 0.075)
border-radius 6px
> .side
width 275px
flex-shrink 0
> p
display block
margin 0
padding 0 12px
text-align center
font-size 0.8em
color #aaa
> .nav
padding 16px
font-size 12px
color #aaa
background #fff
border solid 1px rgba(#000, 0.075)
border-radius 6px
a
color #999
i
color #ccc
.xygkxeaeontfaokvqmiblezmhvhostak[data-darkmode]
root(true)
.xygkxeaeontfaokvqmiblezmhvhostak:not([data-darkmode])
root(false)
</style>

View File

@ -7,18 +7,6 @@
</button> </button>
<div class="body" :style="{ backgroundImage: `url('${ welcomeBgUrl }')` }"> <div class="body" :style="{ backgroundImage: `url('${ welcomeBgUrl }')` }">
<div class="container"> <div class="container">
<main>
<div class="about">
<h1 v-if="name">{{ name }}</h1>
<h1 v-else><img :src="$store.state.device.darkmode ? 'assets/title.dark.svg' : 'assets/title.light.svg'" alt="Misskey"></h1>
<p class="powerd-by" v-if="name">powerd by <b>Misskey</b></p>
<p class="desc" v-html="description || '%i18n:common.about%'"></p>
<a ref="signup" @click="signup">%i18n:@signup%</a>
</div>
<div class="login">
<mk-signin/>
</div>
</main>
<div class="info"> <div class="info">
<span>%i18n:common.misskey% <b>{{ host }}</b></span> <span>%i18n:common.misskey% <b>{{ host }}</b></span>
<span class="stats" v-if="stats"> <span class="stats" v-if="stats">
@ -26,13 +14,28 @@
<span>%fa:pencil-alt% {{ stats.originalNotesCount | number }}</span> <span>%fa:pencil-alt% {{ stats.originalNotesCount | number }}</span>
</span> </span>
</div> </div>
<main>
<div class="about">
<h1 v-if="name">{{ name }}</h1>
<h1 v-else><img :src="$store.state.device.darkmode ? 'assets/title.dark.svg' : 'assets/title.light.svg'" alt="Misskey"></h1>
<p class="powerd-by" v-if="name">powerd by <b>Misskey</b></p>
<p class="desc" v-html="description || '%i18n:common.about%'"></p>
<a ref="signup" @click="signup">📦 %i18n:@signup%</a>
</div>
<div class="login">
<mk-signin/>
</div>
</main>
<div class="hashtags">
<router-link v-for="tag in tags" :key="tag" :to="`/tags/${ tag }`" :title="tag">#{{ tag }}</router-link>
</div>
<mk-nav class="nav"/> <mk-nav class="nav"/>
</div> </div>
<mk-forkit class="forkit"/> <mk-forkit class="forkit"/>
<img src="assets/title.dark.svg" alt="Misskey"> <img src="assets/title.dark.svg" alt="Misskey">
</div> </div>
<div class="tl"> <div class="tl">
<mk-welcome-timeline/> <mk-welcome-timeline :max="20"/>
</div> </div>
<modal name="signup" width="500px" height="auto" scrollable> <modal name="signup" width="500px" height="auto" scrollable>
<header :class="$style.signupFormHeader">%i18n:@signup%</header> <header :class="$style.signupFormHeader">%i18n:@signup%</header>
@ -54,13 +57,18 @@ export default Vue.extend({
host, host,
name, name,
description, description,
pointerInterval: null pointerInterval: null,
tags: []
}; };
}, },
created() { created() {
(this as any).api('stats').then(stats => { (this as any).api('stats').then(stats => {
this.stats = stats; this.stats = stats;
}); });
(this as any).api('hashtags/trend').then(stats => {
this.tags = stats.map(x => x.tag);
});
}, },
mounted() { mounted() {
this.point(); this.point();
@ -161,6 +169,20 @@ root(isDark)
$loginWidth = 340px $loginWidth = 340px
$width = $aboutWidth + $loginWidth $width = $aboutWidth + $loginWidth
> .info
margin 0 auto 16px auto
width $width
font-size 14px
color #fff
> .stats
margin-left 16px
padding-left 16px
border-left solid 1px #fff
> *
margin-right 16px
> main > main
display flex display flex
margin auto margin auto
@ -199,24 +221,19 @@ root(isDark)
> .login > .login
width $loginWidth width $loginWidth
padding 16px 32px 32px 32px padding 16px 32px 32px 32px
background #f5f5f5 background isDark ? #2e3440 : #f5f5f5
> .info > .hashtags
margin 16px auto margin 16px auto
padding 12px
width $width width $width
font-size 14px font-size 14px
color #fff color #fff
background rgba(#000, 0.2) background rgba(#000, 0.3)
border-radius 8px border-radius 8px
> .stats > *
margin-left 16px display inline-block
padding-left 16px margin 14px
border-left solid 1px #fff
> *
margin-right 16px
> .nav > .nav
display block display block

View File

@ -11,7 +11,7 @@ import { DriveStreamManager } from './common/scripts/streaming/drive';
import { ServerStatsStreamManager } from './common/scripts/streaming/server-stats'; import { ServerStatsStreamManager } from './common/scripts/streaming/server-stats';
import { NotesStatsStreamManager } from './common/scripts/streaming/notes-stats'; import { NotesStatsStreamManager } from './common/scripts/streaming/notes-stats';
import { MessagingIndexStreamManager } from './common/scripts/streaming/messaging-index'; import { MessagingIndexStreamManager } from './common/scripts/streaming/messaging-index';
import { OthelloStreamManager } from './common/scripts/streaming/othello'; import { ReversiStreamManager } from './common/scripts/streaming/reversi';
import Err from './common/views/components/connect-failed.vue'; import Err from './common/views/components/connect-failed.vue';
import { LocalTimelineStreamManager } from './common/scripts/streaming/local-timeline'; import { LocalTimelineStreamManager } from './common/scripts/streaming/local-timeline';
@ -108,7 +108,7 @@ export default class MiOS extends EventEmitter {
serverStatsStream: ServerStatsStreamManager; serverStatsStream: ServerStatsStreamManager;
notesStatsStream: NotesStatsStreamManager; notesStatsStream: NotesStatsStreamManager;
messagingIndexStream: MessagingIndexStreamManager; messagingIndexStream: MessagingIndexStreamManager;
othelloStream: OthelloStreamManager; reversiStream: ReversiStreamManager;
} = { } = {
localTimelineStream: null, localTimelineStream: null,
globalTimelineStream: null, globalTimelineStream: null,
@ -116,7 +116,7 @@ export default class MiOS extends EventEmitter {
serverStatsStream: null, serverStatsStream: null,
notesStatsStream: null, notesStatsStream: null,
messagingIndexStream: null, messagingIndexStream: null,
othelloStream: null reversiStream: null
}; };
/** /**
@ -233,7 +233,7 @@ export default class MiOS extends EventEmitter {
this.streams.globalTimelineStream = new GlobalTimelineStreamManager(this, this.store.state.i); this.streams.globalTimelineStream = new GlobalTimelineStreamManager(this, this.store.state.i);
this.streams.driveStream = new DriveStreamManager(this, this.store.state.i); this.streams.driveStream = new DriveStreamManager(this, this.store.state.i);
this.streams.messagingIndexStream = new MessagingIndexStreamManager(this, this.store.state.i); this.streams.messagingIndexStream = new MessagingIndexStreamManager(this, this.store.state.i);
this.streams.othelloStream = new OthelloStreamManager(this, this.store.state.i); this.streams.reversiStream = new ReversiStreamManager(this, this.store.state.i);
}); });
//#endregion //#endregion

View File

@ -1,5 +1,18 @@
export default function(opts) { import OS from '../../mios';
import Dialog from '../views/components/dialog.vue';
export default (os: OS) => opts => {
return new Promise<string>((res, rej) => { return new Promise<string>((res, rej) => {
alert('dialog not implemented yet'); const o = opts || {};
const d = os.new(Dialog, {
title: o.title,
text: o.text,
modal: o.modal,
buttons: o.actions
});
d.$once('clicked', id => {
res(id);
});
document.body.appendChild(d.$el);
}); });
} };

View File

@ -18,7 +18,7 @@ export default (os) => (opts) => {
} }
}).$mount(); }).$mount();
vm.$once('cancel', recover); vm.$once('cancel', recover);
vm.$once('note', recover); vm.$once('posted', recover);
document.body.appendChild(vm.$el); document.body.appendChild(vm.$el);
(vm as any).focus(); (vm as any).focus();
}; };

View File

@ -35,8 +35,10 @@ import MkFavorites from './views/pages/favorites.vue';
import MkUserLists from './views/pages/user-lists.vue'; import MkUserLists from './views/pages/user-lists.vue';
import MkUserList from './views/pages/user-list.vue'; import MkUserList from './views/pages/user-list.vue';
import MkSettings from './views/pages/settings.vue'; import MkSettings from './views/pages/settings.vue';
import MkOthello from './views/pages/othello.vue'; import MkReversi from './views/pages/reversi.vue';
import MkTag from './views/pages/tag.vue'; import MkTag from './views/pages/tag.vue';
import MkShare from './views/pages/share.vue';
import MkFollow from '../common/views/pages/follow.vue';
/** /**
* init * init
@ -73,12 +75,14 @@ init((launch) => {
{ path: '/selectdrive', component: MkSelectDrive }, { path: '/selectdrive', component: MkSelectDrive },
{ path: '/search', component: MkSearch }, { path: '/search', component: MkSearch },
{ path: '/tags/:tag', component: MkTag }, { path: '/tags/:tag', component: MkTag },
{ path: '/othello', name: 'othello', component: MkOthello }, { path: '/share', component: MkShare },
{ path: '/othello/:game', component: MkOthello }, { path: '/reversi', name: 'reversi', component: MkReversi },
{ path: '/reversi/:game', component: MkReversi },
{ path: '/@:user', component: MkUser }, { path: '/@:user', component: MkUser },
{ path: '/@:user/followers', component: MkFollowers }, { path: '/@:user/followers', component: MkFollowers },
{ path: '/@:user/following', component: MkFollowing }, { path: '/@:user/following', component: MkFollowing },
{ path: '/notes/:note', component: MkNote } { path: '/notes/:note', component: MkNote },
{ path: '/authorize-follow', component: MkFollow }
] ]
}); });
@ -86,7 +90,7 @@ init((launch) => {
launch(router, os => ({ launch(router, os => ({
chooseDriveFolder, chooseDriveFolder,
chooseDriveFile, chooseDriveFile,
dialog, dialog: dialog(os),
input, input,
post: post(os), post: post(os),
notify notify

View File

@ -0,0 +1,171 @@
<template>
<div class="mk-dialog">
<div class="bg" ref="bg" @click="onBgClick"></div>
<div class="main" ref="main">
<header v-html="title" :class="$style.header"></header>
<div class="body" v-html="text"></div>
<div class="buttons">
<button v-for="button in buttons" @click="click(button)">{{ button.text }}</button>
</div>
</div>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import * as anime from 'animejs';
export default Vue.extend({
props: {
title: {
type: String,
required: false
},
text: {
type: String,
required: true
},
buttons: {
type: Array,
default: () => {
return [{
text: 'OK'
}];
}
},
modal: {
type: Boolean,
default: false
}
},
mounted() {
this.$nextTick(() => {
(this.$refs.bg as any).style.pointerEvents = 'auto';
anime({
targets: this.$refs.bg,
opacity: 1,
duration: 100,
easing: 'linear'
});
anime({
targets: this.$refs.main,
opacity: 1,
scale: [1.2, 1],
duration: 300,
easing: [0, 0.5, 0.5, 1]
});
});
},
methods: {
click(button) {
this.$emit('clicked', button.id);
this.close();
},
close() {
(this.$refs.bg as any).style.pointerEvents = 'none';
anime({
targets: this.$refs.bg,
opacity: 0,
duration: 300,
easing: 'linear'
});
(this.$refs.main as any).style.pointerEvents = 'none';
anime({
targets: this.$refs.main,
opacity: 0,
scale: 0.8,
duration: 300,
easing: [ 0.5, -0.5, 1, 0.5 ],
complete: () => this.$destroy()
});
},
onBgClick() {
if (!this.modal) {
this.close();
}
}
}
});
</script>
<style lang="stylus" scoped>
@import '~const.styl'
.mk-dialog
> .bg
display block
position fixed
z-index 8192
top 0
left 0
width 100%
height 100%
background rgba(#000, 0.7)
opacity 0
pointer-events none
> .main
display block
position fixed
z-index 8192
top 20%
left 0
right 0
margin 0 auto 0 auto
padding 16px
width calc(100% - 32px)
max-width 300px
background #fff
opacity 0
> .body
margin 1em 0
color #888
> .buttons
> button
display inline-block
float right
margin 0
padding 0 10px
font-size 1.1em
font-weight normal
text-decoration none
color #888
background transparent
outline none
border none
border-radius 0
cursor pointer
transition color 0.1s ease
i
margin 0 0.375em
&:hover
color $theme-color
&:active
color darken($theme-color, 10%)
transition color 0s ease
</style>
<style lang="stylus" module>
@import '~const.styl'
.header
margin 0 0 1em 0
color $theme-color
// color #43A4EC
font-weight bold
&:empty
display none
> i
margin-right 0.5em
</style>

View File

@ -22,6 +22,7 @@ import userTimeline from './user-timeline.vue';
import userListTimeline from './user-list-timeline.vue'; import userListTimeline from './user-list-timeline.vue';
import activity from './activity.vue'; import activity from './activity.vue';
import widgetContainer from './widget-container.vue'; import widgetContainer from './widget-container.vue';
import postForm from './post-form.vue';
Vue.component('mk-ui', ui); Vue.component('mk-ui', ui);
Vue.component('mk-note', note); Vue.component('mk-note', note);
@ -45,3 +46,4 @@ Vue.component('mk-user-timeline', userTimeline);
Vue.component('mk-user-list-timeline', userListTimeline); Vue.component('mk-user-list-timeline', userListTimeline);
Vue.component('mk-activity', activity); Vue.component('mk-activity', activity);
Vue.component('mk-widget-container', widgetContainer); Vue.component('mk-widget-container', widgetContainer);
Vue.component('mk-post-form', postForm);

View File

@ -38,7 +38,7 @@
<div class="text"> <div class="text">
<span v-if="p.isHidden" style="opacity: 0.5">(%i18n:@private%)</span> <span v-if="p.isHidden" style="opacity: 0.5">(%i18n:@private%)</span>
<span v-if="p.deletedAt" style="opacity: 0.5">(%i18n:@deleted%)</span> <span v-if="p.deletedAt" style="opacity: 0.5">(%i18n:@deleted%)</span>
<mk-note-html v-if="p.text" :text="p.text" :i="$store.state.i"/> <misskey-flavored-markdown v-if="p.text" :text="p.text" :i="$store.state.i"/>
</div> </div>
<div class="tags" v-if="p.tags && p.tags.length > 0"> <div class="tags" v-if="p.tags && p.tags.length > 0">
<router-link v-for="tag in p.tags" :key="tag" :to="`/tags/${tag}`">{{ tag }}</router-link> <router-link v-for="tag in p.tags" :key="tag" :to="`/tags/${tag}`">{{ tag }}</router-link>
@ -83,7 +83,7 @@
<script lang="ts"> <script lang="ts">
import Vue from 'vue'; import Vue from 'vue';
import parse from '../../../../../text/parse'; import parse from '../../../../../mfm/parse';
import MkNoteMenu from '../../../common/views/components/note-menu.vue'; import MkNoteMenu from '../../../common/views/components/note-menu.vue';
import MkReactionPicker from '../../../common/views/components/reaction-picker.vue'; import MkReactionPicker from '../../../common/views/components/reaction-picker.vue';

View File

@ -25,7 +25,7 @@
<span v-if="p.isHidden" style="opacity: 0.5">(%i18n:@private%)</span> <span v-if="p.isHidden" style="opacity: 0.5">(%i18n:@private%)</span>
<span v-if="p.deletedAt" style="opacity: 0.5">(%i18n:@deleted%)</span> <span v-if="p.deletedAt" style="opacity: 0.5">(%i18n:@deleted%)</span>
<a class="reply" v-if="p.reply">%fa:reply%</a> <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" :class="$style.text"/> <misskey-flavored-markdown v-if="p.text" :text="p.text" :i="$store.state.i" :class="$style.text"/>
<a class="rp" v-if="p.renote != null">RP:</a> <a class="rp" v-if="p.renote != null">RP:</a>
</div> </div>
<div class="media" v-if="p.media.length > 0"> <div class="media" v-if="p.media.length > 0">
@ -68,8 +68,7 @@
<script lang="ts"> <script lang="ts">
import Vue from 'vue'; import Vue from 'vue';
import parse from '../../../../../text/parse'; import parse from '../../../../../mfm/parse';
import canHideText from '../../../common/scripts/can-hide-text';
import MkNoteMenu from '../../../common/views/components/note-menu.vue'; import MkNoteMenu from '../../../common/views/components/note-menu.vue';
import MkReactionPicker from '../../../common/views/components/reaction-picker.vue'; import MkReactionPicker from '../../../common/views/components/reaction-picker.vue';
@ -165,8 +164,6 @@ export default Vue.extend({
}, },
methods: { methods: {
canHideText,
capture(withHandler = false) { capture(withHandler = false) {
if (this.$store.getters.isSignedIn) { if (this.$store.getters.isSignedIn) {
this.connection.send({ this.connection.send({
@ -424,10 +421,10 @@ root(isDark)
> * > *
display inline-block display inline-block
margin 0 8px 0 0 margin 0 0 4px 6px
padding 2px 8px 2px 16px padding 2px 8px 2px 16px
font-size 90% font-size 90%
color #8d969e color $theme-color
background isDark ? #313543 : #edf0f3 background isDark ? #313543 : #edf0f3
border-radius 4px border-radius 4px

View File

@ -13,7 +13,9 @@
<button @click="resolveInitPromise">%i18n:@retry%</button> <button @click="resolveInitPromise">%i18n:@retry%</button>
</div> </div>
<transition-group name="mk-notes" class="transition"> <!-- トランジションを有効にするとなぜかメモリリークする -->
<!-- <transition-group name="mk-notes" class="transition"> -->
<div class="transition">
<template v-for="(note, i) in _notes"> <template v-for="(note, i) in _notes">
<mk-note :note="note" :key="note.id" @update:note="onNoteUpdated(i, $event)"/> <mk-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"> <p class="date" :key="note.id + '_date'" v-if="i != notes.length - 1 && note._date != _notes[i + 1]._date">
@ -21,7 +23,8 @@
<span>%fa:angle-down%{{ _notes[i + 1]._datetext }}</span> <span>%fa:angle-down%{{ _notes[i + 1]._datetext }}</span>
</p> </p>
</template> </template>
</transition-group> </div>
<!-- </transition-group> -->
<footer v-if="more"> <footer v-if="more">
<button @click="loadMore" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }"> <button @click="loadMore" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }">

View File

@ -1,6 +1,8 @@
<template> <template>
<div class="mk-notifications"> <div class="mk-notifications">
<transition-group name="mk-notifications" class="transition notifications"> <!-- トランジションを有効にするとなぜかメモリリークする -->
<!-- <transition-group name="mk-notifications" class="transition notifications"> -->
<div class="transition notifications">
<template v-for="(notification, i) in _notifications"> <template v-for="(notification, i) in _notifications">
<mk-notification :notification="notification" :key="notification.id"/> <mk-notification :notification="notification" :key="notification.id"/>
<p class="date" :key="notification.id + '_date'" v-if="i != notifications.length - 1 && notification._date != _notifications[i + 1]._date"> <p class="date" :key="notification.id + '_date'" v-if="i != notifications.length - 1 && notification._date != _notifications[i + 1]._date">
@ -8,7 +10,8 @@
<span>%fa:angle-down%{{ _notifications[i + 1]._datetext }}</span> <span>%fa:angle-down%{{ _notifications[i + 1]._datetext }}</span>
</p> </p>
</template> </template>
</transition-group> </div>
<!-- </transition-group> -->
<button class="more" v-if="moreNotifications" @click="fetchMoreNotifications" :disabled="fetchingMoreNotifications"> <button class="more" v-if="moreNotifications" @click="fetchMoreNotifications" :disabled="fetchingMoreNotifications">
<template v-if="fetchingMoreNotifications">%fa:spinner .pulse .fw%</template> <template v-if="fetchingMoreNotifications">%fa:spinner .pulse .fw%</template>

View File

@ -45,7 +45,7 @@ import Vue from 'vue';
import * as XDraggable from 'vuedraggable'; import * as XDraggable from 'vuedraggable';
import MkVisibilityChooser from '../../../common/views/components/visibility-chooser.vue'; import MkVisibilityChooser from '../../../common/views/components/visibility-chooser.vue';
import getKao from '../../../common/scripts/get-kao'; import getKao from '../../../common/scripts/get-kao';
import parse from '../../../../../text/parse'; import parse from '../../../../../mfm/parse';
import { host } from '../../../config'; import { host } from '../../../config';
export default Vue.extend({ export default Vue.extend({
@ -54,7 +54,25 @@ export default Vue.extend({
MkVisibilityChooser MkVisibilityChooser
}, },
props: ['reply', 'renote'], props: {
reply: {
type: Object,
required: false
},
renote: {
type: Object,
required: false
},
initialText: {
type: String,
required: false
},
instant: {
type: Boolean,
required: false,
default: false
}
},
data() { data() {
return { return {
@ -112,6 +130,10 @@ export default Vue.extend({
}, },
mounted() { mounted() {
if (this.initialText) {
this.text = this.initialText;
}
if (this.reply && this.reply.user.host != null) { if (this.reply && this.reply.user.host != null) {
this.text = `@${this.reply.user.username}@${this.reply.user.host} `; this.text = `@${this.reply.user.username}@${this.reply.user.host} `;
} }
@ -252,8 +274,10 @@ export default Vue.extend({
visibleUserIds: this.visibility == 'specified' ? this.visibleUsers.map(u => u.id) : undefined, visibleUserIds: this.visibility == 'specified' ? this.visibleUsers.map(u => u.id) : undefined,
viaMobile: viaMobile viaMobile: viaMobile
}).then(data => { }).then(data => {
this.$emit('note'); this.$emit('posted');
this.$destroy(); this.$nextTick(() => {
this.$destroy();
});
}).catch(err => { }).catch(err => {
this.posting = false; this.posting = false;
}); });

View File

@ -4,7 +4,7 @@
<span v-if="note.isHidden" style="opacity: 0.5">(%i18n:@private%)</span> <span v-if="note.isHidden" style="opacity: 0.5">(%i18n:@private%)</span>
<span v-if="note.deletedAt" style="opacity: 0.5">(%i18n:@deleted%)</span> <span v-if="note.deletedAt" style="opacity: 0.5">(%i18n:@deleted%)</span>
<a class="reply" v-if="note.replyId">%fa:reply%</a> <a class="reply" v-if="note.replyId">%fa:reply%</a>
<mk-note-html v-if="note.text" :text="note.text" :i="$store.state.i"/> <misskey-flavored-markdown v-if="note.text" :text="note.text" :i="$store.state.i"/>
<a class="rp" v-if="note.renoteId">RP: ...</a> <a class="rp" v-if="note.renoteId">RP: ...</a>
</div> </div>
<details v-if="note.media.length > 0"> <details v-if="note.media.length > 0">

View File

@ -45,8 +45,8 @@ export default Vue.extend({
this.connection = (this as any).os.stream.getConnection(); this.connection = (this as any).os.stream.getConnection();
this.connectionId = (this as any).os.stream.use(); this.connectionId = (this as any).os.stream.use();
this.connection.on('othello_invited', this.onOthelloInvited); this.connection.on('reversi_invited', this.onReversiInvited);
this.connection.on('othello_no_invites', this.onOthelloNoInvites); this.connection.on('reversi_no_invites', this.onReversiNoInvites);
const ago = (new Date().getTime() - new Date(this.$store.state.i.lastUsedAt).getTime()) / 1000; const ago = (new Date().getTime() - new Date(this.$store.state.i.lastUsedAt).getTime()) / 1000;
const isHisasiburi = ago >= 3600; const isHisasiburi = ago >= 3600;
@ -98,16 +98,16 @@ export default Vue.extend({
}, },
beforeDestroy() { beforeDestroy() {
if (this.$store.getters.isSignedIn) { if (this.$store.getters.isSignedIn) {
this.connection.off('othello_invited', this.onOthelloInvited); this.connection.off('reversi_invited', this.onReversiInvited);
this.connection.off('othello_no_invites', this.onOthelloNoInvites); this.connection.off('reversi_no_invites', this.onReversiNoInvites);
(this as any).os.stream.dispose(this.connectionId); (this as any).os.stream.dispose(this.connectionId);
} }
}, },
methods: { methods: {
onOthelloInvited() { onReversiInvited() {
this.hasGameInvitation = true; this.hasGameInvitation = true;
}, },
onOthelloNoInvites() { onReversiNoInvites() {
this.hasGameInvitation = false; this.hasGameInvitation = false;
} }
} }

View File

@ -19,7 +19,7 @@
<li><router-link to="/i/notifications" :data-active="$route.name == 'notifications'">%fa:R bell%%i18n:@notifications%<template v-if="hasUnreadNotification">%fa:circle%</template>%fa:angle-right%</router-link></li> <li><router-link to="/i/notifications" :data-active="$route.name == 'notifications'">%fa:R bell%%i18n:@notifications%<template v-if="hasUnreadNotification">%fa:circle%</template>%fa:angle-right%</router-link></li>
<li><router-link to="/i/messaging" :data-active="$route.name == 'messaging'">%fa:R comments%%i18n:@messaging%<template v-if="hasUnreadMessagingMessage">%fa:circle%</template>%fa:angle-right%</router-link></li> <li><router-link to="/i/messaging" :data-active="$route.name == 'messaging'">%fa:R comments%%i18n:@messaging%<template v-if="hasUnreadMessagingMessage">%fa:circle%</template>%fa:angle-right%</router-link></li>
<li v-if="$store.getters.isSignedIn && $store.state.i.isLocked"><router-link to="/i/received-follow-requests" :data-active="$route.name == 'received-follow-requests'">%fa:R envelope%%i18n:@follow-requests%<template v-if="$store.getters.isSignedIn && $store.state.i.pendingReceivedFollowRequestsCount">%fa:circle%</template>%fa:angle-right%</router-link></li> <li v-if="$store.getters.isSignedIn && $store.state.i.isLocked"><router-link to="/i/received-follow-requests" :data-active="$route.name == 'received-follow-requests'">%fa:R envelope%%i18n:@follow-requests%<template v-if="$store.getters.isSignedIn && $store.state.i.pendingReceivedFollowRequestsCount">%fa:circle%</template>%fa:angle-right%</router-link></li>
<li><router-link to="/othello" :data-active="$route.name == 'othello'">%fa:gamepad%%i18n:@game%<template v-if="hasGameInvitation">%fa:circle%</template>%fa:angle-right%</router-link></li> <li><router-link to="/reversi" :data-active="$route.name == 'reversi'">%fa:gamepad%%i18n:@game%<template v-if="hasGameInvitation">%fa:circle%</template>%fa:angle-right%</router-link></li>
</ul> </ul>
<ul> <ul>
<li><router-link to="/i/widgets" :data-active="$route.name == 'widgets'">%fa:R calendar-alt%%i18n:@widgets%%fa:angle-right%</router-link></li> <li><router-link to="/i/widgets" :data-active="$route.name == 'widgets'">%fa:R calendar-alt%%i18n:@widgets%%fa:angle-right%</router-link></li>
@ -66,14 +66,14 @@ export default Vue.extend({
this.connection = (this as any).os.stream.getConnection(); this.connection = (this as any).os.stream.getConnection();
this.connectionId = (this as any).os.stream.use(); this.connectionId = (this as any).os.stream.use();
this.connection.on('othello_invited', this.onOthelloInvited); this.connection.on('reversi_invited', this.onReversiInvited);
this.connection.on('othello_no_invites', this.onOthelloNoInvites); this.connection.on('reversi_no_invites', this.onReversiNoInvites);
} }
}, },
beforeDestroy() { beforeDestroy() {
if (this.$store.getters.isSignedIn) { if (this.$store.getters.isSignedIn) {
this.connection.off('othello_invited', this.onOthelloInvited); this.connection.off('reversi_invited', this.onReversiInvited);
this.connection.off('othello_no_invites', this.onOthelloNoInvites); this.connection.off('reversi_no_invites', this.onReversiNoInvites);
(this as any).os.stream.dispose(this.connectionId); (this as any).os.stream.dispose(this.connectionId);
} }
}, },
@ -83,10 +83,10 @@ export default Vue.extend({
if (query == null || query == '') return; if (query == null || query == '') return;
this.$router.push('/search?q=' + encodeURIComponent(query)); this.$router.push('/search?q=' + encodeURIComponent(query));
}, },
onOthelloInvited() { onReversiInvited() {
this.hasGameInvitation = true; this.hasGameInvitation = true;
}, },
onOthelloNoInvites() { onReversiNoInvites() {
this.hasGameInvitation = false; this.hasGameInvitation = false;
}, },
dark() { dark() {

View File

@ -1,7 +1,7 @@
<template> <template>
<mk-ui> <mk-ui>
<span slot="header">%fa:gamepad%オセロ</span> <span slot="header">%fa:gamepad%リバーシ</span>
<mk-othello v-if="!fetching" :init-game="game" @gamed="onGamed"/> <mk-reversi v-if="!fetching" :init-game="game" @gamed="onGamed"/>
</mk-ui> </mk-ui>
</template> </template>
@ -23,7 +23,7 @@ export default Vue.extend({
this.fetch(); this.fetch();
}, },
mounted() { mounted() {
document.title = 'Misskey オセロ'; document.title = 'Misskey リバーシ';
document.documentElement.style.background = '#fff'; document.documentElement.style.background = '#fff';
}, },
methods: { methods: {
@ -33,7 +33,7 @@ export default Vue.extend({
Progress.start(); Progress.start();
this.fetching = true; this.fetching = true;
(this as any).api('othello/games/show', { (this as any).api('reversi/games/show', {
gameId: this.$route.params.game gameId: this.$route.params.game
}).then(game => { }).then(game => {
this.game = game; this.game = game;
@ -43,7 +43,7 @@ export default Vue.extend({
}); });
}, },
onGamed(game) { onGamed(game) {
history.pushState(null, null, '/othello/' + game.id); history.pushState(null, null, '/reversi/' + game.id);
} }
} }
}); });

View File

@ -12,6 +12,8 @@
<ui-switch v-model="darkmode">%i18n:@dark-mode%</ui-switch> <ui-switch v-model="darkmode">%i18n:@dark-mode%</ui-switch>
<ui-switch v-model="$store.state.settings.circleIcons" @change="onChangeCircleIcons">%i18n:@circle-icons%</ui-switch> <ui-switch v-model="$store.state.settings.circleIcons" @change="onChangeCircleIcons">%i18n:@circle-icons%</ui-switch>
<ui-switch v-model="$store.state.settings.iLikeSushi" @change="onChangeILikeSushi">%i18n:common.i-like-sushi%</ui-switch>
<ui-switch v-model="$store.state.settings.reversiBoardLabels" @change="onChangeReversiBoardLabels">%i18n:common.show-reversi-board-labels%</ui-switch>
<div> <div>
<div>%i18n:@timeline%</div> <div>%i18n:@timeline%</div>
@ -174,6 +176,20 @@ export default Vue.extend({
}); });
}, },
onChangeILikeSushi(v) {
this.$store.dispatch('settings/set', {
key: 'iLikeSushi',
value: v
});
},
onChangeReversiBoardLabels(v) {
this.$store.dispatch('settings/set', {
key: 'reversiBoardLabels',
value: v
});
},
onChangeShowReplyTarget(v) { onChangeShowReplyTarget(v) {
this.$store.dispatch('settings/set', { this.$store.dispatch('settings/set', {
key: 'showReplyTarget', key: 'showReplyTarget',

View File

@ -0,0 +1,56 @@
<template>
<div class="azibmfpleajagva420swmu4c3r7ni7iw">
<h1>Misskeyで共有</h1>
<div>
<mk-signin v-if="!$store.getters.isSignedIn"/>
<mk-post-form v-else-if="!posted" :initial-text="text" :instant="true" @posted="posted = true"/>
<p v-if="posted" class="posted">%fa:check%</p>
</div>
<ui-button class="close" v-if="posted" @click="close">閉じる</ui-button>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
export default Vue.extend({
data() {
return {
posted: false,
text: new URLSearchParams(location.search).get('text')
};
},
methods: {
close() {
window.close();
}
}
});
</script>
<style lang="stylus" scoped>
.azibmfpleajagva420swmu4c3r7ni7iw
> h1
margin 8px 0
color #555
font-size 20px
text-align center
> div
max-width 500px
margin 0 auto
> .posted
display block
margin 0 auto
padding 64px
text-align center
background #fff
border-radius 6px
width calc(100% - 32px)
> .close
display block
margin 16px auto
width calc(100% - 32px)
</style>

View File

@ -18,7 +18,9 @@
<span class="username"><mk-acct :user="user"/></span> <span class="username"><mk-acct :user="user"/></span>
<span class="followed" v-if="user.isFollowed">%i18n:@follows-you%</span> <span class="followed" v-if="user.isFollowed">%i18n:@follows-you%</span>
</div> </div>
<div class="description">{{ user.description }}</div> <div class="description">
<misskey-flavored-markdown v-if="user.description" :text="user.description" :i="$store.state.i"/>
</div>
<div class="info"> <div class="info">
<p class="location" v-if="user.host === null && user.profile.location"> <p class="location" v-if="user.host === null && user.profile.location">
%fa:map-marker%{{ user.profile.location }} %fa:map-marker%{{ user.profile.location }}

View File

@ -14,6 +14,9 @@
<div class="tl"> <div class="tl">
<mk-welcome-timeline/> <mk-welcome-timeline/>
</div> </div>
<div class="hashtags">
<router-link v-for="tag in tags" :key="tag" :to="`/tags/${ tag }`" :title="tag">#{{ tag }}</router-link>
</div>
<div class="stats" v-if="stats"> <div class="stats" v-if="stats">
<span>%fa:user% {{ stats.originalUsersCount | number }}</span> <span>%fa:user% {{ stats.originalUsersCount | number }}</span>
<span>%fa:pencil-alt% {{ stats.originalNotesCount | number }}</span> <span>%fa:pencil-alt% {{ stats.originalNotesCount | number }}</span>
@ -37,13 +40,18 @@ export default Vue.extend({
stats: null, stats: null,
host, host,
name, name,
description description,
tags: []
}; };
}, },
created() { created() {
(this as any).api('stats').then(stats => { (this as any).api('stats').then(stats => {
this.stats = stats; this.stats = stats;
}); });
(this as any).api('hashtags/trend').then(stats => {
this.tags = stats.map(x => x.tag);
});
} }
}); });
</script> </script>
@ -116,12 +124,22 @@ export default Vue.extend({
box-shadow 0 1px 3px rgba(#000, 0.075), inset 0 0 5px rgba(#000, 0.2) box-shadow 0 1px 3px rgba(#000, 0.075), inset 0 0 5px rgba(#000, 0.2)
> .tl > .tl
margin 16px 0
> * > *
max-height 300px max-height 300px
border-radius 6px border-radius 6px
overflow auto overflow auto
-webkit-overflow-scrolling touch -webkit-overflow-scrolling touch
> .hashtags
padding 16px 0
border solid 2px #ddd
border-radius 8px
> *
margin 0 16px
> .stats > .stats
margin 16px 0 margin 16px 0
padding 8px padding 8px

View File

@ -18,7 +18,9 @@ const defaultSettings = {
showRenotedMyNotes: true, showRenotedMyNotes: true,
loadRemoteMedia: true, loadRemoteMedia: true,
disableViaMobile: false, disableViaMobile: false,
memo: null memo: null,
iLikeSushi: false,
reversiBoardLabels: false
}; };
const defaultDeviceSettings = { const defaultDeviceSettings = {

View File

@ -4,11 +4,39 @@
"start_url": "/", "start_url": "/",
"display": "standalone", "display": "standalone",
"background_color": "#313a42", "background_color": "#313a42",
"icons": { "icons": [
"16": "/assets/favicon/16.png", {
"32": "/assets/favicon/32.png", "src": "/assets/icons/16.png",
"64": "/assets/favicon/64.png", "sizes": "16x16",
"128": "/assets/favicon/128.png", "type": "image/png"
"256": "/assets/favicon/256.png" },
{
"src": "/assets/icons/32.png",
"sizes": "32x32",
"type": "image/png"
},
{
"src": "/assets/icons/64.png",
"sizes": "64x64",
"type": "image/png"
},
{
"src": "/assets/icons/128.png",
"sizes": "128x128",
"type": "image/png"
},
{
"src": "/assets/icons/192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/assets/icons/256.png",
"sizes": "256x256",
"type": "image/png"
}
],
"share_target": {
"url_template": "share?text=【{title}】%0A{text}%0A{url}"
} }
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

View File

@ -19,9 +19,10 @@ import generateVars from '../vars';
const langs = Object.keys(locales); const langs = Object.keys(locales);
const kebab = string => string.replace(/([a-z])([A-Z])/g, '$1-$2').replace(/\s+/g, '-').toLowerCase(); const kebab = (string: string) => string.replace(/([a-z])([A-Z])/g, '$1-$2').replace(/\s+/g, '-').toLowerCase();
const parseParam = param => { // WIP type
const parseParam = (param: any) => {
const id = param.type.match(/^id\((.+?)\)|^id/); const id = param.type.match(/^id\((.+?)\)|^id/);
const entity = param.type.match(/^entity\((.+?)\)/); const entity = param.type.match(/^entity\((.+?)\)/);
const isObject = /^object/.test(param.type); const isObject = /^object/.test(param.type);
@ -57,7 +58,7 @@ const parseParam = param => {
return param; return param;
}; };
const sortParams = params => { const sortParams = (params: Array<{name: string}>) => {
params.sort((a, b) => { params.sort((a, b) => {
if (a.name < b.name) if (a.name < b.name)
return -1; return -1;
@ -68,14 +69,15 @@ const sortParams = params => {
return params; return params;
}; };
const extractDefs = params => { // WIP type
let defs = []; const extractDefs = (params: any[]) => {
let defs: any[] = [];
params.forEach(param => { params.forEach(param => {
if (param.def) { if (param.def) {
defs.push({ defs.push({
name: param.defName, name: param.defName,
params: sortParams(param.def.map(p => parseParam(p))) params: sortParams(param.def.map((p: any) => parseParam(p)))
}); });
const childDefs = extractDefs(param.def); const childDefs = extractDefs(param.def);
@ -109,8 +111,10 @@ gulp.task('doc:api:endpoints', async () => {
path: ep.endpoint path: ep.endpoint
}, },
desc: ep.desc, desc: ep.desc,
// @ts-ignore
params: sortParams(ep.params.map(p => parseParam(p))), params: sortParams(ep.params.map(p => parseParam(p))),
paramDefs: extractDefs(ep.params), paramDefs: extractDefs(ep.params),
// @ts-ignore
res: ep.res ? sortParams(ep.res.map(p => parseParam(p))) : null, res: ep.res ? sortParams(ep.res.map(p => parseParam(p))) : null,
resDefs: ep.res ? extractDefs(ep.res) : null, resDefs: ep.res ? extractDefs(ep.res) : null,
}; };
@ -155,7 +159,8 @@ gulp.task('doc:api:entities', async () => {
const vars = { const vars = {
name: entity.name, name: entity.name,
desc: entity.desc, desc: entity.desc,
props: sortParams(entity.props.map(p => parseParam(p))), // WIP type
props: sortParams(entity.props.map((p: any) => parseParam(p))),
propDefs: extractDefs(entity.props), propDefs: extractDefs(entity.props),
}; };
langs.forEach(lang => { langs.forEach(lang => {

View File

@ -8,8 +8,8 @@ import * as glob from 'glob';
import * as gulp from 'gulp'; import * as gulp from 'gulp';
import * as pug from 'pug'; import * as pug from 'pug';
import * as mkdirp from 'mkdirp'; import * as mkdirp from 'mkdirp';
import stylus = require('gulp-stylus'); const stylus = require('gulp-stylus');
import cssnano = require('gulp-cssnano'); const cssnano = require('gulp-cssnano');
import I18nReplacer from '../../build/i18n'; import I18nReplacer from '../../build/i18n';
import fa from '../../build/fa'; import fa from '../../build/fa';

View File

@ -38,7 +38,7 @@ export default async function(): Promise<{ [key: string]: any }> {
vars['docs'][name]['title'][lang] = fs.readFileSync(x, 'utf-8').match(/^h1 (.+?)\r?\n/)[1]; vars['docs'][name]['title'][lang] = fs.readFileSync(x, 'utf-8').match(/^h1 (.+?)\r?\n/)[1];
}); });
vars['kebab'] = string => string.replace(/([a-z])([A-Z])/g, '$1-$2').replace(/\s+/g, '-').toLowerCase(); vars['kebab'] = (string: string) => string.replace(/([a-z])([A-Z])/g, '$1-$2').replace(/\s+/g, '-').toLowerCase();
vars['config'] = config; vars['config'] = config;

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