Compare commits
39 Commits
Author | SHA1 | Date | |
---|---|---|---|
796252357e | |||
b0344d52e9 | |||
8e6da3a0d9 | |||
756e4eaeec | |||
3126d0730a | |||
748e9f15df | |||
7c714f5788 | |||
d3c3ad839b | |||
168de3c316 | |||
9e20fc5c88 | |||
1ff5151786 | |||
a56738a331 | |||
2d04a3d6d2 | |||
e0a55b9100 | |||
0a57eecb3a | |||
51f98020f6 | |||
70123805e1 | |||
1448b11d00 | |||
490b81ed05 | |||
96f675abed | |||
4cd451c613 | |||
187792dfc4 | |||
3dde561fe5 | |||
a75ec45172 | |||
3732ddf75f | |||
b8d8097734 | |||
1092532292 | |||
8a79ba0e2b | |||
ca2949fbb4 | |||
17b373ac07 | |||
7aa66f438f | |||
73641fd78d | |||
64aac9d6ad | |||
2be13736c8 | |||
ff4f5fec1d | |||
7d64f8abe4 | |||
88e6929e9f | |||
5fb0a995dd | |||
58a04ce1a5 |
@ -84,40 +84,54 @@ redis:
|
||||
drive:
|
||||
storage: 'fs'
|
||||
|
||||
# OR
|
||||
# OR
|
||||
|
||||
# storage: 'minio'
|
||||
# bucket:
|
||||
# prefix:
|
||||
# config:
|
||||
# endPoint:
|
||||
# port:
|
||||
# useSSL:
|
||||
# accessKey:
|
||||
# secretKey:
|
||||
#drive:
|
||||
# storage: 'minio'
|
||||
# bucket:
|
||||
# prefix:
|
||||
# config:
|
||||
# endPoint:
|
||||
# port:
|
||||
# useSSL:
|
||||
# accessKey:
|
||||
# secretKey:
|
||||
|
||||
# S3 example
|
||||
# storage: 'minio'
|
||||
# bucket: bucket-name
|
||||
# prefix: files
|
||||
# config:
|
||||
# endPoint: s3-us-west-2.amazonaws.com
|
||||
# region: us-west-2
|
||||
# useSSL: true
|
||||
# accessKey: XXX
|
||||
# secretKey: YYY
|
||||
# S3/GCS example
|
||||
#
|
||||
# * Replace <endpoint> to
|
||||
# S3: see https://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region
|
||||
# GCS: use 'storage.googleapis.com'
|
||||
#
|
||||
# * Replace <region> to
|
||||
# S3: see https://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region
|
||||
# GCS: not needed (just delete the region line)
|
||||
#
|
||||
#drive:
|
||||
# storage: 'minio'
|
||||
# bucket: bucket-name
|
||||
# prefix: files
|
||||
# baseUrl: https://bucket-name.<endpoint>
|
||||
# config:
|
||||
# endPoint: <endpoint>
|
||||
# region: <region>
|
||||
# useSSL: true
|
||||
# accessKey: XXX
|
||||
# secretKey: YYY
|
||||
|
||||
# S3 example (with CDN, custom domain)
|
||||
# storage: 'minio'
|
||||
# bucket: drive.example.com
|
||||
# prefix: files
|
||||
# baseUrl: https://drive.example.com
|
||||
# config:
|
||||
# endPoint: s3-us-west-2.amazonaws.com
|
||||
# region: us-west-2
|
||||
# useSSL: true
|
||||
# accessKey: XXX
|
||||
# secretKey: YYY
|
||||
# S3/GCS example (with CDN, custom domain)
|
||||
#
|
||||
#drive:
|
||||
# storage: 'minio'
|
||||
# bucket: drive.example.com
|
||||
# prefix: files
|
||||
# baseUrl: https://drive.example.com
|
||||
# config:
|
||||
# endPoint: <endpoint>
|
||||
# region: <region>
|
||||
# useSSL: true
|
||||
# accessKey: XXX
|
||||
# secretKey: YYY
|
||||
|
||||
# ┌───────────────┐
|
||||
#───┘ ID generation └───────────────────────────────────────────
|
||||
@ -149,3 +163,6 @@ autoAdmin: true
|
||||
|
||||
# Clustering
|
||||
#clusterLimit: 1
|
||||
|
||||
# IP address family used for outgoing request (ipv4, ipv6 or dual)
|
||||
#outgoingAddressFamily: ipv4
|
||||
|
48
CHANGELOG.md
48
CHANGELOG.md
@ -73,6 +73,54 @@ mongodb:
|
||||
8. master ブランチに戻す
|
||||
9. enjoy
|
||||
|
||||
11.12.0 (2019/05/10)
|
||||
--------------------
|
||||
### 注意
|
||||
このアップデートを適用した後、プロセスを起動(もしくは再起動)する前に[マイグレーション](#migration)の手順を実行してください
|
||||
|
||||
### Improvements
|
||||
* インスタンス運営者がおすすめアカウントを設定できるように
|
||||
* MisskeyPagesでNAME環境変数がNULLにならないように
|
||||
* MisskeyPagesにNULL環境変数を追加
|
||||
* MisskeyPagesで変数を並べ替えられるように
|
||||
* MisskeyPagesのテキストのリスト内で変数埋め込みできるように
|
||||
* 自分の指定した投稿のRenoteを全て解除するAPIを追加
|
||||
|
||||
### Fixes
|
||||
* Noteをpull取得した時にhost名がvalidateされていない問題を修正
|
||||
* みつけるで人気のタグが表示されない問題を修正
|
||||
|
||||
### その他
|
||||
* アカウントのisVerifiedフラグを廃止
|
||||
|
||||
11.11.2 (2019/05/07)
|
||||
--------------------
|
||||
### Fixes
|
||||
* IPv4 onlyホストからDualstackホストにAP deliverできない問題を修正
|
||||
* ストリーミングに接続するまでラグがある問題を修正
|
||||
* 2段階認証のコードが0から始まる時正しく入力できない問題を修正
|
||||
* ユーザーの更新日時が新しい順で更新日時がnullのユーザーが先頭に来る問題を修正
|
||||
* 値選択時の問題を修正
|
||||
* リバーシでマップの変更が反映されない問題を修正
|
||||
* リバーシで対局終了直後に盤面を巻き戻してもすぐ最終ターンまでリセットされる問題を修正
|
||||
|
||||
11.11.1 (2019/05/05)
|
||||
--------------------
|
||||
### Fixes
|
||||
* MisskeyPagesのリストから選択関数が使えない問題を修正
|
||||
|
||||
11.11.0 (2019/05/05)
|
||||
--------------------
|
||||
### Improvements
|
||||
* MisskeyPagesにリストから選択関数を追加
|
||||
* MisskeyPagesに確率を指定できるテキストランダム選択関数を追加
|
||||
* 外部サービス連携ログインリンクにアイコン追加
|
||||
|
||||
### Fixes
|
||||
* MisskeyPagesでifを入れ子にできなくなっていた問題を修正
|
||||
* MisskeyPagesで数値入力を作成するとテキスト入力になる問題を修正
|
||||
* 外部サービス連携に関する問題を修正
|
||||
|
||||
11.10.1 (2019/05/04)
|
||||
--------------------
|
||||
### Fixes
|
||||
|
12
README.md
12
README.md
@ -105,6 +105,7 @@ Please see the [Contribution Guide](./CONTRIBUTING.md).
|
||||
<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/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/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/13099460/43cecdbaa63a40d79bf50a96b9910b9d/1.jpe?token-time=2145916800&token-hash=bqwLTk0Wo0hUJJ8J5y7ii05bLzz-_CDA7Bo0Mp4RFU0%3D" alt="ne_moni" 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/5670915/ee175f0bfb6347ffa4ea101a8c097bff/1.jpg?token-time=2145916800&token-hash=mPLM9CA-riFHx-myr3bLZJuH2xBRHA9se5VbHhLIOuA%3D" alt="osapon" width="100"></td>
|
||||
@ -112,6 +113,7 @@ Please see the [Contribution Guide](./CONTRIBUTING.md).
|
||||
</tr><tr>
|
||||
<td><a href="https://www.patreon.com/rane_hs">Hiroshi Seki</a></td>
|
||||
<td><a href="https://www.patreon.com/weepjp">weepjp</a></td>
|
||||
<td><a href="https://www.patreon.com/user?u=19045173">kiritan</a></td>
|
||||
<td><a href="https://www.patreon.com/user?u=13099460">ne_moni</a></td>
|
||||
<td><a href="https://www.patreon.com/user?u=12913507">Melilot</a></td>
|
||||
<td><a href="https://www.patreon.com/osapon">osapon</a></td>
|
||||
@ -127,7 +129,6 @@ Please see the [Contribution Guide](./CONTRIBUTING.md).
|
||||
<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://c8.patreon.com/2/200/17463605" alt="Sampot" 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/13737140/1adf7835017d479280d90fe8d30aade2/1.png?token-time=2145916800&token-hash=0pdle8h5pDZrww0BDOjdz6zO-HudeGTh36a3qi1biVU%3D" alt="Satsuki Yanagi" width="100"></td>
|
||||
</tr><tr>
|
||||
<td><a href="https://www.patreon.com/Yuzulia">YuzuRyo61</a></td>
|
||||
<td><a href="https://www.patreon.com/gutfuckllc">gutfuckllc</a></td>
|
||||
@ -138,9 +139,9 @@ Please see the [Contribution Guide](./CONTRIBUTING.md).
|
||||
<td><a href="https://www.patreon.com/yukimochi">YUKIMOCHI</a></td>
|
||||
<td><a href="https://www.patreon.com/user?u=17463605">Sampot</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=13737140">Satsuki Yanagi</a></td>
|
||||
</tr></table>
|
||||
<table><tr>
|
||||
<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/83884b38afc74d4cbe83c30a13b10edd/1.png?token-time=2145916800&token-hash=R5Tog8RWg0rguRoCIoir3lThokrdPvs8Utfikhc0nhY%3D" alt="Atsuko Tominaga" width="100"></td>
|
||||
@ -149,8 +150,8 @@ Please see the [Contribution Guide](./CONTRIBUTING.md).
|
||||
<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>
|
||||
<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>
|
||||
</tr><tr>
|
||||
<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>
|
||||
@ -159,17 +160,18 @@ Please see the [Contribution Guide](./CONTRIBUTING.md).
|
||||
<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>
|
||||
</tr></table>
|
||||
<table><tr>
|
||||
<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://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/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=12531784">Takashi Shibuya</a></td>
|
||||
</tr></table>
|
||||
|
||||
**Last updated:** Fri, 03 May 2019 05:33:07 UTC
|
||||
**Last updated:** Tue, 07 May 2019 11:55:07 UTC
|
||||
<!-- PATREON_END -->
|
||||
|
||||
:four_leaf_clover: Copyright
|
||||
|
@ -61,6 +61,7 @@ common:
|
||||
month-and-day: "{day}. {month}."
|
||||
trash: "Koš"
|
||||
drive: "Disk"
|
||||
pages: "Stránky"
|
||||
messaging: "Konverzace"
|
||||
home: "Domů"
|
||||
deck: "Deck"
|
||||
@ -71,12 +72,20 @@ common:
|
||||
favorites: "Oblíbené"
|
||||
permissions:
|
||||
"read:account": "Zobrazit informace o účtu"
|
||||
"write:account": "Narábět s účtem"
|
||||
"read:blocks": "Prohlížet blokování"
|
||||
"write:blocks": "Narábět s blokováním"
|
||||
"read:drive": "Prohlížet Disk"
|
||||
"write:drive": "Pracovat s Diskem"
|
||||
"read:favorites": "Prohlížet oblíbené"
|
||||
"write:favorites": "Narábět s oblíbeními"
|
||||
"read:following": "Prohlížet následování"
|
||||
"write:following": "Pracovat s následováním"
|
||||
"read:messaging": "Prohlížet konverzaci"
|
||||
"write:messaging": "Pracovat s konverzaci"
|
||||
"read:mutes": "Prohlížet ztlumené"
|
||||
"write:mutes": "Narábět s utíšeními"
|
||||
"write:notes": "Narábět s poznámkami"
|
||||
"read:notifications": "Prohlížet oznámení"
|
||||
"write:notifications": "Pracovat s oznámeními"
|
||||
"read:reactions": "Prohlížet reakce"
|
||||
@ -377,6 +386,7 @@ common/views/components/theme.vue:
|
||||
installed: "\"{}\" byl nainstalován"
|
||||
create-a-theme: "Vytvořit motiv"
|
||||
save-created-theme: "Uložit motiv"
|
||||
text-color: "Barva textu"
|
||||
base-theme: "Základní vzhled"
|
||||
base-theme-light: "Světlý"
|
||||
base-theme-dark: "Tmavý"
|
||||
@ -454,6 +464,7 @@ common/views/components/user-menu.vue:
|
||||
suspend: "Zmrazit"
|
||||
common/views/components/poll.vue:
|
||||
vote-count: "{} hlasů"
|
||||
total-votes: "{} hlasů celkem"
|
||||
vote: "Hlasovat"
|
||||
show-result: "Podívat se na výsledky"
|
||||
voted: "Už jste hlasovaly"
|
||||
@ -464,10 +475,21 @@ common/views/components/poll.vue:
|
||||
remaining-seconds: "zbývá {s} sekund"
|
||||
common/views/components/poll-editor.vue:
|
||||
no-only-one-choice: "Musíte vybrat alespoň dvě možnosti"
|
||||
choice-n: "Volba {}"
|
||||
remove: "Odstranit tuto možnost"
|
||||
add: "+ Přidat možnost"
|
||||
destroy: "Zahodit dotazník"
|
||||
expiration: "Termín"
|
||||
infinite: "Nekonečne"
|
||||
at: "Výběr data a času"
|
||||
deadline-date: "Termín ukončení"
|
||||
interval: "Trvání"
|
||||
second: "Sekunda"
|
||||
minute: "Minuta"
|
||||
hour: "Hodina"
|
||||
day: "Ne"
|
||||
common/views/components/reaction-picker.vue:
|
||||
choose-reaction: "Vyberte svoji reakci"
|
||||
common/views/components/emoji-picker.vue:
|
||||
custom-emoji: "Emoji"
|
||||
people: "Lidé"
|
||||
@ -1198,3 +1220,42 @@ deck/deck.user-column.vue:
|
||||
activity: "Aktivita"
|
||||
dev/views/new-app.vue:
|
||||
app-name-desc: "Jméno vaší aplikace"
|
||||
pages:
|
||||
title: "Titulek"
|
||||
blocks:
|
||||
post: "Formulář pro psaní"
|
||||
_post:
|
||||
text: "Obsah"
|
||||
_textInput:
|
||||
text: "Titulek"
|
||||
_textareaInput:
|
||||
text: "Titulek"
|
||||
_numberInput:
|
||||
text: "Titulek"
|
||||
_switch:
|
||||
text: "Titulek"
|
||||
_counter:
|
||||
text: "Titulek"
|
||||
_button:
|
||||
text: "Titulek"
|
||||
_action:
|
||||
_dialog:
|
||||
content: "Obsah"
|
||||
script:
|
||||
categories:
|
||||
random: "Náhodně"
|
||||
list: "Seznamy"
|
||||
blocks:
|
||||
_join:
|
||||
arg1: "Seznamy"
|
||||
random: "Náhodně"
|
||||
_randomPick:
|
||||
arg1: "Seznamy"
|
||||
_dailyRandomPick:
|
||||
arg1: "Seznamy"
|
||||
_seedRandomPick:
|
||||
arg2: "Seznamy"
|
||||
_pick:
|
||||
arg1: "Seznamy"
|
||||
types:
|
||||
array: "Seznamy"
|
||||
|
@ -53,6 +53,7 @@ common:
|
||||
month-and-day: "{day}/{month}"
|
||||
trash: "Papierkorb"
|
||||
drive: "Drive"
|
||||
pages: "Seite"
|
||||
messaging: "Unterhaltungen"
|
||||
home: "Home"
|
||||
deck: "Stapel"
|
||||
@ -64,6 +65,7 @@ common:
|
||||
permissions:
|
||||
"read:account": "Accountinformationen anzeigen."
|
||||
"write:account": "Accountinformationen bearbeiten."
|
||||
"read:blocks": "Blöcke anzeigen"
|
||||
"read:drive": "Dateien anzeigen"
|
||||
"write:drive": "Dateien bearbeiten"
|
||||
"read:favorites": "Favoriten anzeigen"
|
||||
@ -718,25 +720,6 @@ deck/deck.user-column.vue:
|
||||
docs:
|
||||
edit-this-page-on-github: "Hast Du einen Fehler gefunden oder Lust, diese Dokumentation zu verbessern?"
|
||||
edit-this-page-on-github-link: "Seite auf GitHub bearbeiten!"
|
||||
api:
|
||||
entities:
|
||||
properties: "Eigenschaften"
|
||||
endpoints:
|
||||
params: "Parameter"
|
||||
no-params: "Keine Parameter."
|
||||
res: "Antwort"
|
||||
require-credential: "Dieser Endpunkt erfordert eine Authentifizierung."
|
||||
require-permission: "Dieser Endpunkt erfordert die {permission} Berechtigung."
|
||||
has-limit: "Es gibt eine Ratenbegrenzung."
|
||||
duration-limit: "Es sind maximal {max} Anfragen pro {duration} Millisekunden möglich."
|
||||
min-interval-limit: "Es ist nur eine Anfrage alle {interval} Millisekunden möglich."
|
||||
show-src: "Quellcode anzeigen."
|
||||
show-src-link: "Quellcode auf GitHub anzeigen"
|
||||
generated: "Dieses Dokument wird automatisch anhand der API-Definition generiert."
|
||||
props:
|
||||
name: "Name"
|
||||
type: "Typ"
|
||||
description: "Beschreibung"
|
||||
dev/views/index.vue:
|
||||
manage-apps: "Anwendungen verwalten"
|
||||
dev/views/apps.vue:
|
||||
@ -753,3 +736,24 @@ dev/views/new-app.vue:
|
||||
authority: "Berechtigungen"
|
||||
authority-desc: "Nur die hier eingetragenen Berechtigungen, werden per API zur Verfügung stehen."
|
||||
authority-warning: "Dies kann auch nach dem erstellen der Anwendung geändert werden, allerdings werden dann alle bisher generierten Token ungültig."
|
||||
pages:
|
||||
blocks:
|
||||
post: "\"Neuer Beitrag\"-Formular"
|
||||
script:
|
||||
categories:
|
||||
random: "Zufällige Auswahl"
|
||||
list: "Listen"
|
||||
blocks:
|
||||
_join:
|
||||
arg1: "Listen"
|
||||
random: "Zufällige Auswahl"
|
||||
_randomPick:
|
||||
arg1: "Listen"
|
||||
_dailyRandomPick:
|
||||
arg1: "Listen"
|
||||
_seedRandomPick:
|
||||
arg2: "Listen"
|
||||
_pick:
|
||||
arg1: "Listen"
|
||||
types:
|
||||
array: "Listen"
|
||||
|
@ -34,6 +34,7 @@ common:
|
||||
signup: "Sign up"
|
||||
signout: "Logout"
|
||||
reload-to-apply-the-setting: "You'll need to reload the page to reflect this setting. Do you want to reload it now?"
|
||||
fetching-as-ap-object: "Inquiring to union"
|
||||
got-it: "Got it!"
|
||||
customization-tips:
|
||||
title: "Customization tips"
|
||||
@ -61,6 +62,7 @@ common:
|
||||
month-and-day: "{month}/{day}"
|
||||
trash: "Trash"
|
||||
drive: "Drive"
|
||||
pages: "Pages"
|
||||
messaging: "Talk"
|
||||
home: "Home"
|
||||
deck: "Deck"
|
||||
@ -1621,25 +1623,6 @@ deck/deck.user-column.vue:
|
||||
docs:
|
||||
edit-this-page-on-github: "Found an error, or do you want to contribute to the documentation?"
|
||||
edit-this-page-on-github-link: "Edit this page at GitHub!"
|
||||
api:
|
||||
entities:
|
||||
properties: "Properties"
|
||||
endpoints:
|
||||
params: "Parameters"
|
||||
no-params: "No parameter."
|
||||
res: "Response"
|
||||
require-credential: "This endpoint requires the authentication information."
|
||||
require-permission: "This endpoint requires {permission} permission."
|
||||
has-limit: "There is a rate limit."
|
||||
duration-limit: "If you have sent your requests more than {max} times in {duration} milliseconds, you will be unable to send more requests."
|
||||
min-interval-limit: "If {interval} milliseconds haven't passed since the last request, you can't send a request."
|
||||
show-src: "You can view the source code for this endpoint."
|
||||
show-src-link: "See the code on GitHub"
|
||||
generated: "This document is generated by the API definition."
|
||||
props:
|
||||
name: "Name"
|
||||
type: "Type"
|
||||
description: "Description"
|
||||
dev/views/index.vue:
|
||||
manage-apps: "Manage apps"
|
||||
dev/views/apps.vue:
|
||||
@ -1648,13 +1631,252 @@ dev/views/apps.vue:
|
||||
app-missing: "No apps"
|
||||
dev/views/new-app.vue:
|
||||
new-app: "New Application"
|
||||
new-app-info: "You can also create an application with the API. (app/create)"
|
||||
create-app: "Creating application"
|
||||
app-name: "Application name"
|
||||
app-name-placeholder: "ex) Misskey for iOS"
|
||||
app-name-desc: "The name of your app"
|
||||
app-overview: "Application summary"
|
||||
app-overview-placeholder: " ex) Misskey iOS Client."
|
||||
app-overview-desc: "A brief description, or an introduction of your app."
|
||||
callback-url: "The callback URL (optional)"
|
||||
callback-url-placeholder: "ex) https://your.app.example.com/callback.php"
|
||||
callback-url-desc: "The URL to redirect to after the user is authenticated via the authentication form."
|
||||
authority: "Permissions"
|
||||
authority-desc: "Only the functions requested here can be accessed via the API."
|
||||
authority-warning: "You can change it even after creating the application, but if you give different permissions, all user keys associated at that time will be invalidated."
|
||||
pages:
|
||||
new-page: "Create a page"
|
||||
edit-page: "Edit a page"
|
||||
read-page: "Viewing the source"
|
||||
page-created: "Created the page!"
|
||||
page-updated: "Updated the page"
|
||||
are-you-sure-delete: "Do you want to delete this page?"
|
||||
page-deleted: "The page has been deleted"
|
||||
edit-this-page: "Edit this page"
|
||||
view-source: "View Source"
|
||||
view-page: "View page"
|
||||
inspector: "Inspector"
|
||||
content: "Page block"
|
||||
variables: "Variables"
|
||||
more-details: "Description"
|
||||
title: "Title"
|
||||
url: "Page URL"
|
||||
summary: "Summary of page"
|
||||
align-center: "Center align"
|
||||
font: "Font"
|
||||
fontSerif: "Serif"
|
||||
fontSansSerif: "Sans Serif"
|
||||
set-eye-catching-image: "Set an eye-catching image"
|
||||
remove-eye-catching-image: "Delete an eye-catching image"
|
||||
choose-block: "Add a block"
|
||||
select-type: "Select a type"
|
||||
enter-variable-name: "Please choose a variable name"
|
||||
the-variable-name-is-already-used: "This variable name is already used"
|
||||
content-blocks: "Content"
|
||||
input-blocks: "Input"
|
||||
special-blocks: "Special"
|
||||
post-from-post-form: "Post this content"
|
||||
posted-from-post-form: "Posted!"
|
||||
blocks:
|
||||
text: "Text"
|
||||
textarea: "Text area"
|
||||
section: "Section"
|
||||
image: "Images"
|
||||
button: "Button"
|
||||
if: "If"
|
||||
_if:
|
||||
variable: "Variables"
|
||||
post: "Post form"
|
||||
_post:
|
||||
text: "Content"
|
||||
textInput: "Text input"
|
||||
_textInput:
|
||||
name: "Variable name"
|
||||
text: "Title"
|
||||
default: "Default value"
|
||||
textareaInput: "Multiple type text input"
|
||||
_textareaInput:
|
||||
name: "Variable name"
|
||||
text: "Title"
|
||||
default: "Default value"
|
||||
numberInput: "Numeric input"
|
||||
_numberInput:
|
||||
name: "Variable name"
|
||||
text: "Title"
|
||||
default: "Default value"
|
||||
switch: "Switch"
|
||||
_switch:
|
||||
name: "Variable name"
|
||||
text: "Title"
|
||||
default: "Default value"
|
||||
counter: "Counter"
|
||||
_counter:
|
||||
name: "Variable name"
|
||||
text: "Title"
|
||||
inc: "Increase number"
|
||||
_button:
|
||||
text: "Title"
|
||||
action: "Operation when the button pressed"
|
||||
_action:
|
||||
dialog: "Show a dialog"
|
||||
_dialog:
|
||||
content: "Content"
|
||||
resetRandom: "Reset a random number"
|
||||
script:
|
||||
categories:
|
||||
flow: "Control"
|
||||
logical: "Logical operation"
|
||||
operation: "Compute"
|
||||
comparison: "Compare"
|
||||
random: "Random"
|
||||
value: "Value"
|
||||
fn: "Function"
|
||||
text: "Text operation"
|
||||
convert: "Variable"
|
||||
list: "Lists"
|
||||
blocks:
|
||||
text: "Text"
|
||||
multiLineText: "Text (Multiple lines)"
|
||||
textList: "List of text"
|
||||
_textList:
|
||||
info: "Separate each one with a newline"
|
||||
strLen: "Length of text"
|
||||
_strLen:
|
||||
arg1: "Text"
|
||||
strPick: "Extract character"
|
||||
_strPick:
|
||||
arg1: "Text"
|
||||
arg2: "Position of character"
|
||||
strReplace: "Replace string(s)"
|
||||
_strReplace:
|
||||
arg1: "Text"
|
||||
arg2: "Before replacement"
|
||||
arg3: "After replacement"
|
||||
strReverse: "Flip text"
|
||||
_strReverse:
|
||||
arg1: "Text"
|
||||
_join:
|
||||
arg1: "Lists"
|
||||
arg2: "Separator"
|
||||
add: "+ Plus"
|
||||
_add:
|
||||
arg1: "A"
|
||||
arg2: "B"
|
||||
subtract: "- Minus"
|
||||
_subtract:
|
||||
arg1: "A"
|
||||
arg2: "B"
|
||||
multiply: "× Multiply"
|
||||
_multiply:
|
||||
arg1: "A"
|
||||
arg2: "B"
|
||||
divide: "÷ Divide"
|
||||
_divide:
|
||||
arg1: "A"
|
||||
arg2: "B"
|
||||
_remind:
|
||||
arg1: "A"
|
||||
arg2: "B"
|
||||
eq: "A and B are equal"
|
||||
_eq:
|
||||
arg1: "A"
|
||||
arg2: "B"
|
||||
notEq: "A and B are different"
|
||||
_notEq:
|
||||
arg1: "A"
|
||||
arg2: "B"
|
||||
and: "A and B"
|
||||
_and:
|
||||
arg1: "A"
|
||||
arg2: "B"
|
||||
or: "A or B"
|
||||
_or:
|
||||
arg1: "A"
|
||||
arg2: "B"
|
||||
lt: "A is smaller than B"
|
||||
_lt:
|
||||
arg1: "A"
|
||||
arg2: "B"
|
||||
gt: "A is bigger than B"
|
||||
_gt:
|
||||
arg1: "A"
|
||||
arg2: "B"
|
||||
ltEq: "A is smaller or same than B"
|
||||
_ltEq:
|
||||
arg1: "A"
|
||||
arg2: "B"
|
||||
gtEq: "A is bigger or same than B"
|
||||
_gtEq:
|
||||
arg1: "A"
|
||||
arg2: "B"
|
||||
if: "Branch"
|
||||
_if:
|
||||
arg1: "If"
|
||||
arg2: "then"
|
||||
arg3: "else"
|
||||
not: "denial"
|
||||
_not:
|
||||
arg1: "denial"
|
||||
random: "Random"
|
||||
_random:
|
||||
arg1: "Probability"
|
||||
rannum: "Random number"
|
||||
_rannum:
|
||||
arg1: "Minimum"
|
||||
arg2: "Maximum"
|
||||
randomPick: "Choose at random from the list"
|
||||
_randomPick:
|
||||
arg1: "Lists"
|
||||
dailyRandom: "Random (Daily for each user)"
|
||||
_dailyRandom:
|
||||
arg1: "Probability"
|
||||
dailyRannum: "Random number (Daily for each user)"
|
||||
_dailyRannum:
|
||||
arg1: "Minimum"
|
||||
arg2: "Maximum"
|
||||
dailyRandomPick: "Choose at random from the list (Daily for each user)"
|
||||
_dailyRandomPick:
|
||||
arg1: "Lists"
|
||||
_seedRandom:
|
||||
arg1: "Seed"
|
||||
arg2: "Probability"
|
||||
_seedRannum:
|
||||
arg1: "Seed"
|
||||
arg2: "Minimum"
|
||||
arg3: "Maximum"
|
||||
_seedRandomPick:
|
||||
arg1: "Seed"
|
||||
arg2: "Lists"
|
||||
_DRPWPM:
|
||||
arg1: "List of text"
|
||||
_pick:
|
||||
arg1: "Lists"
|
||||
arg2: "Position"
|
||||
number: "Number"
|
||||
stringToNumber: "Text to number"
|
||||
_stringToNumber:
|
||||
arg1: "Text"
|
||||
numberToString: "Number to text"
|
||||
_numberToString:
|
||||
arg1: "Number"
|
||||
splitStrByLine: "Split the text by lines"
|
||||
_splitStrByLine:
|
||||
arg1: "Text"
|
||||
ref: "Variables"
|
||||
fn: "Function"
|
||||
_fn:
|
||||
slots: "Slots"
|
||||
arg1: "Output"
|
||||
for: "Repeat"
|
||||
thereIsEmptySlot: "Slot {slot} is empty!"
|
||||
types:
|
||||
string: "Text"
|
||||
number: "Number"
|
||||
boolean: "Flag"
|
||||
array: "Lists"
|
||||
stringArray: "List of text"
|
||||
emptySlot: "Empty slot"
|
||||
enviromentVariables: "Environment variable"
|
||||
pageVariables: "Page element"
|
||||
argVariables: "Input slot"
|
||||
|
@ -969,3 +969,24 @@ deck:
|
||||
rename: "Renombrar"
|
||||
deck/deck.user-column.vue:
|
||||
activity: "Actividad"
|
||||
pages:
|
||||
blocks:
|
||||
post: "Formulario"
|
||||
script:
|
||||
categories:
|
||||
random: "Aleatorio"
|
||||
list: "Listas"
|
||||
blocks:
|
||||
_join:
|
||||
arg1: "Listas"
|
||||
random: "Aleatorio"
|
||||
_randomPick:
|
||||
arg1: "Listas"
|
||||
_dailyRandomPick:
|
||||
arg1: "Listas"
|
||||
_seedRandomPick:
|
||||
arg2: "Listas"
|
||||
_pick:
|
||||
arg1: "Listas"
|
||||
types:
|
||||
array: "Listas"
|
||||
|
@ -60,6 +60,7 @@ common:
|
||||
month-and-day: "{day}-{month}"
|
||||
trash: "Corbeille"
|
||||
drive: "Drive"
|
||||
pages: "Pages"
|
||||
messaging: "Conversations"
|
||||
home: "Principal"
|
||||
deck: "Deck"
|
||||
@ -1469,6 +1470,7 @@ mobile/views/pages/drive.vue:
|
||||
contextmenu:
|
||||
upload: "Téléverser un fichier"
|
||||
create-folder: "Créer un dossier"
|
||||
rename-folder: "Renommer le dossier"
|
||||
mobile/views/pages/user-lists.vue:
|
||||
title: "Listes"
|
||||
mobile/views/pages/signup.vue:
|
||||
@ -1570,25 +1572,6 @@ deck/deck.user-column.vue:
|
||||
docs:
|
||||
edit-this-page-on-github: "Vous avez trouvé une erreur ou vous voulez contribuer à la documentation ?"
|
||||
edit-this-page-on-github-link: "Éditez cette page sur GitHub !"
|
||||
api:
|
||||
entities:
|
||||
properties: "Propriétés"
|
||||
endpoints:
|
||||
params: "Paramètres"
|
||||
no-params: "Aucun paramètre"
|
||||
res: "Réponse"
|
||||
require-credential: "Ce point de communication nécessite une authentification."
|
||||
require-permission: "Ce point de communication nécessite la permission {permission}."
|
||||
has-limit: "Il y’a un taux limite."
|
||||
duration-limit: "Si vous avez envoyé plus de {max} requêtes en {duration} millisecondes, vous ne serez pas en mesure d'envoyer d'autres requêtes."
|
||||
min-interval-limit: "Vous ne pourrez pas effectuer une nouvelle requête si {interval} millisecondes ne se sont pas écoulées depuis la dernière demande."
|
||||
show-src: "Vous pouvez voir le code source ce point de communication."
|
||||
show-src-link: "Consulter le code sur GitHub"
|
||||
generated: "Ce document est généré à partir de la définition de l’API."
|
||||
props:
|
||||
name: "Nom"
|
||||
type: "Type"
|
||||
description: "Description"
|
||||
dev/views/index.vue:
|
||||
manage-apps: "Gestion des applications"
|
||||
dev/views/apps.vue:
|
||||
@ -1605,3 +1588,142 @@ dev/views/new-app.vue:
|
||||
authority: "Autorisations "
|
||||
authority-desc: "Sont accessibles via l’API, uniquement les fonctionnalités demandées ici."
|
||||
authority-warning: "Vous pouvez le changer même après avoir créé l'application, mais si vous attribuez une nouvelle permission, toutes les clés utilisateur associées seront dès lors invalides."
|
||||
pages:
|
||||
title: "Titre"
|
||||
blocks:
|
||||
text: "Texte"
|
||||
textarea: "Zone de texte"
|
||||
section: "Section"
|
||||
image: "Images"
|
||||
button: "Bouton"
|
||||
if: "Si"
|
||||
_if:
|
||||
variable: "Variables"
|
||||
post: "Champs de publication"
|
||||
_post:
|
||||
text: "Contenu"
|
||||
_textInput:
|
||||
name: "Nom de la variable"
|
||||
text: "Titre"
|
||||
default: "Valeur par défaut"
|
||||
_textareaInput:
|
||||
name: "Nom de la variable"
|
||||
text: "Titre"
|
||||
default: "Valeur par défaut"
|
||||
_numberInput:
|
||||
name: "Nom de la variable"
|
||||
text: "Titre"
|
||||
default: "Valeur par défaut"
|
||||
switch: "Basculer"
|
||||
_switch:
|
||||
name: "Nom de la variable"
|
||||
text: "Titre"
|
||||
default: "Valeur par défaut"
|
||||
counter: "Compteur"
|
||||
_counter:
|
||||
name: "Nom de la variable"
|
||||
text: "Titre"
|
||||
_button:
|
||||
text: "Titre"
|
||||
_action:
|
||||
_dialog:
|
||||
content: "Contenu"
|
||||
script:
|
||||
categories:
|
||||
flow: "Contrôle"
|
||||
logical: "Opération logique"
|
||||
operation: "Calculer"
|
||||
comparison: "Comparer"
|
||||
random: "Aléatoire"
|
||||
value: "Valeur"
|
||||
fn: "Fonction"
|
||||
list: "Listes"
|
||||
blocks:
|
||||
text: "Texte"
|
||||
strLen: "Longueur du texte"
|
||||
_strLen:
|
||||
arg1: "Texte"
|
||||
strPick: "Extraire un caractère"
|
||||
_strPick:
|
||||
arg1: "Texte"
|
||||
_strReplace:
|
||||
arg1: "Texte"
|
||||
arg2: "Avant le remplacement"
|
||||
arg3: "Après le remplacement"
|
||||
strReverse: "Inverser le texte"
|
||||
_strReverse:
|
||||
arg1: "Texte"
|
||||
_join:
|
||||
arg1: "Listes"
|
||||
arg2: "Séparateur"
|
||||
add: "+ Plus"
|
||||
_add:
|
||||
arg1: "A"
|
||||
arg2: "B"
|
||||
subtract: "- Moins"
|
||||
_subtract:
|
||||
arg1: "A"
|
||||
arg2: "B"
|
||||
multiply: "× Multiplier par"
|
||||
_multiply:
|
||||
arg1: "A"
|
||||
arg2: "B"
|
||||
divide: "÷ Diviser par"
|
||||
_divide:
|
||||
arg1: "A"
|
||||
arg2: "B"
|
||||
_remind:
|
||||
arg1: "A"
|
||||
arg2: "B"
|
||||
eq: "A et B sont équivalents"
|
||||
_eq:
|
||||
arg1: "A"
|
||||
arg2: "B"
|
||||
notEq: "A et B sont différents"
|
||||
_notEq:
|
||||
arg1: "A"
|
||||
arg2: "B"
|
||||
_and:
|
||||
arg1: "A"
|
||||
arg2: "B"
|
||||
_or:
|
||||
arg1: "A"
|
||||
arg2: "B"
|
||||
_lt:
|
||||
arg1: "A"
|
||||
arg2: "B"
|
||||
_gt:
|
||||
arg1: "A"
|
||||
arg2: "B"
|
||||
_ltEq:
|
||||
arg1: "A"
|
||||
arg2: "B"
|
||||
_gtEq:
|
||||
arg1: "A"
|
||||
arg2: "B"
|
||||
random: "Aléatoire"
|
||||
_randomPick:
|
||||
arg1: "Listes"
|
||||
_dailyRandomPick:
|
||||
arg1: "Listes"
|
||||
_seedRandomPick:
|
||||
arg2: "Listes"
|
||||
_pick:
|
||||
arg1: "Listes"
|
||||
number: "Numérique"
|
||||
_stringToNumber:
|
||||
arg1: "Texte"
|
||||
_numberToString:
|
||||
arg1: "Numérique"
|
||||
_splitStrByLine:
|
||||
arg1: "Texte"
|
||||
fn: "Fonction"
|
||||
_fn:
|
||||
arg1: "Sortie"
|
||||
for: "Répéter"
|
||||
types:
|
||||
string: "Texte"
|
||||
number: "Numérique"
|
||||
array: "Listes"
|
||||
stringArray: "Liste de texte"
|
||||
enviromentVariables: "Variables d'environnement"
|
||||
|
@ -263,7 +263,6 @@ common:
|
||||
update-available-title: "更新があります"
|
||||
update-available: "Misskeyの新しいバージョンがあります({newer}。現在{current}を利用中)。ページを再度読み込みすると更新が適用されます。"
|
||||
my-token-regenerated: "あなたのトークンが更新されたのでサインアウトします。"
|
||||
verified-user: "公式アカウント"
|
||||
hide-password: "パスワードを隠す"
|
||||
show-password: "パスワードを表示する"
|
||||
|
||||
@ -339,7 +338,7 @@ auth/views/index.vue:
|
||||
sign-in: "サインインしてください"
|
||||
|
||||
common/views/pages/explore.vue:
|
||||
verified-users: "公式アカウント"
|
||||
pinned-users: "ピン留めされたユーザー"
|
||||
popular-users: "人気のユーザー"
|
||||
recently-updated-users: "最近投稿したユーザー"
|
||||
recently-registered-users: "新規ユーザー"
|
||||
@ -1264,7 +1263,7 @@ admin/views/instance.vue:
|
||||
invite: "招待"
|
||||
save: "保存"
|
||||
saved: "保存しました"
|
||||
user-recommendation-config: "おすすめユーザー"
|
||||
pinned-users: "ピン留めユーザー"
|
||||
email-config: "メールサーバーの設定"
|
||||
email-config-info: "メールアドレス確認やパスワードリセットの際に使われます。"
|
||||
enable-email: "メール配信を有効にする"
|
||||
@ -1351,12 +1350,6 @@ admin/views/users.vue:
|
||||
silence-confirm: "サイレンスしますか?"
|
||||
unmake-silence: "サイレンスの解除"
|
||||
unsilence-confirm: "サイレンスを解除しますか?"
|
||||
verify: "公式アカウントにする"
|
||||
verify-confirm: "公式アカウントにしますか?"
|
||||
verified: "公式アカウントにしました"
|
||||
unverify: "公式アカウントを解除する"
|
||||
unverify-confirm: "公式アカウントを解除しますか?"
|
||||
unverified: "公式アカウントを解除しました"
|
||||
update-remote-user: "リモートユーザー情報の更新"
|
||||
remote-user-updated: "リモートユーザー情報を更新しました"
|
||||
users:
|
||||
@ -1373,7 +1366,6 @@ admin/views/users.vue:
|
||||
admin: "管理者"
|
||||
moderator: "モデレーター"
|
||||
adminOrModerator: "管理者+モデレーター"
|
||||
verified: "公式アカウント"
|
||||
silenced: "サイレンス済み"
|
||||
suspended: "凍結済み"
|
||||
origin:
|
||||
@ -1865,8 +1857,8 @@ pages:
|
||||
font: "フォント"
|
||||
fontSerif: "セリフ"
|
||||
fontSansSerif: "サンセリフ"
|
||||
set-eye-catchig-image: "アイキャッチ画像を設定"
|
||||
remove-eye-catchig-image: "アイキャッチ画像を削除"
|
||||
set-eye-catching-image: "アイキャッチ画像を設定"
|
||||
remove-eye-catching-image: "アイキャッチ画像を削除"
|
||||
choose-block: "ブロックを追加"
|
||||
select-type: "種類を選択"
|
||||
enter-variable-name: "変数名を決めてください"
|
||||
@ -1941,6 +1933,7 @@ pages:
|
||||
fn: "関数"
|
||||
text: "テキスト操作"
|
||||
convert: "変換"
|
||||
list: "リスト"
|
||||
blocks:
|
||||
text: "テキスト"
|
||||
multiLineText: "テキスト(複数行)"
|
||||
@ -2059,6 +2052,13 @@ pages:
|
||||
_seedRandomPick:
|
||||
arg1: "シード"
|
||||
arg2: "リスト"
|
||||
DRPWPM: "確率付きリストからランダムに選択 (ユーザーごとに日替わり)"
|
||||
_DRPWPM:
|
||||
arg1: "テキストのリスト"
|
||||
pick: "リストから選択"
|
||||
_pick:
|
||||
arg1: "リスト"
|
||||
arg2: "位置"
|
||||
number: "数値"
|
||||
stringToNumber: "テキストを数値に"
|
||||
_stringToNumber:
|
||||
|
@ -1246,25 +1246,6 @@ deck/deck.user-column.vue:
|
||||
docs:
|
||||
edit-this-page-on-github: "間違いや改善点を見つけましたか?"
|
||||
edit-this-page-on-github-link: "このページをGitHubで編集"
|
||||
api:
|
||||
entities:
|
||||
properties: "プロパティ"
|
||||
endpoints:
|
||||
params: "パラメータ"
|
||||
no-params: "パラメータはありません"
|
||||
res: "レスポンス"
|
||||
require-credential: "このエンドポイントは認証情報が必須です。"
|
||||
require-permission: "このエンドポイントは{permission}の権限を必要とします。"
|
||||
has-limit: "レートリミットがあります。"
|
||||
duration-limit: "直近{duration}ミリ秒の間のこのエンドポイントへのリクエスト数の合計が{max}を超える場合はリクエストできません。"
|
||||
min-interval-limit: "前回のリクエストから{interval}ミリ秒経っていない場合はリクエストできません。"
|
||||
show-src: "このエンドポイントのソースコードも閲覧できます。"
|
||||
show-src-link: "コードをGitHubで見る"
|
||||
generated: "このドキュメントはAPI定義に基づき自動生成されています。"
|
||||
props:
|
||||
name: "名前"
|
||||
type: "型"
|
||||
description: "説明"
|
||||
dev/views/index.vue:
|
||||
manage-apps: "アプリの管理"
|
||||
dev/views/apps.vue:
|
||||
@ -1281,3 +1262,25 @@ dev/views/new-app.vue:
|
||||
authority: "権限"
|
||||
authority-desc: "ここにチェックした機能しかAPIからアクセスできひんから気ぃつけてな"
|
||||
authority-warning: "アプリ作った後でも変えれるけど、新しいやつ追加したらそん時関連付いてるユーザーキーは全部ほかされるで。"
|
||||
pages:
|
||||
blocks:
|
||||
image: "画像"
|
||||
post: "投稿フォーム"
|
||||
script:
|
||||
categories:
|
||||
random: "いんじゃんほい"
|
||||
list: "リスト"
|
||||
blocks:
|
||||
_join:
|
||||
arg1: "リスト"
|
||||
random: "いんじゃんほい"
|
||||
_randomPick:
|
||||
arg1: "リスト"
|
||||
_dailyRandomPick:
|
||||
arg1: "リスト"
|
||||
_seedRandomPick:
|
||||
arg2: "リスト"
|
||||
_pick:
|
||||
arg1: "リスト"
|
||||
types:
|
||||
array: "リスト"
|
||||
|
@ -34,6 +34,7 @@ common:
|
||||
signup: "신규 등록"
|
||||
signout: "로그아웃"
|
||||
reload-to-apply-the-setting: "이 설정을 적용하려면 페이지를 새로고침해야 합니다. 바로 새로고침하시겠습니까?"
|
||||
fetching-as-ap-object: "연합에서 조회 중"
|
||||
got-it: "알겠습니다"
|
||||
customization-tips:
|
||||
title: "커스터마이징 도움말"
|
||||
@ -61,6 +62,7 @@ common:
|
||||
month-and-day: "{month}월 {day}일"
|
||||
trash: "휴지통"
|
||||
drive: "드라이브"
|
||||
pages: "페이지"
|
||||
messaging: "대화"
|
||||
home: "홈"
|
||||
deck: "덱"
|
||||
@ -72,8 +74,23 @@ common:
|
||||
permissions:
|
||||
"read:account": "계정 정보 보기"
|
||||
"write:account": "계정 정보 변경"
|
||||
"read:blocks": "차단 보기"
|
||||
"write:blocks": "차단 수정"
|
||||
"read:drive": "드라이브 보기"
|
||||
"write:drive": "드라이브 수정"
|
||||
"read:favorites": "즐겨찾기 보기"
|
||||
"write:favorites": "즐겨찾기 수정"
|
||||
"read:following": "팔로우 정보 보기"
|
||||
"write:following": "팔로잉, 팔로우 수정"
|
||||
"read:messaging": "대화 보기"
|
||||
"write:messaging": "대화 수정"
|
||||
"read:mutes": "뮤트 보기"
|
||||
"write:mutes": "뮤트 수정"
|
||||
"write:notes": "글 작성, 삭제"
|
||||
"read:notifications": "글 보기"
|
||||
"write:notifications": "알림 수정"
|
||||
"read:reactions": "리액션 보기"
|
||||
"write:reactions": "리액션 수정"
|
||||
"write:votes": "투표하기"
|
||||
empty-timeline-info:
|
||||
follow-users-to-make-your-timeline: "사용자를 팔로우하면 글이 타임라인에 표시됩니다."
|
||||
@ -293,12 +310,12 @@ auth/views/form.vue:
|
||||
accept: "접근 권한 허용"
|
||||
auth/views/index.vue:
|
||||
loading: "로드 중"
|
||||
denied: "어플리케이션의 연계를 취소하였습니다."
|
||||
denied: "애플리케이션의 연계를 취소하였습니다."
|
||||
denied-paragraph: "이 앱이 당신의 계정에 액세스할 수 없습니다."
|
||||
already-authorized: "이 앱은 이미 연결되어 있습니다."
|
||||
allowed: "어플리케이션의 연동을 허용하였습니다."
|
||||
callback-url: "어플리케이션으로 돌아갑니다."
|
||||
please-go-back: "어플리케이션으로 돌아가여 시도하여 주십시오."
|
||||
allowed: "애플리케이션의 연동을 허용하였습니다."
|
||||
callback-url: "애플리케이션으로 돌아갑니다."
|
||||
please-go-back: "애플리케이션으로 돌아가여 시도하여 주십시오."
|
||||
error: "세션이 존재하지 않습니다."
|
||||
sign-in: "로그인 해주시기 바랍니다"
|
||||
common/views/pages/explore.vue:
|
||||
@ -474,8 +491,12 @@ common/views/components/user-menu.vue:
|
||||
mention: "멘션"
|
||||
mute: "뮤트"
|
||||
unmute: "뮤트 해제"
|
||||
mute-confirm: "이 사용자를 뮤트하시겠습니까?"
|
||||
unmute-confirm: "이 사용자를 뮤트 해제하시겠습니까?"
|
||||
block: "차단"
|
||||
unblock: "차단 해제"
|
||||
block-confirm: "이 사용자를 차단하시겠습니까?"
|
||||
unblock-confirm: "이 사용자를 차단 해제하시겠습니까?"
|
||||
push-to-list: "리스트에 추가"
|
||||
select-list: "리스트를 선택하여 주십시오"
|
||||
report-abuse: "스팸 신고"
|
||||
@ -483,8 +504,12 @@ common/views/components/user-menu.vue:
|
||||
report-abuse-reported: "관리자에게 보고되었습니다. 협조해주셔서 감사합니다."
|
||||
silence: "침묵"
|
||||
unsilence: "침묵 해제"
|
||||
silence-confirm: "이 사용자를 침묵하시겠습니까?"
|
||||
unsilence-confirm: "이 사용자를 침묵 해제하시겠습니까?"
|
||||
suspend: "정지"
|
||||
unsuspend: "정지 해제"
|
||||
suspend-confirm: "이 사용자를 정지하시겠습니까?"
|
||||
unsuspend-confirm: "이 사용자를 정지 해제하시겠습니까?"
|
||||
common/views/components/poll.vue:
|
||||
vote-to: "\"{}\"에 투표하기"
|
||||
vote-count: "{}표"
|
||||
@ -668,6 +693,7 @@ common/views/components/user-list-editor.vue:
|
||||
delete-are-you-sure: "리스트 \"$1\"을 삭제하시겠습니까?"
|
||||
deleted: "삭제하였습니다"
|
||||
common/views/components/user-lists.vue:
|
||||
create-list: "리스트 만들기"
|
||||
list-name: "리스트 이름"
|
||||
common/views/widgets/broadcast.vue:
|
||||
fetching: "확인중"
|
||||
@ -946,7 +972,7 @@ common/views/components/api-settings.vue:
|
||||
sending: "응답을 기다리는 중"
|
||||
response: "결과"
|
||||
desktop/views/components/settings.apps.vue:
|
||||
no-apps: "연결된 어플리케이션이 없습니다"
|
||||
no-apps: "연결된 애플리케이션이 없습니다"
|
||||
common/views/components/drive-settings.vue:
|
||||
max: "최대 용량"
|
||||
in-use: "사용중"
|
||||
@ -1194,7 +1220,9 @@ admin/views/users.vue:
|
||||
unsuspend-confirm: "정지를 해제하시겠습니까?"
|
||||
unsuspended: "정지를 해제하였습니다"
|
||||
make-silence: "침묵"
|
||||
silence-confirm: "침묵으로 설정합니까?"
|
||||
unmake-silence: "침묵 해제"
|
||||
unsilence-confirm: "침묵 해제하시겠습니까?"
|
||||
verify: "공식 계정으로 설정"
|
||||
verify-confirm: "공식 계정으로 설정하시겠습니까?"
|
||||
verified: "공식 계정으로 설정하였습니다"
|
||||
@ -1388,6 +1416,7 @@ desktop/views/widgets/polls.vue:
|
||||
desktop/views/widgets/post-form.vue:
|
||||
title: "글쓰기"
|
||||
note: "글쓰기"
|
||||
something-happened: "알 수 없는 문제로 글을 게시할 수 없습니다."
|
||||
desktop/views/widgets/profile.vue:
|
||||
update-banner: "클릭하여 배너 변경"
|
||||
update-avatar: "클릭하여 아바타 변경"
|
||||
@ -1410,6 +1439,7 @@ mobile/views/components/drive.vue:
|
||||
here-is-root: "현재 경로는 루트 경로로 폴더가 아닙니다."
|
||||
url-prompt: "업로드 하려는 파일의 URL"
|
||||
uploading: "업로드를 요청하였습니다. 업로드가 완료될 때까지 시간이 소요될 수 있습니다."
|
||||
folder-name-cannot-empty: "폴더 이름은 비워둘 수 없습니다."
|
||||
mobile/views/components/drive-file-chooser.vue:
|
||||
select-file: "파일 선택"
|
||||
mobile/views/components/drive-folder-chooser.vue:
|
||||
@ -1486,7 +1516,11 @@ mobile/views/components/ui.nav.vue:
|
||||
mobile/views/pages/drive.vue:
|
||||
contextmenu:
|
||||
upload: "파일 업로드"
|
||||
url-upload: "파일을 URL로부터 업로드"
|
||||
create-folder: "폴더 만들기"
|
||||
rename-folder: "폴더 이름 바꾸기"
|
||||
move-folder: "이 폴더를 이동"
|
||||
delete-folder: "이 폴더를 삭제"
|
||||
mobile/views/pages/user-lists.vue:
|
||||
title: "리스트"
|
||||
mobile/views/pages/signup.vue:
|
||||
@ -1589,25 +1623,6 @@ deck/deck.user-column.vue:
|
||||
docs:
|
||||
edit-this-page-on-github: "틀린 점이나 개선할 점을 찾으셨나요?"
|
||||
edit-this-page-on-github-link: "이 페이지를 GitHub에서 편집"
|
||||
api:
|
||||
entities:
|
||||
properties: "프로퍼티"
|
||||
endpoints:
|
||||
params: "매개변수"
|
||||
no-params: "매개변수가 없습니다"
|
||||
res: "응답"
|
||||
require-credential: "이 엔드포인트는 인증 정보가 필수적입니다."
|
||||
require-permission: "이 엔드포인트는 {permission} 권한을 필요로 합니다."
|
||||
has-limit: "Rate limit(요청 비율 제한)이 있습니다."
|
||||
duration-limit: "최근 {duration} 밀리초 사이에 엔드포인트로의 요청 수의 합계가 {max}를 넘는 경우 요청이 불가능합니다."
|
||||
min-interval-limit: "이전 요청으로부터 {interval} 밀리초가 지나지 않은 경우 요청할 수 없습니다."
|
||||
show-src: "이 엔드포인트에 대한 소스코드를 확인할 수 있습니다."
|
||||
show-src-link: "코드를 Github에서 보기"
|
||||
generated: "이 문서는 API 정의를 기반으로 자동으로 생성됩니다."
|
||||
props:
|
||||
name: "이름"
|
||||
type: "자료형"
|
||||
description: "설명"
|
||||
dev/views/index.vue:
|
||||
manage-apps: "앱 관리"
|
||||
dev/views/apps.vue:
|
||||
@ -1615,12 +1630,64 @@ dev/views/apps.vue:
|
||||
create-app: "앱 생성"
|
||||
app-missing: "앱 없음"
|
||||
dev/views/new-app.vue:
|
||||
create-app: "어플리케이션 생성"
|
||||
app-name: "어플리케이션 이름"
|
||||
new-app: "새 애플리케이션"
|
||||
new-app-info: "애플리케이션은 API에서도 생성할 수 있습니다. (app/create)"
|
||||
create-app: "애플리케이션 생성"
|
||||
app-name: "애플리케이션 이름"
|
||||
app-name-placeholder: "ex) Misskey for iOS"
|
||||
app-name-desc: "앱의 이름."
|
||||
app-overview: "앱 개요"
|
||||
app-overview-placeholder: "ex) Misskey iOS 클라이언트."
|
||||
app-overview-desc: "애플리케이션에 대한 간단한 설명이나 소개"
|
||||
callback-url: "콜백 URL (옵션)"
|
||||
callback-url-placeholder: "ex) https://your.app.example.com/callback.php"
|
||||
callback-url-desc: "사용자가 인증 폼에서 인증한 뒤 리다이렉트할 URL을 설정합니다."
|
||||
authority: "권한"
|
||||
authority-desc: "이곳에서 요청한 권한에 한정하여 API로 액세스할 수 있습니다."
|
||||
authority-warning: "앱을 생성한 뒤에도 변경할 수 있지만, 새로운 권한을 설정하는 경우 그 시점부터 예전에 발급받았던 유저 키는 모두 무효화됩니다."
|
||||
pages:
|
||||
new-page: "페이지 만들기"
|
||||
edit-page: "페이지 수정"
|
||||
read-page: "소스 표시중"
|
||||
page-created: "페이지를 만들었습니다"
|
||||
page-updated: "페이지를 수정했습니다"
|
||||
are-you-sure-delete: "이 페이지를 삭제하시겠습니까?"
|
||||
title: "제목"
|
||||
blocks:
|
||||
image: "이미지"
|
||||
post: "게시 양식"
|
||||
_post:
|
||||
text: "내용"
|
||||
_textInput:
|
||||
text: "제목"
|
||||
_textareaInput:
|
||||
text: "제목"
|
||||
_numberInput:
|
||||
text: "제목"
|
||||
_switch:
|
||||
text: "제목"
|
||||
_counter:
|
||||
text: "제목"
|
||||
_button:
|
||||
text: "제목"
|
||||
_action:
|
||||
_dialog:
|
||||
content: "내용"
|
||||
script:
|
||||
categories:
|
||||
random: "랜덤"
|
||||
list: "리스트"
|
||||
blocks:
|
||||
_join:
|
||||
arg1: "리스트"
|
||||
random: "랜덤"
|
||||
_randomPick:
|
||||
arg1: "리스트"
|
||||
_dailyRandomPick:
|
||||
arg1: "리스트"
|
||||
_seedRandomPick:
|
||||
arg2: "리스트"
|
||||
_pick:
|
||||
arg1: "리스트"
|
||||
types:
|
||||
array: "리스트"
|
||||
|
@ -619,13 +619,22 @@ deck/deck.user-column.vue:
|
||||
docs:
|
||||
edit-this-page-on-github: "Heb je een fout ontdekt of wil je bijdragen aan de documentatie? "
|
||||
edit-this-page-on-github-link: "Bewerk deze pagina op GitHub!"
|
||||
api:
|
||||
entities:
|
||||
properties: "Eigenschappen"
|
||||
endpoints:
|
||||
params: "Parameters"
|
||||
res: "Antwoord"
|
||||
props:
|
||||
name: "Naam"
|
||||
type: "Type"
|
||||
description: "Omschrijving"
|
||||
pages:
|
||||
blocks:
|
||||
image: "Afbeeldingen"
|
||||
script:
|
||||
categories:
|
||||
list: "Lijsten"
|
||||
blocks:
|
||||
_join:
|
||||
arg1: "Lijsten"
|
||||
_randomPick:
|
||||
arg1: "Lijsten"
|
||||
_dailyRandomPick:
|
||||
arg1: "Lijsten"
|
||||
_seedRandomPick:
|
||||
arg2: "Lijsten"
|
||||
_pick:
|
||||
arg1: "Lijsten"
|
||||
types:
|
||||
array: "Lijsten"
|
||||
|
@ -489,14 +489,24 @@ deck/deck.user-column.vue:
|
||||
following: "Følger"
|
||||
followers: "Følgere"
|
||||
images: "Bilder"
|
||||
docs:
|
||||
api:
|
||||
entities:
|
||||
properties: "Egenskaper"
|
||||
endpoints:
|
||||
params: "Parametere"
|
||||
res: "Respons"
|
||||
props:
|
||||
name: "Navn"
|
||||
type: "Type"
|
||||
description: "Beskrivelse"
|
||||
pages:
|
||||
blocks:
|
||||
image: "Bilder"
|
||||
script:
|
||||
categories:
|
||||
random: "Tilfeldig"
|
||||
list: "Lister"
|
||||
blocks:
|
||||
_join:
|
||||
arg1: "Lister"
|
||||
random: "Tilfeldig"
|
||||
_randomPick:
|
||||
arg1: "Lister"
|
||||
_dailyRandomPick:
|
||||
arg1: "Lister"
|
||||
_seedRandomPick:
|
||||
arg2: "Lister"
|
||||
_pick:
|
||||
arg1: "Lister"
|
||||
types:
|
||||
array: "Lister"
|
||||
|
@ -54,6 +54,7 @@ common:
|
||||
month-and-day: "{month}-{day}"
|
||||
trash: "Kosz"
|
||||
drive: "Dysk"
|
||||
pages: "Strony"
|
||||
messaging: "Rozmowy"
|
||||
home: "Strona główna"
|
||||
deck: "Tablice"
|
||||
@ -127,6 +128,7 @@ common:
|
||||
behavior: "Zachowanie"
|
||||
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"
|
||||
line-width: "Szerokości linii"
|
||||
line-width-thin: "Cienka"
|
||||
@ -1190,23 +1192,6 @@ deck/deck.user-column.vue:
|
||||
docs:
|
||||
edit-this-page-on-github: "Znalazłeś błąd lub chcesz pomóc w tworzeniu dokumentacji?"
|
||||
edit-this-page-on-github-link: "Edytuj stronę na GitHubie!"
|
||||
api:
|
||||
entities:
|
||||
properties: "Właściwości"
|
||||
endpoints:
|
||||
params: "Parametry"
|
||||
no-params: "Brak parametrów."
|
||||
res: "Odpowiedź"
|
||||
require-credential: "Punkt końcowy wymaga informacji o uwierzytelnieniu."
|
||||
require-permission: "Ten punkt końcowy wymaga uprawnienia {permission}."
|
||||
has-limit: "Istnieje limit częstotliwości."
|
||||
min-interval-limit: "Nie możesz wykonać żądania przed upłynięciem {interval} od ostatniego żądania."
|
||||
show-src: "Możesz zobaczyć kod źródłowy tego punktu końcowego."
|
||||
show-src-link: "Zobacz kod na GitHubie"
|
||||
props:
|
||||
name: "Nazwa"
|
||||
type: "Rodzaj"
|
||||
description: "Opis"
|
||||
dev/views/index.vue:
|
||||
manage-apps: "Zarządzaj aplikacjami"
|
||||
dev/views/apps.vue:
|
||||
@ -1215,3 +1200,38 @@ dev/views/apps.vue:
|
||||
dev/views/new-app.vue:
|
||||
app-name: "Nazwa Aplikacji"
|
||||
authority: "Uprawnienia"
|
||||
pages:
|
||||
title: "Tytuł"
|
||||
blocks:
|
||||
image: "Zdjęcia"
|
||||
post: "Formularz tworzenia"
|
||||
_textInput:
|
||||
text: "Tytuł"
|
||||
_textareaInput:
|
||||
text: "Tytuł"
|
||||
_numberInput:
|
||||
text: "Tytuł"
|
||||
_switch:
|
||||
text: "Tytuł"
|
||||
_counter:
|
||||
text: "Tytuł"
|
||||
_button:
|
||||
text: "Tytuł"
|
||||
script:
|
||||
categories:
|
||||
random: "Losowy"
|
||||
list: "Listy"
|
||||
blocks:
|
||||
_join:
|
||||
arg1: "Listy"
|
||||
random: "Losowy"
|
||||
_randomPick:
|
||||
arg1: "Listy"
|
||||
_dailyRandomPick:
|
||||
arg1: "Listy"
|
||||
_seedRandomPick:
|
||||
arg2: "Listy"
|
||||
_pick:
|
||||
arg1: "Listy"
|
||||
types:
|
||||
array: "Listy"
|
||||
|
@ -274,18 +274,9 @@ deck/deck.user-column.vue:
|
||||
timeline: "Linha do tempo"
|
||||
docs:
|
||||
edit-this-page-on-github-link: "Edite esta página no GitHub!"
|
||||
api:
|
||||
entities:
|
||||
properties: "Propriedades"
|
||||
endpoints:
|
||||
params: "Parâmetros"
|
||||
no-params: "Sem parâmetros"
|
||||
res: "Resposta"
|
||||
show-src-link: "Veja o código no GitHub"
|
||||
generated: "Este documento foi gerado pelas definições da API."
|
||||
props:
|
||||
name: "Nome"
|
||||
type: "Tipo"
|
||||
description: "Descrição"
|
||||
dev/views/index.vue:
|
||||
manage-apps: "Gerenciar aplicativos"
|
||||
pages:
|
||||
blocks:
|
||||
image: "Imagens"
|
||||
post: "Formulário de publicação"
|
||||
|
@ -146,3 +146,9 @@ mobile/views/components/sub-note-content.vue:
|
||||
poll: "Голосования"
|
||||
mobile/views/pages/widgets.vue:
|
||||
customization-tips: "Советы по настройке"
|
||||
pages:
|
||||
script:
|
||||
categories:
|
||||
random: "Случайно"
|
||||
blocks:
|
||||
random: "Случайно"
|
||||
|
@ -62,6 +62,7 @@ common:
|
||||
month-and-day: "{month}月 {day}日"
|
||||
trash: "垃圾箱"
|
||||
drive: "网盘"
|
||||
pages: "页面"
|
||||
messaging: "聊天"
|
||||
home: "首页"
|
||||
deck: "Deck"
|
||||
@ -1622,25 +1623,6 @@ deck/deck.user-column.vue:
|
||||
docs:
|
||||
edit-this-page-on-github: "发现错误或想要为文档做出贡献?"
|
||||
edit-this-page-on-github-link: "在GitHub上编辑这个页面。"
|
||||
api:
|
||||
entities:
|
||||
properties: "属性"
|
||||
endpoints:
|
||||
params: "参数"
|
||||
no-params: "没有参数"
|
||||
res: "回应"
|
||||
require-credential: "此端点需要身份验证信息。"
|
||||
require-permission: "此端点需要{permission}权限。"
|
||||
has-limit: "有一个速率限制。"
|
||||
duration-limit: "如果您发送请求在{duration}毫秒内多于{max}次,则无法发送更多请求。"
|
||||
min-interval-limit: "如果自上次请求后未传递{interval}毫秒,则无法发送请求。"
|
||||
show-src: "您可以查看此端点的源代码。"
|
||||
show-src-link: "查阅GitHub上的代码"
|
||||
generated: "该文档由API定义生成。"
|
||||
props:
|
||||
name: "名称"
|
||||
type: "型号"
|
||||
description: "描述"
|
||||
dev/views/index.vue:
|
||||
manage-apps: "管理应用"
|
||||
dev/views/apps.vue:
|
||||
@ -1663,3 +1645,247 @@ dev/views/new-app.vue:
|
||||
authority: "权限"
|
||||
authority-desc: "只能通过API访问此处请求的功能。"
|
||||
authority-warning: "您可以在创建应用程序后对其进行更改,但如果您授予不同的权限,则当时关联的所有用户密钥都将失效。"
|
||||
pages:
|
||||
new-page: "创建页面"
|
||||
edit-page: "编辑页面"
|
||||
read-page: "查看源"
|
||||
page-created: "页面已创建"
|
||||
page-updated: "页面已更新"
|
||||
are-you-sure-delete: "是否删除此页面?"
|
||||
page-deleted: "该页面已被删除。"
|
||||
edit-this-page: "编辑此页面"
|
||||
view-source: "查看源代码"
|
||||
view-page: "查看页面"
|
||||
inspector: "检查器"
|
||||
content: "页面内容"
|
||||
variables: "变量"
|
||||
variables-info: "您可以使用变量创建动态页面。在文本中通过<b>{变量名}</b>的写法来嵌入变量值。例如在文本<b>Hello { thing } world!</b>中,如果变量(thing)的值为<b>ai</b>,那么该文本会成为<b>Hello ai world!</b>。"
|
||||
variables-info2: "因为变量的计算(计算变量值)是从上到下执行的,所以不能在变量中引用下面的变量。例如从上到下依次定义了<b>A,B,C</b>3个变量,那么<b>C</b>中可以引用<b>A</b>或<b>B</b>,但是<b>A</b>无法引用<b>B</b>或<b>C</b>。"
|
||||
variables-info3: "为了接收来自用户的输入,页面上设有“用户输入”块,在“变量名称”中设置要在其中保存输入值的变量名(变量会自动创建)。您可以使用该变量执行操作以响应用户输入。"
|
||||
variables-info4: "通过使用函数,您可以将数值计算过程组合成可重用的形式。要创建函数,需要创建一个“函数”类型的变量。你可以将函数设定为槽函数(参数)的格式,槽函数的值可作为函数中的变量使用。另外,AiScript标准中还有一些函数会将函数作为参数(称为高阶函数)。\n除了已经预先定义的函数外,您也可以将它们设置为这些高阶函数的槽函数。"
|
||||
more-details: "详细说明"
|
||||
title: "标题"
|
||||
url: "页面URL"
|
||||
summary: "页面摘要"
|
||||
align-center: "居中"
|
||||
font: "字体"
|
||||
fontSerif: "衬线字体"
|
||||
fontSansSerif: "无衬线字体"
|
||||
choose-block: "添加块"
|
||||
select-type: "类型选择"
|
||||
enter-variable-name: "请确定变量名"
|
||||
the-variable-name-is-already-used: "变量名已使用"
|
||||
content-blocks: "内容"
|
||||
input-blocks: "输入"
|
||||
special-blocks: "特殊"
|
||||
post-from-post-form: "发布此内容"
|
||||
posted-from-post-form: "已发布"
|
||||
blocks:
|
||||
text: "文本"
|
||||
textarea: "文本区域"
|
||||
section: "章节"
|
||||
image: "图片"
|
||||
button: "按钮"
|
||||
if: "如果"
|
||||
_if:
|
||||
variable: "变量"
|
||||
post: "投稿形式"
|
||||
_post:
|
||||
text: "内容"
|
||||
textInput: "文本输入"
|
||||
_textInput:
|
||||
name: "变量名"
|
||||
text: "标题"
|
||||
default: "默认值"
|
||||
textareaInput: "多行文本输入"
|
||||
_textareaInput:
|
||||
name: "变量名"
|
||||
text: "标题"
|
||||
default: "默认值"
|
||||
numberInput: "数值输入"
|
||||
_numberInput:
|
||||
name: "变量名"
|
||||
text: "标题"
|
||||
default: "默认值"
|
||||
switch: "开关"
|
||||
_switch:
|
||||
name: "变量名"
|
||||
text: "标题"
|
||||
default: "默认值"
|
||||
counter: "计数器"
|
||||
_counter:
|
||||
name: "变量名"
|
||||
text: "标题"
|
||||
inc: "增加值"
|
||||
_button:
|
||||
text: "标题"
|
||||
action: "按下按钮时的行为"
|
||||
_action:
|
||||
dialog: "显示对话框"
|
||||
_dialog:
|
||||
content: "内容"
|
||||
resetRandom: "随机值重置"
|
||||
script:
|
||||
categories:
|
||||
flow: "控制"
|
||||
logical: "逻辑运算"
|
||||
operation: "计算"
|
||||
comparison: "比较"
|
||||
random: "随机"
|
||||
value: "值"
|
||||
fn: "函数"
|
||||
text: "文本操作"
|
||||
list: "列表"
|
||||
blocks:
|
||||
text: "文本"
|
||||
multiLineText: "文本 (多行)"
|
||||
textList: "文本列表"
|
||||
_textList:
|
||||
info: "情使用换行符分隔每行"
|
||||
strLen: "文本长度"
|
||||
_strLen:
|
||||
arg1: "文本"
|
||||
strPick: "字符提取"
|
||||
_strPick:
|
||||
arg1: "文本"
|
||||
arg2: "字符位置"
|
||||
strReplace: "文本替换"
|
||||
_strReplace:
|
||||
arg1: "文本"
|
||||
arg2: "替换之前"
|
||||
arg3: "替换之后"
|
||||
strReverse: "文本反向"
|
||||
_strReverse:
|
||||
arg1: "文本"
|
||||
join: "合并文本"
|
||||
_join:
|
||||
arg1: "列表"
|
||||
arg2: "分隔符"
|
||||
add: "+ 加"
|
||||
_add:
|
||||
arg1: "A"
|
||||
arg2: "B"
|
||||
subtract: "- 减"
|
||||
_subtract:
|
||||
arg1: "A"
|
||||
arg2: "B"
|
||||
multiply: "× 乘"
|
||||
_multiply:
|
||||
arg1: "A"
|
||||
arg2: "B"
|
||||
divide: "÷ 除"
|
||||
_divide:
|
||||
arg1: "A"
|
||||
arg2: "B"
|
||||
remind: "÷ 取模"
|
||||
_remind:
|
||||
arg1: "A"
|
||||
arg2: "B"
|
||||
eq: "A和B相等"
|
||||
_eq:
|
||||
arg1: "A"
|
||||
arg2: "B"
|
||||
notEq: "A和B不等"
|
||||
_notEq:
|
||||
arg1: "A"
|
||||
arg2: "B"
|
||||
and: "A和B"
|
||||
_and:
|
||||
arg1: "A"
|
||||
arg2: "B"
|
||||
or: "A或B"
|
||||
_or:
|
||||
arg1: "A"
|
||||
arg2: "B"
|
||||
lt: "< A小于B"
|
||||
_lt:
|
||||
arg1: "A"
|
||||
arg2: "B"
|
||||
gt: "> A大于B"
|
||||
_gt:
|
||||
arg1: "A"
|
||||
arg2: "B"
|
||||
ltEq: "<= A小于等于B"
|
||||
_ltEq:
|
||||
arg1: "A"
|
||||
arg2: "B"
|
||||
gtEq: ">= A大于等于B"
|
||||
_gtEq:
|
||||
arg1: "A"
|
||||
arg2: "B"
|
||||
if: "分支"
|
||||
_if:
|
||||
arg1: "如果"
|
||||
arg2: "的话"
|
||||
arg3: "否则"
|
||||
random: "随机"
|
||||
_random:
|
||||
arg1: "概率"
|
||||
rannum: "随机"
|
||||
_rannum:
|
||||
arg1: "最小"
|
||||
arg2: "最大"
|
||||
randomPick: "从列表中随机选择"
|
||||
_randomPick:
|
||||
arg1: "列表"
|
||||
dailyRandom: "随机(每个用户每日)"
|
||||
_dailyRandom:
|
||||
arg1: "概率"
|
||||
dailyRannum: "随机数(每个用户每日)"
|
||||
_dailyRannum:
|
||||
arg1: "最小"
|
||||
arg2: "最大"
|
||||
dailyRandomPick: "从列表中随机选择(每个用户每日)"
|
||||
_dailyRandomPick:
|
||||
arg1: "列表"
|
||||
seedRandom: "随机 (种子)"
|
||||
_seedRandom:
|
||||
arg1: "种子"
|
||||
arg2: "概率"
|
||||
seedRannum: "随机数(种子)"
|
||||
_seedRannum:
|
||||
arg1: "种子"
|
||||
arg2: "最小"
|
||||
arg3: "最大"
|
||||
seedRandomPick: "从列表中随机选择 (种子)"
|
||||
_seedRandomPick:
|
||||
arg1: "种子"
|
||||
arg2: "列表"
|
||||
_DRPWPM:
|
||||
arg1: "文本列表"
|
||||
pick: "从列表中选择"
|
||||
_pick:
|
||||
arg1: "列表"
|
||||
arg2: "位置"
|
||||
number: "数值"
|
||||
stringToNumber: "文本到数字"
|
||||
_stringToNumber:
|
||||
arg1: "文本"
|
||||
numberToString: "数字到文本"
|
||||
_numberToString:
|
||||
arg1: "数值"
|
||||
splitStrByLine: "将文本按行拆分"
|
||||
_splitStrByLine:
|
||||
arg1: "文本"
|
||||
ref: "变量"
|
||||
fn: "函数"
|
||||
_fn:
|
||||
slots: "槽函数"
|
||||
slots-info: "请使用换行符分隔每个槽函数"
|
||||
arg1: "输出"
|
||||
for: "重复"
|
||||
_for:
|
||||
arg1: "次数"
|
||||
arg2: "处理"
|
||||
typeError: "槽函数{slot}需要传入“{expect}”,但是实际传入为“{actual}”!"
|
||||
thereIsEmptySlot: "槽函数{slot}为空!"
|
||||
types:
|
||||
string: "文本"
|
||||
number: "数值"
|
||||
boolean: "布尔值"
|
||||
array: "列表"
|
||||
stringArray: "文本列表"
|
||||
emptySlot: "空白槽函数"
|
||||
enviromentVariables: "环境变量"
|
||||
pageVariables: "页面元素"
|
||||
argVariables: "输入槽函数"
|
||||
|
13
migration/1557476068003-PinnedUsers.ts
Normal file
13
migration/1557476068003-PinnedUsers.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import {MigrationInterface, QueryRunner} from "typeorm";
|
||||
|
||||
export class PinnedUsers1557476068003 implements MigrationInterface {
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<any> {
|
||||
await queryRunner.query(`ALTER TABLE "meta" ADD "pinnedUsers" character varying(256) array NOT NULL DEFAULT '{}'::varchar[]`);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<any> {
|
||||
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "pinnedUsers"`);
|
||||
}
|
||||
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "misskey",
|
||||
"author": "syuilo <i@syuilo.com>",
|
||||
"version": "11.10.1",
|
||||
"version": "11.12.0",
|
||||
"codename": "daybreak",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
@ -82,6 +82,14 @@
|
||||
</section>
|
||||
</ui-card>
|
||||
|
||||
<ui-card>
|
||||
<template #title>{{ $t('pinned-users') }}</template>
|
||||
<section>
|
||||
<ui-textarea v-model="pinnedUsers"></ui-textarea>
|
||||
<ui-button @click="updateMeta">{{ $t('save') }}</ui-button>
|
||||
</section>
|
||||
</ui-card>
|
||||
|
||||
<ui-card>
|
||||
<template #title>{{ $t('invite') }}</template>
|
||||
<section>
|
||||
@ -190,6 +198,7 @@ export default Vue.extend({
|
||||
enableServiceWorker: false,
|
||||
swPublicKey: null,
|
||||
swPrivateKey: null,
|
||||
pinnedUsers: [],
|
||||
faHeadset, faShieldAlt, faGhost, faUserPlus, farEnvelope, faBolt
|
||||
};
|
||||
},
|
||||
@ -239,6 +248,7 @@ export default Vue.extend({
|
||||
this.enableServiceWorker = meta.enableServiceWorker;
|
||||
this.swPublicKey = meta.swPublickey;
|
||||
this.swPrivateKey = meta.swPrivateKey;
|
||||
this.pinnedUsers = meta.pinnedUsers.join('\n');
|
||||
});
|
||||
},
|
||||
|
||||
@ -297,7 +307,8 @@ export default Vue.extend({
|
||||
smtpPass: this.smtpAuth ? this.smtpPass : '',
|
||||
enableServiceWorker: this.enableServiceWorker,
|
||||
swPublicKey: this.swPublicKey,
|
||||
swPrivateKey: this.swPrivateKey
|
||||
swPrivateKey: this.swPrivateKey,
|
||||
pinnedUsers: this.pinnedUsers.split('\n')
|
||||
}).then(() => {
|
||||
this.$root.dialog({
|
||||
type: 'success',
|
||||
|
@ -11,7 +11,6 @@
|
||||
<span class="username">@{{ user | acct }}</span>
|
||||
<span class="is-admin" v-if="user.isAdmin">admin</span>
|
||||
<span class="is-moderator" v-if="user.isModerator">moderator</span>
|
||||
<span class="is-verified" v-if="user.isVerified" :title="$t('@.verified-user')"><fa icon="star"/></span>
|
||||
<span class="is-silenced" v-if="user.isSilenced" :title="$t('@.silenced-user')"><fa :icon="faMicrophoneSlash"/></span>
|
||||
<span class="is-suspended" v-if="user.isSuspended" :title="$t('@.suspended-user')"><fa :icon="faSnowflake"/></span>
|
||||
</header>
|
||||
@ -77,7 +76,6 @@ export default Vue.extend({
|
||||
background var(--noteHeaderAdminBg)
|
||||
color var(--noteHeaderAdminFg)
|
||||
|
||||
> .is-verified
|
||||
> .is-silenced
|
||||
> .is-suspended
|
||||
margin 0 0 0 .5em
|
||||
|
@ -12,10 +12,6 @@
|
||||
<x-user :user='user'/>
|
||||
<div class="actions">
|
||||
<ui-button @click="resetPassword"><fa :icon="faKey"/> {{ $t('reset-password') }}</ui-button>
|
||||
<ui-horizon-group>
|
||||
<ui-button @click="verifyUser" :disabled="verifying"><fa :icon="faCertificate"/> {{ $t('verify') }}</ui-button>
|
||||
<ui-button @click="unverifyUser" :disabled="unverifying">{{ $t('unverify') }}</ui-button>
|
||||
</ui-horizon-group>
|
||||
<ui-horizon-group>
|
||||
<ui-button @click="silenceUser"><fa :icon="faMicrophoneSlash"/> {{ $t('make-silence') }}</ui-button>
|
||||
<ui-button @click="unsilenceUser">{{ $t('unmake-silence') }}</ui-button>
|
||||
@ -47,7 +43,6 @@
|
||||
<option value="all">{{ $t('users.state.all') }}</option>
|
||||
<option value="admin">{{ $t('users.state.admin') }}</option>
|
||||
<option value="moderator">{{ $t('users.state.moderator') }}</option>
|
||||
<option value="verified">{{ $t('users.state.verified') }}</option>
|
||||
<option value="silenced">{{ $t('users.state.silenced') }}</option>
|
||||
<option value="suspended">{{ $t('users.state.suspended') }}</option>
|
||||
</ui-select>
|
||||
@ -71,7 +66,7 @@
|
||||
import Vue from 'vue';
|
||||
import i18n from '../../i18n';
|
||||
import parseAcct from "../../../../misc/acct/parse";
|
||||
import { faCertificate, faUsers, faTerminal, faSearch, faKey, faSync, faMicrophoneSlash } from '@fortawesome/free-solid-svg-icons';
|
||||
import { faUsers, faTerminal, faSearch, faKey, faSync, faMicrophoneSlash } from '@fortawesome/free-solid-svg-icons';
|
||||
import { faSnowflake } from '@fortawesome/free-regular-svg-icons';
|
||||
import XUser from './users.user.vue';
|
||||
|
||||
@ -84,8 +79,6 @@ export default Vue.extend({
|
||||
return {
|
||||
user: null,
|
||||
target: null,
|
||||
verifying: false,
|
||||
unverifying: false,
|
||||
suspending: false,
|
||||
unsuspending: false,
|
||||
sort: '+createdAt',
|
||||
@ -95,7 +88,7 @@ export default Vue.extend({
|
||||
offset: 0,
|
||||
users: [],
|
||||
existMore: false,
|
||||
faTerminal, faCertificate, faUsers, faSnowflake, faSearch, faKey, faSync, faMicrophoneSlash
|
||||
faTerminal, faUsers, faSnowflake, faSearch, faKey, faSync, faMicrophoneSlash
|
||||
};
|
||||
},
|
||||
|
||||
@ -181,56 +174,6 @@ export default Vue.extend({
|
||||
});
|
||||
},
|
||||
|
||||
async verifyUser() {
|
||||
if (!await this.getConfirmed(this.$t('verify-confirm'))) return;
|
||||
|
||||
this.verifying = true;
|
||||
|
||||
const process = async () => {
|
||||
await this.$root.api('admin/verify-user', { userId: this.user.id });
|
||||
this.$root.dialog({
|
||||
type: 'success',
|
||||
text: this.$t('verified')
|
||||
});
|
||||
};
|
||||
|
||||
await process().catch(e => {
|
||||
this.$root.dialog({
|
||||
type: 'error',
|
||||
text: e.toString()
|
||||
});
|
||||
});
|
||||
|
||||
this.verifying = false;
|
||||
|
||||
this.refreshUser();
|
||||
},
|
||||
|
||||
async unverifyUser() {
|
||||
if (!await this.getConfirmed(this.$t('unverify-confirm'))) return;
|
||||
|
||||
this.unverifying = true;
|
||||
|
||||
const process = async () => {
|
||||
await this.$root.api('admin/unverify-user', { userId: this.user.id });
|
||||
this.$root.dialog({
|
||||
type: 'success',
|
||||
text: this.$t('unverified')
|
||||
});
|
||||
};
|
||||
|
||||
await process().catch(e => {
|
||||
this.$root.dialog({
|
||||
type: 'error',
|
||||
text: e.toString()
|
||||
});
|
||||
});
|
||||
|
||||
this.unverifying = false;
|
||||
|
||||
this.refreshUser();
|
||||
},
|
||||
|
||||
async silenceUser() {
|
||||
if (!await this.getConfirmed(this.$t('silence-confirm'))) return;
|
||||
|
||||
|
@ -34,7 +34,7 @@ body
|
||||
.peg
|
||||
display block
|
||||
position absolute
|
||||
right 0px
|
||||
right 0
|
||||
width 100px
|
||||
height 100%
|
||||
box-shadow 0 0 10px var(--primary), 0 0 5px var(--primary)
|
||||
|
@ -98,7 +98,7 @@ export default Vue.extend({
|
||||
margin 0 auto
|
||||
text-align center
|
||||
background #fff
|
||||
box-shadow 0px 4px 16px rgba(#000, 0.2)
|
||||
box-shadow 0 4px 16px rgba(#000, 0.2)
|
||||
|
||||
> .fetching
|
||||
margin 0
|
||||
|
@ -52,7 +52,7 @@ function match(e: KeyboardEvent, patterns: action['patterns']): boolean {
|
||||
pattern.ctrl == e.ctrlKey &&
|
||||
pattern.shift == e.shiftKey &&
|
||||
pattern.alt == e.altKey &&
|
||||
e.metaKey == false
|
||||
!e.metaKey
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -11,9 +11,9 @@ export default function(me, settings, note) {
|
||||
return (
|
||||
(!isMyNote && note.reply && includesMutedWords(note.reply.text)) ||
|
||||
(!isMyNote && note.renote && includesMutedWords(note.renote.text)) ||
|
||||
(settings.showMyRenotes === false && isMyNote && isPureRenote) ||
|
||||
(settings.showRenotedMyNotes === false && isPureRenote && note.renote.userId == me.id) ||
|
||||
(settings.showLocalRenotes === false && isPureRenote && note.renote.user.host == null) ||
|
||||
(!settings.showMyRenotes && isMyNote && isPureRenote) ||
|
||||
(!settings.showRenotedMyNotes && isPureRenote && note.renote.userId == me.id) ||
|
||||
(!settings.showLocalRenotes && isPureRenote && note.renote.user.host == null) ||
|
||||
(!isMyNote && includesMutedWords(note.text))
|
||||
);
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ export default class Stream extends EventEmitter {
|
||||
|
||||
const user = os.store.state.i;
|
||||
|
||||
this.stream = new ReconnectingWebsocket(wsUrl + (user ? `?i=${user.token}` : ''));
|
||||
this.stream = new ReconnectingWebsocket(wsUrl + (user ? `?i=${user.token}` : ''), '', { minReconnectionDelay: 1 }); // https://github.com/pladaria/reconnecting-websocket/issues/91
|
||||
this.stream.addEventListener('open', this.onOpen);
|
||||
this.stream.addEventListener('close', this.onClose);
|
||||
this.stream.addEventListener('message', this.onMessage);
|
||||
|
@ -80,7 +80,7 @@ export default Vue.extend({
|
||||
|
||||
ms(): number {
|
||||
return this.now.getMilliseconds() * this.smooth;
|
||||
}
|
||||
},
|
||||
s(): number {
|
||||
return this.now.getSeconds();
|
||||
},
|
||||
|
@ -200,6 +200,7 @@ export default Vue.extend({
|
||||
// 通信を取りこぼしてもいいように定期的にポーリングさせる
|
||||
if (this.game.isStarted && !this.game.isEnded) {
|
||||
this.pollingClock = setInterval(() => {
|
||||
if (this.game.isEnded) return;
|
||||
const crc32 = CRC32.str(this.logs.map(x => x.pos.toString()).join(''));
|
||||
this.connection.send('check', {
|
||||
crc32: crc32
|
||||
|
@ -230,7 +230,7 @@ export default Vue.extend({
|
||||
this.game.map = Object.values(maps).find(x => x.name == this.mapName).data;
|
||||
}
|
||||
this.$forceUpdate();
|
||||
this.updateSettings();
|
||||
this.updateSettings('map');
|
||||
},
|
||||
|
||||
onPixelClick(pos, pixel) {
|
||||
|
@ -202,7 +202,7 @@ export default Vue.extend({
|
||||
left 0
|
||||
z-index 1
|
||||
width 100%
|
||||
box-shadow 0 0px 2px rgba(#000, 0.2)
|
||||
box-shadow 0 0 2px rgba(#000, 0.2)
|
||||
|
||||
> .form
|
||||
background rgba(0, 0, 0, 0.02)
|
||||
|
@ -8,7 +8,6 @@
|
||||
<span class="is-bot" v-if="note.user.isBot">bot</span>
|
||||
<span class="is-cat" v-if="note.user.isCat">cat</span>
|
||||
<span class="username"><mk-acct :user="note.user"/></span>
|
||||
<span class="is-verified" v-if="note.user.isVerified" :title="$t('@.verified-user')"><fa icon="star"/></span>
|
||||
<div class="info">
|
||||
<span class="app" v-if="note.app && !mini && $store.state.settings.showVia">via <b>{{ note.app.name }}</b></span>
|
||||
<span class="mobile" v-if="note.viaMobile"><fa icon="mobile-alt"/></span>
|
||||
@ -95,10 +94,6 @@ export default Vue.extend({
|
||||
color var(--noteHeaderAcct)
|
||||
flex-shrink 2147483647
|
||||
|
||||
> .is-verified
|
||||
margin 0 .5em 0 0
|
||||
color #4dabf7
|
||||
|
||||
> .info
|
||||
margin-left auto
|
||||
font-size 0.9em
|
||||
|
@ -14,7 +14,7 @@ import XImage from './els/page-editor.el.image.vue';
|
||||
import XButton from './els/page-editor.el.button.vue';
|
||||
import XTextInput from './els/page-editor.el.text-input.vue';
|
||||
import XTextareaInput from './els/page-editor.el.textarea-input.vue';
|
||||
import XNumberInput from './els/page-editor.el.text-input.vue';
|
||||
import XNumberInput from './els/page-editor.el.number-input.vue';
|
||||
import XSwitch from './els/page-editor.el.switch.vue';
|
||||
import XIf from './els/page-editor.el.if.vue';
|
||||
import XPost from './els/page-editor.el.post.vue';
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<x-container :removable="removable" @remove="() => $emit('remove')" :error="error" :warn="warn">
|
||||
<x-container :removable="removable" @remove="() => $emit('remove')" :error="error" :warn="warn" :draggable="draggable">
|
||||
<template #header><fa v-if="icon" :icon="icon"/> <template v-if="title">{{ title }} <span class="turmquns" v-if="typeText">({{ typeText }})</span></template><template v-else-if="typeText">{{ typeText }}</template></template>
|
||||
<template #func>
|
||||
<button @click="changeType()">
|
||||
@ -93,6 +93,10 @@ export default Vue.extend({
|
||||
fnSlots: {
|
||||
required: false,
|
||||
},
|
||||
draggable: {
|
||||
required: false,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
|
@ -36,10 +36,10 @@
|
||||
</ui-select>
|
||||
|
||||
<div class="eyeCatch">
|
||||
<ui-button v-if="eyeCatchingImageId == null && !readonly" @click="setEyeCatchingImage()"><fa :icon="faPlus"/> {{ $t('set-eye-catchig-image') }}</ui-button>
|
||||
<ui-button v-if="eyeCatchingImageId == null && !readonly" @click="setEyeCatchingImage()"><fa :icon="faPlus"/> {{ $t('set-eye-catching-image') }}</ui-button>
|
||||
<div v-else-if="eyeCatchingImage">
|
||||
<img :src="eyeCatchingImage.url" :alt="eyeCatchingImage.name"/>
|
||||
<ui-button @click="removeEyeCatchingImage()" v-if="!readonly"><fa :icon="faTrashAlt"/> {{ $t('remove-eye-catchig-image') }}</ui-button>
|
||||
<ui-button @click="removeEyeCatchingImage()" v-if="!readonly"><fa :icon="faTrashAlt"/> {{ $t('remove-eye-catching-image') }}</ui-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@ -53,20 +53,19 @@
|
||||
<ui-container :body-togglable="true">
|
||||
<template #header><fa :icon="faMagic"/> {{ $t('variables') }}</template>
|
||||
<div class="qmuvgica">
|
||||
<div class="variables" v-show="variables.length > 0">
|
||||
<template v-for="variable in variables">
|
||||
<x-variable
|
||||
:value="variable"
|
||||
:removable="true"
|
||||
@input="v => updateVariable(v)"
|
||||
@remove="() => removeVariable(variable)"
|
||||
:key="variable.name"
|
||||
:ai-script="aiScript"
|
||||
:name="variable.name"
|
||||
:title="variable.name"
|
||||
/>
|
||||
</template>
|
||||
</div>
|
||||
<x-draggable tag="div" class="variables" v-show="variables.length > 0" :list="variables" handle=".drag-handle" :group="{ name: 'variables' }" animation="150" swap-threshold="0.5">
|
||||
<x-variable v-for="variable in variables"
|
||||
:value="variable"
|
||||
:removable="true"
|
||||
@input="v => updateVariable(v)"
|
||||
@remove="() => removeVariable(variable)"
|
||||
:key="variable.name"
|
||||
:ai-script="aiScript"
|
||||
:name="variable.name"
|
||||
:title="variable.name"
|
||||
:draggable="true"
|
||||
/>
|
||||
</x-draggable>
|
||||
|
||||
<ui-button @click="addVariable()" class="add" v-if="!readonly"><fa :icon="faPlus"/></ui-button>
|
||||
|
||||
@ -92,6 +91,7 @@
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import * as XDraggable from 'vuedraggable';
|
||||
import { faICursor, faPlus, faMagic, faCog, faCode, faExternalLinkSquareAlt } from '@fortawesome/free-solid-svg-icons';
|
||||
import { faSave, faStickyNote, faTrashAlt } from '@fortawesome/free-regular-svg-icons';
|
||||
import i18n from '../../../../i18n';
|
||||
@ -107,7 +107,7 @@ export default Vue.extend({
|
||||
i18n: i18n('pages'),
|
||||
|
||||
components: {
|
||||
XVariable, XBlocks
|
||||
XDraggable, XVariable, XBlocks
|
||||
},
|
||||
|
||||
props: {
|
||||
@ -337,7 +337,7 @@ export default Vue.extend({
|
||||
getScriptBlockList(type: string = null) {
|
||||
const list = [];
|
||||
|
||||
const blocks = blockDefs.filter(block => type === null || block.out === null || block.out === type);
|
||||
const blocks = blockDefs.filter(block => type === null || block.out === null || block.out === type || typeof block.out === 'number');
|
||||
|
||||
for (const block of blocks) {
|
||||
const category = list.find(x => x.category === block.category);
|
||||
|
@ -54,7 +54,11 @@ export default Vue.extend({
|
||||
},
|
||||
|
||||
mounted() {
|
||||
document.cookie = `i=${this.$store.state.i.token}`;
|
||||
if (!document.cookie.match(/i=(\w+)/)) {
|
||||
document.cookie = `i=${this.$store.state.i.token}; path=/;` +
|
||||
` domain=${document.location.hostname}; max-age=31536000;` +
|
||||
(document.location.protocol.startsWith('https') ? ' secure' : '');
|
||||
}
|
||||
this.$watch('$store.state.i', () => {
|
||||
if (this.$store.state.i.twitter) {
|
||||
if (this.twitterForm) this.twitterForm.close();
|
||||
|
@ -273,7 +273,7 @@ export default Vue.extend({
|
||||
|
||||
import_() {
|
||||
(this.$refs.file as any).click();
|
||||
}
|
||||
},
|
||||
|
||||
export_() {
|
||||
const blob = new Blob([this.selectedThemeCode], {
|
||||
|
@ -10,14 +10,14 @@
|
||||
<span>{{ $t('password') }}</span>
|
||||
<template #prefix><fa icon="lock"/></template>
|
||||
</ui-input>
|
||||
<ui-input v-if="user && user.twoFactorEnabled" v-model="token" type="number" required>
|
||||
<ui-input v-if="user && user.twoFactorEnabled" v-model="token" type="text" pattern="^[0-9]{6}$" autocomplete="off" spellcheck="false" required>
|
||||
<span>{{ $t('@.2fa') }}</span>
|
||||
<template #prefix><fa icon="gavel"/></template>
|
||||
</ui-input>
|
||||
<ui-button type="submit" :disabled="signing">{{ signing ? $t('signing-in') : $t('@.signin') }}</ui-button>
|
||||
<p v-if="meta && meta.enableTwitterIntegration" style="margin: 8px 0;"><a :href="`${apiUrl}/signin/twitter`">{{ $t('signin-with-twitter') }}</a></p>
|
||||
<p v-if="meta && meta.enableGithubIntegration" style="margin: 8px 0;"><a :href="`${apiUrl}/signin/github`">{{ $t('signin-with-github') }}</a></p>
|
||||
<p v-if="meta && meta.enableDiscordIntegration" style="margin: 8px 0;"><a :href="`${apiUrl}/signin/discord`">{{ $t('signin-with-discord') /* TODO: Make these layouts better */ }}</a></p>
|
||||
<p v-if="meta && meta.enableTwitterIntegration" style="margin: 8px 0;"><a :href="`${apiUrl}/signin/twitter`"><fa :icon="['fab', 'twitter']"/> {{ $t('signin-with-twitter') }}</a></p>
|
||||
<p v-if="meta && meta.enableGithubIntegration" style="margin: 8px 0;"><a :href="`${apiUrl}/signin/github`"><fa :icon="['fab', 'github']"/> {{ $t('signin-with-github') }}</a></p>
|
||||
<p v-if="meta && meta.enableDiscordIntegration" style="margin: 8px 0;"><a :href="`${apiUrl}/signin/discord`"><fa :icon="['fab', 'discord']"/> {{ $t('signin-with-discord') /* TODO: Make these layouts better */ }}</a></p>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
|
@ -322,7 +322,7 @@ root(fill)
|
||||
|
||||
> .value
|
||||
display block
|
||||
width 0%
|
||||
width 0
|
||||
height 100%
|
||||
background transparent
|
||||
border-radius 6px
|
||||
|
@ -5,10 +5,9 @@
|
||||
<span class="label" ref="label"><slot name="label"></slot></span>
|
||||
<div class="prefix" ref="prefix"><slot name="prefix"></slot></div>
|
||||
<select ref="input"
|
||||
:value="v"
|
||||
v-model="v"
|
||||
:required="required"
|
||||
:disabled="disabled"
|
||||
@input="$emit('input', $event.target.value)"
|
||||
@focus="focused = true"
|
||||
@blur="focused = false"
|
||||
>
|
||||
@ -56,20 +55,22 @@ export default Vue.extend({
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
v: this.value,
|
||||
focused: false
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
v: {
|
||||
get() {
|
||||
return this.value;
|
||||
},
|
||||
set(v) {
|
||||
this.$emit('input', v);
|
||||
}
|
||||
},
|
||||
filled(): boolean {
|
||||
return this.v != '' && this.v != null;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
value(v) {
|
||||
this.v = v;
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (this.$refs.prefix) {
|
||||
this.$refs.label.style.left = (this.$refs.prefix.offsetLeft + this.$refs.prefix.offsetWidth) + 'px';
|
||||
|
@ -166,7 +166,7 @@ export default Vue.extend({
|
||||
> .follow-button
|
||||
position absolute
|
||||
top 8px
|
||||
right 0px
|
||||
right 0
|
||||
|
||||
> .more
|
||||
display block
|
||||
|
@ -160,7 +160,7 @@ export default Vue.extend({
|
||||
this.$emit('top');
|
||||
}
|
||||
|
||||
if (this.$store.state.settings.fetchOnScroll !== false) {
|
||||
if (this.$store.state.settings.fetchOnScroll) {
|
||||
const current = this.$refs.body.scrollTop + this.$refs.body.clientHeight;
|
||||
if (current > this.$refs.body.scrollHeight - 1) this.$emit('bottom');
|
||||
}
|
||||
|
@ -205,7 +205,7 @@ export default Vue.extend({
|
||||
top -32px
|
||||
left 0
|
||||
right 0
|
||||
width 0px
|
||||
width 0
|
||||
margin 0 auto
|
||||
border-top solid 16px transparent
|
||||
border-left solid 16px transparent
|
||||
|
@ -102,7 +102,7 @@ class Autocomplete {
|
||||
}
|
||||
}
|
||||
|
||||
if (isHashtag && opened == false) {
|
||||
if (isHashtag && !opened) {
|
||||
const hashtag = text.substr(hashtagIndex + 1);
|
||||
if (!hashtag.includes(' ')) {
|
||||
this.open('hashtag', hashtag);
|
||||
@ -110,7 +110,7 @@ class Autocomplete {
|
||||
}
|
||||
}
|
||||
|
||||
if (isEmoji && opened == false) {
|
||||
if (isEmoji && !opened) {
|
||||
const emoji = text.substr(emojiIndex + 1);
|
||||
if (!emoji.includes(' ')) {
|
||||
this.open('emoji', emoji);
|
||||
|
@ -13,8 +13,8 @@
|
||||
<template #header><fa :icon="faHashtag" fixed-width/>{{ $t('popular-tags') }}</template>
|
||||
|
||||
<div class="vxjfqztj">
|
||||
<router-link v-for="tag in tagsLocal" :to="`/explore/tags/${tag.name}`" :key="'local:' + tag.name" class="local">{{ tag.name }}</router-link>
|
||||
<router-link v-for="tag in tagsRemote" :to="`/explore/tags/${tag.name}`" :key="'remote:' + tag.name">{{ tag.name }}</router-link>
|
||||
<router-link v-for="tag in tagsLocal" :to="`/explore/tags/${tag.tag}`" :key="'local:' + tag.tag" class="local">{{ tag.tag }}</router-link>
|
||||
<router-link v-for="tag in tagsRemote" :to="`/explore/tags/${tag.tag}`" :key="'remote:' + tag.tag">{{ tag.tag }}</router-link>
|
||||
</div>
|
||||
</ui-container>
|
||||
|
||||
@ -26,8 +26,8 @@
|
||||
</mk-user-list>
|
||||
|
||||
<template v-if="tag == null">
|
||||
<mk-user-list :make-promise="verifiedUsers">
|
||||
<fa :icon="faBookmark" fixed-width/>{{ $t('verified-users') }}
|
||||
<mk-user-list :make-promise="pinnedUsers">
|
||||
<fa :icon="faBookmark" fixed-width/>{{ $t('pinned-users') }}
|
||||
</mk-user-list>
|
||||
<mk-user-list :make-promise="popularUsers">
|
||||
<fa :icon="faChartLine" fixed-width/>{{ $t('popular-users') }}
|
||||
@ -60,12 +60,7 @@ export default Vue.extend({
|
||||
|
||||
data() {
|
||||
return {
|
||||
verifiedUsers: () => this.$root.api('users', {
|
||||
state: 'verified',
|
||||
origin: 'local',
|
||||
sort: '+follower',
|
||||
limit: 10
|
||||
}),
|
||||
pinnedUsers: () => this.$root.api('pinned-users'),
|
||||
popularUsers: () => this.$root.api('users', {
|
||||
state: 'alive',
|
||||
origin: 'local',
|
||||
|
@ -47,7 +47,7 @@ class Script {
|
||||
|
||||
public interpolate(str: string) {
|
||||
if (str == null) return null;
|
||||
return str.replace(/\{(.+?)\}/g, match => {
|
||||
return str.replace(/{(.+?)}/g, match => {
|
||||
const v = this.vars[match.slice(1, -1).trim()];
|
||||
return v == null ? 'NULL' : v.toString();
|
||||
});
|
||||
|
@ -750,12 +750,17 @@ export default Vue.extend({
|
||||
bottom 0
|
||||
animation-delay -1.0s
|
||||
|
||||
@keyframes sk-rotate { 100% { transform: rotate(360deg); }}
|
||||
@keyframes sk-rotate {
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes sk-bounce {
|
||||
0%, 100% {
|
||||
transform: scale(0.0);
|
||||
} 50% {
|
||||
}
|
||||
50% {
|
||||
transform: scale(1.0);
|
||||
}
|
||||
}
|
||||
|
@ -181,7 +181,7 @@ export default Vue.extend({
|
||||
this.releaseQueue();
|
||||
}
|
||||
|
||||
if (this.$store.state.settings.fetchOnScroll !== false) {
|
||||
if (this.$store.state.settings.fetchOnScroll) {
|
||||
const current = window.scrollY + window.innerHeight;
|
||||
if (current > document.body.offsetHeight - 8) this.fetchMore();
|
||||
}
|
||||
|
@ -377,7 +377,7 @@ export default Vue.extend({
|
||||
}, err => {
|
||||
this.$root.dialog({
|
||||
type: 'error',
|
||||
title: this.$t('error')
|
||||
title: this.$t('error'),
|
||||
text: err.message
|
||||
});
|
||||
}, {
|
||||
|
@ -480,7 +480,7 @@ export default Vue.extend({
|
||||
&:focus
|
||||
&:not([data-is-modal])
|
||||
> .body
|
||||
box-shadow 0 0 0px 1px var(--primaryAlpha05), 0 2px 12px 0 var(--desktopWindowShadow)
|
||||
box-shadow 0 0 0 1px var(--primaryAlpha05), 0 2px 12px 0 var(--desktopWindowShadow)
|
||||
|
||||
> .handle
|
||||
$size = 8px
|
||||
|
@ -352,7 +352,7 @@ export default Vue.extend({
|
||||
padding 0 16px
|
||||
line-height 48px
|
||||
background var(--faceHeader)
|
||||
box-shadow 0 1px 0px rgba(0, 0, 0, 0.1)
|
||||
box-shadow 0 1px 0 rgba(0, 0, 0, 0.1)
|
||||
|
||||
& + div
|
||||
max-height calc(100% - 48px)
|
||||
|
@ -505,7 +505,7 @@ class WindowSystem extends EventEmitter {
|
||||
function urlBase64ToUint8Array(base64String: string): Uint8Array {
|
||||
const padding = '='.repeat((4 - base64String.length % 4) % 4);
|
||||
const base64 = (base64String + padding)
|
||||
.replace(/\-/g, '+')
|
||||
.replace(/-/g, '+')
|
||||
.replace(/_/g, '/');
|
||||
|
||||
const rawData = window.atob(base64);
|
||||
|
@ -83,7 +83,7 @@ export default Vue.extend({
|
||||
hierarchyFolders: [],
|
||||
selectedFiles: [],
|
||||
info: null,
|
||||
connection: null
|
||||
connection: null,
|
||||
|
||||
fetching: true,
|
||||
fetchingMoreFiles: false,
|
||||
@ -385,7 +385,7 @@ export default Vue.extend({
|
||||
|
||||
createFolder() {
|
||||
this.$root.dialog({
|
||||
title: this.$t('folder-name')
|
||||
title: this.$t('folder-name'),
|
||||
input: {
|
||||
default: this.folder.name
|
||||
}
|
||||
@ -415,7 +415,7 @@ export default Vue.extend({
|
||||
return;
|
||||
}
|
||||
this.$root.dialog({
|
||||
title: this.$t('folder-name')
|
||||
title: this.$t('folder-name'),
|
||||
input: {
|
||||
default: this.folder.name
|
||||
}
|
||||
@ -597,12 +597,17 @@ export default Vue.extend({
|
||||
bottom 0
|
||||
animation-delay -1.0s
|
||||
|
||||
@keyframes sk-rotate { 100% { transform: rotate(360deg); }}
|
||||
@keyframes sk-rotate {
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes sk-bounce {
|
||||
0%, 100% {
|
||||
transform: scale(0.0);
|
||||
} 50% {
|
||||
}
|
||||
50% {
|
||||
transform: scale(1.0);
|
||||
}
|
||||
}
|
||||
|
@ -175,7 +175,7 @@ export default Vue.extend({
|
||||
this.releaseQueue();
|
||||
}
|
||||
|
||||
if (this.$store.state.settings.fetchOnScroll !== false) {
|
||||
if (this.$store.state.settings.fetchOnScroll) {
|
||||
// 親要素が display none だったら弾く
|
||||
// https://github.com/syuilo/misskey/issues/1569
|
||||
// http://d.hatena.ne.jp/favril/20091105/1257403319
|
||||
|
@ -115,7 +115,7 @@ export default Vue.extend({
|
||||
},
|
||||
|
||||
onScroll() {
|
||||
if (this.$store.state.settings.fetchOnScroll !== false) {
|
||||
if (this.$store.state.settings.fetchOnScroll) {
|
||||
// 親要素が display none だったら弾く
|
||||
// https://github.com/syuilo/misskey/issues/1569
|
||||
// http://d.hatena.ne.jp/favril/20091105/1257403319
|
||||
|
@ -295,7 +295,7 @@ export default Vue.extend({
|
||||
}, err => {
|
||||
this.$root.dialog({
|
||||
type: 'error',
|
||||
title: this.$t('error')
|
||||
title: this.$t('error'),
|
||||
text: err.message
|
||||
});
|
||||
}, {
|
||||
@ -341,7 +341,7 @@ export default Vue.extend({
|
||||
|
||||
post() {
|
||||
this.posting = true;
|
||||
const viaMobile = this.$store.state.settings.disableViaMobile !== true;
|
||||
const viaMobile = !this.$store.state.settings.disableViaMobile;
|
||||
this.$root.api('notes/create', {
|
||||
text: this.text == '' ? undefined : this.text,
|
||||
fileIds: this.files.length > 0 ? this.files.map(f => f.id) : undefined,
|
||||
|
@ -49,7 +49,7 @@ export default Vue.extend({
|
||||
padding 0 8px
|
||||
|
||||
&.shadow
|
||||
box-shadow 0 0px 8px rgba(0, 0, 0, 0.25)
|
||||
box-shadow 0 0 8px rgba(0, 0, 0, 0.25)
|
||||
|
||||
&, *
|
||||
user-select none
|
||||
|
@ -1,5 +1,5 @@
|
||||
input
|
||||
min-width 0px
|
||||
min-width 0
|
||||
|
||||
input:not([type])
|
||||
input[type='text']
|
||||
|
@ -126,7 +126,7 @@ export default (os: MiOS) => new Vuex.Store({
|
||||
|
||||
logout(ctx) {
|
||||
ctx.commit('updateI', null);
|
||||
document.cookie = 'i=;';
|
||||
document.cookie = `i=; max-age=0; domain=${document.location.hostname}`;
|
||||
localStorage.removeItem('i');
|
||||
},
|
||||
|
||||
|
@ -44,6 +44,8 @@ export type Source = {
|
||||
clusterLimit?: number;
|
||||
|
||||
id: string;
|
||||
|
||||
outgoingAddressFamily?: 'ipv4' | 'ipv6' | 'dual';
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -129,7 +129,7 @@ export const mfmLanguage = P.createLanguage({
|
||||
mention: () => {
|
||||
return P((input, i) => {
|
||||
const text = input.substr(i);
|
||||
const match = text.match(/^@\w([\w-]*\w)?(?:@[\w\.\-]+\w)?/);
|
||||
const match = text.match(/^@\w([\w-]*\w)?(?:@[\w.\-]+\w)?/);
|
||||
if (!match) return P.makeFailure(i, 'not a mention');
|
||||
if (input[i - 1] != null && input[i - 1].match(/[a-z0-9]/i)) return P.makeFailure(i, 'not a mention');
|
||||
return P.makeSuccess(i + match[0].length, match[0]);
|
||||
@ -141,7 +141,7 @@ export const mfmLanguage = P.createLanguage({
|
||||
},
|
||||
hashtag: () => P((input, i) => {
|
||||
const text = input.substr(i);
|
||||
const match = text.match(/^#([^\s\.,!\?'"#:\/\[\]【】]+)/i);
|
||||
const match = text.match(/^#([^\s.,!?'"#:\/\[\]【】]+)/i);
|
||||
if (!match) return P.makeFailure(i, 'not a hashtag');
|
||||
let hashtag = match[1];
|
||||
hashtag = removeOrphanedBrackets(hashtag);
|
||||
|
@ -36,4 +36,4 @@ export function createTree(type: string, children: MfmForest, props: any): MfmTr
|
||||
return T.createTree({ type, props }, children);
|
||||
}
|
||||
|
||||
export const urlRegex = /^https?:\/\/[\w\/:%#@\$&\?!\(\)\[\]~\.,=\+\-]+/;
|
||||
export const urlRegex = /^https?:\/\/[\w\/:%#@$&?!()\[\]~.,=+\-]+/;
|
||||
|
@ -31,7 +31,7 @@ export class ASEvaluator {
|
||||
VERSION: opts.version,
|
||||
URL: opts.page ? `${opts.url}/@${opts.page.user.username}/pages/${opts.page.name}` : '',
|
||||
LOGIN: opts.visitor != null,
|
||||
NAME: opts.visitor ? opts.visitor.name : '',
|
||||
NAME: opts.visitor ? opts.visitor.name || opts.visitor.username : '',
|
||||
USERNAME: opts.visitor ? opts.visitor.username : '',
|
||||
USERID: opts.visitor ? opts.visitor.id : '',
|
||||
NOTES_COUNT: opts.visitor ? opts.visitor.notesCount : 0,
|
||||
@ -42,7 +42,8 @@ export class ASEvaluator {
|
||||
MY_FOLLOWERS_COUNT: opts.user ? opts.user.followersCount : 0,
|
||||
MY_FOLLOWING_COUNT: opts.user ? opts.user.followingCount : 0,
|
||||
SEED: opts.randomSeed ? opts.randomSeed : '',
|
||||
YMD: `${date.getFullYear()}/${date.getMonth() + 1}/${date.getDate()}`
|
||||
YMD: `${date.getFullYear()}/${date.getMonth() + 1}/${date.getDate()}`,
|
||||
NULL: null
|
||||
};
|
||||
}
|
||||
|
||||
@ -64,7 +65,7 @@ export class ASEvaluator {
|
||||
|
||||
@autobind
|
||||
private interpolate(str: string, scope: Scope) {
|
||||
return str.replace(/\{(.+?)\}/g, match => {
|
||||
return str.replace(/{(.+?)}/g, match => {
|
||||
const v = scope.getState(match.slice(1, -1).trim());
|
||||
return v == null ? 'NULL' : v.toString();
|
||||
});
|
||||
@ -104,7 +105,7 @@ export class ASEvaluator {
|
||||
}
|
||||
|
||||
if (block.type === 'textList') {
|
||||
return block.value.trim().split('\n');
|
||||
return this.interpolate(block.value || '', scope).trim().split('\n');
|
||||
}
|
||||
|
||||
if (block.type === 'ref') {
|
||||
@ -169,6 +170,7 @@ export class ASEvaluator {
|
||||
stringToNumber: (a: string) => parseInt(a),
|
||||
numberToString: (a: number) => a.toString(),
|
||||
splitStrByLine: (a: string) => a.split('\n'),
|
||||
pick: (list: any[], i: number) => list[i - 1],
|
||||
random: (probability: number) => Math.floor(seedrandom(`${this.opts.randomSeed}:${block.id}`)() * 100) < probability,
|
||||
rannum: (min: number, max: number) => min + Math.floor(seedrandom(`${this.opts.randomSeed}:${block.id}`)() * (max - min + 1)),
|
||||
randomPick: (list: any[]) => list[Math.floor(seedrandom(`${this.opts.randomSeed}:${block.id}`)() * list.length)],
|
||||
@ -178,6 +180,27 @@ export class ASEvaluator {
|
||||
seedRandom: (seed: any, probability: number) => Math.floor(seedrandom(seed)() * 100) < probability,
|
||||
seedRannum: (seed: any, min: number, max: number) => min + Math.floor(seedrandom(seed)() * (max - min + 1)),
|
||||
seedRandomPick: (seed: any, list: any[]) => list[Math.floor(seedrandom(seed)() * list.length)],
|
||||
DRPWPM: (list: string[]) => {
|
||||
const xs = [];
|
||||
let totalFactor = 0;
|
||||
for (const x of list) {
|
||||
const parts = x.split(' ');
|
||||
const factor = parseInt(parts.pop()!, 10);
|
||||
const text = parts.join(' ');
|
||||
totalFactor += factor;
|
||||
xs.push({ factor, text });
|
||||
}
|
||||
const r = seedrandom(`${day}:${block.id}`)() * totalFactor;
|
||||
let stackedFactor = 0;
|
||||
for (const x of xs) {
|
||||
if (r >= stackedFactor && r <= x.factor) {
|
||||
return x.text;
|
||||
} else {
|
||||
stackedFactor += x.factor;
|
||||
}
|
||||
}
|
||||
return xs[0].text;
|
||||
},
|
||||
};
|
||||
|
||||
const fnName = block.type;
|
||||
|
@ -23,6 +23,7 @@ import {
|
||||
faSortNumericUp,
|
||||
faExchangeAlt,
|
||||
faRecycle,
|
||||
faIndent,
|
||||
} from '@fortawesome/free-solid-svg-icons';
|
||||
import { faFlag } from '@fortawesome/free-regular-svg-icons';
|
||||
|
||||
@ -72,6 +73,7 @@ export const funcDefs: Record<string, { in: any[]; out: any; category: string; i
|
||||
stringToNumber: { in: ['string'], out: 'number', category: 'convert', icon: faExchangeAlt, },
|
||||
numberToString: { in: ['number'], out: 'string', category: 'convert', icon: faExchangeAlt, },
|
||||
splitStrByLine: { in: ['string'], out: 'stringArray', category: 'convert', icon: faExchangeAlt, },
|
||||
pick: { in: [null, 'number'], out: null, category: 'list', icon: faIndent, },
|
||||
rannum: { in: ['number', 'number'], out: 'number', category: 'random', icon: faDice, },
|
||||
dailyRannum: { in: ['number', 'number'], out: 'number', category: 'random', icon: faDice, },
|
||||
seedRannum: { in: [null, 'number', 'number'], out: 'number', category: 'random', icon: faDice, },
|
||||
@ -81,6 +83,7 @@ export const funcDefs: Record<string, { in: any[]; out: any; category: string; i
|
||||
randomPick: { in: [0], out: 0, category: 'random', icon: faDice, },
|
||||
dailyRandomPick: { in: [0], out: 0, category: 'random', icon: faDice, },
|
||||
seedRandomPick: { in: [null, 0], out: 0, category: 'random', icon: faDice, },
|
||||
DRPWPM: { in: ['stringArray'], out: 'string', category: 'random', icon: faDice, }, // dailyRandomPickWithProbabilityMapping
|
||||
};
|
||||
|
||||
export const literalDefs: Record<string, { out: any; category: string; icon: any; }> = {
|
||||
@ -124,6 +127,7 @@ export const envVarsDef: Record<string, Type> = {
|
||||
MY_FOLLOWING_COUNT: 'number',
|
||||
SEED: null,
|
||||
YMD: 'string',
|
||||
NULL: null,
|
||||
};
|
||||
|
||||
export function isLiteralBlock(v: Block) {
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { ulid } from 'ulid';
|
||||
import { genAid } from './id/aid';
|
||||
import { genMeid } from './id/meid';
|
||||
import { genMeidg } from './id/meidg';
|
||||
import { genObjectId } from './id/object-id';
|
||||
import config from '../config';
|
||||
|
||||
@ -12,6 +13,7 @@ export function genId(date?: Date): string {
|
||||
switch (metohd) {
|
||||
case 'aid': return genAid(date);
|
||||
case 'meid': return genMeid(date);
|
||||
case 'meidg': return genMeidg(date);
|
||||
case 'ulid': return ulid(date.getTime());
|
||||
case 'objectid': return genObjectId(date);
|
||||
default: throw new Error('unknown id generation method');
|
||||
|
28
src/misc/id/meidg.ts
Normal file
28
src/misc/id/meidg.ts
Normal file
@ -0,0 +1,28 @@
|
||||
const CHARS = '0123456789abcdef';
|
||||
|
||||
// 4bit Fixed hex value 'g'
|
||||
// 44bit UNIX Time ms in Hex
|
||||
// 48bit Random value in Hex
|
||||
|
||||
function getTime(time: number) {
|
||||
if (time < 0) time = 0;
|
||||
if (time === 0) {
|
||||
return CHARS[0];
|
||||
}
|
||||
|
||||
return time.toString(16).padStart(11, CHARS[0]);
|
||||
}
|
||||
|
||||
function getRandom() {
|
||||
let str = '';
|
||||
|
||||
for (let i = 0; i < 12; i++) {
|
||||
str += CHARS[Math.floor(Math.random() * CHARS.length)];
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
export function genMeidg(date: Date): string {
|
||||
return 'g' + getTime(date.getTime()) + getRandom();
|
||||
}
|
@ -69,6 +69,11 @@ export class Meta {
|
||||
})
|
||||
public langs: string[];
|
||||
|
||||
@Column('varchar', {
|
||||
length: 256, array: true, default: '{}'
|
||||
})
|
||||
public pinnedUsers: string[];
|
||||
|
||||
@Column('varchar', {
|
||||
length: 256, array: true, default: '{}'
|
||||
})
|
||||
|
@ -26,7 +26,7 @@ export class UserProfile {
|
||||
public birthday: string | null;
|
||||
|
||||
@Column('varchar', {
|
||||
length: 1024, nullable: true,
|
||||
length: 2048, nullable: true,
|
||||
comment: 'The description (bio) of the User.'
|
||||
})
|
||||
public description: string | null;
|
||||
|
@ -157,11 +157,6 @@ export class User {
|
||||
})
|
||||
public isModerator: boolean;
|
||||
|
||||
@Column('boolean', {
|
||||
default: false,
|
||||
})
|
||||
public isVerified: boolean;
|
||||
|
||||
@Column('varchar', {
|
||||
length: 128, array: true, default: '{}'
|
||||
})
|
||||
|
@ -87,7 +87,6 @@ export class UserRepository extends Repository<User> {
|
||||
isAdmin: user.isAdmin || falsy,
|
||||
isBot: user.isBot || falsy,
|
||||
isCat: user.isCat || falsy,
|
||||
isVerified: user.isVerified || falsy,
|
||||
|
||||
// カスタム絵文字添付
|
||||
emojis: user.emojis.length > 0 ? Emojis.find({
|
||||
@ -128,6 +127,19 @@ export class UserRepository extends Repository<User> {
|
||||
detail: true
|
||||
}),
|
||||
twoFactorEnabled: profile!.twoFactorEnabled,
|
||||
twitter: profile!.twitter ? {
|
||||
id: profile!.twitterUserId,
|
||||
screenName: profile!.twitterScreenName
|
||||
} : null,
|
||||
github: profile!.github ? {
|
||||
id: profile!.githubId,
|
||||
login: profile!.githubLogin
|
||||
} : null,
|
||||
discord: profile!.discord ? {
|
||||
id: profile!.discordId,
|
||||
username: profile!.discordUsername,
|
||||
discriminator: profile!.discordDiscriminator
|
||||
} : null,
|
||||
} : {}),
|
||||
|
||||
...(opts.detail && meId === user.id ? {
|
||||
@ -217,7 +229,7 @@ export class UserRepository extends Repository<User> {
|
||||
}
|
||||
|
||||
public isValidBirthday(birthday: string): boolean {
|
||||
return typeof birthday == 'string' && /^([0-9]{4})\-([0-9]{2})-([0-9]{2})$/.test(birthday);
|
||||
return typeof birthday == 'string' && /^([0-9]{4})-([0-9]{2})-([0-9]{2})$/.test(birthday);
|
||||
}
|
||||
//#endregion
|
||||
}
|
||||
@ -356,10 +368,6 @@ export const packedUserSchema = {
|
||||
nullable: bool.false, optional: bool.true,
|
||||
description: 'Whether this account is a moderator.'
|
||||
},
|
||||
isVerified: {
|
||||
type: types.boolean,
|
||||
nullable: bool.false, optional: bool.true,
|
||||
},
|
||||
isLocked: {
|
||||
type: types.boolean,
|
||||
nullable: bool.false, optional: bool.true,
|
||||
|
@ -25,6 +25,28 @@ import { ensure } from '../../../prelude/ensure';
|
||||
|
||||
const logger = apLogger;
|
||||
|
||||
export function validateNote(object: any, uri: string) {
|
||||
const expectHost = extractDbHost(uri);
|
||||
|
||||
if (object == null) {
|
||||
return new Error('invalid Note: object is null');
|
||||
}
|
||||
|
||||
if (!['Note', 'Question', 'Article'].includes(object.type)) {
|
||||
return new Error(`invalid Note: invalied object type ${object.type}`);
|
||||
}
|
||||
|
||||
if (object.id && extractDbHost(object.id) !== expectHost) {
|
||||
return new Error(`invalid Note: id has different host. expected: ${expectHost}, actual: ${extractDbHost(object.id)}`);
|
||||
}
|
||||
|
||||
if (object.attributedTo && extractDbHost(object.attributedTo) !== expectHost) {
|
||||
return new Error(`invalid Note: attributedTo has different host. expected: ${expectHost}, actual: ${extractDbHost(object.attributedTo)}`);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Noteをフェッチします。
|
||||
*
|
||||
@ -59,8 +81,10 @@ export async function createNote(value: any, resolver?: Resolver, silent = false
|
||||
|
||||
const object: any = await resolver.resolve(value);
|
||||
|
||||
if (!object || !['Note', 'Question', 'Article'].includes(object.type)) {
|
||||
logger.error(`invalid note: ${value}`, {
|
||||
const entryUri = value.id || value;
|
||||
const err = validateNote(object, entryUri);
|
||||
if (err) {
|
||||
logger.error(`${err.message}`, {
|
||||
resolver: {
|
||||
history: resolver.getHistory()
|
||||
},
|
||||
|
@ -101,11 +101,18 @@ export default async (user: ILocalUser, url: string, object: any) => {
|
||||
* Resolve host (with cached, asynchrony)
|
||||
*/
|
||||
async function resolveAddr(domain: string) {
|
||||
const af = config.outgoingAddressFamily || 'ipv4';
|
||||
const useV4 = af == 'ipv4' || af == 'dual';
|
||||
const useV6 = af == 'ipv6' || af == 'dual';
|
||||
|
||||
const promises = [];
|
||||
|
||||
if (!useV4 && !useV6) throw 'No usable address family available';
|
||||
if (useV4) promises.push(resolveAddrInner(domain, { family: 4 }));
|
||||
if (useV6) promises.push(resolveAddrInner(domain, { family: 6 }));
|
||||
|
||||
// v4/v6で先に取得できた方を採用する
|
||||
return await promiseAny([
|
||||
resolveAddrInner(domain, { family: 4 }),
|
||||
resolveAddrInner(domain, { family: 6 })
|
||||
]);
|
||||
return await promiseAny(promises);
|
||||
}
|
||||
|
||||
function resolveAddrInner(domain: string, options: IRunOptions = {}): Promise<string> {
|
||||
|
@ -36,7 +36,6 @@ export const meta = {
|
||||
'admin',
|
||||
'moderator',
|
||||
'adminOrModerator',
|
||||
'verified',
|
||||
'silenced',
|
||||
'suspended',
|
||||
]),
|
||||
@ -61,7 +60,6 @@ export default define(meta, async (ps, me) => {
|
||||
case 'admin': query.where('user.isAdmin = TRUE'); break;
|
||||
case 'moderator': query.where('user.isModerator = TRUE'); break;
|
||||
case 'adminOrModerator': query.where('user.isAdmin = TRUE OR isModerator = TRUE'); break;
|
||||
case 'verified': query.where('user.isVerified = TRUE'); break;
|
||||
case 'alive': query.where('user.updatedAt > :date', { date: new Date(Date.now() - 1000 * 60 * 60 * 24 * 5) }); break;
|
||||
case 'silenced': query.where('user.isSilenced = TRUE'); break;
|
||||
case 'suspended': query.where('user.isSuspended = TRUE'); break;
|
||||
|
@ -1,38 +0,0 @@
|
||||
import $ from 'cafy';
|
||||
import { ID } from '../../../../misc/cafy-id';
|
||||
import define from '../../define';
|
||||
import { Users } from '../../../../models';
|
||||
|
||||
export const meta = {
|
||||
desc: {
|
||||
'ja-JP': '指定したユーザーの公式アカウントを解除します。',
|
||||
'en-US': 'Mark a user as unverified.'
|
||||
},
|
||||
|
||||
tags: ['admin'],
|
||||
|
||||
requireCredential: true,
|
||||
requireModerator: true,
|
||||
|
||||
params: {
|
||||
userId: {
|
||||
validator: $.type(ID),
|
||||
desc: {
|
||||
'ja-JP': '対象のユーザーID',
|
||||
'en-US': 'The user ID which you want to unverify'
|
||||
}
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, async (ps) => {
|
||||
const user = await Users.findOne(ps.userId as string);
|
||||
|
||||
if (user == null) {
|
||||
throw new Error('user not found');
|
||||
}
|
||||
|
||||
await Users.update(user.id, {
|
||||
isVerified: false
|
||||
});
|
||||
});
|
@ -56,6 +56,13 @@ export const meta = {
|
||||
}
|
||||
},
|
||||
|
||||
pinnedUsers: {
|
||||
validator: $.optional.nullable.arr($.str),
|
||||
desc: {
|
||||
'ja-JP': 'ピン留めユーザー'
|
||||
}
|
||||
},
|
||||
|
||||
hiddenTags: {
|
||||
validator: $.optional.nullable.arr($.str),
|
||||
desc: {
|
||||
@ -353,6 +360,10 @@ export default define(meta, async (ps) => {
|
||||
set.useStarForReactionFallback = ps.useStarForReactionFallback;
|
||||
}
|
||||
|
||||
if (Array.isArray(ps.pinnedUsers)) {
|
||||
set.pinnedUsers = ps.pinnedUsers;
|
||||
}
|
||||
|
||||
if (Array.isArray(ps.hiddenTags)) {
|
||||
set.hiddenTags = ps.hiddenTags;
|
||||
}
|
||||
|
@ -1,38 +0,0 @@
|
||||
import $ from 'cafy';
|
||||
import { ID } from '../../../../misc/cafy-id';
|
||||
import define from '../../define';
|
||||
import { Users } from '../../../../models';
|
||||
|
||||
export const meta = {
|
||||
desc: {
|
||||
'ja-JP': '指定したユーザーを公式アカウントにします。',
|
||||
'en-US': 'Mark a user as verified.'
|
||||
},
|
||||
|
||||
tags: ['admin'],
|
||||
|
||||
requireCredential: true,
|
||||
requireModerator: true,
|
||||
|
||||
params: {
|
||||
userId: {
|
||||
validator: $.type(ID),
|
||||
desc: {
|
||||
'ja-JP': '対象のユーザーID',
|
||||
'en-US': 'The user ID which you want to verify'
|
||||
}
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, async (ps) => {
|
||||
const user = await Users.findOne(ps.userId as string);
|
||||
|
||||
if (user == null) {
|
||||
throw new Error('user not found');
|
||||
}
|
||||
|
||||
await Users.update(user.id, {
|
||||
isVerified: true
|
||||
});
|
||||
});
|
@ -37,7 +37,7 @@ export const meta = {
|
||||
},
|
||||
|
||||
type: {
|
||||
validator: $.optional.str.match(/^[a-zA-Z\/\-\*]+$/)
|
||||
validator: $.optional.str.match(/^[a-zA-Z\/\-*]+$/)
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -27,7 +27,7 @@ export const meta = {
|
||||
},
|
||||
|
||||
type: {
|
||||
validator: $.optional.str.match(/^[a-zA-Z\/\-\*]+$/)
|
||||
validator: $.optional.str.match(/^[a-zA-Z\/\-*]+$/)
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -160,6 +160,7 @@ export default define(meta, async (ps, me) => {
|
||||
|
||||
if (me && (me.isAdmin || me.isModerator)) {
|
||||
response.useStarForReactionFallback = instance.useStarForReactionFallback;
|
||||
response.pinnedUsers = instance.pinnedUsers;
|
||||
response.hiddenTags = instance.hiddenTags;
|
||||
response.recaptchaSecretKey = instance.recaptchaSecretKey;
|
||||
response.proxyAccount = instance.proxyAccount;
|
||||
|
60
src/server/api/endpoints/notes/unrenote.ts
Normal file
60
src/server/api/endpoints/notes/unrenote.ts
Normal file
@ -0,0 +1,60 @@
|
||||
import $ from 'cafy';
|
||||
import { ID } from '../../../../misc/cafy-id';
|
||||
import deleteNote from '../../../../services/note/delete';
|
||||
import define from '../../define';
|
||||
import * as ms from 'ms';
|
||||
import { getNote } from '../../common/getters';
|
||||
import { ApiError } from '../../error';
|
||||
import { Notes } from '../../../../models';
|
||||
|
||||
export const meta = {
|
||||
desc: {
|
||||
'ja-JP': '指定した投稿のRenoteを解除します。',
|
||||
},
|
||||
|
||||
tags: ['notes'],
|
||||
|
||||
requireCredential: true,
|
||||
|
||||
kind: 'write:notes',
|
||||
|
||||
limit: {
|
||||
duration: ms('1hour'),
|
||||
max: 300,
|
||||
minInterval: ms('1sec')
|
||||
},
|
||||
|
||||
params: {
|
||||
noteId: {
|
||||
validator: $.type(ID),
|
||||
desc: {
|
||||
'ja-JP': '対象の投稿のID',
|
||||
'en-US': 'Target note ID.'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
errors: {
|
||||
noSuchNote: {
|
||||
message: 'No such note.',
|
||||
code: 'NO_SUCH_NOTE',
|
||||
id: 'efd4a259-2442-496b-8dd7-b255aa1a160f'
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
export default define(meta, async (ps, user) => {
|
||||
const note = await getNote(ps.noteId).catch(e => {
|
||||
if (e.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote);
|
||||
throw e;
|
||||
});
|
||||
|
||||
const renotes = await Notes.find({
|
||||
userId: user.id,
|
||||
renoteId: note.id
|
||||
});
|
||||
|
||||
for (const note of renotes) {
|
||||
deleteNote(user, note);
|
||||
}
|
||||
});
|
33
src/server/api/endpoints/pinned-users.ts
Normal file
33
src/server/api/endpoints/pinned-users.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import define from '../define';
|
||||
import { Users } from '../../../models';
|
||||
import { types, bool } from '../../../misc/schema';
|
||||
import { fetchMeta } from '../../../misc/fetch-meta';
|
||||
import parseAcct from '../../../misc/acct/parse';
|
||||
import { User } from '../../../models/entities/user';
|
||||
|
||||
export const meta = {
|
||||
tags: ['users'],
|
||||
|
||||
requireCredential: false,
|
||||
|
||||
params: {
|
||||
},
|
||||
|
||||
res: {
|
||||
type: types.array,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
items: {
|
||||
type: types.object,
|
||||
optional: bool.false, nullable: bool.false,
|
||||
ref: 'User',
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default define(meta, async (ps, me) => {
|
||||
const meta = await fetchMeta();
|
||||
|
||||
const users = await Promise.all(meta.pinnedUsers.map(acct => Users.findOne(parseAcct(acct))));
|
||||
|
||||
return await Users.packMany(users.filter(x => x !== undefined) as User[], me, { detail: true });
|
||||
});
|
@ -37,7 +37,6 @@ export const meta = {
|
||||
'admin',
|
||||
'moderator',
|
||||
'adminOrModerator',
|
||||
'verified',
|
||||
'alive'
|
||||
]),
|
||||
default: 'all'
|
||||
@ -71,7 +70,6 @@ export default define(meta, async (ps, me) => {
|
||||
case 'admin': query.where('user.isAdmin = TRUE'); break;
|
||||
case 'moderator': query.where('user.isModerator = TRUE'); break;
|
||||
case 'adminOrModerator': query.where('user.isAdmin = TRUE OR isModerator = TRUE'); break;
|
||||
case 'verified': query.where('user.isVerified = TRUE'); break;
|
||||
case 'alive': query.where('user.updatedAt > :date', { date: new Date(Date.now() - 1000 * 60 * 60 * 24 * 5) }); break;
|
||||
}
|
||||
|
||||
@ -85,8 +83,8 @@ export default define(meta, async (ps, me) => {
|
||||
case '-follower': query.orderBy('user.followersCount', 'ASC'); break;
|
||||
case '+createdAt': query.orderBy('user.createdAt', 'DESC'); break;
|
||||
case '-createdAt': query.orderBy('user.createdAt', 'ASC'); break;
|
||||
case '+updatedAt': query.orderBy('user.updatedAt', 'DESC'); break;
|
||||
case '-updatedAt': query.orderBy('user.updatedAt', 'ASC'); break;
|
||||
case '+updatedAt': query.andWhere('user.updatedAt IS NOT NULL').orderBy('user.updatedAt', 'DESC'); break;
|
||||
case '-updatedAt': query.andWhere('user.updatedAt IS NOT NULL').orderBy('user.updatedAt', 'ASC'); break;
|
||||
default: query.orderBy('user.id', 'ASC'); break;
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,7 @@ for (const endpoint of endpoints) {
|
||||
} else {
|
||||
if (endpoint.name.includes('-')) {
|
||||
// 後方互換性のため
|
||||
router.post(`/${endpoint.name.replace(/\-/g, '_')}`, handler.bind(null, endpoint));
|
||||
router.post(`/${endpoint.name.replace(/-/g, '_')}`, handler.bind(null, endpoint));
|
||||
}
|
||||
router.post(`/${endpoint.name}`, handler.bind(null, endpoint));
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ export function convertSchemaToOpenApiSchema(schema: Schema) {
|
||||
const res: any = schema;
|
||||
|
||||
if (schema.type === 'object' && schema.properties) {
|
||||
res.required = Object.entries(schema.properties).filter(([k, v]) => v.optional !== true).map(([k]) => k);
|
||||
res.required = Object.entries(schema.properties).filter(([k, v]) => !v.optional).map(([k]) => k);
|
||||
|
||||
for (const k of Object.keys(schema.properties)) {
|
||||
res.properties[k] = convertSchemaToOpenApiSchema(schema.properties[k]);
|
||||
|
@ -302,16 +302,13 @@ export default class extends Channel {
|
||||
}
|
||||
|
||||
@autobind
|
||||
private async check(crc32: string) {
|
||||
private async check(crc32: string | number) {
|
||||
const game = await ReversiGames.findOne(this.gameId!);
|
||||
if (game == null) throw new Error('game not found');
|
||||
|
||||
if (!game.isStarted) return;
|
||||
|
||||
// 互換性のため
|
||||
if (game.crc32 == null) return;
|
||||
|
||||
if (crc32 !== game.crc32) {
|
||||
if (crc32.toString() !== game.crc32) {
|
||||
this.send('rescue', await ReversiGames.pack(game, this.user));
|
||||
}
|
||||
}
|
||||
|
@ -34,7 +34,7 @@
|
||||
"radix": false,
|
||||
"ban-types": [
|
||||
true,
|
||||
"Object"
|
||||
["Object", "Use {} instead."]
|
||||
],
|
||||
"ban": [
|
||||
true,
|
||||
|
@ -95,7 +95,7 @@ module.exports = {
|
||||
loader: 'css-loader'
|
||||
}, postcss]
|
||||
}, {
|
||||
test: /\.(eot|woff|woff2|svg|ttf)([\?]?.*)$/,
|
||||
test: /\.(eot|woff|woff2|svg|ttf)([?]?.*)$/,
|
||||
loader: 'url-loader'
|
||||
}, {
|
||||
test: /\.json5$/,
|
||||
|
Reference in New Issue
Block a user