Compare commits
42 Commits
Author | SHA1 | Date | |
---|---|---|---|
1a2a190828 | |||
251cf1d76f | |||
52774bbe64 | |||
68a6758302 | |||
13e43a4f74 | |||
b7d62d09ec | |||
321ec18173 | |||
a44ac3306e | |||
951288ecf0 | |||
cc8a7dd588 | |||
813c52f51e | |||
be3298639d | |||
e8d2959717 | |||
e7680e08eb | |||
bd792d7661 | |||
4920983f23 | |||
2756f553c6 | |||
fc52e95ad0 | |||
5d1d6bc028 | |||
b106acac91 | |||
a5071db864 | |||
bae874eb45 | |||
60da17940d | |||
385eeed732 | |||
2e908758d8 | |||
a164f8ad95 | |||
372138dfea | |||
922a657c7e | |||
3409a51cca | |||
7174a55846 | |||
6656a59402 | |||
7612ead551 | |||
fa78fe665d | |||
c89aa7eb95 | |||
43f4c5b7cd | |||
2b6c566386 | |||
91ef328b6b | |||
5a9d9dc41d | |||
a48e503caa | |||
fe00cb9ad5 | |||
ed0fdaddbd | |||
893795a31d |
18
CHANGELOG.md
18
CHANGELOG.md
@ -1,6 +1,24 @@
|
|||||||
ChangeLog
|
ChangeLog
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
10.89.0
|
||||||
|
----------
|
||||||
|
* APIのエラーの形式を統一
|
||||||
|
* APIドキュメント刷新
|
||||||
|
* /api/v1/instance/peers 復活
|
||||||
|
* 「返信が遷移後も残り続ける問題を修正」([9beddc9](https://github.com/syuilo/misskey/commit/9beddc941a716f1322ae0b7d71d159edd642a399)) によって遷移前に返信が表示されなくなった問題を修正
|
||||||
|
* デッキモードにてユーザーのプロフィールを連続で見たとき、アクティビティや画像が前のユーザーのもののまま表示される問題を修正
|
||||||
|
|
||||||
|
10.88.0
|
||||||
|
----------
|
||||||
|
* アカウントの削除を試験的に実装
|
||||||
|
* デッキでメディア投稿のみ表示するオプションが機能していない問題を修正
|
||||||
|
* デッキでユーザーを表示したときにタイムラインが残存する問題を修正
|
||||||
|
* モバイルのユーザーページで、ユーザーAのタイムラインから他のユーザーBを選択してユーザーBのタイムラインに移動したとき、ユーザーAのタイムラインが残る問題を修正
|
||||||
|
* ハイライトでミュートしているユーザーの投稿が含まれる問題を修正
|
||||||
|
* 「みつける」でミュートしているユーザーが含まれる問題を修正
|
||||||
|
* デザインの調整
|
||||||
|
|
||||||
10.87.5
|
10.87.5
|
||||||
----------
|
----------
|
||||||
* モバイル版でも連携サービスを表示するように
|
* モバイル版でも連携サービスを表示するように
|
||||||
|
@ -106,7 +106,6 @@ Please see the [Contribution Guide](./CONTRIBUTING.md).
|
|||||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/12913507/f7181eacafe8469a93033d85f5969c29/3?token-time=2145916800&token-hash=c8HeVqLtmdgH-gSBJg8i10gmOcwllM87MDHeznl3el0%3D" alt="Melilot" width="100"></td>
|
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/12913507/f7181eacafe8469a93033d85f5969c29/3?token-time=2145916800&token-hash=c8HeVqLtmdgH-gSBJg8i10gmOcwllM87MDHeznl3el0%3D" alt="Melilot" width="100"></td>
|
||||||
<td><img src="https://c8.patreon.com/2/200/16869916" alt="見当かなみ" width="100"></td>
|
<td><img src="https://c8.patreon.com/2/200/16869916" alt="見当かなみ" width="100"></td>
|
||||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/12999811/5f349fafcce44dd1824a8b1ebbec4564/3?token-time=2145916800&token-hash=LtV2lRi3L2jOWMLwccr9qWYfPrFlzIo2jYZHKzHEb6k%3D" alt="Xeltica" width="100"></td>
|
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/12999811/5f349fafcce44dd1824a8b1ebbec4564/3?token-time=2145916800&token-hash=LtV2lRi3L2jOWMLwccr9qWYfPrFlzIo2jYZHKzHEb6k%3D" alt="Xeltica" width="100"></td>
|
||||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/3384329/8b713330cb27404ea6e9fac50ff96efe/1?token-time=2145916800&token-hash=Ch3iF81ZGP0LMo894Y9ajpLisgtE91SnxtZE7fxsgrM%3D" alt="べすれい" width="100"></td>
|
|
||||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/12021162/963128bb8d14476dbd8407943db8f31a/1?token-time=2145916800&token-hash=1FlxS9MEgmNGH_RHUVHbO5hIXB5I1z0lvA33CTvYvjA%3D" alt="gutfuckllc" width="100"></td>
|
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/12021162/963128bb8d14476dbd8407943db8f31a/1?token-time=2145916800&token-hash=1FlxS9MEgmNGH_RHUVHbO5hIXB5I1z0lvA33CTvYvjA%3D" alt="gutfuckllc" width="100"></td>
|
||||||
</tr><tr>
|
</tr><tr>
|
||||||
<td><a href="https://www.patreon.com/weepjp">weep</a></td>
|
<td><a href="https://www.patreon.com/weepjp">weep</a></td>
|
||||||
@ -114,7 +113,6 @@ Please see the [Contribution Guide](./CONTRIBUTING.md).
|
|||||||
<td><a href="https://www.patreon.com/user?u=12913507">Melilot</a></td>
|
<td><a href="https://www.patreon.com/user?u=12913507">Melilot</a></td>
|
||||||
<td><a href="https://www.patreon.com/user?u=16869916">見当かなみ</a></td>
|
<td><a href="https://www.patreon.com/user?u=16869916">見当かなみ</a></td>
|
||||||
<td><a href="https://www.patreon.com/Xeltica">Xeltica</a></td>
|
<td><a href="https://www.patreon.com/Xeltica">Xeltica</a></td>
|
||||||
<td><a href="https://www.patreon.com/user?u=3384329">べすれい</a></td>
|
|
||||||
<td><a href="https://www.patreon.com/gutfuckllc">gutfuckllc</a></td>
|
<td><a href="https://www.patreon.com/gutfuckllc">gutfuckllc</a></td>
|
||||||
</tr></table>
|
</tr></table>
|
||||||
<table><tr>
|
<table><tr>
|
||||||
@ -152,7 +150,7 @@ Please see the [Contribution Guide](./CONTRIBUTING.md).
|
|||||||
<td><a href="https://www.patreon.com/user?u=12531784">Takashi Shibuya</a></td>
|
<td><a href="https://www.patreon.com/user?u=12531784">Takashi Shibuya</a></td>
|
||||||
</tr></table>
|
</tr></table>
|
||||||
|
|
||||||
**Last updated:** Fri, 15 Feb 2019 19:12:06 UTC
|
**Last updated:** Thu, 21 Feb 2019 16:10:06 UTC
|
||||||
<!-- PATREON_END -->
|
<!-- PATREON_END -->
|
||||||
|
|
||||||
:four_leaf_clover: Copyright
|
:four_leaf_clover: Copyright
|
||||||
|
BIN
assets/api-doc.png
Normal file
BIN
assets/api-doc.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.9 KiB |
@ -55,14 +55,9 @@ As root:
|
|||||||
*6.* Build Misskey
|
*6.* Build Misskey
|
||||||
----------------------------------------------------------------
|
----------------------------------------------------------------
|
||||||
|
|
||||||
Before build, you need to set `NODE_ENV` to `production`. like this:
|
|
||||||
* Linux: `export NODE_ENV=production`
|
|
||||||
* Windows (PowerShell): `$env:NODE_ENV="production"`
|
|
||||||
* Windows (CMD): `set NODE_ENV=production`
|
|
||||||
|
|
||||||
Build misskey with the following:
|
Build misskey with the following:
|
||||||
|
|
||||||
`npm run build`
|
`NODE_ENV=production npm run build`
|
||||||
|
|
||||||
If you're on Debian, you will need to install the `build-essential`, `python` package.
|
If you're on Debian, you will need to install the `build-essential`, `python` package.
|
||||||
|
|
||||||
@ -71,14 +66,14 @@ If you're still encountering errors about some modules, use node-gyp:
|
|||||||
1. `npm install -g node-gyp`
|
1. `npm install -g node-gyp`
|
||||||
2. `node-gyp configure`
|
2. `node-gyp configure`
|
||||||
3. `node-gyp build`
|
3. `node-gyp build`
|
||||||
4. `npm run build`
|
4. `NODE_ENV=production npm run build`
|
||||||
|
|
||||||
*7.* That is it.
|
*7.* That is it.
|
||||||
----------------------------------------------------------------
|
----------------------------------------------------------------
|
||||||
Well done! Now, you have an environment that run to Misskey.
|
Well done! Now, you have an environment that run to Misskey.
|
||||||
|
|
||||||
### Launch normally
|
### Launch normally
|
||||||
Just `npm start`. GLHF!
|
Just `NODE_ENV=production npm start`. GLHF!
|
||||||
|
|
||||||
### Launch with systemd
|
### Launch with systemd
|
||||||
|
|
||||||
@ -94,6 +89,7 @@ Type=simple
|
|||||||
User=misskey
|
User=misskey
|
||||||
ExecStart=/usr/bin/npm start
|
ExecStart=/usr/bin/npm start
|
||||||
WorkingDirectory=/home/misskey/misskey
|
WorkingDirectory=/home/misskey/misskey
|
||||||
|
Environment="NODE_ENV=production"
|
||||||
TimeoutSec=60
|
TimeoutSec=60
|
||||||
StandardOutput=syslog
|
StandardOutput=syslog
|
||||||
StandardError=syslog
|
StandardError=syslog
|
||||||
@ -113,7 +109,7 @@ You can check if the service is running with `systemctl status misskey`.
|
|||||||
1. `git fetch`
|
1. `git fetch`
|
||||||
2. `git checkout $(git tag -l | grep -v 'rc[0-9]*$' | sort -V | tail -n 1)`
|
2. `git checkout $(git tag -l | grep -v 'rc[0-9]*$' | sort -V | tail -n 1)`
|
||||||
3. `npm install`
|
3. `npm install`
|
||||||
4. `npm run build`
|
4. `NODE_ENV=production npm run build`
|
||||||
5. Check [ChangeLog](../CHANGELOG.md) for migration information
|
5. Check [ChangeLog](../CHANGELOG.md) for migration information
|
||||||
6. Restart your Misskey process to apply changes
|
6. Restart your Misskey process to apply changes
|
||||||
7. Enjoy
|
7. Enjoy
|
||||||
|
@ -57,7 +57,7 @@ En root :
|
|||||||
|
|
||||||
Construisez Misskey comme ceci :
|
Construisez Misskey comme ceci :
|
||||||
|
|
||||||
`npm run build`
|
`NODE_ENV=production npm run build`
|
||||||
|
|
||||||
Si vous êtes sous Debian, vous serez amené à installer les paquets `build-essential` et `python`.
|
Si vous êtes sous Debian, vous serez amené à installer les paquets `build-essential` et `python`.
|
||||||
|
|
||||||
@ -66,14 +66,14 @@ Si vous rencontrez des erreurs concernant certains modules, utilisez node-gyp:
|
|||||||
1. `npm install -g node-gyp`
|
1. `npm install -g node-gyp`
|
||||||
2. `node-gyp configure`
|
2. `node-gyp configure`
|
||||||
3. `node-gyp build`
|
3. `node-gyp build`
|
||||||
4. `npm run build`
|
4. `NODE_ENV=production npm run build`
|
||||||
|
|
||||||
*7.* C'est tout.
|
*7.* C'est tout.
|
||||||
----------------------------------------------------------------
|
----------------------------------------------------------------
|
||||||
Excellent ! Maintenant, vous avez un environnement prêt pour lancer Misskey
|
Excellent ! Maintenant, vous avez un environnement prêt pour lancer Misskey
|
||||||
|
|
||||||
### Lancement conventionnel
|
### Lancement conventionnel
|
||||||
Lancez tout simplement `npm start`. Bonne chance et amusez-vous bien !
|
Lancez tout simplement `NODE_ENV=production npm start`. Bonne chance et amusez-vous bien !
|
||||||
|
|
||||||
### Démarrage avec systemd
|
### Démarrage avec systemd
|
||||||
|
|
||||||
@ -89,6 +89,7 @@ Type=simple
|
|||||||
User=misskey
|
User=misskey
|
||||||
ExecStart=/usr/bin/npm start
|
ExecStart=/usr/bin/npm start
|
||||||
WorkingDirectory=/home/misskey/misskey
|
WorkingDirectory=/home/misskey/misskey
|
||||||
|
Environment="NODE_ENV=production"
|
||||||
TimeoutSec=60
|
TimeoutSec=60
|
||||||
StandardOutput=syslog
|
StandardOutput=syslog
|
||||||
StandardError=syslog
|
StandardError=syslog
|
||||||
@ -108,7 +109,7 @@ Vous pouvez vérifier si le service a démarré en utilisant la commande `system
|
|||||||
1. `git fetch`
|
1. `git fetch`
|
||||||
2. `git checkout $(git tag -l | grep -v 'rc[0-9]*$' | sort -V | tail -n 1)`
|
2. `git checkout $(git tag -l | grep -v 'rc[0-9]*$' | sort -V | tail -n 1)`
|
||||||
3. `npm install`
|
3. `npm install`
|
||||||
4. `npm run build`
|
4. `NODE_ENV=production npm run build`
|
||||||
5. Consultez [ChangeLog](../CHANGELOG.md) pour les information de migration.
|
5. Consultez [ChangeLog](../CHANGELOG.md) pour les information de migration.
|
||||||
|
|
||||||
----------------------------------------------------------------
|
----------------------------------------------------------------
|
||||||
|
@ -62,14 +62,9 @@ adduser --disabled-password --disabled-login misskey
|
|||||||
*6.* Misskeyのビルド
|
*6.* Misskeyのビルド
|
||||||
----------------------------------------------------------------
|
----------------------------------------------------------------
|
||||||
|
|
||||||
ビルドする前に、`NODE_ENV`を`production`にする必要があります。例:
|
|
||||||
* Linux: `export NODE_ENV=production`
|
|
||||||
* Windows (PowerShell): `$env:NODE_ENV="production"`
|
|
||||||
* Windows (CMD): `set NODE_ENV=production`
|
|
||||||
|
|
||||||
次のコマンドでMisskeyをビルドしてください:
|
次のコマンドでMisskeyをビルドしてください:
|
||||||
|
|
||||||
`npm run build`
|
`NODE_ENV=production npm run build`
|
||||||
|
|
||||||
Debianをお使いであれば、`build-essential`パッケージをインストールする必要があります。
|
Debianをお使いであれば、`build-essential`パッケージをインストールする必要があります。
|
||||||
|
|
||||||
@ -77,14 +72,14 @@ Debianをお使いであれば、`build-essential`パッケージをインスト
|
|||||||
1. `npm install -g node-gyp`
|
1. `npm install -g node-gyp`
|
||||||
2. `node-gyp configure`
|
2. `node-gyp configure`
|
||||||
3. `node-gyp build`
|
3. `node-gyp build`
|
||||||
4. `npm run build`
|
4. `NODE_ENV=production npm run build`
|
||||||
|
|
||||||
*7.* 以上です!
|
*7.* 以上です!
|
||||||
----------------------------------------------------------------
|
----------------------------------------------------------------
|
||||||
お疲れ様でした。これでMisskeyを動かす準備は整いました。
|
お疲れ様でした。これでMisskeyを動かす準備は整いました。
|
||||||
|
|
||||||
### 通常起動
|
### 通常起動
|
||||||
`npm start`するだけです。GLHF!
|
`NODE_ENV=production npm start`するだけです。GLHF!
|
||||||
|
|
||||||
### systemdを用いた起動
|
### systemdを用いた起動
|
||||||
1. systemdサービスのファイルを作成: `/etc/systemd/system/misskey.service`
|
1. systemdサービスのファイルを作成: `/etc/systemd/system/misskey.service`
|
||||||
@ -99,6 +94,7 @@ Type=simple
|
|||||||
User=misskey
|
User=misskey
|
||||||
ExecStart=/usr/bin/npm start
|
ExecStart=/usr/bin/npm start
|
||||||
WorkingDirectory=/home/misskey/misskey
|
WorkingDirectory=/home/misskey/misskey
|
||||||
|
Environment="NODE_ENV=production"
|
||||||
TimeoutSec=60
|
TimeoutSec=60
|
||||||
StandardOutput=syslog
|
StandardOutput=syslog
|
||||||
StandardError=syslog
|
StandardError=syslog
|
||||||
@ -119,7 +115,7 @@ CentOSで1024以下のポートを使用してMisskeyを使用する場合は`Ex
|
|||||||
1. `git fetch`
|
1. `git fetch`
|
||||||
2. `git checkout $(git tag -l | grep -v 'rc[0-9]*$' | sort -V | tail -n 1)`
|
2. `git checkout $(git tag -l | grep -v 'rc[0-9]*$' | sort -V | tail -n 1)`
|
||||||
3. `npm install`
|
3. `npm install`
|
||||||
4. `npm run build`
|
4. `NODE_ENV=production npm run build`
|
||||||
5. [ChangeLog](../CHANGELOG.md)でマイグレーション情報を確認する
|
5. [ChangeLog](../CHANGELOG.md)でマイグレーション情報を確認する
|
||||||
|
|
||||||
なにか問題が発生した場合は、`npm run clean`すると直る場合があります。
|
なにか問題が発生した場合は、`npm run clean`すると直る場合があります。
|
||||||
|
@ -144,6 +144,7 @@ common:
|
|||||||
is-remote-post: "この投稿情報はコピーです。"
|
is-remote-post: "この投稿情報はコピーです。"
|
||||||
view-on-remote: "正確な情報を見る"
|
view-on-remote: "正確な情報を見る"
|
||||||
renoted-by: "{user}がRenote"
|
renoted-by: "{user}がRenote"
|
||||||
|
no-notes: "投稿がありません"
|
||||||
error:
|
error:
|
||||||
title: "問題が発生しました"
|
title: "問題が発生しました"
|
||||||
retry: "やり直す"
|
retry: "やり直す"
|
||||||
@ -537,6 +538,10 @@ common/views/components/profile-editor.vue:
|
|||||||
mute-list: "ミュート"
|
mute-list: "ミュート"
|
||||||
blocking-list: "ブロック"
|
blocking-list: "ブロック"
|
||||||
export-requested: "エクスポートをリクエストしました。これには時間がかかる場合があります。エクスポートが終わると、ドライブにファイルが追加されます。"
|
export-requested: "エクスポートをリクエストしました。これには時間がかかる場合があります。エクスポートが終わると、ドライブにファイルが追加されます。"
|
||||||
|
enter-password: "パスワードを入力してください"
|
||||||
|
danger-zone: "危険な設定"
|
||||||
|
delete-account: "アカウントを削除"
|
||||||
|
account-deleted: "アカウントが削除されました。データが消えるまで時間がかかる場合があります。"
|
||||||
common/views/components/user-list-editor.vue:
|
common/views/components/user-list-editor.vue:
|
||||||
users: "ユーザー"
|
users: "ユーザー"
|
||||||
rename: "リスト名を変更"
|
rename: "リスト名を変更"
|
||||||
@ -785,8 +790,6 @@ desktop/views/components/renote-form.vue:
|
|||||||
failure: "Renoteに失敗しました"
|
failure: "Renoteに失敗しました"
|
||||||
desktop/views/components/renote-form-window.vue:
|
desktop/views/components/renote-form-window.vue:
|
||||||
title: "この投稿をRenoteしますか?"
|
title: "この投稿をRenoteしますか?"
|
||||||
desktop/views/components/timeline.core.vue:
|
|
||||||
empty: "投稿がありません"
|
|
||||||
desktop/views/pages/user-following-or-followers.vue:
|
desktop/views/pages/user-following-or-followers.vue:
|
||||||
following: "{user}のフォロー"
|
following: "{user}のフォロー"
|
||||||
followers: "{user}のフォロワー"
|
followers: "{user}のフォロワー"
|
||||||
@ -1364,7 +1367,6 @@ desktop/views/pages/user/user.timeline.vue:
|
|||||||
with-replies: "投稿と返信"
|
with-replies: "投稿と返信"
|
||||||
with-media: "メディア"
|
with-media: "メディア"
|
||||||
my-posts: "私の投稿"
|
my-posts: "私の投稿"
|
||||||
empty: "このユーザーはまだ何も投稿していないようです。"
|
|
||||||
desktop/views/widgets/messaging.vue:
|
desktop/views/widgets/messaging.vue:
|
||||||
title: "メッセージ"
|
title: "メッセージ"
|
||||||
desktop/views/widgets/notifications.vue:
|
desktop/views/widgets/notifications.vue:
|
||||||
@ -1462,8 +1464,6 @@ mobile/views/components/sub-note-content.vue:
|
|||||||
deleted: "この投稿は削除されました"
|
deleted: "この投稿は削除されました"
|
||||||
media-count: "{}つのメディア"
|
media-count: "{}つのメディア"
|
||||||
poll: "アンケート"
|
poll: "アンケート"
|
||||||
mobile/views/components/timeline.vue:
|
|
||||||
empty: "投稿がありません"
|
|
||||||
mobile/views/components/ui.header.vue:
|
mobile/views/components/ui.header.vue:
|
||||||
welcome-back: "おかえりなさい、"
|
welcome-back: "おかえりなさい、"
|
||||||
adjective: "さん"
|
adjective: "さん"
|
||||||
@ -1480,9 +1480,6 @@ mobile/views/components/ui.nav.vue:
|
|||||||
settings: "設定"
|
settings: "設定"
|
||||||
admin: "管理"
|
admin: "管理"
|
||||||
about: "Misskeyについて"
|
about: "Misskeyについて"
|
||||||
mobile/views/components/user-timeline.vue:
|
|
||||||
no-notes: "このユーザーは投稿していないようです。"
|
|
||||||
no-notes-with-media: "メディア付き投稿はありません。"
|
|
||||||
mobile/views/pages/favorites.vue:
|
mobile/views/pages/favorites.vue:
|
||||||
title: "お気に入り"
|
title: "お気に入り"
|
||||||
mobile/views/pages/user-lists.vue:
|
mobile/views/pages/user-lists.vue:
|
||||||
@ -1501,8 +1498,6 @@ mobile/views/pages/home.vue:
|
|||||||
global: "グローバル"
|
global: "グローバル"
|
||||||
mentions: "あなた宛て"
|
mentions: "あなた宛て"
|
||||||
messages: "メッセージ"
|
messages: "メッセージ"
|
||||||
mobile/views/pages/home.timeline.vue:
|
|
||||||
empty: "投稿がありません"
|
|
||||||
mobile/views/pages/tag.vue:
|
mobile/views/pages/tag.vue:
|
||||||
no-posts-found: "ハッシュタグ「{q}」が付けられた投稿は見つかりませんでした。"
|
no-posts-found: "ハッシュタグ「{q}」が付けられた投稿は見つかりませんでした。"
|
||||||
mobile/views/pages/welcome.vue:
|
mobile/views/pages/welcome.vue:
|
||||||
@ -1595,8 +1590,6 @@ mobile/views/pages/user/home.vue:
|
|||||||
frequently-replied-users: "よく話すユーザー"
|
frequently-replied-users: "よく話すユーザー"
|
||||||
followers-you-know: "知り合いのフォロワー"
|
followers-you-know: "知り合いのフォロワー"
|
||||||
last-used-at: "最終ログイン"
|
last-used-at: "最終ログイン"
|
||||||
mobile/views/pages/user/home.notes.vue:
|
|
||||||
no-notes: "投稿はありません"
|
|
||||||
mobile/views/pages/user/home.photos.vue:
|
mobile/views/pages/user/home.photos.vue:
|
||||||
no-photos: "写真はありません"
|
no-photos: "写真はありません"
|
||||||
deck:
|
deck:
|
||||||
@ -1624,7 +1617,6 @@ deck:
|
|||||||
description: "サーバーの運営者により、このタイムラインは使用できない状態に設定されています。"
|
description: "サーバーの運営者により、このタイムラインは使用できない状態に設定されています。"
|
||||||
deck/deck.tl-column.vue:
|
deck/deck.tl-column.vue:
|
||||||
is-media-only: "メディア投稿のみ"
|
is-media-only: "メディア投稿のみ"
|
||||||
is-media-view: "メディアビュー"
|
|
||||||
edit: "オプション"
|
edit: "オプション"
|
||||||
deck/deck.user-column.vue:
|
deck/deck.user-column.vue:
|
||||||
follows-you: "フォローされています"
|
follows-you: "フォローされています"
|
||||||
|
@ -144,6 +144,7 @@ common:
|
|||||||
is-remote-post: "この投稿情報はコピーです。"
|
is-remote-post: "この投稿情報はコピーです。"
|
||||||
view-on-remote: "正確な情報を見る"
|
view-on-remote: "正確な情報を見る"
|
||||||
renoted-by: "{user}がRenote"
|
renoted-by: "{user}がRenote"
|
||||||
|
no-notes: "投稿がありません"
|
||||||
error:
|
error:
|
||||||
title: "問題が発生しました"
|
title: "問題が発生しました"
|
||||||
retry: "Erneut versuchen"
|
retry: "Erneut versuchen"
|
||||||
@ -537,6 +538,10 @@ common/views/components/profile-editor.vue:
|
|||||||
mute-list: "ミュート"
|
mute-list: "ミュート"
|
||||||
blocking-list: "ブロック"
|
blocking-list: "ブロック"
|
||||||
export-requested: "エクスポートをリクエストしました。これには時間がかかる場合があります。エクスポートが終わると、ドライブにファイルが追加されます。"
|
export-requested: "エクスポートをリクエストしました。これには時間がかかる場合があります。エクスポートが終わると、ドライブにファイルが追加されます。"
|
||||||
|
enter-password: "パスワードを入力してください"
|
||||||
|
danger-zone: "危険な設定"
|
||||||
|
delete-account: "アカウントを削除"
|
||||||
|
account-deleted: "アカウントが削除されました。データが消えるまで時間がかかる場合があります。"
|
||||||
common/views/components/user-list-editor.vue:
|
common/views/components/user-list-editor.vue:
|
||||||
users: "ユーザー"
|
users: "ユーザー"
|
||||||
rename: "リスト名を変更"
|
rename: "リスト名を変更"
|
||||||
@ -785,8 +790,6 @@ desktop/views/components/renote-form.vue:
|
|||||||
failure: "Weitersagen fehlgeschlagen"
|
failure: "Weitersagen fehlgeschlagen"
|
||||||
desktop/views/components/renote-form-window.vue:
|
desktop/views/components/renote-form-window.vue:
|
||||||
title: "Bist du dir sicher, dass du das reposten willst?"
|
title: "Bist du dir sicher, dass du das reposten willst?"
|
||||||
desktop/views/components/timeline.core.vue:
|
|
||||||
empty: "投稿がありません"
|
|
||||||
desktop/views/pages/user-following-or-followers.vue:
|
desktop/views/pages/user-following-or-followers.vue:
|
||||||
following: "{user}のフォロー"
|
following: "{user}のフォロー"
|
||||||
followers: "{user}のフォロワー"
|
followers: "{user}のフォロワー"
|
||||||
@ -1364,7 +1367,6 @@ desktop/views/pages/user/user.timeline.vue:
|
|||||||
with-replies: "投稿と返信"
|
with-replies: "投稿と返信"
|
||||||
with-media: "メディア"
|
with-media: "メディア"
|
||||||
my-posts: "私の投稿"
|
my-posts: "私の投稿"
|
||||||
empty: "このユーザーはまだ何も投稿していないようです。"
|
|
||||||
desktop/views/widgets/messaging.vue:
|
desktop/views/widgets/messaging.vue:
|
||||||
title: "メッセージ"
|
title: "メッセージ"
|
||||||
desktop/views/widgets/notifications.vue:
|
desktop/views/widgets/notifications.vue:
|
||||||
@ -1462,8 +1464,6 @@ mobile/views/components/sub-note-content.vue:
|
|||||||
deleted: "この投稿は削除されました"
|
deleted: "この投稿は削除されました"
|
||||||
media-count: "{}つのメディア"
|
media-count: "{}つのメディア"
|
||||||
poll: "アンケート"
|
poll: "アンケート"
|
||||||
mobile/views/components/timeline.vue:
|
|
||||||
empty: "投稿がありません"
|
|
||||||
mobile/views/components/ui.header.vue:
|
mobile/views/components/ui.header.vue:
|
||||||
welcome-back: "おかえりなさい、"
|
welcome-back: "おかえりなさい、"
|
||||||
adjective: "さん"
|
adjective: "さん"
|
||||||
@ -1480,9 +1480,6 @@ mobile/views/components/ui.nav.vue:
|
|||||||
settings: "設定"
|
settings: "設定"
|
||||||
admin: "管理"
|
admin: "管理"
|
||||||
about: "Misskeyについて"
|
about: "Misskeyについて"
|
||||||
mobile/views/components/user-timeline.vue:
|
|
||||||
no-notes: "このユーザーは投稿していないようです。"
|
|
||||||
no-notes-with-media: "メディア付き投稿はありません。"
|
|
||||||
mobile/views/pages/favorites.vue:
|
mobile/views/pages/favorites.vue:
|
||||||
title: "Favoriten"
|
title: "Favoriten"
|
||||||
mobile/views/pages/user-lists.vue:
|
mobile/views/pages/user-lists.vue:
|
||||||
@ -1501,8 +1498,6 @@ mobile/views/pages/home.vue:
|
|||||||
global: "グローバル"
|
global: "グローバル"
|
||||||
mentions: "あなた宛て"
|
mentions: "あなた宛て"
|
||||||
messages: "メッセージ"
|
messages: "メッセージ"
|
||||||
mobile/views/pages/home.timeline.vue:
|
|
||||||
empty: "投稿がありません"
|
|
||||||
mobile/views/pages/tag.vue:
|
mobile/views/pages/tag.vue:
|
||||||
no-posts-found: "ハッシュタグ「{q}」が付けられた投稿は見つかりませんでした。"
|
no-posts-found: "ハッシュタグ「{q}」が付けられた投稿は見つかりませんでした。"
|
||||||
mobile/views/pages/welcome.vue:
|
mobile/views/pages/welcome.vue:
|
||||||
@ -1595,8 +1590,6 @@ mobile/views/pages/user/home.vue:
|
|||||||
frequently-replied-users: "よく話すユーザー"
|
frequently-replied-users: "よく話すユーザー"
|
||||||
followers-you-know: "知り合いのフォロワー"
|
followers-you-know: "知り合いのフォロワー"
|
||||||
last-used-at: "最終ログイン"
|
last-used-at: "最終ログイン"
|
||||||
mobile/views/pages/user/home.notes.vue:
|
|
||||||
no-notes: "投稿はありません"
|
|
||||||
mobile/views/pages/user/home.photos.vue:
|
mobile/views/pages/user/home.photos.vue:
|
||||||
no-photos: "写真はありません"
|
no-photos: "写真はありません"
|
||||||
deck:
|
deck:
|
||||||
@ -1624,7 +1617,6 @@ deck:
|
|||||||
description: "サーバーの運営者により、このタイムラインは使用できない状態に設定されています。"
|
description: "サーバーの運営者により、このタイムラインは使用できない状態に設定されています。"
|
||||||
deck/deck.tl-column.vue:
|
deck/deck.tl-column.vue:
|
||||||
is-media-only: "メディア投稿のみ"
|
is-media-only: "メディア投稿のみ"
|
||||||
is-media-view: "メディアビュー"
|
|
||||||
edit: "オプション"
|
edit: "オプション"
|
||||||
deck/deck.user-column.vue:
|
deck/deck.user-column.vue:
|
||||||
follows-you: "フォローされています"
|
follows-you: "フォローされています"
|
||||||
|
@ -8,12 +8,12 @@ common:
|
|||||||
about: "Thank you for finding Misskey. Misskey is a <b>decentralized microblogging platform</b> 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?"
|
about: "Thank you for finding Misskey. Misskey is a <b>decentralized microblogging platform</b> 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?"
|
||||||
intro:
|
intro:
|
||||||
title: "What is Misskey?"
|
title: "What is Misskey?"
|
||||||
about: "Misskey is an open-source, <b>decentralized microblogging service</b>. Sophisticated, fully customizable UI, varieties of reactions for posts, free file storage providing an integrated management system and other advanced features are available. In addition, Misskey connects to a network system called the “Fediverse”, that enables us to communicate with users on other SNSs. For example, when you post something, it will be sent not only to Misskey, but also to Mastodon, Osada and Pleroma. Just imagine that the planet is sending a radio transmission to another planet to communicate."
|
about: "Misskey is an open-source, <b>decentralized microblogging software</b>. It has a sophisticated, fully customizable user interface, a variety of ways for expressing a reaction to posts, free file storage providing an integrated management system, and other advanced features are available. In addition, Misskey connects to a network system called the “Fediverse”, which enables us to communicate with users on other SNSs. For example, when you post something, it will be sent not only to Misskey users, but also those on Mastodon and Pleroma. Just imagine that the planet is sending a radio transmission to another planet, in order to communicate."
|
||||||
features: "Features"
|
features: "Features"
|
||||||
rich-contents: "Post"
|
rich-contents: "Post"
|
||||||
rich-contents-desc: "Just post your idea, hot topics, and anything you want to share. You may want to decorate your words, attach your favorite pictures, send files, including videos, or create a poll - those are some of the things you can do with Misskey!"
|
rich-contents-desc: "Just post your idea, hot topics, and anything you want to share. You may want to decorate your words, attach your favorite pictures, send files, including videos, or create a poll - those are some of the things you can do with Misskey!"
|
||||||
reaction: "Reactions"
|
reaction: "Reactions"
|
||||||
reaction-desc: "Easiest way to tell your emotions. Misskey allows you to add various type of reactions to other’s post. The emotional experience on Misskey will never be on other SNSs which only able to push “likes”."
|
reaction-desc: "The easiest way to express your emotions. Misskey allows you to add various kinds of reactions to other's posts. The emotional experience on Misskey will never be on other SNSs, which are only able to push “likes”."
|
||||||
ui: "Interface"
|
ui: "Interface"
|
||||||
ui-desc: "No UI fits for everyone. Therefore, Misskey has a highly customizable UI for your taste. Make your original home by editing, adjusting layouts of timeline and placing selectable widgets you can easily customize."
|
ui-desc: "No UI fits for everyone. Therefore, Misskey has a highly customizable UI for your taste. Make your original home by editing, adjusting layouts of timeline and placing selectable widgets you can easily customize."
|
||||||
drive: "Drive"
|
drive: "Drive"
|
||||||
@ -60,7 +60,7 @@ common:
|
|||||||
messaging: "Talk"
|
messaging: "Talk"
|
||||||
deck: "Deck"
|
deck: "Deck"
|
||||||
timeline: "Timeline"
|
timeline: "Timeline"
|
||||||
explore: "Discover"
|
explore: "Explore"
|
||||||
following: "Following"
|
following: "Following"
|
||||||
followers: "Followers"
|
followers: "Followers"
|
||||||
empty-timeline-info:
|
empty-timeline-info:
|
||||||
@ -144,6 +144,7 @@ common:
|
|||||||
is-remote-post: "These post contents are mirrored."
|
is-remote-post: "These post contents are mirrored."
|
||||||
view-on-remote: "For completion, view it remotely."
|
view-on-remote: "For completion, view it remotely."
|
||||||
renoted-by: "Renoted by {user}"
|
renoted-by: "Renoted by {user}"
|
||||||
|
no-notes: "Without any notes"
|
||||||
error:
|
error:
|
||||||
title: "Something happened :("
|
title: "Something happened :("
|
||||||
retry: "Retry"
|
retry: "Retry"
|
||||||
@ -537,6 +538,10 @@ common/views/components/profile-editor.vue:
|
|||||||
mute-list: "List of muted accounts"
|
mute-list: "List of muted accounts"
|
||||||
blocking-list: "List of blocked accounts"
|
blocking-list: "List of blocked accounts"
|
||||||
export-requested: "You have requested an export. This may take a while. After the export is complete, the resulting file will be added to the drive."
|
export-requested: "You have requested an export. This may take a while. After the export is complete, the resulting file will be added to the drive."
|
||||||
|
enter-password: "Please enter your password"
|
||||||
|
danger-zone: "Cautious options"
|
||||||
|
delete-account: "Remove the account"
|
||||||
|
account-deleted: "The account has been deleted. It may take some time until all of the data disappears."
|
||||||
common/views/components/user-list-editor.vue:
|
common/views/components/user-list-editor.vue:
|
||||||
users: "User"
|
users: "User"
|
||||||
rename: "Rename list"
|
rename: "Rename list"
|
||||||
@ -785,8 +790,6 @@ desktop/views/components/renote-form.vue:
|
|||||||
failure: "Failed to Repost"
|
failure: "Failed to Repost"
|
||||||
desktop/views/components/renote-form-window.vue:
|
desktop/views/components/renote-form-window.vue:
|
||||||
title: "Do you want to Repost it?"
|
title: "Do you want to Repost it?"
|
||||||
desktop/views/components/timeline.core.vue:
|
|
||||||
empty: "Without any notes"
|
|
||||||
desktop/views/pages/user-following-or-followers.vue:
|
desktop/views/pages/user-following-or-followers.vue:
|
||||||
following: "{user}'s following"
|
following: "{user}'s following"
|
||||||
followers: "{user}'s follower"
|
followers: "{user}'s follower"
|
||||||
@ -1353,7 +1356,7 @@ desktop/views/pages/user/user.header.vue:
|
|||||||
following: "Following"
|
following: "Following"
|
||||||
followers: "Followers"
|
followers: "Followers"
|
||||||
is-bot: "This account is a Bot"
|
is-bot: "This account is a Bot"
|
||||||
no-description: "自己紹介はありません"
|
no-description: "The user has not written their profile introduction"
|
||||||
years-old: "{age} years old"
|
years-old: "{age} years old"
|
||||||
year: "/"
|
year: "/"
|
||||||
month: "/"
|
month: "/"
|
||||||
@ -1364,7 +1367,6 @@ desktop/views/pages/user/user.timeline.vue:
|
|||||||
with-replies: "Posts and replies"
|
with-replies: "Posts and replies"
|
||||||
with-media: "Media"
|
with-media: "Media"
|
||||||
my-posts: "My posts"
|
my-posts: "My posts"
|
||||||
empty: "This user doesn't seem to have posted anything yet."
|
|
||||||
desktop/views/widgets/messaging.vue:
|
desktop/views/widgets/messaging.vue:
|
||||||
title: "Message"
|
title: "Message"
|
||||||
desktop/views/widgets/notifications.vue:
|
desktop/views/widgets/notifications.vue:
|
||||||
@ -1462,8 +1464,6 @@ mobile/views/components/sub-note-content.vue:
|
|||||||
deleted: "This post has been deleted"
|
deleted: "This post has been deleted"
|
||||||
media-count: "{} media attached"
|
media-count: "{} media attached"
|
||||||
poll: "Poll"
|
poll: "Poll"
|
||||||
mobile/views/components/timeline.vue:
|
|
||||||
empty: "No notes"
|
|
||||||
mobile/views/components/ui.header.vue:
|
mobile/views/components/ui.header.vue:
|
||||||
welcome-back: "Welcome back, "
|
welcome-back: "Welcome back, "
|
||||||
adjective: "Sir"
|
adjective: "Sir"
|
||||||
@ -1480,9 +1480,6 @@ mobile/views/components/ui.nav.vue:
|
|||||||
settings: "Settings"
|
settings: "Settings"
|
||||||
admin: "Admin"
|
admin: "Admin"
|
||||||
about: "About Misskey"
|
about: "About Misskey"
|
||||||
mobile/views/components/user-timeline.vue:
|
|
||||||
no-notes: "It seems this user hasn't posted anything yet."
|
|
||||||
no-notes-with-media: "There are no notes with media attachments"
|
|
||||||
mobile/views/pages/favorites.vue:
|
mobile/views/pages/favorites.vue:
|
||||||
title: "Favorites"
|
title: "Favorites"
|
||||||
mobile/views/pages/user-lists.vue:
|
mobile/views/pages/user-lists.vue:
|
||||||
@ -1501,8 +1498,6 @@ mobile/views/pages/home.vue:
|
|||||||
global: "Global"
|
global: "Global"
|
||||||
mentions: "Mentions"
|
mentions: "Mentions"
|
||||||
messages: "Messages"
|
messages: "Messages"
|
||||||
mobile/views/pages/home.timeline.vue:
|
|
||||||
empty: "Without any notes"
|
|
||||||
mobile/views/pages/tag.vue:
|
mobile/views/pages/tag.vue:
|
||||||
no-posts-found: "No posts contains \"{q}\" found."
|
no-posts-found: "No posts contains \"{q}\" found."
|
||||||
mobile/views/pages/welcome.vue:
|
mobile/views/pages/welcome.vue:
|
||||||
@ -1595,8 +1590,6 @@ mobile/views/pages/user/home.vue:
|
|||||||
frequently-replied-users: "Frequent mentions"
|
frequently-replied-users: "Frequent mentions"
|
||||||
followers-you-know: "Followers you know"
|
followers-you-know: "Followers you know"
|
||||||
last-used-at: "Last active:"
|
last-used-at: "Last active:"
|
||||||
mobile/views/pages/user/home.notes.vue:
|
|
||||||
no-notes: "No notes"
|
|
||||||
mobile/views/pages/user/home.photos.vue:
|
mobile/views/pages/user/home.photos.vue:
|
||||||
no-photos: "No photos"
|
no-photos: "No photos"
|
||||||
deck:
|
deck:
|
||||||
@ -1624,7 +1617,6 @@ deck:
|
|||||||
description: "This timeline has been disabled by the server administrator."
|
description: "This timeline has been disabled by the server administrator."
|
||||||
deck/deck.tl-column.vue:
|
deck/deck.tl-column.vue:
|
||||||
is-media-only: "Only media posts"
|
is-media-only: "Only media posts"
|
||||||
is-media-view: "Media view"
|
|
||||||
edit: "Options"
|
edit: "Options"
|
||||||
deck/deck.user-column.vue:
|
deck/deck.user-column.vue:
|
||||||
follows-you: "Follows you"
|
follows-you: "Follows you"
|
||||||
|
@ -144,6 +144,7 @@ common:
|
|||||||
is-remote-post: "この投稿情報はコピーです。"
|
is-remote-post: "この投稿情報はコピーです。"
|
||||||
view-on-remote: "正確な情報を見る"
|
view-on-remote: "正確な情報を見る"
|
||||||
renoted-by: "{user}がRenote"
|
renoted-by: "{user}がRenote"
|
||||||
|
no-notes: "投稿がありません"
|
||||||
error:
|
error:
|
||||||
title: "問題が発生しました"
|
title: "問題が発生しました"
|
||||||
retry: "やり直す"
|
retry: "やり直す"
|
||||||
@ -537,6 +538,10 @@ common/views/components/profile-editor.vue:
|
|||||||
mute-list: "ミュート"
|
mute-list: "ミュート"
|
||||||
blocking-list: "ブロック"
|
blocking-list: "ブロック"
|
||||||
export-requested: "エクスポートをリクエストしました。これには時間がかかる場合があります。エクスポートが終わると、ドライブにファイルが追加されます。"
|
export-requested: "エクスポートをリクエストしました。これには時間がかかる場合があります。エクスポートが終わると、ドライブにファイルが追加されます。"
|
||||||
|
enter-password: "パスワードを入力してください"
|
||||||
|
danger-zone: "危険な設定"
|
||||||
|
delete-account: "アカウントを削除"
|
||||||
|
account-deleted: "アカウントが削除されました。データが消えるまで時間がかかる場合があります。"
|
||||||
common/views/components/user-list-editor.vue:
|
common/views/components/user-list-editor.vue:
|
||||||
users: "Usuarios"
|
users: "Usuarios"
|
||||||
rename: "リスト名を変更"
|
rename: "リスト名を変更"
|
||||||
@ -785,8 +790,6 @@ desktop/views/components/renote-form.vue:
|
|||||||
failure: "La publicación ha fallado"
|
failure: "La publicación ha fallado"
|
||||||
desktop/views/components/renote-form-window.vue:
|
desktop/views/components/renote-form-window.vue:
|
||||||
title: "¿Seguro qué quieres volver a publicarlo?"
|
title: "¿Seguro qué quieres volver a publicarlo?"
|
||||||
desktop/views/components/timeline.core.vue:
|
|
||||||
empty: "投稿がありません"
|
|
||||||
desktop/views/pages/user-following-or-followers.vue:
|
desktop/views/pages/user-following-or-followers.vue:
|
||||||
following: "{user} sigue a"
|
following: "{user} sigue a"
|
||||||
followers: "Seguidores de {user}"
|
followers: "Seguidores de {user}"
|
||||||
@ -1364,7 +1367,6 @@ desktop/views/pages/user/user.timeline.vue:
|
|||||||
with-replies: "投稿と返信"
|
with-replies: "投稿と返信"
|
||||||
with-media: "メディア"
|
with-media: "メディア"
|
||||||
my-posts: "私の投稿"
|
my-posts: "私の投稿"
|
||||||
empty: "このユーザーはまだ何も投稿していないようです。"
|
|
||||||
desktop/views/widgets/messaging.vue:
|
desktop/views/widgets/messaging.vue:
|
||||||
title: "メッセージ"
|
title: "メッセージ"
|
||||||
desktop/views/widgets/notifications.vue:
|
desktop/views/widgets/notifications.vue:
|
||||||
@ -1462,8 +1464,6 @@ mobile/views/components/sub-note-content.vue:
|
|||||||
deleted: "この投稿は削除されました"
|
deleted: "この投稿は削除されました"
|
||||||
media-count: "{}つのメディア"
|
media-count: "{}つのメディア"
|
||||||
poll: "アンケート"
|
poll: "アンケート"
|
||||||
mobile/views/components/timeline.vue:
|
|
||||||
empty: "投稿がありません"
|
|
||||||
mobile/views/components/ui.header.vue:
|
mobile/views/components/ui.header.vue:
|
||||||
welcome-back: "おかえりなさい、"
|
welcome-back: "おかえりなさい、"
|
||||||
adjective: "さん"
|
adjective: "さん"
|
||||||
@ -1480,9 +1480,6 @@ mobile/views/components/ui.nav.vue:
|
|||||||
settings: "設定"
|
settings: "設定"
|
||||||
admin: "管理"
|
admin: "管理"
|
||||||
about: "Misskeyについて"
|
about: "Misskeyについて"
|
||||||
mobile/views/components/user-timeline.vue:
|
|
||||||
no-notes: "このユーザーは投稿していないようです。"
|
|
||||||
no-notes-with-media: "メディア付き投稿はありません。"
|
|
||||||
mobile/views/pages/favorites.vue:
|
mobile/views/pages/favorites.vue:
|
||||||
title: "お気に入り"
|
title: "お気に入り"
|
||||||
mobile/views/pages/user-lists.vue:
|
mobile/views/pages/user-lists.vue:
|
||||||
@ -1501,8 +1498,6 @@ mobile/views/pages/home.vue:
|
|||||||
global: "グローバル"
|
global: "グローバル"
|
||||||
mentions: "あなた宛て"
|
mentions: "あなた宛て"
|
||||||
messages: "メッセージ"
|
messages: "メッセージ"
|
||||||
mobile/views/pages/home.timeline.vue:
|
|
||||||
empty: "投稿がありません"
|
|
||||||
mobile/views/pages/tag.vue:
|
mobile/views/pages/tag.vue:
|
||||||
no-posts-found: "ハッシュタグ「{q}」が付けられた投稿は見つかりませんでした。"
|
no-posts-found: "ハッシュタグ「{q}」が付けられた投稿は見つかりませんでした。"
|
||||||
mobile/views/pages/welcome.vue:
|
mobile/views/pages/welcome.vue:
|
||||||
@ -1595,8 +1590,6 @@ mobile/views/pages/user/home.vue:
|
|||||||
frequently-replied-users: "よく話すユーザー"
|
frequently-replied-users: "よく話すユーザー"
|
||||||
followers-you-know: "知り合いのフォロワー"
|
followers-you-know: "知り合いのフォロワー"
|
||||||
last-used-at: "最終ログイン"
|
last-used-at: "最終ログイン"
|
||||||
mobile/views/pages/user/home.notes.vue:
|
|
||||||
no-notes: "投稿はありません"
|
|
||||||
mobile/views/pages/user/home.photos.vue:
|
mobile/views/pages/user/home.photos.vue:
|
||||||
no-photos: "写真はありません"
|
no-photos: "写真はありません"
|
||||||
deck:
|
deck:
|
||||||
@ -1624,7 +1617,6 @@ deck:
|
|||||||
description: "サーバーの運営者により、このタイムラインは使用できない状態に設定されています。"
|
description: "サーバーの運営者により、このタイムラインは使用できない状態に設定されています。"
|
||||||
deck/deck.tl-column.vue:
|
deck/deck.tl-column.vue:
|
||||||
is-media-only: "メディア投稿のみ"
|
is-media-only: "メディア投稿のみ"
|
||||||
is-media-view: "メディアビュー"
|
|
||||||
edit: "オプション"
|
edit: "オプション"
|
||||||
deck/deck.user-column.vue:
|
deck/deck.user-column.vue:
|
||||||
follows-you: "フォローされています"
|
follows-you: "フォローされています"
|
||||||
|
@ -144,6 +144,7 @@ common:
|
|||||||
is-remote-post: "Ceci est une publication distante."
|
is-remote-post: "Ceci est une publication distante."
|
||||||
view-on-remote: " Consulter le profil complet"
|
view-on-remote: " Consulter le profil complet"
|
||||||
renoted-by: "Renoté par {user}"
|
renoted-by: "Renoté par {user}"
|
||||||
|
no-notes: "投稿がありません"
|
||||||
error:
|
error:
|
||||||
title: "Une erreur est survenue"
|
title: "Une erreur est survenue"
|
||||||
retry: "Réessayer"
|
retry: "Réessayer"
|
||||||
@ -537,6 +538,10 @@ common/views/components/profile-editor.vue:
|
|||||||
mute-list: "Liste des comptes mis en sourdine"
|
mute-list: "Liste des comptes mis en sourdine"
|
||||||
blocking-list: "Liste des comptes bloqués"
|
blocking-list: "Liste des comptes bloqués"
|
||||||
export-requested: "エクスポートをリクエストしました。これには時間がかかる場合があります。エクスポートが終わると、ドライブにファイルが追加されます。"
|
export-requested: "エクスポートをリクエストしました。これには時間がかかる場合があります。エクスポートが終わると、ドライブにファイルが追加されます。"
|
||||||
|
enter-password: "パスワードを入力してください"
|
||||||
|
danger-zone: "危険な設定"
|
||||||
|
delete-account: "アカウントを削除"
|
||||||
|
account-deleted: "アカウントが削除されました。データが消えるまで時間がかかる場合があります。"
|
||||||
common/views/components/user-list-editor.vue:
|
common/views/components/user-list-editor.vue:
|
||||||
users: "Utilisateur·rice"
|
users: "Utilisateur·rice"
|
||||||
rename: "Renommer la liste"
|
rename: "Renommer la liste"
|
||||||
@ -785,8 +790,6 @@ desktop/views/components/renote-form.vue:
|
|||||||
failure: "La renote a échoué"
|
failure: "La renote a échoué"
|
||||||
desktop/views/components/renote-form-window.vue:
|
desktop/views/components/renote-form-window.vue:
|
||||||
title: "Êtes vous sûr de vouloir renote cette note?"
|
title: "Êtes vous sûr de vouloir renote cette note?"
|
||||||
desktop/views/components/timeline.core.vue:
|
|
||||||
empty: "Sans aucune note"
|
|
||||||
desktop/views/pages/user-following-or-followers.vue:
|
desktop/views/pages/user-following-or-followers.vue:
|
||||||
following: "{user} suit"
|
following: "{user} suit"
|
||||||
followers: "Abonné·e·s de {user}"
|
followers: "Abonné·e·s de {user}"
|
||||||
@ -1364,7 +1367,6 @@ desktop/views/pages/user/user.timeline.vue:
|
|||||||
with-replies: "Publications et réponses"
|
with-replies: "Publications et réponses"
|
||||||
with-media: "Média"
|
with-media: "Média"
|
||||||
my-posts: "Mes Messages"
|
my-posts: "Mes Messages"
|
||||||
empty: "Cet·te utilisateur·rice n'a rien posté encore."
|
|
||||||
desktop/views/widgets/messaging.vue:
|
desktop/views/widgets/messaging.vue:
|
||||||
title: "Messagerie"
|
title: "Messagerie"
|
||||||
desktop/views/widgets/notifications.vue:
|
desktop/views/widgets/notifications.vue:
|
||||||
@ -1462,8 +1464,6 @@ mobile/views/components/sub-note-content.vue:
|
|||||||
deleted: "cette publication a été supprimée"
|
deleted: "cette publication a été supprimée"
|
||||||
media-count: "{} médias attachés"
|
media-count: "{} médias attachés"
|
||||||
poll: "Sondage"
|
poll: "Sondage"
|
||||||
mobile/views/components/timeline.vue:
|
|
||||||
empty: "Pas de notes"
|
|
||||||
mobile/views/components/ui.header.vue:
|
mobile/views/components/ui.header.vue:
|
||||||
welcome-back: "Content de vous revoir ! "
|
welcome-back: "Content de vous revoir ! "
|
||||||
adjective: "M."
|
adjective: "M."
|
||||||
@ -1480,9 +1480,6 @@ mobile/views/components/ui.nav.vue:
|
|||||||
settings: "Réglages"
|
settings: "Réglages"
|
||||||
admin: "Admin"
|
admin: "Admin"
|
||||||
about: "À propos de Misskey"
|
about: "À propos de Misskey"
|
||||||
mobile/views/components/user-timeline.vue:
|
|
||||||
no-notes: "Il semble que cet·te utilisateur·rice n’a rien publié pour le moment."
|
|
||||||
no-notes-with-media: "Aucune note comprenant des médias"
|
|
||||||
mobile/views/pages/favorites.vue:
|
mobile/views/pages/favorites.vue:
|
||||||
title: "Favoris"
|
title: "Favoris"
|
||||||
mobile/views/pages/user-lists.vue:
|
mobile/views/pages/user-lists.vue:
|
||||||
@ -1501,8 +1498,6 @@ mobile/views/pages/home.vue:
|
|||||||
global: "Global"
|
global: "Global"
|
||||||
mentions: "Mentions"
|
mentions: "Mentions"
|
||||||
messages: "Messages"
|
messages: "Messages"
|
||||||
mobile/views/pages/home.timeline.vue:
|
|
||||||
empty: "Sans aucune note"
|
|
||||||
mobile/views/pages/tag.vue:
|
mobile/views/pages/tag.vue:
|
||||||
no-posts-found: "Aucune publication ayant pour hashtag « {q} » n’a été trouvée."
|
no-posts-found: "Aucune publication ayant pour hashtag « {q} » n’a été trouvée."
|
||||||
mobile/views/pages/welcome.vue:
|
mobile/views/pages/welcome.vue:
|
||||||
@ -1595,8 +1590,6 @@ mobile/views/pages/user/home.vue:
|
|||||||
frequently-replied-users: "Mentions fréquentes"
|
frequently-replied-users: "Mentions fréquentes"
|
||||||
followers-you-know: "Abonné·e·s que vous connaissez"
|
followers-you-know: "Abonné·e·s que vous connaissez"
|
||||||
last-used-at: "Dernière connexion il y a"
|
last-used-at: "Dernière connexion il y a"
|
||||||
mobile/views/pages/user/home.notes.vue:
|
|
||||||
no-notes: "Pas de notes"
|
|
||||||
mobile/views/pages/user/home.photos.vue:
|
mobile/views/pages/user/home.photos.vue:
|
||||||
no-photos: "Pas de photos"
|
no-photos: "Pas de photos"
|
||||||
deck:
|
deck:
|
||||||
@ -1624,7 +1617,6 @@ deck:
|
|||||||
description: "Ce fil a été désactivé par l'administrateur du serveur."
|
description: "Ce fil a été désactivé par l'administrateur du serveur."
|
||||||
deck/deck.tl-column.vue:
|
deck/deck.tl-column.vue:
|
||||||
is-media-only: "Les publications médias uniquement"
|
is-media-only: "Les publications médias uniquement"
|
||||||
is-media-view: "Vue média"
|
|
||||||
edit: "Option"
|
edit: "Option"
|
||||||
deck/deck.user-column.vue:
|
deck/deck.user-column.vue:
|
||||||
follows-you: "Vous suit"
|
follows-you: "Vous suit"
|
||||||
|
@ -144,6 +144,7 @@ common:
|
|||||||
is-remote-post: "この投稿情報はコピーです。"
|
is-remote-post: "この投稿情報はコピーです。"
|
||||||
view-on-remote: "正確な情報を見る"
|
view-on-remote: "正確な情報を見る"
|
||||||
renoted-by: "{user}がRenote"
|
renoted-by: "{user}がRenote"
|
||||||
|
no-notes: "投稿がありません"
|
||||||
error:
|
error:
|
||||||
title: "問題が発生しました"
|
title: "問題が発生しました"
|
||||||
retry: "やり直す"
|
retry: "やり直す"
|
||||||
@ -537,6 +538,10 @@ common/views/components/profile-editor.vue:
|
|||||||
mute-list: "ミュート"
|
mute-list: "ミュート"
|
||||||
blocking-list: "ブロック"
|
blocking-list: "ブロック"
|
||||||
export-requested: "エクスポートをリクエストしました。これには時間がかかる場合があります。エクスポートが終わると、ドライブにファイルが追加されます。"
|
export-requested: "エクスポートをリクエストしました。これには時間がかかる場合があります。エクスポートが終わると、ドライブにファイルが追加されます。"
|
||||||
|
enter-password: "パスワードを入力してください"
|
||||||
|
danger-zone: "危険な設定"
|
||||||
|
delete-account: "アカウントを削除"
|
||||||
|
account-deleted: "アカウントが削除されました。データが消えるまで時間がかかる場合があります。"
|
||||||
common/views/components/user-list-editor.vue:
|
common/views/components/user-list-editor.vue:
|
||||||
users: "ユーザー"
|
users: "ユーザー"
|
||||||
rename: "リスト名を変更"
|
rename: "リスト名を変更"
|
||||||
@ -785,8 +790,6 @@ desktop/views/components/renote-form.vue:
|
|||||||
failure: "Renoteに失敗しました"
|
failure: "Renoteに失敗しました"
|
||||||
desktop/views/components/renote-form-window.vue:
|
desktop/views/components/renote-form-window.vue:
|
||||||
title: "この投稿をRenoteしますか?"
|
title: "この投稿をRenoteしますか?"
|
||||||
desktop/views/components/timeline.core.vue:
|
|
||||||
empty: "投稿がありません"
|
|
||||||
desktop/views/pages/user-following-or-followers.vue:
|
desktop/views/pages/user-following-or-followers.vue:
|
||||||
following: "{user}のフォロー"
|
following: "{user}のフォロー"
|
||||||
followers: "{user}のフォロワー"
|
followers: "{user}のフォロワー"
|
||||||
@ -1364,7 +1367,6 @@ desktop/views/pages/user/user.timeline.vue:
|
|||||||
with-replies: "投稿と返信"
|
with-replies: "投稿と返信"
|
||||||
with-media: "メディア"
|
with-media: "メディア"
|
||||||
my-posts: "私の投稿"
|
my-posts: "私の投稿"
|
||||||
empty: "このユーザーはまだ何も投稿していないようです。"
|
|
||||||
desktop/views/widgets/messaging.vue:
|
desktop/views/widgets/messaging.vue:
|
||||||
title: "メッセージ"
|
title: "メッセージ"
|
||||||
desktop/views/widgets/notifications.vue:
|
desktop/views/widgets/notifications.vue:
|
||||||
@ -1462,8 +1464,6 @@ mobile/views/components/sub-note-content.vue:
|
|||||||
deleted: "この投稿は削除されました"
|
deleted: "この投稿は削除されました"
|
||||||
media-count: "{}つのメディア"
|
media-count: "{}つのメディア"
|
||||||
poll: "アンケート"
|
poll: "アンケート"
|
||||||
mobile/views/components/timeline.vue:
|
|
||||||
empty: "投稿がありません"
|
|
||||||
mobile/views/components/ui.header.vue:
|
mobile/views/components/ui.header.vue:
|
||||||
welcome-back: "おかえりなさい、"
|
welcome-back: "おかえりなさい、"
|
||||||
adjective: "さん"
|
adjective: "さん"
|
||||||
@ -1480,9 +1480,6 @@ mobile/views/components/ui.nav.vue:
|
|||||||
settings: "設定"
|
settings: "設定"
|
||||||
admin: "管理"
|
admin: "管理"
|
||||||
about: "Misskeyについて"
|
about: "Misskeyについて"
|
||||||
mobile/views/components/user-timeline.vue:
|
|
||||||
no-notes: "このユーザーは投稿していないようです。"
|
|
||||||
no-notes-with-media: "メディア付き投稿はありません。"
|
|
||||||
mobile/views/pages/favorites.vue:
|
mobile/views/pages/favorites.vue:
|
||||||
title: "お気に入り"
|
title: "お気に入り"
|
||||||
mobile/views/pages/user-lists.vue:
|
mobile/views/pages/user-lists.vue:
|
||||||
@ -1501,8 +1498,6 @@ mobile/views/pages/home.vue:
|
|||||||
global: "グローバル"
|
global: "グローバル"
|
||||||
mentions: "あなた宛て"
|
mentions: "あなた宛て"
|
||||||
messages: "メッセージ"
|
messages: "メッセージ"
|
||||||
mobile/views/pages/home.timeline.vue:
|
|
||||||
empty: "投稿がありません"
|
|
||||||
mobile/views/pages/tag.vue:
|
mobile/views/pages/tag.vue:
|
||||||
no-posts-found: "ハッシュタグ「{q}」が付けられた投稿は見つかりませんでした。"
|
no-posts-found: "ハッシュタグ「{q}」が付けられた投稿は見つかりませんでした。"
|
||||||
mobile/views/pages/welcome.vue:
|
mobile/views/pages/welcome.vue:
|
||||||
@ -1595,8 +1590,6 @@ mobile/views/pages/user/home.vue:
|
|||||||
frequently-replied-users: "よく話すユーザー"
|
frequently-replied-users: "よく話すユーザー"
|
||||||
followers-you-know: "知り合いのフォロワー"
|
followers-you-know: "知り合いのフォロワー"
|
||||||
last-used-at: "最終ログイン"
|
last-used-at: "最終ログイン"
|
||||||
mobile/views/pages/user/home.notes.vue:
|
|
||||||
no-notes: "投稿はありません"
|
|
||||||
mobile/views/pages/user/home.photos.vue:
|
mobile/views/pages/user/home.photos.vue:
|
||||||
no-photos: "写真はありません"
|
no-photos: "写真はありません"
|
||||||
deck:
|
deck:
|
||||||
@ -1624,7 +1617,6 @@ deck:
|
|||||||
description: "サーバーの運営者により、このタイムラインは使用できない状態に設定されています。"
|
description: "サーバーの運営者により、このタイムラインは使用できない状態に設定されています。"
|
||||||
deck/deck.tl-column.vue:
|
deck/deck.tl-column.vue:
|
||||||
is-media-only: "メディア投稿のみ"
|
is-media-only: "メディア投稿のみ"
|
||||||
is-media-view: "メディアビュー"
|
|
||||||
edit: "オプション"
|
edit: "オプション"
|
||||||
deck/deck.user-column.vue:
|
deck/deck.user-column.vue:
|
||||||
follows-you: "フォローされています"
|
follows-you: "フォローされています"
|
||||||
|
@ -154,6 +154,7 @@ common:
|
|||||||
is-remote-post: "この投稿情報はコピーです。"
|
is-remote-post: "この投稿情報はコピーです。"
|
||||||
view-on-remote: "正確な情報を見る"
|
view-on-remote: "正確な情報を見る"
|
||||||
renoted-by: "{user}がRenote"
|
renoted-by: "{user}がRenote"
|
||||||
|
no-notes: "投稿がありません"
|
||||||
|
|
||||||
error:
|
error:
|
||||||
title: "問題が発生しました"
|
title: "問題が発生しました"
|
||||||
@ -588,6 +589,10 @@ common/views/components/profile-editor.vue:
|
|||||||
mute-list: "ミュート"
|
mute-list: "ミュート"
|
||||||
blocking-list: "ブロック"
|
blocking-list: "ブロック"
|
||||||
export-requested: "エクスポートをリクエストしました。これには時間がかかる場合があります。エクスポートが終わると、ドライブにファイルが追加されます。"
|
export-requested: "エクスポートをリクエストしました。これには時間がかかる場合があります。エクスポートが終わると、ドライブにファイルが追加されます。"
|
||||||
|
enter-password: "パスワードを入力してください"
|
||||||
|
danger-zone: "危険な設定"
|
||||||
|
delete-account: "アカウントを削除"
|
||||||
|
account-deleted: "アカウントが削除されました。データが消えるまで時間がかかる場合があります。"
|
||||||
|
|
||||||
common/views/components/user-list-editor.vue:
|
common/views/components/user-list-editor.vue:
|
||||||
users: "ユーザー"
|
users: "ユーザー"
|
||||||
@ -879,9 +884,6 @@ desktop/views/components/renote-form.vue:
|
|||||||
desktop/views/components/renote-form-window.vue:
|
desktop/views/components/renote-form-window.vue:
|
||||||
title: "この投稿をRenoteしますか?"
|
title: "この投稿をRenoteしますか?"
|
||||||
|
|
||||||
desktop/views/components/timeline.core.vue:
|
|
||||||
empty: "投稿がありません"
|
|
||||||
|
|
||||||
desktop/views/pages/user-following-or-followers.vue:
|
desktop/views/pages/user-following-or-followers.vue:
|
||||||
following: "{user}のフォロー"
|
following: "{user}のフォロー"
|
||||||
followers: "{user}のフォロワー"
|
followers: "{user}のフォロワー"
|
||||||
@ -1518,7 +1520,6 @@ desktop/views/pages/user/user.timeline.vue:
|
|||||||
with-replies: "投稿と返信"
|
with-replies: "投稿と返信"
|
||||||
with-media: "メディア"
|
with-media: "メディア"
|
||||||
my-posts: "私の投稿"
|
my-posts: "私の投稿"
|
||||||
empty: "このユーザーはまだ何も投稿していないようです。"
|
|
||||||
|
|
||||||
desktop/views/widgets/messaging.vue:
|
desktop/views/widgets/messaging.vue:
|
||||||
title: "メッセージ"
|
title: "メッセージ"
|
||||||
@ -1638,9 +1639,6 @@ mobile/views/components/sub-note-content.vue:
|
|||||||
media-count: "{}つのメディア"
|
media-count: "{}つのメディア"
|
||||||
poll: "アンケート"
|
poll: "アンケート"
|
||||||
|
|
||||||
mobile/views/components/timeline.vue:
|
|
||||||
empty: "投稿がありません"
|
|
||||||
|
|
||||||
mobile/views/components/ui.header.vue:
|
mobile/views/components/ui.header.vue:
|
||||||
welcome-back: "おかえりなさい、"
|
welcome-back: "おかえりなさい、"
|
||||||
adjective: "さん"
|
adjective: "さん"
|
||||||
@ -1659,10 +1657,6 @@ mobile/views/components/ui.nav.vue:
|
|||||||
admin: "管理"
|
admin: "管理"
|
||||||
about: "Misskeyについて"
|
about: "Misskeyについて"
|
||||||
|
|
||||||
mobile/views/components/user-timeline.vue:
|
|
||||||
no-notes: "このユーザーは投稿していないようです。"
|
|
||||||
no-notes-with-media: "メディア付き投稿はありません。"
|
|
||||||
|
|
||||||
mobile/views/pages/favorites.vue:
|
mobile/views/pages/favorites.vue:
|
||||||
title: "お気に入り"
|
title: "お気に入り"
|
||||||
|
|
||||||
@ -1687,9 +1681,6 @@ mobile/views/pages/home.vue:
|
|||||||
mentions: "あなた宛て"
|
mentions: "あなた宛て"
|
||||||
messages: "メッセージ"
|
messages: "メッセージ"
|
||||||
|
|
||||||
mobile/views/pages/home.timeline.vue:
|
|
||||||
empty: "投稿がありません"
|
|
||||||
|
|
||||||
mobile/views/pages/tag.vue:
|
mobile/views/pages/tag.vue:
|
||||||
no-posts-found: "ハッシュタグ「{q}」が付けられた投稿は見つかりませんでした。"
|
no-posts-found: "ハッシュタグ「{q}」が付けられた投稿は見つかりませんでした。"
|
||||||
|
|
||||||
@ -1796,9 +1787,6 @@ mobile/views/pages/user/home.vue:
|
|||||||
followers-you-know: "知り合いのフォロワー"
|
followers-you-know: "知り合いのフォロワー"
|
||||||
last-used-at: "最終ログイン"
|
last-used-at: "最終ログイン"
|
||||||
|
|
||||||
mobile/views/pages/user/home.notes.vue:
|
|
||||||
no-notes: "投稿はありません"
|
|
||||||
|
|
||||||
mobile/views/pages/user/home.photos.vue:
|
mobile/views/pages/user/home.photos.vue:
|
||||||
no-photos: "写真はありません"
|
no-photos: "写真はありません"
|
||||||
|
|
||||||
@ -1828,7 +1816,6 @@ deck:
|
|||||||
|
|
||||||
deck/deck.tl-column.vue:
|
deck/deck.tl-column.vue:
|
||||||
is-media-only: "メディア投稿のみ"
|
is-media-only: "メディア投稿のみ"
|
||||||
is-media-view: "メディアビュー"
|
|
||||||
edit: "オプション"
|
edit: "オプション"
|
||||||
|
|
||||||
deck/deck.user-column.vue:
|
deck/deck.user-column.vue:
|
||||||
|
@ -144,6 +144,7 @@ common:
|
|||||||
is-remote-post: "この投稿情報はコピーです。"
|
is-remote-post: "この投稿情報はコピーです。"
|
||||||
view-on-remote: "ちゃんとした情報見せてや!"
|
view-on-remote: "ちゃんとした情報見せてや!"
|
||||||
renoted-by: "{user}がRenote"
|
renoted-by: "{user}がRenote"
|
||||||
|
no-notes: "投稿がありません"
|
||||||
error:
|
error:
|
||||||
title: "問題が起こったわ"
|
title: "問題が起こったわ"
|
||||||
retry: "もっぺん"
|
retry: "もっぺん"
|
||||||
@ -537,6 +538,10 @@ common/views/components/profile-editor.vue:
|
|||||||
mute-list: "ミュート"
|
mute-list: "ミュート"
|
||||||
blocking-list: "ブロック"
|
blocking-list: "ブロック"
|
||||||
export-requested: "エクスポートをリクエストしました。これには時間がかかる場合があります。エクスポートが終わると、ドライブにファイルが追加されます。"
|
export-requested: "エクスポートをリクエストしました。これには時間がかかる場合があります。エクスポートが終わると、ドライブにファイルが追加されます。"
|
||||||
|
enter-password: "パスワードを入力してください"
|
||||||
|
danger-zone: "危険な設定"
|
||||||
|
delete-account: "アカウントを削除"
|
||||||
|
account-deleted: "アカウントが削除されました。データが消えるまで時間がかかる場合があります。"
|
||||||
common/views/components/user-list-editor.vue:
|
common/views/components/user-list-editor.vue:
|
||||||
users: "ユーザー"
|
users: "ユーザー"
|
||||||
rename: "リスト名を変更"
|
rename: "リスト名を変更"
|
||||||
@ -785,8 +790,6 @@ desktop/views/components/renote-form.vue:
|
|||||||
failure: "Renoteでけへん"
|
failure: "Renoteでけへん"
|
||||||
desktop/views/components/renote-form-window.vue:
|
desktop/views/components/renote-form-window.vue:
|
||||||
title: "この投稿をRenoteしてもええか?"
|
title: "この投稿をRenoteしてもええか?"
|
||||||
desktop/views/components/timeline.core.vue:
|
|
||||||
empty: "投稿がありません"
|
|
||||||
desktop/views/pages/user-following-or-followers.vue:
|
desktop/views/pages/user-following-or-followers.vue:
|
||||||
following: "{user}のフォロー"
|
following: "{user}のフォロー"
|
||||||
followers: "{user}のフォロワー"
|
followers: "{user}のフォロワー"
|
||||||
@ -1364,7 +1367,6 @@ desktop/views/pages/user/user.timeline.vue:
|
|||||||
with-replies: "投稿と返信"
|
with-replies: "投稿と返信"
|
||||||
with-media: "メディア"
|
with-media: "メディア"
|
||||||
my-posts: "私の投稿"
|
my-posts: "私の投稿"
|
||||||
empty: "このユーザーはまだ何も投稿しとらんようや。"
|
|
||||||
desktop/views/widgets/messaging.vue:
|
desktop/views/widgets/messaging.vue:
|
||||||
title: "メッセージ"
|
title: "メッセージ"
|
||||||
desktop/views/widgets/notifications.vue:
|
desktop/views/widgets/notifications.vue:
|
||||||
@ -1462,8 +1464,6 @@ mobile/views/components/sub-note-content.vue:
|
|||||||
deleted: "この投稿なんか無くなってもうたわ"
|
deleted: "この投稿なんか無くなってもうたわ"
|
||||||
media-count: "{}つのメディア"
|
media-count: "{}つのメディア"
|
||||||
poll: "アンケート"
|
poll: "アンケート"
|
||||||
mobile/views/components/timeline.vue:
|
|
||||||
empty: "投稿はあらへん"
|
|
||||||
mobile/views/components/ui.header.vue:
|
mobile/views/components/ui.header.vue:
|
||||||
welcome-back: "おかえり、"
|
welcome-back: "おかえり、"
|
||||||
adjective: "はん"
|
adjective: "はん"
|
||||||
@ -1480,9 +1480,6 @@ mobile/views/components/ui.nav.vue:
|
|||||||
settings: "設定"
|
settings: "設定"
|
||||||
admin: "管理"
|
admin: "管理"
|
||||||
about: "Misskeyってなんや?"
|
about: "Misskeyってなんや?"
|
||||||
mobile/views/components/user-timeline.vue:
|
|
||||||
no-notes: "このユーザーは投稿しとらんようや。"
|
|
||||||
no-notes-with-media: "メディア付き投稿はあらへん。"
|
|
||||||
mobile/views/pages/favorites.vue:
|
mobile/views/pages/favorites.vue:
|
||||||
title: "お気に入り"
|
title: "お気に入り"
|
||||||
mobile/views/pages/user-lists.vue:
|
mobile/views/pages/user-lists.vue:
|
||||||
@ -1501,8 +1498,6 @@ mobile/views/pages/home.vue:
|
|||||||
global: "グローバル"
|
global: "グローバル"
|
||||||
mentions: "あんた宛て"
|
mentions: "あんた宛て"
|
||||||
messages: "メッセージ"
|
messages: "メッセージ"
|
||||||
mobile/views/pages/home.timeline.vue:
|
|
||||||
empty: "投稿がありません"
|
|
||||||
mobile/views/pages/tag.vue:
|
mobile/views/pages/tag.vue:
|
||||||
no-posts-found: "ハッシュタグ「{q}」が付けられた投稿はあらへんかった。"
|
no-posts-found: "ハッシュタグ「{q}」が付けられた投稿はあらへんかった。"
|
||||||
mobile/views/pages/welcome.vue:
|
mobile/views/pages/welcome.vue:
|
||||||
@ -1595,8 +1590,6 @@ mobile/views/pages/user/home.vue:
|
|||||||
frequently-replied-users: "よく話すユーザー"
|
frequently-replied-users: "よく話すユーザー"
|
||||||
followers-you-know: "知っとるフォロワー"
|
followers-you-know: "知っとるフォロワー"
|
||||||
last-used-at: "最後いつ来た?"
|
last-used-at: "最後いつ来た?"
|
||||||
mobile/views/pages/user/home.notes.vue:
|
|
||||||
no-notes: "投稿はあらへん"
|
|
||||||
mobile/views/pages/user/home.photos.vue:
|
mobile/views/pages/user/home.photos.vue:
|
||||||
no-photos: "写真はあらへんで"
|
no-photos: "写真はあらへんで"
|
||||||
deck:
|
deck:
|
||||||
@ -1624,7 +1617,6 @@ deck:
|
|||||||
description: "サーバーの運営者により、このタイムラインは使用できない状態に設定されています。"
|
description: "サーバーの運営者により、このタイムラインは使用できない状態に設定されています。"
|
||||||
deck/deck.tl-column.vue:
|
deck/deck.tl-column.vue:
|
||||||
is-media-only: "メディア投稿だけや"
|
is-media-only: "メディア投稿だけや"
|
||||||
is-media-view: "メディアビュー"
|
|
||||||
edit: "オプション"
|
edit: "オプション"
|
||||||
deck/deck.user-column.vue:
|
deck/deck.user-column.vue:
|
||||||
follows-you: "フォローされています"
|
follows-you: "フォローされています"
|
||||||
|
@ -144,6 +144,7 @@ common:
|
|||||||
is-remote-post: "이 글 정보는 복사본입니다."
|
is-remote-post: "이 글 정보는 복사본입니다."
|
||||||
view-on-remote: "정확한 정보 보기"
|
view-on-remote: "정확한 정보 보기"
|
||||||
renoted-by: "{user}이(가) 리노트"
|
renoted-by: "{user}이(가) 리노트"
|
||||||
|
no-notes: "글이 없습니다"
|
||||||
error:
|
error:
|
||||||
title: "오류가 발생했습니다"
|
title: "오류가 발생했습니다"
|
||||||
retry: "다시 시도"
|
retry: "다시 시도"
|
||||||
@ -537,6 +538,10 @@ common/views/components/profile-editor.vue:
|
|||||||
mute-list: "뮤트"
|
mute-list: "뮤트"
|
||||||
blocking-list: "차단"
|
blocking-list: "차단"
|
||||||
export-requested: "내보내기를 요청하였습니다. 이 작업은 시간이 걸릴 수 있습니다. 내보내기가 완료되면 드라이브에 파일이 추가됩니다."
|
export-requested: "내보내기를 요청하였습니다. 이 작업은 시간이 걸릴 수 있습니다. 내보내기가 완료되면 드라이브에 파일이 추가됩니다."
|
||||||
|
enter-password: "비밀번호를 입력하여 주십시오"
|
||||||
|
danger-zone: "위험한 설정"
|
||||||
|
delete-account: "계정 삭제"
|
||||||
|
account-deleted: "계정이 삭제되었습니다. 데이터가 사라질 때까지 시간이 걸릴 수 있습니다."
|
||||||
common/views/components/user-list-editor.vue:
|
common/views/components/user-list-editor.vue:
|
||||||
users: "사용자"
|
users: "사용자"
|
||||||
rename: "리스트 이름 바꾸기"
|
rename: "리스트 이름 바꾸기"
|
||||||
@ -785,8 +790,6 @@ desktop/views/components/renote-form.vue:
|
|||||||
failure: "리노트에 실패하였습니다"
|
failure: "리노트에 실패하였습니다"
|
||||||
desktop/views/components/renote-form-window.vue:
|
desktop/views/components/renote-form-window.vue:
|
||||||
title: "이 글을 리노트하시겠습니까?"
|
title: "이 글을 리노트하시겠습니까?"
|
||||||
desktop/views/components/timeline.core.vue:
|
|
||||||
empty: "글이 없습니다"
|
|
||||||
desktop/views/pages/user-following-or-followers.vue:
|
desktop/views/pages/user-following-or-followers.vue:
|
||||||
following: "{user}의 팔로잉"
|
following: "{user}의 팔로잉"
|
||||||
followers: "{user}의 팔로워"
|
followers: "{user}의 팔로워"
|
||||||
@ -1364,7 +1367,6 @@ desktop/views/pages/user/user.timeline.vue:
|
|||||||
with-replies: "글과 답글"
|
with-replies: "글과 답글"
|
||||||
with-media: "미디어"
|
with-media: "미디어"
|
||||||
my-posts: "내 글"
|
my-posts: "내 글"
|
||||||
empty: "이 사용자는 아직 아무것도 게시하지 않은 것 같습니다."
|
|
||||||
desktop/views/widgets/messaging.vue:
|
desktop/views/widgets/messaging.vue:
|
||||||
title: "메시지"
|
title: "메시지"
|
||||||
desktop/views/widgets/notifications.vue:
|
desktop/views/widgets/notifications.vue:
|
||||||
@ -1462,8 +1464,6 @@ mobile/views/components/sub-note-content.vue:
|
|||||||
deleted: "이 글은 삭제되었습니다"
|
deleted: "이 글은 삭제되었습니다"
|
||||||
media-count: "{}개의 미디어"
|
media-count: "{}개의 미디어"
|
||||||
poll: "투표"
|
poll: "투표"
|
||||||
mobile/views/components/timeline.vue:
|
|
||||||
empty: "글이 없습니다"
|
|
||||||
mobile/views/components/ui.header.vue:
|
mobile/views/components/ui.header.vue:
|
||||||
welcome-back: "돌아오신 걸 환영합니다."
|
welcome-back: "돌아오신 걸 환영합니다."
|
||||||
adjective: "님"
|
adjective: "님"
|
||||||
@ -1480,9 +1480,6 @@ mobile/views/components/ui.nav.vue:
|
|||||||
settings: "설정"
|
settings: "설정"
|
||||||
admin: "관리"
|
admin: "관리"
|
||||||
about: "Misskey에 대하여"
|
about: "Misskey에 대하여"
|
||||||
mobile/views/components/user-timeline.vue:
|
|
||||||
no-notes: "이 사용자는 작성한 글이 없는 것 같습니다."
|
|
||||||
no-notes-with-media: "미디어가 첨부된 글이 없습니다."
|
|
||||||
mobile/views/pages/favorites.vue:
|
mobile/views/pages/favorites.vue:
|
||||||
title: "즐겨찾기"
|
title: "즐겨찾기"
|
||||||
mobile/views/pages/user-lists.vue:
|
mobile/views/pages/user-lists.vue:
|
||||||
@ -1501,8 +1498,6 @@ mobile/views/pages/home.vue:
|
|||||||
global: "글로벌"
|
global: "글로벌"
|
||||||
mentions: "받은 멘션"
|
mentions: "받은 멘션"
|
||||||
messages: "메시지"
|
messages: "메시지"
|
||||||
mobile/views/pages/home.timeline.vue:
|
|
||||||
empty: "글이 없습니다"
|
|
||||||
mobile/views/pages/tag.vue:
|
mobile/views/pages/tag.vue:
|
||||||
no-posts-found: "해시태그 \"{q}\"가 붙은 글을 찾을 수 없습니다."
|
no-posts-found: "해시태그 \"{q}\"가 붙은 글을 찾을 수 없습니다."
|
||||||
mobile/views/pages/welcome.vue:
|
mobile/views/pages/welcome.vue:
|
||||||
@ -1595,8 +1590,6 @@ mobile/views/pages/user/home.vue:
|
|||||||
frequently-replied-users: "자주 언급되는 사용자"
|
frequently-replied-users: "자주 언급되는 사용자"
|
||||||
followers-you-know: "아는 사람의 팔로워"
|
followers-you-know: "아는 사람의 팔로워"
|
||||||
last-used-at: "마지막 로그인"
|
last-used-at: "마지막 로그인"
|
||||||
mobile/views/pages/user/home.notes.vue:
|
|
||||||
no-notes: "글이 없습니다"
|
|
||||||
mobile/views/pages/user/home.photos.vue:
|
mobile/views/pages/user/home.photos.vue:
|
||||||
no-photos: "사진이 없습니다"
|
no-photos: "사진이 없습니다"
|
||||||
deck:
|
deck:
|
||||||
@ -1624,7 +1617,6 @@ deck:
|
|||||||
description: "서버 운영자에 의해 이 타임라인이 사용할 수 없도록 설정되어 있습니다."
|
description: "서버 운영자에 의해 이 타임라인이 사용할 수 없도록 설정되어 있습니다."
|
||||||
deck/deck.tl-column.vue:
|
deck/deck.tl-column.vue:
|
||||||
is-media-only: "미디어가 달린 글만"
|
is-media-only: "미디어가 달린 글만"
|
||||||
is-media-view: "미디어 보기"
|
|
||||||
edit: "옵션"
|
edit: "옵션"
|
||||||
deck/deck.user-column.vue:
|
deck/deck.user-column.vue:
|
||||||
follows-you: "당신을 팔로우합니다"
|
follows-you: "당신을 팔로우합니다"
|
||||||
|
@ -144,6 +144,7 @@ common:
|
|||||||
is-remote-post: "この投稿情報はコピーです。"
|
is-remote-post: "この投稿情報はコピーです。"
|
||||||
view-on-remote: "正確な情報を見る"
|
view-on-remote: "正確な情報を見る"
|
||||||
renoted-by: "{user}がRenote"
|
renoted-by: "{user}がRenote"
|
||||||
|
no-notes: "投稿がありません"
|
||||||
error:
|
error:
|
||||||
title: "問題が発生しました"
|
title: "問題が発生しました"
|
||||||
retry: "やり直す"
|
retry: "やり直す"
|
||||||
@ -537,6 +538,10 @@ common/views/components/profile-editor.vue:
|
|||||||
mute-list: "ミュート"
|
mute-list: "ミュート"
|
||||||
blocking-list: "ブロック"
|
blocking-list: "ブロック"
|
||||||
export-requested: "エクスポートをリクエストしました。これには時間がかかる場合があります。エクスポートが終わると、ドライブにファイルが追加されます。"
|
export-requested: "エクスポートをリクエストしました。これには時間がかかる場合があります。エクスポートが終わると、ドライブにファイルが追加されます。"
|
||||||
|
enter-password: "パスワードを入力してください"
|
||||||
|
danger-zone: "危険な設定"
|
||||||
|
delete-account: "アカウントを削除"
|
||||||
|
account-deleted: "アカウントが削除されました。データが消えるまで時間がかかる場合があります。"
|
||||||
common/views/components/user-list-editor.vue:
|
common/views/components/user-list-editor.vue:
|
||||||
users: "ユーザー"
|
users: "ユーザー"
|
||||||
rename: "リスト名を変更"
|
rename: "リスト名を変更"
|
||||||
@ -785,8 +790,6 @@ desktop/views/components/renote-form.vue:
|
|||||||
failure: "Renote mislukt"
|
failure: "Renote mislukt"
|
||||||
desktop/views/components/renote-form-window.vue:
|
desktop/views/components/renote-form-window.vue:
|
||||||
title: "Weet je zeker dat je deze notitie wilt renoten?"
|
title: "Weet je zeker dat je deze notitie wilt renoten?"
|
||||||
desktop/views/components/timeline.core.vue:
|
|
||||||
empty: "投稿がありません"
|
|
||||||
desktop/views/pages/user-following-or-followers.vue:
|
desktop/views/pages/user-following-or-followers.vue:
|
||||||
following: "{user}のフォロー"
|
following: "{user}のフォロー"
|
||||||
followers: "{user}のフォロワー"
|
followers: "{user}のフォロワー"
|
||||||
@ -1364,7 +1367,6 @@ desktop/views/pages/user/user.timeline.vue:
|
|||||||
with-replies: "Berichten en antwoorden"
|
with-replies: "Berichten en antwoorden"
|
||||||
with-media: "Media"
|
with-media: "Media"
|
||||||
my-posts: "私の投稿"
|
my-posts: "私の投稿"
|
||||||
empty: "Deze gebruiker heeft nog niks geplaatst."
|
|
||||||
desktop/views/widgets/messaging.vue:
|
desktop/views/widgets/messaging.vue:
|
||||||
title: "Gesprekken"
|
title: "Gesprekken"
|
||||||
desktop/views/widgets/notifications.vue:
|
desktop/views/widgets/notifications.vue:
|
||||||
@ -1462,8 +1464,6 @@ mobile/views/components/sub-note-content.vue:
|
|||||||
deleted: "この投稿は削除されました"
|
deleted: "この投稿は削除されました"
|
||||||
media-count: "{} media"
|
media-count: "{} media"
|
||||||
poll: "Peiling"
|
poll: "Peiling"
|
||||||
mobile/views/components/timeline.vue:
|
|
||||||
empty: "Geen notities"
|
|
||||||
mobile/views/components/ui.header.vue:
|
mobile/views/components/ui.header.vue:
|
||||||
welcome-back: "おかえりなさい、"
|
welcome-back: "おかえりなさい、"
|
||||||
adjective: "さん"
|
adjective: "さん"
|
||||||
@ -1480,9 +1480,6 @@ mobile/views/components/ui.nav.vue:
|
|||||||
settings: "Instellingen"
|
settings: "Instellingen"
|
||||||
admin: "管理"
|
admin: "管理"
|
||||||
about: "Over Misskey"
|
about: "Over Misskey"
|
||||||
mobile/views/components/user-timeline.vue:
|
|
||||||
no-notes: "Het lijkt erop dat deze gebruiker nog niks heeft geplaatst"
|
|
||||||
no-notes-with-media: "Er zijn geen notities met bijgevoegde media"
|
|
||||||
mobile/views/pages/favorites.vue:
|
mobile/views/pages/favorites.vue:
|
||||||
title: "お気に入り"
|
title: "お気に入り"
|
||||||
mobile/views/pages/user-lists.vue:
|
mobile/views/pages/user-lists.vue:
|
||||||
@ -1501,8 +1498,6 @@ mobile/views/pages/home.vue:
|
|||||||
global: "グローバル"
|
global: "グローバル"
|
||||||
mentions: "あなた宛て"
|
mentions: "あなた宛て"
|
||||||
messages: "メッセージ"
|
messages: "メッセージ"
|
||||||
mobile/views/pages/home.timeline.vue:
|
|
||||||
empty: "投稿がありません"
|
|
||||||
mobile/views/pages/tag.vue:
|
mobile/views/pages/tag.vue:
|
||||||
no-posts-found: "ハッシュタグ「{q}」が付けられた投稿は見つかりませんでした。"
|
no-posts-found: "ハッシュタグ「{q}」が付けられた投稿は見つかりませんでした。"
|
||||||
mobile/views/pages/welcome.vue:
|
mobile/views/pages/welcome.vue:
|
||||||
@ -1595,8 +1590,6 @@ mobile/views/pages/user/home.vue:
|
|||||||
frequently-replied-users: "よく話すユーザー"
|
frequently-replied-users: "よく話すユーザー"
|
||||||
followers-you-know: "Volgers die je kent"
|
followers-you-know: "Volgers die je kent"
|
||||||
last-used-at: "Laatst actief"
|
last-used-at: "Laatst actief"
|
||||||
mobile/views/pages/user/home.notes.vue:
|
|
||||||
no-notes: "Geen notities"
|
|
||||||
mobile/views/pages/user/home.photos.vue:
|
mobile/views/pages/user/home.photos.vue:
|
||||||
no-photos: "Geen foto's"
|
no-photos: "Geen foto's"
|
||||||
deck:
|
deck:
|
||||||
@ -1624,7 +1617,6 @@ deck:
|
|||||||
description: "サーバーの運営者により、このタイムラインは使用できない状態に設定されています。"
|
description: "サーバーの運営者により、このタイムラインは使用できない状態に設定されています。"
|
||||||
deck/deck.tl-column.vue:
|
deck/deck.tl-column.vue:
|
||||||
is-media-only: "メディア投稿のみ"
|
is-media-only: "メディア投稿のみ"
|
||||||
is-media-view: "メディアビュー"
|
|
||||||
edit: "オプション"
|
edit: "オプション"
|
||||||
deck/deck.user-column.vue:
|
deck/deck.user-column.vue:
|
||||||
follows-you: "フォローされています"
|
follows-you: "フォローされています"
|
||||||
|
@ -144,6 +144,7 @@ common:
|
|||||||
is-remote-post: "この投稿情報はコピーです。"
|
is-remote-post: "この投稿情報はコピーです。"
|
||||||
view-on-remote: "正確な情報を見る"
|
view-on-remote: "正確な情報を見る"
|
||||||
renoted-by: "{user}がRenote"
|
renoted-by: "{user}がRenote"
|
||||||
|
no-notes: "投稿がありません"
|
||||||
error:
|
error:
|
||||||
title: "問題が発生しました"
|
title: "問題が発生しました"
|
||||||
retry: "やり直す"
|
retry: "やり直す"
|
||||||
@ -537,6 +538,10 @@ common/views/components/profile-editor.vue:
|
|||||||
mute-list: "ミュート"
|
mute-list: "ミュート"
|
||||||
blocking-list: "ブロック"
|
blocking-list: "ブロック"
|
||||||
export-requested: "エクスポートをリクエストしました。これには時間がかかる場合があります。エクスポートが終わると、ドライブにファイルが追加されます。"
|
export-requested: "エクスポートをリクエストしました。これには時間がかかる場合があります。エクスポートが終わると、ドライブにファイルが追加されます。"
|
||||||
|
enter-password: "パスワードを入力してください"
|
||||||
|
danger-zone: "危険な設定"
|
||||||
|
delete-account: "アカウントを削除"
|
||||||
|
account-deleted: "アカウントが削除されました。データが消えるまで時間がかかる場合があります。"
|
||||||
common/views/components/user-list-editor.vue:
|
common/views/components/user-list-editor.vue:
|
||||||
users: "ユーザー"
|
users: "ユーザー"
|
||||||
rename: "リスト名を変更"
|
rename: "リスト名を変更"
|
||||||
@ -785,8 +790,6 @@ desktop/views/components/renote-form.vue:
|
|||||||
failure: "Renoteに失敗しました"
|
failure: "Renoteに失敗しました"
|
||||||
desktop/views/components/renote-form-window.vue:
|
desktop/views/components/renote-form-window.vue:
|
||||||
title: "この投稿をRenoteしますか?"
|
title: "この投稿をRenoteしますか?"
|
||||||
desktop/views/components/timeline.core.vue:
|
|
||||||
empty: "投稿がありません"
|
|
||||||
desktop/views/pages/user-following-or-followers.vue:
|
desktop/views/pages/user-following-or-followers.vue:
|
||||||
following: "{user}のフォロー"
|
following: "{user}のフォロー"
|
||||||
followers: "{user}のフォロワー"
|
followers: "{user}のフォロワー"
|
||||||
@ -1364,7 +1367,6 @@ desktop/views/pages/user/user.timeline.vue:
|
|||||||
with-replies: "Innlegg og svar"
|
with-replies: "Innlegg og svar"
|
||||||
with-media: "Media"
|
with-media: "Media"
|
||||||
my-posts: "私の投稿"
|
my-posts: "私の投稿"
|
||||||
empty: "このユーザーはまだ何も投稿していないようです。"
|
|
||||||
desktop/views/widgets/messaging.vue:
|
desktop/views/widgets/messaging.vue:
|
||||||
title: "Melding"
|
title: "Melding"
|
||||||
desktop/views/widgets/notifications.vue:
|
desktop/views/widgets/notifications.vue:
|
||||||
@ -1462,8 +1464,6 @@ mobile/views/components/sub-note-content.vue:
|
|||||||
deleted: "この投稿は削除されました"
|
deleted: "この投稿は削除されました"
|
||||||
media-count: "{}つのメディア"
|
media-count: "{}つのメディア"
|
||||||
poll: "アンケート"
|
poll: "アンケート"
|
||||||
mobile/views/components/timeline.vue:
|
|
||||||
empty: "投稿がありません"
|
|
||||||
mobile/views/components/ui.header.vue:
|
mobile/views/components/ui.header.vue:
|
||||||
welcome-back: "おかえりなさい、"
|
welcome-back: "おかえりなさい、"
|
||||||
adjective: "Mr."
|
adjective: "Mr."
|
||||||
@ -1480,9 +1480,6 @@ mobile/views/components/ui.nav.vue:
|
|||||||
settings: "Innstillinger"
|
settings: "Innstillinger"
|
||||||
admin: "Admin"
|
admin: "Admin"
|
||||||
about: "Misskeyについて"
|
about: "Misskeyについて"
|
||||||
mobile/views/components/user-timeline.vue:
|
|
||||||
no-notes: "このユーザーは投稿していないようです。"
|
|
||||||
no-notes-with-media: "メディア付き投稿はありません。"
|
|
||||||
mobile/views/pages/favorites.vue:
|
mobile/views/pages/favorites.vue:
|
||||||
title: "Favoritter"
|
title: "Favoritter"
|
||||||
mobile/views/pages/user-lists.vue:
|
mobile/views/pages/user-lists.vue:
|
||||||
@ -1501,8 +1498,6 @@ mobile/views/pages/home.vue:
|
|||||||
global: "Globalt"
|
global: "Globalt"
|
||||||
mentions: "あなた宛て"
|
mentions: "あなた宛て"
|
||||||
messages: "メッセージ"
|
messages: "メッセージ"
|
||||||
mobile/views/pages/home.timeline.vue:
|
|
||||||
empty: "投稿がありません"
|
|
||||||
mobile/views/pages/tag.vue:
|
mobile/views/pages/tag.vue:
|
||||||
no-posts-found: "ハッシュタグ「{q}」が付けられた投稿は見つかりませんでした。"
|
no-posts-found: "ハッシュタグ「{q}」が付けられた投稿は見つかりませんでした。"
|
||||||
mobile/views/pages/welcome.vue:
|
mobile/views/pages/welcome.vue:
|
||||||
@ -1595,8 +1590,6 @@ mobile/views/pages/user/home.vue:
|
|||||||
frequently-replied-users: "よく話すユーザー"
|
frequently-replied-users: "よく話すユーザー"
|
||||||
followers-you-know: "知り合いのフォロワー"
|
followers-you-know: "知り合いのフォロワー"
|
||||||
last-used-at: "最終ログイン"
|
last-used-at: "最終ログイン"
|
||||||
mobile/views/pages/user/home.notes.vue:
|
|
||||||
no-notes: "投稿はありません"
|
|
||||||
mobile/views/pages/user/home.photos.vue:
|
mobile/views/pages/user/home.photos.vue:
|
||||||
no-photos: "写真はありません"
|
no-photos: "写真はありません"
|
||||||
deck:
|
deck:
|
||||||
@ -1624,7 +1617,6 @@ deck:
|
|||||||
description: "サーバーの運営者により、このタイムラインは使用できない状態に設定されています。"
|
description: "サーバーの運営者により、このタイムラインは使用できない状態に設定されています。"
|
||||||
deck/deck.tl-column.vue:
|
deck/deck.tl-column.vue:
|
||||||
is-media-only: "メディア投稿のみ"
|
is-media-only: "メディア投稿のみ"
|
||||||
is-media-view: "メディアビュー"
|
|
||||||
edit: "オプション"
|
edit: "オプション"
|
||||||
deck/deck.user-column.vue:
|
deck/deck.user-column.vue:
|
||||||
follows-you: "フォローされています"
|
follows-you: "フォローされています"
|
||||||
|
@ -144,6 +144,7 @@ common:
|
|||||||
is-remote-post: "この投稿情報はコピーです。"
|
is-remote-post: "この投稿情報はコピーです。"
|
||||||
view-on-remote: "Dla dopełnienia, zobacz to zdalnie."
|
view-on-remote: "Dla dopełnienia, zobacz to zdalnie."
|
||||||
renoted-by: "{user} udostępnił(a)"
|
renoted-by: "{user} udostępnił(a)"
|
||||||
|
no-notes: "投稿がありません"
|
||||||
error:
|
error:
|
||||||
title: "Coś poszło nie tak"
|
title: "Coś poszło nie tak"
|
||||||
retry: "Ponów próbę"
|
retry: "Ponów próbę"
|
||||||
@ -537,6 +538,10 @@ common/views/components/profile-editor.vue:
|
|||||||
mute-list: "ミュート"
|
mute-list: "ミュート"
|
||||||
blocking-list: "ブロック"
|
blocking-list: "ブロック"
|
||||||
export-requested: "エクスポートをリクエストしました。これには時間がかかる場合があります。エクスポートが終わると、ドライブにファイルが追加されます。"
|
export-requested: "エクスポートをリクエストしました。これには時間がかかる場合があります。エクスポートが終わると、ドライブにファイルが追加されます。"
|
||||||
|
enter-password: "パスワードを入力してください"
|
||||||
|
danger-zone: "危険な設定"
|
||||||
|
delete-account: "アカウントを削除"
|
||||||
|
account-deleted: "アカウントが削除されました。データが消えるまで時間がかかる場合があります。"
|
||||||
common/views/components/user-list-editor.vue:
|
common/views/components/user-list-editor.vue:
|
||||||
users: "Użytkownicy"
|
users: "Użytkownicy"
|
||||||
rename: "Zmień nazwę listy"
|
rename: "Zmień nazwę listy"
|
||||||
@ -785,8 +790,6 @@ desktop/views/components/renote-form.vue:
|
|||||||
failure: "Nie udało się udostępnić"
|
failure: "Nie udało się udostępnić"
|
||||||
desktop/views/components/renote-form-window.vue:
|
desktop/views/components/renote-form-window.vue:
|
||||||
title: "Czy na pewno chcesz udostępnić ten wpis?"
|
title: "Czy na pewno chcesz udostępnić ten wpis?"
|
||||||
desktop/views/components/timeline.core.vue:
|
|
||||||
empty: "投稿がありません"
|
|
||||||
desktop/views/pages/user-following-or-followers.vue:
|
desktop/views/pages/user-following-or-followers.vue:
|
||||||
following: "{user}のフォロー"
|
following: "{user}のフォロー"
|
||||||
followers: "{user}のフォロワー"
|
followers: "{user}のフォロワー"
|
||||||
@ -1364,7 +1367,6 @@ desktop/views/pages/user/user.timeline.vue:
|
|||||||
with-replies: "Wpisy i odpowiedzi"
|
with-replies: "Wpisy i odpowiedzi"
|
||||||
with-media: "Multimedia"
|
with-media: "Multimedia"
|
||||||
my-posts: "Moje wpisy"
|
my-posts: "Moje wpisy"
|
||||||
empty: "Ten użytkownik nie umieścił jeszcze niczego."
|
|
||||||
desktop/views/widgets/messaging.vue:
|
desktop/views/widgets/messaging.vue:
|
||||||
title: "Wiadomości"
|
title: "Wiadomości"
|
||||||
desktop/views/widgets/notifications.vue:
|
desktop/views/widgets/notifications.vue:
|
||||||
@ -1462,8 +1464,6 @@ mobile/views/components/sub-note-content.vue:
|
|||||||
deleted: "ten wpis został usunięty"
|
deleted: "ten wpis został usunięty"
|
||||||
media-count: "{}zawartości multimedialnej"
|
media-count: "{}zawartości multimedialnej"
|
||||||
poll: "Ankieta"
|
poll: "Ankieta"
|
||||||
mobile/views/components/timeline.vue:
|
|
||||||
empty: "Brak wpisów"
|
|
||||||
mobile/views/components/ui.header.vue:
|
mobile/views/components/ui.header.vue:
|
||||||
welcome-back: "Witaj ponownie, "
|
welcome-back: "Witaj ponownie, "
|
||||||
adjective: "さん"
|
adjective: "さん"
|
||||||
@ -1480,9 +1480,6 @@ mobile/views/components/ui.nav.vue:
|
|||||||
settings: "Ustawienia"
|
settings: "Ustawienia"
|
||||||
admin: "Admin"
|
admin: "Admin"
|
||||||
about: "O Misskey"
|
about: "O Misskey"
|
||||||
mobile/views/components/user-timeline.vue:
|
|
||||||
no-notes: "Wygląda na to, że ten użytkownik nie opublikował jeszcze niczego"
|
|
||||||
no-notes-with-media: "Brak wpisów z zawartością multimedialną"
|
|
||||||
mobile/views/pages/favorites.vue:
|
mobile/views/pages/favorites.vue:
|
||||||
title: "Ulubione"
|
title: "Ulubione"
|
||||||
mobile/views/pages/user-lists.vue:
|
mobile/views/pages/user-lists.vue:
|
||||||
@ -1501,8 +1498,6 @@ mobile/views/pages/home.vue:
|
|||||||
global: "Globalne"
|
global: "Globalne"
|
||||||
mentions: "Wspomnienia"
|
mentions: "Wspomnienia"
|
||||||
messages: "Wiadomości"
|
messages: "Wiadomości"
|
||||||
mobile/views/pages/home.timeline.vue:
|
|
||||||
empty: "投稿がありません"
|
|
||||||
mobile/views/pages/tag.vue:
|
mobile/views/pages/tag.vue:
|
||||||
no-posts-found: "ハッシュタグ「{q}」が付けられた投稿は見つかりませんでした。"
|
no-posts-found: "ハッシュタグ「{q}」が付けられた投稿は見つかりませんでした。"
|
||||||
mobile/views/pages/welcome.vue:
|
mobile/views/pages/welcome.vue:
|
||||||
@ -1595,8 +1590,6 @@ mobile/views/pages/user/home.vue:
|
|||||||
frequently-replied-users: "よく話すユーザー"
|
frequently-replied-users: "よく話すユーザー"
|
||||||
followers-you-know: "Śledzący których znasz"
|
followers-you-know: "Śledzący których znasz"
|
||||||
last-used-at: "Ostatnio aktywny"
|
last-used-at: "Ostatnio aktywny"
|
||||||
mobile/views/pages/user/home.notes.vue:
|
|
||||||
no-notes: "Brak wpisów"
|
|
||||||
mobile/views/pages/user/home.photos.vue:
|
mobile/views/pages/user/home.photos.vue:
|
||||||
no-photos: "Brak zdjęć"
|
no-photos: "Brak zdjęć"
|
||||||
deck:
|
deck:
|
||||||
@ -1624,7 +1617,6 @@ deck:
|
|||||||
description: "サーバーの運営者により、このタイムラインは使用できない状態に設定されています。"
|
description: "サーバーの運営者により、このタイムラインは使用できない状態に設定されています。"
|
||||||
deck/deck.tl-column.vue:
|
deck/deck.tl-column.vue:
|
||||||
is-media-only: "Tylko wpisy z zawartością multimedialną"
|
is-media-only: "Tylko wpisy z zawartością multimedialną"
|
||||||
is-media-view: "Widok multimediów"
|
|
||||||
edit: "Opcje"
|
edit: "Opcje"
|
||||||
deck/deck.user-column.vue:
|
deck/deck.user-column.vue:
|
||||||
follows-you: "フォローされています"
|
follows-you: "フォローされています"
|
||||||
|
@ -144,6 +144,7 @@ common:
|
|||||||
is-remote-post: "この投稿情報はコピーです。"
|
is-remote-post: "この投稿情報はコピーです。"
|
||||||
view-on-remote: "正確な情報を見る"
|
view-on-remote: "正確な情報を見る"
|
||||||
renoted-by: "{user}がRenote"
|
renoted-by: "{user}がRenote"
|
||||||
|
no-notes: "投稿がありません"
|
||||||
error:
|
error:
|
||||||
title: "問題が発生しました"
|
title: "問題が発生しました"
|
||||||
retry: "やり直す"
|
retry: "やり直す"
|
||||||
@ -537,6 +538,10 @@ common/views/components/profile-editor.vue:
|
|||||||
mute-list: "ミュート"
|
mute-list: "ミュート"
|
||||||
blocking-list: "ブロック"
|
blocking-list: "ブロック"
|
||||||
export-requested: "エクスポートをリクエストしました。これには時間がかかる場合があります。エクスポートが終わると、ドライブにファイルが追加されます。"
|
export-requested: "エクスポートをリクエストしました。これには時間がかかる場合があります。エクスポートが終わると、ドライブにファイルが追加されます。"
|
||||||
|
enter-password: "パスワードを入力してください"
|
||||||
|
danger-zone: "危険な設定"
|
||||||
|
delete-account: "アカウントを削除"
|
||||||
|
account-deleted: "アカウントが削除されました。データが消えるまで時間がかかる場合があります。"
|
||||||
common/views/components/user-list-editor.vue:
|
common/views/components/user-list-editor.vue:
|
||||||
users: "ユーザー"
|
users: "ユーザー"
|
||||||
rename: "リスト名を変更"
|
rename: "リスト名を変更"
|
||||||
@ -785,8 +790,6 @@ desktop/views/components/renote-form.vue:
|
|||||||
failure: "Renoteに失敗しました"
|
failure: "Renoteに失敗しました"
|
||||||
desktop/views/components/renote-form-window.vue:
|
desktop/views/components/renote-form-window.vue:
|
||||||
title: "この投稿をRenoteしますか?"
|
title: "この投稿をRenoteしますか?"
|
||||||
desktop/views/components/timeline.core.vue:
|
|
||||||
empty: "投稿がありません"
|
|
||||||
desktop/views/pages/user-following-or-followers.vue:
|
desktop/views/pages/user-following-or-followers.vue:
|
||||||
following: "{user}のフォロー"
|
following: "{user}のフォロー"
|
||||||
followers: "{user}のフォロワー"
|
followers: "{user}のフォロワー"
|
||||||
@ -1364,7 +1367,6 @@ desktop/views/pages/user/user.timeline.vue:
|
|||||||
with-replies: "投稿と返信"
|
with-replies: "投稿と返信"
|
||||||
with-media: "メディア"
|
with-media: "メディア"
|
||||||
my-posts: "私の投稿"
|
my-posts: "私の投稿"
|
||||||
empty: "このユーザーはまだ何も投稿していないようです。"
|
|
||||||
desktop/views/widgets/messaging.vue:
|
desktop/views/widgets/messaging.vue:
|
||||||
title: "メッセージ"
|
title: "メッセージ"
|
||||||
desktop/views/widgets/notifications.vue:
|
desktop/views/widgets/notifications.vue:
|
||||||
@ -1462,8 +1464,6 @@ mobile/views/components/sub-note-content.vue:
|
|||||||
deleted: "この投稿は削除されました"
|
deleted: "この投稿は削除されました"
|
||||||
media-count: "{}つのメディア"
|
media-count: "{}つのメディア"
|
||||||
poll: "アンケート"
|
poll: "アンケート"
|
||||||
mobile/views/components/timeline.vue:
|
|
||||||
empty: "投稿がありません"
|
|
||||||
mobile/views/components/ui.header.vue:
|
mobile/views/components/ui.header.vue:
|
||||||
welcome-back: "おかえりなさい、"
|
welcome-back: "おかえりなさい、"
|
||||||
adjective: "さん"
|
adjective: "さん"
|
||||||
@ -1480,9 +1480,6 @@ mobile/views/components/ui.nav.vue:
|
|||||||
settings: "設定"
|
settings: "設定"
|
||||||
admin: "管理"
|
admin: "管理"
|
||||||
about: "Misskeyについて"
|
about: "Misskeyについて"
|
||||||
mobile/views/components/user-timeline.vue:
|
|
||||||
no-notes: "このユーザーは投稿していないようです。"
|
|
||||||
no-notes-with-media: "メディア付き投稿はありません。"
|
|
||||||
mobile/views/pages/favorites.vue:
|
mobile/views/pages/favorites.vue:
|
||||||
title: "お気に入り"
|
title: "お気に入り"
|
||||||
mobile/views/pages/user-lists.vue:
|
mobile/views/pages/user-lists.vue:
|
||||||
@ -1501,8 +1498,6 @@ mobile/views/pages/home.vue:
|
|||||||
global: "グローバル"
|
global: "グローバル"
|
||||||
mentions: "あなた宛て"
|
mentions: "あなた宛て"
|
||||||
messages: "メッセージ"
|
messages: "メッセージ"
|
||||||
mobile/views/pages/home.timeline.vue:
|
|
||||||
empty: "投稿がありません"
|
|
||||||
mobile/views/pages/tag.vue:
|
mobile/views/pages/tag.vue:
|
||||||
no-posts-found: "ハッシュタグ「{q}」が付けられた投稿は見つかりませんでした。"
|
no-posts-found: "ハッシュタグ「{q}」が付けられた投稿は見つかりませんでした。"
|
||||||
mobile/views/pages/welcome.vue:
|
mobile/views/pages/welcome.vue:
|
||||||
@ -1595,8 +1590,6 @@ mobile/views/pages/user/home.vue:
|
|||||||
frequently-replied-users: "よく話すユーザー"
|
frequently-replied-users: "よく話すユーザー"
|
||||||
followers-you-know: "Seguidores que você conhece"
|
followers-you-know: "Seguidores que você conhece"
|
||||||
last-used-at: "Ativo pela última vez"
|
last-used-at: "Ativo pela última vez"
|
||||||
mobile/views/pages/user/home.notes.vue:
|
|
||||||
no-notes: "Nenhuma mensagem"
|
|
||||||
mobile/views/pages/user/home.photos.vue:
|
mobile/views/pages/user/home.photos.vue:
|
||||||
no-photos: "Sem fotos"
|
no-photos: "Sem fotos"
|
||||||
deck:
|
deck:
|
||||||
@ -1624,7 +1617,6 @@ deck:
|
|||||||
description: "サーバーの運営者により、このタイムラインは使用できない状態に設定されています。"
|
description: "サーバーの運営者により、このタイムラインは使用できない状態に設定されています。"
|
||||||
deck/deck.tl-column.vue:
|
deck/deck.tl-column.vue:
|
||||||
is-media-only: "メディア投稿のみ"
|
is-media-only: "メディア投稿のみ"
|
||||||
is-media-view: "メディアビュー"
|
|
||||||
edit: "オプション"
|
edit: "オプション"
|
||||||
deck/deck.user-column.vue:
|
deck/deck.user-column.vue:
|
||||||
follows-you: "フォローされています"
|
follows-you: "フォローされています"
|
||||||
|
@ -144,6 +144,7 @@ common:
|
|||||||
is-remote-post: "この投稿情報はコピーです。"
|
is-remote-post: "この投稿情報はコピーです。"
|
||||||
view-on-remote: "正確な情報を見る"
|
view-on-remote: "正確な情報を見る"
|
||||||
renoted-by: "{user}がRenote"
|
renoted-by: "{user}がRenote"
|
||||||
|
no-notes: "投稿がありません"
|
||||||
error:
|
error:
|
||||||
title: "Что-то пошло не так :("
|
title: "Что-то пошло не так :("
|
||||||
retry: "Повторить"
|
retry: "Повторить"
|
||||||
@ -537,6 +538,10 @@ common/views/components/profile-editor.vue:
|
|||||||
mute-list: "ミュート"
|
mute-list: "ミュート"
|
||||||
blocking-list: "ブロック"
|
blocking-list: "ブロック"
|
||||||
export-requested: "エクスポートをリクエストしました。これには時間がかかる場合があります。エクスポートが終わると、ドライブにファイルが追加されます。"
|
export-requested: "エクスポートをリクエストしました。これには時間がかかる場合があります。エクスポートが終わると、ドライブにファイルが追加されます。"
|
||||||
|
enter-password: "パスワードを入力してください"
|
||||||
|
danger-zone: "危険な設定"
|
||||||
|
delete-account: "アカウントを削除"
|
||||||
|
account-deleted: "アカウントが削除されました。データが消えるまで時間がかかる場合があります。"
|
||||||
common/views/components/user-list-editor.vue:
|
common/views/components/user-list-editor.vue:
|
||||||
users: "ユーザー"
|
users: "ユーザー"
|
||||||
rename: "リスト名を変更"
|
rename: "リスト名を変更"
|
||||||
@ -785,8 +790,6 @@ desktop/views/components/renote-form.vue:
|
|||||||
failure: "Renoteに失敗しました"
|
failure: "Renoteに失敗しました"
|
||||||
desktop/views/components/renote-form-window.vue:
|
desktop/views/components/renote-form-window.vue:
|
||||||
title: "この投稿をRenoteしますか?"
|
title: "この投稿をRenoteしますか?"
|
||||||
desktop/views/components/timeline.core.vue:
|
|
||||||
empty: "投稿がありません"
|
|
||||||
desktop/views/pages/user-following-or-followers.vue:
|
desktop/views/pages/user-following-or-followers.vue:
|
||||||
following: "{user}のフォロー"
|
following: "{user}のフォロー"
|
||||||
followers: "{user}のフォロワー"
|
followers: "{user}のフォロワー"
|
||||||
@ -1364,7 +1367,6 @@ desktop/views/pages/user/user.timeline.vue:
|
|||||||
with-replies: "投稿と返信"
|
with-replies: "投稿と返信"
|
||||||
with-media: "メディア"
|
with-media: "メディア"
|
||||||
my-posts: "私の投稿"
|
my-posts: "私の投稿"
|
||||||
empty: "このユーザーはまだ何も投稿していないようです。"
|
|
||||||
desktop/views/widgets/messaging.vue:
|
desktop/views/widgets/messaging.vue:
|
||||||
title: "メッセージ"
|
title: "メッセージ"
|
||||||
desktop/views/widgets/notifications.vue:
|
desktop/views/widgets/notifications.vue:
|
||||||
@ -1462,8 +1464,6 @@ mobile/views/components/sub-note-content.vue:
|
|||||||
deleted: "この投稿は削除されました"
|
deleted: "この投稿は削除されました"
|
||||||
media-count: "{}つのメディア"
|
media-count: "{}つのメディア"
|
||||||
poll: "アンケート"
|
poll: "アンケート"
|
||||||
mobile/views/components/timeline.vue:
|
|
||||||
empty: "投稿がありません"
|
|
||||||
mobile/views/components/ui.header.vue:
|
mobile/views/components/ui.header.vue:
|
||||||
welcome-back: "おかえりなさい、"
|
welcome-back: "おかえりなさい、"
|
||||||
adjective: "さん"
|
adjective: "さん"
|
||||||
@ -1480,9 +1480,6 @@ mobile/views/components/ui.nav.vue:
|
|||||||
settings: "設定"
|
settings: "設定"
|
||||||
admin: "管理"
|
admin: "管理"
|
||||||
about: "Misskeyについて"
|
about: "Misskeyについて"
|
||||||
mobile/views/components/user-timeline.vue:
|
|
||||||
no-notes: "このユーザーは投稿していないようです。"
|
|
||||||
no-notes-with-media: "メディア付き投稿はありません。"
|
|
||||||
mobile/views/pages/favorites.vue:
|
mobile/views/pages/favorites.vue:
|
||||||
title: "お気に入り"
|
title: "お気に入り"
|
||||||
mobile/views/pages/user-lists.vue:
|
mobile/views/pages/user-lists.vue:
|
||||||
@ -1501,8 +1498,6 @@ mobile/views/pages/home.vue:
|
|||||||
global: "グローバル"
|
global: "グローバル"
|
||||||
mentions: "あなた宛て"
|
mentions: "あなた宛て"
|
||||||
messages: "メッセージ"
|
messages: "メッセージ"
|
||||||
mobile/views/pages/home.timeline.vue:
|
|
||||||
empty: "投稿がありません"
|
|
||||||
mobile/views/pages/tag.vue:
|
mobile/views/pages/tag.vue:
|
||||||
no-posts-found: "ハッシュタグ「{q}」が付けられた投稿は見つかりませんでした。"
|
no-posts-found: "ハッシュタグ「{q}」が付けられた投稿は見つかりませんでした。"
|
||||||
mobile/views/pages/welcome.vue:
|
mobile/views/pages/welcome.vue:
|
||||||
@ -1595,8 +1590,6 @@ mobile/views/pages/user/home.vue:
|
|||||||
frequently-replied-users: "よく話すユーザー"
|
frequently-replied-users: "よく話すユーザー"
|
||||||
followers-you-know: "知り合いのフォロワー"
|
followers-you-know: "知り合いのフォロワー"
|
||||||
last-used-at: "最終ログイン"
|
last-used-at: "最終ログイン"
|
||||||
mobile/views/pages/user/home.notes.vue:
|
|
||||||
no-notes: "投稿はありません"
|
|
||||||
mobile/views/pages/user/home.photos.vue:
|
mobile/views/pages/user/home.photos.vue:
|
||||||
no-photos: "写真はありません"
|
no-photos: "写真はありません"
|
||||||
deck:
|
deck:
|
||||||
@ -1624,7 +1617,6 @@ deck:
|
|||||||
description: "サーバーの運営者により、このタイムラインは使用できない状態に設定されています。"
|
description: "サーバーの運営者により、このタイムラインは使用できない状態に設定されています。"
|
||||||
deck/deck.tl-column.vue:
|
deck/deck.tl-column.vue:
|
||||||
is-media-only: "メディア投稿のみ"
|
is-media-only: "メディア投稿のみ"
|
||||||
is-media-view: "メディアビュー"
|
|
||||||
edit: "オプション"
|
edit: "オプション"
|
||||||
deck/deck.user-column.vue:
|
deck/deck.user-column.vue:
|
||||||
follows-you: "フォローされています"
|
follows-you: "フォローされています"
|
||||||
|
@ -144,6 +144,7 @@ common:
|
|||||||
is-remote-post: "该投稿已被复制."
|
is-remote-post: "该投稿已被复制."
|
||||||
view-on-remote: "查看准确的信息"
|
view-on-remote: "查看准确的信息"
|
||||||
renoted-by: "由 {user} Renote"
|
renoted-by: "由 {user} Renote"
|
||||||
|
no-notes: "没有帖子"
|
||||||
error:
|
error:
|
||||||
title: "出现问题"
|
title: "出现问题"
|
||||||
retry: "重试"
|
retry: "重试"
|
||||||
@ -537,6 +538,10 @@ common/views/components/profile-editor.vue:
|
|||||||
mute-list: "屏蔽列表"
|
mute-list: "屏蔽列表"
|
||||||
blocking-list: "黑名单"
|
blocking-list: "黑名单"
|
||||||
export-requested: "导出请求已提交。可能需要花一些时间。导出的文件将保存到网盘中。"
|
export-requested: "导出请求已提交。可能需要花一些时间。导出的文件将保存到网盘中。"
|
||||||
|
enter-password: "请输入您的密码"
|
||||||
|
danger-zone: "危险选项"
|
||||||
|
delete-account: "删除帐户"
|
||||||
|
account-deleted: "帐户已被删除。 数据会在一段时间之后清除。"
|
||||||
common/views/components/user-list-editor.vue:
|
common/views/components/user-list-editor.vue:
|
||||||
users: "用户"
|
users: "用户"
|
||||||
rename: "重命名列表"
|
rename: "重命名列表"
|
||||||
@ -785,8 +790,6 @@ desktop/views/components/renote-form.vue:
|
|||||||
failure: "重新发送失败"
|
failure: "重新发送失败"
|
||||||
desktop/views/components/renote-form-window.vue:
|
desktop/views/components/renote-form-window.vue:
|
||||||
title: "您是否要重新发送?"
|
title: "您是否要重新发送?"
|
||||||
desktop/views/components/timeline.core.vue:
|
|
||||||
empty: "没有帖子"
|
|
||||||
desktop/views/pages/user-following-or-followers.vue:
|
desktop/views/pages/user-following-or-followers.vue:
|
||||||
following: "{user}的正在关注"
|
following: "{user}的正在关注"
|
||||||
followers: "{user}的关注者"
|
followers: "{user}的关注者"
|
||||||
@ -1364,7 +1367,6 @@ desktop/views/pages/user/user.timeline.vue:
|
|||||||
with-replies: "帖子与回复"
|
with-replies: "帖子与回复"
|
||||||
with-media: "媒体"
|
with-media: "媒体"
|
||||||
my-posts: "我的帖子"
|
my-posts: "我的帖子"
|
||||||
empty: "看起来这个用户还没有发布什么呢。"
|
|
||||||
desktop/views/widgets/messaging.vue:
|
desktop/views/widgets/messaging.vue:
|
||||||
title: "信息"
|
title: "信息"
|
||||||
desktop/views/widgets/notifications.vue:
|
desktop/views/widgets/notifications.vue:
|
||||||
@ -1462,8 +1464,6 @@ mobile/views/components/sub-note-content.vue:
|
|||||||
deleted: "帖子已删除"
|
deleted: "帖子已删除"
|
||||||
media-count: "附加{}媒体"
|
media-count: "附加{}媒体"
|
||||||
poll: "投票"
|
poll: "投票"
|
||||||
mobile/views/components/timeline.vue:
|
|
||||||
empty: "无帖子"
|
|
||||||
mobile/views/components/ui.header.vue:
|
mobile/views/components/ui.header.vue:
|
||||||
welcome-back: "欢迎回来!"
|
welcome-back: "欢迎回来!"
|
||||||
adjective: "先生"
|
adjective: "先生"
|
||||||
@ -1480,9 +1480,6 @@ mobile/views/components/ui.nav.vue:
|
|||||||
settings: "设置"
|
settings: "设置"
|
||||||
admin: "管理"
|
admin: "管理"
|
||||||
about: "关于 Misskey"
|
about: "关于 Misskey"
|
||||||
mobile/views/components/user-timeline.vue:
|
|
||||||
no-notes: "看起来该用户还没有发表任何东西哎。"
|
|
||||||
no-notes-with-media: "媒体附件没有备注"
|
|
||||||
mobile/views/pages/favorites.vue:
|
mobile/views/pages/favorites.vue:
|
||||||
title: "收藏"
|
title: "收藏"
|
||||||
mobile/views/pages/user-lists.vue:
|
mobile/views/pages/user-lists.vue:
|
||||||
@ -1501,8 +1498,6 @@ mobile/views/pages/home.vue:
|
|||||||
global: "Global"
|
global: "Global"
|
||||||
mentions: "Mentions"
|
mentions: "Mentions"
|
||||||
messages: "信息"
|
messages: "信息"
|
||||||
mobile/views/pages/home.timeline.vue:
|
|
||||||
empty: "没有帖子"
|
|
||||||
mobile/views/pages/tag.vue:
|
mobile/views/pages/tag.vue:
|
||||||
no-posts-found: "没有找到带有主题标签“{q}”的帖子"
|
no-posts-found: "没有找到带有主题标签“{q}”的帖子"
|
||||||
mobile/views/pages/welcome.vue:
|
mobile/views/pages/welcome.vue:
|
||||||
@ -1595,8 +1590,6 @@ mobile/views/pages/user/home.vue:
|
|||||||
frequently-replied-users: "活跃用户"
|
frequently-replied-users: "活跃用户"
|
||||||
followers-you-know: "您可能认识的关注者"
|
followers-you-know: "您可能认识的关注者"
|
||||||
last-used-at: "上次登录:"
|
last-used-at: "上次登录:"
|
||||||
mobile/views/pages/user/home.notes.vue:
|
|
||||||
no-notes: "没有帖子"
|
|
||||||
mobile/views/pages/user/home.photos.vue:
|
mobile/views/pages/user/home.photos.vue:
|
||||||
no-photos: "没有图片"
|
no-photos: "没有图片"
|
||||||
deck:
|
deck:
|
||||||
@ -1624,7 +1617,6 @@ deck:
|
|||||||
description: "服务器管理员已禁用时间线。"
|
description: "服务器管理员已禁用时间线。"
|
||||||
deck/deck.tl-column.vue:
|
deck/deck.tl-column.vue:
|
||||||
is-media-only: "只有媒体的帖子"
|
is-media-only: "只有媒体的帖子"
|
||||||
is-media-view: "媒体视图"
|
|
||||||
edit: "选项"
|
edit: "选项"
|
||||||
deck/deck.user-column.vue:
|
deck/deck.user-column.vue:
|
||||||
follows-you: "关注您"
|
follows-you: "关注您"
|
||||||
|
16
package.json
16
package.json
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "misskey",
|
"name": "misskey",
|
||||||
"author": "syuilo <i@syuilo.com>",
|
"author": "syuilo <i@syuilo.com>",
|
||||||
"version": "10.87.5",
|
"version": "10.89.0",
|
||||||
"codename": "nighthike",
|
"codename": "nighthike",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@ -95,14 +95,14 @@
|
|||||||
"@types/websocket": "0.0.40",
|
"@types/websocket": "0.0.40",
|
||||||
"@types/ws": "6.0.1",
|
"@types/ws": "6.0.1",
|
||||||
"animejs": "3.0.1",
|
"animejs": "3.0.1",
|
||||||
"apexcharts": "3.3.0",
|
"apexcharts": "3.4.1",
|
||||||
"autobind-decorator": "2.4.0",
|
"autobind-decorator": "2.4.0",
|
||||||
"autosize": "4.0.2",
|
"autosize": "4.0.2",
|
||||||
"autwh": "0.1.0",
|
"autwh": "0.1.0",
|
||||||
"bcryptjs": "2.4.3",
|
"bcryptjs": "2.4.3",
|
||||||
"bee-queue": "1.2.2",
|
"bee-queue": "1.2.2",
|
||||||
"bootstrap-vue": "2.0.0-rc.11",
|
"bootstrap-vue": "2.0.0-rc.11",
|
||||||
"cafy": "14.0.1",
|
"cafy": "15.1.0",
|
||||||
"chai": "4.2.0",
|
"chai": "4.2.0",
|
||||||
"chai-http": "4.2.1",
|
"chai-http": "4.2.1",
|
||||||
"chalk": "2.4.2",
|
"chalk": "2.4.2",
|
||||||
@ -228,20 +228,20 @@
|
|||||||
"uuid": "3.3.2",
|
"uuid": "3.3.2",
|
||||||
"v-animate-css": "0.0.3",
|
"v-animate-css": "0.0.3",
|
||||||
"video-thumbnail-generator": "1.1.3",
|
"video-thumbnail-generator": "1.1.3",
|
||||||
"vue": "2.6.6",
|
"vue": "2.6.7",
|
||||||
"vue-color": "2.7.0",
|
"vue-color": "2.7.0",
|
||||||
"vue-content-loading": "1.5.3",
|
"vue-content-loading": "1.5.3",
|
||||||
"vue-cropperjs": "3.0.0",
|
"vue-cropperjs": "3.0.0",
|
||||||
"vue-i18n": "8.8.1",
|
"vue-i18n": "8.8.2",
|
||||||
"vue-js-modal": "1.3.28",
|
"vue-js-modal": "1.3.28",
|
||||||
"vue-loader": "15.6.2",
|
"vue-loader": "15.6.4",
|
||||||
"vue-marquee-text-component": "1.1.1",
|
"vue-marquee-text-component": "1.1.1",
|
||||||
"vue-prism-component": "1.1.1",
|
"vue-prism-component": "1.1.1",
|
||||||
"vue-router": "3.0.2",
|
"vue-router": "3.0.2",
|
||||||
"vue-sequential-entrance": "1.1.3",
|
"vue-sequential-entrance": "1.1.3",
|
||||||
"vue-style-loader": "4.1.2",
|
"vue-style-loader": "4.1.2",
|
||||||
"vue-svg-inline-loader": "1.2.10",
|
"vue-svg-inline-loader": "1.2.10",
|
||||||
"vue-template-compiler": "2.6.6",
|
"vue-template-compiler": "2.6.7",
|
||||||
"vuedraggable": "2.17.0",
|
"vuedraggable": "2.17.0",
|
||||||
"vuewordcloud": "18.7.11",
|
"vuewordcloud": "18.7.11",
|
||||||
"vuex": "3.1.0",
|
"vuex": "3.1.0",
|
||||||
@ -251,7 +251,7 @@
|
|||||||
"webpack": "4.28.4",
|
"webpack": "4.28.4",
|
||||||
"webpack-cli": "3.2.1",
|
"webpack-cli": "3.2.1",
|
||||||
"websocket": "1.0.28",
|
"websocket": "1.0.28",
|
||||||
"ws": "6.1.3",
|
"ws": "6.1.4",
|
||||||
"xev": "2.0.1"
|
"xev": "2.0.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -128,15 +128,16 @@ export default Vue.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
close() {
|
close() {
|
||||||
|
this.$el.style.pointerEvents = 'none';
|
||||||
(this.$refs.bg as any).style.pointerEvents = 'none';
|
(this.$refs.bg as any).style.pointerEvents = 'none';
|
||||||
|
(this.$refs.main as any).style.pointerEvents = 'none';
|
||||||
|
|
||||||
anime({
|
anime({
|
||||||
targets: this.$refs.bg,
|
targets: this.$refs.bg,
|
||||||
opacity: 0,
|
opacity: 0,
|
||||||
duration: 300,
|
duration: 300,
|
||||||
easing: 'linear'
|
easing: 'linear'
|
||||||
});
|
});
|
||||||
|
|
||||||
(this.$refs.main as any).style.pointerEvents = 'none';
|
|
||||||
anime({
|
anime({
|
||||||
targets: this.$refs.main,
|
targets: this.$refs.main,
|
||||||
opacity: 0,
|
opacity: 0,
|
||||||
|
@ -14,8 +14,12 @@ export default Vue.extend({
|
|||||||
|
|
||||||
<style lang="stylus" scoped>
|
<style lang="stylus" scoped>
|
||||||
.zxrjzpcj
|
.zxrjzpcj
|
||||||
|
display inline-block
|
||||||
padding 6px 8px 6px 6px
|
padding 6px 8px 6px 6px
|
||||||
|
margin-top 4px
|
||||||
|
margin-bottom 4px
|
||||||
border-radius 32px
|
border-radius 32px
|
||||||
|
white-space nowrap
|
||||||
|
|
||||||
&:hover
|
&:hover
|
||||||
text-decoration none
|
text-decoration none
|
||||||
|
@ -101,6 +101,13 @@
|
|||||||
<ui-button @click="doExport()"><fa :icon="faDownload"/> {{ $t('export') }}</ui-button>
|
<ui-button @click="doExport()"><fa :icon="faDownload"/> {{ $t('export') }}</ui-button>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<details>
|
||||||
|
<summary>{{ $t('danger-zone') }}</summary>
|
||||||
|
<ui-button @click="deleteAccount()">{{ $t('delete-account') }}</ui-button>
|
||||||
|
</details>
|
||||||
|
</section>
|
||||||
</ui-card>
|
</ui-card>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -283,6 +290,25 @@ export default Vue.extend({
|
|||||||
type: 'info',
|
type: 'info',
|
||||||
text: this.$t('export-requested')
|
text: this.$t('export-requested')
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
async deleteAccount() {
|
||||||
|
const { canceled: canceled, result: password } = await this.$root.dialog({
|
||||||
|
title: this.$t('enter-password'),
|
||||||
|
input: {
|
||||||
|
type: 'password'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (canceled) return;
|
||||||
|
|
||||||
|
this.$root.api('i/delete-account', {
|
||||||
|
password
|
||||||
|
}).then(() => {
|
||||||
|
this.$root.dialog({
|
||||||
|
type: 'success',
|
||||||
|
text: this.$t('account-deleted')
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
<div class="newer-indicator" :style="{ top: $store.state.uiHeaderHeight + 'px' }" v-show="queue.length > 0"></div>
|
<div class="newer-indicator" :style="{ top: $store.state.uiHeaderHeight + 'px' }" v-show="queue.length > 0"></div>
|
||||||
|
|
||||||
<slot name="empty" v-if="notes.length == 0 && !fetching && inited"></slot>
|
<div class="empty" v-if="notes.length == 0 && !fetching && inited">{{ $t('@.no-notes') }}</div>
|
||||||
|
|
||||||
<mk-error v-if="!fetching && !inited" @retry="init()"/>
|
<mk-error v-if="!fetching && !inited" @retry="init()"/>
|
||||||
|
|
||||||
@ -209,6 +209,11 @@ export default Vue.extend({
|
|||||||
> *
|
> *
|
||||||
transition transform .3s ease, opacity .3s ease
|
transition transform .3s ease, opacity .3s ease
|
||||||
|
|
||||||
|
> .empty
|
||||||
|
padding 16px
|
||||||
|
text-align center
|
||||||
|
color var(--text)
|
||||||
|
|
||||||
> .placeholder
|
> .placeholder
|
||||||
padding 32px
|
padding 32px
|
||||||
opacity 0.3
|
opacity 0.3
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<x-notes ref="timeline" :make-promise="makePromise" :media-view="mediaView" @inited="() => $emit('loaded')"/>
|
<x-notes ref="timeline" :make-promise="makePromise" @inited="() => $emit('loaded')"/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
@ -22,11 +22,6 @@ export default Vue.extend({
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: false,
|
required: false,
|
||||||
default: false
|
default: false
|
||||||
},
|
|
||||||
mediaView: {
|
|
||||||
type: Boolean,
|
|
||||||
required: false,
|
|
||||||
default: false
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<x-notes ref="timeline" :make-promise="makePromise" :media-view="mediaView" @inited="() => $emit('loaded')"/>
|
<x-notes ref="timeline" :make-promise="makePromise" @inited="() => $emit('loaded')"/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
@ -22,11 +22,6 @@ export default Vue.extend({
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: false,
|
required: false,
|
||||||
default: false
|
default: false
|
||||||
},
|
|
||||||
mediaView: {
|
|
||||||
type: Boolean,
|
|
||||||
required: false,
|
|
||||||
default: false
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="eamppglmnmimdhrlzhplwpvyeaqmmhxu">
|
<div class="eamppglmnmimdhrlzhplwpvyeaqmmhxu">
|
||||||
<slot name="empty" v-if="notes.length == 0 && !fetching && inited"></slot>
|
<div class="empty" v-if="notes.length == 0 && !fetching && inited">{{ $t('@.no-notes') }}</div>
|
||||||
|
|
||||||
<mk-error v-if="!fetching && !inited" @retry="init()"/>
|
<mk-error v-if="!fetching && !inited" @retry="init()"/>
|
||||||
|
|
||||||
@ -17,7 +17,6 @@
|
|||||||
:note="note"
|
:note="note"
|
||||||
:key="note.id"
|
:key="note.id"
|
||||||
@update:note="onNoteUpdated(i, $event)"
|
@update:note="onNoteUpdated(i, $event)"
|
||||||
:media-view="mediaView"
|
|
||||||
:compact="true"
|
:compact="true"
|
||||||
:mini="true"/>
|
:mini="true"/>
|
||||||
<p class="date" :key="note.id + '_date'" v-if="i != notes.length - 1 && note._date != _notes[i + 1]._date">
|
<p class="date" :key="note.id + '_date'" v-if="i != notes.length - 1 && note._date != _notes[i + 1]._date">
|
||||||
@ -56,11 +55,6 @@ export default Vue.extend({
|
|||||||
props: {
|
props: {
|
||||||
makePromise: {
|
makePromise: {
|
||||||
required: true
|
required: true
|
||||||
},
|
|
||||||
mediaView: {
|
|
||||||
type: Boolean,
|
|
||||||
required: false,
|
|
||||||
default: false
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -91,6 +85,9 @@ export default Vue.extend({
|
|||||||
watch: {
|
watch: {
|
||||||
queue(q) {
|
queue(q) {
|
||||||
this.count(q.length);
|
this.count(q.length);
|
||||||
|
},
|
||||||
|
makePromise() {
|
||||||
|
this.init();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -115,12 +112,12 @@ export default Vue.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
reload() {
|
reload() {
|
||||||
this.queue = [];
|
|
||||||
this.notes = [];
|
|
||||||
this.init();
|
this.init();
|
||||||
},
|
},
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
|
this.queue = [];
|
||||||
|
this.notes = [];
|
||||||
this.fetching = true;
|
this.fetching = true;
|
||||||
this.makePromise().then(x => {
|
this.makePromise().then(x => {
|
||||||
if (Array.isArray(x)) {
|
if (Array.isArray(x)) {
|
||||||
@ -204,6 +201,11 @@ export default Vue.extend({
|
|||||||
> *
|
> *
|
||||||
transition transform .3s ease, opacity .3s ease
|
transition transform .3s ease, opacity .3s ease
|
||||||
|
|
||||||
|
> .empty
|
||||||
|
padding 16px
|
||||||
|
text-align center
|
||||||
|
color var(--text)
|
||||||
|
|
||||||
> .placeholder
|
> .placeholder
|
||||||
padding 16px
|
padding 16px
|
||||||
opacity 0.3
|
opacity 0.3
|
||||||
|
@ -12,25 +12,21 @@
|
|||||||
|
|
||||||
<div class="editor" style="padding:12px" v-if="edit">
|
<div class="editor" style="padding:12px" v-if="edit">
|
||||||
<ui-switch v-model="column.isMediaOnly" @change="onChangeSettings">{{ $t('is-media-only') }}</ui-switch>
|
<ui-switch v-model="column.isMediaOnly" @change="onChangeSettings">{{ $t('is-media-only') }}</ui-switch>
|
||||||
<ui-switch v-model="column.isMediaView" @change="onChangeSettings">{{ $t('is-media-view') }}</ui-switch>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<x-list-tl v-if="column.type == 'list'"
|
<x-list-tl v-if="column.type == 'list'"
|
||||||
:list="column.list"
|
:list="column.list"
|
||||||
:media-only="column.isMediaOnly"
|
:media-only="column.isMediaOnly"
|
||||||
:media-view="column.isMediaView"
|
|
||||||
ref="tl"
|
ref="tl"
|
||||||
/>
|
/>
|
||||||
<x-hashtag-tl v-else-if="column.type == 'hashtag'"
|
<x-hashtag-tl v-else-if="column.type == 'hashtag'"
|
||||||
:tag-tl="$store.state.settings.tagTimelines.find(x => x.id == column.tagTlId)"
|
:tag-tl="$store.state.settings.tagTimelines.find(x => x.id == column.tagTlId)"
|
||||||
:media-only="column.isMediaOnly"
|
:media-only="column.isMediaOnly"
|
||||||
:media-view="column.isMediaView"
|
|
||||||
ref="tl"
|
ref="tl"
|
||||||
/>
|
/>
|
||||||
<x-tl v-else
|
<x-tl v-else
|
||||||
:src="column.type"
|
:src="column.type"
|
||||||
:media-only="column.isMediaOnly"
|
:media-only="column.isMediaOnly"
|
||||||
:media-view="column.isMediaView"
|
|
||||||
ref="tl"
|
ref="tl"
|
||||||
/>
|
/>
|
||||||
</x-column>
|
</x-column>
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
</p>
|
</p>
|
||||||
<p class="desc">{{ $t('disabled-timeline.description') }}</p>
|
<p class="desc">{{ $t('disabled-timeline.description') }}</p>
|
||||||
</div>
|
</div>
|
||||||
<x-notes v-else ref="timeline" :make-promise="makePromise" :media-view="mediaView" @inited="() => $emit('loaded')"/>
|
<x-notes v-else ref="timeline" :make-promise="makePromise" @inited="() => $emit('loaded')"/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
@ -34,11 +34,6 @@ export default Vue.extend({
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: false,
|
required: false,
|
||||||
default: false
|
default: false
|
||||||
},
|
|
||||||
mediaView: {
|
|
||||||
type: Boolean,
|
|
||||||
required: false,
|
|
||||||
default: false
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -73,16 +68,18 @@ export default Vue.extend({
|
|||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
mediaOnly() {
|
mediaOnly() {
|
||||||
this.fetch();
|
(this.$refs.timeline as any).reload();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
created() {
|
created() {
|
||||||
this.makePromise = cursor => this.$root.api(this.endpoint, {
|
this.makePromise = cursor => this.$root.api(this.endpoint, {
|
||||||
limit: fetchLimit + 1,
|
limit: fetchLimit + 1,
|
||||||
untilDate: cursor ? undefined : (this.date ? this.date.getTime() : undefined),
|
|
||||||
untilId: cursor ? cursor : undefined,
|
untilId: cursor ? cursor : undefined,
|
||||||
...this.baseQuery, ...this.query
|
withFiles: this.mediaOnly,
|
||||||
|
includeMyRenotes: this.$store.state.settings.showMyRenotes,
|
||||||
|
includeRenotedMyNotes: this.$store.state.settings.showRenotedMyNotes,
|
||||||
|
includeLocalRenotes: this.$store.state.settings.showLocalRenotes
|
||||||
}).then(notes => {
|
}).then(notes => {
|
||||||
if (notes.length == fetchLimit + 1) {
|
if (notes.length == fetchLimit + 1) {
|
||||||
notes.pop();
|
notes.pop();
|
||||||
|
@ -61,7 +61,26 @@ export default Vue.extend({
|
|||||||
return {
|
return {
|
||||||
withFiles: false,
|
withFiles: false,
|
||||||
images: [],
|
images: [],
|
||||||
makePromise: cursor => this.$root.api('users/notes', {
|
makePromise: null,
|
||||||
|
chart: null as ApexCharts
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
user() {
|
||||||
|
this.fetch();
|
||||||
|
this.genPromiseMaker();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
created() {
|
||||||
|
this.fetch();
|
||||||
|
this.genPromiseMaker();
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
genPromiseMaker() {
|
||||||
|
this.makePromise = cursor => this.$root.api('users/notes', {
|
||||||
userId: this.user.id,
|
userId: this.user.id,
|
||||||
limit: fetchLimit + 1,
|
limit: fetchLimit + 1,
|
||||||
untilId: cursor ? cursor : undefined,
|
untilId: cursor ? cursor : undefined,
|
||||||
@ -82,15 +101,9 @@ export default Vue.extend({
|
|||||||
cursor: null
|
cursor: null
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
};
|
},
|
||||||
},
|
|
||||||
|
|
||||||
created() {
|
|
||||||
this.fetch();
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
|
||||||
fetch() {
|
fetch() {
|
||||||
const image = [
|
const image = [
|
||||||
'image/jpeg',
|
'image/jpeg',
|
||||||
@ -144,7 +157,9 @@ export default Vue.extend({
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const chart = new ApexCharts(this.$refs.chart, {
|
if (this.chart) this.chart.destroy();
|
||||||
|
|
||||||
|
this.chart = new ApexCharts(this.$refs.chart, {
|
||||||
chart: {
|
chart: {
|
||||||
type: 'bar',
|
type: 'bar',
|
||||||
stacked: true,
|
stacked: true,
|
||||||
@ -190,7 +205,7 @@ export default Vue.extend({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
chart.render();
|
this.chart.render();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -8,9 +8,6 @@
|
|||||||
<router-link to="/explore">{{ $t('@.empty-timeline-info.explore') }}</router-link>
|
<router-link to="/explore">{{ $t('@.empty-timeline-info.explore') }}</router-link>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #empty>
|
|
||||||
<fa :icon="['far', 'comments']"/>{{ $t('empty') }}
|
|
||||||
</template>
|
|
||||||
</mk-notes>
|
</mk-notes>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -9,7 +9,6 @@
|
|||||||
<span :data-active="mode == 'my-posts'" @click="mode = 'my-posts'"><fa icon="user"/> {{ $t('my-posts') }}</span>
|
<span :data-active="mode == 'my-posts'" @click="mode = 'my-posts'"><fa icon="user"/> {{ $t('my-posts') }}</span>
|
||||||
</header>
|
</header>
|
||||||
</template>
|
</template>
|
||||||
<template #empty><fa :icon="['far', 'comments']"/>{{ $t('empty') }}</template>
|
|
||||||
</mk-notes>
|
</mk-notes>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -122,6 +122,10 @@ export default Vue.extend({
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
this.fetchReplies();
|
||||||
|
},
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
note() {
|
note() {
|
||||||
this.fetchReplies();
|
this.fetchReplies();
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="ivaojijs">
|
<div class="ivaojijs">
|
||||||
<slot name="empty" v-if="notes.length == 0 && !fetching && inited"></slot>
|
<div class="empty" v-if="notes.length == 0 && !fetching && inited">{{ $t('@.no-notes') }}</div>
|
||||||
|
|
||||||
<mk-error v-if="!fetching && !inited" @retry="init()"/>
|
<mk-error v-if="!fetching && !inited" @retry="init()"/>
|
||||||
|
|
||||||
@ -197,6 +197,11 @@ export default Vue.extend({
|
|||||||
@media (min-width 500px)
|
@media (min-width 500px)
|
||||||
box-shadow 0 8px 32px rgba(#000, 0.1)
|
box-shadow 0 8px 32px rgba(#000, 0.1)
|
||||||
|
|
||||||
|
> .empty
|
||||||
|
padding 16px
|
||||||
|
text-align center
|
||||||
|
color var(--text)
|
||||||
|
|
||||||
.transition
|
.transition
|
||||||
.mk-notes-enter
|
.mk-notes-enter
|
||||||
.mk-notes-leave-to
|
.mk-notes-leave-to
|
||||||
|
@ -1,11 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="mk-user-timeline">
|
<div class="mk-user-timeline">
|
||||||
<mk-notes ref="timeline" :make-promise="makePromise" @inited="() => $emit('loaded')">
|
<mk-notes ref="timeline" :make-promise="makePromise" @inited="() => $emit('loaded')"/>
|
||||||
<template #empty>
|
|
||||||
<fa :icon="['far', 'comments']"/>
|
|
||||||
{{ withMedia ? this.$t('no-notes-with-media') : this.$t('no-notes') }}
|
|
||||||
</template>
|
|
||||||
</mk-notes>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -7,11 +7,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</ui-container>
|
</ui-container>
|
||||||
|
|
||||||
<mk-notes ref="timeline" :make-promise="makePromise" @inited="() => $emit('loaded')">
|
<mk-notes ref="timeline" :make-promise="makePromise" @inited="() => $emit('loaded')"/>
|
||||||
<template #empty>
|
|
||||||
<fa :icon="['far', 'comments']"/>{{ $t('empty') }}
|
|
||||||
</template>
|
|
||||||
</mk-notes>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<div v-if="!fetching && notes.length > 0">
|
<div v-if="!fetching && notes.length > 0">
|
||||||
<mk-note-card v-for="note in notes" :key="note.id" :note="note"/>
|
<mk-note-card v-for="note in notes" :key="note.id" :note="note"/>
|
||||||
</div>
|
</div>
|
||||||
<p class="empty" v-if="!fetching && notes.length == 0">{{ $t('no-notes') }}</p>
|
<p class="empty" v-if="!fetching && notes.length == 0">{{ $t('@.no-notes') }}</p>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<mk-ui>
|
<mk-ui>
|
||||||
<template #header v-if="!fetching"><img :src="avator" alt="">
|
<template #header v-if="!fetching">
|
||||||
<mk-user-name :user="user"/>
|
<img :src="avator" alt=""><mk-user-name :user="user"/>
|
||||||
</template>
|
</template>
|
||||||
<div class="wwtwuxyh" v-if="!fetching">
|
<div class="wwtwuxyh" v-if="!fetching">
|
||||||
<div class="is-suspended" v-if="user.isSuspended"><p><fa icon="exclamation-triangle"/> {{ $t('@.user-suspended') }}</p></div>
|
<div class="is-suspended" v-if="user.isSuspended"><p><fa icon="exclamation-triangle"/> {{ $t('@.user-suspended') }}</p></div>
|
||||||
@ -23,7 +23,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="description">
|
<div class="description">
|
||||||
<mfm v-if="user.description" :text="user.description" :is-note="false" :author="user" :i="$store.state.i" :custom-emojis="user.emojis"/>
|
<mfm v-if="user.description" :text="user.description" :is-note="false" :author="user" :i="$store.state.i" :custom-emojis="user.emojis"/>
|
||||||
<x-integrations :user="user" style="margin:24px 0;"/>
|
<x-integrations :user="user" style="margin:20px 0;"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="fields" v-if="user.fields">
|
<div class="fields" v-if="user.fields">
|
||||||
<dl class="field" v-for="(field, i) in user.fields" :key="i">
|
<dl class="field" v-for="(field, i) in user.fields" :key="i">
|
||||||
@ -68,9 +68,9 @@
|
|||||||
</nav>
|
</nav>
|
||||||
<main>
|
<main>
|
||||||
<template v-if="$route.name == 'user'">
|
<template v-if="$route.name == 'user'">
|
||||||
<x-home v-if="page == 'home'" :user="user"/>
|
<x-home v-if="page == 'home'" :user="user" :key="user.id"/>
|
||||||
<mk-user-timeline v-if="page == 'notes'" :user="user" key="tl"/>
|
<mk-user-timeline v-if="page == 'notes'" :user="user" :key="`tl:${user.id}`"/>
|
||||||
<mk-user-timeline v-if="page == 'media'" :user="user" :with-media="true" key="media"/>
|
<mk-user-timeline v-if="page == 'media'" :user="user" :with-media="true" :key="`media:${user.id}`"/>
|
||||||
</template>
|
</template>
|
||||||
<router-view :user="user"></router-view>
|
<router-view :user="user"></router-view>
|
||||||
</main>
|
</main>
|
||||||
@ -251,9 +251,6 @@ export default Vue.extend({
|
|||||||
@media (max-width 450px)
|
@media (max-width 450px)
|
||||||
font-size 15px
|
font-size 15px
|
||||||
|
|
||||||
@media (max-width 400px)
|
|
||||||
font-size 14px
|
|
||||||
|
|
||||||
> .fields
|
> .fields
|
||||||
margin 8px 0
|
margin 8px 0
|
||||||
|
|
||||||
@ -285,6 +282,9 @@ export default Vue.extend({
|
|||||||
> .info
|
> .info
|
||||||
margin 8px 0
|
margin 8px 0
|
||||||
|
|
||||||
|
@media (max-width 450px)
|
||||||
|
font-size 15px
|
||||||
|
|
||||||
> p
|
> p
|
||||||
display inline
|
display inline
|
||||||
margin 0 16px 0 0
|
margin 0 16px 0 0
|
||||||
|
24
src/client/assets/redoc.html
Normal file
24
src/client/assets/redoc.html
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Misskey API</title>
|
||||||
|
<!-- needed for adaptive design -->
|
||||||
|
<meta charset="utf-8"/>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<link href="https://fonts.googleapis.com/css?family=Montserrat:300,400,700|Roboto:300,400,700" rel="stylesheet">
|
||||||
|
|
||||||
|
<!--
|
||||||
|
ReDoc doesn't change outer page styles
|
||||||
|
-->
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<redoc spec-url='/api.json'></redoc>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/redoc@next/bundles/redoc.standalone.js"> </script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -74,7 +74,7 @@ APIはすべてリクエストのパラメータ・レスポンスともにJSON
|
|||||||
|
|
||||||
ストリーミングAPIも提供しています。
|
ストリーミングAPIも提供しています。
|
||||||
|
|
||||||
APIリファレンスもご確認ください。
|
[APIリファレンス](/api-doc)もご確認ください。
|
||||||
|
|
||||||
### レートリミット
|
### レートリミット
|
||||||
Misskey APIにはレートリミットがあり、短時間のうちに多数のリクエストを送信すると、一定時間APIを利用することができなくなることがあります。
|
Misskey APIにはレートリミットがあり、短時間のうちに多数のリクエストを送信すると、一定時間APIを利用することができなくなることがあります。
|
||||||
|
@ -1,40 +0,0 @@
|
|||||||
@import "../style"
|
|
||||||
|
|
||||||
#url
|
|
||||||
padding 8px 12px 8px 8px
|
|
||||||
font-family Consolas, 'Courier New', Courier, Monaco, monospace
|
|
||||||
color #fff
|
|
||||||
background #222e40
|
|
||||||
border-radius 4px
|
|
||||||
overflow auto
|
|
||||||
white-space nowrap
|
|
||||||
|
|
||||||
> .method
|
|
||||||
display inline-block
|
|
||||||
margin 0 8px 0 0
|
|
||||||
padding 0 6px
|
|
||||||
color #fff
|
|
||||||
background #17afc7
|
|
||||||
border-radius 4px
|
|
||||||
user-select none
|
|
||||||
pointer-events none
|
|
||||||
|
|
||||||
> .host
|
|
||||||
opacity 0.7
|
|
||||||
|
|
||||||
#stability
|
|
||||||
padding 8px 12px
|
|
||||||
color #fff
|
|
||||||
border-radius 4px
|
|
||||||
|
|
||||||
&.deprecated
|
|
||||||
background #f42443
|
|
||||||
|
|
||||||
&.experimental
|
|
||||||
background #f2781a
|
|
||||||
|
|
||||||
&.stable
|
|
||||||
background #3dcc90
|
|
||||||
|
|
||||||
> b
|
|
||||||
margin-left 4px
|
|
@ -1,81 +0,0 @@
|
|||||||
extends ../../base
|
|
||||||
include ../mixins
|
|
||||||
|
|
||||||
block meta
|
|
||||||
link(rel="stylesheet" href="/docs/assets/api/endpoints/style.css")
|
|
||||||
|
|
||||||
block main
|
|
||||||
h1= title
|
|
||||||
|
|
||||||
p#url
|
|
||||||
span.method POST
|
|
||||||
span.host
|
|
||||||
= endpointUrl.host
|
|
||||||
| /
|
|
||||||
span.path= endpointUrl.path
|
|
||||||
|
|
||||||
- var stability = endpoint.stability || 'experimental';
|
|
||||||
p#stability(class=stability)
|
|
||||||
| Stability:
|
|
||||||
b= stability
|
|
||||||
|
|
||||||
if endpoint.desc
|
|
||||||
p#desc= endpoint.desc[lang] || endpoint.desc['ja-JP']
|
|
||||||
|
|
||||||
if endpoint.requireCredential
|
|
||||||
div.ui.info: p
|
|
||||||
i.fas.fa-id-card-alt(style="margin-right: 4px")
|
|
||||||
= i18n('docs.api.endpoints.require-credential')
|
|
||||||
|
|
||||||
if endpoint.kind
|
|
||||||
div.ui.info: p
|
|
||||||
i.fas.fa-unlock-alt(style="margin-right: 4px")
|
|
||||||
!= i18n('docs.api.endpoints.require-permission').replace('{permission}', `<code>${endpoint.kind}</code>`)
|
|
||||||
|
|
||||||
if endpoint.limit
|
|
||||||
div.ui.info.warn: p
|
|
||||||
i.far.fa-clock(style="margin-right: 4px")
|
|
||||||
b!= i18n('docs.api.endpoints.has-limit')
|
|
||||||
if endpoint.limit.duration
|
|
||||||
!= i18n('docs.api.endpoints.duration-limit').replace('{duration}', endpoint.limit.duration).replace('{max}', endpoint.limit.max)
|
|
||||||
if endpoint.limit.minInterval
|
|
||||||
!= i18n('docs.api.endpoints.min-interval-limit').replace('{interval}', endpoint.limit.minInterval)
|
|
||||||
|
|
||||||
if params && Object.keys(params).length > 0
|
|
||||||
section
|
|
||||||
h2= i18n('docs.api.endpoints.params')
|
|
||||||
+propTable(params)
|
|
||||||
|
|
||||||
if paramDefs
|
|
||||||
each paramDef in paramDefs
|
|
||||||
section(id= paramDef.name)
|
|
||||||
h3= paramDef.name
|
|
||||||
+propTable(paramDef.params)
|
|
||||||
if params && Object.keys(params).length == 0
|
|
||||||
section
|
|
||||||
h2= i18n('docs.api.endpoints.params')
|
|
||||||
p= i18n('docs.api.endpoints.no-params')
|
|
||||||
|
|
||||||
if res
|
|
||||||
section
|
|
||||||
h2= i18n('docs.api.endpoints.res')
|
|
||||||
|
|
||||||
if resProps
|
|
||||||
+propTable(resProps)
|
|
||||||
|
|
||||||
if resDefs
|
|
||||||
each resDef in resDefs
|
|
||||||
section(id= resDef.name)
|
|
||||||
h3= resDef.name
|
|
||||||
+propTable(resDef.props)
|
|
||||||
else
|
|
||||||
if res.type.startsWith('entity')
|
|
||||||
a(href=`/docs/${lang}/api/entities/${kebab(res.entity)}`)= res.entity
|
|
||||||
|
|
||||||
block footer
|
|
||||||
div.ui.info: p
|
|
||||||
i.fas.fa-info-circle(style="margin-right: 4px")
|
|
||||||
= i18n('docs.api.endpoints.generated')
|
|
||||||
p
|
|
||||||
= i18n('docs.api.endpoints.show-src')
|
|
||||||
a(href=src target="_blank")= i18n('docs.api.endpoints.show-src-link')
|
|
@ -1,90 +0,0 @@
|
|||||||
name: "DriveFile"
|
|
||||||
|
|
||||||
desc:
|
|
||||||
ja-JP: "ドライブのファイル。"
|
|
||||||
en-US: "A file of Drive."
|
|
||||||
|
|
||||||
props:
|
|
||||||
id:
|
|
||||||
type: "id"
|
|
||||||
optional: false
|
|
||||||
desc:
|
|
||||||
ja-JP: "ファイルID"
|
|
||||||
en-US: "The ID of this file"
|
|
||||||
|
|
||||||
createdAt:
|
|
||||||
type: "date"
|
|
||||||
optional: false
|
|
||||||
desc:
|
|
||||||
ja-JP: "アップロード日時"
|
|
||||||
en-US: "The upload date of this file"
|
|
||||||
|
|
||||||
userId:
|
|
||||||
type: "id(User)"
|
|
||||||
optional: false
|
|
||||||
desc:
|
|
||||||
ja-JP: "所有者ID"
|
|
||||||
en-US: "The ID of the owner of this file"
|
|
||||||
|
|
||||||
user:
|
|
||||||
type: "entity(User)"
|
|
||||||
optional: true
|
|
||||||
desc:
|
|
||||||
ja-JP: "所有者"
|
|
||||||
en-US: "The owner of this file"
|
|
||||||
|
|
||||||
name:
|
|
||||||
type: "string"
|
|
||||||
optional: false
|
|
||||||
desc:
|
|
||||||
ja-JP: "ファイル名"
|
|
||||||
en-US: "The name of this file"
|
|
||||||
|
|
||||||
md5:
|
|
||||||
type: "string"
|
|
||||||
optional: false
|
|
||||||
desc:
|
|
||||||
ja-JP: "ファイルのMD5ハッシュ値"
|
|
||||||
en-US: "The md5 hash value of this file"
|
|
||||||
|
|
||||||
type:
|
|
||||||
type: "string"
|
|
||||||
optional: false
|
|
||||||
desc:
|
|
||||||
ja-JP: "ファイルの種類"
|
|
||||||
en-US: "The type of this file"
|
|
||||||
|
|
||||||
datasize:
|
|
||||||
type: "number"
|
|
||||||
optional: false
|
|
||||||
desc:
|
|
||||||
ja-JP: "ファイルサイズ(bytes)"
|
|
||||||
en-US: "The size of this file (bytes)"
|
|
||||||
|
|
||||||
url:
|
|
||||||
type: "string"
|
|
||||||
optional: false
|
|
||||||
desc:
|
|
||||||
ja-JP: "ファイルのURL"
|
|
||||||
en-US: "The URL of this file"
|
|
||||||
|
|
||||||
folderId:
|
|
||||||
type: "id(DriveFolder)"
|
|
||||||
optional: true
|
|
||||||
desc:
|
|
||||||
ja-JP: "フォルダID"
|
|
||||||
en-US: "The ID of the folder of this file"
|
|
||||||
|
|
||||||
folder:
|
|
||||||
type: "entity(DriveFolder)"
|
|
||||||
optional: true
|
|
||||||
desc:
|
|
||||||
ja-JP: "フォルダ"
|
|
||||||
en-US: "The folder of this file"
|
|
||||||
|
|
||||||
isSensitive:
|
|
||||||
type: "boolean"
|
|
||||||
optional: true
|
|
||||||
desc:
|
|
||||||
ja-JP: "このメディアが「閲覧注意」(NSFW)かどうか"
|
|
||||||
en-US: "Whether this media is NSFW"
|
|
@ -1,41 +0,0 @@
|
|||||||
name: "DriveFolder"
|
|
||||||
|
|
||||||
desc:
|
|
||||||
ja-JP: "ドライブのフォルダを表します。"
|
|
||||||
en-US: "A folder of Drive."
|
|
||||||
|
|
||||||
props:
|
|
||||||
id:
|
|
||||||
type: "id"
|
|
||||||
optional: false
|
|
||||||
desc:
|
|
||||||
ja-JP: "フォルダID"
|
|
||||||
en-US: "The ID of this folder"
|
|
||||||
|
|
||||||
createdAt:
|
|
||||||
type: "date"
|
|
||||||
optional: false
|
|
||||||
desc:
|
|
||||||
ja-JP: "作成日時"
|
|
||||||
en-US: "The created date of this folder"
|
|
||||||
|
|
||||||
userId:
|
|
||||||
type: "id(User)"
|
|
||||||
optional: false
|
|
||||||
desc:
|
|
||||||
ja-JP: "所有者ID"
|
|
||||||
en-US: "The ID of the owner of this folder"
|
|
||||||
|
|
||||||
parentId:
|
|
||||||
type: "entity(DriveFolder)"
|
|
||||||
optional: false
|
|
||||||
desc:
|
|
||||||
ja-JP: "親フォルダのID (ルートなら null)"
|
|
||||||
en-US: "The ID of parent folder"
|
|
||||||
|
|
||||||
name:
|
|
||||||
type: "string"
|
|
||||||
optional: false
|
|
||||||
desc:
|
|
||||||
ja-JP: "フォルダ名"
|
|
||||||
en-US: "The name of this folder"
|
|
@ -1,211 +0,0 @@
|
|||||||
name: "Note"
|
|
||||||
|
|
||||||
desc:
|
|
||||||
ja-JP: "投稿。"
|
|
||||||
en-US: "A note."
|
|
||||||
|
|
||||||
props:
|
|
||||||
id:
|
|
||||||
type: "id"
|
|
||||||
optional: false
|
|
||||||
desc:
|
|
||||||
ja-JP: "投稿ID"
|
|
||||||
en-US: "The ID of this note"
|
|
||||||
|
|
||||||
createdAt:
|
|
||||||
type: "date"
|
|
||||||
optional: false
|
|
||||||
desc:
|
|
||||||
ja-JP: "投稿日時"
|
|
||||||
en-US: "The posted date of this note"
|
|
||||||
|
|
||||||
viaMobile:
|
|
||||||
type: "boolean"
|
|
||||||
optional: true
|
|
||||||
desc:
|
|
||||||
ja-JP: "モバイル端末から投稿したか否か(自己申告であることに留意)"
|
|
||||||
en-US: "Whether this note sent via a mobile device"
|
|
||||||
|
|
||||||
localOnly:
|
|
||||||
type: "boolean"
|
|
||||||
optional: true
|
|
||||||
desc:
|
|
||||||
ja-JP: "ローカルのみに公開する投稿か否か"
|
|
||||||
en-US: "Whether this note is no federation"
|
|
||||||
|
|
||||||
text:
|
|
||||||
type: "string"
|
|
||||||
optional: true
|
|
||||||
desc:
|
|
||||||
ja-JP: "投稿の本文"
|
|
||||||
en-US: "The text of this note"
|
|
||||||
|
|
||||||
fileIds:
|
|
||||||
type: "id(DriveFile)[]"
|
|
||||||
optional: true
|
|
||||||
desc:
|
|
||||||
ja-JP: "添付されているファイルのID (なければレスポンスでは空配列)"
|
|
||||||
en-US: "The IDs of the attached files (empty array for response if no files is attached)"
|
|
||||||
|
|
||||||
files:
|
|
||||||
type: "entity(DriveFile)[]"
|
|
||||||
optional: true
|
|
||||||
desc:
|
|
||||||
ja-JP: "添付されているファイル"
|
|
||||||
en-US: "The attached files"
|
|
||||||
|
|
||||||
userId:
|
|
||||||
type: "id(User)"
|
|
||||||
optional: false
|
|
||||||
desc:
|
|
||||||
ja-JP: "投稿者ID"
|
|
||||||
en-US: "The ID of author of this note"
|
|
||||||
|
|
||||||
user:
|
|
||||||
type: "entity(User)"
|
|
||||||
optional: true
|
|
||||||
desc:
|
|
||||||
ja-JP: "投稿者"
|
|
||||||
en-US: "The author of this note"
|
|
||||||
|
|
||||||
myReaction:
|
|
||||||
type: "string"
|
|
||||||
optional: true
|
|
||||||
desc:
|
|
||||||
ja-JP: "この投稿に対する自分の<a href='/docs/api/reactions'>リアクション</a>"
|
|
||||||
en-US: "The your <a href='/docs/api/reactions'>reaction</a> of this note"
|
|
||||||
|
|
||||||
renoteCount:
|
|
||||||
type: "number"
|
|
||||||
optional: false
|
|
||||||
desc:
|
|
||||||
ja-JP: "この投稿がRenoteされた数"
|
|
||||||
en-US: "The number of renotes for this post"
|
|
||||||
|
|
||||||
repliesCount:
|
|
||||||
type: "number"
|
|
||||||
optional: false
|
|
||||||
desc:
|
|
||||||
ja-JP: "この投稿に返信された数"
|
|
||||||
en-US: "The number of replies to this post"
|
|
||||||
|
|
||||||
reactionCounts:
|
|
||||||
type: "object"
|
|
||||||
optional: false
|
|
||||||
desc:
|
|
||||||
ja-JP: "<a href='/docs/api/reactions'>リアクション</a>をキーとし、この投稿に対するそのリアクションの数を値としたオブジェクト"
|
|
||||||
|
|
||||||
replyId:
|
|
||||||
type: "id(Note)"
|
|
||||||
optional: true
|
|
||||||
desc:
|
|
||||||
ja-JP: "返信した投稿のID"
|
|
||||||
en-US: "The ID of the replyed note"
|
|
||||||
|
|
||||||
reply:
|
|
||||||
type: "entity(Note)"
|
|
||||||
optional: true
|
|
||||||
desc:
|
|
||||||
ja-JP: "返信した投稿"
|
|
||||||
en-US: "The replyed note"
|
|
||||||
|
|
||||||
renoteId:
|
|
||||||
type: "id(Note)"
|
|
||||||
optional: true
|
|
||||||
desc:
|
|
||||||
ja-JP: "引用した投稿のID"
|
|
||||||
en-US: "The ID of the quoted note"
|
|
||||||
|
|
||||||
renote:
|
|
||||||
type: "entity(Note)"
|
|
||||||
optional: true
|
|
||||||
desc:
|
|
||||||
ja-JP: "引用した投稿"
|
|
||||||
en-US: "The quoted note"
|
|
||||||
|
|
||||||
poll:
|
|
||||||
type: "object"
|
|
||||||
optional: true
|
|
||||||
desc:
|
|
||||||
ja-JP: "投票"
|
|
||||||
en-US: "The poll"
|
|
||||||
|
|
||||||
props:
|
|
||||||
choices:
|
|
||||||
type: "object[]"
|
|
||||||
optional: false
|
|
||||||
desc:
|
|
||||||
ja-JP: "投票の選択肢"
|
|
||||||
en-US: "The choices of this poll"
|
|
||||||
|
|
||||||
props:
|
|
||||||
id:
|
|
||||||
type: "number"
|
|
||||||
optional: false
|
|
||||||
desc:
|
|
||||||
ja-JP: "選択肢ID"
|
|
||||||
en-US: "The ID of this choice"
|
|
||||||
|
|
||||||
isVoted:
|
|
||||||
type: "boolean"
|
|
||||||
optional: true
|
|
||||||
desc:
|
|
||||||
ja-JP: "自分がこの選択肢に投票したかどうか"
|
|
||||||
en-US: "Whether you voted to this choice"
|
|
||||||
|
|
||||||
text:
|
|
||||||
type: "string"
|
|
||||||
optional: false
|
|
||||||
desc:
|
|
||||||
ja-JP: "選択肢本文"
|
|
||||||
en-US: "The text of this choice"
|
|
||||||
|
|
||||||
votes:
|
|
||||||
type: "number"
|
|
||||||
optional: false
|
|
||||||
desc:
|
|
||||||
ja-JP: "この選択肢に投票された数"
|
|
||||||
en-US: "The number voted for this choice"
|
|
||||||
geo:
|
|
||||||
type: "object"
|
|
||||||
optional: true
|
|
||||||
desc:
|
|
||||||
ja-JP: "位置情報"
|
|
||||||
en-US: "Geo location"
|
|
||||||
|
|
||||||
props:
|
|
||||||
coordinates:
|
|
||||||
type: "number[]"
|
|
||||||
optional: false
|
|
||||||
desc:
|
|
||||||
ja-JP: "座標。最初に経度:-180〜180で表す。最後に緯度:-90〜90で表す。"
|
|
||||||
|
|
||||||
altitude:
|
|
||||||
type: "number"
|
|
||||||
optional: false
|
|
||||||
desc:
|
|
||||||
ja-JP: "高度。メートル単位で表す。"
|
|
||||||
|
|
||||||
accuracy:
|
|
||||||
type: "number"
|
|
||||||
optional: false
|
|
||||||
desc:
|
|
||||||
ja-JP: "緯度、経度の精度。メートル単位で表す。"
|
|
||||||
|
|
||||||
altitudeAccuracy:
|
|
||||||
type: "number"
|
|
||||||
optional: false
|
|
||||||
desc:
|
|
||||||
ja-JP: "高度の精度。メートル単位で表す。"
|
|
||||||
|
|
||||||
heading:
|
|
||||||
type: "number"
|
|
||||||
optional: false
|
|
||||||
desc:
|
|
||||||
ja-JP: "方角。0〜360の角度で表す。0が北、90が東、180が南、270が西。"
|
|
||||||
|
|
||||||
speed:
|
|
||||||
type: "number"
|
|
||||||
optional: false
|
|
||||||
desc:
|
|
||||||
ja-JP: "速度。メートル / 秒数で表す。"
|
|
@ -1 +0,0 @@
|
|||||||
@import "../style"
|
|
@ -1,174 +0,0 @@
|
|||||||
name: "User"
|
|
||||||
|
|
||||||
desc:
|
|
||||||
ja-JP: "ユーザー。"
|
|
||||||
en-US: "A user."
|
|
||||||
|
|
||||||
props:
|
|
||||||
id:
|
|
||||||
type: "id"
|
|
||||||
optional: false
|
|
||||||
desc:
|
|
||||||
ja-JP: "ユーザーID"
|
|
||||||
en-US: "The ID of this user"
|
|
||||||
|
|
||||||
createdAt:
|
|
||||||
type: "date"
|
|
||||||
optional: false
|
|
||||||
desc:
|
|
||||||
ja-JP: "アカウント作成日時"
|
|
||||||
en-US: "The registered date of this user"
|
|
||||||
|
|
||||||
username:
|
|
||||||
type: "string"
|
|
||||||
optional: false
|
|
||||||
desc:
|
|
||||||
ja-JP: "ユーザー名"
|
|
||||||
en-US: "The username of this user"
|
|
||||||
|
|
||||||
description:
|
|
||||||
type: "string"
|
|
||||||
optional: false
|
|
||||||
desc:
|
|
||||||
ja-JP: "アカウントの説明(自己紹介)"
|
|
||||||
en-US: "The description of this user"
|
|
||||||
|
|
||||||
avatarId:
|
|
||||||
type: "id(DriveFile)"
|
|
||||||
optional: true
|
|
||||||
desc:
|
|
||||||
ja-JP: "アバターのID"
|
|
||||||
en-US: "The ID of the avatar of this user"
|
|
||||||
|
|
||||||
avatarUrl:
|
|
||||||
type: "string"
|
|
||||||
optional: false
|
|
||||||
desc:
|
|
||||||
ja-JP: "アバターのURL"
|
|
||||||
en-US: "The URL of the avatar of this user"
|
|
||||||
|
|
||||||
bannerId:
|
|
||||||
type: "id(DriveFile)"
|
|
||||||
optional: true
|
|
||||||
desc:
|
|
||||||
ja-JP: "バナーのID"
|
|
||||||
en-US: "The ID of the banner of this user"
|
|
||||||
|
|
||||||
bannerUrl:
|
|
||||||
type: "string"
|
|
||||||
optional: false
|
|
||||||
desc:
|
|
||||||
ja-JP: "バナーのURL"
|
|
||||||
en-US: "The URL of the banner of this user"
|
|
||||||
|
|
||||||
followersCount:
|
|
||||||
type: "number"
|
|
||||||
optional: false
|
|
||||||
desc:
|
|
||||||
ja-JP: "フォロワーの数"
|
|
||||||
en-US: "The number of the followers for this user"
|
|
||||||
|
|
||||||
followingCount:
|
|
||||||
type: "number"
|
|
||||||
optional: false
|
|
||||||
desc:
|
|
||||||
ja-JP: "フォローしているユーザーの数"
|
|
||||||
en-US: "The number of the following users for this user"
|
|
||||||
|
|
||||||
isFollowing:
|
|
||||||
type: "boolean"
|
|
||||||
optional: true
|
|
||||||
desc:
|
|
||||||
ja-JP: "自分がこのユーザーをフォローしているか"
|
|
||||||
|
|
||||||
isFollowed:
|
|
||||||
type: "boolean"
|
|
||||||
optional: true
|
|
||||||
desc:
|
|
||||||
ja-JP: "自分がこのユーザーにフォローされているか"
|
|
||||||
|
|
||||||
isMuted:
|
|
||||||
type: "boolean"
|
|
||||||
optional: true
|
|
||||||
desc:
|
|
||||||
ja-JP: "自分がこのユーザーをミュートしているか"
|
|
||||||
en-US: "Whether you muted this user"
|
|
||||||
|
|
||||||
notesCount:
|
|
||||||
type: "number"
|
|
||||||
optional: false
|
|
||||||
desc:
|
|
||||||
ja-JP: "投稿の数"
|
|
||||||
en-US: "The number of the notes of this user"
|
|
||||||
|
|
||||||
pinnedNotes:
|
|
||||||
type: "entity(Note)[]"
|
|
||||||
optional: true
|
|
||||||
desc:
|
|
||||||
ja-JP: "ピン留めされた投稿"
|
|
||||||
en-US: "The pinned note of this user"
|
|
||||||
|
|
||||||
pinnedNoteIds:
|
|
||||||
type: "id(Note)[]"
|
|
||||||
optional: true
|
|
||||||
desc:
|
|
||||||
ja-JP: "ピン留めされた投稿のID"
|
|
||||||
en-US: "The ID of the pinned note of this user"
|
|
||||||
|
|
||||||
host:
|
|
||||||
type: "string | null"
|
|
||||||
optional: false
|
|
||||||
desc:
|
|
||||||
ja-JP: "ホスト (例: example.com:3000)"
|
|
||||||
en-US: "Host (e.g. example.com:3000)"
|
|
||||||
|
|
||||||
twitter:
|
|
||||||
type: "object"
|
|
||||||
optional: true
|
|
||||||
desc:
|
|
||||||
ja-JP: "連携されているTwitterアカウント情報"
|
|
||||||
en-US: "The info of the connected twitter account of this user"
|
|
||||||
|
|
||||||
props:
|
|
||||||
userId:
|
|
||||||
type: "string"
|
|
||||||
optional: false
|
|
||||||
desc:
|
|
||||||
ja-JP: "ユーザーID"
|
|
||||||
en-US: "The user ID"
|
|
||||||
|
|
||||||
screenName:
|
|
||||||
type: "string"
|
|
||||||
optional: false
|
|
||||||
desc:
|
|
||||||
ja-JP: "ユーザー名"
|
|
||||||
en-US: "The screen name of this user"
|
|
||||||
|
|
||||||
isBot:
|
|
||||||
type: "boolean"
|
|
||||||
optional: true
|
|
||||||
desc:
|
|
||||||
ja-JP: "botか否か(自己申告であることに留意)"
|
|
||||||
en-US: "Whether is bot or not"
|
|
||||||
|
|
||||||
profile:
|
|
||||||
type: "object"
|
|
||||||
optional: false
|
|
||||||
desc:
|
|
||||||
ja-JP: "プロフィール"
|
|
||||||
en-US: "The profile of this user"
|
|
||||||
|
|
||||||
props:
|
|
||||||
location:
|
|
||||||
type: "string"
|
|
||||||
optional: true
|
|
||||||
desc:
|
|
||||||
ja-JP: "場所"
|
|
||||||
en-US: "The location of this user"
|
|
||||||
|
|
||||||
birthday:
|
|
||||||
type: "string"
|
|
||||||
optional: true
|
|
||||||
desc:
|
|
||||||
ja-JP: "誕生日 (YYYY-MM-DD)"
|
|
||||||
en-US: "The birthday of this user (YYYY-MM-DD)"
|
|
@ -1,20 +0,0 @@
|
|||||||
extends ../../base
|
|
||||||
include ../mixins
|
|
||||||
|
|
||||||
block meta
|
|
||||||
link(rel="stylesheet" href="/docs/assets/api/entities/style.css")
|
|
||||||
|
|
||||||
block main
|
|
||||||
h1= name
|
|
||||||
|
|
||||||
p#desc= desc[lang] || desc['ja-JP']
|
|
||||||
|
|
||||||
section
|
|
||||||
h2= i18n('docs.api.entities.properties')
|
|
||||||
+propTable(props)
|
|
||||||
|
|
||||||
if propDefs
|
|
||||||
each propDef in propDefs
|
|
||||||
section(id= propDef.name)
|
|
||||||
h3= propDef.name
|
|
||||||
+propTable(propDef.props)
|
|
@ -1,34 +0,0 @@
|
|||||||
mixin type(prop)
|
|
||||||
i= prop.type
|
|
||||||
if prop.kind == 'id'
|
|
||||||
if prop.entity
|
|
||||||
| (
|
|
||||||
a(href=`/docs/${lang}/api/entities/${kebab(prop.entity)}`)= prop.entity
|
|
||||||
| ID)
|
|
||||||
else
|
|
||||||
| (ID)
|
|
||||||
else if prop.kind == 'entity'
|
|
||||||
| (
|
|
||||||
a(href=`/docs/${lang}/api/entities/${kebab(prop.entity)}`)= prop.entity
|
|
||||||
| )
|
|
||||||
else if prop.kind == 'object'
|
|
||||||
if prop.hasDef
|
|
||||||
| (
|
|
||||||
a(href=`#${prop.name}`)= prop.name
|
|
||||||
| )
|
|
||||||
else if prop.kind == 'date'
|
|
||||||
| (Date)
|
|
||||||
|
|
||||||
mixin propTable(props)
|
|
||||||
table.props
|
|
||||||
thead: tr
|
|
||||||
th= i18n('docs.api.props.name')
|
|
||||||
th= i18n('docs.api.props.type')
|
|
||||||
th= i18n('docs.api.props.description')
|
|
||||||
tbody
|
|
||||||
each prop in props
|
|
||||||
tr
|
|
||||||
td.name= prop.name
|
|
||||||
td.type
|
|
||||||
+type(prop)
|
|
||||||
td.desc!= prop.desc ? prop.desc[lang] || prop.desc['ja-JP'] : null
|
|
@ -1,11 +0,0 @@
|
|||||||
@import "../style"
|
|
||||||
|
|
||||||
table.props
|
|
||||||
.name
|
|
||||||
font-weight bold
|
|
||||||
|
|
||||||
.name
|
|
||||||
.type
|
|
||||||
.optional
|
|
||||||
font-family Consolas, 'Courier New', Courier, Monaco, monospace
|
|
||||||
|
|
@ -17,17 +17,6 @@ html(lang= lang)
|
|||||||
ul
|
ul
|
||||||
each doc in docs
|
each doc in docs
|
||||||
li: a(href=`/docs/${lang}/${doc.name}`)= doc.title[lang] || doc.title['ja-JP']
|
li: a(href=`/docs/${lang}/${doc.name}`)= doc.title[lang] || doc.title['ja-JP']
|
||||||
section
|
|
||||||
h2 API
|
|
||||||
ul
|
|
||||||
li Entities
|
|
||||||
ul
|
|
||||||
each entity in entities
|
|
||||||
li: a(href=`/docs/${lang}/api/entities/${kebab(entity)}`)= entity
|
|
||||||
li Endpoints
|
|
||||||
ul
|
|
||||||
each endpoint in endpoints
|
|
||||||
li: a(href=`/docs/${lang}/api/endpoints/${kebab(endpoint.name)}`)= endpoint.name
|
|
||||||
main
|
main
|
||||||
article
|
article
|
||||||
block main
|
block main
|
||||||
|
@ -26,6 +26,8 @@ export type ObjectId = mongo.ObjectID;
|
|||||||
* ID
|
* ID
|
||||||
*/
|
*/
|
||||||
export default class ID<Maybe = string> extends Context<string | Maybe> {
|
export default class ID<Maybe = string> extends Context<string | Maybe> {
|
||||||
|
public readonly name = 'ID';
|
||||||
|
|
||||||
constructor(optional = false, nullable = false) {
|
constructor(optional = false, nullable = false) {
|
||||||
super(optional, nullable);
|
super(optional, nullable);
|
||||||
|
|
||||||
@ -38,7 +40,7 @@ export default class ID<Maybe = string> extends Context<string | Maybe> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public getType() {
|
public getType() {
|
||||||
return super.getType('string');
|
return super.getType('String');
|
||||||
}
|
}
|
||||||
|
|
||||||
public makeOptional(): ID<undefined> {
|
public makeOptional(): ID<undefined> {
|
||||||
|
13
src/misc/identifiable-error.ts
Normal file
13
src/misc/identifiable-error.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
/**
|
||||||
|
* ID付きエラー
|
||||||
|
*/
|
||||||
|
export class IdentifiableError extends Error {
|
||||||
|
public message: string;
|
||||||
|
public id: string;
|
||||||
|
|
||||||
|
constructor(id: string, message?: string) {
|
||||||
|
super(message);
|
||||||
|
this.message = message;
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
}
|
@ -1,15 +1,13 @@
|
|||||||
import * as os from 'os';
|
import * as os from 'os';
|
||||||
import * as sysUtils from 'systeminformation';
|
import * as sysUtils from 'systeminformation';
|
||||||
import Logger from "./logger";
|
import Logger from './logger';
|
||||||
|
|
||||||
export async function showMachineInfo(parentLogger: Logger) {
|
export async function showMachineInfo(parentLogger: Logger) {
|
||||||
const logger = parentLogger.createSubLogger('machine');
|
const logger = parentLogger.createSubLogger('machine');
|
||||||
logger.debug(`Hostname: ${os.hostname()}`);
|
logger.debug(`Hostname: ${os.hostname()}`);
|
||||||
logger.debug(`Platform: ${process.platform}`);
|
logger.debug(`Platform: ${process.platform} Arch: ${process.arch}`);
|
||||||
logger.debug(`Architecture: ${process.arch}`);
|
|
||||||
logger.debug(`CPU: ${os.cpus().length} core`);
|
|
||||||
const mem = await sysUtils.mem();
|
const mem = await sysUtils.mem();
|
||||||
const totalmem = (mem.total / 1024 / 1024 / 1024).toFixed(1);
|
const totalmem = (mem.total / 1024 / 1024 / 1024).toFixed(1);
|
||||||
const availmem = (mem.available / 1024 / 1024 / 1024).toFixed(1);
|
const availmem = (mem.available / 1024 / 1024 / 1024).toFixed(1);
|
||||||
logger.debug(`MEM: ${totalmem}GB (available: ${availmem}GB)`);
|
logger.debug(`CPU: ${os.cpus().length} core MEM: ${totalmem}GB (available: ${availmem}GB)`);
|
||||||
}
|
}
|
||||||
|
@ -55,6 +55,8 @@ type IUserBase = {
|
|||||||
emojis?: string[];
|
emojis?: string[];
|
||||||
tags?: string[];
|
tags?: string[];
|
||||||
|
|
||||||
|
isDeleted: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 凍結されているか否か
|
* 凍結されているか否か
|
||||||
*/
|
*/
|
||||||
|
@ -70,6 +70,32 @@ export function processInbox(activity: any, signature: httpSignature.IParsedSign
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function createDeleteNotesJob(user: ILocalUser) {
|
||||||
|
const data = {
|
||||||
|
type: 'deleteNotes',
|
||||||
|
user: user
|
||||||
|
};
|
||||||
|
|
||||||
|
if (queueAvailable && enableQueueProcessing) {
|
||||||
|
return queue.createJob(data).save();
|
||||||
|
} else {
|
||||||
|
return handler({ data }, () => {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createDeleteDriveFilesJob(user: ILocalUser) {
|
||||||
|
const data = {
|
||||||
|
type: 'deleteDriveFiles',
|
||||||
|
user: user
|
||||||
|
};
|
||||||
|
|
||||||
|
if (queueAvailable && enableQueueProcessing) {
|
||||||
|
return queue.createJob(data).save();
|
||||||
|
} else {
|
||||||
|
return handler({ data }, () => {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function createExportNotesJob(user: ILocalUser) {
|
export function createExportNotesJob(user: ILocalUser) {
|
||||||
const data = {
|
const data = {
|
||||||
type: 'exportNotes',
|
type: 'exportNotes',
|
||||||
|
55
src/queue/processors/delete-drive-files.ts
Normal file
55
src/queue/processors/delete-drive-files.ts
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
import * as bq from 'bee-queue';
|
||||||
|
import * as mongo from 'mongodb';
|
||||||
|
|
||||||
|
import { queueLogger } from '../logger';
|
||||||
|
import User from '../../models/user';
|
||||||
|
import DriveFile from '../../models/drive-file';
|
||||||
|
import deleteFile from '../../services/drive/delete-file';
|
||||||
|
|
||||||
|
const logger = queueLogger.createSubLogger('delete-drive-files');
|
||||||
|
|
||||||
|
export async function deleteDriveFiles(job: bq.Job, done: any): Promise<void> {
|
||||||
|
logger.info(`Deleting drive files of ${job.data.user._id} ...`);
|
||||||
|
|
||||||
|
const user = await User.findOne({
|
||||||
|
_id: new mongo.ObjectID(job.data.user._id.toString())
|
||||||
|
});
|
||||||
|
|
||||||
|
let deletedCount = 0;
|
||||||
|
let ended = false;
|
||||||
|
let cursor: any = null;
|
||||||
|
|
||||||
|
while (!ended) {
|
||||||
|
const files = await DriveFile.find({
|
||||||
|
userId: user._id,
|
||||||
|
...(cursor ? { _id: { $gt: cursor } } : {})
|
||||||
|
}, {
|
||||||
|
limit: 100,
|
||||||
|
sort: {
|
||||||
|
_id: 1
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (files.length === 0) {
|
||||||
|
ended = true;
|
||||||
|
if (job.reportProgress) job.reportProgress(100);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
cursor = files[files.length - 1]._id;
|
||||||
|
|
||||||
|
for (const file of files) {
|
||||||
|
await deleteFile(file);
|
||||||
|
deletedCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
const total = await DriveFile.count({
|
||||||
|
userId: user._id,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (job.reportProgress) job.reportProgress(deletedCount / total);
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.succ(`All drive files (${deletedCount}) of ${user._id} has been deleted.`);
|
||||||
|
done();
|
||||||
|
}
|
55
src/queue/processors/delete-notes.ts
Normal file
55
src/queue/processors/delete-notes.ts
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
import * as bq from 'bee-queue';
|
||||||
|
import * as mongo from 'mongodb';
|
||||||
|
|
||||||
|
import { queueLogger } from '../logger';
|
||||||
|
import Note from '../../models/note';
|
||||||
|
import deleteNote from '../../services/note/delete';
|
||||||
|
import User from '../../models/user';
|
||||||
|
|
||||||
|
const logger = queueLogger.createSubLogger('delete-notes');
|
||||||
|
|
||||||
|
export async function deleteNotes(job: bq.Job, done: any): Promise<void> {
|
||||||
|
logger.info(`Deleting notes of ${job.data.user._id} ...`);
|
||||||
|
|
||||||
|
const user = await User.findOne({
|
||||||
|
_id: new mongo.ObjectID(job.data.user._id.toString())
|
||||||
|
});
|
||||||
|
|
||||||
|
let deletedCount = 0;
|
||||||
|
let ended = false;
|
||||||
|
let cursor: any = null;
|
||||||
|
|
||||||
|
while (!ended) {
|
||||||
|
const notes = await Note.find({
|
||||||
|
userId: user._id,
|
||||||
|
...(cursor ? { _id: { $gt: cursor } } : {})
|
||||||
|
}, {
|
||||||
|
limit: 100,
|
||||||
|
sort: {
|
||||||
|
_id: 1
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (notes.length === 0) {
|
||||||
|
ended = true;
|
||||||
|
if (job.reportProgress) job.reportProgress(100);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
cursor = notes[notes.length - 1]._id;
|
||||||
|
|
||||||
|
for (const note of notes) {
|
||||||
|
await deleteNote(user, note, true);
|
||||||
|
deletedCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
const total = await Note.count({
|
||||||
|
userId: user._id,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (job.reportProgress) job.reportProgress(deletedCount / total);
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.succ(`All notes (${deletedCount}) of ${user._id} has been deleted.`);
|
||||||
|
done();
|
||||||
|
}
|
@ -1,5 +1,7 @@
|
|||||||
import deliver from './http/deliver';
|
import deliver from './http/deliver';
|
||||||
import processInbox from './http/process-inbox';
|
import processInbox from './http/process-inbox';
|
||||||
|
import { deleteNotes } from './delete-notes';
|
||||||
|
import { deleteDriveFiles } from './delete-drive-files';
|
||||||
import { exportNotes } from './export-notes';
|
import { exportNotes } from './export-notes';
|
||||||
import { exportFollowing } from './export-following';
|
import { exportFollowing } from './export-following';
|
||||||
import { exportMute } from './export-mute';
|
import { exportMute } from './export-mute';
|
||||||
@ -9,6 +11,8 @@ import { queueLogger } from '../logger';
|
|||||||
const handlers: any = {
|
const handlers: any = {
|
||||||
deliver,
|
deliver,
|
||||||
processInbox,
|
processInbox,
|
||||||
|
deleteNotes,
|
||||||
|
deleteDriveFiles,
|
||||||
exportNotes,
|
exportNotes,
|
||||||
exportFollowing,
|
exportFollowing,
|
||||||
exportMute,
|
exportMute,
|
||||||
|
@ -48,7 +48,6 @@ export default async (ctx: Router.IRouterContext) => {
|
|||||||
const partOf = `${config.url}/users/${userId}/followers`;
|
const partOf = `${config.url}/users/${userId}/followers`;
|
||||||
|
|
||||||
if (page) {
|
if (page) {
|
||||||
// Construct query
|
|
||||||
const query = {
|
const query = {
|
||||||
followeeId: user._id
|
followeeId: user._id
|
||||||
} as any;
|
} as any;
|
||||||
|
@ -48,7 +48,6 @@ export default async (ctx: Router.IRouterContext) => {
|
|||||||
const partOf = `${config.url}/users/${userId}/following`;
|
const partOf = `${config.url}/users/${userId}/following`;
|
||||||
|
|
||||||
if (page) {
|
if (page) {
|
||||||
// Construct query
|
|
||||||
const query = {
|
const query = {
|
||||||
followerId: user._id
|
followerId: user._id
|
||||||
} as any;
|
} as any;
|
||||||
|
@ -78,7 +78,6 @@ export default async (ctx: Router.IRouterContext) => {
|
|||||||
}
|
}
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
// Issue query
|
|
||||||
const notes = await Note
|
const notes = await Note
|
||||||
.find(query, {
|
.find(query, {
|
||||||
limit: limit,
|
limit: limit,
|
||||||
|
@ -3,45 +3,36 @@ import * as Koa from 'koa';
|
|||||||
import { IEndpoint } from './endpoints';
|
import { IEndpoint } from './endpoints';
|
||||||
import authenticate from './authenticate';
|
import authenticate from './authenticate';
|
||||||
import call from './call';
|
import call from './call';
|
||||||
import { IUser } from '../../models/user';
|
import { ApiError } from './error';
|
||||||
import { IApp } from '../../models/app';
|
|
||||||
|
|
||||||
export default async (endpoint: IEndpoint, ctx: Koa.BaseContext) => {
|
export default (endpoint: IEndpoint, ctx: Koa.BaseContext) => new Promise((res) => {
|
||||||
const body = ctx.is('multipart/form-data') ? (ctx.req as any).body : ctx.request.body;
|
const body = ctx.is('multipart/form-data') ? (ctx.req as any).body : ctx.request.body;
|
||||||
|
|
||||||
const reply = (x?: any, y?: any) => {
|
const reply = (x?: any, y?: ApiError) => {
|
||||||
if (x === undefined) {
|
if (x == null) {
|
||||||
ctx.status = 204;
|
ctx.status = 204;
|
||||||
} else if (typeof x === 'number') {
|
} else if (typeof x === 'number') {
|
||||||
ctx.status = x;
|
ctx.status = x;
|
||||||
ctx.body = {
|
ctx.body = { error: y };
|
||||||
error: x === 500 ? 'INTERNAL_ERROR' : y
|
|
||||||
};
|
|
||||||
} else {
|
} else {
|
||||||
ctx.body = x;
|
ctx.body = x;
|
||||||
}
|
}
|
||||||
|
res();
|
||||||
};
|
};
|
||||||
|
|
||||||
let user: IUser;
|
|
||||||
let app: IApp;
|
|
||||||
|
|
||||||
// Authentication
|
// Authentication
|
||||||
try {
|
authenticate(body['i']).then(([user, app]) => {
|
||||||
[user, app] = await authenticate(body['i']);
|
// API invoking
|
||||||
} catch (e) {
|
call(endpoint.name, user, app, body, (ctx.req as any).file).then(res => {
|
||||||
reply(403, 'AUTHENTICATION_FAILED');
|
reply(res);
|
||||||
return;
|
}).catch(e => {
|
||||||
}
|
reply(e.httpStatusCode ? e.httpStatusCode : e.kind == 'client' ? 400 : 500, e);
|
||||||
|
});
|
||||||
let res;
|
}).catch(() => {
|
||||||
|
reply(403, new ApiError({
|
||||||
// API invoking
|
message: 'Authentication failed. Please ensure your token is correct.',
|
||||||
try {
|
code: 'AUTHENTICATION_FAILED',
|
||||||
res = await call(endpoint.name, user, app, body, (ctx.req as any).file);
|
id: 'b0a7f5f8-dc2f-4171-b91f-de88ad238e14'
|
||||||
} catch (e) {
|
}));
|
||||||
reply(400, e);
|
});
|
||||||
return;
|
});
|
||||||
}
|
|
||||||
|
|
||||||
reply(res);
|
|
||||||
};
|
|
||||||
|
@ -2,6 +2,14 @@ import limiter from './limiter';
|
|||||||
import { IUser } from '../../models/user';
|
import { IUser } from '../../models/user';
|
||||||
import { IApp } from '../../models/app';
|
import { IApp } from '../../models/app';
|
||||||
import endpoints from './endpoints';
|
import endpoints from './endpoints';
|
||||||
|
import { ApiError } from './error';
|
||||||
|
import { apiLogger } from './logger';
|
||||||
|
|
||||||
|
const accessDenied = {
|
||||||
|
message: 'Access denied.',
|
||||||
|
code: 'ACCESS_DENIED',
|
||||||
|
id: '56f35758-7dd5-468b-8439-5d6fb8ec9b8e'
|
||||||
|
};
|
||||||
|
|
||||||
export default async (endpoint: string, user: IUser, app: IApp, data: any, file?: any) => {
|
export default async (endpoint: string, user: IUser, app: IApp, data: any, file?: any) => {
|
||||||
const isSecure = user != null && app == null;
|
const isSecure = user != null && app == null;
|
||||||
@ -9,58 +17,72 @@ export default async (endpoint: string, user: IUser, app: IApp, data: any, file?
|
|||||||
const ep = endpoints.find(e => e.name === endpoint);
|
const ep = endpoints.find(e => e.name === endpoint);
|
||||||
|
|
||||||
if (ep == null) {
|
if (ep == null) {
|
||||||
throw 'ENDPOINT_NOT_FOUND';
|
throw new ApiError({
|
||||||
|
message: 'No such endpoint.',
|
||||||
|
code: 'NO_SUCH_ENDPOINT',
|
||||||
|
id: 'f8080b67-5f9c-4eb7-8c18-7f1eeae8f709',
|
||||||
|
httpStatusCode: 404
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ep.meta.secure && !isSecure) {
|
if (ep.meta.secure && !isSecure) {
|
||||||
throw 'ACCESS_DENIED';
|
throw new ApiError(accessDenied);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ep.meta.requireCredential && user == null) {
|
if (ep.meta.requireCredential && user == null) {
|
||||||
throw 'CREDENTIAL_REQUIRED';
|
throw new ApiError({
|
||||||
|
message: 'Credential required.',
|
||||||
|
code: 'CREDENTIAL_REQUIRED',
|
||||||
|
id: '1384574d-a912-4b81-8601-c7b1c4085df1',
|
||||||
|
httpStatusCode: 401
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ep.meta.requireCredential && user.isSuspended) {
|
if (ep.meta.requireCredential && user.isSuspended) {
|
||||||
throw 'YOUR_ACCOUNT_HAS_BEEN_SUSPENDED';
|
throw new ApiError(accessDenied, { reason: 'Your account has been suspended.' });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ep.meta.requireAdmin && !user.isAdmin) {
|
if (ep.meta.requireAdmin && !user.isAdmin) {
|
||||||
throw 'YOU_ARE_NOT_ADMIN';
|
throw new ApiError(accessDenied, { reason: 'You are not the admin.' });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ep.meta.requireModerator && !user.isAdmin && !user.isModerator) {
|
if (ep.meta.requireModerator && !user.isAdmin && !user.isModerator) {
|
||||||
throw 'YOU_ARE_NOT_MODERATOR';
|
throw new ApiError(accessDenied, { reason: 'You are not a moderator.' });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (app && ep.meta.kind && !app.permission.some(p => p === ep.meta.kind)) {
|
if (app && ep.meta.kind && !app.permission.some(p => p === ep.meta.kind)) {
|
||||||
throw 'PERMISSION_DENIED';
|
throw new ApiError({
|
||||||
|
message: 'Your app does not have the necessary permissions to use this endpoint.',
|
||||||
|
code: 'PERMISSION_DENIED',
|
||||||
|
id: '1370e5b7-d4eb-4566-bb1d-7748ee6a1838',
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ep.meta.requireCredential && ep.meta.limit) {
|
if (ep.meta.requireCredential && ep.meta.limit) {
|
||||||
try {
|
// Rate limit
|
||||||
await limiter(ep, user); // Rate limit
|
await limiter(ep, user).catch(e => {
|
||||||
} catch (e) {
|
throw new ApiError({
|
||||||
// drop request if limit exceeded
|
message: 'Rate limit exceeded. Please try again later.',
|
||||||
throw 'RATE_LIMIT_EXCEEDED';
|
code: 'RATE_LIMIT_EXCEEDED',
|
||||||
}
|
id: 'd5826d14-3982-4d2e-8011-b9e9f02499ef',
|
||||||
|
httpStatusCode: 429
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let res;
|
|
||||||
|
|
||||||
// API invoking
|
// API invoking
|
||||||
try {
|
return await ep.exec(data, user, app, file).catch((e: Error) => {
|
||||||
res = await ep.exec(data, user, app, file);
|
if (e instanceof ApiError) {
|
||||||
} catch (e) {
|
|
||||||
if (e && e.name == 'INVALID_PARAM') {
|
|
||||||
throw {
|
|
||||||
code: e.name,
|
|
||||||
param: e.param,
|
|
||||||
reason: e.message
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
throw e;
|
throw e;
|
||||||
|
} else {
|
||||||
|
apiLogger.error(e);
|
||||||
|
throw new ApiError(null, {
|
||||||
|
e: {
|
||||||
|
message: e.message,
|
||||||
|
code: e.name,
|
||||||
|
stack: e.stack
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
return res;
|
|
||||||
};
|
};
|
||||||
|
@ -1,18 +1,19 @@
|
|||||||
import * as mongo from 'mongodb';
|
import * as mongo from 'mongodb';
|
||||||
import Note from "../../../models/note";
|
import Note from '../../../models/note';
|
||||||
import User, { isRemoteUser, isLocalUser } from "../../../models/user";
|
import User, { isRemoteUser, isLocalUser } from '../../../models/user';
|
||||||
|
import { IdentifiableError } from '../../../misc/identifiable-error';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get valied note for API processing
|
* Get note for API processing
|
||||||
*/
|
*/
|
||||||
export async function getValiedNote(noteId: mongo.ObjectID) {
|
export async function getNote(noteId: mongo.ObjectID) {
|
||||||
const note = await Note.findOne({
|
const note = await Note.findOne({
|
||||||
_id: noteId,
|
_id: noteId,
|
||||||
deletedAt: { $exists: false }
|
deletedAt: { $exists: false }
|
||||||
});
|
});
|
||||||
|
|
||||||
if (note === null) {
|
if (note === null) {
|
||||||
throw 'note not found';
|
throw new IdentifiableError('9725d0ce-ba28-4dde-95a7-2cbb2c15de24', 'No such note.');
|
||||||
}
|
}
|
||||||
|
|
||||||
return note;
|
return note;
|
||||||
@ -23,11 +24,22 @@ export async function getValiedNote(noteId: mongo.ObjectID) {
|
|||||||
*/
|
*/
|
||||||
export async function getUser(userId: mongo.ObjectID) {
|
export async function getUser(userId: mongo.ObjectID) {
|
||||||
const user = await User.findOne({
|
const user = await User.findOne({
|
||||||
_id: userId
|
_id: userId,
|
||||||
|
$or: [{
|
||||||
|
isDeleted: { $exists: false }
|
||||||
|
}, {
|
||||||
|
isDeleted: false
|
||||||
|
}]
|
||||||
|
}, {
|
||||||
|
fields: {
|
||||||
|
data: false,
|
||||||
|
profile: false,
|
||||||
|
clientSettings: false
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (user == null) {
|
if (user === null) {
|
||||||
throw 'user not found';
|
throw new IdentifiableError('15348ddd-432d-49c2-8a5a-8069753becff', 'No such user.');
|
||||||
}
|
}
|
||||||
|
|
||||||
return user;
|
return user;
|
||||||
|
@ -2,6 +2,7 @@ import * as fs from 'fs';
|
|||||||
import { ILocalUser } from '../../models/user';
|
import { ILocalUser } from '../../models/user';
|
||||||
import { IApp } from '../../models/app';
|
import { IApp } from '../../models/app';
|
||||||
import { IEndpointMeta } from './endpoints';
|
import { IEndpointMeta } from './endpoints';
|
||||||
|
import { ApiError } from './error';
|
||||||
|
|
||||||
type Params<T extends IEndpointMeta> = {
|
type Params<T extends IEndpointMeta> = {
|
||||||
[P in keyof T['params']]: T['params'][P]['transform'] extends Function
|
[P in keyof T['params']]: T['params'][P]['transform'] extends Function
|
||||||
@ -9,13 +10,19 @@ type Params<T extends IEndpointMeta> = {
|
|||||||
: ReturnType<T['params'][P]['validator']['get']>[0];
|
: ReturnType<T['params'][P]['validator']['get']>[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function <T extends IEndpointMeta>(meta: T, cb: (params: Params<T>, user: ILocalUser, app: IApp, file?: any, cleanup?: Function) => Promise<any>): (params: any, user: ILocalUser, app: IApp, file?: any) => Promise<any> {
|
export type Response = Record<string, any> | void;
|
||||||
|
|
||||||
|
export default function <T extends IEndpointMeta>(meta: T, cb: (params: Params<T>, user: ILocalUser, app: IApp, file?: any, cleanup?: Function) => Promise<Response>): (params: any, user: ILocalUser, app: IApp, file?: any) => Promise<any> {
|
||||||
return (params: any, user: ILocalUser, app: IApp, file?: any) => {
|
return (params: any, user: ILocalUser, app: IApp, file?: any) => {
|
||||||
function cleanup() {
|
function cleanup() {
|
||||||
fs.unlink(file.path, () => {});
|
fs.unlink(file.path, () => {});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (meta.requireFile && file == null) return Promise.reject('file required');
|
if (meta.requireFile && file == null) return Promise.reject(new ApiError({
|
||||||
|
message: 'File required.',
|
||||||
|
code: 'FILE_REQUIRED',
|
||||||
|
id: '4267801e-70d1-416a-b011-4ee502885d8b',
|
||||||
|
}));
|
||||||
|
|
||||||
const [ps, pserr] = getParams(meta, params);
|
const [ps, pserr] = getParams(meta, params);
|
||||||
if (pserr) {
|
if (pserr) {
|
||||||
@ -27,17 +34,22 @@ export default function <T extends IEndpointMeta>(meta: T, cb: (params: Params<T
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function getParams<T extends IEndpointMeta>(defs: T, params: any): [Params<T>, Error] {
|
function getParams<T extends IEndpointMeta>(defs: T, params: any): [Params<T>, ApiError] {
|
||||||
if (defs.params == null) return [params, null];
|
if (defs.params == null) return [params, null];
|
||||||
|
|
||||||
const x: any = {};
|
const x: any = {};
|
||||||
let err: Error = null;
|
let err: ApiError = null;
|
||||||
Object.entries(defs.params).some(([k, def]) => {
|
Object.entries(defs.params).some(([k, def]) => {
|
||||||
const [v, e] = def.validator.get(params[k]);
|
const [v, e] = def.validator.get(params[k]);
|
||||||
if (e) {
|
if (e) {
|
||||||
err = new Error(e.message);
|
err = new ApiError({
|
||||||
err.name = 'INVALID_PARAM';
|
message: 'Invalid param.',
|
||||||
(err as any).param = k;
|
code: 'INVALID_PARAM',
|
||||||
|
id: '3d81ceae-475f-4600-b2a8-2bc116157532',
|
||||||
|
}, {
|
||||||
|
param: k,
|
||||||
|
reason: e.message
|
||||||
|
});
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
if (v === undefined && def.hasOwnProperty('default')) {
|
if (v === undefined && def.hasOwnProperty('default')) {
|
||||||
|
@ -2,18 +2,30 @@ import { Context } from 'cafy';
|
|||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as glob from 'glob';
|
import * as glob from 'glob';
|
||||||
|
|
||||||
|
export type Param = {
|
||||||
|
validator: Context<any>;
|
||||||
|
transform?: any;
|
||||||
|
default?: any;
|
||||||
|
desc?: { [key: string]: string };
|
||||||
|
ref?: string;
|
||||||
|
};
|
||||||
|
|
||||||
export interface IEndpointMeta {
|
export interface IEndpointMeta {
|
||||||
stability?: string; //'deprecated' | 'experimental' | 'stable';
|
stability?: string; //'deprecated' | 'experimental' | 'stable';
|
||||||
|
|
||||||
desc?: { [key: string]: string };
|
desc?: { [key: string]: string };
|
||||||
|
|
||||||
|
tags?: string[];
|
||||||
|
|
||||||
params?: {
|
params?: {
|
||||||
|
[key: string]: Param;
|
||||||
|
};
|
||||||
|
|
||||||
|
errors?: {
|
||||||
[key: string]: {
|
[key: string]: {
|
||||||
validator: Context<any>;
|
message: string;
|
||||||
transform?: any;
|
code: string;
|
||||||
default?: any;
|
id: string;
|
||||||
desc?: { [key: string]: string };
|
|
||||||
ref?: string;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -4,6 +4,8 @@ import Report, { packMany } from '../../../../models/abuse-user-report';
|
|||||||
import define from '../../define';
|
import define from '../../define';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
|
tags: ['admin'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requireModerator: true,
|
requireModerator: true,
|
||||||
|
|
||||||
@ -25,11 +27,7 @@ export const meta = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default define(meta, (ps) => new Promise(async (res, rej) => {
|
export default define(meta, async (ps) => {
|
||||||
if (ps.sinceId && ps.untilId) {
|
|
||||||
return rej('cannot set sinceId and untilId');
|
|
||||||
}
|
|
||||||
|
|
||||||
const sort = {
|
const sort = {
|
||||||
_id: -1
|
_id: -1
|
||||||
};
|
};
|
||||||
@ -51,5 +49,5 @@ export default define(meta, (ps) => new Promise(async (res, rej) => {
|
|||||||
sort: sort
|
sort: sort
|
||||||
});
|
});
|
||||||
|
|
||||||
res(await packMany(reports));
|
return await packMany(reports);
|
||||||
}));
|
});
|
||||||
|
@ -4,6 +4,8 @@ import define from '../../../define';
|
|||||||
import { fallback } from '../../../../../prelude/symbol';
|
import { fallback } from '../../../../../prelude/symbol';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
|
tags: ['admin'],
|
||||||
|
|
||||||
requireCredential: false,
|
requireCredential: false,
|
||||||
requireModerator: true,
|
requireModerator: true,
|
||||||
|
|
||||||
@ -46,7 +48,7 @@ const sort: any = { // < https://github.com/Microsoft/TypeScript/issues/1863
|
|||||||
[fallback]: { _id: -1 }
|
[fallback]: { _id: -1 }
|
||||||
};
|
};
|
||||||
|
|
||||||
export default define(meta, (ps, me) => new Promise(async (res, rej) => {
|
export default define(meta, async (ps, me) => {
|
||||||
const q = {
|
const q = {
|
||||||
'metadata.deletedAt': { $exists: false },
|
'metadata.deletedAt': { $exists: false },
|
||||||
} as any;
|
} as any;
|
||||||
@ -61,5 +63,5 @@ export default define(meta, (ps, me) => new Promise(async (res, rej) => {
|
|||||||
skip: ps.offset
|
skip: ps.offset
|
||||||
});
|
});
|
||||||
|
|
||||||
res(await packMany(files, { detail: true, withUser: true, self: true }));
|
return await packMany(files, { detail: true, withUser: true, self: true });
|
||||||
}));
|
});
|
||||||
|
@ -2,8 +2,11 @@ import $ from 'cafy';
|
|||||||
import ID, { transform } from '../../../../../misc/cafy-id';
|
import ID, { transform } from '../../../../../misc/cafy-id';
|
||||||
import define from '../../../define';
|
import define from '../../../define';
|
||||||
import DriveFile from '../../../../../models/drive-file';
|
import DriveFile from '../../../../../models/drive-file';
|
||||||
|
import { ApiError } from '../../../error';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
|
tags: ['admin'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requireModerator: true,
|
requireModerator: true,
|
||||||
|
|
||||||
@ -12,17 +15,25 @@ export const meta = {
|
|||||||
validator: $.type(ID),
|
validator: $.type(ID),
|
||||||
transform: transform,
|
transform: transform,
|
||||||
},
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
errors: {
|
||||||
|
noSuchFile: {
|
||||||
|
message: 'No such file.',
|
||||||
|
code: 'NO_SUCH_FILE',
|
||||||
|
id: 'caf3ca38-c6e5-472e-a30c-b05377dcc240'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default define(meta, (ps, me) => new Promise(async (res, rej) => {
|
export default define(meta, async (ps, me) => {
|
||||||
const file = await DriveFile.findOne({
|
const file = await DriveFile.findOne({
|
||||||
_id: ps.fileId
|
_id: ps.fileId
|
||||||
});
|
});
|
||||||
|
|
||||||
if (file == null) {
|
if (file == null) {
|
||||||
return rej('file not found');
|
throw new ApiError(meta.errors.noSuchFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
res(file);
|
return file;
|
||||||
}));
|
});
|
||||||
|
@ -7,6 +7,8 @@ export const meta = {
|
|||||||
'ja-JP': 'カスタム絵文字を追加します。'
|
'ja-JP': 'カスタム絵文字を追加します。'
|
||||||
},
|
},
|
||||||
|
|
||||||
|
tags: ['admin'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requireModerator: true,
|
requireModerator: true,
|
||||||
|
|
||||||
@ -26,7 +28,7 @@ export const meta = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default define(meta, (ps) => new Promise(async (res, rej) => {
|
export default define(meta, async (ps) => {
|
||||||
const emoji = await Emoji.insert({
|
const emoji = await Emoji.insert({
|
||||||
updatedAt: new Date(),
|
updatedAt: new Date(),
|
||||||
name: ps.name,
|
name: ps.name,
|
||||||
@ -35,7 +37,7 @@ export default define(meta, (ps) => new Promise(async (res, rej) => {
|
|||||||
url: ps.url
|
url: ps.url
|
||||||
});
|
});
|
||||||
|
|
||||||
res({
|
return {
|
||||||
id: emoji._id
|
id: emoji._id
|
||||||
});
|
};
|
||||||
}));
|
});
|
||||||
|
@ -7,6 +7,8 @@ export const meta = {
|
|||||||
'ja-JP': 'カスタム絵文字を取得します。'
|
'ja-JP': 'カスタム絵文字を取得します。'
|
||||||
},
|
},
|
||||||
|
|
||||||
|
tags: ['admin'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requireModerator: true,
|
requireModerator: true,
|
||||||
|
|
||||||
@ -18,16 +20,16 @@ export const meta = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default define(meta, (ps) => new Promise(async (res, rej) => {
|
export default define(meta, async (ps) => {
|
||||||
const emojis = await Emoji.find({
|
const emojis = await Emoji.find({
|
||||||
host: ps.host
|
host: ps.host
|
||||||
});
|
});
|
||||||
|
|
||||||
res(emojis.map(e => ({
|
return emojis.map(e => ({
|
||||||
id: e._id,
|
id: e._id,
|
||||||
name: e.name,
|
name: e.name,
|
||||||
aliases: e.aliases,
|
aliases: e.aliases,
|
||||||
host: e.host,
|
host: e.host,
|
||||||
url: e.url
|
url: e.url
|
||||||
})));
|
}));
|
||||||
}));
|
});
|
||||||
|
@ -8,6 +8,8 @@ export const meta = {
|
|||||||
'ja-JP': 'カスタム絵文字を削除します。'
|
'ja-JP': 'カスタム絵文字を削除します。'
|
||||||
},
|
},
|
||||||
|
|
||||||
|
tags: ['admin'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requireModerator: true,
|
requireModerator: true,
|
||||||
|
|
||||||
@ -18,14 +20,14 @@ export const meta = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default define(meta, (ps) => new Promise(async (res, rej) => {
|
export default define(meta, async (ps) => {
|
||||||
const emoji = await Emoji.findOne({
|
const emoji = await Emoji.findOne({
|
||||||
_id: ps.id
|
_id: ps.id
|
||||||
});
|
});
|
||||||
|
|
||||||
if (emoji == null) return rej('emoji not found');
|
if (emoji == null) throw new Error('emoji not found');
|
||||||
|
|
||||||
await Emoji.remove({ _id: emoji._id });
|
await Emoji.remove({ _id: emoji._id });
|
||||||
|
|
||||||
res();
|
return;
|
||||||
}));
|
});
|
||||||
|
@ -8,6 +8,8 @@ export const meta = {
|
|||||||
'ja-JP': 'カスタム絵文字を更新します。'
|
'ja-JP': 'カスタム絵文字を更新します。'
|
||||||
},
|
},
|
||||||
|
|
||||||
|
tags: ['admin'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requireModerator: true,
|
requireModerator: true,
|
||||||
|
|
||||||
@ -30,12 +32,12 @@ export const meta = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default define(meta, (ps) => new Promise(async (res, rej) => {
|
export default define(meta, async (ps) => {
|
||||||
const emoji = await Emoji.findOne({
|
const emoji = await Emoji.findOne({
|
||||||
_id: ps.id
|
_id: ps.id
|
||||||
});
|
});
|
||||||
|
|
||||||
if (emoji == null) return rej('emoji not found');
|
if (emoji == null) throw new Error('emoji not found');
|
||||||
|
|
||||||
await Emoji.update({ _id: emoji._id }, {
|
await Emoji.update({ _id: emoji._id }, {
|
||||||
$set: {
|
$set: {
|
||||||
@ -46,5 +48,5 @@ export default define(meta, (ps) => new Promise(async (res, rej) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
res();
|
return;
|
||||||
}));
|
});
|
||||||
|
@ -5,6 +5,8 @@ import User from '../../../../../models/user';
|
|||||||
import deleteFollowing from '../../../../../services/following/delete';
|
import deleteFollowing from '../../../../../services/following/delete';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
|
tags: ['admin'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requireModerator: true,
|
requireModerator: true,
|
||||||
|
|
||||||
@ -15,7 +17,7 @@ export const meta = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default define(meta, (ps, me) => new Promise(async (res, rej) => {
|
export default define(meta, async (ps, me) => {
|
||||||
const followings = await Following.find({
|
const followings = await Following.find({
|
||||||
'_follower.host': ps.host
|
'_follower.host': ps.host
|
||||||
});
|
});
|
||||||
@ -29,5 +31,5 @@ export default define(meta, (ps, me) => new Promise(async (res, rej) => {
|
|||||||
deleteFollowing(pair[0], pair[1]);
|
deleteFollowing(pair[0], pair[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
res();
|
return;
|
||||||
}));
|
});
|
||||||
|
@ -3,6 +3,8 @@ import define from '../../../define';
|
|||||||
import Instance from '../../../../../models/instance';
|
import Instance from '../../../../../models/instance';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
|
tags: ['admin'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requireModerator: true,
|
requireModerator: true,
|
||||||
|
|
||||||
@ -21,11 +23,11 @@ export const meta = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default define(meta, (ps, me) => new Promise(async (res, rej) => {
|
export default define(meta, async (ps, me) => {
|
||||||
const instance = await Instance.findOne({ host: ps.host });
|
const instance = await Instance.findOne({ host: ps.host });
|
||||||
|
|
||||||
if (instance == null) {
|
if (instance == null) {
|
||||||
return rej('instance not found');
|
throw new Error('instance not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
Instance.update({ host: ps.host }, {
|
Instance.update({ host: ps.host }, {
|
||||||
@ -35,5 +37,5 @@ export default define(meta, (ps, me) => new Promise(async (res, rej) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
res();
|
return;
|
||||||
}));
|
});
|
||||||
|
@ -7,13 +7,15 @@ export const meta = {
|
|||||||
'ja-JP': '招待コードを発行します。'
|
'ja-JP': '招待コードを発行します。'
|
||||||
},
|
},
|
||||||
|
|
||||||
|
tags: ['admin'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requireModerator: true,
|
requireModerator: true,
|
||||||
|
|
||||||
params: {}
|
params: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default define(meta, (ps) => new Promise(async (res, rej) => {
|
export default define(meta, async (ps) => {
|
||||||
const code = rndstr({ length: 5, chars: '0-9' });
|
const code = rndstr({ length: 5, chars: '0-9' });
|
||||||
|
|
||||||
await RegistrationTicket.insert({
|
await RegistrationTicket.insert({
|
||||||
@ -21,7 +23,7 @@ export default define(meta, (ps) => new Promise(async (res, rej) => {
|
|||||||
code: code
|
code: code
|
||||||
});
|
});
|
||||||
|
|
||||||
res({
|
return {
|
||||||
code: code
|
code: code
|
||||||
});
|
};
|
||||||
}));
|
});
|
||||||
|
@ -9,6 +9,8 @@ export const meta = {
|
|||||||
'en-US': 'Mark a user as moderator.'
|
'en-US': 'Mark a user as moderator.'
|
||||||
},
|
},
|
||||||
|
|
||||||
|
tags: ['admin'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requireAdmin: true,
|
requireAdmin: true,
|
||||||
|
|
||||||
@ -24,13 +26,13 @@ export const meta = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default define(meta, (ps) => new Promise(async (res, rej) => {
|
export default define(meta, async (ps) => {
|
||||||
const user = await User.findOne({
|
const user = await User.findOne({
|
||||||
_id: ps.userId
|
_id: ps.userId
|
||||||
});
|
});
|
||||||
|
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
return rej('user not found');
|
throw new Error('user not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
await User.update({
|
await User.update({
|
||||||
@ -41,5 +43,5 @@ export default define(meta, (ps) => new Promise(async (res, rej) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
res();
|
return;
|
||||||
}));
|
});
|
||||||
|
@ -9,6 +9,8 @@ export const meta = {
|
|||||||
'en-US': 'Unmark a user as moderator.'
|
'en-US': 'Unmark a user as moderator.'
|
||||||
},
|
},
|
||||||
|
|
||||||
|
tags: ['admin'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requireAdmin: true,
|
requireAdmin: true,
|
||||||
|
|
||||||
@ -24,13 +26,13 @@ export const meta = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default define(meta, (ps) => new Promise(async (res, rej) => {
|
export default define(meta, async (ps) => {
|
||||||
const user = await User.findOne({
|
const user = await User.findOne({
|
||||||
_id: ps.userId
|
_id: ps.userId
|
||||||
});
|
});
|
||||||
|
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
return rej('user not found');
|
throw new Error('user not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
await User.update({
|
await User.update({
|
||||||
@ -41,5 +43,5 @@ export default define(meta, (ps) => new Promise(async (res, rej) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
res();
|
return;
|
||||||
}));
|
});
|
||||||
|
@ -2,14 +2,16 @@ import define from '../../../define';
|
|||||||
import { destroy } from '../../../../../queue';
|
import { destroy } from '../../../../../queue';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
|
tags: ['admin'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requireModerator: true,
|
requireModerator: true,
|
||||||
|
|
||||||
params: {}
|
params: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default define(meta, (ps) => new Promise(async (res, rej) => {
|
export default define(meta, async (ps) => {
|
||||||
destroy();
|
destroy();
|
||||||
|
|
||||||
res();
|
return;
|
||||||
}));
|
});
|
||||||
|
@ -4,6 +4,8 @@ import define from '../../define';
|
|||||||
import AbuseUserReport from '../../../../models/abuse-user-report';
|
import AbuseUserReport from '../../../../models/abuse-user-report';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
|
tags: ['admin'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requireModerator: true,
|
requireModerator: true,
|
||||||
|
|
||||||
@ -15,18 +17,18 @@ export const meta = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default define(meta, (ps) => new Promise(async (res, rej) => {
|
export default define(meta, async (ps) => {
|
||||||
const report = await AbuseUserReport.findOne({
|
const report = await AbuseUserReport.findOne({
|
||||||
_id: ps.reportId
|
_id: ps.reportId
|
||||||
});
|
});
|
||||||
|
|
||||||
if (report == null) {
|
if (report == null) {
|
||||||
return rej('report not found');
|
throw new Error('report not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
await AbuseUserReport.remove({
|
await AbuseUserReport.remove({
|
||||||
_id: report._id
|
_id: report._id
|
||||||
});
|
});
|
||||||
|
|
||||||
res();
|
return;
|
||||||
}));
|
});
|
||||||
|
@ -10,6 +10,8 @@ export const meta = {
|
|||||||
'ja-JP': '指定したユーザーのパスワードをリセットします。',
|
'ja-JP': '指定したユーザーのパスワードをリセットします。',
|
||||||
},
|
},
|
||||||
|
|
||||||
|
tags: ['admin'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requireModerator: true,
|
requireModerator: true,
|
||||||
|
|
||||||
@ -25,17 +27,17 @@ export const meta = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default define(meta, (ps) => new Promise(async (res, rej) => {
|
export default define(meta, async (ps) => {
|
||||||
const user = await User.findOne({
|
const user = await User.findOne({
|
||||||
_id: ps.userId
|
_id: ps.userId
|
||||||
});
|
});
|
||||||
|
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
return rej('user not found');
|
throw new Error('user not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user.isAdmin) {
|
if (user.isAdmin) {
|
||||||
return rej('cannot reset password of admin');
|
throw new Error('cannot reset password of admin');
|
||||||
}
|
}
|
||||||
|
|
||||||
const passwd = rndstr('a-zA-Z0-9', 8);
|
const passwd = rndstr('a-zA-Z0-9', 8);
|
||||||
@ -46,12 +48,12 @@ export default define(meta, (ps) => new Promise(async (res, rej) => {
|
|||||||
await User.findOneAndUpdate({
|
await User.findOneAndUpdate({
|
||||||
_id: user._id
|
_id: user._id
|
||||||
}, {
|
}, {
|
||||||
$set: {
|
$set: {
|
||||||
password: hash
|
password: hash
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
res({
|
|
||||||
password: passwd
|
|
||||||
});
|
});
|
||||||
}));
|
|
||||||
|
return {
|
||||||
|
password: passwd
|
||||||
|
};
|
||||||
|
});
|
||||||
|
@ -8,6 +8,8 @@ export const meta = {
|
|||||||
'ja-JP': '指定したユーザーの情報を取得します。',
|
'ja-JP': '指定したユーザーの情報を取得します。',
|
||||||
},
|
},
|
||||||
|
|
||||||
|
tags: ['admin'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requireModerator: true,
|
requireModerator: true,
|
||||||
|
|
||||||
@ -23,18 +25,18 @@ export const meta = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default define(meta, (ps, me) => new Promise(async (res, rej) => {
|
export default define(meta, async (ps, me) => {
|
||||||
const user = await User.findOne({
|
const user = await User.findOne({
|
||||||
_id: ps.userId
|
_id: ps.userId
|
||||||
});
|
});
|
||||||
|
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
return rej('user not found');
|
throw new Error('user not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (me.isModerator && user.isAdmin) {
|
if (me.isModerator && user.isAdmin) {
|
||||||
return rej('cannot show info of admin');
|
throw new Error('cannot show info of admin');
|
||||||
}
|
}
|
||||||
|
|
||||||
res(user);
|
return user;
|
||||||
}));
|
});
|
||||||
|
@ -4,6 +4,8 @@ import define from '../../define';
|
|||||||
import { fallback } from '../../../../prelude/symbol';
|
import { fallback } from '../../../../prelude/symbol';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
|
tags: ['admin'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requireModerator: true,
|
requireModerator: true,
|
||||||
|
|
||||||
@ -63,7 +65,7 @@ const sort: any = { // < https://github.com/Microsoft/TypeScript/issues/1863
|
|||||||
[fallback]: { _id: -1 }
|
[fallback]: { _id: -1 }
|
||||||
};
|
};
|
||||||
|
|
||||||
export default define(meta, (ps, me) => new Promise(async (res, rej) => {
|
export default define(meta, async (ps, me) => {
|
||||||
const q = {
|
const q = {
|
||||||
$and: []
|
$and: []
|
||||||
} as any;
|
} as any;
|
||||||
@ -99,5 +101,5 @@ export default define(meta, (ps, me) => new Promise(async (res, rej) => {
|
|||||||
skip: ps.offset
|
skip: ps.offset
|
||||||
});
|
});
|
||||||
|
|
||||||
res(await Promise.all(users.map(user => pack(user, me, { detail: true }))));
|
return await Promise.all(users.map(user => pack(user, me, { detail: true })));
|
||||||
}));
|
});
|
||||||
|
@ -9,6 +9,8 @@ export const meta = {
|
|||||||
'en-US': 'Make silence a user.'
|
'en-US': 'Make silence a user.'
|
||||||
},
|
},
|
||||||
|
|
||||||
|
tags: ['admin'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requireModerator: true,
|
requireModerator: true,
|
||||||
|
|
||||||
@ -24,17 +26,17 @@ export const meta = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default define(meta, (ps) => new Promise(async (res, rej) => {
|
export default define(meta, async (ps) => {
|
||||||
const user = await User.findOne({
|
const user = await User.findOne({
|
||||||
_id: ps.userId
|
_id: ps.userId
|
||||||
});
|
});
|
||||||
|
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
return rej('user not found');
|
throw new Error('user not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user.isAdmin) {
|
if (user.isAdmin) {
|
||||||
return rej('cannot silence admin');
|
throw new Error('cannot silence admin');
|
||||||
}
|
}
|
||||||
|
|
||||||
await User.findOneAndUpdate({
|
await User.findOneAndUpdate({
|
||||||
@ -45,5 +47,5 @@ export default define(meta, (ps) => new Promise(async (res, rej) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
res();
|
return;
|
||||||
}));
|
});
|
||||||
|
@ -9,6 +9,8 @@ export const meta = {
|
|||||||
'en-US': 'Suspend a user.'
|
'en-US': 'Suspend a user.'
|
||||||
},
|
},
|
||||||
|
|
||||||
|
tags: ['admin'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requireModerator: true,
|
requireModerator: true,
|
||||||
|
|
||||||
@ -24,30 +26,30 @@ export const meta = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default define(meta, (ps) => new Promise(async (res, rej) => {
|
export default define(meta, async (ps) => {
|
||||||
const user = await User.findOne({
|
const user = await User.findOne({
|
||||||
_id: ps.userId
|
_id: ps.userId
|
||||||
});
|
});
|
||||||
|
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
return rej('user not found');
|
throw new Error('user not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user.isAdmin) {
|
if (user.isAdmin) {
|
||||||
return rej('cannot suspend admin');
|
throw new Error('cannot suspend admin');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user.isModerator) {
|
if (user.isModerator) {
|
||||||
return rej('cannot suspend moderator');
|
throw new Error('cannot suspend moderator');
|
||||||
}
|
}
|
||||||
|
|
||||||
await User.findOneAndUpdate({
|
await User.findOneAndUpdate({
|
||||||
_id: user._id
|
_id: user._id
|
||||||
}, {
|
}, {
|
||||||
$set: {
|
$set: {
|
||||||
isSuspended: true
|
isSuspended: true
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
res();
|
return;
|
||||||
}));
|
});
|
||||||
|
@ -9,6 +9,8 @@ export const meta = {
|
|||||||
'en-US': 'Unsilence a user.'
|
'en-US': 'Unsilence a user.'
|
||||||
},
|
},
|
||||||
|
|
||||||
|
tags: ['admin'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requireModerator: true,
|
requireModerator: true,
|
||||||
|
|
||||||
@ -24,13 +26,13 @@ export const meta = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default define(meta, (ps) => new Promise(async (res, rej) => {
|
export default define(meta, async (ps) => {
|
||||||
const user = await User.findOne({
|
const user = await User.findOne({
|
||||||
_id: ps.userId
|
_id: ps.userId
|
||||||
});
|
});
|
||||||
|
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
return rej('user not found');
|
throw new Error('user not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
await User.findOneAndUpdate({
|
await User.findOneAndUpdate({
|
||||||
@ -41,5 +43,5 @@ export default define(meta, (ps) => new Promise(async (res, rej) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
res();
|
return;
|
||||||
}));
|
});
|
||||||
|
@ -9,6 +9,8 @@ export const meta = {
|
|||||||
'en-US': 'Unsuspend a user.'
|
'en-US': 'Unsuspend a user.'
|
||||||
},
|
},
|
||||||
|
|
||||||
|
tags: ['admin'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requireModerator: true,
|
requireModerator: true,
|
||||||
|
|
||||||
@ -24,22 +26,22 @@ export const meta = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default define(meta, (ps) => new Promise(async (res, rej) => {
|
export default define(meta, async (ps) => {
|
||||||
const user = await User.findOne({
|
const user = await User.findOne({
|
||||||
_id: ps.userId
|
_id: ps.userId
|
||||||
});
|
});
|
||||||
|
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
return rej('user not found');
|
throw new Error('user not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
await User.findOneAndUpdate({
|
await User.findOneAndUpdate({
|
||||||
_id: user._id
|
_id: user._id
|
||||||
}, {
|
}, {
|
||||||
$set: {
|
$set: {
|
||||||
isSuspended: false
|
isSuspended: false
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
res();
|
return;
|
||||||
}));
|
});
|
||||||
|
@ -9,6 +9,8 @@ export const meta = {
|
|||||||
'en-US': 'Mark a user as unverified.'
|
'en-US': 'Mark a user as unverified.'
|
||||||
},
|
},
|
||||||
|
|
||||||
|
tags: ['admin'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requireModerator: true,
|
requireModerator: true,
|
||||||
|
|
||||||
@ -24,22 +26,22 @@ export const meta = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default define(meta, (ps) => new Promise(async (res, rej) => {
|
export default define(meta, async (ps) => {
|
||||||
const user = await User.findOne({
|
const user = await User.findOne({
|
||||||
_id: ps.userId
|
_id: ps.userId
|
||||||
});
|
});
|
||||||
|
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
return rej('user not found');
|
throw new Error('user not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
await User.findOneAndUpdate({
|
await User.findOneAndUpdate({
|
||||||
_id: user._id
|
_id: user._id
|
||||||
}, {
|
}, {
|
||||||
$set: {
|
$set: {
|
||||||
isVerified: false
|
isVerified: false
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
res();
|
return;
|
||||||
}));
|
});
|
||||||
|
@ -7,6 +7,8 @@ export const meta = {
|
|||||||
'ja-JP': 'インスタンスの設定を更新します。'
|
'ja-JP': 'インスタンスの設定を更新します。'
|
||||||
},
|
},
|
||||||
|
|
||||||
|
tags: ['admin'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requireModerator: true,
|
requireModerator: true,
|
||||||
|
|
||||||
@ -323,7 +325,7 @@ export const meta = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default define(meta, (ps) => new Promise(async (res, rej) => {
|
export default define(meta, async (ps) => {
|
||||||
const set = {} as any;
|
const set = {} as any;
|
||||||
|
|
||||||
if (ps.broadcasts) {
|
if (ps.broadcasts) {
|
||||||
@ -506,5 +508,5 @@ export default define(meta, (ps) => new Promise(async (res, rej) => {
|
|||||||
$set: set
|
$set: set
|
||||||
}, { upsert: true });
|
}, { upsert: true });
|
||||||
|
|
||||||
res();
|
return;
|
||||||
}));
|
});
|
||||||
|
@ -11,6 +11,8 @@ export const meta = {
|
|||||||
'en-US': 'Update specified remote user information.'
|
'en-US': 'Update specified remote user information.'
|
||||||
},
|
},
|
||||||
|
|
||||||
|
tags: ['admin'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requireModerator: true,
|
requireModerator: true,
|
||||||
|
|
||||||
@ -26,9 +28,10 @@ export const meta = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default define(meta, (ps) => new Promise((res, rej) => {
|
export default define(meta, async (ps) => {
|
||||||
updatePersonById(ps.userId).then(() => res(), e => rej(e));
|
await updatePersonById(ps.userId);
|
||||||
}));
|
return;
|
||||||
|
});
|
||||||
|
|
||||||
async function updatePersonById(userId: mongo.ObjectID) {
|
async function updatePersonById(userId: mongo.ObjectID) {
|
||||||
const user = await getRemoteUser(userId);
|
const user = await getRemoteUser(userId);
|
||||||
|
@ -9,6 +9,8 @@ export const meta = {
|
|||||||
'en-US': 'Mark a user as verified.'
|
'en-US': 'Mark a user as verified.'
|
||||||
},
|
},
|
||||||
|
|
||||||
|
tags: ['admin'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requireModerator: true,
|
requireModerator: true,
|
||||||
|
|
||||||
@ -24,22 +26,22 @@ export const meta = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default define(meta, (ps) => new Promise(async (res, rej) => {
|
export default define(meta, async (ps) => {
|
||||||
const user = await User.findOne({
|
const user = await User.findOne({
|
||||||
_id: ps.userId
|
_id: ps.userId
|
||||||
});
|
});
|
||||||
|
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
return rej('user not found');
|
throw new Error('user not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
await User.findOneAndUpdate({
|
await User.findOneAndUpdate({
|
||||||
_id: user._id
|
_id: user._id
|
||||||
}, {
|
}, {
|
||||||
$set: {
|
$set: {
|
||||||
isVerified: true
|
isVerified: true
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
res();
|
return;
|
||||||
}));
|
});
|
||||||
|
@ -3,10 +3,12 @@ import define from '../../define';
|
|||||||
import fetchMeta from '../../../../misc/fetch-meta';
|
import fetchMeta from '../../../../misc/fetch-meta';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
|
tags: ['hashtags'],
|
||||||
|
|
||||||
requireCredential: false,
|
requireCredential: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default define(meta, (ps) => new Promise(async (res, rej) => {
|
export default define(meta, async (ps) => {
|
||||||
const instance = await fetchMeta();
|
const instance = await fetchMeta();
|
||||||
const hidedTags = instance.hidedTags.map(t => t.toLowerCase());
|
const hidedTags = instance.hidedTags.map(t => t.toLowerCase());
|
||||||
|
|
||||||
@ -40,7 +42,7 @@ export default define(meta, (ps) => new Promise(async (res, rej) => {
|
|||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
if (data.length == 0) {
|
if (data.length == 0) {
|
||||||
return res([]);
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
let tags: {
|
let tags: {
|
||||||
@ -66,5 +68,5 @@ export default define(meta, (ps) => new Promise(async (res, rej) => {
|
|||||||
|
|
||||||
tags = tags.slice(0, 30);
|
tags = tags.slice(0, 30);
|
||||||
|
|
||||||
res(tags);
|
return tags;
|
||||||
}));
|
});
|
||||||
|
@ -7,8 +7,11 @@ import { createPerson } from '../../../../remote/activitypub/models/person';
|
|||||||
import Note, { pack as packNote, INote } from '../../../../models/note';
|
import Note, { pack as packNote, INote } from '../../../../models/note';
|
||||||
import { createNote } from '../../../../remote/activitypub/models/note';
|
import { createNote } from '../../../../remote/activitypub/models/note';
|
||||||
import Resolver from '../../../../remote/activitypub/resolver';
|
import Resolver from '../../../../remote/activitypub/resolver';
|
||||||
|
import { ApiError } from '../../error';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
|
tags: ['federation'],
|
||||||
|
|
||||||
desc: {
|
desc: {
|
||||||
'ja-JP': 'URIを指定してActivityPubオブジェクトを参照します。'
|
'ja-JP': 'URIを指定してActivityPubオブジェクトを参照します。'
|
||||||
},
|
},
|
||||||
@ -23,13 +26,24 @@ export const meta = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
errors: {
|
||||||
|
noSuchObject: {
|
||||||
|
message: 'No such object.',
|
||||||
|
code: 'NO_SUCH_OBJECT',
|
||||||
|
id: 'dc94d745-1262-4e63-a17d-fecaa57efc82'
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default define(meta, (ps) => new Promise((res, rej) => {
|
export default define(meta, async (ps) => {
|
||||||
fetchAny(ps.uri)
|
const object = await fetchAny(ps.uri);
|
||||||
.then(object => object != null ? res(object) : rej('object not found'))
|
if (object) {
|
||||||
.catch(e => rej(e));
|
return object;
|
||||||
}));
|
} else {
|
||||||
|
throw new ApiError(meta.errors.noSuchObject);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* URIからUserかNoteを解決する
|
* URIからUserかNoteを解決する
|
||||||
|
@ -4,6 +4,8 @@ import App, { pack } from '../../../../models/app';
|
|||||||
import define from '../../define';
|
import define from '../../define';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
|
tags: ['app'],
|
||||||
|
|
||||||
requireCredential: false,
|
requireCredential: false,
|
||||||
|
|
||||||
params: {
|
params: {
|
||||||
@ -27,7 +29,7 @@ export const meta = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
export default define(meta, async (ps, user) => {
|
||||||
// Generate secret
|
// Generate secret
|
||||||
const secret = rndstr('a-zA-Z0-9', 32);
|
const secret = rndstr('a-zA-Z0-9', 32);
|
||||||
|
|
||||||
@ -42,9 +44,8 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
|||||||
secret: secret
|
secret: secret
|
||||||
});
|
});
|
||||||
|
|
||||||
// Response
|
return await pack(app, null, {
|
||||||
res(await pack(app, null, {
|
|
||||||
detail: true,
|
detail: true,
|
||||||
includeSecret: true
|
includeSecret: true
|
||||||
}));
|
});
|
||||||
}));
|
});
|
||||||
|
@ -2,29 +2,39 @@ import $ from 'cafy';
|
|||||||
import ID, { transform } from '../../../../misc/cafy-id';
|
import ID, { transform } from '../../../../misc/cafy-id';
|
||||||
import App, { pack } from '../../../../models/app';
|
import App, { pack } from '../../../../models/app';
|
||||||
import define from '../../define';
|
import define from '../../define';
|
||||||
|
import { ApiError } from '../../error';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
|
tags: ['app'],
|
||||||
|
|
||||||
params: {
|
params: {
|
||||||
appId: {
|
appId: {
|
||||||
validator: $.type(ID),
|
validator: $.type(ID),
|
||||||
transform: transform
|
transform: transform
|
||||||
},
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
errors: {
|
||||||
|
noSuchApp: {
|
||||||
|
message: 'No such app.',
|
||||||
|
code: 'NO_SUCH_APP',
|
||||||
|
id: 'dce83913-2dc6-4093-8a7b-71dbb11718a3'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default define(meta, (ps, user, app) => new Promise(async (res, rej) => {
|
export default define(meta, async (ps, user, app) => {
|
||||||
const isSecure = user != null && app == null;
|
const isSecure = user != null && app == null;
|
||||||
|
|
||||||
// Lookup app
|
// Lookup app
|
||||||
const ap = await App.findOne({ _id: ps.appId });
|
const ap = await App.findOne({ _id: ps.appId });
|
||||||
|
|
||||||
if (ap === null) {
|
if (ap === null) {
|
||||||
return rej('app not found');
|
throw new ApiError(meta.errors.noSuchApp);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send response
|
return await pack(ap, user, {
|
||||||
res(await pack(ap, user, {
|
|
||||||
detail: true,
|
detail: true,
|
||||||
includeSecret: isSecure && ap.userId.equals(user._id)
|
includeSecret: isSecure && ap.userId.equals(user._id)
|
||||||
}));
|
});
|
||||||
}));
|
});
|
||||||
|
@ -5,8 +5,11 @@ import App from '../../../../models/app';
|
|||||||
import AuthSess from '../../../../models/auth-session';
|
import AuthSess from '../../../../models/auth-session';
|
||||||
import AccessToken from '../../../../models/access-token';
|
import AccessToken from '../../../../models/access-token';
|
||||||
import define from '../../define';
|
import define from '../../define';
|
||||||
|
import { ApiError } from '../../error';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
|
tags: ['auth'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
|
|
||||||
secure: true,
|
secure: true,
|
||||||
@ -15,16 +18,24 @@ export const meta = {
|
|||||||
token: {
|
token: {
|
||||||
validator: $.str
|
validator: $.str
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
errors: {
|
||||||
|
noSuchSession: {
|
||||||
|
message: 'No such session.',
|
||||||
|
code: 'NO_SUCH_SESSION',
|
||||||
|
id: '9c72d8de-391a-43c1-9d06-08d29efde8df'
|
||||||
|
},
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
export default define(meta, async (ps, user) => {
|
||||||
// Fetch token
|
// Fetch token
|
||||||
const session = await AuthSess
|
const session = await AuthSess
|
||||||
.findOne({ token: ps.token });
|
.findOne({ token: ps.token });
|
||||||
|
|
||||||
if (session === null) {
|
if (session === null) {
|
||||||
return rej('session not found');
|
throw new ApiError(meta.errors.noSuchSession);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate access token
|
// Generate access token
|
||||||
@ -64,6 +75,5 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Response
|
return;
|
||||||
res();
|
});
|
||||||
}));
|
|
||||||
|
@ -4,25 +4,36 @@ import App from '../../../../../models/app';
|
|||||||
import AuthSess from '../../../../../models/auth-session';
|
import AuthSess from '../../../../../models/auth-session';
|
||||||
import config from '../../../../../config';
|
import config from '../../../../../config';
|
||||||
import define from '../../../define';
|
import define from '../../../define';
|
||||||
|
import { ApiError } from '../../../error';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
|
tags: ['auth'],
|
||||||
|
|
||||||
requireCredential: false,
|
requireCredential: false,
|
||||||
|
|
||||||
params: {
|
params: {
|
||||||
appSecret: {
|
appSecret: {
|
||||||
validator: $.str
|
validator: $.str
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
errors: {
|
||||||
|
noSuchApp: {
|
||||||
|
message: 'No such app.',
|
||||||
|
code: 'NO_SUCH_APP',
|
||||||
|
id: '92f93e63-428e-4f2f-a5a4-39e1407fe998'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default define(meta, (ps) => new Promise(async (res, rej) => {
|
export default define(meta, async (ps) => {
|
||||||
// Lookup app
|
// Lookup app
|
||||||
const app = await App.findOne({
|
const app = await App.findOne({
|
||||||
secret: ps.appSecret
|
secret: ps.appSecret
|
||||||
});
|
});
|
||||||
|
|
||||||
if (app == null) {
|
if (app == null) {
|
||||||
return rej('app not found');
|
throw new ApiError(meta.errors.noSuchApp);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate token
|
// Generate token
|
||||||
@ -35,9 +46,8 @@ export default define(meta, (ps) => new Promise(async (res, rej) => {
|
|||||||
token: token
|
token: token
|
||||||
});
|
});
|
||||||
|
|
||||||
// Response
|
return {
|
||||||
res({
|
|
||||||
token: doc.token,
|
token: doc.token,
|
||||||
url: `${config.auth_url}/${doc.token}`
|
url: `${config.auth_url}/${doc.token}`
|
||||||
});
|
};
|
||||||
}));
|
});
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user