Compare commits
403 Commits
Author | SHA1 | Date | |
---|---|---|---|
4c4cb2bb17 | |||
fe319a529f | |||
91bea1f6c7 | |||
01745f7c65 | |||
5d3943ffa8 | |||
e66d7babc5 | |||
80e5645a84 | |||
a766faeae9 | |||
4d2d226446 | |||
61e83b10c3 | |||
ed675f0956 | |||
9cce8ab214 | |||
daa409cd82 | |||
9d65415fdc | |||
8c40917cc2 | |||
871f886702 | |||
f19075c50a | |||
71da205ab7 | |||
a34cc47a11 | |||
cbddaf1d19 | |||
1f1ed2da4c | |||
8d81bd0dc0 | |||
5773a5bfa6 | |||
7275a48102 | |||
8f84dd610c | |||
f1f466ed23 | |||
0ca5237139 | |||
20549bfdf0 | |||
d692bb3c52 | |||
44cd1e9223 | |||
f0fec654ff | |||
4e04e5e0c0 | |||
4991fb2769 | |||
4d90d554f8 | |||
e5468713ac | |||
77013f982d | |||
0460cdedd7 | |||
73f5bf69e8 | |||
750c0d7df2 | |||
2fcebdd281 | |||
e4e65a4cd5 | |||
e010ecb03f | |||
fc74db668d | |||
1bac3418b4 | |||
53df8c48b7 | |||
92702fe47e | |||
017c4c12cd | |||
830d246ba4 | |||
6b33afa916 | |||
69a3efd534 | |||
2d0adb8f4c | |||
da9d8cb138 | |||
2acaca8582 | |||
11cf82c6a4 | |||
1ef66c962a | |||
03f20599ba | |||
d150b10b3e | |||
c4f323aae3 | |||
8297f8ccd0 | |||
f336241576 | |||
f6d9a7e7c3 | |||
80d1ee7543 | |||
e55a254353 | |||
555a0f276c | |||
792632d726 | |||
9cac293efc | |||
cd8bfca29c | |||
b5b437b878 | |||
cc2947063a | |||
2864a9027f | |||
e11f547308 | |||
cdce7aa5e2 | |||
82cea185b2 | |||
f92a4bb195 | |||
9f4f88df9c | |||
e69803cbd1 | |||
f164661ef2 | |||
c9d993b838 | |||
65f35dc9f4 | |||
b600d462c1 | |||
fa5a82c9ab | |||
a9885be09e | |||
7b011f4a91 | |||
41c404abe6 | |||
2089a761cf | |||
0ee2df010d | |||
466844c016 | |||
bbf9a08649 | |||
c985c66652 | |||
f9dc96320e | |||
42552789fe | |||
1a2ffeb0b5 | |||
4f75493249 | |||
42193695fb | |||
02af0de21e | |||
5f8e10e524 | |||
cee93d746c | |||
08704a383f | |||
7c596be638 | |||
07265f594b | |||
392cb1ba89 | |||
e6f33e997f | |||
a44387f250 | |||
b1b1b7592b | |||
ca668898f4 | |||
fcd437c89f | |||
7f7d7edc7f | |||
bd827f946a | |||
ad8aa1c179 | |||
3ebaf83ce0 | |||
39b1978ff3 | |||
bddff17e5e | |||
0ac9120064 | |||
d90f75425f | |||
dec7d537dc | |||
11e95ea092 | |||
c5e9b69eb3 | |||
120c11b181 | |||
a1ae832129 | |||
3a4833818f | |||
8814fc9c9c | |||
e6e02ece89 | |||
9059c149dd | |||
7d8e70b2ac | |||
89105f5641 | |||
1813d17b4c | |||
ce27b36fd0 | |||
e635a87628 | |||
80c52433cc | |||
1472f0b141 | |||
4d914f5c0a | |||
0318f7344f | |||
413fbb3d0c | |||
8bc47baf4f | |||
e3f6d42a47 | |||
8230935fd3 | |||
f968d05ea0 | |||
d6e5dc2167 | |||
460147fea2 | |||
cea44834bb | |||
1af50fd7b8 | |||
b18013025f | |||
acdf7c244f | |||
399eb60809 | |||
ed67e3506b | |||
a72b6745aa | |||
24086e9023 | |||
c3d4b5ad38 | |||
cc618a83e5 | |||
9eaa0b27db | |||
a8835a679e | |||
656bc6df84 | |||
019aaf7d82 | |||
76bafbf398 | |||
030bcb99b1 | |||
d8ff37fc45 | |||
2fcc3bb1ea | |||
2e680c3d1e | |||
af0a0ef41b | |||
bbfccb0bbf | |||
c89eb5d69f | |||
ebde84214e | |||
03fbae7b6d | |||
f90e9596d4 | |||
944f9524e2 | |||
c61050244e | |||
90337adbbc | |||
7b67e41c5b | |||
91db24fcfc | |||
bb53db905f | |||
0e9a1efe46 | |||
289cd3e200 | |||
e0f847e539 | |||
c2842b486e | |||
7235ade42f | |||
850be2df1d | |||
d504501440 | |||
208392f12c | |||
0fe036c640 | |||
a40c41f0b0 | |||
4affa5b710 | |||
4eb574d991 | |||
2c1577ea24 | |||
b87e7e50b6 | |||
36215d50bd | |||
5ff1245d0c | |||
ebd189fb27 | |||
6f724827bd | |||
b6a0982012 | |||
c3e375e8a5 | |||
302409fd83 | |||
a2046461c1 | |||
6660c34120 | |||
b88ccf0ddd | |||
b898bbf94c | |||
787e89eb95 | |||
1022c2c438 | |||
ba21c62ed4 | |||
bfe66c919b | |||
3dacf7f661 | |||
c0a3ae2612 | |||
da612ef789 | |||
df9cb7cf6e | |||
9c1a26110e | |||
0883d18a6c | |||
c7246c61a5 | |||
c5a1431fc0 | |||
f0118a0dff | |||
cffe96e46f | |||
a9256578f0 | |||
05ed202904 | |||
963b63389a | |||
e04706dc74 | |||
04d4ce5ce1 | |||
24cf3730fa | |||
0700be86e2 | |||
7cca509eb3 | |||
7d7193cb63 | |||
1cf10d05ff | |||
2ec25a7729 | |||
2a9065a61e | |||
7518e30dcf | |||
dc3c80e3ce | |||
a25f61f6be | |||
e70fb71a04 | |||
f499630c2b | |||
43319a8588 | |||
d62b943c5d | |||
8baddf2ea3 | |||
600482660b | |||
72ab5c143e | |||
96ab0e7b4c | |||
b60903e2b4 | |||
b4f4d3f267 | |||
6e017c86e8 | |||
afcfc2dca5 | |||
59e22a12a9 | |||
b740ac3e01 | |||
9719f0df03 | |||
d4be599538 | |||
f88195c90a | |||
3b33f7e752 | |||
67a37294f7 | |||
fd88955696 | |||
9d248dbb5a | |||
20ec4104c6 | |||
6c232d116d | |||
2ef78bcd40 | |||
94ce658ab9 | |||
d8cf4cd341 | |||
0360337df9 | |||
119d38ea08 | |||
bee77afb7f | |||
16d4b16872 | |||
951b2346ab | |||
b29ff0e94b | |||
c8dd8341ca | |||
8bcf44bc16 | |||
50b37a8420 | |||
22df795733 | |||
7e3bf06db1 | |||
6630ca595c | |||
5d01e19ce7 | |||
56df89f8dd | |||
13de984ce3 | |||
15fc0e30d7 | |||
4289c11185 | |||
a3f564e702 | |||
f6734a0c98 | |||
72fb416239 | |||
833f5b09d2 | |||
b21b21f30a | |||
2f77a3f6d2 | |||
0bda655452 | |||
4f80bb7031 | |||
fbe7b3cc9b | |||
8402f0abd7 | |||
149b2ee5a7 | |||
f9d5af0600 | |||
72c4ccaee8 | |||
92999dcaf2 | |||
5bbd318518 | |||
8807894890 | |||
63b7820717 | |||
9e7e2d6977 | |||
89e4c280ae | |||
b6c9f29be4 | |||
74cbbc84ed | |||
ead4197670 | |||
4fc69ccdc8 | |||
f556cb44b9 | |||
45b540d375 | |||
af2d36a3c9 | |||
42a4f92cfa | |||
ccb9ed3489 | |||
773b2aa3d1 | |||
30d5b8d65b | |||
763676a18c | |||
e166ad6780 | |||
034c96d070 | |||
f34f8d304c | |||
944000c05c | |||
e2503cdb47 | |||
52db63bca2 | |||
55dfd9e2a1 | |||
d193cbf2b7 | |||
bdec56a543 | |||
e0a6d9740c | |||
0ce9c057e1 | |||
12a2fdbc20 | |||
57c294bc89 | |||
9758757805 | |||
f9350fa35f | |||
e120da4ecd | |||
328a10b70c | |||
1ed97c8deb | |||
91b970e2aa | |||
99af1bb479 | |||
11ddcbdee3 | |||
6e8a1086d8 | |||
c78945436e | |||
6eff8fde74 | |||
726d5a177e | |||
33495b5cb3 | |||
fe159a13a9 | |||
22a1dc0566 | |||
02e6b732e9 | |||
cc6fa135ac | |||
5747732156 | |||
581d1617d8 | |||
6152fd20bf | |||
19300ca65c | |||
2f3d744e19 | |||
724e812972 | |||
9a6246fd4e | |||
34f44de59c | |||
16e446c121 | |||
8f232a9da9 | |||
ebeb7f8578 | |||
f790673068 | |||
335ab5ab54 | |||
00e0d6ce2c | |||
414fb6d303 | |||
9c35a12211 | |||
bb4fe5174f | |||
3ffd6ff5a2 | |||
b05feb5bf7 | |||
fa171f237d | |||
f2ccb684eb | |||
ffea6522ac | |||
3d40a7df00 | |||
638c41476b | |||
c6d3088374 | |||
0f93be9dd4 | |||
f59982c9c5 | |||
dff67a5e54 | |||
6adcc3b2ed | |||
877ed3663c | |||
6000a82917 | |||
6805f9b3e0 | |||
1366c785f9 | |||
70540b4500 | |||
0967f23b6e | |||
1f7d66169c | |||
af501f5eeb | |||
60be60c923 | |||
48746101e0 | |||
af9c5c6ab7 | |||
602284d38c | |||
26898142c2 | |||
b0a8d7abe9 | |||
dc2b266b75 | |||
07bbd9506a | |||
14bb218287 | |||
29f238c929 | |||
a39a1d4fa5 | |||
15117c63f5 | |||
507ffb6fc6 | |||
6b2e0164cf | |||
02e06eb1de | |||
1b50f78733 | |||
ead629407c | |||
0abbc9e7dd | |||
37681e859e | |||
caabdc68f3 | |||
9e97eaf24d | |||
4cd06a789b | |||
a3ffd968de | |||
0cf40563aa | |||
3e7e7f864b | |||
6ae415e36a | |||
6cefa3ae26 | |||
70de3af3ea | |||
66ed814527 | |||
e12cc3b7a8 | |||
93ea19d7ad | |||
79d592b431 | |||
c9c3a0be82 | |||
f04be199dd | |||
f36cb1cc66 | |||
a5597e3df9 | |||
7f4c28053e | |||
ea24043b22 |
@ -1,3 +1,9 @@
|
|||||||
|
# インスタンス名
|
||||||
|
name:
|
||||||
|
|
||||||
|
# インスタンスの紹介
|
||||||
|
description:
|
||||||
|
|
||||||
# サーバーのメンテナ情報
|
# サーバーのメンテナ情報
|
||||||
maintainer:
|
maintainer:
|
||||||
# メンテナの名前
|
# メンテナの名前
|
||||||
@ -55,3 +61,7 @@ twitter:
|
|||||||
|
|
||||||
# インテグレーション用アプリのコンシューマーシークレット
|
# インテグレーション用アプリのコンシューマーシークレット
|
||||||
consumer_secret:
|
consumer_secret:
|
||||||
|
|
||||||
|
# true にすると、リモートのファイルをキャッシュしなくなります(直リンクします)。
|
||||||
|
# ストレージ容量を節約することができますが、「リモートメディアを表示しない」設定をオンにしているユーザーは、リモートの画像などは見えなくなります。
|
||||||
|
preventCache: false
|
||||||
|
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -1,3 +1,4 @@
|
|||||||
*.svg -diff -text
|
*.svg -diff -text
|
||||||
*.psd -diff -text
|
*.psd -diff -text
|
||||||
*.ai -diff -text
|
*.ai -diff -text
|
||||||
|
yarn.lock -diff -text
|
||||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -11,4 +11,4 @@ npm-debug.log
|
|||||||
run.bat
|
run.bat
|
||||||
api-docs.json
|
api-docs.json
|
||||||
package-lock.json
|
package-lock.json
|
||||||
yarn.lock
|
*.log
|
||||||
|
28
CHANGELOG.md
Normal file
28
CHANGELOG.md
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
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
|
||||||
|
-----
|
||||||
|
|
||||||
|
### Migration
|
||||||
|
|
||||||
|
起動する前に、`node cli/recount-stats`してください。
|
||||||
|
|
||||||
|
Please run `node cli/recount-stats` before launch.
|
41
README.md
41
README.md
@ -12,15 +12,18 @@
|
|||||||
> Lead Maintainer: [syuilo][syuilo-link]
|
> Lead Maintainer: [syuilo][syuilo-link]
|
||||||
|
|
||||||
**[Misskey](https://misskey.xyz)** is a completely open source,
|
**[Misskey](https://misskey.xyz)** is a completely open source,
|
||||||
ultimately sophisticated new type of mini-blog based SNS.
|
ultimately sophisticated professional microblogging software.
|
||||||
|
|
||||||
<a href="https://www.patreon.com/syuilo"><img src="https://c5.patreon.com/external/logo/become_a_patron_button@2x.png" alt="Become a Patron!" width="160" /></a>
|
<a href="https://www.patreon.com/syuilo"><img src="https://c5.patreon.com/external/logo/become_a_patron_button@2x.png" alt="Become a Patron!" width="160" /></a>
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
:sparkles: Features
|
:sparkles: Features
|
||||||
----------------------------------------------------------------
|
----------------------------------------------------------------
|
||||||
* Reactions
|
* Reactions
|
||||||
* User lists
|
* User lists
|
||||||
* Cusromizable column view (known as MisskeyDeck)
|
* Customizable column view (known as MisskeyDeck)
|
||||||
|
* and widgets!
|
||||||
* Private messages
|
* Private messages
|
||||||
* Mute
|
* Mute
|
||||||
* Streaming
|
* Streaming
|
||||||
@ -46,18 +49,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]
|
||||||
|
|
||||||
:mortar_board: Notable contributors
|
| ![][ooo-icon] |
|
||||||
----------------------------------------------------------------
|
|:-:|
|
||||||
| ![syuilo][syuilo-icon] | ![Morisawa Aya][ayamorisawa-icon] | ![otofune][otofune-icon] | ![akihikodaki][akihikodaki-icon] | ![tamaina][tamaina-icon] | ![rinsuki][rinsuki-icon] |
|
| [ooo][ooo-link] |
|
||||||
|:-:|:-:|:-:|:-:|:-:|:-:|
|
|
||||||
| [syuilo][syuilo-link]<br>Owner | [Aya Morisawa][ayamorisawa-link]<br>Collaborator | [otofune][otofune-link]<br>Collaborator | [akihikodaki][akihikodaki-link] | [tamaina][tamaina-link] | [rinsuki][rinsuki-link] |
|
|
||||||
|
|
||||||
[List of all contributors](https://github.com/syuilo/misskey/graphs/contributors)
|
|
||||||
|
|
||||||
### :earth_americas: Translators
|
|
||||||
| ![][mirro-san-icon] | ![][Conan-kun-icon] | ![][m4sk1n-icon] |
|
|
||||||
|:-:|:-:|:-:|
|
|
||||||
| [Mirro][mirro-san-link]<br>English, French | [Asriel][Conan-kun-link]<br>English, French | [Marcin Mikołajczak][m4sk1n-link]<br>Polish |
|
|
||||||
|
|
||||||
:four_leaf_clover: Copyright
|
:four_leaf_clover: Copyright
|
||||||
----------------------------------------------------------------
|
----------------------------------------------------------------
|
||||||
@ -85,23 +79,8 @@ Misskey is an open-source software licensed under [GNU AGPLv3](LICENSE).
|
|||||||
[sponsors-image]: https://opencollective.com/misskey/sponsors.svg
|
[sponsors-image]: https://opencollective.com/misskey/sponsors.svg
|
||||||
[support-url]: https://opencollective.com/misskey#support
|
[support-url]: https://opencollective.com/misskey#support
|
||||||
|
|
||||||
<!-- Contributors Info -->
|
|
||||||
[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
|
||||||
[ayamorisawa-link]: https://github.com/ayamorisawa
|
|
||||||
[ayamorisawa-icon]: https://avatars0.githubusercontent.com/u/10798641?v=3&s=70
|
|
||||||
[otofune-link]: https://github.com/otofune
|
|
||||||
[otofune-icon]: https://avatars0.githubusercontent.com/u/15062473?v=3&s=70
|
|
||||||
[akihikodaki-link]: https://github.com/akihikodaki
|
|
||||||
[akihikodaki-icon]: https://avatars2.githubusercontent.com/u/17036990?s=70&v=4
|
|
||||||
[rinsuki-link]: https://github.com/rinsuki
|
|
||||||
[rinsuki-icon]: https://avatars0.githubusercontent.com/u/6533808?s=70&v=4
|
|
||||||
[tamaina-link]: https://github.com/tamaina
|
|
||||||
[tamaina-icon]: https://avatars1.githubusercontent.com/u/7973572?s=70&v=4
|
|
||||||
|
|
||||||
[mirro-san-link]: https://github.com/mirro-san
|
[ooo-link]: https://www.patreon.com/user/creators?u=11601413
|
||||||
[mirro-san-icon]: https://avatars1.githubusercontent.com/u/17948612?s=70&v=4
|
[ooo-icon]: https://c10.patreonusercontent.com/3/eyJ2IjoiMSIsInciOjIwMH0%3D/patreon-media/user/11601413/20cb15f209924302b399b99d3c98b850?token-time=2145916800&token-hash=IO31nK6VZCMWBWU2VAk2c824BX2QZ4DNPKyHHZXS0iw%3D
|
||||||
[Conan-kun-link]: https://github.com/Conan-kun
|
|
||||||
[Conan-kun-icon]: https://avatars3.githubusercontent.com/u/30003708?s=70&v=4
|
|
||||||
[m4sk1n-link]: https://github.com/m4sk1n
|
|
||||||
[m4sk1n-icon]: https://avatars3.githubusercontent.com/u/21127288?s=70&v=4
|
|
||||||
|
BIN
assets/icons/128.png
Normal file
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
BIN
assets/icons/16.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 446 B |
BIN
assets/icons/192.png
Normal file
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
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
BIN
assets/icons/32.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 774 B |
BIN
assets/icons/64.png
Normal file
BIN
assets/icons/64.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
42
cli/recount-stats.js
Normal file
42
cli/recount-stats.js
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
const { default: Note } = require('../built/models/note');
|
||||||
|
const { default: Meta } = require('../built/models/meta');
|
||||||
|
const { default: User } = require('../built/models/user');
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
const meta = await Meta.findOne({});
|
||||||
|
|
||||||
|
const notesCount = await Note.count();
|
||||||
|
|
||||||
|
const usersCount = await User.count();
|
||||||
|
|
||||||
|
const originalNotesCount = await Note.count({
|
||||||
|
'_user.host': null
|
||||||
|
});
|
||||||
|
|
||||||
|
const originalUsersCount = await User.count({
|
||||||
|
host: null
|
||||||
|
});
|
||||||
|
|
||||||
|
const stats = {
|
||||||
|
notesCount,
|
||||||
|
usersCount,
|
||||||
|
originalNotesCount,
|
||||||
|
originalUsersCount
|
||||||
|
};
|
||||||
|
|
||||||
|
if (meta) {
|
||||||
|
await Meta.update({}, {
|
||||||
|
$set: {
|
||||||
|
stats
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await Meta.insert({
|
||||||
|
stats
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
main().then(() => {
|
||||||
|
console.log('done');
|
||||||
|
}).catch(console.error);
|
12
cli/update-remote-user.js
Normal file
12
cli/update-remote-user.js
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
const updatePerson = require('../built/remote/activitypub/models/person').updatePerson;
|
||||||
|
|
||||||
|
const args = process.argv.slice(2);
|
||||||
|
const user = args[0];
|
||||||
|
|
||||||
|
console.log(`Updating ${user}...`);
|
||||||
|
|
||||||
|
updatePerson(user).then(() => {
|
||||||
|
console.log(`Updated ${user}`);
|
||||||
|
}, e => {
|
||||||
|
console.error(e);
|
||||||
|
});
|
@ -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';
|
||||||
|
232
locales/de.yml
232
locales/de.yml
@ -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:
|
||||||
@ -57,30 +57,36 @@ common:
|
|||||||
memo: "Notizen"
|
memo: "Notizen"
|
||||||
trends: "Trends"
|
trends: "Trends"
|
||||||
photo-stream: "Bilder"
|
photo-stream: "Bilder"
|
||||||
|
posts-monitor: "投稿チャート"
|
||||||
slideshow: "Diashow"
|
slideshow: "Diashow"
|
||||||
version: "Version"
|
version: "Version"
|
||||||
broadcast: "ブロードキャスト"
|
broadcast: "ブロードキャスト"
|
||||||
notifications: "Benachrichtigungen"
|
notifications: "Benachrichtigungen"
|
||||||
users: "Empfohlene Benutzer"
|
users: "Empfohlene Benutzer"
|
||||||
polls: "Umfragen"
|
polls: "アンケート"
|
||||||
post-form: "投稿フォーム"
|
post-form: "Beitragsform"
|
||||||
messaging: "Nachrichten"
|
messaging: "Nachrichten"
|
||||||
server: "Server-Info"
|
server: "Server-Info"
|
||||||
donation: "Spenden"
|
donation: "Spenden"
|
||||||
nav: "Navigation"
|
nav: "Navigation"
|
||||||
tips: "Tipps"
|
tips: "Tipps"
|
||||||
|
hashtags: "ハッシュタグ"
|
||||||
deck:
|
deck:
|
||||||
widgets: "ウィジェット"
|
widgets: "Widget hinzufügen:"
|
||||||
home: "ホーム"
|
home: "Startseite"
|
||||||
local: "ローカル"
|
local: "Lokal"
|
||||||
global: "グローバル"
|
global: "Global"
|
||||||
notifications: "通知"
|
notifications: "Mitteilungen"
|
||||||
list: "リスト"
|
list: "Listen"
|
||||||
swap-left: "左に移動"
|
swap-left: "Nach links"
|
||||||
swap-right: "右に移動"
|
swap-right: "Nach rechts"
|
||||||
remove: "カラムを削除"
|
swap-up: "Nach oben"
|
||||||
add-column: "カラムを追加"
|
swap-down: "Nach unten"
|
||||||
rename: "名前を変更"
|
remove: "Spalte löschen"
|
||||||
|
add-column: "Eine Spalte hinzufügen"
|
||||||
|
rename: "Umbenennen"
|
||||||
|
stack-left: "Nach links schichten"
|
||||||
|
pop-right: "右に出す"
|
||||||
common/views/components/connect-failed.vue:
|
common/views/components/connect-failed.vue:
|
||||||
title: "Verbindung zum Server ist fehlgeschlagen"
|
title: "Verbindung zum Server ist fehlgeschlagen"
|
||||||
description: "Es gibt entweder ein Problem mit deiner Internetverbindung, der Server ist nicht erreichbar oder wird gerade gewartet. Bitte versuche es später noch einmal."
|
description: "Es gibt entweder ein Problem mit deiner Internetverbindung, der Server ist nicht erreichbar oder wird gerade gewartet. Bitte versuche es später noch einmal."
|
||||||
@ -199,7 +205,7 @@ common/views/components/uploader.vue:
|
|||||||
common/views/components/visibility-chooser.vue:
|
common/views/components/visibility-chooser.vue:
|
||||||
public: "Öffentlich"
|
public: "Öffentlich"
|
||||||
home: "Home"
|
home: "Home"
|
||||||
home-desc: "ホームタイムラインにのみ公開"
|
home-desc: "Nur auf die Startseite posten"
|
||||||
followers: "Folgende"
|
followers: "Folgende"
|
||||||
followers-desc: "Nur für diejenigen sichtbar, die dir folgen"
|
followers-desc: "Nur für diejenigen sichtbar, die dir folgen"
|
||||||
specified: "Direkt"
|
specified: "Direkt"
|
||||||
@ -216,6 +222,13 @@ common/views/widgets/donation.vue:
|
|||||||
common/views/widgets/photo-stream.vue:
|
common/views/widgets/photo-stream.vue:
|
||||||
title: "Fotostream"
|
title: "Fotostream"
|
||||||
no-photos: "Keine Fotos"
|
no-photos: "Keine Fotos"
|
||||||
|
common/views/widgets/posts-monitor.vue:
|
||||||
|
title: "投稿チャート"
|
||||||
|
toggle: "表示を切り替え"
|
||||||
|
common/views/widgets/hashtags.vue:
|
||||||
|
title: "ハッシュタグ"
|
||||||
|
count: "{}人が投稿"
|
||||||
|
empty: "トレンドなし"
|
||||||
common/views/widgets/server.vue:
|
common/views/widgets/server.vue:
|
||||||
title: "Serverinformationen"
|
title: "Serverinformationen"
|
||||||
toggle: "Sicht umschalten"
|
toggle: "Sicht umschalten"
|
||||||
@ -260,7 +273,7 @@ desktop/views/components/drive.file.vue:
|
|||||||
rename: "Umbenennen"
|
rename: "Umbenennen"
|
||||||
copy-url: "URL kopieren"
|
copy-url: "URL kopieren"
|
||||||
download: "Download"
|
download: "Download"
|
||||||
else-files: "その他..."
|
else-files: "Anderes…"
|
||||||
set-as-avatar: "Als Avatar festlegen"
|
set-as-avatar: "Als Avatar festlegen"
|
||||||
set-as-banner: "Setze als Banner"
|
set-as-banner: "Setze als Banner"
|
||||||
open-in-app: "In der App öffnen"
|
open-in-app: "In der App öffnen"
|
||||||
@ -302,10 +315,10 @@ desktop/views/components/drive.vue:
|
|||||||
upload: "Eine Datei hochladen"
|
upload: "Eine Datei hochladen"
|
||||||
url-upload: "Von einer URL hochladen"
|
url-upload: "Von einer URL hochladen"
|
||||||
desktop/views/components/follow-button.vue:
|
desktop/views/components/follow-button.vue:
|
||||||
following: "フォロー中"
|
following: "Folge ich"
|
||||||
follow: "フォロー"
|
follow: "Folgen"
|
||||||
request-pending: "フォロー許可待ち"
|
request-pending: "Ausstehend"
|
||||||
follow-request: "フォロー申請"
|
follow-request: "Follower-Anfragen"
|
||||||
desktop/views/components/followers-window.vue:
|
desktop/views/components/followers-window.vue:
|
||||||
followers: "{} のフォロワー"
|
followers: "{} のフォロワー"
|
||||||
desktop/views/components/followers.vue:
|
desktop/views/components/followers.vue:
|
||||||
@ -313,18 +326,18 @@ desktop/views/components/followers.vue:
|
|||||||
desktop/views/components/following-window.vue:
|
desktop/views/components/following-window.vue:
|
||||||
following: "{} のフォロー"
|
following: "{} のフォロー"
|
||||||
desktop/views/components/following.vue:
|
desktop/views/components/following.vue:
|
||||||
empty: "フォロー中のユーザーはいないようです。"
|
empty: "Du folgst niemanden"
|
||||||
desktop/views/components/friends-maker.vue:
|
desktop/views/components/friends-maker.vue:
|
||||||
title: "気になるユーザーをフォロー:"
|
title: "Wem folgen?"
|
||||||
empty: "おすすめのユーザーは見つかりませんでした。"
|
empty: "Der ausgewählte Benutzer konnte nicht gefunden werden."
|
||||||
fetching: "読み込んでいます"
|
fetching: "Lade…"
|
||||||
refresh: "もっと見る"
|
refresh: "Mehr"
|
||||||
close: "閉じる"
|
close: "Schließen"
|
||||||
desktop/views/components/game-window.vue:
|
desktop/views/components/game-window.vue:
|
||||||
game: "オセロ"
|
game: "Reversi"
|
||||||
desktop/views/components/home.vue:
|
desktop/views/components/home.vue:
|
||||||
done: "完了"
|
done: "Verbunden"
|
||||||
add-widget: "ウィジェットを追加:"
|
add-widget: "Widget hinzufügen:"
|
||||||
add: "Hinzufügen"
|
add: "Hinzufügen"
|
||||||
desktop/views/input-dialog.vue:
|
desktop/views/input-dialog.vue:
|
||||||
cancel: "Abbrechen"
|
cancel: "Abbrechen"
|
||||||
@ -335,9 +348,9 @@ desktop/views/components/messaging-window.vue:
|
|||||||
title: "Nachrichten"
|
title: "Nachrichten"
|
||||||
desktop/views/components/note-detail.vue:
|
desktop/views/components/note-detail.vue:
|
||||||
more: "Lade weitere Konversationen"
|
more: "Lade weitere Konversationen"
|
||||||
private: "この投稿は非公開です"
|
private: "Dieser Post ist privat"
|
||||||
deleted: "この投稿は削除されました"
|
deleted: "Dieser Beitrag wurde entfernt"
|
||||||
reposted-by: "{}がRenote"
|
reposted-by: "Repostet von {}"
|
||||||
location: "Ort"
|
location: "Ort"
|
||||||
renote: "Anmerkung"
|
renote: "Anmerkung"
|
||||||
add-reaction: "Reaktion hinzufügen"
|
add-reaction: "Reaktion hinzufügen"
|
||||||
@ -347,8 +360,8 @@ desktop/views/components/notes.note.vue:
|
|||||||
renote: "Anmerken"
|
renote: "Anmerken"
|
||||||
add-reaction: "Eine Reaktion hinzufügen"
|
add-reaction: "Eine Reaktion hinzufügen"
|
||||||
detail: "Zeige Details"
|
detail: "Zeige Details"
|
||||||
private: "この投稿は非公開です"
|
private: "Dieser Beitrag ist eine privat"
|
||||||
deleted: "この投稿は削除されました"
|
deleted: "Dieser Beitrag wurde entfernt"
|
||||||
desktop/views/components/notes.vue:
|
desktop/views/components/notes.vue:
|
||||||
error: "Laden fehlgeschlagen."
|
error: "Laden fehlgeschlagen."
|
||||||
retry: "Erneut versuchen"
|
retry: "Erneut versuchen"
|
||||||
@ -358,7 +371,7 @@ desktop/views/components/notifications.vue:
|
|||||||
desktop/views/components/post-form.vue:
|
desktop/views/components/post-form.vue:
|
||||||
reply-placeholder: "Antworte auf diese Anmerkung..."
|
reply-placeholder: "Antworte auf diese Anmerkung..."
|
||||||
quote-placeholder: "Zitiere diese Anmerkung..."
|
quote-placeholder: "Zitiere diese Anmerkung..."
|
||||||
submit: "投稿"
|
submit: "Beitragsform"
|
||||||
reply: "Antworten"
|
reply: "Antworten"
|
||||||
renote: "Anmerkung"
|
renote: "Anmerkung"
|
||||||
posted: "Gepostet!"
|
posted: "Gepostet!"
|
||||||
@ -389,56 +402,56 @@ desktop/views/components/renote-form.vue:
|
|||||||
success: "Weitergesagt!"
|
success: "Weitergesagt!"
|
||||||
failure: "Weitersagen fehlgeschlagen"
|
failure: "Weitersagen fehlgeschlagen"
|
||||||
desktop/views/components/renote-form-window.vue:
|
desktop/views/components/renote-form-window.vue:
|
||||||
title: "この投稿をRenoteしますか?"
|
title: "Bist du dir sicher, dass du das reposten willst?"
|
||||||
desktop/views/components/settings-window.vue:
|
desktop/views/components/settings-window.vue:
|
||||||
settings: "設定"
|
settings: "Experimentelles"
|
||||||
desktop/views/components/settings.vue:
|
desktop/views/components/settings.vue:
|
||||||
profile: "プロフィール"
|
profile: "Profil"
|
||||||
notification: "通知"
|
notification: "Mitteilungen"
|
||||||
apps: "アプリ"
|
apps: "In App öffnen"
|
||||||
mute: "ミュート"
|
mute: "Stummschalten"
|
||||||
drive: "ドライブ"
|
drive: "Dateien vom Drive anfügen"
|
||||||
security: "セキュリティ"
|
security: "Sicherheit"
|
||||||
signin: "サインイン履歴"
|
signin: "サインイン履歴"
|
||||||
password: "パスワード"
|
password: "Passwort"
|
||||||
2fa: "二段階認証"
|
2fa: "Zwei-Faktor-Authentifizierung"
|
||||||
other: "その他"
|
other: "Anderes"
|
||||||
license: "ライセンス"
|
license: "Lizenz"
|
||||||
behaviour: "動作"
|
behaviour: "Verhalten"
|
||||||
fetch-on-scroll: "スクロールで自動読み込み"
|
fetch-on-scroll: "Aktualisieren beim scrollen"
|
||||||
fetch-on-scroll-desc: "ページを下までスクロールしたときに自動で追加のコンテンツを読み込みます。"
|
fetch-on-scroll-desc: "Wenn du runterscrollst empfängt die Seite automatisch zusätzliche Inhalte."
|
||||||
auto-popout: "ウィンドウの自動ポップアウト"
|
auto-popout: "Automatische Pop-out Fenster"
|
||||||
auto-popout-desc: "ウィンドウが開かれるとき、ポップアウト(ブラウザ外に切り離す)可能なら自動でポップアウトします。この設定はブラウザに記憶されます。"
|
auto-popout-desc: "Pop-out ein offenes Fenster wenn möglich. Diese Einstellung wird im Browser gespeichert."
|
||||||
advanced: "詳細設定"
|
advanced: "Erweiterte Einstellungen"
|
||||||
api-via-stream: "ストリームを経由したAPIリクエスト"
|
api-via-stream: "API-Anfrage via stream"
|
||||||
api-via-stream-desc: "この設定をオンにすると、websocket接続を経由してAPIリクエストが行われます(パフォーマンス向上が期待できます)。オフにすると、ネイティブの fetch APIが利用されます。この設定はこのデバイスのみ有効です。"
|
api-via-stream-desc: "API-Anfrage über WebSocket statt native Aktualisierungs-API (für bessere Leistung). Diese Einstellung wird im Browser gespeichert."
|
||||||
display: "デザインと表示"
|
display: "Erscheinungsbild und Anzeige"
|
||||||
customize: "ホームをカスタマイズ"
|
customize: "Startseite anpassen"
|
||||||
dark-mode: "ダークモード"
|
dark-mode: "Nacht Modus"
|
||||||
circle-icons: "円形のアイコンを使用"
|
circle-icons: "Kreisförmige Icons"
|
||||||
gradient-window-header: "ウィンドウのタイトルバーにグラデーションを使用"
|
gradient-window-header: "Übergang in Fensterköpfen"
|
||||||
post-form-on-timeline: "タイムライン上部に投稿フォームを表示する"
|
post-form-on-timeline: "タイムライン上部に投稿フォームを表示する"
|
||||||
show-reply-target: "リプライ先を表示する"
|
show-reply-target: "Zeige Antworten"
|
||||||
show-my-renotes: "自分の行ったRenoteをタイムラインに表示する"
|
show-my-renotes: "Zeige meine Reposts auf der Zeitleiste"
|
||||||
show-renoted-my-notes: "Renoteされた自分の投稿をタイムラインに表示する"
|
show-renoted-my-notes: "Zeige meine Reposts, die geteilt wurden, auf der Zeitleiste"
|
||||||
show-maps: "マップの自動展開"
|
show-maps: "Karte anzeigen"
|
||||||
show-maps-desc: "位置情報が添付された投稿のマップを自動的に展開します。"
|
show-maps-desc: "Zeige den Standort zu diesem Beitrag automatisch an."
|
||||||
sound: "サウンド"
|
sound: "Ton"
|
||||||
enable-sounds: "サウンドを有効にする"
|
enable-sounds: "Ton aktivieren"
|
||||||
enable-sounds-desc: "投稿やメッセージを送受信したときなどにサウンドを再生します。この設定はブラウザに記憶されます。"
|
enable-sounds-desc: "Spiel einen Ton ab beim Erhalten eines Beitrags bzw. einer Nachricht. Diese Einstellung wird im Browser gespeichert."
|
||||||
volume: "ボリューム"
|
volume: "Lautstärke"
|
||||||
test: "テスト"
|
test: "Test"
|
||||||
mobile: "モバイル"
|
mobile: "Mobil"
|
||||||
disable-via-mobile: "「モバイルからの投稿」フラグを付けない"
|
disable-via-mobile: "Diesen Beitrag nicht mit 'vom Handy' absenden"
|
||||||
language: "言語"
|
language: "Sprache"
|
||||||
pick-language: "言語を選択"
|
pick-language: "Sprache auswählen"
|
||||||
recommended: "推奨"
|
recommended: "Empfohlen"
|
||||||
auto: "自動"
|
auto: "Automatisch"
|
||||||
specify-language: "言語を指定"
|
specify-language: "Sprache auswählen"
|
||||||
language-desc: "変更はページの再度読み込み後に反映されます。"
|
language-desc: "変更はページの再度読み込み後に反映されます。"
|
||||||
cache: "キャッシュ"
|
cache: "キャッシュ"
|
||||||
clean-cache: "クリーンアップ"
|
clean-cache: "クリーンアップ"
|
||||||
cache-warn: "クリーンアップを行うと、ブラウザに記憶されたアカウント情報のキャッシュ、書きかけの投稿・返信・メッセージ、およびその他のデータ(設定情報含む)が削除されます。クリーンアップを行った後はページを再度読み込みする必要があります。"
|
cache-warn: "Der Cache deines Benutzerkontos (Info, Beiträge, Antworten, Direktnachrichten, Einstellungen), die lokal im Browser gespeichert sind werden gelöscht.\nDu musst die Seite aktualisieren nachdem du aufgeräumt hast."
|
||||||
cache-cleared: "キャッシュを削除しました"
|
cache-cleared: "キャッシュを削除しました"
|
||||||
cache-cleared-desc: "ページを再度読み込みしてください。"
|
cache-cleared-desc: "ページを再度読み込みしてください。"
|
||||||
auto-watch: "投稿の自動ウォッチ"
|
auto-watch: "投稿の自動ウォッチ"
|
||||||
@ -447,9 +460,9 @@ desktop/views/components/settings.vue:
|
|||||||
operator: "このサーバーの運営者"
|
operator: "このサーバーの運営者"
|
||||||
update: "Misskey Update"
|
update: "Misskey Update"
|
||||||
version: "バージョン:"
|
version: "バージョン:"
|
||||||
latest-version: "最新のバージョン:"
|
latest-version: "Neuste Version:"
|
||||||
update-checking: "アップデートを確認中"
|
update-checking: "Suche nach Updates"
|
||||||
do-update: "アップデートを確認"
|
do-update: "Suche nach Updates"
|
||||||
update-settings: "詳細設定"
|
update-settings: "詳細設定"
|
||||||
prevent-update: "アップデートを延期する(非推奨)"
|
prevent-update: "アップデートを延期する(非推奨)"
|
||||||
prevent-update-desc: "この設定をオンにしてもアップデートが反映される場合があります。この設定はこのデバイスのみ有効です。"
|
prevent-update-desc: "この設定をオンにしてもアップデートが反映される場合があります。この設定はこのデバイスのみ有効です。"
|
||||||
@ -461,20 +474,20 @@ desktop/views/components/settings.vue:
|
|||||||
debug-mode: "デバッグモードを有効にする"
|
debug-mode: "デバッグモードを有効にする"
|
||||||
debug-mode-desc: "この設定はブラウザに記憶されます。"
|
debug-mode-desc: "この設定はブラウザに記憶されます。"
|
||||||
experimental: "実験的機能を有効にする"
|
experimental: "実験的機能を有効にする"
|
||||||
experimental-desc: "実験的機能を有効にするとMisskeyの動作が不安定になる可能性があります。この設定はブラウザに記憶されます。"
|
experimental-desc: "Experimentelle Funktionen können die Stabilität von Misskey beeinträchtigen. Diese Einstellung wird im Browser gespeichert."
|
||||||
tools: "ツール"
|
tools: "Werkzeuge"
|
||||||
task-manager: "タスクマネージャ"
|
task-manager: "Taskmanager"
|
||||||
third-parties: "サードパーティ"
|
third-parties: "サードパーティ"
|
||||||
desktop/views/components/settings.2fa.vue:
|
desktop/views/components/settings.2fa.vue:
|
||||||
intro: "二段階認証を設定すると、サインイン時にパスワードだけでなく、予め登録しておいた物理的なデバイス(例えばあなたのスマートフォンなど)も必要になり、よりセキュリティが向上します。"
|
intro: "二段階認証を設定すると、サインイン時にパスワードだけでなく、予め登録しておいた物理的なデバイス(例えばあなたのスマートフォンなど)も必要になり、よりセキュリティが向上します。"
|
||||||
detail: "詳細..."
|
detail: "詳細..."
|
||||||
url: "https://www.google.co.jp/intl/ja/landing/2step/"
|
url: "https://www.google.de/intl/de/landing/2step/"
|
||||||
caution: "登録したデバイスを紛失するなどした場合、Misskeyにサインインできなくなりますのでご注意ください。"
|
caution: "登録したデバイスを紛失するなどした場合、Misskeyにサインインできなくなりますのでご注意ください。"
|
||||||
register: "デバイスを登録する"
|
register: "Ein Gerät registrieren"
|
||||||
already-registered: "既に設定は完了しています。"
|
already-registered: "Das Gerät wurde bereits registriert"
|
||||||
unregister: "設定を解除"
|
unregister: "Abschalten"
|
||||||
unregistered: "二段階認証が無効になりました。"
|
unregistered: "Zwei-Faktor-Authentifizierung wurde deaktiviert."
|
||||||
enter-password: "パスワードを入力してください"
|
enter-password: "Bitte Passwort eingeben"
|
||||||
authenticator: "まず、Google Authenticatorをお使いのデバイスにインストールします:"
|
authenticator: "まず、Google Authenticatorをお使いのデバイスにインストールします:"
|
||||||
howtoinstall: "インストール方法はこちら"
|
howtoinstall: "インストール方法はこちら"
|
||||||
scan: "次に、表示されているQRコードをスキャンします:"
|
scan: "次に、表示されているQRコードをスキャンします:"
|
||||||
@ -489,16 +502,16 @@ desktop/views/components/settings.api.vue:
|
|||||||
regeneration-of-token: "万が一このトークンが漏れたりその可能性がある場合はトークンを再生成できます。"
|
regeneration-of-token: "万が一このトークンが漏れたりその可能性がある場合はトークンを再生成できます。"
|
||||||
regenerate-token: "トークンを再生成"
|
regenerate-token: "トークンを再生成"
|
||||||
token: "Token:"
|
token: "Token:"
|
||||||
enter-password: "パスワードを入力してください"
|
enter-password: "Bitte Passwort eingeben"
|
||||||
desktop/views/components/settings.apps.vue:
|
desktop/views/components/settings.apps.vue:
|
||||||
no-apps: "連携しているアプリケーションはありません"
|
no-apps: "連携しているアプリケーションはありません"
|
||||||
desktop/views/components/settings.mute.vue:
|
desktop/views/components/settings.mute.vue:
|
||||||
no-users: "ミュートしているユーザーはいません"
|
no-users: "ミュートしているユーザーはいません"
|
||||||
desktop/views/components/settings.password.vue:
|
desktop/views/components/settings.password.vue:
|
||||||
reset: "パスワードを変更する"
|
reset: "パスワードを変更する"
|
||||||
enter-current-password: "現在のパスワードを入力してください"
|
enter-current-password: "Derzeitiges Passwort eingeben"
|
||||||
enter-new-password: "新しいパスワードを入力してください"
|
enter-new-password: "Neues Passwort eingeben"
|
||||||
enter-new-password-again: "もう一度新しいパスワードを入力してください"
|
enter-new-password-again: "Neues Passwort erneut eingeben"
|
||||||
not-match: "新しいパスワードが一致しません"
|
not-match: "新しいパスワードが一致しません"
|
||||||
changed: "パスワードを変更しました"
|
changed: "パスワードを変更しました"
|
||||||
desktop/views/components/settings.profile.vue:
|
desktop/views/components/settings.profile.vue:
|
||||||
@ -515,9 +528,9 @@ desktop/views/components/sub-note-content.vue:
|
|||||||
private: "この投稿は非公開です"
|
private: "この投稿は非公開です"
|
||||||
deleted: "この投稿は削除されました"
|
deleted: "この投稿は削除されました"
|
||||||
media-count: "{}つのメディア"
|
media-count: "{}つのメディア"
|
||||||
poll: "投票"
|
poll: "アンケート"
|
||||||
desktop/views/components/taskmanager.vue:
|
desktop/views/components/taskmanager.vue:
|
||||||
title: "タスクマネージャ"
|
title: "Taskmanager"
|
||||||
desktop/views/components/timeline.vue:
|
desktop/views/components/timeline.vue:
|
||||||
home: "Home"
|
home: "Home"
|
||||||
local: "Lokal"
|
local: "Lokal"
|
||||||
@ -559,12 +572,19 @@ desktop/views/components/users-list.vue:
|
|||||||
all: "すべて"
|
all: "すべて"
|
||||||
iknow: "知り合い"
|
iknow: "知り合い"
|
||||||
load-more: "もっと"
|
load-more: "もっと"
|
||||||
fetching: "読み込んでいます"
|
fetching: "Lade…"
|
||||||
desktop/views/components/users-list-item.vue:
|
desktop/views/components/users-list-item.vue:
|
||||||
followed: "フォローされています"
|
followed: "フォローされています"
|
||||||
desktop/views/components/window.vue:
|
desktop/views/components/window.vue:
|
||||||
popout: "ポップアウト"
|
popout: "ポップアウト"
|
||||||
close: "閉じる"
|
close: "閉じる"
|
||||||
|
desktop/views/pages/deck/deck.tl-column.vue:
|
||||||
|
is-media-only: "メディア投稿のみ"
|
||||||
|
is-media-view: "メディアビュー"
|
||||||
|
desktop/views/pages/deck/deck.note.vue:
|
||||||
|
reposted-by: "{}がRenote"
|
||||||
|
private: "この投稿は非公開です"
|
||||||
|
deleted: "この投稿は削除されました"
|
||||||
desktop/views/pages/welcome.vue:
|
desktop/views/pages/welcome.vue:
|
||||||
about: "詳しく..."
|
about: "詳しく..."
|
||||||
gotit: "わかった"
|
gotit: "わかった"
|
||||||
@ -628,7 +648,7 @@ desktop/views/widgets/notifications.vue:
|
|||||||
title: "通知"
|
title: "通知"
|
||||||
settings: "通知の設定"
|
settings: "通知の設定"
|
||||||
desktop/views/widgets/polls.vue:
|
desktop/views/widgets/polls.vue:
|
||||||
title: "投票"
|
title: "アンケート"
|
||||||
refresh: "他を見る"
|
refresh: "他を見る"
|
||||||
nothing: "ありません!"
|
nothing: "ありません!"
|
||||||
desktop/views/widgets/post-form.vue:
|
desktop/views/widgets/post-form.vue:
|
||||||
@ -681,7 +701,7 @@ mobile/views/components/follow-button.vue:
|
|||||||
mobile/views/components/friends-maker.vue:
|
mobile/views/components/friends-maker.vue:
|
||||||
title: "気になるユーザーをフォロー"
|
title: "気になるユーザーをフォロー"
|
||||||
empty: "おすすめのユーザーは見つかりませんでした。"
|
empty: "おすすめのユーザーは見つかりませんでした。"
|
||||||
fetching: "読み込んでいます"
|
fetching: "Lade…"
|
||||||
refresh: "もっと見る"
|
refresh: "もっと見る"
|
||||||
close: "閉じる"
|
close: "閉じる"
|
||||||
mobile/views/components/note.vue:
|
mobile/views/components/note.vue:
|
||||||
@ -727,7 +747,7 @@ mobile/views/components/sub-note-content.vue:
|
|||||||
private: "この投稿は非公開です"
|
private: "この投稿は非公開です"
|
||||||
deleted: "この投稿は削除されました"
|
deleted: "この投稿は削除されました"
|
||||||
media-count: "{}つのメディア"
|
media-count: "{}つのメディア"
|
||||||
poll: "投票"
|
poll: "アンケート"
|
||||||
mobile/views/components/timeline.vue:
|
mobile/views/components/timeline.vue:
|
||||||
empty: "投稿がありません"
|
empty: "投稿がありません"
|
||||||
load-more: "もっと"
|
load-more: "もっと"
|
||||||
@ -785,7 +805,7 @@ mobile/views/pages/notifications.vue:
|
|||||||
notifications: "通知"
|
notifications: "通知"
|
||||||
read-all: "すべての通知を既読にしますか?"
|
read-all: "すべての通知を既読にしますか?"
|
||||||
mobile/views/pages/settings/settings.profile.vue:
|
mobile/views/pages/settings/settings.profile.vue:
|
||||||
title: "プロフィール"
|
title: "Profil"
|
||||||
name: "名前"
|
name: "名前"
|
||||||
account: "アカウント"
|
account: "アカウント"
|
||||||
location: "場所"
|
location: "場所"
|
||||||
@ -795,7 +815,7 @@ mobile/views/pages/settings/settings.profile.vue:
|
|||||||
banner: "バナー"
|
banner: "バナー"
|
||||||
is-cat: "このアカウントはCatです"
|
is-cat: "このアカウントはCatです"
|
||||||
save: "保存"
|
save: "保存"
|
||||||
saved: "プロフィールを保存しました"
|
saved: "Profil wurde aktualisiert"
|
||||||
uploading: "アップロード中"
|
uploading: "アップロード中"
|
||||||
upload-failed: "アップロードに失敗しました"
|
upload-failed: "アップロードに失敗しました"
|
||||||
mobile/views/pages/search.vue:
|
mobile/views/pages/search.vue:
|
||||||
@ -809,7 +829,7 @@ mobile/views/pages/settings.vue:
|
|||||||
lang-tip: "変更はページの再読み込み後に反映されます。"
|
lang-tip: "変更はページの再読み込み後に反映されます。"
|
||||||
recommended: "推奨"
|
recommended: "推奨"
|
||||||
auto: "自動"
|
auto: "自動"
|
||||||
specify-language: "言語を指定"
|
specify-language: "Sprache auswählen"
|
||||||
design: "デザインと表示"
|
design: "デザインと表示"
|
||||||
dark-mode: "ダークモード"
|
dark-mode: "ダークモード"
|
||||||
i-am-under-limited-internet: "私は通信を制限されている"
|
i-am-under-limited-internet: "私は通信を制限されている"
|
||||||
@ -832,9 +852,9 @@ mobile/views/pages/settings.vue:
|
|||||||
twitter-disconnect: "切断する"
|
twitter-disconnect: "切断する"
|
||||||
update: "Misskey Update"
|
update: "Misskey Update"
|
||||||
version: "バージョン:"
|
version: "バージョン:"
|
||||||
latest-version: "最新のバージョン:"
|
latest-version: "Neuste Version:"
|
||||||
update-checking: "アップデートを確認中"
|
update-checking: "Suche nach Updates"
|
||||||
check-for-updates: "アップデートを確認"
|
check-for-updates: "Suche nach Updates"
|
||||||
no-updates: "利用可能な更新はありません"
|
no-updates: "利用可能な更新はありません"
|
||||||
no-updates-desc: "お使いのMisskeyは最新です。"
|
no-updates-desc: "お使いのMisskeyは最新です。"
|
||||||
update-available: "新しいバージョンが利用可能です"
|
update-available: "新しいバージョンが利用可能です"
|
||||||
|
@ -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:
|
||||||
@ -54,9 +54,10 @@ common:
|
|||||||
timemachine: "Calendar (Time Machine)"
|
timemachine: "Calendar (Time Machine)"
|
||||||
activity: "Activity"
|
activity: "Activity"
|
||||||
rss: "RSS reader"
|
rss: "RSS reader"
|
||||||
memo: "Memo"
|
memo: "Sticky note"
|
||||||
trends: "Trends"
|
trends: "Trends"
|
||||||
photo-stream: "Photo stream"
|
photo-stream: "Photo stream"
|
||||||
|
posts-monitor: "Chart of posts"
|
||||||
slideshow: "Slideshow"
|
slideshow: "Slideshow"
|
||||||
version: "Version"
|
version: "Version"
|
||||||
broadcast: "Broadcast"
|
broadcast: "Broadcast"
|
||||||
@ -69,6 +70,7 @@ common:
|
|||||||
donation: "Donation"
|
donation: "Donation"
|
||||||
nav: "Navigation"
|
nav: "Navigation"
|
||||||
tips: "Tips"
|
tips: "Tips"
|
||||||
|
hashtags: "Hashtags"
|
||||||
deck:
|
deck:
|
||||||
widgets: "Widgets"
|
widgets: "Widgets"
|
||||||
home: "Home"
|
home: "Home"
|
||||||
@ -76,11 +78,15 @@ common:
|
|||||||
global: "Global"
|
global: "Global"
|
||||||
notifications: "Notifications"
|
notifications: "Notifications"
|
||||||
list: "List"
|
list: "List"
|
||||||
swap-left: "Move Left"
|
swap-left: "Move left"
|
||||||
swap-right: "Move Right"
|
swap-right: "Move right"
|
||||||
|
swap-up: "Move upward"
|
||||||
|
swap-down: "Move downward"
|
||||||
remove: "Remove"
|
remove: "Remove"
|
||||||
add-column: "Add a column"
|
add-column: "Add a column"
|
||||||
rename: "名前を変更"
|
rename: "Rename"
|
||||||
|
stack-left: "Stack to left"
|
||||||
|
pop-right: "Pop to right"
|
||||||
common/views/components/connect-failed.vue:
|
common/views/components/connect-failed.vue:
|
||||||
title: "Unable to connect to the server"
|
title: "Unable to connect to the server"
|
||||||
description: "There is a problem either with your Internet connection, or the server may be down or under maintenance. Please {try again} later."
|
description: "There is a problem either with your Internet connection, or the server may be down or under maintenance. Please {try again} later."
|
||||||
@ -216,11 +222,18 @@ common/views/widgets/donation.vue:
|
|||||||
common/views/widgets/photo-stream.vue:
|
common/views/widgets/photo-stream.vue:
|
||||||
title: "Photostream"
|
title: "Photostream"
|
||||||
no-photos: "No photos"
|
no-photos: "No photos"
|
||||||
|
common/views/widgets/posts-monitor.vue:
|
||||||
|
title: "Chart of posts"
|
||||||
|
toggle: "Toggle views"
|
||||||
|
common/views/widgets/hashtags.vue:
|
||||||
|
title: "Hashtags"
|
||||||
|
count: "{} users mentioned"
|
||||||
|
empty: "トレンドなし"
|
||||||
common/views/widgets/server.vue:
|
common/views/widgets/server.vue:
|
||||||
title: "Server info"
|
title: "Server info"
|
||||||
toggle: "Toggle views"
|
toggle: "Toggle views"
|
||||||
common/views/widgets/memo.vue:
|
common/views/widgets/memo.vue:
|
||||||
title: "Memo"
|
title: "Sticky note"
|
||||||
memo: "Write here!"
|
memo: "Write here!"
|
||||||
save: "Save"
|
save: "Save"
|
||||||
desktop/views/components/activity.chart.vue:
|
desktop/views/components/activity.chart.vue:
|
||||||
@ -321,7 +334,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:"
|
||||||
@ -422,7 +435,7 @@ desktop/views/components/settings.vue:
|
|||||||
show-my-renotes: "Show my reposts in the timeline"
|
show-my-renotes: "Show my reposts in the timeline"
|
||||||
show-renoted-my-notes: "Show my posts that have been shared in the timeline"
|
show-renoted-my-notes: "Show my posts that have been shared in the timeline"
|
||||||
show-maps: "Show the map"
|
show-maps: "Show the map"
|
||||||
show-maps-desc: "Automatically show the map of the location attached to the post."
|
show-maps-desc: "Automatically show the location on the map attached to this post."
|
||||||
sound: "Sound"
|
sound: "Sound"
|
||||||
enable-sounds: "Enable sound"
|
enable-sounds: "Enable sound"
|
||||||
enable-sounds-desc: "Play a sound when you receive a post/message. This setting is stored in the browser."
|
enable-sounds-desc: "Play a sound when you receive a post/message. This setting is stored in the browser."
|
||||||
@ -515,7 +528,7 @@ desktop/views/components/sub-note-content.vue:
|
|||||||
private: "this post is private"
|
private: "this post is private"
|
||||||
deleted: "this post has been deleted"
|
deleted: "this post has been deleted"
|
||||||
media-count: "{} media attached"
|
media-count: "{} media attached"
|
||||||
poll: "Polls"
|
poll: "Poll"
|
||||||
desktop/views/components/taskmanager.vue:
|
desktop/views/components/taskmanager.vue:
|
||||||
title: "Task Manager"
|
title: "Task Manager"
|
||||||
desktop/views/components/timeline.vue:
|
desktop/views/components/timeline.vue:
|
||||||
@ -537,7 +550,7 @@ desktop/views/components/ui.header.nav.vue:
|
|||||||
home: "Home"
|
home: "Home"
|
||||||
deck: "Deck"
|
deck: "Deck"
|
||||||
messaging: "Messages"
|
messaging: "Messages"
|
||||||
game: "Play Othello"
|
game: "Play Reversi"
|
||||||
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:
|
||||||
@ -565,6 +578,13 @@ desktop/views/components/users-list-item.vue:
|
|||||||
desktop/views/components/window.vue:
|
desktop/views/components/window.vue:
|
||||||
popout: "Popout"
|
popout: "Popout"
|
||||||
close: "Close"
|
close: "Close"
|
||||||
|
desktop/views/pages/deck/deck.tl-column.vue:
|
||||||
|
is-media-only: "Only media posts"
|
||||||
|
is-media-view: "Media view"
|
||||||
|
desktop/views/pages/deck/deck.note.vue:
|
||||||
|
reposted-by: "Reposted by {}"
|
||||||
|
private: "this post is private"
|
||||||
|
deleted: "this post has been deleted"
|
||||||
desktop/views/pages/welcome.vue:
|
desktop/views/pages/welcome.vue:
|
||||||
about: "about"
|
about: "about"
|
||||||
gotit: "Got it!"
|
gotit: "Got it!"
|
||||||
|
578
locales/es.yml
578
locales/es.yml
@ -1,226 +1,239 @@
|
|||||||
---
|
---
|
||||||
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: "削除"
|
delete: "eliminar"
|
||||||
loading: "読み込み中"
|
loading: "cargando"
|
||||||
ok: "わかった"
|
ok: "OK"
|
||||||
update-available: "Misskeyの新しいバージョンがあります({newer}。現在{current}を利用中)。ページを再度読み込みすると更新が適用されます。"
|
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: "あなたのトークンが更新されたのでサインアウトします。"
|
my-token-regenerated: "Tu token se ha regenerado vas a ser desconectado."
|
||||||
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"
|
||||||
slideshow: "スライドショー"
|
posts-monitor: "Gráfico de publicaciones"
|
||||||
version: "バージョン"
|
slideshow: "Diapositivas"
|
||||||
broadcast: "ブロードキャスト"
|
version: "Versión"
|
||||||
notifications: "通知"
|
broadcast: "Transmisión"
|
||||||
users: "おすすめユーザー"
|
notifications: "Notificaciones"
|
||||||
polls: "投票"
|
users: "Usuarios destacados"
|
||||||
post-form: "投稿フォーム"
|
polls: "Encuestas"
|
||||||
messaging: "メッセージ"
|
post-form: "Formulario"
|
||||||
server: "サーバー情報"
|
messaging: "Mensajes"
|
||||||
donation: "寄付のお願い"
|
server: "Información del servidor"
|
||||||
nav: "ナビゲーション"
|
donation: "Donaciones"
|
||||||
tips: "ヒント"
|
nav: "Navegación"
|
||||||
|
tips: "Consejos"
|
||||||
|
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."
|
||||||
remove: "カラムを削除"
|
swap-up: "Desplazar arriba"
|
||||||
add-column: "カラムを追加"
|
swap-down: "Desplazar abajo"
|
||||||
rename: "名前を変更"
|
remove: "Borrar"
|
||||||
|
add-column: "Añadir columna"
|
||||||
|
rename: "Renombrar"
|
||||||
|
stack-left: "A la izqda."
|
||||||
|
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: "フォトストリーム"
|
||||||
no-photos: "写真はありません"
|
no-photos: "写真はありません"
|
||||||
|
common/views/widgets/posts-monitor.vue:
|
||||||
|
title: "投稿チャート"
|
||||||
|
toggle: "表示を切り替え"
|
||||||
|
common/views/widgets/hashtags.vue:
|
||||||
|
title: "ハッシュタグ"
|
||||||
|
count: "{}人が投稿"
|
||||||
|
empty: "トレンドなし"
|
||||||
common/views/widgets/server.vue:
|
common/views/widgets/server.vue:
|
||||||
title: "サーバー情報"
|
title: "サーバー情報"
|
||||||
toggle: "表示を切り替え"
|
toggle: "表示を切り替え"
|
||||||
common/views/widgets/memo.vue:
|
common/views/widgets/memo.vue:
|
||||||
title: "メモ"
|
title: "付箋"
|
||||||
memo: "ここに書いて!"
|
memo: "ここに書いて!"
|
||||||
save: "保存"
|
save: "保存"
|
||||||
desktop/views/components/activity.chart.vue:
|
desktop/views/components/activity.chart.vue:
|
||||||
@ -245,66 +258,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: "{} のフォロワー"
|
||||||
@ -321,7 +334,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: "ウィジェットを追加:"
|
||||||
@ -369,55 +382,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された自分の投稿をタイムラインに表示する"
|
||||||
@ -515,7 +528,7 @@ desktop/views/components/sub-note-content.vue:
|
|||||||
private: "この投稿は非公開です"
|
private: "この投稿は非公開です"
|
||||||
deleted: "この投稿は削除されました"
|
deleted: "この投稿は削除されました"
|
||||||
media-count: "{}つのメディア"
|
media-count: "{}つのメディア"
|
||||||
poll: "投票"
|
poll: "アンケート"
|
||||||
desktop/views/components/taskmanager.vue:
|
desktop/views/components/taskmanager.vue:
|
||||||
title: "タスクマネージャ"
|
title: "タスクマネージャ"
|
||||||
desktop/views/components/timeline.vue:
|
desktop/views/components/timeline.vue:
|
||||||
@ -565,6 +578,13 @@ desktop/views/components/users-list-item.vue:
|
|||||||
desktop/views/components/window.vue:
|
desktop/views/components/window.vue:
|
||||||
popout: "ポップアウト"
|
popout: "ポップアウト"
|
||||||
close: "閉じる"
|
close: "閉じる"
|
||||||
|
desktop/views/pages/deck/deck.tl-column.vue:
|
||||||
|
is-media-only: "メディア投稿のみ"
|
||||||
|
is-media-view: "メディアビュー"
|
||||||
|
desktop/views/pages/deck/deck.note.vue:
|
||||||
|
reposted-by: "{}がRenote"
|
||||||
|
private: "この投稿は非公開です"
|
||||||
|
deleted: "この投稿は削除されました"
|
||||||
desktop/views/pages/welcome.vue:
|
desktop/views/pages/welcome.vue:
|
||||||
about: "詳しく..."
|
about: "詳しく..."
|
||||||
gotit: "わかった"
|
gotit: "わかった"
|
||||||
@ -628,7 +648,7 @@ desktop/views/widgets/notifications.vue:
|
|||||||
title: "通知"
|
title: "通知"
|
||||||
settings: "通知の設定"
|
settings: "通知の設定"
|
||||||
desktop/views/widgets/polls.vue:
|
desktop/views/widgets/polls.vue:
|
||||||
title: "投票"
|
title: "アンケート"
|
||||||
refresh: "他を見る"
|
refresh: "他を見る"
|
||||||
nothing: "ありません!"
|
nothing: "ありません!"
|
||||||
desktop/views/widgets/post-form.vue:
|
desktop/views/widgets/post-form.vue:
|
||||||
@ -727,7 +747,7 @@ mobile/views/components/sub-note-content.vue:
|
|||||||
private: "この投稿は非公開です"
|
private: "この投稿は非公開です"
|
||||||
deleted: "この投稿は削除されました"
|
deleted: "この投稿は削除されました"
|
||||||
media-count: "{}つのメディア"
|
media-count: "{}つのメディア"
|
||||||
poll: "投票"
|
poll: "アンケート"
|
||||||
mobile/views/components/timeline.vue:
|
mobile/views/components/timeline.vue:
|
||||||
empty: "投稿がありません"
|
empty: "投稿がありません"
|
||||||
load-more: "もっと"
|
load-more: "もっと"
|
||||||
|
184
locales/fr.yml
184
locales/fr.yml
@ -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: "Misskeyを見つけていただき、ありがとうございます。Misskeyは、地球で生まれた<b>分散マイクロブログSNS</b>です。Fediverse(様々なSNSで構成される宇宙)の中に存在するため、他のSNSと相互に繋がっています。暫し都会の喧騒から離れて、新しいインターネットにダイブしてみませんか。"
|
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"
|
||||||
@ -24,28 +24,28 @@ common:
|
|||||||
wednesday: "M"
|
wednesday: "M"
|
||||||
thursday: "J"
|
thursday: "J"
|
||||||
friday: "V"
|
friday: "V"
|
||||||
saturday: "土"
|
saturday: "S"
|
||||||
reactions:
|
reactions:
|
||||||
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: "今どうしてる?"
|
a: "Que faîtes vous maintenant ?"
|
||||||
b: "何かありましたか?"
|
b: "Quoi de neuf ?"
|
||||||
c: "Qu'avez-vous en tête ?"
|
c: "Qu'avez-vous en tête ?"
|
||||||
d: "言いたいことは?"
|
d: "Voulez-vous exprimer quelque chose ?"
|
||||||
e: "Écrivez ici"
|
e: "Écrivez ici"
|
||||||
f: "En attente de vos écrits"
|
f: "En attente de vos écrits"
|
||||||
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: "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é."
|
||||||
widgets:
|
widgets:
|
||||||
analog-clock: "Horloge analogique"
|
analog-clock: "Horloge analogique"
|
||||||
@ -54,9 +54,10 @@ common:
|
|||||||
timemachine: "カレンダー(タイムマシン)"
|
timemachine: "カレンダー(タイムマシン)"
|
||||||
activity: "Activité"
|
activity: "Activité"
|
||||||
rss: "Lecteur de flux RSS"
|
rss: "Lecteur de flux RSS"
|
||||||
memo: "Note"
|
memo: "Pense-bête"
|
||||||
trends: "Tendances"
|
trends: "Tendances"
|
||||||
photo-stream: "Flux de photos"
|
photo-stream: "Flux de photos"
|
||||||
|
posts-monitor: "Graph des publications"
|
||||||
slideshow: "Diaporama"
|
slideshow: "Diaporama"
|
||||||
version: "Version"
|
version: "Version"
|
||||||
broadcast: "Diffusion"
|
broadcast: "Diffusion"
|
||||||
@ -69,6 +70,7 @@ common:
|
|||||||
donation: "Dons"
|
donation: "Dons"
|
||||||
nav: "Navigation"
|
nav: "Navigation"
|
||||||
tips: "Conseils"
|
tips: "Conseils"
|
||||||
|
hashtags: "Étiquettes"
|
||||||
deck:
|
deck:
|
||||||
widgets: "Widgets"
|
widgets: "Widgets"
|
||||||
home: "Accueil"
|
home: "Accueil"
|
||||||
@ -78,9 +80,13 @@ common:
|
|||||||
list: "Liste"
|
list: "Liste"
|
||||||
swap-left: "Déplacer à gauche"
|
swap-left: "Déplacer à gauche"
|
||||||
swap-right: "Déplacer à droite"
|
swap-right: "Déplacer à droite"
|
||||||
|
swap-up: "Vers le haut"
|
||||||
|
swap-down: "Vers le bas"
|
||||||
remove: "Supprimer"
|
remove: "Supprimer"
|
||||||
add-column: "Ajouter une colonne"
|
add-column: "Ajouter une colonne"
|
||||||
rename: "名前を変更"
|
rename: "Renommer"
|
||||||
|
stack-left: "Vers la gauche"
|
||||||
|
pop-right: "Vers la droite"
|
||||||
common/views/components/connect-failed.vue:
|
common/views/components/connect-failed.vue:
|
||||||
title: "Impossible de se connecter au server."
|
title: "Impossible de se connecter au server."
|
||||||
description: "Il y a soit un problème avec votre connexion internet, soit le serveur est hors-ligne ou en maintenance. Veuillez {ressayer} plus tard."
|
description: "Il y a soit un problème avec votre connexion internet, soit le serveur est hors-ligne ou en maintenance. Veuillez {ressayer} plus tard."
|
||||||
@ -104,7 +110,7 @@ common/views/components/connect-failed.troubleshooter.vue:
|
|||||||
success: "Connexion au serveur de Misskey reussie!"
|
success: "Connexion au serveur de Misskey reussie!"
|
||||||
success-desc: "La connexion au serveur a été reussie. Veuillez recharger la page."
|
success-desc: "La connexion au serveur a été reussie. Veuillez recharger la page."
|
||||||
flush: "Vider le cache"
|
flush: "Vider le cache"
|
||||||
set-version: "バージョン指定"
|
set-version: "Choisissez une version"
|
||||||
common/views/components/messaging.vue:
|
common/views/components/messaging.vue:
|
||||||
search-user: "Trouver un utilisateur"
|
search-user: "Trouver un utilisateur"
|
||||||
you: "Vous"
|
you: "Vous"
|
||||||
@ -146,11 +152,11 @@ common/views/components/poll.vue:
|
|||||||
show-result: "Montrer les résultats"
|
show-result: "Montrer les résultats"
|
||||||
voted: "Voté"
|
voted: "Voté"
|
||||||
common/views/components/poll-editor.vue:
|
common/views/components/poll-editor.vue:
|
||||||
no-only-one-choice: "Vous devez entrer au moins deux choix"
|
no-only-one-choice: "Vous devez saisir au moins deux choix."
|
||||||
choice-n: "Choix {}"
|
choice-n: "Choix {}"
|
||||||
remove: "Supprimer ce choix"
|
remove: "Supprimer ce choix"
|
||||||
add: "+ Ajouter un choix"
|
add: "+ Ajouter un choix"
|
||||||
destroy: "Supprimer ce sondage"
|
destroy: "Annuler ce sondage"
|
||||||
common/views/components/reaction-picker.vue:
|
common/views/components/reaction-picker.vue:
|
||||||
choose-reaction: "Choisissez votre réaction"
|
choose-reaction: "Choisissez votre réaction"
|
||||||
common/views/components/signin.vue:
|
common/views/components/signin.vue:
|
||||||
@ -199,7 +205,7 @@ common/views/components/uploader.vue:
|
|||||||
common/views/components/visibility-chooser.vue:
|
common/views/components/visibility-chooser.vue:
|
||||||
public: "Public"
|
public: "Public"
|
||||||
home: "Accueil"
|
home: "Accueil"
|
||||||
home-desc: "ホームタイムラインにのみ公開"
|
home-desc: "Publier sur le fil d'Accueil uniquement"
|
||||||
followers: "Abonnés"
|
followers: "Abonnés"
|
||||||
followers-desc: "Publier à vos abonnés uniquement"
|
followers-desc: "Publier à vos abonnés uniquement"
|
||||||
specified: "Direct"
|
specified: "Direct"
|
||||||
@ -216,18 +222,25 @@ common/views/widgets/donation.vue:
|
|||||||
common/views/widgets/photo-stream.vue:
|
common/views/widgets/photo-stream.vue:
|
||||||
title: "Flux de photo"
|
title: "Flux de photo"
|
||||||
no-photos: "Pas de photos"
|
no-photos: "Pas de photos"
|
||||||
|
common/views/widgets/posts-monitor.vue:
|
||||||
|
title: "Graph des publications"
|
||||||
|
toggle: "表示を切り替え"
|
||||||
|
common/views/widgets/hashtags.vue:
|
||||||
|
title: "Étiquettes"
|
||||||
|
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"
|
||||||
common/views/widgets/memo.vue:
|
common/views/widgets/memo.vue:
|
||||||
title: "Note"
|
title: "Pense-bête"
|
||||||
memo: "Écrivez ici !"
|
memo: "Écrivez ici !"
|
||||||
save: "Enregistrer"
|
save: "Enregistrer"
|
||||||
desktop/views/components/activity.chart.vue:
|
desktop/views/components/activity.chart.vue:
|
||||||
total: "Black ... Total"
|
total: "Black ... Total"
|
||||||
notes: "Blue ... Notes"
|
notes: "Bleu ... Notes"
|
||||||
replies: "Red ... Replies"
|
replies: "Rouge ... Réponses"
|
||||||
renotes: "Green ... Renotes"
|
renotes: "Vert ... Partages"
|
||||||
desktop/views/components/activity.vue:
|
desktop/views/components/activity.vue:
|
||||||
title: "Activitié"
|
title: "Activitié"
|
||||||
toggle: "Afficher les vues"
|
toggle: "Afficher les vues"
|
||||||
@ -304,7 +317,7 @@ desktop/views/components/drive.vue:
|
|||||||
desktop/views/components/follow-button.vue:
|
desktop/views/components/follow-button.vue:
|
||||||
following: "Abonnements"
|
following: "Abonnements"
|
||||||
follow: "Suivre"
|
follow: "Suivre"
|
||||||
request-pending: "フォロー許可待ち"
|
request-pending: "En attente d'approbation"
|
||||||
follow-request: "Demande d'abonnement"
|
follow-request: "Demande d'abonnement"
|
||||||
desktop/views/components/followers-window.vue:
|
desktop/views/components/followers-window.vue:
|
||||||
followers: "{} abonnés"
|
followers: "{} abonnés"
|
||||||
@ -316,14 +329,14 @@ desktop/views/components/following.vue:
|
|||||||
empty: "Vous ne suivez aucun compte."
|
empty: "Vous ne suivez aucun compte."
|
||||||
desktop/views/components/friends-maker.vue:
|
desktop/views/components/friends-maker.vue:
|
||||||
title: "Utilisateurs recommandés :"
|
title: "Utilisateurs recommandés :"
|
||||||
empty: "おすすめのユーザーは見つかりませんでした。"
|
empty: "Impossible de trouver des utilisateurs à recommander."
|
||||||
fetching: "Chargement"
|
fetching: "Chargement"
|
||||||
refresh: "Plus"
|
refresh: "Plus"
|
||||||
close: "Fermer"
|
close: "Fermer"
|
||||||
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: "完了"
|
done: "Envoyer"
|
||||||
add-widget: "Ajouter un widget"
|
add-widget: "Ajouter un widget"
|
||||||
add: "Ajouter"
|
add: "Ajouter"
|
||||||
desktop/views/input-dialog.vue:
|
desktop/views/input-dialog.vue:
|
||||||
@ -337,14 +350,14 @@ desktop/views/components/note-detail.vue:
|
|||||||
more: "Charger davantage de conversations"
|
more: "Charger davantage de conversations"
|
||||||
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"
|
||||||
reposted-by: "{}がRenote"
|
reposted-by: "Republié par {}"
|
||||||
location: "Géolocalisation"
|
location: "Géolocalisation"
|
||||||
renote: "Renote"
|
renote: "Republier"
|
||||||
add-reaction: "Ajouter votre reaction"
|
add-reaction: "Ajouter votre reaction"
|
||||||
desktop/views/components/notes.note.vue:
|
desktop/views/components/notes.note.vue:
|
||||||
reposted-by: "Reposté par {}"
|
reposted-by: "Reposté par {}"
|
||||||
reply: "Répondre"
|
reply: "Répondre"
|
||||||
renote: "Renote"
|
renote: "Republier"
|
||||||
add-reaction: "Ajouter votre reaction"
|
add-reaction: "Ajouter votre reaction"
|
||||||
detail: "Afficher les détails"
|
detail: "Afficher les détails"
|
||||||
private: "cette publication est privée"
|
private: "cette publication est privée"
|
||||||
@ -360,7 +373,7 @@ desktop/views/components/post-form.vue:
|
|||||||
quote-placeholder: "Citer cette note"
|
quote-placeholder: "Citer cette note"
|
||||||
submit: "Poster"
|
submit: "Poster"
|
||||||
reply: "Répondre"
|
reply: "Répondre"
|
||||||
renote: "Renote"
|
renote: "Republier"
|
||||||
posted: "Posté!"
|
posted: "Posté!"
|
||||||
replied: "Répondu!"
|
replied: "Répondu!"
|
||||||
reposted: "Reposté!"
|
reposted: "Reposté!"
|
||||||
@ -384,7 +397,7 @@ desktop/views/components/progress-dialog.vue:
|
|||||||
desktop/views/components/renote-form.vue:
|
desktop/views/components/renote-form.vue:
|
||||||
quote: "Citer..."
|
quote: "Citer..."
|
||||||
cancel: "Annuler"
|
cancel: "Annuler"
|
||||||
renote: "Renote"
|
renote: "Republier"
|
||||||
reposting: "Repost en cours..."
|
reposting: "Repost en cours..."
|
||||||
success: "Reposté!"
|
success: "Reposté!"
|
||||||
failure: "La renote a échoué"
|
failure: "La renote a échoué"
|
||||||
@ -405,25 +418,25 @@ desktop/views/components/settings.vue:
|
|||||||
other: "Autres"
|
other: "Autres"
|
||||||
license: "License"
|
license: "License"
|
||||||
behaviour: "Comportement"
|
behaviour: "Comportement"
|
||||||
fetch-on-scroll: "スクロールで自動読み込み"
|
fetch-on-scroll: "Chargement lors du défilement"
|
||||||
fetch-on-scroll-desc: "ページを下までスクロールしたときに自動で追加のコンテンツを読み込みます。"
|
fetch-on-scroll-desc: "Chargement automatique du contenu lors du défilement de la page."
|
||||||
auto-popout: "ウィンドウの自動ポップアウト"
|
auto-popout: "Fenêtre contextuelle automatique"
|
||||||
auto-popout-desc: "ウィンドウが開かれるとき、ポップアウト(ブラウザ外に切り離す)可能なら自動でポップアウトします。この設定はブラウザに記憶されます。"
|
auto-popout-desc: "ウィンドウが開かれるとき、ポップアウト(ブラウザ外に切り離す)可能なら自動でポップアウトします。この設定はブラウザに記憶されます。"
|
||||||
advanced: "Paramètres avancés"
|
advanced: "Paramètres avancés"
|
||||||
api-via-stream: "ストリームを経由したAPIリクエスト"
|
api-via-stream: "Requête API via le flux"
|
||||||
api-via-stream-desc: "この設定をオンにすると、websocket接続を経由してAPIリクエストが行われます(パフォーマンス向上が期待できます)。オフにすると、ネイティブの fetch APIが利用されます。この設定はこのデバイスのみ有効です。"
|
api-via-stream-desc: "この設定をオンにすると、websocket接続を経由してAPIリクエストが行われます(パフォーマンス向上が期待できます)。オフにすると、ネイティブの fetch APIが利用されます。この設定はこのデバイスのみ有効です。"
|
||||||
display: "デザインと表示"
|
display: "Affichage et design"
|
||||||
customize: "Personnaliser l'Accueil"
|
customize: "Personnaliser l'Accueil"
|
||||||
dark-mode: "Mode nuit"
|
dark-mode: "Mode nuit"
|
||||||
circle-icons: "Utiliser des icônes circulaires"
|
circle-icons: "Utiliser des icônes circulaires"
|
||||||
gradient-window-header: "ウィンドウのタイトルバーにグラデーションを使用"
|
gradient-window-header: "ウィンドウのタイトルバーにグラデーションを使用"
|
||||||
post-form-on-timeline: "タイムライン上部に投稿フォームを表示する"
|
post-form-on-timeline: "タイムライン上部に投稿フォームを表示する"
|
||||||
show-reply-target: "リプライ先を表示する"
|
show-reply-target: "リプライ先を表示する"
|
||||||
show-my-renotes: "自分の行ったRenoteをタイムラインに表示する"
|
show-my-renotes: "Afficher mes republications dans le fil"
|
||||||
show-renoted-my-notes: "Renoteされた自分の投稿をタイムラインに表示する"
|
show-renoted-my-notes: "Renoteされた自分の投稿をタイムラインに表示する"
|
||||||
show-maps: "Afficher la carte"
|
show-maps: "Afficher la carte"
|
||||||
show-maps-desc: "位置情報が添付された投稿のマップを自動的に展開します。"
|
show-maps-desc: "位置情報が添付された投稿のマップを自動的に展開します。"
|
||||||
sound: "サウンド"
|
sound: "Son"
|
||||||
enable-sounds: "Activer le son"
|
enable-sounds: "Activer le son"
|
||||||
enable-sounds-desc: "投稿やメッセージを送受信したときなどにサウンドを再生します。この設定はブラウザに記憶されます。"
|
enable-sounds-desc: "投稿やメッセージを送受信したときなどにサウンドを再生します。この設定はブラウザに記憶されます。"
|
||||||
volume: "Volume"
|
volume: "Volume"
|
||||||
@ -439,32 +452,32 @@ desktop/views/components/settings.vue:
|
|||||||
cache: "Cache"
|
cache: "Cache"
|
||||||
clean-cache: "Nettoyage"
|
clean-cache: "Nettoyage"
|
||||||
cache-warn: "クリーンアップを行うと、ブラウザに記憶されたアカウント情報のキャッシュ、書きかけの投稿・返信・メッセージ、およびその他のデータ(設定情報含む)が削除されます。クリーンアップを行った後はページを再度読み込みする必要があります。"
|
cache-warn: "クリーンアップを行うと、ブラウザに記憶されたアカウント情報のキャッシュ、書きかけの投稿・返信・メッセージ、およびその他のデータ(設定情報含む)が削除されます。クリーンアップを行った後はページを再度読み込みする必要があります。"
|
||||||
cache-cleared: "キャッシュを削除しました"
|
cache-cleared: "Cache nettoyé"
|
||||||
cache-cleared-desc: "ページを再度読み込みしてください。"
|
cache-cleared-desc: "Veuillez recharger la page."
|
||||||
auto-watch: "投稿の自動ウォッチ"
|
auto-watch: "投稿の自動ウォッチ"
|
||||||
auto-watch-desc: "リアクションしたり返信したりした投稿に関する通知を自動的に受け取るようにします。"
|
auto-watch-desc: "リアクションしたり返信したりした投稿に関する通知を自動的に受け取るようにします。"
|
||||||
about: "À propose de Misskey"
|
about: "À propose de Misskey"
|
||||||
operator: "このサーバーの運営者"
|
operator: "L'admin de cette instance"
|
||||||
update: "Mise à jour de Misskey"
|
update: "Mise à jour de Misskey"
|
||||||
version: "Version :"
|
version: "Version :"
|
||||||
latest-version: "Dernière version :"
|
latest-version: "Dernière version :"
|
||||||
update-checking: "Recherche de mises à jour"
|
update-checking: "Recherche de mises à jour"
|
||||||
do-update: "アップデートを確認"
|
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."
|
||||||
update-available: "Nouvelle version disponible !"
|
update-available: "Nouvelle version disponible !"
|
||||||
update-available-desc: "ページを再度読み込みすると更新が適用されます。"
|
update-available-desc: "ページを再度読み込みすると更新が適用されます。"
|
||||||
advanced-settings: "Réglages avancés"
|
advanced-settings: "Réglages avancés"
|
||||||
debug-mode: "デバッグモードを有効にする"
|
debug-mode: "Activer le mode debug"
|
||||||
debug-mode-desc: "この設定はブラウザに記憶されます。"
|
debug-mode-desc: "Ce paramètre est stocké dans le navigateur."
|
||||||
experimental: "実験的機能を有効にする"
|
experimental: "Activer les fonctionnalités expérimentales"
|
||||||
experimental-desc: "実験的機能を有効にするとMisskeyの動作が不安定になる可能性があります。この設定はブラウザに記憶されます。"
|
experimental-desc: "実験的機能を有効にするとMisskeyの動作が不安定になる可能性があります。この設定はブラウザに記憶されます。"
|
||||||
tools: "Outils"
|
tools: "Outils"
|
||||||
task-manager: "Gestionnaire de tâches"
|
task-manager: "Gestionnaire de tâches"
|
||||||
third-parties: "サードパーティ"
|
third-parties: "Services tiers"
|
||||||
desktop/views/components/settings.2fa.vue:
|
desktop/views/components/settings.2fa.vue:
|
||||||
intro: "Si vous configurez la vérication en deux étapes vous aurez non seulement besoin de votre mot de passe mais aussi un appareil déjà pré-enregistré(tel que votre smartphone) ce qui ameliora grandement la sécurité de votre compte."
|
intro: "Si vous configurez la vérication en deux étapes vous aurez non seulement besoin de votre mot de passe mais aussi un appareil déjà pré-enregistré(tel que votre smartphone) ce qui ameliora grandement la sécurité de votre compte."
|
||||||
detail: "Voir les détails..."
|
detail: "Voir les détails..."
|
||||||
@ -491,7 +504,7 @@ desktop/views/components/settings.api.vue:
|
|||||||
token: "Jeton :"
|
token: "Jeton :"
|
||||||
enter-password: "Veuillez entrer le mot de passe"
|
enter-password: "Veuillez entrer le mot de passe"
|
||||||
desktop/views/components/settings.apps.vue:
|
desktop/views/components/settings.apps.vue:
|
||||||
no-apps: "連携しているアプリケーションはありません"
|
no-apps: "Aucune application autorisée"
|
||||||
desktop/views/components/settings.mute.vue:
|
desktop/views/components/settings.mute.vue:
|
||||||
no-users: "Aucun utilisateurs mis en sourdine"
|
no-users: "Aucun utilisateurs mis en sourdine"
|
||||||
desktop/views/components/settings.password.vue:
|
desktop/views/components/settings.password.vue:
|
||||||
@ -515,7 +528,7 @@ desktop/views/components/sub-note-content.vue:
|
|||||||
private: "cette publication est privée"
|
private: "cette publication est privée"
|
||||||
deleted: "cette publication a été supprimée"
|
deleted: "cette publication a été supprimée"
|
||||||
media-count: "{} médias attachés"
|
media-count: "{} médias attachés"
|
||||||
poll: "Sondages"
|
poll: "Sondage"
|
||||||
desktop/views/components/taskmanager.vue:
|
desktop/views/components/taskmanager.vue:
|
||||||
title: "Gestionnaire de tâches"
|
title: "Gestionnaire de tâches"
|
||||||
desktop/views/components/timeline.vue:
|
desktop/views/components/timeline.vue:
|
||||||
@ -553,7 +566,7 @@ desktop/views/components/user-lists-window.vue:
|
|||||||
create-list: "Créer une liste"
|
create-list: "Créer une liste"
|
||||||
desktop/views/components/user-preview.vue:
|
desktop/views/components/user-preview.vue:
|
||||||
notes: "Publications"
|
notes: "Publications"
|
||||||
following: "フォロー"
|
following: "Abonné à"
|
||||||
followers: "Abonnés"
|
followers: "Abonnés"
|
||||||
desktop/views/components/users-list.vue:
|
desktop/views/components/users-list.vue:
|
||||||
all: "Tout"
|
all: "Tout"
|
||||||
@ -565,13 +578,20 @@ desktop/views/components/users-list-item.vue:
|
|||||||
desktop/views/components/window.vue:
|
desktop/views/components/window.vue:
|
||||||
popout: "ポップアウト"
|
popout: "ポップアウト"
|
||||||
close: "Fermer"
|
close: "Fermer"
|
||||||
|
desktop/views/pages/deck/deck.tl-column.vue:
|
||||||
|
is-media-only: "Les publications médias uniquement"
|
||||||
|
is-media-view: "メディアビュー"
|
||||||
|
desktop/views/pages/deck/deck.note.vue:
|
||||||
|
reposted-by: "Reposté par {}"
|
||||||
|
private: "cette publication est privée"
|
||||||
|
deleted: "cette publication a été supprimée"
|
||||||
desktop/views/pages/welcome.vue:
|
desktop/views/pages/welcome.vue:
|
||||||
about: "à propos"
|
about: "à propos"
|
||||||
gotit: "J'ai compris !"
|
gotit: "J'ai compris !"
|
||||||
signin: "Connexion"
|
signin: "Connexion"
|
||||||
signup: "S'enregistrer"
|
signup: "S'enregistrer"
|
||||||
signin-button: "Se connecter"
|
signin-button: "Se connecter"
|
||||||
signup-button: "やる"
|
signup-button: "S'inscrire"
|
||||||
timeline: "Fil d'actualité"
|
timeline: "Fil d'actualité"
|
||||||
desktop/views/pages/drive.vue:
|
desktop/views/pages/drive.vue:
|
||||||
title: "Lecteur de Misskey"
|
title: "Lecteur de Misskey"
|
||||||
@ -655,11 +675,11 @@ mobile/views/components/drive.vue:
|
|||||||
nothing-in-drive: "Rien"
|
nothing-in-drive: "Rien"
|
||||||
folder-is-empty: "Ce dossier est vide"
|
folder-is-empty: "Ce dossier est vide"
|
||||||
prompt: "何をしますか?(数字を入力してください): <1 → ファイルをアップロード | 2 → ファイルをURLでアップロード | 3 → フォルダ作成 | 4 → このフォルダ名を変更 | 5 → このフォルダを移動 | 6 → このフォルダを削除>"
|
prompt: "何をしますか?(数字を入力してください): <1 → ファイルをアップロード | 2 → ファイルをURLでアップロード | 3 → フォルダ作成 | 4 → このフォルダ名を変更 | 5 → このフォルダを移動 | 6 → このフォルダを削除>"
|
||||||
deletion-alert: "ごめんなさい!フォルダの削除は未実装です...。"
|
deletion-alert: "Désolé ! La suppression d’un dossier n’est pas encore implémentée."
|
||||||
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"
|
||||||
@ -674,12 +694,12 @@ 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: "気になるユーザーをフォロー"
|
title: "Abonnez-vous aux utilisateurs"
|
||||||
empty: "おすすめのユーザーは見つかりませんでした。"
|
empty: "おすすめのユーザーは見つかりませんでした。"
|
||||||
fetching: "Chargement"
|
fetching: "Chargement"
|
||||||
refresh: "Voir plus"
|
refresh: "Voir plus"
|
||||||
@ -715,34 +735,34 @@ mobile/views/components/notifications.vue:
|
|||||||
mobile/views/components/post-form.vue:
|
mobile/views/components/post-form.vue:
|
||||||
add-visible-user: "Ajouter un utilisateur"
|
add-visible-user: "Ajouter un utilisateur"
|
||||||
submit: "Poster"
|
submit: "Poster"
|
||||||
reply: "返信"
|
reply: "Répondre"
|
||||||
renote: "Renote"
|
renote: "Republier"
|
||||||
quote-placeholder: "この投稿を引用... (オプション)"
|
quote-placeholder: "Citer ce billet ... (Facultatif)"
|
||||||
reply-placeholder: "Répondre à cette note"
|
reply-placeholder: "Répondre à cette note"
|
||||||
cw-placeholder: "内容への注釈 (オプション)"
|
cw-placeholder: "内容への注釈 (オプション)"
|
||||||
location-alert: "お使いの端末は位置情報に対応していません"
|
location-alert: "Votre appareil ne prend pas en charge les services de localisation"
|
||||||
error: "エラー"
|
error: "Erreur"
|
||||||
username-prompt: "ユーザー名を入力してください"
|
username-prompt: "Saisir un nom d'utilisateur"
|
||||||
mobile/views/components/sub-note-content.vue:
|
mobile/views/components/sub-note-content.vue:
|
||||||
private: "この投稿は非公開です"
|
private: "cette publication est privée"
|
||||||
deleted: "この投稿は削除されました"
|
deleted: "cette publication a été supprimée"
|
||||||
media-count: "{}つのメディア"
|
media-count: "{} médias attachés"
|
||||||
poll: "Sondage"
|
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"
|
||||||
mobile/views/components/ui.nav.vue:
|
mobile/views/components/ui.nav.vue:
|
||||||
timeline: "タイムライン"
|
timeline: "Fil d'actualité"
|
||||||
notifications: "Notifications"
|
notifications: "Notifications"
|
||||||
messaging: "Messages"
|
messaging: "Messages"
|
||||||
follow-requests: "フォロー申請"
|
follow-requests: "Demandes d'abonnement"
|
||||||
search: "Rechercher"
|
search: "Rechercher"
|
||||||
drive: "Drive"
|
drive: "Drive"
|
||||||
favorites: "お気に入り"
|
favorites: "Favoris"
|
||||||
user-lists: "リスト"
|
user-lists: "Listes"
|
||||||
widgets: "ウィジェット"
|
widgets: "Modules"
|
||||||
game: "ゲーム"
|
game: "Jeux"
|
||||||
darkmode: "ダークモード"
|
darkmode: "Mode nuit"
|
||||||
settings: "Réglages"
|
settings: "Réglages"
|
||||||
about: "À propose de Misskey"
|
about: "À propose de Misskey"
|
||||||
mobile/views/components/user-timeline.vue:
|
mobile/views/components/user-timeline.vue:
|
||||||
@ -757,10 +777,10 @@ mobile/views/pages/favorites.vue:
|
|||||||
title: "Favoris"
|
title: "Favoris"
|
||||||
mobile/views/pages/user-lists.vue:
|
mobile/views/pages/user-lists.vue:
|
||||||
title: "Listes"
|
title: "Listes"
|
||||||
enter-list-name: "リスト名を入力してください"
|
enter-list-name: "Nom de la liste"
|
||||||
mobile/views/pages/drive.vue:
|
mobile/views/pages/drive.vue:
|
||||||
drive: "Drive"
|
drive: "Drive"
|
||||||
more: "もっと見る"
|
more: "Afficher plus ..."
|
||||||
mobile/views/pages/followers.vue:
|
mobile/views/pages/followers.vue:
|
||||||
followers-of: "Abonnés de {}"
|
followers-of: "Abonnés de {}"
|
||||||
mobile/views/pages/following.vue:
|
mobile/views/pages/following.vue:
|
||||||
@ -806,7 +826,7 @@ mobile/views/pages/selectdrive.vue:
|
|||||||
mobile/views/pages/settings.vue:
|
mobile/views/pages/settings.vue:
|
||||||
signed-in-as: "Connecté en tant que {}"
|
signed-in-as: "Connecté en tant que {}"
|
||||||
lang: "Langue"
|
lang: "Langue"
|
||||||
lang-tip: "変更はページの再読み込み後に反映されます。"
|
lang-tip: "Le rechargement de la page est requis afin d'appliquer les modifications."
|
||||||
recommended: "Recommandé"
|
recommended: "Recommandé"
|
||||||
auto: "Automatique"
|
auto: "Automatique"
|
||||||
specify-language: "Spécifier la langue"
|
specify-language: "Spécifier la langue"
|
||||||
@ -822,7 +842,7 @@ mobile/views/pages/settings.vue:
|
|||||||
post-style-standard: "Standard"
|
post-style-standard: "Standard"
|
||||||
post-style-smart: "Intelligent"
|
post-style-smart: "Intelligent"
|
||||||
behavior: "Comportement"
|
behavior: "Comportement"
|
||||||
fetch-on-scroll: "スクロールで自動読み込み"
|
fetch-on-scroll: "Chargement lors du défilement"
|
||||||
disable-via-mobile: "「モバイルからの投稿」フラグを付けない"
|
disable-via-mobile: "「モバイルからの投稿」フラグを付けない"
|
||||||
load-raw-images: "Afficher les photos jointes en haute qualité"
|
load-raw-images: "Afficher les photos jointes en haute qualité"
|
||||||
load-remote-media: "Afficher les médias sur le serveur distant"
|
load-remote-media: "Afficher les médias sur le serveur distant"
|
||||||
|
@ -5,12 +5,15 @@
|
|||||||
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';
|
||||||
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'),
|
||||||
@ -23,4 +26,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;
|
||||||
|
@ -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:
|
||||||
@ -54,21 +54,23 @@ common:
|
|||||||
timemachine: "カレンダー(タイムマシン)"
|
timemachine: "カレンダー(タイムマシン)"
|
||||||
activity: "アクティビティ"
|
activity: "アクティビティ"
|
||||||
rss: "RSSリーダー"
|
rss: "RSSリーダー"
|
||||||
memo: "メモ"
|
memo: "付箋"
|
||||||
trends: "トレンド"
|
trends: "トレンド"
|
||||||
photo-stream: "フォトストリーム"
|
photo-stream: "フォトストリーム"
|
||||||
|
posts-monitor: "投稿チャート"
|
||||||
slideshow: "スライドショー"
|
slideshow: "スライドショー"
|
||||||
version: "バージョン"
|
version: "バージョン"
|
||||||
broadcast: "ブロードキャスト"
|
broadcast: "ブロードキャスト"
|
||||||
notifications: "通知"
|
notifications: "通知"
|
||||||
users: "おすすめユーザー"
|
users: "おすすめユーザー"
|
||||||
polls: "投票"
|
polls: "アンケート"
|
||||||
post-form: "投稿フォーム"
|
post-form: "投稿フォーム"
|
||||||
messaging: "メッセージ"
|
messaging: "メッセージ"
|
||||||
server: "サーバー情報"
|
server: "サーバー情報"
|
||||||
donation: "寄付のお願い"
|
donation: "寄付のお願い"
|
||||||
nav: "ナビゲーション"
|
nav: "ナビゲーション"
|
||||||
tips: "ヒント"
|
tips: "ヒント"
|
||||||
|
hashtags: "ハッシュタグ"
|
||||||
deck:
|
deck:
|
||||||
widgets: "ウィジェット"
|
widgets: "ウィジェット"
|
||||||
home: "ホーム"
|
home: "ホーム"
|
||||||
@ -78,9 +80,13 @@ common:
|
|||||||
list: "リスト"
|
list: "リスト"
|
||||||
swap-left: "左に移動"
|
swap-left: "左に移動"
|
||||||
swap-right: "右に移動"
|
swap-right: "右に移動"
|
||||||
|
swap-up: "上に移動"
|
||||||
|
swap-down: "下に移動"
|
||||||
remove: "カラムを削除"
|
remove: "カラムを削除"
|
||||||
add-column: "カラムを追加"
|
add-column: "カラムを追加"
|
||||||
rename: "名前を変更"
|
rename: "名前を変更"
|
||||||
|
stack-left: "左に重ねる"
|
||||||
|
pop-right: "右に出す"
|
||||||
common/views/components/connect-failed.vue:
|
common/views/components/connect-failed.vue:
|
||||||
title: "サーバーに接続できません"
|
title: "サーバーに接続できません"
|
||||||
description: "インターネット回線に問題があるか、サーバーがダウンまたはメンテナンスしている可能性があります。しばらくしてから{再度お試し}ください。"
|
description: "インターネット回線に問題があるか、サーバーがダウンまたはメンテナンスしている可能性があります。しばらくしてから{再度お試し}ください。"
|
||||||
@ -146,11 +152,11 @@ common/views/components/poll.vue:
|
|||||||
show-result: "結果を見る"
|
show-result: "結果を見る"
|
||||||
voted: "投票済み"
|
voted: "投票済み"
|
||||||
common/views/components/poll-editor.vue:
|
common/views/components/poll-editor.vue:
|
||||||
no-only-one-choice: "投票には、選択肢が最低2つ必要です"
|
no-only-one-choice: "アンケートには、選択肢が最低2つ必要です"
|
||||||
choice-n: "選択肢{}"
|
choice-n: "選択肢{}"
|
||||||
remove: "この選択肢を削除"
|
remove: "この選択肢を削除"
|
||||||
add: "+選択肢を追加"
|
add: "+選択肢を追加"
|
||||||
destroy: "投票を破棄"
|
destroy: "アンケートを破棄"
|
||||||
common/views/components/reaction-picker.vue:
|
common/views/components/reaction-picker.vue:
|
||||||
choose-reaction: "リアクションを選択"
|
choose-reaction: "リアクションを選択"
|
||||||
common/views/components/signin.vue:
|
common/views/components/signin.vue:
|
||||||
@ -216,11 +222,18 @@ common/views/widgets/donation.vue:
|
|||||||
common/views/widgets/photo-stream.vue:
|
common/views/widgets/photo-stream.vue:
|
||||||
title: "フォトストリーム"
|
title: "フォトストリーム"
|
||||||
no-photos: "写真はありません"
|
no-photos: "写真はありません"
|
||||||
|
common/views/widgets/posts-monitor.vue:
|
||||||
|
title: "投稿チャート"
|
||||||
|
toggle: "表示を切り替え"
|
||||||
|
common/views/widgets/hashtags.vue:
|
||||||
|
title: "ハッシュタグ"
|
||||||
|
count: "{}人が投稿"
|
||||||
|
empty: "トレンドなし"
|
||||||
common/views/widgets/server.vue:
|
common/views/widgets/server.vue:
|
||||||
title: "サーバー情報"
|
title: "サーバー情報"
|
||||||
toggle: "表示を切り替え"
|
toggle: "表示を切り替え"
|
||||||
common/views/widgets/memo.vue:
|
common/views/widgets/memo.vue:
|
||||||
title: "メモ"
|
title: "付箋"
|
||||||
memo: "ここに書いて!"
|
memo: "ここに書いて!"
|
||||||
save: "保存"
|
save: "保存"
|
||||||
desktop/views/components/activity.chart.vue:
|
desktop/views/components/activity.chart.vue:
|
||||||
@ -321,7 +334,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: "ウィジェットを追加:"
|
||||||
@ -372,7 +385,7 @@ desktop/views/components/post-form.vue:
|
|||||||
attach-media-from-drive: "ドライブからメディアを添付"
|
attach-media-from-drive: "ドライブからメディアを添付"
|
||||||
attach-cancel: "添付取り消し"
|
attach-cancel: "添付取り消し"
|
||||||
insert-a-kao: "v(‘ω’)v"
|
insert-a-kao: "v(‘ω’)v"
|
||||||
create-poll: "投票を作成"
|
create-poll: "アンケートを作成"
|
||||||
text-remain: "残り{}文字"
|
text-remain: "残り{}文字"
|
||||||
desktop/views/components/post-form-window.vue:
|
desktop/views/components/post-form-window.vue:
|
||||||
note: "新規投稿"
|
note: "新規投稿"
|
||||||
@ -515,7 +528,7 @@ desktop/views/components/sub-note-content.vue:
|
|||||||
private: "この投稿は非公開です"
|
private: "この投稿は非公開です"
|
||||||
deleted: "この投稿は削除されました"
|
deleted: "この投稿は削除されました"
|
||||||
media-count: "{}つのメディア"
|
media-count: "{}つのメディア"
|
||||||
poll: "投票"
|
poll: "アンケート"
|
||||||
desktop/views/components/taskmanager.vue:
|
desktop/views/components/taskmanager.vue:
|
||||||
title: "タスクマネージャ"
|
title: "タスクマネージャ"
|
||||||
desktop/views/components/timeline.vue:
|
desktop/views/components/timeline.vue:
|
||||||
@ -565,6 +578,13 @@ desktop/views/components/users-list-item.vue:
|
|||||||
desktop/views/components/window.vue:
|
desktop/views/components/window.vue:
|
||||||
popout: "ポップアウト"
|
popout: "ポップアウト"
|
||||||
close: "閉じる"
|
close: "閉じる"
|
||||||
|
desktop/views/pages/deck/deck.tl-column.vue:
|
||||||
|
is-media-only: "メディア投稿のみ"
|
||||||
|
is-media-view: "メディアビュー"
|
||||||
|
desktop/views/pages/deck/deck.note.vue:
|
||||||
|
reposted-by: "{}がRenote"
|
||||||
|
private: "この投稿は非公開です"
|
||||||
|
deleted: "この投稿は削除されました"
|
||||||
desktop/views/pages/welcome.vue:
|
desktop/views/pages/welcome.vue:
|
||||||
about: "詳しく..."
|
about: "詳しく..."
|
||||||
gotit: "わかった"
|
gotit: "わかった"
|
||||||
@ -628,7 +648,7 @@ desktop/views/widgets/notifications.vue:
|
|||||||
title: "通知"
|
title: "通知"
|
||||||
settings: "通知の設定"
|
settings: "通知の設定"
|
||||||
desktop/views/widgets/polls.vue:
|
desktop/views/widgets/polls.vue:
|
||||||
title: "投票"
|
title: "アンケート"
|
||||||
refresh: "他を見る"
|
refresh: "他を見る"
|
||||||
nothing: "ありません!"
|
nothing: "ありません!"
|
||||||
desktop/views/widgets/post-form.vue:
|
desktop/views/widgets/post-form.vue:
|
||||||
@ -727,7 +747,7 @@ mobile/views/components/sub-note-content.vue:
|
|||||||
private: "この投稿は非公開です"
|
private: "この投稿は非公開です"
|
||||||
deleted: "この投稿は削除されました"
|
deleted: "この投稿は削除されました"
|
||||||
media-count: "{}つのメディア"
|
media-count: "{}つのメディア"
|
||||||
poll: "投票"
|
poll: "アンケート"
|
||||||
mobile/views/components/timeline.vue:
|
mobile/views/components/timeline.vue:
|
||||||
empty: "投稿がありません"
|
empty: "投稿がありません"
|
||||||
load-more: "もっと"
|
load-more: "もっと"
|
||||||
|
@ -3,7 +3,7 @@ meta:
|
|||||||
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と相互に繋がっています。暫し都会の喧騒から離れて、新しいインターネットにダイブしてみませんか。"
|
||||||
|
|
||||||
@ -60,21 +60,23 @@ common:
|
|||||||
timemachine: "カレンダー(タイムマシン)"
|
timemachine: "カレンダー(タイムマシン)"
|
||||||
activity: "アクティビティ"
|
activity: "アクティビティ"
|
||||||
rss: "RSSリーダー"
|
rss: "RSSリーダー"
|
||||||
memo: "メモ"
|
memo: "付箋"
|
||||||
trends: "トレンド"
|
trends: "トレンド"
|
||||||
photo-stream: "フォトストリーム"
|
photo-stream: "フォトストリーム"
|
||||||
|
posts-monitor: "投稿チャート"
|
||||||
slideshow: "スライドショー"
|
slideshow: "スライドショー"
|
||||||
version: "バージョン"
|
version: "バージョン"
|
||||||
broadcast: "ブロードキャスト"
|
broadcast: "ブロードキャスト"
|
||||||
notifications: "通知"
|
notifications: "通知"
|
||||||
users: "おすすめユーザー"
|
users: "おすすめユーザー"
|
||||||
polls: "投票"
|
polls: "アンケート"
|
||||||
post-form: "投稿フォーム"
|
post-form: "投稿フォーム"
|
||||||
messaging: "メッセージ"
|
messaging: "メッセージ"
|
||||||
server: "サーバー情報"
|
server: "サーバー情報"
|
||||||
donation: "寄付のお願い"
|
donation: "寄付のお願い"
|
||||||
nav: "ナビゲーション"
|
nav: "ナビゲーション"
|
||||||
tips: "ヒント"
|
tips: "ヒント"
|
||||||
|
hashtags: "ハッシュタグ"
|
||||||
|
|
||||||
deck:
|
deck:
|
||||||
widgets: "ウィジェット"
|
widgets: "ウィジェット"
|
||||||
@ -85,9 +87,13 @@ common:
|
|||||||
list: "リスト"
|
list: "リスト"
|
||||||
swap-left: "左に移動"
|
swap-left: "左に移動"
|
||||||
swap-right: "右に移動"
|
swap-right: "右に移動"
|
||||||
|
swap-up: "上に移動"
|
||||||
|
swap-down: "下に移動"
|
||||||
remove: "カラムを削除"
|
remove: "カラムを削除"
|
||||||
add-column: "カラムを追加"
|
add-column: "カラムを追加"
|
||||||
rename: "名前を変更"
|
rename: "名前を変更"
|
||||||
|
stack-left: "左に重ねる"
|
||||||
|
pop-right: "右に出す"
|
||||||
|
|
||||||
common/views/components/connect-failed.vue:
|
common/views/components/connect-failed.vue:
|
||||||
title: "サーバーに接続できません"
|
title: "サーバーに接続できません"
|
||||||
@ -163,11 +169,11 @@ common/views/components/poll.vue:
|
|||||||
voted: "投票済み"
|
voted: "投票済み"
|
||||||
|
|
||||||
common/views/components/poll-editor.vue:
|
common/views/components/poll-editor.vue:
|
||||||
no-only-one-choice: "投票には、選択肢が最低2つ必要です"
|
no-only-one-choice: "アンケートには、選択肢が最低2つ必要です"
|
||||||
choice-n: "選択肢{}"
|
choice-n: "選択肢{}"
|
||||||
remove: "この選択肢を削除"
|
remove: "この選択肢を削除"
|
||||||
add: "+選択肢を追加"
|
add: "+選択肢を追加"
|
||||||
destroy: "投票を破棄"
|
destroy: "アンケートを破棄"
|
||||||
|
|
||||||
common/views/components/reaction-picker.vue:
|
common/views/components/reaction-picker.vue:
|
||||||
choose-reaction: "リアクションを選択"
|
choose-reaction: "リアクションを選択"
|
||||||
@ -245,12 +251,21 @@ common/views/widgets/photo-stream.vue:
|
|||||||
title: "フォトストリーム"
|
title: "フォトストリーム"
|
||||||
no-photos: "写真はありません"
|
no-photos: "写真はありません"
|
||||||
|
|
||||||
|
common/views/widgets/posts-monitor.vue:
|
||||||
|
title: "投稿チャート"
|
||||||
|
toggle: "表示を切り替え"
|
||||||
|
|
||||||
|
common/views/widgets/hashtags.vue:
|
||||||
|
title: "ハッシュタグ"
|
||||||
|
count: "{}人が投稿"
|
||||||
|
empty: "トレンドなし"
|
||||||
|
|
||||||
common/views/widgets/server.vue:
|
common/views/widgets/server.vue:
|
||||||
title: "サーバー情報"
|
title: "サーバー情報"
|
||||||
toggle: "表示を切り替え"
|
toggle: "表示を切り替え"
|
||||||
|
|
||||||
common/views/widgets/memo.vue:
|
common/views/widgets/memo.vue:
|
||||||
title: "メモ"
|
title: "付箋"
|
||||||
memo: "ここに書いて!"
|
memo: "ここに書いて!"
|
||||||
save: "保存"
|
save: "保存"
|
||||||
|
|
||||||
@ -369,7 +384,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: "完了"
|
||||||
@ -429,7 +444,7 @@ desktop/views/components/post-form.vue:
|
|||||||
attach-media-from-drive: "ドライブからメディアを添付"
|
attach-media-from-drive: "ドライブからメディアを添付"
|
||||||
attach-cancel: "添付取り消し"
|
attach-cancel: "添付取り消し"
|
||||||
insert-a-kao: "v(‘ω’)v"
|
insert-a-kao: "v(‘ω’)v"
|
||||||
create-poll: "投票を作成"
|
create-poll: "アンケートを作成"
|
||||||
text-remain: "残り{}文字"
|
text-remain: "残り{}文字"
|
||||||
|
|
||||||
desktop/views/components/post-form-window.vue:
|
desktop/views/components/post-form-window.vue:
|
||||||
@ -595,7 +610,7 @@ desktop/views/components/sub-note-content.vue:
|
|||||||
private: "この投稿は非公開です"
|
private: "この投稿は非公開です"
|
||||||
deleted: "この投稿は削除されました"
|
deleted: "この投稿は削除されました"
|
||||||
media-count: "{}つのメディア"
|
media-count: "{}つのメディア"
|
||||||
poll: "投票"
|
poll: "アンケート"
|
||||||
|
|
||||||
desktop/views/components/taskmanager.vue:
|
desktop/views/components/taskmanager.vue:
|
||||||
title: "タスクマネージャ"
|
title: "タスクマネージャ"
|
||||||
@ -659,6 +674,15 @@ desktop/views/components/window.vue:
|
|||||||
popout: "ポップアウト"
|
popout: "ポップアウト"
|
||||||
close: "閉じる"
|
close: "閉じる"
|
||||||
|
|
||||||
|
desktop/views/pages/deck/deck.tl-column.vue:
|
||||||
|
is-media-only: "メディア投稿のみ"
|
||||||
|
is-media-view: "メディアビュー"
|
||||||
|
|
||||||
|
desktop/views/pages/deck/deck.note.vue:
|
||||||
|
reposted-by: "{}がRenote"
|
||||||
|
private: "この投稿は非公開です"
|
||||||
|
deleted: "この投稿は削除されました"
|
||||||
|
|
||||||
desktop/views/pages/welcome.vue:
|
desktop/views/pages/welcome.vue:
|
||||||
about: "詳しく..."
|
about: "詳しく..."
|
||||||
gotit: "わかった"
|
gotit: "わかった"
|
||||||
@ -738,7 +762,7 @@ desktop/views/widgets/notifications.vue:
|
|||||||
settings: "通知の設定"
|
settings: "通知の設定"
|
||||||
|
|
||||||
desktop/views/widgets/polls.vue:
|
desktop/views/widgets/polls.vue:
|
||||||
title: "投票"
|
title: "アンケート"
|
||||||
refresh: "他を見る"
|
refresh: "他を見る"
|
||||||
nothing: "ありません!"
|
nothing: "ありません!"
|
||||||
|
|
||||||
@ -856,7 +880,7 @@ mobile/views/components/sub-note-content.vue:
|
|||||||
private: "この投稿は非公開です"
|
private: "この投稿は非公開です"
|
||||||
deleted: "この投稿は削除されました"
|
deleted: "この投稿は削除されました"
|
||||||
media-count: "{}つのメディア"
|
media-count: "{}つのメディア"
|
||||||
poll: "投票"
|
poll: "アンケート"
|
||||||
|
|
||||||
mobile/views/components/timeline.vue:
|
mobile/views/components/timeline.vue:
|
||||||
empty: "投稿がありません"
|
empty: "投稿がありません"
|
||||||
|
@ -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:
|
||||||
@ -54,21 +54,23 @@ common:
|
|||||||
timemachine: "カレンダー(タイムマシン)"
|
timemachine: "カレンダー(タイムマシン)"
|
||||||
activity: "アクティビティ"
|
activity: "アクティビティ"
|
||||||
rss: "RSSリーダー"
|
rss: "RSSリーダー"
|
||||||
memo: "メモ"
|
memo: "付箋"
|
||||||
trends: "トレンド"
|
trends: "トレンド"
|
||||||
photo-stream: "フォトストリーム"
|
photo-stream: "フォトストリーム"
|
||||||
|
posts-monitor: "投稿チャート"
|
||||||
slideshow: "スライドショー"
|
slideshow: "スライドショー"
|
||||||
version: "バージョン"
|
version: "バージョン"
|
||||||
broadcast: "ブロードキャスト"
|
broadcast: "ブロードキャスト"
|
||||||
notifications: "通知"
|
notifications: "通知"
|
||||||
users: "おすすめユーザー"
|
users: "おすすめユーザー"
|
||||||
polls: "投票"
|
polls: "アンケート"
|
||||||
post-form: "投稿フォーム"
|
post-form: "投稿フォーム"
|
||||||
messaging: "メッセージ"
|
messaging: "メッセージ"
|
||||||
server: "サーバー情報"
|
server: "サーバー情報"
|
||||||
donation: "寄付のお願い"
|
donation: "寄付のお願い"
|
||||||
nav: "ナビゲーション"
|
nav: "ナビゲーション"
|
||||||
tips: "ヒント"
|
tips: "ヒント"
|
||||||
|
hashtags: "ハッシュタグ"
|
||||||
deck:
|
deck:
|
||||||
widgets: "ウィジェット"
|
widgets: "ウィジェット"
|
||||||
home: "ホーム"
|
home: "ホーム"
|
||||||
@ -78,9 +80,13 @@ common:
|
|||||||
list: "リスト"
|
list: "リスト"
|
||||||
swap-left: "左に移動"
|
swap-left: "左に移動"
|
||||||
swap-right: "右に移動"
|
swap-right: "右に移動"
|
||||||
|
swap-up: "上に移動"
|
||||||
|
swap-down: "下に移動"
|
||||||
remove: "カラムを削除"
|
remove: "カラムを削除"
|
||||||
add-column: "カラムを追加"
|
add-column: "カラムを追加"
|
||||||
rename: "名前を変更"
|
rename: "名前を変更"
|
||||||
|
stack-left: "左に重ねる"
|
||||||
|
pop-right: "右に出す"
|
||||||
common/views/components/connect-failed.vue:
|
common/views/components/connect-failed.vue:
|
||||||
title: "サーバーに接続できません"
|
title: "サーバーに接続できません"
|
||||||
description: "インターネット回線に問題があるか、サーバーがダウンまたはメンテナンスしている可能性があります。しばらくしてから{再度お試し}ください。"
|
description: "インターネット回線に問題があるか、サーバーがダウンまたはメンテナンスしている可能性があります。しばらくしてから{再度お試し}ください。"
|
||||||
@ -146,11 +152,11 @@ common/views/components/poll.vue:
|
|||||||
show-result: "結果を見る"
|
show-result: "結果を見る"
|
||||||
voted: "投票済み"
|
voted: "投票済み"
|
||||||
common/views/components/poll-editor.vue:
|
common/views/components/poll-editor.vue:
|
||||||
no-only-one-choice: "投票には、選択肢が最低2つ必要です"
|
no-only-one-choice: "アンケートには、選択肢が最低2つ必要です"
|
||||||
choice-n: "選択肢{}"
|
choice-n: "選択肢{}"
|
||||||
remove: "この選択肢を削除"
|
remove: "この選択肢を削除"
|
||||||
add: "+選択肢を追加"
|
add: "+選択肢を追加"
|
||||||
destroy: "投票を破棄"
|
destroy: "アンケートを破棄"
|
||||||
common/views/components/reaction-picker.vue:
|
common/views/components/reaction-picker.vue:
|
||||||
choose-reaction: "リアクションを選択"
|
choose-reaction: "リアクションを選択"
|
||||||
common/views/components/signin.vue:
|
common/views/components/signin.vue:
|
||||||
@ -216,11 +222,18 @@ common/views/widgets/donation.vue:
|
|||||||
common/views/widgets/photo-stream.vue:
|
common/views/widgets/photo-stream.vue:
|
||||||
title: "フォトストリーム"
|
title: "フォトストリーム"
|
||||||
no-photos: "写真はありません"
|
no-photos: "写真はありません"
|
||||||
|
common/views/widgets/posts-monitor.vue:
|
||||||
|
title: "投稿チャート"
|
||||||
|
toggle: "表示を切り替え"
|
||||||
|
common/views/widgets/hashtags.vue:
|
||||||
|
title: "ハッシュタグ"
|
||||||
|
count: "{}人が投稿"
|
||||||
|
empty: "トレンドなし"
|
||||||
common/views/widgets/server.vue:
|
common/views/widgets/server.vue:
|
||||||
title: "サーバー情報"
|
title: "サーバー情報"
|
||||||
toggle: "表示を切り替え"
|
toggle: "表示を切り替え"
|
||||||
common/views/widgets/memo.vue:
|
common/views/widgets/memo.vue:
|
||||||
title: "メモ"
|
title: "付箋"
|
||||||
memo: "ここに書いて!"
|
memo: "ここに書いて!"
|
||||||
save: "保存"
|
save: "保存"
|
||||||
desktop/views/components/activity.chart.vue:
|
desktop/views/components/activity.chart.vue:
|
||||||
@ -321,7 +334,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: "ウィジェットを追加:"
|
||||||
@ -372,7 +385,7 @@ desktop/views/components/post-form.vue:
|
|||||||
attach-media-from-drive: "ドライブからメディアを添付"
|
attach-media-from-drive: "ドライブからメディアを添付"
|
||||||
attach-cancel: "添付取り消し"
|
attach-cancel: "添付取り消し"
|
||||||
insert-a-kao: "v(‘ω’)v"
|
insert-a-kao: "v(‘ω’)v"
|
||||||
create-poll: "投票を作成"
|
create-poll: "アンケートを作成"
|
||||||
text-remain: "残り{}文字"
|
text-remain: "残り{}文字"
|
||||||
desktop/views/components/post-form-window.vue:
|
desktop/views/components/post-form-window.vue:
|
||||||
note: "新規投稿"
|
note: "新規投稿"
|
||||||
@ -515,7 +528,7 @@ desktop/views/components/sub-note-content.vue:
|
|||||||
private: "この投稿は非公開です"
|
private: "この投稿は非公開です"
|
||||||
deleted: "この投稿は削除されました"
|
deleted: "この投稿は削除されました"
|
||||||
media-count: "{}つのメディア"
|
media-count: "{}つのメディア"
|
||||||
poll: "投票"
|
poll: "アンケート"
|
||||||
desktop/views/components/taskmanager.vue:
|
desktop/views/components/taskmanager.vue:
|
||||||
title: "タスクマネージャ"
|
title: "タスクマネージャ"
|
||||||
desktop/views/components/timeline.vue:
|
desktop/views/components/timeline.vue:
|
||||||
@ -565,6 +578,13 @@ desktop/views/components/users-list-item.vue:
|
|||||||
desktop/views/components/window.vue:
|
desktop/views/components/window.vue:
|
||||||
popout: "ポップアウト"
|
popout: "ポップアウト"
|
||||||
close: "閉じる"
|
close: "閉じる"
|
||||||
|
desktop/views/pages/deck/deck.tl-column.vue:
|
||||||
|
is-media-only: "メディア投稿のみ"
|
||||||
|
is-media-view: "メディアビュー"
|
||||||
|
desktop/views/pages/deck/deck.note.vue:
|
||||||
|
reposted-by: "{}がRenote"
|
||||||
|
private: "この投稿は非公開です"
|
||||||
|
deleted: "この投稿は削除されました"
|
||||||
desktop/views/pages/welcome.vue:
|
desktop/views/pages/welcome.vue:
|
||||||
about: "詳しく..."
|
about: "詳しく..."
|
||||||
gotit: "わかった"
|
gotit: "わかった"
|
||||||
@ -628,7 +648,7 @@ desktop/views/widgets/notifications.vue:
|
|||||||
title: "通知"
|
title: "通知"
|
||||||
settings: "通知の設定"
|
settings: "通知の設定"
|
||||||
desktop/views/widgets/polls.vue:
|
desktop/views/widgets/polls.vue:
|
||||||
title: "投票"
|
title: "アンケート"
|
||||||
refresh: "他を見る"
|
refresh: "他を見る"
|
||||||
nothing: "ありません!"
|
nothing: "ありません!"
|
||||||
desktop/views/widgets/post-form.vue:
|
desktop/views/widgets/post-form.vue:
|
||||||
@ -727,7 +747,7 @@ mobile/views/components/sub-note-content.vue:
|
|||||||
private: "この投稿は非公開です"
|
private: "この投稿は非公開です"
|
||||||
deleted: "この投稿は削除されました"
|
deleted: "この投稿は削除されました"
|
||||||
media-count: "{}つのメディア"
|
media-count: "{}つのメディア"
|
||||||
poll: "投票"
|
poll: "アンケート"
|
||||||
mobile/views/components/timeline.vue:
|
mobile/views/components/timeline.vue:
|
||||||
empty: "投稿がありません"
|
empty: "投稿がありません"
|
||||||
load-more: "もっと"
|
load-more: "もっと"
|
||||||
|
@ -3,9 +3,9 @@ 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: "Misskeyを見つけていただき、ありがとうございます。Misskeyは、地球で生まれた<b>分散マイクロブログSNS</b>です。Fediverse(様々なSNSで構成される宇宙)の中に存在するため、他のSNSと相互に繋がっています。暫し都会の喧騒から離れて、新しいインターネットにダイブしてみませんか。"
|
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:
|
||||||
unknown: "nieznany"
|
unknown: "nieznany"
|
||||||
future: "w przyszłości"
|
future: "w przyszłości"
|
||||||
@ -54,9 +54,10 @@ common:
|
|||||||
timemachine: "Kalendarz (wehikuł czasu)"
|
timemachine: "Kalendarz (wehikuł czasu)"
|
||||||
activity: "Aktywność"
|
activity: "Aktywność"
|
||||||
rss: "Czytnik RSS"
|
rss: "Czytnik RSS"
|
||||||
memo: "Notatki"
|
memo: "Notatka"
|
||||||
trends: "Na czasie"
|
trends: "Na czasie"
|
||||||
photo-stream: "Photostream"
|
photo-stream: "Photostream"
|
||||||
|
posts-monitor: "Wykres wpisów"
|
||||||
slideshow: "Pokaz slajdów"
|
slideshow: "Pokaz slajdów"
|
||||||
version: "Wersja"
|
version: "Wersja"
|
||||||
broadcast: "Transmisja"
|
broadcast: "Transmisja"
|
||||||
@ -69,6 +70,7 @@ common:
|
|||||||
donation: "Dotacje"
|
donation: "Dotacje"
|
||||||
nav: "Nawigacja"
|
nav: "Nawigacja"
|
||||||
tips: "Wskazówki"
|
tips: "Wskazówki"
|
||||||
|
hashtags: "Hashtagi"
|
||||||
deck:
|
deck:
|
||||||
widgets: "Widżety"
|
widgets: "Widżety"
|
||||||
home: "Strona główna"
|
home: "Strona główna"
|
||||||
@ -78,9 +80,13 @@ common:
|
|||||||
list: "Listy"
|
list: "Listy"
|
||||||
swap-left: "Przesuń w lewo"
|
swap-left: "Przesuń w lewo"
|
||||||
swap-right: "Przesuń w prawo"
|
swap-right: "Przesuń w prawo"
|
||||||
|
swap-up: "Przenieś w górę"
|
||||||
|
swap-down: "Przenieś w dół"
|
||||||
remove: "Usuń"
|
remove: "Usuń"
|
||||||
add-column: "Dodaj kolumnę"
|
add-column: "Dodaj kolumnę"
|
||||||
rename: "名前を変更"
|
rename: "Zmień nazwę"
|
||||||
|
stack-left: "左に重ねる"
|
||||||
|
pop-right: "右に出す"
|
||||||
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."
|
||||||
@ -146,11 +152,11 @@ common/views/components/poll.vue:
|
|||||||
show-result: "Pokaż wyniki"
|
show-result: "Pokaż wyniki"
|
||||||
voted: "Zagłosowano"
|
voted: "Zagłosowano"
|
||||||
common/views/components/poll-editor.vue:
|
common/views/components/poll-editor.vue:
|
||||||
no-only-one-choice: "Musisz wprowadzić dwie lub więcej opcji."
|
no-only-one-choice: "Musisz wprowadzić przynajmniej dwie opcje."
|
||||||
choice-n: "Opcja {}"
|
choice-n: "Opcja {}"
|
||||||
remove: "Usuń tą opcję"
|
remove: "Usuń tą opcję"
|
||||||
add: "+ Dodaj opcję"
|
add: "+ Dodaj opcję"
|
||||||
destroy: "Usuń ankietę"
|
destroy: "Usuń tę ankietę"
|
||||||
common/views/components/reaction-picker.vue:
|
common/views/components/reaction-picker.vue:
|
||||||
choose-reaction: "Wybierz reakcję"
|
choose-reaction: "Wybierz reakcję"
|
||||||
common/views/components/signin.vue:
|
common/views/components/signin.vue:
|
||||||
@ -216,11 +222,18 @@ common/views/widgets/donation.vue:
|
|||||||
common/views/widgets/photo-stream.vue:
|
common/views/widgets/photo-stream.vue:
|
||||||
title: "Photostream"
|
title: "Photostream"
|
||||||
no-photos: "Brak zdjęć"
|
no-photos: "Brak zdjęć"
|
||||||
|
common/views/widgets/posts-monitor.vue:
|
||||||
|
title: "Wykres wpisów"
|
||||||
|
toggle: "Przełącz widok"
|
||||||
|
common/views/widgets/hashtags.vue:
|
||||||
|
title: "Hashtagi"
|
||||||
|
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"
|
||||||
common/views/widgets/memo.vue:
|
common/views/widgets/memo.vue:
|
||||||
title: "Notatki"
|
title: "Notatka"
|
||||||
memo: "Napisz tutaj!"
|
memo: "Napisz tutaj!"
|
||||||
save: "Zapisz"
|
save: "Zapisz"
|
||||||
desktop/views/components/activity.chart.vue:
|
desktop/views/components/activity.chart.vue:
|
||||||
@ -321,7 +334,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:"
|
||||||
@ -515,7 +528,7 @@ desktop/views/components/sub-note-content.vue:
|
|||||||
private: "ten wpis jest prywatny"
|
private: "ten wpis jest prywatny"
|
||||||
deleted: "ten wpis został usunięty"
|
deleted: "ten wpis został usunięty"
|
||||||
media-count: "{}zawartości multimedialnej"
|
media-count: "{}zawartości multimedialnej"
|
||||||
poll: "Ankiety"
|
poll: "Ankieta"
|
||||||
desktop/views/components/taskmanager.vue:
|
desktop/views/components/taskmanager.vue:
|
||||||
title: "Menedżer zadań"
|
title: "Menedżer zadań"
|
||||||
desktop/views/components/timeline.vue:
|
desktop/views/components/timeline.vue:
|
||||||
@ -535,7 +548,7 @@ desktop/views/components/ui.header.account.vue:
|
|||||||
dark: "Sprowadź ciemność"
|
dark: "Sprowadź ciemność"
|
||||||
desktop/views/components/ui.header.nav.vue:
|
desktop/views/components/ui.header.nav.vue:
|
||||||
home: "Strona główna"
|
home: "Strona główna"
|
||||||
deck: "デッキ"
|
deck: "Talia"
|
||||||
messaging: "Wiadomości"
|
messaging: "Wiadomości"
|
||||||
game: "Gra"
|
game: "Gra"
|
||||||
desktop/views/components/ui.header.notifications.vue:
|
desktop/views/components/ui.header.notifications.vue:
|
||||||
@ -565,6 +578,13 @@ desktop/views/components/users-list-item.vue:
|
|||||||
desktop/views/components/window.vue:
|
desktop/views/components/window.vue:
|
||||||
popout: "Pop-out"
|
popout: "Pop-out"
|
||||||
close: "Zamknij"
|
close: "Zamknij"
|
||||||
|
desktop/views/pages/deck/deck.tl-column.vue:
|
||||||
|
is-media-only: "Tylko wpisy z zawartością multimedialną"
|
||||||
|
is-media-view: "Widok multimediów"
|
||||||
|
desktop/views/pages/deck/deck.note.vue:
|
||||||
|
reposted-by: "Udostępniono przez {}"
|
||||||
|
private: "ten wpis jest prywatny"
|
||||||
|
deleted: "ten wpis został usunięty"
|
||||||
desktop/views/pages/welcome.vue:
|
desktop/views/pages/welcome.vue:
|
||||||
about: "O Misskey"
|
about: "O Misskey"
|
||||||
gotit: "Rozumiem!"
|
gotit: "Rozumiem!"
|
||||||
|
@ -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:
|
||||||
@ -54,21 +54,23 @@ common:
|
|||||||
timemachine: "カレンダー(タイムマシン)"
|
timemachine: "カレンダー(タイムマシン)"
|
||||||
activity: "アクティビティ"
|
activity: "アクティビティ"
|
||||||
rss: "RSSリーダー"
|
rss: "RSSリーダー"
|
||||||
memo: "メモ"
|
memo: "付箋"
|
||||||
trends: "トレンド"
|
trends: "トレンド"
|
||||||
photo-stream: "フォトストリーム"
|
photo-stream: "フォトストリーム"
|
||||||
|
posts-monitor: "投稿チャート"
|
||||||
slideshow: "スライドショー"
|
slideshow: "スライドショー"
|
||||||
version: "バージョン"
|
version: "バージョン"
|
||||||
broadcast: "ブロードキャスト"
|
broadcast: "ブロードキャスト"
|
||||||
notifications: "通知"
|
notifications: "通知"
|
||||||
users: "おすすめユーザー"
|
users: "おすすめユーザー"
|
||||||
polls: "投票"
|
polls: "アンケート"
|
||||||
post-form: "投稿フォーム"
|
post-form: "投稿フォーム"
|
||||||
messaging: "メッセージ"
|
messaging: "メッセージ"
|
||||||
server: "サーバー情報"
|
server: "サーバー情報"
|
||||||
donation: "寄付のお願い"
|
donation: "寄付のお願い"
|
||||||
nav: "ナビゲーション"
|
nav: "ナビゲーション"
|
||||||
tips: "ヒント"
|
tips: "ヒント"
|
||||||
|
hashtags: "ハッシュタグ"
|
||||||
deck:
|
deck:
|
||||||
widgets: "ウィジェット"
|
widgets: "ウィジェット"
|
||||||
home: "ホーム"
|
home: "ホーム"
|
||||||
@ -78,9 +80,13 @@ common:
|
|||||||
list: "リスト"
|
list: "リスト"
|
||||||
swap-left: "左に移動"
|
swap-left: "左に移動"
|
||||||
swap-right: "右に移動"
|
swap-right: "右に移動"
|
||||||
|
swap-up: "上に移動"
|
||||||
|
swap-down: "下に移動"
|
||||||
remove: "カラムを削除"
|
remove: "カラムを削除"
|
||||||
add-column: "カラムを追加"
|
add-column: "カラムを追加"
|
||||||
rename: "名前を変更"
|
rename: "名前を変更"
|
||||||
|
stack-left: "左に重ねる"
|
||||||
|
pop-right: "右に出す"
|
||||||
common/views/components/connect-failed.vue:
|
common/views/components/connect-failed.vue:
|
||||||
title: "サーバーに接続できません"
|
title: "サーバーに接続できません"
|
||||||
description: "インターネット回線に問題があるか、サーバーがダウンまたはメンテナンスしている可能性があります。しばらくしてから{再度お試し}ください。"
|
description: "インターネット回線に問題があるか、サーバーがダウンまたはメンテナンスしている可能性があります。しばらくしてから{再度お試し}ください。"
|
||||||
@ -146,11 +152,11 @@ common/views/components/poll.vue:
|
|||||||
show-result: "結果を見る"
|
show-result: "結果を見る"
|
||||||
voted: "投票済み"
|
voted: "投票済み"
|
||||||
common/views/components/poll-editor.vue:
|
common/views/components/poll-editor.vue:
|
||||||
no-only-one-choice: "投票には、選択肢が最低2つ必要です"
|
no-only-one-choice: "アンケートには、選択肢が最低2つ必要です"
|
||||||
choice-n: "選択肢{}"
|
choice-n: "選択肢{}"
|
||||||
remove: "この選択肢を削除"
|
remove: "この選択肢を削除"
|
||||||
add: "+選択肢を追加"
|
add: "+選択肢を追加"
|
||||||
destroy: "投票を破棄"
|
destroy: "アンケートを破棄"
|
||||||
common/views/components/reaction-picker.vue:
|
common/views/components/reaction-picker.vue:
|
||||||
choose-reaction: "リアクションを選択"
|
choose-reaction: "リアクションを選択"
|
||||||
common/views/components/signin.vue:
|
common/views/components/signin.vue:
|
||||||
@ -216,11 +222,18 @@ common/views/widgets/donation.vue:
|
|||||||
common/views/widgets/photo-stream.vue:
|
common/views/widgets/photo-stream.vue:
|
||||||
title: "フォトストリーム"
|
title: "フォトストリーム"
|
||||||
no-photos: "写真はありません"
|
no-photos: "写真はありません"
|
||||||
|
common/views/widgets/posts-monitor.vue:
|
||||||
|
title: "投稿チャート"
|
||||||
|
toggle: "表示を切り替え"
|
||||||
|
common/views/widgets/hashtags.vue:
|
||||||
|
title: "ハッシュタグ"
|
||||||
|
count: "{}人が投稿"
|
||||||
|
empty: "トレンドなし"
|
||||||
common/views/widgets/server.vue:
|
common/views/widgets/server.vue:
|
||||||
title: "サーバー情報"
|
title: "サーバー情報"
|
||||||
toggle: "表示を切り替え"
|
toggle: "表示を切り替え"
|
||||||
common/views/widgets/memo.vue:
|
common/views/widgets/memo.vue:
|
||||||
title: "メモ"
|
title: "付箋"
|
||||||
memo: "ここに書いて!"
|
memo: "ここに書いて!"
|
||||||
save: "保存"
|
save: "保存"
|
||||||
desktop/views/components/activity.chart.vue:
|
desktop/views/components/activity.chart.vue:
|
||||||
@ -321,7 +334,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: "ウィジェットを追加:"
|
||||||
@ -372,7 +385,7 @@ desktop/views/components/post-form.vue:
|
|||||||
attach-media-from-drive: "ドライブからメディアを添付"
|
attach-media-from-drive: "ドライブからメディアを添付"
|
||||||
attach-cancel: "添付取り消し"
|
attach-cancel: "添付取り消し"
|
||||||
insert-a-kao: "v(‘ω’)v"
|
insert-a-kao: "v(‘ω’)v"
|
||||||
create-poll: "投票を作成"
|
create-poll: "アンケートを作成"
|
||||||
text-remain: "残り{}文字"
|
text-remain: "残り{}文字"
|
||||||
desktop/views/components/post-form-window.vue:
|
desktop/views/components/post-form-window.vue:
|
||||||
note: "新規投稿"
|
note: "新規投稿"
|
||||||
@ -515,7 +528,7 @@ desktop/views/components/sub-note-content.vue:
|
|||||||
private: "この投稿は非公開です"
|
private: "この投稿は非公開です"
|
||||||
deleted: "この投稿は削除されました"
|
deleted: "この投稿は削除されました"
|
||||||
media-count: "{}つのメディア"
|
media-count: "{}つのメディア"
|
||||||
poll: "投票"
|
poll: "アンケート"
|
||||||
desktop/views/components/taskmanager.vue:
|
desktop/views/components/taskmanager.vue:
|
||||||
title: "タスクマネージャ"
|
title: "タスクマネージャ"
|
||||||
desktop/views/components/timeline.vue:
|
desktop/views/components/timeline.vue:
|
||||||
@ -565,6 +578,13 @@ desktop/views/components/users-list-item.vue:
|
|||||||
desktop/views/components/window.vue:
|
desktop/views/components/window.vue:
|
||||||
popout: "ポップアウト"
|
popout: "ポップアウト"
|
||||||
close: "閉じる"
|
close: "閉じる"
|
||||||
|
desktop/views/pages/deck/deck.tl-column.vue:
|
||||||
|
is-media-only: "メディア投稿のみ"
|
||||||
|
is-media-view: "メディアビュー"
|
||||||
|
desktop/views/pages/deck/deck.note.vue:
|
||||||
|
reposted-by: "{}がRenote"
|
||||||
|
private: "この投稿は非公開です"
|
||||||
|
deleted: "この投稿は削除されました"
|
||||||
desktop/views/pages/welcome.vue:
|
desktop/views/pages/welcome.vue:
|
||||||
about: "詳しく..."
|
about: "詳しく..."
|
||||||
gotit: "わかった"
|
gotit: "わかった"
|
||||||
@ -628,7 +648,7 @@ desktop/views/widgets/notifications.vue:
|
|||||||
title: "通知"
|
title: "通知"
|
||||||
settings: "通知の設定"
|
settings: "通知の設定"
|
||||||
desktop/views/widgets/polls.vue:
|
desktop/views/widgets/polls.vue:
|
||||||
title: "投票"
|
title: "アンケート"
|
||||||
refresh: "他を見る"
|
refresh: "他を見る"
|
||||||
nothing: "ありません!"
|
nothing: "ありません!"
|
||||||
desktop/views/widgets/post-form.vue:
|
desktop/views/widgets/post-form.vue:
|
||||||
@ -727,7 +747,7 @@ mobile/views/components/sub-note-content.vue:
|
|||||||
private: "この投稿は非公開です"
|
private: "この投稿は非公開です"
|
||||||
deleted: "この投稿は削除されました"
|
deleted: "この投稿は削除されました"
|
||||||
media-count: "{}つのメディア"
|
media-count: "{}つのメディア"
|
||||||
poll: "投票"
|
poll: "アンケート"
|
||||||
mobile/views/components/timeline.vue:
|
mobile/views/components/timeline.vue:
|
||||||
empty: "投稿がありません"
|
empty: "投稿がありません"
|
||||||
load-more: "もっと"
|
load-more: "もっと"
|
||||||
|
@ -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:
|
||||||
@ -54,21 +54,23 @@ common:
|
|||||||
timemachine: "カレンダー(タイムマシン)"
|
timemachine: "カレンダー(タイムマシン)"
|
||||||
activity: "アクティビティ"
|
activity: "アクティビティ"
|
||||||
rss: "RSSリーダー"
|
rss: "RSSリーダー"
|
||||||
memo: "メモ"
|
memo: "付箋"
|
||||||
trends: "トレンド"
|
trends: "トレンド"
|
||||||
photo-stream: "フォトストリーム"
|
photo-stream: "フォトストリーム"
|
||||||
|
posts-monitor: "投稿チャート"
|
||||||
slideshow: "スライドショー"
|
slideshow: "スライドショー"
|
||||||
version: "バージョン"
|
version: "バージョン"
|
||||||
broadcast: "ブロードキャスト"
|
broadcast: "ブロードキャスト"
|
||||||
notifications: "通知"
|
notifications: "通知"
|
||||||
users: "おすすめユーザー"
|
users: "おすすめユーザー"
|
||||||
polls: "投票"
|
polls: "アンケート"
|
||||||
post-form: "投稿フォーム"
|
post-form: "投稿フォーム"
|
||||||
messaging: "メッセージ"
|
messaging: "メッセージ"
|
||||||
server: "サーバー情報"
|
server: "サーバー情報"
|
||||||
donation: "寄付のお願い"
|
donation: "寄付のお願い"
|
||||||
nav: "ナビゲーション"
|
nav: "ナビゲーション"
|
||||||
tips: "ヒント"
|
tips: "ヒント"
|
||||||
|
hashtags: "ハッシュタグ"
|
||||||
deck:
|
deck:
|
||||||
widgets: "ウィジェット"
|
widgets: "ウィジェット"
|
||||||
home: "ホーム"
|
home: "ホーム"
|
||||||
@ -78,9 +80,13 @@ common:
|
|||||||
list: "リスト"
|
list: "リスト"
|
||||||
swap-left: "左に移動"
|
swap-left: "左に移動"
|
||||||
swap-right: "右に移動"
|
swap-right: "右に移動"
|
||||||
|
swap-up: "上に移動"
|
||||||
|
swap-down: "下に移動"
|
||||||
remove: "カラムを削除"
|
remove: "カラムを削除"
|
||||||
add-column: "カラムを追加"
|
add-column: "カラムを追加"
|
||||||
rename: "名前を変更"
|
rename: "名前を変更"
|
||||||
|
stack-left: "左に重ねる"
|
||||||
|
pop-right: "右に出す"
|
||||||
common/views/components/connect-failed.vue:
|
common/views/components/connect-failed.vue:
|
||||||
title: "サーバーに接続できません"
|
title: "サーバーに接続できません"
|
||||||
description: "インターネット回線に問題があるか、サーバーがダウンまたはメンテナンスしている可能性があります。しばらくしてから{再度お試し}ください。"
|
description: "インターネット回線に問題があるか、サーバーがダウンまたはメンテナンスしている可能性があります。しばらくしてから{再度お試し}ください。"
|
||||||
@ -146,11 +152,11 @@ common/views/components/poll.vue:
|
|||||||
show-result: "結果を見る"
|
show-result: "結果を見る"
|
||||||
voted: "投票済み"
|
voted: "投票済み"
|
||||||
common/views/components/poll-editor.vue:
|
common/views/components/poll-editor.vue:
|
||||||
no-only-one-choice: "投票には、選択肢が最低2つ必要です"
|
no-only-one-choice: "アンケートには、選択肢が最低2つ必要です"
|
||||||
choice-n: "選択肢{}"
|
choice-n: "選択肢{}"
|
||||||
remove: "この選択肢を削除"
|
remove: "この選択肢を削除"
|
||||||
add: "+選択肢を追加"
|
add: "+選択肢を追加"
|
||||||
destroy: "投票を破棄"
|
destroy: "アンケートを破棄"
|
||||||
common/views/components/reaction-picker.vue:
|
common/views/components/reaction-picker.vue:
|
||||||
choose-reaction: "リアクションを選択"
|
choose-reaction: "リアクションを選択"
|
||||||
common/views/components/signin.vue:
|
common/views/components/signin.vue:
|
||||||
@ -216,11 +222,18 @@ common/views/widgets/donation.vue:
|
|||||||
common/views/widgets/photo-stream.vue:
|
common/views/widgets/photo-stream.vue:
|
||||||
title: "フォトストリーム"
|
title: "フォトストリーム"
|
||||||
no-photos: "写真はありません"
|
no-photos: "写真はありません"
|
||||||
|
common/views/widgets/posts-monitor.vue:
|
||||||
|
title: "投稿チャート"
|
||||||
|
toggle: "表示を切り替え"
|
||||||
|
common/views/widgets/hashtags.vue:
|
||||||
|
title: "ハッシュタグ"
|
||||||
|
count: "{}人が投稿"
|
||||||
|
empty: "トレンドなし"
|
||||||
common/views/widgets/server.vue:
|
common/views/widgets/server.vue:
|
||||||
title: "サーバー情報"
|
title: "サーバー情報"
|
||||||
toggle: "表示を切り替え"
|
toggle: "表示を切り替え"
|
||||||
common/views/widgets/memo.vue:
|
common/views/widgets/memo.vue:
|
||||||
title: "メモ"
|
title: "付箋"
|
||||||
memo: "ここに書いて!"
|
memo: "ここに書いて!"
|
||||||
save: "保存"
|
save: "保存"
|
||||||
desktop/views/components/activity.chart.vue:
|
desktop/views/components/activity.chart.vue:
|
||||||
@ -321,7 +334,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: "ウィジェットを追加:"
|
||||||
@ -372,7 +385,7 @@ desktop/views/components/post-form.vue:
|
|||||||
attach-media-from-drive: "ドライブからメディアを添付"
|
attach-media-from-drive: "ドライブからメディアを添付"
|
||||||
attach-cancel: "添付取り消し"
|
attach-cancel: "添付取り消し"
|
||||||
insert-a-kao: "v(‘ω’)v"
|
insert-a-kao: "v(‘ω’)v"
|
||||||
create-poll: "投票を作成"
|
create-poll: "アンケートを作成"
|
||||||
text-remain: "残り{}文字"
|
text-remain: "残り{}文字"
|
||||||
desktop/views/components/post-form-window.vue:
|
desktop/views/components/post-form-window.vue:
|
||||||
note: "新規投稿"
|
note: "新規投稿"
|
||||||
@ -515,7 +528,7 @@ desktop/views/components/sub-note-content.vue:
|
|||||||
private: "この投稿は非公開です"
|
private: "この投稿は非公開です"
|
||||||
deleted: "この投稿は削除されました"
|
deleted: "この投稿は削除されました"
|
||||||
media-count: "{}つのメディア"
|
media-count: "{}つのメディア"
|
||||||
poll: "投票"
|
poll: "アンケート"
|
||||||
desktop/views/components/taskmanager.vue:
|
desktop/views/components/taskmanager.vue:
|
||||||
title: "タスクマネージャ"
|
title: "タスクマネージャ"
|
||||||
desktop/views/components/timeline.vue:
|
desktop/views/components/timeline.vue:
|
||||||
@ -565,6 +578,13 @@ desktop/views/components/users-list-item.vue:
|
|||||||
desktop/views/components/window.vue:
|
desktop/views/components/window.vue:
|
||||||
popout: "ポップアウト"
|
popout: "ポップアウト"
|
||||||
close: "閉じる"
|
close: "閉じる"
|
||||||
|
desktop/views/pages/deck/deck.tl-column.vue:
|
||||||
|
is-media-only: "メディア投稿のみ"
|
||||||
|
is-media-view: "メディアビュー"
|
||||||
|
desktop/views/pages/deck/deck.note.vue:
|
||||||
|
reposted-by: "{}がRenote"
|
||||||
|
private: "この投稿は非公開です"
|
||||||
|
deleted: "この投稿は削除されました"
|
||||||
desktop/views/pages/welcome.vue:
|
desktop/views/pages/welcome.vue:
|
||||||
about: "詳しく..."
|
about: "詳しく..."
|
||||||
gotit: "わかった"
|
gotit: "わかった"
|
||||||
@ -628,7 +648,7 @@ desktop/views/widgets/notifications.vue:
|
|||||||
title: "通知"
|
title: "通知"
|
||||||
settings: "通知の設定"
|
settings: "通知の設定"
|
||||||
desktop/views/widgets/polls.vue:
|
desktop/views/widgets/polls.vue:
|
||||||
title: "投票"
|
title: "アンケート"
|
||||||
refresh: "他を見る"
|
refresh: "他を見る"
|
||||||
nothing: "ありません!"
|
nothing: "ありません!"
|
||||||
desktop/views/widgets/post-form.vue:
|
desktop/views/widgets/post-form.vue:
|
||||||
@ -727,7 +747,7 @@ mobile/views/components/sub-note-content.vue:
|
|||||||
private: "この投稿は非公開です"
|
private: "この投稿は非公開です"
|
||||||
deleted: "この投稿は削除されました"
|
deleted: "この投稿は削除されました"
|
||||||
media-count: "{}つのメディア"
|
media-count: "{}つのメディア"
|
||||||
poll: "投票"
|
poll: "アンケート"
|
||||||
mobile/views/components/timeline.vue:
|
mobile/views/components/timeline.vue:
|
||||||
empty: "投稿がありません"
|
empty: "投稿がありません"
|
||||||
load-more: "もっと"
|
load-more: "もっと"
|
||||||
|
@ -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:
|
||||||
@ -54,21 +54,23 @@ common:
|
|||||||
timemachine: "カレンダー(タイムマシン)"
|
timemachine: "カレンダー(タイムマシン)"
|
||||||
activity: "アクティビティ"
|
activity: "アクティビティ"
|
||||||
rss: "RSSリーダー"
|
rss: "RSSリーダー"
|
||||||
memo: "メモ"
|
memo: "付箋"
|
||||||
trends: "トレンド"
|
trends: "トレンド"
|
||||||
photo-stream: "フォトストリーム"
|
photo-stream: "フォトストリーム"
|
||||||
|
posts-monitor: "投稿チャート"
|
||||||
slideshow: "スライドショー"
|
slideshow: "スライドショー"
|
||||||
version: "バージョン"
|
version: "バージョン"
|
||||||
broadcast: "ブロードキャスト"
|
broadcast: "ブロードキャスト"
|
||||||
notifications: "通知"
|
notifications: "通知"
|
||||||
users: "おすすめユーザー"
|
users: "おすすめユーザー"
|
||||||
polls: "投票"
|
polls: "アンケート"
|
||||||
post-form: "投稿フォーム"
|
post-form: "投稿フォーム"
|
||||||
messaging: "メッセージ"
|
messaging: "メッセージ"
|
||||||
server: "サーバー情報"
|
server: "サーバー情報"
|
||||||
donation: "寄付のお願い"
|
donation: "寄付のお願い"
|
||||||
nav: "ナビゲーション"
|
nav: "ナビゲーション"
|
||||||
tips: "ヒント"
|
tips: "ヒント"
|
||||||
|
hashtags: "ハッシュタグ"
|
||||||
deck:
|
deck:
|
||||||
widgets: "ウィジェット"
|
widgets: "ウィジェット"
|
||||||
home: "ホーム"
|
home: "ホーム"
|
||||||
@ -78,9 +80,13 @@ common:
|
|||||||
list: "リスト"
|
list: "リスト"
|
||||||
swap-left: "左に移動"
|
swap-left: "左に移動"
|
||||||
swap-right: "右に移動"
|
swap-right: "右に移動"
|
||||||
|
swap-up: "上に移動"
|
||||||
|
swap-down: "下に移動"
|
||||||
remove: "カラムを削除"
|
remove: "カラムを削除"
|
||||||
add-column: "カラムを追加"
|
add-column: "カラムを追加"
|
||||||
rename: "名前を変更"
|
rename: "名前を変更"
|
||||||
|
stack-left: "左に重ねる"
|
||||||
|
pop-right: "右に出す"
|
||||||
common/views/components/connect-failed.vue:
|
common/views/components/connect-failed.vue:
|
||||||
title: "サーバーに接続できません"
|
title: "サーバーに接続できません"
|
||||||
description: "インターネット回線に問題があるか、サーバーがダウンまたはメンテナンスしている可能性があります。しばらくしてから{再度お試し}ください。"
|
description: "インターネット回線に問題があるか、サーバーがダウンまたはメンテナンスしている可能性があります。しばらくしてから{再度お試し}ください。"
|
||||||
@ -146,11 +152,11 @@ common/views/components/poll.vue:
|
|||||||
show-result: "結果を見る"
|
show-result: "結果を見る"
|
||||||
voted: "投票済み"
|
voted: "投票済み"
|
||||||
common/views/components/poll-editor.vue:
|
common/views/components/poll-editor.vue:
|
||||||
no-only-one-choice: "投票には、選択肢が最低2つ必要です"
|
no-only-one-choice: "アンケートには、選択肢が最低2つ必要です"
|
||||||
choice-n: "選択肢{}"
|
choice-n: "選択肢{}"
|
||||||
remove: "この選択肢を削除"
|
remove: "この選択肢を削除"
|
||||||
add: "+選択肢を追加"
|
add: "+選択肢を追加"
|
||||||
destroy: "投票を破棄"
|
destroy: "アンケートを破棄"
|
||||||
common/views/components/reaction-picker.vue:
|
common/views/components/reaction-picker.vue:
|
||||||
choose-reaction: "リアクションを選択"
|
choose-reaction: "リアクションを選択"
|
||||||
common/views/components/signin.vue:
|
common/views/components/signin.vue:
|
||||||
@ -216,11 +222,18 @@ common/views/widgets/donation.vue:
|
|||||||
common/views/widgets/photo-stream.vue:
|
common/views/widgets/photo-stream.vue:
|
||||||
title: "フォトストリーム"
|
title: "フォトストリーム"
|
||||||
no-photos: "写真はありません"
|
no-photos: "写真はありません"
|
||||||
|
common/views/widgets/posts-monitor.vue:
|
||||||
|
title: "投稿チャート"
|
||||||
|
toggle: "表示を切り替え"
|
||||||
|
common/views/widgets/hashtags.vue:
|
||||||
|
title: "ハッシュタグ"
|
||||||
|
count: "{}人が投稿"
|
||||||
|
empty: "トレンドなし"
|
||||||
common/views/widgets/server.vue:
|
common/views/widgets/server.vue:
|
||||||
title: "サーバー情報"
|
title: "サーバー情報"
|
||||||
toggle: "表示を切り替え"
|
toggle: "表示を切り替え"
|
||||||
common/views/widgets/memo.vue:
|
common/views/widgets/memo.vue:
|
||||||
title: "メモ"
|
title: "付箋"
|
||||||
memo: "ここに書いて!"
|
memo: "ここに書いて!"
|
||||||
save: "保存"
|
save: "保存"
|
||||||
desktop/views/components/activity.chart.vue:
|
desktop/views/components/activity.chart.vue:
|
||||||
@ -321,7 +334,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: "ウィジェットを追加:"
|
||||||
@ -372,7 +385,7 @@ desktop/views/components/post-form.vue:
|
|||||||
attach-media-from-drive: "ドライブからメディアを添付"
|
attach-media-from-drive: "ドライブからメディアを添付"
|
||||||
attach-cancel: "添付取り消し"
|
attach-cancel: "添付取り消し"
|
||||||
insert-a-kao: "v(‘ω’)v"
|
insert-a-kao: "v(‘ω’)v"
|
||||||
create-poll: "投票を作成"
|
create-poll: "アンケートを作成"
|
||||||
text-remain: "残り{}文字"
|
text-remain: "残り{}文字"
|
||||||
desktop/views/components/post-form-window.vue:
|
desktop/views/components/post-form-window.vue:
|
||||||
note: "新規投稿"
|
note: "新規投稿"
|
||||||
@ -515,7 +528,7 @@ desktop/views/components/sub-note-content.vue:
|
|||||||
private: "この投稿は非公開です"
|
private: "この投稿は非公開です"
|
||||||
deleted: "この投稿は削除されました"
|
deleted: "この投稿は削除されました"
|
||||||
media-count: "{}つのメディア"
|
media-count: "{}つのメディア"
|
||||||
poll: "投票"
|
poll: "アンケート"
|
||||||
desktop/views/components/taskmanager.vue:
|
desktop/views/components/taskmanager.vue:
|
||||||
title: "タスクマネージャ"
|
title: "タスクマネージャ"
|
||||||
desktop/views/components/timeline.vue:
|
desktop/views/components/timeline.vue:
|
||||||
@ -565,6 +578,13 @@ desktop/views/components/users-list-item.vue:
|
|||||||
desktop/views/components/window.vue:
|
desktop/views/components/window.vue:
|
||||||
popout: "ポップアウト"
|
popout: "ポップアウト"
|
||||||
close: "閉じる"
|
close: "閉じる"
|
||||||
|
desktop/views/pages/deck/deck.tl-column.vue:
|
||||||
|
is-media-only: "メディア投稿のみ"
|
||||||
|
is-media-view: "メディアビュー"
|
||||||
|
desktop/views/pages/deck/deck.note.vue:
|
||||||
|
reposted-by: "{}がRenote"
|
||||||
|
private: "この投稿は非公開です"
|
||||||
|
deleted: "この投稿は削除されました"
|
||||||
desktop/views/pages/welcome.vue:
|
desktop/views/pages/welcome.vue:
|
||||||
about: "詳しく..."
|
about: "詳しく..."
|
||||||
gotit: "わかった"
|
gotit: "わかった"
|
||||||
@ -628,7 +648,7 @@ desktop/views/widgets/notifications.vue:
|
|||||||
title: "通知"
|
title: "通知"
|
||||||
settings: "通知の設定"
|
settings: "通知の設定"
|
||||||
desktop/views/widgets/polls.vue:
|
desktop/views/widgets/polls.vue:
|
||||||
title: "投票"
|
title: "アンケート"
|
||||||
refresh: "他を見る"
|
refresh: "他を見る"
|
||||||
nothing: "ありません!"
|
nothing: "ありません!"
|
||||||
desktop/views/widgets/post-form.vue:
|
desktop/views/widgets/post-form.vue:
|
||||||
@ -727,7 +747,7 @@ mobile/views/components/sub-note-content.vue:
|
|||||||
private: "この投稿は非公開です"
|
private: "この投稿は非公開です"
|
||||||
deleted: "この投稿は削除されました"
|
deleted: "この投稿は削除されました"
|
||||||
media-count: "{}つのメディア"
|
media-count: "{}つのメディア"
|
||||||
poll: "投票"
|
poll: "アンケート"
|
||||||
mobile/views/components/timeline.vue:
|
mobile/views/components/timeline.vue:
|
||||||
empty: "投稿がありません"
|
empty: "投稿がありません"
|
||||||
load-more: "もっと"
|
load-more: "もっと"
|
||||||
|
21
package.json
21
package.json
@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"name": "misskey",
|
"name": "misskey",
|
||||||
"author": "syuilo <i@syuilo.com>",
|
"author": "syuilo <i@syuilo.com>",
|
||||||
"version": "2.29.1",
|
"version": "4.2.0",
|
||||||
"clientVersion": "1.0.6218",
|
"clientVersion": "1.0.6620",
|
||||||
"codename": "nighthike",
|
"codename": "nighthike",
|
||||||
"main": "./built/index.js",
|
"main": "./built/index.js",
|
||||||
"private": true,
|
"private": true,
|
||||||
@ -23,10 +23,10 @@
|
|||||||
"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",
|
"@prezzemolo/zip": "0.0.3",
|
||||||
@ -34,7 +34,6 @@
|
|||||||
"@types/debug": "0.0.30",
|
"@types/debug": "0.0.30",
|
||||||
"@types/deep-equal": "1.0.1",
|
"@types/deep-equal": "1.0.1",
|
||||||
"@types/elasticsearch": "5.0.23",
|
"@types/elasticsearch": "5.0.23",
|
||||||
"@types/eventemitter3": "2.0.2",
|
|
||||||
"@types/gm": "1.18.0",
|
"@types/gm": "1.18.0",
|
||||||
"@types/gulp": "3.8.36",
|
"@types/gulp": "3.8.36",
|
||||||
"@types/gulp-htmlmin": "1.3.32",
|
"@types/gulp-htmlmin": "1.3.32",
|
||||||
@ -63,7 +62,6 @@
|
|||||||
"@types/mkdirp": "0.5.2",
|
"@types/mkdirp": "0.5.2",
|
||||||
"@types/mocha": "5.2.0",
|
"@types/mocha": "5.2.0",
|
||||||
"@types/mongodb": "3.0.18",
|
"@types/mongodb": "3.0.18",
|
||||||
"@types/monk": "6.0.0",
|
|
||||||
"@types/ms": "0.7.30",
|
"@types/ms": "0.7.30",
|
||||||
"@types/node": "10.1.2",
|
"@types/node": "10.1.2",
|
||||||
"@types/nopt": "3.0.29",
|
"@types/nopt": "3.0.29",
|
||||||
@ -152,7 +150,7 @@
|
|||||||
"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.8",
|
"mongodb": "3.0.10",
|
||||||
"monk": "6.0.6",
|
"monk": "6.0.6",
|
||||||
"ms": "2.1.1",
|
"ms": "2.1.1",
|
||||||
"nan": "2.10.0",
|
"nan": "2.10.0",
|
||||||
@ -206,7 +204,6 @@
|
|||||||
"vue-js-modal": "1.3.13",
|
"vue-js-modal": "1.3.13",
|
||||||
"vue-json-tree-view": "2.1.4",
|
"vue-json-tree-view": "2.1.4",
|
||||||
"vue-loader": "15.2.1",
|
"vue-loader": "15.2.1",
|
||||||
"vue-material": "^1.0.0-beta-10.2",
|
|
||||||
"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",
|
||||||
@ -218,6 +215,8 @@
|
|||||||
"webpack-cli": "2.1.4",
|
"webpack-cli": "2.1.4",
|
||||||
"websocket": "1.0.26",
|
"websocket": "1.0.26",
|
||||||
"ws": "5.2.0",
|
"ws": "5.2.0",
|
||||||
"xev": "2.0.0"
|
"xev": "2.0.1",
|
||||||
|
"@types/file-type": "5.2.1",
|
||||||
|
"@types/jsdom": "11.0.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 };
|
||||||
};
|
};
|
||||||
|
@ -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}`;
|
||||||
};
|
};
|
||||||
|
@ -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`);
|
||||||
|
@ -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) {
|
||||||
|
@ -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
|
||||||
|
@ -7,11 +7,6 @@ html
|
|||||||
cursor progress !important
|
cursor progress !important
|
||||||
|
|
||||||
body
|
body
|
||||||
// for md
|
|
||||||
font-size 16px !important
|
|
||||||
line-height initial !important
|
|
||||||
letter-spacing initial !important
|
|
||||||
|
|
||||||
overflow-wrap break-word
|
overflow-wrap break-word
|
||||||
|
|
||||||
#error
|
#error
|
||||||
|
@ -42,7 +42,7 @@ html
|
|||||||
| JavaScriptを有効にしてください
|
| JavaScriptを有効にしてください
|
||||||
br
|
br
|
||||||
| Please turn on your JavaScript
|
| Please turn on your JavaScript
|
||||||
div#ini: p
|
div#ini.
|
||||||
span .
|
<svg viewBox="0 0 50 50">
|
||||||
span .
|
<path fill=#{themeColor} d="M25.251,6.461c-10.318,0-18.683,8.365-18.683,18.683h4.068c0-8.071,6.543-14.615,14.615-14.615V6.461z" />
|
||||||
span .
|
</svg>
|
||||||
|
@ -55,7 +55,7 @@ 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)}さんから`,
|
||||||
|
@ -3,15 +3,15 @@ import StreamManager from './stream-manager';
|
|||||||
import MiOS from '../../../mios';
|
import MiOS from '../../../mios';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Server stream connection
|
* Notes stats stream connection
|
||||||
*/
|
*/
|
||||||
export class ServerStream extends Stream {
|
export class NotesStatsStream extends Stream {
|
||||||
constructor(os: MiOS) {
|
constructor(os: MiOS) {
|
||||||
super(os, 'server');
|
super(os, 'notes-stats');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ServerStreamManager extends StreamManager<ServerStream> {
|
export class NotesStatsStreamManager extends StreamManager<NotesStatsStream> {
|
||||||
private os: MiOS;
|
private os: MiOS;
|
||||||
|
|
||||||
constructor(os: MiOS) {
|
constructor(os: MiOS) {
|
||||||
@ -22,7 +22,7 @@ export class ServerStreamManager extends StreamManager<ServerStream> {
|
|||||||
|
|
||||||
public getConnection() {
|
public getConnection() {
|
||||||
if (this.connection == null) {
|
if (this.connection == null) {
|
||||||
this.connection = new ServerStream(this.os);
|
this.connection = new NotesStatsStream(this.os);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.connection;
|
return this.connection;
|
@ -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
|
||||||
});
|
});
|
@ -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;
|
30
src/client/app/common/scripts/streaming/server-stats.ts
Normal file
30
src/client/app/common/scripts/streaming/server-stats.ts
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import Stream from './stream';
|
||||||
|
import StreamManager from './stream-manager';
|
||||||
|
import MiOS from '../../../mios';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Server stats stream connection
|
||||||
|
*/
|
||||||
|
export class ServerStatsStream extends Stream {
|
||||||
|
constructor(os: MiOS) {
|
||||||
|
super(os, 'server-stats');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ServerStatsStreamManager extends StreamManager<ServerStatsStream> {
|
||||||
|
private os: MiOS;
|
||||||
|
|
||||||
|
constructor(os: MiOS) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.os = os;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getConnection() {
|
||||||
|
if (this.connection == null) {
|
||||||
|
this.connection = new ServerStatsStream(this.os);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.connection;
|
||||||
|
}
|
||||||
|
}
|
@ -13,9 +13,6 @@
|
|||||||
|
|
||||||
.a
|
.a
|
||||||
display block
|
display block
|
||||||
position fixed
|
|
||||||
top 0
|
|
||||||
right 0
|
|
||||||
|
|
||||||
> svg
|
> svg
|
||||||
display block
|
display block
|
||||||
|
@ -2,6 +2,7 @@ import Vue from 'vue';
|
|||||||
|
|
||||||
import analogClock from './analog-clock.vue';
|
import analogClock from './analog-clock.vue';
|
||||||
import menu from './menu.vue';
|
import menu from './menu.vue';
|
||||||
|
import noteHeader from './note-header.vue';
|
||||||
import signin from './signin.vue';
|
import signin from './signin.vue';
|
||||||
import signup from './signup.vue';
|
import signup from './signup.vue';
|
||||||
import forkit from './forkit.vue';
|
import forkit from './forkit.vue';
|
||||||
@ -26,11 +27,20 @@ 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 uiButton from './ui/button.vue';
|
||||||
|
import uiCard from './ui/card.vue';
|
||||||
|
import uiForm from './ui/form.vue';
|
||||||
|
import uiTextarea from './ui/textarea.vue';
|
||||||
|
import uiSwitch from './ui/switch.vue';
|
||||||
|
import uiRadio from './ui/radio.vue';
|
||||||
|
import uiSelect from './ui/select.vue';
|
||||||
|
|
||||||
Vue.component('mk-analog-clock', analogClock);
|
Vue.component('mk-analog-clock', analogClock);
|
||||||
Vue.component('mk-menu', menu);
|
Vue.component('mk-menu', menu);
|
||||||
|
Vue.component('mk-note-header', noteHeader);
|
||||||
Vue.component('mk-signin', signin);
|
Vue.component('mk-signin', signin);
|
||||||
Vue.component('mk-signup', signup);
|
Vue.component('mk-signup', signup);
|
||||||
Vue.component('mk-forkit', forkit);
|
Vue.component('mk-forkit', forkit);
|
||||||
@ -55,5 +65,13 @@ 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-button', uiButton);
|
||||||
|
Vue.component('ui-card', uiCard);
|
||||||
|
Vue.component('ui-form', uiForm);
|
||||||
|
Vue.component('ui-textarea', uiTextarea);
|
||||||
|
Vue.component('ui-switch', uiSwitch);
|
||||||
|
Vue.component('ui-radio', uiRadio);
|
||||||
|
Vue.component('ui-select', uiSelect);
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="mk-menu">
|
<div class="mk-menu">
|
||||||
<div class="backdrop" ref="backdrop" @click="close"></div>
|
<div class="backdrop" ref="backdrop" @click="close"></div>
|
||||||
<div class="popover" :class="{ compact }" ref="popover">
|
<div class="popover" :class="{ hukidasi }" ref="popover">
|
||||||
<template v-for="item in items">
|
<template v-for="item in items">
|
||||||
<div v-if="item == null"></div>
|
<div v-if="item === null"></div>
|
||||||
<button v-else @click="clicked(item.onClick)" v-html="item.content"></button>
|
<button v-if="item" @click="clicked(item.action)" v-html="item.icon ? item.icon + ' ' + item.text : item.text"></button>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -15,7 +15,25 @@ import Vue from 'vue';
|
|||||||
import * as anime from 'animejs';
|
import * as anime from 'animejs';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
props: ['source', 'compact', 'items'],
|
props: {
|
||||||
|
source: {
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
items: {
|
||||||
|
type: Array,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
compact: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
hukidasi: !this.compact
|
||||||
|
};
|
||||||
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
const popover = this.$refs.popover as any;
|
const popover = this.$refs.popover as any;
|
||||||
@ -24,18 +42,34 @@ export default Vue.extend({
|
|||||||
const width = popover.offsetWidth;
|
const width = popover.offsetWidth;
|
||||||
const height = popover.offsetHeight;
|
const height = popover.offsetHeight;
|
||||||
|
|
||||||
|
let left;
|
||||||
|
let top;
|
||||||
|
|
||||||
if (this.compact) {
|
if (this.compact) {
|
||||||
const x = rect.left + window.pageXOffset + (this.source.offsetWidth / 2);
|
const x = rect.left + window.pageXOffset + (this.source.offsetWidth / 2);
|
||||||
const y = rect.top + window.pageYOffset + (this.source.offsetHeight / 2);
|
const y = rect.top + window.pageYOffset + (this.source.offsetHeight / 2);
|
||||||
popover.style.left = (x - (width / 2)) + 'px';
|
left = (x - (width / 2));
|
||||||
popover.style.top = (y - (height / 2)) + 'px';
|
top = (y - (height / 2));
|
||||||
} else {
|
} else {
|
||||||
const x = rect.left + window.pageXOffset + (this.source.offsetWidth / 2);
|
const x = rect.left + window.pageXOffset + (this.source.offsetWidth / 2);
|
||||||
const y = rect.top + window.pageYOffset + this.source.offsetHeight;
|
const y = rect.top + window.pageYOffset + this.source.offsetHeight;
|
||||||
popover.style.left = (x - (width / 2)) + 'px';
|
left = (x - (width / 2));
|
||||||
popover.style.top = y + 'px';
|
top = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (left + width - window.pageXOffset > window.innerWidth) {
|
||||||
|
left = window.innerWidth - width + window.pageXOffset;
|
||||||
|
this.hukidasi = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (top + height - window.pageYOffset > window.innerHeight) {
|
||||||
|
top = window.innerHeight - height + window.pageYOffset;
|
||||||
|
this.hukidasi = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
popover.style.left = left + 'px';
|
||||||
|
popover.style.top = top + 'px';
|
||||||
|
|
||||||
anime({
|
anime({
|
||||||
targets: this.$refs.backdrop,
|
targets: this.$refs.backdrop,
|
||||||
opacity: 1,
|
opacity: 1,
|
||||||
@ -113,14 +147,18 @@ $border-color = rgba(27, 31, 35, 0.15)
|
|||||||
|
|
||||||
$balloon-size = 16px
|
$balloon-size = 16px
|
||||||
|
|
||||||
&:not(.compact)
|
&.hukidasi
|
||||||
margin-top $balloon-size
|
margin-top $balloon-size
|
||||||
transform-origin center -($balloon-size)
|
transform-origin center -($balloon-size)
|
||||||
|
|
||||||
&:before
|
&:before
|
||||||
|
&:after
|
||||||
content ""
|
content ""
|
||||||
display block
|
display block
|
||||||
position absolute
|
position absolute
|
||||||
|
pointer-events none
|
||||||
|
|
||||||
|
&:before
|
||||||
top -($balloon-size * 2)
|
top -($balloon-size * 2)
|
||||||
left s('calc(50% - %s)', $balloon-size)
|
left s('calc(50% - %s)', $balloon-size)
|
||||||
border-top solid $balloon-size transparent
|
border-top solid $balloon-size transparent
|
||||||
@ -129,9 +167,6 @@ $border-color = rgba(27, 31, 35, 0.15)
|
|||||||
border-bottom solid $balloon-size $border-color
|
border-bottom solid $balloon-size $border-color
|
||||||
|
|
||||||
&:after
|
&:after
|
||||||
content ""
|
|
||||||
display block
|
|
||||||
position absolute
|
|
||||||
top -($balloon-size * 2) + 1.5px
|
top -($balloon-size * 2) + 1.5px
|
||||||
left s('calc(50% - %s)', $balloon-size)
|
left s('calc(50% - %s)', $balloon-size)
|
||||||
border-top solid $balloon-size transparent
|
border-top solid $balloon-size transparent
|
||||||
|
117
src/client/app/common/views/components/note-header.vue
Normal file
117
src/client/app/common/views/components/note-header.vue
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
<template>
|
||||||
|
<header class="bvonvjxbwzaiskogyhbwgyxvcgserpmu">
|
||||||
|
<mk-avatar class="avatar" :user="note.user" v-if="$store.state.device.postStyle == 'smart'"/>
|
||||||
|
<router-link class="name" :to="note.user | userPage" v-user-preview="note.user.id">{{ note.user | userName }}</router-link>
|
||||||
|
<span class="is-admin" v-if="note.user.isAdmin">admin</span>
|
||||||
|
<span class="is-bot" v-if="note.user.isBot">bot</span>
|
||||||
|
<span class="is-cat" v-if="note.user.isCat">cat</span>
|
||||||
|
<span class="username"><mk-acct :user="note.user"/></span>
|
||||||
|
<div class="info">
|
||||||
|
<span class="app" v-if="note.app && !mini">via <b>{{ note.app.name }}</b></span>
|
||||||
|
<span class="mobile" v-if="note.viaMobile">%fa:mobile-alt%</span>
|
||||||
|
<router-link class="created-at" :to="note | notePage">
|
||||||
|
<mk-time :time="note.createdAt"/>
|
||||||
|
</router-link>
|
||||||
|
<span class="visibility" v-if="note.visibility != 'public'">
|
||||||
|
<template v-if="note.visibility == 'home'">%fa:home%</template>
|
||||||
|
<template v-if="note.visibility == 'followers'">%fa:unlock%</template>
|
||||||
|
<template v-if="note.visibility == 'specified'">%fa:envelope%</template>
|
||||||
|
<template v-if="note.visibility == 'private'">%fa:lock%</template>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import Vue from 'vue';
|
||||||
|
|
||||||
|
export default Vue.extend({
|
||||||
|
props: {
|
||||||
|
note: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
mini: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="stylus" scoped>
|
||||||
|
@import '~const.styl'
|
||||||
|
|
||||||
|
root(isDark)
|
||||||
|
display flex
|
||||||
|
align-items baseline
|
||||||
|
white-space nowrap
|
||||||
|
|
||||||
|
> .avatar
|
||||||
|
flex-shrink 0
|
||||||
|
margin-right 8px
|
||||||
|
width 20px
|
||||||
|
height 20px
|
||||||
|
border-radius 100%
|
||||||
|
|
||||||
|
> .name
|
||||||
|
display block
|
||||||
|
margin 0 .5em 0 0
|
||||||
|
padding 0
|
||||||
|
overflow hidden
|
||||||
|
color isDark ? #fff : #627079
|
||||||
|
font-size 1em
|
||||||
|
font-weight bold
|
||||||
|
text-decoration none
|
||||||
|
text-overflow ellipsis
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
text-decoration underline
|
||||||
|
|
||||||
|
> .is-admin
|
||||||
|
> .is-bot
|
||||||
|
> .is-cat
|
||||||
|
align-self center
|
||||||
|
margin 0 .5em 0 0
|
||||||
|
padding 1px 6px
|
||||||
|
font-size 80%
|
||||||
|
color isDark ? #758188 : #aaa
|
||||||
|
border solid 1px isDark ? #57616f : #ddd
|
||||||
|
border-radius 3px
|
||||||
|
|
||||||
|
&.is-admin
|
||||||
|
border-color isDark ? #d42c41 : #f56a7b
|
||||||
|
color isDark ? #d42c41 : #f56a7b
|
||||||
|
|
||||||
|
> .username
|
||||||
|
margin 0 .5em 0 0
|
||||||
|
overflow hidden
|
||||||
|
text-overflow ellipsis
|
||||||
|
color isDark ? #606984 : #ccc
|
||||||
|
|
||||||
|
> .info
|
||||||
|
margin-left auto
|
||||||
|
font-size 0.9em
|
||||||
|
|
||||||
|
> *
|
||||||
|
color isDark ? #606984 : #c0c0c0
|
||||||
|
|
||||||
|
> .mobile
|
||||||
|
margin-right 8px
|
||||||
|
|
||||||
|
> .app
|
||||||
|
margin-right 8px
|
||||||
|
padding-right 8px
|
||||||
|
border-right solid 1px isDark ? #1c2023 : #eaeaea
|
||||||
|
|
||||||
|
> .visibility
|
||||||
|
margin-left 8px
|
||||||
|
|
||||||
|
.bvonvjxbwzaiskogyhbwgyxvcgserpmu[data-darkmode]
|
||||||
|
root(true)
|
||||||
|
|
||||||
|
.bvonvjxbwzaiskogyhbwgyxvcgserpmu:not([data-darkmode])
|
||||||
|
root(false)
|
||||||
|
|
||||||
|
</style>
|
@ -40,6 +40,17 @@ export default Vue.component('mk-note-html', {
|
|||||||
ast = this.ast;
|
ast = this.ast;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ast.filter(x => x.type != 'hashtag').length == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (ast[ast.length - 1] && (
|
||||||
|
ast[ast.length - 1].type == 'hashtag' ||
|
||||||
|
(ast[ast.length - 1].type == 'text' && ast[ast.length - 1].content == ' ') ||
|
||||||
|
(ast[ast.length - 1].type == 'text' && ast[ast.length - 1].content == '\n'))) {
|
||||||
|
ast.pop();
|
||||||
|
}
|
||||||
|
|
||||||
// Parse ast to DOM
|
// Parse ast to DOM
|
||||||
const els = flatten(ast.map(token => {
|
const els = flatten(ast.map(token => {
|
||||||
switch (token.type) {
|
switch (token.type) {
|
||||||
@ -92,7 +103,7 @@ export default Vue.component('mk-note-html', {
|
|||||||
case 'hashtag':
|
case 'hashtag':
|
||||||
return createElement('a', {
|
return createElement('a', {
|
||||||
attrs: {
|
attrs: {
|
||||||
href: `${url}/search?q=${token.content}`,
|
href: `${url}/tags/${token.hashtag}`,
|
||||||
target: '_blank'
|
target: '_blank'
|
||||||
}
|
}
|
||||||
}, token.content);
|
}, token.content);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="mk-note-menu" style="position:initial">
|
<div style="position:initial">
|
||||||
<mk-menu ref="menu" :source="source" :compact="compact" :items="items" @closed="$destroy"/>
|
<mk-menu :source="source" :compact="compact" :items="items" @closed="closed"/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -13,23 +13,27 @@ export default Vue.extend({
|
|||||||
items() {
|
items() {
|
||||||
const items = [];
|
const items = [];
|
||||||
items.push({
|
items.push({
|
||||||
content: '%i18n:@favorite%',
|
icon: '%fa:star%',
|
||||||
onClick: this.favorite
|
text: '%i18n:@favorite%',
|
||||||
|
action: this.favorite
|
||||||
});
|
});
|
||||||
if (this.note.userId == this.$store.state.i.id) {
|
if (this.note.userId == this.$store.state.i.id) {
|
||||||
items.push({
|
items.push({
|
||||||
content: '%i18n:@pin%',
|
icon: '%fa:thumbtack%',
|
||||||
onClick: this.pin
|
text: '%i18n:@pin%',
|
||||||
|
action: this.pin
|
||||||
});
|
});
|
||||||
items.push({
|
items.push({
|
||||||
content: '%i18n:@delete%',
|
icon: '%fa:trash-alt R%',
|
||||||
onClick: this.del
|
text: '%i18n:@delete%',
|
||||||
|
action: this.del
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (this.note.uri) {
|
if (this.note.uri) {
|
||||||
items.push({
|
items.push({
|
||||||
content: '%i18n:@remote%',
|
icon: '%fa:external-link-square-alt%',
|
||||||
onClick: () => {
|
text: '%i18n:@remote%',
|
||||||
|
action: () => {
|
||||||
window.open(this.note.uri, '_blank');
|
window.open(this.note.uri, '_blank');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -63,8 +67,10 @@ export default Vue.extend({
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
close() {
|
closed() {
|
||||||
this.$refs.menu.close();
|
this.$nextTick(() => {
|
||||||
|
this.$destroy();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -43,7 +43,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 +52,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
|
||||||
@ -98,7 +98,7 @@ export default Vue.extend({
|
|||||||
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 +115,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 +163,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 +187,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 +213,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
|
@ -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() {
|
@ -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'],
|
@ -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>
|
||||||
@ -11,14 +11,14 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="index" v-else>
|
<div class="index" v-else>
|
||||||
<h1>Misskey %fa:circle%thell%fa:circle R%</h1>
|
<h1>Misskey %fa:circle%thell%fa:circle R%</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
|
||||||
|
|
@ -1,24 +1,33 @@
|
|||||||
<template>
|
<template>
|
||||||
<form class="mk-signin" :class="{ signing }" @submit.prevent="onSubmit">
|
<form class="mk-signin" :class="{ signing }" @submit.prevent="onSubmit">
|
||||||
<label class="user-name">
|
<div class="avatar" :style="{ backgroundImage: user ? `url('${ user.avatarUrl }')` : null }" v-show="withAvatar"></div>
|
||||||
<input v-model="username" type="text" pattern="^[a-zA-Z0-9_]+$" placeholder="%i18n:@username%" autofocus required @change="onUsernameChange"/>%fa:at%
|
<ui-input v-model="username" type="text" pattern="^[a-zA-Z0-9_]+$" spellcheck="false" autofocus required @input="onUsernameChange">
|
||||||
</label>
|
<span>%i18n:@username%</span>
|
||||||
<label class="password">
|
<span slot="prefix">@</span>
|
||||||
<input v-model="password" type="password" placeholder="%i18n:@password%" required/>%fa:lock%
|
<span slot="suffix">@{{ host }}</span>
|
||||||
</label>
|
</ui-input>
|
||||||
<label class="token" v-if="user && user.twoFactorEnabled">
|
<ui-input v-model="password" type="password" required>
|
||||||
<input v-model="token" type="number" placeholder="%i18n:@token%" required/>%fa:lock%
|
<span>%i18n:@password%</span>
|
||||||
</label>
|
<span slot="prefix">%fa:lock%</span>
|
||||||
<button type="submit" :disabled="signing">{{ signing ? '%i18n:@signing-in%' : '%i18n:@signin%' }}</button>
|
</ui-input>
|
||||||
もしくは <a :href="`${apiUrl}/signin/twitter`">Twitterでログイン</a>
|
<ui-input v-if="user && user.twoFactorEnabled" v-model="token" type="number" required/>
|
||||||
|
<ui-button type="submit" :disabled="signing">{{ signing ? '%i18n:@signing-in%' : '%i18n:@signin%' }}</ui-button>
|
||||||
|
<p style="margin: 8px 0;">または<a :href="`${apiUrl}/signin/twitter`">Twitterでログイン</a></p>
|
||||||
</form>
|
</form>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import { apiUrl } from '../../../config';
|
import { apiUrl, host } from '../../../config';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
|
props: {
|
||||||
|
withAvatar: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: true
|
||||||
|
}
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
signing: false,
|
signing: false,
|
||||||
@ -27,6 +36,7 @@ export default Vue.extend({
|
|||||||
password: '',
|
password: '',
|
||||||
token: '',
|
token: '',
|
||||||
apiUrl,
|
apiUrl,
|
||||||
|
host
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@ -35,6 +45,8 @@ export default Vue.extend({
|
|||||||
username: this.username
|
username: this.username
|
||||||
}).then(user => {
|
}).then(user => {
|
||||||
this.user = user;
|
this.user = user;
|
||||||
|
}, () => {
|
||||||
|
this.user = null;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onSubmit() {
|
onSubmit() {
|
||||||
@ -59,84 +71,19 @@ export default Vue.extend({
|
|||||||
@import '~const.styl'
|
@import '~const.styl'
|
||||||
|
|
||||||
.mk-signin
|
.mk-signin
|
||||||
|
color #555
|
||||||
|
|
||||||
&.signing
|
&.signing
|
||||||
&, *
|
&, *
|
||||||
cursor wait !important
|
cursor wait !important
|
||||||
|
|
||||||
label
|
> .avatar
|
||||||
display block
|
margin 16px auto 0 auto
|
||||||
margin 12px 0
|
width 64px
|
||||||
|
height 64px
|
||||||
[data-fa]
|
background #ddd
|
||||||
display block
|
background-position center
|
||||||
pointer-events none
|
background-size cover
|
||||||
position absolute
|
border-radius 100%
|
||||||
bottom 0
|
|
||||||
top 0
|
|
||||||
left 0
|
|
||||||
z-index 1
|
|
||||||
margin auto
|
|
||||||
padding 0 16px
|
|
||||||
height 1em
|
|
||||||
color #898786
|
|
||||||
|
|
||||||
input[type=text]
|
|
||||||
input[type=password]
|
|
||||||
input[type=number]
|
|
||||||
user-select text
|
|
||||||
display inline-block
|
|
||||||
cursor auto
|
|
||||||
padding 0 0 0 38px
|
|
||||||
margin 0
|
|
||||||
width 100%
|
|
||||||
line-height 44px
|
|
||||||
font-size 1em
|
|
||||||
color rgba(#000, 0.7)
|
|
||||||
background #fff
|
|
||||||
outline none
|
|
||||||
border solid 1px #eee
|
|
||||||
border-radius 4px
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
background rgba(255, 255, 255, 0.7)
|
|
||||||
border-color #ddd
|
|
||||||
|
|
||||||
& + i
|
|
||||||
color #797776
|
|
||||||
|
|
||||||
&:focus
|
|
||||||
background #fff
|
|
||||||
border-color #ccc
|
|
||||||
|
|
||||||
& + i
|
|
||||||
color #797776
|
|
||||||
|
|
||||||
[type=submit]
|
|
||||||
cursor pointer
|
|
||||||
padding 16px
|
|
||||||
margin -6px 0 0 0
|
|
||||||
width 100%
|
|
||||||
font-size 1.2em
|
|
||||||
color rgba(#000, 0.5)
|
|
||||||
outline none
|
|
||||||
border none
|
|
||||||
border-radius 0
|
|
||||||
background transparent
|
|
||||||
transition all .5s ease
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
color $theme-color
|
|
||||||
transition all .2s ease
|
|
||||||
|
|
||||||
&:focus
|
|
||||||
color $theme-color
|
|
||||||
transition all .2s ease
|
|
||||||
|
|
||||||
&:active
|
|
||||||
color darken($theme-color, 30%)
|
|
||||||
transition all .2s ease
|
|
||||||
|
|
||||||
&:disabled
|
|
||||||
opacity 0.7
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
@ -1,60 +1,58 @@
|
|||||||
<template>
|
<template>
|
||||||
<form class="mk-signup" @submit.prevent="onSubmit" autocomplete="off">
|
<form class="mk-signup" @submit.prevent="onSubmit" :autocomplete="Math.random()">
|
||||||
<label class="username">
|
<ui-input v-model="username" type="text" pattern="^[a-zA-Z0-9_]{1,20}$" :autocomplete="Math.random()" spellcheck="false" required @input="onChangeUsername">
|
||||||
<p class="caption">%fa:at%%i18n:@username%</p>
|
<span>%i18n:@username%</span>
|
||||||
<input v-model="username" type="text" pattern="^[a-zA-Z0-9_]{1,20}$" placeholder="a~z、A~Z、0~9、-" autocomplete="off" required @input="onChangeUsername"/>
|
<span slot="prefix">@</span>
|
||||||
<p class="profile-page-url-preview" v-if="shouldShowProfileUrl">{{ `${url}/@${username}` }}</p>
|
<span slot="suffix">@{{ host }}</span>
|
||||||
<p class="info" v-if="usernameState == 'wait'" style="color:#999">%fa:spinner .pulse .fw%%i18n:@checking%</p>
|
<p slot="text" v-if="usernameState == 'wait'" style="color:#999">%fa:spinner .pulse .fw% %i18n:@checking%</p>
|
||||||
<p class="info" v-if="usernameState == 'ok'" style="color:#3CB7B5">%fa:check .fw%%i18n:@available%</p>
|
<p slot="text" v-if="usernameState == 'ok'" style="color:#3CB7B5">%fa:check .fw% %i18n:@available%</p>
|
||||||
<p class="info" v-if="usernameState == 'unavailable'" style="color:#FF1161">%fa:exclamation-triangle .fw%%i18n:@unavailable%</p>
|
<p slot="text" v-if="usernameState == 'unavailable'" style="color:#FF1161">%fa:exclamation-triangle .fw% %i18n:@unavailable%</p>
|
||||||
<p class="info" v-if="usernameState == 'error'" style="color:#FF1161">%fa:exclamation-triangle .fw%%i18n:@error%</p>
|
<p slot="text" v-if="usernameState == 'error'" style="color:#FF1161">%fa:exclamation-triangle .fw% %i18n:@error%</p>
|
||||||
<p class="info" v-if="usernameState == 'invalid-format'" style="color:#FF1161">%fa:exclamation-triangle .fw%%i18n:@invalid-format%</p>
|
<p slot="text" v-if="usernameState == 'invalid-format'" style="color:#FF1161">%fa:exclamation-triangle .fw% %i18n:@invalid-format%</p>
|
||||||
<p class="info" v-if="usernameState == 'min-range'" style="color:#FF1161">%fa:exclamation-triangle .fw%%i18n:@too-short%</p>
|
<p slot="text" v-if="usernameState == 'min-range'" style="color:#FF1161">%fa:exclamation-triangle .fw% %i18n:@too-short%</p>
|
||||||
<p class="info" v-if="usernameState == 'max-range'" style="color:#FF1161">%fa:exclamation-triangle .fw%%i18n:@too-long%</p>
|
<p slot="text" v-if="usernameState == 'max-range'" style="color:#FF1161">%fa:exclamation-triangle .fw% %i18n:@too-long%</p>
|
||||||
</label>
|
</ui-input>
|
||||||
<label class="password">
|
<ui-input v-model="password" type="password" :autocomplete="Math.random()" required @input="onChangePassword" :with-password-meter="true">
|
||||||
<p class="caption">%fa:lock%%i18n:@password%</p>
|
<span>%i18n:@password%</span>
|
||||||
<input v-model="password" type="password" placeholder="%i18n:@password-placeholder%" autocomplete="off" required @input="onChangePassword"/>
|
<span slot="prefix">%fa:lock%</span>
|
||||||
<div class="meter" v-show="passwordStrength != ''" :data-strength="passwordStrength">
|
<div slot="text">
|
||||||
<div class="value" ref="passwordMetar"></div>
|
<p slot="text" v-if="passwordStrength == 'low'" style="color:#FF1161">%fa:exclamation-triangle .fw% %i18n:@weak-password%</p>
|
||||||
|
<p slot="text" v-if="passwordStrength == 'medium'" style="color:#3CB7B5">%fa:check .fw% %i18n:@normal-password%</p>
|
||||||
|
<p slot="text" v-if="passwordStrength == 'high'" style="color:#3CB7B5">%fa:check .fw% %i18n:@strong-password%</p>
|
||||||
</div>
|
</div>
|
||||||
<p class="info" v-if="passwordStrength == 'low'" style="color:#FF1161">%fa:exclamation-triangle .fw%%i18n:@weak-password%</p>
|
</ui-input>
|
||||||
<p class="info" v-if="passwordStrength == 'medium'" style="color:#3CB7B5">%fa:check .fw%%i18n:@normal-password%</p>
|
<ui-input v-model="retypedPassword" type="password" :autocomplete="Math.random()" required @input="onChangePasswordRetype">
|
||||||
<p class="info" v-if="passwordStrength == 'high'" style="color:#3CB7B5">%fa:check .fw%%i18n:@strong-password%</p>
|
<span>%i18n:@password% (%i18n:@retype%)</span>
|
||||||
</label>
|
<span slot="prefix">%fa:lock%</span>
|
||||||
<label class="retype-password">
|
<div slot="text">
|
||||||
<p class="caption">%fa:lock%%i18n:@password%(%i18n:@retype%)</p>
|
<p slot="text" v-if="passwordRetypeState == 'match'" style="color:#3CB7B5">%fa:check .fw% %i18n:@password-matched%</p>
|
||||||
<input v-model="retypedPassword" type="password" placeholder="%i18n:@retype-placeholder%" autocomplete="off" required @input="onChangePasswordRetype"/>
|
<p slot="text" v-if="passwordRetypeState == 'not-match'" style="color:#FF1161">%fa:exclamation-triangle .fw% %i18n:@password-not-matched%</p>
|
||||||
<p class="info" v-if="passwordRetypeState == 'match'" style="color:#3CB7B5">%fa:check .fw%%i18n:@password-matched%</p>
|
</div>
|
||||||
<p class="info" v-if="passwordRetypeState == 'not-match'" style="color:#FF1161">%fa:exclamation-triangle .fw%%i18n:@password-not-matched%</p>
|
</ui-input>
|
||||||
</label>
|
<div class="g-recaptcha" :data-sitekey="recaptchaSitekey" style="margin: 16px 0;"></div>
|
||||||
<label class="recaptcha">
|
<label class="agree-tou" style="display: block; margin: 16px 0;">
|
||||||
<p class="caption"><template v-if="recaptchaed">%fa:toggle-on%</template><template v-if="!recaptchaed">%fa:toggle-off%</template>%i18n:@recaptcha%</p>
|
<input name="agree-tou" type="checkbox" required/>
|
||||||
<div class="g-recaptcha" data-callback="onRecaptchaed" data-expired-callback="onRecaptchaExpired" :data-sitekey="recaptchaSitekey"></div>
|
|
||||||
</label>
|
|
||||||
<label class="agree-tou">
|
|
||||||
<input name="agree-tou" type="checkbox" autocomplete="off" required/>
|
|
||||||
<p><a :href="touUrl" target="_blank">利用規約</a>に同意する</p>
|
<p><a :href="touUrl" target="_blank">利用規約</a>に同意する</p>
|
||||||
</label>
|
</label>
|
||||||
<button type="submit">%i18n:@create%</button>
|
<ui-button type="submit">%i18n:@create%</ui-button>
|
||||||
</form>
|
</form>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
const getPasswordStrength = require('syuilo-password-strength');
|
const getPasswordStrength = require('syuilo-password-strength');
|
||||||
import { url, docsUrl, lang, recaptchaSitekey } from '../../../config';
|
import { host, url, docsUrl, lang, recaptchaSitekey } from '../../../config';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
host,
|
||||||
username: '',
|
username: '',
|
||||||
password: '',
|
password: '',
|
||||||
retypedPassword: '',
|
retypedPassword: '',
|
||||||
url,
|
url,
|
||||||
touUrl: `${docsUrl}/${lang}/tou`,
|
touUrl: `${docsUrl}/${lang}/tou`,
|
||||||
recaptchaSitekey,
|
recaptchaSitekey,
|
||||||
recaptchaed: false,
|
|
||||||
usernameState: null,
|
usernameState: null,
|
||||||
passwordStrength: '',
|
passwordStrength: '',
|
||||||
passwordRetypeState: null
|
passwordRetypeState: null
|
||||||
@ -104,7 +102,6 @@ export default Vue.extend({
|
|||||||
|
|
||||||
const strength = getPasswordStrength(this.password);
|
const strength = getPasswordStrength(this.password);
|
||||||
this.passwordStrength = strength > 0.7 ? 'high' : strength > 0.3 ? 'medium' : 'low';
|
this.passwordStrength = strength > 0.7 ? 'high' : strength > 0.3 ? 'medium' : 'low';
|
||||||
(this.$refs.passwordMetar as any).style.width = `${strength * 100}%`;
|
|
||||||
},
|
},
|
||||||
onChangePasswordRetype() {
|
onChangePasswordRetype() {
|
||||||
if (this.retypedPassword == '') {
|
if (this.retypedPassword == '') {
|
||||||
@ -130,19 +127,9 @@ export default Vue.extend({
|
|||||||
alert('%i18n:@some-error%');
|
alert('%i18n:@some-error%');
|
||||||
|
|
||||||
(window as any).grecaptcha.reset();
|
(window as any).grecaptcha.reset();
|
||||||
this.recaptchaed = false;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
|
||||||
(window as any).onRecaptchaed = () => {
|
|
||||||
this.recaptchaed = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
(window as any).onRecaptchaExpired = () => {
|
|
||||||
this.recaptchaed = false;
|
|
||||||
};
|
|
||||||
},
|
|
||||||
mounted() {
|
mounted() {
|
||||||
const head = document.getElementsByTagName('head')[0];
|
const head = document.getElementsByTagName('head')[0];
|
||||||
const script = document.createElement('script');
|
const script = document.createElement('script');
|
||||||
@ -158,100 +145,6 @@ export default Vue.extend({
|
|||||||
.mk-signup
|
.mk-signup
|
||||||
min-width 302px
|
min-width 302px
|
||||||
|
|
||||||
label
|
|
||||||
display block
|
|
||||||
margin 0 0 16px 0
|
|
||||||
|
|
||||||
> .caption
|
|
||||||
margin 0 0 4px 0
|
|
||||||
color #828888
|
|
||||||
font-size 0.95em
|
|
||||||
|
|
||||||
> [data-fa]
|
|
||||||
margin-right 0.25em
|
|
||||||
color #96adac
|
|
||||||
|
|
||||||
> .info
|
|
||||||
display block
|
|
||||||
margin 4px 0
|
|
||||||
font-size 0.8em
|
|
||||||
|
|
||||||
> [data-fa]
|
|
||||||
margin-right 0.3em
|
|
||||||
|
|
||||||
&.username
|
|
||||||
.profile-page-url-preview
|
|
||||||
display block
|
|
||||||
margin 4px 8px 0 4px
|
|
||||||
font-size 0.8em
|
|
||||||
color #888
|
|
||||||
|
|
||||||
&:empty
|
|
||||||
display none
|
|
||||||
|
|
||||||
&:not(:empty) + .info
|
|
||||||
margin-top 0
|
|
||||||
|
|
||||||
&.password
|
|
||||||
.meter
|
|
||||||
display block
|
|
||||||
margin-top 8px
|
|
||||||
width 100%
|
|
||||||
height 8px
|
|
||||||
|
|
||||||
&[data-strength='']
|
|
||||||
display none
|
|
||||||
|
|
||||||
&[data-strength='low']
|
|
||||||
> .value
|
|
||||||
background #d73612
|
|
||||||
|
|
||||||
&[data-strength='medium']
|
|
||||||
> .value
|
|
||||||
background #d7ca12
|
|
||||||
|
|
||||||
&[data-strength='high']
|
|
||||||
> .value
|
|
||||||
background #61bb22
|
|
||||||
|
|
||||||
> .value
|
|
||||||
display block
|
|
||||||
width 0%
|
|
||||||
height 100%
|
|
||||||
background transparent
|
|
||||||
border-radius 4px
|
|
||||||
transition all 0.1s ease
|
|
||||||
|
|
||||||
[type=text], [type=password]
|
|
||||||
user-select text
|
|
||||||
display inline-block
|
|
||||||
cursor auto
|
|
||||||
padding 0 12px
|
|
||||||
margin 0
|
|
||||||
width 100%
|
|
||||||
line-height 44px
|
|
||||||
font-size 1em
|
|
||||||
color #333 !important
|
|
||||||
background #fff !important
|
|
||||||
outline none
|
|
||||||
border solid 1px rgba(#000, 0.1)
|
|
||||||
border-radius 4px
|
|
||||||
box-shadow 0 0 0 114514px #fff inset
|
|
||||||
transition all .3s ease
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
border-color rgba(#000, 0.2)
|
|
||||||
transition all .1s ease
|
|
||||||
|
|
||||||
&:focus
|
|
||||||
color $theme-color !important
|
|
||||||
border-color $theme-color
|
|
||||||
box-shadow 0 0 0 1024px #fff inset, 0 0 0 4px rgba($theme-color, 10%)
|
|
||||||
transition all 0s ease
|
|
||||||
|
|
||||||
&:disabled
|
|
||||||
opacity 0.5
|
|
||||||
|
|
||||||
.agree-tou
|
.agree-tou
|
||||||
padding 4px
|
padding 4px
|
||||||
border-radius 4px
|
border-radius 4px
|
||||||
@ -269,19 +162,4 @@ export default Vue.extend({
|
|||||||
display inline
|
display inline
|
||||||
color #555
|
color #555
|
||||||
|
|
||||||
button
|
|
||||||
margin 0
|
|
||||||
padding 16px
|
|
||||||
width 100%
|
|
||||||
font-size 1em
|
|
||||||
color #fff
|
|
||||||
background $theme-color
|
|
||||||
border-radius 3px
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
background lighten($theme-color, 5%)
|
|
||||||
|
|
||||||
&:active
|
|
||||||
background darken($theme-color, 5%)
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
@ -58,18 +58,21 @@ export default Vue.extend({
|
|||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
if (this.mode == 'relative' || this.mode == 'detail') {
|
if (this.mode == 'relative' || this.mode == 'detail') {
|
||||||
this.tick();
|
this.tickId = window.requestAnimationFrame(this.tick);
|
||||||
this.tickId = setInterval(this.tick, 5000);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
destroyed() {
|
destroyed() {
|
||||||
if (this.mode === 'relative' || this.mode === 'detail') {
|
if (this.mode === 'relative' || this.mode === 'detail') {
|
||||||
clearInterval(this.tickId);
|
window.clearTimeout(this.tickId);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
tick() {
|
tick() {
|
||||||
this.now = new Date();
|
this.now = new Date();
|
||||||
|
|
||||||
|
this.tickId = setTimeout(() => {
|
||||||
|
window.requestAnimationFrame(this.tick);
|
||||||
|
}, 10000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
82
src/client/app/common/views/components/ui/button.vue
Normal file
82
src/client/app/common/views/components/ui/button.vue
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
<template>
|
||||||
|
<div class="ui-button" :class="[styl]">
|
||||||
|
<button :type="type" @click="$emit('click')">
|
||||||
|
<slot></slot>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import Vue from 'vue';
|
||||||
|
export default Vue.extend({
|
||||||
|
props: {
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
required: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
styl: 'fill'
|
||||||
|
};
|
||||||
|
},
|
||||||
|
inject: {
|
||||||
|
isCardChild: { default: false }
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
if (this.isCardChild) {
|
||||||
|
this.styl = 'line';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="stylus" scoped>
|
||||||
|
@import '~const.styl'
|
||||||
|
|
||||||
|
root(isDark, fill)
|
||||||
|
> button
|
||||||
|
display block
|
||||||
|
width 100%
|
||||||
|
margin 0
|
||||||
|
padding 0
|
||||||
|
font-weight bold
|
||||||
|
font-size 16px
|
||||||
|
line-height 44px
|
||||||
|
border none
|
||||||
|
border-radius 6px
|
||||||
|
outline none
|
||||||
|
box-shadow none
|
||||||
|
|
||||||
|
if fill
|
||||||
|
color $theme-color-foreground
|
||||||
|
background $theme-color
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
background lighten($theme-color, 5%)
|
||||||
|
|
||||||
|
&:active
|
||||||
|
background darken($theme-color, 5%)
|
||||||
|
else
|
||||||
|
color $theme-color
|
||||||
|
background none
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
color darken($theme-color, 5%)
|
||||||
|
|
||||||
|
&:active
|
||||||
|
background rgba($theme-color, 0.3)
|
||||||
|
|
||||||
|
.ui-button[data-darkmode]
|
||||||
|
&.fill
|
||||||
|
root(true, true)
|
||||||
|
&:not(.fill)
|
||||||
|
root(true, false)
|
||||||
|
|
||||||
|
.ui-button:not([data-darkmode])
|
||||||
|
&.fill
|
||||||
|
root(false, true)
|
||||||
|
&:not(.fill)
|
||||||
|
root(false, false)
|
||||||
|
|
||||||
|
</style>
|
46
src/client/app/common/views/components/ui/card.vue
Normal file
46
src/client/app/common/views/components/ui/card.vue
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
<template>
|
||||||
|
<div class="ui-card">
|
||||||
|
<header>
|
||||||
|
<slot name="title"></slot>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import Vue from 'vue';
|
||||||
|
export default Vue.extend({
|
||||||
|
provide() {
|
||||||
|
return {
|
||||||
|
isCardChild: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="stylus" scoped>
|
||||||
|
@import '~const.styl'
|
||||||
|
|
||||||
|
root(isDark)
|
||||||
|
margin 16px
|
||||||
|
padding 16px
|
||||||
|
color isDark ? #fff : #000
|
||||||
|
background isDark ? #282C37 : #fff
|
||||||
|
box-shadow 0 3px 1px -2px rgba(#000, 0.2), 0 2px 2px 0 rgba(#000, 0.14), 0 1px 5px 0 rgba(#000, 0.12)
|
||||||
|
|
||||||
|
@media (min-width 500px)
|
||||||
|
padding 32px
|
||||||
|
|
||||||
|
> header
|
||||||
|
font-weight normal
|
||||||
|
font-size 24px
|
||||||
|
color isDark ? #fff : #444
|
||||||
|
|
||||||
|
.ui-card[data-darkmode]
|
||||||
|
root(true)
|
||||||
|
|
||||||
|
.ui-card:not([data-darkmode])
|
||||||
|
root(false)
|
||||||
|
|
||||||
|
</style>
|
30
src/client/app/common/views/components/ui/form.vue
Normal file
30
src/client/app/common/views/components/ui/form.vue
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<template>
|
||||||
|
<div class="ui-form">
|
||||||
|
<fieldset :disabled="disabled">
|
||||||
|
<slot></slot>
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import Vue from 'vue';
|
||||||
|
export default Vue.extend({
|
||||||
|
props: {
|
||||||
|
disabled: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="stylus" scoped>
|
||||||
|
@import '~const.styl'
|
||||||
|
|
||||||
|
.ui-form
|
||||||
|
> fieldset
|
||||||
|
margin 0
|
||||||
|
padding 0
|
||||||
|
border none
|
||||||
|
|
||||||
|
</style>
|
350
src/client/app/common/views/components/ui/input.vue
Normal file
350
src/client/app/common/views/components/ui/input.vue
Normal file
@ -0,0 +1,350 @@
|
|||||||
|
<template>
|
||||||
|
<div class="ui-input" :class="[{ focused, filled }, styl]">
|
||||||
|
<div class="icon" ref="icon"><slot name="icon"></slot></div>
|
||||||
|
<div class="input">
|
||||||
|
<div class="password-meter" v-if="withPasswordMeter" v-show="passwordStrength != ''" :data-strength="passwordStrength">
|
||||||
|
<div class="value" ref="passwordMetar"></div>
|
||||||
|
</div>
|
||||||
|
<span class="label" ref="label"><slot></slot></span>
|
||||||
|
<div class="prefix" ref="prefix"><slot name="prefix"></slot></div>
|
||||||
|
<template v-if="type != 'file'">
|
||||||
|
<input ref="input"
|
||||||
|
:type="type"
|
||||||
|
v-model="v"
|
||||||
|
:required="required"
|
||||||
|
:readonly="readonly"
|
||||||
|
:pattern="pattern"
|
||||||
|
:autocomplete="autocomplete"
|
||||||
|
:spellcheck="spellcheck"
|
||||||
|
@focus="focused = true"
|
||||||
|
@blur="focused = false">
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<input ref="input"
|
||||||
|
type="text"
|
||||||
|
:value="placeholder"
|
||||||
|
readonly
|
||||||
|
@click="chooseFile">
|
||||||
|
<input ref="file"
|
||||||
|
type="file"
|
||||||
|
:value="value"
|
||||||
|
@change="onChangeFile">
|
||||||
|
</template>
|
||||||
|
<div class="suffix" ref="suffix"><slot name="suffix"></slot></div>
|
||||||
|
</div>
|
||||||
|
<div class="text"><slot name="text"></slot></div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import Vue from 'vue';
|
||||||
|
const getPasswordStrength = require('syuilo-password-strength');
|
||||||
|
|
||||||
|
export default Vue.extend({
|
||||||
|
props: {
|
||||||
|
value: {
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
required: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
readonly: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
pattern: {
|
||||||
|
type: String,
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
autocomplete: {
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
spellcheck: {
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
withPasswordMeter: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
v: this.value,
|
||||||
|
focused: false,
|
||||||
|
passwordStrength: '',
|
||||||
|
styl: 'fill'
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
filled(): boolean {
|
||||||
|
return this.v != '' && this.v != null;
|
||||||
|
},
|
||||||
|
placeholder(): string {
|
||||||
|
if (this.type != 'file') return null;
|
||||||
|
if (this.v == null) return null;
|
||||||
|
|
||||||
|
if (typeof this.v == 'string') return this.v;
|
||||||
|
|
||||||
|
if (Array.isArray(this.v)) {
|
||||||
|
return this.v.map(file => file.name).join(', ');
|
||||||
|
} else {
|
||||||
|
return this.v.name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
value(v) {
|
||||||
|
this.v = v;
|
||||||
|
},
|
||||||
|
v(v) {
|
||||||
|
this.$emit('input', v);
|
||||||
|
|
||||||
|
if (this.withPasswordMeter) {
|
||||||
|
if (v == '') {
|
||||||
|
this.passwordStrength = '';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const strength = getPasswordStrength(v);
|
||||||
|
this.passwordStrength = strength > 0.7 ? 'high' : strength > 0.3 ? 'medium' : 'low';
|
||||||
|
(this.$refs.passwordMetar as any).style.width = `${strength * 100}%`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
inject: {
|
||||||
|
isCardChild: { default: false }
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
if (this.isCardChild) {
|
||||||
|
this.styl = 'line';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
if (this.$refs.prefix) {
|
||||||
|
this.$refs.label.style.left = (this.$refs.prefix.offsetLeft + this.$refs.prefix.offsetWidth) + 'px';
|
||||||
|
if (this.$refs.prefix.offsetWidth) {
|
||||||
|
this.$refs.input.style.paddingLeft = this.$refs.prefix.offsetWidth + 'px';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.$refs.suffix) {
|
||||||
|
if (this.$refs.suffix.offsetWidth) {
|
||||||
|
this.$refs.input.style.paddingRight = this.$refs.suffix.offsetWidth + 'px';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
focus() {
|
||||||
|
this.$refs.input.focus();
|
||||||
|
},
|
||||||
|
chooseFile() {
|
||||||
|
this.$refs.file.click();
|
||||||
|
},
|
||||||
|
onChangeFile() {
|
||||||
|
this.v = Array.from((this.$refs.file as any).files);
|
||||||
|
this.$emit('input', this.v);
|
||||||
|
this.$emit('change', this.v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="stylus" scoped>
|
||||||
|
@import '~const.styl'
|
||||||
|
|
||||||
|
root(isDark, fill)
|
||||||
|
margin 32px 0
|
||||||
|
|
||||||
|
> .icon
|
||||||
|
position absolute
|
||||||
|
top 0
|
||||||
|
left 0
|
||||||
|
width 24px
|
||||||
|
text-align center
|
||||||
|
line-height 32px
|
||||||
|
color isDark ? rgba(#fff, 0.7) : rgba(#000, 0.54)
|
||||||
|
|
||||||
|
&:not(:empty) + .input
|
||||||
|
margin-left 28px
|
||||||
|
|
||||||
|
> .input
|
||||||
|
|
||||||
|
if !fill
|
||||||
|
&:before
|
||||||
|
content ''
|
||||||
|
display block
|
||||||
|
position absolute
|
||||||
|
bottom 0
|
||||||
|
left 0
|
||||||
|
right 0
|
||||||
|
height 1px
|
||||||
|
background isDark ? rgba(#fff, 0.7) : rgba(#000, 0.42)
|
||||||
|
|
||||||
|
&:after
|
||||||
|
content ''
|
||||||
|
display block
|
||||||
|
position absolute
|
||||||
|
bottom 0
|
||||||
|
left 0
|
||||||
|
right 0
|
||||||
|
height 2px
|
||||||
|
background $theme-color
|
||||||
|
opacity 0
|
||||||
|
transform scaleX(0.12)
|
||||||
|
transition border 0.3s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.3s cubic-bezier(0.4, 0, 0.2, 1), transform 0.3s cubic-bezier(0.4, 0, 0.2, 1)
|
||||||
|
will-change border opacity transform
|
||||||
|
|
||||||
|
> .password-meter
|
||||||
|
position absolute
|
||||||
|
top 0
|
||||||
|
left 0
|
||||||
|
width 100%
|
||||||
|
height 100%
|
||||||
|
border-radius 6px
|
||||||
|
overflow hidden
|
||||||
|
opacity 0.3
|
||||||
|
|
||||||
|
&[data-strength='']
|
||||||
|
display none
|
||||||
|
|
||||||
|
&[data-strength='low']
|
||||||
|
> .value
|
||||||
|
background #d73612
|
||||||
|
|
||||||
|
&[data-strength='medium']
|
||||||
|
> .value
|
||||||
|
background #d7ca12
|
||||||
|
|
||||||
|
&[data-strength='high']
|
||||||
|
> .value
|
||||||
|
background #61bb22
|
||||||
|
|
||||||
|
> .value
|
||||||
|
display block
|
||||||
|
width 0%
|
||||||
|
height 100%
|
||||||
|
background transparent
|
||||||
|
border-radius 6px
|
||||||
|
transition all 0.1s ease
|
||||||
|
|
||||||
|
> .label
|
||||||
|
position absolute
|
||||||
|
z-index 1
|
||||||
|
top fill ? 6px : 0
|
||||||
|
left 0
|
||||||
|
pointer-events none
|
||||||
|
transition 0.4s cubic-bezier(0.25, 0.8, 0.25, 1)
|
||||||
|
transition-duration 0.3s
|
||||||
|
font-size 16px
|
||||||
|
line-height 32px
|
||||||
|
color isDark ? rgba(#fff, 0.7) : rgba(#000, 0.54)
|
||||||
|
pointer-events none
|
||||||
|
//will-change transform
|
||||||
|
transform-origin top left
|
||||||
|
transform scale(1)
|
||||||
|
|
||||||
|
> input
|
||||||
|
display block
|
||||||
|
width 100%
|
||||||
|
margin 0
|
||||||
|
padding 0
|
||||||
|
font inherit
|
||||||
|
font-weight fill ? bold : normal
|
||||||
|
font-size 16px
|
||||||
|
line-height 32px
|
||||||
|
color isDark ? #fff : #000
|
||||||
|
background transparent
|
||||||
|
border none
|
||||||
|
border-radius 0
|
||||||
|
outline none
|
||||||
|
box-shadow none
|
||||||
|
|
||||||
|
if fill
|
||||||
|
padding 6px 12px
|
||||||
|
background rgba(#000, 0.035)
|
||||||
|
border-radius 6px
|
||||||
|
|
||||||
|
&[type='file']
|
||||||
|
display none
|
||||||
|
|
||||||
|
> .prefix
|
||||||
|
> .suffix
|
||||||
|
display block
|
||||||
|
position absolute
|
||||||
|
z-index 1
|
||||||
|
top 0
|
||||||
|
font-size 16px
|
||||||
|
line-height fill ? 44px : 32px
|
||||||
|
color isDark ? rgba(#fff, 0.7) : rgba(#000, 0.54)
|
||||||
|
pointer-events none
|
||||||
|
|
||||||
|
&:empty
|
||||||
|
display none
|
||||||
|
|
||||||
|
> *
|
||||||
|
display block
|
||||||
|
min-width 16px
|
||||||
|
max-width 150px
|
||||||
|
overflow hidden
|
||||||
|
white-space nowrap
|
||||||
|
text-overflow ellipsis
|
||||||
|
|
||||||
|
> .prefix
|
||||||
|
left 0
|
||||||
|
padding-right 4px
|
||||||
|
|
||||||
|
if fill
|
||||||
|
padding-left 12px
|
||||||
|
|
||||||
|
> .suffix
|
||||||
|
right 0
|
||||||
|
padding-left 4px
|
||||||
|
|
||||||
|
if fill
|
||||||
|
padding-right 12px
|
||||||
|
|
||||||
|
> .text
|
||||||
|
margin 6px 0
|
||||||
|
font-size 13px
|
||||||
|
|
||||||
|
*
|
||||||
|
margin 0
|
||||||
|
|
||||||
|
&.focused
|
||||||
|
> .input
|
||||||
|
if fill
|
||||||
|
background rgba(#000, 0.05)
|
||||||
|
else
|
||||||
|
&:after
|
||||||
|
opacity 1
|
||||||
|
transform scaleX(1)
|
||||||
|
|
||||||
|
> .label
|
||||||
|
color $theme-color
|
||||||
|
|
||||||
|
&.focused
|
||||||
|
&.filled
|
||||||
|
> .input
|
||||||
|
> .label
|
||||||
|
top fill ? -24px : -17px
|
||||||
|
left 0 !important
|
||||||
|
transform scale(0.75)
|
||||||
|
|
||||||
|
.ui-input[data-darkmode]
|
||||||
|
&.fill
|
||||||
|
root(true, true)
|
||||||
|
&:not(.fill)
|
||||||
|
root(true, false)
|
||||||
|
|
||||||
|
.ui-input:not([data-darkmode])
|
||||||
|
&.fill
|
||||||
|
root(false, true)
|
||||||
|
&:not(.fill)
|
||||||
|
root(false, false)
|
||||||
|
|
||||||
|
</style>
|
120
src/client/app/common/views/components/ui/radio.vue
Normal file
120
src/client/app/common/views/components/ui/radio.vue
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="ui-radio"
|
||||||
|
:class="{ disabled, checked }"
|
||||||
|
:aria-checked="checked"
|
||||||
|
:aria-disabled="disabled"
|
||||||
|
@click="toggle"
|
||||||
|
>
|
||||||
|
<input type="radio"
|
||||||
|
:disabled="disabled"
|
||||||
|
>
|
||||||
|
<span class="button">
|
||||||
|
<span></span>
|
||||||
|
</span>
|
||||||
|
<span class="label"><slot></slot></span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import Vue from 'vue';
|
||||||
|
export default Vue.extend({
|
||||||
|
model: {
|
||||||
|
prop: 'model',
|
||||||
|
event: 'change'
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
model: {
|
||||||
|
type: String,
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
type: String,
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
disabled: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
checked(): boolean {
|
||||||
|
return this.model === this.value;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
toggle() {
|
||||||
|
this.$emit('change', this.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="stylus" scoped>
|
||||||
|
@import '~const.styl'
|
||||||
|
|
||||||
|
root(isDark)
|
||||||
|
display inline-block
|
||||||
|
margin 32px 32px 32px 0
|
||||||
|
cursor pointer
|
||||||
|
transition all 0.3s
|
||||||
|
|
||||||
|
> *
|
||||||
|
user-select none
|
||||||
|
|
||||||
|
&.disabled
|
||||||
|
opacity 0.6
|
||||||
|
cursor not-allowed
|
||||||
|
|
||||||
|
&.checked
|
||||||
|
> .button
|
||||||
|
border-color $theme-color
|
||||||
|
|
||||||
|
&:after
|
||||||
|
background-color $theme-color
|
||||||
|
transform scale(1)
|
||||||
|
opacity 1
|
||||||
|
|
||||||
|
> input
|
||||||
|
position absolute
|
||||||
|
width 0
|
||||||
|
height 0
|
||||||
|
opacity 0
|
||||||
|
margin 0
|
||||||
|
|
||||||
|
> .button
|
||||||
|
position absolute
|
||||||
|
width 20px
|
||||||
|
height 20px
|
||||||
|
background none
|
||||||
|
border solid 2px isDark ? rgba(#fff, 0.7) : rgba(#000, 0.54)
|
||||||
|
border-radius 100%
|
||||||
|
transition inherit
|
||||||
|
|
||||||
|
&:after
|
||||||
|
content ''
|
||||||
|
display block
|
||||||
|
position absolute
|
||||||
|
top 3px
|
||||||
|
right 3px
|
||||||
|
bottom 3px
|
||||||
|
left 3px
|
||||||
|
border-radius 100%
|
||||||
|
opacity 0
|
||||||
|
transform scale(0)
|
||||||
|
transition 0.4s cubic-bezier(0.25, 0.8, 0.25, 1)
|
||||||
|
|
||||||
|
> .label
|
||||||
|
margin-left 28px
|
||||||
|
display block
|
||||||
|
font-size 16px
|
||||||
|
line-height 20px
|
||||||
|
cursor pointer
|
||||||
|
|
||||||
|
.ui-radio[data-darkmode]
|
||||||
|
root(true)
|
||||||
|
|
||||||
|
.ui-radio:not([data-darkmode])
|
||||||
|
root(false)
|
||||||
|
|
||||||
|
</style>
|
215
src/client/app/common/views/components/ui/select.vue
Normal file
215
src/client/app/common/views/components/ui/select.vue
Normal file
@ -0,0 +1,215 @@
|
|||||||
|
<template>
|
||||||
|
<div class="ui-select" :class="[{ focused, filled }, styl]">
|
||||||
|
<div class="icon" ref="icon"><slot name="icon"></slot></div>
|
||||||
|
<div class="input" @click="focus">
|
||||||
|
<span class="label" ref="label"><slot name="label"></slot></span>
|
||||||
|
<div class="prefix" ref="prefix"><slot name="prefix"></slot></div>
|
||||||
|
<select ref="input"
|
||||||
|
:value="v"
|
||||||
|
:required="required"
|
||||||
|
@input="$emit('input', $event.target.value)"
|
||||||
|
@focus="focused = true"
|
||||||
|
@blur="focused = false">
|
||||||
|
<slot></slot>
|
||||||
|
</select>
|
||||||
|
<div class="suffix"><slot name="suffix"></slot></div>
|
||||||
|
</div>
|
||||||
|
<div class="text"><slot name="text"></slot></div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import Vue from 'vue';
|
||||||
|
|
||||||
|
export default Vue.extend({
|
||||||
|
props: {
|
||||||
|
value: {
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
required: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
v: this.value,
|
||||||
|
focused: false,
|
||||||
|
styl: 'fill'
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
filled(): boolean {
|
||||||
|
return this.v != '' && this.v != null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
value(v) {
|
||||||
|
this.v = v;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
inject: {
|
||||||
|
isCardChild: { default: false }
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
if (this.isCardChild) {
|
||||||
|
this.styl = 'line';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
if (this.$refs.prefix) {
|
||||||
|
this.$refs.label.style.left = (this.$refs.prefix.offsetLeft + this.$refs.prefix.offsetWidth) + 'px';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
focus() {
|
||||||
|
this.$refs.input.focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="stylus" scoped>
|
||||||
|
@import '~const.styl'
|
||||||
|
|
||||||
|
root(isDark, fill)
|
||||||
|
margin 32px 0
|
||||||
|
|
||||||
|
> .icon
|
||||||
|
position absolute
|
||||||
|
top 0
|
||||||
|
left 0
|
||||||
|
width 24px
|
||||||
|
text-align center
|
||||||
|
line-height 32px
|
||||||
|
color rgba(#000, 0.54)
|
||||||
|
|
||||||
|
&:not(:empty) + .input
|
||||||
|
margin-left 28px
|
||||||
|
|
||||||
|
> .input
|
||||||
|
display flex
|
||||||
|
|
||||||
|
if fill
|
||||||
|
padding 6px 12px
|
||||||
|
background rgba(#000, 0.035)
|
||||||
|
border-radius 6px
|
||||||
|
else
|
||||||
|
&:before
|
||||||
|
content ''
|
||||||
|
display block
|
||||||
|
position absolute
|
||||||
|
bottom 0
|
||||||
|
left 0
|
||||||
|
right 0
|
||||||
|
height 1px
|
||||||
|
background isDark ? rgba(#fff, 0.7) : rgba(#000, 0.42)
|
||||||
|
|
||||||
|
&:after
|
||||||
|
content ''
|
||||||
|
display block
|
||||||
|
position absolute
|
||||||
|
bottom 0
|
||||||
|
left 0
|
||||||
|
right 0
|
||||||
|
height 2px
|
||||||
|
background $theme-color
|
||||||
|
opacity 0
|
||||||
|
transform scaleX(0.12)
|
||||||
|
transition border 0.3s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.3s cubic-bezier(0.4, 0, 0.2, 1), transform 0.3s cubic-bezier(0.4, 0, 0.2, 1)
|
||||||
|
will-change border opacity transform
|
||||||
|
|
||||||
|
> .label
|
||||||
|
position absolute
|
||||||
|
top fill ? 6px : 0
|
||||||
|
left 0
|
||||||
|
pointer-events none
|
||||||
|
transition 0.4s cubic-bezier(0.25, 0.8, 0.25, 1)
|
||||||
|
transition-duration 0.3s
|
||||||
|
font-size 16px
|
||||||
|
line-height 32px
|
||||||
|
color rgba(#000, 0.54)
|
||||||
|
pointer-events none
|
||||||
|
//will-change transform
|
||||||
|
transform-origin top left
|
||||||
|
transform scale(1)
|
||||||
|
|
||||||
|
> select
|
||||||
|
display block
|
||||||
|
flex 1
|
||||||
|
width 100%
|
||||||
|
padding 0
|
||||||
|
font inherit
|
||||||
|
font-weight fill ? bold : normal
|
||||||
|
font-size 16px
|
||||||
|
height 32px
|
||||||
|
color isDark ? #fff : #000
|
||||||
|
background transparent
|
||||||
|
border none
|
||||||
|
border-radius 0
|
||||||
|
outline none
|
||||||
|
box-shadow none
|
||||||
|
|
||||||
|
*
|
||||||
|
color #000
|
||||||
|
|
||||||
|
> .prefix
|
||||||
|
> .suffix
|
||||||
|
display block
|
||||||
|
align-self center
|
||||||
|
justify-self center
|
||||||
|
font-size 16px
|
||||||
|
line-height 32px
|
||||||
|
color rgba(#000, 0.54)
|
||||||
|
pointer-events none
|
||||||
|
|
||||||
|
> *
|
||||||
|
display block
|
||||||
|
min-width 16px
|
||||||
|
|
||||||
|
> .prefix
|
||||||
|
padding-right 4px
|
||||||
|
|
||||||
|
> .suffix
|
||||||
|
padding-left 4px
|
||||||
|
|
||||||
|
> .text
|
||||||
|
margin 6px 0
|
||||||
|
font-size 13px
|
||||||
|
|
||||||
|
*
|
||||||
|
margin 0
|
||||||
|
|
||||||
|
&.focused
|
||||||
|
> .input
|
||||||
|
if fill
|
||||||
|
background rgba(#000, 0.05)
|
||||||
|
else
|
||||||
|
&:after
|
||||||
|
opacity 1
|
||||||
|
transform scaleX(1)
|
||||||
|
|
||||||
|
> .label
|
||||||
|
color $theme-color
|
||||||
|
|
||||||
|
&.focused
|
||||||
|
&.filled
|
||||||
|
> .input
|
||||||
|
> .label
|
||||||
|
top fill ? -24px : -17px
|
||||||
|
left 0 !important
|
||||||
|
transform scale(0.75)
|
||||||
|
|
||||||
|
.ui-select[data-darkmode]
|
||||||
|
&.fill
|
||||||
|
root(true, true)
|
||||||
|
&:not(.fill)
|
||||||
|
root(true, false)
|
||||||
|
|
||||||
|
.ui-select:not([data-darkmode])
|
||||||
|
&.fill
|
||||||
|
root(false, true)
|
||||||
|
&:not(.fill)
|
||||||
|
root(false, false)
|
||||||
|
|
||||||
|
</style>
|
135
src/client/app/common/views/components/ui/switch.vue
Normal file
135
src/client/app/common/views/components/ui/switch.vue
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="ui-switch"
|
||||||
|
:class="{ disabled, checked }"
|
||||||
|
role="switch"
|
||||||
|
:aria-checked="checked"
|
||||||
|
:aria-disabled="disabled"
|
||||||
|
@click="toggle"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
ref="input"
|
||||||
|
:disabled="disabled"
|
||||||
|
@keydown.enter="toggle"
|
||||||
|
>
|
||||||
|
<span class="button">
|
||||||
|
<span></span>
|
||||||
|
</span>
|
||||||
|
<span class="label">
|
||||||
|
<span :aria-hidden="!checked"><slot></slot></span>
|
||||||
|
<p :aria-hidden="!checked">
|
||||||
|
<slot name="text"></slot>
|
||||||
|
</p>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import Vue from 'vue';
|
||||||
|
export default Vue.extend({
|
||||||
|
model: {
|
||||||
|
prop: 'value',
|
||||||
|
event: 'change'
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
value: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
disabled: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
checked(): boolean {
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
toggle() {
|
||||||
|
this.$emit('change', !this.checked);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="stylus" scoped>
|
||||||
|
@import '~const.styl'
|
||||||
|
|
||||||
|
root(isDark)
|
||||||
|
display flex
|
||||||
|
margin 32px 0
|
||||||
|
cursor pointer
|
||||||
|
transition all 0.3s
|
||||||
|
|
||||||
|
> *
|
||||||
|
user-select none
|
||||||
|
|
||||||
|
&.disabled
|
||||||
|
opacity 0.6
|
||||||
|
cursor not-allowed
|
||||||
|
|
||||||
|
&.checked
|
||||||
|
> .button
|
||||||
|
background-color rgba($theme-color, 0.4)
|
||||||
|
border-color rgba($theme-color, 0.4)
|
||||||
|
|
||||||
|
> *
|
||||||
|
background-color $theme-color
|
||||||
|
transform translateX(14px)
|
||||||
|
|
||||||
|
> input
|
||||||
|
position absolute
|
||||||
|
width 0
|
||||||
|
height 0
|
||||||
|
opacity 0
|
||||||
|
margin 0
|
||||||
|
|
||||||
|
> .button
|
||||||
|
display inline-block
|
||||||
|
margin 3px 0 0 0
|
||||||
|
width 34px
|
||||||
|
height 14px
|
||||||
|
background isDark ? rgba(#fff, 0.15) : rgba(#000, 0.25)
|
||||||
|
outline none
|
||||||
|
border-radius 14px
|
||||||
|
transition inherit
|
||||||
|
|
||||||
|
> *
|
||||||
|
position absolute
|
||||||
|
top -3px
|
||||||
|
left 0
|
||||||
|
border-radius 100%
|
||||||
|
transition background-color 0.3s, transform 0.3s
|
||||||
|
width 20px
|
||||||
|
height 20px
|
||||||
|
background-color #fff
|
||||||
|
box-shadow 0 2px 1px -1px rgba(#000, 0.2), 0 1px 1px 0 rgba(#000, 0.14), 0 1px 3px 0 rgba(#000, 0.12)
|
||||||
|
|
||||||
|
> .label
|
||||||
|
margin-left 8px
|
||||||
|
display block
|
||||||
|
font-size 16px
|
||||||
|
cursor pointer
|
||||||
|
transition inherit
|
||||||
|
|
||||||
|
> span
|
||||||
|
display block
|
||||||
|
line-height 20px
|
||||||
|
color isDark ? #c4ccd2 : rgba(#000, 0.75)
|
||||||
|
transition inherit
|
||||||
|
|
||||||
|
> p
|
||||||
|
margin 0
|
||||||
|
//font-size 90%
|
||||||
|
color isDark ? #78858e : #9daab3
|
||||||
|
|
||||||
|
.ui-switch[data-darkmode]
|
||||||
|
root(true)
|
||||||
|
|
||||||
|
.ui-switch:not([data-darkmode])
|
||||||
|
root(false)
|
||||||
|
|
||||||
|
</style>
|
174
src/client/app/common/views/components/ui/textarea.vue
Normal file
174
src/client/app/common/views/components/ui/textarea.vue
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
<template>
|
||||||
|
<div class="ui-textarea" :class="{ focused, filled }">
|
||||||
|
<div class="input">
|
||||||
|
<span class="label" ref="label"><slot></slot></span>
|
||||||
|
<textarea ref="input"
|
||||||
|
:value="value"
|
||||||
|
:required="required"
|
||||||
|
:readonly="readonly"
|
||||||
|
:pattern="pattern"
|
||||||
|
:autocomplete="autocomplete"
|
||||||
|
@input="$emit('input', $event.target.value)"
|
||||||
|
@focus="focused = true"
|
||||||
|
@blur="focused = false">
|
||||||
|
</textarea>
|
||||||
|
</div>
|
||||||
|
<div class="text"><slot name="text"></slot></div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import Vue from 'vue';
|
||||||
|
const getPasswordStrength = require('syuilo-password-strength');
|
||||||
|
|
||||||
|
export default Vue.extend({
|
||||||
|
props: {
|
||||||
|
value: {
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
required: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
readonly: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
pattern: {
|
||||||
|
type: String,
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
autocomplete: {
|
||||||
|
type: String,
|
||||||
|
required: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
focused: false,
|
||||||
|
passwordStrength: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
filled(): boolean {
|
||||||
|
return this.value != '' && this.value != null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
focus() {
|
||||||
|
this.$refs.input.focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="stylus" scoped>
|
||||||
|
@import '~const.styl'
|
||||||
|
|
||||||
|
root(isDark, fill)
|
||||||
|
margin 42px 0 32px 0
|
||||||
|
|
||||||
|
> .input
|
||||||
|
padding 12px
|
||||||
|
|
||||||
|
if fill
|
||||||
|
background rgba(#000, 0.035)
|
||||||
|
border-radius 6px
|
||||||
|
else
|
||||||
|
&:before
|
||||||
|
content ''
|
||||||
|
display block
|
||||||
|
position absolute
|
||||||
|
top 0
|
||||||
|
bottom 0
|
||||||
|
left 0
|
||||||
|
right 0
|
||||||
|
background none
|
||||||
|
border solid 1px isDark ? rgba(#fff, 0.7) : rgba(#000, 0.42)
|
||||||
|
border-radius 3px
|
||||||
|
pointer-events none
|
||||||
|
|
||||||
|
&:after
|
||||||
|
content ''
|
||||||
|
display block
|
||||||
|
position absolute
|
||||||
|
top 0
|
||||||
|
bottom 0
|
||||||
|
left 0
|
||||||
|
right 0
|
||||||
|
background none
|
||||||
|
border solid 2px $theme-color
|
||||||
|
border-radius 3px
|
||||||
|
opacity 0
|
||||||
|
transition opacity 0.3s cubic-bezier(0.4, 0, 0.2, 1)
|
||||||
|
pointer-events none
|
||||||
|
|
||||||
|
> .label
|
||||||
|
position absolute
|
||||||
|
top 6px
|
||||||
|
left 12px
|
||||||
|
pointer-events none
|
||||||
|
transition 0.4s cubic-bezier(0.25, 0.8, 0.25, 1)
|
||||||
|
transition-duration 0.3s
|
||||||
|
font-size 16px
|
||||||
|
line-height 32px
|
||||||
|
color isDark ? rgba(#fff, 0.7) : rgba(#000, 0.54)
|
||||||
|
pointer-events none
|
||||||
|
//will-change transform
|
||||||
|
transform-origin top left
|
||||||
|
transform scale(1)
|
||||||
|
|
||||||
|
> textarea
|
||||||
|
display block
|
||||||
|
width 100%
|
||||||
|
min-height 100px
|
||||||
|
padding 0
|
||||||
|
font inherit
|
||||||
|
font-weight fill ? bold : normal
|
||||||
|
font-size 16px
|
||||||
|
color isDark ? #fff : #000
|
||||||
|
background transparent
|
||||||
|
border none
|
||||||
|
border-radius 0
|
||||||
|
outline none
|
||||||
|
box-shadow none
|
||||||
|
|
||||||
|
> .text
|
||||||
|
margin 6px 0
|
||||||
|
font-size 13px
|
||||||
|
|
||||||
|
*
|
||||||
|
margin 0
|
||||||
|
|
||||||
|
&.focused
|
||||||
|
> .input
|
||||||
|
if fill
|
||||||
|
background rgba(#000, 0.05)
|
||||||
|
else
|
||||||
|
&:after
|
||||||
|
opacity 1
|
||||||
|
|
||||||
|
> .label
|
||||||
|
color $theme-color
|
||||||
|
|
||||||
|
&.focused
|
||||||
|
&.filled
|
||||||
|
> .input
|
||||||
|
> .label
|
||||||
|
top -24px
|
||||||
|
left 0 !important
|
||||||
|
transform scale(0.75)
|
||||||
|
|
||||||
|
.ui-textarea[data-darkmode]
|
||||||
|
&.fill
|
||||||
|
root(true, true)
|
||||||
|
&:not(.fill)
|
||||||
|
root(true, false)
|
||||||
|
|
||||||
|
.ui-textarea:not([data-darkmode])
|
||||||
|
&.fill
|
||||||
|
root(false, true)
|
||||||
|
&:not(.fill)
|
||||||
|
root(false, false)
|
||||||
|
|
||||||
|
</style>
|
@ -203,6 +203,7 @@ root(isDark)
|
|||||||
justify-content center
|
justify-content center
|
||||||
align-items center
|
align-items center
|
||||||
margin-right 10px
|
margin-right 10px
|
||||||
|
width 16px
|
||||||
|
|
||||||
> *:last-child
|
> *:last-child
|
||||||
flex 1 1 auto
|
flex 1 1 auto
|
||||||
|
@ -109,6 +109,9 @@ root(isDark)
|
|||||||
> .created-at
|
> .created-at
|
||||||
color isDark ? #606984 : #c0c0c0
|
color isDark ? #606984 : #c0c0c0
|
||||||
|
|
||||||
|
> .text
|
||||||
|
text-align left
|
||||||
|
|
||||||
.mk-welcome-timeline[data-darkmode]
|
.mk-welcome-timeline[data-darkmode]
|
||||||
root(true)
|
root(true)
|
||||||
|
|
||||||
|
89
src/client/app/common/views/widgets/hashtags.chart.vue
Normal file
89
src/client/app/common/views/widgets/hashtags.chart.vue
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
<template>
|
||||||
|
<svg :viewBox="`0 0 ${ viewBoxX } ${ viewBoxY }`" style="overflow:visible">
|
||||||
|
<defs>
|
||||||
|
<linearGradient :id="gradientId" x1="0" x2="0" y1="1" y2="0">
|
||||||
|
<stop offset="0%" stop-color="hsl(200, 80%, 70%)"></stop>
|
||||||
|
<stop offset="100%" stop-color="hsl(90, 80%, 70%)"></stop>
|
||||||
|
</linearGradient>
|
||||||
|
<mask :id="maskId" x="0" y="0" :width="viewBoxX" :height="viewBoxY">
|
||||||
|
<polygon
|
||||||
|
:points="polygonPoints"
|
||||||
|
fill="#fff"
|
||||||
|
fill-opacity="0.5"/>
|
||||||
|
<polyline
|
||||||
|
:points="polylinePoints"
|
||||||
|
fill="none"
|
||||||
|
stroke="#fff"
|
||||||
|
stroke-width="2"/>
|
||||||
|
<circle
|
||||||
|
:cx="headX"
|
||||||
|
:cy="headY"
|
||||||
|
r="3"
|
||||||
|
fill="#fff"/>
|
||||||
|
</mask>
|
||||||
|
</defs>
|
||||||
|
<rect
|
||||||
|
x="-10" y="-10"
|
||||||
|
:width="viewBoxX + 20" :height="viewBoxY + 20"
|
||||||
|
:style="`stroke: none; fill: url(#${ gradientId }); mask: url(#${ maskId })`"/>
|
||||||
|
</svg>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import Vue from 'vue';
|
||||||
|
import * as uuid from 'uuid';
|
||||||
|
|
||||||
|
export default Vue.extend({
|
||||||
|
props: {
|
||||||
|
src: {
|
||||||
|
type: Array,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
viewBoxX: 50,
|
||||||
|
viewBoxY: 30,
|
||||||
|
gradientId: uuid(),
|
||||||
|
maskId: uuid(),
|
||||||
|
polylinePoints: '',
|
||||||
|
polygonPoints: '',
|
||||||
|
headX: null,
|
||||||
|
headY: null,
|
||||||
|
clock: null
|
||||||
|
};
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
src() {
|
||||||
|
this.draw();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.draw();
|
||||||
|
|
||||||
|
// Vueが何故かWatchを発動させない場合があるので
|
||||||
|
this.clock = setInterval(this.draw, 1000);
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
clearInterval(this.clock);
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
draw() {
|
||||||
|
const stats = this.src.slice().reverse();
|
||||||
|
const peak = Math.max.apply(null, stats) || 1;
|
||||||
|
|
||||||
|
const polylinePoints = stats.map((n, i) => [
|
||||||
|
i * (this.viewBoxX / (stats.length - 1)),
|
||||||
|
(1 - (n / peak)) * this.viewBoxY
|
||||||
|
]);
|
||||||
|
|
||||||
|
this.polylinePoints = polylinePoints.map(xy => `${xy[0]},${xy[1]}`).join(' ');
|
||||||
|
|
||||||
|
this.polygonPoints = `0,${ this.viewBoxY } ${ this.polylinePoints } ${ this.viewBoxX },${ this.viewBoxY }`;
|
||||||
|
|
||||||
|
this.headX = polylinePoints[polylinePoints.length - 1][0];
|
||||||
|
this.headY = polylinePoints[polylinePoints.length - 1][1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
118
src/client/app/common/views/widgets/hashtags.vue
Normal file
118
src/client/app/common/views/widgets/hashtags.vue
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
<template>
|
||||||
|
<div class="mkw-hashtags">
|
||||||
|
<mk-widget-container :show-header="!props.compact">
|
||||||
|
<template slot="header">%fa:hashtag%%i18n:@title%</template>
|
||||||
|
|
||||||
|
<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="empty" v-else-if="stats.length == 0">%fa:exclamation-circle%%i18n:@empty%</p>
|
||||||
|
<transition-group v-else tag="div" name="chart">
|
||||||
|
<div v-for="stat in stats" :key="stat.tag">
|
||||||
|
<div class="tag">
|
||||||
|
<router-link :to="`/tags/${ stat.tag }`" :title="stat.tag">#{{ stat.tag }}</router-link>
|
||||||
|
<p>{{ '%i18n:@count%'.replace('{}', stat.usersCount) }}</p>
|
||||||
|
</div>
|
||||||
|
<x-chart class="chart" :src="stat.chart"/>
|
||||||
|
</div>
|
||||||
|
</transition-group>
|
||||||
|
</div>
|
||||||
|
</mk-widget-container>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import define from '../../../common/define-widget';
|
||||||
|
import XChart from './hashtags.chart.vue';
|
||||||
|
|
||||||
|
export default define({
|
||||||
|
name: 'hashtags',
|
||||||
|
props: () => ({
|
||||||
|
compact: false
|
||||||
|
})
|
||||||
|
}).extend({
|
||||||
|
components: {
|
||||||
|
XChart
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
stats: [],
|
||||||
|
fetching: true,
|
||||||
|
clock: null
|
||||||
|
};
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.fetch();
|
||||||
|
this.clock = setInterval(this.fetch, 1000 * 60);
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
clearInterval(this.clock);
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
func() {
|
||||||
|
this.props.compact = !this.props.compact;
|
||||||
|
this.save();
|
||||||
|
},
|
||||||
|
fetch() {
|
||||||
|
(this as any).api('hashtags/trend').then(stats => {
|
||||||
|
this.stats = stats;
|
||||||
|
this.fetching = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="stylus" scoped>
|
||||||
|
root(isDark)
|
||||||
|
.mkw-hashtags--body
|
||||||
|
> .fetching
|
||||||
|
> .empty
|
||||||
|
margin 0
|
||||||
|
padding 16px
|
||||||
|
text-align center
|
||||||
|
color #aaa
|
||||||
|
|
||||||
|
> [data-fa]
|
||||||
|
margin-right 4px
|
||||||
|
|
||||||
|
> div
|
||||||
|
.chart-move
|
||||||
|
transition transform 1s ease
|
||||||
|
|
||||||
|
> div
|
||||||
|
display flex
|
||||||
|
align-items center
|
||||||
|
padding 14px 16px
|
||||||
|
|
||||||
|
&:not(:last-child)
|
||||||
|
border-bottom solid 1px isDark ? #393f4f : #eee
|
||||||
|
|
||||||
|
> .tag
|
||||||
|
flex 1
|
||||||
|
overflow hidden
|
||||||
|
font-size 14px
|
||||||
|
color isDark ? #9baec8 : #65727b
|
||||||
|
|
||||||
|
> a
|
||||||
|
display block
|
||||||
|
width 100%
|
||||||
|
white-space nowrap
|
||||||
|
overflow hidden
|
||||||
|
text-overflow ellipsis
|
||||||
|
color inherit
|
||||||
|
|
||||||
|
> p
|
||||||
|
margin 0
|
||||||
|
font-size 75%
|
||||||
|
opacity 0.7
|
||||||
|
|
||||||
|
> .chart
|
||||||
|
height 30px
|
||||||
|
|
||||||
|
.mkw-hashtags[data-darkmode]
|
||||||
|
root(true)
|
||||||
|
|
||||||
|
.mkw-hashtags:not([data-darkmode])
|
||||||
|
root(false)
|
||||||
|
|
||||||
|
</style>
|
@ -4,6 +4,7 @@ import wAnalogClock from './analog-clock.vue';
|
|||||||
import wVersion from './version.vue';
|
import wVersion from './version.vue';
|
||||||
import wRss from './rss.vue';
|
import wRss from './rss.vue';
|
||||||
import wServer from './server.vue';
|
import wServer from './server.vue';
|
||||||
|
import wPostsMonitor from './posts-monitor.vue';
|
||||||
import wMemo from './memo.vue';
|
import wMemo from './memo.vue';
|
||||||
import wBroadcast from './broadcast.vue';
|
import wBroadcast from './broadcast.vue';
|
||||||
import wCalendar from './calendar.vue';
|
import wCalendar from './calendar.vue';
|
||||||
@ -12,6 +13,7 @@ import wSlideshow from './slideshow.vue';
|
|||||||
import wTips from './tips.vue';
|
import wTips from './tips.vue';
|
||||||
import wDonation from './donation.vue';
|
import wDonation from './donation.vue';
|
||||||
import wNav from './nav.vue';
|
import wNav from './nav.vue';
|
||||||
|
import wHashtags from './hashtags.vue';
|
||||||
|
|
||||||
Vue.component('mkw-analog-clock', wAnalogClock);
|
Vue.component('mkw-analog-clock', wAnalogClock);
|
||||||
Vue.component('mkw-nav', wNav);
|
Vue.component('mkw-nav', wNav);
|
||||||
@ -22,6 +24,8 @@ Vue.component('mkw-tips', wTips);
|
|||||||
Vue.component('mkw-donation', wDonation);
|
Vue.component('mkw-donation', wDonation);
|
||||||
Vue.component('mkw-broadcast', wBroadcast);
|
Vue.component('mkw-broadcast', wBroadcast);
|
||||||
Vue.component('mkw-server', wServer);
|
Vue.component('mkw-server', wServer);
|
||||||
|
Vue.component('mkw-posts-monitor', wPostsMonitor);
|
||||||
Vue.component('mkw-memo', wMemo);
|
Vue.component('mkw-memo', wMemo);
|
||||||
Vue.component('mkw-rss', wRss);
|
Vue.component('mkw-rss', wRss);
|
||||||
Vue.component('mkw-version', wVersion);
|
Vue.component('mkw-version', wVersion);
|
||||||
|
Vue.component('mkw-hashtags', wHashtags);
|
||||||
|
211
src/client/app/common/views/widgets/posts-monitor.vue
Normal file
211
src/client/app/common/views/widgets/posts-monitor.vue
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
<template>
|
||||||
|
<div class="mkw-posts-monitor">
|
||||||
|
<mk-widget-container :show-header="props.design == 0" :naked="props.design == 2">
|
||||||
|
<template slot="header">%fa:chart-line%%i18n:@title%</template>
|
||||||
|
<button slot="func" @click="toggle" title="%i18n:@toggle%">%fa:sort%</button>
|
||||||
|
|
||||||
|
<div class="qpdmibaztplkylerhdbllwcokyrfxeyj" :class="{ dual: props.view == 0 }" :data-darkmode="$store.state.device.darkmode">
|
||||||
|
<svg :viewBox="`0 0 ${ viewBoxX } ${ viewBoxY }`" v-show="props.view != 2">
|
||||||
|
<defs>
|
||||||
|
<linearGradient :id="localGradientId" x1="0" x2="0" y1="1" y2="0">
|
||||||
|
<stop offset="0%" stop-color="hsl(200, 80%, 70%)"></stop>
|
||||||
|
<stop offset="100%" stop-color="hsl(90, 80%, 70%)"></stop>
|
||||||
|
</linearGradient>
|
||||||
|
<mask :id="localMaskId" x="0" y="0" :width="viewBoxX" :height="viewBoxY">
|
||||||
|
<polygon
|
||||||
|
:points="localPolygonPoints"
|
||||||
|
fill="#fff"
|
||||||
|
fill-opacity="0.5"/>
|
||||||
|
<polyline
|
||||||
|
:points="localPolylinePoints"
|
||||||
|
fill="none"
|
||||||
|
stroke="#fff"
|
||||||
|
stroke-width="1"/>
|
||||||
|
<circle
|
||||||
|
:cx="localHeadX"
|
||||||
|
:cy="localHeadY"
|
||||||
|
r="1.5"
|
||||||
|
fill="#fff"/>
|
||||||
|
</mask>
|
||||||
|
</defs>
|
||||||
|
<rect
|
||||||
|
x="-2" y="-2"
|
||||||
|
:width="viewBoxX + 4" :height="viewBoxY + 4"
|
||||||
|
:style="`stroke: none; fill: url(#${ localGradientId }); mask: url(#${ localMaskId })`"/>
|
||||||
|
<text x="1" y="5">Local</text>
|
||||||
|
</svg>
|
||||||
|
<svg :viewBox="`0 0 ${ viewBoxX } ${ viewBoxY }`" v-show="props.view != 1">
|
||||||
|
<defs>
|
||||||
|
<linearGradient :id="fediGradientId" x1="0" x2="0" y1="1" y2="0">
|
||||||
|
<stop offset="0%" stop-color="hsl(200, 80%, 70%)"></stop>
|
||||||
|
<stop offset="100%" stop-color="hsl(90, 80%, 70%)"></stop>
|
||||||
|
</linearGradient>
|
||||||
|
<mask :id="fediMaskId" x="0" y="0" :width="viewBoxX" :height="viewBoxY">
|
||||||
|
<polygon
|
||||||
|
:points="fediPolygonPoints"
|
||||||
|
fill="#fff"
|
||||||
|
fill-opacity="0.5"/>
|
||||||
|
<polyline
|
||||||
|
:points="fediPolylinePoints"
|
||||||
|
fill="none"
|
||||||
|
stroke="#fff"
|
||||||
|
stroke-width="1"/>
|
||||||
|
<circle
|
||||||
|
:cx="fediHeadX"
|
||||||
|
:cy="fediHeadY"
|
||||||
|
r="1.5"
|
||||||
|
fill="#fff"/>
|
||||||
|
</mask>
|
||||||
|
</defs>
|
||||||
|
<rect
|
||||||
|
x="-2" y="-2"
|
||||||
|
:width="viewBoxX + 4" :height="viewBoxY + 4"
|
||||||
|
:style="`stroke: none; fill: url(#${ fediGradientId }); mask: url(#${ fediMaskId })`"/>
|
||||||
|
<text x="1" y="5">Fedi</text>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</mk-widget-container>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import define from '../../../common/define-widget';
|
||||||
|
import * as uuid from 'uuid';
|
||||||
|
|
||||||
|
export default define({
|
||||||
|
name: 'server',
|
||||||
|
props: () => ({
|
||||||
|
design: 0,
|
||||||
|
view: 0
|
||||||
|
})
|
||||||
|
}).extend({
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
connection: null,
|
||||||
|
connectionId: null,
|
||||||
|
viewBoxY: 30,
|
||||||
|
stats: [],
|
||||||
|
fediGradientId: uuid(),
|
||||||
|
fediMaskId: uuid(),
|
||||||
|
localGradientId: uuid(),
|
||||||
|
localMaskId: uuid(),
|
||||||
|
fediPolylinePoints: '',
|
||||||
|
localPolylinePoints: '',
|
||||||
|
fediPolygonPoints: '',
|
||||||
|
localPolygonPoints: '',
|
||||||
|
fediHeadX: null,
|
||||||
|
fediHeadY: null,
|
||||||
|
localHeadX: null,
|
||||||
|
localHeadY: null
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
viewBoxX(): number {
|
||||||
|
return this.props.view == 0 ? 50 : 100;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
viewBoxX() {
|
||||||
|
this.draw();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.connection = (this as any).os.streams.notesStatsStream.getConnection();
|
||||||
|
this.connectionId = (this as any).os.streams.notesStatsStream.use();
|
||||||
|
|
||||||
|
this.connection.on('stats', this.onStats);
|
||||||
|
this.connection.on('statsLog', this.onStatsLog);
|
||||||
|
this.connection.send({
|
||||||
|
type: 'requestLog',
|
||||||
|
id: Math.random().toString()
|
||||||
|
});
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
this.connection.off('stats', this.onStats);
|
||||||
|
this.connection.off('statsLog', this.onStatsLog);
|
||||||
|
(this as any).os.streams.notesStatsStream.dispose(this.connectionId);
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
toggle() {
|
||||||
|
if (this.props.view == 2) {
|
||||||
|
this.props.view = 0;
|
||||||
|
} else {
|
||||||
|
this.props.view++;
|
||||||
|
}
|
||||||
|
this.save();
|
||||||
|
},
|
||||||
|
func() {
|
||||||
|
if (this.props.design == 2) {
|
||||||
|
this.props.design = 0;
|
||||||
|
} else {
|
||||||
|
this.props.design++;
|
||||||
|
}
|
||||||
|
this.save();
|
||||||
|
},
|
||||||
|
draw() {
|
||||||
|
const stats = this.props.view == 0 ? this.stats.slice(-50) : this.stats;
|
||||||
|
const fediPeak = Math.max.apply(null, stats.map(x => x.all)) || 1;
|
||||||
|
const localPeak = Math.max.apply(null, stats.map(x => x.local)) || 1;
|
||||||
|
|
||||||
|
const fediPolylinePoints = stats.map((s, i) => [this.viewBoxX - ((stats.length - 1) - i), (1 - (s.all / fediPeak)) * this.viewBoxY]);
|
||||||
|
const localPolylinePoints = stats.map((s, i) => [this.viewBoxX - ((stats.length - 1) - i), (1 - (s.local / localPeak)) * this.viewBoxY]);
|
||||||
|
this.fediPolylinePoints = fediPolylinePoints.map(xy => `${xy[0]},${xy[1]}`).join(' ');
|
||||||
|
this.localPolylinePoints = localPolylinePoints.map(xy => `${xy[0]},${xy[1]}`).join(' ');
|
||||||
|
|
||||||
|
this.fediPolygonPoints = `${this.viewBoxX - (stats.length - 1)},${ this.viewBoxY } ${ this.fediPolylinePoints } ${ this.viewBoxX },${ this.viewBoxY }`;
|
||||||
|
this.localPolygonPoints = `${this.viewBoxX - (stats.length - 1)},${ this.viewBoxY } ${ this.localPolylinePoints } ${ this.viewBoxX },${ this.viewBoxY }`;
|
||||||
|
|
||||||
|
this.fediHeadX = fediPolylinePoints[fediPolylinePoints.length - 1][0];
|
||||||
|
this.fediHeadY = fediPolylinePoints[fediPolylinePoints.length - 1][1];
|
||||||
|
this.localHeadX = localPolylinePoints[localPolylinePoints.length - 1][0];
|
||||||
|
this.localHeadY = localPolylinePoints[localPolylinePoints.length - 1][1];
|
||||||
|
},
|
||||||
|
onStats(stats) {
|
||||||
|
this.stats.push(stats);
|
||||||
|
if (this.stats.length > 100) this.stats.shift();
|
||||||
|
this.draw();
|
||||||
|
},
|
||||||
|
onStatsLog(statsLog) {
|
||||||
|
statsLog.forEach(stats => this.onStats(stats));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="stylus" scoped>
|
||||||
|
root(isDark)
|
||||||
|
&.dual
|
||||||
|
> svg
|
||||||
|
width 50%
|
||||||
|
float left
|
||||||
|
|
||||||
|
&:first-child
|
||||||
|
padding-right 5px
|
||||||
|
|
||||||
|
&:last-child
|
||||||
|
padding-left 5px
|
||||||
|
|
||||||
|
> svg
|
||||||
|
display block
|
||||||
|
padding 10px
|
||||||
|
width 100%
|
||||||
|
|
||||||
|
> text
|
||||||
|
font-size 5px
|
||||||
|
fill isDark ? rgba(#fff, 0.55) : rgba(#000, 0.55)
|
||||||
|
|
||||||
|
> tspan
|
||||||
|
opacity 0.5
|
||||||
|
|
||||||
|
&:after
|
||||||
|
content ""
|
||||||
|
display block
|
||||||
|
clear both
|
||||||
|
|
||||||
|
.qpdmibaztplkylerhdbllwcokyrfxeyj[data-darkmode]
|
||||||
|
root(true)
|
||||||
|
|
||||||
|
.qpdmibaztplkylerhdbllwcokyrfxeyj:not([data-darkmode])
|
||||||
|
root(false)
|
||||||
|
|
||||||
|
</style>
|
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="cpu-memory">
|
<div class="cpu-memory">
|
||||||
<svg :viewBox="`0 0 ${ viewBoxX } ${ viewBoxY }`" preserveAspectRatio="none">
|
<svg :viewBox="`0 0 ${ viewBoxX } ${ viewBoxY }`">
|
||||||
<defs>
|
<defs>
|
||||||
<linearGradient :id="cpuGradientId" x1="0" x2="0" y1="1" y2="0">
|
<linearGradient :id="cpuGradientId" x1="0" x2="0" y1="1" y2="0">
|
||||||
<stop offset="0%" stop-color="hsl(180, 80%, 70%)"></stop>
|
<stop offset="0%" stop-color="hsl(180, 80%, 70%)"></stop>
|
||||||
@ -16,15 +16,20 @@
|
|||||||
fill="none"
|
fill="none"
|
||||||
stroke="#fff"
|
stroke="#fff"
|
||||||
stroke-width="1"/>
|
stroke-width="1"/>
|
||||||
|
<circle
|
||||||
|
:cx="cpuHeadX"
|
||||||
|
:cy="cpuHeadY"
|
||||||
|
r="1.5"
|
||||||
|
fill="#fff"/>
|
||||||
</mask>
|
</mask>
|
||||||
</defs>
|
</defs>
|
||||||
<rect
|
<rect
|
||||||
x="-1" y="-1"
|
x="-2" y="-2"
|
||||||
:width="viewBoxX + 2" :height="viewBoxY + 2"
|
:width="viewBoxX + 4" :height="viewBoxY + 4"
|
||||||
:style="`stroke: none; fill: url(#${ cpuGradientId }); mask: url(#${ cpuMaskId })`"/>
|
:style="`stroke: none; fill: url(#${ cpuGradientId }); mask: url(#${ cpuMaskId })`"/>
|
||||||
<text x="1" y="5">CPU <tspan>{{ cpuP }}%</tspan></text>
|
<text x="1" y="5">CPU <tspan>{{ cpuP }}%</tspan></text>
|
||||||
</svg>
|
</svg>
|
||||||
<svg :viewBox="`0 0 ${ viewBoxX } ${ viewBoxY }`" preserveAspectRatio="none">
|
<svg :viewBox="`0 0 ${ viewBoxX } ${ viewBoxY }`">
|
||||||
<defs>
|
<defs>
|
||||||
<linearGradient :id="memGradientId" x1="0" x2="0" y1="1" y2="0">
|
<linearGradient :id="memGradientId" x1="0" x2="0" y1="1" y2="0">
|
||||||
<stop offset="0%" stop-color="hsl(180, 80%, 70%)"></stop>
|
<stop offset="0%" stop-color="hsl(180, 80%, 70%)"></stop>
|
||||||
@ -40,11 +45,16 @@
|
|||||||
fill="none"
|
fill="none"
|
||||||
stroke="#fff"
|
stroke="#fff"
|
||||||
stroke-width="1"/>
|
stroke-width="1"/>
|
||||||
|
<circle
|
||||||
|
:cx="memHeadX"
|
||||||
|
:cy="memHeadY"
|
||||||
|
r="1.5"
|
||||||
|
fill="#fff"/>
|
||||||
</mask>
|
</mask>
|
||||||
</defs>
|
</defs>
|
||||||
<rect
|
<rect
|
||||||
x="-1" y="-1"
|
x="-2" y="-2"
|
||||||
:width="viewBoxX + 2" :height="viewBoxY + 2"
|
:width="viewBoxX + 4" :height="viewBoxY + 4"
|
||||||
:style="`stroke: none; fill: url(#${ memGradientId }); mask: url(#${ memMaskId })`"/>
|
:style="`stroke: none; fill: url(#${ memGradientId }); mask: url(#${ memMaskId })`"/>
|
||||||
<text x="1" y="5">MEM <tspan>{{ memP }}%</tspan></text>
|
<text x="1" y="5">MEM <tspan>{{ memP }}%</tspan></text>
|
||||||
</svg>
|
</svg>
|
||||||
@ -70,15 +80,25 @@ export default Vue.extend({
|
|||||||
memPolylinePoints: '',
|
memPolylinePoints: '',
|
||||||
cpuPolygonPoints: '',
|
cpuPolygonPoints: '',
|
||||||
memPolygonPoints: '',
|
memPolygonPoints: '',
|
||||||
|
cpuHeadX: null,
|
||||||
|
cpuHeadY: null,
|
||||||
|
memHeadX: null,
|
||||||
|
memHeadY: null,
|
||||||
cpuP: '',
|
cpuP: '',
|
||||||
memP: ''
|
memP: ''
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.connection.on('stats', this.onStats);
|
this.connection.on('stats', this.onStats);
|
||||||
|
this.connection.on('statsLog', this.onStatsLog);
|
||||||
|
this.connection.send({
|
||||||
|
type: 'requestLog',
|
||||||
|
id: Math.random().toString()
|
||||||
|
});
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
this.connection.off('stats', this.onStats);
|
this.connection.off('stats', this.onStats);
|
||||||
|
this.connection.off('statsLog', this.onStatsLog);
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
onStats(stats) {
|
onStats(stats) {
|
||||||
@ -86,14 +106,24 @@ export default Vue.extend({
|
|||||||
this.stats.push(stats);
|
this.stats.push(stats);
|
||||||
if (this.stats.length > 50) this.stats.shift();
|
if (this.stats.length > 50) this.stats.shift();
|
||||||
|
|
||||||
this.cpuPolylinePoints = this.stats.map((s, i) => `${this.viewBoxX - ((this.stats.length - 1) - i)},${(1 - s.cpu_usage) * this.viewBoxY}`).join(' ');
|
const cpuPolylinePoints = this.stats.map((s, i) => [this.viewBoxX - ((this.stats.length - 1) - i), (1 - s.cpu_usage) * this.viewBoxY]);
|
||||||
this.memPolylinePoints = this.stats.map((s, i) => `${this.viewBoxX - ((this.stats.length - 1) - i)},${(1 - (s.mem.used / s.mem.total)) * this.viewBoxY}`).join(' ');
|
const memPolylinePoints = this.stats.map((s, i) => [this.viewBoxX - ((this.stats.length - 1) - i), (1 - (s.mem.used / s.mem.total)) * this.viewBoxY]);
|
||||||
|
this.cpuPolylinePoints = cpuPolylinePoints.map(xy => `${xy[0]},${xy[1]}`).join(' ');
|
||||||
|
this.memPolylinePoints = memPolylinePoints.map(xy => `${xy[0]},${xy[1]}`).join(' ');
|
||||||
|
|
||||||
this.cpuPolygonPoints = `${this.viewBoxX - (this.stats.length - 1)},${ this.viewBoxY } ${ this.cpuPolylinePoints } ${ this.viewBoxX },${ this.viewBoxY }`;
|
this.cpuPolygonPoints = `${this.viewBoxX - (this.stats.length - 1)},${ this.viewBoxY } ${ this.cpuPolylinePoints } ${ this.viewBoxX },${ this.viewBoxY }`;
|
||||||
this.memPolygonPoints = `${this.viewBoxX - (this.stats.length - 1)},${ this.viewBoxY } ${ this.memPolylinePoints } ${ this.viewBoxX },${ this.viewBoxY }`;
|
this.memPolygonPoints = `${this.viewBoxX - (this.stats.length - 1)},${ this.viewBoxY } ${ this.memPolylinePoints } ${ this.viewBoxX },${ this.viewBoxY }`;
|
||||||
|
|
||||||
|
this.cpuHeadX = cpuPolylinePoints[cpuPolylinePoints.length - 1][0];
|
||||||
|
this.cpuHeadY = cpuPolylinePoints[cpuPolylinePoints.length - 1][1];
|
||||||
|
this.memHeadX = memPolylinePoints[memPolylinePoints.length - 1][0];
|
||||||
|
this.memHeadY = memPolylinePoints[memPolylinePoints.length - 1][1];
|
||||||
|
|
||||||
this.cpuP = (stats.cpu_usage * 100).toFixed(0);
|
this.cpuP = (stats.cpu_usage * 100).toFixed(0);
|
||||||
this.memP = (stats.mem.used / stats.mem.total * 100).toFixed(0);
|
this.memP = (stats.mem.used / stats.mem.total * 100).toFixed(0);
|
||||||
|
},
|
||||||
|
onStatsLog(statsLog) {
|
||||||
|
statsLog.forEach(stats => this.onStats(stats));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -55,11 +55,11 @@ export default define({
|
|||||||
this.fetching = false;
|
this.fetching = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.connection = (this as any).os.streams.serverStream.getConnection();
|
this.connection = (this as any).os.streams.serverStatsStream.getConnection();
|
||||||
this.connectionId = (this as any).os.streams.serverStream.use();
|
this.connectionId = (this as any).os.streams.serverStatsStream.use();
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
(this as any).os.streams.serverStream.dispose(this.connectionId);
|
(this as any).os.streams.serverStatsStream.dispose(this.connectionId);
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
toggle() {
|
toggle() {
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
declare const _HOST_: string;
|
declare const _HOST_: string;
|
||||||
declare const _HOSTNAME_: string;
|
declare const _HOSTNAME_: string;
|
||||||
declare const _URL_: string;
|
declare const _URL_: string;
|
||||||
|
declare const _NAME_: string;
|
||||||
|
declare const _DESCRIPTION_: string;
|
||||||
declare const _API_URL_: string;
|
declare const _API_URL_: string;
|
||||||
declare const _WS_URL_: string;
|
declare const _WS_URL_: string;
|
||||||
declare const _DOCS_URL_: string;
|
declare const _DOCS_URL_: string;
|
||||||
@ -17,10 +19,13 @@ declare const _VERSION_: string;
|
|||||||
declare const _CODENAME_: string;
|
declare const _CODENAME_: string;
|
||||||
declare const _LICENSE_: string;
|
declare const _LICENSE_: string;
|
||||||
declare const _GOOGLE_MAPS_API_KEY_: string;
|
declare const _GOOGLE_MAPS_API_KEY_: string;
|
||||||
|
declare const _WELCOME_BG_URL_: string;
|
||||||
|
|
||||||
export const host = _HOST_;
|
export const host = _HOST_;
|
||||||
export const hostname = _HOSTNAME_;
|
export const hostname = _HOSTNAME_;
|
||||||
export const url = _URL_;
|
export const url = _URL_;
|
||||||
|
export const name = _NAME_;
|
||||||
|
export const description = _DESCRIPTION_;
|
||||||
export const apiUrl = _API_URL_;
|
export const apiUrl = _API_URL_;
|
||||||
export const wsUrl = _WS_URL_;
|
export const wsUrl = _WS_URL_;
|
||||||
export const docsUrl = _DOCS_URL_;
|
export const docsUrl = _DOCS_URL_;
|
||||||
@ -37,3 +42,4 @@ export const version = _VERSION_;
|
|||||||
export const codename = _CODENAME_;
|
export const codename = _CODENAME_;
|
||||||
export const license = _LICENSE_;
|
export const license = _LICENSE_;
|
||||||
export const googleMapsApiKey = _GOOGLE_MAPS_API_KEY_;
|
export const googleMapsApiKey = _GOOGLE_MAPS_API_KEY_;
|
||||||
|
export const welcomeBgUrl = _WELCOME_BG_URL_;
|
||||||
|
@ -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');
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,9 @@ import MkHomeCustomize from './views/pages/home-customize.vue';
|
|||||||
import MkMessagingRoom from './views/pages/messaging-room.vue';
|
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 MkOthello from './views/pages/othello.vue';
|
import MkTag from './views/pages/tag.vue';
|
||||||
|
import MkReversi from './views/pages/reversi.vue';
|
||||||
|
import MkShare from './views/pages/share.vue';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* init
|
* init
|
||||||
@ -60,8 +62,10 @@ init(async (launch) => {
|
|||||||
{ path: '/i/lists/:list', component: MkUserList },
|
{ path: '/i/lists/:list', component: MkUserList },
|
||||||
{ path: '/selectdrive', component: MkSelectDrive },
|
{ path: '/selectdrive', component: MkSelectDrive },
|
||||||
{ path: '/search', component: MkSearch },
|
{ path: '/search', component: MkSearch },
|
||||||
{ path: '/othello', component: MkOthello },
|
{ path: '/tags/:tag', component: MkTag },
|
||||||
{ path: '/othello/:game', component: MkOthello },
|
{ path: '/share', component: MkShare },
|
||||||
|
{ 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 }
|
||||||
]
|
]
|
||||||
@ -162,8 +166,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
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<svg viewBox="0 0 21 7" preserveAspectRatio="none">
|
<svg viewBox="0 0 21 7">
|
||||||
<rect v-for="record in data" class="day"
|
<rect v-for="record in data" class="day"
|
||||||
width="1" height="1"
|
width="1" height="1"
|
||||||
:x="record.x" :y="record.date.weekday"
|
:x="record.x" :y="record.date.weekday"
|
||||||
@ -15,7 +15,7 @@
|
|||||||
style="pointer-events: none;"/>
|
style="pointer-events: none;"/>
|
||||||
<rect class="today"
|
<rect class="today"
|
||||||
width="1" height="1"
|
width="1" height="1"
|
||||||
:x="data[data.length - 1].x" :y="data[data.length - 1].date.weekday"
|
:x="data[0].x" :y="data[0].date.weekday"
|
||||||
rx="1" ry="1"
|
rx="1" ry="1"
|
||||||
fill="none"
|
fill="none"
|
||||||
stroke-width="0.1"
|
stroke-width="0.1"
|
||||||
@ -33,7 +33,7 @@ export default Vue.extend({
|
|||||||
const peak = Math.max.apply(null, this.data.map(d => d.total));
|
const peak = Math.max.apply(null, this.data.map(d => d.total));
|
||||||
|
|
||||||
let x = 0;
|
let x = 0;
|
||||||
this.data.reverse().forEach(d => {
|
this.data.slice().reverse().forEach(d => {
|
||||||
d.x = x;
|
d.x = x;
|
||||||
d.date.weekday = (new Date(d.date.year, d.date.month - 1, d.date.day)).getDay();
|
d.date.weekday = (new Date(d.date.year, d.date.month - 1, d.date.day)).getDay();
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<svg :viewBox="`0 0 ${ viewBoxX } ${ viewBoxY }`" preserveAspectRatio="none" @mousedown.prevent="onMousedown">
|
<svg :viewBox="`0 0 ${ viewBoxX } ${ viewBoxY }`" @mousedown.prevent="onMousedown">
|
||||||
<title>%i18n:@total%<br/>%i18n:@notes%<br/>%i18n:@replies%<br/>%i18n:@renotes%</title>
|
<title>%i18n:@total%<br/>%i18n:@notes%<br/>%i18n:@replies%<br/>%i18n:@renotes%</title>
|
||||||
<polyline
|
<polyline
|
||||||
:points="pointsNote"
|
:points="pointsNote"
|
||||||
@ -55,7 +55,6 @@ export default Vue.extend({
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.data.reverse();
|
|
||||||
this.data.forEach(d => d.total = d.notes + d.replies + d.renotes);
|
this.data.forEach(d => d.total = d.notes + d.replies + d.renotes);
|
||||||
this.render();
|
this.render();
|
||||||
},
|
},
|
||||||
@ -63,10 +62,11 @@ export default Vue.extend({
|
|||||||
render() {
|
render() {
|
||||||
const peak = Math.max.apply(null, this.data.map(d => d.total));
|
const peak = Math.max.apply(null, this.data.map(d => d.total));
|
||||||
if (peak != 0) {
|
if (peak != 0) {
|
||||||
this.pointsNote = this.data.map((d, i) => `${(i * this.zoom) + this.pos},${(1 - (d.notes / peak)) * this.viewBoxY}`).join(' ');
|
const data = this.data.slice().reverse();
|
||||||
this.pointsReply = this.data.map((d, i) => `${(i * this.zoom) + this.pos},${(1 - (d.replies / peak)) * this.viewBoxY}`).join(' ');
|
this.pointsNote = data.map((d, i) => `${(i * this.zoom) + this.pos},${(1 - (d.notes / peak)) * this.viewBoxY}`).join(' ');
|
||||||
this.pointsRenote = this.data.map((d, i) => `${(i * this.zoom) + this.pos},${(1 - (d.renotes / peak)) * this.viewBoxY}`).join(' ');
|
this.pointsReply = data.map((d, i) => `${(i * this.zoom) + this.pos},${(1 - (d.replies / peak)) * this.viewBoxY}`).join(' ');
|
||||||
this.pointsTotal = this.data.map((d, i) => `${(i * this.zoom) + this.pos},${(1 - (d.total / peak)) * this.viewBoxY}`).join(' ');
|
this.pointsRenote = data.map((d, i) => `${(i * this.zoom) + this.pos},${(1 - (d.renotes / peak)) * this.viewBoxY}`).join(' ');
|
||||||
|
this.pointsTotal = data.map((d, i) => `${(i * this.zoom) + this.pos},${(1 - (d.total / peak)) * this.viewBoxY}`).join(' ');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onMousedown(e) {
|
onMousedown(e) {
|
||||||
|
@ -1,16 +1,18 @@
|
|||||||
<template>
|
<template>
|
||||||
<ul class="menu">
|
<ul class="menu">
|
||||||
<li v-for="(item, i) in menu" :class="item.type">
|
<li v-for="(item, i) in menu" :class="item ? item.type : item === null ? 'divider' : null">
|
||||||
<template v-if="item.type == 'item'">
|
<template v-if="item">
|
||||||
|
<template v-if="item.type == null || item.type == 'item'">
|
||||||
<p @click="click(item)"><span :class="$style.icon" v-if="item.icon" v-html="item.icon"></span>{{ item.text }}</p>
|
<p @click="click(item)"><span :class="$style.icon" v-if="item.icon" v-html="item.icon"></span>{{ item.text }}</p>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="item.type == 'link'">
|
<template v-else-if="item.type == 'link'">
|
||||||
<a :href="item.href" :target="item.target" @click="click(item)"><span :class="$style.icon" v-if="item.icon" v-html="item.icon"></span>{{ item.text }}</a>
|
<a :href="item.href" :target="item.target" @click="click(item)"><span :class="$style.icon" v-if="item.icon" v-html="item.icon"></span>{{ item.text }}</a>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="item.type == 'nest'">
|
<template v-else-if="item.type == 'nest'">
|
||||||
<p><span :class="$style.icon" v-if="item.icon" v-html="item.icon"></span>{{ item.text }}...<span class="caret">%fa:caret-right%</span></p>
|
<p><span :class="$style.icon" v-if="item.icon" v-html="item.icon"></span>{{ item.text }}...<span class="caret">%fa:caret-right%</span></p>
|
||||||
<me-nu :menu="item.menu" @x="click"/>
|
<me-nu :menu="item.menu" @x="click"/>
|
||||||
</template>
|
</template>
|
||||||
|
</template>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</template>
|
</template>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="context-menu" :style="{ left: `${x}px`, top: `${y}px` }" @contextmenu.prevent="() => {}">
|
<div class="context-menu" @contextmenu.prevent="() => {}">
|
||||||
<x-menu :menu="menu" @x="click"/>
|
<x-menu :menu="menu" @x="click"/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -17,6 +17,23 @@ export default Vue.extend({
|
|||||||
props: ['x', 'y', 'menu'],
|
props: ['x', 'y', 'menu'],
|
||||||
mounted() {
|
mounted() {
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
|
const width = this.$el.offsetWidth;
|
||||||
|
const height = this.$el.offsetHeight;
|
||||||
|
|
||||||
|
let x = this.x;
|
||||||
|
let y = this.y;
|
||||||
|
|
||||||
|
if (x + width - window.pageXOffset > window.innerWidth) {
|
||||||
|
x = window.innerWidth - width + window.pageXOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y + height - window.pageYOffset > window.innerHeight) {
|
||||||
|
y = window.innerHeight - height + window.pageYOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$el.style.left = x + 'px';
|
||||||
|
this.$el.style.top = y + 'px';
|
||||||
|
|
||||||
Array.from(document.querySelectorAll('body *')).forEach(el => {
|
Array.from(document.querySelectorAll('body *')).forEach(el => {
|
||||||
el.addEventListener('mousedown', this.onMousedown);
|
el.addEventListener('mousedown', this.onMousedown);
|
||||||
});
|
});
|
||||||
@ -38,7 +55,7 @@ export default Vue.extend({
|
|||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
click(item) {
|
click(item) {
|
||||||
if (item.onClick) item.onClick();
|
if (item.action) item.action();
|
||||||
this.close();
|
this.close();
|
||||||
},
|
},
|
||||||
close() {
|
close() {
|
||||||
@ -59,7 +76,6 @@ root(isDark)
|
|||||||
$item-height = 38px
|
$item-height = 38px
|
||||||
$padding = 10px
|
$padding = 10px
|
||||||
|
|
||||||
display none
|
|
||||||
position fixed
|
position fixed
|
||||||
top 0
|
top 0
|
||||||
left 0
|
left 0
|
||||||
|
@ -66,37 +66,33 @@ export default Vue.extend({
|
|||||||
type: 'item',
|
type: 'item',
|
||||||
text: '%i18n:@contextmenu.rename%',
|
text: '%i18n:@contextmenu.rename%',
|
||||||
icon: '%fa:i-cursor%',
|
icon: '%fa:i-cursor%',
|
||||||
onClick: this.rename
|
action: this.rename
|
||||||
}, {
|
}, {
|
||||||
type: 'item',
|
type: 'item',
|
||||||
text: '%i18n:@contextmenu.copy-url%',
|
text: '%i18n:@contextmenu.copy-url%',
|
||||||
icon: '%fa:link%',
|
icon: '%fa:link%',
|
||||||
onClick: this.copyUrl
|
action: this.copyUrl
|
||||||
}, {
|
}, {
|
||||||
type: 'link',
|
type: 'link',
|
||||||
href: `${this.file.url}?download`,
|
href: `${this.file.url}?download`,
|
||||||
text: '%i18n:@contextmenu.download%',
|
text: '%i18n:@contextmenu.download%',
|
||||||
icon: '%fa:download%',
|
icon: '%fa:download%',
|
||||||
}, {
|
}, null, {
|
||||||
type: 'divider',
|
|
||||||
}, {
|
|
||||||
type: 'item',
|
type: 'item',
|
||||||
text: '%i18n:common.delete%',
|
text: '%i18n:common.delete%',
|
||||||
icon: '%fa:R trash-alt%',
|
icon: '%fa:R trash-alt%',
|
||||||
onClick: this.deleteFile
|
action: this.deleteFile
|
||||||
}, {
|
}, null, {
|
||||||
type: 'divider',
|
|
||||||
}, {
|
|
||||||
type: 'nest',
|
type: 'nest',
|
||||||
text: '%i18n:@contextmenu.else-files%',
|
text: '%i18n:@contextmenu.else-files%',
|
||||||
menu: [{
|
menu: [{
|
||||||
type: 'item',
|
type: 'item',
|
||||||
text: '%i18n:@contextmenu.set-as-avatar%',
|
text: '%i18n:@contextmenu.set-as-avatar%',
|
||||||
onClick: this.setAsAvatar
|
action: this.setAsAvatar
|
||||||
}, {
|
}, {
|
||||||
type: 'item',
|
type: 'item',
|
||||||
text: '%i18n:@contextmenu.set-as-banner%',
|
text: '%i18n:@contextmenu.set-as-banner%',
|
||||||
onClick: this.setAsBanner
|
action: this.setAsBanner
|
||||||
}]
|
}]
|
||||||
}, {
|
}, {
|
||||||
type: 'nest',
|
type: 'nest',
|
||||||
@ -104,7 +100,7 @@ export default Vue.extend({
|
|||||||
menu: [{
|
menu: [{
|
||||||
type: 'item',
|
type: 'item',
|
||||||
text: '%i18n:@contextmenu.add-app%...',
|
text: '%i18n:@contextmenu.add-app%...',
|
||||||
onClick: this.addApp
|
action: this.addApp
|
||||||
}]
|
}]
|
||||||
}], {
|
}], {
|
||||||
closed: () => {
|
closed: () => {
|
||||||
@ -149,7 +145,7 @@ export default Vue.extend({
|
|||||||
(this as any).api('drive/files/update', {
|
(this as any).api('drive/files/update', {
|
||||||
fileId: this.file.id,
|
fileId: this.file.id,
|
||||||
name: name
|
name: name
|
||||||
})
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -177,7 +173,9 @@ export default Vue.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
deleteFile() {
|
deleteFile() {
|
||||||
alert('not implemented yet');
|
(this as any).api('drive/files/delete', {
|
||||||
|
fileId: this.file.id
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -56,26 +56,22 @@ export default Vue.extend({
|
|||||||
type: 'item',
|
type: 'item',
|
||||||
text: '%i18n:@contextmenu.move-to-this-folder%',
|
text: '%i18n:@contextmenu.move-to-this-folder%',
|
||||||
icon: '%fa:arrow-right%',
|
icon: '%fa:arrow-right%',
|
||||||
onClick: this.go
|
action: this.go
|
||||||
}, {
|
}, {
|
||||||
type: 'item',
|
type: 'item',
|
||||||
text: '%i18n:@contextmenu.show-in-new-window%',
|
text: '%i18n:@contextmenu.show-in-new-window%',
|
||||||
icon: '%fa:R window-restore%',
|
icon: '%fa:R window-restore%',
|
||||||
onClick: this.newWindow
|
action: this.newWindow
|
||||||
}, {
|
}, null, {
|
||||||
type: 'divider',
|
|
||||||
}, {
|
|
||||||
type: 'item',
|
type: 'item',
|
||||||
text: '%i18n:@contextmenu.rename%',
|
text: '%i18n:@contextmenu.rename%',
|
||||||
icon: '%fa:i-cursor%',
|
icon: '%fa:i-cursor%',
|
||||||
onClick: this.rename
|
action: this.rename
|
||||||
}, {
|
}, null, {
|
||||||
type: 'divider',
|
|
||||||
}, {
|
|
||||||
type: 'item',
|
type: 'item',
|
||||||
text: '%i18n:common.delete%',
|
text: '%i18n:common.delete%',
|
||||||
icon: '%fa:R trash-alt%',
|
icon: '%fa:R trash-alt%',
|
||||||
onClick: this.deleteFolder
|
action: this.deleteFolder
|
||||||
}], {
|
}], {
|
||||||
closed: () => {
|
closed: () => {
|
||||||
this.isContextmenuShowing = false;
|
this.isContextmenuShowing = false;
|
||||||
|
@ -118,6 +118,7 @@ export default Vue.extend({
|
|||||||
|
|
||||||
this.connection.on('file_created', this.onStreamDriveFileCreated);
|
this.connection.on('file_created', this.onStreamDriveFileCreated);
|
||||||
this.connection.on('file_updated', this.onStreamDriveFileUpdated);
|
this.connection.on('file_updated', this.onStreamDriveFileUpdated);
|
||||||
|
this.connection.on('file_deleted', this.onStreamDriveFileDeleted);
|
||||||
this.connection.on('folder_created', this.onStreamDriveFolderCreated);
|
this.connection.on('folder_created', this.onStreamDriveFolderCreated);
|
||||||
this.connection.on('folder_updated', this.onStreamDriveFolderUpdated);
|
this.connection.on('folder_updated', this.onStreamDriveFolderUpdated);
|
||||||
|
|
||||||
@ -130,6 +131,7 @@ export default Vue.extend({
|
|||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
this.connection.off('file_created', this.onStreamDriveFileCreated);
|
this.connection.off('file_created', this.onStreamDriveFileCreated);
|
||||||
this.connection.off('file_updated', this.onStreamDriveFileUpdated);
|
this.connection.off('file_updated', this.onStreamDriveFileUpdated);
|
||||||
|
this.connection.off('file_deleted', this.onStreamDriveFileDeleted);
|
||||||
this.connection.off('folder_created', this.onStreamDriveFolderCreated);
|
this.connection.off('folder_created', this.onStreamDriveFolderCreated);
|
||||||
this.connection.off('folder_updated', this.onStreamDriveFolderUpdated);
|
this.connection.off('folder_updated', this.onStreamDriveFolderUpdated);
|
||||||
(this as any).os.streams.driveStream.dispose(this.connectionId);
|
(this as any).os.streams.driveStream.dispose(this.connectionId);
|
||||||
@ -140,17 +142,17 @@ export default Vue.extend({
|
|||||||
type: 'item',
|
type: 'item',
|
||||||
text: '%i18n:@contextmenu.create-folder%',
|
text: '%i18n:@contextmenu.create-folder%',
|
||||||
icon: '%fa:R folder%',
|
icon: '%fa:R folder%',
|
||||||
onClick: this.createFolder
|
action: this.createFolder
|
||||||
}, {
|
}, {
|
||||||
type: 'item',
|
type: 'item',
|
||||||
text: '%i18n:@contextmenu.upload%',
|
text: '%i18n:@contextmenu.upload%',
|
||||||
icon: '%fa:upload%',
|
icon: '%fa:upload%',
|
||||||
onClick: this.selectLocalFile
|
action: this.selectLocalFile
|
||||||
}, {
|
}, {
|
||||||
type: 'item',
|
type: 'item',
|
||||||
text: '%i18n:@contextmenu.url-upload%',
|
text: '%i18n:@contextmenu.url-upload%',
|
||||||
icon: '%fa:cloud-upload-alt%',
|
icon: '%fa:cloud-upload-alt%',
|
||||||
onClick: this.urlUpload
|
action: this.urlUpload
|
||||||
}]);
|
}]);
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -167,6 +169,10 @@ export default Vue.extend({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
onStreamDriveFileDeleted(fileId) {
|
||||||
|
this.removeFile(fileId);
|
||||||
|
},
|
||||||
|
|
||||||
onStreamDriveFolderCreated(folder) {
|
onStreamDriveFolderCreated(folder) {
|
||||||
this.addFolder(folder, true);
|
this.addFolder(folder, true);
|
||||||
},
|
},
|
||||||
|
@ -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`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -23,6 +23,8 @@
|
|||||||
<option value="post-form">%i18n:common.widgets.post-form%</option>
|
<option value="post-form">%i18n:common.widgets.post-form%</option>
|
||||||
<option value="messaging">%i18n:common.widgets.messaging%</option>
|
<option value="messaging">%i18n:common.widgets.messaging%</option>
|
||||||
<option value="memo">%i18n:common.widgets.memo%</option>
|
<option value="memo">%i18n:common.widgets.memo%</option>
|
||||||
|
<option value="hashtags">%i18n:common.widgets.hashtags%</option>
|
||||||
|
<option value="posts-monitor">%i18n:common.widgets.posts-monitor%</option>
|
||||||
<option value="server">%i18n:common.widgets.server%</option>
|
<option value="server">%i18n:common.widgets.server%</option>
|
||||||
<option value="donation">%i18n:common.widgets.donation%</option>
|
<option value="donation">%i18n:common.widgets.donation%</option>
|
||||||
<option value="nav">%i18n:common.widgets.nav%</option>
|
<option value="nav">%i18n:common.widgets.nav%</option>
|
||||||
@ -82,7 +84,7 @@ const defaultDesktopHomeWidgets = {
|
|||||||
'calendar',
|
'calendar',
|
||||||
'activity',
|
'activity',
|
||||||
'rss',
|
'rss',
|
||||||
'trends',
|
'hashtags',
|
||||||
'photo-stream',
|
'photo-stream',
|
||||||
'version'
|
'version'
|
||||||
],
|
],
|
||||||
|
@ -48,7 +48,7 @@
|
|||||||
<mk-poll v-if="p.poll" :note="p"/>
|
<mk-poll v-if="p.poll" :note="p"/>
|
||||||
<mk-url-preview v-for="url in urls" :url="url" :key="url"/>
|
<mk-url-preview v-for="url in urls" :url="url" :key="url"/>
|
||||||
<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="`/search?q=#${tag}`">{{ tag }}</router-link>
|
<router-link v-for="tag in p.tags" :key="tag" :to="`/tags/${tag}`">{{ tag }}</router-link>
|
||||||
</div>
|
</div>
|
||||||
<a class="location" v-if="p.geo" :href="`http://maps.google.com/maps?q=${p.geo.coordinates[1]},${p.geo.coordinates[0]}`" target="_blank">%fa:map-marker-alt% %i18n:@location%</a>
|
<a class="location" v-if="p.geo" :href="`http://maps.google.com/maps?q=${p.geo.coordinates[1]},${p.geo.coordinates[0]}`" target="_blank">%fa:map-marker-alt% %i18n:@location%</a>
|
||||||
<div class="map" v-if="p.geo" ref="map"></div>
|
<div class="map" v-if="p.geo" ref="map"></div>
|
||||||
|
@ -1,23 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="mk-note-preview" :title="title">
|
<div class="mk-note-preview" :title="title">
|
||||||
<mk-avatar class="avatar" :user="note.user"/>
|
<mk-avatar class="avatar" :user="note.user" v-if="!mini"/>
|
||||||
<div class="main">
|
<div class="main">
|
||||||
<header>
|
<mk-note-header class="header" :note="note" :mini="true"/>
|
||||||
<router-link class="name" :to="note.user | userPage" v-user-preview="note.userId">{{ note.user | userName }}</router-link>
|
|
||||||
<span class="username"><mk-acct :user="note.user"/></span>
|
|
||||||
<div class="info">
|
|
||||||
<span class="mobile" v-if="note.viaMobile">%fa:mobile-alt%</span>
|
|
||||||
<router-link class="created-at" :to="note | notePage">
|
|
||||||
<mk-time :time="note.createdAt"/>
|
|
||||||
</router-link>
|
|
||||||
<span class="visibility" v-if="note.visibility != 'public'">
|
|
||||||
<template v-if="note.visibility == 'home'">%fa:home%</template>
|
|
||||||
<template v-if="note.visibility == 'followers'">%fa:unlock%</template>
|
|
||||||
<template v-if="note.visibility == 'specified'">%fa:envelope%</template>
|
|
||||||
<template v-if="note.visibility == 'private'">%fa:lock%</template>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
<div class="body">
|
<div class="body">
|
||||||
<mk-sub-note-content class="text" :note="note"/>
|
<mk-sub-note-content class="text" :note="note"/>
|
||||||
</div>
|
</div>
|
||||||
@ -30,7 +15,17 @@ import Vue from 'vue';
|
|||||||
import dateStringify from '../../../common/scripts/date-stringify';
|
import dateStringify from '../../../common/scripts/date-stringify';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
props: ['note'],
|
props: {
|
||||||
|
note: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
mini: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
computed: {
|
computed: {
|
||||||
title(): string {
|
title(): string {
|
||||||
return dateStringify(this.note.createdAt);
|
return dateStringify(this.note.createdAt);
|
||||||
@ -56,43 +51,6 @@ root(isDark)
|
|||||||
flex 1
|
flex 1
|
||||||
min-width 0
|
min-width 0
|
||||||
|
|
||||||
> header
|
|
||||||
display flex
|
|
||||||
align-items baseline
|
|
||||||
white-space nowrap
|
|
||||||
|
|
||||||
> .name
|
|
||||||
margin 0 .5em 0 0
|
|
||||||
padding 0
|
|
||||||
overflow hidden
|
|
||||||
color isDark ? #fff : #607073
|
|
||||||
font-size 1em
|
|
||||||
font-weight bold
|
|
||||||
text-decoration none
|
|
||||||
text-overflow ellipsis
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
text-decoration underline
|
|
||||||
|
|
||||||
> .username
|
|
||||||
margin 0 .5em 0 0
|
|
||||||
overflow hidden
|
|
||||||
text-overflow ellipsis
|
|
||||||
color isDark ? #606984 : #d1d8da
|
|
||||||
|
|
||||||
> .info
|
|
||||||
margin-left auto
|
|
||||||
font-size 0.9em
|
|
||||||
|
|
||||||
> *
|
|
||||||
color isDark ? #606984 : #b2b8bb
|
|
||||||
|
|
||||||
> .mobile
|
|
||||||
margin-right 6px
|
|
||||||
|
|
||||||
> .visibility
|
|
||||||
margin-left 6px
|
|
||||||
|
|
||||||
> .body
|
> .body
|
||||||
|
|
||||||
> .text
|
> .text
|
||||||
|
@ -2,25 +2,7 @@
|
|||||||
<div class="sub" :title="title">
|
<div class="sub" :title="title">
|
||||||
<mk-avatar class="avatar" :user="note.user"/>
|
<mk-avatar class="avatar" :user="note.user"/>
|
||||||
<div class="main">
|
<div class="main">
|
||||||
<header>
|
<mk-note-header class="header" :note="note"/>
|
||||||
<router-link class="name" :to="note.user | userPage" v-user-preview="note.userId">{{ note.user | userName }}</router-link>
|
|
||||||
<span class="is-admin" v-if="note.user.isAdmin">admin</span>
|
|
||||||
<span class="is-bot" v-if="note.user.isBot">bot</span>
|
|
||||||
<span class="is-cat" v-if="note.user.isCat">cat</span>
|
|
||||||
<span class="username"><mk-acct :user="note.user"/></span>
|
|
||||||
<div class="info">
|
|
||||||
<span class="mobile" v-if="note.viaMobile">%fa:mobile-alt%</span>
|
|
||||||
<router-link class="created-at" :to="note | notePage">
|
|
||||||
<mk-time :time="note.createdAt"/>
|
|
||||||
</router-link>
|
|
||||||
<span class="visibility" v-if="note.visibility != 'public'">
|
|
||||||
<template v-if="note.visibility == 'home'">%fa:home%</template>
|
|
||||||
<template v-if="note.visibility == 'followers'">%fa:unlock%</template>
|
|
||||||
<template v-if="note.visibility == 'specified'">%fa:envelope%</template>
|
|
||||||
<template v-if="note.visibility == 'private'">%fa:lock%</template>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
<div class="body">
|
<div class="body">
|
||||||
<mk-sub-note-content class="text" :note="note"/>
|
<mk-sub-note-content class="text" :note="note"/>
|
||||||
</div>
|
</div>
|
||||||
@ -62,57 +44,8 @@ root(isDark)
|
|||||||
flex 1
|
flex 1
|
||||||
min-width 0
|
min-width 0
|
||||||
|
|
||||||
> header
|
> .header
|
||||||
display flex
|
|
||||||
align-items baseline
|
|
||||||
margin-bottom 2px
|
margin-bottom 2px
|
||||||
white-space nowrap
|
|
||||||
|
|
||||||
> .name
|
|
||||||
display block
|
|
||||||
margin 0 .5em 0 0
|
|
||||||
padding 0
|
|
||||||
overflow hidden
|
|
||||||
color isDark ? #fff : #607073
|
|
||||||
font-size 1em
|
|
||||||
font-weight bold
|
|
||||||
text-decoration none
|
|
||||||
text-overflow ellipsis
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
text-decoration underline
|
|
||||||
|
|
||||||
> .is-admin
|
|
||||||
> .is-bot
|
|
||||||
> .is-cat
|
|
||||||
align-self center
|
|
||||||
margin 0 0.5em 0 0
|
|
||||||
padding 1px 5px
|
|
||||||
font-size 10px
|
|
||||||
color isDark ? #758188 : #aaa
|
|
||||||
border solid 1px isDark ? #57616f : #ddd
|
|
||||||
border-radius 3px
|
|
||||||
|
|
||||||
&.is-admin
|
|
||||||
border-color isDark ? #d42c41 : #f56a7b
|
|
||||||
color isDark ? #d42c41 : #f56a7b
|
|
||||||
|
|
||||||
> .username
|
|
||||||
margin 0 .5em 0 0
|
|
||||||
color isDark ? #606984 : #d1d8da
|
|
||||||
|
|
||||||
> .info
|
|
||||||
margin-left auto
|
|
||||||
font-size 0.9em
|
|
||||||
|
|
||||||
> *
|
|
||||||
color isDark ? #606984 : #b2b8bb
|
|
||||||
|
|
||||||
> .mobile
|
|
||||||
margin-right 6px
|
|
||||||
|
|
||||||
> .visibility
|
|
||||||
margin-left 6px
|
|
||||||
|
|
||||||
> .body
|
> .body
|
||||||
|
|
||||||
|
@ -14,26 +14,7 @@
|
|||||||
<article>
|
<article>
|
||||||
<mk-avatar class="avatar" :user="p.user"/>
|
<mk-avatar class="avatar" :user="p.user"/>
|
||||||
<div class="main">
|
<div class="main">
|
||||||
<header>
|
<mk-note-header class="header" :note="p"/>
|
||||||
<router-link class="name" :to="p.user | userPage" v-user-preview="p.user.id">{{ p.user | userName }}</router-link>
|
|
||||||
<span class="is-admin" v-if="p.user.isAdmin">admin</span>
|
|
||||||
<span class="is-bot" v-if="p.user.isBot">bot</span>
|
|
||||||
<span class="is-cat" v-if="p.user.isCat">cat</span>
|
|
||||||
<span class="username"><mk-acct :user="p.user"/></span>
|
|
||||||
<div class="info">
|
|
||||||
<span class="app" v-if="p.app">via <b>{{ p.app.name }}</b></span>
|
|
||||||
<span class="mobile" v-if="p.viaMobile">%fa:mobile-alt%</span>
|
|
||||||
<router-link class="created-at" :to="p | notePage">
|
|
||||||
<mk-time :time="p.createdAt"/>
|
|
||||||
</router-link>
|
|
||||||
<span class="visibility" v-if="p.visibility != 'public'">
|
|
||||||
<template v-if="p.visibility == 'home'">%fa:home%</template>
|
|
||||||
<template v-if="p.visibility == 'followers'">%fa:unlock%</template>
|
|
||||||
<template v-if="p.visibility == 'specified'">%fa:envelope%</template>
|
|
||||||
<template v-if="p.visibility == 'private'">%fa:lock%</template>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
<div class="body">
|
<div class="body">
|
||||||
<p v-if="p.cw != null" class="cw">
|
<p v-if="p.cw != null" class="cw">
|
||||||
<span class="text" v-if="p.cw != ''">{{ p.cw }}</span>
|
<span class="text" v-if="p.cw != ''">{{ p.cw }}</span>
|
||||||
@ -52,7 +33,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<mk-poll v-if="p.poll" :note="p" ref="pollViewer"/>
|
<mk-poll v-if="p.poll" :note="p" ref="pollViewer"/>
|
||||||
<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="`/search?q=#${tag}`">{{ tag }}</router-link>
|
<router-link v-for="tag in p.tags" :key="tag" :to="`/tags/${tag}`">{{ tag }}</router-link>
|
||||||
</div>
|
</div>
|
||||||
<a class="location" v-if="p.geo" :href="`http://maps.google.com/maps?q=${p.geo.coordinates[1]},${p.geo.coordinates[0]}`" target="_blank">%fa:map-marker-alt% 位置情報</a>
|
<a class="location" v-if="p.geo" :href="`http://maps.google.com/maps?q=${p.geo.coordinates[1]},${p.geo.coordinates[0]}`" target="_blank">%fa:map-marker-alt% 位置情報</a>
|
||||||
<div class="map" v-if="p.geo" ref="map"></div>
|
<div class="map" v-if="p.geo" ref="map"></div>
|
||||||
@ -409,64 +390,8 @@ root(isDark)
|
|||||||
flex 1
|
flex 1
|
||||||
min-width 0
|
min-width 0
|
||||||
|
|
||||||
> header
|
> .header
|
||||||
display flex
|
|
||||||
align-items baseline
|
|
||||||
margin-bottom 4px
|
margin-bottom 4px
|
||||||
white-space nowrap
|
|
||||||
|
|
||||||
> .name
|
|
||||||
display block
|
|
||||||
margin 0 .5em 0 0
|
|
||||||
padding 0
|
|
||||||
overflow hidden
|
|
||||||
color isDark ? #fff : #627079
|
|
||||||
font-size 1em
|
|
||||||
font-weight bold
|
|
||||||
text-decoration none
|
|
||||||
text-overflow ellipsis
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
text-decoration underline
|
|
||||||
|
|
||||||
> .is-admin
|
|
||||||
> .is-bot
|
|
||||||
> .is-cat
|
|
||||||
align-self center
|
|
||||||
margin 0 .5em 0 0
|
|
||||||
padding 1px 6px
|
|
||||||
font-size 12px
|
|
||||||
color isDark ? #758188 : #aaa
|
|
||||||
border solid 1px isDark ? #57616f : #ddd
|
|
||||||
border-radius 3px
|
|
||||||
|
|
||||||
&.is-admin
|
|
||||||
border-color isDark ? #d42c41 : #f56a7b
|
|
||||||
color isDark ? #d42c41 : #f56a7b
|
|
||||||
|
|
||||||
> .username
|
|
||||||
margin 0 .5em 0 0
|
|
||||||
overflow hidden
|
|
||||||
text-overflow ellipsis
|
|
||||||
color isDark ? #606984 : #ccc
|
|
||||||
|
|
||||||
> .info
|
|
||||||
margin-left auto
|
|
||||||
font-size 0.9em
|
|
||||||
|
|
||||||
> *
|
|
||||||
color isDark ? #606984 : #c0c0c0
|
|
||||||
|
|
||||||
> .mobile
|
|
||||||
margin-right 8px
|
|
||||||
|
|
||||||
> .app
|
|
||||||
margin-right 8px
|
|
||||||
padding-right 8px
|
|
||||||
border-right solid 1px isDark ? #1c2023 : #eaeaea
|
|
||||||
|
|
||||||
> .visibility
|
|
||||||
margin-left 8px
|
|
||||||
|
|
||||||
> .body
|
> .body
|
||||||
|
|
||||||
|
@ -206,7 +206,7 @@ root(isDark)
|
|||||||
margin 0
|
margin 0
|
||||||
padding 16px
|
padding 16px
|
||||||
overflow-wrap break-word
|
overflow-wrap break-word
|
||||||
font-size 12px
|
font-size 13px
|
||||||
border-bottom solid 1px isDark ? #1c2023 : rgba(#000, 0.05)
|
border-bottom solid 1px isDark ? #1c2023 : rgba(#000, 0.05)
|
||||||
|
|
||||||
&:last-child
|
&:last-child
|
||||||
|
@ -50,6 +50,7 @@ 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 '../../../../../text/parse';
|
||||||
|
import { host } from '../../../config';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
components: {
|
components: {
|
||||||
@ -57,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 {
|
||||||
@ -117,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} `;
|
||||||
}
|
}
|
||||||
@ -129,6 +152,7 @@ export default Vue.extend({
|
|||||||
|
|
||||||
// 自分は除外
|
// 自分は除外
|
||||||
if (this.$store.state.i.username == x.username && x.host == null) return;
|
if (this.$store.state.i.username == x.username && x.host == null) return;
|
||||||
|
if (this.$store.state.i.username == x.username && x.host == host) return;
|
||||||
|
|
||||||
// 重複は除外
|
// 重複は除外
|
||||||
if (this.text.indexOf(`${mention} `) != -1) return;
|
if (this.text.indexOf(`${mention} `) != -1) return;
|
||||||
@ -139,6 +163,7 @@ export default Vue.extend({
|
|||||||
|
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
// 書きかけの投稿を復元
|
// 書きかけの投稿を復元
|
||||||
|
if (!this.instant) {
|
||||||
const draft = JSON.parse(localStorage.getItem('drafts') || '{}')[this.draftId];
|
const draft = JSON.parse(localStorage.getItem('drafts') || '{}')[this.draftId];
|
||||||
if (draft) {
|
if (draft) {
|
||||||
this.text = draft.data.text;
|
this.text = draft.data.text;
|
||||||
@ -151,6 +176,7 @@ export default Vue.extend({
|
|||||||
}
|
}
|
||||||
this.$emit('change-attached-media', this.files);
|
this.$emit('change-attached-media', this.files);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.$nextTick(() => this.watch());
|
this.$nextTick(() => this.watch());
|
||||||
});
|
});
|
||||||
@ -347,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] = {
|
||||||
|
@ -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;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -17,7 +17,11 @@ export default Vue.extend({
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
onSubmit() {
|
onSubmit() {
|
||||||
location.href = `/search?q=${encodeURIComponent(this.q)}`;
|
if (this.q.startsWith('#')) {
|
||||||
|
this.$router.push(`/tags/${encodeURIComponent(this.q.substr(1))}`);
|
||||||
|
} else {
|
||||||
|
this.$router.push(`/search?q=${encodeURIComponent(this.q)}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="mk-ui" :style="style">
|
<div class="mk-ui" :style="style">
|
||||||
<x-header class="header"/>
|
<x-header class="header" v-show="!zenMode"/>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</div>
|
</div>
|
||||||
@ -16,6 +16,11 @@ export default Vue.extend({
|
|||||||
components: {
|
components: {
|
||||||
XHeader
|
XHeader
|
||||||
},
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
zenMode: false
|
||||||
|
};
|
||||||
|
},
|
||||||
computed: {
|
computed: {
|
||||||
style(): any {
|
style(): any {
|
||||||
if (!this.$store.getters.isSignedIn || this.$store.state.i.wallpaperUrl == null) return {};
|
if (!this.$store.getters.isSignedIn || this.$store.state.i.wallpaperUrl == null) return {};
|
||||||
@ -39,6 +44,11 @@ export default Vue.extend({
|
|||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
(this as any).apis.post();
|
(this as any).apis.post();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (e.which == 90) { // z
|
||||||
|
e.preventDefault();
|
||||||
|
this.zenMode = !this.zenMode;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
35
src/client/app/desktop/views/pages/deck/deck.column-core.vue
Normal file
35
src/client/app/desktop/views/pages/deck/deck.column-core.vue
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<template>
|
||||||
|
<x-widgets-column v-if="column.type == 'widgets'" :column="column" :is-stacked="isStacked"/>
|
||||||
|
<x-notifications-column v-else-if="column.type == 'notifications'" :column="column" :is-stacked="isStacked"/>
|
||||||
|
<x-tl-column v-else-if="column.type == 'home'" :column="column" :is-stacked="isStacked"/>
|
||||||
|
<x-tl-column v-else-if="column.type == 'local'" :column="column" :is-stacked="isStacked"/>
|
||||||
|
<x-tl-column v-else-if="column.type == 'global'" :column="column" :is-stacked="isStacked"/>
|
||||||
|
<x-tl-column v-else-if="column.type == 'list'" :column="column" :is-stacked="isStacked"/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import Vue from 'vue';
|
||||||
|
import XTlColumn from './deck.tl-column.vue';
|
||||||
|
import XNotificationsColumn from './deck.notifications-column.vue';
|
||||||
|
import XWidgetsColumn from './deck.widgets-column.vue';
|
||||||
|
|
||||||
|
export default Vue.extend({
|
||||||
|
components: {
|
||||||
|
XTlColumn,
|
||||||
|
XNotificationsColumn,
|
||||||
|
XWidgetsColumn
|
||||||
|
},
|
||||||
|
|
||||||
|
props: {
|
||||||
|
column: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
isStacked: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
@ -1,10 +1,22 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="dnpfarvgbnfmyzbdquhhzyxcmstpdqzs" :class="{ naked, narrow }">
|
<div class="dnpfarvgbnfmyzbdquhhzyxcmstpdqzs" :class="{ naked, narrow, active, isStacked, draghover, dragging, dropready }"
|
||||||
<header :class="{ indicate }">
|
@dragover.prevent.stop="onDragover"
|
||||||
|
@dragenter.prevent="onDragenter"
|
||||||
|
@dragleave="onDragleave"
|
||||||
|
@drop.prevent.stop="onDrop"
|
||||||
|
>
|
||||||
|
<header :class="{ indicate: count > 0 }"
|
||||||
|
draggable="true"
|
||||||
|
@click="toggleActive"
|
||||||
|
@dragstart="onDragstart"
|
||||||
|
@dragend="onDragend"
|
||||||
|
@contextmenu.prevent.stop="onContextmenu"
|
||||||
|
>
|
||||||
<slot name="header"></slot>
|
<slot name="header"></slot>
|
||||||
<button ref="menu" @click="showMenu">%fa:caret-down%</button>
|
<span class="count" v-if="count > 0">({{ count }})</span>
|
||||||
|
<button ref="menu" @click.stop="showMenu">%fa:caret-down%</button>
|
||||||
</header>
|
</header>
|
||||||
<div ref="body">
|
<div ref="body" v-show="active">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -13,12 +25,17 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import Menu from '../../../../common/views/components/menu.vue';
|
import Menu from '../../../../common/views/components/menu.vue';
|
||||||
|
import contextmenu from '../../../api/contextmenu';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
props: {
|
props: {
|
||||||
id: {
|
column: {
|
||||||
type: String,
|
type: Object,
|
||||||
required: false
|
required: true
|
||||||
|
},
|
||||||
|
isStacked: {
|
||||||
|
type: Boolean,
|
||||||
|
required: true
|
||||||
},
|
},
|
||||||
name: {
|
name: {
|
||||||
type: String,
|
type: String,
|
||||||
@ -26,7 +43,8 @@ export default Vue.extend({
|
|||||||
},
|
},
|
||||||
menu: {
|
menu: {
|
||||||
type: Array,
|
type: Array,
|
||||||
required: false
|
required: false,
|
||||||
|
default: null
|
||||||
},
|
},
|
||||||
naked: {
|
naked: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
@ -40,30 +58,69 @@ export default Vue.extend({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
inject: {
|
||||||
|
getColumnVm: { from: 'getColumnVm' }
|
||||||
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
indicate: false
|
count: 0,
|
||||||
|
active: true,
|
||||||
|
dragging: false,
|
||||||
|
draghover: false,
|
||||||
|
dropready: false
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
active(v) {
|
||||||
|
if (v && this.isScrollTop()) {
|
||||||
|
this.$emit('top');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dragging(v) {
|
||||||
|
this.$root.$emit(v ? 'deck.column.dragStart' : 'deck.column.dragEnd');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
provide() {
|
provide() {
|
||||||
return {
|
return {
|
||||||
column: this,
|
column: this,
|
||||||
isScrollTop: this.isScrollTop,
|
isScrollTop: this.isScrollTop,
|
||||||
indicate: v => this.indicate = v
|
count: v => this.count = v
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
this.$refs.body.addEventListener('scroll', this.onScroll, { passive: true });
|
this.$refs.body.addEventListener('scroll', this.onScroll, { passive: true });
|
||||||
|
this.$root.$on('deck.column.dragStart', this.onOtherDragStart);
|
||||||
|
this.$root.$on('deck.column.dragEnd', this.onOtherDragEnd);
|
||||||
},
|
},
|
||||||
|
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
this.$refs.body.removeEventListener('scroll', this.onScroll);
|
this.$refs.body.removeEventListener('scroll', this.onScroll);
|
||||||
|
this.$root.$off('deck.column.dragStart', this.onOtherDragStart);
|
||||||
|
this.$root.$off('deck.column.dragEnd', this.onOtherDragEnd);
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
onOtherDragStart() {
|
||||||
|
this.dropready = true;
|
||||||
|
},
|
||||||
|
|
||||||
|
onOtherDragEnd() {
|
||||||
|
this.dropready = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
toggleActive() {
|
||||||
|
if (!this.isStacked) return;
|
||||||
|
const vms = this.$store.state.settings.deck.layout.find(ids => ids.indexOf(this.column.id) != -1).map(id => this.getColumnVm(id));
|
||||||
|
if (this.active && vms.filter(vm => vm.$el.classList.contains('active')).length == 1) return;
|
||||||
|
this.active = !this.active;
|
||||||
|
},
|
||||||
|
|
||||||
isScrollTop() {
|
isScrollTop() {
|
||||||
return this.$refs.body.scrollTop == 0;
|
return this.active && this.$refs.body.scrollTop == 0;
|
||||||
},
|
},
|
||||||
|
|
||||||
onScroll() {
|
onScroll() {
|
||||||
@ -77,32 +134,60 @@ export default Vue.extend({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
showMenu() {
|
getMenu() {
|
||||||
const items = [{
|
const items = [{
|
||||||
content: '%fa:pencil-alt% %i18n:common.deck.rename%',
|
icon: '%fa:pencil-alt%',
|
||||||
onClick: () => {
|
text: '%i18n:common.deck.rename%',
|
||||||
|
action: () => {
|
||||||
(this as any).apis.input({
|
(this as any).apis.input({
|
||||||
title: '%i18n:common.deck.rename%',
|
title: '%i18n:common.deck.rename%',
|
||||||
default: this.name,
|
default: this.name,
|
||||||
allowEmpty: false
|
allowEmpty: false
|
||||||
}).then(name => {
|
}).then(name => {
|
||||||
this.$store.dispatch('settings/renameDeckColumn', { id: this.id, name });
|
this.$store.dispatch('settings/renameDeckColumn', { id: this.column.id, name });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, null, {
|
}, null, {
|
||||||
content: '%fa:arrow-left% %i18n:common.deck.swap-left%',
|
icon: '%fa:arrow-left%',
|
||||||
onClick: () => {
|
text: '%i18n:common.deck.swap-left%',
|
||||||
this.$store.dispatch('settings/swapLeftDeckColumn', this.id);
|
action: () => {
|
||||||
|
this.$store.dispatch('settings/swapLeftDeckColumn', this.column.id);
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
content: '%fa:arrow-right% %i18n:common.deck.swap-right%',
|
icon: '%fa:arrow-right%',
|
||||||
onClick: () => {
|
text: '%i18n:common.deck.swap-right%',
|
||||||
this.$store.dispatch('settings/swapRightDeckColumn', this.id);
|
action: () => {
|
||||||
|
this.$store.dispatch('settings/swapRightDeckColumn', this.column.id);
|
||||||
}
|
}
|
||||||
}, null, {
|
}, this.isStacked ? {
|
||||||
content: '%fa:trash-alt R% %i18n:common.deck.remove%',
|
icon: '%fa:arrow-up%',
|
||||||
onClick: () => {
|
text: '%i18n:common.deck.swap-up%',
|
||||||
this.$store.dispatch('settings/removeDeckColumn', this.id);
|
action: () => {
|
||||||
|
this.$store.dispatch('settings/swapUpDeckColumn', this.column.id);
|
||||||
|
}
|
||||||
|
} : undefined, this.isStacked ? {
|
||||||
|
icon: '%fa:arrow-down%',
|
||||||
|
text: '%i18n:common.deck.swap-down%',
|
||||||
|
action: () => {
|
||||||
|
this.$store.dispatch('settings/swapDownDeckColumn', this.column.id);
|
||||||
|
}
|
||||||
|
} : undefined, null, {
|
||||||
|
icon: '%fa:window-restore R%',
|
||||||
|
text: '%i18n:common.deck.stack-left%',
|
||||||
|
action: () => {
|
||||||
|
this.$store.dispatch('settings/stackLeftDeckColumn', this.column.id);
|
||||||
|
}
|
||||||
|
}, this.isStacked ? {
|
||||||
|
icon: '%fa:window-maximize R%',
|
||||||
|
text: '%i18n:common.deck.pop-right%',
|
||||||
|
action: () => {
|
||||||
|
this.$store.dispatch('settings/popRightDeckColumn', this.column.id);
|
||||||
|
}
|
||||||
|
} : undefined, null, {
|
||||||
|
icon: '%fa:trash-alt R%',
|
||||||
|
text: '%i18n:common.deck.remove%',
|
||||||
|
action: () => {
|
||||||
|
this.$store.dispatch('settings/removeDeckColumn', this.column.id);
|
||||||
}
|
}
|
||||||
}];
|
}];
|
||||||
|
|
||||||
@ -111,11 +196,63 @@ export default Vue.extend({
|
|||||||
this.menu.reverse().forEach(i => items.unshift(i));
|
this.menu.reverse().forEach(i => items.unshift(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return items;
|
||||||
|
},
|
||||||
|
|
||||||
|
onContextmenu(e) {
|
||||||
|
contextmenu((this as any).os)(e, this.getMenu());
|
||||||
|
},
|
||||||
|
|
||||||
|
showMenu() {
|
||||||
this.os.new(Menu, {
|
this.os.new(Menu, {
|
||||||
source: this.$refs.menu,
|
source: this.$refs.menu,
|
||||||
compact: false,
|
compact: false,
|
||||||
items
|
items: this.getMenu()
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
onDragstart(e) {
|
||||||
|
e.dataTransfer.effectAllowed = 'move';
|
||||||
|
e.dataTransfer.setData('mk-deck-column', this.column.id);
|
||||||
|
this.dragging = true;
|
||||||
|
},
|
||||||
|
|
||||||
|
onDragend(e) {
|
||||||
|
this.dragging = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
onDragover(e) {
|
||||||
|
// 自分自身がドラッグされている場合
|
||||||
|
if (this.dragging) {
|
||||||
|
// 自分自身にはドロップさせない
|
||||||
|
e.dataTransfer.dropEffect = 'none';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const isDeckColumn = e.dataTransfer.types[0] == 'mk-deck-column';
|
||||||
|
|
||||||
|
e.dataTransfer.dropEffect = isDeckColumn ? 'move' : 'none';
|
||||||
|
},
|
||||||
|
|
||||||
|
onDragenter() {
|
||||||
|
if (!this.dragging) this.draghover = true;
|
||||||
|
},
|
||||||
|
|
||||||
|
onDragleave() {
|
||||||
|
this.draghover = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
onDrop(e) {
|
||||||
|
this.draghover = false;
|
||||||
|
this.$root.$emit('deck.column.dragEnd');
|
||||||
|
|
||||||
|
const id = e.dataTransfer.getData('mk-deck-column');
|
||||||
|
if (id != null && id != '') {
|
||||||
|
this.$store.dispatch('settings/swapDeckColumn', {
|
||||||
|
a: this.column.id,
|
||||||
|
b: id
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -128,14 +265,30 @@ root(isDark)
|
|||||||
$header-height = 42px
|
$header-height = 42px
|
||||||
|
|
||||||
width 330px
|
width 330px
|
||||||
|
min-width 330px
|
||||||
height 100%
|
height 100%
|
||||||
background isDark ? #282C37 : #fff
|
background isDark ? #282C37 : #fff
|
||||||
border-radius 6px
|
border-radius 6px
|
||||||
box-shadow 0 2px 16px rgba(#000, 0.1)
|
box-shadow 0 2px 16px rgba(#000, 0.1)
|
||||||
overflow hidden
|
overflow hidden
|
||||||
|
|
||||||
&.narrow
|
&.draghover
|
||||||
|
box-shadow 0 0 0 2px rgba($theme-color, 0.8)
|
||||||
|
|
||||||
|
&.dragging
|
||||||
|
box-shadow 0 0 0 2px rgba($theme-color, 0.4)
|
||||||
|
|
||||||
|
&.dropready
|
||||||
|
*
|
||||||
|
pointer-events none
|
||||||
|
|
||||||
|
&:not(.active)
|
||||||
|
flex-basis $header-height
|
||||||
|
min-height $header-height
|
||||||
|
|
||||||
|
&:not(.isStacked).narrow
|
||||||
width 285px
|
width 285px
|
||||||
|
min-width 285px
|
||||||
|
|
||||||
&.naked
|
&.naked
|
||||||
background rgba(#000, isDark ? 0.25 : 0.1)
|
background rgba(#000, isDark ? 0.25 : 0.1)
|
||||||
@ -156,6 +309,13 @@ root(isDark)
|
|||||||
color isDark ? #e3e5e8 : #888
|
color isDark ? #e3e5e8 : #888
|
||||||
background isDark ? #313543 : #fff
|
background isDark ? #313543 : #fff
|
||||||
box-shadow 0 1px rgba(#000, 0.15)
|
box-shadow 0 1px rgba(#000, 0.15)
|
||||||
|
cursor pointer
|
||||||
|
|
||||||
|
&, *
|
||||||
|
user-select none
|
||||||
|
|
||||||
|
*:not(button)
|
||||||
|
pointer-events none
|
||||||
|
|
||||||
&.indicate
|
&.indicate
|
||||||
box-shadow 0 3px 0 0 $theme-color
|
box-shadow 0 3px 0 0 $theme-color
|
||||||
@ -164,12 +324,17 @@ root(isDark)
|
|||||||
[data-fa]
|
[data-fa]
|
||||||
margin-right 8px
|
margin-right 8px
|
||||||
|
|
||||||
|
> .count
|
||||||
|
margin-left 4px
|
||||||
|
opacity 0.5
|
||||||
|
|
||||||
> button
|
> button
|
||||||
position absolute
|
position absolute
|
||||||
top 0
|
top 0
|
||||||
right 0
|
right 0
|
||||||
width $header-height
|
width $header-height
|
||||||
line-height $header-height
|
line-height $header-height
|
||||||
|
font-size 16px
|
||||||
color isDark ? #9baec8 : #ccc
|
color isDark ? #9baec8 : #ccc
|
||||||
|
|
||||||
&:hover
|
&:hover
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<x-notes ref="timeline" :more="existMore ? more : null"/>
|
<x-notes ref="timeline" :more="existMore ? more : null" :media-view="mediaView"/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
@ -23,6 +23,11 @@ export default Vue.extend({
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: false,
|
required: false,
|
||||||
default: false
|
default: false
|
||||||
|
},
|
||||||
|
mediaView: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -2,25 +2,7 @@
|
|||||||
<div class="fnlfosztlhtptnongximhlbykxblytcq">
|
<div class="fnlfosztlhtptnongximhlbykxblytcq">
|
||||||
<mk-avatar class="avatar" :user="note.user"/>
|
<mk-avatar class="avatar" :user="note.user"/>
|
||||||
<div class="main">
|
<div class="main">
|
||||||
<header>
|
<mk-note-header class="header" :note="note" :mini="true"/>
|
||||||
<router-link class="name" :to="note.user | userPage">{{ note.user | userName }}</router-link>
|
|
||||||
<span class="is-admin" v-if="note.user.isAdmin">%i18n:@admin%</span>
|
|
||||||
<span class="is-bot" v-if="note.user.isBot">%i18n:@bot%</span>
|
|
||||||
<span class="is-cat" v-if="note.user.isCat">%i18n:@cat%</span>
|
|
||||||
<span class="username"><mk-acct :user="note.user"/></span>
|
|
||||||
<div class="info">
|
|
||||||
<span class="mobile" v-if="note.viaMobile">%fa:mobile-alt%</span>
|
|
||||||
<router-link class="created-at" :to="note | notePage">
|
|
||||||
<mk-time :time="note.createdAt"/>
|
|
||||||
</router-link>
|
|
||||||
<span class="visibility" v-if="note.visibility != 'public'">
|
|
||||||
<template v-if="note.visibility == 'home'">%fa:home%</template>
|
|
||||||
<template v-if="note.visibility == 'followers'">%fa:unlock%</template>
|
|
||||||
<template v-if="note.visibility == 'specified'">%fa:envelope%</template>
|
|
||||||
<template v-if="note.visibility == 'private'">%fa:lock%</template>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
<div class="body">
|
<div class="body">
|
||||||
<mk-sub-note-content class="text" :note="note"/>
|
<mk-sub-note-content class="text" :note="note"/>
|
||||||
</div>
|
</div>
|
||||||
@ -72,66 +54,8 @@ root(isDark)
|
|||||||
flex 1
|
flex 1
|
||||||
min-width 0
|
min-width 0
|
||||||
|
|
||||||
> header
|
> .header
|
||||||
display flex
|
|
||||||
align-items baseline
|
|
||||||
margin-bottom 2px
|
margin-bottom 2px
|
||||||
white-space nowrap
|
|
||||||
|
|
||||||
> .avatar
|
|
||||||
flex-shrink 0
|
|
||||||
margin-right 8px
|
|
||||||
width 18px
|
|
||||||
height 18px
|
|
||||||
border-radius 100%
|
|
||||||
|
|
||||||
> .name
|
|
||||||
display block
|
|
||||||
margin 0 0.5em 0 0
|
|
||||||
padding 0
|
|
||||||
overflow hidden
|
|
||||||
color isDark ? #fff : #607073
|
|
||||||
font-size 1em
|
|
||||||
font-weight 700
|
|
||||||
text-align left
|
|
||||||
text-decoration none
|
|
||||||
text-overflow ellipsis
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
text-decoration underline
|
|
||||||
|
|
||||||
> .is-admin
|
|
||||||
> .is-bot
|
|
||||||
> .is-cat
|
|
||||||
align-self center
|
|
||||||
margin 0 0.5em 0 0
|
|
||||||
padding 1px 5px
|
|
||||||
font-size 0.8em
|
|
||||||
color isDark ? #758188 : #aaa
|
|
||||||
border solid 1px isDark ? #57616f : #ddd
|
|
||||||
border-radius 3px
|
|
||||||
|
|
||||||
&.is-admin
|
|
||||||
border-color isDark ? #d42c41 : #f56a7b
|
|
||||||
color isDark ? #d42c41 : #f56a7b
|
|
||||||
|
|
||||||
> .username
|
|
||||||
text-align left
|
|
||||||
margin 0
|
|
||||||
color isDark ? #606984 : #d1d8da
|
|
||||||
|
|
||||||
> .info
|
|
||||||
margin-left auto
|
|
||||||
font-size 0.9em
|
|
||||||
|
|
||||||
> *
|
|
||||||
color isDark ? #606984 : #b2b8bb
|
|
||||||
|
|
||||||
> .mobile
|
|
||||||
margin-right 6px
|
|
||||||
|
|
||||||
> .visibility
|
|
||||||
margin-left 6px
|
|
||||||
|
|
||||||
> .body
|
> .body
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="zyjjkidcqjnlegkqebitfviomuqmseqk" :class="{ renote: isRenote }">
|
<div v-if="!mediaView" class="zyjjkidcqjnlegkqebitfviomuqmseqk" :class="{ renote: isRenote }">
|
||||||
<div class="reply-to" v-if="p.reply && (!$store.getters.isSignedIn || $store.state.settings.showReplyTarget)">
|
<div class="reply-to" v-if="p.reply && (!$store.getters.isSignedIn || $store.state.settings.showReplyTarget)">
|
||||||
<x-sub :note="p.reply"/>
|
<x-sub :note="p.reply"/>
|
||||||
</div>
|
</div>
|
||||||
@ -14,25 +14,7 @@
|
|||||||
<article>
|
<article>
|
||||||
<mk-avatar class="avatar" :user="p.user"/>
|
<mk-avatar class="avatar" :user="p.user"/>
|
||||||
<div class="main">
|
<div class="main">
|
||||||
<header>
|
<mk-note-header class="header" :note="p" :mini="true"/>
|
||||||
<router-link class="name" :to="p.user | userPage">{{ p.user | userName }}</router-link>
|
|
||||||
<span class="is-admin" v-if="p.user.isAdmin">admin</span>
|
|
||||||
<span class="is-bot" v-if="p.user.isBot">bot</span>
|
|
||||||
<span class="is-cat" v-if="p.user.isCat">cat</span>
|
|
||||||
<span class="username"><mk-acct :user="p.user"/></span>
|
|
||||||
<div class="info">
|
|
||||||
<span class="mobile" v-if="p.viaMobile">%fa:mobile-alt%</span>
|
|
||||||
<router-link class="created-at" :to="p | notePage">
|
|
||||||
<mk-time :time="p.createdAt"/>
|
|
||||||
</router-link>
|
|
||||||
<span class="visibility" v-if="p.visibility != 'public'">
|
|
||||||
<template v-if="p.visibility == 'home'">%fa:home%</template>
|
|
||||||
<template v-if="p.visibility == 'followers'">%fa:unlock%</template>
|
|
||||||
<template v-if="p.visibility == 'specified'">%fa:envelope%</template>
|
|
||||||
<template v-if="p.visibility == 'private'">%fa:lock%</template>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
<div class="body">
|
<div class="body">
|
||||||
<p v-if="p.cw != null" class="cw">
|
<p v-if="p.cw != null" class="cw">
|
||||||
<span class="text" v-if="p.cw != ''">{{ p.cw }}</span>
|
<span class="text" v-if="p.cw != ''">{{ p.cw }}</span>
|
||||||
@ -51,11 +33,11 @@
|
|||||||
</div>
|
</div>
|
||||||
<mk-poll v-if="p.poll" :note="p" ref="pollViewer"/>
|
<mk-poll v-if="p.poll" :note="p" ref="pollViewer"/>
|
||||||
<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="`/search?q=#${tag}`">{{ tag }}</router-link>
|
<router-link v-for="tag in p.tags" :key="tag" :to="`/tags/${tag}`">{{ tag }}</router-link>
|
||||||
</div>
|
</div>
|
||||||
<a class="location" v-if="p.geo" :href="`http://maps.google.com/maps?q=${p.geo.coordinates[1]},${p.geo.coordinates[0]}`" target="_blank">%fa:map-marker-alt% %i18n:@location%</a>
|
<a class="location" v-if="p.geo" :href="`http://maps.google.com/maps?q=${p.geo.coordinates[1]},${p.geo.coordinates[0]}`" target="_blank">%fa:map-marker-alt% %i18n:@location%</a>
|
||||||
<div class="renote" v-if="p.renote">
|
<div class="renote" v-if="p.renote">
|
||||||
<mk-note-preview :note="p.renote"/>
|
<mk-note-preview :note="p.renote" :mini="true"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<span class="app" v-if="p.app">via <b>{{ p.app.name }}</b></span>
|
<span class="app" v-if="p.app">via <b>{{ p.app.name }}</b></span>
|
||||||
@ -73,6 +55,14 @@
|
|||||||
</div>
|
</div>
|
||||||
</article>
|
</article>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-else class="srwrkujossgfuhrbnvqkybtzxpblgchi">
|
||||||
|
<div v-if="note.media.length > 0">
|
||||||
|
<mk-media-list :media-list="note.media"/>
|
||||||
|
</div>
|
||||||
|
<div v-if="note.renote && note.renote.media.length > 0">
|
||||||
|
<mk-media-list :media-list="note.renote.media"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
@ -89,7 +79,17 @@ export default Vue.extend({
|
|||||||
XSub
|
XSub
|
||||||
},
|
},
|
||||||
|
|
||||||
props: ['note'],
|
props: {
|
||||||
|
note: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
mediaView: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@ -217,8 +217,18 @@ export default Vue.extend({
|
|||||||
<style lang="stylus" scoped>
|
<style lang="stylus" scoped>
|
||||||
@import '~const.styl'
|
@import '~const.styl'
|
||||||
|
|
||||||
|
mediaRoot(isDark)
|
||||||
|
font-size 13px
|
||||||
|
margin 4px 12px
|
||||||
|
|
||||||
|
&:first-child
|
||||||
|
margin-top 12px
|
||||||
|
|
||||||
|
&:last-child
|
||||||
|
margin-bottom 12px
|
||||||
|
|
||||||
root(isDark)
|
root(isDark)
|
||||||
font-size 12px
|
font-size 13px
|
||||||
border-bottom solid 1px isDark ? #1c2023 : #eaeaea
|
border-bottom solid 1px isDark ? #1c2023 : #eaeaea
|
||||||
|
|
||||||
&:last-of-type
|
&:last-of-type
|
||||||
@ -234,7 +244,7 @@ root(isDark)
|
|||||||
> .renote
|
> .renote
|
||||||
display flex
|
display flex
|
||||||
align-items center
|
align-items center
|
||||||
padding 8px 16px
|
padding 8px 16px 0 16px
|
||||||
line-height 28px
|
line-height 28px
|
||||||
white-space pre
|
white-space pre
|
||||||
color #9dbb00
|
color #9dbb00
|
||||||
@ -275,7 +285,7 @@ root(isDark)
|
|||||||
|
|
||||||
> article
|
> article
|
||||||
display flex
|
display flex
|
||||||
padding 16px 16px 9px
|
padding 16px 16px 4px
|
||||||
|
|
||||||
> .avatar
|
> .avatar
|
||||||
flex-shrink 0
|
flex-shrink 0
|
||||||
@ -292,62 +302,6 @@ root(isDark)
|
|||||||
flex 1
|
flex 1
|
||||||
min-width 0
|
min-width 0
|
||||||
|
|
||||||
> header
|
|
||||||
display flex
|
|
||||||
align-items baseline
|
|
||||||
white-space nowrap
|
|
||||||
|
|
||||||
> .avatar
|
|
||||||
flex-shrink 0
|
|
||||||
margin-right 8px
|
|
||||||
width 20px
|
|
||||||
height 20px
|
|
||||||
border-radius 100%
|
|
||||||
|
|
||||||
> .name
|
|
||||||
display block
|
|
||||||
margin 0 0.5em 0 0
|
|
||||||
padding 0
|
|
||||||
overflow hidden
|
|
||||||
color isDark ? #fff : #627079
|
|
||||||
font-weight bold
|
|
||||||
text-decoration none
|
|
||||||
text-overflow ellipsis
|
|
||||||
|
|
||||||
> .is-admin
|
|
||||||
> .is-bot
|
|
||||||
> .is-cat
|
|
||||||
align-self center
|
|
||||||
margin 0 0.5em 0 0
|
|
||||||
padding 1px 6px
|
|
||||||
font-size 0.8em
|
|
||||||
color isDark ? #758188 : #aaa
|
|
||||||
border solid 1px isDark ? #57616f : #ddd
|
|
||||||
border-radius 3px
|
|
||||||
|
|
||||||
&.is-admin
|
|
||||||
border-color isDark ? #d42c41 : #f56a7b
|
|
||||||
color isDark ? #d42c41 : #f56a7b
|
|
||||||
|
|
||||||
> .username
|
|
||||||
margin 0 0.5em 0 0
|
|
||||||
overflow hidden
|
|
||||||
text-overflow ellipsis
|
|
||||||
color isDark ? #606984 : #ccc
|
|
||||||
|
|
||||||
> .info
|
|
||||||
margin-left auto
|
|
||||||
font-size 0.9em
|
|
||||||
|
|
||||||
> *
|
|
||||||
color isDark ? #606984 : #c0c0c0
|
|
||||||
|
|
||||||
> .mobile
|
|
||||||
margin-right 6px
|
|
||||||
|
|
||||||
> .visibility
|
|
||||||
margin-left 6px
|
|
||||||
|
|
||||||
> .body
|
> .body
|
||||||
|
|
||||||
> .cw
|
> .cw
|
||||||
@ -482,7 +436,7 @@ root(isDark)
|
|||||||
> footer
|
> footer
|
||||||
> button
|
> button
|
||||||
margin 0
|
margin 0
|
||||||
padding 8px
|
padding 4px 8px 8px 8px
|
||||||
background transparent
|
background transparent
|
||||||
border none
|
border none
|
||||||
box-shadow none
|
box-shadow none
|
||||||
@ -510,4 +464,10 @@ root(isDark)
|
|||||||
.zyjjkidcqjnlegkqebitfviomuqmseqk:not([data-darkmode])
|
.zyjjkidcqjnlegkqebitfviomuqmseqk:not([data-darkmode])
|
||||||
root(false)
|
root(false)
|
||||||
|
|
||||||
|
.srwrkujossgfuhrbnvqkybtzxpblgchi[data-darkmode]
|
||||||
|
mediaRoot(true)
|
||||||
|
|
||||||
|
.srwrkujossgfuhrbnvqkybtzxpblgchi:not([data-darkmode])
|
||||||
|
mediaRoot(false)
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
<transition-group name="mk-notes" class="transition">
|
<transition-group name="mk-notes" class="transition">
|
||||||
<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)" :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">
|
||||||
<span>%fa:angle-up%{{ note._datetext }}</span>
|
<span>%fa:angle-up%{{ note._datetext }}</span>
|
||||||
<span>%fa:angle-down%{{ _notes[i + 1]._datetext }}</span>
|
<span>%fa:angle-down%{{ _notes[i + 1]._datetext }}</span>
|
||||||
@ -28,24 +28,27 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import { url } from '../../../config';
|
|
||||||
import getNoteSummary from '../../../../../renderers/get-note-summary';
|
|
||||||
|
|
||||||
import XNote from './deck.note.vue';
|
import XNote from './deck.note.vue';
|
||||||
|
|
||||||
const displayLimit = 30;
|
const displayLimit = 20;
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
components: {
|
components: {
|
||||||
XNote
|
XNote
|
||||||
},
|
},
|
||||||
|
|
||||||
inject: ['column', 'isScrollTop', 'indicate'],
|
inject: ['column', 'isScrollTop', 'count'],
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
more: {
|
more: {
|
||||||
type: Function,
|
type: Function,
|
||||||
required: false
|
required: false
|
||||||
|
},
|
||||||
|
mediaView: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -55,7 +58,6 @@ export default Vue.extend({
|
|||||||
requestInitPromise: null as () => Promise<any[]>,
|
requestInitPromise: null as () => Promise<any[]>,
|
||||||
notes: [],
|
notes: [],
|
||||||
queue: [],
|
queue: [],
|
||||||
unreadCount: 0,
|
|
||||||
fetching: true,
|
fetching: true,
|
||||||
moreFetching: false
|
moreFetching: false
|
||||||
};
|
};
|
||||||
@ -73,6 +75,12 @@ export default Vue.extend({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
queue(q) {
|
||||||
|
this.count(q.length);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
created() {
|
created() {
|
||||||
this.column.$on('top', this.onTop);
|
this.column.$on('top', this.onTop);
|
||||||
this.column.$on('bottom', this.onBottom);
|
this.column.$on('bottom', this.onBottom);
|
||||||
@ -141,7 +149,6 @@ export default Vue.extend({
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.queue.push(note);
|
this.queue.push(note);
|
||||||
this.indicate(true);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -156,7 +163,6 @@ export default Vue.extend({
|
|||||||
releaseQueue() {
|
releaseQueue() {
|
||||||
this.queue.forEach(n => this.prepend(n, true));
|
this.queue.forEach(n => this.prepend(n, true));
|
||||||
this.queue = [];
|
this.queue = [];
|
||||||
this.indicate(false);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
async loadMore() {
|
async loadMore() {
|
||||||
|
@ -112,7 +112,7 @@ export default Vue.extend({
|
|||||||
root(isDark)
|
root(isDark)
|
||||||
> .notification
|
> .notification
|
||||||
padding 16px
|
padding 16px
|
||||||
font-size 12px
|
font-size 13px
|
||||||
overflow-wrap break-word
|
overflow-wrap break-word
|
||||||
|
|
||||||
&:after
|
&:after
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<x-column :name="name" :column="column" :is-stacked="isStacked">
|
||||||
<x-column :id="column.id" :name="name">
|
|
||||||
<span slot="header">%fa:bell R%{{ name }}</span>
|
<span slot="header">%fa:bell R%{{ name }}</span>
|
||||||
|
|
||||||
<x-notifications/>
|
<x-notifications/>
|
||||||
</x-column>
|
</x-column>
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
@ -23,6 +21,10 @@ export default Vue.extend({
|
|||||||
column: {
|
column: {
|
||||||
type: Object,
|
type: Object,
|
||||||
required: true
|
required: true
|
||||||
|
},
|
||||||
|
isStacked: {
|
||||||
|
type: Boolean,
|
||||||
|
required: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -21,20 +21,27 @@
|
|||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import XNotification from './deck.notification.vue';
|
import XNotification from './deck.notification.vue';
|
||||||
|
|
||||||
|
const displayLimit = 20;
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
components: {
|
components: {
|
||||||
XNotification
|
XNotification
|
||||||
},
|
},
|
||||||
|
|
||||||
|
inject: ['column', 'isScrollTop', 'count'],
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
fetching: true,
|
fetching: true,
|
||||||
fetchingMoreNotifications: false,
|
fetchingMoreNotifications: false,
|
||||||
notifications: [],
|
notifications: [],
|
||||||
|
queue: [],
|
||||||
moreNotifications: false,
|
moreNotifications: false,
|
||||||
connection: null,
|
connection: null,
|
||||||
connectionId: null
|
connectionId: null
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
_notifications(): any[] {
|
_notifications(): any[] {
|
||||||
return (this.notifications as any).map(notification => {
|
return (this.notifications as any).map(notification => {
|
||||||
@ -46,12 +53,22 @@ export default Vue.extend({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
queue(q) {
|
||||||
|
this.count(q.length);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
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('notification', this.onNotification);
|
this.connection.on('notification', this.onNotification);
|
||||||
|
|
||||||
|
this.column.$on('top', this.onTop);
|
||||||
|
this.column.$on('bottom', this.onBottom);
|
||||||
|
|
||||||
const max = 10;
|
const max = 10;
|
||||||
|
|
||||||
(this as any).api('i/notifications', {
|
(this as any).api('i/notifications', {
|
||||||
@ -66,15 +83,20 @@ export default Vue.extend({
|
|||||||
this.fetching = false;
|
this.fetching = false;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
this.connection.off('notification', this.onNotification);
|
this.connection.off('notification', this.onNotification);
|
||||||
(this as any).os.stream.dispose(this.connectionId);
|
(this as any).os.stream.dispose(this.connectionId);
|
||||||
|
|
||||||
|
this.column.$off('top', this.onTop);
|
||||||
|
this.column.$off('bottom', this.onBottom);
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
fetchMoreNotifications() {
|
fetchMoreNotifications() {
|
||||||
this.fetchingMoreNotifications = true;
|
this.fetchingMoreNotifications = true;
|
||||||
|
|
||||||
const max = 30;
|
const max = 20;
|
||||||
|
|
||||||
(this as any).api('i/notifications', {
|
(this as any).api('i/notifications', {
|
||||||
limit: max + 1,
|
limit: max + 1,
|
||||||
@ -90,6 +112,7 @@ export default Vue.extend({
|
|||||||
this.fetchingMoreNotifications = false;
|
this.fetchingMoreNotifications = false;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
onNotification(notification) {
|
onNotification(notification) {
|
||||||
// TODO: ユーザーが画面を見てないと思われるとき(ブラウザやタブがアクティブじゃないなど)は送信しない
|
// TODO: ユーザーが画面を見てないと思われるとき(ブラウザやタブがアクティブじゃないなど)は送信しない
|
||||||
this.connection.send({
|
this.connection.send({
|
||||||
@ -97,7 +120,34 @@ export default Vue.extend({
|
|||||||
id: notification.id
|
id: notification.id
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.prepend(notification);
|
||||||
|
},
|
||||||
|
|
||||||
|
prepend(notification) {
|
||||||
|
if (this.isScrollTop()) {
|
||||||
|
// Prepend the notification
|
||||||
this.notifications.unshift(notification);
|
this.notifications.unshift(notification);
|
||||||
|
|
||||||
|
// オーバーフローしたら古い通知は捨てる
|
||||||
|
if (this.notifications.length >= displayLimit) {
|
||||||
|
this.notifications = this.notifications.slice(0, displayLimit);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.queue.push(notification);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
releaseQueue() {
|
||||||
|
this.queue.forEach(n => this.prepend(n));
|
||||||
|
this.queue = [];
|
||||||
|
},
|
||||||
|
|
||||||
|
onTop() {
|
||||||
|
this.releaseQueue();
|
||||||
|
},
|
||||||
|
|
||||||
|
onBottom() {
|
||||||
|
this.fetchMoreNotifications();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<x-column :menu="menu" :name="name" :column="column" :is-stacked="isStacked">
|
||||||
<x-column :id="column.id" :menu="menu" :name="name">
|
|
||||||
<span slot="header">
|
<span slot="header">
|
||||||
<template v-if="column.type == 'home'">%fa:home%</template>
|
<template v-if="column.type == 'home'">%fa:home%</template>
|
||||||
<template v-if="column.type == 'local'">%fa:R comments%</template>
|
<template v-if="column.type == 'local'">%fa:R comments%</template>
|
||||||
@ -9,14 +8,13 @@
|
|||||||
<span>{{ name }}</span>
|
<span>{{ name }}</span>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<div class="editor" v-if="edit">
|
<div class="editor" style="padding:0 12px" v-if="edit">
|
||||||
<mk-switch v-model="column.isMediaOnly" @change="onChangeSettings" text="%i18n:@is-media-only%"/>
|
<mk-switch v-model="column.isMediaOnly" @change="onChangeSettings" text="%i18n:@is-media-only%"/>
|
||||||
<mk-switch v-model="column.isMediaView" @change="onChangeSettings" text="%i18n:@is-media-view%"/>
|
<mk-switch v-model="column.isMediaView" @change="onChangeSettings" text="%i18n:@is-media-view%"/>
|
||||||
</div>
|
</div>
|
||||||
<x-list-tl v-if="column.type == 'list'" :list="column.list" :media-only="column.isMediaOnly"/>
|
<x-list-tl v-if="column.type == 'list'" :list="column.list" :media-only="column.isMediaOnly" :media-view="column.isMediaView"/>
|
||||||
<x-tl v-else :src="column.type" :media-only="column.isMediaOnly"/>
|
<x-tl v-else :src="column.type" :media-only="column.isMediaOnly" :media-view="column.isMediaView"/>
|
||||||
</x-column>
|
</x-column>
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
@ -36,6 +34,10 @@ export default Vue.extend({
|
|||||||
column: {
|
column: {
|
||||||
type: Object,
|
type: Object,
|
||||||
required: true
|
required: true
|
||||||
|
},
|
||||||
|
isStacked: {
|
||||||
|
type: Boolean,
|
||||||
|
required: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -43,8 +45,9 @@ export default Vue.extend({
|
|||||||
return {
|
return {
|
||||||
edit: false,
|
edit: false,
|
||||||
menu: [{
|
menu: [{
|
||||||
content: '%fa:cog% %i18n:@edit%',
|
icon: '%fa:cog%',
|
||||||
onClick: () => {
|
text: '%i18n:@edit%',
|
||||||
|
action: () => {
|
||||||
this.edit = !this.edit;
|
this.edit = !this.edit;
|
||||||
}
|
}
|
||||||
}]
|
}]
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user