Compare commits
185 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
d38fc490ad | ||
![]() |
662167e792 | ||
![]() |
36c91f03d9 | ||
![]() |
33ccee26b5 | ||
![]() |
ed5cb991e3 | ||
![]() |
bea84ec2bf | ||
![]() |
08c176e549 | ||
![]() |
810ed50976 | ||
![]() |
2684541693 | ||
![]() |
a5b12bac54 | ||
![]() |
fea1b06e43 | ||
![]() |
182ca5d434 | ||
![]() |
facde9a75d | ||
![]() |
41385640b9 | ||
![]() |
7bad9db32e | ||
![]() |
af66f0a497 | ||
![]() |
95e1b80f41 | ||
![]() |
556e2eba95 | ||
![]() |
efe530cb17 | ||
![]() |
34e7c99283 | ||
![]() |
4157ea8bc3 | ||
![]() |
550517bbf3 | ||
![]() |
eb910cd8a1 | ||
![]() |
75131c4e8a | ||
![]() |
ee29ab95be | ||
![]() |
e97951fc51 | ||
![]() |
dfabdef60f | ||
![]() |
5a87763193 | ||
![]() |
6bb90f56fa | ||
![]() |
c883ae1350 | ||
![]() |
09e25e6a02 | ||
![]() |
bf5d43054b | ||
![]() |
63b3c65691 | ||
![]() |
f193da7f67 | ||
![]() |
40f38c2c0a | ||
![]() |
db439ef804 | ||
![]() |
56eb896a03 | ||
![]() |
68d43e43b6 | ||
![]() |
c60517e49a | ||
![]() |
3f59d261f2 | ||
![]() |
4068d220e5 | ||
![]() |
18968e7208 | ||
![]() |
38656103c0 | ||
![]() |
0f65b1bcc5 | ||
![]() |
a628821834 | ||
![]() |
6ceff60c1e | ||
![]() |
d762a6ce58 | ||
![]() |
75a8037a46 | ||
![]() |
1179920790 | ||
![]() |
b323a160e3 | ||
![]() |
b157e9535e | ||
![]() |
7668475bd6 | ||
![]() |
8bda2a1fb7 | ||
![]() |
b092086b5b | ||
![]() |
69a0d9034f | ||
![]() |
f5be8fd313 | ||
![]() |
7f835d7f76 | ||
![]() |
ddbb7c5993 | ||
![]() |
00a3fe39e8 | ||
![]() |
7537fb88d4 | ||
![]() |
a81bc71a1e | ||
![]() |
0a0aa0e2db | ||
![]() |
c56b94ae96 | ||
![]() |
e90712706d | ||
![]() |
eb0623331f | ||
![]() |
d15bd59109 | ||
![]() |
60e0b19372 | ||
![]() |
922eb937ff | ||
![]() |
87573284f1 | ||
![]() |
a91c585f55 | ||
![]() |
953ea21d5e | ||
![]() |
ecb00968bc | ||
![]() |
50ad8adb2d | ||
![]() |
16878caf09 | ||
![]() |
5bc30c5493 | ||
![]() |
85d89cf4c4 | ||
![]() |
db693f598b | ||
![]() |
0494c770a1 | ||
![]() |
c473b62aed | ||
![]() |
f19ac5320e | ||
![]() |
612e3aafbc | ||
![]() |
0e97fec451 | ||
![]() |
e8c8626ee4 | ||
![]() |
d89e0f07f8 | ||
![]() |
e7f81a42ce | ||
![]() |
ac614148b8 | ||
![]() |
5eb02b4901 | ||
![]() |
65631525f6 | ||
![]() |
969435cfe9 | ||
![]() |
c932f7a25b | ||
![]() |
42d164dc57 | ||
![]() |
a7e60f80bd | ||
![]() |
3dd5f313b7 | ||
![]() |
883962c393 | ||
![]() |
8a30ff1c76 | ||
![]() |
e47c354916 | ||
![]() |
496f42805d | ||
![]() |
c3d34bda37 | ||
![]() |
bb6ede2b8f | ||
![]() |
822400a1ba | ||
![]() |
e3e08843f1 | ||
![]() |
ce0d4f77fa | ||
![]() |
94fdb4e974 | ||
![]() |
4d425fc8a4 | ||
![]() |
c6cdfa2f5a | ||
![]() |
0fff2e4f16 | ||
![]() |
80a2172715 | ||
![]() |
5a0a297634 | ||
![]() |
948a133b7b | ||
![]() |
2ee826c958 | ||
![]() |
539409faf8 | ||
![]() |
606e46e4d7 | ||
![]() |
a179cfd69a | ||
![]() |
d8379253d4 | ||
![]() |
c3344fbd68 | ||
![]() |
4cebd6e84a | ||
![]() |
90fbf9dbb0 | ||
![]() |
d365b9f634 | ||
![]() |
a2f06acaa4 | ||
![]() |
8c90cbcbfb | ||
![]() |
a4a47772dc | ||
![]() |
5dde1f4602 | ||
![]() |
9dc0909eeb | ||
![]() |
0ed2592e41 | ||
![]() |
76cff98220 | ||
![]() |
60604b6f51 | ||
![]() |
f410b7aecb | ||
![]() |
1a61f2cee9 | ||
![]() |
78a8293520 | ||
![]() |
03cfb4fc8d | ||
![]() |
144345a359 | ||
![]() |
fd2c01515e | ||
![]() |
219570e08b | ||
![]() |
69df556ff5 | ||
![]() |
5f4a52574f | ||
![]() |
5a1f6c5839 | ||
![]() |
91d0342fe8 | ||
![]() |
8cc236daf8 | ||
![]() |
d283ec69f7 | ||
![]() |
d1aea7596c | ||
![]() |
c934987b14 | ||
![]() |
00c9f4a2e5 | ||
![]() |
6605c1d07f | ||
![]() |
7325d66c52 | ||
![]() |
a485061e22 | ||
![]() |
1f63f50343 | ||
![]() |
cd3170dabd | ||
![]() |
841cedc5f8 | ||
![]() |
7f4882734d | ||
![]() |
e7d647d412 | ||
![]() |
913d14a58a | ||
![]() |
909272ec3d | ||
![]() |
7af40ffbbe | ||
![]() |
9df79a3ec9 | ||
![]() |
4f2eee06aa | ||
![]() |
1b9cf76008 | ||
![]() |
d035a43ed6 | ||
![]() |
95ee9a6e09 | ||
![]() |
02a63cdcb3 | ||
![]() |
f02125dd47 | ||
![]() |
c11e813146 | ||
![]() |
a365849048 | ||
![]() |
a493c9f769 | ||
![]() |
a13f522b2a | ||
![]() |
1ed70b2e2c | ||
![]() |
86d5a599b7 | ||
![]() |
c226fc8d63 | ||
![]() |
bbf4e1c413 | ||
![]() |
a24a20a83d | ||
![]() |
725600da8f | ||
![]() |
f74a32ed9b | ||
![]() |
e08e72dd10 | ||
![]() |
ce02e1e528 | ||
![]() |
0b27d8a717 | ||
![]() |
2782e7d26f | ||
![]() |
2c83a05e80 | ||
![]() |
467f68502a | ||
![]() |
d95b0dee6b | ||
![]() |
a1f3323fa5 | ||
![]() |
494796a7f0 | ||
![]() |
94f2c20d35 | ||
![]() |
c1deb9438d | ||
![]() |
ea86527c66 | ||
![]() |
d1a18fe266 | ||
![]() |
737064da82 |
14
.github/ISSUE_TEMPLATE/01_bug-report.md
vendored
14
.github/ISSUE_TEMPLATE/01_bug-report.md
vendored
@@ -1,30 +1,30 @@
|
|||||||
---
|
---
|
||||||
name: Bug Report
|
name: 🐛 Bug Report
|
||||||
about: Create a report to help us improve
|
about: Create a report to help us improve
|
||||||
title: ''
|
title: ''
|
||||||
labels: bug
|
labels: ⚠️bug?
|
||||||
assignees: ''
|
assignees: ''
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# Summary
|
## Summary
|
||||||
|
|
||||||
<!-- Tell us what the bug is -->
|
<!-- Tell us what the bug is -->
|
||||||
|
|
||||||
# Expected Behavior
|
## Expected Behavior
|
||||||
|
|
||||||
<!--- Tell us what should happen -->
|
<!--- Tell us what should happen -->
|
||||||
|
|
||||||
# Actual Behavior
|
## Actual Behavior
|
||||||
|
|
||||||
<!--- Tell us what happens instead of the expected behavior -->
|
<!--- Tell us what happens instead of the expected behavior -->
|
||||||
|
|
||||||
# Steps to Reproduce
|
## Steps to Reproduce
|
||||||
|
|
||||||
1.
|
1.
|
||||||
2.
|
2.
|
||||||
3.
|
3.
|
||||||
|
|
||||||
# Environment
|
## Environment
|
||||||
|
|
||||||
<!-- Tell us where on the platform it happens -->
|
<!-- Tell us where on the platform it happens -->
|
||||||
|
@@ -1,31 +0,0 @@
|
|||||||
---
|
|
||||||
name: Client-side Bug Report
|
|
||||||
about: Create a report to help us improve
|
|
||||||
title: ''
|
|
||||||
labels: bug, client-side
|
|
||||||
assignees: ''
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Summary
|
|
||||||
|
|
||||||
<!-- Tell us what the bug is -->
|
|
||||||
|
|
||||||
# Expected Behavior
|
|
||||||
|
|
||||||
<!--- Tell us what should happen -->
|
|
||||||
|
|
||||||
# Actual Behavior
|
|
||||||
|
|
||||||
<!--- Tell us what happens instead of the expected behavior -->
|
|
||||||
|
|
||||||
# Steps to Reproduce
|
|
||||||
|
|
||||||
1.
|
|
||||||
2.
|
|
||||||
3.
|
|
||||||
|
|
||||||
# Environment
|
|
||||||
|
|
||||||
<!-- Tell us where on the platform it happens -->
|
|
||||||
<!-- e.g. desktop or mobile version, your browser, your OS -->
|
|
@@ -1,12 +1,12 @@
|
|||||||
---
|
---
|
||||||
name: Feature Request
|
name: ✨ Feature Request
|
||||||
about: Suggest an idea for this project
|
about: Suggest an idea for this project
|
||||||
title: ''
|
title: ''
|
||||||
labels: feature
|
labels: ✨Feature
|
||||||
assignees: ''
|
assignees: ''
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# Summary
|
## Summary
|
||||||
|
|
||||||
<!-- Tell us what the suggestion is -->
|
<!-- Tell us what the suggestion is -->
|
@@ -1,31 +0,0 @@
|
|||||||
---
|
|
||||||
name: Server-side Bug Report
|
|
||||||
about: Create a report to help us improve
|
|
||||||
title: ''
|
|
||||||
labels: bug, server-side
|
|
||||||
assignees: ''
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Summary
|
|
||||||
|
|
||||||
<!-- Tell us what the bug is -->
|
|
||||||
|
|
||||||
# Expected Behavior
|
|
||||||
|
|
||||||
<!--- Tell us what should happen -->
|
|
||||||
|
|
||||||
# Actual Behavior
|
|
||||||
|
|
||||||
<!--- Tell us what happens instead of the expected behavior -->
|
|
||||||
|
|
||||||
# Steps to Reproduce
|
|
||||||
|
|
||||||
1.
|
|
||||||
2.
|
|
||||||
3.
|
|
||||||
|
|
||||||
# Environment
|
|
||||||
|
|
||||||
<!-- Tell us where on the platform it happens -->
|
|
||||||
<!-- e.g. your Node.js version, your OS -->
|
|
@@ -1,12 +0,0 @@
|
|||||||
---
|
|
||||||
name: Client-side Feature Request
|
|
||||||
about: Suggest an idea for this project
|
|
||||||
title: ''
|
|
||||||
labels: client-side, feature
|
|
||||||
assignees: ''
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Summary
|
|
||||||
|
|
||||||
<!-- Tell us what the suggestion is -->
|
|
@@ -1,12 +0,0 @@
|
|||||||
---
|
|
||||||
name: Server-side Feature Request
|
|
||||||
about: Suggest an idea for this project
|
|
||||||
title: ''
|
|
||||||
labels: feature, server-side
|
|
||||||
assignees: ''
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Summary
|
|
||||||
|
|
||||||
<!-- Tell us what the suggestion is -->
|
|
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -1,4 +1,4 @@
|
|||||||
# Summary
|
## Summary
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
-
|
-
|
||||||
|
98
CHANGELOG.md
98
CHANGELOG.md
@@ -1,6 +1,104 @@
|
|||||||
ChangeLog
|
ChangeLog
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
If you encounter any problems with updating, please try the following:
|
||||||
|
1. `npm run clean` or `npm run cleanall`
|
||||||
|
2. Retry update (Don't forget `npm i`)
|
||||||
|
|
||||||
|
10.97.2
|
||||||
|
----------
|
||||||
|
* ビルド時に警告が出ないように修正
|
||||||
|
|
||||||
|
10.97.1
|
||||||
|
----------
|
||||||
|
* デザインの調整
|
||||||
|
|
||||||
|
10.97.0
|
||||||
|
----------
|
||||||
|
* リアクションに絵文字やカスタム絵文字を使えるように
|
||||||
|
* 不明なリアクションのフォールバックに star を使えるように
|
||||||
|
* デザインの調整
|
||||||
|
|
||||||
|
10.96.0
|
||||||
|
----------
|
||||||
|
* 連合ユーザーの投稿に対してActivityPubオブジェクトを要求されたら元のインスタンスにリダイレクトするように
|
||||||
|
* updatePersonを試行した時点でもlastFetchedAtを更新するように
|
||||||
|
* 管理画面でリモートインスタンスの登録日時を表示
|
||||||
|
* ユーザーサジェストが機能しなくなっていた問題を修正
|
||||||
|
* 最近使ったハッシュタグ表示が機能していない問題を修正
|
||||||
|
* バグ修正
|
||||||
|
* デザインの調整
|
||||||
|
|
||||||
|
10.95.0
|
||||||
|
----------
|
||||||
|
* ジョブを一覧できるように
|
||||||
|
* MFMでURLを明示する構文の追加
|
||||||
|
* Articleタイプのアクティビティを受け入れるように
|
||||||
|
* 凍結されたユーザーをサジェストしないように
|
||||||
|
* ファビコンが保存されないのを修正
|
||||||
|
* キューのジョブクリアの動作を修正
|
||||||
|
* デザインの調整
|
||||||
|
|
||||||
|
10.94.0
|
||||||
|
----------
|
||||||
|
* Faviconを設定できるように
|
||||||
|
* アカウントを凍結したときすべてのフォローを解除するように
|
||||||
|
* シェアページが機能していない問題を修正
|
||||||
|
* インスタンスブロックをしていてもRenote等すると取得されてしまう問題を修正
|
||||||
|
* デザインの調整
|
||||||
|
|
||||||
|
10.93.1
|
||||||
|
----------
|
||||||
|
* データのエクスポートとインポートの動作を修正
|
||||||
|
* デザインの調整
|
||||||
|
|
||||||
|
10.93.0
|
||||||
|
----------
|
||||||
|
* フォローリストをインポートできるように
|
||||||
|
* embedプレイヤーを閉じれるように
|
||||||
|
* リストをインポートしたときにプロキシアカウントがフォローするように修正
|
||||||
|
* Web Share Targetの動作を修正
|
||||||
|
* おすすめアンケートのチョイスを修正
|
||||||
|
* デザインの調整
|
||||||
|
|
||||||
|
10.92.4
|
||||||
|
----------
|
||||||
|
* リストのエクスポートをできるように
|
||||||
|
* ジョブキューウィジェットを追加
|
||||||
|
* URLプレビューのサムネイルが表示されないことがある問題を修正
|
||||||
|
|
||||||
|
10.92.3
|
||||||
|
----------
|
||||||
|
* 管理画面の各種ジョブ数がおかしい問題を修正
|
||||||
|
* ジョブキューの動作を調整
|
||||||
|
|
||||||
|
10.92.2
|
||||||
|
----------
|
||||||
|
* 管理画面で各種ジョブ数を一覧できるように
|
||||||
|
* ジョブキューの動作を修正
|
||||||
|
* notes/children が遅い問題を修正
|
||||||
|
|
||||||
|
10.92.1
|
||||||
|
----------
|
||||||
|
* アンケートの結果をリモートと同期するように
|
||||||
|
* ジョブキューを有効に
|
||||||
|
* 投稿の返信一覧に引用Renoteも含めるように
|
||||||
|
* robots.txt追加
|
||||||
|
* デザインの調整
|
||||||
|
|
||||||
|
10.92.0
|
||||||
|
----------
|
||||||
|
* Mastodonのアンケートに対応
|
||||||
|
* 複数回答できるアンケートを作成できるように
|
||||||
|
* アンケートに期限を設定できるように
|
||||||
|
* 絵文字ピッカーを改良
|
||||||
|
* ハッシュタグの判定を改善
|
||||||
|
* デッキのタグTLで別のタグをクリックしてもTLが変わらない問題を修正
|
||||||
|
* ユーザーサジェストで表示名が変わらない問題を修正
|
||||||
|
* UIのバグ修正
|
||||||
|
* デザインの調整
|
||||||
|
* など
|
||||||
|
|
||||||
10.91.2
|
10.91.2
|
||||||
----------
|
----------
|
||||||
* 10.91.1 で追加した依存関係にXSS脆弱性があったので他のパッケージに差し替え
|
* 10.91.1 で追加した依存関係にXSS脆弱性があったので他のパッケージに差し替え
|
||||||
|
@@ -46,6 +46,9 @@ Convert な(na) to にゃ(nya)
|
|||||||
Revert Nyaize
|
Revert Nyaize
|
||||||
|
|
||||||
## Code style
|
## Code style
|
||||||
|
### Use semicolon
|
||||||
|
To avoid ASI Hazard
|
||||||
|
|
||||||
### Don't use `export default`
|
### Don't use `export default`
|
||||||
Bad:
|
Bad:
|
||||||
``` ts
|
``` ts
|
||||||
|
12
README.md
12
README.md
@@ -1,4 +1,4 @@
|
|||||||
<img src="https://github.com/syuilo/misskey/blob/develop/assets/ai-orig.png?raw=true" align="right" height="320px"/>
|
<a href="https://ai.misskey.xyz/"><img src="https://github.com/syuilo/misskey/blob/develop/assets/ai-orig.png?raw=true" align="right" height="320px"/></a>
|
||||||
|
|
||||||
[](https://misskey.xyz/)
|
[](https://misskey.xyz/)
|
||||||
================================================================
|
================================================================
|
||||||
@@ -103,7 +103,7 @@ Please see the [Contribution Guide](./CONTRIBUTING.md).
|
|||||||
<table><tr>
|
<table><tr>
|
||||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/12190916/fb7fa7983c14425f890369535b1506a4/1?token-time=2145916800&token-hash=WeuDzzz24cRXJogyIkU-mxARqkdyms-rcZKbO-GpGjw%3D" alt="weep" width="100"></td>
|
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/12190916/fb7fa7983c14425f890369535b1506a4/1?token-time=2145916800&token-hash=WeuDzzz24cRXJogyIkU-mxARqkdyms-rcZKbO-GpGjw%3D" alt="weep" width="100"></td>
|
||||||
<td><img src="https://c8.patreon.com/2/200/12059069" alt="naga_rus" width="100"></td>
|
<td><img src="https://c8.patreon.com/2/200/12059069" alt="naga_rus" width="100"></td>
|
||||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/12913507/f7181eacafe8469a93033d85f5969c29/3?token-time=2145916800&token-hash=c8HeVqLtmdgH-gSBJg8i10gmOcwllM87MDHeznl3el0%3D" alt="Melilot" width="100"></td>
|
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/12913507/f7181eacafe8469a93033d85f5969c29/4?token-time=2145916800&token-hash=vZdDTTF-ahiKBjjgppS2ev4rkD8H7TTKkXXoxsucs6Y%3D" alt="Melilot" width="100"></td>
|
||||||
<td><img src="https://c8.patreon.com/2/200/16869916" alt="見当かなみ" width="100"></td>
|
<td><img src="https://c8.patreon.com/2/200/16869916" alt="見当かなみ" width="100"></td>
|
||||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/12999811/5f349fafcce44dd1824a8b1ebbec4564/3?token-time=2145916800&token-hash=LtV2lRi3L2jOWMLwccr9qWYfPrFlzIo2jYZHKzHEb6k%3D" alt="Xeltica" width="100"></td>
|
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/12999811/5f349fafcce44dd1824a8b1ebbec4564/3?token-time=2145916800&token-hash=LtV2lRi3L2jOWMLwccr9qWYfPrFlzIo2jYZHKzHEb6k%3D" alt="Xeltica" width="100"></td>
|
||||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/12021162/963128bb8d14476dbd8407943db8f31a/1?token-time=2145916800&token-hash=1FlxS9MEgmNGH_RHUVHbO5hIXB5I1z0lvA33CTvYvjA%3D" alt="gutfuckllc" width="100"></td>
|
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/12021162/963128bb8d14476dbd8407943db8f31a/1?token-time=2145916800&token-hash=1FlxS9MEgmNGH_RHUVHbO5hIXB5I1z0lvA33CTvYvjA%3D" alt="gutfuckllc" width="100"></td>
|
||||||
@@ -124,6 +124,7 @@ Please see the [Contribution Guide](./CONTRIBUTING.md).
|
|||||||
<td><img src="https://c8.patreon.com/2/200/17463605" alt="Sampot" width="100"></td>
|
<td><img src="https://c8.patreon.com/2/200/17463605" alt="Sampot" width="100"></td>
|
||||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/17880724/311738c8a48f4a6b9443c2445a75adde/1?token-time=2145916800&token-hash=95p8VdGX45E8BitZR_eOcDlqCjumjzNLBPQJrJdeCpI%3D" alt="takimura" width="100"></td>
|
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/17880724/311738c8a48f4a6b9443c2445a75adde/1?token-time=2145916800&token-hash=95p8VdGX45E8BitZR_eOcDlqCjumjzNLBPQJrJdeCpI%3D" alt="takimura" width="100"></td>
|
||||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/17195955/be45e5e14c3e48b2bee0456c84e19df4/4?token-time=2145916800&token-hash=SbdZeN5SmsuT9stD6v0jN1z0hftg0FmRiCTxysU0Ihw%3D" alt="Damillora" width="100"></td>
|
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/17195955/be45e5e14c3e48b2bee0456c84e19df4/4?token-time=2145916800&token-hash=SbdZeN5SmsuT9stD6v0jN1z0hftg0FmRiCTxysU0Ihw%3D" alt="Damillora" width="100"></td>
|
||||||
|
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/16900731/935a10339daa4ede8e555903a0707060/1?token-time=2145916800&token-hash=3CrpqH-XtKs_NoIlSsTyVs8wCzP1WFCsG2xwps1IJq0%3D" alt="Atsuko Tominaga" width="100"></td>
|
||||||
</tr><tr>
|
</tr><tr>
|
||||||
<td><a href="https://www.patreon.com/mydarkstar">mydarkstar</a></td>
|
<td><a href="https://www.patreon.com/mydarkstar">mydarkstar</a></td>
|
||||||
<td><a href="https://www.patreon.com/user?u=12718187">Peter G.</a></td>
|
<td><a href="https://www.patreon.com/user?u=12718187">Peter G.</a></td>
|
||||||
@@ -133,10 +134,12 @@ Please see the [Contribution Guide](./CONTRIBUTING.md).
|
|||||||
<td><a href="https://www.patreon.com/user?u=17463605">Sampot</a></td>
|
<td><a href="https://www.patreon.com/user?u=17463605">Sampot</a></td>
|
||||||
<td><a href="https://www.patreon.com/takimura">takimura</a></td>
|
<td><a href="https://www.patreon.com/takimura">takimura</a></td>
|
||||||
<td><a href="https://www.patreon.com/damillora">Damillora</a></td>
|
<td><a href="https://www.patreon.com/damillora">Damillora</a></td>
|
||||||
|
<td><a href="https://www.patreon.com/user?u=16900731">Atsuko Tominaga</a></td>
|
||||||
</tr></table>
|
</tr></table>
|
||||||
<table><tr>
|
<table><tr>
|
||||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/4389829/9f709180ac714651a70f74a82f3ffdb9/2?token-time=2145916800&token-hash=zcwFxb2zopzWwksKVU1YpfAEjsl4yKT02aQ6yiAFRiQ%3D" alt="natalie" width="100"></td>
|
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/4389829/9f709180ac714651a70f74a82f3ffdb9/3?token-time=2145916800&token-hash=-iJszBqgYBhsM5qMdA1knf9wvprhEfESzKfR2oh7mIA%3D" alt="natalie" width="100"></td>
|
||||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/13034746/c711c7f58e204ecfbc2fd646bc8a4eee/1?token-time=2145916800&token-hash=5T8XcaAf9Zyzfg3QubR06s_kJZkArVEM2dwObrBVAU4%3D" alt="Hiratake" width="100"></td>
|
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/13034746/c711c7f58e204ecfbc2fd646bc8a4eee/1?token-time=2145916800&token-hash=5T8XcaAf9Zyzfg3QubR06s_kJZkArVEM2dwObrBVAU4%3D" alt="Hiratake" width="100"></td>
|
||||||
|
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/18072312/98e894d960314fa7bc236a72a39488fe/1?token-time=2145916800&token-hash=D6QK3fPyqiYKJfOzc-QqaSSairUrWdjld-ewp2waj6s%3D" alt="Hekovic" width="100"></td>
|
||||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/4503830/ccf2cc867ea64de0b524bb2e24b9a1cb/1?token-time=2145916800&token-hash=Ksk_2l3gjPDbnzMUOCSW1E-hdPJsNs2tSR4_RAakRK8%3D" alt="dansup" width="100"></td>
|
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/4503830/ccf2cc867ea64de0b524bb2e24b9a1cb/1?token-time=2145916800&token-hash=Ksk_2l3gjPDbnzMUOCSW1E-hdPJsNs2tSR4_RAakRK8%3D" alt="dansup" width="100"></td>
|
||||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/619786/32cf01444db24e578cd1982c197f6fc6/1?token-time=2145916800&token-hash=CXe9AqlZy9AsYfiWd3OBYVOzvODoN47Litz0Tu4BFpU%3D" alt="Gargron" width="100"></td>
|
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/619786/32cf01444db24e578cd1982c197f6fc6/1?token-time=2145916800&token-hash=CXe9AqlZy9AsYfiWd3OBYVOzvODoN47Litz0Tu4BFpU%3D" alt="Gargron" width="100"></td>
|
||||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/5731881/4b6038e6cda34c04b83a5fcce3806a93/1?token-time=2145916800&token-hash=xhR1n6NAAyEb-IUXLD6_dshkFa3mefU5ZZuk1L8qKTs%3D" alt="Nokotaro Takeda" width="100"></td>
|
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/5731881/4b6038e6cda34c04b83a5fcce3806a93/1?token-time=2145916800&token-hash=xhR1n6NAAyEb-IUXLD6_dshkFa3mefU5ZZuk1L8qKTs%3D" alt="Nokotaro Takeda" width="100"></td>
|
||||||
@@ -144,13 +147,14 @@ Please see the [Contribution Guide](./CONTRIBUTING.md).
|
|||||||
</tr><tr>
|
</tr><tr>
|
||||||
<td><a href="https://www.patreon.com/user?u=4389829">natalie</a></td>
|
<td><a href="https://www.patreon.com/user?u=4389829">natalie</a></td>
|
||||||
<td><a href="https://www.patreon.com/hiratake">Hiratake</a></td>
|
<td><a href="https://www.patreon.com/hiratake">Hiratake</a></td>
|
||||||
|
<td><a href="https://www.patreon.com/hekovic">Hekovic</a></td>
|
||||||
<td><a href="https://www.patreon.com/dansup">dansup</a></td>
|
<td><a href="https://www.patreon.com/dansup">dansup</a></td>
|
||||||
<td><a href="https://www.patreon.com/mastodon">Gargron</a></td>
|
<td><a href="https://www.patreon.com/mastodon">Gargron</a></td>
|
||||||
<td><a href="https://www.patreon.com/takenoko">Nokotaro Takeda</a></td>
|
<td><a href="https://www.patreon.com/takenoko">Nokotaro Takeda</a></td>
|
||||||
<td><a href="https://www.patreon.com/user?u=12531784">Takashi Shibuya</a></td>
|
<td><a href="https://www.patreon.com/user?u=12531784">Takashi Shibuya</a></td>
|
||||||
</tr></table>
|
</tr></table>
|
||||||
|
|
||||||
**Last updated:** Fri, 01 Mar 2019 23:59:07 UTC
|
**Last updated:** Tue, 12 Mar 2019 00:50:06 UTC
|
||||||
<!-- PATREON_END -->
|
<!-- PATREON_END -->
|
||||||
|
|
||||||
:four_leaf_clover: Copyright
|
:four_leaf_clover: Copyright
|
||||||
|
4
assets/robots.txt
Normal file
4
assets/robots.txt
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
user-agent: *
|
||||||
|
allow: /
|
||||||
|
|
||||||
|
# todo: sitemap
|
@@ -118,7 +118,7 @@ CentOSで1024以下のポートを使用してMisskeyを使用する場合は`Ex
|
|||||||
4. `NODE_ENV=production npm run build`
|
4. `NODE_ENV=production npm run build`
|
||||||
5. [ChangeLog](../CHANGELOG.md)でマイグレーション情報を確認する
|
5. [ChangeLog](../CHANGELOG.md)でマイグレーション情報を確認する
|
||||||
|
|
||||||
なにか問題が発生した場合は、`npm run clean`すると直る場合があります。
|
なにか問題が発生した場合は、`npm run clean`または`npm run cleanall`すると直る場合があります。
|
||||||
|
|
||||||
----------------------------------------------------------------
|
----------------------------------------------------------------
|
||||||
|
|
||||||
|
@@ -5,7 +5,6 @@
|
|||||||
import * as gulp from 'gulp';
|
import * as gulp from 'gulp';
|
||||||
import * as gutil from 'gulp-util';
|
import * as gutil from 'gulp-util';
|
||||||
import * as ts from 'gulp-typescript';
|
import * as ts from 'gulp-typescript';
|
||||||
const yaml = require('gulp-yaml');
|
|
||||||
const sourcemaps = require('gulp-sourcemaps');
|
const sourcemaps = require('gulp-sourcemaps');
|
||||||
import tslint from 'gulp-tslint';
|
import tslint from 'gulp-tslint';
|
||||||
const cssnano = require('gulp-cssnano');
|
const cssnano = require('gulp-cssnano');
|
||||||
@@ -126,12 +125,6 @@ gulp.task('copy:client', () =>
|
|||||||
.pipe(gulp.dest('./built/client/assets/'))
|
.pipe(gulp.dest('./built/client/assets/'))
|
||||||
);
|
);
|
||||||
|
|
||||||
gulp.task('locales', () =>
|
|
||||||
gulp.src('./locales/*.yml')
|
|
||||||
.pipe(yaml({ schema: 'DEFAULT_SAFE_SCHEMA' }))
|
|
||||||
.pipe(gulp.dest('./built/client/assets/locales/'))
|
|
||||||
);
|
|
||||||
|
|
||||||
gulp.task('doc', () =>
|
gulp.task('doc', () =>
|
||||||
gulp.src('./src/docs/**/*.styl')
|
gulp.src('./src/docs/**/*.styl')
|
||||||
.pipe(stylus())
|
.pipe(stylus())
|
||||||
@@ -149,7 +142,6 @@ gulp.task('build', gulp.parallel(
|
|||||||
'build:ts',
|
'build:ts',
|
||||||
'build:copy',
|
'build:copy',
|
||||||
'build:client',
|
'build:client',
|
||||||
'locales',
|
|
||||||
'doc'
|
'doc'
|
||||||
));
|
));
|
||||||
|
|
||||||
|
@@ -2,12 +2,12 @@
|
|||||||
meta:
|
meta:
|
||||||
lang: "Čeština"
|
lang: "Čeština"
|
||||||
common:
|
common:
|
||||||
misskey: "⭐ ve fediverse"
|
misskey: "⭐ ve fedivesmíru"
|
||||||
about-title: "⭐ ve fediverse."
|
about-title: "⭐ ve fedivesmíru."
|
||||||
about: "Děkujeme, že jste našli Misskey. Misskey je <b>decentralizovaná mikroblogovací platforma</b> zrozená na Zemi. Neboť existuje ve Fediverse (vesmíru, kde jsou organizovány různé sociální sítě), je vzájemně propojena s jinými sociálními sítěmi. Co takhle si chvilku odpočinout od ruchu a shonu města a ponořit se do nového internetu?"
|
about: "Děkujeme, že jste našli Misskey. Misskey je <b>decentralizovaná mikroblogovací platforma</b> zrozená na Zemi. Neboť existuje ve fedivesmíru (vesmíru, kde jsou organizovány různé sociální sítě), je vzájemně propojena s jinými sociálními sítěmi. Co takhle si chvilku odpočinout od ruchu a shonu města a ponořit se do nového internetu?"
|
||||||
intro:
|
intro:
|
||||||
title: "Co je Misskey?"
|
title: "Co je Misskey?"
|
||||||
about: "Misskey je open-source <b>decentralizovaný mikroblogovací software</b>. Má sofistikované, zcela přizpůsobitelné uživatelské rozhraní, různé způsoby reagování na příspěvky, bezplatné úložiště souborů nabízející integrovaný management system, a další pokročilé vlastnosti. Misskey je navíc připojeno k systému sítí zvanému „fediverse“, který nám dovoluje komunikovat s uživateli na jiných sociálních sítí. Pokud například něco napíšete, nebude to posláno pouze uživatelů Misskey, ale také lidem na sítích Mastodon a Pleroma. Jen si představte, že planeta posílá jiné planetě rádiový signál, aby s ní komunikovala."
|
about: "Misskey je open-source <b>decentralizovaný mikroblogovací software</b>. Má sofistikované, zcela přizpůsobitelné uživatelské rozhraní, různé způsoby reagování na příspěvky, bezplatné úložiště souborů nabízející integrovaný management system, a další pokročilé vlastnosti. Misskey je navíc připojeno k systému sítí zvanému „fedivesmír“ nebo „fediverse“, který nám dovoluje komunikovat s uživateli na jiných sociálních sítí. Pokud například něco napíšete, nebude to posláno pouze uživatelů Misskey, ale také lidem na sítích Mastodon a Pleroma. Jen si představte, že planeta posílá jiné planetě rádiový signál, aby s ní komunikovala."
|
||||||
features: "Vlastnosti"
|
features: "Vlastnosti"
|
||||||
rich-contents: "Příspěvky"
|
rich-contents: "Příspěvky"
|
||||||
rich-contents-desc: "Pouze napište svoje nápady, žhavá témata a cokoliv, co chcete sdílet. Můžete ozdobit svá slova, připojit vaše oblíbené obrázky, posílat soubory včetně videí či vytvořit hlasování – to je jen několik věcí, co můžete dělat s Misskey!"
|
rich-contents-desc: "Pouze napište svoje nápady, žhavá témata a cokoliv, co chcete sdílet. Můžete ozdobit svá slova, připojit vaše oblíbené obrázky, posílat soubory včetně videí či vytvořit hlasování – to je jen několik věcí, co můžete dělat s Misskey!"
|
||||||
@@ -93,7 +93,7 @@ common:
|
|||||||
love: "Super"
|
love: "Super"
|
||||||
laugh: "Smích"
|
laugh: "Smích"
|
||||||
hmm: "Hmm...?"
|
hmm: "Hmm...?"
|
||||||
surprise: "Páni"
|
surprise: "Překvapení"
|
||||||
congrats: "Gratuluji!"
|
congrats: "Gratuluji!"
|
||||||
angry: "Naštvaný"
|
angry: "Naštvaný"
|
||||||
confused: "Zmatený"
|
confused: "Zmatený"
|
||||||
@@ -101,14 +101,14 @@ common:
|
|||||||
pudding: "Pudink"
|
pudding: "Pudink"
|
||||||
note-visibility:
|
note-visibility:
|
||||||
public: "Veřejná"
|
public: "Veřejná"
|
||||||
home: "Domovský"
|
home: "Domovská"
|
||||||
home-desc: "Poslat pouze na domovskou časovou osu"
|
home-desc: "Poslat pouze na domovskou časovou osu"
|
||||||
followers: "Pro sledující"
|
followers: "Pro sledující"
|
||||||
followers-desc: "Poslat pouze sledujícím"
|
followers-desc: "Poslat pouze sledujícím"
|
||||||
specified: "Přímý"
|
specified: "Přímá"
|
||||||
specified-desc: "Poslat pouze zmíněným uživatelům"
|
specified-desc: "Poslat pouze zmíněným uživatelům"
|
||||||
local-public: "Veřejný (pouze místní)"
|
local-public: "Veřejná (pouze místní)"
|
||||||
local-home: "Domovský (pouze místní)"
|
local-home: "Domovská (pouze místní)"
|
||||||
local-followers: "Pro sledující (pouze místní)"
|
local-followers: "Pro sledující (pouze místní)"
|
||||||
note-placeholders:
|
note-placeholders:
|
||||||
a: "Co právě děláte?"
|
a: "Co právě děláte?"
|
||||||
@@ -122,7 +122,8 @@ common:
|
|||||||
profile: "Profil"
|
profile: "Profil"
|
||||||
notification: "Oznámení"
|
notification: "Oznámení"
|
||||||
apps: "Aplikace"
|
apps: "Aplikace"
|
||||||
tags: "Tagy"
|
tags: "Hashtagy"
|
||||||
|
mute-and-block: "Ztlumit/blokovat"
|
||||||
blocking: "Blokování"
|
blocking: "Blokování"
|
||||||
security: "Zabezpečení"
|
security: "Zabezpečení"
|
||||||
signin: "Historie přihlášení"
|
signin: "Historie přihlášení"
|
||||||
@@ -131,97 +132,184 @@ common:
|
|||||||
appearance: "Vzhled"
|
appearance: "Vzhled"
|
||||||
behavior: "Chování"
|
behavior: "Chování"
|
||||||
fetch-on-scroll: "Nekonečné rolování"
|
fetch-on-scroll: "Nekonečné rolování"
|
||||||
note-visibility: "Viditelnost statusu"
|
fetch-on-scroll-desc: "Pokud budete rolovat dolů po stránce, automaticky bude načten další obsah."
|
||||||
default-note-visibility: "Výchozí viditelnost statusu"
|
note-visibility: "Viditelnost příspěvku"
|
||||||
|
default-note-visibility: "Výchozí viditelnost příspěvku"
|
||||||
|
remember-note-visibility: "Zapamatovat viditelnost příspěvků"
|
||||||
web-search-engine: "Webové vyhledávače"
|
web-search-engine: "Webové vyhledávače"
|
||||||
web-search-engine-desc: "Například: https://www.google.com/?#q={{query}}"
|
web-search-engine-desc: "Například: https://www.google.com/?#q={{query}}"
|
||||||
keep-cw: "Zachovat varování o obsahu"
|
keep-cw: "Zachovat varování o obsahu"
|
||||||
keep-cw-desc: "Při odpovědi na příspěvek bude varování o obsahu nastaveno stejně jako původní příspěvek."
|
keep-cw-desc: "Při odpovědi na příspěvek bude varování o obsahu nastaveno stejně jako původní příspěvek."
|
||||||
i-like-sushi: "Mam radši sushi (než puding)"
|
i-like-sushi: "Mam radši sushi (než puding)"
|
||||||
|
show-reversi-board-labels: "Zobrazit označení řad a sloupců v Reversi"
|
||||||
|
use-avatar-reversi-stones: "Použít avatar jako figurku v Reversi"
|
||||||
|
disable-animated-mfm: "Vypnout pohyblivé texty v příspěvku"
|
||||||
|
disable-showing-animated-images: "Nepřehrávat animované obrázky"
|
||||||
|
suggest-recent-hashtags: "Navrhovat nedávné hashtagy v rámci psacího pole"
|
||||||
|
always-show-nsfw: "Vždycky ukázat NSFW obsah"
|
||||||
|
always-mark-nsfw: "Označovat všechny příspěvky za delikátní"
|
||||||
|
show-full-acct: "Zaradit hostovací server jako součast přezdívky"
|
||||||
show-via: "zobrazit přes"
|
show-via: "zobrazit přes"
|
||||||
reduce-motion: "Snížit pohyb v rozhraní"
|
reduce-motion: "Snížit pohyb v rozhraní"
|
||||||
|
this-setting-is-this-device-only: "Pouze pro toto zařízení"
|
||||||
|
use-os-default-emojis: "Použít výchozí emoji systému"
|
||||||
|
line-width: "Hrubka línie"
|
||||||
|
line-width-thin: "Úzka"
|
||||||
|
line-width-normal: "Běžná"
|
||||||
|
line-width-thick: "Tlustá"
|
||||||
|
font-size: "Velikost písma"
|
||||||
|
font-size-x-small: "Malé"
|
||||||
|
font-size-small: "Dost malé"
|
||||||
|
font-size-medium: "Průměrné"
|
||||||
|
font-size-large: "Dost velké"
|
||||||
|
font-size-x-large: "Velké"
|
||||||
|
deck-column-align: "Zarovnání sloupců v Decku"
|
||||||
deck-column-align-center: "Na střed"
|
deck-column-align-center: "Na střed"
|
||||||
deck-column-align-left: "Vlevo"
|
deck-column-align-left: "Vlevo"
|
||||||
deck-column-width-wide: "široké"
|
deck-column-align-flexible: "Flexibilní"
|
||||||
wallpaper: "Pozadí"
|
deck-column-width: "Šířka sloupců v Decku"
|
||||||
|
deck-column-width-narrow: "Úzké"
|
||||||
|
deck-column-width-narrower: "Poněkud úzké"
|
||||||
|
deck-column-width-normal: "Normální"
|
||||||
|
deck-column-width-wider: "Poněkud široké"
|
||||||
|
deck-column-width-wide: "Široké"
|
||||||
|
use-shadow: "Používat v rozhraní stíny"
|
||||||
|
rounded-corners: "Zakulatit rohy v rozhraní"
|
||||||
|
circle-icons: "Používat kulaté ikony"
|
||||||
|
contrasted-acct: "Přidat uživatelskému účtu kontrast"
|
||||||
|
wallpaper: "Obrázek na pozadí"
|
||||||
choose-wallpaper: "Zvolit pozadí"
|
choose-wallpaper: "Zvolit pozadí"
|
||||||
delete-wallpaper: "Odstranit pozadí"
|
delete-wallpaper: "Odstranit pozadí"
|
||||||
post-form-on-timeline: "Zobrazit formulář pro nové příspěvky nad časovou osou"
|
post-form-on-timeline: "Zobrazit formulář pro nové příspěvky nad časovou osou"
|
||||||
show-clock-on-header: "Zobrazit hodiny v pravém horním rohu"
|
show-clock-on-header: "Zobrazit hodiny v pravém horním rohu"
|
||||||
|
show-reply-target: "Zobrazit cíl odpovědi"
|
||||||
timeline: "Časová osa"
|
timeline: "Časová osa"
|
||||||
|
show-my-renotes: "Zobrazit moje renoty v časové ose"
|
||||||
|
show-renoted-my-notes: "Zobrazit renoty vašich vlastních příspěvků v časové ose"
|
||||||
|
show-local-renotes: "Zobrazit renoty místních příspěvků v časové ose"
|
||||||
remain-deleted-note: "I nadále zobrazovat odstraněné příspěvky"
|
remain-deleted-note: "I nadále zobrazovat odstraněné příspěvky"
|
||||||
sound: "Zvuk"
|
sound: "Zvuk"
|
||||||
enable-sounds: "Povolit zvuk"
|
enable-sounds: "Povolit zvuk"
|
||||||
update: "Misskey aktualizace"
|
enable-sounds-desc: "Přehrát zvuk, například při odeslání nebo přijetí příspěvku, či zprávy. Toto nastavení je uloženo v prohlížeči."
|
||||||
|
volume: "Hlasitost"
|
||||||
|
test: "Test"
|
||||||
|
update: "Aktualizace Misskey"
|
||||||
version: "Verze:"
|
version: "Verze:"
|
||||||
latest-version: "Nejnovější verze:"
|
latest-version: "Nejnovější verze:"
|
||||||
advanced-settings: "Pokročilé nastavení"
|
update-checking: "Kontroluji aktualizace"
|
||||||
navbar-position: "Pozice navigace"
|
do-update: "Zkontrolovat aktualizace"
|
||||||
|
update-settings: "Pokročilá nastavení"
|
||||||
|
no-updates: "Nejsou dostupné žádné aktualizace"
|
||||||
|
no-updates-desc: "Váš server Misskey je aktuální."
|
||||||
|
update-available: "Je dostupná nová verze"
|
||||||
|
update-available-desc: "Aktualizace budou aplikovány po znovunačtení stránky."
|
||||||
|
advanced-settings: "Pokročilá nastavení"
|
||||||
|
debug-mode: "Povolit režim ladění"
|
||||||
|
debug-mode-desc: "Toto nastavení je uloženo v prohlížeči."
|
||||||
|
navbar-position: "Poloha navigačního panelu"
|
||||||
navbar-position-top: "Nahoře"
|
navbar-position-top: "Nahoře"
|
||||||
navbar-position-left: "Vlevo"
|
navbar-position-left: "Vlevo"
|
||||||
navbar-position-right: "Vpravo"
|
navbar-position-right: "Vpravo"
|
||||||
i-am-under-limited-internet: "Mam omezený (pomalý) internet"
|
i-am-under-limited-internet: "Mam omezený (pomalý) internet"
|
||||||
|
post-style: "Styl zobrazení poznámek"
|
||||||
|
post-style-standard: "Standardní"
|
||||||
post-style-smart: "Chytrý"
|
post-style-smart: "Chytrý"
|
||||||
|
notification-position: "Poloha oznámení"
|
||||||
notification-position-bottom: "Dole"
|
notification-position-bottom: "Dole"
|
||||||
notification-position-top: "Nahoře"
|
notification-position-top: "Nahoře"
|
||||||
load-raw-images: "Zobrazit obrázky v originální kvalitě"
|
disable-via-mobile: "Neoznačovat příspěvky jako „z mobilu“"
|
||||||
search: "Vyhledávání"
|
load-raw-images: "Zobrazovat obrázky v původní kvalitě"
|
||||||
|
load-remote-media: "Zobrazovat média ze vzdáleného serveru"
|
||||||
|
search: "Hledání"
|
||||||
delete: "Odstranit"
|
delete: "Odstranit"
|
||||||
loading: "Nahrávám..."
|
loading: "Načítám..."
|
||||||
ok: "OK"
|
ok: "OK"
|
||||||
cancel: "Zrušit"
|
cancel: "Zrušit"
|
||||||
update-available-title: "Aktualizace k dispozici"
|
update-available-title: "Aktualizace k dispozici"
|
||||||
update-available: "Nová verze Misskey je k dispozici({newer}, Vaše verze je {current}). Načtěte znovu stránku pro aktivování nové verze."
|
update-available: "Je k dispozici nová verze Misskey ({newer},vaše verze je {current}). Pro aplikování nové verze znovunačtěte stránku."
|
||||||
verified-user: "Ověřené účty"
|
verified-user: "Ověřené účty"
|
||||||
hide-password: "Skrýt heslo"
|
hide-password: "Skrýt heslo"
|
||||||
show-password: "Zobrazit heslo"
|
show-password: "Zobrazit heslo"
|
||||||
do-not-use-in-production: "Tohle je vývojářský build. Nepoužívejte v produkci."
|
do-not-use-in-production: "Tohle je vývojářský build. Nepoužívejte v produkci."
|
||||||
user-suspended: "Tomuto uživateli byl pozastaven účet."
|
user-suspended: "Tomuto uživateli byl pozastaven účet."
|
||||||
is-remote-user: "Informace o tomto uživateli nemusí být kompletní."
|
is-remote-user: "Informace o tomto uživateli nemusí být kompletní."
|
||||||
|
is-remote-post: "Obsah tohoto příspěvku je zrcadlen."
|
||||||
|
view-on-remote: "Pro kompletnost jej zobrazte vzdáleně."
|
||||||
|
renoted-by: "{user} renotoval/a"
|
||||||
|
no-notes: "Bez poznámek"
|
||||||
|
turn-on-darkmode: "Přepnout na tmavý režim"
|
||||||
|
turn-off-darkmode: "Světlý režim"
|
||||||
error:
|
error:
|
||||||
|
title: "Něco se stalo :("
|
||||||
retry: "Zkusit znovu"
|
retry: "Zkusit znovu"
|
||||||
reversi:
|
reversi:
|
||||||
drawn: "Remíza"
|
drawn: "Remíza"
|
||||||
my-turn: "Váš tah"
|
my-turn: "Váš tah"
|
||||||
|
opponent-turn: "Je řada na protivníkovi"
|
||||||
turn-of: "{name} je na tahu"
|
turn-of: "{name} je na tahu"
|
||||||
won: "{name} vyhrál"
|
past-turn-of: "{name} byl/a na tahu"
|
||||||
|
won: "{name} vyhrál/a"
|
||||||
black: "Černá"
|
black: "Černá"
|
||||||
white: "Bílá"
|
white: "Bílá"
|
||||||
total: "Celkem"
|
total: "Celkem"
|
||||||
|
this-turn: "{count}. kolo"
|
||||||
widgets:
|
widgets:
|
||||||
analog-clock: "Analogové hodiny"
|
analog-clock: "Analogové hodiny"
|
||||||
profile: "Profil"
|
profile: "Profil"
|
||||||
calendar: "Kalendář"
|
calendar: "Kalendář"
|
||||||
|
timemachine: "Kalendář (Stroj času)"
|
||||||
activity: "Aktivita"
|
activity: "Aktivita"
|
||||||
rss: "RSS čtečka"
|
rss: "RSS čtečka"
|
||||||
memo: "Poznámky"
|
memo: "Rychlé poznámky"
|
||||||
trends: "Trendy"
|
trends: "Trendy"
|
||||||
|
photo-stream: "Proud fotek"
|
||||||
posts-monitor: "Grafy příspěvků"
|
posts-monitor: "Grafy příspěvků"
|
||||||
slideshow: "Prezentace"
|
slideshow: "Prezentace"
|
||||||
version: "Verze"
|
version: "Verze"
|
||||||
|
broadcast: "Rozhlas"
|
||||||
notifications: "Oznámení"
|
notifications: "Oznámení"
|
||||||
users: "Doporučení uživatelé"
|
users: "Doporučení uživatelé"
|
||||||
polls: "Ankety"
|
polls: "Ankety"
|
||||||
|
post-form: "Formulář pro psaní"
|
||||||
server: "Informace o serveru"
|
server: "Informace o serveru"
|
||||||
nav: "Navigace"
|
nav: "Navigace"
|
||||||
|
tips: "Tipy"
|
||||||
hashtags: "Hashtagy"
|
hashtags: "Hashtagy"
|
||||||
dev: "Nepodařilo se vytvořit aplikace. Prosím zkuste to znovu."
|
dev: "Nepodařilo se vytvořit aplikace. Prosím zkuste to znovu."
|
||||||
ai-chan-kawaii: "Ai-chan kawaii!"
|
ai-chan-kawaii: "Ai-chan kawaii!"
|
||||||
you: "Vy"
|
you: "Vy"
|
||||||
auth/views/form.vue:
|
auth/views/form.vue:
|
||||||
share-access: "Chcete dovolit <i>{name}</i> přístup k Vašemu účtu?"
|
share-access: "Chcete dovolit aplikaci <i>{name}</i> přístup k vašemu účtu?"
|
||||||
permission-ask: "Tato aplikace vyžaduje následující oprávnění:"
|
permission-ask: "Tato aplikace vyžaduje následující oprávnění:"
|
||||||
|
account-read: "Zobrazit informace účtu"
|
||||||
|
note-write: "Odeslat."
|
||||||
|
following-write: "Sledovat a přestat sledovat"
|
||||||
|
drive-read: "Přečíst váš Disk"
|
||||||
|
notification-read: "Sledovat oznámení."
|
||||||
|
notification-write: "Zpravovat notifikace."
|
||||||
cancel: "Zrušit"
|
cancel: "Zrušit"
|
||||||
|
accept: "Povolit přístup"
|
||||||
auth/views/index.vue:
|
auth/views/index.vue:
|
||||||
loading: "Nahrávám..."
|
loading: "Načítám..."
|
||||||
|
already-authorized: "Tato aplikace byla již autorizována."
|
||||||
|
error: "Taková relace neexistuje."
|
||||||
|
sign-in: "Prosím přihlaste se."
|
||||||
common/views/pages/explore.vue:
|
common/views/pages/explore.vue:
|
||||||
verified-users: "Ověřené účty"
|
verified-users: "Ověřené účty"
|
||||||
|
popular-users: "Populární uživatelé"
|
||||||
|
recently-updated-users: "Nedávno aktívni uživatelé"
|
||||||
|
recently-registered-users: "Nedávno registrovaní uživatelé"
|
||||||
popular-tags: "Populární tagy"
|
popular-tags: "Populární tagy"
|
||||||
federated: "Z fediversu"
|
federated: "Z fedivesmíru"
|
||||||
|
explore: "Prozkoumat {host}"
|
||||||
|
common/views/components/url-preview.vue:
|
||||||
|
enable-player: "Otevřít v přehrávači"
|
||||||
|
disable-player: "Zavřít přehrávač"
|
||||||
common/views/components/user-list.vue:
|
common/views/components/user-list.vue:
|
||||||
no-users: "Žádní uživatelé"
|
no-users: "Žádní uživatelé"
|
||||||
common/views/components/games/reversi/reversi.vue:
|
common/views/components/games/reversi/reversi.vue:
|
||||||
matching:
|
matching:
|
||||||
|
waiting-for: "Čeká se na {}"
|
||||||
cancel: "Zrušit"
|
cancel: "Zrušit"
|
||||||
common/views/components/games/reversi/reversi.game.vue:
|
common/views/components/games/reversi/reversi.game.vue:
|
||||||
surrender: "Vzdát se"
|
surrender: "Vzdát se"
|
||||||
@@ -235,14 +323,21 @@ common/views/components/games/reversi/reversi.index.vue:
|
|||||||
my-games: "Moje hra"
|
my-games: "Moje hra"
|
||||||
all-games: "Všechny hry"
|
all-games: "Všechny hry"
|
||||||
enter-username: "Zadejte své uživatelské jméno"
|
enter-username: "Zadejte své uživatelské jméno"
|
||||||
|
game-state:
|
||||||
|
ended: "Ukončené"
|
||||||
|
playing: "Probíhají"
|
||||||
common/views/components/games/reversi/reversi.room.vue:
|
common/views/components/games/reversi/reversi.room.vue:
|
||||||
settings-of-the-game: "Nastavení hry"
|
settings-of-the-game: "Nastavení hry"
|
||||||
choose-map: "Vybrat mapu"
|
choose-map: "Vybrat mapu"
|
||||||
random: "Náhodně"
|
random: "Náhodně"
|
||||||
|
black-or-white: "Černé/bílé"
|
||||||
black-is: "Černá je {}"
|
black-is: "Černá je {}"
|
||||||
rules: "Pravidla"
|
rules: "Pravidla"
|
||||||
looped-map: "Zacyklená mapa"
|
looped-map: "Zacyklená mapa"
|
||||||
|
settings-of-the-bot: "Nastavení Botu"
|
||||||
this-game-is-started-soon: "Hra začne za pár vteřin"
|
this-game-is-started-soon: "Hra začne za pár vteřin"
|
||||||
|
waiting-for-other: "Čeká se na protivníka"
|
||||||
|
waiting-for-me: "Čeká se na Vás"
|
||||||
waiting-for-both: "Připravuji"
|
waiting-for-both: "Připravuji"
|
||||||
cancel: "Zrušit"
|
cancel: "Zrušit"
|
||||||
ready: "Připraveno"
|
ready: "Připraveno"
|
||||||
@@ -255,7 +350,22 @@ common/views/components/connect-failed.troubleshooter.vue:
|
|||||||
checking-network: "Prověřit síťové připojení"
|
checking-network: "Prověřit síťové připojení"
|
||||||
internet: "Připojení k internetu"
|
internet: "Připojení k internetu"
|
||||||
checking-internet: "Ověřuji připojení k internetu."
|
checking-internet: "Ověřuji připojení k internetu."
|
||||||
|
server: "Připojení k serveru"
|
||||||
|
no-network-desc: "Ujistěte se že jste připojeni k Internetu."
|
||||||
|
no-internet: "Nejste připojeni k internetu"
|
||||||
|
no-internet-desc: "Jste připojen k síti, ale zdá se že stále chybí připojení k Internetu. Prosím zkontrolujte Vaše připojení k Internetu."
|
||||||
|
common/views/components/media-banner.vue:
|
||||||
|
click-to-show: "Klikněte pro zobrazení"
|
||||||
common/views/components/theme.vue:
|
common/views/components/theme.vue:
|
||||||
|
light-theme: "Šablona pro použití ve světlém vzhledu"
|
||||||
|
dark-theme: "Šablona pro použití v tmavém vzhledu"
|
||||||
|
light-themes: "Světlý vzhled"
|
||||||
|
dark-themes: "Tmavý vzhled"
|
||||||
|
install-a-theme: "Nainstalovat šablonu"
|
||||||
|
theme-code: "Kód šablony"
|
||||||
|
install: "Nainstalovat"
|
||||||
|
installed: "\"{}\" byl nainstalován"
|
||||||
|
create-a-theme: "Vytvořit motiv"
|
||||||
base-theme: "Základní vzhled"
|
base-theme: "Základní vzhled"
|
||||||
find-more-theme: "Najít další vzhledy"
|
find-more-theme: "Najít další vzhledy"
|
||||||
theme-name: "Jméno vzhledu"
|
theme-name: "Jméno vzhledu"
|
||||||
@@ -289,6 +399,7 @@ common/views/components/messaging-room.vue:
|
|||||||
only-one-file-attached: "Jenom JEDEN soubor může být přiložen ke zprávě."
|
only-one-file-attached: "Jenom JEDEN soubor může být přiložen ke zprávě."
|
||||||
common/views/components/messaging-room.form.vue:
|
common/views/components/messaging-room.form.vue:
|
||||||
send: "Odeslat"
|
send: "Odeslat"
|
||||||
|
attach-from-local: "Přiložit soubory z Vašeho zařízení"
|
||||||
only-one-file-attached: "Jenom JEDEN soubor může být přiložen ke zprávě."
|
only-one-file-attached: "Jenom JEDEN soubor může být přiložen ke zprávě."
|
||||||
common/views/components/messaging-room.message.vue:
|
common/views/components/messaging-room.message.vue:
|
||||||
is-read: "Přečtené"
|
is-read: "Přečtené"
|
||||||
@@ -301,13 +412,44 @@ common/views/components/nav.vue:
|
|||||||
donors: "Dárci"
|
donors: "Dárci"
|
||||||
repository: "Úložiště"
|
repository: "Úložiště"
|
||||||
develop: "Vývojáři"
|
develop: "Vývojáři"
|
||||||
|
feedback: "Zpětná vazba"
|
||||||
common/views/components/note-menu.vue:
|
common/views/components/note-menu.vue:
|
||||||
|
mention: "Zmínění"
|
||||||
|
detail: "Více"
|
||||||
|
copy-content: "Zkopírovat obsah"
|
||||||
|
copy-link: "Zkopírovat odkaz"
|
||||||
|
favorite: "Přidat do oblíbených"
|
||||||
|
unfavorite: "Odebrat z oblízených"
|
||||||
|
watch: "Sledovat"
|
||||||
|
unwatch: "Přestat sledovat"
|
||||||
|
pin: "Připnout"
|
||||||
|
unpin: "Odepnout"
|
||||||
delete: "Odstranit"
|
delete: "Odstranit"
|
||||||
delete-confirm: "Opravdu chcete smazat tento příspěvek?"
|
delete-confirm: "Opravdu chcete smazat tento příspěvek?"
|
||||||
|
remote: "Ukázat originální poznámku"
|
||||||
common/views/components/user-menu.vue:
|
common/views/components/user-menu.vue:
|
||||||
|
mention: "Zmínění"
|
||||||
mute: "Umlčet"
|
mute: "Umlčet"
|
||||||
block: "Blokováno"
|
unmute: "Zrušit umlčení"
|
||||||
|
block: "Blokován"
|
||||||
|
unblock: "Odblokovat"
|
||||||
|
push-to-list: "Přidat do seznamu"
|
||||||
|
select-list: "Vyberte seznam"
|
||||||
|
report-abuse-reported: "Problém byl nahlášen administrátorovi. Děkujeme za Vaší kooperaci."
|
||||||
|
common/views/components/poll.vue:
|
||||||
|
vote-count: "{} hlasů"
|
||||||
|
vote: "Hlasovat"
|
||||||
|
show-result: "Podívat se na výsledky"
|
||||||
|
voted: "Už jste hlasovaly"
|
||||||
|
remaining-days: "zbývá {d} dnů, {h} hodin"
|
||||||
|
remaining-hours: "zbývá {h} hodin, a {m} minut"
|
||||||
|
remaining-minutes: "zbývá {m} minut, a {s} sekund"
|
||||||
|
remaining-seconds: "zbývá {s} sekund"
|
||||||
|
common/views/components/poll-editor.vue:
|
||||||
|
no-only-one-choice: "Musíte vybrat alespoň dvě možnosti"
|
||||||
|
day: "Ne"
|
||||||
common/views/components/emoji-picker.vue:
|
common/views/components/emoji-picker.vue:
|
||||||
|
custom-emoji: "Emoji"
|
||||||
people: "Lidé"
|
people: "Lidé"
|
||||||
animals-and-nature: "Zvířata a příroda"
|
animals-and-nature: "Zvířata a příroda"
|
||||||
food-and-drink: "Jídlo a pití"
|
food-and-drink: "Jídlo a pití"
|
||||||
@@ -360,20 +502,53 @@ common/views/components/notification-settings.vue:
|
|||||||
mark-as-read-all-notifications: "Označit všechna oznámení za přečtená"
|
mark-as-read-all-notifications: "Označit všechna oznámení za přečtená"
|
||||||
mark-as-read-all-unread-notes: "Označit všechny příspěvky za přečtené"
|
mark-as-read-all-unread-notes: "Označit všechny příspěvky za přečtené"
|
||||||
mark-as-read-all-talk-messages: "Označit všechny zprávy za přečtené"
|
mark-as-read-all-talk-messages: "Označit všechny zprávy za přečtené"
|
||||||
|
common/views/components/integration-settings.vue:
|
||||||
|
connect: "Připojit"
|
||||||
|
disconnect: "Odpojit"
|
||||||
common/views/components/github-setting.vue:
|
common/views/components/github-setting.vue:
|
||||||
description: "Jakmile spojíte Váš GitHub účet s Vaším Misskey účtem, uvidíte informace o Vašem GitHub účtu na Vašem profilu a budete se moci přihlásit skrze GitHub."
|
description: "Jakmile spojíte Váš GitHub účet s Vaším Misskey účtem, uvidíte informace o Vašem GitHub účtu na Vašem profilu a budete se moci přihlásit skrze GitHub."
|
||||||
|
connected-to: "Je připojen k tomuto GitHub účtu"
|
||||||
detail: "Více…"
|
detail: "Více…"
|
||||||
|
reconnect: "Znovu připojit"
|
||||||
|
connect: "Připojit Váš GitHub účet"
|
||||||
|
disconnect: "Odpojit"
|
||||||
common/views/components/discord-setting.vue:
|
common/views/components/discord-setting.vue:
|
||||||
description: "Jakmile spojíte Váš Discord účet s Vaším Misskey účtem, uvidíte informace o Vašem Discord účtu na Vašem profilu a budete se moci přihlásit skrze Discord."
|
description: "Jakmile spojíte Váš Discord účet s Vaším Misskey účtem, uvidíte informace o Vašem Discord účtu na Vašem profilu a budete se moci přihlásit skrze Discord."
|
||||||
|
connected-to: "Je připojen k tomuto Discord účtu"
|
||||||
detail: "Více…"
|
detail: "Více…"
|
||||||
|
reconnect: "Znovu připojit"
|
||||||
|
connect: "Připojit Váš Discord účet"
|
||||||
|
disconnect: "Odpojit"
|
||||||
|
common/views/components/uploader.vue:
|
||||||
|
waiting: "Čekáme"
|
||||||
common/views/components/visibility-chooser.vue:
|
common/views/components/visibility-chooser.vue:
|
||||||
local-public: "Veřejný (pouze místní)"
|
public: "Veřejné"
|
||||||
local-home: "Domovský (pouze místní)"
|
home: "Domů"
|
||||||
|
specified-desc: "Poslat pouze zmíněným uživatelům"
|
||||||
|
local-public: "Veřejná (pouze místní)"
|
||||||
|
local-home: "Domovská (pouze místní)"
|
||||||
local-followers: "Pro sledující (pouze místní)"
|
local-followers: "Pro sledující (pouze místní)"
|
||||||
|
common/views/components/trends.vue:
|
||||||
|
count: "{} zmíněných uživatelů"
|
||||||
|
empty: "Žádný trend"
|
||||||
|
common/views/components/language-settings.vue:
|
||||||
|
title: "Zobrazit jazyky"
|
||||||
|
pick-language: "Zvolte jazyk"
|
||||||
|
recommended: "Doporučené"
|
||||||
|
info: "Pro aktivování změn musíte znovu načíst stránky."
|
||||||
common/views/components/profile-editor.vue:
|
common/views/components/profile-editor.vue:
|
||||||
title: "Profil"
|
title: "Profil"
|
||||||
|
name: "Jméno"
|
||||||
|
account: "Účet"
|
||||||
|
location: "Lokace"
|
||||||
|
description: "O mně"
|
||||||
|
you-can-include-hashtags: "V popisku o Vás můžete použít i hastagy."
|
||||||
|
language: "Jazyk"
|
||||||
|
birthday: "Datum narození"
|
||||||
avatar: "Avatar"
|
avatar: "Avatar"
|
||||||
banner: "Baner"
|
banner: "Baner"
|
||||||
|
is-cat: "Tento účet je kočka"
|
||||||
|
is-bot: "Tento účet je Bot"
|
||||||
advanced: "Ostatní"
|
advanced: "Ostatní"
|
||||||
privacy: "Osobní údaje"
|
privacy: "Osobní údaje"
|
||||||
save: "Uložit"
|
save: "Uložit"
|
||||||
@@ -385,10 +560,12 @@ common/views/components/profile-editor.vue:
|
|||||||
email-verified: "Váš e-mail byl ověřen"
|
email-verified: "Váš e-mail byl ověřen"
|
||||||
email-not-verified: "Váš email není potvrzen. Prosím zkontrolujte si svou schránku."
|
email-not-verified: "Váš email není potvrzen. Prosím zkontrolujte si svou schránku."
|
||||||
export: "Exportovat"
|
export: "Exportovat"
|
||||||
|
import: "Importovat"
|
||||||
export-targets:
|
export-targets:
|
||||||
following-list: "Seznam následovníků"
|
following-list: "Seznam sledujících"
|
||||||
mute-list: "Seznam ztlumených uživatelů"
|
mute-list: "Seznam ztlumených uživatelů"
|
||||||
blocking-list: "Seznam blokovaných uživatelů"
|
blocking-list: "Seznam blokovaných uživatelů"
|
||||||
|
user-lists: "Seznamy"
|
||||||
enter-password: "Prosím, zadejte Vaše heslo"
|
enter-password: "Prosím, zadejte Vaše heslo"
|
||||||
danger-zone: "Nebezpečná zóna"
|
danger-zone: "Nebezpečná zóna"
|
||||||
delete-account: "Smazat účet"
|
delete-account: "Smazat účet"
|
||||||
@@ -401,6 +578,7 @@ common/views/components/user-list-editor.vue:
|
|||||||
delete-are-you-sure: "Smazat seznam \"$1\"?"
|
delete-are-you-sure: "Smazat seznam \"$1\"?"
|
||||||
deleted: "Smazáno"
|
deleted: "Smazáno"
|
||||||
common/views/widgets/broadcast.vue:
|
common/views/widgets/broadcast.vue:
|
||||||
|
fetching: "Načítám"
|
||||||
next: "Další"
|
next: "Další"
|
||||||
common/views/widgets/calendar.vue:
|
common/views/widgets/calendar.vue:
|
||||||
year: "Rok {}"
|
year: "Rok {}"
|
||||||
@@ -413,10 +591,12 @@ common/views/widgets/photo-stream.vue:
|
|||||||
no-photos: "Žádné obrázky"
|
no-photos: "Žádné obrázky"
|
||||||
common/views/widgets/posts-monitor.vue:
|
common/views/widgets/posts-monitor.vue:
|
||||||
title: "Grafy příspěvků"
|
title: "Grafy příspěvků"
|
||||||
|
toggle: "Přepnout zobrazení"
|
||||||
common/views/widgets/hashtags.vue:
|
common/views/widgets/hashtags.vue:
|
||||||
title: "Hashtagy"
|
title: "Hashtagy"
|
||||||
common/views/widgets/server.vue:
|
common/views/widgets/server.vue:
|
||||||
title: "Informace o serveru"
|
title: "Informace o serveru"
|
||||||
|
toggle: "Přepnout zobrazení"
|
||||||
common/views/widgets/memo.vue:
|
common/views/widgets/memo.vue:
|
||||||
title: "Poznámky"
|
title: "Poznámky"
|
||||||
memo: "Pište sem!"
|
memo: "Pište sem!"
|
||||||
@@ -425,12 +605,19 @@ common/views/widgets/slideshow.vue:
|
|||||||
no-image: "V této složce nebyly nalezeny žádné fotky."
|
no-image: "V této složce nebyly nalezeny žádné fotky."
|
||||||
desktop:
|
desktop:
|
||||||
banner: "Baner"
|
banner: "Baner"
|
||||||
|
avatar-crop-title: "Vyberte část, která se zobrazí jako avatar"
|
||||||
|
avatar: "Avatar"
|
||||||
|
uploading-avatar: "Nahrál nový avatar"
|
||||||
|
avatar-updated: "Vaše avatar byl aktualizován"
|
||||||
|
invalid-filetype: "Tento formát souboru není podporován"
|
||||||
desktop/views/components/activity.chart.vue:
|
desktop/views/components/activity.chart.vue:
|
||||||
total: "Černá ... Celkem"
|
total: "Černá ... Celkem"
|
||||||
notes: "Modrá ... Poznámky"
|
notes: "Modrá ... Poznámky"
|
||||||
replies: "Červená ... Odpovědi"
|
replies: "Červená ... Odpovědi"
|
||||||
|
renotes: "Zelená ... Renoty"
|
||||||
desktop/views/components/activity.vue:
|
desktop/views/components/activity.vue:
|
||||||
title: "Aktivita"
|
title: "Aktivita"
|
||||||
|
toggle: "Přepnout zobrazení"
|
||||||
desktop/views/components/calendar.vue:
|
desktop/views/components/calendar.vue:
|
||||||
title: "{month}. {year}"
|
title: "{month}. {year}"
|
||||||
prev: "Předchozí měsíc"
|
prev: "Předchozí měsíc"
|
||||||
@@ -448,6 +635,8 @@ desktop/views/components/choose-folder-from-drive-window.vue:
|
|||||||
desktop/views/components/crop-window.vue:
|
desktop/views/components/crop-window.vue:
|
||||||
cancel: "Zrušit"
|
cancel: "Zrušit"
|
||||||
ok: "OK"
|
ok: "OK"
|
||||||
|
desktop/views/components/drive-window.vue:
|
||||||
|
used: "využito"
|
||||||
desktop/views/components/drive.file.vue:
|
desktop/views/components/drive.file.vue:
|
||||||
avatar: "Avatar"
|
avatar: "Avatar"
|
||||||
banner: "Baner"
|
banner: "Baner"
|
||||||
@@ -479,10 +668,42 @@ desktop/views/components/drive.vue:
|
|||||||
empty-folder: "Tato složka je prázdná"
|
empty-folder: "Tato složka je prázdná"
|
||||||
unable-to-process: "Operace nemohla být dokončena."
|
unable-to-process: "Operace nemohla být dokončena."
|
||||||
unhandled-error: "Neznámá chyba"
|
unhandled-error: "Neznámá chyba"
|
||||||
|
url-upload: "Nahrát z URL adresy"
|
||||||
|
url-of-file: "URL adresa souboru, který chcete nahrát"
|
||||||
|
may-take-time: "Může trvat nějakou dobu, dokud nebude dokončeno nahrávání."
|
||||||
|
create-folder: "Vytvořit složku"
|
||||||
|
folder-name: "Název složky"
|
||||||
|
contextmenu:
|
||||||
|
create-folder: "Vytvořit složku"
|
||||||
|
upload: "Nahrát soubor"
|
||||||
|
url-upload: "Nahrát z URL"
|
||||||
|
desktop/views/components/media-video.vue:
|
||||||
|
click-to-show: "Klikněte pro zobrazení"
|
||||||
|
desktop/views/components/game-window.vue:
|
||||||
|
game: "Reversi"
|
||||||
|
desktop/views/components/home.vue:
|
||||||
|
done: "Hotovo"
|
||||||
|
add: "Přidat"
|
||||||
desktop/views/input-dialog.vue:
|
desktop/views/input-dialog.vue:
|
||||||
cancel: "Zrušit"
|
cancel: "Zrušit"
|
||||||
|
ok: "OK"
|
||||||
|
desktop/views/components/messaging-room-window.vue:
|
||||||
|
title: "Zprávy:"
|
||||||
|
desktop/views/components/messaging-window.vue:
|
||||||
|
title: "Zprávy"
|
||||||
|
desktop/views/components/note-detail.vue:
|
||||||
|
private: "Tento příspěvek je soukromý"
|
||||||
|
deleted: "Tento příspěvek byl odstraněn"
|
||||||
|
renote: "Renotovat"
|
||||||
|
add-reaction: "Přidat reakci"
|
||||||
|
undo-reaction: "Odebrat reakci"
|
||||||
desktop/views/components/note.vue:
|
desktop/views/components/note.vue:
|
||||||
reply: "Odpovědět"
|
reply: "Odpovědět"
|
||||||
|
renote: "Renote"
|
||||||
|
add-reaction: "Přidat reakci"
|
||||||
|
undo-reaction: "Odebrat reakci"
|
||||||
|
detail: "Více"
|
||||||
|
private: "Tento příspěvek je soukromý"
|
||||||
deleted: "Tento příspěvek byl odstraněn"
|
deleted: "Tento příspěvek byl odstraněn"
|
||||||
desktop/views/components/notes.vue:
|
desktop/views/components/notes.vue:
|
||||||
error: "Načítání selhalo."
|
error: "Načítání selhalo."
|
||||||
@@ -493,37 +714,62 @@ desktop/views/components/post-form.vue:
|
|||||||
hide-contents: "Schovat obsah"
|
hide-contents: "Schovat obsah"
|
||||||
reply-placeholder: "Odpovědět na tento příspěvěk"
|
reply-placeholder: "Odpovědět na tento příspěvěk"
|
||||||
quote-placeholder: "Citovat tento příspěvek"
|
quote-placeholder: "Citovat tento příspěvek"
|
||||||
|
submit: "Příspěvek"
|
||||||
reply: "Odpovědět"
|
reply: "Odpovědět"
|
||||||
|
renote: "Renotovat"
|
||||||
posted: "Odesláno!"
|
posted: "Odesláno!"
|
||||||
replied: "Odpověděno!"
|
replied: "Odpověděno!"
|
||||||
|
reposted: "Renotováno!"
|
||||||
|
note-failed: "Nepodařilo se přidat příspěvek"
|
||||||
|
renote-failed: "Renotování neuspělo"
|
||||||
insert-a-kao: "v('ω')v"
|
insert-a-kao: "v('ω')v"
|
||||||
create-poll: "Vytvořit anketu"
|
create-poll: "Vytvořit anketu"
|
||||||
text-remain: "{0} znaků zbývá"
|
text-remain: "{0} znaků zbývá"
|
||||||
recent-tags: "Nejnovější"
|
recent-tags: "Nejnovější"
|
||||||
visibility: "Viditelnost"
|
visibility: "Viditelnost"
|
||||||
|
geolocation-alert: "Vaše zařízení nepodporuje lokační službu"
|
||||||
error: "Chyba"
|
error: "Chyba"
|
||||||
enter-username: "Zadejte své uživatelské jméno..."
|
enter-username: "Zadejte své uživatelské jméno..."
|
||||||
desktop/views/components/post-form-window.vue:
|
desktop/views/components/post-form-window.vue:
|
||||||
note: "Nový příspěvek"
|
note: "Nový příspěvek"
|
||||||
reply: "Odpovědět"
|
reply: "Odpovědět"
|
||||||
|
desktop/views/components/progress-dialog.vue:
|
||||||
|
waiting: "Čekáme"
|
||||||
desktop/views/components/renote-form.vue:
|
desktop/views/components/renote-form.vue:
|
||||||
|
quote: "Citovat..."
|
||||||
cancel: "Zrušit"
|
cancel: "Zrušit"
|
||||||
|
renote: "Renotovat"
|
||||||
|
renote-home: "Renote (domů)"
|
||||||
|
reposting: "Renotuji..."
|
||||||
|
success: "Renotováno!"
|
||||||
|
failure: "Renotování neuspělo"
|
||||||
|
desktop/views/components/renote-form-window.vue:
|
||||||
|
title: "Chcete tohle renotovat?"
|
||||||
desktop/views/components/settings.2fa.vue:
|
desktop/views/components/settings.2fa.vue:
|
||||||
detail: "Více…"
|
detail: "Více…"
|
||||||
url: "https://www.google.cz/landing/2step/"
|
url: "https://www.google.cz/landing/2step/"
|
||||||
|
common/views/components/media-image.vue:
|
||||||
|
click-to-show: "Klikněte pro zobrazení"
|
||||||
common/views/components/api-settings.vue:
|
common/views/components/api-settings.vue:
|
||||||
|
token: "Token:"
|
||||||
|
enter-password: "Prosím zadejte heslo"
|
||||||
console:
|
console:
|
||||||
title: "API konzole"
|
title: "API konzole"
|
||||||
|
endpoint: "Endpoint"
|
||||||
parameter: "Parametry"
|
parameter: "Parametry"
|
||||||
send: "Odeslat"
|
send: "Odeslat"
|
||||||
sending: "Odesílám"
|
sending: "Odesílám"
|
||||||
response: "Výsledek"
|
response: "Výsledek"
|
||||||
|
desktop/views/components/settings.apps.vue:
|
||||||
|
no-apps: "Žádné připojené aplikace"
|
||||||
common/views/components/drive-settings.vue:
|
common/views/components/drive-settings.vue:
|
||||||
|
max: "Velikost úložiště"
|
||||||
|
in-use: "využito"
|
||||||
stats: "Statistiky"
|
stats: "Statistiky"
|
||||||
common/views/components/mute-and-block.vue:
|
common/views/components/mute-and-block.vue:
|
||||||
mute-and-block: "Umlčet / Blokovat"
|
mute-and-block: "Umlčet/blokovat"
|
||||||
mute: "Umlčet"
|
mute: "Umlčet"
|
||||||
block: "Blokováno"
|
block: "Blokován"
|
||||||
no-muted-users: "Žádný uživatel nebyl umlčen"
|
no-muted-users: "Žádný uživatel nebyl umlčen"
|
||||||
no-blocked-users: "Žádný uživatel není blokován"
|
no-blocked-users: "Žádný uživatel není blokován"
|
||||||
save: "Uložit"
|
save: "Uložit"
|
||||||
@@ -546,21 +792,55 @@ desktop/views/components/settings.tags.vue:
|
|||||||
desktop/views/components/taskmanager.vue:
|
desktop/views/components/taskmanager.vue:
|
||||||
title: "Správce úloh"
|
title: "Správce úloh"
|
||||||
desktop/views/components/timeline.vue:
|
desktop/views/components/timeline.vue:
|
||||||
|
home: "Domů"
|
||||||
local: "Lokální"
|
local: "Lokální"
|
||||||
global: "Globální"
|
global: "Globální"
|
||||||
|
mentions: "Zmínění"
|
||||||
|
messages: "Zprávy"
|
||||||
list: "Seznamy"
|
list: "Seznamy"
|
||||||
hashtag: "Hashtag"
|
hashtag: "Hashtag"
|
||||||
add-list: "Přidat do seznamu"
|
add-list: "Přidat do seznamu"
|
||||||
list-name: "Název seznamu"
|
list-name: "Název seznamu"
|
||||||
desktop/views/components/ui.header.vue:
|
desktop/views/components/ui.header.vue:
|
||||||
welcome-back: "Vítejte zpátky,"
|
welcome-back: "Vítejte zpátky,"
|
||||||
|
adjective: "Pán"
|
||||||
desktop/views/components/ui.header.account.vue:
|
desktop/views/components/ui.header.account.vue:
|
||||||
profile: "Váš profil"
|
profile: "Váš profil"
|
||||||
|
lists: "Seznamy"
|
||||||
|
admin: "Administrace"
|
||||||
|
desktop/views/components/ui.header.nav.vue:
|
||||||
|
game: "Hry"
|
||||||
|
desktop/views/components/ui.header.notifications.vue:
|
||||||
|
title: "Oznámení"
|
||||||
desktop/views/components/ui.header.post.vue:
|
desktop/views/components/ui.header.post.vue:
|
||||||
post: "Nový příspěvek"
|
post: "Nový příspěvek"
|
||||||
|
desktop/views/components/ui.header.search.vue:
|
||||||
|
placeholder: "Vyhledávání"
|
||||||
|
desktop/views/components/received-follow-requests-window.vue:
|
||||||
|
accept: "Přijmout"
|
||||||
|
reject: "Odmítnout"
|
||||||
|
desktop/views/components/user-lists-window.vue:
|
||||||
|
title: "Seznamy uživatelů"
|
||||||
|
create-list: "Vytvořit seznam"
|
||||||
|
list-name: "Název seznamu"
|
||||||
|
desktop/views/components/user-preview.vue:
|
||||||
|
notes: "Příspěvky"
|
||||||
|
desktop/views/components/users-list.vue:
|
||||||
|
all: "Všechny"
|
||||||
|
iknow: "Znáte"
|
||||||
|
fetching: "Načítám…"
|
||||||
|
desktop/views/components/window.vue:
|
||||||
|
close: "Zavřít"
|
||||||
admin/views/index.vue:
|
admin/views/index.vue:
|
||||||
federation: "Z fediversu"
|
instance: "Instance"
|
||||||
|
emoji: "Emoji"
|
||||||
|
moderators: "Moderátoři"
|
||||||
|
users: "Uživatelé"
|
||||||
|
federation: "Federovaná"
|
||||||
|
announcements: "Oznámení"
|
||||||
hashtags: "Hashtagy"
|
hashtags: "Hashtagy"
|
||||||
|
queue: "Fronta úloh"
|
||||||
|
logs: "Logy"
|
||||||
back-to-misskey: "Zpět na Misskey"
|
back-to-misskey: "Zpět na Misskey"
|
||||||
admin/views/dashboard.vue:
|
admin/views/dashboard.vue:
|
||||||
accounts: "Účty"
|
accounts: "Účty"
|
||||||
@@ -568,9 +848,7 @@ admin/views/dashboard.vue:
|
|||||||
drive: "Disk"
|
drive: "Disk"
|
||||||
instances: "Instance"
|
instances: "Instance"
|
||||||
this-instance: "Tato instance"
|
this-instance: "Tato instance"
|
||||||
federated: "Z fediversu"
|
federated: "Federovaná"
|
||||||
admin/views/queue.vue:
|
|
||||||
operation: "Akce"
|
|
||||||
admin/views/abuse.vue:
|
admin/views/abuse.vue:
|
||||||
details: "Popis"
|
details: "Popis"
|
||||||
remove-report: "Odstranit"
|
remove-report: "Odstranit"
|
||||||
@@ -611,9 +889,19 @@ admin/views/instance.vue:
|
|||||||
saved: "Uloženo"
|
saved: "Uloženo"
|
||||||
user-recommendation-config: "Doporučení uživatelé"
|
user-recommendation-config: "Doporučení uživatelé"
|
||||||
email: "Emailová adresa"
|
email: "Emailová adresa"
|
||||||
|
smtp-port: "SMTP Port"
|
||||||
|
smtp-auth: "Provést SMTP autentikaci"
|
||||||
|
smtp-user: "SMTP uživatel"
|
||||||
|
smtp-pass: "SMTP heslo"
|
||||||
|
serviceworker-config: "ServiceWorker"
|
||||||
|
enable-serviceworker: "Povolit ServiceWorker"
|
||||||
|
vapid-publickey: "VAPID veřejný klíč"
|
||||||
|
vapid-privatekey: "VAPID osobní klíč"
|
||||||
admin/views/charts.vue:
|
admin/views/charts.vue:
|
||||||
|
title: "Graf"
|
||||||
per-day: "za den"
|
per-day: "za den"
|
||||||
per-hour: "za hodinu"
|
per-hour: "za hodinu"
|
||||||
|
federation: "Federace"
|
||||||
notes: "Příspěvky"
|
notes: "Příspěvky"
|
||||||
users: "Uživatelé"
|
users: "Uživatelé"
|
||||||
drive: "Disk"
|
drive: "Disk"
|
||||||
@@ -621,11 +909,20 @@ admin/views/charts.vue:
|
|||||||
charts:
|
charts:
|
||||||
federation-instances: "Počet instancí: zvýšení/snížení"
|
federation-instances: "Počet instancí: zvýšení/snížení"
|
||||||
federation-instances-total: "Celkový počet instancí"
|
federation-instances-total: "Celkový počet instancí"
|
||||||
|
notes-total: "Celkem příspěvků"
|
||||||
|
users-total: "Celkem uživatelů"
|
||||||
|
active-users: "Aktivní uživatelé"
|
||||||
|
network-requests: "Požadavek"
|
||||||
network-time: "Doba odezvy"
|
network-time: "Doba odezvy"
|
||||||
|
network-usage: "Síťový provoz"
|
||||||
admin/views/drive.vue:
|
admin/views/drive.vue:
|
||||||
operation: "Operace"
|
operation: "Operace"
|
||||||
|
fileid-or-url: "ID nebo URL souboru"
|
||||||
file-not-found: "Soubor nebyl nalezen"
|
file-not-found: "Soubor nebyl nalezen"
|
||||||
sort:
|
sort:
|
||||||
|
title: "Seřadit"
|
||||||
|
createdAtAsc: "Věk - od nejstaršího"
|
||||||
|
createdAtDesc: "Věk - od nejmladšího"
|
||||||
sizeAsc: "Velikost - od nejmenších"
|
sizeAsc: "Velikost - od nejmenších"
|
||||||
sizeDesc: "Velikost – od největších"
|
sizeDesc: "Velikost – od největších"
|
||||||
origin:
|
origin:
|
||||||
@@ -642,8 +939,17 @@ admin/views/users.vue:
|
|||||||
reset-password: "Resetovat heslo"
|
reset-password: "Resetovat heslo"
|
||||||
reset-password-confirm: "Opravdu chcete resetovat Vaše heslo?"
|
reset-password-confirm: "Opravdu chcete resetovat Vaše heslo?"
|
||||||
password-updated: "Heslo je nyní \"{password}\""
|
password-updated: "Heslo je nyní \"{password}\""
|
||||||
|
verify: "Ověřit účet"
|
||||||
|
verify-confirm: "Chcete aby toto byl ověřený účet?"
|
||||||
|
verified: "Účet se nyní ověřuje"
|
||||||
|
unverify: "Zrušit ověření účtu"
|
||||||
|
unverify-confirm: "Opravdu chcete zrušit designaci \"ověřený účet\"?"
|
||||||
|
unverified: "Ruší se potvrzení účtu"
|
||||||
|
update-remote-user: "Aktualizovat informace o vzdáleném účtu"
|
||||||
users:
|
users:
|
||||||
|
title: "Uživatel"
|
||||||
state:
|
state:
|
||||||
|
all: "Všechny"
|
||||||
moderator: "Moderátor"
|
moderator: "Moderátor"
|
||||||
adminOrModerator: "Admin/Moderátor"
|
adminOrModerator: "Admin/Moderátor"
|
||||||
verified: "Ověřený účet"
|
verified: "Ověřený účet"
|
||||||
@@ -689,67 +995,187 @@ admin/views/announcements.vue:
|
|||||||
admin/views/hashtags.vue:
|
admin/views/hashtags.vue:
|
||||||
hided-tags: "Skryté tagy"
|
hided-tags: "Skryté tagy"
|
||||||
admin/views/federation.vue:
|
admin/views/federation.vue:
|
||||||
federation: "Z fediversu"
|
instance: "Instance"
|
||||||
host: "Hostitel"
|
host: "Hostitel"
|
||||||
notes: "Poznámky"
|
notes: "Poznámky"
|
||||||
users: "Uživatelé"
|
users: "Uživatelé"
|
||||||
|
caught-at: "Vytvořeno"
|
||||||
status: "Status"
|
status: "Status"
|
||||||
latest-request-received-at: "Poslední požadavek přijat"
|
latest-request-received-at: "Poslední požadavek přijat"
|
||||||
block: "Blokováno"
|
block: "Blokován"
|
||||||
|
instances: "Federovaná"
|
||||||
states:
|
states:
|
||||||
blocked: "Blokováno"
|
all: "Všechny"
|
||||||
|
blocked: "Blokován"
|
||||||
|
not-responding: "Bez odpovědi"
|
||||||
|
marked-as-closed: "Označeno jako uzavřené"
|
||||||
|
charts: "Graf"
|
||||||
|
chart-srcs:
|
||||||
|
requests: "Požadavek"
|
||||||
|
users-total: "Celkem uživatelů"
|
||||||
|
notes-total: "Celkem příspěvků"
|
||||||
chart-spans:
|
chart-spans:
|
||||||
hour: "za hodinu"
|
hour: "za hodinu"
|
||||||
day: "za den"
|
day: "za den"
|
||||||
|
desktop/views/pages/welcome.vue:
|
||||||
|
about: "O Misskey"
|
||||||
|
timeline: "Časová osa"
|
||||||
|
announcements: "Oznámení"
|
||||||
|
photos: "Nedávné obrázky"
|
||||||
|
powered-by-misskey: "Běží na <b>Misskey</b>."
|
||||||
|
info: "Informace"
|
||||||
desktop/views/pages/drive.vue:
|
desktop/views/pages/drive.vue:
|
||||||
title: "Misskey Disk"
|
title: "Misskey Disk"
|
||||||
|
desktop/views/pages/note.vue:
|
||||||
|
prev: "Předchozí příspěvěk"
|
||||||
|
next: "Následující příspěvek"
|
||||||
desktop/views/pages/selectdrive.vue:
|
desktop/views/pages/selectdrive.vue:
|
||||||
|
title: "Vyberte soubor(y)"
|
||||||
|
ok: "OK"
|
||||||
cancel: "Zrušit"
|
cancel: "Zrušit"
|
||||||
|
upload: "Nahrajte soubory z vašeho zařízení"
|
||||||
|
desktop/views/pages/search.vue:
|
||||||
|
not-available: "Vyhledávání je vypnuté pro tuto instanci."
|
||||||
|
not-found: "Pro '{q}' nebyly nalezeny žádné příspěvky."
|
||||||
|
desktop/views/pages/tag.vue:
|
||||||
|
no-posts-found: "Nebyly nalezeny žádné příspěvky s \"{q}\"."
|
||||||
desktop/views/pages/user-list.users.vue:
|
desktop/views/pages/user-list.users.vue:
|
||||||
|
users: "Uživatel"
|
||||||
|
add-user: "Přidat uživatele"
|
||||||
username: "Přezdívka"
|
username: "Přezdívka"
|
||||||
desktop/views/pages/user/user.followers-you-know.vue:
|
desktop/views/pages/user/user.followers-you-know.vue:
|
||||||
loading: "Nahrávám..."
|
loading: "Načítám..."
|
||||||
desktop/views/pages/user/user.friends.vue:
|
desktop/views/pages/user/user.friends.vue:
|
||||||
loading: "Nahrávám..."
|
title: "Častá zmínění"
|
||||||
|
loading: "Načítám..."
|
||||||
|
no-users: "Žádná častá zmínění"
|
||||||
desktop/views/pages/user/user.photos.vue:
|
desktop/views/pages/user/user.photos.vue:
|
||||||
loading: "Nahrávám..."
|
title: "Fotky"
|
||||||
|
loading: "Načítám..."
|
||||||
no-photos: "Žádné obrázky"
|
no-photos: "Žádné obrázky"
|
||||||
desktop/views/pages/user/user.header.vue:
|
desktop/views/pages/user/user.header.vue:
|
||||||
|
posts: "Poznámky"
|
||||||
month: "Po"
|
month: "Po"
|
||||||
day: "Ne"
|
day: "Ne"
|
||||||
|
desktop/views/widgets/messaging.vue:
|
||||||
|
title: "Zprávy"
|
||||||
|
desktop/views/widgets/notifications.vue:
|
||||||
|
title: "Oznámení"
|
||||||
desktop/views/widgets/polls.vue:
|
desktop/views/widgets/polls.vue:
|
||||||
title: "Ankety"
|
title: "Ankety"
|
||||||
desktop/views/widgets/users.vue:
|
desktop/views/widgets/users.vue:
|
||||||
title: "Doporučení uživatelé"
|
title: "Doporučení uživatelé"
|
||||||
|
mobile/views/components/drive.vue:
|
||||||
|
used: "využito"
|
||||||
|
file-count: "Soubor(ů)"
|
||||||
|
folder-is-empty: "Tato složka je prázdná"
|
||||||
|
deletion-alert: "Omlouváme se, ale mazání složek ještě nebylo implementováno."
|
||||||
|
folder-name: "Název složky"
|
||||||
|
url-prompt: "URL adresa souboru, který chcete nahrát"
|
||||||
|
uploading: "Byl zahájen upload. Může chvilku trvat než bude dokončen."
|
||||||
|
mobile/views/components/drive-file-chooser.vue:
|
||||||
|
select-file: "Vybrat soubory"
|
||||||
|
mobile/views/components/drive-folder-chooser.vue:
|
||||||
|
select-folder: "Vyberte složku"
|
||||||
mobile/views/components/drive.file-detail.vue:
|
mobile/views/components/drive.file-detail.vue:
|
||||||
download: "Stáhnout"
|
download: "Stáhnout"
|
||||||
rename: "Přejmenovat"
|
rename: "Přejmenovat"
|
||||||
|
move: "Přesunout"
|
||||||
|
hash: "Hash (md5)"
|
||||||
|
exif: "EXIF"
|
||||||
|
mobile/views/components/media-video.vue:
|
||||||
|
click-to-show: "Klikněte pro zobrazení"
|
||||||
|
common/views/components/follow-button.vue:
|
||||||
|
follow-processing: "Zpracovávám"
|
||||||
|
mobile/views/components/note.vue:
|
||||||
|
private: "Tento příspěvek je soukromý"
|
||||||
|
deleted: "Tento příspěvek byl odstraněn"
|
||||||
|
location: "Lokace"
|
||||||
mobile/views/components/note-detail.vue:
|
mobile/views/components/note-detail.vue:
|
||||||
reply: "Odpovědět"
|
reply: "Odpovědět"
|
||||||
|
reaction: "Reakce"
|
||||||
|
private: "Tento příspěvek je soukromý"
|
||||||
|
deleted: "Tento příspěvek byl odstraněn"
|
||||||
|
location: "Lokace"
|
||||||
|
mobile/views/components/note-preview.vue:
|
||||||
|
admin: "admin"
|
||||||
|
bot: "bot"
|
||||||
|
cat: "kočka"
|
||||||
|
mobile/views/components/note-sub.vue:
|
||||||
|
admin: "admin"
|
||||||
|
bot: "bot"
|
||||||
|
cat: "kočka"
|
||||||
mobile/views/components/post-form.vue:
|
mobile/views/components/post-form.vue:
|
||||||
|
add-visible-user: "Přidat uživatele"
|
||||||
|
submit: "Příspěvek"
|
||||||
reply: "Odpovědět"
|
reply: "Odpovědět"
|
||||||
|
renote: "Renotovat"
|
||||||
reply-placeholder: "Odpovědět na tento příspěvěk"
|
reply-placeholder: "Odpovědět na tento příspěvěk"
|
||||||
|
location-alert: "Vaše zařízení nepodporuje lokační službu"
|
||||||
|
error: "Chyba"
|
||||||
|
username-prompt: "Zadejte uživatelské jméno"
|
||||||
mobile/views/components/sub-note-content.vue:
|
mobile/views/components/sub-note-content.vue:
|
||||||
|
private: "Tento příspěvek je soukromý"
|
||||||
|
deleted: "Tento příspěvek byl odstraněn"
|
||||||
poll: "Ankety"
|
poll: "Ankety"
|
||||||
mobile/views/components/ui.header.vue:
|
mobile/views/components/ui.header.vue:
|
||||||
welcome-back: "Vítejte zpátky,"
|
welcome-back: "Vítejte zpátky,"
|
||||||
|
adjective: "Pán"
|
||||||
mobile/views/components/ui.nav.vue:
|
mobile/views/components/ui.nav.vue:
|
||||||
|
timeline: "Časová osa"
|
||||||
|
notifications: "Oznámení"
|
||||||
|
search: "Vyhledávání"
|
||||||
|
user-lists: "Seznamy"
|
||||||
|
widgets: "Widgety"
|
||||||
|
game: "Hry"
|
||||||
|
admin: "Administrace"
|
||||||
about: "O Misskey"
|
about: "O Misskey"
|
||||||
|
mobile/views/pages/user-lists.vue:
|
||||||
|
title: "Seznamy"
|
||||||
|
mobile/views/pages/signup.vue:
|
||||||
|
lets-start: "Váš účet je připraven! 📦"
|
||||||
mobile/views/pages/home.vue:
|
mobile/views/pages/home.vue:
|
||||||
|
home: "Domů"
|
||||||
local: "Lokální"
|
local: "Lokální"
|
||||||
global: "Globální"
|
global: "Globální"
|
||||||
|
mentions: "Zmínění"
|
||||||
|
messages: "Zprávy"
|
||||||
|
mobile/views/pages/tag.vue:
|
||||||
|
no-posts-found: "Nebyly nalezeny žádné příspěvky s \"{q}\"."
|
||||||
mobile/views/pages/widgets.vue:
|
mobile/views/pages/widgets.vue:
|
||||||
|
add-widget: "Přidat"
|
||||||
customization-tips: "Tipy pro přizpůsobení"
|
customization-tips: "Tipy pro přizpůsobení"
|
||||||
mobile/views/pages/widgets/activity.vue:
|
mobile/views/pages/widgets/activity.vue:
|
||||||
activity: "Aktivita"
|
activity: "Aktivita"
|
||||||
|
mobile/views/pages/share.vue:
|
||||||
|
share-with: "Sdílet na {name}"
|
||||||
|
mobile/views/pages/received-follow-requests.vue:
|
||||||
|
accept: "Přijmout"
|
||||||
|
reject: "Odmítnout"
|
||||||
|
mobile/views/pages/note.vue:
|
||||||
|
prev: "Předchozí příspěvěk"
|
||||||
|
next: "Následující příspěvek"
|
||||||
|
mobile/views/pages/games/reversi.vue:
|
||||||
|
reversi: "Reversi"
|
||||||
|
mobile/views/pages/search.vue:
|
||||||
|
not-found: "Pro '{q}' nebyly nalezeny žádné příspěvky."
|
||||||
|
mobile/views/pages/selectdrive.vue:
|
||||||
|
select-file: "Vybrat soubory"
|
||||||
mobile/views/pages/user/home.vue:
|
mobile/views/pages/user/home.vue:
|
||||||
activity: "Aktivita"
|
activity: "Aktivita"
|
||||||
|
frequently-replied-users: "Častá zmínění"
|
||||||
mobile/views/pages/user/home.photos.vue:
|
mobile/views/pages/user/home.photos.vue:
|
||||||
no-photos: "Žádné obrázky"
|
no-photos: "Žádné obrázky"
|
||||||
deck:
|
deck:
|
||||||
|
widgets: "Widgety"
|
||||||
|
home: "Domů"
|
||||||
local: "Lokální"
|
local: "Lokální"
|
||||||
hashtag: "Hashtagy"
|
hashtag: "Hashtagy"
|
||||||
global: "Globální"
|
global: "Globální"
|
||||||
|
mentions: "Zmínění"
|
||||||
|
notifications: "Oznámení"
|
||||||
|
list: "Seznamy"
|
||||||
|
select-list: "Vyberte seznam"
|
||||||
swap-left: "Posunout doleva"
|
swap-left: "Posunout doleva"
|
||||||
swap-right: "Posunout doprava"
|
swap-right: "Posunout doprava"
|
||||||
rename: "Přejmenovat"
|
rename: "Přejmenovat"
|
||||||
@@ -758,4 +1184,10 @@ deck/deck.user-column.vue:
|
|||||||
dev/views/new-app.vue:
|
dev/views/new-app.vue:
|
||||||
app-name-desc: "Jméno vaší aplikace"
|
app-name-desc: "Jméno vaší aplikace"
|
||||||
app-desc: "Stručný popis nebo představení vaší aplikace."
|
app-desc: "Stručný popis nebo představení vaší aplikace."
|
||||||
|
account-read: "Zobrazit informace účtu"
|
||||||
|
note-write: "Odeslat."
|
||||||
reaction-write: "Přidat nebo odebrat reakce."
|
reaction-write: "Přidat nebo odebrat reakce."
|
||||||
|
following-write: "Sledovat a přestat sledovat"
|
||||||
|
drive-read: "Přečíst váš Disk"
|
||||||
|
notification-read: "Sledovat oznámení."
|
||||||
|
notification-write: "Zpravovat notifikace."
|
||||||
|
@@ -270,7 +270,6 @@ common/views/components/note-menu.vue:
|
|||||||
common/views/components/poll.vue:
|
common/views/components/poll.vue:
|
||||||
vote-to: "Stimme für '{}'"
|
vote-to: "Stimme für '{}'"
|
||||||
vote-count: "{} Stimmen"
|
vote-count: "{} Stimmen"
|
||||||
total-users: "{} Nutzer haben abgestimmt"
|
|
||||||
vote: "Abstimmen"
|
vote: "Abstimmen"
|
||||||
show-result: "Zeige Ergebnis"
|
show-result: "Zeige Ergebnis"
|
||||||
voted: "Abgestimmt"
|
voted: "Abgestimmt"
|
||||||
@@ -280,6 +279,7 @@ common/views/components/poll-editor.vue:
|
|||||||
remove: "Diese Auswahl entfernen"
|
remove: "Diese Auswahl entfernen"
|
||||||
add: "+ Eine Auswahl hinzufügen"
|
add: "+ Eine Auswahl hinzufügen"
|
||||||
destroy: "Diese Abstimmung löschen"
|
destroy: "Diese Abstimmung löschen"
|
||||||
|
day: "So"
|
||||||
common/views/components/reaction-picker.vue:
|
common/views/components/reaction-picker.vue:
|
||||||
choose-reaction: "Wähle eine Reaktion aus"
|
choose-reaction: "Wähle eine Reaktion aus"
|
||||||
common/views/components/emoji-picker.vue:
|
common/views/components/emoji-picker.vue:
|
||||||
@@ -339,6 +339,9 @@ common/views/components/profile-editor.vue:
|
|||||||
banner: "Banner"
|
banner: "Banner"
|
||||||
save: "Speichern"
|
save: "Speichern"
|
||||||
export: "Exportieren"
|
export: "Exportieren"
|
||||||
|
import: "Importieren"
|
||||||
|
export-targets:
|
||||||
|
user-lists: "Listen"
|
||||||
enter-password: "Bitte Passwort eingeben"
|
enter-password: "Bitte Passwort eingeben"
|
||||||
common/views/widgets/broadcast.vue:
|
common/views/widgets/broadcast.vue:
|
||||||
fetching: "Laden"
|
fetching: "Laden"
|
||||||
|
@@ -24,8 +24,8 @@ common:
|
|||||||
application-authorization: "Application authorizations"
|
application-authorization: "Application authorizations"
|
||||||
close: "Close"
|
close: "Close"
|
||||||
do-not-copy-paste: "Please do not enter or paste the code here. Account may be compromised."
|
do-not-copy-paste: "Please do not enter or paste the code here. Account may be compromised."
|
||||||
load-more: "Load more"
|
load-more: "Read more"
|
||||||
enter-password: "Please enter the Password"
|
enter-password: "Enter your password"
|
||||||
2fa: "Two-factor authentication"
|
2fa: "Two-factor authentication"
|
||||||
customize-home: "Customize home layout"
|
customize-home: "Customize home layout"
|
||||||
featured-notes: "Featured notes"
|
featured-notes: "Featured notes"
|
||||||
@@ -114,7 +114,7 @@ common:
|
|||||||
a: "What are you doing?"
|
a: "What are you doing?"
|
||||||
b: "What's happening?"
|
b: "What's happening?"
|
||||||
c: "What’s on your mind?"
|
c: "What’s on your mind?"
|
||||||
d: "Would you post any words?"
|
d: "What do you want to say?"
|
||||||
e: "Write here"
|
e: "Write here"
|
||||||
f: "Waiting for your writing."
|
f: "Waiting for your writing."
|
||||||
settings: "Settings"
|
settings: "Settings"
|
||||||
@@ -169,9 +169,9 @@ common:
|
|||||||
deck-column-align-flexible: "Flexible"
|
deck-column-align-flexible: "Flexible"
|
||||||
deck-column-width: "Deck column width"
|
deck-column-width: "Deck column width"
|
||||||
deck-column-width-narrow: "Narrow"
|
deck-column-width-narrow: "Narrow"
|
||||||
deck-column-width-narrower: "Somewhat narrow"
|
deck-column-width-narrower: "Narrower"
|
||||||
deck-column-width-normal: "Regular"
|
deck-column-width-normal: "Regular"
|
||||||
deck-column-width-wider: "Somewhat wide"
|
deck-column-width-wider: "Slightly wide"
|
||||||
deck-column-width-wide: "Wide"
|
deck-column-width-wide: "Wide"
|
||||||
use-shadow: "Use shadows in the UI"
|
use-shadow: "Use shadows in the UI"
|
||||||
rounded-corners: "Round the corners of the UI"
|
rounded-corners: "Round the corners of the UI"
|
||||||
@@ -223,8 +223,8 @@ common:
|
|||||||
search: "Search"
|
search: "Search"
|
||||||
delete: "Delete"
|
delete: "Delete"
|
||||||
loading: "Loading"
|
loading: "Loading"
|
||||||
ok: "It's OK"
|
ok: "Confirm"
|
||||||
cancel: "Quit"
|
cancel: "Exit"
|
||||||
update-available-title: "Update available"
|
update-available-title: "Update available"
|
||||||
update-available: "A new version of Misskey is now available({newer}, the current version is {current}). Reload the page to apply updates."
|
update-available: "A new version of Misskey is now available({newer}, the current version is {current}). Reload the page to apply updates."
|
||||||
my-token-regenerated: "Your token has been regenerated, so you will be signed out."
|
my-token-regenerated: "Your token has been regenerated, so you will be signed out."
|
||||||
@@ -285,7 +285,7 @@ auth/views/form.vue:
|
|||||||
account-read: "View account information."
|
account-read: "View account information."
|
||||||
account-write: "Modify account information."
|
account-write: "Modify account information."
|
||||||
note-write: "Post."
|
note-write: "Post."
|
||||||
like-write: "React to posts."
|
like-write: "Express yourself about this post."
|
||||||
following-write: "Follow and unfollow."
|
following-write: "Follow and unfollow."
|
||||||
drive-read: "Read your drive."
|
drive-read: "Read your drive."
|
||||||
drive-write: "Upload/delete files in your drive."
|
drive-write: "Upload/delete files in your drive."
|
||||||
@@ -304,7 +304,7 @@ auth/views/index.vue:
|
|||||||
error: "Session does not exist."
|
error: "Session does not exist."
|
||||||
sign-in: "Please sign in."
|
sign-in: "Please sign in."
|
||||||
common/views/pages/explore.vue:
|
common/views/pages/explore.vue:
|
||||||
verified-users: "Verified accounts"
|
verified-users: "Official accounts"
|
||||||
popular-users: "Popular users"
|
popular-users: "Popular users"
|
||||||
recently-updated-users: "Recently active users"
|
recently-updated-users: "Recently active users"
|
||||||
recently-registered-users: "Users who joined recently"
|
recently-registered-users: "Users who joined recently"
|
||||||
@@ -314,6 +314,7 @@ common/views/pages/explore.vue:
|
|||||||
users-info: "Currently, {users} users are registered here"
|
users-info: "Currently, {users} users are registered here"
|
||||||
common/views/components/url-preview.vue:
|
common/views/components/url-preview.vue:
|
||||||
enable-player: "Enable playback"
|
enable-player: "Enable playback"
|
||||||
|
disable-player: "Close the player"
|
||||||
common/views/components/user-list.vue:
|
common/views/components/user-list.vue:
|
||||||
no-users: "There are no users."
|
no-users: "There are no users."
|
||||||
common/views/components/games/reversi/reversi.vue:
|
common/views/components/games/reversi/reversi.vue:
|
||||||
@@ -489,16 +490,35 @@ common/views/components/user-menu.vue:
|
|||||||
common/views/components/poll.vue:
|
common/views/components/poll.vue:
|
||||||
vote-to: "Vote for '{}'"
|
vote-to: "Vote for '{}'"
|
||||||
vote-count: "{} votes"
|
vote-count: "{} votes"
|
||||||
total-users: "{} users voted"
|
total-votes: "{} votes in total"
|
||||||
vote: "Vote"
|
vote: "Vote"
|
||||||
show-result: "Show results"
|
show-result: "Show results"
|
||||||
voted: "Voted"
|
voted: "Voted"
|
||||||
|
closed: "Ended"
|
||||||
|
remaining-days: "{d} days, {h} hours remain"
|
||||||
|
remaining-hours: "{h} hours, and {m} minutes remain"
|
||||||
|
remaining-minutes: "{m} minutes, and {s} seconds remaining"
|
||||||
|
remaining-seconds: "{s} seconds remaining"
|
||||||
common/views/components/poll-editor.vue:
|
common/views/components/poll-editor.vue:
|
||||||
no-only-one-choice: "At least two choices are required"
|
no-only-one-choice: "At least two choices are required"
|
||||||
choice-n: "Choice {}"
|
choice-n: "Choice {}"
|
||||||
remove: "Delete the choice"
|
remove: "Delete the choice"
|
||||||
add: "+ Add a choice"
|
add: "+ Add a choice"
|
||||||
destroy: "Discard the poll"
|
destroy: "Discard the poll"
|
||||||
|
multiple: "More than one answer is allowed"
|
||||||
|
expiration: "Valid until"
|
||||||
|
infinite: "Indefinitely"
|
||||||
|
at: "Date and time pick"
|
||||||
|
after: "Progression specifics"
|
||||||
|
no-more: "You cannot add any more"
|
||||||
|
deadline-date: "Finish date"
|
||||||
|
deadline-time: "Time duration"
|
||||||
|
interval: "Duration"
|
||||||
|
unit: "Unit"
|
||||||
|
second: "Seconds"
|
||||||
|
minute: "Minutes"
|
||||||
|
hour: "Hours"
|
||||||
|
day: "S"
|
||||||
common/views/components/reaction-picker.vue:
|
common/views/components/reaction-picker.vue:
|
||||||
choose-reaction: "Send a reaction"
|
choose-reaction: "Send a reaction"
|
||||||
common/views/components/emoji-picker.vue:
|
common/views/components/emoji-picker.vue:
|
||||||
@@ -520,7 +540,7 @@ common/views/components/signin.vue:
|
|||||||
signin-with-twitter: "Log in with Twitter"
|
signin-with-twitter: "Log in with Twitter"
|
||||||
signin-with-github: "Sign in with GitHub"
|
signin-with-github: "Sign in with GitHub"
|
||||||
signin-with-discord: "Sign in with Discord"
|
signin-with-discord: "Sign in with Discord"
|
||||||
login-failed: "Log in failed. Make sure you have entered your correct username and password."
|
login-failed: "Logging in has failed. Make sure you have entered the correct username and password."
|
||||||
common/views/components/signup.vue:
|
common/views/components/signup.vue:
|
||||||
invitation-code: "Invitation code"
|
invitation-code: "Invitation code"
|
||||||
invitation-info: "If you do not have an invitation code, please contact an <a href=\"{}\">administrator</a>."
|
invitation-info: "If you do not have an invitation code, please contact an <a href=\"{}\">administrator</a>."
|
||||||
@@ -628,12 +648,16 @@ common/views/components/profile-editor.vue:
|
|||||||
email-verified: "Your email has been verified."
|
email-verified: "Your email has been verified."
|
||||||
email-not-verified: "Email address is not confirmed. Please check your inbox."
|
email-not-verified: "Email address is not confirmed. Please check your inbox."
|
||||||
export: "Export"
|
export: "Export"
|
||||||
|
import: "Import"
|
||||||
|
export-and-import: "Export and Import"
|
||||||
export-targets:
|
export-targets:
|
||||||
all-notes: "All posted Notes"
|
all-notes: "All posted Notes"
|
||||||
following-list: "List of followers"
|
following-list: "List of followers"
|
||||||
mute-list: "List of muted accounts"
|
mute-list: "List of muted accounts"
|
||||||
blocking-list: "List of blocked accounts"
|
blocking-list: "List of blocked accounts"
|
||||||
|
user-lists: "Lists"
|
||||||
export-requested: "You have requested an export. This may take a while. After the export is complete, the resulting file will be added to the drive."
|
export-requested: "You have requested an export. This may take a while. After the export is complete, the resulting file will be added to the drive."
|
||||||
|
import-requested: "You have initiated an import. This may take quite some time."
|
||||||
enter-password: "Please enter your password"
|
enter-password: "Please enter your password"
|
||||||
danger-zone: "Cautious options"
|
danger-zone: "Cautious options"
|
||||||
delete-account: "Remove the account"
|
delete-account: "Remove the account"
|
||||||
@@ -1033,7 +1057,7 @@ admin/views/dashboard.vue:
|
|||||||
this-instance: "This instance"
|
this-instance: "This instance"
|
||||||
federated: "Federated"
|
federated: "Federated"
|
||||||
admin/views/queue.vue:
|
admin/views/queue.vue:
|
||||||
operation: "Action(s)"
|
title: "Queue"
|
||||||
remove-all-jobs: "Clear all queued jobs"
|
remove-all-jobs: "Clear all queued jobs"
|
||||||
admin/views/abuse.vue:
|
admin/views/abuse.vue:
|
||||||
title: "Abuse"
|
title: "Abuse"
|
||||||
@@ -1089,6 +1113,7 @@ admin/views/instance.vue:
|
|||||||
disable-local-timeline: "Disable the Local Timeline"
|
disable-local-timeline: "Disable the Local Timeline"
|
||||||
disable-global-timeline: "Disable global timeline"
|
disable-global-timeline: "Disable global timeline"
|
||||||
disabling-timelines-info: "Even if you disable these timelines, the administrator as well as moderators can use them continually."
|
disabling-timelines-info: "Even if you disable these timelines, the administrator as well as moderators can use them continually."
|
||||||
|
enable-emoji-reaction: "Enable pictograms for reactions"
|
||||||
invite: "Invite"
|
invite: "Invite"
|
||||||
save: "Save"
|
save: "Save"
|
||||||
saved: "Saved"
|
saved: "Saved"
|
||||||
@@ -1196,7 +1221,7 @@ admin/views/users.vue:
|
|||||||
updatedAtAsc: "Last Updated (Ascending)"
|
updatedAtAsc: "Last Updated (Ascending)"
|
||||||
updatedAtDesc: "Last Updated (Descending)"
|
updatedAtDesc: "Last Updated (Descending)"
|
||||||
state:
|
state:
|
||||||
title: "Status"
|
title: "Sort"
|
||||||
all: "All"
|
all: "All"
|
||||||
admin: "Administrator"
|
admin: "Administrator"
|
||||||
moderator: "Moderator"
|
moderator: "Moderator"
|
||||||
@@ -1251,13 +1276,14 @@ admin/views/announcements.vue:
|
|||||||
admin/views/hashtags.vue:
|
admin/views/hashtags.vue:
|
||||||
hided-tags: "Hidden Tags"
|
hided-tags: "Hidden Tags"
|
||||||
admin/views/federation.vue:
|
admin/views/federation.vue:
|
||||||
federation: "Federation"
|
instance: "Instance"
|
||||||
host: "Host"
|
host: "Host"
|
||||||
notes: "Notes"
|
notes: "Notes"
|
||||||
users: "Users"
|
users: "Users"
|
||||||
following: "Following"
|
following: "Following"
|
||||||
followers: "Followers"
|
followers: "Followers"
|
||||||
status: "Status"
|
caught-at: "Created at"
|
||||||
|
status: "Statuses"
|
||||||
latest-request-sent-at: "Time of last request sent"
|
latest-request-sent-at: "Time of last request sent"
|
||||||
latest-request-received-at: "Last request received at"
|
latest-request-received-at: "Last request received at"
|
||||||
remove-all-following: "Withold all followers"
|
remove-all-following: "Withold all followers"
|
||||||
@@ -1265,7 +1291,7 @@ admin/views/federation.vue:
|
|||||||
block: "Block"
|
block: "Block"
|
||||||
marked-as-closed: "Marked as closed"
|
marked-as-closed: "Marked as closed"
|
||||||
lookup: "Look up"
|
lookup: "Look up"
|
||||||
instances: "Instances"
|
instances: "Federated"
|
||||||
instance-not-registered: "The instance has not been discovered"
|
instance-not-registered: "The instance has not been discovered"
|
||||||
sort: "Sort by"
|
sort: "Sort by"
|
||||||
sorts:
|
sorts:
|
||||||
@@ -1273,19 +1299,19 @@ admin/views/federation.vue:
|
|||||||
caughtAtDesc: "Date of discovery (Descending)"
|
caughtAtDesc: "Date of discovery (Descending)"
|
||||||
lastCommunicatedAtAsc: "The date and time of the older interactions"
|
lastCommunicatedAtAsc: "The date and time of the older interactions"
|
||||||
lastCommunicatedAtDesc: "The date and time of the newer interactions"
|
lastCommunicatedAtDesc: "The date and time of the newer interactions"
|
||||||
notesAsc: "Order by least Notes posted"
|
notesAsc: "Least Notes posted"
|
||||||
notesDesc: "Order by most Notes posted"
|
notesDesc: "Most Notes posted"
|
||||||
usersAsc: "Less followers"
|
usersAsc: "Less followers"
|
||||||
usersDesc: "More followers"
|
usersDesc: "More followers"
|
||||||
followingAsc: "Least followed"
|
followingAsc: "Least followed"
|
||||||
followingDesc: "Has more followers"
|
followingDesc: "Most followed"
|
||||||
followersAsc: "Sort by having less followers"
|
followersAsc: "Having less followers"
|
||||||
followersDesc: "Sort by the larger number of followers"
|
followersDesc: "The largest number of followers"
|
||||||
driveUsageAsc: "Least storage used"
|
driveUsageAsc: "Least storage used"
|
||||||
driveUsageDesc: "Most storage used"
|
driveUsageDesc: "Most storage used"
|
||||||
driveFilesAsc: "By the smallest number of files stored on Drive"
|
driveFilesAsc: "Least files stored on Drive"
|
||||||
driveFilesDesc: "By the largest number of files stored on Drive"
|
driveFilesDesc: "The largest number of files stored on Drive"
|
||||||
state: "Status"
|
state: "Sort"
|
||||||
states:
|
states:
|
||||||
all: "All"
|
all: "All"
|
||||||
blocked: "Blocked"
|
blocked: "Blocked"
|
||||||
@@ -1328,8 +1354,6 @@ desktop/views/pages/selectdrive.vue:
|
|||||||
desktop/views/pages/search.vue:
|
desktop/views/pages/search.vue:
|
||||||
not-available: "Search feature is turned off in the settings for this instance."
|
not-available: "Search feature is turned off in the settings for this instance."
|
||||||
not-found: "No posts were found for '{q}'"
|
not-found: "No posts were found for '{q}'"
|
||||||
desktop/views/pages/share.vue:
|
|
||||||
share-with: "Share on {name}"
|
|
||||||
desktop/views/pages/tag.vue:
|
desktop/views/pages/tag.vue:
|
||||||
no-posts-found: "No posts contains \"{q}\" found."
|
no-posts-found: "No posts contains \"{q}\" found."
|
||||||
desktop/views/pages/user-list.users.vue:
|
desktop/views/pages/user-list.users.vue:
|
||||||
@@ -1353,7 +1377,7 @@ desktop/views/pages/user/user.header.vue:
|
|||||||
following: "Following"
|
following: "Following"
|
||||||
followers: "Followers"
|
followers: "Followers"
|
||||||
is-bot: "This account is a Bot"
|
is-bot: "This account is a Bot"
|
||||||
no-description: "The user has not written their profile introduction"
|
no-description: "This user has not written their profile introduction"
|
||||||
years-old: "{age} years old"
|
years-old: "{age} years old"
|
||||||
year: "/"
|
year: "/"
|
||||||
month: "/"
|
month: "/"
|
||||||
@@ -1365,7 +1389,7 @@ desktop/views/pages/user/user.timeline.vue:
|
|||||||
with-media: "Media"
|
with-media: "Media"
|
||||||
my-posts: "My posts"
|
my-posts: "My posts"
|
||||||
desktop/views/widgets/messaging.vue:
|
desktop/views/widgets/messaging.vue:
|
||||||
title: "Message"
|
title: "Messaging"
|
||||||
desktop/views/widgets/notifications.vue:
|
desktop/views/widgets/notifications.vue:
|
||||||
title: "Notifications"
|
title: "Notifications"
|
||||||
desktop/views/widgets/polls.vue:
|
desktop/views/widgets/polls.vue:
|
||||||
|
@@ -103,6 +103,32 @@ common:
|
|||||||
tags: "Etiquetas"
|
tags: "Etiquetas"
|
||||||
blocking: "Bloquear"
|
blocking: "Bloquear"
|
||||||
password: "Contraseña"
|
password: "Contraseña"
|
||||||
|
use-os-default-emojis: "Usar los emoticonos estándar del sistema operativo"
|
||||||
|
line-width: "Grosor de línea"
|
||||||
|
line-width-thick: "Grosor"
|
||||||
|
font-size: "Tamaño del texto"
|
||||||
|
font-size-x-small: "Muy pequeño"
|
||||||
|
font-size-small: "Pequeño"
|
||||||
|
font-size-medium: "Normal"
|
||||||
|
font-size-large: "Grande"
|
||||||
|
font-size-x-large: "Muy grande"
|
||||||
|
deck-column-align: "Alineamiento de las columnas"
|
||||||
|
deck-column-align-center: "Centrar"
|
||||||
|
deck-column-align-left: "Izquierda"
|
||||||
|
deck-column-align-flexible: "Flexible"
|
||||||
|
deck-column-width: "Ancho de las columnas"
|
||||||
|
deck-column-width-narrow: "Estrecho"
|
||||||
|
deck-column-width-narrower: "Un poco estrecho"
|
||||||
|
deck-column-width-normal: "Normal"
|
||||||
|
deck-column-width-wider: "Un poco ancho"
|
||||||
|
deck-column-width-wide: "Ancho"
|
||||||
|
use-shadow: "Usar sombras en la Interfaz de Usuario"
|
||||||
|
rounded-corners: "Esquinas redondeadas en la Interfaz de Usuario"
|
||||||
|
circle-icons: "Usar iconos circulares"
|
||||||
|
contrasted-acct: "Añadir contraste al nombre de usuario"
|
||||||
|
wallpaper: "Fondo de pantalla"
|
||||||
|
choose-wallpaper: "Escoge un fondo de pantalla"
|
||||||
|
navbar-position-left: "Izquierda"
|
||||||
search: "Buscar"
|
search: "Buscar"
|
||||||
delete: "eliminar"
|
delete: "eliminar"
|
||||||
loading: "cargando"
|
loading: "cargando"
|
||||||
@@ -303,7 +329,6 @@ common/views/components/user-menu.vue:
|
|||||||
common/views/components/poll.vue:
|
common/views/components/poll.vue:
|
||||||
vote-to: "'{}' para votar"
|
vote-to: "'{}' para votar"
|
||||||
vote-count: "{} votos"
|
vote-count: "{} votos"
|
||||||
total-users: "{} usuario(s) que ha(n) votado"
|
|
||||||
vote: "Vota"
|
vote: "Vota"
|
||||||
show-result: "Mostrar resultados"
|
show-result: "Mostrar resultados"
|
||||||
voted: "Votado"
|
voted: "Votado"
|
||||||
@@ -313,6 +338,7 @@ common/views/components/poll-editor.vue:
|
|||||||
remove: "Borra la opción"
|
remove: "Borra la opción"
|
||||||
add: "+ Añade una opción"
|
add: "+ Añade una opción"
|
||||||
destroy: "Cancelar la encuesta"
|
destroy: "Cancelar la encuesta"
|
||||||
|
day: "domingo"
|
||||||
common/views/components/reaction-picker.vue:
|
common/views/components/reaction-picker.vue:
|
||||||
choose-reaction: "Escoge una reacción"
|
choose-reaction: "Escoge una reacción"
|
||||||
common/views/components/emoji-picker.vue:
|
common/views/components/emoji-picker.vue:
|
||||||
@@ -395,9 +421,11 @@ common/views/components/profile-editor.vue:
|
|||||||
save: "Guardar"
|
save: "Guardar"
|
||||||
email-address: "Correo electrónico"
|
email-address: "Correo electrónico"
|
||||||
export: "Exportar"
|
export: "Exportar"
|
||||||
|
import: "Importar"
|
||||||
export-targets:
|
export-targets:
|
||||||
mute-list: "Silenciar"
|
mute-list: "Silenciar"
|
||||||
blocking-list: "Bloquear"
|
blocking-list: "Bloquear"
|
||||||
|
user-lists: "Listas"
|
||||||
enter-password: "Escribe una contraseña"
|
enter-password: "Escribe una contraseña"
|
||||||
common/views/components/user-list-editor.vue:
|
common/views/components/user-list-editor.vue:
|
||||||
users: "Usuarios"
|
users: "Usuarios"
|
||||||
@@ -787,11 +815,11 @@ admin/views/announcements.vue:
|
|||||||
remove: "eliminar"
|
remove: "eliminar"
|
||||||
add: "Agregar"
|
add: "Agregar"
|
||||||
admin/views/federation.vue:
|
admin/views/federation.vue:
|
||||||
|
instance: "Instancia"
|
||||||
host: "Host"
|
host: "Host"
|
||||||
following: "Siguiendo"
|
following: "Siguiendo"
|
||||||
status: "Estado"
|
status: "Estado"
|
||||||
block: "Bloquear"
|
block: "Bloquear"
|
||||||
instances: "Instancia"
|
|
||||||
states:
|
states:
|
||||||
all: "Todo"
|
all: "Todo"
|
||||||
blocked: "Bloquear"
|
blocked: "Bloquear"
|
||||||
|
@@ -383,7 +383,6 @@ common/views/components/user-menu.vue:
|
|||||||
common/views/components/poll.vue:
|
common/views/components/poll.vue:
|
||||||
vote-to: "Voter pour '{}'"
|
vote-to: "Voter pour '{}'"
|
||||||
vote-count: "{} votes"
|
vote-count: "{} votes"
|
||||||
total-users: "{} utilisateur·rice·s ont voté"
|
|
||||||
vote: "Vote"
|
vote: "Vote"
|
||||||
show-result: "Montrer les résultats"
|
show-result: "Montrer les résultats"
|
||||||
voted: "Voté"
|
voted: "Voté"
|
||||||
@@ -393,6 +392,7 @@ common/views/components/poll-editor.vue:
|
|||||||
remove: "Supprimer ce choix"
|
remove: "Supprimer ce choix"
|
||||||
add: "+ Ajouter un choix"
|
add: "+ Ajouter un choix"
|
||||||
destroy: "Annuler ce sondage"
|
destroy: "Annuler ce sondage"
|
||||||
|
day: "D"
|
||||||
common/views/components/reaction-picker.vue:
|
common/views/components/reaction-picker.vue:
|
||||||
choose-reaction: "Choisissez votre réaction"
|
choose-reaction: "Choisissez votre réaction"
|
||||||
common/views/components/emoji-picker.vue:
|
common/views/components/emoji-picker.vue:
|
||||||
@@ -522,11 +522,13 @@ common/views/components/profile-editor.vue:
|
|||||||
email-verified: "L’adresse du courrier électronique a été vérifiée."
|
email-verified: "L’adresse du courrier électronique a été vérifiée."
|
||||||
email-not-verified: "Adresse de courriel n’est pas confirmée. Veuillez vérifier votre boite de réception."
|
email-not-verified: "Adresse de courriel n’est pas confirmée. Veuillez vérifier votre boite de réception."
|
||||||
export: "Exporter"
|
export: "Exporter"
|
||||||
|
import: "Importer"
|
||||||
export-targets:
|
export-targets:
|
||||||
all-notes: "Toutes les notes publiées"
|
all-notes: "Toutes les notes publiées"
|
||||||
following-list: "Liste des abonnements"
|
following-list: "Liste des abonnements"
|
||||||
mute-list: "Liste des comptes mis en sourdine"
|
mute-list: "Liste des comptes mis en sourdine"
|
||||||
blocking-list: "Liste des comptes bloqués"
|
blocking-list: "Liste des comptes bloqués"
|
||||||
|
user-lists: "Listes"
|
||||||
export-requested: "Vous avez demandé une exportation. Cela peut prendre un certain temps. Une fois l'exportation terminée, le fichier résultant sera ajouté dans le Drive."
|
export-requested: "Vous avez demandé une exportation. Cela peut prendre un certain temps. Une fois l'exportation terminée, le fichier résultant sera ajouté dans le Drive."
|
||||||
enter-password: "Veuillez saisir votre mot de passe"
|
enter-password: "Veuillez saisir votre mot de passe"
|
||||||
danger-zone: "Zone de danger"
|
danger-zone: "Zone de danger"
|
||||||
@@ -925,7 +927,6 @@ admin/views/dashboard.vue:
|
|||||||
this-instance: "Cette instance"
|
this-instance: "Cette instance"
|
||||||
federated: "Fédérées"
|
federated: "Fédérées"
|
||||||
admin/views/queue.vue:
|
admin/views/queue.vue:
|
||||||
operation: "Action(s)"
|
|
||||||
remove-all-jobs: "Enlever toutes les tâches en attente"
|
remove-all-jobs: "Enlever toutes les tâches en attente"
|
||||||
admin/views/abuse.vue:
|
admin/views/abuse.vue:
|
||||||
title: "Abus"
|
title: "Abus"
|
||||||
@@ -1141,12 +1142,13 @@ admin/views/announcements.vue:
|
|||||||
admin/views/hashtags.vue:
|
admin/views/hashtags.vue:
|
||||||
hided-tags: "Tags cachés"
|
hided-tags: "Tags cachés"
|
||||||
admin/views/federation.vue:
|
admin/views/federation.vue:
|
||||||
federation: "Fédération"
|
instance: "Instance"
|
||||||
host: "Hôte"
|
host: "Hôte"
|
||||||
notes: "Notes"
|
notes: "Notes"
|
||||||
users: "Utilisateur·rice·s"
|
users: "Utilisateur·rice·s"
|
||||||
following: "Abonnements"
|
following: "Abonnements"
|
||||||
followers: "Abonné·e·s"
|
followers: "Abonné·e·s"
|
||||||
|
caught-at: "Créé le"
|
||||||
status: "Statuts"
|
status: "Statuts"
|
||||||
latest-request-sent-at: "Dernière requête envoyée"
|
latest-request-sent-at: "Dernière requête envoyée"
|
||||||
latest-request-received-at: "Dernière requête reçue"
|
latest-request-received-at: "Dernière requête reçue"
|
||||||
@@ -1154,7 +1156,7 @@ admin/views/federation.vue:
|
|||||||
block: "Bloquer"
|
block: "Bloquer"
|
||||||
marked-as-closed: "Marquées comme fermées"
|
marked-as-closed: "Marquées comme fermées"
|
||||||
lookup: "Recherche"
|
lookup: "Recherche"
|
||||||
instances: "Instances"
|
instances: "Fédérées"
|
||||||
sort: "Trier par"
|
sort: "Trier par"
|
||||||
sorts:
|
sorts:
|
||||||
caughtAtAsc: "Date d’inscription (Ascendant)"
|
caughtAtAsc: "Date d’inscription (Ascendant)"
|
||||||
@@ -1207,8 +1209,6 @@ desktop/views/pages/selectdrive.vue:
|
|||||||
desktop/views/pages/search.vue:
|
desktop/views/pages/search.vue:
|
||||||
not-available: "La fonction de recherche est désactivée dans les paramètres de l’instance."
|
not-available: "La fonction de recherche est désactivée dans les paramètres de l’instance."
|
||||||
not-found: "Aucune publication trouvée pour « {q} »."
|
not-found: "Aucune publication trouvée pour « {q} »."
|
||||||
desktop/views/pages/share.vue:
|
|
||||||
share-with: "Partager avec {name}"
|
|
||||||
desktop/views/pages/tag.vue:
|
desktop/views/pages/tag.vue:
|
||||||
no-posts-found: "Aucune publication contenant « {q} » n’a été trouvée."
|
no-posts-found: "Aucune publication contenant « {q} » n’a été trouvée."
|
||||||
desktop/views/pages/user-list.users.vue:
|
desktop/views/pages/user-list.users.vue:
|
||||||
|
@@ -5,22 +5,49 @@
|
|||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const yaml = require('js-yaml');
|
const yaml = require('js-yaml');
|
||||||
|
|
||||||
const langs = ['de-DE', 'en-US', 'fr-FR', 'ja-JP', 'ja-KS', 'pl-PL', 'es-ES', 'nl-NL', 'zh-CN', 'ko-KR'];
|
const merge = (...args) => args.reduce((a, c) => ({
|
||||||
|
...a,
|
||||||
|
...c,
|
||||||
|
...Object.entries(a)
|
||||||
|
.filter(([k]) => c && typeof c[k] === 'object')
|
||||||
|
.reduce((a, [k, v]) => (a[k] = merge(v, c[k]), a), {})
|
||||||
|
}), {});
|
||||||
|
|
||||||
const loadLocale = lang => yaml.safeLoad(fs.readFileSync(`${__dirname}/${lang}.yml`, 'utf-8'));
|
const languages = [
|
||||||
const locales = langs
|
'cs-CZ',
|
||||||
.map(lang => [lang, loadLocale(lang)])
|
'de-DE',
|
||||||
.map(([lang, locale], _, locales) => {
|
'en-US',
|
||||||
switch (lang) {
|
'es-ES',
|
||||||
case 'ja-JP': return [lang, locale];
|
'fr-FR',
|
||||||
case 'en-US': return [lang, { ...locales['ja-JP'], ...locale }];
|
'ja-JP',
|
||||||
default: return [lang, {
|
'ja-KS',
|
||||||
...(lang.startsWith('ja-') ? {} : locales['en-US']),
|
'ko-KR',
|
||||||
...locales['ja-JP'],
|
'nl-NL',
|
||||||
...locale
|
'pl-PL',
|
||||||
}];
|
'zh-CN',
|
||||||
|
'zh-TW',
|
||||||
|
];
|
||||||
|
|
||||||
|
const primaries = {
|
||||||
|
'en': 'US',
|
||||||
|
'ja': 'JP',
|
||||||
|
'zh': 'CN',
|
||||||
|
};
|
||||||
|
|
||||||
|
const locales = languages.reduce((a, c) => (a[c] = yaml.safeLoad(fs.readFileSync(`${__dirname}/${c}.yml`, 'utf-8')) || {}, a), {});
|
||||||
|
|
||||||
|
module.exports = Object.entries(locales)
|
||||||
|
.reduce((a, [k ,v]) => (a[k] = (() => {
|
||||||
|
const [lang] = k.split('-');
|
||||||
|
switch (k) {
|
||||||
|
case 'ja-JP': return v;
|
||||||
|
case 'ja-KS':
|
||||||
|
case 'en-US': return merge(locales['ja-JP'], v);
|
||||||
|
default: return merge(
|
||||||
|
locales['ja-JP'],
|
||||||
|
locales['en-US'],
|
||||||
|
locales[`${lang}-${primaries[lang]}`] || {},
|
||||||
|
v
|
||||||
|
);
|
||||||
}
|
}
|
||||||
})
|
})(), a), {});
|
||||||
.map(([lang, locale]) => ({ [lang]: loadLocale(lang) }));
|
|
||||||
|
|
||||||
module.exports = locales.reduce((a, b) => ({ ...a, ...b }));
|
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
meta:
|
meta:
|
||||||
lang: "In Italiano"
|
lang: "Italiano"
|
||||||
common:
|
common:
|
||||||
misskey: "A ⭐ of the fediverse"
|
misskey: "A ⭐ of the fediverse"
|
||||||
about-title: "A ⭐ of the fediverse."
|
about-title: "A ⭐ of the fediverse."
|
||||||
|
@@ -334,6 +334,7 @@ common/views/pages/explore.vue:
|
|||||||
|
|
||||||
common/views/components/url-preview.vue:
|
common/views/components/url-preview.vue:
|
||||||
enable-player: "プレイヤーを開く"
|
enable-player: "プレイヤーを開く"
|
||||||
|
disable-player: "プレイヤーを閉じる"
|
||||||
|
|
||||||
common/views/components/user-list.vue:
|
common/views/components/user-list.vue:
|
||||||
no-users: "ユーザーがいません"
|
no-users: "ユーザーがいません"
|
||||||
@@ -527,10 +528,15 @@ common/views/components/user-menu.vue:
|
|||||||
common/views/components/poll.vue:
|
common/views/components/poll.vue:
|
||||||
vote-to: "「{}」に投票する"
|
vote-to: "「{}」に投票する"
|
||||||
vote-count: "{}票"
|
vote-count: "{}票"
|
||||||
total-users: "{}人が投票"
|
total-votes: "計{}票"
|
||||||
vote: "投票する"
|
vote: "投票する"
|
||||||
show-result: "結果を見る"
|
show-result: "結果を見る"
|
||||||
voted: "投票済み"
|
voted: "投票済み"
|
||||||
|
closed: "終了済み"
|
||||||
|
remaining-days: "終了まであと{d}日{h}時間"
|
||||||
|
remaining-hours: "終了まであと{h}時間{m}分"
|
||||||
|
remaining-minutes: "終了まであと{m}分{s}秒"
|
||||||
|
remaining-seconds: "終了まであと{s}秒"
|
||||||
|
|
||||||
common/views/components/poll-editor.vue:
|
common/views/components/poll-editor.vue:
|
||||||
no-only-one-choice: "アンケートには、選択肢が最低2つ必要です"
|
no-only-one-choice: "アンケートには、選択肢が最低2つ必要です"
|
||||||
@@ -538,6 +544,20 @@ common/views/components/poll-editor.vue:
|
|||||||
remove: "この選択肢を削除"
|
remove: "この選択肢を削除"
|
||||||
add: "+選択肢を追加"
|
add: "+選択肢を追加"
|
||||||
destroy: "アンケートを破棄"
|
destroy: "アンケートを破棄"
|
||||||
|
multiple: "複数回答可"
|
||||||
|
expiration: "期限"
|
||||||
|
infinite: "無期限"
|
||||||
|
at: "日時指定"
|
||||||
|
after: "経過指定"
|
||||||
|
no-more: "これ以上追加できません"
|
||||||
|
deadline-date: "期日"
|
||||||
|
deadline-time: "時間"
|
||||||
|
interval: "期間"
|
||||||
|
unit: "単位"
|
||||||
|
second: "秒"
|
||||||
|
minute: "分"
|
||||||
|
hour: "時間"
|
||||||
|
day: "日"
|
||||||
|
|
||||||
common/views/components/reaction-picker.vue:
|
common/views/components/reaction-picker.vue:
|
||||||
choose-reaction: "リアクションを選択"
|
choose-reaction: "リアクションを選択"
|
||||||
@@ -682,12 +702,16 @@ common/views/components/profile-editor.vue:
|
|||||||
email-verified: "メールアドレスが確認されました"
|
email-verified: "メールアドレスが確認されました"
|
||||||
email-not-verified: "メールアドレスが確認されていません。メールボックスをご確認ください。"
|
email-not-verified: "メールアドレスが確認されていません。メールボックスをご確認ください。"
|
||||||
export: "エクスポート"
|
export: "エクスポート"
|
||||||
|
import: "インポート"
|
||||||
|
export-and-import: "エクスポートとインポート"
|
||||||
export-targets:
|
export-targets:
|
||||||
all-notes: "すべての投稿データ"
|
all-notes: "すべての投稿データ"
|
||||||
following-list: "フォロー"
|
following-list: "フォロー"
|
||||||
mute-list: "ミュート"
|
mute-list: "ミュート"
|
||||||
blocking-list: "ブロック"
|
blocking-list: "ブロック"
|
||||||
|
user-lists: "リスト"
|
||||||
export-requested: "エクスポートをリクエストしました。これには時間がかかる場合があります。エクスポートが終わると、ドライブにファイルが追加されます。"
|
export-requested: "エクスポートをリクエストしました。これには時間がかかる場合があります。エクスポートが終わると、ドライブにファイルが追加されます。"
|
||||||
|
import-requested: "インポートをリクエストしました。これには時間がかかる場合があります。"
|
||||||
enter-password: "パスワードを入力してください"
|
enter-password: "パスワードを入力してください"
|
||||||
danger-zone: "危険な設定"
|
danger-zone: "危険な設定"
|
||||||
delete-account: "アカウントを削除"
|
delete-account: "アカウントを削除"
|
||||||
@@ -1156,7 +1180,7 @@ admin/views/dashboard.vue:
|
|||||||
federated: "連合"
|
federated: "連合"
|
||||||
|
|
||||||
admin/views/queue.vue:
|
admin/views/queue.vue:
|
||||||
operation: "操作"
|
title: "キュー"
|
||||||
remove-all-jobs: "すべてのジョブをクリア"
|
remove-all-jobs: "すべてのジョブをクリア"
|
||||||
|
|
||||||
admin/views/abuse.vue:
|
admin/views/abuse.vue:
|
||||||
@@ -1214,6 +1238,8 @@ admin/views/instance.vue:
|
|||||||
disable-local-timeline: "ローカルタイムラインを無効にする"
|
disable-local-timeline: "ローカルタイムラインを無効にする"
|
||||||
disable-global-timeline: "グローバルタイムラインを無効にする"
|
disable-global-timeline: "グローバルタイムラインを無効にする"
|
||||||
disabling-timelines-info: "これらのタイムラインを無効にしても、管理者およびモデレーターは引き続き利用できます。"
|
disabling-timelines-info: "これらのタイムラインを無効にしても、管理者およびモデレーターは引き続き利用できます。"
|
||||||
|
enable-emoji-reaction: "リアクションに絵文字を使えるようにする"
|
||||||
|
use-star-for-reaction-fallback: "不明なリアクションのフォールバックに star を使う"
|
||||||
invite: "招待"
|
invite: "招待"
|
||||||
save: "保存"
|
save: "保存"
|
||||||
saved: "保存しました"
|
saved: "保存しました"
|
||||||
@@ -1384,12 +1410,13 @@ admin/views/hashtags.vue:
|
|||||||
hided-tags: "Hidden Tags"
|
hided-tags: "Hidden Tags"
|
||||||
|
|
||||||
admin/views/federation.vue:
|
admin/views/federation.vue:
|
||||||
federation: "連合"
|
instance: "インスタンス"
|
||||||
host: "ホスト"
|
host: "ホスト"
|
||||||
notes: "投稿"
|
notes: "投稿"
|
||||||
users: "ユーザー"
|
users: "ユーザー"
|
||||||
following: "フォロー中"
|
following: "フォロー中"
|
||||||
followers: "フォロワー"
|
followers: "フォロワー"
|
||||||
|
caught-at: "登録日時"
|
||||||
status: "ステータス"
|
status: "ステータス"
|
||||||
latest-request-sent-at: "直近のリクエスト送信"
|
latest-request-sent-at: "直近のリクエスト送信"
|
||||||
latest-request-received-at: "直近のリクエスト受信"
|
latest-request-received-at: "直近のリクエスト受信"
|
||||||
@@ -1398,7 +1425,7 @@ admin/views/federation.vue:
|
|||||||
block: "ブロック"
|
block: "ブロック"
|
||||||
marked-as-closed: "閉鎖されているとマーク"
|
marked-as-closed: "閉鎖されているとマーク"
|
||||||
lookup: "照会"
|
lookup: "照会"
|
||||||
instances: "インスタンス"
|
instances: "連合"
|
||||||
instance-not-registered: "そのインスタンスは登録されていません"
|
instance-not-registered: "そのインスタンスは登録されていません"
|
||||||
sort: "ソート"
|
sort: "ソート"
|
||||||
sorts:
|
sorts:
|
||||||
@@ -1467,9 +1494,6 @@ desktop/views/pages/search.vue:
|
|||||||
not-available: "検索機能はインスタンスの設定で無効になっています。"
|
not-available: "検索機能はインスタンスの設定で無効になっています。"
|
||||||
not-found: "「{q}」に関する投稿は見つかりませんでした。"
|
not-found: "「{q}」に関する投稿は見つかりませんでした。"
|
||||||
|
|
||||||
desktop/views/pages/share.vue:
|
|
||||||
share-with: "{name}で共有"
|
|
||||||
|
|
||||||
desktop/views/pages/tag.vue:
|
desktop/views/pages/tag.vue:
|
||||||
no-posts-found: "ハッシュタグ「{q}」が付けられた投稿は見つかりませんでした。"
|
no-posts-found: "ハッシュタグ「{q}」が付けられた投稿は見つかりませんでした。"
|
||||||
|
|
||||||
|
@@ -344,7 +344,6 @@ common/views/components/user-menu.vue:
|
|||||||
common/views/components/poll.vue:
|
common/views/components/poll.vue:
|
||||||
vote-to: "「{}」に投票や!"
|
vote-to: "「{}」に投票や!"
|
||||||
vote-count: "{}票"
|
vote-count: "{}票"
|
||||||
total-users: "{}人が投票"
|
|
||||||
vote: "投票するで"
|
vote: "投票するで"
|
||||||
show-result: "結果を見よか"
|
show-result: "結果を見よか"
|
||||||
voted: "投票済みや"
|
voted: "投票済みや"
|
||||||
@@ -354,6 +353,7 @@ common/views/components/poll-editor.vue:
|
|||||||
remove: "この選択肢を消すで"
|
remove: "この選択肢を消すで"
|
||||||
add: "+選択肢を追加"
|
add: "+選択肢を追加"
|
||||||
destroy: "アンケートをほかそ"
|
destroy: "アンケートをほかそ"
|
||||||
|
day: "日"
|
||||||
common/views/components/reaction-picker.vue:
|
common/views/components/reaction-picker.vue:
|
||||||
choose-reaction: "リアクション、どれにするんや?"
|
choose-reaction: "リアクション、どれにするんや?"
|
||||||
common/views/components/emoji-picker.vue:
|
common/views/components/emoji-picker.vue:
|
||||||
@@ -476,10 +476,12 @@ common/views/components/profile-editor.vue:
|
|||||||
email-verified: "このメールアドレスOKや!"
|
email-verified: "このメールアドレスOKや!"
|
||||||
email-not-verified: "メールアドレスが確認されとらん。メールボックスもっぺん見てくれへん?"
|
email-not-verified: "メールアドレスが確認されとらん。メールボックスもっぺん見てくれへん?"
|
||||||
export: "エクスポート"
|
export: "エクスポート"
|
||||||
|
import: "インポート"
|
||||||
export-targets:
|
export-targets:
|
||||||
following-list: "フォロー"
|
following-list: "フォロー"
|
||||||
mute-list: "ミュート"
|
mute-list: "ミュート"
|
||||||
blocking-list: "ブロック"
|
blocking-list: "ブロック"
|
||||||
|
user-lists: "リスト"
|
||||||
enter-password: "パスワードを入れてや"
|
enter-password: "パスワードを入れてや"
|
||||||
common/views/components/user-list-editor.vue:
|
common/views/components/user-list-editor.vue:
|
||||||
users: "ユーザー"
|
users: "ユーザー"
|
||||||
@@ -858,8 +860,6 @@ admin/views/dashboard.vue:
|
|||||||
instances: "インスタンス"
|
instances: "インスタンス"
|
||||||
this-instance: "ワイのインスタンス"
|
this-instance: "ワイのインスタンス"
|
||||||
federated: "連合"
|
federated: "連合"
|
||||||
admin/views/queue.vue:
|
|
||||||
operation: "操作"
|
|
||||||
admin/views/abuse.vue:
|
admin/views/abuse.vue:
|
||||||
details: "もっと"
|
details: "もっと"
|
||||||
remove-report: "削除"
|
remove-report: "削除"
|
||||||
@@ -988,7 +988,7 @@ admin/views/announcements.vue:
|
|||||||
add: "増やす"
|
add: "増やす"
|
||||||
saved: "保存したで!"
|
saved: "保存したで!"
|
||||||
admin/views/federation.vue:
|
admin/views/federation.vue:
|
||||||
federation: "連合"
|
instance: "インスタンス"
|
||||||
host: "ホスト"
|
host: "ホスト"
|
||||||
notes: "投稿"
|
notes: "投稿"
|
||||||
users: "ユーザー"
|
users: "ユーザー"
|
||||||
@@ -997,7 +997,7 @@ admin/views/federation.vue:
|
|||||||
status: "ステータス"
|
status: "ステータス"
|
||||||
block: "ブロック"
|
block: "ブロック"
|
||||||
lookup: "照会"
|
lookup: "照会"
|
||||||
instances: "インスタンス"
|
instances: "連合"
|
||||||
states:
|
states:
|
||||||
all: "すべて"
|
all: "すべて"
|
||||||
blocked: "ブロック"
|
blocked: "ブロック"
|
||||||
|
@@ -314,6 +314,7 @@ common/views/pages/explore.vue:
|
|||||||
users-info: "현재 {users} 사용자가 등록되어 있습니다"
|
users-info: "현재 {users} 사용자가 등록되어 있습니다"
|
||||||
common/views/components/url-preview.vue:
|
common/views/components/url-preview.vue:
|
||||||
enable-player: "플레이어 열기"
|
enable-player: "플레이어 열기"
|
||||||
|
disable-player: "플레이어 닫기"
|
||||||
common/views/components/user-list.vue:
|
common/views/components/user-list.vue:
|
||||||
no-users: "사용자가 없습니다"
|
no-users: "사용자가 없습니다"
|
||||||
common/views/components/games/reversi/reversi.vue:
|
common/views/components/games/reversi/reversi.vue:
|
||||||
@@ -489,16 +490,35 @@ common/views/components/user-menu.vue:
|
|||||||
common/views/components/poll.vue:
|
common/views/components/poll.vue:
|
||||||
vote-to: "\"{}\"에 투표하기"
|
vote-to: "\"{}\"에 투표하기"
|
||||||
vote-count: "{}표"
|
vote-count: "{}표"
|
||||||
total-users: "{}명이 투표"
|
total-votes: "총 {}표"
|
||||||
vote: "투표하기"
|
vote: "투표하기"
|
||||||
show-result: "결과 보기"
|
show-result: "결과 보기"
|
||||||
voted: "투표함"
|
voted: "투표함"
|
||||||
|
closed: "종료됨"
|
||||||
|
remaining-days: "종료까지 앞으로 {d}일 {h}시간"
|
||||||
|
remaining-hours: "종료까지 앞으로 {h}시간 {m}분"
|
||||||
|
remaining-minutes: "종료까지 앞으로 {m}분 {s}초"
|
||||||
|
remaining-seconds: "종료까지 앞으로 {s}초"
|
||||||
common/views/components/poll-editor.vue:
|
common/views/components/poll-editor.vue:
|
||||||
no-only-one-choice: "투표에는 선택지가 최소한 두 개 필요합니다"
|
no-only-one-choice: "투표에는 선택지가 최소한 두 개 필요합니다"
|
||||||
choice-n: "선택지 {}"
|
choice-n: "선택지 {}"
|
||||||
remove: "이 선택지를 제거"
|
remove: "이 선택지를 제거"
|
||||||
add: "+선택지 추가"
|
add: "+선택지 추가"
|
||||||
destroy: "투표 제거"
|
destroy: "투표 제거"
|
||||||
|
multiple: "복수 응답 가능"
|
||||||
|
expiration: "기한"
|
||||||
|
infinite: "무기한"
|
||||||
|
at: "일시 지정"
|
||||||
|
after: "기간 지정"
|
||||||
|
no-more: "더 이상 추가할 수 없습니다"
|
||||||
|
deadline-date: "기한"
|
||||||
|
deadline-time: "시간"
|
||||||
|
interval: "기간"
|
||||||
|
unit: "단위"
|
||||||
|
second: "초"
|
||||||
|
minute: "분"
|
||||||
|
hour: "시간"
|
||||||
|
day: "일"
|
||||||
common/views/components/reaction-picker.vue:
|
common/views/components/reaction-picker.vue:
|
||||||
choose-reaction: "반응 선택"
|
choose-reaction: "반응 선택"
|
||||||
common/views/components/emoji-picker.vue:
|
common/views/components/emoji-picker.vue:
|
||||||
@@ -628,12 +648,16 @@ common/views/components/profile-editor.vue:
|
|||||||
email-verified: "매일 주소가 확인되었습니다"
|
email-verified: "매일 주소가 확인되었습니다"
|
||||||
email-not-verified: "메일 주소가 확인되지 않았습니다. 받은 편지함을 확인하여 주시기 바랍니다."
|
email-not-verified: "메일 주소가 확인되지 않았습니다. 받은 편지함을 확인하여 주시기 바랍니다."
|
||||||
export: "내보내기"
|
export: "내보내기"
|
||||||
|
import: "가져오기"
|
||||||
|
export-and-import: "내보내기와 가져오기"
|
||||||
export-targets:
|
export-targets:
|
||||||
all-notes: "모든 글 데이터"
|
all-notes: "모든 글 데이터"
|
||||||
following-list: "팔로잉"
|
following-list: "팔로잉"
|
||||||
mute-list: "뮤트"
|
mute-list: "뮤트"
|
||||||
blocking-list: "차단"
|
blocking-list: "차단"
|
||||||
|
user-lists: "리스트"
|
||||||
export-requested: "내보내기를 요청하였습니다. 이 작업은 시간이 걸릴 수 있습니다. 내보내기가 완료되면 드라이브에 파일이 추가됩니다."
|
export-requested: "내보내기를 요청하였습니다. 이 작업은 시간이 걸릴 수 있습니다. 내보내기가 완료되면 드라이브에 파일이 추가됩니다."
|
||||||
|
import-requested: "가져오기를 요청하였습니다. 이 작업에는 시간이 걸릴 수 있습니다."
|
||||||
enter-password: "비밀번호를 입력하여 주십시오"
|
enter-password: "비밀번호를 입력하여 주십시오"
|
||||||
danger-zone: "위험한 설정"
|
danger-zone: "위험한 설정"
|
||||||
delete-account: "계정 삭제"
|
delete-account: "계정 삭제"
|
||||||
@@ -1033,7 +1057,7 @@ admin/views/dashboard.vue:
|
|||||||
this-instance: "이 인스턴스"
|
this-instance: "이 인스턴스"
|
||||||
federated: "연합"
|
federated: "연합"
|
||||||
admin/views/queue.vue:
|
admin/views/queue.vue:
|
||||||
operation: "동작"
|
title: "큐"
|
||||||
remove-all-jobs: "모든 작업 제거"
|
remove-all-jobs: "모든 작업 제거"
|
||||||
admin/views/abuse.vue:
|
admin/views/abuse.vue:
|
||||||
title: "스팸 신고"
|
title: "스팸 신고"
|
||||||
@@ -1251,12 +1275,13 @@ admin/views/announcements.vue:
|
|||||||
admin/views/hashtags.vue:
|
admin/views/hashtags.vue:
|
||||||
hided-tags: "Hidden Tags"
|
hided-tags: "Hidden Tags"
|
||||||
admin/views/federation.vue:
|
admin/views/federation.vue:
|
||||||
federation: "연합"
|
instance: "인스턴스"
|
||||||
host: "호스트"
|
host: "호스트"
|
||||||
notes: "글"
|
notes: "글"
|
||||||
users: "사용자"
|
users: "사용자"
|
||||||
following: "팔로우 중"
|
following: "팔로우 중"
|
||||||
followers: "팔로워"
|
followers: "팔로워"
|
||||||
|
caught-at: "등록 날짜"
|
||||||
status: "상태"
|
status: "상태"
|
||||||
latest-request-sent-at: "마지막으로 요청을 전송한 시간"
|
latest-request-sent-at: "마지막으로 요청을 전송한 시간"
|
||||||
latest-request-received-at: "마지막으로 요청을 받은 시간"
|
latest-request-received-at: "마지막으로 요청을 받은 시간"
|
||||||
@@ -1265,7 +1290,7 @@ admin/views/federation.vue:
|
|||||||
block: "차단"
|
block: "차단"
|
||||||
marked-as-closed: "폐쇄된 것으로 표시"
|
marked-as-closed: "폐쇄된 것으로 표시"
|
||||||
lookup: "조회"
|
lookup: "조회"
|
||||||
instances: "인스턴스"
|
instances: "연합"
|
||||||
instance-not-registered: "해당 인스턴스가 등록되어 있지 않습니다"
|
instance-not-registered: "해당 인스턴스가 등록되어 있지 않습니다"
|
||||||
sort: "정렬"
|
sort: "정렬"
|
||||||
sorts:
|
sorts:
|
||||||
@@ -1328,8 +1353,6 @@ desktop/views/pages/selectdrive.vue:
|
|||||||
desktop/views/pages/search.vue:
|
desktop/views/pages/search.vue:
|
||||||
not-available: "검색 기능은 인스턴스 설정에서 비활성화되어 있습니다."
|
not-available: "검색 기능은 인스턴스 설정에서 비활성화되어 있습니다."
|
||||||
not-found: "\"{q}\" 와 일치하는 글을 찾을 수 없습니다."
|
not-found: "\"{q}\" 와 일치하는 글을 찾을 수 없습니다."
|
||||||
desktop/views/pages/share.vue:
|
|
||||||
share-with: "{name}(으)로 공유"
|
|
||||||
desktop/views/pages/tag.vue:
|
desktop/views/pages/tag.vue:
|
||||||
no-posts-found: "해시태그 \"{q}\"가 붙은 글을 찾을 수 없습니다."
|
no-posts-found: "해시태그 \"{q}\"가 붙은 글을 찾을 수 없습니다."
|
||||||
desktop/views/pages/user-list.users.vue:
|
desktop/views/pages/user-list.users.vue:
|
||||||
|
@@ -131,7 +131,6 @@ common/views/components/note-menu.vue:
|
|||||||
common/views/components/poll.vue:
|
common/views/components/poll.vue:
|
||||||
vote-to: "Stemmen op '{}'"
|
vote-to: "Stemmen op '{}'"
|
||||||
vote-count: "{} stemmen"
|
vote-count: "{} stemmen"
|
||||||
total-users: "{} gebruikers hebben gestemd"
|
|
||||||
vote: "Stemmen"
|
vote: "Stemmen"
|
||||||
show-result: "Resultaten tonen"
|
show-result: "Resultaten tonen"
|
||||||
voted: "Gestemd"
|
voted: "Gestemd"
|
||||||
@@ -141,6 +140,7 @@ common/views/components/poll-editor.vue:
|
|||||||
remove: "Deze keuze verwijderen"
|
remove: "Deze keuze verwijderen"
|
||||||
add: "+ Keuze toevoegen"
|
add: "+ Keuze toevoegen"
|
||||||
destroy: "Deze peiling vernietigen"
|
destroy: "Deze peiling vernietigen"
|
||||||
|
day: "Z"
|
||||||
common/views/components/reaction-picker.vue:
|
common/views/components/reaction-picker.vue:
|
||||||
choose-reaction: "Kies een reactie"
|
choose-reaction: "Kies een reactie"
|
||||||
common/views/components/emoji-picker.vue:
|
common/views/components/emoji-picker.vue:
|
||||||
@@ -196,6 +196,7 @@ common/views/components/profile-editor.vue:
|
|||||||
banner: "Omslagfoto"
|
banner: "Omslagfoto"
|
||||||
export-targets:
|
export-targets:
|
||||||
following-list: "Volgend"
|
following-list: "Volgend"
|
||||||
|
user-lists: "Lijsten"
|
||||||
enter-password: "Voer het wachtwoord in"
|
enter-password: "Voer het wachtwoord in"
|
||||||
common/views/components/user-list-editor.vue:
|
common/views/components/user-list-editor.vue:
|
||||||
users: "Gebruiker"
|
users: "Gebruiker"
|
||||||
|
@@ -151,6 +151,7 @@ common/views/components/poll.vue:
|
|||||||
voted: "Stemt"
|
voted: "Stemt"
|
||||||
common/views/components/poll-editor.vue:
|
common/views/components/poll-editor.vue:
|
||||||
choice-n: "Valg {}"
|
choice-n: "Valg {}"
|
||||||
|
day: "S"
|
||||||
common/views/components/signin.vue:
|
common/views/components/signin.vue:
|
||||||
username: "Brukernavn"
|
username: "Brukernavn"
|
||||||
password: "Passord"
|
password: "Passord"
|
||||||
@@ -186,6 +187,7 @@ common/views/components/profile-editor.vue:
|
|||||||
save: "Lagre"
|
save: "Lagre"
|
||||||
export-targets:
|
export-targets:
|
||||||
following-list: "Følger"
|
following-list: "Følger"
|
||||||
|
user-lists: "Lister"
|
||||||
common/views/components/user-list-editor.vue:
|
common/views/components/user-list-editor.vue:
|
||||||
users: "Bruker"
|
users: "Bruker"
|
||||||
common/views/widgets/broadcast.vue:
|
common/views/widgets/broadcast.vue:
|
||||||
|
@@ -26,6 +26,7 @@ common:
|
|||||||
dark-mode: "Tryb ciemny"
|
dark-mode: "Tryb ciemny"
|
||||||
signin: "Zaloguj się"
|
signin: "Zaloguj się"
|
||||||
signup: "Rejestracja"
|
signup: "Rejestracja"
|
||||||
|
signout: "Wyloguj się"
|
||||||
got-it: "Rozumiem!"
|
got-it: "Rozumiem!"
|
||||||
customization-tips:
|
customization-tips:
|
||||||
title: "Wskazówki o dostosowywaniu"
|
title: "Wskazówki o dostosowywaniu"
|
||||||
@@ -120,7 +121,35 @@ common:
|
|||||||
other: "Inne"
|
other: "Inne"
|
||||||
appearance: "Wygląd"
|
appearance: "Wygląd"
|
||||||
behavior: "Zachowanie"
|
behavior: "Zachowanie"
|
||||||
|
fetch-on-scroll: "Automatycznie ładuj po przeciągnięciu w dół"
|
||||||
|
note-visibility: "Widoczność wpisów"
|
||||||
|
web-search-engine: "Wyszukiwarka internetowa"
|
||||||
|
line-width: "Szerokości linii"
|
||||||
|
line-width-thin: "Cienka"
|
||||||
|
line-width-normal: "Normalna"
|
||||||
|
line-width-thick: "Gruba"
|
||||||
|
font-size: "Rozmiar tekstu"
|
||||||
|
font-size-x-small: "Małe"
|
||||||
|
font-size-medium: "Normalna"
|
||||||
|
font-size-large: "Trochę duży"
|
||||||
|
font-size-x-large: "Duży"
|
||||||
|
deck-column-align-center: "Po środku"
|
||||||
|
deck-column-align-left: "Z lewej"
|
||||||
|
deck-column-align-flexible: "Elastyczne"
|
||||||
|
deck-column-width: "Szerokość kolumn w talii"
|
||||||
|
deck-column-width-narrow: "Wąska"
|
||||||
|
deck-column-width-narrower: "Trochę wąska"
|
||||||
|
deck-column-width-normal: "Normalna"
|
||||||
|
deck-column-width-wider: "Trochę szerokie"
|
||||||
|
deck-column-width-wide: "Szeroka"
|
||||||
|
wallpaper: "Tapeta"
|
||||||
|
choose-wallpaper: "Wybierz tapetę"
|
||||||
timeline: "Oś czasu"
|
timeline: "Oś czasu"
|
||||||
|
sound: "Dźwięk"
|
||||||
|
test: "Test"
|
||||||
|
update: "Aktualizacja Misskey"
|
||||||
|
version: "Wersja:"
|
||||||
|
navbar-position-left: "Z lewej"
|
||||||
search: "Szukaj"
|
search: "Szukaj"
|
||||||
delete: "Usuń"
|
delete: "Usuń"
|
||||||
loading: "Ładowanie"
|
loading: "Ładowanie"
|
||||||
@@ -346,7 +375,6 @@ common/views/components/user-menu.vue:
|
|||||||
common/views/components/poll.vue:
|
common/views/components/poll.vue:
|
||||||
vote-to: "Zagłosuj na '{}'"
|
vote-to: "Zagłosuj na '{}'"
|
||||||
vote-count: "{} głosów"
|
vote-count: "{} głosów"
|
||||||
total-users: "{} głosujących"
|
|
||||||
vote: "Zagłosuj"
|
vote: "Zagłosuj"
|
||||||
show-result: "Pokaż wyniki"
|
show-result: "Pokaż wyniki"
|
||||||
voted: "Zagłosowano"
|
voted: "Zagłosowano"
|
||||||
@@ -356,6 +384,7 @@ common/views/components/poll-editor.vue:
|
|||||||
remove: "Usuń tą opcję"
|
remove: "Usuń tą opcję"
|
||||||
add: "+ Dodaj opcję"
|
add: "+ Dodaj opcję"
|
||||||
destroy: "Usuń tę ankietę"
|
destroy: "Usuń tę ankietę"
|
||||||
|
day: "N"
|
||||||
common/views/components/reaction-picker.vue:
|
common/views/components/reaction-picker.vue:
|
||||||
choose-reaction: "Wybierz reakcję"
|
choose-reaction: "Wybierz reakcję"
|
||||||
common/views/components/emoji-picker.vue:
|
common/views/components/emoji-picker.vue:
|
||||||
@@ -472,10 +501,12 @@ common/views/components/profile-editor.vue:
|
|||||||
email-address: "Adres e-mail"
|
email-address: "Adres e-mail"
|
||||||
email-verified: "Twój adres e-mail został zweryfikowany."
|
email-verified: "Twój adres e-mail został zweryfikowany."
|
||||||
export: "Eksportuj"
|
export: "Eksportuj"
|
||||||
|
import: "Importuj"
|
||||||
export-targets:
|
export-targets:
|
||||||
following-list: "Śledzeni"
|
following-list: "Śledzeni"
|
||||||
mute-list: "Wycisz"
|
mute-list: "Wycisz"
|
||||||
blocking-list: "Zablokuj"
|
blocking-list: "Zablokuj"
|
||||||
|
user-lists: "Listy"
|
||||||
enter-password: "Wprowadź hasło"
|
enter-password: "Wprowadź hasło"
|
||||||
common/views/components/user-list-editor.vue:
|
common/views/components/user-list-editor.vue:
|
||||||
users: "Użytkownicy"
|
users: "Użytkownicy"
|
||||||
@@ -916,13 +947,14 @@ admin/views/announcements.vue:
|
|||||||
are-you-sure: "Usunąć \"$1\"?"
|
are-you-sure: "Usunąć \"$1\"?"
|
||||||
removed: "Usunięto"
|
removed: "Usunięto"
|
||||||
admin/views/federation.vue:
|
admin/views/federation.vue:
|
||||||
|
instance: "Instancja"
|
||||||
notes: "Wpis"
|
notes: "Wpis"
|
||||||
users: "Użytkownicy"
|
users: "Użytkownicy"
|
||||||
following: "Śledzisz"
|
following: "Śledzisz"
|
||||||
followers: "Śledzący"
|
followers: "Śledzący"
|
||||||
|
caught-at: "Utworzono"
|
||||||
status: "Stan"
|
status: "Stan"
|
||||||
block: "Zablokuj"
|
block: "Zablokuj"
|
||||||
instances: "Instancja"
|
|
||||||
sort: "Sortuj"
|
sort: "Sortuj"
|
||||||
states:
|
states:
|
||||||
all: "Wszyscy"
|
all: "Wszyscy"
|
||||||
|
@@ -158,6 +158,8 @@ common/views/components/messaging.vue:
|
|||||||
you: "Você"
|
you: "Você"
|
||||||
common/views/components/note-menu.vue:
|
common/views/components/note-menu.vue:
|
||||||
delete: "Apagar"
|
delete: "Apagar"
|
||||||
|
common/views/components/poll-editor.vue:
|
||||||
|
day: "Dom"
|
||||||
common/views/components/visibility-chooser.vue:
|
common/views/components/visibility-chooser.vue:
|
||||||
followers: "Seguidores"
|
followers: "Seguidores"
|
||||||
common/views/components/profile-editor.vue:
|
common/views/components/profile-editor.vue:
|
||||||
|
@@ -127,6 +127,8 @@ common/views/components/connect-failed.vue:
|
|||||||
title: "Невозможно подключиться к серверу"
|
title: "Невозможно подключиться к серверу"
|
||||||
common/views/components/cw-button.vue:
|
common/views/components/cw-button.vue:
|
||||||
poll: "Голосования"
|
poll: "Голосования"
|
||||||
|
common/views/components/poll-editor.vue:
|
||||||
|
day: "Вс"
|
||||||
common/views/widgets/memo.vue:
|
common/views/widgets/memo.vue:
|
||||||
title: "Заметка"
|
title: "Заметка"
|
||||||
desktop/views/components/sub-note-content.vue:
|
desktop/views/components/sub-note-content.vue:
|
||||||
|
@@ -314,6 +314,7 @@ common/views/pages/explore.vue:
|
|||||||
users-info: "当前有{users}个注册用户"
|
users-info: "当前有{users}个注册用户"
|
||||||
common/views/components/url-preview.vue:
|
common/views/components/url-preview.vue:
|
||||||
enable-player: "打开播放器"
|
enable-player: "打开播放器"
|
||||||
|
disable-player: "关闭播放器"
|
||||||
common/views/components/user-list.vue:
|
common/views/components/user-list.vue:
|
||||||
no-users: "无用户"
|
no-users: "无用户"
|
||||||
common/views/components/games/reversi/reversi.vue:
|
common/views/components/games/reversi/reversi.vue:
|
||||||
@@ -489,16 +490,35 @@ common/views/components/user-menu.vue:
|
|||||||
common/views/components/poll.vue:
|
common/views/components/poll.vue:
|
||||||
vote-to: "为\"{}\"投票"
|
vote-to: "为\"{}\"投票"
|
||||||
vote-count: "{}票"
|
vote-count: "{}票"
|
||||||
total-users: "{} 人投票"
|
total-votes: "总票数{}"
|
||||||
vote: "投票"
|
vote: "投票"
|
||||||
show-result: "显示结果"
|
show-result: "显示结果"
|
||||||
voted: "已投票"
|
voted: "已投票"
|
||||||
|
closed: "已截止"
|
||||||
|
remaining-days: "{d}天{h}小时后截止"
|
||||||
|
remaining-hours: "{h}小时{m}分后截止"
|
||||||
|
remaining-minutes: "{m}分{s}秒后截止"
|
||||||
|
remaining-seconds: "{s}秒后截止"
|
||||||
common/views/components/poll-editor.vue:
|
common/views/components/poll-editor.vue:
|
||||||
no-only-one-choice: "至少选择两个选项"
|
no-only-one-choice: "至少选择两个选项"
|
||||||
choice-n: "选择{}"
|
choice-n: "选择{}"
|
||||||
remove: "删除选项"
|
remove: "删除选项"
|
||||||
add: "+添加一个选项"
|
add: "+添加一个选项"
|
||||||
destroy: "放弃投票"
|
destroy: "放弃投票"
|
||||||
|
multiple: "允许多个投票"
|
||||||
|
expiration: "截止时间"
|
||||||
|
infinite: "永久"
|
||||||
|
at: "指定日期"
|
||||||
|
after: "指定时间"
|
||||||
|
no-more: "最多只能添加十个回答"
|
||||||
|
deadline-date: "日期"
|
||||||
|
deadline-time: "时间"
|
||||||
|
interval: "时长"
|
||||||
|
unit: "单位"
|
||||||
|
second: "秒"
|
||||||
|
minute: "分"
|
||||||
|
hour: "小时"
|
||||||
|
day: "日"
|
||||||
common/views/components/reaction-picker.vue:
|
common/views/components/reaction-picker.vue:
|
||||||
choose-reaction: "选择回应"
|
choose-reaction: "选择回应"
|
||||||
common/views/components/emoji-picker.vue:
|
common/views/components/emoji-picker.vue:
|
||||||
@@ -628,12 +648,16 @@ common/views/components/profile-editor.vue:
|
|||||||
email-verified: "电子邮件地址已验证"
|
email-verified: "电子邮件地址已验证"
|
||||||
email-not-verified: "邮件地址尚未验证。 请检查您的邮箱。"
|
email-not-verified: "邮件地址尚未验证。 请检查您的邮箱。"
|
||||||
export: "导出"
|
export: "导出"
|
||||||
|
import: "导入"
|
||||||
|
export-and-import: "导出/导入"
|
||||||
export-targets:
|
export-targets:
|
||||||
all-notes: "所有发帖"
|
all-notes: "所有发帖"
|
||||||
following-list: "关注列表"
|
following-list: "关注列表"
|
||||||
mute-list: "屏蔽列表"
|
mute-list: "屏蔽列表"
|
||||||
blocking-list: "黑名单"
|
blocking-list: "黑名单"
|
||||||
|
user-lists: "列表"
|
||||||
export-requested: "导出请求已提交。可能需要花一些时间。导出的文件将保存到网盘中。"
|
export-requested: "导出请求已提交。可能需要花一些时间。导出的文件将保存到网盘中。"
|
||||||
|
import-requested: "导入请求已提交。这可能需要花一点时间。"
|
||||||
enter-password: "请输入您的密码"
|
enter-password: "请输入您的密码"
|
||||||
danger-zone: "危险选项"
|
danger-zone: "危险选项"
|
||||||
delete-account: "删除帐户"
|
delete-account: "删除帐户"
|
||||||
@@ -1033,7 +1057,7 @@ admin/views/dashboard.vue:
|
|||||||
this-instance: "此实例"
|
this-instance: "此实例"
|
||||||
federated: "联合"
|
federated: "联合"
|
||||||
admin/views/queue.vue:
|
admin/views/queue.vue:
|
||||||
operation: "操作"
|
title: "队列"
|
||||||
remove-all-jobs: "清除所有作业"
|
remove-all-jobs: "清除所有作业"
|
||||||
admin/views/abuse.vue:
|
admin/views/abuse.vue:
|
||||||
title: "举报垃圾信息"
|
title: "举报垃圾信息"
|
||||||
@@ -1251,12 +1275,13 @@ admin/views/announcements.vue:
|
|||||||
admin/views/hashtags.vue:
|
admin/views/hashtags.vue:
|
||||||
hided-tags: "隐藏标签"
|
hided-tags: "隐藏标签"
|
||||||
admin/views/federation.vue:
|
admin/views/federation.vue:
|
||||||
federation: "联合"
|
instance: "例"
|
||||||
host: "主机名"
|
host: "主机名"
|
||||||
notes: "帖子"
|
notes: "帖子"
|
||||||
users: "用户"
|
users: "用户"
|
||||||
following: "正在关注"
|
following: "正在关注"
|
||||||
followers: "关注者"
|
followers: "关注者"
|
||||||
|
caught-at: "注册日期"
|
||||||
status: "状态"
|
status: "状态"
|
||||||
latest-request-sent-at: "上次发送的请求"
|
latest-request-sent-at: "上次发送的请求"
|
||||||
latest-request-received-at: "上次收到的请求"
|
latest-request-received-at: "上次收到的请求"
|
||||||
@@ -1265,7 +1290,7 @@ admin/views/federation.vue:
|
|||||||
block: "拉黑"
|
block: "拉黑"
|
||||||
marked-as-closed: "标记为已关闭"
|
marked-as-closed: "标记为已关闭"
|
||||||
lookup: "查询"
|
lookup: "查询"
|
||||||
instances: "实例"
|
instances: "联合"
|
||||||
instance-not-registered: "实例未注册"
|
instance-not-registered: "实例未注册"
|
||||||
sort: "排序"
|
sort: "排序"
|
||||||
sorts:
|
sorts:
|
||||||
@@ -1328,8 +1353,6 @@ desktop/views/pages/selectdrive.vue:
|
|||||||
desktop/views/pages/search.vue:
|
desktop/views/pages/search.vue:
|
||||||
not-available: "在此实例的设置中关闭搜索功能。"
|
not-available: "在此实例的设置中关闭搜索功能。"
|
||||||
not-found: "没有找到“{q}”的帖子"
|
not-found: "没有找到“{q}”的帖子"
|
||||||
desktop/views/pages/share.vue:
|
|
||||||
share-with: "共享{name}"
|
|
||||||
desktop/views/pages/tag.vue:
|
desktop/views/pages/tag.vue:
|
||||||
no-posts-found: "没有找到带有主题标签“{q}”的帖子"
|
no-posts-found: "没有找到带有主题标签“{q}”的帖子"
|
||||||
desktop/views/pages/user-list.users.vue:
|
desktop/views/pages/user-list.users.vue:
|
||||||
|
88
locales/zh-TW.yml
Normal file
88
locales/zh-TW.yml
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
---
|
||||||
|
meta:
|
||||||
|
lang: "中文(繁体)"
|
||||||
|
common:
|
||||||
|
intro:
|
||||||
|
title: "什麽是 Misskey 呢?"
|
||||||
|
rich-contents: "發佈"
|
||||||
|
reaction: "回應"
|
||||||
|
drive: "雲端硬碟"
|
||||||
|
adblock:
|
||||||
|
detected: "請禁用廣告封鎖器"
|
||||||
|
close: "關閉"
|
||||||
|
enter-password: "請輸入密碼"
|
||||||
|
2fa: "雙重身份驗證"
|
||||||
|
dark-mode: "夜間模式"
|
||||||
|
signup: "註冊"
|
||||||
|
signout: "登出"
|
||||||
|
notification:
|
||||||
|
reversi-invited: "您已被邀請加入壹場遊戲"
|
||||||
|
reversi-invited-by: "來自{}的邀請"
|
||||||
|
notified-by: "來自{}的邀請"
|
||||||
|
time:
|
||||||
|
future: "未來"
|
||||||
|
just_now: "剛剛"
|
||||||
|
drive: "雲端硬碟"
|
||||||
|
weekday:
|
||||||
|
sunday: "週日"
|
||||||
|
monday: "週一"
|
||||||
|
tuesday: "週二"
|
||||||
|
wednesday: "週三"
|
||||||
|
thursday: "週四"
|
||||||
|
friday: "週五"
|
||||||
|
saturday: "週六"
|
||||||
|
reactions:
|
||||||
|
like: "贊"
|
||||||
|
love: "喜歡"
|
||||||
|
congrats: "恭喜"
|
||||||
|
_settings:
|
||||||
|
password: "密碼"
|
||||||
|
font-size: "字體大小"
|
||||||
|
font-size-x-small: "小"
|
||||||
|
font-size-small: "較小"
|
||||||
|
deck-column-width-wide: "寬"
|
||||||
|
timeline: "時間軸"
|
||||||
|
common/views/components/connect-failed.troubleshooter.vue:
|
||||||
|
flush: "清除快取"
|
||||||
|
common/views/components/theme.vue:
|
||||||
|
light-themes: "淺色主題"
|
||||||
|
dark-themes: "深色主題"
|
||||||
|
install-a-theme: "安裝主題"
|
||||||
|
save-created-theme: "保存主題"
|
||||||
|
common/views/components/signin.vue:
|
||||||
|
signin-with-twitter: "用 Twitter 帳號登入"
|
||||||
|
signin-with-github: "用 GitHub 帳號登入"
|
||||||
|
signin-with-discord: "用 Discord 帳號登入"
|
||||||
|
login-failed: "登錄失敗。 請檢查用戶名和密碼。"
|
||||||
|
common/views/components/signup.vue:
|
||||||
|
invitation-code: "邀請碼"
|
||||||
|
username: "用戶名"
|
||||||
|
available: "可用"
|
||||||
|
too-long: "請不要超過20個字元"
|
||||||
|
password: "密碼"
|
||||||
|
password-placeholder: "建議至少8個字元"
|
||||||
|
common/views/components/stream-indicator.vue:
|
||||||
|
connecting: "正在連線"
|
||||||
|
reconnecting: "正在重新連線"
|
||||||
|
connected: "已建立連線"
|
||||||
|
common/views/components/integration-settings.vue:
|
||||||
|
disconnect: "中斷連線"
|
||||||
|
common/views/components/github-setting.vue:
|
||||||
|
reconnect: "重新連線"
|
||||||
|
disconnect: "中斷連線"
|
||||||
|
common/views/components/discord-setting.vue:
|
||||||
|
reconnect: "重新連線"
|
||||||
|
disconnect: "中斷連線"
|
||||||
|
common/views/components/language-settings.vue:
|
||||||
|
recommended: "推薦"
|
||||||
|
auto: "自動"
|
||||||
|
specify-language: "指定語言"
|
||||||
|
common/views/components/profile-editor.vue:
|
||||||
|
title: "個人資料"
|
||||||
|
name: "名稱"
|
||||||
|
birthday: "生日:"
|
||||||
|
privacy: "隱私"
|
||||||
|
admin/views/dashboard.vue:
|
||||||
|
drive: "雲端硬碟"
|
||||||
|
admin/views/charts.vue:
|
||||||
|
drive: "雲端硬碟"
|
60
package.json
60
package.json
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "misskey",
|
"name": "misskey",
|
||||||
"author": "syuilo <i@syuilo.com>",
|
"author": "syuilo <i@syuilo.com>",
|
||||||
"version": "10.91.2",
|
"version": "10.97.2",
|
||||||
"codename": "nighthike",
|
"codename": "nighthike",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@@ -32,6 +32,7 @@
|
|||||||
"@prezzemolo/rap": "0.1.2",
|
"@prezzemolo/rap": "0.1.2",
|
||||||
"@prezzemolo/zip": "0.0.3",
|
"@prezzemolo/zip": "0.0.3",
|
||||||
"@types/bcryptjs": "2.4.2",
|
"@types/bcryptjs": "2.4.2",
|
||||||
|
"@types/bull": "3.5.8",
|
||||||
"@types/chai-http": "3.0.5",
|
"@types/chai-http": "3.0.5",
|
||||||
"@types/dateformat": "3.0.0",
|
"@types/dateformat": "3.0.0",
|
||||||
"@types/deep-equal": "1.0.1",
|
"@types/deep-equal": "1.0.1",
|
||||||
@@ -45,7 +46,6 @@
|
|||||||
"@types/gulp-uglify": "3.0.6",
|
"@types/gulp-uglify": "3.0.6",
|
||||||
"@types/gulp-util": "3.0.34",
|
"@types/gulp-util": "3.0.34",
|
||||||
"@types/is-root": "1.0.0",
|
"@types/is-root": "1.0.0",
|
||||||
"@types/is-svg": "3.0.0",
|
|
||||||
"@types/is-url": "1.2.28",
|
"@types/is-url": "1.2.28",
|
||||||
"@types/js-yaml": "3.12.0",
|
"@types/js-yaml": "3.12.0",
|
||||||
"@types/jsdom": "12.2.3",
|
"@types/jsdom": "12.2.3",
|
||||||
@@ -58,7 +58,7 @@
|
|||||||
"@types/koa-logger": "3.1.1",
|
"@types/koa-logger": "3.1.1",
|
||||||
"@types/koa-mount": "3.0.1",
|
"@types/koa-mount": "3.0.1",
|
||||||
"@types/koa-multer": "1.0.0",
|
"@types/koa-multer": "1.0.0",
|
||||||
"@types/koa-router": "7.0.39",
|
"@types/koa-router": "7.0.40",
|
||||||
"@types/koa-send": "4.1.1",
|
"@types/koa-send": "4.1.1",
|
||||||
"@types/koa-views": "2.0.3",
|
"@types/koa-views": "2.0.3",
|
||||||
"@types/koa__cors": "2.2.3",
|
"@types/koa__cors": "2.2.3",
|
||||||
@@ -66,7 +66,7 @@
|
|||||||
"@types/mkdirp": "0.5.2",
|
"@types/mkdirp": "0.5.2",
|
||||||
"@types/mocha": "5.2.5",
|
"@types/mocha": "5.2.5",
|
||||||
"@types/mongodb": "3.1.20",
|
"@types/mongodb": "3.1.20",
|
||||||
"@types/node": "10.12.24",
|
"@types/node": "11.10.4",
|
||||||
"@types/nodemailer": "4.6.6",
|
"@types/nodemailer": "4.6.6",
|
||||||
"@types/nprogress": "0.0.29",
|
"@types/nprogress": "0.0.29",
|
||||||
"@types/oauth": "0.9.1",
|
"@types/oauth": "0.9.1",
|
||||||
@@ -84,7 +84,7 @@
|
|||||||
"@types/seedrandom": "2.4.27",
|
"@types/seedrandom": "2.4.27",
|
||||||
"@types/sharp": "0.21.2",
|
"@types/sharp": "0.21.2",
|
||||||
"@types/showdown": "1.9.2",
|
"@types/showdown": "1.9.2",
|
||||||
"@types/speakeasy": "2.0.3",
|
"@types/speakeasy": "2.0.4",
|
||||||
"@types/systeminformation": "3.23.1",
|
"@types/systeminformation": "3.23.1",
|
||||||
"@types/tinycolor2": "1.4.1",
|
"@types/tinycolor2": "1.4.1",
|
||||||
"@types/tmp": "0.0.33",
|
"@types/tmp": "0.0.33",
|
||||||
@@ -95,34 +95,34 @@
|
|||||||
"@types/websocket": "0.0.40",
|
"@types/websocket": "0.0.40",
|
||||||
"@types/ws": "6.0.1",
|
"@types/ws": "6.0.1",
|
||||||
"animejs": "3.0.1",
|
"animejs": "3.0.1",
|
||||||
"apexcharts": "3.5.0",
|
"apexcharts": "3.6.2",
|
||||||
"autobind-decorator": "2.4.0",
|
"autobind-decorator": "2.4.0",
|
||||||
"autosize": "4.0.2",
|
"autosize": "4.0.2",
|
||||||
"autwh": "0.1.0",
|
"autwh": "0.1.0",
|
||||||
"bcryptjs": "2.4.3",
|
"bcryptjs": "2.4.3",
|
||||||
"bee-queue": "1.2.2",
|
"bootstrap-vue": "2.0.0-rc.13",
|
||||||
"bootstrap-vue": "2.0.0-rc.11",
|
"bull": "3.7.0",
|
||||||
"cafy": "15.1.0",
|
"cafy": "15.1.0",
|
||||||
"chai": "4.2.0",
|
"chai": "4.2.0",
|
||||||
"chai-http": "4.2.1",
|
"chai-http": "4.2.1",
|
||||||
"chalk": "2.4.2",
|
"chalk": "2.4.2",
|
||||||
"commander": "2.19.0",
|
"commander": "2.19.0",
|
||||||
"crc-32": "1.2.0",
|
"crc-32": "1.2.0",
|
||||||
"css-loader": "2.1.0",
|
"css-loader": "2.1.1",
|
||||||
"cssnano": "4.1.10",
|
"cssnano": "4.1.10",
|
||||||
"dateformat": "3.0.3",
|
"dateformat": "3.0.3",
|
||||||
"deep-equal": "1.0.1",
|
"deep-equal": "1.0.1",
|
||||||
"deepcopy": "0.6.3",
|
"deepcopy": "0.6.3",
|
||||||
"diskusage": "1.0.0",
|
"diskusage": "1.0.0",
|
||||||
"double-ended-queue": "2.1.0-0",
|
"double-ended-queue": "2.1.0-0",
|
||||||
"elasticsearch": "15.3.1",
|
"elasticsearch": "15.4.1",
|
||||||
"emojilib": "2.4.0",
|
"emojilib": "2.4.0",
|
||||||
"escape-regexp": "0.0.1",
|
"escape-regexp": "0.0.1",
|
||||||
"eslint": "5.12.0",
|
"eslint": "5.15.1",
|
||||||
"eslint-plugin-vue": "5.2.2",
|
"eslint-plugin-vue": "5.2.2",
|
||||||
"eventemitter3": "3.1.0",
|
"eventemitter3": "3.1.0",
|
||||||
"feed": "2.0.2",
|
"feed": "2.0.4",
|
||||||
"file-type": "10.7.1",
|
"file-type": "10.9.0",
|
||||||
"fuckadblock": "3.2.1",
|
"fuckadblock": "3.2.1",
|
||||||
"gulp": "4.0.0",
|
"gulp": "4.0.0",
|
||||||
"gulp-cssnano": "2.1.3",
|
"gulp-cssnano": "2.1.3",
|
||||||
@@ -130,21 +130,20 @@
|
|||||||
"gulp-mocha": "6.0.0",
|
"gulp-mocha": "6.0.0",
|
||||||
"gulp-rename": "1.4.0",
|
"gulp-rename": "1.4.0",
|
||||||
"gulp-replace": "1.0.0",
|
"gulp-replace": "1.0.0",
|
||||||
"gulp-sourcemaps": "2.6.4",
|
"gulp-sourcemaps": "2.6.5",
|
||||||
"gulp-stylus": "2.7.0",
|
"gulp-stylus": "2.7.0",
|
||||||
"gulp-tslint": "8.1.3",
|
"gulp-tslint": "8.1.4",
|
||||||
"gulp-typescript": "5.0.0",
|
"gulp-typescript": "5.0.0",
|
||||||
"gulp-uglify": "3.0.1",
|
"gulp-uglify": "3.0.2",
|
||||||
"gulp-util": "3.0.8",
|
"gulp-util": "3.0.8",
|
||||||
"gulp-yaml": "2.0.3",
|
|
||||||
"hard-source-webpack-plugin": "0.13.1",
|
"hard-source-webpack-plugin": "0.13.1",
|
||||||
"html-minifier": "3.5.21",
|
"html-minifier": "3.5.21",
|
||||||
"http-signature": "1.2.0",
|
"http-signature": "1.2.0",
|
||||||
"insert-text-at-cursor": "0.1.2",
|
"insert-text-at-cursor": "0.1.2",
|
||||||
"is-root": "2.0.0",
|
"is-root": "2.0.0",
|
||||||
"is-svg": "3.0.0",
|
"is-svg": "4.0.0",
|
||||||
"js-yaml": "3.12.1",
|
"js-yaml": "3.12.2",
|
||||||
"jsdom": "13.2.0",
|
"jsdom": "14.0.0",
|
||||||
"json5": "2.1.0",
|
"json5": "2.1.0",
|
||||||
"json5-loader": "1.0.1",
|
"json5-loader": "1.0.1",
|
||||||
"katex": "0.10.1",
|
"katex": "0.10.1",
|
||||||
@@ -176,7 +175,6 @@
|
|||||||
"nodemailer": "5.1.1",
|
"nodemailer": "5.1.1",
|
||||||
"nprogress": "0.2.0",
|
"nprogress": "0.2.0",
|
||||||
"object-assign-deep": "0.4.0",
|
"object-assign-deep": "0.4.0",
|
||||||
"on-build-webpack": "0.1.0",
|
|
||||||
"os-utils": "0.0.14",
|
"os-utils": "0.0.14",
|
||||||
"parse5": "5.1.0",
|
"parse5": "5.1.0",
|
||||||
"parsimmon": "1.12.0",
|
"parsimmon": "1.12.0",
|
||||||
@@ -190,13 +188,13 @@
|
|||||||
"pug": "2.0.3",
|
"pug": "2.0.3",
|
||||||
"punycode": "2.1.1",
|
"punycode": "2.1.1",
|
||||||
"qrcode": "1.3.3",
|
"qrcode": "1.3.3",
|
||||||
"randomcolor": "0.5.3",
|
"randomcolor": "0.5.4",
|
||||||
"ratelimiter": "3.2.0",
|
"ratelimiter": "3.3.0",
|
||||||
"recaptcha-promise": "0.1.3",
|
"recaptcha-promise": "0.1.3",
|
||||||
"reconnecting-websocket": "4.1.10",
|
"reconnecting-websocket": "4.1.10",
|
||||||
"redis": "2.8.0",
|
"redis": "2.8.0",
|
||||||
"request": "2.88.0",
|
"request": "2.88.0",
|
||||||
"request-promise-native": "1.0.5",
|
"request-promise-native": "1.0.7",
|
||||||
"request-stats": "3.0.0",
|
"request-stats": "3.0.0",
|
||||||
"rimraf": "2.6.3",
|
"rimraf": "2.6.3",
|
||||||
"rndstr": "1.0.0",
|
"rndstr": "1.0.0",
|
||||||
@@ -211,14 +209,14 @@
|
|||||||
"stylus": "0.54.5",
|
"stylus": "0.54.5",
|
||||||
"stylus-loader": "3.0.2",
|
"stylus-loader": "3.0.2",
|
||||||
"summaly": "2.2.0",
|
"summaly": "2.2.0",
|
||||||
"systeminformation": "4.0.14",
|
"systeminformation": "4.0.16",
|
||||||
"syuilo-password-strength": "0.0.1",
|
"syuilo-password-strength": "0.0.1",
|
||||||
"terser-webpack-plugin": "1.2.3",
|
"terser-webpack-plugin": "1.2.3",
|
||||||
"textarea-caret": "3.1.0",
|
"textarea-caret": "3.1.0",
|
||||||
"tinycolor2": "1.4.1",
|
"tinycolor2": "1.4.1",
|
||||||
"tmp": "0.0.33",
|
"tmp": "0.0.33",
|
||||||
"ts-loader": "5.3.3",
|
"ts-loader": "5.3.3",
|
||||||
"ts-node": "8.0.2",
|
"ts-node": "8.0.3",
|
||||||
"tslint": "5.13.1",
|
"tslint": "5.13.1",
|
||||||
"tslint-sonarts": "1.9.0",
|
"tslint-sonarts": "1.9.0",
|
||||||
"typescript": "3.3.3333",
|
"typescript": "3.3.3333",
|
||||||
@@ -233,7 +231,7 @@
|
|||||||
"vue-color": "2.7.0",
|
"vue-color": "2.7.0",
|
||||||
"vue-content-loading": "1.5.3",
|
"vue-content-loading": "1.5.3",
|
||||||
"vue-cropperjs": "3.0.0",
|
"vue-cropperjs": "3.0.0",
|
||||||
"vue-i18n": "8.8.2",
|
"vue-i18n": "8.9.0",
|
||||||
"vue-js-modal": "1.3.28",
|
"vue-js-modal": "1.3.28",
|
||||||
"vue-json-pretty": "1.4.1",
|
"vue-json-pretty": "1.4.1",
|
||||||
"vue-loader": "15.7.0",
|
"vue-loader": "15.7.0",
|
||||||
@@ -242,18 +240,18 @@
|
|||||||
"vue-router": "3.0.2",
|
"vue-router": "3.0.2",
|
||||||
"vue-sequential-entrance": "1.1.3",
|
"vue-sequential-entrance": "1.1.3",
|
||||||
"vue-style-loader": "4.1.2",
|
"vue-style-loader": "4.1.2",
|
||||||
"vue-svg-inline-loader": "1.2.12",
|
"vue-svg-inline-loader": "1.2.13",
|
||||||
"vue-template-compiler": "2.6.8",
|
"vue-template-compiler": "2.6.8",
|
||||||
"vuedraggable": "2.18.1",
|
"vuedraggable": "2.19.2",
|
||||||
"vuewordcloud": "18.7.11",
|
"vuewordcloud": "18.7.11",
|
||||||
"vuex": "3.1.0",
|
"vuex": "3.1.0",
|
||||||
"vuex-persistedstate": "2.5.4",
|
"vuex-persistedstate": "2.5.4",
|
||||||
"web-push": "3.3.3",
|
"web-push": "3.3.3",
|
||||||
"webfinger.js": "2.7.0",
|
"webfinger.js": "2.7.0",
|
||||||
"webpack": "4.28.4",
|
"webpack": "4.28.4",
|
||||||
"webpack-cli": "3.2.1",
|
"webpack-cli": "3.2.3",
|
||||||
"websocket": "1.0.28",
|
"websocket": "1.0.28",
|
||||||
"ws": "6.1.4",
|
"ws": "6.2.0",
|
||||||
"xev": "2.0.1"
|
"xev": "2.0.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -5,8 +5,7 @@ program
|
|||||||
.version(pkg.version)
|
.version(pkg.version)
|
||||||
.option('--no-daemons', 'Disable daemon processes (for debbuging)')
|
.option('--no-daemons', 'Disable daemon processes (for debbuging)')
|
||||||
.option('--disable-clustering', 'Disable clustering')
|
.option('--disable-clustering', 'Disable clustering')
|
||||||
.option('--disable-queue', 'Disable job queue processing')
|
.option('--only-server', 'Run server only (without job queue processing)')
|
||||||
.option('--only-server', 'Run server only (without job queue)')
|
|
||||||
.option('--only-queue', 'Pocessing job queue only (without server)')
|
.option('--only-queue', 'Pocessing job queue only (without server)')
|
||||||
.option('--quiet', 'Suppress all logs')
|
.option('--quiet', 'Suppress all logs')
|
||||||
.option('--verbose', 'Enable all logs')
|
.option('--verbose', 'Enable all logs')
|
||||||
@@ -15,7 +14,6 @@ program
|
|||||||
.option('--color', 'This option is a dummy for some external program\'s (e.g. forever) issue.')
|
.option('--color', 'This option is a dummy for some external program\'s (e.g. forever) issue.')
|
||||||
.parse(process.argv);
|
.parse(process.argv);
|
||||||
|
|
||||||
/*if (process.env.MK_DISABLE_QUEUE)*/ program.disableQueue = true;
|
|
||||||
if (process.env.MK_ONLY_QUEUE) program.onlyQueue = true;
|
if (process.env.MK_ONLY_QUEUE) program.onlyQueue = true;
|
||||||
|
|
||||||
export { program };
|
export { program };
|
||||||
|
@@ -181,7 +181,12 @@ export default Vue.extend({
|
|||||||
},
|
},
|
||||||
grid: {
|
grid: {
|
||||||
clipMarkers: false,
|
clipMarkers: false,
|
||||||
borderColor: 'rgba(0, 0, 0, 0.1)'
|
borderColor: 'rgba(0, 0, 0, 0.1)',
|
||||||
|
xaxis: {
|
||||||
|
lines: {
|
||||||
|
show: true,
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
stroke: {
|
stroke: {
|
||||||
curve: 'straight',
|
curve: 'straight',
|
196
src/client/app/admin/views/dashboard.queue-charts.vue
Normal file
196
src/client/app/admin/views/dashboard.queue-charts.vue
Normal file
@@ -0,0 +1,196 @@
|
|||||||
|
<template>
|
||||||
|
<div class="mzxlfysy">
|
||||||
|
<div>
|
||||||
|
<header>
|
||||||
|
<span><fa :icon="faInbox"/> In</span>
|
||||||
|
<span v-if="latestStats">{{ latestStats.inbox.activeSincePrevTick | number }} / {{ latestStats.inbox.delayed | number }}</span>
|
||||||
|
</header>
|
||||||
|
<div ref="in"></div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<header>
|
||||||
|
<span><fa :icon="faPaperPlane"/> Out</span>
|
||||||
|
<span v-if="latestStats">{{ latestStats.deliver.activeSincePrevTick | number }} / {{ latestStats.deliver.delayed | number }}</span>
|
||||||
|
</header>
|
||||||
|
<div ref="out"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import Vue from 'vue';
|
||||||
|
import { faInbox } from '@fortawesome/free-solid-svg-icons';
|
||||||
|
import { faPaperPlane } from '@fortawesome/free-regular-svg-icons';
|
||||||
|
import ApexCharts from 'apexcharts';
|
||||||
|
|
||||||
|
const limit = 150;
|
||||||
|
|
||||||
|
export default Vue.extend({
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
stats: [],
|
||||||
|
inChart: null,
|
||||||
|
outChart: null,
|
||||||
|
faInbox, faPaperPlane
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
latestStats(): any {
|
||||||
|
return this.stats[this.stats.length - 1];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
stats(stats) {
|
||||||
|
this.inChart.updateSeries([{
|
||||||
|
data: stats.map((x, i) => ({ x: i, y: x.inbox.activeSincePrevTick }))
|
||||||
|
}, {
|
||||||
|
data: stats.map((x, i) => ({ x: i, y: x.inbox.active }))
|
||||||
|
}, {
|
||||||
|
data: stats.map((x, i) => ({ x: i, y: x.inbox.waiting }))
|
||||||
|
}, {
|
||||||
|
data: stats.map((x, i) => ({ x: i, y: x.inbox.delayed }))
|
||||||
|
}]);
|
||||||
|
this.outChart.updateSeries([{
|
||||||
|
data: stats.map((x, i) => ({ x: i, y: x.deliver.activeSincePrevTick }))
|
||||||
|
}, {
|
||||||
|
data: stats.map((x, i) => ({ x: i, y: x.deliver.active }))
|
||||||
|
}, {
|
||||||
|
data: stats.map((x, i) => ({ x: i, y: x.deliver.waiting }))
|
||||||
|
}, {
|
||||||
|
data: stats.map((x, i) => ({ x: i, y: x.deliver.delayed }))
|
||||||
|
}]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
const chartOpts = {
|
||||||
|
chart: {
|
||||||
|
type: 'area',
|
||||||
|
height: 200,
|
||||||
|
animations: {
|
||||||
|
dynamicAnimation: {
|
||||||
|
enabled: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
toolbar: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
zoom: {
|
||||||
|
enabled: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dataLabels: {
|
||||||
|
enabled: false
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
clipMarkers: false,
|
||||||
|
borderColor: 'rgba(0, 0, 0, 0.1)'
|
||||||
|
},
|
||||||
|
stroke: {
|
||||||
|
curve: 'straight',
|
||||||
|
width: 2
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
enabled: false
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
colors: ['#00E396', '#00BCD4', '#FFB300', '#e53935'],
|
||||||
|
series: [{ data: [] }, { data: [] }, { data: [] }, { data: [] }] as any,
|
||||||
|
xaxis: {
|
||||||
|
type: 'numeric',
|
||||||
|
labels: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
enabled: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
yaxis: {
|
||||||
|
show: false,
|
||||||
|
min: 0,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.inChart = new ApexCharts(this.$refs.in, chartOpts);
|
||||||
|
this.outChart = new ApexCharts(this.$refs.out, chartOpts);
|
||||||
|
|
||||||
|
this.inChart.render();
|
||||||
|
this.outChart.render();
|
||||||
|
|
||||||
|
const connection = this.$root.stream.useSharedConnection('queueStats');
|
||||||
|
connection.on('stats', this.onStats);
|
||||||
|
connection.on('statsLog', this.onStatsLog);
|
||||||
|
connection.send('requestLog', {
|
||||||
|
id: Math.random().toString().substr(2, 8),
|
||||||
|
length: limit
|
||||||
|
});
|
||||||
|
|
||||||
|
this.$once('hook:beforeDestroy', () => {
|
||||||
|
connection.dispose();
|
||||||
|
this.inChart.destroy();
|
||||||
|
this.outChart.destroy();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
onStats(stats) {
|
||||||
|
this.stats.push(stats);
|
||||||
|
if (this.stats.length > limit) this.stats.shift();
|
||||||
|
},
|
||||||
|
|
||||||
|
onStatsLog(statsLog) {
|
||||||
|
for (const stats of statsLog.reverse()) {
|
||||||
|
this.onStats(stats);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="stylus" scoped>
|
||||||
|
.mzxlfysy
|
||||||
|
display flex
|
||||||
|
|
||||||
|
> div
|
||||||
|
display block
|
||||||
|
flex 1
|
||||||
|
padding 20px 12px 0 12px
|
||||||
|
box-shadow 0 2px 4px rgba(0, 0, 0, 0.1)
|
||||||
|
background var(--face)
|
||||||
|
border-radius 8px
|
||||||
|
|
||||||
|
&:first-child
|
||||||
|
margin-right 16px
|
||||||
|
|
||||||
|
> header
|
||||||
|
display flex
|
||||||
|
padding 0 8px
|
||||||
|
margin-bottom -16px
|
||||||
|
color var(--adminDashboardCardFg)
|
||||||
|
font-size 14px
|
||||||
|
|
||||||
|
> span
|
||||||
|
&:last-child
|
||||||
|
margin-left auto
|
||||||
|
opacity 0.7
|
||||||
|
|
||||||
|
> span
|
||||||
|
opacity 0.7
|
||||||
|
|
||||||
|
> div
|
||||||
|
margin-bottom -10px
|
||||||
|
|
||||||
|
@media (max-width 1000px)
|
||||||
|
display block
|
||||||
|
margin-bottom 26px
|
||||||
|
|
||||||
|
> div
|
||||||
|
&:first-child
|
||||||
|
margin-right 0
|
||||||
|
margin-bottom 26px
|
||||||
|
|
||||||
|
</style>
|
@@ -73,6 +73,10 @@
|
|||||||
<x-charts ref="charts"/>
|
<x-charts ref="charts"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="queue">
|
||||||
|
<x-queue/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="cpu-memory">
|
<div class="cpu-memory">
|
||||||
<x-cpu-memory :connection="connection"/>
|
<x-cpu-memory :connection="connection"/>
|
||||||
</div>
|
</div>
|
||||||
@@ -86,9 +90,10 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import i18n from '../../i18n';
|
import i18n from '../../i18n';
|
||||||
import XCpuMemory from "./cpu-memory.vue";
|
import XCpuMemory from "./dashboard.cpu-memory.vue";
|
||||||
import XCharts from "./charts.vue";
|
import XQueue from "./dashboard.queue-charts.vue";
|
||||||
import XApLog from "./ap-log.vue";
|
import XCharts from "./dashboard.charts.vue";
|
||||||
|
import XApLog from "./dashboard.ap-log.vue";
|
||||||
import { faDatabase } from '@fortawesome/free-solid-svg-icons';
|
import { faDatabase } from '@fortawesome/free-solid-svg-icons';
|
||||||
import MarqueeText from 'vue-marquee-text-component';
|
import MarqueeText from 'vue-marquee-text-component';
|
||||||
import randomColor from 'randomcolor';
|
import randomColor from 'randomcolor';
|
||||||
@@ -98,6 +103,7 @@ export default Vue.extend({
|
|||||||
|
|
||||||
components: {
|
components: {
|
||||||
XCpuMemory,
|
XCpuMemory,
|
||||||
|
XQueue,
|
||||||
XCharts,
|
XCharts,
|
||||||
XApLog,
|
XApLog,
|
||||||
MarqueeText
|
MarqueeText
|
||||||
@@ -274,6 +280,9 @@ export default Vue.extend({
|
|||||||
> .charts
|
> .charts
|
||||||
margin-bottom 16px
|
margin-bottom 16px
|
||||||
|
|
||||||
|
> .queue
|
||||||
|
margin-bottom 16px
|
||||||
|
|
||||||
> .cpu-memory
|
> .cpu-memory
|
||||||
margin-bottom 16px
|
margin-bottom 16px
|
||||||
|
|
||||||
|
@@ -1,43 +1,58 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<ui-card>
|
<ui-card>
|
||||||
<template #title><fa :icon="faTerminal"/> {{ $t('federation') }}</template>
|
<template #title><fa :icon="faTerminal"/> {{ $t('instance') }}</template>
|
||||||
<section class="fit-top">
|
<section class="fit-top">
|
||||||
<ui-input class="target" v-model="target" type="text" @enter="showInstance()">
|
<ui-input class="target" v-model="target" type="text" @enter="showInstance()">
|
||||||
<span>{{ $t('host') }}</span>
|
<span>{{ $t('host') }}</span>
|
||||||
|
<template #prefix><fa :icon="faServer"/></template>
|
||||||
</ui-input>
|
</ui-input>
|
||||||
<ui-button @click="showInstance()"><fa :icon="faSearch"/> {{ $t('lookup') }}</ui-button>
|
<ui-button @click="showInstance()"><fa :icon="faSearch"/> {{ $t('lookup') }}</ui-button>
|
||||||
|
|
||||||
<div class="instance" v-if="instance">
|
<div class="instance" v-if="instance">
|
||||||
<ui-input :value="instance.host" type="text" readonly>
|
<ui-horizon-group inputs>
|
||||||
<span>{{ $t('host') }}</span>
|
<ui-input :value="instance.host" type="text" readonly>
|
||||||
</ui-input>
|
<span>{{ $t('host') }}</span>
|
||||||
|
<template #prefix><fa :icon="faServer"/></template>
|
||||||
|
</ui-input>
|
||||||
|
<ui-input :value="instance.caughtAt | date" type="text" readonly>
|
||||||
|
<span>{{ $t('caught-at') }}</span>
|
||||||
|
<template #prefix><fa :icon="faCrosshairs"/></template>
|
||||||
|
</ui-input>
|
||||||
|
</ui-horizon-group>
|
||||||
<ui-horizon-group inputs>
|
<ui-horizon-group inputs>
|
||||||
<ui-input :value="instance.notesCount | number" type="text" readonly>
|
<ui-input :value="instance.notesCount | number" type="text" readonly>
|
||||||
<span>{{ $t('notes') }}</span>
|
<span>{{ $t('notes') }}</span>
|
||||||
|
<template #prefix><fa :icon="faEnvelopeOpenText"/></template>
|
||||||
</ui-input>
|
</ui-input>
|
||||||
<ui-input :value="instance.usersCount | number" type="text" readonly>
|
<ui-input :value="instance.usersCount | number" type="text" readonly>
|
||||||
<span>{{ $t('users') }}</span>
|
<span>{{ $t('users') }}</span>
|
||||||
|
<template #prefix><fa :icon="faUsers"/></template>
|
||||||
</ui-input>
|
</ui-input>
|
||||||
</ui-horizon-group>
|
</ui-horizon-group>
|
||||||
<ui-horizon-group inputs>
|
<ui-horizon-group inputs>
|
||||||
<ui-input :value="instance.followingCount | number" type="text" readonly>
|
<ui-input :value="instance.followingCount | number" type="text" readonly>
|
||||||
<span>{{ $t('following') }}</span>
|
<span>{{ $t('following') }}</span>
|
||||||
|
<template #prefix><fa :icon="faCaretDown"/></template>
|
||||||
</ui-input>
|
</ui-input>
|
||||||
<ui-input :value="instance.followersCount | number" type="text" readonly>
|
<ui-input :value="instance.followersCount | number" type="text" readonly>
|
||||||
<span>{{ $t('followers') }}</span>
|
<span>{{ $t('followers') }}</span>
|
||||||
|
<template #prefix><fa :icon="faCaretUp"/></template>
|
||||||
</ui-input>
|
</ui-input>
|
||||||
</ui-horizon-group>
|
</ui-horizon-group>
|
||||||
<ui-horizon-group inputs>
|
<ui-horizon-group inputs>
|
||||||
<ui-input :value="instance.latestRequestSentAt" type="text" readonly>
|
<ui-input :value="instance.latestRequestSentAt | date" type="text" readonly>
|
||||||
<span>{{ $t('latest-request-sent-at') }}</span>
|
<span>{{ $t('latest-request-sent-at') }}</span>
|
||||||
|
<template #prefix><fa :icon="faPaperPlane"/></template>
|
||||||
</ui-input>
|
</ui-input>
|
||||||
<ui-input :value="instance.latestStatus" type="text" readonly>
|
<ui-input :value="instance.latestStatus" type="text" readonly>
|
||||||
<span>{{ $t('status') }}</span>
|
<span>{{ $t('status') }}</span>
|
||||||
|
<template #prefix><fa :icon="faTrafficLight"/></template>
|
||||||
</ui-input>
|
</ui-input>
|
||||||
</ui-horizon-group>
|
</ui-horizon-group>
|
||||||
<ui-input :value="instance.latestRequestReceivedAt" type="text" readonly>
|
<ui-input :value="instance.latestRequestReceivedAt | date" type="text" readonly>
|
||||||
<span>{{ $t('latest-request-received-at') }}</span>
|
<span>{{ $t('latest-request-received-at') }}</span>
|
||||||
|
<template #prefix><fa :icon="faInbox"/></template>
|
||||||
</ui-input>
|
</ui-input>
|
||||||
<ui-switch v-model="instance.isBlocked" @change="updateInstance()">{{ $t('block') }}</ui-switch>
|
<ui-switch v-model="instance.isBlocked" @change="updateInstance()">{{ $t('block') }}</ui-switch>
|
||||||
<ui-switch v-model="instance.isMarkedAsClosed" @change="updateInstance()">{{ $t('marked-as-closed') }}</ui-switch>
|
<ui-switch v-model="instance.isMarkedAsClosed" @change="updateInstance()">{{ $t('marked-as-closed') }}</ui-switch>
|
||||||
@@ -133,7 +148,8 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import i18n from '../../i18n';
|
import i18n from '../../i18n';
|
||||||
import { faGlobe, faTerminal, faSearch, faMinusCircle, faServer } from '@fortawesome/free-solid-svg-icons';
|
import { faPaperPlane } from '@fortawesome/free-regular-svg-icons';
|
||||||
|
import { faGlobe, faTerminal, faSearch, faMinusCircle, faServer, faCrosshairs, faEnvelopeOpenText, faUsers, faCaretDown, faCaretUp, faTrafficLight, faInbox } from '@fortawesome/free-solid-svg-icons';
|
||||||
import ApexCharts from 'apexcharts';
|
import ApexCharts from 'apexcharts';
|
||||||
import * as tinycolor from 'tinycolor2';
|
import * as tinycolor from 'tinycolor2';
|
||||||
|
|
||||||
@@ -144,19 +160,23 @@ const negate = arr => arr.map(x => -x);
|
|||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
i18n: i18n('admin/views/federation.vue'),
|
i18n: i18n('admin/views/federation.vue'),
|
||||||
|
|
||||||
|
filters: {
|
||||||
|
date: v => v ? new Date(v).toLocaleString() : 'N/A'
|
||||||
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
instance: null,
|
instance: null,
|
||||||
target: null,
|
target: null,
|
||||||
sort: '+lastCommunicatedAt',
|
sort: '+lastCommunicatedAt',
|
||||||
state: 'all',
|
state: 'all',
|
||||||
limit: 50,
|
limit: 100,
|
||||||
instances: [],
|
instances: [],
|
||||||
chart: null,
|
chart: null,
|
||||||
chartSrc: 'requests',
|
chartSrc: 'requests',
|
||||||
chartSpan: 'hour',
|
chartSpan: 'hour',
|
||||||
chartInstance: null,
|
chartInstance: null,
|
||||||
faGlobe, faTerminal, faSearch, faMinusCircle, faServer
|
faGlobe, faTerminal, faSearch, faMinusCircle, faServer, faCrosshairs, faEnvelopeOpenText, faUsers, faCaretDown, faCaretUp, faPaperPlane, faTrafficLight, faInbox
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@@ -6,6 +6,7 @@
|
|||||||
<ui-input :value="host" readonly>{{ $t('host') }}</ui-input>
|
<ui-input :value="host" readonly>{{ $t('host') }}</ui-input>
|
||||||
<ui-input v-model="name">{{ $t('instance-name') }}</ui-input>
|
<ui-input v-model="name">{{ $t('instance-name') }}</ui-input>
|
||||||
<ui-textarea v-model="description">{{ $t('instance-description') }}</ui-textarea>
|
<ui-textarea v-model="description">{{ $t('instance-description') }}</ui-textarea>
|
||||||
|
<ui-input v-model="iconUrl"><template #icon><fa icon="link"/></template>{{ $t('icon-url') }}</ui-input>
|
||||||
<ui-input v-model="mascotImageUrl"><template #icon><fa icon="link"/></template>{{ $t('logo-url') }}</ui-input>
|
<ui-input v-model="mascotImageUrl"><template #icon><fa icon="link"/></template>{{ $t('logo-url') }}</ui-input>
|
||||||
<ui-input v-model="bannerUrl"><template #icon><fa icon="link"/></template>{{ $t('banner-url') }}</ui-input>
|
<ui-input v-model="bannerUrl"><template #icon><fa icon="link"/></template>{{ $t('banner-url') }}</ui-input>
|
||||||
<ui-input v-model="errorImageUrl"><template #icon><fa icon="link"/></template>{{ $t('error-image-url') }}</ui-input>
|
<ui-input v-model="errorImageUrl"><template #icon><fa icon="link"/></template>{{ $t('error-image-url') }}</ui-input>
|
||||||
@@ -24,6 +25,8 @@
|
|||||||
<ui-switch v-model="disableLocalTimeline">{{ $t('disable-local-timeline') }}</ui-switch>
|
<ui-switch v-model="disableLocalTimeline">{{ $t('disable-local-timeline') }}</ui-switch>
|
||||||
<ui-switch v-model="disableGlobalTimeline">{{ $t('disable-global-timeline') }}</ui-switch>
|
<ui-switch v-model="disableGlobalTimeline">{{ $t('disable-global-timeline') }}</ui-switch>
|
||||||
<ui-info>{{ $t('disabling-timelines-info') }}</ui-info>
|
<ui-info>{{ $t('disabling-timelines-info') }}</ui-info>
|
||||||
|
<ui-switch v-model="enableEmojiReaction">{{ $t('enable-emoji-reaction') }}</ui-switch>
|
||||||
|
<ui-switch v-model="useStarForReactionFallback">{{ $t('use-star-for-reaction-fallback') }}</ui-switch>
|
||||||
</section>
|
</section>
|
||||||
<section class="fit-bottom">
|
<section class="fit-bottom">
|
||||||
<header><fa icon="cloud"/> {{ $t('drive-config') }}</header>
|
<header><fa icon="cloud"/> {{ $t('drive-config') }}</header>
|
||||||
@@ -154,9 +157,12 @@ export default Vue.extend({
|
|||||||
disableRegistration: false,
|
disableRegistration: false,
|
||||||
disableLocalTimeline: false,
|
disableLocalTimeline: false,
|
||||||
disableGlobalTimeline: false,
|
disableGlobalTimeline: false,
|
||||||
|
enableEmojiReaction: true,
|
||||||
|
useStarForReactionFallback: false,
|
||||||
mascotImageUrl: null,
|
mascotImageUrl: null,
|
||||||
bannerUrl: null,
|
bannerUrl: null,
|
||||||
errorImageUrl: null,
|
errorImageUrl: null,
|
||||||
|
iconUrl: null,
|
||||||
name: null,
|
name: null,
|
||||||
description: null,
|
description: null,
|
||||||
languages: null,
|
languages: null,
|
||||||
@@ -204,9 +210,12 @@ export default Vue.extend({
|
|||||||
this.disableRegistration = meta.disableRegistration;
|
this.disableRegistration = meta.disableRegistration;
|
||||||
this.disableLocalTimeline = meta.disableLocalTimeline;
|
this.disableLocalTimeline = meta.disableLocalTimeline;
|
||||||
this.disableGlobalTimeline = meta.disableGlobalTimeline;
|
this.disableGlobalTimeline = meta.disableGlobalTimeline;
|
||||||
|
this.enableEmojiReaction = meta.enableEmojiReaction;
|
||||||
|
this.useStarForReactionFallback = meta.useStarForReactionFallback;
|
||||||
this.mascotImageUrl = meta.mascotImageUrl;
|
this.mascotImageUrl = meta.mascotImageUrl;
|
||||||
this.bannerUrl = meta.bannerUrl;
|
this.bannerUrl = meta.bannerUrl;
|
||||||
this.errorImageUrl = meta.errorImageUrl;
|
this.errorImageUrl = meta.errorImageUrl;
|
||||||
|
this.iconUrl = meta.iconUrl;
|
||||||
this.name = meta.name;
|
this.name = meta.name;
|
||||||
this.description = meta.description;
|
this.description = meta.description;
|
||||||
this.languages = meta.langs.join(' ');
|
this.languages = meta.langs.join(' ');
|
||||||
@@ -264,9 +273,12 @@ export default Vue.extend({
|
|||||||
disableRegistration: this.disableRegistration,
|
disableRegistration: this.disableRegistration,
|
||||||
disableLocalTimeline: this.disableLocalTimeline,
|
disableLocalTimeline: this.disableLocalTimeline,
|
||||||
disableGlobalTimeline: this.disableGlobalTimeline,
|
disableGlobalTimeline: this.disableGlobalTimeline,
|
||||||
|
enableEmojiReaction: this.enableEmojiReaction,
|
||||||
|
useStarForReactionFallback: this.useStarForReactionFallback,
|
||||||
mascotImageUrl: this.mascotImageUrl,
|
mascotImageUrl: this.mascotImageUrl,
|
||||||
bannerUrl: this.bannerUrl,
|
bannerUrl: this.bannerUrl,
|
||||||
errorImageUrl: this.errorImageUrl,
|
errorImageUrl: this.errorImageUrl,
|
||||||
|
iconUrl: this.iconUrl,
|
||||||
name: this.name,
|
name: this.name,
|
||||||
description: this.description,
|
description: this.description,
|
||||||
langs: this.languages.split(' '),
|
langs: this.languages.split(' '),
|
||||||
|
@@ -4,7 +4,7 @@
|
|||||||
<template #title><fa :icon="faStream"/> {{ $t('logs') }}</template>
|
<template #title><fa :icon="faStream"/> {{ $t('logs') }}</template>
|
||||||
<section class="fit-top">
|
<section class="fit-top">
|
||||||
<ui-horizon-group inputs>
|
<ui-horizon-group inputs>
|
||||||
<ui-input v-model="domain" debounce>
|
<ui-input v-model="domain" :debounce="true">
|
||||||
<span>{{ $t('domain') }}</span>
|
<span>{{ $t('domain') }}</span>
|
||||||
</ui-input>
|
</ui-input>
|
||||||
<ui-select v-model="level">
|
<ui-select v-model="level">
|
||||||
@@ -85,11 +85,10 @@ export default Vue.extend({
|
|||||||
|
|
||||||
<style lang="stylus" scoped>
|
<style lang="stylus" scoped>
|
||||||
.nqjzuvev
|
.nqjzuvev
|
||||||
white-space nowrap
|
|
||||||
overflow auto
|
|
||||||
padding 8px
|
padding 8px
|
||||||
background #000
|
background #000
|
||||||
color #fff
|
color #fff
|
||||||
|
font-size 14px
|
||||||
|
|
||||||
> code
|
> code
|
||||||
display block
|
display block
|
||||||
|
@@ -1,26 +1,261 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<ui-card>
|
<ui-card>
|
||||||
<template #title>{{ $t('operation') }}</template>
|
<template #title><fa :icon="faChartBar"/> {{ $t('title') }}</template>
|
||||||
|
<section class="wptihjuy">
|
||||||
|
<header><fa :icon="faPaperPlane"/> Deliver</header>
|
||||||
|
<ui-info warn v-if="latestStats && latestStats.deliver.waiting > 0">The queue is jammed.</ui-info>
|
||||||
|
<ui-horizon-group inputs v-if="latestStats" class="fit-bottom">
|
||||||
|
<ui-input :value="latestStats.deliver.activeSincePrevTick | number" type="text" readonly>
|
||||||
|
<span>Process</span>
|
||||||
|
<template #prefix><fa :icon="fasPlayCircle"/></template>
|
||||||
|
<template #suffix>jobs/tick</template>
|
||||||
|
</ui-input>
|
||||||
|
<ui-input :value="latestStats.deliver.active | number" type="text" readonly>
|
||||||
|
<span>Active</span>
|
||||||
|
<template #prefix><fa :icon="farPlayCircle"/></template>
|
||||||
|
<template #suffix>jobs</template>
|
||||||
|
</ui-input>
|
||||||
|
<ui-input :value="latestStats.deliver.waiting | number" type="text" readonly>
|
||||||
|
<span>Waiting</span>
|
||||||
|
<template #prefix><fa :icon="faStopCircle"/></template>
|
||||||
|
<template #suffix>jobs</template>
|
||||||
|
</ui-input>
|
||||||
|
<ui-input :value="latestStats.deliver.delayed | number" type="text" readonly>
|
||||||
|
<span>Delayed</span>
|
||||||
|
<template #prefix><fa :icon="faStopwatch"/></template>
|
||||||
|
<template #suffix>jobs</template>
|
||||||
|
</ui-input>
|
||||||
|
</ui-horizon-group>
|
||||||
|
<div ref="deliverChart" class="chart"></div>
|
||||||
|
</section>
|
||||||
|
<section class="wptihjuy">
|
||||||
|
<header><fa :icon="faInbox"/> Inbox</header>
|
||||||
|
<ui-info warn v-if="latestStats && latestStats.inbox.waiting > 0">The queue is jammed.</ui-info>
|
||||||
|
<ui-horizon-group inputs v-if="latestStats" class="fit-bottom">
|
||||||
|
<ui-input :value="latestStats.inbox.activeSincePrevTick | number" type="text" readonly>
|
||||||
|
<span>Process</span>
|
||||||
|
<template #prefix><fa :icon="fasPlayCircle"/></template>
|
||||||
|
<template #suffix>jobs/tick</template>
|
||||||
|
</ui-input>
|
||||||
|
<ui-input :value="latestStats.inbox.active | number" type="text" readonly>
|
||||||
|
<span>Active</span>
|
||||||
|
<template #prefix><fa :icon="farPlayCircle"/></template>
|
||||||
|
<template #suffix>jobs</template>
|
||||||
|
</ui-input>
|
||||||
|
<ui-input :value="latestStats.inbox.waiting | number" type="text" readonly>
|
||||||
|
<span>Waiting</span>
|
||||||
|
<template #prefix><fa :icon="faStopCircle"/></template>
|
||||||
|
<template #suffix>jobs</template>
|
||||||
|
</ui-input>
|
||||||
|
<ui-input :value="latestStats.inbox.delayed | number" type="text" readonly>
|
||||||
|
<span>Delayed</span>
|
||||||
|
<template #prefix><fa :icon="faStopwatch"/></template>
|
||||||
|
<template #suffix>jobs</template>
|
||||||
|
</ui-input>
|
||||||
|
</ui-horizon-group>
|
||||||
|
<div ref="inboxChart" class="chart"></div>
|
||||||
|
</section>
|
||||||
<section>
|
<section>
|
||||||
<ui-button @click="removeAllJobs">{{ $t('remove-all-jobs') }}</ui-button>
|
<ui-button @click="removeAllJobs">{{ $t('remove-all-jobs') }}</ui-button>
|
||||||
</section>
|
</section>
|
||||||
</ui-card>
|
</ui-card>
|
||||||
|
|
||||||
|
<ui-card>
|
||||||
|
<template #title><fa :icon="faTasks"/> {{ $t('jobs') }}</template>
|
||||||
|
<section class="fit-top">
|
||||||
|
<ui-horizon-group inputs>
|
||||||
|
<ui-select v-model="domain">
|
||||||
|
<template #label>{{ $t('queue') }}</template>
|
||||||
|
<option value="deliver">{{ $t('domains.deliver') }}</option>
|
||||||
|
<option value="inbox">{{ $t('domains.inbox') }}</option>
|
||||||
|
</ui-select>
|
||||||
|
<ui-select v-model="state">
|
||||||
|
<template #label>{{ $t('state') }}</template>
|
||||||
|
<option value="delayed">{{ $t('states.delayed') }}</option>
|
||||||
|
</ui-select>
|
||||||
|
</ui-horizon-group>
|
||||||
|
<sequential-entrance animation="entranceFromTop" delay="25">
|
||||||
|
<div class="xvvuvgsv" v-for="job in jobs">
|
||||||
|
<b>{{ job.id }}</b>
|
||||||
|
<template v-if="domain === 'deliver'">
|
||||||
|
<span>{{ job.data.to }}</span>
|
||||||
|
</template>
|
||||||
|
<template v-if="domain === 'inbox'">
|
||||||
|
<span>{{ job.activity.id }}</span>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</sequential-entrance>
|
||||||
|
<ui-info v-if="jobs.length == jobsLimit">{{ $t('result-is-truncated', { n: jobsLimit }) }}</ui-info>
|
||||||
|
</section>
|
||||||
|
</ui-card>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import i18n from '../../i18n';
|
import i18n from '../../i18n';
|
||||||
|
import ApexCharts from 'apexcharts';
|
||||||
|
import * as tinycolor from 'tinycolor2';
|
||||||
|
import { faTasks, faInbox, faStopwatch, faPlayCircle as fasPlayCircle } from '@fortawesome/free-solid-svg-icons';
|
||||||
|
import { faPaperPlane, faStopCircle, faPlayCircle as farPlayCircle, faChartBar } from '@fortawesome/free-regular-svg-icons';
|
||||||
|
|
||||||
|
const limit = 200;
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
i18n: i18n('admin/views/queue.vue'),
|
i18n: i18n('admin/views/queue.vue'),
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
stats: [],
|
||||||
|
deliverChart: null,
|
||||||
|
inboxChart: null,
|
||||||
|
jobs: [],
|
||||||
|
jobsLimit: 50,
|
||||||
|
domain: 'deliver',
|
||||||
|
state: 'delayed',
|
||||||
|
faTasks, faPaperPlane, faInbox, faStopwatch, faStopCircle, farPlayCircle, fasPlayCircle, faChartBar
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
latestStats(): any {
|
||||||
|
return this.stats[this.stats.length - 1];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
stats(stats) {
|
||||||
|
this.inboxChart.updateSeries([{
|
||||||
|
name: 'Process',
|
||||||
|
type: 'area',
|
||||||
|
data: stats.map((x, i) => ({ x: i, y: x.inbox.activeSincePrevTick }))
|
||||||
|
}, {
|
||||||
|
name: 'Active',
|
||||||
|
type: 'area',
|
||||||
|
data: stats.map((x, i) => ({ x: i, y: x.inbox.active }))
|
||||||
|
}, {
|
||||||
|
name: 'Waiting',
|
||||||
|
type: 'line',
|
||||||
|
data: stats.map((x, i) => ({ x: i, y: x.inbox.waiting }))
|
||||||
|
}, {
|
||||||
|
name: 'Delayed',
|
||||||
|
type: 'line',
|
||||||
|
data: stats.map((x, i) => ({ x: i, y: x.inbox.delayed }))
|
||||||
|
}]);
|
||||||
|
this.deliverChart.updateSeries([{
|
||||||
|
name: 'Process',
|
||||||
|
type: 'area',
|
||||||
|
data: stats.map((x, i) => ({ x: i, y: x.deliver.activeSincePrevTick }))
|
||||||
|
}, {
|
||||||
|
name: 'Active',
|
||||||
|
type: 'area',
|
||||||
|
data: stats.map((x, i) => ({ x: i, y: x.deliver.active }))
|
||||||
|
}, {
|
||||||
|
name: 'Waiting',
|
||||||
|
type: 'line',
|
||||||
|
data: stats.map((x, i) => ({ x: i, y: x.deliver.waiting }))
|
||||||
|
}, {
|
||||||
|
name: 'Delayed',
|
||||||
|
type: 'line',
|
||||||
|
data: stats.map((x, i) => ({ x: i, y: x.deliver.delayed }))
|
||||||
|
}]);
|
||||||
|
},
|
||||||
|
|
||||||
|
domain() {
|
||||||
|
this.jobs = [];
|
||||||
|
this.fetchJobs();
|
||||||
|
},
|
||||||
|
|
||||||
|
state() {
|
||||||
|
this.jobs = [];
|
||||||
|
this.fetchJobs();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
this.fetchJobs();
|
||||||
|
|
||||||
|
const chartOpts = id => ({
|
||||||
|
chart: {
|
||||||
|
id,
|
||||||
|
group: 'queue',
|
||||||
|
type: 'area',
|
||||||
|
height: 200,
|
||||||
|
animations: {
|
||||||
|
dynamicAnimation: {
|
||||||
|
enabled: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
toolbar: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
zoom: {
|
||||||
|
enabled: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dataLabels: {
|
||||||
|
enabled: false
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
clipMarkers: false,
|
||||||
|
borderColor: 'rgba(0, 0, 0, 0.1)',
|
||||||
|
xaxis: {
|
||||||
|
lines: {
|
||||||
|
show: true,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
stroke: {
|
||||||
|
curve: 'straight',
|
||||||
|
width: 2
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
enabled: false
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
labels: {
|
||||||
|
colors: tinycolor(getComputedStyle(document.documentElement).getPropertyValue('--text')).toRgbString()
|
||||||
|
},
|
||||||
|
},
|
||||||
|
series: [] as any,
|
||||||
|
colors: ['#00E396', '#00BCD4', '#FFB300', '#e53935'],
|
||||||
|
xaxis: {
|
||||||
|
type: 'numeric',
|
||||||
|
labels: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
enabled: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
yaxis: {
|
||||||
|
show: false,
|
||||||
|
min: 0,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.inboxChart = new ApexCharts(this.$refs.inboxChart, chartOpts('a'));
|
||||||
|
this.deliverChart = new ApexCharts(this.$refs.deliverChart, chartOpts('b'));
|
||||||
|
|
||||||
|
this.inboxChart.render();
|
||||||
|
this.deliverChart.render();
|
||||||
|
|
||||||
|
const connection = this.$root.stream.useSharedConnection('queueStats');
|
||||||
|
connection.on('stats', this.onStats);
|
||||||
|
connection.on('statsLog', this.onStatsLog);
|
||||||
|
connection.send('requestLog', {
|
||||||
|
id: Math.random().toString().substr(2, 8),
|
||||||
|
length: limit
|
||||||
|
});
|
||||||
|
|
||||||
|
this.$once('hook:beforeDestroy', () => {
|
||||||
|
connection.dispose();
|
||||||
|
this.inboxChart.destroy();
|
||||||
|
this.deliverChart.destroy();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
async removeAllJobs() {
|
async removeAllJobs() {
|
||||||
const process = async () => {
|
const process = async () => {
|
||||||
@@ -38,6 +273,39 @@ export default Vue.extend({
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
onStats(stats) {
|
||||||
|
this.stats.push(stats);
|
||||||
|
if (this.stats.length > limit) this.stats.shift();
|
||||||
|
},
|
||||||
|
|
||||||
|
onStatsLog(statsLog) {
|
||||||
|
for (const stats of statsLog.reverse()) {
|
||||||
|
this.onStats(stats);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
fetchJobs() {
|
||||||
|
this.$root.api('admin/queue/jobs', {
|
||||||
|
domain: this.domain,
|
||||||
|
state: this.state,
|
||||||
|
limit: this.jobsLimit
|
||||||
|
}).then(jobs => {
|
||||||
|
this.jobs = jobs;
|
||||||
|
});
|
||||||
|
},
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style lang="stylus" scoped>
|
||||||
|
.wptihjuy
|
||||||
|
> .chart
|
||||||
|
min-height 200px !important
|
||||||
|
margin 0 -8px
|
||||||
|
|
||||||
|
.xvvuvgsv
|
||||||
|
> b
|
||||||
|
margin-right 16px
|
||||||
|
|
||||||
|
</style>
|
||||||
|
@@ -69,7 +69,7 @@ export default Vue.extend({
|
|||||||
},
|
},
|
||||||
plotOptions: {
|
plotOptions: {
|
||||||
bar: {
|
bar: {
|
||||||
columnWidth: '90%'
|
columnWidth: '80%'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
grid: {
|
grid: {
|
||||||
|
@@ -4,7 +4,7 @@
|
|||||||
<li v-for="user in users" @click="complete(type, user)" @keydown="onKeydown" tabindex="-1">
|
<li v-for="user in users" @click="complete(type, user)" @keydown="onKeydown" tabindex="-1">
|
||||||
<img class="avatar" :src="user.avatarUrl" alt=""/>
|
<img class="avatar" :src="user.avatarUrl" alt=""/>
|
||||||
<span class="name">
|
<span class="name">
|
||||||
<mk-user-name :user="user"/>
|
<mk-user-name :user="user" :key="user.id"/>
|
||||||
</span>
|
</span>
|
||||||
<span class="username">@{{ user | acct }}</span>
|
<span class="username">@{{ user | acct }}</span>
|
||||||
</li>
|
</li>
|
||||||
|
@@ -3,32 +3,31 @@
|
|||||||
<header>
|
<header>
|
||||||
<button v-for="category in categories"
|
<button v-for="category in categories"
|
||||||
:title="category.text"
|
:title="category.text"
|
||||||
@click="go(category.ref)"
|
@click="go(category)"
|
||||||
:class="{ active: category.isActive }"
|
:class="{ active: category.isActive }"
|
||||||
>
|
>
|
||||||
<fa :icon="category.icon" fixed-width/>
|
<fa :icon="category.icon" fixed-width/>
|
||||||
</button>
|
</button>
|
||||||
</header>
|
</header>
|
||||||
<div class="emojis" ref="emojis" @scroll.passive="onScroll">
|
<div class="emojis">
|
||||||
<section v-for="category in categories" :ref="category.ref">
|
<header><fa :icon="categories.find(x => x.isActive).icon" fixed-width/> {{ categories.find(x => x.isActive).text }}</header>
|
||||||
<header><fa :icon="category.icon" fixed-width/> {{ category.text }}</header>
|
<div v-if="categories.find(x => x.isActive).name">
|
||||||
<div v-if="category.name">
|
<button v-for="emoji in Object.entries(lib).filter(([k, v]) => v.category === categories.find(x => x.isActive).name)"
|
||||||
<button v-for="emoji in Object.entries(lib).filter(([k, v]) => v.category === category.name)"
|
:title="emoji[0]"
|
||||||
:title="emoji[0]"
|
@click="chosen(emoji[1].char)"
|
||||||
@click="chosen(emoji[1].char)"
|
:key="emoji[0]"
|
||||||
>
|
>
|
||||||
<mk-emoji :emoji="emoji[1].char"/>
|
<mk-emoji :emoji="emoji[1].char"/>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<button v-for="emoji in customEmojis"
|
<button v-for="emoji in customEmojis"
|
||||||
:title="emoji.name"
|
:title="emoji.name"
|
||||||
@click="chosen(`:${emoji.name}:`)"
|
@click="chosen(`:${emoji.name}:`)"
|
||||||
>
|
>
|
||||||
<img :src="emoji.url" :alt="emoji.name"/>
|
<img :src="emoji.url" :alt="emoji.name"/>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -48,55 +47,46 @@ export default Vue.extend({
|
|||||||
lib,
|
lib,
|
||||||
customEmojis: [],
|
customEmojis: [],
|
||||||
categories: [{
|
categories: [{
|
||||||
ref: 'customEmojiSection',
|
|
||||||
text: this.$t('custom-emoji'),
|
text: this.$t('custom-emoji'),
|
||||||
icon: faAsterisk,
|
icon: faAsterisk,
|
||||||
isActive: true
|
isActive: true
|
||||||
}, {
|
}, {
|
||||||
name: 'people',
|
name: 'people',
|
||||||
ref: 'peopleSection',
|
|
||||||
text: this.$t('people'),
|
text: this.$t('people'),
|
||||||
icon: ['far', 'laugh'],
|
icon: ['far', 'laugh'],
|
||||||
isActive: false
|
isActive: false
|
||||||
}, {
|
}, {
|
||||||
name: 'animals_and_nature',
|
name: 'animals_and_nature',
|
||||||
ref: 'animalsAndNatureSection',
|
|
||||||
text: this.$t('animals-and-nature'),
|
text: this.$t('animals-and-nature'),
|
||||||
icon: faLeaf,
|
icon: faLeaf,
|
||||||
isActive: false
|
isActive: false
|
||||||
}, {
|
}, {
|
||||||
name: 'food_and_drink',
|
name: 'food_and_drink',
|
||||||
ref: 'foodAndDrinkSection',
|
|
||||||
text: this.$t('food-and-drink'),
|
text: this.$t('food-and-drink'),
|
||||||
icon: faUtensils,
|
icon: faUtensils,
|
||||||
isActive: false
|
isActive: false
|
||||||
}, {
|
}, {
|
||||||
name: 'activity',
|
name: 'activity',
|
||||||
ref: 'activitySection',
|
|
||||||
text: this.$t('activity'),
|
text: this.$t('activity'),
|
||||||
icon: faFutbol,
|
icon: faFutbol,
|
||||||
isActive: false
|
isActive: false
|
||||||
}, {
|
}, {
|
||||||
name: 'travel_and_places',
|
name: 'travel_and_places',
|
||||||
ref: 'travelAndPlacesSection',
|
|
||||||
text: this.$t('travel-and-places'),
|
text: this.$t('travel-and-places'),
|
||||||
icon: faCity,
|
icon: faCity,
|
||||||
isActive: false
|
isActive: false
|
||||||
}, {
|
}, {
|
||||||
name: 'objects',
|
name: 'objects',
|
||||||
ref: 'objectsSection',
|
|
||||||
text: this.$t('objects'),
|
text: this.$t('objects'),
|
||||||
icon: faDice,
|
icon: faDice,
|
||||||
isActive: false
|
isActive: false
|
||||||
}, {
|
}, {
|
||||||
name: 'symbols',
|
name: 'symbols',
|
||||||
ref: 'symbolsSection',
|
|
||||||
text: this.$t('symbols'),
|
text: this.$t('symbols'),
|
||||||
icon: faHeart,
|
icon: faHeart,
|
||||||
isActive: false
|
isActive: false
|
||||||
}, {
|
}, {
|
||||||
name: 'flags',
|
name: 'flags',
|
||||||
ref: 'flagsSection',
|
|
||||||
text: this.$t('flags'),
|
text: this.$t('flags'),
|
||||||
icon: faFlag,
|
icon: faFlag,
|
||||||
isActive: false
|
isActive: false
|
||||||
@@ -109,15 +99,9 @@ export default Vue.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
go(ref) {
|
go(category) {
|
||||||
this.$refs.emojis.scrollTop = this.$refs[ref][0].offsetTop;
|
for (const c of this.categories) {
|
||||||
},
|
c.isActive = c.name === category.name;
|
||||||
|
|
||||||
onScroll(e) {
|
|
||||||
for (const x of this.categories) {
|
|
||||||
const top = e.target.scrollTop;
|
|
||||||
const el = this.$refs[x.ref][0];
|
|
||||||
x.isActive = el.offsetTop <= top && el.offsetTop + el.offsetHeight > top;
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -156,47 +140,46 @@ export default Vue.extend({
|
|||||||
overflow-y auto
|
overflow-y auto
|
||||||
overflow-x hidden
|
overflow-x hidden
|
||||||
|
|
||||||
> section
|
> header
|
||||||
> header
|
position sticky
|
||||||
position sticky
|
top 0
|
||||||
top 0
|
left 0
|
||||||
left 0
|
z-index 1
|
||||||
z-index 1
|
padding 8px
|
||||||
padding 8px
|
background var(--faceHeader)
|
||||||
background var(--faceHeader)
|
color var(--text)
|
||||||
color var(--text)
|
font-size 12px
|
||||||
font-size 12px
|
|
||||||
|
|
||||||
> div
|
> div
|
||||||
display grid
|
display grid
|
||||||
grid-template-columns 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr
|
grid-template-columns 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr
|
||||||
gap 4px
|
gap 4px
|
||||||
padding 8px
|
padding 8px
|
||||||
|
|
||||||
> button
|
> button
|
||||||
padding 0
|
padding 0
|
||||||
width 100%
|
width 100%
|
||||||
|
|
||||||
&:before
|
&:before
|
||||||
content ''
|
content ''
|
||||||
display block
|
display block
|
||||||
width 1px
|
width 1px
|
||||||
height 0
|
height 0
|
||||||
padding-bottom 100%
|
padding-bottom 100%
|
||||||
|
|
||||||
&:hover
|
|
||||||
> *
|
|
||||||
transform scale(1.2)
|
|
||||||
transition transform 0s
|
|
||||||
|
|
||||||
|
&:hover
|
||||||
> *
|
> *
|
||||||
position absolute
|
transform scale(1.2)
|
||||||
top 0
|
transition transform 0s
|
||||||
left 0
|
|
||||||
width 100%
|
> *
|
||||||
height 100%
|
position absolute
|
||||||
font-size 28px
|
top 0
|
||||||
transition transform 0.2s ease
|
left 0
|
||||||
pointer-events none
|
width 100%
|
||||||
|
height 100%
|
||||||
|
font-size 28px
|
||||||
|
transition transform 0.2s ease
|
||||||
|
pointer-events none
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
@@ -29,7 +29,11 @@ export default Vue.extend({
|
|||||||
customEmojis: {
|
customEmojis: {
|
||||||
required: false,
|
required: false,
|
||||||
default: () => []
|
default: () => []
|
||||||
}
|
},
|
||||||
|
isReaction: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
@@ -46,7 +50,7 @@ export default Vue.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
useOsDefaultEmojis(): boolean {
|
useOsDefaultEmojis(): boolean {
|
||||||
return this.$store.state.device.useOsDefaultEmojis;
|
return this.$store.state.device.useOsDefaultEmojis && !this.isReaction;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<a class="a" href="https://github.com/syuilo/misskey" target="_blank" title="View source on GitHub">
|
<a class="a" :href="repo" target="_blank" title="View source on GitHub">
|
||||||
<svg width="80" height="80" viewBox="0 0 250 250" aria-hidden="aria-hidden">
|
<svg width="80" height="80" viewBox="0 0 250 250" aria-hidden="aria-hidden">
|
||||||
<path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path>
|
<path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path>
|
||||||
<path class="octo-arm" d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor"></path>
|
<path class="octo-arm" d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor"></path>
|
||||||
@@ -8,9 +8,25 @@
|
|||||||
</a>
|
</a>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import Vue from 'vue'
|
||||||
|
export default Vue.extend({
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
repositoryUrl: 'https://github.com/syuilo/misskey'
|
||||||
|
};
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.$root.getMeta().then(meta => {
|
||||||
|
if (meta.maintainer)
|
||||||
|
this.repositoryUrl = meta.maintainer.repository_url;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
<style lang="stylus" scoped>
|
<style lang="stylus" scoped>
|
||||||
|
|
||||||
|
|
||||||
.a
|
.a
|
||||||
display block
|
display block
|
||||||
|
|
||||||
|
@@ -5,17 +5,17 @@
|
|||||||
|
|
||||||
<div style="overflow: hidden; line-height: 28px;">
|
<div style="overflow: hidden; line-height: 28px;">
|
||||||
<p class="turn" v-if="!iAmPlayer && !game.isEnded">
|
<p class="turn" v-if="!iAmPlayer && !game.isEnded">
|
||||||
<mfm :text="$t('@.reversi.turn-of', { name: $options.filters.userName(turnUser) })" :should-break="false" :plain-text="true" :custom-emojis="turnUser.emojis"/>
|
<mfm :key="'turn:' + $options.filters.userName(turnUser)" :text="$t('@.reversi.turn-of', { name: $options.filters.userName(turnUser) })" :should-break="false" :plain-text="true" :custom-emojis="turnUser.emojis"/>
|
||||||
<mk-ellipsis/>
|
<mk-ellipsis/>
|
||||||
</p>
|
</p>
|
||||||
<p class="turn" v-if="logPos != logs.length">
|
<p class="turn" v-if="logPos != logs.length">
|
||||||
<mfm :text="$t('@.reversi.past-turn-of', { name: $options.filters.userName(turnUser) })" :should-break="false" :plain-text="true" :custom-emojis="turnUser.emojis"/>
|
<mfm :key="'past-turn-of:' + $options.filters.userName(turnUser)" :text="$t('@.reversi.past-turn-of', { name: $options.filters.userName(turnUser) })" :should-break="false" :plain-text="true" :custom-emojis="turnUser.emojis"/>
|
||||||
</p>
|
</p>
|
||||||
<p class="turn1" v-if="iAmPlayer && !game.isEnded && !isMyTurn">{{ $t('@.reversi.opponent-turn') }}<mk-ellipsis/></p>
|
<p class="turn1" v-if="iAmPlayer && !game.isEnded && !isMyTurn">{{ $t('@.reversi.opponent-turn') }}<mk-ellipsis/></p>
|
||||||
<p class="turn2" v-if="iAmPlayer && !game.isEnded && isMyTurn" v-animate-css="{ classes: 'tada', iteration: 'infinite' }">{{ $t('@.reversi.my-turn') }}</p>
|
<p class="turn2" v-if="iAmPlayer && !game.isEnded && isMyTurn" v-animate-css="{ classes: 'tada', iteration: 'infinite' }">{{ $t('@.reversi.my-turn') }}</p>
|
||||||
<p class="result" v-if="game.isEnded && logPos == logs.length">
|
<p class="result" v-if="game.isEnded && logPos == logs.length">
|
||||||
<template v-if="game.winner">
|
<template v-if="game.winner">
|
||||||
<mfm :text="$t('@.reversi.won', { name: $options.filters.userName(game.winner) })" :should-break="false" :plain-text="true" :custom-emojis="game.winner.emojis"/>
|
<mfm :key="'won'" :text="$t('@.reversi.won', { name: $options.filters.userName(game.winner) })" :should-break="false" :plain-text="true" :custom-emojis="game.winner.emojis"/>
|
||||||
<span v-if="game.surrendered != null"> ({{ $t('surrendered') }})</span>
|
<span v-if="game.surrendered != null"> ({{ $t('surrendered') }})</span>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>{{ $t('@.reversi.drawn') }}</template>
|
<template v-else>{{ $t('@.reversi.drawn') }}</template>
|
||||||
|
@@ -12,21 +12,54 @@
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<button class="add" v-if="choices.length < 10" @click="add">{{ $t('add') }}</button>
|
<button class="add" v-if="choices.length < 10" @click="add">{{ $t('add') }}</button>
|
||||||
|
<button class="add" v-else disabled>{{ $t('no-more') }}</button>
|
||||||
<button class="destroy" @click="destroy" :title="$t('destroy')">
|
<button class="destroy" @click="destroy" :title="$t('destroy')">
|
||||||
<fa icon="times"/>
|
<fa icon="times"/>
|
||||||
</button>
|
</button>
|
||||||
|
<section>
|
||||||
|
<ui-switch v-model="multiple">{{ $t('multiple') }}</ui-switch>
|
||||||
|
<div>
|
||||||
|
<ui-select v-model="expiration">
|
||||||
|
<template #label>{{ $t('expiration') }}</template>
|
||||||
|
<option value="infinite">{{ $t('infinite') }}</option>
|
||||||
|
<option value="at">{{ $t('at') }}</option>
|
||||||
|
<option value="after">{{ $t('after') }}</option>
|
||||||
|
</ui-select>
|
||||||
|
<section v-if="expiration === 'at'">
|
||||||
|
<ui-input v-model="atDate" type="date">{{ $t('deadline-date') }}</ui-input>
|
||||||
|
<ui-input v-model="atTime" type="time">{{ $t('deadline-time') }}</ui-input>
|
||||||
|
</section>
|
||||||
|
<section v-if="expiration === 'after'">
|
||||||
|
<ui-input v-model="after" type="number">{{ $t('interval') }}</ui-input>
|
||||||
|
<ui-select v-model="unit">
|
||||||
|
<template #label>{{ $t('unit') }}</template>
|
||||||
|
<option value="second">{{ $t('second') }}</option>
|
||||||
|
<option value="minute">{{ $t('minute') }}</option>
|
||||||
|
<option value="hour">{{ $t('hour') }}</option>
|
||||||
|
<option value="day">{{ $t('day') }}</option>
|
||||||
|
</ui-select>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
|
import * as moment from 'moment';
|
||||||
import i18n from '../../../i18n';
|
import i18n from '../../../i18n';
|
||||||
import { erase } from '../../../../../prelude/array';
|
import { erase } from '../../../../../prelude/array';
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
i18n: i18n('common/views/components/poll-editor.vue'),
|
i18n: i18n('common/views/components/poll-editor.vue'),
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
choices: ['', '']
|
choices: ['', ''],
|
||||||
|
multiple: false,
|
||||||
|
expiration: 'infinite',
|
||||||
|
atDate: moment().add(1, 'day').toISOString().split('T')[0],
|
||||||
|
atTime: '00:00',
|
||||||
|
after: 0,
|
||||||
|
unit: 'second'
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
@@ -55,15 +88,46 @@ export default Vue.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
get() {
|
get() {
|
||||||
|
const at = () => {
|
||||||
|
const [date] = moment(this.atDate).toISOString().split('T');
|
||||||
|
const [hour, minute] = this.atTime.split(':');
|
||||||
|
return moment(`${date}T${hour}:${minute}Z`).valueOf();
|
||||||
|
};
|
||||||
|
|
||||||
|
const after = () => {
|
||||||
|
let base = parseInt(this.after);
|
||||||
|
switch (this.unit) {
|
||||||
|
case 'day': base *= 24;
|
||||||
|
case 'hour': base *= 60;
|
||||||
|
case 'minute': base *= 60;
|
||||||
|
case 'second': return base *= 1000;
|
||||||
|
default: return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
choices: erase('', this.choices)
|
choices: erase('', this.choices),
|
||||||
}
|
multiple: this.multiple,
|
||||||
|
...(
|
||||||
|
this.expiration === 'at' ? { expiresAt: at() } :
|
||||||
|
this.expiration === 'after' ? { expiredAfter: after() } : {})
|
||||||
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
set(data) {
|
set(data) {
|
||||||
if (data.choices.length == 0) return;
|
if (data.choices.length == 0) return;
|
||||||
this.choices = data.choices;
|
this.choices = data.choices;
|
||||||
if (data.choices.length == 1) this.choices = this.choices.concat('');
|
if (data.choices.length == 1) this.choices = this.choices.concat('');
|
||||||
|
this.multiple = data.multiple;
|
||||||
|
if (data.expiresAt) {
|
||||||
|
this.expiration = 'at';
|
||||||
|
this.atDate = this.atTime = data.expiresAt;
|
||||||
|
} else if (typeof data.expiredAfter === 'number') {
|
||||||
|
this.expiration = 'after';
|
||||||
|
this.after = data.expiredAfter;
|
||||||
|
} else {
|
||||||
|
this.expiration = 'infinite';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -128,6 +192,7 @@ export default Vue.extend({
|
|||||||
margin 8px 0 0 0
|
margin 8px 0 0 0
|
||||||
vertical-align top
|
vertical-align top
|
||||||
color var(--primary)
|
color var(--primary)
|
||||||
|
z-index 1
|
||||||
|
|
||||||
> .destroy
|
> .destroy
|
||||||
position absolute
|
position absolute
|
||||||
@@ -142,4 +207,23 @@ export default Vue.extend({
|
|||||||
&:active
|
&:active
|
||||||
color var(--primaryDarken30)
|
color var(--primaryDarken30)
|
||||||
|
|
||||||
|
> section
|
||||||
|
margin 16px 0 -16px 0
|
||||||
|
|
||||||
|
> div
|
||||||
|
margin 0 8px
|
||||||
|
|
||||||
|
&:last-child
|
||||||
|
flex 1 0 auto
|
||||||
|
|
||||||
|
> section
|
||||||
|
align-items center
|
||||||
|
display flex
|
||||||
|
margin -32px 0 0
|
||||||
|
|
||||||
|
> :first-child
|
||||||
|
margin-right 16px
|
||||||
|
|
||||||
|
> .ui-input
|
||||||
|
flex 1 0 auto
|
||||||
</style>
|
</style>
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="mk-poll" :data-is-voted="isVoted">
|
<div class="mk-poll" :data-done="closed || isVoted">
|
||||||
<ul>
|
<ul>
|
||||||
<li v-for="choice in poll.choices" :key="choice.id" @click="vote(choice.id)" :class="{ voted: choice.voted }" :title="!isVoted ? $t('vote-to').replace('{}', choice.text) : ''">
|
<li v-for="choice in poll.choices" :key="choice.id" @click="vote(choice.id)" :class="{ voted: choice.voted }" :title="!closed && !isVoted ? $t('vote-to').replace('{}', choice.text) : ''">
|
||||||
<div class="backdrop" :style="{ 'width': (showResult ? (choice.votes / total * 100) : 0) + '%' }"></div>
|
<div class="backdrop" :style="{ 'width': `${showResult ? (choice.votes / total * 100) : 0}%` }"></div>
|
||||||
<span>
|
<span>
|
||||||
<template v-if="choice.isVoted"><fa icon="check"/></template>
|
<template v-if="choice.isVoted"><fa icon="check"/></template>
|
||||||
<mfm :text="choice.text" :should-break="false" :plain-text="true" :custom-emojis="note.emojis"/>
|
<mfm :text="choice.text" :should-break="false" :plain-text="true" :custom-emojis="note.emojis"/>
|
||||||
@@ -10,11 +10,13 @@
|
|||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<p v-if="total > 0">
|
<p>
|
||||||
<span>{{ $t('total-users').replace('{}', total) }}</span>
|
<span>{{ $t('total-votes').replace('{}', total) }}</span>
|
||||||
<span>・</span>
|
<span> · </span>
|
||||||
<a v-if="!isVoted" @click="toggleShowResult">{{ showResult ? $t('vote') : $t('show-result') }}</a>
|
<a v-if="!closed && !isVoted" @click="toggleShowResult">{{ showResult ? $t('vote') : $t('show-result') }}</a>
|
||||||
<span v-if="isVoted">{{ $t('voted') }}</span>
|
<span v-if="isVoted">{{ $t('voted') }}</span>
|
||||||
|
<span v-else-if="closed">{{ $t('closed') }}</span>
|
||||||
|
<span v-if="remaining > 0"> · {{ timer }}</span>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -28,6 +30,7 @@ export default Vue.extend({
|
|||||||
props: ['note'],
|
props: ['note'],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
remaining: -1,
|
||||||
showResult: false
|
showResult: false
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@@ -38,19 +41,43 @@ export default Vue.extend({
|
|||||||
total(): number {
|
total(): number {
|
||||||
return sum(this.poll.choices.map(x => x.votes));
|
return sum(this.poll.choices.map(x => x.votes));
|
||||||
},
|
},
|
||||||
|
closed(): boolean {
|
||||||
|
return !this.remaining;
|
||||||
|
},
|
||||||
|
timer(): string {
|
||||||
|
return this.$t(
|
||||||
|
this.remaining > 86400 ? 'remaining-days' :
|
||||||
|
this.remaining > 3600 ? 'remaining-hours' :
|
||||||
|
this.remaining > 60 ? 'remaining-minutes' : 'remaining-seconds')
|
||||||
|
.replace('{s}', Math.floor(this.remaining % 60))
|
||||||
|
.replace('{m}', Math.floor(this.remaining / 60) % 60)
|
||||||
|
.replace('{h}', Math.floor(this.remaining / 3600) % 24)
|
||||||
|
.replace('{d}', Math.floor(this.remaining / 86400));
|
||||||
|
},
|
||||||
isVoted(): boolean {
|
isVoted(): boolean {
|
||||||
return this.poll.choices.some(c => c.isVoted);
|
return !this.poll.multiple && this.poll.choices.some(c => c.isVoted);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.showResult = this.isVoted;
|
this.showResult = this.isVoted;
|
||||||
|
|
||||||
|
if (this.note.poll.expiresAt) {
|
||||||
|
const update = () => {
|
||||||
|
if (this.remaining = Math.floor(Math.max(new Date(this.note.poll.expiresAt).getTime() - Date.now(), 0) / 1000))
|
||||||
|
requestAnimationFrame(update);
|
||||||
|
else
|
||||||
|
this.showResult = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
update();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
toggleShowResult() {
|
toggleShowResult() {
|
||||||
this.showResult = !this.showResult;
|
this.showResult = !this.showResult;
|
||||||
},
|
},
|
||||||
vote(id) {
|
vote(id) {
|
||||||
if (this.poll.choices.some(c => c.isVoted)) return;
|
if (this.closed || !this.poll.multiple && this.poll.choices.some(c => c.isVoted)) return;
|
||||||
this.$root.api('notes/polls/vote', {
|
this.$root.api('notes/polls/vote', {
|
||||||
noteId: this.note.id,
|
noteId: this.note.id,
|
||||||
choice: id
|
choice: id
|
||||||
@@ -61,7 +88,7 @@ export default Vue.extend({
|
|||||||
Vue.set(c, 'isVoted', true);
|
Vue.set(c, 'isVoted', true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.showResult = true;
|
if (!this.showResult) this.showResult = !this.poll.multiple;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -114,7 +141,7 @@ export default Vue.extend({
|
|||||||
a
|
a
|
||||||
color inherit
|
color inherit
|
||||||
|
|
||||||
&[data-is-voted]
|
&[data-done]
|
||||||
> ul > li
|
> ul > li
|
||||||
cursor default
|
cursor default
|
||||||
|
|
||||||
|
@@ -1,19 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<span class="mk-reaction-icon">
|
<mk-emoji :emoji="str.startsWith(':') ? null : str" :name="str.startsWith(':') ? str.substr(1, str.length - 2) : null" :is-reaction="true" :custom-emojis="customEmojis" :normal="true"/>
|
||||||
<img v-if="reaction == 'like'" src="https://twemoji.maxcdn.com/2/svg/1f44d.svg" :alt="$t('@.reactions.like')">
|
|
||||||
<img v-if="reaction == 'love'" src="https://twemoji.maxcdn.com/2/svg/2764.svg" :alt="$t('@.reactions.love')">
|
|
||||||
<img v-if="reaction == 'laugh'" src="https://twemoji.maxcdn.com/2/svg/1f606.svg" :alt="$t('@.reactions.laugh')">
|
|
||||||
<img v-if="reaction == 'hmm'" src="https://twemoji.maxcdn.com/2/svg/1f914.svg" :alt="$t('@.reactions.hmm')">
|
|
||||||
<img v-if="reaction == 'surprise'" src="https://twemoji.maxcdn.com/2/svg/1f62e.svg" :alt="$t('@.reactions.surprise')">
|
|
||||||
<img v-if="reaction == 'congrats'" src="https://twemoji.maxcdn.com/2/svg/1f389.svg" :alt="$t('@.reactions.congrats')">
|
|
||||||
<img v-if="reaction == 'angry'" src="https://twemoji.maxcdn.com/2/svg/1f4a2.svg" :alt="$t('@.reactions.angry')">
|
|
||||||
<img v-if="reaction == 'confused'" src="https://twemoji.maxcdn.com/2/svg/1f625.svg" :alt="$t('@.reactions.confused')">
|
|
||||||
<img v-if="reaction == 'rip'" src="https://twemoji.maxcdn.com/2/svg/1f607.svg" :alt="$t('@.reactions.rip')">
|
|
||||||
<template v-if="reaction == 'pudding'">
|
|
||||||
<img v-if="$store.getters.isSignedIn && $store.state.settings.iLikeSushi" src="https://twemoji.maxcdn.com/2/svg/1f363.svg" :alt="$t('@.reactions.pudding')">
|
|
||||||
<img v-else src="https://twemoji.maxcdn.com/2/svg/1f36e.svg" :alt="$t('@.reactions.pudding')">
|
|
||||||
</template>
|
|
||||||
</span>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
@@ -21,7 +7,35 @@ import Vue from 'vue';
|
|||||||
import i18n from '../../../i18n';
|
import i18n from '../../../i18n';
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
i18n: i18n(),
|
i18n: i18n(),
|
||||||
props: ['reaction']
|
props: {
|
||||||
|
reaction: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
customEmojis: (this.$root.getMetaSync() || { emojis: [] }).emojis || []
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
str(): any {
|
||||||
|
switch (this.reaction) {
|
||||||
|
case 'like': return '👍';
|
||||||
|
case 'love': return '❤';
|
||||||
|
case 'laugh': return '😆';
|
||||||
|
case 'hmm': return '🤔';
|
||||||
|
case 'surprise': return '😮';
|
||||||
|
case 'congrats': return '🎉';
|
||||||
|
case 'angry': return '💢';
|
||||||
|
case 'confused': return '😥';
|
||||||
|
case 'rip': return '😇';
|
||||||
|
case 'pudding': return (this.$store.getters.isSignedIn && this.$store.state.settings.iLikeSushi) ? '🍣' : '🍮';
|
||||||
|
case 'star': return '⭐';
|
||||||
|
default: return this.reaction;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
<div class="backdrop" ref="backdrop" @click="close"></div>
|
<div class="backdrop" ref="backdrop" @click="close"></div>
|
||||||
<div class="popover" :class="{ isMobile: $root.isMobile }" ref="popover">
|
<div class="popover" :class="{ isMobile: $root.isMobile }" ref="popover">
|
||||||
<p v-if="!$root.isMobile">{{ title }}</p>
|
<p v-if="!$root.isMobile">{{ title }}</p>
|
||||||
<div ref="buttons" :class="{ showFocus }">
|
<div class="buttons" ref="buttons" :class="{ showFocus }">
|
||||||
<button @click="react('like')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="1" :title="$t('@.reactions.like')" v-particle><mk-reaction-icon reaction="like"/></button>
|
<button @click="react('like')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="1" :title="$t('@.reactions.like')" v-particle><mk-reaction-icon reaction="like"/></button>
|
||||||
<button @click="react('love')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="2" :title="$t('@.reactions.love')" v-particle><mk-reaction-icon reaction="love"/></button>
|
<button @click="react('love')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="2" :title="$t('@.reactions.love')" v-particle><mk-reaction-icon reaction="love"/></button>
|
||||||
<button @click="react('laugh')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="3" :title="$t('@.reactions.laugh')" v-particle><mk-reaction-icon reaction="laugh"/></button>
|
<button @click="react('laugh')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="3" :title="$t('@.reactions.laugh')" v-particle><mk-reaction-icon reaction="laugh"/></button>
|
||||||
@@ -15,6 +15,9 @@
|
|||||||
<button @click="react('rip')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="9" :title="$t('@.reactions.rip')" v-particle><mk-reaction-icon reaction="rip"/></button>
|
<button @click="react('rip')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="9" :title="$t('@.reactions.rip')" v-particle><mk-reaction-icon reaction="rip"/></button>
|
||||||
<button @click="react('pudding')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="10" :title="$t('@.reactions.pudding')" v-particle><mk-reaction-icon reaction="pudding"/></button>
|
<button @click="react('pudding')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="10" :title="$t('@.reactions.pudding')" v-particle><mk-reaction-icon reaction="pudding"/></button>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-if="enableEmojiReaction" class="text">
|
||||||
|
<input v-model="text" placeholder="または絵文字を入力" @keyup.enter="reactText" @input="tryReactText" v-autocomplete="{ model: 'text' }">
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -23,6 +26,7 @@
|
|||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import i18n from '../../../i18n';
|
import i18n from '../../../i18n';
|
||||||
import anime from 'animejs';
|
import anime from 'animejs';
|
||||||
|
import { emojiRegex } from '../../../../../misc/emoji-regex';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
i18n: i18n('common/views/components/reaction-picker.vue'),
|
i18n: i18n('common/views/components/reaction-picker.vue'),
|
||||||
@@ -56,6 +60,8 @@ export default Vue.extend({
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
title: this.$t('choose-reaction'),
|
title: this.$t('choose-reaction'),
|
||||||
|
text: null,
|
||||||
|
enableEmojiReaction: false,
|
||||||
focus: null
|
focus: null
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@@ -94,6 +100,10 @@ export default Vue.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
|
this.$root.getMeta().then(meta => {
|
||||||
|
this.enableEmojiReaction = meta.enableEmojiReaction;
|
||||||
|
});
|
||||||
|
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.focus = 0;
|
this.focus = 0;
|
||||||
|
|
||||||
@@ -143,6 +153,17 @@ export default Vue.extend({
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
reactText() {
|
||||||
|
if (!this.text) return;
|
||||||
|
this.react(this.text);
|
||||||
|
},
|
||||||
|
|
||||||
|
tryReactText() {
|
||||||
|
if (!this.text) return;
|
||||||
|
if (!this.text.match(emojiRegex)) return;
|
||||||
|
this.reactText();
|
||||||
|
},
|
||||||
|
|
||||||
onMouseover(e) {
|
onMouseover(e) {
|
||||||
this.title = e.target.title;
|
this.title = e.target.title;
|
||||||
},
|
},
|
||||||
@@ -256,9 +277,9 @@ export default Vue.extend({
|
|||||||
color var(--popupFg)
|
color var(--popupFg)
|
||||||
border-bottom solid var(--lineWidth) var(--faceDivider)
|
border-bottom solid var(--lineWidth) var(--faceDivider)
|
||||||
|
|
||||||
> div
|
> .buttons
|
||||||
padding 4px
|
padding 4px
|
||||||
width 240px
|
width 216px
|
||||||
text-align center
|
text-align center
|
||||||
|
|
||||||
&.showFocus
|
&.showFocus
|
||||||
@@ -283,6 +304,9 @@ export default Vue.extend({
|
|||||||
font-size 24px
|
font-size 24px
|
||||||
border-radius 2px
|
border-radius 2px
|
||||||
|
|
||||||
|
> *
|
||||||
|
height 1em
|
||||||
|
|
||||||
&:hover
|
&:hover
|
||||||
background var(--reactionPickerButtonHoverBg)
|
background var(--reactionPickerButtonHoverBg)
|
||||||
|
|
||||||
@@ -290,4 +314,29 @@ export default Vue.extend({
|
|||||||
background var(--primary)
|
background var(--primary)
|
||||||
box-shadow inset 0 0.15em 0.3em rgba(27, 31, 35, 0.15)
|
box-shadow inset 0 0.15em 0.3em rgba(27, 31, 35, 0.15)
|
||||||
|
|
||||||
|
> .text
|
||||||
|
width 216px
|
||||||
|
padding 4px 8px 8px 8px
|
||||||
|
|
||||||
|
> input
|
||||||
|
width 100%
|
||||||
|
padding 10px
|
||||||
|
margin 0
|
||||||
|
text-align center
|
||||||
|
font-size 16px
|
||||||
|
color var(--desktopPostFormTextareaFg)
|
||||||
|
background var(--desktopPostFormTextareaBg)
|
||||||
|
outline none
|
||||||
|
border solid 1px var(--primaryAlpha01)
|
||||||
|
border-radius 4px
|
||||||
|
transition border-color .2s ease
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
border-color var(--primaryAlpha02)
|
||||||
|
transition border-color .1s ease
|
||||||
|
|
||||||
|
&:focus
|
||||||
|
border-color var(--primaryAlpha05)
|
||||||
|
transition border-color 0s ease
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
@@ -136,12 +136,8 @@ export default Vue.extend({
|
|||||||
&:hover
|
&:hover
|
||||||
background var(--reactionViewerButtonHoverBg)
|
background var(--reactionViewerButtonHoverBg)
|
||||||
|
|
||||||
> .mk-reaction-icon
|
|
||||||
font-size 1.4em
|
|
||||||
|
|
||||||
> span
|
> span
|
||||||
font-size 1.1em
|
font-size 1.1em
|
||||||
line-height 32px
|
line-height 32px
|
||||||
vertical-align middle
|
|
||||||
color var(--text)
|
color var(--text)
|
||||||
</style>
|
</style>
|
||||||
|
@@ -93,12 +93,17 @@ export default Vue.extend({
|
|||||||
},
|
},
|
||||||
plotOptions: {
|
plotOptions: {
|
||||||
bar: {
|
bar: {
|
||||||
columnWidth: '90%'
|
columnWidth: '80%'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
grid: {
|
grid: {
|
||||||
clipMarkers: false,
|
clipMarkers: false,
|
||||||
borderColor: 'rgba(0, 0, 0, 0.1)'
|
borderColor: 'rgba(0, 0, 0, 0.1)',
|
||||||
|
xaxis: {
|
||||||
|
lines: {
|
||||||
|
show: true,
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
tooltip: {
|
tooltip: {
|
||||||
shared: true,
|
shared: true,
|
||||||
|
@@ -51,12 +51,12 @@
|
|||||||
<template #desc v-if="bannerUploading">{{ $t('uploading') }}<mk-ellipsis/></template>
|
<template #desc v-if="bannerUploading">{{ $t('uploading') }}<mk-ellipsis/></template>
|
||||||
</ui-input>
|
</ui-input>
|
||||||
|
|
||||||
<ui-button @click="save(true)">{{ $t('save') }}</ui-button>
|
<ui-button @click="save(true)"><fa :icon="faSave"/> {{ $t('save') }}</ui-button>
|
||||||
</ui-form>
|
</ui-form>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
<header>{{ $t('advanced') }}</header>
|
<header><fa :icon="faCogs"/> {{ $t('advanced') }}</header>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<ui-switch v-model="isCat" @change="save(false)">{{ $t('is-cat') }}</ui-switch>
|
<ui-switch v-model="isCat" @change="save(false)">{{ $t('is-cat') }}</ui-switch>
|
||||||
@@ -66,7 +66,7 @@
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
<header>{{ $t('privacy') }}</header>
|
<header><fa :icon="faUnlockAlt"/> {{ $t('privacy') }}</header>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<ui-switch v-model="isLocked" @change="save(false)">{{ $t('is-locked') }}</ui-switch>
|
<ui-switch v-model="isLocked" @change="save(false)">{{ $t('is-locked') }}</ui-switch>
|
||||||
@@ -76,7 +76,7 @@
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section v-if="enableEmail">
|
<section v-if="enableEmail">
|
||||||
<header>{{ $t('email') }}</header>
|
<header><fa :icon="faEnvelope"/> {{ $t('email') }}</header>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<template v-if="$store.state.i.email != null">
|
<template v-if="$store.state.i.email != null">
|
||||||
@@ -84,12 +84,12 @@
|
|||||||
<ui-info v-else warn>{{ $t('email-not-verified') }}</ui-info>
|
<ui-info v-else warn>{{ $t('email-not-verified') }}</ui-info>
|
||||||
</template>
|
</template>
|
||||||
<ui-input v-model="email" type="email"><span>{{ $t('email-address') }}</span></ui-input>
|
<ui-input v-model="email" type="email"><span>{{ $t('email-address') }}</span></ui-input>
|
||||||
<ui-button @click="updateEmail()">{{ $t('save') }}</ui-button>
|
<ui-button @click="updateEmail()"><fa :icon="faSave"/> {{ $t('save') }}</ui-button>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
<header>{{ $t('export') }}</header>
|
<header><fa :icon="faBoxes"/> {{ $t('export-and-import') }}</header>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<ui-select v-model="exportTarget">
|
<ui-select v-model="exportTarget">
|
||||||
@@ -97,8 +97,12 @@
|
|||||||
<option value="following">{{ $t('export-targets.following-list') }}</option>
|
<option value="following">{{ $t('export-targets.following-list') }}</option>
|
||||||
<option value="mute">{{ $t('export-targets.mute-list') }}</option>
|
<option value="mute">{{ $t('export-targets.mute-list') }}</option>
|
||||||
<option value="blocking">{{ $t('export-targets.blocking-list') }}</option>
|
<option value="blocking">{{ $t('export-targets.blocking-list') }}</option>
|
||||||
|
<option value="user-lists">{{ $t('export-targets.user-lists') }}</option>
|
||||||
</ui-select>
|
</ui-select>
|
||||||
<ui-button @click="doExport()"><fa :icon="faDownload"/> {{ $t('export') }}</ui-button>
|
<ui-horizon-group class="fit-bottom">
|
||||||
|
<ui-button @click="doExport()"><fa :icon="faDownload"/> {{ $t('export') }}</ui-button>
|
||||||
|
<ui-button @click="doImport()" :disabled="!['following', 'user-lists'].includes(exportTarget)"><fa :icon="faUpload"/> {{ $t('import') }}</ui-button>
|
||||||
|
</ui-horizon-group>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
@@ -118,7 +122,8 @@ import { apiUrl, host } from '../../../../config';
|
|||||||
import { toUnicode } from 'punycode';
|
import { toUnicode } from 'punycode';
|
||||||
import langmap from 'langmap';
|
import langmap from 'langmap';
|
||||||
import { unique } from '../../../../../../prelude/array';
|
import { unique } from '../../../../../../prelude/array';
|
||||||
import { faDownload } from '@fortawesome/free-solid-svg-icons';
|
import { faDownload, faUpload, faUnlockAlt, faBoxes, faCogs } from '@fortawesome/free-solid-svg-icons';
|
||||||
|
import { faSave, faEnvelope } from '@fortawesome/free-regular-svg-icons';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
i18n: i18n('common/views/components/profile-editor.vue'),
|
i18n: i18n('common/views/components/profile-editor.vue'),
|
||||||
@@ -147,7 +152,7 @@ export default Vue.extend({
|
|||||||
avatarUploading: false,
|
avatarUploading: false,
|
||||||
bannerUploading: false,
|
bannerUploading: false,
|
||||||
exportTarget: 'notes',
|
exportTarget: 'notes',
|
||||||
faDownload
|
faDownload, faUpload, faSave, faEnvelope, faUnlockAlt, faBoxes, faCogs
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -284,6 +289,7 @@ export default Vue.extend({
|
|||||||
this.exportTarget == 'following' ? 'i/export-following' :
|
this.exportTarget == 'following' ? 'i/export-following' :
|
||||||
this.exportTarget == 'mute' ? 'i/export-mute' :
|
this.exportTarget == 'mute' ? 'i/export-mute' :
|
||||||
this.exportTarget == 'blocking' ? 'i/export-blocking' :
|
this.exportTarget == 'blocking' ? 'i/export-blocking' :
|
||||||
|
this.exportTarget == 'user-lists' ? 'i/export-user-lists' :
|
||||||
null, {});
|
null, {});
|
||||||
|
|
||||||
this.$root.dialog({
|
this.$root.dialog({
|
||||||
@@ -292,6 +298,22 @@ export default Vue.extend({
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
doImport() {
|
||||||
|
this.$chooseDriveFile().then(file => {
|
||||||
|
this.$root.api(
|
||||||
|
this.exportTarget == 'following' ? 'i/import-following' :
|
||||||
|
this.exportTarget == 'user-lists' ? 'i/import-user-lists' :
|
||||||
|
null, {
|
||||||
|
fileId: file.id
|
||||||
|
});
|
||||||
|
|
||||||
|
this.$root.dialog({
|
||||||
|
type: 'info',
|
||||||
|
text: this.$t('import-requested')
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
async deleteAccount() {
|
async deleteAccount() {
|
||||||
const { canceled: canceled, result: password } = await this.$root.dialog({
|
const { canceled: canceled, result: password } = await this.$root.dialog({
|
||||||
title: this.$t('enter-password'),
|
title: this.$t('enter-password'),
|
||||||
|
@@ -386,7 +386,7 @@ export default Vue.extend({
|
|||||||
height: 50px;
|
height: 50px;
|
||||||
background-color: #83D8FF;
|
background-color: #83D8FF;
|
||||||
border-radius: 90px - 6;
|
border-radius: 90px - 6;
|
||||||
transition: background-color 200ms cubic-bezier(0.445, 0.05, 0.55, 0.95);
|
transition: background-color 200ms cubic-bezier(0.445, 0.05, 0.55, 0.95) !important;
|
||||||
|
|
||||||
&:before {
|
&:before {
|
||||||
content: 'Light';
|
content: 'Light';
|
||||||
@@ -418,14 +418,14 @@ export default Vue.extend({
|
|||||||
background-color: #FFCF96;
|
background-color: #FFCF96;
|
||||||
border-radius: 50px;
|
border-radius: 50px;
|
||||||
box-shadow: 0 2px 6px rgba(0,0,0,.3);
|
box-shadow: 0 2px 6px rgba(0,0,0,.3);
|
||||||
transition: all 400ms cubic-bezier(0.68, -0.55, 0.265, 1.55);
|
transition: all 400ms cubic-bezier(0.68, -0.55, 0.265, 1.55) !important;
|
||||||
transform: rotate(-45deg);
|
transform: rotate(-45deg);
|
||||||
|
|
||||||
.crater {
|
.crater {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
background-color: #E8CDA5;
|
background-color: #E8CDA5;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transition: opacity 200ms ease-in-out;
|
transition: opacity 200ms ease-in-out !important;
|
||||||
border-radius: 100%;
|
border-radius: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -454,7 +454,7 @@ export default Vue.extend({
|
|||||||
.star {
|
.star {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
background-color: #ffffff;
|
background-color: #ffffff;
|
||||||
transition: all 300ms cubic-bezier(0.445, 0.05, 0.55, 0.95);
|
transition: all 300ms cubic-bezier(0.445, 0.05, 0.55, 0.95) !important;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -486,7 +486,7 @@ export default Vue.extend({
|
|||||||
.star--5,
|
.star--5,
|
||||||
.star--6 {
|
.star--6 {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transition: all 300ms 0 cubic-bezier(0.445, 0.05, 0.55, 0.95);
|
transition: all 300ms 0 cubic-bezier(0.445, 0.05, 0.55, 0.95) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.star--4 {
|
.star--4 {
|
||||||
@@ -559,13 +559,13 @@ export default Vue.extend({
|
|||||||
transform: translate3d(0,0,0);
|
transform: translate3d(0,0,0);
|
||||||
}
|
}
|
||||||
.star--4 {
|
.star--4 {
|
||||||
transition: all 300ms 200ms cubic-bezier(0.445, 0.05, 0.55, 0.95);
|
transition: all 300ms 200ms cubic-bezier(0.445, 0.05, 0.55, 0.95) !important;
|
||||||
}
|
}
|
||||||
.star--5 {
|
.star--5 {
|
||||||
transition: all 300ms 300ms cubic-bezier(0.445, 0.05, 0.55, 0.95);
|
transition: all 300ms 300ms cubic-bezier(0.445, 0.05, 0.55, 0.95) !important;
|
||||||
}
|
}
|
||||||
.star--6 {
|
.star--6 {
|
||||||
transition: all 300ms 400ms cubic-bezier(0.445, 0.05, 0.55, 0.95);
|
transition: all 300ms 400ms cubic-bezier(0.445, 0.05, 0.55, 0.95) !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="playerEnabled" class="player" :style="`padding: ${(player.height || 0) / (player.width || 1) * 100}% 0 0`">
|
<div v-if="playerEnabled" class="player" :style="`padding: ${(player.height || 0) / (player.width || 1) * 100}% 0 0`">
|
||||||
|
<button class="disablePlayer" @click="playerEnabled = false" :title="$t('disable-player')"><fa icon="times"/></button>
|
||||||
<iframe :src="player.url + (player.url.match(/\?/) ? '&autoplay=1&auto_play=1' : '?autoplay=1&auto_play=1')" :width="player.width || '100%'" :heigth="player.height || 250" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen />
|
<iframe :src="player.url + (player.url.match(/\?/) ? '&autoplay=1&auto_play=1' : '?autoplay=1&auto_play=1')" :width="player.width || '100%'" :heigth="player.height || 250" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen />
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="tweetUrl && detail" class="twitter">
|
<div v-else-if="tweetUrl && detail" class="twitter">
|
||||||
@@ -126,6 +127,22 @@ export default Vue.extend({
|
|||||||
position relative
|
position relative
|
||||||
width 100%
|
width 100%
|
||||||
|
|
||||||
|
> button
|
||||||
|
position absolute
|
||||||
|
top -1.5em
|
||||||
|
right 0
|
||||||
|
font-size 1em
|
||||||
|
width 1.5em
|
||||||
|
height 1.5em
|
||||||
|
padding 0
|
||||||
|
margin 0
|
||||||
|
color var(--text)
|
||||||
|
background rgba(128, 128, 128, 0.2)
|
||||||
|
opacity 0.7
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
opacity 0.9
|
||||||
|
|
||||||
> iframe
|
> iframe
|
||||||
height 100%
|
height 100%
|
||||||
left 0
|
left 0
|
||||||
|
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
<div class="xroyrflcmhhtmlwmyiwpfqiirqokfueb">
|
<div class="xroyrflcmhhtmlwmyiwpfqiirqokfueb">
|
||||||
<div ref="chart" class="chart"></div>
|
<div ref="chart" class="chart"></div>
|
||||||
<x-hashtag-tl :tag-tl="tagTl" class="tl"/>
|
<x-hashtag-tl :tag-tl="tagTl" class="tl" :key="JSON.stringify(tagTl)"/>
|
||||||
</div>
|
</div>
|
||||||
</x-column>
|
</x-column>
|
||||||
</template>
|
</template>
|
||||||
|
@@ -172,7 +172,7 @@ export default Vue.extend({
|
|||||||
},
|
},
|
||||||
plotOptions: {
|
plotOptions: {
|
||||||
bar: {
|
bar: {
|
||||||
columnWidth: '90%'
|
columnWidth: '80%'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
grid: {
|
grid: {
|
||||||
|
@@ -26,6 +26,7 @@
|
|||||||
<option value="hashtags">{{ $t('@.widgets.hashtags') }}</option>
|
<option value="hashtags">{{ $t('@.widgets.hashtags') }}</option>
|
||||||
<option value="posts-monitor">{{ $t('@.widgets.posts-monitor') }}</option>
|
<option value="posts-monitor">{{ $t('@.widgets.posts-monitor') }}</option>
|
||||||
<option value="server">{{ $t('@.widgets.server') }}</option>
|
<option value="server">{{ $t('@.widgets.server') }}</option>
|
||||||
|
<option value="queue">{{ $t('@.widgets.queue') }}</option>
|
||||||
<option value="nav">{{ $t('@.widgets.nav') }}</option>
|
<option value="nav">{{ $t('@.widgets.nav') }}</option>
|
||||||
<option value="tips">{{ $t('@.widgets.tips') }}</option>
|
<option value="tips">{{ $t('@.widgets.tips') }}</option>
|
||||||
</select>
|
</select>
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
<h1>{{ $t('share-with', { name }) }}</h1>
|
<h1>{{ $t('share-with', { name }) }}</h1>
|
||||||
<div>
|
<div>
|
||||||
<mk-signin v-if="!$store.getters.isSignedIn"/>
|
<mk-signin v-if="!$store.getters.isSignedIn"/>
|
||||||
<mk-post-form v-else-if="!posted" :initial-text="text" :instant="true" @posted="posted = true"/>
|
<mk-post-form v-else-if="!posted" :initial-text="template" :instant="true" @posted="posted = true"/>
|
||||||
<p v-if="posted" class="posted"><fa icon="check"/></p>
|
<p v-if="posted" class="posted"><fa icon="check"/></p>
|
||||||
</div>
|
</div>
|
||||||
<ui-button class="close" v-if="posted" @click="close">{{ $t('@.close') }}</ui-button>
|
<ui-button class="close" v-if="posted" @click="close">{{ $t('@.close') }}</ui-button>
|
||||||
@@ -20,9 +20,21 @@ export default Vue.extend({
|
|||||||
return {
|
return {
|
||||||
name: null,
|
name: null,
|
||||||
posted: false,
|
posted: false,
|
||||||
text: new URLSearchParams(location.search).get('text')
|
text: new URLSearchParams(location.search).get('text'),
|
||||||
|
url: new URLSearchParams(location.search).get('url'),
|
||||||
|
title: new URLSearchParams(location.search).get('title'),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
template(): string {
|
||||||
|
let t = '';
|
||||||
|
if (this.title && this.url) t += `【[${this.title}](${this.url})】\n`;
|
||||||
|
if (this.title && !this.url) t += `【${this.title}】\n`;
|
||||||
|
if (this.text) t += `${this.text}\n`;
|
||||||
|
if (!this.title && this.url) t += `${this.url}`;
|
||||||
|
return t.trim();
|
||||||
|
}
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
close() {
|
close() {
|
||||||
window.close();
|
window.close();
|
@@ -31,3 +31,4 @@ Vue.component('mkw-version', wVersion);
|
|||||||
Vue.component('mkw-hashtags', wHashtags);
|
Vue.component('mkw-hashtags', wHashtags);
|
||||||
Vue.component('mkw-instance', wInstance);
|
Vue.component('mkw-instance', wInstance);
|
||||||
Vue.component('mkw-post-form', wPostForm);
|
Vue.component('mkw-post-form', wPostForm);
|
||||||
|
Vue.component('mkw-queue', () => import('./queue.vue').then(m => m.default));
|
||||||
|
170
src/client/app/common/views/widgets/queue.vue
Normal file
170
src/client/app/common/views/widgets/queue.vue
Normal file
@@ -0,0 +1,170 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<ui-container :show-header="!props.compact">
|
||||||
|
<template #header><fa :icon="faTasks"/>Queue</template>
|
||||||
|
|
||||||
|
<div class="mntrproz">
|
||||||
|
<div>
|
||||||
|
<b>In</b>
|
||||||
|
<span v-if="latestStats">{{ latestStats.inbox.activeSincePrevTick | number }} / {{ latestStats.inbox.delayed | number }}</span>
|
||||||
|
<div ref="in"></div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<b>Out</b>
|
||||||
|
<span v-if="latestStats">{{ latestStats.deliver.activeSincePrevTick | number }} / {{ latestStats.deliver.delayed | number }}</span>
|
||||||
|
<div ref="out"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ui-container>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import define from '../../define-widget';
|
||||||
|
import { faTasks } from '@fortawesome/free-solid-svg-icons';
|
||||||
|
import ApexCharts from 'apexcharts';
|
||||||
|
|
||||||
|
export default define({
|
||||||
|
name: 'queue',
|
||||||
|
props: () => ({
|
||||||
|
compact: false
|
||||||
|
})
|
||||||
|
}).extend({
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
stats: [],
|
||||||
|
inChart: null,
|
||||||
|
outChart: null,
|
||||||
|
faTasks
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
stats(stats) {
|
||||||
|
this.inChart.updateSeries([{
|
||||||
|
type: 'area',
|
||||||
|
data: stats.map((x, i) => ({ x: i, y: x.inbox.activeSincePrevTick }))
|
||||||
|
}, {
|
||||||
|
type: 'area',
|
||||||
|
data: stats.map((x, i) => ({ x: i, y: x.inbox.active }))
|
||||||
|
}, {
|
||||||
|
type: 'line',
|
||||||
|
data: stats.map((x, i) => ({ x: i, y: x.inbox.waiting }))
|
||||||
|
}, {
|
||||||
|
type: 'line',
|
||||||
|
data: stats.map((x, i) => ({ x: i, y: x.inbox.delayed }))
|
||||||
|
}]);
|
||||||
|
this.outChart.updateSeries([{
|
||||||
|
type: 'area',
|
||||||
|
data: stats.map((x, i) => ({ x: i, y: x.deliver.activeSincePrevTick }))
|
||||||
|
}, {
|
||||||
|
type: 'area',
|
||||||
|
data: stats.map((x, i) => ({ x: i, y: x.deliver.active }))
|
||||||
|
}, {
|
||||||
|
type: 'line',
|
||||||
|
data: stats.map((x, i) => ({ x: i, y: x.deliver.waiting }))
|
||||||
|
}, {
|
||||||
|
type: 'line',
|
||||||
|
data: stats.map((x, i) => ({ x: i, y: x.deliver.delayed }))
|
||||||
|
}]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
latestStats(): any {
|
||||||
|
return this.stats[this.stats.length - 1];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
const chartOpts = {
|
||||||
|
chart: {
|
||||||
|
type: 'area',
|
||||||
|
height: 70,
|
||||||
|
animations: {
|
||||||
|
dynamicAnimation: {
|
||||||
|
enabled: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
sparkline: {
|
||||||
|
enabled: true,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
enabled: false
|
||||||
|
},
|
||||||
|
stroke: {
|
||||||
|
curve: 'straight',
|
||||||
|
width: 1
|
||||||
|
},
|
||||||
|
colors: ['#00E396', '#00BCD4', '#FFB300', '#e53935'],
|
||||||
|
series: [{ data: [] }, { data: [] }, { data: [] }, { data: [] }] as any,
|
||||||
|
yaxis: {
|
||||||
|
min: 0,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.inChart = new ApexCharts(this.$refs.in, chartOpts);
|
||||||
|
this.outChart = new ApexCharts(this.$refs.out, chartOpts);
|
||||||
|
|
||||||
|
this.inChart.render();
|
||||||
|
this.outChart.render();
|
||||||
|
|
||||||
|
const connection = this.$root.stream.useSharedConnection('queueStats');
|
||||||
|
connection.on('stats', this.onStats);
|
||||||
|
connection.on('statsLog', this.onStatsLog);
|
||||||
|
connection.send('requestLog', {
|
||||||
|
id: Math.random().toString().substr(2, 8),
|
||||||
|
length: 50
|
||||||
|
});
|
||||||
|
|
||||||
|
this.$once('hook:beforeDestroy', () => {
|
||||||
|
connection.dispose();
|
||||||
|
this.inChart.destroy();
|
||||||
|
this.outChart.destroy();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
func() {
|
||||||
|
this.props.compact = !this.props.compact;
|
||||||
|
this.save();
|
||||||
|
},
|
||||||
|
|
||||||
|
onStats(stats) {
|
||||||
|
this.stats.push(stats);
|
||||||
|
if (this.stats.length > 50) this.stats.shift();
|
||||||
|
},
|
||||||
|
|
||||||
|
onStatsLog(statsLog) {
|
||||||
|
for (const stats of statsLog.reverse()) {
|
||||||
|
this.onStats(stats);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="stylus" scoped>
|
||||||
|
.mntrproz
|
||||||
|
display flex
|
||||||
|
padding 4px
|
||||||
|
|
||||||
|
> div
|
||||||
|
width 50%
|
||||||
|
padding 4px
|
||||||
|
|
||||||
|
> b
|
||||||
|
display block
|
||||||
|
font-size 12px
|
||||||
|
color var(--text)
|
||||||
|
|
||||||
|
> span
|
||||||
|
position absolute
|
||||||
|
top 4px
|
||||||
|
right 4px
|
||||||
|
opacity 0.7
|
||||||
|
font-size 12px
|
||||||
|
color var(--text)
|
||||||
|
|
||||||
|
</style>
|
@@ -18,7 +18,7 @@ import MkSelectDrive from './views/pages/selectdrive.vue';
|
|||||||
import MkDrive from './views/pages/drive.vue';
|
import MkDrive from './views/pages/drive.vue';
|
||||||
import MkMessagingRoom from './views/pages/messaging-room.vue';
|
import MkMessagingRoom from './views/pages/messaging-room.vue';
|
||||||
import MkReversi from './views/pages/games/reversi.vue';
|
import MkReversi from './views/pages/games/reversi.vue';
|
||||||
import MkShare from './views/pages/share.vue';
|
import MkShare from '../common/views/pages/share.vue';
|
||||||
import MkFollow from '../common/views/pages/follow.vue';
|
import MkFollow from '../common/views/pages/follow.vue';
|
||||||
import MkNotFound from '../common/views/pages/not-found.vue';
|
import MkNotFound from '../common/views/pages/not-found.vue';
|
||||||
import MkSettings from './views/pages/settings.vue';
|
import MkSettings from './views/pages/settings.vue';
|
||||||
|
@@ -129,9 +129,9 @@ export default Vue.extend({
|
|||||||
mounted() {
|
mounted() {
|
||||||
// Get replies
|
// Get replies
|
||||||
if (!this.compact) {
|
if (!this.compact) {
|
||||||
this.$root.api('notes/replies', {
|
this.$root.api('notes/children', {
|
||||||
noteId: this.appearNote.id,
|
noteId: this.appearNote.id,
|
||||||
limit: 8
|
limit: 30
|
||||||
}).then(replies => {
|
}).then(replies => {
|
||||||
this.replies = replies;
|
this.replies = replies;
|
||||||
});
|
});
|
||||||
|
@@ -123,9 +123,9 @@ export default Vue.extend({
|
|||||||
|
|
||||||
created() {
|
created() {
|
||||||
if (this.detail) {
|
if (this.detail) {
|
||||||
this.$root.api('notes/replies', {
|
this.$root.api('notes/children', {
|
||||||
noteId: this.appearNote.id,
|
noteId: this.appearNote.id,
|
||||||
limit: 8
|
limit: 30
|
||||||
}).then(replies => {
|
}).then(replies => {
|
||||||
this.replies = replies;
|
this.replies = replies;
|
||||||
});
|
});
|
||||||
|
@@ -115,6 +115,8 @@ export default Vue.extend({
|
|||||||
uploadings: [],
|
uploadings: [],
|
||||||
poll: false,
|
poll: false,
|
||||||
pollChoices: [],
|
pollChoices: [],
|
||||||
|
pollMultiple: false,
|
||||||
|
pollExpiration: [],
|
||||||
useCw: false,
|
useCw: false,
|
||||||
cw: null,
|
cw: null,
|
||||||
geo: null,
|
geo: null,
|
||||||
@@ -295,7 +297,10 @@ export default Vue.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
onPollUpdate() {
|
onPollUpdate() {
|
||||||
this.pollChoices = this.$refs.poll.get().choices;
|
const got = this.$refs.poll.get();
|
||||||
|
this.pollChoices = got.choices;
|
||||||
|
this.pollMultiple = got.multiple;
|
||||||
|
this.pollExpiration = [got.expiration, got.expiresAt || got.expiredAfter];
|
||||||
this.saveDraft();
|
this.saveDraft();
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -475,7 +480,7 @@ export default Vue.extend({
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (this.text && this.text != '') {
|
if (this.text && this.text != '') {
|
||||||
const hashtags = parse(this.text).filter(x => x.type == 'hashtag').map(x => x.hashtag);
|
const hashtags = parse(this.text).filter(x => x.node.type === 'hashtag').map(x => x.node.props.hashtag);
|
||||||
const history = JSON.parse(localStorage.getItem('hashtags') || '[]') as string[];
|
const history = JSON.parse(localStorage.getItem('hashtags') || '[]') as string[];
|
||||||
localStorage.setItem('hashtags', JSON.stringify(unique(hashtags.concat(history))));
|
localStorage.setItem('hashtags', JSON.stringify(unique(hashtags.concat(history))));
|
||||||
}
|
}
|
||||||
|
@@ -27,6 +27,7 @@
|
|||||||
<option value="hashtags">{{ $t('@.widgets.hashtags') }}</option>
|
<option value="hashtags">{{ $t('@.widgets.hashtags') }}</option>
|
||||||
<option value="posts-monitor">{{ $t('@.widgets.posts-monitor') }}</option>
|
<option value="posts-monitor">{{ $t('@.widgets.posts-monitor') }}</option>
|
||||||
<option value="server">{{ $t('@.widgets.server') }}</option>
|
<option value="server">{{ $t('@.widgets.server') }}</option>
|
||||||
|
<option value="queue">{{ $t('@.widgets.queue') }}</option>
|
||||||
<option value="nav">{{ $t('@.widgets.nav') }}</option>
|
<option value="nav">{{ $t('@.widgets.nav') }}</option>
|
||||||
<option value="tips">{{ $t('@.widgets.tips') }}</option>
|
<option value="tips">{{ $t('@.widgets.tips') }}</option>
|
||||||
</select>
|
</select>
|
||||||
|
@@ -1,66 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="pptjhabgjtt7kwskbfv4y3uml6fpuhmr">
|
|
||||||
<h1>{{ this.$t('share-with', { name }) }}</h1>
|
|
||||||
<div>
|
|
||||||
<mk-signin v-if="!$store.getters.isSignedIn"/>
|
|
||||||
<mk-post-form v-else-if="!posted" :initial-text="text" :instant="true" @posted="posted = true"/>
|
|
||||||
<p v-if="posted" class="posted"><fa icon="check"/></p>
|
|
||||||
</div>
|
|
||||||
<button v-if="posted" class="ui button" @click="close">{{ $t('@.close') }}</button>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import Vue from 'vue';
|
|
||||||
import i18n from '../../../i18n';
|
|
||||||
|
|
||||||
export default Vue.extend({
|
|
||||||
i18n: i18n('desktop/views/pages/share.vue'),
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
name: null,
|
|
||||||
posted: false,
|
|
||||||
text: new URLSearchParams(location.search).get('text')
|
|
||||||
};
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
close() {
|
|
||||||
window.close();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.$root.getMeta().then(meta => {
|
|
||||||
this.name = meta.name;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="stylus" scoped>
|
|
||||||
.pptjhabgjtt7kwskbfv4y3uml6fpuhmr
|
|
||||||
padding 16px
|
|
||||||
|
|
||||||
> h1
|
|
||||||
margin 0 0 8px 0
|
|
||||||
color #555
|
|
||||||
font-size 20px
|
|
||||||
text-align center
|
|
||||||
|
|
||||||
> div
|
|
||||||
max-width 500px
|
|
||||||
margin 0 auto
|
|
||||||
background #fff
|
|
||||||
border solid 1px rgba(#000, 0.1)
|
|
||||||
border-radius 6px
|
|
||||||
overflow hidden
|
|
||||||
|
|
||||||
> .posted
|
|
||||||
display block
|
|
||||||
margin 0
|
|
||||||
padding 64px
|
|
||||||
text-align center
|
|
||||||
|
|
||||||
> button
|
|
||||||
display block
|
|
||||||
margin 16px auto
|
|
||||||
</style>
|
|
@@ -16,11 +16,11 @@ import App from './app.vue';
|
|||||||
import checkForUpdate from './common/scripts/check-for-update';
|
import checkForUpdate from './common/scripts/check-for-update';
|
||||||
import MiOS from './mios';
|
import MiOS from './mios';
|
||||||
import { version, codename, lang, locale } from './config';
|
import { version, codename, lang, locale } from './config';
|
||||||
import { builtinThemes, applyTheme, darkTheme } from './theme';
|
import { builtinThemes, applyTheme, blackTheme } from './theme';
|
||||||
import Dialog from './common/views/components/dialog.vue';
|
import Dialog from './common/views/components/dialog.vue';
|
||||||
|
|
||||||
if (localStorage.getItem('theme') == null) {
|
if (localStorage.getItem('theme') == null) {
|
||||||
applyTheme(darkTheme);
|
applyTheme(blackTheme);
|
||||||
}
|
}
|
||||||
|
|
||||||
//#region FontAwesome
|
//#region FontAwesome
|
||||||
|
@@ -172,7 +172,11 @@ export default class MiOS extends EventEmitter {
|
|||||||
callback();
|
callback();
|
||||||
|
|
||||||
// Init service worker
|
// Init service worker
|
||||||
if (this.shouldRegisterSw) this.registerSw();
|
if (this.shouldRegisterSw) {
|
||||||
|
this.getMeta().then(data => {
|
||||||
|
this.registerSw(data.swPublickey);
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// キャッシュがあったとき
|
// キャッシュがあったとき
|
||||||
@@ -302,7 +306,7 @@ export default class MiOS extends EventEmitter {
|
|||||||
* Register service worker
|
* Register service worker
|
||||||
*/
|
*/
|
||||||
@autobind
|
@autobind
|
||||||
private registerSw() {
|
private registerSw(swPublickey) {
|
||||||
// Check whether service worker and push manager supported
|
// Check whether service worker and push manager supported
|
||||||
const isSwSupported =
|
const isSwSupported =
|
||||||
('serviceWorker' in navigator) && ('PushManager' in window);
|
('serviceWorker' in navigator) && ('PushManager' in window);
|
||||||
@@ -328,7 +332,7 @@ export default class MiOS extends EventEmitter {
|
|||||||
|
|
||||||
// A public key your push server will use to send
|
// A public key your push server will use to send
|
||||||
// messages to client apps via a push server.
|
// messages to client apps via a push server.
|
||||||
applicationServerKey: urlBase64ToUint8Array(this.meta.data.swPublickey)
|
applicationServerKey: urlBase64ToUint8Array(swPublickey)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Subscribe push notification
|
// Subscribe push notification
|
||||||
|
@@ -26,7 +26,7 @@ import MkUserLists from './views/pages/user-lists.vue';
|
|||||||
import MkUserList from './views/pages/user-list.vue';
|
import MkUserList from './views/pages/user-list.vue';
|
||||||
import MkReversi from './views/pages/games/reversi.vue';
|
import MkReversi from './views/pages/games/reversi.vue';
|
||||||
import MkTag from './views/pages/tag.vue';
|
import MkTag from './views/pages/tag.vue';
|
||||||
import MkShare from './views/pages/share.vue';
|
import MkShare from '../common/views/pages/share.vue';
|
||||||
import MkFollow from '../common/views/pages/follow.vue';
|
import MkFollow from '../common/views/pages/follow.vue';
|
||||||
import MkNotFound from '../common/views/pages/not-found.vue';
|
import MkNotFound from '../common/views/pages/not-found.vue';
|
||||||
|
|
||||||
|
@@ -135,9 +135,9 @@ export default Vue.extend({
|
|||||||
methods: {
|
methods: {
|
||||||
fetchReplies() {
|
fetchReplies() {
|
||||||
if (this.compact) return;
|
if (this.compact) return;
|
||||||
this.$root.api('notes/replies', {
|
this.$root.api('notes/children', {
|
||||||
noteId: this.appearNote.id,
|
noteId: this.appearNote.id,
|
||||||
limit: 8
|
limit: 30
|
||||||
}).then(replies => {
|
}).then(replies => {
|
||||||
this.replies = replies;
|
this.replies = replies;
|
||||||
});
|
});
|
||||||
|
@@ -115,9 +115,9 @@ export default Vue.extend({
|
|||||||
|
|
||||||
created() {
|
created() {
|
||||||
if (this.detail) {
|
if (this.detail) {
|
||||||
this.$root.api('notes/replies', {
|
this.$root.api('notes/children', {
|
||||||
noteId: this.appearNote.id,
|
noteId: this.appearNote.id,
|
||||||
limit: 8
|
limit: 30
|
||||||
}).then(replies => {
|
}).then(replies => {
|
||||||
this.replies = replies;
|
this.replies = replies;
|
||||||
});
|
});
|
||||||
|
@@ -105,6 +105,7 @@ export default Vue.extend({
|
|||||||
files: [],
|
files: [],
|
||||||
poll: false,
|
poll: false,
|
||||||
pollChoices: [],
|
pollChoices: [],
|
||||||
|
pollMultiple: false,
|
||||||
geo: null,
|
geo: null,
|
||||||
visibility: 'public',
|
visibility: 'public',
|
||||||
visibleUsers: [],
|
visibleUsers: [],
|
||||||
@@ -273,7 +274,9 @@ export default Vue.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
onPollUpdate() {
|
onPollUpdate() {
|
||||||
this.pollChoices = this.$refs.poll.get().choices;
|
const got = this.$refs.poll.get();
|
||||||
|
this.pollChoices = got.choices;
|
||||||
|
this.pollMultiple = got.multiple;
|
||||||
},
|
},
|
||||||
|
|
||||||
upload(file) {
|
upload(file) {
|
||||||
@@ -364,7 +367,7 @@ export default Vue.extend({
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (this.text && this.text != '') {
|
if (this.text && this.text != '') {
|
||||||
const hashtags = parse(this.text).filter(x => x.type == 'hashtag').map(x => x.hashtag);
|
const hashtags = parse(this.text).filter(x => x.node.type === 'hashtag').map(x => x.node.props.hashtag);
|
||||||
const history = JSON.parse(localStorage.getItem('hashtags') || '[]') as string[];
|
const history = JSON.parse(localStorage.getItem('hashtags') || '[]') as string[];
|
||||||
localStorage.setItem('hashtags', JSON.stringify(unique(hashtags.concat(history))));
|
localStorage.setItem('hashtags', JSON.stringify(unique(hashtags.concat(history))));
|
||||||
}
|
}
|
||||||
|
@@ -19,6 +19,7 @@
|
|||||||
<option value="posts-monitor">{{ $t('@.widgets.posts-monitor') }}</option>
|
<option value="posts-monitor">{{ $t('@.widgets.posts-monitor') }}</option>
|
||||||
<option value="version">{{ $t('@.widgets.version') }}</option>
|
<option value="version">{{ $t('@.widgets.version') }}</option>
|
||||||
<option value="server">{{ $t('@.widgets.server') }}</option>
|
<option value="server">{{ $t('@.widgets.server') }}</option>
|
||||||
|
<option value="queue">{{ $t('@.widgets.queue') }}</option>
|
||||||
<option value="memo">{{ $t('@.widgets.memo') }}</option>
|
<option value="memo">{{ $t('@.widgets.memo') }}</option>
|
||||||
<option value="nav">{{ $t('@.widgets.nav') }}</option>
|
<option value="nav">{{ $t('@.widgets.nav') }}</option>
|
||||||
<option value="tips">{{ $t('@.widgets.tips') }}</option>
|
<option value="tips">{{ $t('@.widgets.tips') }}</option>
|
||||||
|
@@ -49,7 +49,7 @@ const defaultDeviceSettings = {
|
|||||||
roundedCorners: true,
|
roundedCorners: true,
|
||||||
reduceMotion: false,
|
reduceMotion: false,
|
||||||
darkmode: true,
|
darkmode: true,
|
||||||
darkTheme: 'dark',
|
darkTheme: 'bb5a8287-a072-4b0a-8ae5-ea2a0d33f4f2',
|
||||||
lightTheme: 'light',
|
lightTheme: 'light',
|
||||||
lineWidth: 1,
|
lineWidth: 1,
|
||||||
fontSize: 0,
|
fontSize: 0,
|
||||||
|
@@ -43,11 +43,11 @@ export const builtinThemes = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
export function applyTheme(theme: Theme, persisted = true) {
|
export function applyTheme(theme: Theme, persisted = true) {
|
||||||
document.documentElement.classList.add('change-theme');
|
document.documentElement.classList.add('changing-theme');
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
document.documentElement.classList.remove('change-theme');
|
document.documentElement.classList.remove('changing-theme');
|
||||||
}, 500);
|
}, 1000);
|
||||||
|
|
||||||
// Deep copy
|
// Deep copy
|
||||||
const _theme = JSON.parse(JSON.stringify(theme));
|
const _theme = JSON.parse(JSON.stringify(theme));
|
||||||
|
@@ -43,6 +43,11 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"share_target": {
|
"share_target": {
|
||||||
"url_template": "share?text=【{title}】%0A{text}%0A{url}"
|
"action": "/share/",
|
||||||
|
"params": {
|
||||||
|
"title": "title",
|
||||||
|
"text": "text",
|
||||||
|
"url": "url"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -20,11 +20,9 @@ html, body
|
|||||||
text-size-adjust 100%
|
text-size-adjust 100%
|
||||||
font-family sans-serif
|
font-family sans-serif
|
||||||
|
|
||||||
html.change-theme
|
html.changing-theme
|
||||||
&, *
|
&, *
|
||||||
transition-property all
|
transition background 1s ease !important
|
||||||
transition-duration 0.5s
|
|
||||||
transition-timing-function ease
|
|
||||||
|
|
||||||
a
|
a
|
||||||
text-decoration none
|
text-decoration none
|
||||||
|
@@ -3,18 +3,37 @@
|
|||||||
|
|
||||||
name: 'Future',
|
name: 'Future',
|
||||||
author: 'syuilo',
|
author: 'syuilo',
|
||||||
|
desc: 'Sci-fi flavored',
|
||||||
|
|
||||||
base: 'dark',
|
base: 'dark',
|
||||||
|
|
||||||
vars: {
|
vars: {
|
||||||
primary: 'rgb(94, 158, 185)',
|
c0: '#0c0c0c',
|
||||||
secondary: 'rgb(22, 24, 30)',
|
c1: 'rgb(255, 105, 78)',
|
||||||
text: 'rgb(214, 218, 224)',
|
c2: 'rgb(99, 197, 210)',
|
||||||
|
c4: 'rgb(253, 254, 214)',
|
||||||
|
c3: 'rgb(204, 254, 253)',
|
||||||
|
primary: '$c1',
|
||||||
|
secondary: '#131313',
|
||||||
|
text: '$c3',
|
||||||
},
|
},
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
renoteGradient: '#0a2d3c',
|
bg: '$c0',
|
||||||
renoteText: '$primary',
|
noteText: '$c4',
|
||||||
quoteBorder: '$primary',
|
noteHeaderAcct: ':alpha<0.65<$c4',
|
||||||
|
noteHeaderInfo: ':alpha<0.5<$c4',
|
||||||
|
subNoteText: ':alpha<0.7<$c4',
|
||||||
|
renoteGradient: 'rgba(0, 0, 0, 0)',
|
||||||
|
renoteText: '$c2',
|
||||||
|
quoteBorder: '$c2',
|
||||||
|
mfmHashtag: '$c1',
|
||||||
|
mfmUrl: '$c2',
|
||||||
|
mfmLink: '$c2',
|
||||||
|
mfmMention: '$c1',
|
||||||
|
mfmMentionForeground: '#fff',
|
||||||
|
notificationIndicator: '$c2',
|
||||||
|
link: '$c2',
|
||||||
|
desktopHeaderBg: '$secondary',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@@ -19,6 +19,8 @@ export type Source = {
|
|||||||
host: string;
|
host: string;
|
||||||
port: number;
|
port: number;
|
||||||
pass: string;
|
pass: string;
|
||||||
|
db?: number;
|
||||||
|
prefix?: string;
|
||||||
};
|
};
|
||||||
elasticsearch: {
|
elasticsearch: {
|
||||||
host: string;
|
host: string;
|
||||||
|
61
src/daemons/queue-stats.ts
Normal file
61
src/daemons/queue-stats.ts
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
import * as Deque from 'double-ended-queue';
|
||||||
|
import Xev from 'xev';
|
||||||
|
import { deliverQueue, inboxQueue } from '../queue';
|
||||||
|
|
||||||
|
const ev = new Xev();
|
||||||
|
|
||||||
|
const interval = 3000;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Report queue stats regularly
|
||||||
|
*/
|
||||||
|
export default function() {
|
||||||
|
const log = new Deque<any>();
|
||||||
|
|
||||||
|
ev.on('requestQueueStatsLog', x => {
|
||||||
|
ev.emit(`queueStatsLog:${x.id}`, log.toArray().slice(0, x.length || 50));
|
||||||
|
});
|
||||||
|
|
||||||
|
let activeDeliverJobs = 0;
|
||||||
|
let activeInboxJobs = 0;
|
||||||
|
|
||||||
|
deliverQueue.on('global:active', () => {
|
||||||
|
activeDeliverJobs++;
|
||||||
|
});
|
||||||
|
|
||||||
|
inboxQueue.on('global:active', () => {
|
||||||
|
activeInboxJobs++;
|
||||||
|
});
|
||||||
|
|
||||||
|
async function tick() {
|
||||||
|
const deliverJobCounts = await deliverQueue.getJobCounts();
|
||||||
|
const inboxJobCounts = await inboxQueue.getJobCounts();
|
||||||
|
|
||||||
|
const stats = {
|
||||||
|
deliver: {
|
||||||
|
activeSincePrevTick: activeDeliverJobs,
|
||||||
|
active: deliverJobCounts.active,
|
||||||
|
waiting: deliverJobCounts.waiting,
|
||||||
|
delayed: deliverJobCounts.delayed
|
||||||
|
},
|
||||||
|
inbox: {
|
||||||
|
activeSincePrevTick: activeInboxJobs,
|
||||||
|
active: inboxJobCounts.active,
|
||||||
|
waiting: inboxJobCounts.waiting,
|
||||||
|
delayed: inboxJobCounts.delayed
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ev.emit('queueStats', stats);
|
||||||
|
|
||||||
|
log.unshift(stats);
|
||||||
|
if (log.length > 200) log.pop();
|
||||||
|
|
||||||
|
activeDeliverJobs = 0;
|
||||||
|
activeInboxJobs = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
tick();
|
||||||
|
|
||||||
|
setInterval(tick, interval);
|
||||||
|
}
|
@@ -5,6 +5,8 @@ export default config.redis ? redis.createClient(
|
|||||||
config.redis.port,
|
config.redis.port,
|
||||||
config.redis.host,
|
config.redis.host,
|
||||||
{
|
{
|
||||||
auth_pass: config.redis.pass
|
auth_pass: config.redis.pass,
|
||||||
|
prefix: config.redis.prefix,
|
||||||
|
db: config.redis.db || 0
|
||||||
}
|
}
|
||||||
) : null;
|
) : null;
|
||||||
|
18
src/index.ts
18
src/index.ts
@@ -16,6 +16,7 @@ import Xev from 'xev';
|
|||||||
import Logger from './services/logger';
|
import Logger from './services/logger';
|
||||||
import serverStats from './daemons/server-stats';
|
import serverStats from './daemons/server-stats';
|
||||||
import notesStats from './daemons/notes-stats';
|
import notesStats from './daemons/notes-stats';
|
||||||
|
import queueStats from './daemons/queue-stats';
|
||||||
import loadConfig from './config/load';
|
import loadConfig from './config/load';
|
||||||
import { Config } from './config/types';
|
import { Config } from './config/types';
|
||||||
import { lessThan } from './prelude/array';
|
import { lessThan } from './prelude/array';
|
||||||
@@ -50,6 +51,7 @@ function main() {
|
|||||||
if (program.daemons) {
|
if (program.daemons) {
|
||||||
serverStats();
|
serverStats();
|
||||||
notesStats();
|
notesStats();
|
||||||
|
queueStats();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,7 +75,7 @@ function greet() {
|
|||||||
console.log(chalk.keyword('orange')(' If you like Misskey, please donate to support development. https://www.patreon.com/syuilo'));
|
console.log(chalk.keyword('orange')(' If you like Misskey, please donate to support development. https://www.patreon.com/syuilo'));
|
||||||
|
|
||||||
console.log('');
|
console.log('');
|
||||||
console.log(chalk`<${os.hostname()} {gray (PID: ${process.pid.toString()})}>`);
|
console.log(chalk`< ${os.hostname()} {gray (PID: ${process.pid.toString()})} >`);
|
||||||
}
|
}
|
||||||
|
|
||||||
bootLogger.info('Welcome to Misskey!');
|
bootLogger.info('Welcome to Misskey!');
|
||||||
@@ -117,9 +119,6 @@ async function masterMain() {
|
|||||||
await spawnWorkers(config.clusterLimit);
|
await spawnWorkers(config.clusterLimit);
|
||||||
}
|
}
|
||||||
|
|
||||||
// start queue
|
|
||||||
require('./queue').default();
|
|
||||||
|
|
||||||
bootLogger.succ(`Now listening on port ${config.port} on ${config.url}`, null, true);
|
bootLogger.succ(`Now listening on port ${config.port} on ${config.url}`, null, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,6 +129,9 @@ async function workerMain() {
|
|||||||
// start server
|
// start server
|
||||||
await require('./server').default();
|
await require('./server').default();
|
||||||
|
|
||||||
|
// start job queue
|
||||||
|
require('./queue').default();
|
||||||
|
|
||||||
if (cluster.isWorker) {
|
if (cluster.isWorker) {
|
||||||
// Send a 'ready' message to parent process
|
// Send a 'ready' message to parent process
|
||||||
process.send('ready');
|
process.send('ready');
|
||||||
@@ -150,13 +152,9 @@ async function queueMain() {
|
|||||||
bootLogger.succ('Misskey initialized');
|
bootLogger.succ('Misskey initialized');
|
||||||
|
|
||||||
// start processor
|
// start processor
|
||||||
const queue = require('./queue').default();
|
require('./queue').default();
|
||||||
|
|
||||||
if (queue) {
|
bootLogger.succ('Queue started', null, true);
|
||||||
bootLogger.succ('Queue started', null, true);
|
|
||||||
} else {
|
|
||||||
bootLogger.error('Queue not available');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const runningNodejsVersion = process.version.slice(1).split('.').map(x => parseInt(x, 10));
|
const runningNodejsVersion = process.version.slice(1).split('.').map(x => parseInt(x, 10));
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
import { parseFragment, DefaultTreeDocumentFragment } from 'parse5';
|
import { parseFragment, DefaultTreeDocumentFragment } from 'parse5';
|
||||||
import { URL } from 'url';
|
import { URL } from 'url';
|
||||||
|
import { urlRegex } from './prelude';
|
||||||
|
|
||||||
export function fromHtml(html: string): string {
|
export function fromHtml(html: string): string {
|
||||||
if (html == null) return null;
|
if (html == null) return null;
|
||||||
@@ -14,7 +15,7 @@ export function fromHtml(html: string): string {
|
|||||||
|
|
||||||
return text.trim();
|
return text.trim();
|
||||||
|
|
||||||
function getText(node: any) {
|
function getText(node: any): string {
|
||||||
if (node.nodeName == '#text') return node.value;
|
if (node.nodeName == '#text') return node.value;
|
||||||
|
|
||||||
if (node.childNodes) {
|
if (node.childNodes) {
|
||||||
@@ -38,10 +39,11 @@ export function fromHtml(html: string): string {
|
|||||||
const txt = getText(node);
|
const txt = getText(node);
|
||||||
const rel = node.attrs.find((x: any) => x.name == 'rel');
|
const rel = node.attrs.find((x: any) => x.name == 'rel');
|
||||||
const href = node.attrs.find((x: any) => x.name == 'href');
|
const href = node.attrs.find((x: any) => x.name == 'href');
|
||||||
|
const isHashtag = rel && rel.value.match('tag') !== null;
|
||||||
|
|
||||||
// ハッシュタグ / hrefがない / txtがURL
|
// ハッシュタグ / hrefがない / txtがURL
|
||||||
if ((rel && rel.value.match('tag') !== null) || !href || href.value == txt) {
|
if (isHashtag || !href || href.value == txt) {
|
||||||
text += txt;
|
text += isHashtag || txt.match(urlRegex) ? txt : `<${txt}>`;
|
||||||
// メンション
|
// メンション
|
||||||
} else if (txt.startsWith('@') && !(rel && rel.value.match(/^me /))) {
|
} else if (txt.startsWith('@') && !(rel && rel.value.match(/^me /))) {
|
||||||
const part = txt.split('@');
|
const part = txt.split('@');
|
||||||
|
File diff suppressed because one or more lines are too long
@@ -1,6 +1,6 @@
|
|||||||
import * as A from '../prelude/array';
|
import * as A from '../prelude/array';
|
||||||
import * as S from '../prelude/string';
|
import * as S from '../prelude/string';
|
||||||
import { MfmForest, MfmTree } from './types';
|
import { MfmForest, MfmTree } from './prelude';
|
||||||
import { createTree, createLeaf } from '../prelude/tree';
|
import { createTree, createLeaf } from '../prelude/tree';
|
||||||
|
|
||||||
function isEmptyTextTree(t: MfmTree): boolean {
|
function isEmptyTextTree(t: MfmTree): boolean {
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import { mfmLanguage } from './language';
|
import { mfmLanguage } from './language';
|
||||||
import { MfmForest } from './types';
|
import { MfmForest } from './prelude';
|
||||||
import { normalize } from './normalize';
|
import { normalize } from './normalize';
|
||||||
|
|
||||||
export function parse(source: string): MfmForest {
|
export function parse(source: string): MfmForest {
|
||||||
|
@@ -35,3 +35,5 @@ export function createLeaf(type: string, props: any): MfmTree {
|
|||||||
export function createTree(type: string, children: MfmForest, props: any): MfmTree {
|
export function createTree(type: string, children: MfmForest, props: any): MfmTree {
|
||||||
return T.createTree({ type, props }, children);
|
return T.createTree({ type, props }, children);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const urlRegex = /^https?:\/\/[\w\/:%#@\$&\?!\(\)\[\]~\.,=\+\-]+/;
|
@@ -2,7 +2,7 @@ import { JSDOM } from 'jsdom';
|
|||||||
import config from '../config';
|
import config from '../config';
|
||||||
import { INote } from '../models/note';
|
import { INote } from '../models/note';
|
||||||
import { intersperse } from '../prelude/array';
|
import { intersperse } from '../prelude/array';
|
||||||
import { MfmForest, MfmTree } from './types';
|
import { MfmForest, MfmTree } from './prelude';
|
||||||
|
|
||||||
export function toHtml(tokens: MfmForest, mentionedRemoteUsers: INote['mentionedRemoteUsers'] = []) {
|
export function toHtml(tokens: MfmForest, mentionedRemoteUsers: INote['mentionedRemoteUsers'] = []) {
|
||||||
if (tokens == null) {
|
if (tokens == null) {
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import * as isSvg from 'is-svg';
|
import isSvg from 'is-svg';
|
||||||
|
|
||||||
export default function(path: string) {
|
export default function(path: string) {
|
||||||
try {
|
try {
|
||||||
|
27
src/misc/convert-host.ts
Normal file
27
src/misc/convert-host.ts
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import config from '../config';
|
||||||
|
import { toUnicode, toASCII } from 'punycode';
|
||||||
|
import { URL } from 'url';
|
||||||
|
|
||||||
|
export function getFullApAccount(username: string, host: string) {
|
||||||
|
return host ? `${username}@${toApHost(host)}` : `${username}@${toApHost(config.host)}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isSelfHost(host: string) {
|
||||||
|
if (host == null) return true;
|
||||||
|
return toApHost(config.host) === toApHost(host);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function extractDbHost(uri: string) {
|
||||||
|
const url = new URL(uri);
|
||||||
|
return toDbHost(url.hostname);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function toDbHost(host: string) {
|
||||||
|
if (host == null) return null;
|
||||||
|
return toUnicode(host.toLowerCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
export function toApHost(host: string) {
|
||||||
|
if (host == null) return null;
|
||||||
|
return toASCII(host.toLowerCase());
|
||||||
|
}
|
79
src/misc/download-text-file.ts
Normal file
79
src/misc/download-text-file.ts
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
import * as tmp from 'tmp';
|
||||||
|
import * as fs from 'fs';
|
||||||
|
import * as util from 'util';
|
||||||
|
import chalk from 'chalk';
|
||||||
|
import * as request from 'request';
|
||||||
|
import Logger from '../services/logger';
|
||||||
|
import config from '../config';
|
||||||
|
|
||||||
|
const logger = new Logger('download-text-file');
|
||||||
|
|
||||||
|
export async function downloadTextFile(url: string): Promise<string> {
|
||||||
|
// Create temp file
|
||||||
|
const [path, cleanup] = await new Promise<[string, any]>((res, rej) => {
|
||||||
|
tmp.file((e, path, fd, cleanup) => {
|
||||||
|
if (e) return rej(e);
|
||||||
|
res([path, cleanup]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
logger.info(`Temp file is ${path}`);
|
||||||
|
|
||||||
|
// write content at URL to temp file
|
||||||
|
await new Promise((res, rej) => {
|
||||||
|
logger.info(`Downloading ${chalk.cyan(url)} ...`);
|
||||||
|
|
||||||
|
const writable = fs.createWriteStream(path);
|
||||||
|
|
||||||
|
writable.on('finish', () => {
|
||||||
|
logger.succ(`Download finished: ${chalk.cyan(url)}`);
|
||||||
|
res();
|
||||||
|
});
|
||||||
|
|
||||||
|
writable.on('error', error => {
|
||||||
|
logger.error(`Download failed: ${chalk.cyan(url)}: ${error}`, {
|
||||||
|
url: url,
|
||||||
|
e: error
|
||||||
|
});
|
||||||
|
rej(error);
|
||||||
|
});
|
||||||
|
|
||||||
|
const requestUrl = new URL(url).pathname.match(/[^\u0021-\u00ff]/) ? encodeURI(url) : url;
|
||||||
|
|
||||||
|
const req = request({
|
||||||
|
url: requestUrl,
|
||||||
|
proxy: config.proxy,
|
||||||
|
timeout: 10 * 1000,
|
||||||
|
headers: {
|
||||||
|
'User-Agent': config.userAgent
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
req.pipe(writable);
|
||||||
|
|
||||||
|
req.on('response', response => {
|
||||||
|
if (response.statusCode !== 200) {
|
||||||
|
logger.error(`Got ${response.statusCode} (${url})`);
|
||||||
|
writable.close();
|
||||||
|
rej(response.statusCode);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
req.on('error', error => {
|
||||||
|
logger.error(`Failed to start download: ${chalk.cyan(url)}: ${error}`, {
|
||||||
|
url: url,
|
||||||
|
e: error
|
||||||
|
});
|
||||||
|
writable.close();
|
||||||
|
rej(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
logger.succ(`Downloaded to: ${path}`);
|
||||||
|
|
||||||
|
const text = await util.promisify(fs.readFile)(path, 'utf8');
|
||||||
|
|
||||||
|
cleanup();
|
||||||
|
|
||||||
|
return text;
|
||||||
|
}
|
1
src/misc/emoji-regex.ts
Normal file
1
src/misc/emoji-regex.ts
Normal file
File diff suppressed because one or more lines are too long
@@ -1,4 +1,4 @@
|
|||||||
import { EmojiNode, MfmForest } from '../mfm/types';
|
import { EmojiNode, MfmForest } from '../mfm/prelude';
|
||||||
import { preorderF } from '../prelude/tree';
|
import { preorderF } from '../prelude/tree';
|
||||||
import { unique } from '../prelude/array';
|
import { unique } from '../prelude/array';
|
||||||
|
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { HashtagNode, MfmForest } from '../mfm/types';
|
import { HashtagNode, MfmForest } from '../mfm/prelude';
|
||||||
import { preorderF } from '../prelude/tree';
|
import { preorderF } from '../prelude/tree';
|
||||||
import { unique } from '../prelude/array';
|
import { unique } from '../prelude/array';
|
||||||
|
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
// test is located in test/extract-mentions
|
// test is located in test/extract-mentions
|
||||||
|
|
||||||
import { MentionNode, MfmForest } from '../mfm/types';
|
import { MentionNode, MfmForest } from '../mfm/prelude';
|
||||||
import { preorderF } from '../prelude/tree';
|
import { preorderF } from '../prelude/tree';
|
||||||
|
|
||||||
export default function(mfmForest: MfmForest): MentionNode['props'][] {
|
export default function(mfmForest: MfmForest): MentionNode['props'][] {
|
||||||
|
@@ -13,6 +13,7 @@ const defaultMeta: any = {
|
|||||||
originalUsersCount: 0
|
originalUsersCount: 0
|
||||||
},
|
},
|
||||||
maxNoteTextLength: 1000,
|
maxNoteTextLength: 1000,
|
||||||
|
enableEmojiReaction: true,
|
||||||
enableTwitterIntegration: false,
|
enableTwitterIntegration: false,
|
||||||
enableGithubIntegration: false,
|
enableGithubIntegration: false,
|
||||||
enableDiscordIntegration: false,
|
enableDiscordIntegration: false,
|
||||||
|
@@ -10,6 +10,7 @@ export default function(reaction: string): string {
|
|||||||
case 'confused': return '😥';
|
case 'confused': return '😥';
|
||||||
case 'rip': return '😇';
|
case 'rip': return '😇';
|
||||||
case 'pudding': return '🍮';
|
case 'pudding': return '🍮';
|
||||||
default: return '';
|
case 'star': return '⭐';
|
||||||
|
default: return reaction;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
61
src/misc/reaction-lib.ts
Normal file
61
src/misc/reaction-lib.ts
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
import Emoji from '../models/emoji';
|
||||||
|
import { emojiRegex } from './emoji-regex';
|
||||||
|
import fetchMeta from './fetch-meta';
|
||||||
|
|
||||||
|
const basic10: Record<string, string> = {
|
||||||
|
'👍': 'like',
|
||||||
|
'❤': 'love', // ここに記述する場合は異体字セレクタを入れない
|
||||||
|
'😆': 'laugh',
|
||||||
|
'🤔': 'hmm',
|
||||||
|
'😮': 'surprise',
|
||||||
|
'🎉': 'congrats',
|
||||||
|
'💢': 'angry',
|
||||||
|
'😥': 'confused',
|
||||||
|
'😇': 'rip',
|
||||||
|
'🍮': 'pudding',
|
||||||
|
};
|
||||||
|
|
||||||
|
export async function getFallbackReaction(): Promise<string> {
|
||||||
|
const meta = await fetchMeta();
|
||||||
|
return meta.useStarForReactionFallback ? 'star' : 'like';
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function toDbReaction(reaction: string, enableEmoji = true): Promise<string> {
|
||||||
|
if (reaction == null) return await getFallbackReaction();
|
||||||
|
|
||||||
|
// 既存の文字列リアクションはそのまま
|
||||||
|
if (Object.values(basic10).includes(reaction)) return reaction;
|
||||||
|
|
||||||
|
if (!enableEmoji) return await getFallbackReaction();
|
||||||
|
|
||||||
|
// Unicode絵文字
|
||||||
|
const match = emojiRegex.exec(reaction);
|
||||||
|
if (match) {
|
||||||
|
// 合字を含む1つの絵文字
|
||||||
|
const unicode = match[0];
|
||||||
|
|
||||||
|
// 異体字セレクタ除去後の絵文字
|
||||||
|
const normalized = unicode.match('\u200d') ? unicode : unicode.replace(/\ufe0f/g, '');
|
||||||
|
|
||||||
|
// Unicodeプリンは寿司化不能とするため文字列化しない
|
||||||
|
if (normalized === '🍮') return normalized;
|
||||||
|
|
||||||
|
// プリン以外の既存のリアクションは文字列化する
|
||||||
|
if (basic10[normalized]) return basic10[normalized];
|
||||||
|
|
||||||
|
// それ以外はUnicodeのまま
|
||||||
|
return normalized;
|
||||||
|
}
|
||||||
|
|
||||||
|
const custom = reaction.match(/:([\w+-]+):/);
|
||||||
|
if (custom) {
|
||||||
|
const emoji = await Emoji.findOne({
|
||||||
|
host: null,
|
||||||
|
name: custom[1],
|
||||||
|
});
|
||||||
|
|
||||||
|
if (emoji) return reaction;
|
||||||
|
}
|
||||||
|
|
||||||
|
return await getFallbackReaction();
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user