Compare commits
163 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
90cfd87f46 | ||
![]() |
5ff89e1538 | ||
![]() |
8b6968c665 | ||
![]() |
6ef1b1b1a2 | ||
![]() |
fc0e1955d7 | ||
![]() |
c3b8123e32 | ||
![]() |
b6ec3f655a | ||
![]() |
e37840d870 | ||
![]() |
85b7eb1fb8 | ||
![]() |
541f5f1314 | ||
![]() |
a3c7901f87 | ||
![]() |
78ef0a9929 | ||
![]() |
b0bb5d8dfc | ||
![]() |
307fc18138 | ||
![]() |
330f2dedf7 | ||
![]() |
c5c074f201 | ||
![]() |
b16e5bd136 | ||
![]() |
e13f778b33 | ||
![]() |
953142115c | ||
![]() |
1eb5578063 | ||
![]() |
9bc07c1a1c | ||
![]() |
cbbdc98744 | ||
![]() |
4229065a69 | ||
![]() |
932436096f | ||
![]() |
d95242cab0 | ||
![]() |
4214a0618e | ||
![]() |
c012f4f880 | ||
![]() |
3e85aad80a | ||
![]() |
648be3005f | ||
![]() |
66165b1935 | ||
![]() |
e9360ac892 | ||
![]() |
1d234e10bd | ||
![]() |
2a9de356db | ||
![]() |
43f3f8a058 | ||
![]() |
4998ba8866 | ||
![]() |
d18291cf0c | ||
![]() |
fe9371f06c | ||
![]() |
05a15afadb | ||
![]() |
93417912bb | ||
![]() |
07a565a61a | ||
![]() |
332b13dfd0 | ||
![]() |
81477ea7ee | ||
![]() |
39e84539cd | ||
![]() |
6496fbf923 | ||
![]() |
de57dd7c97 | ||
![]() |
9985c010bc | ||
![]() |
f7a328d66e | ||
![]() |
50598bcefb | ||
![]() |
9c38e9722a | ||
![]() |
b241967fb9 | ||
![]() |
1f86a6d329 | ||
![]() |
7a6b5b0bfc | ||
![]() |
e406791b7b | ||
![]() |
4ce2f596ee | ||
![]() |
567f71fe61 | ||
![]() |
70bb5879f9 | ||
![]() |
cfd2d84b14 | ||
![]() |
44ab428803 | ||
![]() |
b34b728fbb | ||
![]() |
8ada1725bf | ||
![]() |
873444c3c6 | ||
![]() |
8bdd4fd061 | ||
![]() |
f3b518fb62 | ||
![]() |
626d64631e | ||
![]() |
608fa287c7 | ||
![]() |
a35d01ee0f | ||
![]() |
77c9b90e6d | ||
![]() |
2f8992f98a | ||
![]() |
c8ab0e9d62 | ||
![]() |
072bc2d9fb | ||
![]() |
cc7fec4b9f | ||
![]() |
570931cff8 | ||
![]() |
88ec15d4c7 | ||
![]() |
c23c8ae4c3 | ||
![]() |
92af4401e2 | ||
![]() |
5b0dfa6130 | ||
![]() |
a664173b5b | ||
![]() |
93a889df82 | ||
![]() |
0c1d3e186b | ||
![]() |
e1cf090440 | ||
![]() |
ff81648134 | ||
![]() |
1eed6911f0 | ||
![]() |
5faf9dc2c9 | ||
![]() |
59a32e9352 | ||
![]() |
bf654c6f42 | ||
![]() |
34c82776fc | ||
![]() |
02bde5150e | ||
![]() |
245b08b624 | ||
![]() |
1e58b3daff | ||
![]() |
4f2b4366f2 | ||
![]() |
7a94117d90 | ||
![]() |
121c7542a0 | ||
![]() |
e0433c6b89 | ||
![]() |
c9bf99fa66 | ||
![]() |
795b56f8ab | ||
![]() |
d2edd67cff | ||
![]() |
1ca6014284 | ||
![]() |
7ff8fb027d | ||
![]() |
d672bb4643 | ||
![]() |
4c6c06c80a | ||
![]() |
97b6af62fe | ||
![]() |
f180f02dd1 | ||
![]() |
3dbd48f744 | ||
![]() |
3c99b2fd12 | ||
![]() |
3d2cfd10bc | ||
![]() |
e563798afb | ||
![]() |
f679926b4f | ||
![]() |
ff20045e1d | ||
![]() |
c81ff10d5b | ||
![]() |
a103ae6755 | ||
![]() |
5c44c75c23 | ||
![]() |
3a973aee69 | ||
![]() |
16d59e9988 | ||
![]() |
93ce25db91 | ||
![]() |
c97a523ada | ||
![]() |
488fe2e7bd | ||
![]() |
8da278a279 | ||
![]() |
da69650505 | ||
![]() |
a85f6edd8a | ||
![]() |
d17c6adba4 | ||
![]() |
2671c6b4f2 | ||
![]() |
a81d5786f3 | ||
![]() |
75e2b075e1 | ||
![]() |
533884dcaa | ||
![]() |
7298b41a16 | ||
![]() |
39561e858a | ||
![]() |
96b88ee369 | ||
![]() |
d94e2025be | ||
![]() |
6ba5968861 | ||
![]() |
cea2d621f2 | ||
![]() |
84be4aa91e | ||
![]() |
a943bf3906 | ||
![]() |
42a14508f6 | ||
![]() |
f4cb62db16 | ||
![]() |
4dc4ac2f0c | ||
![]() |
bf9da8458c | ||
![]() |
1832b2e53c | ||
![]() |
17ebaa01f5 | ||
![]() |
c595f68d9d | ||
![]() |
b040ac6373 | ||
![]() |
e94dd8a5e8 | ||
![]() |
e14509574d | ||
![]() |
3a093f8bd7 | ||
![]() |
ebb9a9b64f | ||
![]() |
ef17838c64 | ||
![]() |
11ddbdc58d | ||
![]() |
4e8047275b | ||
![]() |
c19670d611 | ||
![]() |
540bd3630a | ||
![]() |
49f6b3233e | ||
![]() |
0f2d392b4b | ||
![]() |
53fba9b137 | ||
![]() |
24f2183829 | ||
![]() |
61642539b1 | ||
![]() |
1b7454ca77 | ||
![]() |
60d2558ed6 | ||
![]() |
9f5a763c69 | ||
![]() |
0ef31a8bac | ||
![]() |
1a8632e802 | ||
![]() |
c1c955031e | ||
![]() |
75ab146860 | ||
![]() |
c3f9b2dcc3 | ||
![]() |
c9e33f665e |
@@ -79,6 +79,8 @@ redis:
|
||||
host: localhost
|
||||
port: 6379
|
||||
#pass: example-pass
|
||||
#prefix: example-prefix
|
||||
#db: 1
|
||||
|
||||
# ┌─────────────────────────────┐
|
||||
#───┘ Elasticsearch configuration └─────────────────────────────
|
||||
@@ -120,8 +122,8 @@ autoAdmin: true
|
||||
#clusterLimit: 1
|
||||
|
||||
# Job concurrency per worker
|
||||
# deliverJobConcurrency: 128;
|
||||
# inboxJobConcurrency: 16;
|
||||
# deliverJobConcurrency: 128
|
||||
# inboxJobConcurrency: 16
|
||||
|
||||
# IP address family used for outgoing request (ipv4, ipv6 or dual)
|
||||
#outgoingAddressFamily: ipv4
|
||||
@@ -138,3 +140,6 @@ autoAdmin: true
|
||||
#proxySmtp: http://127.0.0.1:3128 # use HTTP/1.1 CONNECT
|
||||
#proxySmtp: socks4://127.0.0.1:1080 # use SOCKS4
|
||||
#proxySmtp: socks5://127.0.0.1:1080 # use SOCKS5
|
||||
|
||||
# Media Proxy
|
||||
#mediaProxy: https://example.com/proxy
|
||||
|
@@ -1 +1 @@
|
||||
v12.9.1
|
||||
v12.11.1
|
||||
|
119
CHANGELOG.md
119
CHANGELOG.md
@@ -1,6 +1,125 @@
|
||||
ChangeLog
|
||||
=========
|
||||
|
||||
11.37.0 (2020/01/07)
|
||||
--------------------
|
||||
### ✨Improvements
|
||||
* AP引用でquoteUrlに対応
|
||||
* トークの既読を連合
|
||||
* 期限切れ/未保存リモートファイルのローカルプロキシ機能
|
||||
* ミュート/ブロックでページングと解除ができるように
|
||||
* Redis prefixにホスト名を使用するように
|
||||
* AP Resolverの長いエラーメッセージをトリムするように
|
||||
* 管理画面でstatsを継続リクエストしないように
|
||||
* 凍結ユーザーのプロファイルなどを表示しないように
|
||||
* クライアントで、thumbanilUrlが提供されていない画像はプレビューしないように
|
||||
* svgでも画像の平均色を計算するように
|
||||
* 画像の平均色を計算するとき、透過部分のある画像では一律で背景を#fff(白)に
|
||||
* Pages: 小数点を丸める関数を追加
|
||||
|
||||
### 🐛Fixes
|
||||
* カスタム絵文字リアクションの絵文字がNoteに添付されないのを修正
|
||||
* リモートプロキシ時にサムネイルのContent-Typeがおかしい問題を修正
|
||||
* /files/ 下のヘッダ設定タイミングを修正
|
||||
* イベントが同じRedisを使用する他のMisskeyインスタンスに飛んでしまう問題を修正
|
||||
* AP inbox Announce の処理の修正
|
||||
* followers, direct投稿の存在がユーザーの投稿一覧に表示されている問題を修正
|
||||
* Stacked bar chart がおかしいのを修正
|
||||
* リストのインポートがエラーが出るとそこで終わってしまう問題を修正
|
||||
* サムネイル/webpublicのファイル形式がjpeg/pngに固定されていたのをファイルを基に送出するように
|
||||
* syslogが使えない問題を修正
|
||||
|
||||
11.36.0 (2019/11/24)
|
||||
--------------------
|
||||
### ✨Improvements
|
||||
* ジョブキューで試行回数等を表示するように
|
||||
* deliverエラー等の同じようなログが複数出てこないように、上でまとめて出すように
|
||||
* deliverエラーのログではキューの詳細情報を格納しないように
|
||||
* inbox/deliverのログに試行回数とキューが作られてからの時間を表示するように
|
||||
* 無駄なAP deliverをしないように
|
||||
* boot: remove setAttribute() calls and translate reload msg
|
||||
|
||||
### 🐛Fixes
|
||||
* メンションの通知が届かない可能性がある問題を修正
|
||||
* ブロックや閉鎖済みインスタンスのステータスが更新されてしまう問題を修正
|
||||
* 「フォロワーを解除」アクティビティを正しく受け取らない問題を修正
|
||||
* inboxのジョブキューが表示されない問題を修正
|
||||
* ローカルにフォロワー限定投稿が流れてくる問題を修正
|
||||
* リモートユーザーのアイコンがサムネイルで表示されない問題を修正
|
||||
* DBとオブジェクトストレージのジョブキューが表示されない問題を修正
|
||||
* エラーが発生したときにサーバーがクラッシュすることがある問題を修正
|
||||
|
||||
11.35.1 (2019/11/05)
|
||||
--------------------
|
||||
### 🐛Fixes
|
||||
* リモートのフォローボタンを押してmisskeyインスタンスを入力したとき正しく動作しない問題を修正
|
||||
* リアクション設定で改行ができない問題を修正
|
||||
* nodeinfoのmetadataを一般的なものに修正
|
||||
|
||||
11.35.0 (2019/11/01)
|
||||
--------------------
|
||||
### ✨Improvements
|
||||
* 一対一でのトークを連合するように
|
||||
* カスタム絵文字をカテゴリ分け出来るように
|
||||
* カスタム絵文字をカテゴリ, 名前でソートするように
|
||||
* 絵文字ピッカーに最近使った絵文字を表示するように
|
||||
* 絵文字ピッカーで最後に使ったページを覚えておくように
|
||||
* 絵文字ピッカーで正方形じゃない絵文字のアスペクト比を保持するように
|
||||
* EscやBackspaceでメディアビューワが閉じれるように
|
||||
|
||||
### 🐛Fixes
|
||||
* AP: リモートアカウントを解決するとき、そのActorにendpointsが無いとTypeErrorになる問題を修正
|
||||
* AP: 新規投稿のMFMをHTMLに変換する際、リモートユーザーへのメンションのリンク先を(できれば)urlに
|
||||
* AP: menionのclassにu-urlを付けるように
|
||||
* AP: Noteの添付ファイルを提示する時に添付順を保持するように
|
||||
* リモートユーザーの更新に失敗することがある問題を修正
|
||||
* ミュートしているユーザーのプロフィールを開くと投稿が表示されない問題を修正
|
||||
* チャートで値が減ったときの記録が正しく行われていなかった問題を修正
|
||||
* カスタム絵文字を登録できない場合がある問題を修正
|
||||
* カスタム絵文字を重複登録できないように
|
||||
* みつけるの微修正
|
||||
* プロフィールで他のユーザーにうつってもfieldsが更新されない問題を修正
|
||||
* 絵文字ピッカーでアニメーション停止オプションが効かないのを修正
|
||||
|
||||
11.34.0 (2019/10/14)
|
||||
--------------------
|
||||
### ✨Improvements
|
||||
* みつけるに連合分を表示するように
|
||||
* リアクションピッカーをカスタマイズできるように
|
||||
* inputで不正な値を入力したときにメッセージを表示するように
|
||||
* ドライブファイルダウンロードURLにdownloadを付けないように
|
||||
* web-pushでProxyを使用するように
|
||||
|
||||
### 🐛Fixes
|
||||
* 投稿本文が合字を含んで8192文字の場合に制限をパスしても投稿できない問題を修正
|
||||
* meta.maxNoteTextLengthをnote.textの最大サイズより大きく設定できる問題を修正
|
||||
* ページ移動等してもメニュー等が閉じずに残ってしまう問題を修正
|
||||
* ページ移動してもメディアビューワーが残ってしまう問題を修正
|
||||
* APに関する問題の修正
|
||||
* オフライン時に大室櫻子が出てこない問題を修正
|
||||
|
||||
11.33.0 (2019/09/27)
|
||||
--------------------
|
||||
### ✨Improvements
|
||||
* 絵文字ピッカーの Unicode 12.0 対応
|
||||
* Adminページのユーザー一覧フィルターに利用可能アカウントを追加
|
||||
* お知らせウィジェットのデザインを変更
|
||||
|
||||
### 🐛Fixes
|
||||
* ユーザーを特定のリストから外すと他のリストからも消える問題を修正
|
||||
* 任意のグループからユーザーを削除すると他のグループからでも削除されちゃうのを修正
|
||||
* 非公開の投稿にリアクションや返信がついたとき通知が正しく行われない問題を修正
|
||||
* AP: featured collectionの取り扱いが間違ってるのを修正
|
||||
* AP: 存在しないユーザーをAPで参照すると404にするべきところ500になってしまうのを修正
|
||||
* AndoridとデスクトップOSのChromeでPWAとしてインストール(ホーム画面に追加)できない問題を修正
|
||||
* /@:user/* でユーザー用のページを返さない問題を修正
|
||||
* インスタンス設定で空Arrayがうまく保存できない問題を修正
|
||||
* 絵文字サジェスト時にそれがサロゲートペアだった場合「1文字」分しかカーソルが移動しない問題を修正
|
||||
* ハッシュタグパースの修正
|
||||
* MFMでKeycap Number Signが表示できない問題を修正
|
||||
* フォローリクエストページのデザインを修正
|
||||
* selectコンポーネントに余分な下線が付く問題を修正
|
||||
|
||||
11.32.0 (2019/09/10)
|
||||
--------------------
|
||||
### ✨Improvements
|
||||
|
@@ -1,4 +1,4 @@
|
||||
FROM node:12.9.1-alpine AS base
|
||||
FROM node:12.11.1-alpine AS base
|
||||
|
||||
ENV NODE_ENV=production
|
||||
|
||||
|
72
README.md
72
README.md
@@ -1,6 +1,6 @@
|
||||
<a href="https://xn--931a.moe/"><img src="https://github.com/syuilo/misskey/blob/develop/assets/ai-orig.png?raw=true" align="right" height="320px"/></a>
|
||||
|
||||
[](https://misskey.io/)
|
||||
[](https://join.misskey.page/)
|
||||
================================================================
|
||||
|
||||
[](https://circleci.com/gh/syuilo/misskey)
|
||||
@@ -10,10 +10,10 @@
|
||||
**A forever evolving, sophisticated microblogging platform.**
|
||||
|
||||
<p align="justify">
|
||||
<a href="https://misskey.io">Misskey</a> is a decentralized microblogging platform born on Earth.
|
||||
<a href="https://join.misskey.page/">Misskey</a> is a decentralized microblogging platform born on Earth.
|
||||
Since it exists within the Fediverse (a universe where various social media platforms are organized),
|
||||
it is mutually linked with other social media platforms.
|
||||
Why don't you take a short break from the hustle and bustle of the city, and dive into a new Internet? <a href="https://joinmisskey.github.io/">Find an instance!</a>
|
||||
Why don't you take a short break from the hustle and bustle of the city, and dive into a new Internet? <a href="https://join.misskey.page/">Find an instance!</a>
|
||||
</p>
|
||||
|
||||
<a href="https://www.patreon.com/syuilo"><img src="https://c5.patreon.com/external/logo/become_a_patron_button@2x.png" alt="Become a Patron!" width="160" /></a>
|
||||
@@ -103,80 +103,88 @@ Please see the [Contribution Guide](./CONTRIBUTING.md).
|
||||
----------------------------------------------------------------
|
||||
<!-- PATREON_START -->
|
||||
<table><tr>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/5888816/36da0f7c15954df0ab13f9abdf227f66/1.jpeg?token-time=2145916800&token-hash=at8QpJXJ8C0zINY_NmoMKv-MhXVoUK-YzTgaJPJzJYU%3D" alt="Hiroshi Seki" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/20010324/b8af4bd31ae34fbf8806cc0e6228e400/1.png?token-time=2145916800&token-hash=iyiocfousNIUwASmatsIDq8EOsmLUdrQNkWyktHlmJg%3D" alt="Nemo" width="100"></td>
|
||||
<td><img src="https://c8.patreon.com/2/200/27956229" alt="Oliver Maximilian Seidel" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/12190916/fb7fa7983c14425f890369535b1506a4/3.png?token-time=2145916800&token-hash=oH_i7gJjNT7Ot6j9JiVwy7ZJIBqACVnzLqlz4YrDAZA%3D" alt="weepjp" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/605366/c9dc408fdcbf412fb183ca5b06235f8d/1.jpeg?token-time=2145916800&token-hash=oaqsjLqOFjWN5I9hm2epOaTXaEtKwQUy5OW-EpAz6-g%3D" alt="Jon Leibowitz" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/19045173/cb91c0f345c24d4ebfd05f19906d5e26/1.png?token-time=2145916800&token-hash=o_zKBytJs_AxHwSYw_5R8eD0eSJe3RoTR3kR3Q0syN0%3D" alt="kiritan" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/24430516/b1964ac5b9f746d2a12ff53dbc9aa40a/1.jpg?token-time=2145916800&token-hash=bmEiMGYpp3bS7hCCbymjGGsHBZM3AXuBOFO3Kro37PU%3D" alt="Eduardo Quiros" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/14215107/1cbe1912c26143919fa0faca16f12ce1/2.png?token-time=2145916800&token-hash=v0KzlXjyiq18u6aSxyy9qIUxSCAx-nnHlO7MzhSA6Mc%3D" alt="Nesakko" width="100"></td>
|
||||
<td><img src="https://c8.patreon.com/2/200/776209" alt="Denshi" width="100"></td>
|
||||
<td><img src="https://c8.patreon.com/2/200/557245" alt="mkatze" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/12913507/f7181eacafe8469a93033d85f5969c29/4.jpe?token-time=2145916800&token-hash=zEyJqVM7u9d8Ri-65fJYSJcWF1jBH1nJ5a3taRzrTmw%3D" alt="Melilot" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/3075183/c2ae575c604e420297f000ccc396e395/1.jpeg?token-time=2145916800&token-hash=O9qmPtpo6wWb0OuvnkEekhk_1WO2MTdytLr7ZgsAr80%3D" alt="Liaizon Wakest" width="100"></td>
|
||||
</tr><tr>
|
||||
<td><a href="https://www.patreon.com/rane_hs">Hiroshi Seki</a></td>
|
||||
<td><a href="https://www.patreon.com/user?u=20010324">Nemo</a></td>
|
||||
<td><a href="https://www.patreon.com/user?u=27956229">Oliver Maximilian Seidel</a></td>
|
||||
<td><a href="https://www.patreon.com/weepjp">weepjp</a></td>
|
||||
<td><a href="https://www.patreon.com/jonleibowitz">Jon Leibowitz</a></td>
|
||||
<td><a href="https://www.patreon.com/user?u=19045173">kiritan</a></td>
|
||||
<td><a href="https://www.patreon.com/user?u=24430516">Eduardo Quiros</a></td>
|
||||
<td><a href="https://www.patreon.com/Nesakko">Nesakko</a></td>
|
||||
<td><a href="https://www.patreon.com/user?u=776209">Denshi</a></td>
|
||||
<td><a href="https://www.patreon.com/user?u=557245">mkatze</a></td>
|
||||
<td><a href="https://www.patreon.com/user?u=12913507">Melilot</a></td>
|
||||
<td><a href="https://www.patreon.com/wakest">Liaizon Wakest</a></td>
|
||||
</tr></table>
|
||||
<table><tr>
|
||||
<td><img src="https://c8.patreon.com/2/200/557245" alt="mkatze" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/23915207/25428766ecd745478e600b3d7f871eb2/1.png?token-time=2145916800&token-hash=urCLLA4KjJZX92Y1CxcBP4d8bVTHGkiaPnQZp-Tqz68%3D" alt="kabo2468y" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/8249688/4aacf36b6b244ab1bc6653591b6640df/2.png?token-time=2145916800&token-hash=1ZEf2w6L34253cZXS_HlVevLEENWS9QqrnxGUAYblPo%3D" alt="AureoleArk" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/5670915/ee175f0bfb6347ffa4ea101a8c097bff/1.jpg?token-time=2145916800&token-hash=mPLM9CA-riFHx-myr3bLZJuH2xBRHA9se5VbHhLIOuA%3D" alt="osapon" width="100"></td>
|
||||
<td><img src="https://c8.patreon.com/2/200/16869916" alt="見当かなみ" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/18899730/6a22797f68254034a854d69ea2445fc8/1.png?token-time=2145916800&token-hash=b_uj57yxo5VzkSOUS7oXE_762dyOTB_oxzbO6lFNG3k%3D" alt="YuzuRyo61" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/5788159/af42076ab3354bb49803cfba65f94bee/1.jpg?token-time=2145916800&token-hash=iSaxp_Yr2-ZiU2YVi9rcpZZj9mj3UvNSMrZr4CU4qtA%3D" alt="mewl hayabusa" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/11357794/923ce94cd8c44ba788ee931907881839/1.png?token-time=2145916800&token-hash=9nEQje_eMvUjq9a7L3uBqW-MQbS-rRMaMgd7UYVoFNM%3D" alt="mydarkstar" width="100"></td>
|
||||
<td><img src="https://c8.patreon.com/2/200/17866454" alt="sikyosyounin" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/5881381/6235ca5d3fb04c8e95ef5b4ff2abcc18/3.png?token-time=2145916800&token-hash=KjfQL8nf3AIf6WqzLshBYAyX44piAqOAZiYXgZS_H6A%3D" alt="YUKIMOCHI" width="100"></td>
|
||||
</tr><tr>
|
||||
<td><a href="https://www.patreon.com/user?u=557245">mkatze</a></td>
|
||||
<td><a href="https://www.patreon.com/user?u=23915207">kabo2468y</a></td>
|
||||
<td><a href="https://www.patreon.com/AureoleArk">AureoleArk</a></td>
|
||||
<td><a href="https://www.patreon.com/osapon">osapon</a></td>
|
||||
<td><a href="https://www.patreon.com/user?u=16869916">見当かなみ</a></td>
|
||||
<td><a href="https://www.patreon.com/Yuzulia">YuzuRyo61</a></td>
|
||||
<td><a href="https://www.patreon.com/hs_sh_net">mewl hayabusa</a></td>
|
||||
<td><a href="https://www.patreon.com/mydarkstar">mydarkstar</a></td>
|
||||
<td><a href="https://www.patreon.com/user?u=17866454">sikyosyounin</a></td>
|
||||
<td><a href="https://www.patreon.com/yukimochi">YUKIMOCHI</a></td>
|
||||
</tr></table>
|
||||
<table><tr>
|
||||
<td><img src="https://c8.patreon.com/2/200/16542964" alt="Takumi Sugita" width="100"></td>
|
||||
<td><img src="https://c8.patreon.com/2/200/17866454" alt="sikyosyounin" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/5881381/6235ca5d3fb04c8e95ef5b4ff2abcc18/3.png?token-time=2145916800&token-hash=KjfQL8nf3AIf6WqzLshBYAyX44piAqOAZiYXgZS_H6A%3D" alt="YUKIMOCHI" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/19356899/496b4681d33b4520bd7688e0fd19c04d/2.jpeg?token-time=2145916800&token-hash=_sTj3dUBOhn9qwiJ7F19Qd-yWWfUqJC_0jG1h0agEqQ%3D" alt="sheeta.s" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/5827393/59893c191dda408f9cabd0f20a3a5627/1.jpeg?token-time=2145916800&token-hash=i9N05vOph-eP1LTLb9_npATjYOpntL0ZsHNaZFSsPmE%3D" alt="motcha" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/13737140/1adf7835017d479280d90fe8d30aade2/1.png?token-time=2145916800&token-hash=0pdle8h5pDZrww0BDOjdz6zO-HudeGTh36a3qi1biVU%3D" alt="Satsuki Yanagi" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/17880724/311738c8a48f4a6b9443c2445a75adde/1.jpe?token-time=2145916800&token-hash=CPxGQhKIlEaa6WUcgbyHixyKEhakiw9RFdOhsIJBQ_o%3D" alt="takimura" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/17195955/be45e5e14c3e48b2bee0456c84e19df4/4.jpe?token-time=2145916800&token-hash=UslrPVM-8TXOe8AapuNiaFYjcIJgPNcU-fKpGbfGJNI%3D" alt="Damillora" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/16900731/619ab87cc08448439222631ebb26802f/1.gif?token-time=2145916800&token-hash=o27K7M02s1z-LkDUEO5Oa7cu-GviRXeOXxryi4o_6VU%3D" alt="Atsuko Tominaga" width="100"></td>
|
||||
</tr><tr>
|
||||
<td><a href="https://www.patreon.com/user?u=16542964">Takumi Sugita</a></td>
|
||||
<td><a href="https://www.patreon.com/user?u=17866454">sikyosyounin</a></td>
|
||||
<td><a href="https://www.patreon.com/yukimochi">YUKIMOCHI</a></td>
|
||||
<td><a href="https://www.patreon.com/user?u=19356899">sheeta.s</a></td>
|
||||
<td><a href="https://www.patreon.com/user?u=5827393">motcha</a></td>
|
||||
<td><a href="https://www.patreon.com/user?u=13737140">Satsuki Yanagi</a></td>
|
||||
<td><a href="https://www.patreon.com/takimura">takimura</a></td>
|
||||
<td><a href="https://www.patreon.com/user?u=16900731">Atsuko Tominaga</a></td>
|
||||
</tr></table>
|
||||
<table><tr>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/4389829/9f709180ac714651a70f74a82f3ffdb9/3.png?token-time=2145916800&token-hash=FTm3WVom4dJ9NwWMU4OpCL_8Yc13WiwEbKrDPyTZTPs%3D" alt="natalie" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/5923936/2a743cbfbff946c2af3f09026047c0da/2.png?token-time=2145916800&token-hash=h6yphW1qnM0n_NOWaf8qtszMRLXEwIxfk5beu4RxdT0%3D" alt="noellabo" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/2384390/5681180e1efb46a8b28e0e8d4c8b9037/1.jpg?token-time=2145916800&token-hash=SJcMy-Q1BcS940-LFUVOMfR7-5SgrzsEQGhYb3yowFk%3D" alt="CG" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/18072312/98e894d960314fa7bc236a72a39488fe/1.jpe?token-time=2145916800&token-hash=qA8j97lIZNc-74AuZ0p4F3ms6sKPeKjtNt2vEuwpsyo%3D" alt="Hekovic" width="100"></td>
|
||||
</tr><tr>
|
||||
<td><a href="https://www.patreon.com/user?u=19356899">sheeta.s</a></td>
|
||||
<td><a href="https://www.patreon.com/user?u=13737140">Satsuki Yanagi</a></td>
|
||||
<td><a href="https://www.patreon.com/takimura">takimura</a></td>
|
||||
<td><a href="https://www.patreon.com/damillora">Damillora</a></td>
|
||||
<td><a href="https://www.patreon.com/user?u=16900731">Atsuko Tominaga</a></td>
|
||||
<td><a href="https://www.patreon.com/user?u=4389829">natalie</a></td>
|
||||
<td><a href="https://www.patreon.com/noellabo">noellabo</a></td>
|
||||
<td><a href="https://www.patreon.com/Corset">CG</a></td>
|
||||
<td><a href="https://www.patreon.com/hekovic">Hekovic</a></td>
|
||||
</tr></table>
|
||||
<table><tr>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/4503830/ccf2cc867ea64de0b524bb2e24b9a1cb/1.jpeg?token-time=2145916800&token-hash=L55UhJ0rcuNAH3w_ryeeGN4hC6taoOixyAhraEi0bzw%3D" alt="dansup" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/619786/32cf01444db24e578cd1982c197f6fc6/1.jpeg?token-time=2145916800&token-hash=d8jBQLMOHD87KtXs5C9fk1o58DMF73pQ-dYH3uZJPBE%3D" alt="Gargron" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/5731881/4b6038e6cda34c04b83a5fcce3806a93/1.png?token-time=2145916800&token-hash=hBayGfOmQH3kRMdNnDe4oCZD_9fsJWSt29xXR3KRMVk%3D" alt="Nokotaro Takeda" width="100"></td>
|
||||
<td><img src="https://c8.patreon.com/2/200/23932002" alt="nenohi" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/12531784/93a45137841849329ba692da92ac7c60/1.jpeg?token-time=2145916800&token-hash=vGe7wXGqmA8Q7m-kDNb6fyGdwk-Dxk4F-ut8ZZu51RM%3D" alt="Takashi Shibuya" width="100"></td>
|
||||
</tr><tr>
|
||||
<td><a href="https://www.patreon.com/user?u=4389829">natalie</a></td>
|
||||
<td><a href="https://www.patreon.com/noellabo">noellabo</a></td>
|
||||
<td><a href="https://www.patreon.com/Corset">CG</a></td>
|
||||
<td><a href="https://www.patreon.com/hekovic">Hekovic</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/takenoko">Nokotaro Takeda</a></td>
|
||||
<td><a href="https://www.patreon.com/user?u=23932002">nenohi</a></td>
|
||||
<td><a href="https://www.patreon.com/user?u=12531784">Takashi Shibuya</a></td>
|
||||
</tr></table>
|
||||
|
||||
**Last updated:** Sat, 07 Sep 2019 13:23:36 UTC
|
||||
**Last updated:** Sun, 05 Jan 2020 05:37:07 UTC
|
||||
<!-- PATREON_END -->
|
||||
|
||||
:four_leaf_clover: Copyright
|
||||
----------------------------------------------------------------
|
||||
> Copyright (c) 2014-2019 syuilo
|
||||
> Copyright (c) 2014-2020 syuilo
|
||||
|
||||
Misskey is open-source software licensed under the [GNU AGPLv3](LICENSE).
|
||||
|
||||
|
BIN
assets/icons/512.png
Normal file
BIN
assets/icons/512.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
91
assets/icons/icon.svg
Normal file
91
assets/icons/icon.svg
Normal file
@@ -0,0 +1,91 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
id="svg8"
|
||||
version="1.1"
|
||||
viewBox="0 0 135.46667 135.46667"
|
||||
height="512"
|
||||
width="512"
|
||||
sodipodi:docname="icon.svg"
|
||||
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
|
||||
inkscape:export-filename="H:\misskey\assets\icons\512.png"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96">
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="965"
|
||||
id="namedview10"
|
||||
showgrid="false"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:bbox-nodes="true"
|
||||
inkscape:snap-page="true"
|
||||
inkscape:zoom="0.921875"
|
||||
inkscape:cx="219.9952"
|
||||
inkscape:cy="361.00053"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg8" />
|
||||
<defs
|
||||
id="defs2" />
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<rect
|
||||
style="opacity:1;fill:#2ba3bc;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.32291675;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal"
|
||||
id="rect828"
|
||||
width="135.46667"
|
||||
height="135.46667"
|
||||
x="1.896631e-16"
|
||||
y="0" />
|
||||
<g
|
||||
transform="matrix(0.57430748,0,0,0.57430748,11.070705,-35.453717)"
|
||||
id="layer1"
|
||||
style="stroke-width:1.74122751;fill:#ffffff;fill-opacity:1">
|
||||
<g
|
||||
transform="matrix(1.096096,0,0,1.096096,-2.960633,-44.023579)"
|
||||
id="g4502"
|
||||
style="stroke-width:1.74122751;fill:#ffffff;fill-opacity:1">
|
||||
<g
|
||||
id="g5125"
|
||||
transform="translate(-1.3333333e-6,-1.3439941e-6)"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke-width:1.74122751">
|
||||
<g
|
||||
aria-label="Mi"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:141.03404236px;line-height:476.69509888px;font-family:'OTADESIGN Rounded';-inkscape-font-specification:'OTADESIGN Rounded';letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.50409585px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
id="text4489"
|
||||
transform="matrix(0.91391326,0,0,0.91391326,7.9719907,17.595761)">
|
||||
<path
|
||||
id="path5210"
|
||||
transform="matrix(0.26412464,0,0,0.26412464,24.988264,136.28626)"
|
||||
d="m 62.474609,76.585938 c -7.47555,0 -14.595784,1.246427 -21.359375,3.738281 C 29.011968,84.595952 19.044417,92.249798 11.212891,103.28516 3.7373405,113.96451 0,125.88934 0,139.06055 v 233.8789 c 0,17.08697 6.0510264,31.85913 18.154297,44.31836 12.459246,12.10327 27.233346,18.15625 44.320312,18.15625 17.442947,0 32.215089,-6.05298 44.318361,-18.15625 12.45925,-12.45923 18.68945,-27.23139 18.68945,-44.31836 V 330.4082 c 0.13441,-9.21122 9.6225,-6.79429 14.41797,0 8.98111,15.55395 28.02226,28.91242 50.19141,28.83594 22.16915,-0.0764 40.58194,-11.03699 50.19336,-28.83594 3.63981,-4.29263 13.89902,-11.60675 14.95117,0 v 42.53125 c 0,17.08697 6.05102,31.85913 18.15429,44.31836 12.45923,12.10327 27.23335,18.15625 44.32032,18.15625 17.44294,0 32.21509,-6.05298 44.31836,-18.15625 12.45923,-12.45923 18.68945,-27.23139 18.68945,-44.31836 v -233.8789 c 0,-13.17121 -3.9146,-25.09604 -11.74609,-35.77539 -7.47557,-11.035362 -17.26588,-18.689208 -29.36914,-22.960941 -7.11956,-2.491854 -14.23982,-3.738281 -21.35938,-3.738281 -19.22286,0 -35.41865,7.476649 -48.58984,22.427734 l -63.40235,74.199218 c -1.42391,1.06791 -6.14093,9.23242 -16.16015,9.23242 -10.01923,0 -14.20109,-8.16451 -15.625,-9.23242 L 110.53125,99.013672 C 97.716024,84.062587 81.697447,76.585938 62.474609,76.585938 Z m 395.060551,0 c -14.9511,-10e-7 -27.76596,5.340179 -38.44532,16.019531 -10.32338,10.323381 -15.48437,22.961011 -15.48437,37.912111 0,14.9511 5.16099,27.76596 15.48437,38.44531 10.67936,10.32338 23.49422,15.48633 38.44532,15.48633 14.95109,0 27.76596,-5.16295 38.44531,-15.48633 C 506.65982,158.28354 512,145.46868 512,130.51758 512,115.56648 506.65982,102.92885 495.98047,92.605469 485.30112,81.926117 472.48625,76.585938 457.53516,76.585938 Z m 0.5332,118.541012 c -14.9511,0 -27.76596,5.34018 -38.44531,16.01953 -10.67936,10.67936 -16.01758,23.49422 -16.01758,38.44532 v 131.89062 c 0,14.9511 5.33822,27.76596 16.01758,38.44531 10.67935,10.32339 23.49421,15.48633 38.44531,15.48633 14.9511,0 27.58873,-5.16294 37.91211,-15.48633 C 506.65982,409.24838 512,396.43352 512,381.48242 V 249.5918 c 0,-14.9511 -5.34018,-27.76596 -16.01953,-38.44532 -10.32338,-10.67935 -22.96101,-16.01953 -37.91211,-16.01953 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:'OTADESIGN Rounded';-inkscape-font-specification:'OTADESIGN Rounded';fill:#ffffff;fill-opacity:1;stroke-width:1.90855289px"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 5.6 KiB |
@@ -1,7 +1,7 @@
|
||||
# Sample nginx configuration for Misskey
|
||||
#
|
||||
# 1. Replace example.tld to your domain
|
||||
# 2. Copy to /etc/nginx/sites-available/ and then symlink from /etc/nginx/sites-ebabled/
|
||||
# 2. Copy to /etc/nginx/sites-available/ and then symlink from /etc/nginx/sites-enabled/
|
||||
# or copy to /etc/nginx/conf.d/
|
||||
|
||||
# For WebSocket
|
||||
|
28
gulpfile.ts
28
gulpfile.ts
@@ -3,28 +3,22 @@
|
||||
*/
|
||||
|
||||
import * as gulp from 'gulp';
|
||||
import * as gutil from 'gulp-util';
|
||||
import * as ts from 'gulp-typescript';
|
||||
const sourcemaps = require('gulp-sourcemaps');
|
||||
import tslint from 'gulp-tslint';
|
||||
const cssnano = require('gulp-cssnano');
|
||||
const stylus = require('gulp-stylus');
|
||||
import * as uglifyComposer from 'gulp-uglify/composer';
|
||||
import * as rimraf from 'rimraf';
|
||||
import chalk from 'chalk';
|
||||
const imagemin = require('gulp-imagemin');
|
||||
import * as chalk from 'chalk';
|
||||
import * as rename from 'gulp-rename';
|
||||
import * as mocha from 'gulp-mocha';
|
||||
import * as replace from 'gulp-replace';
|
||||
const uglifyes = require('uglify-es');
|
||||
const cleanCSS = require('gulp-clean-css');
|
||||
const terser = require('gulp-terser');
|
||||
|
||||
const locales = require('./locales');
|
||||
|
||||
const uglify = uglifyComposer(uglifyes, console);
|
||||
|
||||
const env = process.env.NODE_ENV || 'development';
|
||||
const isProduction = env === 'production';
|
||||
const isDebug = !isProduction;
|
||||
const isDebug = env !== 'production';
|
||||
|
||||
if (isDebug) {
|
||||
console.warn(chalk.yellow.bold('WARNING! NODE_ENV is not "production".'));
|
||||
@@ -54,6 +48,7 @@ gulp.task('build:copy:fonts', () =>
|
||||
gulp.task('build:copy', gulp.parallel('build:copy:views', 'build:copy:fonts', () =>
|
||||
gulp.src([
|
||||
'./src/const.json',
|
||||
'./src/emojilist.json',
|
||||
'./src/server/web/views/**/*',
|
||||
'./src/**/assets/**/*',
|
||||
'!./src/client/app/**/assets/**/*'
|
||||
@@ -96,22 +91,20 @@ gulp.task('cleanall', gulp.parallel('clean', cb =>
|
||||
));
|
||||
|
||||
gulp.task('build:client:script', () => {
|
||||
const client = require('./built/client/meta.json');
|
||||
const client = require('./built/meta.json');
|
||||
return gulp.src(['./src/client/app/boot.js', './src/client/app/safe.js'])
|
||||
.pipe(replace('VERSION', JSON.stringify(client.version)))
|
||||
.pipe(replace('ENV', JSON.stringify(env)))
|
||||
.pipe(replace('LANGS', JSON.stringify(Object.keys(locales))))
|
||||
.pipe(isProduction ? uglify({
|
||||
.pipe(terser({
|
||||
toplevel: true
|
||||
} as any) : gutil.noop())
|
||||
}))
|
||||
.pipe(gulp.dest('./built/client/assets/'));
|
||||
});
|
||||
|
||||
gulp.task('build:client:styles', () =>
|
||||
gulp.src('./src/client/app/init.css')
|
||||
.pipe(isProduction
|
||||
? (cssnano as any)()
|
||||
: gutil.noop())
|
||||
.pipe(cleanCSS())
|
||||
.pipe(gulp.dest('./built/client/assets/'))
|
||||
);
|
||||
|
||||
@@ -121,7 +114,6 @@ gulp.task('copy:client', () =>
|
||||
'./src/client/assets/**/*',
|
||||
'./src/client/app/*/assets/**/*'
|
||||
])
|
||||
.pipe(isProduction ? (imagemin as any)() : gutil.noop())
|
||||
.pipe(rename(path => {
|
||||
path.dirname = path.dirname!.replace('assets', '.');
|
||||
}))
|
||||
@@ -131,7 +123,7 @@ gulp.task('copy:client', () =>
|
||||
gulp.task('doc', () =>
|
||||
gulp.src('./src/docs/**/*.styl')
|
||||
.pipe(stylus())
|
||||
.pipe((cssnano as any)())
|
||||
.pipe(cleanCSS())
|
||||
.pipe(gulp.dest('./built/docs/assets/'))
|
||||
);
|
||||
|
||||
|
8
index.js
8
index.js
@@ -1 +1,7 @@
|
||||
require('./built').default();
|
||||
const fs = require('fs');
|
||||
|
||||
if (fs.existsSync('./built')) {
|
||||
require('./built').default();
|
||||
} else {
|
||||
console.log('Built code is not found. Probably an error occurred during a build or you just forgot to build.');
|
||||
}
|
||||
|
@@ -31,6 +31,7 @@ common:
|
||||
signup: "Registrovat"
|
||||
signout: "Odhlásit"
|
||||
reload-to-apply-the-setting: "Pro uplatnění tohoto nastavení musíte znovu načíst tuto stránku. Chcete ji načíst teď?"
|
||||
fetching-as-ap-object: "Načítám data z Fediversu..."
|
||||
delete-confirm: "Opravdu chcete smazat tento příspěvek?"
|
||||
signin-required: "Přihlašte se, prosím"
|
||||
notification-type: "Typy oznámení"
|
||||
@@ -101,6 +102,9 @@ common:
|
||||
"read:reactions": "Prohlížet reakce"
|
||||
"write:reactions": "Narabět s reakcemi"
|
||||
"write:votes": "Hlasovat"
|
||||
"read:pages": "Zhlédnutí stránky"
|
||||
"write:pages": "Upravit stránky"
|
||||
"write:user-groups": "Upravit uživatelskou skupinu"
|
||||
empty-timeline-info:
|
||||
follow-users-to-make-your-timeline: "Poznámky sledujících se zobrazí ve vaší časové ose"
|
||||
explore: "Najít uživatele"
|
||||
@@ -115,10 +119,12 @@ common:
|
||||
renote: "Renotovat"
|
||||
posting: "Posílání"
|
||||
attach-media-from-local: "Nahrát soubor z vašeho zařízení"
|
||||
attach-media-from-drive: "Přiložit soubory z vašeho Drivu"
|
||||
insert-a-kao: "v('ω')v"
|
||||
create-poll: "Vytvořit anketu"
|
||||
text-remain: "zbývá ještě {} znaků"
|
||||
recent-tags: "Nejnovější"
|
||||
local-only-message: "Publikovat zprávu pouze lokálně"
|
||||
click-to-tagging: "Klikni pro otágování"
|
||||
visibility: "Viditelnost"
|
||||
geolocation-alert: "Vaše zařízení nedalo k dispozici lokaci"
|
||||
@@ -187,6 +193,7 @@ common:
|
||||
other: "Ostatní"
|
||||
appearance: "Vzhled"
|
||||
behavior: "Chování"
|
||||
reactions: "Reakce"
|
||||
fetch-on-scroll: "Nekonečné načítaní posuvem"
|
||||
fetch-on-scroll-desc: "Pokud budete rolovat dolů po stránce, automaticky bude načten další obsah."
|
||||
note-visibility: "Viditelnost příspěvku"
|
||||
@@ -195,6 +202,8 @@ common:
|
||||
web-search-engine: "Webové vyhledávače"
|
||||
web-search-engine-desc: "Například: https://www.google.com/?#q={{query}}"
|
||||
paste: "Vložit"
|
||||
pasted-file-name-desc: "Například: \"rrrr-MM-dd HH-mm-ss [{{number}}]\" → \"2018-03-20 21-30-24 1\""
|
||||
paste-dialog: "Upravit název vloženého souboru"
|
||||
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."
|
||||
i-like-sushi: "Mam radši sushi (než puding)"
|
||||
@@ -280,6 +289,7 @@ common:
|
||||
sync: "Synchronizace"
|
||||
save: "Uložit"
|
||||
saved: "Uloženo"
|
||||
preview: "Náhled"
|
||||
room: "Místnost"
|
||||
_room:
|
||||
graphicsQuality: "Kvalita grafiky"
|
||||
@@ -383,12 +393,14 @@ common/views/components/games/reversi/reversi.game.vue:
|
||||
surrender: "Vzdát se"
|
||||
surrendered: "Vzdaním se"
|
||||
looped-map: "Zacyklená mapa"
|
||||
can-put-everywhere: "Lze položit kamkoliv"
|
||||
common/views/components/games/reversi/reversi.index.vue:
|
||||
title: "Misskey Reversi"
|
||||
sub-title: "Hrajte Reversi s Vašimi kamarády!"
|
||||
invite: "Pozvat"
|
||||
rule: "Jak hrát"
|
||||
mode-invite: "Pozvat"
|
||||
invitations: "Jste pozvaní ke hře!"
|
||||
my-games: "Moje hra"
|
||||
all-games: "Všechny hry"
|
||||
enter-username: "Zadejte své uživatelské jméno"
|
||||
@@ -432,6 +444,7 @@ common/views/components/connect-failed.troubleshooter.vue:
|
||||
no-server: "Nelze se připojit k serveru Misskey"
|
||||
success: "Úspěšně se podařilo spojit s Misskey serverem"
|
||||
flush: "Vyčistit mezipaměť"
|
||||
set-version: "Vyberte verzi"
|
||||
common/views/components/media-banner.vue:
|
||||
sensitive: "Choulostivý obsah"
|
||||
click-to-show: "Klikněte pro zobrazení"
|
||||
@@ -485,6 +498,7 @@ common/views/components/messaging.vue:
|
||||
group: "Skupina"
|
||||
start-with-user: "Zahájit konverzaci s uživatelem"
|
||||
start-with-group: "Zahájit skupinovou konverzaci"
|
||||
select-group: "Vybrat skupinu"
|
||||
common/views/components/messaging-room.vue:
|
||||
new-message: "Máte novou zprávu"
|
||||
common/views/components/messaging-room.form.vue:
|
||||
@@ -556,6 +570,7 @@ common/views/components/poll-editor.vue:
|
||||
deadline-date: "Termín ukončení"
|
||||
deadline-time: "Doba trvání"
|
||||
interval: "Trvání"
|
||||
unit: "Jednotka"
|
||||
second: "Sekunda"
|
||||
minute: "Minuta"
|
||||
hour: "Hodina"
|
||||
@@ -574,6 +589,12 @@ common/views/components/emoji-picker.vue:
|
||||
symbols: "Symboly"
|
||||
flags: "Vlajky"
|
||||
common/views/components/settings/app-type.vue:
|
||||
title: "Režim"
|
||||
intro: "Můžete vybrat zdali chcete použít stolní, nebo mobilní vzhled."
|
||||
choices:
|
||||
auto: "Vybrat vzhled automaticky"
|
||||
desktop: "Vždy použít stolní vzhled"
|
||||
mobile: "Vždy použít mobilní vzhled"
|
||||
info: "Pro aktivování změn musíte znovu načíst stránky."
|
||||
common/views/components/signin.vue:
|
||||
username: "Přezdívka"
|
||||
@@ -585,6 +606,7 @@ common/views/components/signin.vue:
|
||||
signin-with-github: "Přihlásit se pomocí účtu GitHub"
|
||||
signin-with-discord: "Přihlásit se pomocí účtu Discord"
|
||||
login-failed: "Nelze se přihlásit. Zkontrolujte prosím své uživatelské jméno a heslo."
|
||||
enter-2fa-code: "Vložte Váš verifikační kód"
|
||||
common/views/components/signup.vue:
|
||||
invitation-code: "Kód pozvánky"
|
||||
invitation-info: "Pokud máte pozvánku, prosím kontaktujte <a href=\"{}\">administrátora</a>."
|
||||
@@ -606,6 +628,7 @@ common/views/components/signup.vue:
|
||||
password-matched: "OK"
|
||||
password-not-matched: "Neshodují se"
|
||||
recaptcha: "Potvrzení"
|
||||
agree-to: "Souhlasím s {0}."
|
||||
tos: "Podmínky užívání"
|
||||
create: "Vytvořit účet"
|
||||
some-error: "Pokus o vytvoření účtu selhal. Prosím zkuste to znovu."
|
||||
@@ -622,8 +645,10 @@ common/views/components/notification-settings.vue:
|
||||
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é"
|
||||
common/views/components/integration-settings.vue:
|
||||
title: "Integrace"
|
||||
connect: "Připojit"
|
||||
disconnect: "Odpojit"
|
||||
connected-to: "Jste připojen k tomuto GitHub účtu"
|
||||
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."
|
||||
connected-to: "Je připojen k tomuto GitHub účtu"
|
||||
@@ -643,6 +668,8 @@ common/views/components/uploader.vue:
|
||||
common/views/components/visibility-chooser.vue:
|
||||
public: "Veřejné"
|
||||
home: "Domů"
|
||||
home-desc: "Poslat pouze na domovskou časovou osu"
|
||||
specified: "Přímá"
|
||||
specified-desc: "Poslat pouze zmíněným uživatelům"
|
||||
local-public: "Veřejná (pouze místní)"
|
||||
local-public-desc: "Nepublikovat na vzdálených serverech"
|
||||
@@ -727,12 +754,14 @@ common/views/components/user-groups.vue:
|
||||
group-name: "Název skupiny"
|
||||
owned-groups: "Moje skupiny"
|
||||
invites: "Pozvat"
|
||||
accept-invite: "Přidat se"
|
||||
reject-invite: "Odmítnout"
|
||||
common/views/widgets/broadcast.vue:
|
||||
fetching: "Načítám"
|
||||
no-broadcasts: "Žádná nová oznámení"
|
||||
have-a-nice-day: "Přejeme Vám příjemný den!"
|
||||
next: "Další"
|
||||
prev: "Předchozí"
|
||||
common/views/widgets/calendar.vue:
|
||||
year: "Rok {}"
|
||||
month: "{},"
|
||||
@@ -741,6 +770,7 @@ common/views/widgets/calendar.vue:
|
||||
this-month: "Měsíc:"
|
||||
this-year: "Rok:"
|
||||
common/views/widgets/photo-stream.vue:
|
||||
title: "Foto stream"
|
||||
no-photos: "Žádné obrázky"
|
||||
common/views/widgets/posts-monitor.vue:
|
||||
title: "Grafy příspěvků"
|
||||
@@ -756,6 +786,8 @@ common/views/widgets/memo.vue:
|
||||
save: "Uložit"
|
||||
common/views/widgets/slideshow.vue:
|
||||
no-image: "V této složce nebyly nalezeny žádné fotky."
|
||||
common/views/widgets/tips.vue:
|
||||
tips-line23: "Ai-chan kawaii!"
|
||||
common/views/pages/not-found.vue:
|
||||
page-not-found: "Stránka nenalezena"
|
||||
common/views/pages/follow.vue:
|
||||
@@ -827,6 +859,7 @@ desktop/views/components/drive.folder.vue:
|
||||
input-new-folder-name: "Zadejte nové jméno"
|
||||
else-folders: "Ostatní"
|
||||
desktop/views/components/drive.vue:
|
||||
search: "Vyhledávání"
|
||||
empty-drive-description: "Klikněte pravým tlačítkem myši pro otevření menu, nebo sem přetáhněte soubor pro nahrání."
|
||||
empty-folder: "Tato složka je prázdná"
|
||||
unable-to-process: "Operace nemohla být dokončena."
|
||||
@@ -842,10 +875,13 @@ desktop/views/components/drive.vue:
|
||||
url-upload: "Nahrát z URL"
|
||||
desktop/views/components/media-video.vue:
|
||||
click-to-show: "Klikněte pro zobrazení"
|
||||
desktop/views/components/followers.vue:
|
||||
empty: "Vypadá to že Vás nikdo nesleduje."
|
||||
desktop/views/components/game-window.vue:
|
||||
game: "Reversi"
|
||||
desktop/views/components/home.vue:
|
||||
done: "Hotovo"
|
||||
add-widget: "Přidat widget:"
|
||||
add: "Přidat"
|
||||
desktop/views/input-dialog.vue:
|
||||
cancel: "Zrušit"
|
||||
@@ -853,6 +889,7 @@ desktop/views/input-dialog.vue:
|
||||
desktop/views/components/note-detail.vue:
|
||||
private: "Tento příspěvek je soukromý"
|
||||
deleted: "Tento příspěvek byl odstraněn"
|
||||
location: "Lokace"
|
||||
renote: "Renotovat"
|
||||
add-reaction: "Přidat reakci"
|
||||
undo-reaction: "Odebrat reakci"
|
||||
@@ -867,6 +904,8 @@ desktop/views/components/note.vue:
|
||||
desktop/views/components/notes.vue:
|
||||
error: "Načítání selhalo."
|
||||
retry: "Opakovat"
|
||||
desktop/views/components/notifications.vue:
|
||||
empty: "Žádné nové notifikace!"
|
||||
desktop/views/components/post-form.vue:
|
||||
posted: "Odesláno!"
|
||||
replied: "Odpověděno!"
|
||||
@@ -891,10 +930,29 @@ desktop/views/components/renote-form-window.vue:
|
||||
desktop/views/components/settings.2fa.vue:
|
||||
detail: "Více…"
|
||||
url: "https://www.google.cz/landing/2step/"
|
||||
register: "Přidat zařízení"
|
||||
already-registered: "Toto zařízení je již připojené"
|
||||
unregister: "Odebrat"
|
||||
enter-password: "Prosím zadejte heslo"
|
||||
authenticator: "Nejprve musíte nainstalovat Google Authenticator na Vašem zařízení:"
|
||||
howtoinstall: "Jak nainstalovat"
|
||||
token: "Token"
|
||||
scan: "Poté naskenujte QR kód:"
|
||||
done: "Prosím vložte kód zobrazený na Vašem zařízení:"
|
||||
submit: "Uložit"
|
||||
success: "Nastavení uloženo!"
|
||||
failed: "Nepodařilo se spárovat. Prosím zkontrolujte správnost bezpečnostního kódu."
|
||||
totp-header: "Ověřovací aplikace"
|
||||
security-key-header: "Bezpečnostní klíč"
|
||||
last-used: "Naposledy použito:"
|
||||
activate-key: "Klikněte pro aktivaci bezpečnostního klíče"
|
||||
security-key-name: "Název klíče"
|
||||
key-unregistered: "Bezpečnostní klíč byl odstraněn"
|
||||
common/views/components/media-image.vue:
|
||||
sensitive: "NSFW"
|
||||
click-to-show: "Klikněte pro zobrazení"
|
||||
common/views/components/api-settings.vue:
|
||||
caution: "Nepoužívejte tento kód v žádné jiné aplikace nebo ho sdílejte s ostatními (jinak můžete ohrozit svojí bezpečnost)."
|
||||
token: "Token:"
|
||||
enter-password: "Prosím zadejte heslo"
|
||||
console:
|
||||
@@ -976,20 +1034,48 @@ admin/views/index.vue:
|
||||
announcements: "Oznámení"
|
||||
queue: "Fronta úloh"
|
||||
logs: "Logy"
|
||||
db: "Databáze"
|
||||
back-to-misskey: "Zpět na Misskey"
|
||||
admin/views/db.vue:
|
||||
tables: "Tabulky"
|
||||
vacuum: "Vysavač"
|
||||
vacuum-info: "Uklidí databázi. Neohrozí data a sníží využití disku. Tohle se děje automaticky a opakovaně."
|
||||
vacuum-exclamation: "Vysavač může dočasně přetížit databázi a dočasně omezit akce uživatelů."
|
||||
admin/views/dashboard.vue:
|
||||
dashboard: "Kontrolní panel"
|
||||
accounts: "Účty"
|
||||
notes: "Poznámky"
|
||||
drive: "Disk"
|
||||
instances: "Instance"
|
||||
this-instance: "Tato instance"
|
||||
federated: "Z fedivesmíru"
|
||||
admin/views/queue.vue:
|
||||
title: "Ve frontě"
|
||||
remove-all-jobs: "Vyčistit frontu"
|
||||
jobs: "Úkoly"
|
||||
queue: "Ve frontě"
|
||||
domains:
|
||||
inbox: "Obdržené"
|
||||
db: "Databáze"
|
||||
states:
|
||||
active: "V procesu"
|
||||
delayed: "Naplánováno"
|
||||
waiting: "Ve frontě"
|
||||
result-is-truncated: "Zkrácený výsledek"
|
||||
admin/views/logs.vue:
|
||||
logs: "Logy"
|
||||
domain: "Doména"
|
||||
level: "Úroveň"
|
||||
levels:
|
||||
all: "Vše"
|
||||
info: "Informace"
|
||||
success: "Podařilo se"
|
||||
warning: "Varování"
|
||||
error: "Chyba"
|
||||
debug: "Debug"
|
||||
delete-all: "Smazat vše"
|
||||
admin/views/abuse.vue:
|
||||
target: "Cíl"
|
||||
details: "Popis"
|
||||
remove-report: "Odstranit"
|
||||
admin/views/instance.vue:
|
||||
@@ -997,17 +1083,33 @@ admin/views/instance.vue:
|
||||
instance-name: "Název instance"
|
||||
instance-description: "Popis instance"
|
||||
host: "Hostitel"
|
||||
icon-url: "URL ikonky"
|
||||
logo-url: "URL loga"
|
||||
banner-url: "URL pro baner"
|
||||
error-image-url: "URL pro chybový obrázek"
|
||||
languages: "Jazyk této instance"
|
||||
languages-desc: "Můžete nastavit více než jeden, oddělte mezerami."
|
||||
tos-url: "URL pro smluvní podmínky"
|
||||
repository-url: "URL adresa repositáře"
|
||||
feedback-url: "URL pro zpětnou vazbu"
|
||||
maintainer-config: "Informace o administrátorovi"
|
||||
maintainer-name: "Jméno administrátora"
|
||||
maintainer-email: "Kontakt na administrátora"
|
||||
advanced-config: "Další nastavení"
|
||||
object-storage-base-url: "URL"
|
||||
object-storage-prefix: "Předpona"
|
||||
object-storage-endpoint: "Endpoint"
|
||||
object-storage-region: "Region"
|
||||
object-storage-port: "Port"
|
||||
object-storage-access-key: "Přístupový klíč"
|
||||
object-storage-secret-key: "Tajný Klíč (Secret Key)"
|
||||
object-storage-use-ssl: "Použít SSL"
|
||||
object-storage-s3-info-here: "zde"
|
||||
mb: "V megabajtech"
|
||||
recaptcha-config: "nastavení služby reCAPTCHA"
|
||||
recaptcha-info: "reCAPTCHA token je povinný. Můžete jej získat na https://www.google.com/recaptcha/intro/"
|
||||
enable-recaptcha: "povolit reCAPTCHA"
|
||||
recaptcha-secret-key: "Tajný Klíč (Secret Key)"
|
||||
recaptcha-preview: "Náhled"
|
||||
twitter-integration-config: "Nastavení spojení s Twitterem"
|
||||
twitter-integration-info: "The callback URL is set on {url}."
|
||||
@@ -1206,6 +1308,9 @@ desktop/views/widgets/notifications.vue:
|
||||
title: "Oznámení"
|
||||
desktop/views/widgets/polls.vue:
|
||||
title: "Ankety"
|
||||
nothing: "Žádné nové notifikace!"
|
||||
desktop/views/widgets/trends.vue:
|
||||
nothing: "Žádné nové notifikace!"
|
||||
desktop/views/widgets/users.vue:
|
||||
title: "Doporučení uživatelé"
|
||||
mobile/views/components/drive.vue:
|
||||
@@ -1248,6 +1353,8 @@ mobile/views/components/note-sub.vue:
|
||||
admin: "admin"
|
||||
bot: "bot"
|
||||
cat: "kočka"
|
||||
mobile/views/components/notifications.vue:
|
||||
empty: "Žádné nové notifikace!"
|
||||
mobile/views/components/sub-note-content.vue:
|
||||
private: "Tento příspěvek je soukromý"
|
||||
deleted: "Tento příspěvek byl odstraněn"
|
||||
@@ -1291,6 +1398,7 @@ mobile/views/pages/note.vue:
|
||||
mobile/views/pages/games/reversi.vue:
|
||||
reversi: "Reversi"
|
||||
mobile/views/pages/search.vue:
|
||||
search: "Vyhledávání"
|
||||
not-found: "Pro '{q}' nebyly nalezeny žádné příspěvky."
|
||||
mobile/views/pages/selectdrive.vue:
|
||||
select-file: "Vybrat soubory"
|
||||
|
@@ -166,6 +166,7 @@ common:
|
||||
other: "Andet"
|
||||
appearance: "Udseende"
|
||||
behavior: "Opførsel"
|
||||
reactions: "Reaktion"
|
||||
fetch-on-scroll: "Uendeligt scroll"
|
||||
fetch-on-scroll-desc: "Når du scroller ned ad siden, hentes der automatisk nyt indhold ind"
|
||||
note-visibility: "Post synlighed"
|
||||
@@ -257,6 +258,7 @@ common:
|
||||
load-remote-media: "Vis medie-materiale fra en ekstern server"
|
||||
save: "Gem"
|
||||
saved: "Gemt"
|
||||
preview: "Før-visning"
|
||||
search: "Søg"
|
||||
delete: "Slet"
|
||||
loading: "Henter"
|
||||
@@ -1017,6 +1019,8 @@ common/views/components/mute-and-block.vue:
|
||||
word-mute: "Ordfilter"
|
||||
muted-words: "Frafiltrerede ord"
|
||||
muted-words-description: "Mellemrum mellem ord vil blive håndteret, som om der står AND i mellem ordene i søgningen (dvs. alle ord skal være til stede). Linjeskift mellem ord vil føre til, at der søges med OR mellem ordene (dvs. kun det ene af ordene behøver være til stede)."
|
||||
unmute-confirm: "Er du sikker på, at du vil fjerne annulleringen af denne bruger?"
|
||||
unblock-confirm: "Er du sikker på, at du vil fjerne blokeringen af denne bruger?"
|
||||
save: "Gem"
|
||||
common/views/components/password-settings.vue:
|
||||
reset: "Skift adgangskode"
|
||||
@@ -1152,7 +1156,6 @@ admin/views/instance.vue:
|
||||
object-storage-s3-info-here: "Her"
|
||||
object-storage-gcs-info: "Når du bruger Google Cloud Storage som eksternt lager, skal du indstille \"Terminal\" til storage.googleapis.com og forlade feltet \"Region\"."
|
||||
cache-remote-files: "Cache eksterne filer"
|
||||
cache-remote-files-desc: "Hvis du deaktiverer denne indstilling, kan du linke direkte uden at gemme eksterne filer her. Dermed sparer du plads på din egen server. Til gengæld bliver linksene til de eksterne filer usynlige for brugere, som har deaktiveret direkte links, fordi der ikke vises miniature-billeder. Alt i alt anbefales det at aktivere denne indstilling."
|
||||
local-drive-capacity-mb: "Kapacitet på hver lokal brugers drev"
|
||||
remote-drive-capacity-mb: "Kapacitet på hver ekstern brugers drev"
|
||||
mb: "I megabytes (MB)"
|
||||
@@ -1793,6 +1796,8 @@ pages:
|
||||
_mod:
|
||||
arg1: "A"
|
||||
arg2: "B"
|
||||
_round:
|
||||
arg1: "Tal"
|
||||
eq: "A og B er ens"
|
||||
_eq:
|
||||
arg1: "A"
|
||||
|
@@ -251,6 +251,7 @@ common:
|
||||
load-remote-media: "Zeige Inhalte von fremden Servern"
|
||||
save: "Speichern"
|
||||
saved: "Gespeichert"
|
||||
preview: "Vorschau"
|
||||
search: "Suche"
|
||||
delete: "Löschen"
|
||||
loading: "Laden"
|
||||
@@ -743,6 +744,7 @@ common/views/components/drive-settings.vue:
|
||||
in-use: "benutzt"
|
||||
stats: "Statistiken"
|
||||
common/views/components/mute-and-block.vue:
|
||||
unmute-confirm: "Stummschaltung für diesen Nutzer aufheben?"
|
||||
save: "Speichern"
|
||||
desktop/views/components/sub-note-content.vue:
|
||||
private: "Dieser Beitrag ist privat"
|
||||
|
@@ -12,7 +12,7 @@ common:
|
||||
rich-contents: "Post"
|
||||
rich-contents-desc: "Just post your idea, hot topics, and anything you want to share. You may want to decorate your words, attach your favorite pictures, send files, including videos, or create a poll - those are some of the things you can do with Misskey!"
|
||||
reaction: "Reactions"
|
||||
reaction-desc: "The easiest way to express your emotions. Misskey allows you to add various kinds of reactions to other's posts. The emotional experience on Misskey will never be on other SNSs, which are only able to push “likes”."
|
||||
reaction-desc: "The easiest way to express your emotions. Misskey allows you to add various reactions to posts. Other SNSs only have a \"like\" reaction."
|
||||
ui: "Interface"
|
||||
ui-desc: "No single UI can suit everyone. Therefore, Misskey has a highly customizable UI for your tastes. You can make your home original by editing the layout of your timeline, and moving around selectable widgets that you can easily adjust to make this place your own."
|
||||
drive: "Drive"
|
||||
@@ -91,7 +91,7 @@ common:
|
||||
"write:drive": "Work with the Drive"
|
||||
"read:favorites": "View Favorites"
|
||||
"write:favorites": "Work with Favorites"
|
||||
"read:following": "View Follower info"
|
||||
"read:following": "View your Follow info"
|
||||
"write:following": "Work with Follow info"
|
||||
"read:messaging": "View Messaging"
|
||||
"write:messaging": "Work with Messaging"
|
||||
@@ -103,6 +103,12 @@ common:
|
||||
"read:reactions": "View reactions"
|
||||
"write:reactions": "Work with reactions"
|
||||
"write:votes": "Vote"
|
||||
"read:pages": "View Pages"
|
||||
"write:pages": "Update Pages"
|
||||
"read:page-likes": "View Likes on Pages"
|
||||
"write:page-likes": "Update Likes on Pages"
|
||||
"read:user-groups": "View User groups"
|
||||
"write:user-groups": "Edit User groups"
|
||||
empty-timeline-info:
|
||||
follow-users-to-make-your-timeline: "Following users will show their posts in your timeline."
|
||||
explore: "Find users"
|
||||
@@ -194,6 +200,8 @@ common:
|
||||
other: "Other"
|
||||
appearance: "Appearance"
|
||||
behavior: "Behavior"
|
||||
reactions: "Reaction"
|
||||
reactions-description: "Customize Emojis of Reaction picker delimited by line breaks"
|
||||
fetch-on-scroll: "Endless loading on scroll"
|
||||
fetch-on-scroll-desc: "When you scroll down the page, it automatically fetches additional content."
|
||||
note-visibility: "Post visibility"
|
||||
@@ -292,6 +300,7 @@ common:
|
||||
sync: "Sync"
|
||||
save: "Save"
|
||||
saved: "Saved"
|
||||
preview: "Preview"
|
||||
home-profile: "Home profile"
|
||||
deck-profile: "Deck profile"
|
||||
room: "Room"
|
||||
@@ -384,9 +393,11 @@ common/views/pages/explore.vue:
|
||||
popular-users: "Popular users"
|
||||
recently-updated-users: "Recently active users"
|
||||
recently-registered-users: "Users who joined recently"
|
||||
recently-discovered-users: "Recently Discovered Users"
|
||||
popular-tags: "Popular Tags"
|
||||
federated: "From the fediverse"
|
||||
explore: "Explore {host}"
|
||||
explore-fediverse: "Explore Fediverse"
|
||||
users-info: "Currently, {users} users are registered here"
|
||||
common/views/components/reactions-viewer.details.vue:
|
||||
few-users: "{users} reacted with {reaction}"
|
||||
@@ -619,7 +630,9 @@ common/views/components/reaction-picker.vue:
|
||||
choose-reaction: "Send a reaction"
|
||||
input-reaction-placeholder: "or input Emoji"
|
||||
common/views/components/emoji-picker.vue:
|
||||
recent-emoji: "Recently used"
|
||||
custom-emoji: "Custom Emoji"
|
||||
no-category: "Uncategorized"
|
||||
people: "People"
|
||||
animals-and-nature: "Animals & Nature"
|
||||
food-and-drink: "Food & drink"
|
||||
@@ -691,7 +704,7 @@ common/views/components/integration-settings.vue:
|
||||
title: "Service cooperation"
|
||||
connect: "Connect"
|
||||
disconnect: "Disconnect"
|
||||
connected-to: "You are connected to next account"
|
||||
connected-to: "You are connected to this account"
|
||||
common/views/components/github-setting.vue:
|
||||
description: "Once you connect your GitHub account to your Misskey account, you will be able to see information about your GitHub account on your profile, and you will be able to sign-in via GitHub."
|
||||
connected-to: "You are connected to this GitHub account"
|
||||
@@ -815,6 +828,7 @@ common/views/widgets/broadcast.vue:
|
||||
no-broadcasts: "No announcements"
|
||||
have-a-nice-day: "Have a nice day!"
|
||||
next: "Next"
|
||||
prev: "Previous"
|
||||
common/views/widgets/calendar.vue:
|
||||
year: "Year {}"
|
||||
month: "{},"
|
||||
@@ -1102,6 +1116,8 @@ common/views/components/mute-and-block.vue:
|
||||
word-mute: "Word mute"
|
||||
muted-words: "Muted keywords"
|
||||
muted-words-description: "Separating with spaces results in AND specifications, and delimiting with line breaks results in OR specifications"
|
||||
unmute-confirm: "Are you certain that you want to unmute this user?"
|
||||
unblock-confirm: "Are you certain that you want to unblock this user?"
|
||||
save: "Save"
|
||||
common/views/components/password-settings.vue:
|
||||
reset: "Change password"
|
||||
@@ -1263,7 +1279,9 @@ admin/views/instance.vue:
|
||||
object-storage-s3-info-here: "here"
|
||||
object-storage-gcs-info: "If you are going to use Google Cloud Storage as Object Storage, Set the 'Endpoint' as storage.googleapis.com, and keep the 'Region' is blank."
|
||||
cache-remote-files: "Cache remote files"
|
||||
cache-remote-files-desc: "Without this parameter, all remote files are linked to their host server directly. This will be an effective solution to save your server storage, however make remote files invisible to users who set direct-link disabled, since no thumbnail will be generated, increase traffic. It is recommended that this parameter set enabled."
|
||||
cache-remote-files-desc: "If disabled, All remote files going to be linked to their origin server directly. This will be an effective solution to save your server storage. However, Since no thumbnail will be generated, It will make increasing data usage, and also may remote files are invisible to users who set direct-link disabled. It is recommended that this config set enabled or enabling the next config, 'Proxy remote files'."
|
||||
proxy-remote-files: "Proxy remote files"
|
||||
proxy-remote-files-desc: "If enabled, Remote files that not stored locally or deleted by storage overusage will be proxied locally and also thumbnails will be generated."
|
||||
local-drive-capacity-mb: "Volume of Drive per user"
|
||||
remote-drive-capacity-mb: "Volume of Drive per remote user"
|
||||
mb: "In megabytes"
|
||||
@@ -1293,7 +1311,7 @@ admin/views/instance.vue:
|
||||
discord-integration-client-id: "Client ID"
|
||||
discord-integration-client-secret: "Client Secret"
|
||||
proxy-account-config: "Proxy account"
|
||||
proxy-account-info: "Proxy account can follow a remote user to deliver activities if no one in this instance follow him or her. When you add a remote user who is followed by nobody in this instance to your list, in order to get his or her data, proxy account follow him or her instead of your following."
|
||||
proxy-account-info: "A proxy account is an account that acts as a remote follower for users under certain conditions. For example, when a user adds a remote user to the list, the activity will not be delivered to the server if no one is following that user, so the proxy account will follow instead."
|
||||
proxy-account-username: "Proxy account user name"
|
||||
proxy-account-username-desc: "Specify the user name of the account that is used as a proxy."
|
||||
proxy-account-warn: "You must make an account having this username before this action."
|
||||
@@ -1339,9 +1357,9 @@ admin/views/charts.vue:
|
||||
charts:
|
||||
federation-instances: "The number of instances: increase/decrease"
|
||||
federation-instances-total: "Total number of instances"
|
||||
notes: "The number of posts: increase/decrease (Combined)"
|
||||
local-notes: "The number of posts: increase/decrease (Local)"
|
||||
remote-notes: "The number of posts: increase/decrease (Remote)"
|
||||
notes: "Increase, or decrease in the number of posts (Combined)"
|
||||
local-notes: "Increase, or decrease in the number of posts (Local)"
|
||||
remote-notes: "Increase, or decrease in the number of posts (Remote)"
|
||||
notes-total: "Total posts"
|
||||
users: "The number of users: increase/decrease"
|
||||
users-total: "Total users"
|
||||
@@ -1413,6 +1431,7 @@ admin/views/users.vue:
|
||||
state:
|
||||
title: "Sort"
|
||||
all: "All"
|
||||
available: "Available"
|
||||
admin: "Administrator"
|
||||
moderator: "Moderator"
|
||||
adminOrModerator: "Admin/Moderator"
|
||||
@@ -1443,6 +1462,7 @@ admin/views/emoji.vue:
|
||||
title: "Add emoji"
|
||||
name: "Emoji name"
|
||||
name-desc: "You can use the characters a~z 0~9 _"
|
||||
category: "Categories"
|
||||
aliases: "Aliases"
|
||||
aliases-desc: "You can add more than one, separated by spaces."
|
||||
url: "Image URL"
|
||||
@@ -1518,7 +1538,7 @@ admin/views/federation.vue:
|
||||
chart-srcs:
|
||||
requests: "Requests"
|
||||
users: "Increase, or decrease in the number of users"
|
||||
users-total: "Total number of users"
|
||||
users-total: "Users in total"
|
||||
notes: "Increase, or decrease in the number of notes"
|
||||
notes-total: "Total number of notes"
|
||||
ff: "Increase of followers"
|
||||
@@ -1974,6 +1994,9 @@ pages:
|
||||
_mod:
|
||||
arg1: "A"
|
||||
arg2: "B"
|
||||
round: "Round decimal"
|
||||
_round:
|
||||
arg1: "Number"
|
||||
eq: "A and B are equal"
|
||||
_eq:
|
||||
arg1: "A"
|
||||
|
@@ -16,6 +16,8 @@ common:
|
||||
ui: "Interfaz"
|
||||
ui-desc: "No hay ninguna interfaz que le vaya bien a todos. Por eso, Misskey tiene una interfaz altamente personalizable para tus gustos. Puedes hacer tu página principal única editando la interfaz de tu timeline y moviendo varios widgets para conseguir hacer de este lugar uno propio."
|
||||
drive: "Drive"
|
||||
drive-desc: "¿Quieres postear de nuevo la imagen que has posteado antes? Si es así, ¿Quieres separar y ordenar en carpetas los archivos que has subido? La característica Drive incorporada en la base de Misskey es la solución. Compartir archivos es simple."
|
||||
outro: "Aún hay características que solamente están en Misskey, asegúrate de eso con tus propios ojos. Misskey es un servicio de red social distribuida, si no te gusta esta instancia, puedes probar otra instancia. Así que, ¡buena suerte!"
|
||||
application-authorization: "Autorizaciones de la aplicación."
|
||||
close: "Cerrar"
|
||||
do-not-copy-paste: "Por favor no copies código aquí. Tu cuenta puede resultar comprometida."
|
||||
@@ -28,14 +30,26 @@ common:
|
||||
signin: "Iniciar sesión"
|
||||
signup: "¡Regístrate!"
|
||||
signout: "Cerrar sesión"
|
||||
reload-to-apply-the-setting: "Para aplicar esta configuración, hay que recargar la página. ¿Quiere recargar ahora?"
|
||||
fetching-as-ap-object: "Consultar en el fediverso"
|
||||
unfollow-confirm: "¿Quiere dejar de seguir a {name}?"
|
||||
delete-confirm: "¿Seguro que quieres borrar la publicación?"
|
||||
signin-required: "Inicie sesion"
|
||||
notification-type: "Tipo de notificación"
|
||||
notification-types:
|
||||
all: "Todo"
|
||||
pollVote: "Encuestas"
|
||||
follow: "Seguimientos"
|
||||
receiveFollowRequest: "Solicitudes de seguimiento"
|
||||
reply: "Responder"
|
||||
quote: "Citas"
|
||||
renote: "Volver a publicar"
|
||||
mention: "Menciones"
|
||||
reaction: "Reacciones"
|
||||
got-it: "¡Listo!"
|
||||
customization-tips:
|
||||
title: "Consejos de personalización"
|
||||
paragraph: "<p>Se puede personalizar el inicio agregando/quitando widgets, arrastrarlos, soltarlos y ordenarlos.</p><p>Haciendo <strong>Click <strong>derecho</strong></strong>, se puede modificar la muestra de un widget</p><p>Para quitar un widget, arrastre y suelte el widget en el area que dice <strong>\"Papelera\"</strong> en el cabezal</p><p>Para acabar de personalizar, haga click en \"Listo\" arriba a la derecha</p>"
|
||||
gotit: "¡Comprendido!"
|
||||
notification:
|
||||
file-uploaded: "Archivo cargado."
|
||||
@@ -73,20 +87,42 @@ common:
|
||||
"write:account": "Editar información de la cuenta"
|
||||
"read:blocks": "Ver bloques"
|
||||
"write:blocks": "Editar bloques"
|
||||
"read:drive": "Explorar el drive"
|
||||
"write:drive": "Administrar el drive"
|
||||
"read:favorites": "Ver favoritos"
|
||||
"write:favorites": "Editar favoritos"
|
||||
"read:following": "Ver información de seguidor"
|
||||
"write:following": "Seguir/Dejar de seguir"
|
||||
"read:messaging": "Ver conversación"
|
||||
"write:messaging": "Administrar coversación"
|
||||
"read:mutes": "Ver silenciados"
|
||||
"write:mutes": "Administrar silenciados"
|
||||
"write:notes": "Crear y eliminar articulos"
|
||||
"read:notifications": "Ver notificaciones"
|
||||
"write:notifications": "Administrar notificaciones"
|
||||
"read:reactions": "Ver reacciones"
|
||||
"write:reactions": "Administrar reacciones"
|
||||
"write:votes": "Vota"
|
||||
"read:pages": "Ver páginas"
|
||||
"write:pages": "Administrar páginas"
|
||||
"read:page-likes": "Ver páginas que te gustan"
|
||||
"write:page-likes": "Administrar páginas que te gustan"
|
||||
"read:user-groups": "Ver grupos de usuarios"
|
||||
"write:user-groups": "Administrar grupos de usuarios"
|
||||
empty-timeline-info:
|
||||
follow-users-to-make-your-timeline: "Seguir al usuario mostrará sus posts en la linea de tiempo"
|
||||
explore: "Explorar usuarios"
|
||||
post-form:
|
||||
reply: "Responder"
|
||||
renote: "Volver a publicar"
|
||||
attach-media-from-local: "Agregar medios de tu dispositivo"
|
||||
insert-a-kao: "v('ω')v"
|
||||
recent-tags: "Reciente"
|
||||
error: "Error"
|
||||
enter-username: "Ingresar nombre de usuario"
|
||||
add-visible-user: "Agregar usuario"
|
||||
username-prompt: "Ingresar nombre de usuario"
|
||||
enter-file-name: "Editar nombre del archivo"
|
||||
weekday-short:
|
||||
sunday: "domingo"
|
||||
monday: "lunes"
|
||||
@@ -141,15 +177,18 @@ common:
|
||||
mute-and-block: "Silenciar/Bloquear"
|
||||
blocking: "Bloquear"
|
||||
security: "Seguridad"
|
||||
signin: "Historial de ingresos"
|
||||
password: "Contraseña"
|
||||
other: "Otros"
|
||||
appearance: "Diseño"
|
||||
behavior: "Comportamiento"
|
||||
reactions: "Reacciones"
|
||||
fetch-on-scroll-desc: "Cuando te deslizas al final de la página nuevo contenido se carga automáticamente."
|
||||
note-visibility: "Visibilidad de la publicación"
|
||||
default-note-visibility: "Rango de publicación predeterminado"
|
||||
web-search-engine: "Buscador web"
|
||||
web-search-engine-desc: "Ejemplo: https://www.google.com/?#q={{query}}"
|
||||
keep-cw: "Mantener CW"
|
||||
this-setting-is-this-device-only: "Solo para este dispositivo"
|
||||
use-os-default-emojis: "Usar los emoticonos estándar del sistema operativo"
|
||||
line-width: "Grosor de línea"
|
||||
@@ -201,6 +240,7 @@ common:
|
||||
navbar-position-left: "Izquierda"
|
||||
save: "Guardar"
|
||||
saved: "Guardado"
|
||||
preview: "Vista previa"
|
||||
search: "Buscar"
|
||||
delete: "eliminar"
|
||||
loading: "cargando"
|
||||
@@ -868,6 +908,7 @@ desktop/views/components/settings.tags.vue:
|
||||
desktop/views/components/timeline.vue:
|
||||
home: "Inicio"
|
||||
local: "Local"
|
||||
hybrid: "Social"
|
||||
global: "Global"
|
||||
list: "Listas"
|
||||
hashtag: "Hashtags"
|
||||
@@ -1006,6 +1047,8 @@ admin/views/federation.vue:
|
||||
day: "Por día"
|
||||
blocked-hosts: "Bloquear"
|
||||
save: "Guardar"
|
||||
desktop/views/pages/welcome.vue:
|
||||
timeline: "Timeline"
|
||||
desktop/views/pages/selectdrive.vue:
|
||||
cancel: "Cancelar"
|
||||
desktop/views/pages/user-list.users.vue:
|
||||
@@ -1020,6 +1063,11 @@ desktop/views/pages/user/user.photos.vue:
|
||||
desktop/views/pages/user/user.header.vue:
|
||||
month: "lunes"
|
||||
day: "domingo"
|
||||
desktop/views/pages/user/user.timeline.vue:
|
||||
default: "Posts"
|
||||
with-replies: "Posts y respuestas"
|
||||
with-media: "Multimedia"
|
||||
my-posts: "Mis posts"
|
||||
desktop/views/widgets/notifications.vue:
|
||||
title: "Notificaciones"
|
||||
desktop/views/widgets/polls.vue:
|
||||
@@ -1066,6 +1114,7 @@ mobile/views/components/ui.header.vue:
|
||||
welcome-back: "Bienvenido/a de vuelta,"
|
||||
adjective: "-san"
|
||||
mobile/views/components/ui.nav.vue:
|
||||
timeline: "Timeline"
|
||||
notifications: "Notificaciones"
|
||||
follow-requests: "Solicitudes de seguimiento"
|
||||
search: "Buscar"
|
||||
@@ -1080,6 +1129,7 @@ mobile/views/pages/drive.vue:
|
||||
mobile/views/pages/home.vue:
|
||||
home: "Inicio"
|
||||
local: "Local"
|
||||
hybrid: "Social"
|
||||
global: "Global"
|
||||
mobile/views/pages/widgets.vue:
|
||||
dashboard: "Panel de control"
|
||||
@@ -1093,6 +1143,8 @@ mobile/views/pages/search.vue:
|
||||
search: "Buscar"
|
||||
mobile/views/pages/notifications.vue:
|
||||
notifications: "Notificaciones"
|
||||
mobile/views/pages/user.vue:
|
||||
timeline: "Timeline"
|
||||
mobile/views/pages/user/home.vue:
|
||||
activity: "Actividad"
|
||||
mobile/views/pages/user/home.photos.vue:
|
||||
@@ -1100,6 +1152,7 @@ mobile/views/pages/user/home.photos.vue:
|
||||
deck:
|
||||
home: "Inicio"
|
||||
local: "Local"
|
||||
hybrid: "Social"
|
||||
hashtag: "Etiquetas"
|
||||
global: "Global"
|
||||
notifications: "Notificaciones"
|
||||
@@ -1107,6 +1160,7 @@ deck:
|
||||
rename: "Renombrar"
|
||||
deck/deck.user-column.vue:
|
||||
activity: "Actividad"
|
||||
timeline: "Timeline"
|
||||
pages:
|
||||
pin-this-page: "Fijar en el perfil"
|
||||
like: "Me gusta"
|
||||
|
@@ -31,6 +31,7 @@ common:
|
||||
signup: "S'enregistrer"
|
||||
signout: "Se déconnecter"
|
||||
reload-to-apply-the-setting: "Le rechargement de la page est nécessaire pour appliquer ces paramètres. Désirez-vous la recharger maintenant ?"
|
||||
fetching-as-ap-object: "Récupération depuis le fédiverse"
|
||||
unfollow-confirm: "Désirez-vous vous désabonner de {name} ?"
|
||||
delete-confirm: "Supprimer cette publication ?"
|
||||
signin-required: "Veuillez vous connecter"
|
||||
@@ -48,6 +49,7 @@ common:
|
||||
got-it: "J’ai compris !"
|
||||
customization-tips:
|
||||
title: "Conseils de personnalisation"
|
||||
paragraph: "<p>La personnalisation de la page d'accueil vous permet d'ajouter/supprimer, glisser-déposer et réarranger les widgets.</p><p>Vous pouvez changer l'apparence de certain widget avec le <strong><strong>clic</strong>droit</strong>.</p><p>Pour supprimer un widget, faites glisser le widget sur <strong>la zone \"Corbeille\"</strong> dans l'en-tête.</p><p>Pour terminer la personnalisation, cliquez sur \"Terminé\" en haut à droite.</p>"
|
||||
gotit: "Compris !"
|
||||
notification:
|
||||
file-uploaded: "Le fichier a été téléversé !"
|
||||
@@ -90,15 +92,23 @@ common:
|
||||
"read:favorites": "Afficher les favoris"
|
||||
"write:favorites": "Écrire des favoris"
|
||||
"read:following": "Voir les informations de l'abonné"
|
||||
"write:following": "Suivre/Ne plus suivre"
|
||||
"read:messaging": "Lire les conversations"
|
||||
"write:messaging": "Utiliser la messagerie"
|
||||
"read:mutes": "Voir les comptes masqués"
|
||||
"write:mutes": "Gérer les comptes muets"
|
||||
"write:notes": "Créer ou supprimer des publications"
|
||||
"read:notifications": "Afficher les notifications"
|
||||
"write:notifications": "Gérer vos notifications"
|
||||
"read:reactions": "Lire les réactions"
|
||||
"write:reactions": "Gérer vos réactions"
|
||||
"write:votes": "Vote"
|
||||
"read:pages": "Afficher la page"
|
||||
"write:pages": "Mettre à jour les Pages"
|
||||
"read:page-likes": "Lire les favoris sur les Pages"
|
||||
"write:page-likes": "Mettre à jour les favoris sur les Pages"
|
||||
"read:user-groups": "Voir les groupes d'utilisateur·rice·s"
|
||||
"write:user-groups": "Éditer les groupes des utilisateur·rice·s"
|
||||
empty-timeline-info:
|
||||
follow-users-to-make-your-timeline: "Les utilisateur·rice·s suivant·e·s afficheront leurs publications sur votre fil."
|
||||
explore: "Trouver des utilisateur·rice·s"
|
||||
@@ -109,6 +119,7 @@ common:
|
||||
quote-placeholder: "Citer cette note …"
|
||||
option-quote-placeholder: "Citer ce billet ... (Facultatif)"
|
||||
quote-attached: "Cité"
|
||||
quote-question: "Souhaitez-vous ajoutez une citation ?"
|
||||
submit: "Publication"
|
||||
reply: "Répondre"
|
||||
renote: "Republier"
|
||||
@@ -125,6 +136,7 @@ common:
|
||||
geolocation-alert: "Votre appareil ne prend pas en charge les services de localisation"
|
||||
error: "Erreur"
|
||||
enter-username: "Saisir un nom d'utilisateur"
|
||||
specified-recipient: "Correspondant·e"
|
||||
add-visible-user: "Ajouter un utilisateur"
|
||||
cw-placeholder: "Commenter le contenu (optionnel)"
|
||||
username-prompt: "Saisir un nom d'utilisateur"
|
||||
@@ -188,6 +200,8 @@ common:
|
||||
other: "Avancé"
|
||||
appearance: "Apparence"
|
||||
behavior: "Comportement"
|
||||
reactions: "Réaction"
|
||||
reactions-description: "Personnaliser les émojis à afficher dans le sélecteur de réactions, délimités par les sauts de ligne."
|
||||
fetch-on-scroll: "Chargement automatique lors du défilement"
|
||||
fetch-on-scroll-desc: "Chargement automatique du contenu lors du défilement de la page."
|
||||
note-visibility: "Visibilité de la publication"
|
||||
@@ -196,7 +210,9 @@ common:
|
||||
web-search-engine: "Moteur de recherche Web"
|
||||
web-search-engine-desc: "Exemple : https://www.google.com/?#q={{query}}"
|
||||
paste: "Coller"
|
||||
pasted-file-name: "Modèle de nom de fichier collé"
|
||||
pasted-file-name-desc: "Exemple : \"yyyy-MM-dd HH-mm-ss [{{number}}]\" → \"2018-03-20 21-30-24 1\""
|
||||
paste-dialog: "Modifier le nom du fichier collé"
|
||||
keep-cw: "Maintenir l'avertissement de contenu"
|
||||
keep-cw-desc: "Lorsque vous répondez à un message, le même avertissement de contenu est reprit par défaut dans la réponse, le même que celui qui a été défini dans le message original."
|
||||
i-like-sushi: "Je préfère les sushis plutôt que le pudding"
|
||||
@@ -204,6 +220,7 @@ common:
|
||||
use-avatar-reversi-stones: "Utiliser l’avatar comme pion dans Reversi"
|
||||
disable-animated-mfm: "Désactiver les textes animés dans les publications"
|
||||
disable-showing-animated-images: "Désactiver l'animation des images"
|
||||
enable-quick-notification-view: "Activer l'affichage rapide des notifications"
|
||||
suggest-recent-hashtags: "Afficher les hashtags populaires dans le champs de saisie"
|
||||
always-show-nsfw: "Toujours afficher les contenus sensibles"
|
||||
always-mark-nsfw: "Toujours marquer les notes ayant des médias comme sensibles"
|
||||
@@ -282,6 +299,7 @@ common:
|
||||
sync: "Synchroniser"
|
||||
save: "Enregistrer"
|
||||
saved: "enregistré"
|
||||
preview: "Prévisualisation"
|
||||
home-profile: "Profil principal"
|
||||
deck-profile: "Profil deck"
|
||||
room: "Pièce"
|
||||
@@ -374,9 +392,11 @@ common/views/pages/explore.vue:
|
||||
popular-users: "Utilisateur·rice·s populaires"
|
||||
recently-updated-users: "Utilisateur·rice·s actif·ve·s récemment"
|
||||
recently-registered-users: "Les nouveaux inscrits"
|
||||
recently-discovered-users: "Utilisateurs récemment découverts"
|
||||
popular-tags: "Mots-clés populaires"
|
||||
federated: "Du Fédiverse"
|
||||
explore: "Explorer {host}"
|
||||
explore-fediverse: "Explorer le Fédiverse"
|
||||
users-info: "Actuellement, {users} utilisateur·rice·s se sont inscrit ici"
|
||||
common/views/components/reactions-viewer.details.vue:
|
||||
few-users: "{users} ont réagit avec {reaction}"
|
||||
@@ -546,6 +566,7 @@ common/views/components/note-menu.vue:
|
||||
delete: "Supprimer"
|
||||
delete-confirm: "Supprimer cette publication ?"
|
||||
delete-and-edit: "Supprimer et réécrire"
|
||||
delete-and-edit-confirm: "Êtes-vous sûr de vouloir effacer cette note et la modifier ? Vous perdrez toutes les réactions, renotes et réponses."
|
||||
remote: "Afficher la note originale"
|
||||
pin-limit-exceeded: "Vous ne pouvez plus épingler davantage de publications."
|
||||
common/views/components/user-menu.vue:
|
||||
@@ -569,6 +590,7 @@ common/views/components/user-menu.vue:
|
||||
suspend: "Suspendre"
|
||||
unsuspend: "Ne plus suspendre"
|
||||
suspend-confirm: "Êtes-vous surs de vouloir suspendre cet·te utilisateur·rice ?"
|
||||
unsuspend-confirm: "Êtes-vous sûr de vouloir débloquer cet utilisateur ?"
|
||||
common/views/components/poll.vue:
|
||||
vote-to: "Voter pour '{}'"
|
||||
vote-count: "{} votes"
|
||||
@@ -591,6 +613,7 @@ common/views/components/poll-editor.vue:
|
||||
expiration: "Valide jusqu'à"
|
||||
infinite: "Illimité"
|
||||
at: "Choisir une date et une durée"
|
||||
after: "Choisir la durée"
|
||||
no-more: "Vous ne pouvez pas en ajouter davantage"
|
||||
deadline-date: "Date d’échéance"
|
||||
deadline-time: "Durée"
|
||||
@@ -604,7 +627,9 @@ common/views/components/reaction-picker.vue:
|
||||
choose-reaction: "Envoyer une réaction"
|
||||
input-reaction-placeholder: "ou insérez un émoji"
|
||||
common/views/components/emoji-picker.vue:
|
||||
recent-emoji: "Utilisés récemment"
|
||||
custom-emoji: "Émoji personnalisé"
|
||||
no-category: "Sans catégorie"
|
||||
people: "Personnes"
|
||||
animals-and-nature: "Animaux et nature"
|
||||
food-and-drink: "Nourriture et boisson"
|
||||
@@ -800,6 +825,7 @@ common/views/widgets/broadcast.vue:
|
||||
no-broadcasts: "Aucune annonce"
|
||||
have-a-nice-day: "Passez une bonne journée !"
|
||||
next: "Suivant"
|
||||
prev: "Précédent"
|
||||
common/views/widgets/calendar.vue:
|
||||
year: "Année {}"
|
||||
month: "{},"
|
||||
@@ -844,6 +870,7 @@ common/views/widgets/tips.vue:
|
||||
tips-line19: "Plusieurs fenêtres peuvent être détachées en dehors du navigateur."
|
||||
tips-line20: "Pourcentage sur le widget calendrier qui indique le pourcentage de temps passé"
|
||||
tips-line21: "Vous pouvez aussi utiliser l'API pour développer des Bots."
|
||||
tips-line23: "Ai-chan kawaii!"
|
||||
tips-line24: "Misskey est fonctionnel depuis 2014"
|
||||
tips-line25: "Vous pouvez recevoir les notifications de Misskey dans un navigateur web compatible"
|
||||
common/views/pages/not-found.vue:
|
||||
@@ -1042,6 +1069,7 @@ desktop/views/components/settings.2fa.vue:
|
||||
info: "À partir de maintenant, à chaque fois que vous vous connectez entrez votre mot de passe ainsi que le jeton généré sur votre appareil."
|
||||
totp-header: "Application d'authentification"
|
||||
security-key-header: "Clé de sécurité"
|
||||
security-key: "Pour plus de sécurité, vous pouvez vous connecter à votre compte à l'aide d'une clé de sécurité matérielle qui prend en charge FIDO2. Lorsque vous vous connecterez, vous aurez besoin de la clé de sécurité enregistrée ou d'une application d'authentification avec vous."
|
||||
last-used: "Dernière utilisation :"
|
||||
activate-key: "Cliquez pour activer la clé de sécurité"
|
||||
security-key-name: "Nom de la clé"
|
||||
@@ -1084,6 +1112,8 @@ common/views/components/mute-and-block.vue:
|
||||
word-mute: "Filtre de mots"
|
||||
muted-words: "Mots masqués"
|
||||
muted-words-description: "Description des mots mis en sourdine"
|
||||
unmute-confirm: "Ne plus masquer cet utilisateur ?"
|
||||
unblock-confirm: "Débloquer cet utilisateur ?"
|
||||
save: "Enregistrer"
|
||||
common/views/components/password-settings.vue:
|
||||
reset: "Modifier le mot de passe"
|
||||
@@ -1165,6 +1195,8 @@ admin/views/index.vue:
|
||||
back-to-misskey: "Retour vers Misskey"
|
||||
admin/views/db.vue:
|
||||
tables: "Tables"
|
||||
vacuum: "Vacuum"
|
||||
vacuum-info: "Range la base de données. Conserve les données intactes et réduit l'utilisation du disque. Cela se fait généralement automatiquement et périodiquement."
|
||||
admin/views/dashboard.vue:
|
||||
dashboard: "Tableau de bord"
|
||||
accounts: "Comptes"
|
||||
@@ -1267,6 +1299,7 @@ admin/views/instance.vue:
|
||||
discord-integration-client-id: "ID client"
|
||||
discord-integration-client-secret: "Secret client"
|
||||
proxy-account-config: "Compte proxy"
|
||||
proxy-account-info: "Un compte proxy se comporte, dans certaines conditions, comme un·e abonné·e distant pour les utilisateurs d'autres instances.\nExemple : quand un·e utilisateur·rice distant·e est ajouté·e à une liste, ses publications ne serait pas visibles sur l'instance si personne ne le·la suit. Le compte proxy va donc le·la suivre pour que ses publications soient acheminées."
|
||||
proxy-account-username: "Nom d’utilisateur du compte proxy"
|
||||
proxy-account-username-desc: "Spécifiez le nom d’utilisateur du compte utilisé comme proxy."
|
||||
proxy-account-warn: "Avant d’entamer cette action, vous devez au préalable avoir créé un compte avec ce nom d’utilisateur."
|
||||
@@ -1348,6 +1381,7 @@ admin/views/drive.vue:
|
||||
marked-as-sensitive: "Marqué comme sensible"
|
||||
unmarked-as-sensitive: "Marqué comme non sensible"
|
||||
clean-remote-files: "Nettoyer le cache des fichiers distants"
|
||||
clean-remote-files-are-you-sure: "Êtes-vous sûr de vouloir effacer tout les fichiers distants mis en cache ?"
|
||||
clean-up: "Nettoyage"
|
||||
admin/views/users.vue:
|
||||
operation: "Actions"
|
||||
@@ -1383,6 +1417,7 @@ admin/views/users.vue:
|
||||
state:
|
||||
title: "État"
|
||||
all: "Tout"
|
||||
available: "Disponible"
|
||||
admin: "Admin"
|
||||
moderator: "Modérateur"
|
||||
adminOrModerator: "Administrateur/Modérateur"
|
||||
@@ -1413,6 +1448,7 @@ admin/views/emoji.vue:
|
||||
title: "Ajouter un émoji"
|
||||
name: "Nom de l’émoji"
|
||||
name-desc: "Vous pouvez utiliser les caractères a~z 0~9 _"
|
||||
category: "Catégories"
|
||||
aliases: "Aliases"
|
||||
aliases-desc: "Vous pouvez définir plus d’un, séparés par des espaces."
|
||||
url: "URL de l’image"
|
||||
@@ -1485,6 +1521,7 @@ admin/views/federation.vue:
|
||||
notes: "Augmentation/diminution du nombre des notes"
|
||||
notes-total: "Nombre total des notes"
|
||||
ff: "Augmentation des abonné·e·s"
|
||||
ff-total: "Nombre total d'abonnements"
|
||||
drive-usage: "Augmentation et diminution de la capacité stockage"
|
||||
drive-usage-total: "Utilisation totale du stockage"
|
||||
drive-files-total: "Nombre total des fichiers sur le Drive"
|
||||
@@ -1878,9 +1915,11 @@ pages:
|
||||
value: "Valeur"
|
||||
fn: "Fonction"
|
||||
text: "Actions texte"
|
||||
convert: "Convertir"
|
||||
list: "Listes"
|
||||
blocks:
|
||||
text: "Texte"
|
||||
multiLineText: "Texte (Multi-lignes)"
|
||||
textList: "Liste de texte"
|
||||
strLen: "Longueur du texte"
|
||||
_strLen:
|
||||
@@ -1888,6 +1927,8 @@ pages:
|
||||
strPick: "Extraire un caractère"
|
||||
_strPick:
|
||||
arg1: "Texte"
|
||||
arg2: "Position du joueur"
|
||||
strReplace: "Remplacement de texte"
|
||||
_strReplace:
|
||||
arg1: "Texte"
|
||||
arg2: "Avant le remplacement"
|
||||
@@ -1917,6 +1958,8 @@ pages:
|
||||
_mod:
|
||||
arg1: "A"
|
||||
arg2: "B"
|
||||
_round:
|
||||
arg1: "Numérique"
|
||||
eq: "A et B sont équivalents"
|
||||
_eq:
|
||||
arg1: "A"
|
||||
@@ -1949,6 +1992,7 @@ pages:
|
||||
_gtEq:
|
||||
arg1: "A"
|
||||
arg2: "B"
|
||||
if: "Branche"
|
||||
_if:
|
||||
arg1: "Si"
|
||||
arg2: "donc"
|
||||
@@ -1966,6 +2010,7 @@ pages:
|
||||
randomPick: "Choisir aléatoirement depuis la liste"
|
||||
_randomPick:
|
||||
arg1: "Listes"
|
||||
dailyRandom: "Aléatoire (Quotidien pour chaque utilisateur)"
|
||||
_dailyRandom:
|
||||
arg1: "Probabilité"
|
||||
_dailyRannum:
|
||||
@@ -1973,19 +2018,27 @@ pages:
|
||||
arg2: "Maximum"
|
||||
_dailyRandomPick:
|
||||
arg1: "Listes"
|
||||
seedRandom: "Aléatoire (graine)"
|
||||
_seedRandom:
|
||||
arg1: "Graine"
|
||||
arg2: "Probabilité"
|
||||
seedRannum: "Nombre aléatoire (Graine)"
|
||||
_seedRannum:
|
||||
arg1: "Graine"
|
||||
arg2: "Min"
|
||||
arg3: "Max"
|
||||
seedRandomPick: "Sélection aléatoire dans une liste (Graine)"
|
||||
_seedRandomPick:
|
||||
arg1: "Graine"
|
||||
arg2: "Listes"
|
||||
DRPWPM: "Sélection aléatoire à partir d'une liste pondérée (mise à jour quotidienne par utilisateur)"
|
||||
_DRPWPM:
|
||||
arg1: "Liste de texte"
|
||||
pick: "Sélectionner dans la liste"
|
||||
_pick:
|
||||
arg1: "Listes"
|
||||
arg2: "Position"
|
||||
listLen: "Longueur de la liste"
|
||||
_listLen:
|
||||
arg1: "Listes"
|
||||
number: "Numérique"
|
||||
@@ -1995,12 +2048,14 @@ pages:
|
||||
numberToString: "Chiffres en chaîne"
|
||||
_numberToString:
|
||||
arg1: "Numérique"
|
||||
splitStrByLine: "Séparer le texte par lignes"
|
||||
_splitStrByLine:
|
||||
arg1: "Texte"
|
||||
ref: "Variables"
|
||||
fn: "Fonction"
|
||||
_fn:
|
||||
slots: "Emplacement"
|
||||
slots-info: "Veuillez délimiter chaque emplacement par un saut de ligne"
|
||||
arg1: "Sortie"
|
||||
for: "Répéter"
|
||||
_for:
|
||||
@@ -2016,10 +2071,12 @@ pages:
|
||||
emptySlot: "Slot vide"
|
||||
enviromentVariables: "Variables d'environnement"
|
||||
pageVariables: "Élément de page"
|
||||
argVariables: "Entrée vide"
|
||||
room:
|
||||
add-furniture: "Placer des meubles"
|
||||
translate: "Déplacer"
|
||||
rotate: "Tourner"
|
||||
exit: "Retour"
|
||||
remove: "Enlever"
|
||||
save: "Enregistrer"
|
||||
saved: "enregistré"
|
||||
@@ -2045,6 +2102,7 @@ room:
|
||||
plant2: "Plante d’intérieur 2"
|
||||
eraser: "Gomme"
|
||||
pencil: "Crayon"
|
||||
pudding: "Pudding"
|
||||
cardboard-box: "Boîte en carton"
|
||||
cardboard-box2: "Boîte en carton 2"
|
||||
cardboard-box3: "Boîte en carton 3"
|
||||
@@ -2059,6 +2117,7 @@ room:
|
||||
monitor: "Écran"
|
||||
keyboard: "Clavier"
|
||||
carpet-stripe: "Tapis (zébré)"
|
||||
mat: "Tapis"
|
||||
color-box: "Étagère"
|
||||
wall-clock: "Horloge murale"
|
||||
photoframe: "Cadre photo"
|
||||
|
@@ -107,6 +107,12 @@ common:
|
||||
"read:reactions": "リアクションを見る"
|
||||
"write:reactions": "リアクションを操作する"
|
||||
"write:votes": "投票する"
|
||||
"read:pages": "ページを見る"
|
||||
"write:pages": "ページを操作する"
|
||||
"read:page-likes": "ページのいいねを見る"
|
||||
"write:page-likes": "ページのいいねを操作する"
|
||||
"read:user-groups": "ユーザーグループを見る"
|
||||
"write:user-groups": "ユーザーグループを操作する"
|
||||
|
||||
empty-timeline-info:
|
||||
follow-users-to-make-your-timeline: "ユーザーをフォローすると投稿がタイムラインに表示されます。"
|
||||
@@ -206,6 +212,8 @@ common:
|
||||
other: "その他"
|
||||
appearance: "デザイン"
|
||||
behavior: "動作"
|
||||
reactions: "リアクション"
|
||||
reactions-description: "リアクションピッカーに表示するリアクションを改行で区切って設定します。"
|
||||
fetch-on-scroll: "スクロールで自動読み込み"
|
||||
fetch-on-scroll-desc: "ページを下までスクロールしたときに自動で追加のコンテンツを読み込みます。"
|
||||
note-visibility: "投稿の公開範囲"
|
||||
@@ -304,6 +312,7 @@ common:
|
||||
sync: "同期"
|
||||
save: "保存"
|
||||
saved: "保存しました"
|
||||
preview: "プレビュー"
|
||||
home-profile: "ホームのプロファイル"
|
||||
deck-profile: "デッキのプロファイル"
|
||||
room: "ルーム"
|
||||
@@ -405,9 +414,11 @@ common/views/pages/explore.vue:
|
||||
popular-users: "人気のユーザー"
|
||||
recently-updated-users: "最近投稿したユーザー"
|
||||
recently-registered-users: "新規ユーザー"
|
||||
recently-discovered-users: "最近発見されたユーザー"
|
||||
popular-tags: "人気のタグ"
|
||||
federated: "連合"
|
||||
explore: "{host}を探索"
|
||||
explore-fediverse: "Fediverseを探索"
|
||||
users-info: "現在{users}ユーザーが登録されています"
|
||||
|
||||
common/views/components/reactions-viewer.details.vue:
|
||||
@@ -663,7 +674,9 @@ common/views/components/reaction-picker.vue:
|
||||
input-reaction-placeholder: "または絵文字を入力"
|
||||
|
||||
common/views/components/emoji-picker.vue:
|
||||
recent-emoji: "最近使った絵文字"
|
||||
custom-emoji: "カスタム絵文字"
|
||||
no-category: "カテゴリなし"
|
||||
people: "人"
|
||||
animals-and-nature: "動物&自然"
|
||||
food-and-drink: "食べ物&飲み物"
|
||||
@@ -878,6 +891,7 @@ common/views/widgets/broadcast.vue:
|
||||
no-broadcasts: "お知らせはありません"
|
||||
have-a-nice-day: "良い一日を!"
|
||||
next: "次"
|
||||
prev: "前"
|
||||
|
||||
common/views/widgets/calendar.vue:
|
||||
year: "{}年"
|
||||
@@ -1211,6 +1225,8 @@ common/views/components/mute-and-block.vue:
|
||||
word-mute: "ワードミュート"
|
||||
muted-words: "ミュートされたキーワード"
|
||||
muted-words-description: "スペースで区切るとAND指定になり、改行で区切るとOR指定になります"
|
||||
unmute-confirm: "このユーザーをミュート解除しますか?"
|
||||
unblock-confirm: "このユーザーをブロック解除しますか?"
|
||||
save: "保存"
|
||||
|
||||
common/views/components/password-settings.vue:
|
||||
@@ -1394,7 +1410,9 @@ admin/views/instance.vue:
|
||||
object-storage-s3-info-here: "こちら"
|
||||
object-storage-gcs-info: "Google Cloud Storageをオブジェクトストレージとして使用する場合、「エンドポイント」は storage.googleapis.com に設定し、「リージョン」は空欄にします。"
|
||||
cache-remote-files: "リモートのファイルをキャッシュする"
|
||||
cache-remote-files-desc: "この設定を無効にすると、リモートファイルをキャッシュせず直リンクするようになります。そのためサーバーのストレージを節約できますが、プライバシー設定で直リンクを無効にしているユーザーにはファイルが見えなくなったり、サムネイルが生成されないので通信量が増加します。通常はこの設定をオンにしておくことをおすすめします。"
|
||||
cache-remote-files-desc: "この設定を無効にすると、リモートファイルをキャッシュせず直リンクするようになります。そのためサーバーのストレージを節約できますが、プライバシー設定で直リンクを無効にしているユーザーにはファイルが見えなくなったり、サムネイルが生成されないので通信量が増加します。通常はこの設定をオンにするか次のリモートファイルのプロキシを有効にすることをおすすめします。"
|
||||
proxy-remote-files: "リモートのファイルをプロキシする"
|
||||
proxy-remote-files-desc: "この設定を有効にすると、未保存または保存容量超過で削除されたリモートファイルをローカルでプロキシし、サムネイルも生成するようになります。"
|
||||
local-drive-capacity-mb: "ローカルユーザーひとりあたりのドライブ容量"
|
||||
remote-drive-capacity-mb: "リモートユーザーひとりあたりのドライブ容量"
|
||||
mb: "メガバイト単位"
|
||||
@@ -1547,6 +1565,7 @@ admin/views/users.vue:
|
||||
state:
|
||||
title: "状態"
|
||||
all: "すべて"
|
||||
available: "利用可能"
|
||||
admin: "管理者"
|
||||
moderator: "モデレーター"
|
||||
adminOrModerator: "管理者+モデレーター"
|
||||
@@ -1579,6 +1598,7 @@ admin/views/emoji.vue:
|
||||
title: "絵文字の登録"
|
||||
name: "絵文字名"
|
||||
name-desc: "a~z 0~9 _ の文字が使えます。"
|
||||
category: "カテゴリ"
|
||||
aliases: "エイリアス"
|
||||
aliases-desc: "スペースで区切って複数設定できます。"
|
||||
url: "絵文字画像URL"
|
||||
@@ -2182,6 +2202,9 @@ pages:
|
||||
_mod:
|
||||
arg1: "A"
|
||||
arg2: "B"
|
||||
round: "小数を丸める"
|
||||
_round:
|
||||
arg1: "数値"
|
||||
eq: "AとBが同じ"
|
||||
_eq:
|
||||
arg1: "A"
|
||||
|
@@ -126,9 +126,11 @@ common:
|
||||
blocking: "ブロック"
|
||||
password: "パスワード"
|
||||
other: "その他"
|
||||
reactions: "リアクション"
|
||||
timeline: "タイムライン"
|
||||
save: "保存"
|
||||
saved: "保存したで!"
|
||||
preview: "試してみる"
|
||||
search: "検索"
|
||||
delete: "削除"
|
||||
loading: "読み込み中"
|
||||
@@ -865,7 +867,6 @@ admin/views/instance.vue:
|
||||
drive-config: "ドライブの設定"
|
||||
object-storage-endpoint: "エンドポイント"
|
||||
cache-remote-files: "リモートのファイルをキャッシュする"
|
||||
cache-remote-files-desc: "この設定を無効にすると、リモートファイルをこっちで保管せずに直接リンク張るようになるで。サーバーのストレージは軽くやろうけど、プライバシー設定で直リンクを向こうにしとるユーザーはファイルが見れへんし、サムネイルが無いから通信量が増えたりするから、普通はオンにしといてな。"
|
||||
local-drive-capacity-mb: "ローカルユーザーひとりあたりのドライブ容量"
|
||||
remote-drive-capacity-mb: "リモートユーザーひとりあたりのドライブ容量"
|
||||
mb: "メガバイト単位"
|
||||
|
@@ -83,14 +83,14 @@ common:
|
||||
followers: "팔로워"
|
||||
favorites: "즐겨찾기"
|
||||
permissions:
|
||||
"read:account": "계정의 정보를 볼 수 있습니다."
|
||||
"write:account": "계정의 정보를 변경할 수 있습니다."
|
||||
"read:blocks": "차단 목록을 볼 수 있습니다."
|
||||
"write:blocks": "차단 목록을 조작할 수 있습니다."
|
||||
"read:drive": "드라이브의 파일들을 볼 수 있습니다."
|
||||
"write:drive": "드라이브의 파일들을 조작할 수 있습니다."
|
||||
"read:favorites": "즐겨찾기 목록을 볼 수 있습니다."
|
||||
"write:favorites": "즐겨찾기 목록을 조작할 수 있습니다."
|
||||
"read:account": "계정 정보 보기"
|
||||
"write:account": "계정 정보 변경"
|
||||
"read:blocks": "차단 보기"
|
||||
"write:blocks": "차단 수정"
|
||||
"read:drive": "드라이브 보기"
|
||||
"write:drive": "드라이브 수정"
|
||||
"read:favorites": "즐겨찾기 보기"
|
||||
"write:favorites": "즐겨찾기 수정"
|
||||
"read:following": "팔로우 정보 보기"
|
||||
"write:following": "팔로잉, 팔로우 수정"
|
||||
"read:messaging": "대화 보기"
|
||||
@@ -103,6 +103,12 @@ common:
|
||||
"read:reactions": "리액션 보기"
|
||||
"write:reactions": "리액션 수정"
|
||||
"write:votes": "투표하기"
|
||||
"read:pages": "페이지 보기"
|
||||
"write:pages": "페이지 변경"
|
||||
"read:page-likes": "페이지의 좋아요 보기"
|
||||
"write:page-likes": "페이지의 좋아요 변경"
|
||||
"read:user-groups": "유저 그룹 보기"
|
||||
"write:user-groups": "유저 그룹을 변경"
|
||||
empty-timeline-info:
|
||||
follow-users-to-make-your-timeline: "사용자를 팔로우하면 글이 타임라인에 표시됩니다."
|
||||
explore: "사용자 탐색"
|
||||
@@ -194,6 +200,8 @@ common:
|
||||
other: "기타"
|
||||
appearance: "디자인"
|
||||
behavior: "동작"
|
||||
reactions: "리액션"
|
||||
reactions-description: "리액션 선택창에 표시할 리액션을 줄바꿈으로 구분해 설정합니다."
|
||||
fetch-on-scroll: "스크롤하여 자동으로 불러오기"
|
||||
fetch-on-scroll-desc: "페이지를 아래로 스크롤하였을 때 자동으로 추가 콘텐츠를 불러옵니다."
|
||||
note-visibility: "게시물의 공개 범위"
|
||||
@@ -292,6 +300,7 @@ common:
|
||||
sync: "동기화"
|
||||
save: "저장"
|
||||
saved: "저장하였습니다"
|
||||
preview: "미리보기"
|
||||
home-profile: "홈 프로필"
|
||||
deck-profile: "덱 프로필"
|
||||
room: "룸"
|
||||
@@ -384,9 +393,11 @@ common/views/pages/explore.vue:
|
||||
popular-users: "인기 사용자"
|
||||
recently-updated-users: "최근 게시한 사용자"
|
||||
recently-registered-users: "신규 사용자"
|
||||
recently-discovered-users: "최근 발견된 유저"
|
||||
popular-tags: "인기 태그"
|
||||
federated: "연합"
|
||||
explore: "{host}을(를) 탐색"
|
||||
explore-fediverse: "연합 우주를 탐색"
|
||||
users-info: "현재 {users} 사용자가 등록되어 있습니다"
|
||||
common/views/components/reactions-viewer.details.vue:
|
||||
few-users: "{users}님이 {reaction} 리액션"
|
||||
@@ -619,7 +630,9 @@ common/views/components/reaction-picker.vue:
|
||||
choose-reaction: "리액션 선택"
|
||||
input-reaction-placeholder: "또는 이모지 입력"
|
||||
common/views/components/emoji-picker.vue:
|
||||
recent-emoji: "최근 사용한 이모지"
|
||||
custom-emoji: "커스텀 이모지"
|
||||
no-category: "카테고리 없음"
|
||||
people: "사람들"
|
||||
animals-and-nature: "동물 & 자연"
|
||||
food-and-drink: "음식 & 음료"
|
||||
@@ -815,6 +828,7 @@ common/views/widgets/broadcast.vue:
|
||||
no-broadcasts: "공지사항이 없습니다"
|
||||
have-a-nice-day: "좋은 하루 되세요!"
|
||||
next: "다음"
|
||||
prev: "이전"
|
||||
common/views/widgets/calendar.vue:
|
||||
year: "{}년"
|
||||
month: "{}월"
|
||||
@@ -1102,6 +1116,8 @@ common/views/components/mute-and-block.vue:
|
||||
word-mute: "단어 뮤트"
|
||||
muted-words: "뮤트된 키워드"
|
||||
muted-words-description: "공백으로 구분하는 경우 AND로 지정되며, 줄바꿈으로 구분하는 경우 OR로 지정됩니다"
|
||||
unmute-confirm: "이 사용자를 뮤트 해제하시겠습니까?"
|
||||
unblock-confirm: "이 사용자를 차단 해제하시겠습니까?"
|
||||
save: "저장"
|
||||
common/views/components/password-settings.vue:
|
||||
reset: "비밀번호 변경"
|
||||
@@ -1263,7 +1279,9 @@ admin/views/instance.vue:
|
||||
object-storage-s3-info-here: "이곳"
|
||||
object-storage-gcs-info: "Google Cloud Storage를 오브젝트 스토리지로 사용하는 경우, 「엔드포인트」는 storage.googleapis.com 으로 설정하고, 「리전」 란은 비웁니다."
|
||||
cache-remote-files: "원격 파일을 캐시"
|
||||
cache-remote-files-desc: "이 설정을 해지하면 원격 파일을 캐시하지 않고 해당 파일을 직접 링크하게 됩니다. 그에 따라 서버의 저장 공간을 절약할 수 있지만, 프라이버시 설정에서 직접 링크를 무효로 설정한 사용자에게는 파일이 보이지 않거나, 썸네일이 생성되지 않기 때문에 통신량이 증가합니다. 일반적으로 이 설정을 ON으로 두는 것을 추천합니다."
|
||||
cache-remote-files-desc: "이 설정을 해지하면 원격 파일을 캐시하지 않고 해당 파일을 직접 링크하게 됩니다. 그에 따라 서버의 저장 공간을 절약할 수 있지만, 프라이버시 설정에서 직접 링크를 무효로 설정한 사용자에게는 파일이 보이지 않거나, 썸네일이 생성되지 않기 때문에 통신량이 증가합니다. 보통은 이 설정을 사용하거나 아래의 원격 파일 프록시를 설정하는 것을 추천합니다."
|
||||
proxy-remote-files: "원격 파일 프록시"
|
||||
proxy-remote-files-desc: "이 설정을 사용하면, 저장되지 않았거나 용량 초과로 삭제된 원격 파일을 로컬에서 프록시하여 썸네일을 생성하게 됩니다."
|
||||
local-drive-capacity-mb: "로컬 사용자 한 명당 드라이브 용량"
|
||||
remote-drive-capacity-mb: "원격 사용자 한 명당 드라이브 용량"
|
||||
mb: "메가바이트 단위"
|
||||
@@ -1401,7 +1419,7 @@ admin/views/users.vue:
|
||||
delete-all-files: "모든 파일 삭제"
|
||||
delete-all-files-confirm: "모든 파일을 삭제하시겠습니까?"
|
||||
username: "사용자명"
|
||||
host: "관리자"
|
||||
host: "호스트"
|
||||
users:
|
||||
title: "사용자"
|
||||
sort:
|
||||
@@ -1413,6 +1431,7 @@ admin/views/users.vue:
|
||||
state:
|
||||
title: "상태"
|
||||
all: "모두"
|
||||
available: "이용 가능"
|
||||
admin: "관리자"
|
||||
moderator: "모더레이터"
|
||||
adminOrModerator: "관리자+모더레이터"
|
||||
@@ -1443,6 +1462,7 @@ admin/views/emoji.vue:
|
||||
title: "이모지 등록"
|
||||
name: "이모지 이름"
|
||||
name-desc: "a~z 0~9 _ 의 문자를 사용할 수 있습니다."
|
||||
category: "카테고리"
|
||||
aliases: "별칭"
|
||||
aliases-desc: "공백으로 구분하여 여러 개 설정할 수 있습니다."
|
||||
url: "이모지 이미지 URL"
|
||||
@@ -1974,6 +1994,9 @@ pages:
|
||||
_mod:
|
||||
arg1: "A"
|
||||
arg2: "B"
|
||||
round: "소수점을 반올림"
|
||||
_round:
|
||||
arg1: "수치"
|
||||
eq: "A와 B가 동일"
|
||||
_eq:
|
||||
arg1: "A"
|
||||
@@ -2099,7 +2122,7 @@ room:
|
||||
saved: "저장하였습니다"
|
||||
clear: "모두 치우기"
|
||||
clear-confirm: "정말 방 안의 모든 가구를 치우시겠습니까?"
|
||||
leave-confirm: "저장되지 않은 변경 사항이 있습니다. 정말 떠나시겠습니까?"
|
||||
leave-confirm: "저장되지 않은 변경 사항이 있습니다. 정말 나가시겠습니까?"
|
||||
chooseImage: "이미지 선택"
|
||||
room-type: "룸 종류"
|
||||
carpet-color: "바닥 색상"
|
||||
|
@@ -3,16 +3,58 @@ meta:
|
||||
lang: "Nederlands"
|
||||
common:
|
||||
misskey: "Deel alles met anderen die ook Misskey gebruiken."
|
||||
about-title: "Een ster van het fediverse"
|
||||
about: "Bedankt voor het ontdekken van Misskey. Misskey is een <b>gedecentraliseerd microblogging platform</b> geboren op aarde. Omdat het bestaat binnen het Fediverse (een georganiseerd universum van verschillende sociale mediaplatformen), staat het verbonden met andere sociale medieplatformen. Neem een pauze van de stedelijke drukte, en duik in het nieuwe intenet?"
|
||||
intro:
|
||||
title: "Wat is Misskey?"
|
||||
about: "Misskey is een open source <b>gedecentraliseerd blogplatform</b>. Het heeft een gesofisticeerde, volledig aanpasbare gebruikersinterface, uitgebreide reactiemogelijkheden voor posts, gratis geïntegreerd bestandsoplagbeheer en andere geavanceerde mogelijkheden. Daarnaast staat Misskey verbonden aan een netwerksysteem genaam het \"Fediverse\", hiermee kunnen we communiceren met andere gebruikers op andere SNSs. Dit betekent dat wanneer je iets post het niet enkel verstuurd wordt naar andere Misskey gebruikers, maar ook naar gebruikers op Mastodon en Pleroma. Stel je voor dat een planeet een radiosignaal verzendt naar een andere planeet als manier van communiceren."
|
||||
features: "Kenmerken"
|
||||
rich-contents: "Bericht"
|
||||
rich-contents-desc: "Post jouw idee, hot topic, wat je ook maar wil delen. Maak jouw teksten aantrekkelijk met je favoriete foto's, verzend bestanden, zelfs video's, of maak een poll. Dit zijn enkele van de mogelijkheden die Misskey aanbiedt!"
|
||||
reaction: "Reactie"
|
||||
reaction-desc: "Dé makkelijkste manier om jouw gevoelens uit te drukken. Met Misskey kan je verschillende reacties toevoegen aan jouw posts. Andere SNSs hebben enkel maar een \"vind ik leuk\" reactie."
|
||||
ui: "Interface"
|
||||
ui-desc: "Niet één UI past nij iedereen. Daarom heeft Misskey een uitgebreide keuze om de UI naar jouw hand te zetten. Je kan jouw nieuwe thuis zo origineel maken als je zelf wil door jouw tijdslijn aan te passen door widgets te verplaatsen en hun look te veranderen. Zo maak je van Misskey jouw eigen stek."
|
||||
drive: "Drive"
|
||||
drive-desc: "Wil je een foto posten die je reeds het geüpload? Wens je georganiseerde map met zelfgekozen naam maken voor al jouw bestanden? De beste oplossing voor jou is Misskey Drive. Dit maakt het supermakkelijk om jouw bestanden online te delen."
|
||||
application-authorization: "Geauthoriseerde applicaties"
|
||||
close: "Sluiten"
|
||||
do-not-copy-paste: "Gelieve de code hier niet in te geven of te plakken. De account kan gecompromiseerd zijn."
|
||||
load-more: "Laad meer resultaten"
|
||||
enter-password: "Voer het wachtwoord in"
|
||||
2fa: "Tweestapsverificatie"
|
||||
customize-home: "Layout aanpassen"
|
||||
featured-notes: "Uitgelicht"
|
||||
dark-mode: "Donker thema"
|
||||
signin: "Aanmelden"
|
||||
signup: "Registreren"
|
||||
signout: "Afmelden"
|
||||
reload-to-apply-the-setting: "Herlaad de pagina om je aanpassingen te bekijken. Wil je de pagina nu herladen?"
|
||||
fetching-as-ap-object: "Verzenden naar Fediverse"
|
||||
unfollow-confirm: "Wil stoppen met {name} te volgen?"
|
||||
delete-confirm: "Ben je zeker dat je dit bericht wil verwijderen?"
|
||||
signin-required: "Gelieve in te loggen"
|
||||
notification-type: "Notificatietype"
|
||||
notification-types:
|
||||
all: "Alle"
|
||||
pollVote: "Stemmen"
|
||||
follow: "Volgend"
|
||||
receiveFollowRequest: "Volgverzoeken"
|
||||
reply: "Beantwoorden"
|
||||
quote: "Bron"
|
||||
mention: "Vermeldingen"
|
||||
reaction: "Reactie"
|
||||
got-it: "Ik snap het!"
|
||||
customization-tips:
|
||||
title: "Aanpassingstips"
|
||||
gotit: "Ik snap het!"
|
||||
notification:
|
||||
file-uploaded: "Je bestand is geüpload"
|
||||
message-from: "Bericht van {}:"
|
||||
reversi-invited: "Uitgenodigd voor spel"
|
||||
notified-by: "Bemerkt door: {}"
|
||||
reply-from: "Antwoord van: {}"
|
||||
quoted-by: "Geciteerd door: {}"
|
||||
time:
|
||||
unknown: "onbekend"
|
||||
future: "toekomstig"
|
||||
@@ -24,7 +66,13 @@ common:
|
||||
weeks_ago: "{}week/weken geleden"
|
||||
months_ago: "{}maand(en) geleden"
|
||||
years_ago: "{}jaar geleden"
|
||||
month-and-day: "{day} {month}"
|
||||
trash: "Prullenbak"
|
||||
drive: "Drive"
|
||||
pages: "Pagina's"
|
||||
messaging: "Gesprekken"
|
||||
home: "Startpagina"
|
||||
deck: "Deck"
|
||||
timeline: "Tijdlijn"
|
||||
followers: "Volgers"
|
||||
favorites: "Deze notitie toevoegen aan favorieten"
|
||||
@@ -59,7 +107,11 @@ common:
|
||||
profile: "Je profiel"
|
||||
notification: "Meldingen"
|
||||
password: "Wachtwoord"
|
||||
reactions: "Reactie"
|
||||
deck-column-align-center: "Centreren"
|
||||
deck-column-align-left: "Links"
|
||||
timeline: "Tijdlijn"
|
||||
navbar-position-left: "Links"
|
||||
search: "Zoeken"
|
||||
delete: "Verwijderen"
|
||||
loading: "Bezig met laden"
|
||||
@@ -423,11 +475,13 @@ admin/views/index.vue:
|
||||
users: "Gebruiker"
|
||||
admin/views/dashboard.vue:
|
||||
notes: "Bericht"
|
||||
drive: "Drive"
|
||||
admin/views/abuse.vue:
|
||||
remove-report: "Verwijderen"
|
||||
admin/views/charts.vue:
|
||||
notes: "Bericht"
|
||||
users: "Gebruiker"
|
||||
drive: "Drive"
|
||||
admin/views/drive.vue:
|
||||
origin:
|
||||
local: "Lokaal"
|
||||
@@ -563,6 +617,7 @@ mobile/views/pages/home.vue:
|
||||
global: "Algemeen"
|
||||
mobile/views/pages/widgets.vue:
|
||||
add-widget: "Toevoegen"
|
||||
customization-tips: "Aanpassingstips"
|
||||
mobile/views/pages/widgets/activity.vue:
|
||||
activity: "Activiteit"
|
||||
mobile/views/pages/note.vue:
|
||||
@@ -643,3 +698,4 @@ room:
|
||||
translate: "Verplaatsen"
|
||||
furnitures:
|
||||
moon: "Maan"
|
||||
bin: "Prullenbak"
|
||||
|
@@ -157,10 +157,12 @@ common:
|
||||
other: "Inne"
|
||||
appearance: "Wygląd"
|
||||
behavior: "Zachowanie"
|
||||
reactions: "Reakcja"
|
||||
fetch-on-scroll: "Automatycznie ładuj po przeciągnięciu w dół"
|
||||
note-visibility: "Widoczność wpisów"
|
||||
remember-note-visibility: "Zapamiętaj widoczność wpisów"
|
||||
web-search-engine: "Wyszukiwarka internetowa"
|
||||
web-search-engine-desc: "Wzór: https://www.google.com/?#q={{query}}"
|
||||
paste: "Wklej"
|
||||
line-width: "Szerokości linii"
|
||||
line-width-thin: "Cienka"
|
||||
@@ -192,6 +194,7 @@ common:
|
||||
navbar-position-left: "Z lewej"
|
||||
save: "Zapisz"
|
||||
saved: "Zapisano"
|
||||
preview: "Pokaż podgląd"
|
||||
search: "Szukaj"
|
||||
delete: "Usuń"
|
||||
loading: "Ładowanie"
|
||||
|
@@ -12,7 +12,7 @@ common:
|
||||
rich-contents: "Посты"
|
||||
rich-contents-desc: "Просто выложи свою идею, актуальные темы и всё, что тебе хочется показать миру. Ты можешь декорировать свои слова, прикреплять свои любимые картинки, отправлять файлы с фильмами и создать голосование - это те вещи, которые ты можешь сделать с помощью Misskey!"
|
||||
reaction: "Реакции"
|
||||
reaction-desc: "Самый лёгкий способ выразить свои эмоции. Misskey позволяет добавлять различные виды реакций к постам других людей. Эмоциональный опыт из Misskey никогда не появится в других социальных сетях, позволяющих только жать “лайки”."
|
||||
reaction-desc: "あなたの気持ちを伝える最も簡単な方法です。Misskeyは、他のユーザーの投稿に様々なリアクションを付けることができます。いちどMisskeyのリアクション機能を体験してしまうと、もう「いいね」の概念しか存在しないSNSには戻れなくなるかもしれません。"
|
||||
ui: "Интерфейс"
|
||||
ui-desc: "Нет такого интерфейса, понравившегося всем. Поэтому у Misskey имеется пользовательский интерфейс, широко настраиваемый под ваши вкусы. Создай себе уникальную домашнюю страницу редактируя, подстраивая оформление ленты и размещая виджеты, которые тоже можно кастомизировать."
|
||||
drive: "Хранилище файлов"
|
||||
|
@@ -2,12 +2,12 @@
|
||||
meta:
|
||||
lang: "中文(简体)"
|
||||
common:
|
||||
misskey: "Fediverse中的一颗⭐"
|
||||
about-title: "Fediverse中的一颗⭐"
|
||||
about: "非常感谢您找到了Misskey。 Misskey是诞生于地球的<b>分布式微博SNS</b>。因为她处于Fediverse(由各种SNS组成的宇宙)中,所以她与其他SNS相互连接。想要远离喧嚣的城市,不如深入这个新的互联网来探索一下吧。"
|
||||
misskey: "联邦宇宙中的一颗⭐"
|
||||
about-title: "联邦宇宙中的一颗⭐"
|
||||
about: "非常感谢您找到了Misskey。 Misskey是诞生于地球的<b>分布式微博SNS</b>。因为她处于联邦宇宙(由各种SNS组成的宇宙)中,所以她与其他SNS相互连接。为什么不试试远离喧嚣的城市,潜入这片新的网络海洋之中呢?"
|
||||
intro:
|
||||
title: "什么是 Misskey 呢?"
|
||||
about: "Misskey是开源的<b>分散式微博SNS</b>。复杂的完全可定制的Ui,各种各样的帖子反应,提供集成管理系统和其他先进功能的免费文件存储。此外,称为“Fediverse”的网络系统使我们能够与其他SNS的用户进行通信。比如,如果你张贴一些东西,那么你的帖子不仅会发送给Misskey,还会发送到其他SNS平台。想象一下,正如一颗行星和另一颗行星通过电磁波来进行通信一样。"
|
||||
about: "Misskey是开源的<b>分散式微博SNS</b>。丰富且可以高度定制的Ui,对别人的帖子进行各种回应,集成管理系统的网盘等先进功能。此外,称为“联邦世界”的网络系统使我们能够与其他SNS的用户进行通信。比如,如果你发布一个帖子,那么你的帖子不仅会发送给Misskey,还会发送到其他SNS平台。想象一下,正如一颗行星和另一颗行星通过电磁波来进行通信一样。"
|
||||
features: "功能"
|
||||
rich-contents: "发布"
|
||||
rich-contents-desc: "请分享您的想法,热门话题,以及任何您想与大家分享的内容。如果有需要的话,您可以使用各种语法来修饰文章,发布问卷调查,或者添加各种您喜欢的图像和视频等文件。"
|
||||
@@ -16,7 +16,7 @@ common:
|
||||
ui: "交互界面"
|
||||
ui-desc: "世界上没有一个UI可以适合每一个人. 所以, Misskey 提供一个可以高度定制的UI交互界面. 您可以通过编辑, 调整布局, 放置可选择的小部件来轻松定制您的专属UI界面。"
|
||||
drive: "网盘"
|
||||
drive-desc: "想要发布一张您已经上传过的照片吗?想要管理文件或为上传的文件创建文件夹吗?Misskey的网盘是一个最好的解决方案。"
|
||||
drive-desc: "想要发布一张您已经上传过的照片吗?想要管理文件或为上传的文件创建文件夹吗?Misskey的内置网盘将为您完美解决这些问题。简单地分享您的文件。"
|
||||
outro: "Misskey还有其他更多功能,请亲身体验一下吧。因为 Misskey 是一个分布式的 SNS,如果您感觉某个功能不适合自己,试试其他的吧。祝您玩得开心!"
|
||||
application-authorization: "应用程序授权"
|
||||
close: "关闭"
|
||||
@@ -103,6 +103,12 @@ common:
|
||||
"read:reactions": "查看回应"
|
||||
"write:reactions": "回应操作"
|
||||
"write:votes": "投票"
|
||||
"read:pages": "查看页面"
|
||||
"write:pages": "操作页面"
|
||||
"read:page-likes": "查看喜欢的页面"
|
||||
"write:page-likes": "操作喜欢的页面"
|
||||
"read:user-groups": "查看用户组"
|
||||
"write:user-groups": "操作用户组"
|
||||
empty-timeline-info:
|
||||
follow-users-to-make-your-timeline: "关注其他用户时,帖子将显示在时间线中。"
|
||||
explore: "查找用户"
|
||||
@@ -185,7 +191,7 @@ common:
|
||||
profile: "个人资料"
|
||||
notification: "通知"
|
||||
apps: "应用程序"
|
||||
tags: "哈希标签"
|
||||
tags: "话题标签"
|
||||
mute-and-block: "屏蔽/拉黑"
|
||||
blocking: "拉黑"
|
||||
security: "安全性"
|
||||
@@ -194,6 +200,8 @@ common:
|
||||
other: "其他"
|
||||
appearance: "设计"
|
||||
behavior: "行为"
|
||||
reactions: "回应"
|
||||
reactions-description: "快速选择回应中的自定义表情符号,以换行符分隔。"
|
||||
fetch-on-scroll: "向下滚动时自动加载"
|
||||
fetch-on-scroll-desc: "向下滚动页面时,它会自动提取其他内容。"
|
||||
note-visibility: "帖子可见性"
|
||||
@@ -292,6 +300,7 @@ common:
|
||||
sync: "同步"
|
||||
save: "保存"
|
||||
saved: "已保存"
|
||||
preview: "预览"
|
||||
home-profile: "定制首页数据"
|
||||
deck-profile: "定制Deck数据"
|
||||
room: "房间"
|
||||
@@ -355,7 +364,7 @@ common:
|
||||
notifications: "通知"
|
||||
users: "推荐用户"
|
||||
polls: "调查问卷"
|
||||
post-form: "投稿形式"
|
||||
post-form: "投稿窗口"
|
||||
server: "服务器信息"
|
||||
nav: "导航"
|
||||
tips: "提示"
|
||||
@@ -384,9 +393,11 @@ common/views/pages/explore.vue:
|
||||
popular-users: "热门用户"
|
||||
recently-updated-users: "活跃用户"
|
||||
recently-registered-users: "新用户"
|
||||
recently-discovered-users: "最近发现的用户"
|
||||
popular-tags: "热门标签"
|
||||
federated: "联合"
|
||||
federated: "联邦"
|
||||
explore: "查找{host}"
|
||||
explore-fediverse: "探索Fediverse"
|
||||
users-info: "当前有{users}个注册用户"
|
||||
common/views/components/reactions-viewer.details.vue:
|
||||
few-users: "{users}作出了{reaction}的回应"
|
||||
@@ -619,7 +630,9 @@ common/views/components/reaction-picker.vue:
|
||||
choose-reaction: "选择回应"
|
||||
input-reaction-placeholder: "表情符号输入"
|
||||
common/views/components/emoji-picker.vue:
|
||||
recent-emoji: "最近使用的表情符号"
|
||||
custom-emoji: "自定义表情符号"
|
||||
no-category: "未分类"
|
||||
people: "人"
|
||||
animals-and-nature: "动物与自然"
|
||||
food-and-drink: "食物与饮品"
|
||||
@@ -640,7 +653,7 @@ common/views/components/signin.vue:
|
||||
username: "用户名"
|
||||
password: "密码"
|
||||
token: "Token (令牌)"
|
||||
signing-in: "正在登录..."
|
||||
signing-in: "在弄了在弄了..."
|
||||
or: "或者"
|
||||
signin-with-twitter: "用 Twitter 登录"
|
||||
signin-with-github: "用 GitHub 登录"
|
||||
@@ -815,6 +828,7 @@ common/views/widgets/broadcast.vue:
|
||||
no-broadcasts: "没有公告"
|
||||
have-a-nice-day: "祝你有愉快的一天!"
|
||||
next: "下一个"
|
||||
prev: "上一首"
|
||||
common/views/widgets/calendar.vue:
|
||||
year: "{}年"
|
||||
month: "{}月"
|
||||
@@ -1102,6 +1116,8 @@ common/views/components/mute-and-block.vue:
|
||||
word-mute: "文字屏蔽"
|
||||
muted-words: "屏蔽关键字"
|
||||
muted-words-description: "使用空格分隔会产生AND规范,并且使用换行符分隔会产生OR规范"
|
||||
unmute-confirm: "取消屏蔽用户?"
|
||||
unblock-confirm: "取消拉黑此用户?"
|
||||
save: "保存"
|
||||
common/views/components/password-settings.vue:
|
||||
reset: "更改密码"
|
||||
@@ -1169,16 +1185,16 @@ desktop/views/components/window.vue:
|
||||
popout: "弹出"
|
||||
close: "关闭"
|
||||
admin/views/index.vue:
|
||||
dashboard: "Dashboard"
|
||||
instance: "例"
|
||||
emoji: "Emoji"
|
||||
dashboard: "仪表盘"
|
||||
instance: "实例"
|
||||
emoji: "自定义Emoji"
|
||||
moderators: "版主"
|
||||
users: "用户"
|
||||
federation: "联合"
|
||||
federation: "联邦"
|
||||
announcements: "公告"
|
||||
abuse: "举报垃圾信息"
|
||||
queue: "作业队列"
|
||||
logs: "登录"
|
||||
logs: "日志"
|
||||
db: "数据库"
|
||||
back-to-misskey: "返回 Misskey"
|
||||
admin/views/db.vue:
|
||||
@@ -1191,7 +1207,7 @@ admin/views/dashboard.vue:
|
||||
accounts: "账户"
|
||||
notes: "帖子"
|
||||
drive: "网盘"
|
||||
instances: "例子"
|
||||
instances: "实例"
|
||||
this-instance: "此实例"
|
||||
federated: "联合"
|
||||
admin/views/queue.vue:
|
||||
@@ -1212,7 +1228,7 @@ admin/views/queue.vue:
|
||||
result-is-truncated: "结果已省略"
|
||||
other-queues: "其他队列"
|
||||
admin/views/logs.vue:
|
||||
logs: "登录"
|
||||
logs: "日志"
|
||||
domain: "域"
|
||||
level: "级别"
|
||||
levels:
|
||||
@@ -1230,7 +1246,7 @@ admin/views/abuse.vue:
|
||||
details: "详情"
|
||||
remove-report: "删除"
|
||||
admin/views/instance.vue:
|
||||
instance: "例子"
|
||||
instance: "实例"
|
||||
instance-name: "实例名称"
|
||||
instance-description: "实例介绍"
|
||||
host: "主机名"
|
||||
@@ -1263,7 +1279,7 @@ admin/views/instance.vue:
|
||||
object-storage-s3-info-here: "这里"
|
||||
object-storage-gcs-info: "将Google Cloud Storage用作对象存储时,请将“终端”设置为storage.googleapis.com,并将“区域”留空。"
|
||||
cache-remote-files: "远程文件缓存"
|
||||
cache-remote-files-desc: "如果没有此参数,则所有远程文件都将直接链接到其主机服务器。 这将是保存服务器存储的有效解决方案,但是对于设置禁用直接链接的用户而言,远程文件不可见,因为不会生成缩略图,从而增加流量。 建议启用此参数集。"
|
||||
proxy-remote-files: "代理远程文件"
|
||||
local-drive-capacity-mb: "每个用户的网盘空间"
|
||||
remote-drive-capacity-mb: "每个远程用户的网盘容量"
|
||||
mb: "以兆字节(Mbps)为单位"
|
||||
@@ -1413,6 +1429,7 @@ admin/views/users.vue:
|
||||
state:
|
||||
title: "状态"
|
||||
all: "全部"
|
||||
available: "可用"
|
||||
admin: "管理员"
|
||||
moderator: "版主"
|
||||
adminOrModerator: "管理员+版主"
|
||||
@@ -1433,7 +1450,7 @@ admin/views/moderators.vue:
|
||||
remove: "取消"
|
||||
removed: "取消注册版主"
|
||||
logs:
|
||||
title: "登录"
|
||||
title: "日志"
|
||||
moderator: "版主"
|
||||
type: "操作"
|
||||
at: "日期和时间"
|
||||
@@ -1443,6 +1460,7 @@ admin/views/emoji.vue:
|
||||
title: "添加emoji"
|
||||
name: "Emoji 名称"
|
||||
name-desc: "你可以使用字符a~z 0~9 _"
|
||||
category: "类别"
|
||||
aliases: "别名"
|
||||
aliases-desc: "您可以添加多个,以空格分隔。"
|
||||
url: "emoji 地址"
|
||||
@@ -1487,7 +1505,7 @@ admin/views/federation.vue:
|
||||
block: "拉黑"
|
||||
marked-as-closed: "标记为已关闭"
|
||||
lookup: "查询"
|
||||
instances: "联合"
|
||||
instances: "联邦"
|
||||
instance-not-registered: "实例未注册"
|
||||
sort: "排序"
|
||||
sorts:
|
||||
@@ -1607,7 +1625,7 @@ desktop/views/widgets/trends.vue:
|
||||
desktop/views/widgets/users.vue:
|
||||
title: "推荐用户"
|
||||
refresh: "更多"
|
||||
no-one: "不是!"
|
||||
no-one: "没有任何推荐用户!"
|
||||
mobile/views/components/drive.vue:
|
||||
used: "已使用"
|
||||
folder-count: "文件夹"
|
||||
@@ -1865,10 +1883,10 @@ pages:
|
||||
section: "章节"
|
||||
image: "图片"
|
||||
button: "按钮"
|
||||
if: "如果"
|
||||
if: "判断"
|
||||
_if:
|
||||
variable: "变量"
|
||||
post: "投稿形式"
|
||||
post: "投稿窗口"
|
||||
_post:
|
||||
text: "内容"
|
||||
textInput: "文本输入"
|
||||
@@ -1974,6 +1992,9 @@ pages:
|
||||
_mod:
|
||||
arg1: "A"
|
||||
arg2: "B"
|
||||
round: "四舍五入"
|
||||
_round:
|
||||
arg1: "数值"
|
||||
eq: "A和B相等"
|
||||
_eq:
|
||||
arg1: "A"
|
||||
|
13
migration/1571220798684-CustomEmojiCategory.ts
Normal file
13
migration/1571220798684-CustomEmojiCategory.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import {MigrationInterface, QueryRunner} from "typeorm";
|
||||
|
||||
export class CustomEmojiCategory1571220798684 implements MigrationInterface {
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<any> {
|
||||
await queryRunner.query(`ALTER TABLE "emoji" ADD "category" character varying(128)`, undefined);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<any> {
|
||||
await queryRunner.query(`ALTER TABLE "emoji" DROP COLUMN "category"`, undefined);
|
||||
}
|
||||
|
||||
}
|
29
migration/1572760203493-nodeinfo.ts
Normal file
29
migration/1572760203493-nodeinfo.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import {MigrationInterface, QueryRunner} from "typeorm";
|
||||
|
||||
export class nodeinfo1572760203493 implements MigrationInterface {
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<any> {
|
||||
await queryRunner.query(`ALTER TABLE "instance" DROP COLUMN "system"`, undefined);
|
||||
await queryRunner.query(`ALTER TABLE "instance" ADD "softwareName" character varying(64) DEFAULT null`, undefined);
|
||||
await queryRunner.query(`ALTER TABLE "instance" ADD "softwareVersion" character varying(64) DEFAULT null`, undefined);
|
||||
await queryRunner.query(`ALTER TABLE "instance" ADD "openRegistrations" boolean DEFAULT null`, undefined);
|
||||
await queryRunner.query(`ALTER TABLE "instance" ADD "name" character varying(256) DEFAULT null`, undefined);
|
||||
await queryRunner.query(`ALTER TABLE "instance" ADD "description" character varying(4096) DEFAULT null`, undefined);
|
||||
await queryRunner.query(`ALTER TABLE "instance" ADD "maintainerName" character varying(128) DEFAULT null`, undefined);
|
||||
await queryRunner.query(`ALTER TABLE "instance" ADD "maintainerEmail" character varying(256) DEFAULT null`, undefined);
|
||||
await queryRunner.query(`ALTER TABLE "instance" ADD "infoUpdatedAt" TIMESTAMP WITH TIME ZONE`, undefined);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<any> {
|
||||
await queryRunner.query(`ALTER TABLE "instance" DROP COLUMN "infoUpdatedAt"`, undefined);
|
||||
await queryRunner.query(`ALTER TABLE "instance" DROP COLUMN "maintainerEmail"`, undefined);
|
||||
await queryRunner.query(`ALTER TABLE "instance" DROP COLUMN "maintainerName"`, undefined);
|
||||
await queryRunner.query(`ALTER TABLE "instance" DROP COLUMN "description"`, undefined);
|
||||
await queryRunner.query(`ALTER TABLE "instance" DROP COLUMN "name"`, undefined);
|
||||
await queryRunner.query(`ALTER TABLE "instance" DROP COLUMN "openRegistrations"`, undefined);
|
||||
await queryRunner.query(`ALTER TABLE "instance" DROP COLUMN "softwareVersion"`, undefined);
|
||||
await queryRunner.query(`ALTER TABLE "instance" DROP COLUMN "softwareName"`, undefined);
|
||||
await queryRunner.query(`ALTER TABLE "instance" ADD "system" character varying(64)`, undefined);
|
||||
}
|
||||
|
||||
}
|
14
migration/1576269851876-TalkFederationId.ts
Normal file
14
migration/1576269851876-TalkFederationId.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import {MigrationInterface, QueryRunner} from "typeorm";
|
||||
|
||||
export class TalkFederationId1576269851876 implements MigrationInterface {
|
||||
name = 'TalkFederationId1576269851876'
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<any> {
|
||||
await queryRunner.query(`ALTER TABLE "messaging_message" ADD "uri" character varying(512)`, undefined);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<any> {
|
||||
await queryRunner.query(`ALTER TABLE "messaging_message" DROP COLUMN "uri"`, undefined);
|
||||
}
|
||||
|
||||
}
|
14
migration/1576869585998-ProxyRemoteFiles.ts
Normal file
14
migration/1576869585998-ProxyRemoteFiles.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import {MigrationInterface, QueryRunner} from "typeorm";
|
||||
|
||||
export class ProxyRemoteFiles1576869585998 implements MigrationInterface {
|
||||
name = 'ProxyRemoteFiles1576869585998'
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<any> {
|
||||
await queryRunner.query(`ALTER TABLE "meta" ADD "proxyRemoteFiles" boolean NOT NULL DEFAULT false`, undefined);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<any> {
|
||||
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "proxyRemoteFiles"`, undefined);
|
||||
}
|
||||
|
||||
}
|
215
package.json
215
package.json
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "misskey",
|
||||
"author": "syuilo <i@syuilo.com>",
|
||||
"version": "11.32.0",
|
||||
"version": "11.37.0",
|
||||
"codename": "daybreak",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -26,176 +26,170 @@
|
||||
"format": "gulp format"
|
||||
},
|
||||
"resolutions": {
|
||||
"gulp-cssnano/cssnano/postcss-svgo/svgo/js-yaml": "^3.13.1",
|
||||
"https-proxy-agent": "^3.0.0",
|
||||
"lodash": "^4.17.13"
|
||||
},
|
||||
"dependencies": {
|
||||
"@elastic/elasticsearch": "7.3.0",
|
||||
"@fortawesome/fontawesome-svg-core": "1.2.19",
|
||||
"@fortawesome/free-brands-svg-icons": "5.9.0",
|
||||
"@fortawesome/free-regular-svg-icons": "5.9.0",
|
||||
"@fortawesome/free-solid-svg-icons": "5.9.0",
|
||||
"@fortawesome/vue-fontawesome": "0.1.6",
|
||||
"@elastic/elasticsearch": "7.5.0",
|
||||
"@fortawesome/fontawesome-svg-core": "1.2.26",
|
||||
"@fortawesome/free-brands-svg-icons": "5.12.0",
|
||||
"@fortawesome/free-regular-svg-icons": "5.12.0",
|
||||
"@fortawesome/free-solid-svg-icons": "5.12.0",
|
||||
"@fortawesome/vue-fontawesome": "0.1.9",
|
||||
"@koa/cors": "3.0.0",
|
||||
"@koa/multer": "2.0.2",
|
||||
"@koa/router": "8.0.5",
|
||||
"@types/bcryptjs": "2.4.2",
|
||||
"@types/bull": "3.5.15",
|
||||
"@types/cbor": "2.0.0",
|
||||
"@types/dateformat": "3.0.0",
|
||||
"@types/deep-equal": "1.0.1",
|
||||
"@types/bull": "3.10.6",
|
||||
"@types/cbor": "5.0.0",
|
||||
"@types/dateformat": "3.0.1",
|
||||
"@types/double-ended-queue": "2.1.1",
|
||||
"@types/gulp": "4.0.6",
|
||||
"@types/gulp-mocha": "0.0.32",
|
||||
"@types/gulp-rename": "0.0.33",
|
||||
"@types/gulp-replace": "0.0.31",
|
||||
"@types/gulp-uglify": "3.0.6",
|
||||
"@types/gulp-util": "3.0.34",
|
||||
"@types/is-url": "1.2.28",
|
||||
"@types/js-yaml": "3.12.1",
|
||||
"@types/jsdom": "12.2.4",
|
||||
"@types/katex": "0.10.1",
|
||||
"@types/koa": "2.0.49",
|
||||
"@types/koa-bodyparser": "5.0.2",
|
||||
"@types/katex": "0.11.0",
|
||||
"@types/koa": "2.11.0",
|
||||
"@types/koa-bodyparser": "4.3.0",
|
||||
"@types/koa-compress": "2.0.9",
|
||||
"@types/koa-cors": "0.0.0",
|
||||
"@types/koa-favicon": "2.0.19",
|
||||
"@types/koa-logger": "3.1.1",
|
||||
"@types/koa-mount": "4.0.0",
|
||||
"@types/koa-multer": "1.0.0",
|
||||
"@types/koa-router": "7.0.42",
|
||||
"@types/koa-send": "4.1.2",
|
||||
"@types/koa-views": "2.0.3",
|
||||
"@types/koa__cors": "2.2.3",
|
||||
"@types/lolex": "3.1.1",
|
||||
"@types/koa-views": "2.0.4",
|
||||
"@types/koa__cors": "3.0.0",
|
||||
"@types/koa__multer": "2.0.1",
|
||||
"@types/koa__router": "8.0.2",
|
||||
"@types/lolex": "5.1.0",
|
||||
"@types/mocha": "5.2.7",
|
||||
"@types/node": "12.0.10",
|
||||
"@types/nodemailer": "6.2.0",
|
||||
"@types/node": "13.1.4",
|
||||
"@types/nodemailer": "6.4.0",
|
||||
"@types/nprogress": "0.2.0",
|
||||
"@types/oauth": "0.9.1",
|
||||
"@types/parse5": "5.0.0",
|
||||
"@types/parse5": "5.0.2",
|
||||
"@types/parsimmon": "1.10.0",
|
||||
"@types/portscanner": "2.1.0",
|
||||
"@types/pug": "2.0.4",
|
||||
"@types/qrcode": "1.3.3",
|
||||
"@types/qrcode": "1.3.4",
|
||||
"@types/random-seed": "0.3.3",
|
||||
"@types/ratelimiter": "2.1.28",
|
||||
"@types/redis": "2.8.13",
|
||||
"@types/redis": "2.8.14",
|
||||
"@types/rename": "1.0.1",
|
||||
"@types/request": "2.48.2",
|
||||
"@types/request-promise-native": "1.0.16",
|
||||
"@types/request": "2.48.4",
|
||||
"@types/request-promise-native": "1.0.17",
|
||||
"@types/request-stats": "3.0.0",
|
||||
"@types/rimraf": "2.0.2",
|
||||
"@types/rimraf": "2.0.3",
|
||||
"@types/seedrandom": "2.4.28",
|
||||
"@types/sharp": "0.22.2",
|
||||
"@types/sharp": "0.23.1",
|
||||
"@types/showdown": "1.9.3",
|
||||
"@types/speakeasy": "2.0.4",
|
||||
"@types/systeminformation": "3.23.1",
|
||||
"@types/speakeasy": "2.0.5",
|
||||
"@types/systeminformation": "3.54.1",
|
||||
"@types/tinycolor2": "1.4.2",
|
||||
"@types/tmp": "0.1.0",
|
||||
"@types/uuid": "3.4.5",
|
||||
"@types/uuid": "3.4.6",
|
||||
"@types/web-push": "3.3.0",
|
||||
"@types/webpack": "4.4.34",
|
||||
"@types/webpack": "4.41.1",
|
||||
"@types/webpack-stream": "3.2.10",
|
||||
"@types/websocket": "0.0.40",
|
||||
"@types/ws": "6.0.1",
|
||||
"@typescript-eslint/parser": "1.11.0",
|
||||
"agentkeepalive": "4.0.2",
|
||||
"@types/websocket": "1.0.0",
|
||||
"@types/ws": "6.0.4",
|
||||
"@typescript-eslint/parser": "2.15.0",
|
||||
"agentkeepalive": "4.1.0",
|
||||
"animejs": "3.1.0",
|
||||
"apexcharts": "3.8.6",
|
||||
"apexcharts": "3.12.0",
|
||||
"autobind-decorator": "2.4.0",
|
||||
"autosize": "4.0.2",
|
||||
"autwh": "0.1.0",
|
||||
"aws-sdk": "2.525.0",
|
||||
"aws-sdk": "2.598.0",
|
||||
"bcryptjs": "2.4.3",
|
||||
"bootstrap": "4.3.1",
|
||||
"bootstrap-vue": "2.0.0-rc.13",
|
||||
"bull": "3.10.0",
|
||||
"cafy": "15.1.1",
|
||||
"cbor": "4.3.0",
|
||||
"bootstrap": "4.4.1",
|
||||
"bootstrap-vue": "2.1.0",
|
||||
"bull": "3.12.1",
|
||||
"cafy": "15.2.1",
|
||||
"cbor": "5.0.1",
|
||||
"chai": "4.2.0",
|
||||
"chalk": "2.4.2",
|
||||
"cli-highlight": "2.1.1",
|
||||
"commander": "2.20.0",
|
||||
"chalk": "3.0.0",
|
||||
"cli-highlight": "2.1.4",
|
||||
"commander": "4.1.0",
|
||||
"content-disposition": "0.5.3",
|
||||
"crc-32": "1.2.0",
|
||||
"css-loader": "3.2.0",
|
||||
"css-loader": "3.4.1",
|
||||
"cssnano": "4.1.10",
|
||||
"dateformat": "3.0.3",
|
||||
"deep-equal": "1.1.0",
|
||||
"diskusage": "1.1.3",
|
||||
"double-ended-queue": "2.1.0-0",
|
||||
"emojilib": "2.4.0",
|
||||
"eslint": "6.1.0",
|
||||
"eslint-plugin-vue": "5.2.3",
|
||||
"eslint": "6.8.0",
|
||||
"eslint-plugin-vue": "6.1.2",
|
||||
"eventemitter3": "4.0.0",
|
||||
"feed": "3.0.0",
|
||||
"file-type": "12.3.0",
|
||||
"feed": "4.1.0",
|
||||
"file-type": "13.0.1",
|
||||
"fluent-ffmpeg": "2.1.2",
|
||||
"gulp": "4.0.2",
|
||||
"gulp-cssnano": "2.1.3",
|
||||
"gulp-imagemin": "6.1.0",
|
||||
"gulp-mocha": "6.0.0",
|
||||
"gulp-rename": "1.4.0",
|
||||
"gulp-clean-css": "4.2.0",
|
||||
"gulp-mocha": "7.0.2",
|
||||
"gulp-rename": "2.0.0",
|
||||
"gulp-replace": "1.0.0",
|
||||
"gulp-sourcemaps": "2.6.5",
|
||||
"gulp-stylus": "2.7.0",
|
||||
"gulp-terser": "1.2.0",
|
||||
"gulp-tslint": "8.1.4",
|
||||
"gulp-typescript": "5.0.1",
|
||||
"gulp-uglify": "3.0.2",
|
||||
"gulp-util": "3.0.8",
|
||||
"hard-source-webpack-plugin": "0.13.1",
|
||||
"html-minifier": "4.0.0",
|
||||
"http-signature": "1.2.0",
|
||||
"https-proxy-agent": "2.2.2",
|
||||
"http-signature": "1.3.1",
|
||||
"https-proxy-agent": "4.0.0",
|
||||
"insert-text-at-cursor": "0.3.0",
|
||||
"is-root": "2.1.0",
|
||||
"is-svg": "4.2.0",
|
||||
"js-yaml": "3.13.1",
|
||||
"jsdom": "15.1.1",
|
||||
"json5": "2.1.0",
|
||||
"jsdom": "15.2.1",
|
||||
"json5": "2.1.1",
|
||||
"json5-loader": "3.0.0",
|
||||
"jsrsasign": "8.0.12",
|
||||
"katex": "0.11.0",
|
||||
"koa": "2.8.1",
|
||||
"katex": "0.11.1",
|
||||
"koa": "2.11.0",
|
||||
"koa-bodyparser": "4.2.1",
|
||||
"koa-compress": "3.0.0",
|
||||
"koa-favicon": "2.0.1",
|
||||
"koa-json-body": "5.3.0",
|
||||
"koa-logger": "3.2.1",
|
||||
"koa-mount": "4.0.0",
|
||||
"koa-multer": "1.0.2",
|
||||
"koa-router": "7.4.0",
|
||||
"koa-send": "5.0.0",
|
||||
"koa-slow": "2.1.0",
|
||||
"koa-views": "6.2.1",
|
||||
"langmap": "0.0.16",
|
||||
"loader-utils": "1.2.3",
|
||||
"lolex": "4.2.0",
|
||||
"lolex": "5.1.2",
|
||||
"lookup-dns-cache": "2.1.0",
|
||||
"mocha": "6.2.0",
|
||||
"mocha": "7.0.0",
|
||||
"moji": "0.5.1",
|
||||
"ms": "2.1.2",
|
||||
"nested-property": "1.0.1",
|
||||
"multer": "1.4.2",
|
||||
"nested-property": "1.0.2",
|
||||
"node-fetch": "2.6.0",
|
||||
"nodemailer": "6.3.0",
|
||||
"nodemailer": "6.4.2",
|
||||
"nprogress": "0.2.0",
|
||||
"object-assign-deep": "0.4.0",
|
||||
"os-utils": "0.0.14",
|
||||
"parse5": "5.1.0",
|
||||
"parse5": "5.1.1",
|
||||
"parsimmon": "1.13.0",
|
||||
"pg": "7.12.1",
|
||||
"pg": "7.17.0",
|
||||
"portscanner": "2.2.0",
|
||||
"postcss-loader": "3.0.0",
|
||||
"prismjs": "1.17.1",
|
||||
"prismjs": "1.18.0",
|
||||
"progress-bar-webpack-plugin": "1.12.1",
|
||||
"promise-limit": "2.7.0",
|
||||
"promise-sequential": "1.1.1",
|
||||
"pug": "2.0.4",
|
||||
"punycode": "2.1.1",
|
||||
"pureimage": "0.1.6",
|
||||
"qrcode": "1.4.1",
|
||||
"qrcode": "1.4.4",
|
||||
"random-seed": "0.3.0",
|
||||
"randomcolor": "0.5.4",
|
||||
"ratelimiter": "3.3.1",
|
||||
"ratelimiter": "3.4.0",
|
||||
"recaptcha-promise": "0.1.3",
|
||||
"reconnecting-websocket": "4.2.0",
|
||||
"redis": "2.8.0",
|
||||
@@ -203,69 +197,68 @@
|
||||
"reflect-metadata": "0.1.13",
|
||||
"rename": "1.0.4",
|
||||
"request": "2.88.0",
|
||||
"request-promise-native": "1.0.7",
|
||||
"request-promise-native": "1.0.8",
|
||||
"request-stats": "3.0.0",
|
||||
"require-all": "3.0.0",
|
||||
"rimraf": "2.6.3",
|
||||
"rimraf": "3.0.0",
|
||||
"rndstr": "1.0.0",
|
||||
"s-age": "1.1.2",
|
||||
"seedrandom": "3.0.3",
|
||||
"sharp": "0.23.0",
|
||||
"showdown": "1.9.0",
|
||||
"seedrandom": "3.0.5",
|
||||
"sharp": "0.23.4",
|
||||
"showdown": "1.9.1",
|
||||
"showdown-highlightjs-extension": "0.1.2",
|
||||
"speakeasy": "2.0.0",
|
||||
"stringz": "2.0.0",
|
||||
"style-loader": "0.23.1",
|
||||
"style-loader": "1.1.2",
|
||||
"stylus": "0.54.7",
|
||||
"stylus-loader": "3.0.2",
|
||||
"summaly": "2.3.1",
|
||||
"syslog-pro": "1.0.0",
|
||||
"systeminformation": "4.14.8",
|
||||
"systeminformation": "4.17.3",
|
||||
"syuilo-password-strength": "0.0.1",
|
||||
"terser-webpack-plugin": "2.0.1",
|
||||
"terser-webpack-plugin": "2.3.1",
|
||||
"textarea-caret": "3.1.0",
|
||||
"three": "0.108.0",
|
||||
"three": "0.112.1",
|
||||
"tinycolor2": "1.4.1",
|
||||
"tmp": "0.1.0",
|
||||
"ts-loader": "5.3.3",
|
||||
"ts-node": "7.0.1",
|
||||
"tslint": "5.18.0",
|
||||
"ts-loader": "6.2.1",
|
||||
"ts-node": "8.5.4",
|
||||
"tslint": "5.20.1",
|
||||
"tslint-sonarts": "1.9.0",
|
||||
"typeorm": "0.2.18",
|
||||
"typescript": "3.5.3",
|
||||
"uglify-es": "3.3.9",
|
||||
"typeorm": "0.2.22",
|
||||
"typescript": "3.7.4",
|
||||
"ulid": "2.3.0",
|
||||
"url-loader": "2.1.0",
|
||||
"url-loader": "3.0.0",
|
||||
"uuid": "3.3.3",
|
||||
"v-animate-css": "0.0.3",
|
||||
"v-debounce": "0.1.2",
|
||||
"vue": "2.6.10",
|
||||
"vue": "2.6.11",
|
||||
"vue-color": "2.7.0",
|
||||
"vue-content-loading": "1.6.0",
|
||||
"vue-cropperjs": "4.0.0",
|
||||
"vue-i18n": "8.14.0",
|
||||
"vue-cropperjs": "4.0.1",
|
||||
"vue-i18n": "8.15.3",
|
||||
"vue-js-modal": "1.3.31",
|
||||
"vue-json-pretty": "1.6.2",
|
||||
"vue-loader": "15.7.1",
|
||||
"vue-json-pretty": "1.6.3",
|
||||
"vue-loader": "15.8.3",
|
||||
"vue-marquee-text-component": "1.1.1",
|
||||
"vue-prism-component": "1.1.1",
|
||||
"vue-router": "3.1.3",
|
||||
"vue-sequential-entrance": "1.1.3",
|
||||
"vue-style-loader": "4.1.2",
|
||||
"vue-svg-inline-loader": "1.2.18",
|
||||
"vue-template-compiler": "2.6.10",
|
||||
"vuedraggable": "2.23.0",
|
||||
"vue-svg-inline-loader": "1.4.4",
|
||||
"vue-template-compiler": "2.6.11",
|
||||
"vuedraggable": "2.23.2",
|
||||
"vuewordcloud": "18.7.11",
|
||||
"vuex": "3.1.1",
|
||||
"vuex-persistedstate": "2.5.4",
|
||||
"web-push": "3.3.5",
|
||||
"webpack": "4.39.3",
|
||||
"webpack-cli": "3.3.8",
|
||||
"websocket": "1.0.29",
|
||||
"ws": "7.1.2",
|
||||
"vuex": "3.1.2",
|
||||
"vuex-persistedstate": "2.7.0",
|
||||
"web-push": "3.4.3",
|
||||
"webpack": "4.41.5",
|
||||
"webpack-cli": "3.3.10",
|
||||
"websocket": "1.0.31",
|
||||
"ws": "7.2.1",
|
||||
"xev": "2.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/fluent-ffmpeg": "2.1.10"
|
||||
"@types/fluent-ffmpeg": "2.1.12"
|
||||
}
|
||||
}
|
||||
|
@@ -1,8 +1,8 @@
|
||||
import * as program from 'commander';
|
||||
import * as pkg from '../package.json';
|
||||
import config from './config';
|
||||
|
||||
program
|
||||
.version(pkg.version)
|
||||
.version(config.version)
|
||||
.option('--no-daemons', 'Disable daemon processes (for debbuging)')
|
||||
.option('--disable-clustering', 'Disable clustering')
|
||||
.option('--only-server', 'Run server only (without job queue processing)')
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import * as cluster from 'cluster';
|
||||
import chalk from 'chalk';
|
||||
import * as chalk from 'chalk';
|
||||
import Xev from 'xev';
|
||||
|
||||
import Logger from '../services/logger';
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import * as os from 'os';
|
||||
import * as cluster from 'cluster';
|
||||
import chalk from 'chalk';
|
||||
import * as chalk from 'chalk';
|
||||
import * as portscanner from 'portscanner';
|
||||
import * as isRoot from 'is-root';
|
||||
|
||||
@@ -8,10 +8,10 @@ import Logger from '../services/logger';
|
||||
import loadConfig from '../config/load';
|
||||
import { Config } from '../config/types';
|
||||
import { lessThan } from '../prelude/array';
|
||||
import * as pkg from '../../package.json';
|
||||
import { program } from '../argv';
|
||||
import { showMachineInfo } from '../misc/show-machine-info';
|
||||
import { initDb } from '../db/postgre';
|
||||
import * as meta from '../meta.json';
|
||||
|
||||
const logger = new Logger('core', 'cyan');
|
||||
const bootLogger = logger.createSubLogger('boot', 'magenta', false);
|
||||
@@ -19,7 +19,7 @@ const bootLogger = logger.createSubLogger('boot', 'magenta', false);
|
||||
function greet() {
|
||||
if (!program.quiet) {
|
||||
//#region Misskey logo
|
||||
const v = `v${pkg.version}`;
|
||||
const v = `v${meta.version}`;
|
||||
console.log(' _____ _ _ ');
|
||||
console.log(' | |_|___ ___| |_ ___ _ _ ');
|
||||
console.log(' | | | | |_ -|_ -| \'_| -_| | |');
|
||||
@@ -35,18 +35,18 @@ function greet() {
|
||||
}
|
||||
|
||||
bootLogger.info('Welcome to Misskey!');
|
||||
bootLogger.info(`Misskey v${pkg.version}`, null, true);
|
||||
bootLogger.info(`Misskey v${meta.version}`, null, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Init master process
|
||||
*/
|
||||
export async function masterMain() {
|
||||
greet();
|
||||
|
||||
let config!: Config;
|
||||
|
||||
try {
|
||||
greet();
|
||||
|
||||
// initialize app
|
||||
config = await init();
|
||||
|
||||
|
@@ -115,7 +115,6 @@ export default Vue.extend({
|
||||
connection: null,
|
||||
meta: null,
|
||||
instances: [],
|
||||
clock: null,
|
||||
faDatabase
|
||||
};
|
||||
},
|
||||
@@ -124,7 +123,6 @@ export default Vue.extend({
|
||||
this.connection = this.$root.stream.useSharedConnection('serverStats');
|
||||
|
||||
this.updateStats();
|
||||
this.clock = setInterval(this.updateStats, 3000);
|
||||
|
||||
this.$root.getMeta().then(meta => {
|
||||
this.meta = meta;
|
||||
@@ -145,7 +143,6 @@ export default Vue.extend({
|
||||
|
||||
beforeDestroy() {
|
||||
this.connection.dispose();
|
||||
clearInterval(this.clock);
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
@@ -8,6 +8,9 @@
|
||||
<span>{{ $t('add-emoji.name') }}</span>
|
||||
<template #desc>{{ $t('add-emoji.name-desc') }}</template>
|
||||
</ui-input>
|
||||
<ui-input v-model="category" :datalist="categoryList">
|
||||
<span>{{ $t('add-emoji.category') }}</span>
|
||||
</ui-input>
|
||||
<ui-input v-model="aliases">
|
||||
<span>{{ $t('add-emoji.aliases') }}</span>
|
||||
<template #desc>{{ $t('add-emoji.aliases-desc') }}</template>
|
||||
@@ -24,7 +27,7 @@
|
||||
|
||||
<ui-card>
|
||||
<template #title><fa :icon="faGrin"/> {{ $t('emojis.title') }}</template>
|
||||
<section v-for="emoji in emojis" class="oryfrbft">
|
||||
<section v-for="emoji in emojis" :key="emoji.name" class="oryfrbft">
|
||||
<div>
|
||||
<img :src="emoji.url" :alt="emoji.name" style="width: 64px;"/>
|
||||
</div>
|
||||
@@ -33,6 +36,9 @@
|
||||
<ui-input v-model="emoji.name">
|
||||
<span>{{ $t('add-emoji.name') }}</span>
|
||||
</ui-input>
|
||||
<ui-input v-model="emoji.category" :datalist="categoryList">
|
||||
<span>{{ $t('add-emoji.category') }}</span>
|
||||
</ui-input>
|
||||
<ui-input v-model="emoji.aliases">
|
||||
<span>{{ $t('add-emoji.aliases') }}</span>
|
||||
</ui-input>
|
||||
@@ -55,12 +61,14 @@
|
||||
import Vue from 'vue';
|
||||
import i18n from '../../i18n';
|
||||
import { faGrin } from '@fortawesome/free-regular-svg-icons';
|
||||
import { unique } from '../../../../prelude/array';
|
||||
|
||||
export default Vue.extend({
|
||||
i18n: i18n('admin/views/emoji.vue'),
|
||||
data() {
|
||||
return {
|
||||
name: '',
|
||||
category: '',
|
||||
url: '',
|
||||
aliases: '',
|
||||
emojis: [],
|
||||
@@ -72,10 +80,17 @@ export default Vue.extend({
|
||||
this.fetchEmojis();
|
||||
},
|
||||
|
||||
computed: {
|
||||
categoryList() {
|
||||
return unique(this.emojis.map((x: any) => x.category || '').filter((x: string) => x !== ''));
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
add() {
|
||||
this.$root.api('admin/emoji/add', {
|
||||
name: this.name,
|
||||
category: this.category,
|
||||
url: this.url,
|
||||
aliases: this.aliases.split(' ').filter(x => x.length > 0)
|
||||
}).then(() => {
|
||||
@@ -94,7 +109,6 @@ export default Vue.extend({
|
||||
|
||||
fetchEmojis() {
|
||||
this.$root.api('admin/emoji/list').then(emojis => {
|
||||
emojis.reverse();
|
||||
for (const e of emojis) {
|
||||
e.aliases = (e.aliases || []).join(' ');
|
||||
}
|
||||
@@ -106,6 +120,7 @@ export default Vue.extend({
|
||||
this.$root.api('admin/emoji/update', {
|
||||
id: emoji.id,
|
||||
name: emoji.name,
|
||||
category: emoji.category,
|
||||
url: emoji.url,
|
||||
aliases: emoji.aliases.split(' ').filter(x => x.length > 0)
|
||||
}).then(() => {
|
||||
|
@@ -509,7 +509,7 @@ export default Vue.extend({
|
||||
|
||||
saveBlockedHosts() {
|
||||
this.$root.api('admin/update-meta', {
|
||||
blockedHosts: this.blockedHosts.split('\n')
|
||||
blockedHosts: this.blockedHosts ? this.blockedHosts.split('\n') : []
|
||||
}).then(() => {
|
||||
this.$root.dialog({
|
||||
type: 'success',
|
||||
|
@@ -81,6 +81,7 @@
|
||||
</section>
|
||||
<section>
|
||||
<ui-switch v-model="cacheRemoteFiles">{{ $t('cache-remote-files') }}<template #desc>{{ $t('cache-remote-files-desc') }}</template></ui-switch>
|
||||
<ui-switch v-model="proxyRemoteFiles">{{ $t('proxy-remote-files') }}<template #desc>{{ $t('proxy-remote-files-desc') }}</template></ui-switch>
|
||||
</section>
|
||||
<section class="fit-top fit-bottom">
|
||||
<ui-input v-model="localDriveCapacityMb" type="number">{{ $t('local-drive-capacity-mb') }}<template #suffix>MB</template><template #desc>{{ $t('mb') }}</template></ui-input>
|
||||
@@ -275,6 +276,7 @@ export default Vue.extend({
|
||||
description: null,
|
||||
languages: null,
|
||||
cacheRemoteFiles: false,
|
||||
proxyRemoteFiles: false,
|
||||
localDriveCapacityMb: null,
|
||||
remoteDriveCapacityMb: null,
|
||||
maxNoteTextLength: null,
|
||||
@@ -339,6 +341,7 @@ export default Vue.extend({
|
||||
this.description = meta.description;
|
||||
this.languages = meta.langs.join(' ');
|
||||
this.cacheRemoteFiles = meta.cacheRemoteFiles;
|
||||
this.proxyRemoteFiles = meta.proxyRemoteFiles;
|
||||
this.localDriveCapacityMb = meta.driveCapacityPerLocalUserMb;
|
||||
this.remoteDriveCapacityMb = meta.driveCapacityPerRemoteUserMb;
|
||||
this.maxNoteTextLength = meta.maxNoteTextLength;
|
||||
@@ -461,8 +464,9 @@ export default Vue.extend({
|
||||
iconUrl: this.iconUrl,
|
||||
name: this.name,
|
||||
description: this.description,
|
||||
langs: this.languages.split(' '),
|
||||
langs: this.languages ? this.languages.split(' ') : [],
|
||||
cacheRemoteFiles: this.cacheRemoteFiles,
|
||||
proxyRemoteFiles: this.proxyRemoteFiles,
|
||||
localDriveCapacityMb: parseInt(this.localDriveCapacityMb, 10),
|
||||
remoteDriveCapacityMb: parseInt(this.remoteDriveCapacityMb, 10),
|
||||
maxNoteTextLength: parseInt(this.maxNoteTextLength, 10),
|
||||
@@ -490,8 +494,8 @@ export default Vue.extend({
|
||||
enableServiceWorker: this.enableServiceWorker,
|
||||
swPublicKey: this.swPublicKey,
|
||||
swPrivateKey: this.swPrivateKey,
|
||||
pinnedUsers: this.pinnedUsers.split('\n'),
|
||||
hiddenTags: this.hiddenTags.split('\n'),
|
||||
pinnedUsers: this.pinnedUsers ? this.pinnedUsers.split('\n') : [],
|
||||
hiddenTags: this.hiddenTags ? this.hiddenTags.split('\n') : [],
|
||||
useObjectStorage: this.useObjectStorage,
|
||||
objectStorageBaseUrl: this.objectStorageBaseUrl ? this.objectStorageBaseUrl : null,
|
||||
objectStorageBucket: this.objectStorageBucket ? this.objectStorageBucket : null,
|
||||
|
@@ -48,14 +48,15 @@
|
||||
</ui-select>
|
||||
</ui-horizon-group>
|
||||
<sequential-entrance animation="entranceFromTop" delay="25">
|
||||
<div class="xvvuvgsv" v-for="job in jobs">
|
||||
<div class="xvvuvgsv" v-for="job in jobs" :key="job.id">
|
||||
<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>
|
||||
<span>{{ job.data.activity.id }}</span>
|
||||
</template>
|
||||
<span>{{ `(${job.attempts}/${job.maxAttempts}, ${Math.floor((jobsFetched - job.timestamp) / 1000 / 60)}min)` }}</span>
|
||||
</div>
|
||||
</sequential-entrance>
|
||||
<ui-info v-if="jobs.length == jobsLimit">{{ $t('result-is-truncated', { n: jobsLimit }) }}</ui-info>
|
||||
@@ -84,6 +85,7 @@ export default Vue.extend({
|
||||
chartLimit: 200,
|
||||
jobs: [],
|
||||
jobsLimit: 50,
|
||||
jobsFetched: Date.now(),
|
||||
domain: 'deliver',
|
||||
state: 'delayed',
|
||||
faTasks, faPaperPlane, faInbox, faChartBar, faDatabase, faCloud
|
||||
@@ -140,6 +142,7 @@ export default Vue.extend({
|
||||
state: this.state,
|
||||
limit: this.jobsLimit
|
||||
}).then(jobs => {
|
||||
this.jobsFetched = Date.now(),
|
||||
this.jobs = jobs;
|
||||
});
|
||||
},
|
||||
@@ -149,7 +152,8 @@ export default Vue.extend({
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
.xvvuvgsv
|
||||
> b
|
||||
margin-right 16px
|
||||
margin-left -6px
|
||||
> b, span
|
||||
margin 0 6px
|
||||
|
||||
</style>
|
||||
|
@@ -42,6 +42,7 @@
|
||||
<ui-select v-model="state">
|
||||
<template #label>{{ $t('users.state.title') }}</template>
|
||||
<option value="all">{{ $t('users.state.all') }}</option>
|
||||
<option value="available">{{ $t('users.state.available') }}</option>
|
||||
<option value="admin">{{ $t('users.state.admin') }}</option>
|
||||
<option value="moderator">{{ $t('users.state.moderator') }}</option>
|
||||
<option value="silenced">{{ $t('users.state.silenced') }}</option>
|
||||
|
@@ -72,13 +72,17 @@
|
||||
//#region Fetch locale data
|
||||
const cachedLocale = localStorage.getItem('locale');
|
||||
const localeKey = localStorage.getItem('localeKey');
|
||||
let localeData = null;
|
||||
|
||||
if (cachedLocale == null || localeKey != `${ver}.${lang}`) {
|
||||
const locale = await fetch(`/assets/locales/${lang}.json?ver=${ver}`)
|
||||
.then(response => response.json());
|
||||
localeData = locale;
|
||||
|
||||
localStorage.setItem('locale', JSON.stringify(locale));
|
||||
localStorage.setItem('localeKey', `${ver}.${lang}`);
|
||||
} else {
|
||||
localeData = JSON.parse(cachedLocale);
|
||||
}
|
||||
//#endregion
|
||||
|
||||
@@ -98,15 +102,9 @@
|
||||
|
||||
// If mobile, insert the viewport meta tag
|
||||
if (isMobile) {
|
||||
const meta = document.createElement('meta');
|
||||
meta.setAttribute('name', 'viewport');
|
||||
meta.setAttribute('content',
|
||||
'width=device-width,' +
|
||||
'initial-scale=1,' +
|
||||
'minimum-scale=1,' +
|
||||
'maximum-scale=1,' +
|
||||
'user-scalable=no');
|
||||
head.appendChild(meta);
|
||||
const viewport = document.getElementsByName("viewport").item(0);
|
||||
viewport.content = `${viewport.content},minimum-scale=1,maximum-scale=1,user-scalable=no`;
|
||||
head.appendChild(viewport);
|
||||
}
|
||||
|
||||
// Switch desktop or mobile version
|
||||
@@ -118,9 +116,9 @@
|
||||
// Note: 'async' make it possible to load the script asyncly.
|
||||
// 'defer' make it possible to run the script when the dom loaded.
|
||||
const script = document.createElement('script');
|
||||
script.setAttribute('src', `/assets/${app}.${ver}.js`);
|
||||
script.setAttribute('async', 'true');
|
||||
script.setAttribute('defer', 'true');
|
||||
script.src = `/assets/${app}.${ver}.js`;
|
||||
script.async = true;
|
||||
script.defer = true;
|
||||
head.appendChild(script);
|
||||
|
||||
// 3秒経ってもスクリプトがロードされない場合はバージョンが古くて
|
||||
@@ -143,10 +141,10 @@
|
||||
localStorage.setItem('v', meta.version);
|
||||
|
||||
alert(
|
||||
'Misskeyの新しいバージョンがあります。ページを再度読み込みします。' +
|
||||
'\n\n' +
|
||||
'New version of Misskey available. The page will be reloaded.');
|
||||
|
||||
localeData.common._settings["update-available"] +
|
||||
'\n' +
|
||||
localeData.common._settings["update-available-desc"]
|
||||
);
|
||||
refresh();
|
||||
}
|
||||
}, 3000);
|
||||
|
@@ -43,7 +43,7 @@ export default (opts: Opts = {}) => ({
|
||||
'ctrl+q': this.renoteDirectly,
|
||||
'up|k|shift+tab': this.focusBefore,
|
||||
'down|j|tab': this.focusAfter,
|
||||
'esc': this.blur,
|
||||
//'esc': this.blur,
|
||||
'm|o': () => this.menu(true),
|
||||
's': this.toggleShowContent,
|
||||
'1': () => this.reactDirectly('like'),
|
||||
@@ -143,12 +143,20 @@ export default (opts: Opts = {}) => ({
|
||||
react(viaKeyboard = false) {
|
||||
pleaseLogin(this.$root);
|
||||
this.blur();
|
||||
this.$root.new(MkReactionPicker, {
|
||||
const w = this.$root.new(MkReactionPicker, {
|
||||
source: this.$refs.reactButton,
|
||||
note: this.appearNote,
|
||||
showFocus: viaKeyboard,
|
||||
animation: !viaKeyboard
|
||||
}).$once('closed', this.focus);
|
||||
});
|
||||
w.$once('chosen', reaction => {
|
||||
this.$root.api('notes/reactions/create', {
|
||||
noteId: this.appearNote.id,
|
||||
reaction: reaction
|
||||
}).then(() => {
|
||||
w.close();
|
||||
});
|
||||
});
|
||||
w.$once('closed', this.focus);
|
||||
},
|
||||
|
||||
reactDirectly(reaction) {
|
||||
@@ -195,7 +203,7 @@ export default (opts: Opts = {}) => ({
|
||||
menu(viaKeyboard = false) {
|
||||
if (this.openingMenu) return;
|
||||
this.openingMenu = true;
|
||||
this.$root.new(MkNoteMenu, {
|
||||
const w = this.$root.new(MkNoteMenu, {
|
||||
source: this.$refs.menuButton,
|
||||
note: this.appearNote,
|
||||
animation: !viaKeyboard
|
||||
@@ -203,6 +211,9 @@ export default (opts: Opts = {}) => ({
|
||||
this.openingMenu = false;
|
||||
this.focus();
|
||||
});
|
||||
this.$once('hook:beforeDestroy', () => {
|
||||
w.destroyDom();
|
||||
});
|
||||
},
|
||||
|
||||
toggleShowContent() {
|
||||
|
@@ -328,6 +328,9 @@ export default (opts) => ({
|
||||
w.$once('chosen', v => {
|
||||
this.applyVisibility(v);
|
||||
});
|
||||
this.$once('hook:beforeDestroy', () => {
|
||||
w.close();
|
||||
});
|
||||
},
|
||||
|
||||
applyVisibility(v: string) {
|
||||
@@ -457,6 +460,9 @@ export default (opts) => ({
|
||||
vm.$once('chosen', emoji => {
|
||||
insertTextAtCursor(this.$refs.text, emoji);
|
||||
});
|
||||
this.$once('hook:beforeDestroy', () => {
|
||||
vm.close();
|
||||
});
|
||||
},
|
||||
|
||||
saveDraft() {
|
||||
|
@@ -28,9 +28,9 @@
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import * as emojilib from 'emojilib';
|
||||
import { emojilist } from '../../../../../misc/emojilist';
|
||||
import contains from '../../../common/scripts/contains';
|
||||
import { twemojiBase } from '../../../../../misc/twemoji-base';
|
||||
import { twemojiSvgBase } from '../../../../../misc/twemoji-base';
|
||||
import { getStaticImageUrl } from '../../../common/scripts/get-static-image-url';
|
||||
|
||||
type EmojiDef = {
|
||||
@@ -41,9 +41,7 @@ type EmojiDef = {
|
||||
isCustomEmoji?: boolean;
|
||||
};
|
||||
|
||||
const lib = Object.entries(emojilib.lib).filter((x: any) => {
|
||||
return x[1].category != 'flags';
|
||||
});
|
||||
const lib = emojilist.filter(x => x.category !== 'flags');
|
||||
|
||||
const char2file = (char: string) => {
|
||||
let codes = Array.from(char).map(x => x.codePointAt(0).toString(16));
|
||||
@@ -52,21 +50,21 @@ const char2file = (char: string) => {
|
||||
return codes.join('-');
|
||||
};
|
||||
|
||||
const emjdb: EmojiDef[] = lib.map((x: any) => ({
|
||||
emoji: x[1].char,
|
||||
name: x[0],
|
||||
const emjdb: EmojiDef[] = lib.map(x => ({
|
||||
emoji: x.char,
|
||||
name: x.name,
|
||||
aliasOf: null,
|
||||
url: `${twemojiBase}/2/svg/${char2file(x[1].char)}.svg`
|
||||
url: `${twemojiSvgBase}/${char2file(x.char)}.svg`
|
||||
}));
|
||||
|
||||
for (const x of lib as any) {
|
||||
if (x[1].keywords) {
|
||||
for (const k of x[1].keywords) {
|
||||
for (const x of lib) {
|
||||
if (x.keywords) {
|
||||
for (const k of x.keywords) {
|
||||
emjdb.push({
|
||||
emoji: x[1].char,
|
||||
emoji: x.char,
|
||||
name: k,
|
||||
aliasOf: x[0],
|
||||
url: `${twemojiBase}/2/svg/${char2file(x[1].char)}.svg`
|
||||
aliasOf: x.name,
|
||||
url: `${twemojiSvgBase}/${char2file(x.char)}.svg`
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -85,7 +83,7 @@ export default Vue.extend({
|
||||
hashtags: [],
|
||||
emojis: [],
|
||||
select: -1,
|
||||
emojilib,
|
||||
emojilist,
|
||||
emojiDb: [] as EmojiDef[]
|
||||
}
|
||||
},
|
||||
|
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="mk-connect-failed">
|
||||
<img src="https://raw.githubusercontent.com/syuilo/misskey/develop/src/client/assets/error.jpg" alt=""/>
|
||||
<img src="/assets/error.jpg" onerror="this.src='https://raw.githubusercontent.com/syuilo/misskey/develop/src/client/assets/error.jpg';" alt=""/>
|
||||
<h1>{{ $t('title') }}</h1>
|
||||
<p class="text">
|
||||
<span>{{ this.$t('description').substr(0, this.$t('description').indexOf('{')) }}</span>
|
||||
|
@@ -1,6 +1,12 @@
|
||||
<template>
|
||||
<div class="felqjxyj" :class="{ splash }">
|
||||
<div class="bg" ref="bg" @click="onBgClick"></div>
|
||||
<ui-modal
|
||||
ref="modal"
|
||||
class="modal"
|
||||
:class="{ splash }"
|
||||
:close-anime-duration="300"
|
||||
:close-on-bg-click="false"
|
||||
@bg-click="onBgClick"
|
||||
@before-close="onBeforeClose">
|
||||
<div class="main" ref="main" :class="{ round: $store.state.device.roundedCorners }">
|
||||
<template v-if="type == 'signin'">
|
||||
<mk-signin/>
|
||||
@@ -38,7 +44,7 @@
|
||||
</ui-horizon-group>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</ui-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
@@ -120,14 +126,6 @@ export default Vue.extend({
|
||||
if (this.user) this.canOk = false;
|
||||
|
||||
this.$nextTick(() => {
|
||||
(this.$refs.bg as any).style.pointerEvents = 'auto';
|
||||
anime({
|
||||
targets: this.$refs.bg,
|
||||
opacity: 1,
|
||||
duration: 100,
|
||||
easing: 'linear'
|
||||
});
|
||||
|
||||
anime({
|
||||
targets: this.$refs.main,
|
||||
opacity: 1,
|
||||
@@ -170,33 +168,27 @@ export default Vue.extend({
|
||||
this.close();
|
||||
},
|
||||
|
||||
onBgClick() {
|
||||
if (this.cancelableByBgClick) this.cancel();
|
||||
}
|
||||
|
||||
close() {
|
||||
this.$refs.modal.close();
|
||||
},
|
||||
|
||||
onBeforeClose() {
|
||||
this.$el.style.pointerEvents = 'none';
|
||||
(this.$refs.bg as any).style.pointerEvents = 'none';
|
||||
(this.$refs.main as any).style.pointerEvents = 'none';
|
||||
|
||||
anime({
|
||||
targets: this.$refs.bg,
|
||||
opacity: 0,
|
||||
duration: 300,
|
||||
easing: 'linear'
|
||||
});
|
||||
anime({
|
||||
targets: this.$refs.main,
|
||||
opacity: 0,
|
||||
scale: 0.8,
|
||||
duration: 300,
|
||||
easing: 'cubicBezier(0, 0.5, 0.5, 1)',
|
||||
complete: () => this.destroyDom()
|
||||
});
|
||||
},
|
||||
|
||||
onBgClick() {
|
||||
if (this.cancelableByBgClick) {
|
||||
this.cancel();
|
||||
}
|
||||
},
|
||||
|
||||
onInputKeydown(e) {
|
||||
if (e.which == 13) { // Enter
|
||||
e.preventDefault();
|
||||
@@ -209,34 +201,17 @@ export default Vue.extend({
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
.felqjxyj
|
||||
.modal
|
||||
display flex
|
||||
align-items center
|
||||
justify-content center
|
||||
position fixed
|
||||
z-index 30000
|
||||
top 0
|
||||
left 0
|
||||
width 100%
|
||||
height 100%
|
||||
|
||||
&.splash
|
||||
> .main
|
||||
min-width 0
|
||||
width initial
|
||||
|
||||
> .bg
|
||||
display block
|
||||
position fixed
|
||||
top 0
|
||||
left 0
|
||||
width 100%
|
||||
height 100%
|
||||
background rgba(#000, 0.7)
|
||||
opacity 0
|
||||
pointer-events none
|
||||
|
||||
> .main
|
||||
.main
|
||||
display block
|
||||
position fixed
|
||||
margin auto
|
||||
|
@@ -5,29 +5,52 @@
|
||||
:title="category.text"
|
||||
@click="go(category)"
|
||||
:class="{ active: category.isActive }"
|
||||
:key="category.text"
|
||||
>
|
||||
<fa :icon="category.icon" fixed-width/>
|
||||
</button>
|
||||
</header>
|
||||
<div class="emojis">
|
||||
<header><fa :icon="categories.find(x => x.isActive).icon" fixed-width/> {{ categories.find(x => x.isActive).text }}</header>
|
||||
<div v-if="categories.find(x => x.isActive).name">
|
||||
<button v-for="emoji in Object.entries(lib).filter(([k, v]) => v.category === categories.find(x => x.isActive).name)"
|
||||
:title="emoji[0]"
|
||||
@click="chosen(emoji[1].char)"
|
||||
:key="emoji[0]"
|
||||
>
|
||||
<mk-emoji :emoji="emoji[1].char"/>
|
||||
</button>
|
||||
</div>
|
||||
<div v-else>
|
||||
<button v-for="emoji in customEmojis"
|
||||
<template v-if="categories[0].isActive">
|
||||
<header class="category"><fa :icon="faHistory" fixed-width/> {{ $t('recent-emoji') }}</header>
|
||||
<div class="list">
|
||||
<button v-for="(emoji, i) in ($store.state.device.recentEmojis || [])"
|
||||
:title="emoji.name"
|
||||
@click="chosen(`:${emoji.name}:`)"
|
||||
@click="chosen(emoji)"
|
||||
:key="i"
|
||||
>
|
||||
<img :src="emoji.url" :alt="emoji.name"/>
|
||||
<mk-emoji v-if="emoji.char != null" :emoji="emoji.char"/>
|
||||
<img v-else :src="$store.state.device.disableShowingAnimatedImages ? getStaticImageUrl(emoji.url) : emoji.url"/>
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<header class="category"><fa :icon="categories.find(x => x.isActive).icon" fixed-width/> {{ categories.find(x => x.isActive).text }}</header>
|
||||
<template v-if="categories.find(x => x.isActive).name">
|
||||
<div class="list">
|
||||
<button v-for="emoji in emojilist.filter(e => e.category === categories.find(x => x.isActive).name)"
|
||||
:title="emoji.name"
|
||||
@click="chosen(emoji)"
|
||||
:key="emoji.name"
|
||||
>
|
||||
<mk-emoji :emoji="emoji.char"/>
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div v-for="(key, i) in Object.keys(customEmojis)" :key="i">
|
||||
<header class="sub">{{ key || $t('no-category') }}</header>
|
||||
<div class="list">
|
||||
<button v-for="emoji in customEmojis[key]"
|
||||
:title="emoji.name"
|
||||
@click="chosen(emoji)"
|
||||
:key="emoji.name"
|
||||
>
|
||||
<img :src="$store.state.device.disableShowingAnimatedImages ? getStaticImageUrl(emoji.url) : emoji.url"/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -35,17 +58,21 @@
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import i18n from '../../../i18n';
|
||||
import { lib } from 'emojilib';
|
||||
import { faAsterisk, faLeaf, faUtensils, faFutbol, faCity, faDice } from '@fortawesome/free-solid-svg-icons';
|
||||
import { emojilist } from '../../../../../misc/emojilist';
|
||||
import { getStaticImageUrl } from '../../../common/scripts/get-static-image-url';
|
||||
import { faAsterisk, faLeaf, faUtensils, faFutbol, faCity, faDice, faGlobe, faHistory } from '@fortawesome/free-solid-svg-icons';
|
||||
import { faHeart, faFlag } from '@fortawesome/free-regular-svg-icons';
|
||||
import { groupByX } from '../../../../../prelude/array';
|
||||
|
||||
export default Vue.extend({
|
||||
i18n: i18n('common/views/components/emoji-picker.vue'),
|
||||
|
||||
data() {
|
||||
return {
|
||||
lib,
|
||||
customEmojis: [],
|
||||
emojilist,
|
||||
getStaticImageUrl,
|
||||
customEmojis: {},
|
||||
faGlobe, faHistory,
|
||||
categories: [{
|
||||
text: this.$t('custom-emoji'),
|
||||
icon: faAsterisk,
|
||||
@@ -95,18 +122,43 @@ export default Vue.extend({
|
||||
},
|
||||
|
||||
created() {
|
||||
this.customEmojis = (this.$root.getMetaSync() || { emojis: [] }).emojis || [];
|
||||
},
|
||||
let local = (this.$root.getMetaSync() || { emojis: [] }).emojis || [];
|
||||
local = groupByX(local, (x: any) => x.category || '');
|
||||
this.customEmojis = local;
|
||||
|
||||
methods: {
|
||||
go(category) {
|
||||
for (const c of this.categories) {
|
||||
c.isActive = c.name === category.name;
|
||||
if (this.$store.state.device.activeEmojiCategoryName) {
|
||||
this.goCategory(this.$store.state.device.activeEmojiCategoryName);
|
||||
}
|
||||
},
|
||||
|
||||
chosen(emoji) {
|
||||
this.$emit('chosen', emoji);
|
||||
methods: {
|
||||
go(category: any) {
|
||||
this.goCategory(category.name);
|
||||
},
|
||||
|
||||
goCategory(name: string) {
|
||||
let matched = false;
|
||||
for (const c of this.categories) {
|
||||
c.isActive = c.name === name;
|
||||
if (c.isActive) {
|
||||
matched = true;
|
||||
this.$store.commit('device/set', { key: 'activeEmojiCategoryName', value: c.name });
|
||||
}
|
||||
}
|
||||
if (!matched) {
|
||||
this.categories[0].isActive = true;
|
||||
}
|
||||
},
|
||||
|
||||
chosen(emoji: any) {
|
||||
const getKey = (emoji: any) => emoji.char || `:${emoji.name}:`;
|
||||
|
||||
let recents = this.$store.state.device.recentEmojis || [];
|
||||
recents = recents.filter((e: any) => getKey(e) !== getKey(emoji));
|
||||
recents.unshift(emoji)
|
||||
this.$store.commit('device/set', { key: 'recentEmojis', value: recents.splice(0, 16) });
|
||||
|
||||
this.$emit('chosen', getKey(emoji));
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -140,7 +192,7 @@ export default Vue.extend({
|
||||
overflow-y auto
|
||||
overflow-x hidden
|
||||
|
||||
> header
|
||||
> header.category
|
||||
position sticky
|
||||
top 0
|
||||
left 0
|
||||
@@ -150,7 +202,12 @@ export default Vue.extend({
|
||||
color var(--text)
|
||||
font-size 12px
|
||||
|
||||
> div
|
||||
>>> header.sub
|
||||
padding 4px 8px
|
||||
color var(--text)
|
||||
font-size 12px
|
||||
|
||||
>>> div.list
|
||||
display grid
|
||||
grid-template-columns 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr
|
||||
gap 4px
|
||||
@@ -178,6 +235,7 @@ export default Vue.extend({
|
||||
left 0
|
||||
width 100%
|
||||
height 100%
|
||||
object-fit contain
|
||||
font-size 28px
|
||||
transition transform 0.2s ease
|
||||
pointer-events none
|
||||
|
@@ -7,10 +7,8 @@
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
// スクリプトサイズがデカい
|
||||
//import { lib } from 'emojilib';
|
||||
import { getStaticImageUrl } from '../../../common/scripts/get-static-image-url';
|
||||
import { twemojiBase } from '../../../../../misc/twemoji-base';
|
||||
import { twemojiSvgBase } from '../../../../../misc/twemoji-base';
|
||||
|
||||
export default Vue.extend({
|
||||
props: {
|
||||
@@ -92,7 +90,7 @@ export default Vue.extend({
|
||||
if (!codes.includes('200d')) codes = codes.filter(x => x != 'fe0f');
|
||||
codes = codes.filter(x => x && x.length);
|
||||
|
||||
this.url = `${twemojiBase}/2/svg/${codes.join('-')}.svg`;
|
||||
this.url = `${twemojiSvgBase}/${codes.join('-')}.svg`;
|
||||
}
|
||||
},
|
||||
});
|
||||
|
49
src/client/app/common/views/components/frac.vue
Normal file
49
src/client/app/common/views/components/frac.vue
Normal file
@@ -0,0 +1,49 @@
|
||||
<template>
|
||||
<span class="mk-frac"><span>{{ pad }}</span><span>{{ value }} / {{ total }}</span></span>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import i18n from '../../../i18n';
|
||||
|
||||
export default Vue.extend({
|
||||
i18n: i18n(),
|
||||
props: {
|
||||
value: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
total: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
pad(this: {
|
||||
value: number;
|
||||
total: number;
|
||||
length(value: number): number;
|
||||
}) {
|
||||
return '0'.repeat(this.length(this.total) - this.length(this.value));
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
length(value: number) {
|
||||
const string = value.toString();
|
||||
|
||||
return string.includes('e') ? -~string.substr(string.indexOf('e')) : string.length;
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
.mk-frac
|
||||
-webkit-font-feature-settings 'tnum'
|
||||
-moz-font-feature-settings 'tnum'
|
||||
font-feature-settings 'tnum'
|
||||
font-variant-numeric tabular-nums
|
||||
|
||||
> :first-child
|
||||
visibility hidden
|
||||
</style>
|
@@ -1,60 +1,31 @@
|
||||
<template>
|
||||
<div class="dkjvrdxtkvqrwmhfickhndpmnncsgacq">
|
||||
<div class="bg" @click="close"></div>
|
||||
<img :src="image.url" :alt="image.name" :title="image.name" @click="close"/>
|
||||
</div>
|
||||
<ui-modal ref="modal" v-hotkey.global="keymap">
|
||||
<img :src="image.url" :alt="image.name" :title="image.name" @click="close" />
|
||||
</ui-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import anime from 'animejs';
|
||||
|
||||
export default Vue.extend({
|
||||
props: ['image'],
|
||||
mounted() {
|
||||
anime({
|
||||
targets: this.$el,
|
||||
opacity: 1,
|
||||
duration: 100,
|
||||
easing: 'linear'
|
||||
});
|
||||
computed: {
|
||||
keymap(): any {
|
||||
return {
|
||||
'esc': this.close,
|
||||
};
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
close() {
|
||||
anime({
|
||||
targets: this.$el,
|
||||
opacity: 0,
|
||||
duration: 100,
|
||||
easing: 'linear',
|
||||
complete: () => this.destroyDom()
|
||||
});
|
||||
(this.$refs.modal as any).close();
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
.dkjvrdxtkvqrwmhfickhndpmnncsgacq
|
||||
display block
|
||||
position fixed
|
||||
z-index 2048
|
||||
top 0
|
||||
left 0
|
||||
width 100%
|
||||
height 100%
|
||||
opacity 0
|
||||
|
||||
> .bg
|
||||
display block
|
||||
position fixed
|
||||
z-index 1
|
||||
top 0
|
||||
left 0
|
||||
width 100%
|
||||
height 100%
|
||||
background rgba(#000, 0.7)
|
||||
|
||||
> img
|
||||
img
|
||||
position fixed
|
||||
z-index 2
|
||||
top 0
|
||||
|
@@ -33,6 +33,7 @@ import fileTypeIcon from './file-type-icon.vue';
|
||||
import emoji from './emoji.vue';
|
||||
import welcomeTimeline from './welcome-timeline.vue';
|
||||
import userList from './user-list.vue';
|
||||
import frac from './frac.vue';
|
||||
import uiInput from './ui/input.vue';
|
||||
import uiButton from './ui/button.vue';
|
||||
import uiHorizonGroup from './ui/horizon-group.vue';
|
||||
@@ -46,6 +47,7 @@ import uiInfo from './ui/info.vue';
|
||||
import uiMargin from './ui/margin.vue';
|
||||
import uiHr from './ui/hr.vue';
|
||||
import uiPagination from './ui/pagination.vue';
|
||||
import uiModal from './ui/modal.vue';
|
||||
import formButton from './ui/form/button.vue';
|
||||
import formRadio from './ui/form/radio.vue';
|
||||
|
||||
@@ -82,6 +84,7 @@ Vue.component('mk-file-type-icon', fileTypeIcon);
|
||||
Vue.component('mk-emoji', emoji);
|
||||
Vue.component('mk-welcome-timeline', welcomeTimeline);
|
||||
Vue.component('mk-user-list', userList);
|
||||
Vue.component('mk-frac', frac);
|
||||
Vue.component('ui-input', uiInput);
|
||||
Vue.component('ui-button', uiButton);
|
||||
Vue.component('ui-horizon-group', uiHorizonGroup);
|
||||
@@ -95,5 +98,6 @@ Vue.component('ui-info', uiInfo);
|
||||
Vue.component('ui-margin', uiMargin);
|
||||
Vue.component('ui-hr', uiHr);
|
||||
Vue.component('ui-pagination', uiPagination);
|
||||
Vue.component('ui-modal', uiModal);
|
||||
Vue.component('form-button', formButton);
|
||||
Vue.component('form-radio', formRadio);
|
||||
|
@@ -59,9 +59,12 @@ export default Vue.extend({
|
||||
},
|
||||
methods: {
|
||||
onClick() {
|
||||
this.$root.new(ImageViewer, {
|
||||
const viewer = this.$root.new(ImageViewer, {
|
||||
image: this.image
|
||||
});
|
||||
this.$once('hook:beforeDestroy', () => {
|
||||
viewer.close();
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@@ -42,7 +42,7 @@ export default Vue.extend({
|
||||
},
|
||||
methods: {
|
||||
previewable(file) {
|
||||
return file.type.startsWith('video') || file.type.startsWith('image');
|
||||
return (file.type.startsWith('video') || file.type.startsWith('image')) && file.thumbnailUrl;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@@ -138,7 +138,7 @@ export default Vue.extend({
|
||||
}
|
||||
this.$root.api('users/search', {
|
||||
query: this.q,
|
||||
localOnly: true,
|
||||
localOnly: false,
|
||||
limit: 10,
|
||||
detail: false
|
||||
}).then(users => {
|
||||
|
@@ -19,6 +19,7 @@ export default Vue.extend({
|
||||
|
||||
&.nowrap
|
||||
white-space pre
|
||||
word-wrap normal // https://codeday.me/jp/qa/20190424/690106.html
|
||||
|
||||
>>> .title
|
||||
display block
|
||||
|
@@ -4,16 +4,7 @@
|
||||
<div class="popover" :class="{ isMobile: $root.isMobile }" ref="popover">
|
||||
<p v-if="!$root.isMobile">{{ title }}</p>
|
||||
<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('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('hmm')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="4" :title="$t('@.reactions.hmm')" v-particle><mk-reaction-icon reaction="hmm"/></button>
|
||||
<button @click="react('surprise')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="5" :title="$t('@.reactions.surprise')" v-particle><mk-reaction-icon reaction="surprise"/></button>
|
||||
<button @click="react('congrats')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="6" :title="$t('@.reactions.congrats')" v-particle><mk-reaction-icon reaction="congrats"/></button>
|
||||
<button @click="react('angry')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="7" :title="$t('@.reactions.angry')" v-particle><mk-reaction-icon reaction="angry"/></button>
|
||||
<button @click="react('confused')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="8" :title="$t('@.reactions.confused')" v-particle><mk-reaction-icon reaction="confused"/></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 v-for="(reaction, i) in rs" :key="reaction" @click="react(reaction)" @mouseover="onMouseover" @mouseout="onMouseout" :tabindex="i + 1" :title="/^[a-z]+$/.test(reaction) ? $t('@.reactions.' + reaction) : reaction" v-particle><mk-reaction-icon :reaction="reaction"/></button>
|
||||
</div>
|
||||
<div v-if="enableEmojiReaction" class="text">
|
||||
<input v-model="text" :placeholder="$t('input-reaction-placeholder')" @keyup.enter="reactText" @input="tryReactText" v-autocomplete="{ model: 'text' }">
|
||||
@@ -31,16 +22,11 @@ import { emojiRegex } from '../../../../../misc/emoji-regex';
|
||||
export default Vue.extend({
|
||||
i18n: i18n('common/views/components/reaction-picker.vue'),
|
||||
props: {
|
||||
note: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
|
||||
source: {
|
||||
required: true
|
||||
},
|
||||
|
||||
cb: {
|
||||
reactions: {
|
||||
required: false
|
||||
},
|
||||
|
||||
@@ -59,6 +45,7 @@ export default Vue.extend({
|
||||
|
||||
data() {
|
||||
return {
|
||||
rs: this.reactions || this.$store.state.settings.reactions,
|
||||
title: this.$t('choose-reaction'),
|
||||
text: null,
|
||||
enableEmojiReaction: false,
|
||||
@@ -143,14 +130,7 @@ export default Vue.extend({
|
||||
|
||||
methods: {
|
||||
react(reaction) {
|
||||
this.$root.api('notes/reactions/create', {
|
||||
noteId: this.note.id,
|
||||
reaction: reaction
|
||||
}).then(() => {
|
||||
if (this.cb) this.cb();
|
||||
this.$emit('closed');
|
||||
this.destroyDom();
|
||||
});
|
||||
this.$emit('chosen', reaction);
|
||||
},
|
||||
|
||||
reactText() {
|
||||
|
@@ -0,0 +1,39 @@
|
||||
<template>
|
||||
<div class="muteblockuser">
|
||||
<div class="avatar-link">
|
||||
<a :href="user | userPage(null, true)">
|
||||
<mk-avatar class="avatar" :user="user" :disable-link="true"/>
|
||||
</a>
|
||||
</div>
|
||||
<div class="text">
|
||||
<div><mk-user-name :user="user"/></div>
|
||||
<div class="username">@{{ user | acct }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import i18n from '../../../../i18n';
|
||||
|
||||
export default Vue.extend({
|
||||
i18n: i18n('common/views/components/mute-and-block.user.vue'),
|
||||
props: ['user'],
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
.muteblockuser
|
||||
display flex
|
||||
padding 16px
|
||||
|
||||
> .avatar-link
|
||||
> a
|
||||
> .avatar
|
||||
width 40px
|
||||
height 40px
|
||||
|
||||
> .text
|
||||
color var(--text)
|
||||
margin-left 16px
|
||||
</style>
|
@@ -6,9 +6,13 @@
|
||||
<header>{{ $t('mute') }}</header>
|
||||
<ui-info v-if="!muteFetching && mute.length == 0">{{ $t('no-muted-users') }}</ui-info>
|
||||
<div class="users" v-if="mute.length != 0">
|
||||
<div v-for="user in mute" :key="user.id">
|
||||
<p><b><mk-user-name :user="user"/></b> @{{ user | acct }}</p>
|
||||
<div class="user" v-for="user in mute" :key="user.id">
|
||||
<x-user :user="user"/>
|
||||
<span @click="unmute(user)">
|
||||
<fa icon="times"/>
|
||||
</span>
|
||||
</div>
|
||||
<ui-button v-if="this.muteCursor != null" @click="updateMute()">{{ $t('@.load-more') }}</ui-button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -16,9 +20,13 @@
|
||||
<header>{{ $t('block') }}</header>
|
||||
<ui-info v-if="!blockFetching && block.length == 0">{{ $t('no-blocked-users') }}</ui-info>
|
||||
<div class="users" v-if="block.length != 0">
|
||||
<div v-for="user in block" :key="user.id">
|
||||
<p><b><mk-user-name :user="user"/></b> @{{ user | acct }}</p>
|
||||
<div class="user" v-for="user in block" :key="user.id">
|
||||
<x-user :user="user"/>
|
||||
<span @click="unblock(user)">
|
||||
<fa icon="times"/>
|
||||
</span>
|
||||
</div>
|
||||
<ui-button v-if="this.blockCursor != null" @click="updateBlock()">{{ $t('@.load-more') }}</ui-button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -35,16 +43,25 @@
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import i18n from '../../../../i18n';
|
||||
import XUser from './mute-and-block.user.vue';
|
||||
|
||||
const fetchLimit = 30;
|
||||
|
||||
export default Vue.extend({
|
||||
i18n: i18n('common/views/components/mute-and-block.vue'),
|
||||
|
||||
components: {
|
||||
XUser
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
muteFetching: true,
|
||||
blockFetching: true,
|
||||
mute: [],
|
||||
block: [],
|
||||
muteCursor: undefined,
|
||||
blockCursor: undefined,
|
||||
mutedWords: ''
|
||||
};
|
||||
},
|
||||
@@ -59,21 +76,106 @@ export default Vue.extend({
|
||||
mounted() {
|
||||
this.mutedWords = this._mutedWords.map(words => words.join(' ')).join('\n');
|
||||
|
||||
this.$root.api('mute/list').then(mute => {
|
||||
this.mute = mute.map(x => x.mutee);
|
||||
this.muteFetching = false;
|
||||
});
|
||||
|
||||
this.$root.api('blocking/list').then(blocking => {
|
||||
this.block = blocking.map(x => x.blockee);
|
||||
this.blockFetching = false;
|
||||
});
|
||||
this.updateMute();
|
||||
this.updateBlock();
|
||||
},
|
||||
|
||||
methods: {
|
||||
save() {
|
||||
this._mutedWords = this.mutedWords.split('\n').map(line => line.split(' ').filter(x => x != ''));
|
||||
},
|
||||
|
||||
unmute(user) {
|
||||
this.$root.dialog({
|
||||
type: 'warning',
|
||||
text: this.$t('unmute-confirm'),
|
||||
showCancelButton: true
|
||||
}).then(({ canceled }) => {
|
||||
if (canceled) return;
|
||||
this.$root.api('mute/delete', {
|
||||
userId: user.id
|
||||
}).then(() => {
|
||||
this.muteCursor = undefined;
|
||||
this.updateMute();
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
unblock(user) {
|
||||
this.$root.dialog({
|
||||
type: 'warning',
|
||||
text: this.$t('unblock-confirm'),
|
||||
showCancelButton: true
|
||||
}).then(({ canceled }) => {
|
||||
if (canceled) return;
|
||||
this.$root.api('blocking/delete', {
|
||||
userId: user.id
|
||||
}).then(() => {
|
||||
this.updateBlock();
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
updateMute() {
|
||||
this.muteFetching = true;
|
||||
this.$root.api('mute/list', {
|
||||
limit: fetchLimit + 1,
|
||||
untilId: this.muteCursor,
|
||||
}).then((items: Object[]) => {
|
||||
const past = this.muteCursor ? this.mute : [];
|
||||
|
||||
if (items.length === fetchLimit + 1) {
|
||||
items.pop()
|
||||
this.muteCursor = items[items.length - 1].id;
|
||||
} else {
|
||||
this.muteCursor = undefined;
|
||||
}
|
||||
|
||||
this.mute = past.concat(items.map(x => x.mutee));
|
||||
this.muteFetching = false;
|
||||
});
|
||||
},
|
||||
|
||||
updateBlock() {
|
||||
this.blockFetching = true;
|
||||
this.$root.api('blocking/list', {
|
||||
limit: fetchLimit + 1,
|
||||
untilId: this.blockCursor,
|
||||
}).then((items: Object[]) => {
|
||||
const past = this.blockCursor ? this.block : [];
|
||||
|
||||
if (items.length === fetchLimit + 1) {
|
||||
items.pop()
|
||||
this.blockCursor = items[items.length - 1].id;
|
||||
} else {
|
||||
this.blockCursor = undefined;
|
||||
}
|
||||
|
||||
this.block = past.concat(items.map(x => x.blockee));
|
||||
this.blockFetching = false;
|
||||
});
|
||||
},
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
.users
|
||||
> .user
|
||||
display flex
|
||||
align-items center
|
||||
justify-content flex-end
|
||||
border-radius 6px
|
||||
|
||||
&:hover
|
||||
background-color var(--primary)
|
||||
|
||||
> span
|
||||
margin-left auto
|
||||
cursor pointer
|
||||
padding 16px
|
||||
|
||||
> button
|
||||
margin-top 16px
|
||||
</style>
|
||||
|
||||
|
@@ -108,6 +108,17 @@
|
||||
<ui-switch v-if="$root.isMobile" v-model="disableViaMobile">{{ $t('@._settings.disable-via-mobile') }}</ui-switch>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<header>{{ $t('@._settings.reactions') }}</header>
|
||||
<ui-textarea v-model="reactions">
|
||||
{{ $t('@._settings.reactions') }}<template #desc>{{ $t('@._settings.reactions-description') }}</template>
|
||||
</ui-textarea>
|
||||
<ui-horizon-group>
|
||||
<ui-button @click="save('reactions', reactions.trim().split('\n'))" primary><fa :icon="faSave"/> {{ $t('@._settings.save') }}</ui-button>
|
||||
<ui-button @click="previewReaction()" ref="reactionsPreviewButton"><fa :icon="faEye"/> {{ $t('@._settings.preview') }}</ui-button>
|
||||
</ui-horizon-group>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<header>{{ $t('@._settings.timeline') }}</header>
|
||||
<ui-switch v-model="showMyRenotes">{{ $t('@._settings.show-my-renotes') }}</ui-switch>
|
||||
@@ -304,11 +315,12 @@ import XApi from './api.vue';
|
||||
import XLanguage from './language.vue';
|
||||
import XAppType from './app-type.vue';
|
||||
import XNotification from './notification.vue';
|
||||
import MkReactionPicker from '../reaction-picker.vue';
|
||||
|
||||
import { url, version } from '../../../../config';
|
||||
import checkForUpdate from '../../../scripts/check-for-update';
|
||||
import { formatTimeString } from '../../../../../../misc/format-time-string';
|
||||
import { faSave } from '@fortawesome/free-regular-svg-icons';
|
||||
import { faSave, faEye } from '@fortawesome/free-regular-svg-icons';
|
||||
|
||||
export default Vue.extend({
|
||||
i18n: i18n(),
|
||||
@@ -339,11 +351,12 @@ export default Vue.extend({
|
||||
return {
|
||||
meta: null,
|
||||
version,
|
||||
reactions: this.$store.state.settings.reactions.join('\n'),
|
||||
webSearchEngine: this.$store.state.settings.webSearchEngine,
|
||||
pastedFileName : this.$store.state.settings.pastedFileName,
|
||||
latestVersion: undefined,
|
||||
checkingForUpdate: false,
|
||||
faSave
|
||||
faSave, faEye
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@@ -643,6 +656,16 @@ export default Vue.extend({
|
||||
pastedFileNamePreview() {
|
||||
return `${formatTimeString(new Date(), this.pastedFileName).replace(/{{number}}/g, `1`)}.png`
|
||||
},
|
||||
previewReaction() {
|
||||
const picker = this.$root.new(MkReactionPicker, {
|
||||
source: this.$refs.reactionsPreviewButton.$el,
|
||||
reactions: this.reactions.trim().split('\n'),
|
||||
showFocus: false,
|
||||
});
|
||||
picker.$once('chosen', reaction => {
|
||||
picker.close();
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
@@ -6,7 +6,10 @@
|
||||
<div class="value" ref="passwordMetar"></div>
|
||||
</div>
|
||||
<span class="label" ref="label"><slot></slot></span>
|
||||
<span class="title" ref="title"><slot name="title"></slot></span>
|
||||
<span class="title" ref="title">
|
||||
<slot name="title"></slot>
|
||||
<span class="warning" v-if="invalid"><fa :icon="['fa', 'exclamation-circle']"/>{{ $refs.input.validationMessage }}</span>
|
||||
</span>
|
||||
<div class="prefix" ref="prefix"><slot name="prefix"></slot></div>
|
||||
<template v-if="type != 'file'">
|
||||
<input v-if="debounce" ref="input"
|
||||
@@ -158,6 +161,7 @@ export default Vue.extend({
|
||||
return {
|
||||
v: this.value,
|
||||
focused: false,
|
||||
invalid: false,
|
||||
passwordStrength: '',
|
||||
id: Math.random().toString()
|
||||
};
|
||||
@@ -200,6 +204,8 @@ export default Vue.extend({
|
||||
this.passwordStrength = strength > 0.7 ? 'high' : strength > 0.3 ? 'medium' : 'low';
|
||||
(this.$refs.passwordMetar as any).style.width = `${strength * 100}%`;
|
||||
}
|
||||
|
||||
this.invalid = this.$refs.input.validity.badInput;
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
@@ -365,6 +371,17 @@ root(fill)
|
||||
//will-change transform
|
||||
transform-origin top left
|
||||
transform scale(.75)
|
||||
white-space nowrap
|
||||
width 133%
|
||||
overflow hidden
|
||||
text-overflow ellipsis
|
||||
|
||||
> .warning
|
||||
margin-left 0.5em
|
||||
color var(--infoWarnFg)
|
||||
|
||||
> svg
|
||||
margin-right 0.1em
|
||||
|
||||
> input
|
||||
display block
|
||||
|
80
src/client/app/common/views/components/ui/modal.vue
Normal file
80
src/client/app/common/views/components/ui/modal.vue
Normal file
@@ -0,0 +1,80 @@
|
||||
<template>
|
||||
<div class="modal">
|
||||
<div class="bg" ref="bg" @click="onBgClick" />
|
||||
<slot class="main" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import anime from 'animejs';
|
||||
|
||||
export default Vue.extend({
|
||||
props: {
|
||||
closeOnBgClick: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: true
|
||||
},
|
||||
openAnimeDuration: {
|
||||
type: Number,
|
||||
required: false,
|
||||
default: 100
|
||||
},
|
||||
closeAnimeDuration: {
|
||||
type: Number,
|
||||
required: false,
|
||||
default: 100
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
anime({
|
||||
targets: this.$refs.bg,
|
||||
opacity: 1,
|
||||
duration: this.openAnimeDuration,
|
||||
easing: 'linear'
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
onBgClick() {
|
||||
this.$emit('bg-click');
|
||||
if (this.closeOnBgClick) this.close();
|
||||
},
|
||||
close() {
|
||||
this.$emit('before-close');
|
||||
|
||||
anime({
|
||||
targets: this.$refs.bg,
|
||||
opacity: 0,
|
||||
duration: this.closeAnimeDuration,
|
||||
easing: 'linear',
|
||||
complete: () => (this as any).destroyDom()
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
.modal
|
||||
position fixed
|
||||
z-index 2048
|
||||
top 0
|
||||
left 0
|
||||
width 100%
|
||||
height 100%
|
||||
|
||||
.bg
|
||||
display block
|
||||
position fixed
|
||||
z-index 1
|
||||
top 0
|
||||
left 0
|
||||
width 100%
|
||||
height 100%
|
||||
background rgba(#000, 0.7)
|
||||
opacity 0
|
||||
|
||||
.main
|
||||
z-index 1
|
||||
</style>
|
@@ -176,6 +176,9 @@ root(fill)
|
||||
color rgba(#000, 0.54)
|
||||
pointer-events none
|
||||
|
||||
&:empty
|
||||
display none
|
||||
|
||||
> *
|
||||
display block
|
||||
min-width 16px
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<ui-container :body-togglable="true">
|
||||
<ui-container :body-togglable="true" :expanded="expanded">
|
||||
<template #header><slot></slot></template>
|
||||
|
||||
<mk-error v-if="error" @retry="init()"/>
|
||||
@@ -50,7 +50,11 @@ export default Vue.extend({
|
||||
iconOnly: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
expanded: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
},
|
||||
|
||||
computed: {
|
||||
|
@@ -27,7 +27,7 @@
|
||||
<div class="description">
|
||||
<mfm v-if="user.description" :text="user.description" :is-note="false" :author="user" :i="$store.state.i" :custom-emojis="user.emojis" :key="user.id"/>
|
||||
</div>
|
||||
<div class="fields" v-if="user.fields">
|
||||
<div class="fields" v-if="user.fields" :key="user.id">
|
||||
<dl class="field" v-for="(field, i) in user.fields" :key="i">
|
||||
<dt class="name">
|
||||
<mfm :text="field.name" :plain="true" :custom-emojis="user.emojis"/>
|
||||
@@ -112,10 +112,13 @@ export default Vue.extend({
|
||||
},
|
||||
|
||||
menu() {
|
||||
this.$root.new(XUserMenu, {
|
||||
const w = this.$root.new(XUserMenu, {
|
||||
source: this.$refs.menu,
|
||||
user: this.user
|
||||
});
|
||||
this.$once('hook:beforeDestroy', () => {
|
||||
w.destroyDom();
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@@ -240,7 +240,7 @@ class Autocomplete {
|
||||
// キャレットを戻す
|
||||
this.vm.$nextTick(() => {
|
||||
this.textarea.focus();
|
||||
const pos = trimmedBefore.length + (value.startsWith(':') ? value.length : 1);
|
||||
const pos = trimmedBefore.length + value.length;
|
||||
this.textarea.setSelectionRange(pos, pos);
|
||||
});
|
||||
}
|
||||
|
@@ -1,15 +1,30 @@
|
||||
<template>
|
||||
<div>
|
||||
<ui-container :show-header="false" v-if="meta && stats">
|
||||
<div class="kpdsmpnk" :style="{ backgroundImage: meta.bannerUrl ? `url(${meta.bannerUrl})` : null }">
|
||||
<div>
|
||||
<router-link to="/explore" class="title">{{ $t('explore', { host: meta.name || 'Misskey' }) }}</router-link>
|
||||
<span>{{ $t('users-info', { users: num(stats.originalUsersCount) }) }}</span>
|
||||
<div class="localfedi7" v-if="meta && stats && tag == null" :style="{ backgroundImage: meta.bannerUrl ? `url(${meta.bannerUrl})` : null }">
|
||||
<header>{{ $t('explore', { host: meta.name || 'Misskey' }) }}</header>
|
||||
<div>{{ $t('users-info', { users: num(stats.originalUsersCount) }) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui-container>
|
||||
|
||||
<ui-container :body-togglable="true" :expanded="tag == null" ref="tags">
|
||||
<template v-if="tag == null">
|
||||
<mk-user-list :pagination="pinnedUsers" :expanded="false">
|
||||
<fa :icon="faBookmark" fixed-width/>{{ $t('pinned-users') }}
|
||||
</mk-user-list>
|
||||
<mk-user-list :pagination="popularUsers" :expanded="false">
|
||||
<fa :icon="faChartLine" fixed-width/>{{ $t('popular-users') }}
|
||||
</mk-user-list>
|
||||
<mk-user-list :pagination="recentlyUpdatedUsers" :expanded="false">
|
||||
<fa :icon="faCommentAlt" fixed-width/>{{ $t('recently-updated-users') }}
|
||||
</mk-user-list>
|
||||
<mk-user-list :pagination="recentlyRegisteredUsers" :expanded="false">
|
||||
<fa :icon="faPlus" fixed-width/>{{ $t('recently-registered-users') }}
|
||||
</mk-user-list>
|
||||
</template>
|
||||
|
||||
<div class="localfedi7" v-if="tag == null" :style="{ backgroundImage: `url(/assets/fedi.jpg)` }">
|
||||
<header>{{ $t('explore-fediverse') }}</header>
|
||||
</div>
|
||||
|
||||
<ui-container :body-togglable="true" :expanded="false" ref="tags">
|
||||
<template #header><fa :icon="faHashtag" fixed-width/>{{ $t('popular-tags') }}</template>
|
||||
|
||||
<div class="vxjfqztj">
|
||||
@@ -18,25 +33,18 @@
|
||||
</div>
|
||||
</ui-container>
|
||||
|
||||
<mk-user-list v-if="tag != null" :pagination="tagUsers" :key="`${tag}-local`">
|
||||
<mk-user-list v-if="tag != null" :pagination="tagUsers" :key="`${tag}`">
|
||||
<fa :icon="faHashtag" fixed-width/>{{ tag }}
|
||||
</mk-user-list>
|
||||
<mk-user-list v-if="tag != null" :pagination="tagRemoteUsers" :key="`${tag}-remote`">
|
||||
<fa :icon="faHashtag" fixed-width/>{{ tag }} ({{ $t('federated') }})
|
||||
</mk-user-list>
|
||||
|
||||
<template v-if="tag == null">
|
||||
<mk-user-list :pagination="pinnedUsers">
|
||||
<fa :icon="faBookmark" fixed-width/>{{ $t('pinned-users') }}
|
||||
</mk-user-list>
|
||||
<mk-user-list :pagination="popularUsers">
|
||||
<mk-user-list :pagination="popularUsersF" :expanded="false">
|
||||
<fa :icon="faChartLine" fixed-width/>{{ $t('popular-users') }}
|
||||
</mk-user-list>
|
||||
<mk-user-list :pagination="recentlyUpdatedUsers">
|
||||
<mk-user-list :pagination="recentlyUpdatedUsersF" :expanded="false">
|
||||
<fa :icon="faCommentAlt" fixed-width/>{{ $t('recently-updated-users') }}
|
||||
</mk-user-list>
|
||||
<mk-user-list :pagination="recentlyRegisteredUsers">
|
||||
<fa :icon="faPlus" fixed-width/>{{ $t('recently-registered-users') }}
|
||||
<mk-user-list :pagination="recentlyRegisteredUsersF" :expanded="false">
|
||||
<fa :icon="faRocket" fixed-width/>{{ $t('recently-discovered-users') }}
|
||||
</mk-user-list>
|
||||
</template>
|
||||
</div>
|
||||
@@ -45,7 +53,7 @@
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import i18n from '../../../i18n';
|
||||
import { faChartLine, faPlus, faHashtag } from '@fortawesome/free-solid-svg-icons';
|
||||
import { faChartLine, faPlus, faHashtag, faRocket } from '@fortawesome/free-solid-svg-icons';
|
||||
import { faBookmark, faCommentAlt } from '@fortawesome/free-regular-svg-icons';
|
||||
|
||||
export default Vue.extend({
|
||||
@@ -58,6 +66,12 @@ export default Vue.extend({
|
||||
}
|
||||
},
|
||||
|
||||
inject: {
|
||||
inNakedDeckColumn: {
|
||||
default: false
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
pinnedUsers: { endpoint: 'pinned-users' },
|
||||
@@ -75,12 +89,25 @@ export default Vue.extend({
|
||||
state: 'alive',
|
||||
sort: '+createdAt',
|
||||
} },
|
||||
popularUsersF: { endpoint: 'users', limit: 10, params: {
|
||||
state: 'alive',
|
||||
origin: 'remote',
|
||||
sort: '+follower',
|
||||
} },
|
||||
recentlyUpdatedUsersF: { endpoint: 'users', limit: 10, params: {
|
||||
origin: 'combined',
|
||||
sort: '+updatedAt',
|
||||
} },
|
||||
recentlyRegisteredUsersF: { endpoint: 'users', limit: 10, params: {
|
||||
origin: 'combined',
|
||||
sort: '+createdAt',
|
||||
} },
|
||||
tagsLocal: [],
|
||||
tagsRemote: [],
|
||||
stats: null,
|
||||
meta: null,
|
||||
num: Vue.filter('number'),
|
||||
faBookmark, faChartLine, faCommentAlt, faPlus, faHashtag
|
||||
faBookmark, faChartLine, faCommentAlt, faPlus, faHashtag, faRocket
|
||||
};
|
||||
},
|
||||
|
||||
@@ -91,21 +118,7 @@ export default Vue.extend({
|
||||
limit: 30,
|
||||
params: {
|
||||
tag: this.tag,
|
||||
state: 'alive',
|
||||
origin: 'local',
|
||||
sort: '+follower',
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
tagRemoteUsers(): any {
|
||||
return {
|
||||
endpoint: 'hashtags/users',
|
||||
limit: 30,
|
||||
params: {
|
||||
tag: this.tag,
|
||||
state: 'alive',
|
||||
origin: 'remote',
|
||||
origin: 'combined',
|
||||
sort: '+follower',
|
||||
}
|
||||
};
|
||||
@@ -152,6 +165,28 @@ export default Vue.extend({
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
.localfedi7
|
||||
overflow hidden
|
||||
background var(--face)
|
||||
color #fff
|
||||
text-shadow 0 0 8px #000
|
||||
border-radius 6px
|
||||
padding 16px
|
||||
margin-top 16px
|
||||
margin-bottom 16px
|
||||
height 80px
|
||||
background-position 50%
|
||||
background-size cover
|
||||
> header
|
||||
font-size 20px
|
||||
font-weight bold
|
||||
> div
|
||||
font-size 14px
|
||||
opacity 0.8
|
||||
|
||||
.localfedi7:first-child
|
||||
margin-top 0
|
||||
|
||||
.vxjfqztj
|
||||
padding 16px
|
||||
|
||||
@@ -160,35 +195,4 @@ export default Vue.extend({
|
||||
|
||||
&.local
|
||||
font-weight bold
|
||||
|
||||
.kpdsmpnk
|
||||
min-height 100px
|
||||
padding 16px
|
||||
background-position center
|
||||
background-size cover
|
||||
|
||||
&:before
|
||||
content ""
|
||||
display block
|
||||
position absolute
|
||||
top 0
|
||||
left 0
|
||||
width 100%
|
||||
height 100%
|
||||
background rgba(0, 0, 0, 0.3)
|
||||
|
||||
> div
|
||||
color #fff
|
||||
text-shadow 0 0 8px #00
|
||||
|
||||
> .title
|
||||
display block
|
||||
font-size 20px
|
||||
font-weight bold
|
||||
color inherit
|
||||
|
||||
> span
|
||||
font-size 14px
|
||||
opacity 0.8
|
||||
|
||||
</style>
|
||||
|
@@ -9,7 +9,7 @@
|
||||
<mk-user-name :user="req.follower"/>
|
||||
</router-link>
|
||||
<span>
|
||||
<a @click="accept(req.follower)">{{ $t('accept') }}</a>|<a @click="reject(req.follower)">{{ $t('reject') }}</a>
|
||||
<a @click="accept(req.follower)">{{ $t('accept') }}</a> | <a @click="reject(req.follower)">{{ $t('reject') }}</a>
|
||||
</span>
|
||||
</div>
|
||||
</sequential-entrance>
|
||||
@@ -70,5 +70,6 @@ export default Vue.extend({
|
||||
|
||||
> span
|
||||
margin 0 0 0 auto
|
||||
color var(--text)
|
||||
|
||||
</style>
|
||||
|
@@ -72,11 +72,42 @@ export default Vue.extend({
|
||||
const acct = new URL(location.href).searchParams.get('acct');
|
||||
this.fetching = true;
|
||||
Progress.start();
|
||||
this.$root.api('users/show', parseAcct(acct)).then(user => {
|
||||
this.user = user;
|
||||
if (acct.match(/^https?:/)) {
|
||||
this.$root.api('ap/show', {
|
||||
uri: acct
|
||||
}).then((res: { type: string, object: any }) => {
|
||||
if (res.type === 'User') {
|
||||
this.user = res.object;
|
||||
} else if (res.type === 'Note') {
|
||||
this.$router.replace(`/notes/${res.object.id}`);
|
||||
} else {
|
||||
this.$root.dialog({
|
||||
type: 'error',
|
||||
text: 'Not supported'
|
||||
});
|
||||
}
|
||||
}).catch((e: any) => {
|
||||
this.$root.dialog({
|
||||
type: 'error',
|
||||
text: e.message
|
||||
});
|
||||
}).finally(() => {
|
||||
this.fetching = false;
|
||||
Progress.done();
|
||||
});
|
||||
} else {
|
||||
this.$root.api('users/show', parseAcct(acct)).then((user: any) => {
|
||||
this.user = user;
|
||||
}).catch((e: any) => {
|
||||
this.$root.dialog({
|
||||
type: 'error',
|
||||
text: e.message
|
||||
});
|
||||
}).finally(() => {
|
||||
this.fetching = false;
|
||||
Progress.done();
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
async onClick() {
|
||||
|
@@ -1,11 +1,12 @@
|
||||
<template>
|
||||
<div class="anltbovirfeutcigvwgmgxipejaeozxi">
|
||||
<ui-container :show-header="false" :naked="props.design == 1">
|
||||
<ui-container :show-header="false" :naked="props.design === 1">
|
||||
<div class="anltbovirfeutcigvwgmgxipejaeozxi-body"
|
||||
:data-found="announcements && announcements.length != 0"
|
||||
:data-found="announcements && announcements.length !== 0"
|
||||
:data-melt="props.design == 1"
|
||||
:data-mobile="platform == 'mobile'"
|
||||
>
|
||||
<div class="broadcast-left" v-show="announcements && announcements.length !== 0">
|
||||
<div class="icon">
|
||||
<svg height="32" version="1.1" viewBox="0 0 32 32" width="32">
|
||||
<path class="tower" d="M16.04,11.24c1.79,0,3.239-1.45,3.239-3.24S17.83,4.76,16.04,4.76c-1.79,0-3.24,1.45-3.24,3.24 C12.78,9.78,14.24,11.24,16.04,11.24z M16.04,13.84c-0.82,0-1.66-0.2-2.4-0.6L7.34,29.98h2.98l1.72-2h8l1.681,2H24.7L18.42,13.24 C17.66,13.64,16.859,13.84,16.04,13.84z M16.02,14.8l2.02,7.2h-4L16.02,14.8z M12.04,25.98l2-2h4l2,2H12.04z"></path>
|
||||
@@ -15,6 +16,13 @@
|
||||
<path class="wave d" d="M29.18,1.06c-0.479-0.502-1.273-0.522-1.775-0.044c-0.016,0.015-0.029,0.029-0.045,0.044c-0.5,0.52-0.5,1.36,0,1.88 c1.361,1.4,2.041,3.24,2.041,5.08s-0.68,3.66-2.041,5.08c-0.5,0.52-0.5,1.36,0,1.88c0.509,0.508,1.332,0.508,1.841,0 c1.86-1.92,2.8-4.44,2.8-6.96C31.99,5.424,30.98,2.931,29.18,1.06z"></path>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="broadcast-nav" v-show="announcements && announcements.length > 1">
|
||||
<mk-frac class="broadcast-page" :value="i + 1" :total="announcements.length"/>
|
||||
<ui-button class="broadcast-prev" @click="prev" :title="$t('next')"><fa :icon="faAngleLeft"/></ui-button>
|
||||
<ui-button class="broadcast-next" @click="next" :title="$t('prev')"><fa :icon="faAngleRight"/></ui-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="broadcast-right">
|
||||
<p class="fetching" v-if="fetching">{{ $t('fetching') }}<mk-ellipsis/></p>
|
||||
<h1 v-if="!fetching">{{ announcements.length == 0 ? $t('no-broadcasts') : announcements[i].title }}</h1>
|
||||
<p v-if="!fetching">
|
||||
@@ -22,7 +30,7 @@
|
||||
<img v-if="announcements.length != 0 && announcements[i].image" :src="announcements[i].image" alt="" style="display: block; max-height: 130px; max-width: 100%;"/>
|
||||
<template v-if="announcements.length == 0">{{ $t('have-a-nice-day') }}</template>
|
||||
</p>
|
||||
<a v-if="announcements.length > 1" @click="next">{{ $t('next') }} >></a>
|
||||
</div>
|
||||
</div>
|
||||
</ui-container>
|
||||
</div>
|
||||
@@ -30,6 +38,7 @@
|
||||
|
||||
<script lang="ts">
|
||||
import define from '../../../common/define-widget';
|
||||
import { faAngleLeft, faAngleRight } from '@fortawesome/free-solid-svg-icons';
|
||||
import i18n from '../../../i18n';
|
||||
|
||||
export default define({
|
||||
@@ -43,7 +52,8 @@ export default define({
|
||||
return {
|
||||
i: 0,
|
||||
fetching: true,
|
||||
announcements: []
|
||||
announcements: [],
|
||||
faAngleLeft, faAngleRight
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
@@ -54,14 +64,21 @@ export default define({
|
||||
},
|
||||
methods: {
|
||||
next() {
|
||||
if (this.i == this.announcements.length - 1) {
|
||||
if (this.i === this.announcements.length - 1) {
|
||||
this.i = 0;
|
||||
} else {
|
||||
this.i++;
|
||||
}
|
||||
},
|
||||
prev() {
|
||||
if (this.i === 0) {
|
||||
this.i = this.announcements.length - 1;
|
||||
} else {
|
||||
this.i--;
|
||||
}
|
||||
},
|
||||
func() {
|
||||
if (this.props.design == 1) {
|
||||
if (this.props.design === 1) {
|
||||
this.props.design = 0;
|
||||
} else {
|
||||
this.props.design++;
|
||||
@@ -74,31 +91,21 @@ export default define({
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
.anltbovirfeutcigvwgmgxipejaeozxi-body
|
||||
display flex
|
||||
padding 10px
|
||||
background var(--announcementsBg)
|
||||
|
||||
&[data-melt]
|
||||
background transparent
|
||||
|
||||
&[data-found]
|
||||
padding-left 50px
|
||||
> .broadcast-left
|
||||
width 32px
|
||||
margin-right 8px
|
||||
|
||||
> .icon
|
||||
display block
|
||||
|
||||
&:after
|
||||
content ""
|
||||
display block
|
||||
clear both
|
||||
|
||||
> .icon
|
||||
display none
|
||||
float left
|
||||
margin-left -40px
|
||||
|
||||
> svg
|
||||
fill currentColor
|
||||
color #4078c0
|
||||
color var(--announcementsTitle)
|
||||
|
||||
> .wave
|
||||
opacity 1
|
||||
@@ -128,26 +135,69 @@ export default define({
|
||||
10%
|
||||
opacity 1
|
||||
|
||||
> .broadcast-nav
|
||||
display flex
|
||||
flex-wrap wrap
|
||||
padding 1px 0 2px
|
||||
|
||||
> .broadcast-page
|
||||
width 100%
|
||||
color var(--announcementsTitle)
|
||||
text-align center
|
||||
font-size .6rem
|
||||
|
||||
> .broadcast-prev,
|
||||
> .broadcast-next
|
||||
flex 1
|
||||
width 50%
|
||||
display block
|
||||
margin 0
|
||||
padding 0
|
||||
font-size .9rem
|
||||
line-height 1.3em
|
||||
color var(--link)
|
||||
background transparent
|
||||
cursor pointer
|
||||
|
||||
&:focus
|
||||
&:after
|
||||
top -1px
|
||||
right -1px
|
||||
bottom -1px
|
||||
left -1px
|
||||
|
||||
&.round:focus:after
|
||||
border-radius 5px
|
||||
|
||||
> .broadcast-prev
|
||||
padding-right 3px
|
||||
|
||||
> .broadcast-next
|
||||
padding-left 3px
|
||||
|
||||
> .broadcast-right
|
||||
flex 1
|
||||
word-break break-word
|
||||
|
||||
> h1
|
||||
margin 0
|
||||
font-size 0.95em
|
||||
font-size .975em
|
||||
font-weight normal
|
||||
line-height 1.3em
|
||||
color var(--announcementsTitle)
|
||||
padding-bottom 2px
|
||||
|
||||
> p
|
||||
display block
|
||||
z-index 1
|
||||
margin 0
|
||||
font-size 0.7em
|
||||
font-size .8em
|
||||
color var(--announcementsText)
|
||||
width 100%
|
||||
|
||||
&.fetching
|
||||
text-align center
|
||||
|
||||
> a
|
||||
display block
|
||||
font-size 0.7em
|
||||
|
||||
&[data-mobile]
|
||||
> p
|
||||
color #fff
|
||||
|
@@ -37,7 +37,6 @@ import i18n from '../../../i18n';
|
||||
import copyToClipboard from '../../../common/scripts/copy-to-clipboard';
|
||||
import updateAvatar from '../../api/update-avatar';
|
||||
import updateBanner from '../../api/update-banner';
|
||||
import { appendQuery } from '../../../../../prelude/url';
|
||||
import XFileThumbnail from '../../../common/views/components/drive-file-thumbnail.vue';
|
||||
|
||||
export default Vue.extend({
|
||||
@@ -87,7 +86,8 @@ export default Vue.extend({
|
||||
action: this.copyUrl
|
||||
}, {
|
||||
type: 'link',
|
||||
href: appendQuery(this.file.url, 'download'),
|
||||
href: this.file.url,
|
||||
target: '_blank',
|
||||
text: this.$t('contextmenu.download'),
|
||||
icon: 'download',
|
||||
download: this.file.name
|
||||
|
@@ -1,36 +1,28 @@
|
||||
<template>
|
||||
<div class="mk-media-video-dialog">
|
||||
<div class="bg" @click="close"></div>
|
||||
<video :src="video.url" :title="video.name" controls autoplay ref="video" @volumechange="volumechange"/>
|
||||
</div>
|
||||
<ui-modal v-hotkey.global="keymap">
|
||||
<video :src="video.url" :title="video.name" controls autoplay ref="video" @volumechange="volumechange" />
|
||||
</ui-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import anime from 'animejs';
|
||||
|
||||
export default Vue.extend({
|
||||
props: ['video', 'start'],
|
||||
mounted() {
|
||||
anime({
|
||||
targets: this.$el,
|
||||
opacity: 1,
|
||||
duration: 100,
|
||||
easing: 'linear'
|
||||
});
|
||||
const videoTag = this.$refs.video as HTMLVideoElement;
|
||||
if (this.start) videoTag.currentTime = this.start
|
||||
videoTag.volume = this.$store.state.device.mediaVolume;
|
||||
},
|
||||
computed: {
|
||||
keymap(): any {
|
||||
return {
|
||||
'esc': this.close,
|
||||
};
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
close() {
|
||||
anime({
|
||||
targets: this.$el,
|
||||
opacity: 0,
|
||||
duration: 100,
|
||||
easing: 'linear',
|
||||
complete: () => this.destroyDom()
|
||||
});
|
||||
},
|
||||
volumechange() {
|
||||
const videoTag = this.$refs.video as HTMLVideoElement;
|
||||
@@ -41,27 +33,7 @@ export default Vue.extend({
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
.mk-media-video-dialog
|
||||
display block
|
||||
position fixed
|
||||
z-index 2048
|
||||
top 0
|
||||
left 0
|
||||
width 100%
|
||||
height 100%
|
||||
opacity 0
|
||||
|
||||
> .bg
|
||||
display block
|
||||
position fixed
|
||||
z-index 1
|
||||
top 0
|
||||
left 0
|
||||
width 100%
|
||||
height 100%
|
||||
background rgba(#000, 0.7)
|
||||
|
||||
> video
|
||||
video
|
||||
position fixed
|
||||
z-index 2
|
||||
top 0
|
||||
|
@@ -53,10 +53,13 @@ export default Vue.extend({
|
||||
start = videoTag.currentTime
|
||||
videoTag.pause()
|
||||
}
|
||||
this.$root.new(MkMediaVideoDialog, {
|
||||
const viewer = this.$root.new(MkMediaVideoDialog, {
|
||||
video: this.video,
|
||||
start,
|
||||
})
|
||||
});
|
||||
this.$once('hook:beforeDestroy', () => {
|
||||
viewer.close();
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<div class="kedshtep" :class="{ naked, inNakedDeckColumn, shadow: $store.state.device.useShadow, round: $store.state.device.roundedCorners }">
|
||||
<header v-if="showHeader">
|
||||
<header v-if="showHeader" :class="{ bodyTogglable }" @click="toggleContent(!showBody)">
|
||||
<div class="title"><slot name="header"></slot></div>
|
||||
<slot name="func"></slot>
|
||||
<button v-if="bodyTogglable" @click="toggleContent(!showBody)">
|
||||
<button v-if="bodyTogglable">
|
||||
<template v-if="showBody"><fa icon="angle-up"/></template>
|
||||
<template v-else><fa icon="angle-down"/></template>
|
||||
</button>
|
||||
@@ -47,6 +47,7 @@ export default Vue.extend({
|
||||
},
|
||||
methods: {
|
||||
toggleContent(show: boolean) {
|
||||
if (!this.bodyTogglable) return;
|
||||
this.showBody = show;
|
||||
this.$emit('toggle', show);
|
||||
}
|
||||
@@ -77,6 +78,9 @@ export default Vue.extend({
|
||||
> header
|
||||
background var(--faceHeader)
|
||||
|
||||
&.bodyTogglable
|
||||
cursor pointer
|
||||
|
||||
> .title
|
||||
z-index 1
|
||||
margin 0
|
||||
@@ -120,6 +124,9 @@ export default Vue.extend({
|
||||
color var(--text)
|
||||
background var(--deckColumnBg)
|
||||
|
||||
&.bodyTogglable
|
||||
cursor pointer
|
||||
|
||||
> button
|
||||
position absolute
|
||||
top 0
|
||||
|
@@ -25,7 +25,7 @@
|
||||
<p v-else class="empty">{{ $t('no-description') }}</p>
|
||||
<x-integrations :user="user" style="margin-top:16px;"/>
|
||||
</div>
|
||||
<div class="fields" v-if="user.fields">
|
||||
<div class="fields" v-if="user.fields" :key="user.id">
|
||||
<dl class="field" v-for="(field, i) in user.fields" :key="i">
|
||||
<dt class="name">
|
||||
<mfm :text="field.name" :plain="true" :custom-emojis="user.emojis"/>
|
||||
@@ -106,10 +106,13 @@ export default Vue.extend({
|
||||
},
|
||||
|
||||
menu() {
|
||||
this.$root.new(XUserMenu, {
|
||||
const w = this.$root.new(XUserMenu, {
|
||||
source: this.$refs.menu,
|
||||
user: this.user
|
||||
});
|
||||
this.$once('hook:beforeDestroy', () => {
|
||||
w.destroyDom();
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@@ -57,7 +57,6 @@
|
||||
import Vue from 'vue';
|
||||
import i18n from '../../../i18n';
|
||||
import { gcd } from '../../../../../prelude/math';
|
||||
import { appendQuery } from '../../../../../prelude/url';
|
||||
import XFileThumbnail from '../../../common/views/components/drive-file-thumbnail.vue';
|
||||
|
||||
export default Vue.extend({
|
||||
@@ -91,7 +90,7 @@ export default Vue.extend({
|
||||
},
|
||||
|
||||
dlUrl(): string {
|
||||
return appendQuery(this.file.url, 'download');
|
||||
return this.file.url;
|
||||
}
|
||||
},
|
||||
|
||||
|
@@ -1,6 +1,9 @@
|
||||
<template>
|
||||
<div class="ulveipglmagnxfgvitaxyszerjwiqmwl">
|
||||
<div class="bg" ref="bg"></div>
|
||||
<ui-modal
|
||||
ref="modal"
|
||||
:close-on-bg-click="false"
|
||||
:close-anime-duration="300"
|
||||
@before-close="onBeforeClose">
|
||||
<div class="main" ref="main">
|
||||
<x-post-form ref="form"
|
||||
:reply="reply"
|
||||
@@ -12,7 +15,7 @@
|
||||
@posted="onPosted"
|
||||
@cancel="onCanceled"/>
|
||||
</div>
|
||||
</div>
|
||||
</ui-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
@@ -55,14 +58,6 @@ export default Vue.extend({
|
||||
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
(this.$refs.bg as any).style.pointerEvents = 'auto';
|
||||
anime({
|
||||
targets: this.$refs.bg,
|
||||
opacity: 1,
|
||||
duration: 100,
|
||||
easing: 'linear'
|
||||
});
|
||||
|
||||
anime({
|
||||
targets: this.$refs.main,
|
||||
opacity: 1,
|
||||
@@ -78,26 +73,22 @@ export default Vue.extend({
|
||||
this.$refs.form.focus();
|
||||
},
|
||||
|
||||
close() {
|
||||
(this.$refs.bg as any).style.pointerEvents = 'none';
|
||||
anime({
|
||||
targets: this.$refs.bg,
|
||||
opacity: 0,
|
||||
duration: 300,
|
||||
easing: 'linear'
|
||||
});
|
||||
|
||||
onBeforeClose() {
|
||||
(this.$refs.main as any).style.pointerEvents = 'none';
|
||||
|
||||
anime({
|
||||
targets: this.$refs.main,
|
||||
opacity: 0,
|
||||
translateY: 16,
|
||||
duration: 300,
|
||||
easing: 'easeOutQuad',
|
||||
complete: () => this.destroyDom()
|
||||
easing: 'easeOutQuad'
|
||||
});
|
||||
},
|
||||
|
||||
close() {
|
||||
(this.$refs.modal as any).close();
|
||||
},
|
||||
|
||||
onPosted() {
|
||||
this.$emit('posted');
|
||||
this.close();
|
||||
@@ -112,20 +103,8 @@ export default Vue.extend({
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
.ulveipglmagnxfgvitaxyszerjwiqmwl
|
||||
> .bg
|
||||
display block
|
||||
position fixed
|
||||
z-index 10000
|
||||
top 0
|
||||
left 0
|
||||
width 100%
|
||||
height 100%
|
||||
background rgba(#000, 0.7)
|
||||
opacity 0
|
||||
pointer-events none
|
||||
|
||||
> .main
|
||||
.main
|
||||
display block
|
||||
position fixed
|
||||
z-index 10000
|
||||
|
@@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<div class="ukygtjoj" :class="{ naked, inNakedDeckColumn, hideHeader: !showHeader, shadow: $store.state.device.useShadow, round: $store.state.device.roundedCorners }">
|
||||
<header v-if="showHeader">
|
||||
<header v-if="showHeader" @click="() => showBody = !showBody">
|
||||
<div class="title"><slot name="header"></slot></div>
|
||||
<slot name="func"></slot>
|
||||
<button v-if="bodyTogglable" @click="() => showBody = !showBody">
|
||||
<button v-if="bodyTogglable">
|
||||
<template v-if="showBody"><fa icon="angle-up"/></template>
|
||||
<template v-else><fa icon="angle-down"/></template>
|
||||
</button>
|
||||
@@ -47,6 +47,7 @@ export default Vue.extend({
|
||||
},
|
||||
methods: {
|
||||
toggleContent(show: boolean) {
|
||||
if (!this.bodyTogglable) return;
|
||||
this.showBody = show;
|
||||
}
|
||||
}
|
||||
|
@@ -25,7 +25,7 @@
|
||||
<mfm v-if="user.description" :text="user.description" :is-note="false" :author="user" :i="$store.state.i" :custom-emojis="user.emojis" :key="user.id"/>
|
||||
<x-integrations :user="user" style="margin:20px 0;"/>
|
||||
</div>
|
||||
<div class="fields" v-if="user.fields">
|
||||
<div class="fields" v-if="user.fields" :key="user.id">
|
||||
<dl class="field" v-for="(field, i) in user.fields" :key="i">
|
||||
<dt class="name">
|
||||
<mfm :text="field.name" :plain="true" :custom-emojis="user.emojis"/>
|
||||
|
@@ -23,6 +23,7 @@ button
|
||||
border none
|
||||
cursor pointer
|
||||
color inherit
|
||||
touch-action manipulation
|
||||
|
||||
*
|
||||
pointer-events none
|
||||
|
@@ -41,6 +41,7 @@ const defaultSettings = {
|
||||
uploadFolder: null,
|
||||
pastedFileName: 'yyyy-MM-dd HH-mm-ss [{{number}}]',
|
||||
pasteDialog: false,
|
||||
reactions: ['like', 'love', 'laugh', 'hmm', 'surprise', 'congrats', 'angry', 'confused', 'rip', 'pudding']
|
||||
};
|
||||
|
||||
const defaultDeviceSettings = {
|
||||
@@ -78,6 +79,8 @@ const defaultDeviceSettings = {
|
||||
enableMobileQuickNotificationView: false,
|
||||
roomGraphicsQuality: 'medium',
|
||||
roomUseOrthographicCamera: true,
|
||||
activeEmojiCategoryName: undefined,
|
||||
recentEmojis: [],
|
||||
};
|
||||
|
||||
export default (os: MiOS) => new Vuex.Store({
|
||||
|
@@ -4,13 +4,53 @@
|
||||
|
||||
import composeNotification from './common/scripts/compose-notification';
|
||||
|
||||
// eslint-disable-next-line no-undef
|
||||
const version = _VERSION_;
|
||||
const cacheName = `mk-cache-${version}`;
|
||||
|
||||
const apiUrl = `${location.origin}/api/`;
|
||||
|
||||
// インストールされたとき
|
||||
self.addEventListener('install', ev => {
|
||||
console.info('installed');
|
||||
|
||||
ev.waitUntil(Promise.all([
|
||||
self.skipWaiting(), // Force activate
|
||||
]));
|
||||
ev.waitUntil(
|
||||
caches.open(cacheName)
|
||||
.then(cache => {
|
||||
return cache.addAll([
|
||||
"/",
|
||||
`/assets/desktop.${version}.js`,
|
||||
`/assets/mobile.${version}.js`,
|
||||
"/assets/error.jpg"
|
||||
]);
|
||||
})
|
||||
.then(() => self.skipWaiting())
|
||||
);
|
||||
});
|
||||
|
||||
self.addEventListener('activate', ev => {
|
||||
ev.waitUntil(
|
||||
caches.keys()
|
||||
.then(cacheNames => Promise.all(
|
||||
cacheNames
|
||||
.filter((v) => v !== cacheName)
|
||||
.map(name => caches.delete(name))
|
||||
))
|
||||
.then(() => self.clients.claim())
|
||||
);
|
||||
});
|
||||
|
||||
self.addEventListener('fetch', ev => {
|
||||
if (ev.request.method !== 'GET' || ev.request.url.startsWith(apiUrl)) return;
|
||||
ev.respondWith(
|
||||
caches.match(ev.request)
|
||||
.then(response => {
|
||||
return response || fetch(ev.request);
|
||||
})
|
||||
.catch(() => {
|
||||
return caches.match("/");
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
// プッシュ通知を受け取ったとき
|
||||
|
BIN
src/client/assets/fedi.jpg
Normal file
BIN
src/client/assets/fedi.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 76 KiB |
@@ -5,7 +5,7 @@
|
||||
import * as fs from 'fs';
|
||||
import * as yaml from 'js-yaml';
|
||||
import { Source, Mixin } from './types';
|
||||
import * as pkg from '../../package.json';
|
||||
import * as meta from '../meta.json';
|
||||
|
||||
/**
|
||||
* Path of configuration directory
|
||||
@@ -30,6 +30,7 @@ export default function load() {
|
||||
|
||||
config.port = config.port || parseInt(process.env.PORT || '', 10);
|
||||
|
||||
mixin.version = meta.version;
|
||||
mixin.host = url.host;
|
||||
mixin.hostname = url.hostname;
|
||||
mixin.scheme = url.protocol.replace(/:$/, '');
|
||||
@@ -38,10 +39,12 @@ export default function load() {
|
||||
mixin.apiUrl = `${mixin.scheme}://${mixin.host}/api`;
|
||||
mixin.authUrl = `${mixin.scheme}://${mixin.host}/auth`;
|
||||
mixin.driveUrl = `${mixin.scheme}://${mixin.host}/files`;
|
||||
mixin.userAgent = `Misskey/${pkg.version} (${config.url})`;
|
||||
mixin.userAgent = `Misskey/${meta.version} (${config.url})`;
|
||||
|
||||
if (config.autoAdmin == null) config.autoAdmin = false;
|
||||
|
||||
if (!config.redis.prefix) config.redis.prefix = mixin.host;
|
||||
|
||||
return Object.assign(config, mixin);
|
||||
}
|
||||
|
||||
|
@@ -29,6 +29,7 @@ export type Source = {
|
||||
port: number;
|
||||
pass: string;
|
||||
index?: string;
|
||||
ssl?: boolean;
|
||||
};
|
||||
|
||||
autoAdmin?: boolean;
|
||||
@@ -51,12 +52,15 @@ export type Source = {
|
||||
host: string;
|
||||
port: number;
|
||||
};
|
||||
|
||||
mediaProxy?: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Misskeyが自動的に(ユーザーが設定した情報から推論して)設定する情報
|
||||
*/
|
||||
export type Mixin = {
|
||||
version: string;
|
||||
host: string;
|
||||
hostname: string;
|
||||
scheme: string;
|
||||
|
@@ -1,3 +1,3 @@
|
||||
{
|
||||
"copyright": "Copyright (c) 2014-2019 syuilo"
|
||||
"copyright": "Copyright (c) 2014-2020 syuilo"
|
||||
}
|
||||
|
@@ -32,7 +32,7 @@ const index = {
|
||||
|
||||
// Init ElasticSearch connection
|
||||
const client = config.elasticsearch ? new elasticsearch.Client({
|
||||
node: `http://${config.elasticsearch.host}:${config.elasticsearch.port}`,
|
||||
node: `${config.elasticsearch.ssl ? 'https://' : 'http://'}${config.elasticsearch.host}:${config.elasticsearch.port}`,
|
||||
pingTimeout: 30000
|
||||
}) : null;
|
||||
|
||||
|
@@ -155,7 +155,7 @@ export function initDb(justBorrow = false, sync = false, log = false) {
|
||||
host: config.redis.host,
|
||||
port: config.redis.port,
|
||||
password: config.redis.pass,
|
||||
prefix: config.redis.prefix,
|
||||
prefix: `${config.redis.prefix}:query:`,
|
||||
db: config.redis.db || 0
|
||||
}
|
||||
} : false,
|
||||
|
@@ -27,7 +27,7 @@ Misskeyのリバーシ機能に対応したBotの開発方法をここに記し
|
||||
* `pos`として位置情報が含まれている
|
||||
|
||||
## 位置の計算法
|
||||
8x8のマップを考える場合、各マスの位置(Posと呼びます)は次のようになっています:
|
||||
8x8のマップを考える場合、各マスの位置(インデックスと呼びます)は次のようになっています:
|
||||
```
|
||||
+--+--+--+--+--+--+--+--+
|
||||
| 0| 1| 2| 3| 4| 5| 6| 7|
|
||||
@@ -38,7 +38,7 @@ Misskeyのリバーシ機能に対応したBotの開発方法をここに記し
|
||||
...
|
||||
```
|
||||
|
||||
### X,Y座標 から Pos に変換する
|
||||
### X,Y座標 から インデックス に変換する
|
||||
```
|
||||
pos = x + (y * mapWidth)
|
||||
```
|
||||
@@ -47,7 +47,7 @@ pos = x + (y * mapWidth)
|
||||
mapWidth = map[0].length
|
||||
```
|
||||
|
||||
### Pos から X,Y座標 に変換する
|
||||
### インデックス から X,Y座標 に変換する
|
||||
```
|
||||
x = pos % mapWidth
|
||||
y = Math.floor(pos / mapWidth)
|
||||
|
1655
src/emojilist.json
Normal file
1655
src/emojilist.json
Normal file
File diff suppressed because it is too large
Load Diff
3
src/meta.json
Normal file
3
src/meta.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"version": "unknown"
|
||||
}
|
@@ -145,9 +145,10 @@ export const mfmLanguage = P.createLanguage({
|
||||
if (!match) return P.makeFailure(i, 'not a hashtag');
|
||||
let hashtag = match[1];
|
||||
hashtag = removeOrphanedBrackets(hashtag);
|
||||
if (hashtag.match(/^(\u20e3|\ufe0f)/)) return P.makeFailure(i, 'not a hashtag');
|
||||
if (hashtag.match(/^[0-9]+$/)) return P.makeFailure(i, 'not a hashtag');
|
||||
if (input[i - 1] != null && input[i - 1].match(/[a-z0-9]/i)) return P.makeFailure(i, 'not a hashtag');
|
||||
if (hashtag.length > 50) return P.makeFailure(i, 'not a hashtag');
|
||||
if (Array.from(hashtag || '').length > 128) return P.makeFailure(i, 'not a hashtag');
|
||||
return P.makeSuccess(i + ('#' + hashtag).length, createLeaf('hashtag', { hashtag: hashtag }));
|
||||
}),
|
||||
url: () => {
|
||||
@@ -166,10 +167,7 @@ export const mfmLanguage = P.createLanguage({
|
||||
url = match[0];
|
||||
}
|
||||
url = removeOrphanedBrackets(url);
|
||||
while (url.endsWith('.') || url.endsWith(',')) {
|
||||
if (url.endsWith('.')) url = url.substr(0, url.lastIndexOf('.'));
|
||||
if (url.endsWith(',')) url = url.substr(0, url.lastIndexOf(','));
|
||||
}
|
||||
url = url.replace(/[.,]*$/, '');
|
||||
return P.makeSuccess(i + url.length, url);
|
||||
}).map(x => createLeaf('url', { url: x }));
|
||||
},
|
||||
|
@@ -135,8 +135,8 @@ export function toHtml(tokens: MfmForest | null, mentionedRemoteUsers: IMentione
|
||||
break;
|
||||
default:
|
||||
const remoteUserInfo = mentionedRemoteUsers.find(remoteUser => remoteUser.username === username && remoteUser.host === host);
|
||||
a.href = remoteUserInfo ? remoteUserInfo.uri : `${config.url}/${acct}`;
|
||||
a.className = 'mention';
|
||||
a.href = remoteUserInfo ? (remoteUserInfo.url ? remoteUserInfo.url : remoteUserInfo.uri) : `${config.url}/${acct}`;
|
||||
a.className = 'u-url mention';
|
||||
break;
|
||||
}
|
||||
a.textContent = acct;
|
||||
|
@@ -162,6 +162,7 @@ export class ASEvaluator {
|
||||
multiply: (a: number, b: number) => a * b,
|
||||
divide: (a: number, b: number) => a / b,
|
||||
mod: (a: number, b: number) => a % b,
|
||||
round: (a: number) => Math.round(a),
|
||||
strLen: (a: string) => a.length,
|
||||
strPick: (a: string, b: number) => a[b - 1],
|
||||
strReplace: (a: string, b: string, c: string) => a.split(b).join(c),
|
||||
|
@@ -24,6 +24,7 @@ import {
|
||||
faExchangeAlt,
|
||||
faRecycle,
|
||||
faIndent,
|
||||
faCalculator,
|
||||
} from '@fortawesome/free-solid-svg-icons';
|
||||
import { faFlag } from '@fortawesome/free-regular-svg-icons';
|
||||
|
||||
@@ -59,6 +60,7 @@ export const funcDefs: Record<string, { in: any[]; out: any; category: string; i
|
||||
multiply: { in: ['number', 'number'], out: 'number', category: 'operation', icon: faTimes, },
|
||||
divide: { in: ['number', 'number'], out: 'number', category: 'operation', icon: faDivide, },
|
||||
mod: { in: ['number', 'number'], out: 'number', category: 'operation', icon: faDivide, },
|
||||
round: { in: ['number'], out: 'number', category: 'operation', icon: faCalculator, },
|
||||
eq: { in: [0, 0], out: 'boolean', category: 'comparison', icon: faEquals, },
|
||||
notEq: { in: [0, 0], out: 'boolean', category: 'comparison', icon: faNotEqual, },
|
||||
gt: { in: ['number', 'number'], out: 'boolean', category: 'comparison', icon: faGreaterThan, },
|
||||
|
@@ -20,3 +20,7 @@ const lock: (key: string, timeout?: number) => Promise<() => void>
|
||||
export function getApLock(uri: string, timeout = 30 * 1000) {
|
||||
return lock(`ap-object:${uri}`, timeout);
|
||||
}
|
||||
|
||||
export function getNodeinfoLock(host: string, timeout = 30 * 1000) {
|
||||
return lock(`nodeinfo:${host}`, timeout);
|
||||
}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import * as fs from 'fs';
|
||||
import * as request from 'request';
|
||||
import config from '../config';
|
||||
import chalk from 'chalk';
|
||||
import * as chalk from 'chalk';
|
||||
import Logger from '../services/logger';
|
||||
|
||||
export async function downloadUrl(url: string, path: string) {
|
||||
|
File diff suppressed because one or more lines are too long
7
src/misc/emojilist.ts
Normal file
7
src/misc/emojilist.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
// initial converted from https://github.com/muan/emojilib/commit/242fe68be86ed6536843b83f7e32f376468b38fb
|
||||
export const emojilist = require('../emojilist.json') as {
|
||||
name: string;
|
||||
keywords: string[];
|
||||
char: string;
|
||||
category: 'people' | 'animals_and_nature' | 'food_and_drink' | 'activity' | 'travel_and_places' | 'objects' | 'symbols' | 'flags';
|
||||
}[];
|
8
src/misc/hard-limits.ts
Normal file
8
src/misc/hard-limits.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
|
||||
// If you change DB_* values, you must also change the DB schema.
|
||||
|
||||
/**
|
||||
* Maximum note text length that can be stored in DB.
|
||||
* Surrogate pairs count as one
|
||||
*/
|
||||
export const DB_MAX_NOTE_TEXT_LENGTH = 8192;
|
@@ -1,4 +1 @@
|
||||
export const twemojiBase = 'https://cdn.jsdelivr.net/npm/twemoji@12.0.1';
|
||||
// https://cdn.jsdelivr.net/npm/twemoji@12.0.1
|
||||
// https://cdnjs.cloudflare.com/ajax/libs/twemoji/12.0.1
|
||||
// https://twemoji.maxcdn.com
|
||||
export const twemojiSvgBase = 'https://twemoji.maxcdn.com/v/latest/svg';
|
||||
|
@@ -24,6 +24,11 @@ export class Emoji {
|
||||
})
|
||||
public host: string | null;
|
||||
|
||||
@Column('varchar', {
|
||||
length: 128, nullable: true
|
||||
})
|
||||
public category: string | null;
|
||||
|
||||
@Column('varchar', {
|
||||
length: 512,
|
||||
})
|
||||
|
@@ -25,15 +25,6 @@ export class Instance {
|
||||
})
|
||||
public host: string;
|
||||
|
||||
/**
|
||||
* インスタンスのシステム (MastodonとかMisskeyとかPleromaとか)
|
||||
*/
|
||||
@Column('varchar', {
|
||||
length: 64, nullable: true,
|
||||
comment: 'The system of the Instance.'
|
||||
})
|
||||
public system: string | null;
|
||||
|
||||
/**
|
||||
* インスタンスのユーザー数
|
||||
*/
|
||||
@@ -129,4 +120,45 @@ export class Instance {
|
||||
default: false
|
||||
})
|
||||
public isMarkedAsClosed: boolean;
|
||||
|
||||
@Column('varchar', {
|
||||
length: 64, nullable: true, default: null,
|
||||
comment: 'The software of the Instance.'
|
||||
})
|
||||
public softwareName: string | null;
|
||||
|
||||
@Column('varchar', {
|
||||
length: 64, nullable: true, default: null,
|
||||
})
|
||||
public softwareVersion: string | null;
|
||||
|
||||
@Column('boolean', {
|
||||
nullable: true, default: null,
|
||||
})
|
||||
public openRegistrations: boolean | null;
|
||||
|
||||
@Column('varchar', {
|
||||
length: 256, nullable: true, default: null,
|
||||
})
|
||||
public name: string | null;
|
||||
|
||||
@Column('varchar', {
|
||||
length: 4096, nullable: true, default: null,
|
||||
})
|
||||
public description: string | null;
|
||||
|
||||
@Column('varchar', {
|
||||
length: 128, nullable: true, default: null,
|
||||
})
|
||||
public maintainerName: string | null;
|
||||
|
||||
@Column('varchar', {
|
||||
length: 256, nullable: true, default: null,
|
||||
})
|
||||
public maintainerEmail: string | null;
|
||||
|
||||
@Column('timestamp with time zone', {
|
||||
nullable: true,
|
||||
})
|
||||
public infoUpdatedAt: Date | null;
|
||||
}
|
||||
|
@@ -64,6 +64,11 @@ export class MessagingMessage {
|
||||
})
|
||||
public isRead: boolean;
|
||||
|
||||
@Column('varchar', {
|
||||
length: 512, nullable: true,
|
||||
})
|
||||
public uri: string | null;
|
||||
|
||||
@Column({
|
||||
...id(),
|
||||
array: true, default: '{}'
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user