Compare commits
197 Commits
Author | SHA1 | Date | |
---|---|---|---|
7d70126072 | |||
54bfffa7b9 | |||
3f5b96bf62 | |||
3d8bbedf1b | |||
23c9f6a6ca | |||
5ba8d4949d | |||
a6befdd541 | |||
e5409db0e8 | |||
678d610cd6 | |||
466fe9c368 | |||
13feaea7b7 | |||
e52f9301fa | |||
1b58e18a6d | |||
b779ff08e0 | |||
811f9c22d7 | |||
c3529f0691 | |||
f9f574532e | |||
92dee53dd6 | |||
5d42ee2359 | |||
7c03d37caa | |||
b128b593c2 | |||
342e48ed77 | |||
052f8b265d | |||
2eedc91d74 | |||
410b9ad6bc | |||
24c6dff3e4 | |||
161db7636a | |||
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 | |||
f74e0d9123 | |||
c6249b82d4 | |||
d6131c0b09 | |||
e62c810b7c | |||
2851a1a7ef | |||
12cd2709d6 | |||
bf54e58873 | |||
6b473e3a5c | |||
4b68abd963 | |||
0e764a2b3e | |||
9d1ed1eb0d | |||
a09a3465a2 | |||
001969efaf | |||
e7c515da9a | |||
8367c7dd49 | |||
55e6cae240 | |||
5553c3fb17 | |||
026265cb1e | |||
289c76a802 | |||
7c1bc1d6bc | |||
90cf0d32b5 | |||
88d934f922 | |||
abf11bb03c | |||
2d1f50303d | |||
9fb7c4091f | |||
2fdec27ab0 | |||
aff56469ed | |||
419cb7fbad | |||
7882851539 | |||
358299cf0e | |||
5a2af24869 | |||
6d35872af5 | |||
559dfdaa80 | |||
79c49bc926 | |||
76c538ad25 | |||
e76e358d98 | |||
76f37671b4 | |||
a9fc176c3c | |||
8b13e3c327 | |||
c3cd6ad2d2 | |||
3444b9c9c8 | |||
ca6fc9cd79 | |||
4747ae8b61 | |||
b6c50d63a0 | |||
52ebf2055e | |||
d0af2c2a98 | |||
10216af48a | |||
d0c8d537f5 | |||
1903aaf351 | |||
e6cdf1b995 | |||
2900d22cdc | |||
dc072d4706 | |||
8ae14f146b | |||
57444c6c3f | |||
759719d124 | |||
59782973be | |||
6c647ea91c | |||
c9763dabe1 | |||
da82754659 | |||
a3cc0ad18b | |||
2e8e5c2751 | |||
a60d83b101 | |||
6d45265763 | |||
42e84b77e1 | |||
24121cfadb | |||
93093dd288 | |||
53381c04e6 | |||
c6b64e57f1 | |||
9158426d0a | |||
cef26853df | |||
c0673884c5 | |||
c98eb64598 | |||
8836bd4f3b | |||
a58df29208 | |||
0d64a17d86 | |||
c886c09cdb | |||
e86d0007c6 | |||
624ee76e71 | |||
9406079cb7 | |||
cd2de7f893 | |||
342061803e | |||
05b8111c19 | |||
747a0b1791 | |||
c05586b53a | |||
0cfca4a618 | |||
2b8187f7ab | |||
291e7e7943 | |||
535d10f469 | |||
4cb58c0892 | |||
6721d27e3f | |||
da9dd7c423 | |||
867eb41618 | |||
6fdff13480 | |||
e581ead1ed | |||
7495206db2 | |||
fe87d16d46 | |||
0db54386cd | |||
772258b0b8 | |||
3ef002e14d | |||
b90d473ae5 | |||
f5091d524b | |||
ee5720df2c | |||
afe2037985 | |||
878cd18144 | |||
e8c8f67a09 | |||
7b29e7cf7e | |||
723d3e6871 | |||
f063dee12a | |||
db4b315d3d | |||
64d00b08a3 | |||
74736a941e | |||
c40366f20a | |||
d73e52ac2a | |||
9fac8a611f | |||
9c774a50f8 | |||
4f20ee1909 | |||
1440c5bc65 | |||
5829b2a7c1 | |||
e3c4bc18d0 | |||
8555ec2f72 | |||
8d7cefbbbe | |||
5aa5896b22 | |||
8a55bdd89d | |||
6444ef6444 | |||
701ab6cc68 | |||
3c6ce7a943 | |||
1e54afd217 | |||
4e90fd3a06 | |||
0463c6bb0f | |||
f31f986d66 | |||
c203c8302b |
@ -4,8 +4,9 @@ executors:
|
||||
default:
|
||||
working_directory: /tmp/workspace
|
||||
docker:
|
||||
- image: misskey/ci:latest
|
||||
- image: misskey/ci:v11-node11
|
||||
- image: circleci/redis:latest
|
||||
- image: circleci/postgres:latest
|
||||
docker:
|
||||
working_directory: /tmp/workspace
|
||||
docker:
|
||||
|
@ -6,8 +6,6 @@ mongodb:
|
||||
db: misskey
|
||||
user: syuilo
|
||||
pass: ''
|
||||
drive:
|
||||
storage: 'db'
|
||||
redis:
|
||||
host: localhost
|
||||
port: 6379
|
||||
|
@ -6,8 +6,6 @@ mongodb:
|
||||
db: test-misskey
|
||||
user: admin
|
||||
pass: ''
|
||||
drive:
|
||||
storage: 'db'
|
||||
# __REDIS__
|
||||
redis:
|
||||
host: localhost
|
||||
|
@ -78,47 +78,6 @@ redis:
|
||||
# port: 9200
|
||||
# pass: null
|
||||
|
||||
# ┌────────────────────────────────────┐
|
||||
#───┘ File storage (Drive) configuration └──────────────────────
|
||||
|
||||
drive:
|
||||
storage: 'fs'
|
||||
|
||||
# OR
|
||||
|
||||
# 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 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
|
||||
|
||||
# ┌───────────────┐
|
||||
#───┘ ID generation └───────────────────────────────────────────
|
||||
|
||||
@ -132,6 +91,9 @@ drive:
|
||||
# ulid ... Millisecond accuracy
|
||||
# objectid ... This is left for backward compatibility
|
||||
|
||||
# ONCE YOU HAVE STARTED THE INSTANCE, DO NOT CHANGE THE
|
||||
# ID SETTINGS AFTER THAT!
|
||||
|
||||
id: 'aid'
|
||||
|
||||
# ┌─────────────────────┐
|
||||
@ -146,3 +108,6 @@ autoAdmin: true
|
||||
|
||||
# Clustering
|
||||
#clusterLimit: 1
|
||||
|
||||
# IP address family used for outgoing request (ipv4, ipv6 or dual)
|
||||
#outgoingAddressFamily: ipv4
|
||||
|
4
.github/CODEOWNERS
vendored
4
.github/CODEOWNERS
vendored
@ -1,7 +1,7 @@
|
||||
# PATH OWNERS
|
||||
/.autogen/ @acid-chicken
|
||||
/.circleci/ @syuilo @acid-chicken
|
||||
/.config/ @syuilo @AyaMorisawa @mei23 @acid-chicken
|
||||
/.config/ @syuilo @AyaMorisawa @mei23 @acid-chicken @rinsuki
|
||||
# /.config/mongo_initdb_example.js @khws4v1
|
||||
/.github/ @syuilo @AyaMorisawa @acid-chicken
|
||||
/.vscode/ @acid-chicken
|
||||
@ -12,7 +12,7 @@
|
||||
# /docs/*.fr.md @BoFFire
|
||||
# /docs/docker.*.md @khws4v1
|
||||
/locales/ @syuilo
|
||||
/src/ @syuilo @AyaMorisawa @mei23 @acid-chicken
|
||||
/src/ @syuilo @AyaMorisawa @mei23 @acid-chicken @rinsuki
|
||||
# /src/crypto_key.cc @akihikodaki
|
||||
# /src/crypto_key.d.ts @akihikodaki
|
||||
/.dockerignore @syuilo # @khws4v1
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -20,3 +20,4 @@ api-docs.json
|
||||
yarn.lock
|
||||
.DS_Store
|
||||
/files
|
||||
ormconfig.json
|
||||
|
@ -1 +1 @@
|
||||
v11.7.0
|
||||
v12.1.0
|
||||
|
278
CHANGELOG.md
278
CHANGELOG.md
@ -5,8 +5,27 @@ If you encounter any problems with updating, please try the following:
|
||||
1. `npm run clean` or `npm run cleanall`
|
||||
2. Retry update (Don't forget `npm i`)
|
||||
|
||||
Migration
|
||||
------------------------------
|
||||
#### 1
|
||||
```
|
||||
npm i -g ts-node
|
||||
```
|
||||
|
||||
#### 2
|
||||
```
|
||||
npm run migrate
|
||||
```
|
||||
|
||||
How to migrate to v11 from v10
|
||||
------------------------------
|
||||
### 移行の注意点
|
||||
**以下のデータは引き継がれません**
|
||||
* 通知
|
||||
* リモートの投稿
|
||||
* リバーシの対局
|
||||
|
||||
### 手順
|
||||
1. v11をインストールしたい場所に syuilo/misskey をクローン
|
||||
2. config を設定する
|
||||
* PostgreSQL(`db`)の設定とは別に、v10からMongoDBの設定をコピペしてくる(例は下にあります)
|
||||
@ -35,29 +54,254 @@ mongodb:
|
||||
8. master ブランチに戻す
|
||||
9. enjoy
|
||||
|
||||
11.14.0 (2019/05/16)
|
||||
--------------------
|
||||
### 注意
|
||||
このバージョンからオブジェクトストレージの設定は設定ファイルではなく管理画面から行うようになりました。
|
||||
オブジェクトストレージを使用している場合、アップデートした後管理画面にアクセスしオブジェクトストレージの設定を再度行ってください。
|
||||
|
||||
### ✨Improvements
|
||||
* 特定のユーザーのファイルをすべて削除できるように
|
||||
* インスタンスの設定画面を整理
|
||||
|
||||
### 🐛Fixes
|
||||
* GIF画像のサムネイルが生成されないのを修正
|
||||
* 管理画面の「ログ」で複数の除外条件を設定できない問題を修正
|
||||
|
||||
11.13.0 (2019/05/14)
|
||||
--------------------
|
||||
### 注意
|
||||
このアップデートを適用した後、プロセスを起動(もしくは再起動)する前に[マイグレーション](#migration)の手順を実行してください
|
||||
|
||||
### ✨Improvements
|
||||
* 利用規約URL、リポジトリURL、フィードバックURLを設定できるように
|
||||
* 特定のインスタンスのファイルをすべて削除できるように
|
||||
* _blankで外部リンクされる可能性がある箇所にnoopenerを追加
|
||||
* ユーザーや外部インスタンスが生成するリンクにnofollowを追加
|
||||
* リモートのユーザーページやノートページにnoindexを追加
|
||||
* 自分のユーザーメニューにはミュートなどを表示しないように
|
||||
* デザインの調整
|
||||
|
||||
### 🐛Fixes
|
||||
* インスタンスブロックを設定できない問題を修正
|
||||
* ピン留め投稿の表示順がおかしい問題を修正
|
||||
* 設定の「アップデートを確認」でメッセージが正しく表示されない問題を修正
|
||||
* Firefoxで自分のメニューが開けない問題を修正
|
||||
* Welcomeページのタグクラウドが動かない問題を修正
|
||||
|
||||
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
|
||||
* MisskeyPagesでページブロックを削除できなくなっていた問題を修正
|
||||
|
||||
### その他
|
||||
* Node.js v12対応
|
||||
|
||||
11.10.0 (2019/05/03)
|
||||
--------------------
|
||||
### 注意
|
||||
このアップデートを適用した後、プロセスを起動(もしくは再起動)する前に[マイグレーション](#migration)の手順を実行してください
|
||||
|
||||
### ✨ Improvements
|
||||
* MisskeyPagesに割った余りを求める関数を追加
|
||||
* Mastodon v2.8.0 のフォローリストをインポートできるように
|
||||
* エクスポートリクエストに失敗したらエラーを表示するように
|
||||
* エクスポートファイルでは同一ハッシュチェックをしないように
|
||||
|
||||
### 🐛Fixes
|
||||
* 2段階認証を設定するとログインできなくなる問題を修正
|
||||
* ファイルをアップロードできないことがある問題を修正
|
||||
* リモートファイルをキャッシュしない設定だとサムネイル時にオリジナル画像が表示されない問題を修正
|
||||
* 外部サービス連携の不具合を修正
|
||||
|
||||
11.9.0 (2019/05/02)
|
||||
-------------------
|
||||
### ✨ Improvements
|
||||
* MisskeyPagesで編集時にページブロックをドラッグで並べ替えられるように
|
||||
* MisskeyPagesにカウンターボタンブロックを追加
|
||||
|
||||
11.8.1 (2019/05/02)
|
||||
-------------------
|
||||
### 🐛Fixes
|
||||
* リモートファイルをキャッシュしないオプション有効時にファイルが作成できない問題を修正
|
||||
|
||||
11.8.0-2 (2019/05/01)
|
||||
-------------------
|
||||
* 11.8.0 のリリース内容が 11.7.0 と同一だったのを修正
|
||||
|
||||
11.8.0 (2019/05/01)
|
||||
-------------------
|
||||
### ✨ Improvements
|
||||
* MisskeyPagesで関数を作成できるように
|
||||
* MisskeyPagesでソースを表示できるように
|
||||
* MisskeyPagesにシードを与えるランダム関数を追加
|
||||
* MisskeyPagesに複数行テキストをテキストのリストに変換する関数を追加
|
||||
|
||||
### 🐛Fixes
|
||||
* APIドキュメントが見れなくなっていたのを修正
|
||||
* mention (あなた宛て) streaming にミュートが効かない問題を修正
|
||||
* デザインの調整
|
||||
|
||||
11.7.0 (2019/04/30)
|
||||
-------------------
|
||||
### ✨ Improvements
|
||||
* MisskeyPagesに ifブロック を追加
|
||||
* MisskeyPagesに テキストエリア を追加
|
||||
* MisskeyPagesに 複数行テキスト入力 を追加
|
||||
* MisskeyPagesに 投稿フォーム を追加
|
||||
* MisskeyPagesに 変換系関数 を追加
|
||||
* MisskeyPagesに 環境変数 URL を追加
|
||||
* MisskeyPagesでボタンやスイッチなどのテキストに変数使えるように
|
||||
|
||||
### 🐛Fixes
|
||||
* OGPのサイト名を修正
|
||||
* デザインの調整
|
||||
|
||||
11.6.0 (2019/04/29)
|
||||
-------------------
|
||||
### ✨ Improvements
|
||||
* AiScriptにいくつかの文字列操作関数を追加
|
||||
* ページ編集画面にページへのリンクを表示するように
|
||||
|
||||
### 🐛Fixes
|
||||
* MisskeyPagesで数値入力が文字列として扱われる問題を修正
|
||||
* デザインの調整
|
||||
|
||||
11.5.1 (2019/04/29)
|
||||
-------------------
|
||||
### 🐛Fixes
|
||||
* MisskeyPagesで環境変数を別の変数内で使えない問題を修正
|
||||
* MisskeyPagesで値が0の変数が表示されない問題を修正
|
||||
|
||||
11.5.0 (2019/04/29)
|
||||
-------------------
|
||||
### 注意
|
||||
このアップデートを適用した後、プロセスを起動(もしくは再起動)する前に[マイグレーション](migration)の手順を実行してください
|
||||
|
||||
### New features
|
||||
#### MisskeyPages
|
||||
ページ(記事)を作成できるように。
|
||||
|
||||
* 後から何度でも編集できる
|
||||
* アイキャッチを設定できる
|
||||
* フォントを設定できる
|
||||
* 画像を好きな位置に挿入できる
|
||||
* URLを決められる
|
||||
* タイトルを設定できる
|
||||
* 見出しを設定できる
|
||||
* ページの要約を設定できる(URLプレビュー時などに便利)
|
||||
* 変数や式(aka AiScript)を使用して動的なページも作れる
|
||||
* 目次自動生成(coming soon)
|
||||
|
||||
ページを気に入ったら「いいね」しよう (coming soon)
|
||||
|
||||
### ✨ Improvements
|
||||
* APIコンソールでパラメータテンプレートを表示するように
|
||||
|
||||
### 🐛Fixes
|
||||
* おすすめユーザーに自分自身が含まれる問題を修正
|
||||
* ユーザーサジェストで表示名が変わらない問題を修正
|
||||
|
||||
11.4.0 (2019/04/25)
|
||||
-------------------
|
||||
### ✨ Improvements
|
||||
* 検索でローカルの投稿のみに絞れるように
|
||||
* 検索で特定のインスタンスの投稿のみに絞れるように
|
||||
* 検索で特定のユーザーの投稿のみに絞れるように
|
||||
|
||||
### 🐛Fixes
|
||||
* 投稿が増殖する問題を修正
|
||||
* ストリームで過去の投稿が流れてくる問題を修正
|
||||
* モバイル版のユーザーページで遷移してもユーザー名が変わらない問題を修正
|
||||
* お知らせを切り替えても内容が変わらない問題を修正
|
||||
|
||||
11.3.1 (2019/04/24)
|
||||
-------------------
|
||||
### 🐛Fixes
|
||||
* Webからファイルがアップロードできない問題を修正
|
||||
|
||||
11.3.0 (2019/04/24)
|
||||
-------------------
|
||||
### ✨ Improvements
|
||||
* お知らせにMFMを使えるように
|
||||
* お知らせに画像を添付できるように
|
||||
|
||||
### 🐛Fixes
|
||||
* 投稿のタグ検索APIで大文字小文字が区別されていたのを修正
|
||||
* 公開範囲がホームの投稿がグローバルTLに流れる問題を修正
|
||||
* モバイルビューの投稿詳細にて acct が長いとアイコンが圧迫面接される問題を修正
|
||||
|
||||
11.2.2 (2019/04/22)
|
||||
-------------------
|
||||
### Fixes
|
||||
### 🐛Fixes
|
||||
* 2段階認証を有効にするとログインできない問題を修正
|
||||
* リモートユーザーの修復処理が自動的に実行されない問題を修正
|
||||
* リモートユーザー情報が更新されない問題を修正
|
||||
|
||||
11.2.1 (2019/04/21)
|
||||
-------------------
|
||||
### Fixes
|
||||
### 🐛Fixes
|
||||
* MEIDが25桁になっているのを修正
|
||||
* リモートユーザー情報が更新されない問題を修正
|
||||
|
||||
11.2.0 (2019/04/18)
|
||||
-------------------
|
||||
### Improvements
|
||||
### ✨ Improvements
|
||||
* 検索で日付(日時)を入力するとタイムラインをその時点まで遡るように
|
||||
* APIコンソールでエンドポイントをサジェストするように
|
||||
* モバイル版でドライブのメニューを使いやすく
|
||||
* サイレンス時に確認を表示するように
|
||||
* ユーザーメニューでブロックなどの操作を行う時に確認するように
|
||||
|
||||
### Fixes
|
||||
### 🐛Fixes
|
||||
* アプリケーション連携画面でパーミッションが表示されない問題を修正
|
||||
* アンケートウィジットでもMFMを使用するように
|
||||
* フォローしてないユーザーのホーム投稿がSTLに流れてくる問題を修正
|
||||
@ -66,7 +310,7 @@ mongodb:
|
||||
|
||||
11.1.6 (2019/04/18)
|
||||
-------------------
|
||||
### Fixes
|
||||
### 🐛Fixes
|
||||
* 未認知ユーザーからActivityが飛んできた場合に処理できない問題を修正
|
||||
* その投稿を見たのにも関わらずメンションインジケーターが点灯し続ける問題を修正
|
||||
* ハッシュタグの判定を改善
|
||||
@ -74,14 +318,14 @@ mongodb:
|
||||
|
||||
11.1.5 (2019/04/17)
|
||||
-------------------
|
||||
### Fixes
|
||||
### 🐛Fixes
|
||||
* ユーザー名に含まれているカスタム絵文字が表示されないことがある問題を修正
|
||||
* 壁紙の設定ができない問題を修正
|
||||
* デザインの調整
|
||||
|
||||
11.1.4 (2019/04/17)
|
||||
-------------------
|
||||
### Fixes
|
||||
### 🐛Fixes
|
||||
* タイムライン取得時に削除されたファイルを添付している投稿が含まれているとサーバーでエラーになる問題を修正
|
||||
* 管理画面のインスタンスメニューで変更前の設定が読み込まれないことがある問題を修正
|
||||
* 猫ではないのに猫のままで表示される問題を修正
|
||||
@ -91,12 +335,12 @@ mongodb:
|
||||
|
||||
11.1.3 (2019/04/16)
|
||||
-------------------
|
||||
### Fixes
|
||||
### 🐛Fixes
|
||||
* アプリからAPIにリクエストするときにランダムなユーザーがリクエストしたことになる問題を修正
|
||||
|
||||
11.1.2 (2019/04/15)
|
||||
-------------------
|
||||
### Fixes
|
||||
### 🐛Fixes
|
||||
* 画像描画の依存関係を変更
|
||||
* リモートユーザーのファイルを削除するときに古い方からではなく新しい方から削除されるのを修正
|
||||
* リアクションしてないのにリアクションしたことになる問題を修正
|
||||
@ -104,25 +348,25 @@ mongodb:
|
||||
|
||||
11.1.1 (2019/04/15)
|
||||
-------------------
|
||||
### Fixes
|
||||
### 🐛Fixes
|
||||
* Metaタグの application-name を Misskey で固定するように修正
|
||||
* トークメッセージが既読にならない問題を修正
|
||||
* デフォルトでHTLを表示するように
|
||||
|
||||
11.1.0 (2019/04/15)
|
||||
-------------------
|
||||
### Improvements
|
||||
### ✨ Improvements
|
||||
* アイコン未設定時にランダムな画像を表示するように
|
||||
* 管理者やモデレーターはレートリミット無効に
|
||||
|
||||
### Fixes
|
||||
### 🐛Fixes
|
||||
* メンションの「あなた」インジケーターが表示されない問題を修正
|
||||
* ブロックAPIでエラーが発生する問題を修正
|
||||
* プッシュ通知の購読に失敗する問題を修正
|
||||
|
||||
11.0.3 (2019/04/15)
|
||||
-------------------
|
||||
### Fixes
|
||||
### 🐛Fixes
|
||||
* ハッシュタグ検索APIが動作しない問題を修正
|
||||
* モデレーターなのにアカウントメニューに「管理」が表示されない問題を修正
|
||||
* プッシュ通知の購読に失敗する問題を修正
|
||||
@ -130,7 +374,7 @@ mongodb:
|
||||
|
||||
11.0.2 (2019/04/15)
|
||||
-------------------
|
||||
### Fixes
|
||||
### 🐛Fixes
|
||||
* アプリが作成できない問題を修正
|
||||
* 「ハイライト」が表示されない問題を修正
|
||||
* リモートの投稿に添付されている画像が小さい問題を修正
|
||||
@ -139,19 +383,19 @@ mongodb:
|
||||
|
||||
11.0.1 (2019/04/15)
|
||||
-------------------
|
||||
### Improvements
|
||||
### ✨ Improvements
|
||||
* 不要な依存関係を削除
|
||||
|
||||
11.0.0 daybreak (2019/04/14)
|
||||
----------------------------
|
||||
### Improvements
|
||||
### ✨ Improvements
|
||||
* **データベースがMongoDBからPostgreSQLに変更されました**
|
||||
* **Redisが必須に**
|
||||
* アカウントを完全に削除できるように
|
||||
* 投稿フォームで添付ファイルの閲覧注意を確認/設定できるように
|
||||
* ミュート/ブロック時にそのユーザーの投稿のウォッチをすべて解除するように
|
||||
|
||||
### Fixes
|
||||
### 🐛Fixes
|
||||
* フォロー申請数が実際より1すくなくなる問題を修正
|
||||
* リストからアカウント削除したユーザーを削除できない問題を修正
|
||||
* リストTLでフォローしていないユーザーの非公開投稿が流れる問題を修正
|
||||
|
@ -197,3 +197,13 @@ const user = await Users.findOne(userId).then(ensure);
|
||||
// }
|
||||
// の糖衣構文のような扱いです
|
||||
```
|
||||
|
||||
### Migration作成方法
|
||||
コードの変更をした後、`ormconfig.json`(`npm run ormconfig`で生成)を用意し、
|
||||
|
||||
```
|
||||
npm i -g ts-node
|
||||
ts-node ./node_modules/typeorm/cli.js migration:generate -n 変更の名前
|
||||
```
|
||||
|
||||
作成されたスクリプトは不必要な変更を含むため除去してください。
|
||||
|
@ -1,4 +1,4 @@
|
||||
FROM node:11-alpine AS base
|
||||
FROM node:12.1-alpine AS base
|
||||
|
||||
ENV NODE_ENV=production
|
||||
|
||||
|
38
README.md
38
README.md
@ -1,6 +1,6 @@
|
||||
<a href="https://xn--931a.moe/"><img src="https://github.com/syuilo/misskey/blob/develop/assets/ai-orig.png?raw=true" align="right" height="320px"/></a>
|
||||
|
||||
[](https://misskey.xyz/)
|
||||
[](https://misskey.io/)
|
||||
================================================================
|
||||
|
||||
[](https://circleci.com/gh/syuilo/misskey)
|
||||
@ -10,7 +10,7 @@
|
||||
**A forever evolving, sophisticated microblogging platform.**
|
||||
|
||||
<p align="justify">
|
||||
<a href="https://misskey.xyz">Misskey</a> is a decentralized microblogging platform born on Earth.
|
||||
<a href="https://misskey.io">Misskey</a> is a decentralized microblogging platform born on Earth.
|
||||
Since it exists within the Fediverse (a universe where various social media platforms are organized),
|
||||
it is mutually linked with other social media platforms.
|
||||
Why don't you take a short break from the hustle and bustle of the city, and dive into a new Internet? <a href="https://joinmisskey.github.io/">Find an instance!</a>
|
||||
@ -88,12 +88,14 @@ Please see the [Contribution Guide](./CONTRIBUTING.md).
|
||||
<td><img src="https://avatars0.githubusercontent.com/u/10798641?s=460&v=4" alt="AyaMorisawa" width="100"></td>
|
||||
<td><img src="https://avatars1.githubusercontent.com/u/30769358?s=460&v=4" alt="mei23" width="100"></td>
|
||||
<td><img src="https://avatars2.githubusercontent.com/u/20679825?s=460&v=4" alt="acid-chicken" width="100"></td>
|
||||
<td><img src="https://avatars2.githubusercontent.com/u/6533808?s=460&v=4" alt="rinsuki" width="100"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><a href="https://github.com/syuilo">@syuilo</a></td>
|
||||
<td align="center"><a href="https://github.com/AyaMorisawa">@AyaMorisawa</a></td>
|
||||
<td align="center"><a href="https://github.com/mei23">@mei23</a></td>
|
||||
<td align="center"><a href="https://github.com/acid-chicken">@acid-chicken</a></td>
|
||||
<td align="center"><a href="https://github.com/rinsuki">@rinsuki</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
@ -102,70 +104,76 @@ Please see the [Contribution Guide](./CONTRIBUTING.md).
|
||||
<!-- PATREON_START -->
|
||||
<table><tr>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/5888816/36da0f7c15954df0ab13f9abdf227f66/1.jpeg?token-time=2145916800&token-hash=at8QpJXJ8C0zINY_NmoMKv-MhXVoUK-YzTgaJPJzJYU%3D" alt="Hiroshi Seki" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/12190916/fb7fa7983c14425f890369535b1506a4/3.png?token-time=2145916800&token-hash=oH_i7gJjNT7Ot6j9JiVwy7ZJIBqACVnzLqlz4YrDAZA%3D" alt="weep" 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>
|
||||
<td><img src="https://c8.patreon.com/2/200/16869916" alt="見当かなみ" width="100"></td>
|
||||
</tr><tr>
|
||||
<td><a href="https://www.patreon.com/rane_hs">Hiroshi Seki</a></td>
|
||||
<td><a href="https://www.patreon.com/weepjp">weep</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>
|
||||
<td><a href="https://www.patreon.com/user?u=16869916">見当かなみ</a></td>
|
||||
</tr></table>
|
||||
<table><tr>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/18899730/6a22797f68254034a854d69ea2445fc8/1.png?token-time=2145916800&token-hash=b_uj57yxo5VzkSOUS7oXE_762dyOTB_oxzbO6lFNG3k%3D" alt="YuzuRyo61" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/12021162/963128bb8d14476dbd8407943db8f31a/1.png?token-time=2145916800&token-hash=FMV7cPKBD1TU2WTbl1jg6AcdKSvTb2BSFcDhgc-EO8w%3D" alt="gutfuckllc" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/11357794/923ce94cd8c44ba788ee931907881839/1.png?token-time=2145916800&token-hash=9nEQje_eMvUjq9a7L3uBqW-MQbS-rRMaMgd7UYVoFNM%3D" alt="mydarkstar" width="100"></td>
|
||||
<td><img src="https://c8.patreon.com/2/200/12718187" alt="Peter G." width="100"></td>
|
||||
<td><img src="https://c8.patreon.com/2/200/18833336" alt="itiradi" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/13039004/509d0c412eb14ae08d6a812a3054f7d6/1.jpe?token-time=2145916800&token-hash=UQRWf01TwHDV4Cls1K0YAOAjM29ssif7hLVq0ESQ0hs%3D" alt="nemu" width="100"></td>
|
||||
<td><img src="https://c8.patreon.com/2/200/17866454" alt="sikyosyounin" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/5881381/6235ca5d3fb04c8e95ef5b4ff2abcc18/3.png?token-time=2145916800&token-hash=KjfQL8nf3AIf6WqzLshBYAyX44piAqOAZiYXgZS_H6A%3D" alt="YUKIMOCHI" width="100"></td>
|
||||
<td><img src="https://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/1.jpeg?token-time=2145916800&token-hash=3aMtpAjhwf01G3Uf8iIKYL8FUXXgxV7NvoQLne7lAKE%3D" alt="Ryosuke Yamamoto" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/13737140/1adf7835017d479280d90fe8d30aade2/1.png?token-time=2145916800&token-hash=0pdle8h5pDZrww0BDOjdz6zO-HudeGTh36a3qi1biVU%3D" alt="Satsuki Yanagi" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/19356899/496b4681d33b4520bd7688e0fd19c04d/2.jpeg?token-time=2145916800&token-hash=_sTj3dUBOhn9qwiJ7F19Qd-yWWfUqJC_0jG1h0agEqQ%3D" alt="sheeta.s" 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>
|
||||
<td><a href="https://www.patreon.com/mydarkstar">mydarkstar</a></td>
|
||||
<td><a href="https://www.patreon.com/user?u=12718187">Peter G.</a></td>
|
||||
<td><a href="https://www.patreon.com/user?u=18833336">itiradi</a></td>
|
||||
<td><a href="https://www.patreon.com/user?u=13039004">nemu</a></td>
|
||||
<td><a href="https://www.patreon.com/user?u=17866454">sikyosyounin</a></td>
|
||||
<td><a href="https://www.patreon.com/yukimochi">YUKIMOCHI</a></td>
|
||||
<td><a href="https://www.patreon.com/user?u=17463605">Sampot</a></td>
|
||||
<td><a href="https://www.patreon.com/user?u=19356899">Ryosuke Yamamoto</a></td>
|
||||
<td><a href="https://www.patreon.com/user?u=13737140">Satsuki Yanagi</a></td>
|
||||
<td><a href="https://www.patreon.com/user?u=19356899">sheeta.s</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>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/4389829/9f709180ac714651a70f74a82f3ffdb9/3.png?token-time=2145916800&token-hash=FTm3WVom4dJ9NwWMU4OpCL_8Yc13WiwEbKrDPyTZTPs%3D" alt="natalie" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/13034746/c711c7f58e204ecfbc2fd646bc8a4eee/1.jpe?token-time=2145916800&token-hash=EWxXhVbZYH7KB4IDT3joc8TbIg8zPO40x1r5IDn3R7c%3D" alt="Hiratake" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/5923936/2a743cbfbff946c2af3f09026047c0da/2.png?token-time=2145916800&token-hash=h6yphW1qnM0n_NOWaf8qtszMRLXEwIxfk5beu4RxdT0%3D" alt="noellabo" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/2384390/5681180e1efb46a8b28e0e8d4c8b9037/1.jpg?token-time=2145916800&token-hash=SJcMy-Q1BcS940-LFUVOMfR7-5SgrzsEQGhYb3yowFk%3D" alt="CG" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/18072312/98e894d960314fa7bc236a72a39488fe/1.jpe?token-time=2145916800&token-hash=qA8j97lIZNc-74AuZ0p4F3ms6sKPeKjtNt2vEuwpsyo%3D" alt="Hekovic" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/4503830/ccf2cc867ea64de0b524bb2e24b9a1cb/1.jpeg?token-time=2145916800&token-hash=L55UhJ0rcuNAH3w_ryeeGN4hC6taoOixyAhraEi0bzw%3D" alt="dansup" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/619786/32cf01444db24e578cd1982c197f6fc6/1.jpeg?token-time=2145916800&token-hash=d8jBQLMOHD87KtXs5C9fk1o58DMF73pQ-dYH3uZJPBE%3D" alt="Gargron" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/5731881/4b6038e6cda34c04b83a5fcce3806a93/1.png?token-time=2145916800&token-hash=hBayGfOmQH3kRMdNnDe4oCZD_9fsJWSt29xXR3KRMVk%3D" alt="Nokotaro Takeda" width="100"></td>
|
||||
</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>
|
||||
<td><a href="https://www.patreon.com/user?u=4389829">natalie</a></td>
|
||||
<td><a href="https://www.patreon.com/hiratake">Hiratake</a></td>
|
||||
<td><a href="https://www.patreon.com/noellabo">noellabo</a></td>
|
||||
<td><a href="https://www.patreon.com/Corset">CG</a></td>
|
||||
<td><a href="https://www.patreon.com/hekovic">Hekovic</a></td>
|
||||
<td><a href="https://www.patreon.com/dansup">dansup</a></td>
|
||||
<td><a href="https://www.patreon.com/mastodon">Gargron</a></td>
|
||||
<td><a href="https://www.patreon.com/takenoko">Nokotaro Takeda</a></td>
|
||||
</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:** Thu, 18 Apr 2019 23:38:06 UTC
|
||||
**Last updated:** Mon, 13 May 2019 06:13:06 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"
|
||||
@ -240,7 +249,6 @@ common:
|
||||
update-available-title: "Aktualizace k dispozici"
|
||||
update-available: "Je k dispozici nová verze Misskey ({newer},vaše verze je {current}). Pro aplikování nové verze znovunačtěte stránku."
|
||||
my-token-regenerated: "Váš token byl regenerován, proto budete odhlášen/a."
|
||||
verified-user: "Ověřené účty"
|
||||
hide-password: "Skrýt heslo"
|
||||
show-password: "Zobrazit heslo"
|
||||
do-not-use-in-production: "Tohle je vývojářský build. Nepoužívejte v produkci."
|
||||
@ -303,7 +311,6 @@ auth/views/index.vue:
|
||||
error: "Taková relace neexistuje."
|
||||
sign-in: "Prosím přihlaste se."
|
||||
common/views/pages/explore.vue:
|
||||
verified-users: "Ověřené účty"
|
||||
popular-users: "Populární uživatelé"
|
||||
recently-updated-users: "Nedávno aktívni uživatelé"
|
||||
recently-registered-users: "Nedávno registrovaní uživatelé"
|
||||
@ -377,6 +384,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 +462,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 +473,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é"
|
||||
@ -902,7 +922,6 @@ admin/views/instance.vue:
|
||||
invite: "Pozvat"
|
||||
save: "Uložit"
|
||||
saved: "Uloženo"
|
||||
user-recommendation-config: "Doporučení uživatelé"
|
||||
email: "Emailová adresa"
|
||||
smtp-port: "SMTP Port"
|
||||
smtp-auth: "Provést SMTP autentikaci"
|
||||
@ -954,12 +973,6 @@ admin/views/users.vue:
|
||||
reset-password: "Resetovat heslo"
|
||||
reset-password-confirm: "Opravdu chcete resetovat Vaše heslo?"
|
||||
password-updated: "Heslo je nyní \"{password}\""
|
||||
verify: "Ověřit účet"
|
||||
verify-confirm: "Chcete aby toto byl ověřený účet?"
|
||||
verified: "Účet se nyní ověřuje"
|
||||
unverify: "Zrušit ověření účtu"
|
||||
unverify-confirm: "Opravdu chcete zrušit designaci \"ověřený účet\"?"
|
||||
unverified: "Ruší se potvrzení účtu"
|
||||
update-remote-user: "Aktualizovat informace o vzdáleném účtu"
|
||||
users:
|
||||
title: "Uživatel"
|
||||
@ -967,7 +980,6 @@ admin/views/users.vue:
|
||||
all: "Všechny"
|
||||
moderator: "Moderátor"
|
||||
adminOrModerator: "Admin/Moderátor"
|
||||
verified: "Ověřený účet"
|
||||
origin:
|
||||
title: "Původ"
|
||||
combined: "Lokální + Vzdálené"
|
||||
@ -1032,6 +1044,7 @@ admin/views/federation.vue:
|
||||
chart-spans:
|
||||
hour: "za hodinu"
|
||||
day: "za den"
|
||||
blocked-hosts: "Blokován"
|
||||
desktop/views/pages/welcome.vue:
|
||||
about: "O Misskey"
|
||||
timeline: "Časová osa"
|
||||
@ -1198,3 +1211,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"
|
||||
@ -151,7 +153,6 @@ common:
|
||||
update-available-title: "Aktualisierung verfügbar"
|
||||
update-available: "Eine neue Version von Misskey ist verfügbar ({newer}, aktuell ist {current}). Lade die Seite neu um die aktuelle Version zu laden"
|
||||
my-token-regenerated: "Dein Token wurde generiert. Du wirst jetzt abgemeldet."
|
||||
verified-user: "Verifizierter Benutzer"
|
||||
do-not-use-in-production: "Dies ist eine Entwicklungsversion. Nicht in einer Produktivumgebung verwenden."
|
||||
error:
|
||||
retry: "Erneut versuchen"
|
||||
@ -197,8 +198,6 @@ auth/views/index.vue:
|
||||
please-go-back: "Bitte gehe zurück zur Anwendung."
|
||||
error: "Sitzung ist nicht vorhanden."
|
||||
sign-in: "Bitte melde dich an."
|
||||
common/views/pages/explore.vue:
|
||||
verified-users: "Verifizierter Benutzer"
|
||||
common/views/components/games/reversi/reversi.vue:
|
||||
matching:
|
||||
waiting-for: "Warten auf {}"
|
||||
@ -603,8 +602,6 @@ admin/views/drive.vue:
|
||||
delete: "Löschen"
|
||||
admin/views/users.vue:
|
||||
users:
|
||||
state:
|
||||
verified: "Verifizierter Benutzer"
|
||||
origin:
|
||||
local: "Lokal"
|
||||
admin/views/emoji.vue:
|
||||
@ -718,25 +715,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 +731,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"
|
||||
@ -249,7 +251,6 @@ common:
|
||||
update-available-title: "Update available"
|
||||
update-available: "A new version of Misskey is now available({newer}, the current version is {current}). Reload the page to apply updates."
|
||||
my-token-regenerated: "Your token has been regenerated, so you will be signed out."
|
||||
verified-user: "Verified account"
|
||||
hide-password: "Hide Password"
|
||||
show-password: "Show Password"
|
||||
do-not-use-in-production: "This is a development build. Do not use in production."
|
||||
@ -317,7 +318,7 @@ auth/views/index.vue:
|
||||
error: "Session does not exist."
|
||||
sign-in: "Please sign in."
|
||||
common/views/pages/explore.vue:
|
||||
verified-users: "Official accounts"
|
||||
pinned-users: "Higlighted users"
|
||||
popular-users: "Popular users"
|
||||
recently-updated-users: "Recently active users"
|
||||
recently-registered-users: "Users who joined recently"
|
||||
@ -1137,7 +1138,7 @@ admin/views/instance.vue:
|
||||
invite: "Invite"
|
||||
save: "Save"
|
||||
saved: "Saved"
|
||||
user-recommendation-config: "Recommended users"
|
||||
pinned-users: "Higlighted user"
|
||||
email-config: "Email server settings"
|
||||
email-config-info: "Used to confirm email and password reset etc."
|
||||
enable-email: "Enable email delivery"
|
||||
@ -1221,12 +1222,6 @@ admin/views/users.vue:
|
||||
silence-confirm: "Silence user?"
|
||||
unmake-silence: "Unsilence"
|
||||
unsilence-confirm: "Are you certain that you want to stop silencing this user?"
|
||||
verify: "Verify account"
|
||||
verify-confirm: "Do you want this to be a verified account?"
|
||||
verified: "The account is now being verified"
|
||||
unverify: "Unverify account"
|
||||
unverify-confirm: "Do you want to remove the 'verified account' designation?"
|
||||
unverified: "The account is now being unverified"
|
||||
update-remote-user: "Update information about remote user"
|
||||
remote-user-updated: "The information regarding the remote user has been updated."
|
||||
users:
|
||||
@ -1243,7 +1238,6 @@ admin/views/users.vue:
|
||||
admin: "Administrator"
|
||||
moderator: "Moderator"
|
||||
adminOrModerator: "Admin/Moderator"
|
||||
verified: "Verified account"
|
||||
silenced: "Already silenced"
|
||||
suspended: "Suspended"
|
||||
origin:
|
||||
@ -1351,6 +1345,7 @@ admin/views/federation.vue:
|
||||
chart-spans:
|
||||
hour: "Hourly"
|
||||
day: "Daily"
|
||||
blocked-hosts: "Blocking"
|
||||
desktop/views/pages/welcome.vue:
|
||||
about: "More details..."
|
||||
timeline: "Timeline"
|
||||
@ -1621,25 +1616,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 +1624,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"
|
||||
|
@ -12,7 +12,9 @@ common:
|
||||
rich-contents: "Posts"
|
||||
rich-contents-desc: "Escribe sobre tus pensamientos, eventos, todo lo que quieras compartir. Si es necesario, puedes usar varias sintaxis, decorar tus posts y añadir tus imágenes favoritas, archivos de viddeo y encuestas."
|
||||
reaction: "Reacciones"
|
||||
reaction-desc: "La forma mas facil de expresar tus emociones. Misskey te permite añadir varios tipos de reacciones a los posts de otros usuarios. La emperiencia emocional en Misskey nunca será igual que en otra red social, donde solo puedes poner \"likes\"."
|
||||
ui: "Interfaz"
|
||||
ui-desc: "No hay ninguna interfaz que le vaya bien a todos. Por eso, Misskey tiene una interfaz altamente personalizable para tus gustos. Puedes hacer tu página principal única editando la interfaz de tu timeline y moviendo varios widgets para conseguir hacer de este lugar uno propio."
|
||||
drive: "Drive"
|
||||
adblock:
|
||||
detected: "Por favor, desactive el bloqueador de publicidad."
|
||||
@ -55,6 +57,7 @@ common:
|
||||
month-and-day: "{day} de {month}"
|
||||
trash: "Papelera"
|
||||
drive: "Drive"
|
||||
pages: "Páginas"
|
||||
messaging: "Conversación"
|
||||
home: "Inicio"
|
||||
deck: "Deck"
|
||||
@ -70,8 +73,12 @@ common:
|
||||
"write:blocks": "Editar bloques"
|
||||
"read:favorites": "Ver favoritos"
|
||||
"write:favorites": "Editar favoritos"
|
||||
"read:following": "Ver información de seguidor"
|
||||
"read:messaging": "Ver conversación"
|
||||
"read:mutes": "Ver silenciados"
|
||||
"write:notes": "Crear y eliminar articulos"
|
||||
"read:notifications": "Ver notificaciones"
|
||||
"read:reactions": "Ver reacciones"
|
||||
"write:votes": "Vota"
|
||||
weekday-short:
|
||||
sunday: "domingo"
|
||||
@ -136,8 +143,11 @@ common:
|
||||
default-note-visibility: "Rango de publicación predeterminado"
|
||||
web-search-engine: "Buscador web"
|
||||
web-search-engine-desc: "Ejemplo: https://www.google.com/?#q={{query}}"
|
||||
this-setting-is-this-device-only: "Solo para este dispositivo"
|
||||
use-os-default-emojis: "Usar los emoticonos estándar del sistema operativo"
|
||||
line-width: "Grosor de línea"
|
||||
line-width-thin: "Fino"
|
||||
line-width-normal: "Normal"
|
||||
line-width-thick: "Grosor"
|
||||
font-size: "Tamaño del texto"
|
||||
font-size-x-small: "Muy pequeño"
|
||||
@ -162,13 +172,20 @@ common:
|
||||
wallpaper: "Fondo de pantalla"
|
||||
choose-wallpaper: "Escoge un fondo de pantalla"
|
||||
delete-wallpaper: "Quitar fondo de pantalla"
|
||||
post-form-on-timeline: "Mostrar el formulario de las entradas encima de la línea de tiempo"
|
||||
show-clock-on-header: "Muestra el reloj en la parte superior derecha"
|
||||
show-reply-target: "Mostrar destinatario de la mención"
|
||||
timeline: "Timeline"
|
||||
show-my-renotes: "Mostrar mis renotes en la timeline"
|
||||
show-renoted-my-notes: "Mostrar renotes de mis posts en la timeline"
|
||||
sound: "Sonido"
|
||||
enable-sounds: "Habilitar sonido"
|
||||
volume: "Volúmen"
|
||||
test: "Prueba"
|
||||
update: "Actualizar Misskey"
|
||||
version: "Versión"
|
||||
latest-version: "Última versión"
|
||||
update-checking: "Buscando actualizaciones"
|
||||
no-updates: "No hay actualizaciones disponibles"
|
||||
no-updates-desc: "Tu Misskey está actualizado"
|
||||
update-available: "¡Una nueva versión está disponible!"
|
||||
@ -178,18 +195,36 @@ common:
|
||||
search: "Buscar"
|
||||
delete: "eliminar"
|
||||
loading: "cargando"
|
||||
ok: "Confirmar"
|
||||
cancel: "Cancelar"
|
||||
update-available-title: "Actualización disponible"
|
||||
update-available: "Hay disponible una nueva versión de Misskey ({newer}, la versión actual es {current}). Refresca la página para aplicar las actualizaciones."
|
||||
my-token-regenerated: "Tu token se ha regenerado vas a ser desconectado."
|
||||
verified-user: "Cuenta verificada"
|
||||
hide-password: "Ocultar contraseña"
|
||||
show-password: "Mostrar contraseña"
|
||||
do-not-use-in-production: "Esto está en desarrollo, no usarlo para producción."
|
||||
user-suspended: "Este usuario ha sido suspendido"
|
||||
is-remote-user: "La información sobre este usuario puede no estar completa"
|
||||
is-remote-post: "Es una publicación remota"
|
||||
view-on-remote: "Consultar el perfil completo"
|
||||
renoted-by: "Renotado por {user}"
|
||||
no-notes: "No hay publicaciones"
|
||||
turn-on-darkmode: "Cambiar a modo oscuro"
|
||||
turn-off-darkmode: "Modo claro"
|
||||
error:
|
||||
title: "Se ha producido un problema :("
|
||||
retry: "Inténtalo otra vez"
|
||||
reversi:
|
||||
drawn: "Empatado"
|
||||
my-turn: "Mi turno"
|
||||
opponent-turn: "Turno del oponente"
|
||||
turn-of: "Turno de {name}"
|
||||
past-turn-of: "Turno de {name}"
|
||||
won: "{name} ha ganado"
|
||||
black: "Negro"
|
||||
white: "Blanco"
|
||||
total: "Total"
|
||||
this-turn: "Turno {count}"
|
||||
widgets:
|
||||
analog-clock: "Reloj analógico"
|
||||
profile: "Perfil"
|
||||
@ -212,8 +247,12 @@ common:
|
||||
nav: "Navegación"
|
||||
tips: "Consejos"
|
||||
hashtags: "Etiquetas"
|
||||
queue: "En cola"
|
||||
dev: "Se ha producido un error creando la aplicación. Intentelo de nuevo."
|
||||
ai-chan-kawaii: "Ai-chan es muy mona!"
|
||||
you: "Tú"
|
||||
auth/views/form.vue:
|
||||
share-access: "¿Deseas permitir a <i>{name}</i> acceder a tu cuenta?"
|
||||
permission-ask: "La aplicación requiere los siguientes permisos:"
|
||||
cancel: "Cancelar"
|
||||
accept: "Garantizar acceso."
|
||||
@ -228,7 +267,18 @@ auth/views/index.vue:
|
||||
error: "Esta sesión no existe."
|
||||
sign-in: "Por favor inicia sesión."
|
||||
common/views/pages/explore.vue:
|
||||
verified-users: "Cuenta verificada"
|
||||
popular-users: "Usuarios populares"
|
||||
recently-updated-users: "Usuarios activos recientemente"
|
||||
recently-registered-users: "Usuarios que se han unido recientemente"
|
||||
popular-tags: "Etiquetas populares"
|
||||
federated: "Desde el fediverso"
|
||||
explore: "Explorar {host}"
|
||||
users-info: "Actualmente hay {users} registrados aquí"
|
||||
common/views/components/url-preview.vue:
|
||||
enable-player: "Activar reproducción"
|
||||
disable-player: "Cerrar el reproductor"
|
||||
common/views/components/user-list.vue:
|
||||
no-users: "No hay usuarios."
|
||||
common/views/components/games/reversi/reversi.vue:
|
||||
matching:
|
||||
waiting-for: "Esperando por {}"
|
||||
@ -244,6 +294,7 @@ common/views/components/games/reversi/reversi.index.vue:
|
||||
sub-title: "¡Juega Reversi con tus amigos!"
|
||||
invite: "Invitar"
|
||||
rule: "Cómo jugar"
|
||||
rule-desc: "Reversi es un juego de estrategia para dos jugadores, el cual se juega en un tablero de 8x8. Hay 64 fichas llamadas discos, las cuales son claras de un lado y oscuras del otro. Los jugadores toman turnos colocando fichas en el tablero con su color asignado mirando hacia arriba. Durante una jugada, cualquier disco del color del oponente que esté en fila entre un disco del oponente y otro del mismo color, será volteado para tener el color del jugador que haya hecho la movida. El objetivo del juego es tener la mayoría de los discos de tu color cuando el último cuadro es llenado."
|
||||
mode-invite: "Invitar"
|
||||
mode-invite-desc: "Invitar un usuario al juego."
|
||||
invitations: "¡Has recibido una invitación!"
|
||||
@ -300,23 +351,40 @@ common/views/components/media-banner.vue:
|
||||
click-to-show: "Click para mostrar"
|
||||
common/views/components/theme.vue:
|
||||
theme: "Tema"
|
||||
light-theme: "Tema a usar en Light mode"
|
||||
dark-theme: "Tema a usar en dark mode"
|
||||
light-themes: "Tema claro"
|
||||
dark-themes: "Tema oscuro"
|
||||
install-a-theme: "Instalar tema"
|
||||
theme-code: "Código del tema"
|
||||
install: "Instalación"
|
||||
installed: "\"{}\" se ha instalado"
|
||||
create-a-theme: "Crear tema"
|
||||
save-created-theme: "Guardar tema"
|
||||
primary-color: "Color primario"
|
||||
secondary-color: "Color secundario"
|
||||
text-color: "Color del texto"
|
||||
base-theme: "Tema base"
|
||||
base-theme-light: "Claro"
|
||||
base-theme-dark: "Oscuro"
|
||||
find-more-theme: "Obtener más temas"
|
||||
theme-name: "Nombre del tema"
|
||||
preview-created-theme: "Vista previa"
|
||||
invalid-theme: "No es un tema válido"
|
||||
already-installed: "Este tema ya está instalado."
|
||||
saved: "Guardado"
|
||||
manage-themes: "Gestor de temas"
|
||||
builtin-themes: "Temas estandar"
|
||||
my-themes: "Mis temas"
|
||||
installed-themes: "Temas instalados"
|
||||
select-theme: "Elegir tema"
|
||||
uninstall: "Desinstalar"
|
||||
uninstalled: "\"{}\" ha sido desinstalado"
|
||||
author: "Autor"
|
||||
desc: "Descripción"
|
||||
export: "Exportar"
|
||||
import: "Importar"
|
||||
import-by-code: "o pega el código"
|
||||
common/views/components/cw-button.vue:
|
||||
show: "Mostrar"
|
||||
chars: "{count} letras"
|
||||
@ -430,10 +498,25 @@ common/views/components/stream-indicator.vue:
|
||||
connected: "Conectado"
|
||||
common/views/components/notification-settings.vue:
|
||||
title: "Notificaciones"
|
||||
common/views/components/integration-settings.vue:
|
||||
title: "Integraciones"
|
||||
connect: "Conectar"
|
||||
disconnect: "Desconectarse"
|
||||
connected-to: "Estas conectado a la siguiente cuenta"
|
||||
common/views/components/github-setting.vue:
|
||||
description: "Una vez conectada tu cuenta de GitHub a Misskey podrás ver la información sobre tu perfil de GitHub y además podrás registrarte mediante tu cuenta de GitHub."
|
||||
connected-to: "Estas conectado a esta cuenta de GitHub"
|
||||
detail: "Ver detalles..."
|
||||
reconnect: "Reconectar"
|
||||
connect: "Vincular tu cuenta de GitHub"
|
||||
disconnect: "Desconectarse"
|
||||
common/views/components/discord-setting.vue:
|
||||
description: "Una vez conectada tu cuenta de Discord a Misskey podrás ver la información sobre tu perfil de Discord y además podrás registrarte mediante tu cuenta de Discord."
|
||||
connected-to: "Estas conectado a esta cuenta de Discord"
|
||||
detail: "Ver detalles..."
|
||||
reconnect: "Reconectar"
|
||||
connect: "Vincular tu cuenta de Discord"
|
||||
disconnect: "Desconectarse"
|
||||
common/views/components/uploader.vue:
|
||||
waiting: "Un momento"
|
||||
common/views/components/visibility-chooser.vue:
|
||||
@ -445,27 +528,65 @@ common/views/components/visibility-chooser.vue:
|
||||
specified: "Directo"
|
||||
specified-desc: "Publica solo para los seguidores que quieras"
|
||||
local-public: "Público (sólo local)"
|
||||
local-public-desc: "No publicar para remoto"
|
||||
local-home: "Inicio (sólo local)"
|
||||
local-followers: "Seguidores (sólo local)"
|
||||
common/views/components/trends.vue:
|
||||
count: "{} usuarios mencionados"
|
||||
empty: "Ninguna tendencia popular ahora"
|
||||
common/views/components/language-settings.vue:
|
||||
title: "Mostrar idioma"
|
||||
pick-language: "Selecciona un idioma"
|
||||
recommended: "Recomendado"
|
||||
auto: "Automático"
|
||||
specify-language: "Especifica el idioma"
|
||||
info: "Necesitas recargar la página para que los cambios tengan efecto."
|
||||
common/views/components/profile-editor.vue:
|
||||
title: "Perfil"
|
||||
name: "Nombre"
|
||||
account: "Cuenta"
|
||||
location: "Localización"
|
||||
description: "Acerca de mí"
|
||||
you-can-include-hashtags: "También puedes incluir hashtags en la descripción de tu perfil."
|
||||
language: "Idioma"
|
||||
birthday: "Fecha de nacimiento"
|
||||
avatar: "Avatar"
|
||||
banner: "Banner"
|
||||
is-cat: "Esta cuenta es un gato"
|
||||
is-bot: "Esta cuenta es un bot"
|
||||
is-locked: "Las peticiones de seguimiento necesitan aprobación"
|
||||
careful-bot: "Las peticiones de seguimiento de bots necesitan aprobación"
|
||||
auto-accept-followed: "Aprobar automaticamente las peticiones de follow de gente a la que sigues"
|
||||
advanced: "Otros"
|
||||
privacy: "Privacidad"
|
||||
save: "Guardar"
|
||||
saved: "Perfil actualizado con exito"
|
||||
uploading: "Subiendo"
|
||||
upload-failed: "Error al subir"
|
||||
email: "Preferencias de correo"
|
||||
email-address: "Correo electrónico"
|
||||
email-verified: "Tu cuenta de correo ha sido verificada."
|
||||
email-not-verified: "Tu cuenta de correo no está verificada. Por favor comprueba tu bandeja de entrada."
|
||||
export: "Exportar"
|
||||
import: "Importar"
|
||||
export-and-import: "Exportar/Importar"
|
||||
export-targets:
|
||||
all-notes: "Todas las notas publicadas"
|
||||
following-list: "Seguidores"
|
||||
mute-list: "Silenciar"
|
||||
blocking-list: "Bloquear"
|
||||
user-lists: "Listas"
|
||||
export-requested: "Has solicitado una exportación. Esto puede tardar un rato. Después de que termine la exportación el archivo se añadirá al drive."
|
||||
import-requested: "Has empezado una importación. Esto puede tardar un rato."
|
||||
enter-password: "Escribe una contraseña"
|
||||
danger-zone: "Zona de peligro"
|
||||
delete-account: "Eliminar cuenta"
|
||||
account-deleted: "Esta cuenta ha sido eliminada. Puede tardar un rato hasta que toda la información desaparazca."
|
||||
common/views/components/user-list-editor.vue:
|
||||
users: "Usuarios"
|
||||
rename: "Cambiar el nombre de la lista"
|
||||
delete: "Eliminar lista"
|
||||
remove-user: "Eliminar de la lista"
|
||||
common/views/components/user-lists.vue:
|
||||
list-name: "Nombre de lista"
|
||||
common/views/widgets/broadcast.vue:
|
||||
@ -788,24 +909,46 @@ admin/views/index.vue:
|
||||
instance: "Instancia"
|
||||
moderators: "Moderadores"
|
||||
users: "Usuarios"
|
||||
federation: "Federado"
|
||||
hashtags: "Hashtags"
|
||||
queue: "Cola de trabajos"
|
||||
logs: "Registros"
|
||||
back-to-misskey: "Volver a Misskey"
|
||||
admin/views/dashboard.vue:
|
||||
dashboard: "Panel de Control"
|
||||
accounts: "Cuenta"
|
||||
notes: "Publicaciones"
|
||||
drive: "Drive"
|
||||
instances: "Instancias"
|
||||
this-instance: "Esta instancia"
|
||||
federated: "Federado"
|
||||
admin/views/queue.vue:
|
||||
title: "Cola"
|
||||
remove-all-jobs: "Limpiar todos los trabajos pendientes"
|
||||
admin/views/abuse.vue:
|
||||
title: "Abuso"
|
||||
target: "Destinatario"
|
||||
reporter: "Informador"
|
||||
details: "Detalles"
|
||||
remove-report: "eliminar"
|
||||
admin/views/instance.vue:
|
||||
instance: "Instancia"
|
||||
instance-name: "Nombre de la instancia"
|
||||
instance-description: "Descripción de la instancia"
|
||||
host: "Host"
|
||||
banner-url: "URL de la imagen de banner"
|
||||
error-image-url: "Error en la URL de la imagen"
|
||||
languages: "Idioma de esta instancia"
|
||||
languages-desc: "Puedes añadir mas de uno, separado por espacios."
|
||||
maintainer-config: "Información del administrador"
|
||||
maintainer-name: "Nombre del administrador"
|
||||
maintainer-email: "Contactar con el administrador"
|
||||
drive-config: "Ajustes del Drive"
|
||||
cache-remote-files: "Mantener en cache los archivos remotos"
|
||||
recaptcha-secret-key: "clave secreta reCAPTCHA"
|
||||
invite: "Invitar"
|
||||
save: "Guardar"
|
||||
saved: "Guardado"
|
||||
email: "Correo electrónico"
|
||||
smtp-host: "Host SMTP"
|
||||
smtp-port: "Puerto SMTP"
|
||||
@ -834,7 +977,6 @@ admin/views/users.vue:
|
||||
state:
|
||||
all: "Todo"
|
||||
moderator: "Moderadores"
|
||||
verified: "Cuenta verificada"
|
||||
origin:
|
||||
local: "Local"
|
||||
admin/views/emoji.vue:
|
||||
@ -846,12 +988,14 @@ admin/views/announcements.vue:
|
||||
save: "Guardar"
|
||||
remove: "eliminar"
|
||||
add: "Agregar"
|
||||
saved: "Guardado"
|
||||
admin/views/federation.vue:
|
||||
instance: "Instancia"
|
||||
host: "Host"
|
||||
following: "Siguiendo"
|
||||
status: "Estado"
|
||||
block: "Bloquear"
|
||||
instances: "Federado"
|
||||
states:
|
||||
all: "Todo"
|
||||
blocked: "Bloquear"
|
||||
@ -859,6 +1003,7 @@ admin/views/federation.vue:
|
||||
chart-spans:
|
||||
hour: "Por hora"
|
||||
day: "Por día"
|
||||
blocked-hosts: "Bloquear"
|
||||
desktop/views/pages/selectdrive.vue:
|
||||
cancel: "Cancelar"
|
||||
desktop/views/pages/user-list.users.vue:
|
||||
@ -969,3 +1114,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"
|
||||
|
@ -13,7 +13,7 @@ common:
|
||||
rich-contents-desc: "Partagez vos idées, les événements et les sujets qui vous tiennent à cœur ainsi que tout autre chose que vous souhaitez partager avec les autres. Si vous le désirez, vous pouvez décorer vos messages en utilisant une syntaxe différente ou en y joignant des sondages et des fichiers, tels que les photos ou les vidéos que vous aimez."
|
||||
reaction: "Réactions"
|
||||
reaction-desc: "Une manière simple d'exprimer vos émotions. Misskey peut attacher diverses réactions aux publications des autres utilisateurs. Si vous essayez les réactions sur Misskey, vous ne pourrez plus retourner sur une autre plateforme de réseaux sociaux n'offrant que des « J'aime »."
|
||||
ui: "Interface utilisateur"
|
||||
ui: "Interface"
|
||||
ui-desc: "Aucune interface graphique ne peut plaire à tout le monde. Par conséquent, Misskey possède une interface utilisateur hautement personnalisable selon vos goûts. Vous pouvez rendre votre page d'accueil originale en modifiant la mise en page de votre fil et en déplaçant les widgets que vous pouvez facilement ajuster pour vous approprier cet espace."
|
||||
drive: "Drive"
|
||||
drive-desc: "Vous voulez poster une photo que vous avez déjà transférée ? Vous souhaitez organiser, nommer et créer un dossier pour vos fichiers téléversés ? Misskey Drive est la meilleure solution pour vous. Très facile de partager vos fichiers en ligne."
|
||||
@ -33,6 +33,7 @@ common:
|
||||
signin: "Se connecter"
|
||||
signup: "S'enregistrer"
|
||||
signout: "Se déconnecter"
|
||||
reload-to-apply-the-setting: "Le rechargement de la page est nécessaire pour appliquer ces paramètres. Désirez-vous la recharger maintenant ?"
|
||||
got-it: "J’ai compris !"
|
||||
customization-tips:
|
||||
title: "Conseils de personnalisation"
|
||||
@ -59,6 +60,7 @@ common:
|
||||
month-and-day: "{day}-{month}"
|
||||
trash: "Corbeille"
|
||||
drive: "Drive"
|
||||
pages: "Pages"
|
||||
messaging: "Conversations"
|
||||
home: "Principal"
|
||||
deck: "Deck"
|
||||
@ -70,10 +72,18 @@ common:
|
||||
permissions:
|
||||
"read:account": "Afficher les informations du compte"
|
||||
"write:account": "Mettre à jour les informations de votre compte"
|
||||
"read:blocks": "Voir les blocs"
|
||||
"write:blocks": "Écrire des blocs"
|
||||
"read:drive": "Parcourir le Drive"
|
||||
"write:drive": "Écrire sur le Drive"
|
||||
"read:favorites": "Afficher les favoris"
|
||||
"write:favorites": "Écrire des favoris"
|
||||
"write:messaging": "Utiliser la messagerie"
|
||||
"write:notes": "Créer ou supprimer des publications"
|
||||
"read:notifications": "Afficher les notifications"
|
||||
"write:notifications": "Gérer vos notifications"
|
||||
"read:reactions": "Lire les réactions"
|
||||
"write:reactions": "Gérer vos réactions"
|
||||
"write:votes": "Vote"
|
||||
empty-timeline-info:
|
||||
follow-users-to-make-your-timeline: "Les utilisateurs suivants afficheront leurs publications sur votre fil."
|
||||
@ -129,7 +139,7 @@ common:
|
||||
notification: "Notifications"
|
||||
apps: "Applications"
|
||||
tags: "Hashtags"
|
||||
mute-and-block: "Silencer / Bloquer"
|
||||
mute-and-block: "Silencés / Bloqués"
|
||||
blocking: "En cours blocage"
|
||||
security: "Sécurité"
|
||||
signin: "Historique des connexions"
|
||||
@ -189,6 +199,7 @@ common:
|
||||
show-clock-on-header: "Afficher l'horloge sur le coté supérieur droit"
|
||||
timeline: "Fil d’actualité"
|
||||
show-my-renotes: "Afficher mes republications dans le fil"
|
||||
show-renoted-my-notes: "Afficher les partages de mes propres notes sur le fil"
|
||||
remain-deleted-note: "Continuer à afficher les notes supprimées"
|
||||
sound: "Son"
|
||||
enable-sounds: "Activer les sons"
|
||||
@ -209,16 +220,16 @@ common:
|
||||
debug-mode: "Activer le mode débogage"
|
||||
debug-mode-desc: "Ce paramètre est stocké dans le navigateur."
|
||||
navbar-position: "Position de la barre de navigation"
|
||||
navbar-position-top: "en haut"
|
||||
navbar-position-top: "En haut"
|
||||
navbar-position-left: "À gauche"
|
||||
navbar-position-right: "à droite"
|
||||
navbar-position-right: "À droite"
|
||||
i-am-under-limited-internet: "J'ai un accès Internet limité"
|
||||
post-style: "Style d'affichage des notes"
|
||||
post-style-standard: "Standard"
|
||||
post-style-smart: "Intelligent"
|
||||
notification-position: "Afficher les notifications"
|
||||
notification-position-bottom: "en bas"
|
||||
notification-position-top: "en haut"
|
||||
notification-position-top: "En haut"
|
||||
disable-via-mobile: "Enlever la mention publié via 'mobile'"
|
||||
load-raw-images: "Afficher les photos jointes dans leur qualité originale"
|
||||
load-remote-media: "Afficher les médias depuis le serveur distant"
|
||||
@ -230,7 +241,6 @@ common:
|
||||
update-available-title: "Mise à jour disponible"
|
||||
update-available: "Une nouvelle version de Misskey est disponible ({newer}, version actuelle: {current}). Veuillez recharger la page pour appliquer la mise à jour."
|
||||
my-token-regenerated: "Votre jeton vient d’être généré, vous allez maintenant être déconnecté."
|
||||
verified-user: "Compte vérifié"
|
||||
hide-password: "Masquer le mot de passe"
|
||||
show-password: "Afficher le mot de passe"
|
||||
do-not-use-in-production: "Il s’agit d’une version de développement. Ne pas utiliser dans un environnement de production."
|
||||
@ -298,7 +308,6 @@ auth/views/index.vue:
|
||||
error: "La session n’existe pas."
|
||||
sign-in: "Veuillez vous connecter"
|
||||
common/views/pages/explore.vue:
|
||||
verified-users: "Comptes vérifiés"
|
||||
popular-users: "Utilisateurs populaires"
|
||||
recently-updated-users: "Utilisateurs actifs récemment"
|
||||
recently-registered-users: "Les nouveaux inscrits"
|
||||
@ -307,6 +316,7 @@ common/views/pages/explore.vue:
|
||||
explore: "Explorer {host}"
|
||||
users-info: "Actuellement, {users} utilisateurs se sont inscrit ici"
|
||||
common/views/components/url-preview.vue:
|
||||
enable-player: "Activer la lecture"
|
||||
disable-player: "Fermer le lecteur"
|
||||
common/views/components/user-list.vue:
|
||||
no-users: "Il n'y a aucun utilisateur"
|
||||
@ -450,6 +460,7 @@ common/views/components/nav.vue:
|
||||
repository: "Dépôt"
|
||||
develop: "Développeurs"
|
||||
feedback: "Suggestions"
|
||||
tos: "Conditions d'utilisation"
|
||||
common/views/components/note-menu.vue:
|
||||
mention: "Mention"
|
||||
detail: "Détails"
|
||||
@ -468,8 +479,12 @@ common/views/components/user-menu.vue:
|
||||
mention: "Mention"
|
||||
mute: "Silencier"
|
||||
unmute: "Enlever la sourdine"
|
||||
mute-confirm: "Rendre muet cet utilisateur ?"
|
||||
unmute-confirm: "Ne plus masquer cet utilisateur ?"
|
||||
block: "Bloquer"
|
||||
unblock: "Débloquer"
|
||||
block-confirm: "Bloquer cet utilisateur ?"
|
||||
unblock-confirm: "Débloquer cet utilisateur ?"
|
||||
push-to-list: "Ajouter à une liste"
|
||||
select-list: "Sélectionnez une liste"
|
||||
report-abuse: "Signaler un abus"
|
||||
@ -552,6 +567,7 @@ common/views/components/signup.vue:
|
||||
password-matched: "OK"
|
||||
password-not-matched: "Les mots de passe ne correspondent pas."
|
||||
recaptcha: "Vérifier"
|
||||
tos: "Conditions d'utilisation"
|
||||
create: "Créer un compte"
|
||||
some-error: "La création du compte a échoué. Veuillez réessayer."
|
||||
common/views/components/special-message.vue:
|
||||
@ -647,6 +663,7 @@ common/views/components/profile-editor.vue:
|
||||
blocking-list: "Liste des comptes bloqués"
|
||||
user-lists: "Listes"
|
||||
export-requested: "Vous avez demandé une exportation. Cela peut prendre un certain temps. Une fois l'exportation terminée, le fichier résultant sera ajouté dans le Drive."
|
||||
import-requested: "Vous avez initié un import. Ceci peut prendre un peu de temps."
|
||||
enter-password: "Veuillez saisir votre mot de passe"
|
||||
danger-zone: "Zone de danger"
|
||||
delete-account: "Supprimer le compte"
|
||||
@ -659,6 +676,7 @@ common/views/components/user-list-editor.vue:
|
||||
delete-are-you-sure: "Voulez-vous vraiment supprimer la liste « $1 » ?"
|
||||
deleted: "Supprimé"
|
||||
common/views/components/user-lists.vue:
|
||||
create-list: "Créer une liste"
|
||||
list-name: "Nom de la liste"
|
||||
common/views/widgets/broadcast.vue:
|
||||
fetching: "Récupération"
|
||||
@ -1099,7 +1117,6 @@ admin/views/instance.vue:
|
||||
invite: "Inviter"
|
||||
save: "Sauvegarder"
|
||||
saved: "Enregistré"
|
||||
user-recommendation-config: "Utilisateurs"
|
||||
email-config: "Paramètres du serveur de messagerie"
|
||||
email-config-info: "Utilisé pour confirmer votre adresse de courrier électronique et la réinitialisation de votre mot de passe."
|
||||
enable-email: "Activation de la distribution du courrier"
|
||||
@ -1180,13 +1197,8 @@ admin/views/users.vue:
|
||||
unsuspend-confirm: "Souhaiteriez-vous ne plus suspendre ce compte ?"
|
||||
unsuspended: "La suspension de l’utilisateur a été levée avec succès"
|
||||
make-silence: "Mettre en sourdine"
|
||||
silence-confirm: "Mettre l'utilisateur sous silence ?"
|
||||
unmake-silence: "Enlever la sourdine"
|
||||
verify: "Vérification du compte"
|
||||
verify-confirm: "Souhaiteriez-vous rendre votre compte comme étant un compte vérifié ?"
|
||||
verified: "Le compte a été vérifié"
|
||||
unverify: "Enlever la vérification du compte"
|
||||
unverify-confirm: "Désirez-vous considérer ce compte comme étant non-vérifié ?"
|
||||
unverified: "Ce compte n'est plus vérifié"
|
||||
update-remote-user: "Mettre à jour les informations de l’utilisateur·rice distant·e"
|
||||
remote-user-updated: "Les informations de l’utilisateur·rice distant·e ont étés mis à jour"
|
||||
users:
|
||||
@ -1203,7 +1215,6 @@ admin/views/users.vue:
|
||||
admin: "Admin"
|
||||
moderator: "Modérateur"
|
||||
adminOrModerator: "Administrateur/Modérateur"
|
||||
verified: "Compte vérifié"
|
||||
silenced: "Déjà mis en sourdine"
|
||||
suspended: "Suspendu"
|
||||
origin:
|
||||
@ -1302,6 +1313,7 @@ admin/views/federation.vue:
|
||||
chart-spans:
|
||||
hour: "Par heure"
|
||||
day: "Par jour"
|
||||
blocked-hosts: "En cours blocage"
|
||||
desktop/views/pages/welcome.vue:
|
||||
about: "à propos"
|
||||
timeline: "Fil d’actualité"
|
||||
@ -1463,6 +1475,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:
|
||||
@ -1564,25 +1577,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:
|
||||
@ -1599,3 +1593,168 @@ 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:
|
||||
page-created: "Page a été créée !"
|
||||
are-you-sure-delete: "Confirmez-vous la suppression de cette page ?"
|
||||
page-deleted: "La page a bien été supprimée."
|
||||
edit-this-page: "Éditer cette page"
|
||||
view-source: "Afficher la source"
|
||||
view-page: "Afficher la page"
|
||||
inspector: "Inspecteur"
|
||||
content: "Bloc de page"
|
||||
variables: "Variables"
|
||||
more-details: "Description"
|
||||
title: "Titre"
|
||||
url: "URL de page"
|
||||
summary: "Résumé de page"
|
||||
align-center: "Centrée"
|
||||
font: "Police de caractères"
|
||||
fontSerif: "Serif"
|
||||
fontSansSerif: "Sans Serif"
|
||||
choose-block: "Ajouter un bloc"
|
||||
select-type: "Choisir un type"
|
||||
enter-variable-name: "Veuillez choisir un nom de variable"
|
||||
the-variable-name-is-already-used: "Cette variable est déjà utilisée"
|
||||
content-blocks: "Contenu du cadre"
|
||||
special-blocks: "Spécial"
|
||||
posted-from-post-form: "Publié !"
|
||||
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: "Entrée textuelle"
|
||||
_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: "Entrée numérique"
|
||||
_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"
|
||||
ref: "Variables"
|
||||
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"
|
||||
|
@ -65,6 +65,7 @@ common:
|
||||
|
||||
trash: "ゴミ箱"
|
||||
drive: "ドライブ"
|
||||
pages: "ページ"
|
||||
messaging: "トーク"
|
||||
home: "ホーム"
|
||||
deck: "デッキ"
|
||||
@ -262,7 +263,6 @@ common:
|
||||
update-available-title: "更新があります"
|
||||
update-available: "Misskeyの新しいバージョンがあります({newer}。現在{current}を利用中)。ページを再度読み込みすると更新が適用されます。"
|
||||
my-token-regenerated: "あなたのトークンが更新されたのでサインアウトします。"
|
||||
verified-user: "公式アカウント"
|
||||
hide-password: "パスワードを隠す"
|
||||
show-password: "パスワードを表示する"
|
||||
|
||||
@ -338,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: "新規ユーザー"
|
||||
@ -508,6 +508,7 @@ common/views/components/nav.vue:
|
||||
repository: "リポジトリ"
|
||||
develop: "開発者"
|
||||
feedback: "フィードバック"
|
||||
tos: "利用規約"
|
||||
|
||||
common/views/components/note-menu.vue:
|
||||
mention: "メンション"
|
||||
@ -628,6 +629,8 @@ common/views/components/signup.vue:
|
||||
password-matched: "確認されました"
|
||||
password-not-matched: "一致していません"
|
||||
recaptcha: "認証"
|
||||
agree-to: "{0}に同意します。"
|
||||
tos: "利用規約"
|
||||
create: "アカウント作成"
|
||||
some-error: "何らかの原因によりアカウントの作成に失敗しました。再度お試しください。"
|
||||
|
||||
@ -1184,7 +1187,6 @@ admin/views/index.vue:
|
||||
users: "ユーザー"
|
||||
federation: "連合"
|
||||
announcements: "お知らせ"
|
||||
hashtags: "ハッシュタグ"
|
||||
abuse: "スパム報告"
|
||||
queue: "ジョブキュー"
|
||||
logs: "ログ"
|
||||
@ -1215,14 +1217,34 @@ admin/views/instance.vue:
|
||||
instance-name: "インスタンス名"
|
||||
instance-description: "インスタンスの紹介"
|
||||
host: "ホスト"
|
||||
icon-url: "アイコンURL"
|
||||
logo-url: "ロゴURL"
|
||||
banner-url: "バナー画像URL"
|
||||
error-image-url: "エラー画像URL"
|
||||
languages: "インスタンスの対象言語"
|
||||
languages-desc: "スペースで区切って複数設定できます。"
|
||||
tos-url: "利用規約URL"
|
||||
repository-url: "リポジトリURL"
|
||||
feedback-url: "フィードバックURL"
|
||||
maintainer-config: "管理者情報"
|
||||
maintainer-name: "管理者名"
|
||||
maintainer-email: "管理者の連絡先"
|
||||
advanced-config: "その他の設定"
|
||||
note-and-tl: "投稿とタイムライン"
|
||||
drive-config: "ドライブの設定"
|
||||
use-object-storage: "オブジェクトストレージを使用する"
|
||||
object-storage-base-url: "URL"
|
||||
object-storage-bucket: "バケット名"
|
||||
object-storage-prefix: "プレフィックス"
|
||||
object-storage-endpoint: "エンドポイント"
|
||||
object-storage-region: "リージョン"
|
||||
object-storage-port: "ポート"
|
||||
object-storage-access-key: "アクセスキー"
|
||||
object-storage-secret-key: "シークレットキー"
|
||||
object-storage-use-ssl: "SSLを使用"
|
||||
object-storage-s3-info: "Amazon S3をオブジェクトストレージとして使用する場合の「エンドポイント」と「リージョン」の設定については{0}をご確認ください。"
|
||||
object-storage-s3-info-here: "こちら"
|
||||
object-storage-gcs-info: "Google Cloud Storageをオブジェクトストレージとして使用する場合、「エンドポイント」は storage.googleapis.com に設定し、「リージョン」は空欄にします。"
|
||||
cache-remote-files: "リモートのファイルをキャッシュする"
|
||||
cache-remote-files-desc: "この設定を無効にすると、リモートファイルをキャッシュせず直リンクするようになります。そのためサーバーのストレージを節約できますが、プライバシー設定で直リンクを無効にしているユーザーにはファイルが見えなくなったり、サムネイルが生成されないので通信量が増加します。通常はこの設定をオンにしておくことをおすすめします。"
|
||||
local-drive-capacity-mb: "ローカルユーザーひとりあたりのドライブ容量"
|
||||
@ -1233,6 +1255,9 @@ admin/views/instance.vue:
|
||||
enable-recaptcha: "reCAPTCHAを有効にする"
|
||||
recaptcha-site-key: "reCAPTCHA site key"
|
||||
recaptcha-secret-key: "reCAPTCHA secret key"
|
||||
hidden-tags: "非表示ハッシュタグ"
|
||||
hidden-tags-info: "集計から除外するハッシュタグを改行で区切って記述します。"
|
||||
external-service-integration-config: "外部サービス連携"
|
||||
twitter-integration-config: "Twitter連携の設定"
|
||||
twitter-integration-info: "コールバックURLは {url} に設定します。"
|
||||
enable-twitter-integration: "Twitter連携を有効にする"
|
||||
@ -1263,7 +1288,8 @@ admin/views/instance.vue:
|
||||
invite: "招待"
|
||||
save: "保存"
|
||||
saved: "保存しました"
|
||||
user-recommendation-config: "おすすめユーザー"
|
||||
pinned-users: "ピン留めユーザー"
|
||||
pinned-users-info: "ピン留めしたいユーザーを改行で区切って記述します。"
|
||||
email-config: "メールサーバーの設定"
|
||||
email-config-info: "メールアドレス確認やパスワードリセットの際に使われます。"
|
||||
enable-email: "メール配信を有効にする"
|
||||
@ -1350,14 +1376,10 @@ admin/views/users.vue:
|
||||
silence-confirm: "サイレンスしますか?"
|
||||
unmake-silence: "サイレンスの解除"
|
||||
unsilence-confirm: "サイレンスを解除しますか?"
|
||||
verify: "公式アカウントにする"
|
||||
verify-confirm: "公式アカウントにしますか?"
|
||||
verified: "公式アカウントにしました"
|
||||
unverify: "公式アカウントを解除する"
|
||||
unverify-confirm: "公式アカウントを解除しますか?"
|
||||
unverified: "公式アカウントを解除しました"
|
||||
update-remote-user: "リモートユーザー情報の更新"
|
||||
remote-user-updated: "リモートユーザー情報を更新しました"
|
||||
delete-all-files: "すべてのファイルを削除"
|
||||
delete-all-files-confirm: "すべてのファイルを削除しますか?"
|
||||
users:
|
||||
title: "ユーザー"
|
||||
sort:
|
||||
@ -1372,7 +1394,6 @@ admin/views/users.vue:
|
||||
admin: "管理者"
|
||||
moderator: "モデレーター"
|
||||
adminOrModerator: "管理者+モデレーター"
|
||||
verified: "公式アカウント"
|
||||
silenced: "サイレンス済み"
|
||||
suspended: "凍結済み"
|
||||
origin:
|
||||
@ -1439,6 +1460,7 @@ admin/views/federation.vue:
|
||||
latest-request-received-at: "直近のリクエスト受信"
|
||||
remove-all-following: "フォローを全解除"
|
||||
remove-all-following-info: "{host}からのフォローをすべて解除します。そのインスタンスがもう存在しなくなった場合などに実行してください。"
|
||||
delete-all-files: "ファイルをすべて削除"
|
||||
block: "ブロック"
|
||||
marked-as-closed: "閉鎖されているとマーク"
|
||||
lookup: "照会"
|
||||
@ -1485,6 +1507,8 @@ admin/views/federation.vue:
|
||||
chart-spans:
|
||||
hour: "1時間ごと"
|
||||
day: "1日ごと"
|
||||
blocked-hosts: "ブロック"
|
||||
blocked-hosts-info: "ブロックしたいホストを改行で区切って記述します。"
|
||||
|
||||
desktop/views/pages/welcome.vue:
|
||||
about: "詳しく..."
|
||||
@ -1813,26 +1837,6 @@ 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: "アプリの管理"
|
||||
|
||||
@ -1857,3 +1861,264 @@ 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標準で関数を引数に取る関数(高階関数と呼ばれます)も存在します。関数は予め定義しておくほかに、このような高階関数のスロットに即席でセットすることもできます。"
|
||||
more-details: "詳しい説明"
|
||||
title: "タイトル"
|
||||
url: "ページURL"
|
||||
summary: "ページの要約"
|
||||
align-center: "中央寄せ"
|
||||
font: "フォント"
|
||||
fontSerif: "セリフ"
|
||||
fontSansSerif: "サンセリフ"
|
||||
set-eye-catching-image: "アイキャッチ画像を設定"
|
||||
remove-eye-catching-image: "アイキャッチ画像を削除"
|
||||
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: "テキスト操作"
|
||||
convert: "変換"
|
||||
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: "そうでなければ"
|
||||
not: "否定"
|
||||
_not:
|
||||
arg1: "否定"
|
||||
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: "確率付きリストからランダムに選択 (ユーザーごとに日替わり)"
|
||||
_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: "入力スロット"
|
||||
|
@ -121,7 +121,6 @@ common:
|
||||
update-available-title: "更新があんで"
|
||||
update-available: "Misskeyの新しいバージョンがあんで({newer}。現在{current}をつこてるわ)。ページを再度読み込みしたると更新が適用されるわ。"
|
||||
my-token-regenerated: "あんさんのトークンが更新されたらしいわ。すまんがとりあえずサインアウトすんで。"
|
||||
verified-user: "アメちゃん付きアカウント"
|
||||
do-not-use-in-production: "開発ビルドや。本番環境で使わんといて!知らんで!"
|
||||
is-remote-post: "この投稿情報はコピーです。"
|
||||
view-on-remote: "ちゃんとした情報見せてや!"
|
||||
@ -181,7 +180,6 @@ auth/views/index.vue:
|
||||
error: "セッションが存在してへん。"
|
||||
sign-in: "サインインしてや"
|
||||
common/views/pages/explore.vue:
|
||||
verified-users: "アメちゃん付きアカウント"
|
||||
federated: "連合"
|
||||
common/views/components/games/reversi/reversi.vue:
|
||||
matching:
|
||||
@ -899,7 +897,6 @@ admin/views/instance.vue:
|
||||
invite: "来てや"
|
||||
save: "保存"
|
||||
saved: "保存したで!"
|
||||
user-recommendation-config: "このユーザーええで"
|
||||
email-config: "メールサーバーの設定"
|
||||
email-config-info: "メールアドレス確認やパスワードリセットの際に使うで。"
|
||||
enable-email: "メール配信を有効にする"
|
||||
@ -956,7 +953,6 @@ admin/views/users.vue:
|
||||
state:
|
||||
all: "すべて"
|
||||
moderator: "モデレーター"
|
||||
verified: "アメちゃん付きアカウント"
|
||||
origin:
|
||||
local: "ローカル"
|
||||
admin/views/emoji.vue:
|
||||
@ -995,6 +991,7 @@ admin/views/federation.vue:
|
||||
chart-spans:
|
||||
hour: "1時間ごと"
|
||||
day: "1日ごと"
|
||||
blocked-hosts: "ブロック"
|
||||
desktop/views/pages/welcome.vue:
|
||||
about: "もうちょい……"
|
||||
timeline: "タイムライン"
|
||||
@ -1246,25 +1243,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 +1259,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: "사용자를 팔로우하면 글이 타임라인에 표시됩니다."
|
||||
@ -234,7 +251,6 @@ common:
|
||||
update-available-title: "업데이트가 있습니다"
|
||||
update-available: "Misskey의 새로운 버전이 있습니다 ({newer}. 현재 {current}을 사용 중). 페이지를 다시 로드하면 업데이트가 적용됩니다."
|
||||
my-token-regenerated: "당신의 토큰이 업데이트되었으므로 로그아웃합니다."
|
||||
verified-user: "공식 계정"
|
||||
hide-password: "비밀번호 숨기기"
|
||||
show-password: "비밀번호 표시"
|
||||
do-not-use-in-production: "이것은 개발 빌드입니다. 프로덕션 환경에서 사용하지 마십시오."
|
||||
@ -277,7 +293,7 @@ common:
|
||||
notifications: "알림"
|
||||
users: "추천 사용자"
|
||||
polls: "투표"
|
||||
post-form: "게시 양식"
|
||||
post-form: "글 입력란"
|
||||
server: "서버 정보"
|
||||
nav: "내비게이션"
|
||||
tips: "팁"
|
||||
@ -293,16 +309,16 @@ 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:
|
||||
verified-users: "공식 계정"
|
||||
pinned-users: "고정된 사용자"
|
||||
popular-users: "인기 사용자"
|
||||
recently-updated-users: "최근 게시한 사용자"
|
||||
recently-registered-users: "신규 사용자"
|
||||
@ -456,6 +472,7 @@ common/views/components/nav.vue:
|
||||
repository: "저장소"
|
||||
develop: "개발자"
|
||||
feedback: "피드백"
|
||||
tos: "이용 약관"
|
||||
common/views/components/note-menu.vue:
|
||||
mention: "멘션"
|
||||
detail: "상세"
|
||||
@ -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: "{}표"
|
||||
@ -560,6 +585,7 @@ common/views/components/signup.vue:
|
||||
password-matched: "확인되었습니다"
|
||||
password-not-matched: "일치하지 않습니다"
|
||||
recaptcha: "자동 가입 방지"
|
||||
tos: "이용 약관"
|
||||
create: "계정 만들기"
|
||||
some-error: "알 수 없는 이유로 계정 만들기에 실패했습니다. 다시 한번 시도해 주세요."
|
||||
common/views/components/special-message.vue:
|
||||
@ -668,6 +694,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 +973,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: "사용중"
|
||||
@ -1065,10 +1092,15 @@ admin/views/instance.vue:
|
||||
instance-name: "인스턴스 이름"
|
||||
instance-description: "인스턴스의 소개"
|
||||
host: "관리자"
|
||||
icon-url: "아이콘 URL"
|
||||
logo-url: "로고 URL"
|
||||
banner-url: "배너 이미지 URL"
|
||||
error-image-url: "오류 이미지 URL"
|
||||
languages: "인스턴스의 대상 언어"
|
||||
languages-desc: "공백으로 구분하여 여러 개 설정할 수 있습니다."
|
||||
tos-url: "이용약관 URL"
|
||||
repository-url: "저장소 URL"
|
||||
feedback-url: "피드백 URL"
|
||||
maintainer-config: "관리자 정보"
|
||||
maintainer-name: "관리자 이름"
|
||||
maintainer-email: "관리자 연락처"
|
||||
@ -1113,7 +1145,7 @@ admin/views/instance.vue:
|
||||
invite: "초대"
|
||||
save: "저장"
|
||||
saved: "저장하였습니다"
|
||||
user-recommendation-config: "추천 사용자"
|
||||
pinned-users: "고정된 사용자"
|
||||
email-config: "메일 서버 설정"
|
||||
email-config-info: "메일 주소 확인 혹은 비밀번호 재설정에 사용 됩니다."
|
||||
enable-email: "메일 발신 활성화"
|
||||
@ -1194,13 +1226,9 @@ admin/views/users.vue:
|
||||
unsuspend-confirm: "정지를 해제하시겠습니까?"
|
||||
unsuspended: "정지를 해제하였습니다"
|
||||
make-silence: "침묵"
|
||||
silence-confirm: "침묵으로 설정합니까?"
|
||||
unmake-silence: "침묵 해제"
|
||||
verify: "공식 계정으로 설정"
|
||||
verify-confirm: "공식 계정으로 설정하시겠습니까?"
|
||||
verified: "공식 계정으로 설정하였습니다"
|
||||
unverify: "공식 계정 해제"
|
||||
unverify-confirm: "공식 계정을 해제하시겠습니까?"
|
||||
unverified: "공식 계정을 해제하였습니다"
|
||||
unsilence-confirm: "침묵 해제하시겠습니까?"
|
||||
update-remote-user: "원격 사용자 정보 갱신"
|
||||
remote-user-updated: "원격 사용자 정보를 갱신하였습니다"
|
||||
users:
|
||||
@ -1217,7 +1245,6 @@ admin/views/users.vue:
|
||||
admin: "관리자"
|
||||
moderator: "모더레이터"
|
||||
adminOrModerator: "관리자+모더레이터"
|
||||
verified: "공식 계정"
|
||||
silenced: "침묵됨"
|
||||
suspended: "정지됨"
|
||||
origin:
|
||||
@ -1325,6 +1352,7 @@ admin/views/federation.vue:
|
||||
chart-spans:
|
||||
hour: "1시간마다"
|
||||
day: "1일마다"
|
||||
blocked-hosts: "차단"
|
||||
desktop/views/pages/welcome.vue:
|
||||
about: "자세히..."
|
||||
timeline: "타임라인"
|
||||
@ -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,246 @@ 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: "이 페이지를 삭제하시겠습니까?"
|
||||
page-deleted: "페이지가 삭제되었습니다"
|
||||
edit-this-page: "이 페이지를 편집"
|
||||
view-source: "소스 보기"
|
||||
view-page: "페이지 보기"
|
||||
inspector: "인스펙터"
|
||||
content: "페이지 블록"
|
||||
variables: "변수"
|
||||
more-details: "자세한 설명"
|
||||
title: "제목"
|
||||
url: "페이지 URL"
|
||||
summary: "페이지 요약"
|
||||
align-center: "가운데 정렬"
|
||||
font: "글꼴"
|
||||
fontSerif: "세리프"
|
||||
fontSansSerif: "산 세리프"
|
||||
set-eye-catching-image: "아이캐치 이미지를 설정"
|
||||
remove-eye-catching-image: "아이캐치 이미지를 삭제"
|
||||
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: "텍스트 조작"
|
||||
convert: "변환"
|
||||
list: "리스트"
|
||||
blocks:
|
||||
text: "텍스트"
|
||||
multiLineText: "텍스트 (여러줄)"
|
||||
textList: "텍스트 목록"
|
||||
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: "그렇지 않으면"
|
||||
not: "부정"
|
||||
_not:
|
||||
arg1: "부정"
|
||||
random: "랜덤"
|
||||
_random:
|
||||
arg1: "확률"
|
||||
rannum: "난수"
|
||||
_rannum:
|
||||
arg1: "최소"
|
||||
arg2: "최대"
|
||||
randomPick: "목록에서 임의로 선택"
|
||||
_randomPick:
|
||||
arg1: "리스트"
|
||||
_dailyRandom:
|
||||
arg1: "확률"
|
||||
_dailyRannum:
|
||||
arg1: "최소"
|
||||
arg2: "최대"
|
||||
_dailyRandomPick:
|
||||
arg1: "리스트"
|
||||
_seedRandom:
|
||||
arg1: "시드"
|
||||
arg2: "확률"
|
||||
_seedRannum:
|
||||
arg1: "시드"
|
||||
arg2: "최소"
|
||||
arg3: "최대"
|
||||
_seedRandomPick:
|
||||
arg1: "시드"
|
||||
arg2: "리스트"
|
||||
_DRPWPM:
|
||||
arg1: "텍스트 목록"
|
||||
_pick:
|
||||
arg1: "리스트"
|
||||
number: "수치"
|
||||
stringToNumber: "텍스트를 수치로"
|
||||
_stringToNumber:
|
||||
arg1: "텍스트"
|
||||
_numberToString:
|
||||
arg1: "수치"
|
||||
_splitStrByLine:
|
||||
arg1: "텍스트"
|
||||
ref: "변수"
|
||||
fn: "함수"
|
||||
_fn:
|
||||
slots: "슬롯"
|
||||
arg1: "출력"
|
||||
thereIsEmptySlot: "슬롯 {slot}이(가) 비었습니다!"
|
||||
types:
|
||||
string: "텍스트"
|
||||
number: "수치"
|
||||
boolean: "플래그"
|
||||
array: "리스트"
|
||||
stringArray: "텍스트 목록"
|
||||
emptySlot: "빈 슬롯"
|
||||
enviromentVariables: "환경 변수"
|
||||
pageVariables: "페이지 요소"
|
||||
argVariables: "입력 슬롯"
|
||||
|
@ -422,8 +422,6 @@ admin/views/dashboard.vue:
|
||||
notes: "Bericht"
|
||||
admin/views/abuse.vue:
|
||||
remove-report: "Verwijderen"
|
||||
admin/views/instance.vue:
|
||||
user-recommendation-config: "Aanbevolen gebruikers"
|
||||
admin/views/charts.vue:
|
||||
notes: "Bericht"
|
||||
users: "Gebruiker"
|
||||
@ -619,13 +617,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"
|
||||
@ -164,7 +166,6 @@ common:
|
||||
update-available-title: "Aktualizacja jest dostępna"
|
||||
update-available: "Nowa wersja Misskey jest dostępna ({newer}, obecna to {current}). Odśwież stronę, aby zastosować aktualizację."
|
||||
my-token-regenerated: "Twój token został wygenerowany. Zostaniesz wylogowany."
|
||||
verified-user: "Zweryfikowane konto"
|
||||
hide-password: "Ukryj hasło"
|
||||
show-password: "Pokaż hasło"
|
||||
view-on-remote: "Dla dopełnienia, zobacz to zdalnie."
|
||||
@ -216,8 +217,6 @@ auth/views/index.vue:
|
||||
please-go-back: "Wróć do aplikacji."
|
||||
error: "Sesja nie istnieje."
|
||||
sign-in: "Proszę zalogować się."
|
||||
common/views/pages/explore.vue:
|
||||
verified-users: "Zweryfikowane konto"
|
||||
common/views/components/games/reversi/reversi.vue:
|
||||
matching:
|
||||
waiting-for: "Oczekiwanie na {}"
|
||||
@ -875,7 +874,6 @@ admin/views/instance.vue:
|
||||
invite: "Zaproś"
|
||||
save: "Zapisz"
|
||||
saved: "Zapisano"
|
||||
user-recommendation-config: "Polecani użytkownicy"
|
||||
email: "Adres e-mail"
|
||||
admin/views/charts.vue:
|
||||
notes: "Wpisy"
|
||||
@ -905,7 +903,6 @@ admin/views/users.vue:
|
||||
state:
|
||||
all: "Wszyscy"
|
||||
moderator: "Moderatorzy"
|
||||
verified: "Zweryfikowane konto"
|
||||
origin:
|
||||
title: "Źródło"
|
||||
local: "Lokalny"
|
||||
@ -951,6 +948,7 @@ admin/views/federation.vue:
|
||||
blocked: "Zablokuj"
|
||||
chart-srcs:
|
||||
requests: "Żądania"
|
||||
blocked-hosts: "Zablokuj"
|
||||
desktop/views/pages/welcome.vue:
|
||||
about: "O Misskey"
|
||||
timeline: "Oś czasu"
|
||||
@ -1190,23 +1188,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 +1196,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"
|
||||
|
@ -89,7 +89,6 @@ common:
|
||||
update-available-title: "Atualização disponível"
|
||||
update-available: "Uma nova versão de Misskey está disponível ({newer}). A versão atual é {current}. Recarregue a página para atualizar."
|
||||
my-token-regenerated: "Seu token foi recriado, portanto você foi deslogado."
|
||||
verified-user: "Conta verificada"
|
||||
reversi:
|
||||
drawn: "Empatado"
|
||||
my-turn: "Seu turno"
|
||||
@ -129,8 +128,6 @@ auth/views/index.vue:
|
||||
please-go-back: "Por favor, volte ao aplicativo."
|
||||
error: "A sessão não existe."
|
||||
sign-in: "Por favor, entre."
|
||||
common/views/pages/explore.vue:
|
||||
verified-users: "Conta verificada"
|
||||
common/views/components/games/reversi/reversi.index.vue:
|
||||
invite: "Convidar"
|
||||
rule: "Como jogar"
|
||||
@ -194,10 +191,6 @@ admin/views/instance.vue:
|
||||
invite: "Convidar"
|
||||
admin/views/drive.vue:
|
||||
delete: "Apagar"
|
||||
admin/views/users.vue:
|
||||
users:
|
||||
state:
|
||||
verified: "Conta verificada"
|
||||
admin/views/emoji.vue:
|
||||
emojis:
|
||||
remove: "Apagar"
|
||||
@ -274,18 +267,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: "Случайно"
|
||||
|
@ -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: "Deck"
|
||||
@ -249,7 +251,6 @@ common:
|
||||
update-available-title: "有可用更新"
|
||||
update-available: "新的 Misskey 版本现已发布({newer}。目前版本{current}). 刷新页面以应用更新。"
|
||||
my-token-regenerated: "您的 Token 已被重置, 您将自动登出。"
|
||||
verified-user: "认证用户"
|
||||
hide-password: "隐藏密码"
|
||||
show-password: "显示密码"
|
||||
do-not-use-in-production: "这是一个开发者测试版. 请勿在生产环境中使用."
|
||||
@ -317,7 +318,7 @@ auth/views/index.vue:
|
||||
error: "会话不存在。"
|
||||
sign-in: "请登录。"
|
||||
common/views/pages/explore.vue:
|
||||
verified-users: "官方账户"
|
||||
pinned-users: "已置顶用户"
|
||||
popular-users: "热门用户"
|
||||
recently-updated-users: "活跃用户"
|
||||
recently-registered-users: "新用户"
|
||||
@ -1137,7 +1138,7 @@ admin/views/instance.vue:
|
||||
invite: "邀请"
|
||||
save: "保存"
|
||||
saved: "保存完毕"
|
||||
user-recommendation-config: "推荐用户"
|
||||
pinned-users: "置顶用户"
|
||||
email-config: "电子邮件服务器设置"
|
||||
email-config-info: "用于确认电子邮件和密码重置等。"
|
||||
enable-email: "启用电子邮件送递"
|
||||
@ -1221,12 +1222,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:
|
||||
@ -1243,7 +1238,6 @@ admin/views/users.vue:
|
||||
admin: "管理员"
|
||||
moderator: "版主"
|
||||
adminOrModerator: "管理员+版主"
|
||||
verified: "官方认证账户"
|
||||
silenced: "已禁言"
|
||||
suspended: "已冻结"
|
||||
origin:
|
||||
@ -1351,6 +1345,7 @@ admin/views/federation.vue:
|
||||
chart-spans:
|
||||
hour: "每小时"
|
||||
day: "每天"
|
||||
blocked-hosts: "拉黑"
|
||||
desktop/views/pages/welcome.vue:
|
||||
about: "更多信息..."
|
||||
timeline: "时间线"
|
||||
@ -1621,25 +1616,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:
|
||||
@ -1662,3 +1638,254 @@ 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: "无衬线字体"
|
||||
set-eye-catching-image: "设置封面图片"
|
||||
remove-eye-catching-image: "删除封面图片"
|
||||
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: "文本操作"
|
||||
convert: "转换"
|
||||
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: "否则"
|
||||
not: "否定"
|
||||
_not:
|
||||
arg1: "否定"
|
||||
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: "从概率列表中随机选择(每用户每天)"
|
||||
_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: "输入槽函数"
|
||||
|
31
migration/1556348509290-Pages.ts
Normal file
31
migration/1556348509290-Pages.ts
Normal file
@ -0,0 +1,31 @@
|
||||
import {MigrationInterface, QueryRunner} from "typeorm";
|
||||
|
||||
export class Pages1556348509290 implements MigrationInterface {
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<any> {
|
||||
await queryRunner.query(`CREATE TYPE "page_visibility_enum" AS ENUM('public', 'followers', 'specified')`);
|
||||
await queryRunner.query(`CREATE TABLE "page" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL, "title" character varying(256) NOT NULL, "name" character varying(256) NOT NULL, "summary" character varying(256), "alignCenter" boolean NOT NULL, "font" character varying(32) NOT NULL, "userId" character varying(32) NOT NULL, "eyeCatchingImageId" character varying(32), "content" jsonb NOT NULL DEFAULT '[]', "variables" jsonb NOT NULL DEFAULT '[]', "visibility" "page_visibility_enum" NOT NULL, "visibleUserIds" character varying(32) array NOT NULL DEFAULT '{}'::varchar[], CONSTRAINT "PK_742f4117e065c5b6ad21b37ba1f" PRIMARY KEY ("id"))`);
|
||||
await queryRunner.query(`CREATE INDEX "IDX_fbb4297c927a9b85e9cefa2eb1" ON "page" ("createdAt") `);
|
||||
await queryRunner.query(`CREATE INDEX "IDX_af639b066dfbca78b01a920f8a" ON "page" ("updatedAt") `);
|
||||
await queryRunner.query(`CREATE INDEX "IDX_b82c19c08afb292de4600d99e4" ON "page" ("name") `);
|
||||
await queryRunner.query(`CREATE INDEX "IDX_ae1d917992dd0c9d9bbdad06c4" ON "page" ("userId") `);
|
||||
await queryRunner.query(`CREATE INDEX "IDX_90148bbc2bf0854428786bfc15" ON "page" ("visibleUserIds") `);
|
||||
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_2133ef8317e4bdb839c0dcbf13" ON "page" ("userId", "name") `);
|
||||
await queryRunner.query(`ALTER TABLE "page" ADD CONSTRAINT "FK_ae1d917992dd0c9d9bbdad06c4a" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
|
||||
await queryRunner.query(`ALTER TABLE "page" ADD CONSTRAINT "FK_3126dd7c502c9e4d7597ef7ef10" FOREIGN KEY ("eyeCatchingImageId") REFERENCES "drive_file"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<any> {
|
||||
await queryRunner.query(`ALTER TABLE "page" DROP CONSTRAINT "FK_3126dd7c502c9e4d7597ef7ef10"`);
|
||||
await queryRunner.query(`ALTER TABLE "page" DROP CONSTRAINT "FK_ae1d917992dd0c9d9bbdad06c4a"`);
|
||||
await queryRunner.query(`DROP INDEX "IDX_2133ef8317e4bdb839c0dcbf13"`);
|
||||
await queryRunner.query(`DROP INDEX "IDX_90148bbc2bf0854428786bfc15"`);
|
||||
await queryRunner.query(`DROP INDEX "IDX_ae1d917992dd0c9d9bbdad06c4"`);
|
||||
await queryRunner.query(`DROP INDEX "IDX_b82c19c08afb292de4600d99e4"`);
|
||||
await queryRunner.query(`DROP INDEX "IDX_af639b066dfbca78b01a920f8a"`);
|
||||
await queryRunner.query(`DROP INDEX "IDX_fbb4297c927a9b85e9cefa2eb1"`);
|
||||
await queryRunner.query(`DROP TABLE "page"`);
|
||||
await queryRunner.query(`DROP TYPE "page_visibility_enum"`);
|
||||
}
|
||||
|
||||
}
|
23
migration/1556746559567-UserProfile.ts
Normal file
23
migration/1556746559567-UserProfile.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import {MigrationInterface, QueryRunner} from "typeorm";
|
||||
|
||||
export class UserProfile1556746559567 implements MigrationInterface {
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<any> {
|
||||
await queryRunner.query(`UPDATE "user_profile" SET github = FALSE`);
|
||||
await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "githubId"`);
|
||||
await queryRunner.query(`ALTER TABLE "user_profile" ADD COLUMN "githubId" VARCHAR(64)`);
|
||||
await queryRunner.query(`UPDATE "user_profile" SET discord = FALSE`);
|
||||
await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "discordExpiresDate"`);
|
||||
await queryRunner.query(`ALTER TABLE "user_profile" ADD COLUMN "discordExpiresDate" VARCHAR(64)`);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<any> {
|
||||
await queryRunner.query(`UPDATE "user_profile" SET github = FALSE`);
|
||||
await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "githubId"`);
|
||||
await queryRunner.query(`ALTER TABLE "user_profile" ADD COLUMN "githubId" INTEGER`);
|
||||
await queryRunner.query(`UPDATE "user_profile" SET discord = FALSE`);
|
||||
await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "discordExpiresDate"`);
|
||||
await queryRunner.query(`ALTER TABLE "user_profile" ADD COLUMN "discordExpiresDate" INTEGER`);
|
||||
}
|
||||
|
||||
}
|
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"`);
|
||||
}
|
||||
|
||||
}
|
16
migration/1557761316509-AddSomeUrls.ts
Normal file
16
migration/1557761316509-AddSomeUrls.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import {MigrationInterface, QueryRunner} from "typeorm";
|
||||
|
||||
export class AddSomeUrls1557761316509 implements MigrationInterface {
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<any> {
|
||||
await queryRunner.query(`ALTER TABLE "meta" ADD "ToSUrl" character varying(512)`);
|
||||
await queryRunner.query(`ALTER TABLE "meta" ADD "repositoryUrl" character varying(512) NOT NULL DEFAULT 'https://github.com/syuilo/misskey'`);
|
||||
await queryRunner.query(`ALTER TABLE "meta" ADD "feedbackUrl" character varying(512) DEFAULT 'https://github.com/syuilo/misskey/issues/new'`);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<any> {
|
||||
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "feedbackUrl"`);
|
||||
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "repositoryUrl"`);
|
||||
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "ToSUrl"`);
|
||||
}
|
||||
}
|
31
migration/1557932705754-ObjectStorageSetting.ts
Normal file
31
migration/1557932705754-ObjectStorageSetting.ts
Normal file
@ -0,0 +1,31 @@
|
||||
import {MigrationInterface, QueryRunner} from "typeorm";
|
||||
|
||||
export class ObjectStorageSetting1557932705754 implements MigrationInterface {
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<any> {
|
||||
await queryRunner.query(`ALTER TABLE "meta" ADD "useObjectStorage" boolean NOT NULL DEFAULT false`);
|
||||
await queryRunner.query(`ALTER TABLE "meta" ADD "objectStorageBucket" character varying(512)`);
|
||||
await queryRunner.query(`ALTER TABLE "meta" ADD "objectStoragePrefix" character varying(512)`);
|
||||
await queryRunner.query(`ALTER TABLE "meta" ADD "objectStorageBaseUrl" character varying(512)`);
|
||||
await queryRunner.query(`ALTER TABLE "meta" ADD "objectStorageEndpoint" character varying(512)`);
|
||||
await queryRunner.query(`ALTER TABLE "meta" ADD "objectStorageRegion" character varying(512)`);
|
||||
await queryRunner.query(`ALTER TABLE "meta" ADD "objectStorageAccessKey" character varying(512)`);
|
||||
await queryRunner.query(`ALTER TABLE "meta" ADD "objectStorageSecretKey" character varying(512)`);
|
||||
await queryRunner.query(`ALTER TABLE "meta" ADD "objectStoragePort" integer`);
|
||||
await queryRunner.query(`ALTER TABLE "meta" ADD "objectStorageUseSSL" boolean NOT NULL DEFAULT true`);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<any> {
|
||||
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "objectStorageUseSSL"`);
|
||||
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "objectStoragePort"`);
|
||||
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "objectStorageSecretKey"`);
|
||||
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "objectStorageAccessKey"`);
|
||||
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "objectStorageRegion"`);
|
||||
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "objectStorageEndpoint"`);
|
||||
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "objectStorageBaseUrl"`);
|
||||
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "objectStoragePrefix"`);
|
||||
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "objectStorageBucket"`);
|
||||
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "useObjectStorage"`);
|
||||
}
|
||||
|
||||
}
|
56
package.json
56
package.json
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "misskey",
|
||||
"author": "syuilo <i@syuilo.com>",
|
||||
"version": "11.2.2",
|
||||
"version": "11.14.0",
|
||||
"codename": "daybreak",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@ -12,6 +12,8 @@
|
||||
"scripts": {
|
||||
"start": "node ./index.js",
|
||||
"init": "node ./built/init.js",
|
||||
"ormconfig": "node ./built/ormconfig.js",
|
||||
"migrate": "npm run ormconfig && ts-node ./node_modules/typeorm/cli.js migration:run",
|
||||
"build": "webpack && gulp build",
|
||||
"webpack": "webpack",
|
||||
"watch": "webpack --watch",
|
||||
@ -23,20 +25,19 @@
|
||||
"format": "gulp format"
|
||||
},
|
||||
"dependencies": {
|
||||
"@elastic/elasticsearch": "7.0.0-rc.2",
|
||||
"@fortawesome/fontawesome-svg-core": "1.2.15",
|
||||
"@fortawesome/free-brands-svg-icons": "5.7.2",
|
||||
"@fortawesome/free-regular-svg-icons": "5.7.2",
|
||||
"@fortawesome/free-solid-svg-icons": "5.7.2",
|
||||
"@fortawesome/vue-fontawesome": "0.1.5",
|
||||
"@koa/cors": "2.2.3",
|
||||
"@prezzemolo/rap": "0.1.2",
|
||||
"@prezzemolo/zip": "0.0.3",
|
||||
"@types/bcryptjs": "2.4.2",
|
||||
"@types/bull": "3.5.11",
|
||||
"@types/dateformat": "3.0.0",
|
||||
"@types/deep-equal": "1.0.1",
|
||||
"@types/double-ended-queue": "2.1.0",
|
||||
"@types/elasticsearch": "5.0.32",
|
||||
"@types/file-type": "10.9.1",
|
||||
"@types/gulp": "4.0.6",
|
||||
"@types/gulp-mocha": "0.0.32",
|
||||
@ -64,8 +65,8 @@
|
||||
"@types/lolex": "3.1.1",
|
||||
"@types/minio": "7.0.1",
|
||||
"@types/mocha": "5.2.6",
|
||||
"@types/node": "11.13.4",
|
||||
"@types/nodemailer": "4.6.7",
|
||||
"@types/node": "11.13.8",
|
||||
"@types/nodemailer": "4.6.8",
|
||||
"@types/nprogress": "0.0.29",
|
||||
"@types/oauth": "0.9.1",
|
||||
"@types/parse5": "5.0.0",
|
||||
@ -78,9 +79,10 @@
|
||||
"@types/redis": "2.8.12",
|
||||
"@types/rename": "1.0.1",
|
||||
"@types/request": "2.48.1",
|
||||
"@types/request-promise-native": "1.0.15",
|
||||
"@types/request-promise-native": "1.0.16",
|
||||
"@types/request-stats": "3.0.0",
|
||||
"@types/rimraf": "2.0.2",
|
||||
"@types/seedrandom": "2.4.28",
|
||||
"@types/sharp": "0.22.1",
|
||||
"@types/showdown": "1.9.2",
|
||||
"@types/speakeasy": "2.0.4",
|
||||
@ -89,18 +91,18 @@
|
||||
"@types/tmp": "0.1.0",
|
||||
"@types/uuid": "3.4.4",
|
||||
"@types/web-push": "3.3.0",
|
||||
"@types/webpack": "4.4.27",
|
||||
"@types/webpack": "4.4.29",
|
||||
"@types/webpack-stream": "3.2.10",
|
||||
"@types/websocket": "0.0.40",
|
||||
"@types/ws": "6.0.1",
|
||||
"animejs": "3.0.1",
|
||||
"apexcharts": "3.6.8",
|
||||
"apexcharts": "3.6.11",
|
||||
"autobind-decorator": "2.4.0",
|
||||
"autosize": "4.0.2",
|
||||
"autwh": "0.1.0",
|
||||
"bcryptjs": "2.4.3",
|
||||
"bootstrap-vue": "2.0.0-rc.13",
|
||||
"bull": "3.7.0",
|
||||
"bull": "3.9.1",
|
||||
"cafy": "15.1.1",
|
||||
"chai": "4.2.0",
|
||||
"chalk": "2.4.2",
|
||||
@ -112,17 +114,16 @@
|
||||
"cssnano": "4.1.10",
|
||||
"dateformat": "3.0.3",
|
||||
"deep-equal": "1.0.1",
|
||||
"diskusage": "1.1.0",
|
||||
"diskusage": "1.1.1",
|
||||
"double-ended-queue": "2.1.0-0",
|
||||
"elasticsearch": "15.4.1",
|
||||
"emojilib": "2.4.0",
|
||||
"eslint": "5.16.0",
|
||||
"eslint-plugin-vue": "5.2.2",
|
||||
"eventemitter3": "3.1.0",
|
||||
"eventemitter3": "3.1.2",
|
||||
"feed": "2.0.4",
|
||||
"file-type": "10.11.0",
|
||||
"fuckadblock": "3.2.1",
|
||||
"gulp": "4.0.0",
|
||||
"gulp": "4.0.2",
|
||||
"gulp-cssnano": "2.1.3",
|
||||
"gulp-imagemin": "5.0.3",
|
||||
"gulp-mocha": "6.0.0",
|
||||
@ -141,7 +142,7 @@
|
||||
"is-root": "2.1.0",
|
||||
"is-svg": "4.1.0",
|
||||
"js-yaml": "3.13.1",
|
||||
"jsdom": "14.1.0",
|
||||
"jsdom": "15.1.0",
|
||||
"json5": "2.1.0",
|
||||
"json5-loader": "2.0.0",
|
||||
"katex": "0.10.1",
|
||||
@ -161,20 +162,20 @@
|
||||
"loader-utils": "1.2.3",
|
||||
"lolex": "3.1.0",
|
||||
"lookup-dns-cache": "2.1.0",
|
||||
"minio": "7.0.6",
|
||||
"mocha": "6.1.3",
|
||||
"minio": "7.0.8",
|
||||
"mocha": "6.1.4",
|
||||
"moji": "0.5.1",
|
||||
"moment": "2.24.0",
|
||||
"ms": "2.1.1",
|
||||
"nested-property": "0.0.7",
|
||||
"node-fetch": "2.3.0",
|
||||
"node-fetch": "2.5.0",
|
||||
"nodemailer": "6.1.1",
|
||||
"nprogress": "0.2.0",
|
||||
"object-assign-deep": "0.4.0",
|
||||
"os-utils": "0.0.14",
|
||||
"parse5": "5.1.0",
|
||||
"parsimmon": "1.12.0",
|
||||
"pg": "7.10.0",
|
||||
"pg": "7.11.0",
|
||||
"portscanner": "2.2.0",
|
||||
"postcss-loader": "3.0.0",
|
||||
"prismjs": "1.16.0",
|
||||
@ -201,7 +202,8 @@
|
||||
"rimraf": "2.6.3",
|
||||
"rndstr": "1.0.0",
|
||||
"s-age": "1.1.2",
|
||||
"sharp": "0.22.0",
|
||||
"seedrandom": "3.0.1",
|
||||
"sharp": "0.22.1",
|
||||
"showdown": "1.9.0",
|
||||
"showdown-highlightjs-extension": "0.1.2",
|
||||
"speakeasy": "2.0.0",
|
||||
@ -210,7 +212,7 @@
|
||||
"stylus": "0.54.5",
|
||||
"stylus-loader": "3.0.2",
|
||||
"summaly": "2.2.0",
|
||||
"systeminformation": "4.1.5",
|
||||
"systeminformation": "4.1.6",
|
||||
"syuilo-password-strength": "0.0.1",
|
||||
"terser-webpack-plugin": "1.2.3",
|
||||
"textarea-caret": "3.1.0",
|
||||
@ -234,8 +236,8 @@
|
||||
"vue-color": "2.7.0",
|
||||
"vue-content-loading": "1.6.0",
|
||||
"vue-cropperjs": "3.0.0",
|
||||
"vue-i18n": "8.10.0",
|
||||
"vue-js-modal": "1.3.28",
|
||||
"vue-i18n": "8.11.2",
|
||||
"vue-js-modal": "1.3.31",
|
||||
"vue-json-pretty": "1.6.0",
|
||||
"vue-loader": "15.7.0",
|
||||
"vue-marquee-text-component": "1.1.1",
|
||||
@ -247,13 +249,13 @@
|
||||
"vue-template-compiler": "2.6.10",
|
||||
"vuedraggable": "2.20.0",
|
||||
"vuewordcloud": "18.7.11",
|
||||
"vuex": "3.1.0",
|
||||
"vuex": "3.1.1",
|
||||
"vuex-persistedstate": "2.5.4",
|
||||
"web-push": "3.3.3",
|
||||
"webpack": "4.30.0",
|
||||
"webpack-cli": "3.3.0",
|
||||
"web-push": "3.3.4",
|
||||
"webpack": "4.31.0",
|
||||
"webpack-cli": "3.3.2",
|
||||
"websocket": "1.0.28",
|
||||
"ws": "6.2.1",
|
||||
"ws": "7.0.0",
|
||||
"xev": "2.0.1"
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ function greet() {
|
||||
console.log(' ' + chalk.gray(v) + (' |___|\n'.substr(v.length)));
|
||||
//#endregion
|
||||
|
||||
console.log(' Misskey is maintained by @syuilo, @AyaMorisawa, @mei23, and @acid-chicken.');
|
||||
console.log(' Misskey is maintained by @syuilo, @AyaMorisawa, @mei23, @acid-chicken, and @rinsuki.');
|
||||
console.log(chalk.keyword('orange')(' If you like Misskey, please donate to support development. https://www.patreon.com/syuilo'));
|
||||
|
||||
console.log('');
|
||||
|
@ -9,6 +9,9 @@
|
||||
<ui-textarea v-model="announcement.text">
|
||||
<span>{{ $t('text') }}</span>
|
||||
</ui-textarea>
|
||||
<ui-input v-model="announcement.image">
|
||||
<span>{{ $t('image-url') }}</span>
|
||||
</ui-input>
|
||||
<ui-horizon-group class="fit-bottom">
|
||||
<ui-button @click="save()"><fa :icon="['far', 'save']"/> {{ $t('save') }}</ui-button>
|
||||
<ui-button @click="remove(i)"><fa :icon="['far', 'trash-alt']"/> {{ $t('remove') }}</ui-button>
|
||||
@ -43,7 +46,8 @@ export default Vue.extend({
|
||||
add() {
|
||||
this.announcements.unshift({
|
||||
title: '',
|
||||
text: ''
|
||||
text: '',
|
||||
image: null
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -54,7 +54,6 @@
|
||||
<span>{{ $t('latest-request-received-at') }}</span>
|
||||
<template #prefix><fa :icon="faInbox"/></template>
|
||||
</ui-input>
|
||||
<ui-switch v-model="instance.isBlocked" @change="updateInstance()">{{ $t('block') }}</ui-switch>
|
||||
<ui-switch v-model="instance.isMarkedAsClosed" @change="updateInstance()">{{ $t('marked-as-closed') }}</ui-switch>
|
||||
<details>
|
||||
<summary>{{ $t('charts') }}</summary>
|
||||
@ -79,6 +78,10 @@
|
||||
</ui-horizon-group>
|
||||
<div ref="chart"></div>
|
||||
</details>
|
||||
<details>
|
||||
<summary>{{ $t('delete-all-files') }}</summary>
|
||||
<ui-button @click="deleteAllFiles()" style="margin-top: 16px;"><fa :icon="faTrashAlt"/> {{ $t('delete-all-files') }}</ui-button>
|
||||
</details>
|
||||
<details>
|
||||
<summary>{{ $t('remove-all-following') }}</summary>
|
||||
<ui-button @click="removeAllFollowing()" style="margin-top: 16px;"><fa :icon="faMinusCircle"/> {{ $t('remove-all-following') }}</ui-button>
|
||||
@ -130,7 +133,7 @@
|
||||
<span>{{ $t('status') }}</span>
|
||||
</header>
|
||||
<div v-for="instance in instances" :style="{ opacity: instance.isNotResponding ? 0.5 : 1 }">
|
||||
<a @click.prevent="showInstance(instance.host)" target="_blank" :href="`https://${instance.host}`" :style="{ textDecoration: instance.isMarkedAsClosed ? 'line-through' : 'none' }">{{ instance.host }}</a>
|
||||
<a @click.prevent="showInstance(instance.host)" rel="nofollow noopener" target="_blank" :href="`https://${instance.host}`" :style="{ textDecoration: instance.isMarkedAsClosed ? 'line-through' : 'none' }">{{ instance.host }}</a>
|
||||
<span>{{ instance.notesCount | number }}</span>
|
||||
<span>{{ instance.usersCount | number }}</span>
|
||||
<span>{{ instance.followingCount | number }}</span>
|
||||
@ -142,6 +145,16 @@
|
||||
<ui-info v-if="instances.length == limit">{{ $t('result-is-truncated', { n: limit }) }}</ui-info>
|
||||
</section>
|
||||
</ui-card>
|
||||
|
||||
<ui-card>
|
||||
<template #title><fa :icon="faBan"/> {{ $t('blocked-hosts') }}</template>
|
||||
<section class="fit-top">
|
||||
<ui-textarea v-model="blockedHosts">
|
||||
<template #desc>{{ $t('blocked-hosts-info') }}</template>
|
||||
</ui-textarea>
|
||||
<ui-button @click="saveBlockedHosts">{{ $t('save') }}</ui-button>
|
||||
</section>
|
||||
</ui-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -149,7 +162,7 @@
|
||||
import Vue from 'vue';
|
||||
import i18n from '../../i18n';
|
||||
import { faPaperPlane } from '@fortawesome/free-regular-svg-icons';
|
||||
import { faGlobe, faTerminal, faSearch, faMinusCircle, faServer, faCrosshairs, faEnvelopeOpenText, faUsers, faCaretDown, faCaretUp, faTrafficLight, faInbox } from '@fortawesome/free-solid-svg-icons';
|
||||
import { faTrashAlt, faBan, faGlobe, faTerminal, faSearch, faMinusCircle, faServer, faCrosshairs, faEnvelopeOpenText, faUsers, faCaretDown, faCaretUp, faTrafficLight, faInbox } from '@fortawesome/free-solid-svg-icons';
|
||||
import ApexCharts from 'apexcharts';
|
||||
import * as tinycolor from 'tinycolor2';
|
||||
|
||||
@ -176,7 +189,8 @@ export default Vue.extend({
|
||||
chartSrc: 'requests',
|
||||
chartSpan: 'hour',
|
||||
chartInstance: null,
|
||||
faGlobe, faTerminal, faSearch, faMinusCircle, faServer, faCrosshairs, faEnvelopeOpenText, faUsers, faCaretDown, faCaretUp, faPaperPlane, faTrafficLight, faInbox
|
||||
blockedHosts: '',
|
||||
faTrashAlt, faBan, faGlobe, faTerminal, faSearch, faMinusCircle, faServer, faCrosshairs, faEnvelopeOpenText, faUsers, faCaretDown, faCaretUp, faPaperPlane, faTrafficLight, faInbox
|
||||
};
|
||||
},
|
||||
|
||||
@ -246,6 +260,10 @@ export default Vue.extend({
|
||||
|
||||
mounted() {
|
||||
this.fetchInstances();
|
||||
|
||||
this.$root.getMeta().then(meta => {
|
||||
this.blockedHosts = meta.blockedHosts.join('\n');
|
||||
});
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
@ -293,6 +311,17 @@ export default Vue.extend({
|
||||
});
|
||||
},
|
||||
|
||||
deleteAllFiles() {
|
||||
this.$root.api('admin/federation/delete-all-files', {
|
||||
host: this.instance.host
|
||||
}).then(() => {
|
||||
this.$root.dialog({
|
||||
type: 'success',
|
||||
splash: true
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
updateInstance() {
|
||||
this.$root.api('admin/federation/update-instance', {
|
||||
host: this.instance.host,
|
||||
@ -477,6 +506,22 @@ export default Vue.extend({
|
||||
}]
|
||||
};
|
||||
},
|
||||
|
||||
saveBlockedHosts() {
|
||||
this.$root.api('admin/update-meta', {
|
||||
blockedHosts: this.blockedHosts.split('\n')
|
||||
}).then(() => {
|
||||
this.$root.dialog({
|
||||
type: 'success',
|
||||
text: this.$t('saved')
|
||||
});
|
||||
}).catch(e => {
|
||||
this.$root.dialog({
|
||||
type: 'error',
|
||||
text: e
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
@ -1,41 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<ui-card>
|
||||
<template #title>{{ $t('hided-tags') }}</template>
|
||||
<section>
|
||||
<textarea class="jdnqwkzlnxcfftthoybjxrebyolvoucw" v-model="hiddenTags"></textarea>
|
||||
<ui-button @click="save">{{ $t('save') }}</ui-button>
|
||||
</section>
|
||||
</ui-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import i18n from '../../i18n';
|
||||
|
||||
export default Vue.extend({
|
||||
i18n: i18n('admin/views/hashtags.vue'),
|
||||
data() {
|
||||
return {
|
||||
hiddenTags: '',
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.$root.getMeta().then(meta => {
|
||||
this.hiddenTags = meta.hiddenTags.join('\n');
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
save() {
|
||||
this.$root.api('admin/update-meta', {
|
||||
hiddenTags: this.hiddenTags.split('\n')
|
||||
}).then(() => {
|
||||
//this.$root.os.apis.dialog({ text: `Saved` });
|
||||
}).catch(e => {
|
||||
//this.$root.os.apis.dialog({ text: `Failed ${e}` });
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
@ -28,7 +28,6 @@
|
||||
<li @click="nav('federation')" :class="{ active: page == 'federation' }"><fa :icon="faGlobe" fixed-width/>{{ $t('federation') }}</li>
|
||||
<li @click="nav('emoji')" :class="{ active: page == 'emoji' }"><fa :icon="faGrin" fixed-width/>{{ $t('emoji') }}</li>
|
||||
<li @click="nav('announcements')" :class="{ active: page == 'announcements' }"><fa icon="broadcast-tower" fixed-width/>{{ $t('announcements') }}</li>
|
||||
<li @click="nav('hashtags')" :class="{ active: page == 'hashtags' }"><fa icon="hashtag" fixed-width/>{{ $t('hashtags') }}</li>
|
||||
<li @click="nav('abuse')" :class="{ active: page == 'abuse' }"><fa :icon="faExclamationCircle" fixed-width/>{{ $t('abuse') }}</li>
|
||||
</ul>
|
||||
<div class="back-to-misskey">
|
||||
@ -48,7 +47,6 @@
|
||||
<div v-if="page == 'users'"><x-users/></div>
|
||||
<div v-if="page == 'emoji'"><x-emoji/></div>
|
||||
<div v-if="page == 'announcements'"><x-announcements/></div>
|
||||
<div v-if="page == 'hashtags'"><x-hashtags/></div>
|
||||
<div v-if="page == 'drive'"><x-drive/></div>
|
||||
<div v-if="page == 'federation'"><x-federation/></div>
|
||||
<div v-if="page == 'abuse'"><x-abuse/></div>
|
||||
@ -68,7 +66,6 @@ import XLogs from "./logs.vue";
|
||||
import XModerators from "./moderators.vue";
|
||||
import XEmoji from "./emoji.vue";
|
||||
import XAnnouncements from "./announcements.vue";
|
||||
import XHashtags from "./hashtags.vue";
|
||||
import XUsers from "./users.vue";
|
||||
import XDrive from "./drive.vue";
|
||||
import XAbuse from "./abuse.vue";
|
||||
@ -91,7 +88,6 @@ export default Vue.extend({
|
||||
XModerators,
|
||||
XEmoji,
|
||||
XAnnouncements,
|
||||
XHashtags,
|
||||
XUsers,
|
||||
XDrive,
|
||||
XAbuse,
|
||||
|
@ -2,7 +2,7 @@
|
||||
<div>
|
||||
<ui-card>
|
||||
<template #title><fa icon="cog"/> {{ $t('instance') }}</template>
|
||||
<section class="fit-top fit-bottom">
|
||||
<section class="fit-top">
|
||||
<ui-input :value="host" readonly>{{ $t('host') }}</ui-input>
|
||||
<ui-input v-model="name">{{ $t('instance-name') }}</ui-input>
|
||||
<ui-textarea v-model="description">{{ $t('instance-description') }}</ui-textarea>
|
||||
@ -10,124 +10,229 @@
|
||||
<ui-input v-model="mascotImageUrl"><template #icon><fa icon="link"/></template>{{ $t('logo-url') }}</ui-input>
|
||||
<ui-input v-model="bannerUrl"><template #icon><fa icon="link"/></template>{{ $t('banner-url') }}</ui-input>
|
||||
<ui-input v-model="errorImageUrl"><template #icon><fa icon="link"/></template>{{ $t('error-image-url') }}</ui-input>
|
||||
<ui-input v-model="ToSUrl"><template #icon><fa icon="link"/></template>{{ $t('tos-url') }}</ui-input>
|
||||
<ui-input v-model="languages"><template #icon><fa icon="language"/></template>{{ $t('languages') }}<template #desc>{{ $t('languages-desc') }}</template></ui-input>
|
||||
<details>
|
||||
<summary>{{ $t('advanced-config') }}</summary>
|
||||
<ui-input v-model="repositoryUrl"><template #icon><fa icon="link"/></template>{{ $t('repository-url') }}</ui-input>
|
||||
<ui-input v-model="feedbackUrl"><template #icon><fa icon="link"/></template>{{ $t('feedback-url') }}</ui-input>
|
||||
</details>
|
||||
</section>
|
||||
<section class="fit-bottom">
|
||||
<header><fa :icon="faHeadset"/> {{ $t('maintainer-config') }}</header>
|
||||
<ui-input v-model="maintainerName">{{ $t('maintainer-name') }}</ui-input>
|
||||
<ui-input v-model="maintainerEmail" type="email"><template #icon><fa :icon="farEnvelope"/></template>{{ $t('maintainer-email') }}</ui-input>
|
||||
</section>
|
||||
<section>
|
||||
<ui-switch v-model="disableRegistration">{{ $t('disable-registration') }}</ui-switch>
|
||||
<ui-button v-if="disableRegistration" @click="invite">{{ $t('invite') }}</ui-button>
|
||||
</section>
|
||||
<section>
|
||||
<ui-button @click="updateMeta"><fa :icon="faSave"/> {{ $t('save') }}</ui-button>
|
||||
</section>
|
||||
</ui-card>
|
||||
|
||||
<ui-card>
|
||||
<template #title><fa :icon="faPencilAlt"/> {{ $t('note-and-tl') }}</template>
|
||||
<section class="fit-top fit-bottom">
|
||||
<ui-input v-model="maxNoteTextLength">{{ $t('max-note-text-length') }}</ui-input>
|
||||
</section>
|
||||
<section>
|
||||
<ui-switch v-model="disableRegistration">{{ $t('disable-registration') }}</ui-switch>
|
||||
<ui-switch v-model="disableLocalTimeline">{{ $t('disable-local-timeline') }}</ui-switch>
|
||||
<ui-switch v-model="disableGlobalTimeline">{{ $t('disable-global-timeline') }}</ui-switch>
|
||||
<ui-info>{{ $t('disabling-timelines-info') }}</ui-info>
|
||||
</section>
|
||||
<section>
|
||||
<ui-switch v-model="enableEmojiReaction">{{ $t('enable-emoji-reaction') }}</ui-switch>
|
||||
<ui-switch v-model="useStarForReactionFallback">{{ $t('use-star-for-reaction-fallback') }}</ui-switch>
|
||||
</section>
|
||||
<section class="fit-bottom">
|
||||
<header><fa icon="cloud"/> {{ $t('drive-config') }}</header>
|
||||
<section>
|
||||
<ui-button @click="updateMeta"><fa :icon="faSave"/> {{ $t('save') }}</ui-button>
|
||||
</section>
|
||||
</ui-card>
|
||||
|
||||
<ui-card>
|
||||
<template #title><fa icon="cloud"/> {{ $t('drive-config') }}</template>
|
||||
<section>
|
||||
<ui-switch v-model="useObjectStorage">{{ $t('use-object-storage') }}</ui-switch>
|
||||
<template v-if="useObjectStorage">
|
||||
<ui-info>
|
||||
<i18n path="object-storage-s3-info">
|
||||
<a href="https://docs.aws.amazon.com/general/latest/gr/rande.html" target="_blank">{{ $t('object-storage-s3-info-here') }}</a>
|
||||
</i18n>
|
||||
</ui-info>
|
||||
<ui-info>{{ $t('object-storage-gcs-info') }}</ui-info>
|
||||
<ui-input v-model="objectStorageBaseUrl" :disabled="!useObjectStorage">{{ $t('object-storage-base-url') }}</ui-input>
|
||||
<ui-horizon-group inputs>
|
||||
<ui-input v-model="objectStorageBucket" :disabled="!useObjectStorage">{{ $t('object-storage-bucket') }}</ui-input>
|
||||
<ui-input v-model="objectStoragePrefix" :disabled="!useObjectStorage">{{ $t('object-storage-prefix') }}</ui-input>
|
||||
</ui-horizon-group>
|
||||
<ui-input v-model="objectStorageEndpoint" :disabled="!useObjectStorage">{{ $t('object-storage-endpoint') }}</ui-input>
|
||||
<ui-horizon-group inputs>
|
||||
<ui-input v-model="objectStorageRegion" :disabled="!useObjectStorage">{{ $t('object-storage-region') }}</ui-input>
|
||||
<ui-input v-model="objectStoragePort" type="number" :disabled="!useObjectStorage">{{ $t('object-storage-port') }}</ui-input>
|
||||
</ui-horizon-group>
|
||||
<ui-horizon-group inputs>
|
||||
<ui-input v-model="objectStorageAccessKey" :disabled="!useObjectStorage"><template #icon><fa icon="key"/></template>{{ $t('object-storage-access-key') }}</ui-input>
|
||||
<ui-input v-model="objectStorageSecretKey" :disabled="!useObjectStorage"><template #icon><fa icon="key"/></template>{{ $t('object-storage-secret-key') }}</ui-input>
|
||||
</ui-horizon-group>
|
||||
<ui-switch v-model="objectStorageUseSSL" :disabled="!useObjectStorage">{{ $t('object-storage-use-ssl') }}</ui-switch>
|
||||
</template>
|
||||
</section>
|
||||
<section>
|
||||
<ui-switch v-model="cacheRemoteFiles">{{ $t('cache-remote-files') }}<template #desc>{{ $t('cache-remote-files-desc') }}</template></ui-switch>
|
||||
</section>
|
||||
<section class="fit-top fit-bottom">
|
||||
<ui-input v-model="localDriveCapacityMb" type="number">{{ $t('local-drive-capacity-mb') }}<template #suffix>MB</template><template #desc>{{ $t('mb') }}</template></ui-input>
|
||||
<ui-input v-model="remoteDriveCapacityMb" type="number" :disabled="!cacheRemoteFiles">{{ $t('remote-drive-capacity-mb') }}<template #suffix>MB</template><template #desc>{{ $t('mb') }}</template></ui-input>
|
||||
</section>
|
||||
<section class="fit-bottom">
|
||||
<header><fa :icon="faShieldAlt"/> {{ $t('recaptcha-config') }}</header>
|
||||
<ui-switch v-model="enableRecaptcha">{{ $t('enable-recaptcha') }}</ui-switch>
|
||||
<ui-info>{{ $t('recaptcha-info') }}</ui-info>
|
||||
<ui-horizon-group inputs>
|
||||
<ui-input v-model="recaptchaSiteKey" :disabled="!enableRecaptcha"><template #icon><fa icon="key"/></template>{{ $t('recaptcha-site-key') }}</ui-input>
|
||||
<ui-input v-model="recaptchaSecretKey" :disabled="!enableRecaptcha"><template #icon><fa icon="key"/></template>{{ $t('recaptcha-secret-key') }}</ui-input>
|
||||
</ui-horizon-group>
|
||||
</section>
|
||||
<section>
|
||||
<header><fa :icon="faGhost"/> {{ $t('proxy-account-config') }}</header>
|
||||
<ui-button @click="updateMeta"><fa :icon="faSave"/> {{ $t('save') }}</ui-button>
|
||||
</section>
|
||||
</ui-card>
|
||||
|
||||
<ui-card>
|
||||
<template #title><fa :icon="faThumbtack"/> {{ $t('pinned-users') }}</template>
|
||||
<section class="fit-top">
|
||||
<ui-textarea v-model="pinnedUsers">
|
||||
<template #desc>{{ $t('pinned-users-info') }}</template>
|
||||
</ui-textarea>
|
||||
<ui-button @click="updateMeta"><fa :icon="faSave"/> {{ $t('save') }}</ui-button>
|
||||
</section>
|
||||
</ui-card>
|
||||
|
||||
<ui-card>
|
||||
<template #title><fa :icon="faGhost"/> {{ $t('proxy-account-config') }}</template>
|
||||
<section>
|
||||
<ui-info>{{ $t('proxy-account-info') }}</ui-info>
|
||||
<ui-input v-model="proxyAccount"><template #prefix>@</template>{{ $t('proxy-account-username') }}<template #desc>{{ $t('proxy-account-username-desc') }}</template></ui-input>
|
||||
<ui-info warn>{{ $t('proxy-account-warn') }}</ui-info>
|
||||
</section>
|
||||
<section>
|
||||
<header><fa :icon="farEnvelope"/> {{ $t('email-config') }}</header>
|
||||
<ui-button @click="updateMeta"><fa :icon="faSave"/> {{ $t('save') }}</ui-button>
|
||||
</section>
|
||||
</ui-card>
|
||||
|
||||
<ui-card>
|
||||
<template #title><fa :icon="farEnvelope"/> {{ $t('email-config') }}</template>
|
||||
<section>
|
||||
<ui-switch v-model="enableEmail">{{ $t('enable-email') }}<template #desc>{{ $t('email-config-info') }}</template></ui-switch>
|
||||
<ui-input v-model="email" type="email" :disabled="!enableEmail">{{ $t('email') }}</ui-input>
|
||||
<ui-horizon-group inputs>
|
||||
<ui-input v-model="smtpHost" :disabled="!enableEmail">{{ $t('smtp-host') }}</ui-input>
|
||||
<ui-input v-model="smtpPort" type="number" :disabled="!enableEmail">{{ $t('smtp-port') }}</ui-input>
|
||||
</ui-horizon-group>
|
||||
<ui-switch v-model="smtpAuth">{{ $t('smtp-auth') }}</ui-switch>
|
||||
<ui-horizon-group inputs>
|
||||
<ui-input v-model="smtpUser" :disabled="!enableEmail || !smtpAuth">{{ $t('smtp-user') }}</ui-input>
|
||||
<ui-input v-model="smtpPass" type="password" :withPasswordToggle="true" :disabled="!enableEmail || !smtpAuth">{{ $t('smtp-pass') }}</ui-input>
|
||||
</ui-horizon-group>
|
||||
<ui-switch v-model="smtpSecure" :disabled="!enableEmail">{{ $t('smtp-secure') }}<template #desc>{{ $t('smtp-secure-info') }}</template></ui-switch>
|
||||
<template v-if="enableEmail">
|
||||
<ui-input v-model="email" type="email" :disabled="!enableEmail">{{ $t('email') }}</ui-input>
|
||||
<ui-horizon-group inputs>
|
||||
<ui-input v-model="smtpHost" :disabled="!enableEmail">{{ $t('smtp-host') }}</ui-input>
|
||||
<ui-input v-model="smtpPort" type="number" :disabled="!enableEmail">{{ $t('smtp-port') }}</ui-input>
|
||||
</ui-horizon-group>
|
||||
<ui-switch v-model="smtpAuth">{{ $t('smtp-auth') }}</ui-switch>
|
||||
<ui-horizon-group inputs>
|
||||
<ui-input v-model="smtpUser" :disabled="!enableEmail || !smtpAuth">{{ $t('smtp-user') }}</ui-input>
|
||||
<ui-input v-model="smtpPass" type="password" :with-password-toggle="true" :disabled="!enableEmail || !smtpAuth">{{ $t('smtp-pass') }}</ui-input>
|
||||
</ui-horizon-group>
|
||||
<ui-switch v-model="smtpSecure" :disabled="!enableEmail">{{ $t('smtp-secure') }}<template #desc>{{ $t('smtp-secure-info') }}</template></ui-switch>
|
||||
</template>
|
||||
</section>
|
||||
<section>
|
||||
<header><fa :icon="faBolt"/> {{ $t('serviceworker-config') }}</header>
|
||||
<ui-button @click="updateMeta"><fa :icon="faSave"/> {{ $t('save') }}</ui-button>
|
||||
</section>
|
||||
</ui-card>
|
||||
|
||||
<ui-card>
|
||||
<template #title><fa :icon="faBolt"/> {{ $t('serviceworker-config') }}</template>
|
||||
<section>
|
||||
<ui-switch v-model="enableServiceWorker">{{ $t('enable-serviceworker') }}<template #desc>{{ $t('serviceworker-info') }}</template></ui-switch>
|
||||
<ui-info>{{ $t('vapid-info') }}<br><code>npm i web-push -g<br>web-push generate-vapid-keys</code></ui-info>
|
||||
<ui-horizon-group inputs class="fit-bottom">
|
||||
<ui-input v-model="swPublicKey" :disabled="!enableServiceWorker"><template #icon><fa icon="key"/></template>{{ $t('vapid-publickey') }}</ui-input>
|
||||
<ui-input v-model="swPrivateKey" :disabled="!enableServiceWorker"><template #icon><fa icon="key"/></template>{{ $t('vapid-privatekey') }}</ui-input>
|
||||
</ui-horizon-group>
|
||||
<template v-if="enableServiceWorker">
|
||||
<ui-info>{{ $t('vapid-info') }}<br><code>npm i web-push -g<br>web-push generate-vapid-keys</code></ui-info>
|
||||
<ui-horizon-group inputs class="fit-bottom">
|
||||
<ui-input v-model="swPublicKey" :disabled="!enableServiceWorker"><template #icon><fa icon="key"/></template>{{ $t('vapid-publickey') }}</ui-input>
|
||||
<ui-input v-model="swPrivateKey" :disabled="!enableServiceWorker"><template #icon><fa icon="key"/></template>{{ $t('vapid-privatekey') }}</ui-input>
|
||||
</ui-horizon-group>
|
||||
</template>
|
||||
</section>
|
||||
<section>
|
||||
<header>summaly Proxy</header>
|
||||
<ui-input v-model="summalyProxy">URL</ui-input>
|
||||
</section>
|
||||
<section>
|
||||
<ui-button @click="updateMeta">{{ $t('save') }}</ui-button>
|
||||
<ui-button @click="updateMeta"><fa :icon="faSave"/> {{ $t('save') }}</ui-button>
|
||||
</section>
|
||||
</ui-card>
|
||||
|
||||
<ui-card>
|
||||
<template #title>{{ $t('invite') }}</template>
|
||||
<template #title><fa :icon="faShieldAlt"/> {{ $t('recaptcha-config') }}</template>
|
||||
<section :class="enableRecaptcha ? 'fit-bottom' : ''">
|
||||
<ui-switch v-model="enableRecaptcha">{{ $t('enable-recaptcha') }}</ui-switch>
|
||||
<template v-if="enableRecaptcha">
|
||||
<ui-info>{{ $t('recaptcha-info') }}</ui-info>
|
||||
<ui-horizon-group inputs>
|
||||
<ui-input v-model="recaptchaSiteKey" :disabled="!enableRecaptcha"><template #icon><fa icon="key"/></template>{{ $t('recaptcha-site-key') }}</ui-input>
|
||||
<ui-input v-model="recaptchaSecretKey" :disabled="!enableRecaptcha"><template #icon><fa icon="key"/></template>{{ $t('recaptcha-secret-key') }}</ui-input>
|
||||
</ui-horizon-group>
|
||||
</template>
|
||||
</section>
|
||||
<section>
|
||||
<ui-button @click="invite">{{ $t('invite') }}</ui-button>
|
||||
<p v-if="inviteCode">Code: <code>{{ inviteCode }}</code></p>
|
||||
<ui-button @click="updateMeta"><fa :icon="faSave"/> {{ $t('save') }}</ui-button>
|
||||
</section>
|
||||
</ui-card>
|
||||
|
||||
<ui-card>
|
||||
<template #title><fa :icon="['fab', 'twitter']"/> {{ $t('twitter-integration-config') }}</template>
|
||||
<template #title><fa :icon="faShieldAlt"/> {{ $t('external-service-integration-config') }}</template>
|
||||
<section>
|
||||
<header><fa :icon="['fab', 'twitter']"/> {{ $t('twitter-integration-config') }}</header>
|
||||
<ui-switch v-model="enableTwitterIntegration">{{ $t('enable-twitter-integration') }}</ui-switch>
|
||||
<ui-horizon-group>
|
||||
<ui-input v-model="twitterConsumerKey" :disabled="!enableTwitterIntegration"><template #icon><fa icon="key"/></template>{{ $t('twitter-integration-consumer-key') }}</ui-input>
|
||||
<ui-input v-model="twitterConsumerSecret" :disabled="!enableTwitterIntegration"><template #icon><fa icon="key"/></template>{{ $t('twitter-integration-consumer-secret') }}</ui-input>
|
||||
</ui-horizon-group>
|
||||
<ui-info>{{ $t('twitter-integration-info', { url: `${url}/api/tw/cb` }) }}</ui-info>
|
||||
<ui-button @click="updateMeta">{{ $t('save') }}</ui-button>
|
||||
<template v-if="enableTwitterIntegration">
|
||||
<ui-horizon-group>
|
||||
<ui-input v-model="twitterConsumerKey" :disabled="!enableTwitterIntegration"><template #icon><fa icon="key"/></template>{{ $t('twitter-integration-consumer-key') }}</ui-input>
|
||||
<ui-input v-model="twitterConsumerSecret" :disabled="!enableTwitterIntegration"><template #icon><fa icon="key"/></template>{{ $t('twitter-integration-consumer-secret') }}</ui-input>
|
||||
</ui-horizon-group>
|
||||
<ui-info>{{ $t('twitter-integration-info', { url: `${url}/api/tw/cb` }) }}</ui-info>
|
||||
</template>
|
||||
</section>
|
||||
</ui-card>
|
||||
|
||||
<ui-card>
|
||||
<template #title><fa :icon="['fab', 'github']"/> {{ $t('github-integration-config') }}</template>
|
||||
<section>
|
||||
<header><fa :icon="['fab', 'github']"/> {{ $t('github-integration-config') }}</header>
|
||||
<ui-switch v-model="enableGithubIntegration">{{ $t('enable-github-integration') }}</ui-switch>
|
||||
<ui-horizon-group>
|
||||
<ui-input v-model="githubClientId" :disabled="!enableGithubIntegration"><template #icon><fa icon="key"/></template>{{ $t('github-integration-client-id') }}</ui-input>
|
||||
<ui-input v-model="githubClientSecret" :disabled="!enableGithubIntegration"><template #icon><fa icon="key"/></template>{{ $t('github-integration-client-secret') }}</ui-input>
|
||||
</ui-horizon-group>
|
||||
<ui-info>{{ $t('github-integration-info', { url: `${url}/api/gh/cb` }) }}</ui-info>
|
||||
<ui-button @click="updateMeta">{{ $t('save') }}</ui-button>
|
||||
<template v-if="enableGithubIntegration">
|
||||
<ui-horizon-group>
|
||||
<ui-input v-model="githubClientId" :disabled="!enableGithubIntegration"><template #icon><fa icon="key"/></template>{{ $t('github-integration-client-id') }}</ui-input>
|
||||
<ui-input v-model="githubClientSecret" :disabled="!enableGithubIntegration"><template #icon><fa icon="key"/></template>{{ $t('github-integration-client-secret') }}</ui-input>
|
||||
</ui-horizon-group>
|
||||
<ui-info>{{ $t('github-integration-info', { url: `${url}/api/gh/cb` }) }}</ui-info>
|
||||
</template>
|
||||
</section>
|
||||
<section>
|
||||
<header><fa :icon="['fab', 'discord']"/> {{ $t('discord-integration-config') }}</header>
|
||||
<ui-switch v-model="enableDiscordIntegration">{{ $t('enable-discord-integration') }}</ui-switch>
|
||||
<template v-if="enableDiscordIntegration">
|
||||
<ui-horizon-group>
|
||||
<ui-input v-model="discordClientId" :disabled="!enableDiscordIntegration"><template #icon><fa icon="key"/></template>{{ $t('discord-integration-client-id') }}</ui-input>
|
||||
<ui-input v-model="discordClientSecret" :disabled="!enableDiscordIntegration"><template #icon><fa icon="key"/></template>{{ $t('discord-integration-client-secret') }}</ui-input>
|
||||
</ui-horizon-group>
|
||||
<ui-info>{{ $t('discord-integration-info', { url: `${url}/api/dc/cb` }) }}</ui-info>
|
||||
</template>
|
||||
</section>
|
||||
<section>
|
||||
<ui-button @click="updateMeta"><fa :icon="faSave"/> {{ $t('save') }}</ui-button>
|
||||
</section>
|
||||
</ui-card>
|
||||
|
||||
<ui-card>
|
||||
<template #title><fa :icon="['fab', 'discord']"/> {{ $t('discord-integration-config') }}</template>
|
||||
<section>
|
||||
<ui-switch v-model="enableDiscordIntegration">{{ $t('enable-discord-integration') }}</ui-switch>
|
||||
<ui-horizon-group>
|
||||
<ui-input v-model="discordClientId" :disabled="!enableDiscordIntegration"><template #icon><fa icon="key"/></template>{{ $t('discord-integration-client-id') }}</ui-input>
|
||||
<ui-input v-model="discordClientSecret" :disabled="!enableDiscordIntegration"><template #icon><fa icon="key"/></template>{{ $t('discord-integration-client-secret') }}</ui-input>
|
||||
</ui-horizon-group>
|
||||
<ui-info>{{ $t('discord-integration-info', { url: `${url}/api/dc/cb` }) }}</ui-info>
|
||||
<ui-button @click="updateMeta">{{ $t('save') }}</ui-button>
|
||||
</section>
|
||||
</ui-card>
|
||||
<details>
|
||||
<summary style="color:var(--text);">{{ $t('advanced-config') }}</summary>
|
||||
|
||||
<ui-card>
|
||||
<template #title><fa :icon="faHashtag"/> {{ $t('hidden-tags') }}</template>
|
||||
<section class="fit-top">
|
||||
<ui-textarea v-model="hiddenTags">
|
||||
<template #desc>{{ $t('hidden-tags-info') }}</template>
|
||||
</ui-textarea>
|
||||
<ui-button @click="updateMeta"><fa :icon="faSave"/> {{ $t('save') }}</ui-button>
|
||||
</section>
|
||||
</ui-card>
|
||||
|
||||
<ui-card>
|
||||
<template #title>summaly Proxy</template>
|
||||
<section class="fit-top fit-bottom">
|
||||
<ui-input v-model="summalyProxy">URL</ui-input>
|
||||
</section>
|
||||
<section>
|
||||
<ui-button @click="updateMeta"><fa :icon="faSave"/> {{ $t('save') }}</ui-button>
|
||||
</section>
|
||||
</ui-card>
|
||||
</details>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -136,8 +241,8 @@ import Vue from 'vue';
|
||||
import i18n from '../../i18n';
|
||||
import { url, host } from '../../config';
|
||||
import { toUnicode } from 'punycode';
|
||||
import { faHeadset, faShieldAlt, faGhost, faUserPlus, faBolt } from '@fortawesome/free-solid-svg-icons';
|
||||
import { faEnvelope as farEnvelope } from '@fortawesome/free-regular-svg-icons';
|
||||
import { faHeadset, faShieldAlt, faGhost, faUserPlus, faBolt, faThumbtack, faPencilAlt, faHashtag } from '@fortawesome/free-solid-svg-icons';
|
||||
import { faEnvelope as farEnvelope, faSave } from '@fortawesome/free-regular-svg-icons';
|
||||
|
||||
export default Vue.extend({
|
||||
i18n: i18n('admin/views/instance.vue'),
|
||||
@ -148,6 +253,9 @@ export default Vue.extend({
|
||||
host: toUnicode(host),
|
||||
maintainerName: null,
|
||||
maintainerEmail: null,
|
||||
ToSUrl: null,
|
||||
repositoryUrl: "https://github.com/syuilo/misskey",
|
||||
feedbackUrl: null,
|
||||
disableRegistration: false,
|
||||
disableLocalTimeline: false,
|
||||
disableGlobalTimeline: false,
|
||||
@ -177,7 +285,6 @@ export default Vue.extend({
|
||||
discordClientId: null,
|
||||
discordClientSecret: null,
|
||||
proxyAccount: null,
|
||||
inviteCode: null,
|
||||
summalyProxy: null,
|
||||
enableEmail: false,
|
||||
email: null,
|
||||
@ -190,7 +297,19 @@ export default Vue.extend({
|
||||
enableServiceWorker: false,
|
||||
swPublicKey: null,
|
||||
swPrivateKey: null,
|
||||
faHeadset, faShieldAlt, faGhost, faUserPlus, farEnvelope, faBolt
|
||||
pinnedUsers: '',
|
||||
hiddenTags: '',
|
||||
useObjectStorage: false,
|
||||
objectStorageBaseUrl: null,
|
||||
objectStorageBucket: null,
|
||||
objectStoragePrefix: null,
|
||||
objectStorageEndpoint: null,
|
||||
objectStorageRegion: null,
|
||||
objectStoragePort: null,
|
||||
objectStorageAccessKey: null,
|
||||
objectStorageSecretKey: null,
|
||||
objectStorageUseSSL: false,
|
||||
faHeadset, faShieldAlt, faGhost, faUserPlus, farEnvelope, faBolt, faThumbtack, faPencilAlt, faSave, faHashtag
|
||||
};
|
||||
},
|
||||
|
||||
@ -198,6 +317,9 @@ export default Vue.extend({
|
||||
this.$root.getMeta(true).then(meta => {
|
||||
this.maintainerName = meta.maintainerName;
|
||||
this.maintainerEmail = meta.maintainerEmail;
|
||||
this.ToSUrl = meta.ToSUrl;
|
||||
this.repositoryUrl = meta.repositoryUrl;
|
||||
this.feedbackUrl = meta.feedbackUrl;
|
||||
this.disableRegistration = meta.disableRegistration;
|
||||
this.disableLocalTimeline = meta.disableLocalTimeline;
|
||||
this.disableGlobalTimeline = meta.disableGlobalTimeline;
|
||||
@ -239,13 +361,28 @@ export default Vue.extend({
|
||||
this.enableServiceWorker = meta.enableServiceWorker;
|
||||
this.swPublicKey = meta.swPublickey;
|
||||
this.swPrivateKey = meta.swPrivateKey;
|
||||
this.pinnedUsers = meta.pinnedUsers.join('\n');
|
||||
this.hiddenTags = meta.hiddenTags.join('\n');
|
||||
this.useObjectStorage = meta.useObjectStorage;
|
||||
this.objectStorageBaseUrl = meta.objectStorageBaseUrl;
|
||||
this.objectStorageBucket = meta.objectStorageBucket;
|
||||
this.objectStoragePrefix = meta.objectStoragePrefix;
|
||||
this.objectStorageEndpoint = meta.objectStorageEndpoint;
|
||||
this.objectStorageRegion = meta.objectStorageRegion;
|
||||
this.objectStoragePort = meta.objectStoragePort;
|
||||
this.objectStorageAccessKey = meta.objectStorageAccessKey;
|
||||
this.objectStorageSecretKey = meta.objectStorageSecretKey;
|
||||
this.objectStorageUseSSL = meta.objectStorageUseSSL;
|
||||
});
|
||||
},
|
||||
|
||||
methods: {
|
||||
invite() {
|
||||
this.$root.api('admin/invite').then(x => {
|
||||
this.inviteCode = x.code;
|
||||
this.$root.dialog({
|
||||
type: 'info',
|
||||
text: x.code
|
||||
});
|
||||
}).catch(e => {
|
||||
this.$root.dialog({
|
||||
type: 'error',
|
||||
@ -258,6 +395,9 @@ export default Vue.extend({
|
||||
this.$root.api('admin/update-meta', {
|
||||
maintainerName: this.maintainerName,
|
||||
maintainerEmail: this.maintainerEmail,
|
||||
ToSUrl: this.ToSUrl,
|
||||
repositoryUrl: this.repositoryUrl,
|
||||
feedbackUrl: this.feedbackUrl,
|
||||
disableRegistration: this.disableRegistration,
|
||||
disableLocalTimeline: this.disableLocalTimeline,
|
||||
disableGlobalTimeline: this.disableGlobalTimeline,
|
||||
@ -297,7 +437,19 @@ 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'),
|
||||
hiddenTags: this.hiddenTags.split('\n'),
|
||||
useObjectStorage: this.useObjectStorage,
|
||||
objectStorageBaseUrl: this.objectStorageBaseUrl ? this.objectStorageBaseUrl : null,
|
||||
objectStorageBucket: this.objectStorageBucket ? this.objectStorageBucket : null,
|
||||
objectStoragePrefix: this.objectStoragePrefix ? this.objectStoragePrefix : null,
|
||||
objectStorageEndpoint: this.objectStorageEndpoint ? this.objectStorageEndpoint : null,
|
||||
objectStorageRegion: this.objectStorageRegion ? this.objectStorageRegion : null,
|
||||
objectStoragePort: this.objectStoragePort ? this.objectStoragePort : null,
|
||||
objectStorageAccessKey: this.objectStorageAccessKey ? this.objectStorageAccessKey : null,
|
||||
objectStorageSecretKey: this.objectStorageSecretKey ? this.objectStorageSecretKey : null,
|
||||
objectStorageUseSSL: this.objectStorageUseSSL,
|
||||
}).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
|
||||
|
@ -9,13 +9,10 @@
|
||||
<ui-button @click="showUser"><fa :icon="faSearch"/> {{ $t('lookup') }}</ui-button>
|
||||
|
||||
<div class="user" v-if="user">
|
||||
<x-user :user='user'/>
|
||||
<x-user :user="user"/>
|
||||
<div class="actions">
|
||||
<ui-button v-if="user.host != null" @click="updateRemoteUser"><fa :icon="faSync"/> {{ $t('update-remote-user') }}</ui-button>
|
||||
<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>
|
||||
@ -24,7 +21,7 @@
|
||||
<ui-button @click="suspendUser" :disabled="suspending"><fa :icon="faSnowflake"/> {{ $t('suspend') }}</ui-button>
|
||||
<ui-button @click="unsuspendUser" :disabled="unsuspending">{{ $t('unsuspend') }}</ui-button>
|
||||
</ui-horizon-group>
|
||||
<ui-button v-if="user.host != null" @click="updateRemoteUser"><fa :icon="faSync"/> {{ $t('update-remote-user') }}</ui-button>
|
||||
<ui-button @click="deleteAllFiles"><fa :icon="faTrashAlt"/> {{ $t('delete-all-files') }}</ui-button>
|
||||
<ui-textarea v-if="user" :value="user | json5" readonly tall style="margin-top:16px;"></ui-textarea>
|
||||
</div>
|
||||
</div>
|
||||
@ -47,7 +44,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,8 +67,8 @@
|
||||
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 { faSnowflake } from '@fortawesome/free-regular-svg-icons';
|
||||
import { faUsers, faTerminal, faSearch, faKey, faSync, faMicrophoneSlash } from '@fortawesome/free-solid-svg-icons';
|
||||
import { faSnowflake, faTrashAlt } from '@fortawesome/free-regular-svg-icons';
|
||||
import XUser from './users.user.vue';
|
||||
|
||||
export default Vue.extend({
|
||||
@ -84,8 +80,6 @@ export default Vue.extend({
|
||||
return {
|
||||
user: null,
|
||||
target: null,
|
||||
verifying: false,
|
||||
unverifying: false,
|
||||
suspending: false,
|
||||
unsuspending: false,
|
||||
sort: '+createdAt',
|
||||
@ -95,7 +89,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, faTrashAlt
|
||||
};
|
||||
},
|
||||
|
||||
@ -181,56 +175,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;
|
||||
|
||||
@ -334,6 +278,25 @@ export default Vue.extend({
|
||||
this.refreshUser();
|
||||
},
|
||||
|
||||
async deleteAllFiles() {
|
||||
if (!await this.getConfirmed(this.$t('delete-all-files-confirm'))) return;
|
||||
|
||||
const process = async () => {
|
||||
await this.$root.api('admin/delete-all-files-of-a-user', { userId: this.user.id });
|
||||
this.$root.dialog({
|
||||
type: 'success',
|
||||
splash: true
|
||||
});
|
||||
};
|
||||
|
||||
await process().catch(e => {
|
||||
this.$root.dialog({
|
||||
type: 'error',
|
||||
text: e.toString()
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
async getConfirmed(text: string): Promise<Boolean> {
|
||||
const confirm = await this.$root.dialog({
|
||||
type: 'warning',
|
||||
|
@ -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
|
||||
);
|
||||
}
|
||||
|
||||
|
42
src/client/app/common/scripts/collect-page-vars.ts
Normal file
42
src/client/app/common/scripts/collect-page-vars.ts
Normal file
@ -0,0 +1,42 @@
|
||||
export function collectPageVars(content) {
|
||||
const pageVars = [];
|
||||
const collect = (xs: any[]) => {
|
||||
for (const x of xs) {
|
||||
if (x.type === 'textInput') {
|
||||
pageVars.push({
|
||||
name: x.name,
|
||||
type: 'string',
|
||||
value: x.default || ''
|
||||
});
|
||||
} else if (x.type === 'textareaInput') {
|
||||
pageVars.push({
|
||||
name: x.name,
|
||||
type: 'string',
|
||||
value: x.default || ''
|
||||
});
|
||||
} else if (x.type === 'numberInput') {
|
||||
pageVars.push({
|
||||
name: x.name,
|
||||
type: 'number',
|
||||
value: x.default || 0
|
||||
});
|
||||
} else if (x.type === 'switch') {
|
||||
pageVars.push({
|
||||
name: x.name,
|
||||
type: 'boolean',
|
||||
value: x.default || false
|
||||
});
|
||||
} else if (x.type === 'counter') {
|
||||
pageVars.push({
|
||||
name: x.name,
|
||||
type: 'number',
|
||||
value: 0
|
||||
});
|
||||
} else if (x.children) {
|
||||
collect(x.children);
|
||||
}
|
||||
}
|
||||
};
|
||||
collect(content);
|
||||
return pageVars;
|
||||
}
|
31
src/client/app/common/scripts/gen-search-query.ts
Normal file
31
src/client/app/common/scripts/gen-search-query.ts
Normal file
@ -0,0 +1,31 @@
|
||||
import parseAcct from '../../../../misc/acct/parse';
|
||||
import { host as localHost } from '../../config';
|
||||
|
||||
export async function genSearchQuery(v: any, q: string) {
|
||||
let host: string;
|
||||
let userId: string;
|
||||
if (q.split(' ').some(x => x.startsWith('@'))) {
|
||||
for (const at of q.split(' ').filter(x => x.startsWith('@')).map(x => x.substr(1))) {
|
||||
if (at.includes('.')) {
|
||||
if (at === localHost || at === '.') {
|
||||
host = null;
|
||||
} else {
|
||||
host = at;
|
||||
}
|
||||
} else {
|
||||
const user = await v.$root.api('users/show', parseAcct(at)).catch(x => null);
|
||||
if (user) {
|
||||
userId = user.id;
|
||||
} else {
|
||||
// todo: show error
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return {
|
||||
query: q.split(' ').filter(x => !x.startsWith('/') && !x.startsWith('@')).join(' '),
|
||||
host: host,
|
||||
userId: userId
|
||||
};
|
||||
}
|
@ -3,7 +3,7 @@ import { faHistory } from '@fortawesome/free-solid-svg-icons';
|
||||
export async function search(v: any, q: string) {
|
||||
q = q.trim();
|
||||
|
||||
if (q.startsWith('@')) {
|
||||
if (q.startsWith('@') && !q.includes(' ')) {
|
||||
v.$router.push(`/${q}`);
|
||||
return;
|
||||
}
|
||||
|
@ -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();
|
||||
},
|
||||
|
@ -78,6 +78,7 @@ export default Vue.extend({
|
||||
.mk-avatar
|
||||
display inline-block
|
||||
vertical-align bottom
|
||||
flex-shrink 0
|
||||
|
||||
&:not(.cat)
|
||||
overflow hidden
|
||||
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="felqjxyj" :class="{ splash }">
|
||||
<div class="bg" ref="bg" @click="onBgClick"></div>
|
||||
<div class="main" ref="main">
|
||||
<div class="main" ref="main" :class="{ round: $store.state.device.roundedCorners }">
|
||||
<template v-if="type == 'signin'">
|
||||
<mk-signin/>
|
||||
</template>
|
||||
@ -22,7 +22,14 @@
|
||||
<ui-input v-if="input" v-model="inputValue" autofocus :type="input.type || 'text'" :placeholder="input.placeholder" @keydown="onInputKeydown"></ui-input>
|
||||
<ui-input v-if="user" v-model="userInputValue" autofocus @keydown="onInputKeydown"><template #prefix>@</template></ui-input>
|
||||
<ui-select v-if="select" v-model="selectedValue" autofocus>
|
||||
<option v-for="item in select.items" :value="item.value">{{ item.text }}</option>
|
||||
<template v-if="select.items">
|
||||
<option v-for="item in select.items" :value="item.value">{{ item.text }}</option>
|
||||
</template>
|
||||
<template v-else>
|
||||
<optgroup v-for="groupedItem in select.groupedItems" :label="groupedItem.label">
|
||||
<option v-for="item in groupedItem.items" :value="item.value">{{ item.text }}</option>
|
||||
</optgroup>
|
||||
</template>
|
||||
</ui-select>
|
||||
<ui-horizon-group no-grow class="buttons fit-bottom" v-if="!splash && (showOkButton || showCancelButton)">
|
||||
<ui-button @click="ok" v-if="showOkButton" primary :autofocus="!input && !select && !user">{{ (showCancelButton || input || select || user) ? $t('@.ok') : $t('@.got-it') }}</ui-button>
|
||||
@ -222,15 +229,17 @@ export default Vue.extend({
|
||||
width calc(100% - 32px)
|
||||
text-align center
|
||||
background var(--face)
|
||||
border-radius 8px
|
||||
color var(--faceText)
|
||||
opacity 0
|
||||
|
||||
&.round
|
||||
border-radius 8px
|
||||
|
||||
> .icon
|
||||
font-size 32px
|
||||
|
||||
&.success
|
||||
color #37ec92
|
||||
color #85da5a
|
||||
|
||||
&.error
|
||||
color #ec4137
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<a class="a" :href="repositoryUrl" target="_blank" title="View source on GitHub">
|
||||
<a class="a" :href="repositoryUrl" rel="noopener" target="_blank" title="View source on GitHub">
|
||||
<svg width="80" height="80" viewBox="0 0 250 250" aria-hidden="aria-hidden">
|
||||
<path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path>
|
||||
<path class="octo-arm" d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor"></path>
|
||||
|
@ -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) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<a class="zxrjzpcj" :href="url" :class="service" target="_blank">
|
||||
<a class="zxrjzpcj" :href="url" :class="service" rel="noopener" target="_blank">
|
||||
<fa :icon="icon" size="lg" fixed-width /><span>{{ text }}</span>
|
||||
</a>
|
||||
</template>
|
||||
|
@ -36,7 +36,7 @@ export default Vue.extend({
|
||||
return {
|
||||
hide: true
|
||||
};
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
style(): any {
|
||||
let url = `url(${
|
||||
|
@ -9,7 +9,7 @@
|
||||
<div class="content" v-if="!message.isDeleted">
|
||||
<mfm class="text" v-if="message.text" ref="text" :text="message.text" :i="$store.state.i"/>
|
||||
<div class="file" v-if="message.file">
|
||||
<a :href="message.file.url" target="_blank" :title="message.file.name">
|
||||
<a :href="message.file.url" rel="noopener" target="_blank" :title="message.file.name">
|
||||
<img v-if="message.file.type.split('/')[0] == 'image'" :src="message.file.url" :alt="message.file.name"
|
||||
:style="{ backgroundColor: message.file.properties.avgColor || 'transparent' }"/>
|
||||
<p v-else>{{ message.file.name }}</p>
|
||||
|
@ -13,8 +13,8 @@
|
||||
@click="navigate(user)"
|
||||
tabindex="-1"
|
||||
>
|
||||
<mk-avatar class="avatar" :user="user"/>
|
||||
<span class="name"><mk-user-name :user="user"/></span>
|
||||
<mk-avatar class="avatar" :user="user" :key="user.id"/>
|
||||
<span class="name"><mk-user-name :user="user" :key="user.id"/></span>
|
||||
<span class="username">@{{ user | acct }}</span>
|
||||
</li>
|
||||
</ol>
|
||||
@ -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)
|
||||
|
@ -174,6 +174,7 @@ export default Vue.component('misskey-flavored-markdown', {
|
||||
key: Math.random(),
|
||||
props: {
|
||||
url: token.node.props.url,
|
||||
rel: 'nofollow noopener',
|
||||
target: '_blank'
|
||||
},
|
||||
attrs: {
|
||||
@ -187,6 +188,7 @@ export default Vue.component('misskey-flavored-markdown', {
|
||||
attrs: {
|
||||
class: 'link',
|
||||
href: token.node.props.url,
|
||||
rel: 'nofollow noopener',
|
||||
target: '_blank',
|
||||
title: token.node.props.url,
|
||||
style: 'color:var(--mfmLink);'
|
||||
|
@ -1,12 +1,16 @@
|
||||
<template>
|
||||
<span class="mk-nav">
|
||||
<a :href="aboutUrl">{{ $t('about') }}</a>
|
||||
<template v-if="ToSUrl !== null">
|
||||
<i>・</i>
|
||||
<a :href="ToSUrl" target="_blank">{{ $t('tos') }}</a>
|
||||
</template>
|
||||
<i>・</i>
|
||||
<a :href="repositoryUrl">{{ $t('repository') }}</a>
|
||||
<a :href="repositoryUrl" rel="noopener" target="_blank">{{ $t('repository') }}</a>
|
||||
<i>・</i>
|
||||
<a :href="feedbackUrl" target="_blank">{{ $t('feedback') }}</a>
|
||||
<a :href="feedbackUrl" rel="noopener" target="_blank">{{ $t('feedback') }}</a>
|
||||
<i>・</i>
|
||||
<a href="/dev">{{ $t('develop') }}</a>
|
||||
<a href="/dev" target="_blank">{{ $t('develop') }}</a>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
@ -21,8 +25,17 @@ export default Vue.extend({
|
||||
return {
|
||||
aboutUrl: `/docs/${lang}/about`,
|
||||
repositoryUrl: 'https://github.com/syuilo/misskey',
|
||||
feedbackUrl: 'https://github.com/syuilo/misskey/issues/new'
|
||||
feedbackUrl: 'https://github.com/syuilo/misskey/issues/new',
|
||||
ToSUrl: null
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.$root.getMeta(true).then(meta => {
|
||||
this.repositoryUrl = meta.repositoryUrl;
|
||||
this.feedbackUrl = meta.feedbackUrl;
|
||||
this.ToSUrl = meta.ToSUrl;
|
||||
})
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
@ -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
|
||||
|
@ -0,0 +1,54 @@
|
||||
<template>
|
||||
<x-container @remove="() => $emit('remove')" :draggable="true">
|
||||
<template #header><fa :icon="faBolt"/> {{ $t('blocks.button') }}</template>
|
||||
|
||||
<section class="xfhsjczc">
|
||||
<ui-input v-model="value.text"><span>{{ $t('blocks._button.text') }}</span></ui-input>
|
||||
<ui-select v-model="value.action">
|
||||
<template #label>{{ $t('blocks._button.action') }}</template>
|
||||
<option value="dialog">{{ $t('blocks._button._action.dialog') }}</option>
|
||||
<option value="resetRandom">{{ $t('blocks._button._action.resetRandom') }}</option>
|
||||
</ui-select>
|
||||
<ui-input v-if="value.action === 'dialog'" v-model="value.content"><span>{{ $t('blocks._button._action._dialog.content') }}</span></ui-input>
|
||||
</section>
|
||||
</x-container>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import { faBolt } from '@fortawesome/free-solid-svg-icons';
|
||||
import i18n from '../../../../../i18n';
|
||||
import XContainer from '../page-editor.container.vue';
|
||||
|
||||
export default Vue.extend({
|
||||
i18n: i18n('pages'),
|
||||
|
||||
components: {
|
||||
XContainer
|
||||
},
|
||||
|
||||
props: {
|
||||
value: {
|
||||
required: true
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
faBolt
|
||||
};
|
||||
},
|
||||
|
||||
created() {
|
||||
if (this.value.text == null) Vue.set(this.value, 'text', '');
|
||||
if (this.value.action == null) Vue.set(this.value, 'action', 'dialog');
|
||||
if (this.value.content == null) Vue.set(this.value, 'content', null);
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
.xfhsjczc
|
||||
padding 0 16px 0 16px
|
||||
|
||||
</style>
|
@ -0,0 +1,42 @@
|
||||
<template>
|
||||
<x-container @remove="() => $emit('remove')" :draggable="true">
|
||||
<template #header><fa :icon="faBolt"/> {{ $t('blocks.counter') }}</template>
|
||||
|
||||
<section style="padding: 0 16px 0 16px;">
|
||||
<ui-input v-model="value.name"><template #prefix><fa :icon="faMagic"/></template><span>{{ $t('blocks._counter.name') }}</span></ui-input>
|
||||
<ui-input v-model="value.text"><span>{{ $t('blocks._counter.text') }}</span></ui-input>
|
||||
<ui-input v-model="value.inc" type="number"><span>{{ $t('blocks._counter.increment') }}</span></ui-input>
|
||||
</section>
|
||||
</x-container>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import { faBolt, faMagic } from '@fortawesome/free-solid-svg-icons';
|
||||
import i18n from '../../../../../i18n';
|
||||
import XContainer from '../page-editor.container.vue';
|
||||
|
||||
export default Vue.extend({
|
||||
i18n: i18n('pages'),
|
||||
|
||||
components: {
|
||||
XContainer
|
||||
},
|
||||
|
||||
props: {
|
||||
value: {
|
||||
required: true
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
faBolt, faMagic
|
||||
};
|
||||
},
|
||||
|
||||
created() {
|
||||
if (this.value.name == null) Vue.set(this.value, 'name', '');
|
||||
},
|
||||
});
|
||||
</script>
|
@ -0,0 +1,90 @@
|
||||
<template>
|
||||
<x-container @remove="() => $emit('remove')" :draggable="true">
|
||||
<template #header><fa :icon="faQuestion"/> {{ $t('blocks.if') }}</template>
|
||||
<template #func>
|
||||
<button @click="add()">
|
||||
<fa :icon="faPlus"/>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<section class="romcojzs">
|
||||
<ui-select v-model="value.var">
|
||||
<template #label>{{ $t('blocks._if.variable') }}</template>
|
||||
<option v-for="v in aiScript.getVarsByType('boolean')" :value="v.name">{{ v.name }}</option>
|
||||
<optgroup :label="$t('script.pageVariables')">
|
||||
<option v-for="v in aiScript.getPageVarsByType('boolean')" :value="v">{{ v }}</option>
|
||||
</optgroup>
|
||||
<optgroup :label="$t('script.enviromentVariables')">
|
||||
<option v-for="v in aiScript.getEnvVarsByType('boolean')" :value="v">{{ v }}</option>
|
||||
</optgroup>
|
||||
</ui-select>
|
||||
|
||||
<x-blocks class="children" v-model="value.children" :ai-script="aiScript"/>
|
||||
</section>
|
||||
</x-container>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import * as uuid from 'uuid';
|
||||
import { faPlus, faQuestion } from '@fortawesome/free-solid-svg-icons';
|
||||
import i18n from '../../../../../i18n';
|
||||
import XContainer from '../page-editor.container.vue';
|
||||
|
||||
export default Vue.extend({
|
||||
i18n: i18n('pages'),
|
||||
|
||||
components: {
|
||||
XContainer
|
||||
},
|
||||
|
||||
inject: ['getPageBlockList'],
|
||||
|
||||
props: {
|
||||
value: {
|
||||
required: true
|
||||
},
|
||||
aiScript: {
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
faPlus, faQuestion
|
||||
};
|
||||
},
|
||||
|
||||
beforeCreate() {
|
||||
this.$options.components.XBlocks = require('../page-editor.blocks.vue').default
|
||||
},
|
||||
|
||||
created() {
|
||||
if (this.value.children == null) Vue.set(this.value, 'children', []);
|
||||
if (this.value.var === undefined) Vue.set(this.value, 'var', null);
|
||||
},
|
||||
|
||||
methods: {
|
||||
async add() {
|
||||
const { canceled, result: type } = await this.$root.dialog({
|
||||
type: null,
|
||||
title: this.$t('choose-block'),
|
||||
select: {
|
||||
groupedItems: this.getPageBlockList()
|
||||
},
|
||||
showCancelButton: true
|
||||
});
|
||||
if (canceled) return;
|
||||
|
||||
const id = uuid.v4();
|
||||
this.value.children.push({ id, type });
|
||||
},
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
.romcojzs
|
||||
padding 0 16px 16px 16px
|
||||
|
||||
</style>
|
@ -0,0 +1,78 @@
|
||||
<template>
|
||||
<x-container @remove="() => $emit('remove')" :draggable="true">
|
||||
<template #header><fa :icon="faImage"/> {{ $t('blocks.image') }}</template>
|
||||
<template #func>
|
||||
<button @click="choose()">
|
||||
<fa :icon="faFolderOpen"/>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<section class="oyyftmcf">
|
||||
<x-file-thumbnail class="preview" v-if="file" :file="file" :detail="true" fit="contain" @click="choose()"/>
|
||||
</section>
|
||||
</x-container>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import { faPencilAlt } from '@fortawesome/free-solid-svg-icons';
|
||||
import { faImage, faFolderOpen } from '@fortawesome/free-regular-svg-icons';
|
||||
import i18n from '../../../../../i18n';
|
||||
import XContainer from '../page-editor.container.vue';
|
||||
import XFileThumbnail from '../../drive-file-thumbnail.vue';
|
||||
|
||||
export default Vue.extend({
|
||||
i18n: i18n('pages'),
|
||||
|
||||
components: {
|
||||
XContainer, XFileThumbnail
|
||||
},
|
||||
|
||||
props: {
|
||||
value: {
|
||||
required: true
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
file: null,
|
||||
faPencilAlt, faImage, faFolderOpen
|
||||
};
|
||||
},
|
||||
|
||||
created() {
|
||||
if (this.value.fileId === undefined) Vue.set(this.value, 'fileId', null);
|
||||
},
|
||||
|
||||
mounted() {
|
||||
if (this.value.fileId == null) {
|
||||
this.choose();
|
||||
} else {
|
||||
this.$root.api('drive/files/show', {
|
||||
fileId: this.value.fileId
|
||||
}).then(file => {
|
||||
this.file = file;
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
async choose() {
|
||||
this.$chooseDriveFile({
|
||||
multiple: false
|
||||
}).then(file => {
|
||||
this.file = file;
|
||||
this.value.fileId = file.id;
|
||||
});
|
||||
},
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
.oyyftmcf
|
||||
> .preview
|
||||
height 150px
|
||||
|
||||
</style>
|
@ -0,0 +1,42 @@
|
||||
<template>
|
||||
<x-container @remove="() => $emit('remove')" :draggable="true">
|
||||
<template #header><fa :icon="faBolt"/> {{ $t('blocks.numberInput') }}</template>
|
||||
|
||||
<section style="padding: 0 16px 0 16px;">
|
||||
<ui-input v-model="value.name"><template #prefix><fa :icon="faMagic"/></template><span>{{ $t('blocks._numberInput.name') }}</span></ui-input>
|
||||
<ui-input v-model="value.text"><span>{{ $t('blocks._numberInput.text') }}</span></ui-input>
|
||||
<ui-input v-model="value.default" type="number"><span>{{ $t('blocks._numberInput.default') }}</span></ui-input>
|
||||
</section>
|
||||
</x-container>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import { faBolt, faMagic } from '@fortawesome/free-solid-svg-icons';
|
||||
import i18n from '../../../../../i18n';
|
||||
import XContainer from '../page-editor.container.vue';
|
||||
|
||||
export default Vue.extend({
|
||||
i18n: i18n('pages'),
|
||||
|
||||
components: {
|
||||
XContainer
|
||||
},
|
||||
|
||||
props: {
|
||||
value: {
|
||||
required: true
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
faBolt, faMagic
|
||||
};
|
||||
},
|
||||
|
||||
created() {
|
||||
if (this.value.name == null) Vue.set(this.value, 'name', '');
|
||||
},
|
||||
});
|
||||
</script>
|
@ -0,0 +1,40 @@
|
||||
<template>
|
||||
<x-container @remove="() => $emit('remove')" :draggable="true">
|
||||
<template #header><fa :icon="faPaperPlane"/> {{ $t('blocks.post') }}</template>
|
||||
|
||||
<section style="padding: 0 16px 16px 16px;">
|
||||
<ui-textarea v-model="value.text">{{ $t('blocks._post.text') }}</ui-textarea>
|
||||
</section>
|
||||
</x-container>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import { faPaperPlane } from '@fortawesome/free-regular-svg-icons';
|
||||
import i18n from '../../../../../i18n';
|
||||
import XContainer from '../page-editor.container.vue';
|
||||
|
||||
export default Vue.extend({
|
||||
i18n: i18n('pages'),
|
||||
|
||||
components: {
|
||||
XContainer
|
||||
},
|
||||
|
||||
props: {
|
||||
value: {
|
||||
required: true
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
faPaperPlane
|
||||
};
|
||||
},
|
||||
|
||||
created() {
|
||||
if (this.value.text == null) Vue.set(this.value, 'text', '');
|
||||
},
|
||||
});
|
||||
</script>
|
@ -0,0 +1,103 @@
|
||||
<template>
|
||||
<x-container @remove="() => $emit('remove')" :draggable="true">
|
||||
<template #header><fa :icon="faStickyNote"/> {{ value.title }}</template>
|
||||
<template #func>
|
||||
<button @click="rename()">
|
||||
<fa :icon="faPencilAlt"/>
|
||||
</button>
|
||||
<button @click="add()">
|
||||
<fa :icon="faPlus"/>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<section class="ilrvjyvi">
|
||||
<x-blocks class="children" v-model="value.children" :ai-script="aiScript"/>
|
||||
</section>
|
||||
</x-container>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import * as uuid from 'uuid';
|
||||
import { faPlus, faPencilAlt } from '@fortawesome/free-solid-svg-icons';
|
||||
import { faStickyNote } from '@fortawesome/free-regular-svg-icons';
|
||||
import i18n from '../../../../../i18n';
|
||||
import XContainer from '../page-editor.container.vue';
|
||||
|
||||
export default Vue.extend({
|
||||
i18n: i18n('pages'),
|
||||
|
||||
components: {
|
||||
XContainer
|
||||
},
|
||||
|
||||
inject: ['getPageBlockList'],
|
||||
|
||||
props: {
|
||||
value: {
|
||||
required: true
|
||||
},
|
||||
aiScript: {
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
faStickyNote, faPlus, faPencilAlt
|
||||
};
|
||||
},
|
||||
|
||||
beforeCreate() {
|
||||
this.$options.components.XBlocks = require('../page-editor.blocks.vue').default
|
||||
},
|
||||
|
||||
created() {
|
||||
if (this.value.title == null) Vue.set(this.value, 'title', null);
|
||||
if (this.value.children == null) Vue.set(this.value, 'children', []);
|
||||
},
|
||||
|
||||
mounted() {
|
||||
if (this.value.title == null) {
|
||||
this.rename();
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
async rename() {
|
||||
const { canceled, result: title } = await this.$root.dialog({
|
||||
title: 'Enter title',
|
||||
input: {
|
||||
type: 'text',
|
||||
default: this.value.title
|
||||
},
|
||||
showCancelButton: true
|
||||
});
|
||||
if (canceled) return;
|
||||
this.value.title = title;
|
||||
},
|
||||
|
||||
async add() {
|
||||
const { canceled, result: type } = await this.$root.dialog({
|
||||
type: null,
|
||||
title: this.$t('choose-block'),
|
||||
select: {
|
||||
groupedItems: this.getPageBlockList()
|
||||
},
|
||||
showCancelButton: true
|
||||
});
|
||||
if (canceled) return;
|
||||
|
||||
const id = uuid.v4();
|
||||
this.value.children.push({ id, type });
|
||||
},
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
.ilrvjyvi
|
||||
> .children
|
||||
padding 16px
|
||||
|
||||
</style>
|
@ -0,0 +1,48 @@
|
||||
<template>
|
||||
<x-container @remove="() => $emit('remove')" :draggable="true">
|
||||
<template #header><fa :icon="faBolt"/> {{ $t('blocks.switch') }}</template>
|
||||
|
||||
<section class="kjuadyyj">
|
||||
<ui-input v-model="value.name"><template #prefix><fa :icon="faMagic"/></template><span>{{ $t('blocks._switch.name') }}</span></ui-input>
|
||||
<ui-input v-model="value.text"><span>{{ $t('blocks._switch.text') }}</span></ui-input>
|
||||
<ui-switch v-model="value.default"><span>{{ $t('blocks._switch.default') }}</span></ui-switch>
|
||||
</section>
|
||||
</x-container>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import { faBolt, faMagic } from '@fortawesome/free-solid-svg-icons';
|
||||
import i18n from '../../../../../i18n';
|
||||
import XContainer from '../page-editor.container.vue';
|
||||
|
||||
export default Vue.extend({
|
||||
i18n: i18n('pages'),
|
||||
|
||||
components: {
|
||||
XContainer
|
||||
},
|
||||
|
||||
props: {
|
||||
value: {
|
||||
required: true
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
faBolt, faMagic
|
||||
};
|
||||
},
|
||||
|
||||
created() {
|
||||
if (this.value.name == null) Vue.set(this.value, 'name', '');
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
.kjuadyyj
|
||||
padding 0 16px 16px 16px
|
||||
|
||||
</style>
|
@ -0,0 +1,42 @@
|
||||
<template>
|
||||
<x-container @remove="() => $emit('remove')" :draggable="true">
|
||||
<template #header><fa :icon="faBolt"/> {{ $t('blocks.textInput') }}</template>
|
||||
|
||||
<section style="padding: 0 16px 0 16px;">
|
||||
<ui-input v-model="value.name"><template #prefix><fa :icon="faMagic"/></template><span>{{ $t('blocks._textInput.name') }}</span></ui-input>
|
||||
<ui-input v-model="value.text"><span>{{ $t('blocks._textInput.text') }}</span></ui-input>
|
||||
<ui-input v-model="value.default" type="text"><span>{{ $t('blocks._textInput.default') }}</span></ui-input>
|
||||
</section>
|
||||
</x-container>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import { faBolt, faMagic } from '@fortawesome/free-solid-svg-icons';
|
||||
import i18n from '../../../../../i18n';
|
||||
import XContainer from '../page-editor.container.vue';
|
||||
|
||||
export default Vue.extend({
|
||||
i18n: i18n('pages'),
|
||||
|
||||
components: {
|
||||
XContainer
|
||||
},
|
||||
|
||||
props: {
|
||||
value: {
|
||||
required: true
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
faBolt, faMagic
|
||||
};
|
||||
},
|
||||
|
||||
created() {
|
||||
if (this.value.name == null) Vue.set(this.value, 'name', '');
|
||||
},
|
||||
});
|
||||
</script>
|
@ -0,0 +1,58 @@
|
||||
<template>
|
||||
<x-container @remove="() => $emit('remove')" :draggable="true">
|
||||
<template #header><fa :icon="faAlignLeft"/> {{ $t('blocks.text') }}</template>
|
||||
|
||||
<section class="ihymsbbe">
|
||||
<textarea v-model="value.text"></textarea>
|
||||
</section>
|
||||
</x-container>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import { faAlignLeft } from '@fortawesome/free-solid-svg-icons';
|
||||
import i18n from '../../../../../i18n';
|
||||
import XContainer from '../page-editor.container.vue';
|
||||
|
||||
export default Vue.extend({
|
||||
i18n: i18n('pages'),
|
||||
|
||||
components: {
|
||||
XContainer
|
||||
},
|
||||
|
||||
props: {
|
||||
value: {
|
||||
required: true
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
faAlignLeft,
|
||||
};
|
||||
},
|
||||
|
||||
created() {
|
||||
if (this.value.text == null) Vue.set(this.value, 'text', '');
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
.ihymsbbe
|
||||
> textarea
|
||||
display block
|
||||
-webkit-appearance none
|
||||
-moz-appearance none
|
||||
appearance none
|
||||
width 100%
|
||||
min-width 100%
|
||||
min-height 150px
|
||||
border none
|
||||
box-shadow none
|
||||
padding 16px
|
||||
background transparent
|
||||
color var(--text)
|
||||
font-size 14px
|
||||
</style>
|
@ -0,0 +1,42 @@
|
||||
<template>
|
||||
<x-container @remove="() => $emit('remove')" :draggable="true">
|
||||
<template #header><fa :icon="faBolt"/> {{ $t('blocks.textareaInput') }}</template>
|
||||
|
||||
<section style="padding: 0 16px 16px 16px;">
|
||||
<ui-input v-model="value.name"><template #prefix><fa :icon="faMagic"/></template><span>{{ $t('blocks._textareaInput.name') }}</span></ui-input>
|
||||
<ui-input v-model="value.text"><span>{{ $t('blocks._textareaInput.text') }}</span></ui-input>
|
||||
<ui-textarea v-model="value.default"><span>{{ $t('blocks._textareaInput.default') }}</span></ui-textarea>
|
||||
</section>
|
||||
</x-container>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import { faBolt, faMagic } from '@fortawesome/free-solid-svg-icons';
|
||||
import i18n from '../../../../../i18n';
|
||||
import XContainer from '../page-editor.container.vue';
|
||||
|
||||
export default Vue.extend({
|
||||
i18n: i18n('pages'),
|
||||
|
||||
components: {
|
||||
XContainer
|
||||
},
|
||||
|
||||
props: {
|
||||
value: {
|
||||
required: true
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
faBolt, faMagic
|
||||
};
|
||||
},
|
||||
|
||||
created() {
|
||||
if (this.value.name == null) Vue.set(this.value, 'name', '');
|
||||
},
|
||||
});
|
||||
</script>
|
@ -0,0 +1,58 @@
|
||||
<template>
|
||||
<x-container @remove="() => $emit('remove')" :draggable="true">
|
||||
<template #header><fa :icon="faAlignLeft"/> {{ $t('blocks.textarea') }}</template>
|
||||
|
||||
<section class="ihymsbbe">
|
||||
<textarea v-model="value.text"></textarea>
|
||||
</section>
|
||||
</x-container>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import { faAlignLeft } from '@fortawesome/free-solid-svg-icons';
|
||||
import i18n from '../../../../../i18n';
|
||||
import XContainer from '../page-editor.container.vue';
|
||||
|
||||
export default Vue.extend({
|
||||
i18n: i18n('pages'),
|
||||
|
||||
components: {
|
||||
XContainer
|
||||
},
|
||||
|
||||
props: {
|
||||
value: {
|
||||
required: true
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
faAlignLeft,
|
||||
};
|
||||
},
|
||||
|
||||
created() {
|
||||
if (this.value.text == null) Vue.set(this.value, 'text', '');
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
.ihymsbbe
|
||||
> textarea
|
||||
display block
|
||||
-webkit-appearance none
|
||||
-moz-appearance none
|
||||
appearance none
|
||||
width 100%
|
||||
min-width 100%
|
||||
min-height 150px
|
||||
border none
|
||||
box-shadow none
|
||||
padding 16px
|
||||
background transparent
|
||||
color var(--text)
|
||||
font-size 14px
|
||||
</style>
|
@ -0,0 +1,65 @@
|
||||
<template>
|
||||
<x-draggable tag="div" :list="blocks" handle=".drag-handle" :group="{ name: 'blocks' }" animation="150" swap-threshold="0.5">
|
||||
<component v-for="block in blocks" :is="'x-' + block.type" :value="block" @input="updateItem" @remove="() => removeItem(block)" :key="block.id" :ai-script="aiScript"/>
|
||||
</x-draggable>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import * as XDraggable from 'vuedraggable';
|
||||
import XSection from './els/page-editor.el.section.vue';
|
||||
import XText from './els/page-editor.el.text.vue';
|
||||
import XTextarea from './els/page-editor.el.textarea.vue';
|
||||
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.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';
|
||||
import XCounter from './els/page-editor.el.counter.vue';
|
||||
|
||||
export default Vue.extend({
|
||||
components: {
|
||||
XDraggable, XSection, XText, XImage, XButton, XTextarea, XTextInput, XTextareaInput, XNumberInput, XSwitch, XIf, XPost, XCounter
|
||||
},
|
||||
|
||||
props: {
|
||||
value: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
aiScript: {
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
|
||||
computed: {
|
||||
blocks() {
|
||||
return this.value;
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
updateItem(v) {
|
||||
const i = this.blocks.findIndex(x => x.id === v.id);
|
||||
const newValue = [
|
||||
...this.blocks.slice(0, i),
|
||||
v,
|
||||
...this.blocks.slice(i + 1)
|
||||
];
|
||||
this.$emit('input', newValue);
|
||||
},
|
||||
|
||||
removeItem(el) {
|
||||
const i = this.blocks.findIndex(x => x.id === el.id);
|
||||
const newValue = [
|
||||
...this.blocks.slice(0, i),
|
||||
...this.blocks.slice(i + 1)
|
||||
];
|
||||
this.$emit('input', newValue);
|
||||
},
|
||||
}
|
||||
});
|
||||
</script>
|
@ -0,0 +1,146 @@
|
||||
<template>
|
||||
<div class="cpjygsrt" :class="{ error: error != null, warn: warn != null }">
|
||||
<header>
|
||||
<div class="title"><slot name="header"></slot></div>
|
||||
<div class="buttons">
|
||||
<slot name="func"></slot>
|
||||
<button v-if="removable" @click="remove()">
|
||||
<fa :icon="faTrashAlt"/>
|
||||
</button>
|
||||
<button v-if="draggable" class="drag-handle">
|
||||
<fa :icon="faBars"/>
|
||||
</button>
|
||||
<button @click="toggleContent(!showBody)">
|
||||
<template v-if="showBody"><fa icon="angle-up"/></template>
|
||||
<template v-else><fa icon="angle-down"/></template>
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
<p v-show="showBody" class="error" v-if="error != null">{{ $t('script.typeError', { slot: error.arg + 1, expect: $t(`script.types.${error.expect}`), actual: $t(`script.types.${error.actual}`) }) }}</p>
|
||||
<p v-show="showBody" class="warn" v-if="warn != null">{{ $t('script.thereIsEmptySlot', { slot: warn.slot + 1 }) }}</p>
|
||||
<div v-show="showBody">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import { faBars } from '@fortawesome/free-solid-svg-icons';
|
||||
import { faTrashAlt } from '@fortawesome/free-regular-svg-icons';
|
||||
import i18n from '../../../../i18n';
|
||||
|
||||
export default Vue.extend({
|
||||
i18n: i18n('pages'),
|
||||
|
||||
props: {
|
||||
expanded: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
removable: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
draggable: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
error: {
|
||||
required: false,
|
||||
default: null
|
||||
},
|
||||
warn: {
|
||||
required: false,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showBody: this.expanded,
|
||||
faTrashAlt, faBars
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
toggleContent(show: boolean) {
|
||||
this.showBody = show;
|
||||
this.$emit('toggle', show);
|
||||
},
|
||||
remove() {
|
||||
this.$emit('remove');
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
.cpjygsrt
|
||||
overflow hidden
|
||||
background var(--face)
|
||||
border solid 2px var(--pageBlockBorder)
|
||||
border-radius 6px
|
||||
|
||||
&:hover
|
||||
border solid 2px var(--pageBlockBorderHover)
|
||||
|
||||
&.warn
|
||||
border solid 2px #dec44c
|
||||
|
||||
&.error
|
||||
border solid 2px #f00
|
||||
|
||||
& + .cpjygsrt
|
||||
margin-top 16px
|
||||
|
||||
> header
|
||||
> .title
|
||||
z-index 1
|
||||
margin 0
|
||||
padding 0 16px
|
||||
line-height 42px
|
||||
font-size 0.9em
|
||||
font-weight bold
|
||||
color var(--faceHeaderText)
|
||||
box-shadow 0 1px rgba(#000, 0.07)
|
||||
|
||||
> [data-icon]
|
||||
margin-right 6px
|
||||
|
||||
&:empty
|
||||
display none
|
||||
|
||||
> .buttons
|
||||
position absolute
|
||||
z-index 2
|
||||
top 0
|
||||
right 0
|
||||
|
||||
> button
|
||||
padding 0
|
||||
width 42px
|
||||
font-size 0.9em
|
||||
line-height 42px
|
||||
color var(--faceTextButton)
|
||||
|
||||
&:hover
|
||||
color var(--faceTextButtonHover)
|
||||
|
||||
&:active
|
||||
color var(--faceTextButtonActive)
|
||||
|
||||
.drag-handle
|
||||
cursor move
|
||||
|
||||
> .warn
|
||||
color #b19e49
|
||||
margin 0
|
||||
padding 16px 16px 0 16px
|
||||
font-size 14px
|
||||
|
||||
> .error
|
||||
color #f00
|
||||
margin 0
|
||||
padding 16px 16px 0 16px
|
||||
font-size 14px
|
||||
|
||||
</style>
|
@ -0,0 +1,271 @@
|
||||
<template>
|
||||
<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()">
|
||||
<fa :icon="faPencilAlt"/>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<section v-if="value.type === null" class="pbglfege" @click="changeType()">
|
||||
{{ $t('script.emptySlot') }}
|
||||
</section>
|
||||
<section v-else-if="value.type === 'text'" class="tbwccoaw">
|
||||
<input v-model="value.value"/>
|
||||
</section>
|
||||
<section v-else-if="value.type === 'multiLineText'" class="tbwccoaw">
|
||||
<textarea v-model="value.value"></textarea>
|
||||
</section>
|
||||
<section v-else-if="value.type === 'textList'" class="tbwccoaw">
|
||||
<textarea v-model="value.value" :placeholder="$t('script.blocks._textList.info')"></textarea>
|
||||
</section>
|
||||
<section v-else-if="value.type === 'number'" class="tbwccoaw">
|
||||
<input v-model="value.value" type="number"/>
|
||||
</section>
|
||||
<section v-else-if="value.type === 'ref'" class="hpdwcrvs">
|
||||
<select v-model="value.value">
|
||||
<option v-for="v in aiScript.getVarsByType(getExpectedType ? getExpectedType() : null).filter(x => x.name !== name)" :value="v.name">{{ v.name }}</option>
|
||||
<optgroup :label="$t('script.argVariables')">
|
||||
<option v-for="v in fnSlots" :value="v.name">{{ v.name }}</option>
|
||||
</optgroup>
|
||||
<optgroup :label="$t('script.pageVariables')">
|
||||
<option v-for="v in aiScript.getPageVarsByType(getExpectedType ? getExpectedType() : null)" :value="v">{{ v }}</option>
|
||||
</optgroup>
|
||||
<optgroup :label="$t('script.enviromentVariables')">
|
||||
<option v-for="v in aiScript.getEnvVarsByType(getExpectedType ? getExpectedType() : null)" :value="v">{{ v }}</option>
|
||||
</optgroup>
|
||||
</select>
|
||||
</section>
|
||||
<section v-else-if="value.type === 'fn'" class="" style="padding:0 16px 16px 16px;">
|
||||
<ui-textarea v-model="slots">
|
||||
<span>{{ $t('script.blocks._fn.slots') }}</span>
|
||||
<template #desc>{{ $t('script.blocks._fn.slots-info') }}</template>
|
||||
</ui-textarea>
|
||||
<x-v v-if="value.value.expression" v-model="value.value.expression" :title="$t(`script.blocks._fn.arg1`)" :get-expected-type="() => null" :ai-script="aiScript" :fn-slots="value.value.slots" :name="name"/>
|
||||
</section>
|
||||
<section v-else-if="value.type.startsWith('fn:')" class="" style="padding:16px;">
|
||||
<x-v v-for="(x, i) in value.args" v-model="value.args[i]" :title="aiScript.getVarByName(value.type.split(':')[1]).value.slots[i].name" :get-expected-type="() => null" :ai-script="aiScript" :name="name" :key="i"/>
|
||||
</section>
|
||||
<section v-else class="" style="padding:16px;">
|
||||
<x-v v-for="(x, i) in value.args" v-model="value.args[i]" :title="$t(`script.blocks._${value.type}.arg${i + 1}`)" :get-expected-type="() => _getExpectedType(i)" :ai-script="aiScript" :name="name" :fn-slots="fnSlots" :key="i"/>
|
||||
</section>
|
||||
</x-container>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import i18n from '../../../../i18n';
|
||||
import XContainer from './page-editor.container.vue';
|
||||
import { faPencilAlt, faPlug } from '@fortawesome/free-solid-svg-icons';
|
||||
import { isLiteralBlock, funcDefs, blockDefs } from '../../../../../../misc/aiscript/index';
|
||||
import * as uuid from 'uuid';
|
||||
|
||||
export default Vue.extend({
|
||||
i18n: i18n('pages'),
|
||||
|
||||
components: {
|
||||
XContainer
|
||||
},
|
||||
|
||||
inject: ['getScriptBlockList'],
|
||||
|
||||
props: {
|
||||
getExpectedType: {
|
||||
required: false,
|
||||
default: null
|
||||
},
|
||||
value: {
|
||||
required: true
|
||||
},
|
||||
title: {
|
||||
required: false
|
||||
},
|
||||
removable: {
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
aiScript: {
|
||||
required: true,
|
||||
},
|
||||
name: {
|
||||
required: true,
|
||||
},
|
||||
fnSlots: {
|
||||
required: false,
|
||||
},
|
||||
draggable: {
|
||||
required: false,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
error: null,
|
||||
warn: null,
|
||||
slots: '',
|
||||
faPencilAlt
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
icon(): any {
|
||||
if (this.value.type === null) return null;
|
||||
if (this.value.type.startsWith('fn:')) return faPlug;
|
||||
return blockDefs.find(x => x.type === this.value.type).icon;
|
||||
},
|
||||
typeText(): any {
|
||||
if (this.value.type === null) return null;
|
||||
if (this.value.type.startsWith('fn:')) return this.value.type.split(':')[1];
|
||||
return this.$t(`script.blocks.${this.value.type}`);
|
||||
},
|
||||
},
|
||||
|
||||
watch: {
|
||||
slots() {
|
||||
this.value.value.slots = this.slots.split('\n').map(x => ({
|
||||
name: x,
|
||||
type: null
|
||||
}));
|
||||
}
|
||||
},
|
||||
|
||||
beforeCreate() {
|
||||
this.$options.components.XV = require('./page-editor.script-block.vue').default;
|
||||
},
|
||||
|
||||
created() {
|
||||
if (this.value.value == null) Vue.set(this.value, 'value', null);
|
||||
|
||||
if (this.value.value && this.value.value.slots) this.slots = this.value.value.slots.map(x => x.name).join('\n');
|
||||
|
||||
this.$watch('value.type', (t) => {
|
||||
this.warn = null;
|
||||
|
||||
if (this.value.type === 'fn') {
|
||||
const id = uuid.v4();
|
||||
this.value.value = {};
|
||||
Vue.set(this.value.value, 'slots', []);
|
||||
Vue.set(this.value.value, 'expression', { id, type: null });
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.value.type && this.value.type.startsWith('fn:')) {
|
||||
const fnName = this.value.type.split(':')[1];
|
||||
const fn = this.aiScript.getVarByName(fnName);
|
||||
|
||||
const empties = [];
|
||||
for (let i = 0; i < fn.value.slots.length; i++) {
|
||||
const id = uuid.v4();
|
||||
empties.push({ id, type: null });
|
||||
}
|
||||
Vue.set(this.value, 'args', empties);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isLiteralBlock(this.value)) return;
|
||||
|
||||
const empties = [];
|
||||
for (let i = 0; i < funcDefs[this.value.type].in.length; i++) {
|
||||
const id = uuid.v4();
|
||||
empties.push({ id, type: null });
|
||||
}
|
||||
Vue.set(this.value, 'args', empties);
|
||||
|
||||
for (let i = 0; i < funcDefs[this.value.type].in.length; i++) {
|
||||
const inType = funcDefs[this.value.type].in[i];
|
||||
if (typeof inType !== 'number') {
|
||||
if (inType === 'number') this.value.args[i].type = 'number';
|
||||
if (inType === 'string') this.value.args[i].type = 'text';
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.$watch('value.args', (args) => {
|
||||
if (args == null) {
|
||||
this.warn = null;
|
||||
return;
|
||||
}
|
||||
const emptySlotIndex = args.findIndex(x => x.type === null);
|
||||
if (emptySlotIndex !== -1 && emptySlotIndex < args.length) {
|
||||
this.warn = {
|
||||
slot: emptySlotIndex
|
||||
};
|
||||
} else {
|
||||
this.warn = null;
|
||||
}
|
||||
}, {
|
||||
deep: true
|
||||
});
|
||||
|
||||
this.$watch('aiScript.variables', () => {
|
||||
if (this.type != null && this.value) {
|
||||
this.error = this.aiScript.typeCheck(this.value);
|
||||
}
|
||||
}, {
|
||||
deep: true
|
||||
});
|
||||
},
|
||||
|
||||
methods: {
|
||||
async changeType() {
|
||||
const { canceled, result: type } = await this.$root.dialog({
|
||||
type: null,
|
||||
title: this.$t('select-type'),
|
||||
select: {
|
||||
groupedItems: this.getScriptBlockList(this.getExpectedType ? this.getExpectedType() : null)
|
||||
},
|
||||
showCancelButton: true
|
||||
});
|
||||
if (canceled) return;
|
||||
this.value.type = type;
|
||||
},
|
||||
|
||||
_getExpectedType(slot: number) {
|
||||
return this.aiScript.getExpectedType(this.value, slot);
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
.turmquns
|
||||
opacity 0.7
|
||||
|
||||
.pbglfege
|
||||
opacity 0.5
|
||||
padding 16px
|
||||
text-align center
|
||||
cursor pointer
|
||||
color var(--text)
|
||||
|
||||
.tbwccoaw
|
||||
> input
|
||||
> textarea
|
||||
display block
|
||||
-webkit-appearance none
|
||||
-moz-appearance none
|
||||
appearance none
|
||||
width 100%
|
||||
max-width 100%
|
||||
min-width 100%
|
||||
border none
|
||||
box-shadow none
|
||||
padding 16px
|
||||
font-size 16px
|
||||
background transparent
|
||||
color var(--text)
|
||||
|
||||
> textarea
|
||||
min-height 100px
|
||||
|
||||
.hpdwcrvs
|
||||
padding 16px
|
||||
|
||||
> select
|
||||
display block
|
||||
padding 4px
|
||||
font-size 16px
|
||||
width 100%
|
||||
|
||||
</style>
|
@ -0,0 +1,473 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="gwbmwxkm" :class="{ shadow: $store.state.device.useShadow, round: $store.state.device.roundedCorners }">
|
||||
<header>
|
||||
<div class="title"><fa :icon="faStickyNote"/> {{ readonly ? $t('read-page') : pageId ? $t('edit-page') : $t('new-page') }}</div>
|
||||
<div class="buttons">
|
||||
<button @click="del()" v-if="!readonly"><fa :icon="faTrashAlt"/></button>
|
||||
<button @click="() => showOptions = !showOptions"><fa :icon="faCog"/></button>
|
||||
<button @click="save()" v-if="!readonly"><fa :icon="faSave"/></button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<section>
|
||||
<a class="view" v-if="pageId" :href="`/@${ author.username }/pages/${ currentName }`" target="_blank"><fa :icon="faExternalLinkSquareAlt"/> {{ $t('view-page') }}</a>
|
||||
|
||||
<ui-input v-model="title">
|
||||
<span>{{ $t('title') }}</span>
|
||||
</ui-input>
|
||||
|
||||
<template v-if="showOptions">
|
||||
<ui-input v-model="summary">
|
||||
<span>{{ $t('summary') }}</span>
|
||||
</ui-input>
|
||||
|
||||
<ui-input v-model="name">
|
||||
<template #prefix>{{ url }}/@{{ author.username }}/pages/</template>
|
||||
<span>{{ $t('url') }}</span>
|
||||
</ui-input>
|
||||
|
||||
<ui-switch v-model="alignCenter">{{ $t('align-center') }}</ui-switch>
|
||||
|
||||
<ui-select v-model="font">
|
||||
<template #label>{{ $t('font') }}</template>
|
||||
<option value="serif">{{ $t('fontSerif') }}</option>
|
||||
<option value="sans-serif">{{ $t('fontSansSerif') }}</option>
|
||||
</ui-select>
|
||||
|
||||
<div class="eyeCatch">
|
||||
<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-catching-image') }}</ui-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<x-blocks class="content" v-model="content" :ai-script="aiScript"/>
|
||||
|
||||
<ui-button @click="add()" v-if="!readonly"><fa :icon="faPlus"/></ui-button>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<ui-container :body-togglable="true">
|
||||
<template #header><fa :icon="faMagic"/> {{ $t('variables') }}</template>
|
||||
<div class="qmuvgica">
|
||||
<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>
|
||||
|
||||
<ui-info><span v-html="$t('variables-info')"></span><a @click="() => moreDetails = true" style="display:block;">{{ $t('more-details') }}</a></ui-info>
|
||||
|
||||
<template v-if="moreDetails">
|
||||
<ui-info><span v-html="$t('variables-info2')"></span></ui-info>
|
||||
<ui-info><span v-html="$t('variables-info3')"></span></ui-info>
|
||||
<ui-info><span v-html="$t('variables-info4')"></span></ui-info>
|
||||
</template>
|
||||
</div>
|
||||
</ui-container>
|
||||
|
||||
<ui-container :body-togglable="true" :expanded="false">
|
||||
<template #header><fa :icon="faCode"/> {{ $t('inspector') }}</template>
|
||||
<div style="padding:0 32px 32px 32px;">
|
||||
<ui-textarea :value="JSON.stringify(content, null, 2)" readonly tall>{{ $t('content') }}</ui-textarea>
|
||||
<ui-textarea :value="JSON.stringify(variables, null, 2)" readonly tall>{{ $t('variables') }}</ui-textarea>
|
||||
</div>
|
||||
</ui-container>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<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';
|
||||
import XVariable from './page-editor.script-block.vue';
|
||||
import XBlocks from './page-editor.blocks.vue';
|
||||
import * as uuid from 'uuid';
|
||||
import { blockDefs } from '../../../../../../misc/aiscript/index';
|
||||
import { ASTypeChecker } from '../../../../../../misc/aiscript/type-checker';
|
||||
import { url } from '../../../../config';
|
||||
import { collectPageVars } from '../../../scripts/collect-page-vars';
|
||||
|
||||
export default Vue.extend({
|
||||
i18n: i18n('pages'),
|
||||
|
||||
components: {
|
||||
XDraggable, XVariable, XBlocks
|
||||
},
|
||||
|
||||
props: {
|
||||
page: {
|
||||
type: Object,
|
||||
required: false
|
||||
},
|
||||
readonly: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
author: this.$store.state.i,
|
||||
pageId: null,
|
||||
currentName: null,
|
||||
title: '',
|
||||
summary: null,
|
||||
name: Date.now().toString(),
|
||||
eyeCatchingImage: null,
|
||||
eyeCatchingImageId: null,
|
||||
font: 'sans-serif',
|
||||
content: [],
|
||||
alignCenter: false,
|
||||
variables: [],
|
||||
aiScript: null,
|
||||
showOptions: false,
|
||||
moreDetails: false,
|
||||
url,
|
||||
faPlus, faICursor, faSave, faStickyNote, faMagic, faCog, faTrashAlt, faExternalLinkSquareAlt, faCode
|
||||
};
|
||||
},
|
||||
|
||||
watch: {
|
||||
async eyeCatchingImageId() {
|
||||
if (this.eyeCatchingImageId == null) {
|
||||
this.eyeCatchingImage = null;
|
||||
} else {
|
||||
this.eyeCatchingImage = await this.$root.api('drive/files/show', {
|
||||
fileId: this.eyeCatchingImageId,
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
created() {
|
||||
this.aiScript = new ASTypeChecker();
|
||||
|
||||
this.$watch('variables', () => {
|
||||
this.aiScript.variables = this.variables;
|
||||
}, { deep: true });
|
||||
|
||||
this.$watch('content', () => {
|
||||
this.aiScript.pageVars = collectPageVars(this.content);
|
||||
}, { deep: true });
|
||||
|
||||
if (this.page) {
|
||||
this.author = this.page.user;
|
||||
this.pageId = this.page.id;
|
||||
this.title = this.page.title;
|
||||
this.name = this.page.name;
|
||||
this.currentName = this.page.name;
|
||||
this.summary = this.page.summary;
|
||||
this.font = this.page.font;
|
||||
this.alignCenter = this.page.alignCenter;
|
||||
this.content = this.page.content;
|
||||
this.variables = this.page.variables;
|
||||
this.eyeCatchingImageId = this.page.eyeCatchingImageId;
|
||||
} else {
|
||||
const id = uuid.v4();
|
||||
this.content = [{
|
||||
id,
|
||||
type: 'text',
|
||||
text: 'Hello World!'
|
||||
}];
|
||||
}
|
||||
},
|
||||
|
||||
provide() {
|
||||
return {
|
||||
readonly: this.readonly,
|
||||
getScriptBlockList: this.getScriptBlockList,
|
||||
getPageBlockList: this.getPageBlockList
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
save() {
|
||||
if (this.pageId) {
|
||||
this.$root.api('pages/update', {
|
||||
pageId: this.pageId,
|
||||
title: this.title.trim(),
|
||||
name: this.name.trim(),
|
||||
summary: this.summary,
|
||||
font: this.font,
|
||||
alignCenter: this.alignCenter,
|
||||
content: this.content,
|
||||
variables: this.variables,
|
||||
eyeCatchingImageId: this.eyeCatchingImageId,
|
||||
}).then(page => {
|
||||
this.currentName = this.name.trim();
|
||||
this.$root.dialog({
|
||||
type: 'success',
|
||||
text: this.$t('page-updated')
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.$root.api('pages/create', {
|
||||
title: this.title.trim(),
|
||||
name: this.name.trim(),
|
||||
summary: this.summary,
|
||||
font: this.font,
|
||||
alignCenter: this.alignCenter,
|
||||
content: this.content,
|
||||
variables: this.variables,
|
||||
eyeCatchingImageId: this.eyeCatchingImageId,
|
||||
}).then(page => {
|
||||
this.pageId = page.id;
|
||||
this.currentName = this.name.trim();
|
||||
this.$root.dialog({
|
||||
type: 'success',
|
||||
text: this.$t('page-created')
|
||||
});
|
||||
this.$router.push(`/i/pages/edit/${this.pageId}`);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
del() {
|
||||
this.$root.dialog({
|
||||
type: 'warning',
|
||||
text: this.$t('are-you-sure-delete'),
|
||||
showCancelButton: true
|
||||
}).then(({ canceled }) => {
|
||||
if (canceled) return;
|
||||
this.$root.api('pages/delete', {
|
||||
pageId: this.pageId,
|
||||
}).then(() => {
|
||||
this.$root.dialog({
|
||||
type: 'success',
|
||||
text: this.$t('page-deleted')
|
||||
});
|
||||
this.$router.push(`/i/pages`);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
async add() {
|
||||
const { canceled, result: type } = await this.$root.dialog({
|
||||
type: null,
|
||||
title: this.$t('choose-block'),
|
||||
select: {
|
||||
groupedItems: this.getPageBlockList()
|
||||
},
|
||||
showCancelButton: true
|
||||
});
|
||||
if (canceled) return;
|
||||
|
||||
const id = uuid.v4();
|
||||
this.content.push({ id, type });
|
||||
},
|
||||
|
||||
async addVariable() {
|
||||
let { canceled, result: name } = await this.$root.dialog({
|
||||
title: this.$t('enter-variable-name'),
|
||||
input: {
|
||||
type: 'text',
|
||||
},
|
||||
showCancelButton: true
|
||||
});
|
||||
if (canceled) return;
|
||||
|
||||
name = name.trim();
|
||||
|
||||
if (this.aiScript.isUsedName(name)) {
|
||||
this.$root.dialog({
|
||||
type: 'error',
|
||||
text: this.$t('the-variable-name-is-already-used')
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const id = uuid.v4();
|
||||
this.variables.push({ id, name, type: null });
|
||||
},
|
||||
|
||||
removeVariable(v) {
|
||||
const i = this.variables.findIndex(x => x.name === v.name);
|
||||
const newValue = [
|
||||
...this.variables.slice(0, i),
|
||||
...this.variables.slice(i + 1)
|
||||
];
|
||||
this.variables = newValue;
|
||||
},
|
||||
|
||||
getPageBlockList() {
|
||||
return [{
|
||||
label: this.$t('content-blocks'),
|
||||
items: [
|
||||
{ value: 'section', text: this.$t('blocks.section') },
|
||||
{ value: 'text', text: this.$t('blocks.text') },
|
||||
{ value: 'image', text: this.$t('blocks.image') },
|
||||
{ value: 'textarea', text: this.$t('blocks.textarea') },
|
||||
]
|
||||
}, {
|
||||
label: this.$t('input-blocks'),
|
||||
items: [
|
||||
{ value: 'button', text: this.$t('blocks.button') },
|
||||
{ value: 'textInput', text: this.$t('blocks.textInput') },
|
||||
{ value: 'textareaInput', text: this.$t('blocks.textareaInput') },
|
||||
{ value: 'numberInput', text: this.$t('blocks.numberInput') },
|
||||
{ value: 'switch', text: this.$t('blocks.switch') },
|
||||
{ value: 'counter', text: this.$t('blocks.counter') }
|
||||
]
|
||||
}, {
|
||||
label: this.$t('special-blocks'),
|
||||
items: [
|
||||
{ value: 'if', text: this.$t('blocks.if') },
|
||||
{ value: 'post', text: this.$t('blocks.post') }
|
||||
]
|
||||
}];
|
||||
},
|
||||
|
||||
getScriptBlockList(type: string = null) {
|
||||
const list = [];
|
||||
|
||||
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);
|
||||
if (category) {
|
||||
category.items.push({
|
||||
value: block.type,
|
||||
text: this.$t(`script.blocks.${block.type}`)
|
||||
});
|
||||
} else {
|
||||
list.push({
|
||||
category: block.category,
|
||||
label: this.$t(`script.categories.${block.category}`),
|
||||
items: [{
|
||||
value: block.type,
|
||||
text: this.$t(`script.blocks.${block.type}`)
|
||||
}]
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const userFns = this.variables.filter(x => x.type === 'fn');
|
||||
if (userFns.length > 0) {
|
||||
list.unshift({
|
||||
label: this.$t(`script.categories.fn`),
|
||||
items: userFns.map(v => ({
|
||||
value: 'fn:' + v.name,
|
||||
text: v.name
|
||||
}))
|
||||
});
|
||||
}
|
||||
|
||||
return list;
|
||||
},
|
||||
|
||||
setEyeCatchingImage() {
|
||||
this.$chooseDriveFile({
|
||||
multiple: false
|
||||
}).then(file => {
|
||||
this.eyeCatchingImageId = file.id;
|
||||
});
|
||||
},
|
||||
|
||||
removeEyeCatchingImage() {
|
||||
this.eyeCatchingImageId = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
.gwbmwxkm
|
||||
overflow hidden
|
||||
background var(--face)
|
||||
margin-bottom 16px
|
||||
|
||||
&.round
|
||||
border-radius 6px
|
||||
|
||||
&.shadow
|
||||
box-shadow 0 3px 8px rgba(0, 0, 0, 0.2)
|
||||
|
||||
> header
|
||||
background var(--faceHeader)
|
||||
|
||||
> .title
|
||||
z-index 1
|
||||
margin 0
|
||||
padding 0 16px
|
||||
line-height 42px
|
||||
font-size 0.9em
|
||||
font-weight bold
|
||||
color var(--faceHeaderText)
|
||||
box-shadow 0 var(--lineWidth) rgba(#000, 0.07)
|
||||
|
||||
> [data-icon]
|
||||
margin-right 6px
|
||||
|
||||
&:empty
|
||||
display none
|
||||
|
||||
> .buttons
|
||||
position absolute
|
||||
z-index 2
|
||||
top 0
|
||||
right 0
|
||||
|
||||
> button
|
||||
padding 0
|
||||
width 42px
|
||||
font-size 0.9em
|
||||
line-height 42px
|
||||
color var(--faceTextButton)
|
||||
|
||||
&:hover
|
||||
color var(--faceTextButtonHover)
|
||||
|
||||
&:active
|
||||
color var(--faceTextButtonActive)
|
||||
|
||||
> section
|
||||
padding 0 32px 32px 32px
|
||||
|
||||
@media (max-width 500px)
|
||||
padding 0 16px 16px 16px
|
||||
|
||||
> .view
|
||||
display inline-block
|
||||
margin 16px 0 0 0
|
||||
font-size 14px
|
||||
|
||||
> .content
|
||||
margin-bottom 16px
|
||||
|
||||
> .eyeCatch
|
||||
margin-bottom 16px
|
||||
|
||||
> div
|
||||
> img
|
||||
max-width 100%
|
||||
|
||||
.qmuvgica
|
||||
padding 32px
|
||||
|
||||
@media (max-width 500px)
|
||||
padding 16px
|
||||
|
||||
> .variables
|
||||
margin-bottom 16px
|
||||
|
||||
> .add
|
||||
margin-bottom 16px
|
||||
|
||||
</style>
|
141
src/client/app/common/views/components/page-preview.vue
Normal file
141
src/client/app/common/views/components/page-preview.vue
Normal file
@ -0,0 +1,141 @@
|
||||
<template>
|
||||
<router-link :to="`/@${page.user.username}/pages/${page.name}`" class="vhpxefrj" tabindex="-1" :class="{ shadow: $store.state.device.useShadow, round: $store.state.device.roundedCorners }">
|
||||
<div class="thumbnail" v-if="page.eyeCatchingImage" :style="`background-image: url('${page.eyeCatchingImage.thumbnailUrl}')`"></div>
|
||||
<article>
|
||||
<header>
|
||||
<h1 :title="page.title">{{ page.title }}</h1>
|
||||
</header>
|
||||
<p v-if="page.summary" :title="page.summary">{{ page.summary.length > 85 ? page.summary.slice(0, 85) + '…' : page.summary }}</p>
|
||||
<footer>
|
||||
<img class="icon" :src="page.user.avatarUrl"/>
|
||||
<p>{{ page.user | userName }}</p>
|
||||
</footer>
|
||||
</article>
|
||||
</router-link>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
|
||||
export default Vue.extend({
|
||||
props: {
|
||||
page: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
.vhpxefrj
|
||||
display block
|
||||
overflow hidden
|
||||
width 100%
|
||||
background var(--face)
|
||||
|
||||
&.round
|
||||
border-radius 8px
|
||||
|
||||
&.shadow
|
||||
box-shadow 0 4px 16px rgba(#000, 0.1)
|
||||
|
||||
@media (min-width 500px)
|
||||
box-shadow 0 8px 32px rgba(#000, 0.1)
|
||||
|
||||
> .thumbnail
|
||||
position absolute
|
||||
width 100px
|
||||
height 100%
|
||||
background-position center
|
||||
background-size cover
|
||||
display flex
|
||||
justify-content center
|
||||
align-items center
|
||||
|
||||
> button
|
||||
font-size 3.5em
|
||||
opacity: 0.7
|
||||
|
||||
&:hover
|
||||
font-size 4em
|
||||
opacity 0.9
|
||||
|
||||
& + article
|
||||
left 100px
|
||||
width calc(100% - 100px)
|
||||
|
||||
> article
|
||||
padding 16px
|
||||
|
||||
> header
|
||||
margin-bottom 8px
|
||||
|
||||
> h1
|
||||
margin 0
|
||||
font-size 1em
|
||||
color var(--urlPreviewTitle)
|
||||
|
||||
> p
|
||||
margin 0
|
||||
color var(--urlPreviewText)
|
||||
font-size 0.8em
|
||||
|
||||
> footer
|
||||
margin-top 8px
|
||||
height 16px
|
||||
|
||||
> img
|
||||
display inline-block
|
||||
width 16px
|
||||
height 16px
|
||||
margin-right 4px
|
||||
vertical-align top
|
||||
|
||||
> p
|
||||
display inline-block
|
||||
margin 0
|
||||
color var(--urlPreviewInfo)
|
||||
font-size 0.8em
|
||||
line-height 16px
|
||||
vertical-align top
|
||||
|
||||
@media (max-width 700px)
|
||||
> .thumbnail
|
||||
position relative
|
||||
width 100%
|
||||
height 100px
|
||||
|
||||
& + article
|
||||
left 0
|
||||
width 100%
|
||||
|
||||
@media (max-width 550px)
|
||||
font-size 12px
|
||||
|
||||
> .thumbnail
|
||||
height 80px
|
||||
|
||||
> article
|
||||
padding 12px
|
||||
|
||||
@media (max-width 500px)
|
||||
font-size 10px
|
||||
|
||||
> .thumbnail
|
||||
height 70px
|
||||
|
||||
> article
|
||||
padding 8px
|
||||
|
||||
> header
|
||||
margin-bottom 4px
|
||||
|
||||
> footer
|
||||
margin-top 4px
|
||||
|
||||
> img
|
||||
width 12px
|
||||
height 12px
|
||||
|
||||
</style>
|
@ -9,7 +9,7 @@
|
||||
</template>
|
||||
<div v-if="data && !$store.state.i.twoFactorEnabled">
|
||||
<ol>
|
||||
<li>{{ $t('authenticator') }}<a href="https://support.google.com/accounts/answer/1066447" target="_blank">{{ $t('howtoinstall') }}</a></li>
|
||||
<li>{{ $t('authenticator') }}<a href="https://support.google.com/accounts/answer/1066447" rel="noopener" target="_blank">{{ $t('howtoinstall') }}</a></li>
|
||||
<li>{{ $t('scan') }}<br><img :src="data.qr"></li>
|
||||
<li>{{ $t('done') }}<br>
|
||||
<ui-input v-model="token">{{ $t('token') }}</ui-input>
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
<section>
|
||||
<header><fa icon="terminal"/> {{ $t('console.title') }}</header>
|
||||
<ui-input v-model="endpoint" :datalist="endpoints">
|
||||
<ui-input v-model="endpoint" :datalist="endpoints" @change="onEndpointChange()">
|
||||
<span>{{ $t('console.endpoint') }}</span>
|
||||
</ui-input>
|
||||
<ui-textarea v-model="body">
|
||||
@ -80,6 +80,22 @@ export default Vue.extend({
|
||||
this.sending = false;
|
||||
this.res = JSON5.stringify(err, null, 2);
|
||||
});
|
||||
},
|
||||
|
||||
onEndpointChange() {
|
||||
this.$root.api('endpoint', { endpoint: this.endpoint }).then(endpoint => {
|
||||
const body = {};
|
||||
for (const p of endpoint.params) {
|
||||
body[p.name] =
|
||||
p.type === 'String' ? '' :
|
||||
p.type === 'Number' ? 0 :
|
||||
p.type === 'Boolean' ? false :
|
||||
p.type === 'Array' ? [] :
|
||||
p.type === 'Object' ? {} :
|
||||
null;
|
||||
}
|
||||
this.body = JSON5.stringify(body, null, 2);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -4,21 +4,21 @@
|
||||
|
||||
<section v-if="enableTwitterIntegration">
|
||||
<header><fa :icon="['fab', 'twitter']"/> Twitter</header>
|
||||
<p v-if="$store.state.i.twitter">{{ $t('connected-to') }}: <a :href="`https://twitter.com/${$store.state.i.twitter.screenName}`" target="_blank">@{{ $store.state.i.twitter.screenName }}</a></p>
|
||||
<p v-if="$store.state.i.twitter">{{ $t('connected-to') }}: <a :href="`https://twitter.com/${$store.state.i.twitter.screenName}`" rel="nofollow noopener" target="_blank">@{{ $store.state.i.twitter.screenName }}</a></p>
|
||||
<ui-button v-if="$store.state.i.twitter" @click="disconnectTwitter">{{ $t('disconnect') }}</ui-button>
|
||||
<ui-button v-else @click="connectTwitter">{{ $t('connect') }}</ui-button>
|
||||
</section>
|
||||
|
||||
<section v-if="enableDiscordIntegration">
|
||||
<header><fa :icon="['fab', 'discord']"/> Discord</header>
|
||||
<p v-if="$store.state.i.discord">{{ $t('connected-to') }}: <a :href="`https://discordapp.com/users/${$store.state.i.discord.id}`" target="_blank">@{{ $store.state.i.discord.username }}#{{ $store.state.i.discord.discriminator }}</a></p>
|
||||
<p v-if="$store.state.i.discord">{{ $t('connected-to') }}: <a :href="`https://discordapp.com/users/${$store.state.i.discord.id}`" rel="nofollow noopener" target="_blank">@{{ $store.state.i.discord.username }}#{{ $store.state.i.discord.discriminator }}</a></p>
|
||||
<ui-button v-if="$store.state.i.discord" @click="disconnectDiscord">{{ $t('disconnect') }}</ui-button>
|
||||
<ui-button v-else @click="connectDiscord">{{ $t('connect') }}</ui-button>
|
||||
</section>
|
||||
|
||||
<section v-if="enableGithubIntegration">
|
||||
<header><fa :icon="['fab', 'github']"/> GitHub</header>
|
||||
<p v-if="$store.state.i.github">{{ $t('connected-to') }}: <a :href="`https://github.com/${$store.state.i.github.login}`" target="_blank">@{{ $store.state.i.github.login }}</a></p>
|
||||
<p v-if="$store.state.i.github">{{ $t('connected-to') }}: <a :href="`https://github.com/${$store.state.i.github.login}`" rel="nofollow noopener" target="_blank">@{{ $store.state.i.github.login }}</a></p>
|
||||
<ui-button v-if="$store.state.i.github" @click="disconnectGithub">{{ $t('disconnect') }}</ui-button>
|
||||
<ui-button v-else @click="connectGithub">{{ $t('connect') }}</ui-button>
|
||||
</section>
|
||||
@ -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();
|
||||
|
@ -290,12 +290,17 @@ export default Vue.extend({
|
||||
this.exportTarget == 'mute' ? 'i/export-mute' :
|
||||
this.exportTarget == 'blocking' ? 'i/export-blocking' :
|
||||
this.exportTarget == 'user-lists' ? 'i/export-user-lists' :
|
||||
null, {});
|
||||
|
||||
this.$root.dialog({
|
||||
type: 'info',
|
||||
text: this.$t('export-requested')
|
||||
});
|
||||
null, {}).then(() => {
|
||||
this.$root.dialog({
|
||||
type: 'info',
|
||||
text: this.$t('export-requested')
|
||||
});
|
||||
}).catch((e: any) => {
|
||||
this.$root.dialog({
|
||||
type: 'error',
|
||||
text: e.message
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
doImport() {
|
||||
|
@ -543,8 +543,8 @@ export default Vue.extend({
|
||||
});
|
||||
} else {
|
||||
this.$root.dialog({
|
||||
title: this.$t('update-available'),
|
||||
text: this.$t('update-available-desc')
|
||||
title: this.$t('@._settings.update-available'),
|
||||
text: this.$t('@._settings.update-available-desc')
|
||||
});
|
||||
}
|
||||
});
|
||||
|
@ -45,7 +45,7 @@
|
||||
</ui-select>
|
||||
</label>
|
||||
|
||||
<a href="https://assets.msky.cafe/theme/list" target="_blank">{{ $t('find-more-theme') }}</a>
|
||||
<a href="https://assets.msky.cafe/theme/list" rel="noopener" target="_blank">{{ $t('find-more-theme') }}</a>
|
||||
|
||||
<details class="creator">
|
||||
<summary><fa icon="palette"/> {{ $t('create-a-theme') }}</summary>
|
||||
@ -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>
|
||||
|
||||
|
@ -37,8 +37,13 @@
|
||||
<p v-if="passwordRetypeState == 'not-match'" style="color:#FF1161"><fa icon="exclamation-triangle" fixed-width/> {{ $t('password-not-matched') }}</p>
|
||||
</template>
|
||||
</ui-input>
|
||||
<ui-switch v-model="ToSAgreement" v-if="meta.ToSUrl">
|
||||
<i18n path="agree-to">
|
||||
<a :href="meta.ToSUrl" target="_blank">{{ $t('tos') }}</a>
|
||||
</i18n>
|
||||
</ui-switch>
|
||||
<div v-if="meta.enableRecaptcha" class="g-recaptcha" :data-sitekey="meta.recaptchaSiteKey" style="margin: 16px 0;"></div>
|
||||
<ui-button type="submit">{{ $t('create') }}</ui-button>
|
||||
<ui-button type="submit" :disabled="!(meta.ToSUrl ? ToSAgreement : true)">{{ $t('create') }}</ui-button>
|
||||
</template>
|
||||
</form>
|
||||
</template>
|
||||
@ -64,7 +69,8 @@ export default Vue.extend({
|
||||
usernameState: null,
|
||||
passwordStrength: '',
|
||||
passwordRetypeState: null,
|
||||
meta: null
|
||||
meta: {},
|
||||
ToSAgreement: false
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
<p class="empty" v-else-if="tags.length == 0"><fa icon="exclamation-circle"/>{{ $t('empty') }}</p>
|
||||
<div v-else>
|
||||
<vue-word-cloud
|
||||
:words="tags.slice(0, 20).map(x => [x.name, x.count])"
|
||||
:words="tags.slice(0, 20).map(x => [x.tag, x.count])"
|
||||
:color="color"
|
||||
:spacing="1">
|
||||
<template slot-scope="{word, text, weight}">
|
||||
@ -43,7 +43,7 @@ export default Vue.extend({
|
||||
},
|
||||
methods: {
|
||||
fetch() {
|
||||
this.$root.api('aggregation/hashtags').then(tags => {
|
||||
this.$root.api('hashtags/trend').then(tags => {
|
||||
this.tags = tags;
|
||||
this.fetching = false;
|
||||
});
|
||||
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<component class="dmtdnykelhudezerjlfpbhgovrgnqqgr"
|
||||
:is="link ? 'a' : 'button'"
|
||||
:class="{ inline, primary, wait }"
|
||||
:class="{ inline, primary, wait, round: $store.state.device.roundedCorners }"
|
||||
:type="type"
|
||||
@click="$emit('click')"
|
||||
@mousedown="onMousedown"
|
||||
@ -116,7 +116,6 @@ export default Vue.extend({
|
||||
font-size 16px
|
||||
line-height 24px
|
||||
border none
|
||||
border-radius 6px
|
||||
outline none
|
||||
box-shadow none
|
||||
text-decoration none
|
||||
@ -124,6 +123,9 @@ export default Vue.extend({
|
||||
color var(--text)
|
||||
background var(--buttonBg)
|
||||
|
||||
&.round
|
||||
border-radius 6px
|
||||
|
||||
&:not(:disabled):hover
|
||||
background var(--buttonHoverBg)
|
||||
|
||||
@ -157,7 +159,9 @@ export default Vue.extend({
|
||||
bottom -5px
|
||||
left -5px
|
||||
border 2px solid var(--primaryAlpha03)
|
||||
border-radius 10px
|
||||
|
||||
&.round:focus:after
|
||||
border-radius 10px
|
||||
|
||||
&:not(.inline) + .dmtdnykelhudezerjlfpbhgovrgnqqgr
|
||||
margin-top 16px
|
||||
@ -197,7 +201,6 @@ export default Vue.extend({
|
||||
left 0
|
||||
width 100%
|
||||
height 100%
|
||||
border-radius 6px
|
||||
overflow hidden
|
||||
|
||||
>>> div
|
||||
@ -210,6 +213,9 @@ export default Vue.extend({
|
||||
transform scale(1)
|
||||
transition all 0.5s cubic-bezier(0, .5, .5, 1)
|
||||
|
||||
&.round > .ripples
|
||||
border-radius 6px
|
||||
|
||||
&.primary > .ripples >>> div
|
||||
background rgba(0, 0, 0, 0.15)
|
||||
|
||||
|
@ -23,6 +23,7 @@
|
||||
@focus="focused = true"
|
||||
@blur="focused = false"
|
||||
@keydown="$emit('keydown', $event)"
|
||||
@change="$emit('change', $event)"
|
||||
:list="id"
|
||||
>
|
||||
<input v-else ref="input"
|
||||
@ -38,6 +39,7 @@
|
||||
@focus="focused = true"
|
||||
@blur="focused = false"
|
||||
@keydown="$emit('keydown', $event)"
|
||||
@change="$emit('change', $event)"
|
||||
:list="id"
|
||||
>
|
||||
<datalist :id="id" v-if="datalist">
|
||||
@ -60,7 +62,7 @@
|
||||
<div class="suffix" ref="suffix"><slot name="suffix"></slot></div>
|
||||
</div>
|
||||
<div class="toggle" v-if="withPasswordToggle">
|
||||
<a @click='togglePassword'>
|
||||
<a @click="togglePassword">
|
||||
<span v-if="type == 'password'"><fa :icon="['fa', 'eye']"/> {{ $t('@.show-password') }}</span>
|
||||
<span v-if="type != 'password'"><fa :icon="['far', 'eye-slash']"/> {{ $t('@.hide-password') }}</span>
|
||||
</a>
|
||||
@ -182,7 +184,11 @@ export default Vue.extend({
|
||||
this.v = v;
|
||||
},
|
||||
v(v) {
|
||||
this.$emit('input', v);
|
||||
if (this.type === 'number') {
|
||||
this.$emit('input', parseInt(v, 10));
|
||||
} else {
|
||||
this.$emit('input', v);
|
||||
}
|
||||
|
||||
if (this.withPasswordMeter) {
|
||||
if (v == '') {
|
||||
@ -316,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';
|
||||
|
@ -38,10 +38,10 @@ export default Vue.extend({
|
||||
const data = new FormData();
|
||||
data.append('md5', getMD5(fileData));
|
||||
|
||||
this.$root.api('drive/files/check_existence', {
|
||||
this.$root.api('drive/files/find-by-hash', {
|
||||
md5: getMD5(fileData)
|
||||
}).then(resp => {
|
||||
resolve(resp.file);
|
||||
resolve(resp.length > 0 ? resp[0] : null);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
@ -9,7 +9,7 @@
|
||||
</blockquote>
|
||||
</div>
|
||||
<div v-else class="mk-url-preview">
|
||||
<a :class="{ mini: narrow, compact }" :href="url" target="_blank" :title="url" v-if="!fetching">
|
||||
<a :class="{ mini: narrow, compact }" :href="url" rel="nofollow noopener" target="_blank" :title="url" v-if="!fetching">
|
||||
<div class="thumbnail" v-if="thumbnail" :style="`background-image: url('${thumbnail}')`">
|
||||
<button v-if="!playerEnabled && player.url" @click.prevent="playerEnabled = true" :title="$t('enable-player')"><fa :icon="['far', 'play-circle']"/></button>
|
||||
</div>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<a class="mk-url" :href="url" :target="target">
|
||||
<a class="mk-url" :href="url" :rel="rel" :target="target">
|
||||
<span class="schema">{{ schema }}//</span>
|
||||
<span class="hostname">{{ hostname }}</span>
|
||||
<span class="port" v-if="port != ''">:{{ port }}</span>
|
||||
@ -15,7 +15,7 @@ import Vue from 'vue';
|
||||
import { toUnicode as decodePunycode } from 'punycode';
|
||||
|
||||
export default Vue.extend({
|
||||
props: ['url', 'target'],
|
||||
props: ['url', 'rel', 'target'],
|
||||
data() {
|
||||
return {
|
||||
schema: null,
|
||||
|
@ -77,11 +77,11 @@ export default Vue.extend({
|
||||
input: {
|
||||
default: this.list.name
|
||||
}
|
||||
}).then(({ canceled, result: title }) => {
|
||||
}).then(({ canceled, result: name }) => {
|
||||
if (canceled) return;
|
||||
this.$root.api('users/lists/update', {
|
||||
listId: this.list.id,
|
||||
title: title
|
||||
name: name
|
||||
});
|
||||
});
|
||||
},
|
||||
|
@ -60,9 +60,9 @@ export default Vue.extend({
|
||||
},
|
||||
|
||||
methods: {
|
||||
init() {
|
||||
async init() {
|
||||
this.fetching = true;
|
||||
this.makePromise().then(x => {
|
||||
await (this.makePromise()).then(x => {
|
||||
if (Array.isArray(x)) {
|
||||
this.us = x;
|
||||
} else {
|
||||
@ -76,9 +76,9 @@ export default Vue.extend({
|
||||
});
|
||||
},
|
||||
|
||||
fetchMoreUsers() {
|
||||
async fetchMoreUsers() {
|
||||
this.fetchingMoreUsers = true;
|
||||
this.makePromise(this.cursor).then(x => {
|
||||
await (this.makePromise(this.cursor)).then(x => {
|
||||
this.us = this.us.concat(x.users);
|
||||
this.cursor = x.cursor;
|
||||
this.fetchingMoreUsers = false;
|
||||
@ -166,7 +166,7 @@ export default Vue.extend({
|
||||
> .follow-button
|
||||
position absolute
|
||||
top 8px
|
||||
right 0px
|
||||
right 0
|
||||
|
||||
> .more
|
||||
display block
|
||||
|
@ -28,10 +28,10 @@ export default Vue.extend({
|
||||
this.$root.dialog({
|
||||
title: this.$t('list-name'),
|
||||
input: true
|
||||
}).then(async ({ canceled, result: title }) => {
|
||||
}).then(async ({ canceled, result: name }) => {
|
||||
if (canceled) return;
|
||||
const list = await this.$root.api('users/lists/create', {
|
||||
title
|
||||
name
|
||||
});
|
||||
|
||||
this.lists.push(list)
|
||||
|
@ -7,7 +7,6 @@
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import i18n from '../../../i18n';
|
||||
import copyToClipboard from '../../../common/scripts/copy-to-clipboard';
|
||||
import { faExclamationCircle, faMicrophoneSlash } from '@fortawesome/free-solid-svg-icons';
|
||||
import { faSnowflake } from '@fortawesome/free-regular-svg-icons';
|
||||
|
||||
@ -27,19 +26,23 @@ export default Vue.extend({
|
||||
icon: ['fas', 'list'],
|
||||
text: this.$t('push-to-list'),
|
||||
action: this.pushList
|
||||
}, null, {
|
||||
icon: this.user.isMuted ? ['fas', 'eye'] : ['far', 'eye-slash'],
|
||||
text: this.user.isMuted ? this.$t('unmute') : this.$t('mute'),
|
||||
action: this.toggleMute
|
||||
}, {
|
||||
icon: 'ban',
|
||||
text: this.user.isBlocking ? this.$t('unblock') : this.$t('block'),
|
||||
action: this.toggleBlock
|
||||
}, null, {
|
||||
icon: faExclamationCircle,
|
||||
text: this.$t('report-abuse'),
|
||||
action: this.reportAbuse
|
||||
}];
|
||||
}] as any;
|
||||
|
||||
if (this.$store.getters.isSignedIn && this.$store.state.i.id != this.user.id) {
|
||||
menu = menu.concat([null, {
|
||||
icon: this.user.isMuted ? ['fas', 'eye'] : ['far', 'eye-slash'],
|
||||
text: this.user.isMuted ? this.$t('unmute') : this.$t('mute'),
|
||||
action: this.toggleMute
|
||||
}, {
|
||||
icon: 'ban',
|
||||
text: this.user.isBlocking ? this.$t('unblock') : this.$t('block'),
|
||||
action: this.toggleBlock
|
||||
}, null, {
|
||||
icon: faExclamationCircle,
|
||||
text: this.$t('report-abuse'),
|
||||
action: this.reportAbuse
|
||||
}]);
|
||||
}
|
||||
|
||||
if (this.$store.getters.isSignedIn && (this.$store.state.i.isAdmin || this.$store.state.i.isModerator)) {
|
||||
menu = menu.concat([null, {
|
||||
|
@ -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');
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
<div class="is-remote" v-if="note.user.host != null">
|
||||
<details>
|
||||
<summary><fa icon="exclamation-triangle"/> {{ $t('@.is-remote-post') }}</summary>
|
||||
<a :href="note.url || note.uri" target="_blank">{{ $t('@.view-on-remote') }}</a>
|
||||
<a :href="note.url || note.uri" rel="nofollow noopener" target="_blank">{{ $t('@.view-on-remote') }}</a>
|
||||
</details>
|
||||
</div>
|
||||
<mk-note :note="note" :detail="true" :key="note.id"/>
|
||||
|
@ -110,11 +110,11 @@ export default Vue.extend({
|
||||
this.init();
|
||||
},
|
||||
|
||||
init() {
|
||||
async init() {
|
||||
this.queue = [];
|
||||
this.notes = [];
|
||||
this.fetching = true;
|
||||
this.makePromise().then(x => {
|
||||
await (this.makePromise()).then(x => {
|
||||
if (Array.isArray(x)) {
|
||||
this.notes = x;
|
||||
} else {
|
||||
@ -129,10 +129,10 @@ export default Vue.extend({
|
||||
});
|
||||
},
|
||||
|
||||
fetchMore() {
|
||||
async fetchMore() {
|
||||
if (!this.more || this.moreFetching) return;
|
||||
this.moreFetching = true;
|
||||
this.makePromise(this.notes[this.notes.length - 1].id).then(x => {
|
||||
await (this.makePromise(this.notes[this.notes.length - 1].id)).then(x => {
|
||||
this.notes = this.notes.concat(x.notes);
|
||||
this.more = x.more;
|
||||
this.moreFetching = false;
|
||||
|
@ -14,6 +14,7 @@
|
||||
import Vue from 'vue';
|
||||
import XColumn from './deck.column.vue';
|
||||
import XNotes from './deck.notes.vue';
|
||||
import { genSearchQuery } from '../../../common/scripts/gen-search-query';
|
||||
|
||||
const limit = 20;
|
||||
|
||||
@ -25,10 +26,10 @@ export default Vue.extend({
|
||||
|
||||
data() {
|
||||
return {
|
||||
makePromise: cursor => this.$root.api('notes/search', {
|
||||
makePromise: async cursor => this.$root.api('notes/search', {
|
||||
limit: limit + 1,
|
||||
offset: cursor ? cursor : undefined,
|
||||
query: this.q
|
||||
...(await genSearchQuery(this, this.q))
|
||||
}).then(notes => {
|
||||
if (notes.length == limit + 1) {
|
||||
notes.pop();
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user