Compare commits

..

174 Commits

Author SHA1 Message Date
syuilo 338793d891 Merge branch 'develop' 2021-09-22 22:53:41 +09:00
syuilo 78ac41a613 12.91.0 2021-09-22 22:53:20 +09:00
syuilo be23ccf23b New Crowdin updates (#7823)
* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Esperanto)

* New translations create-plugin.md (Esperanto)
2021-09-22 22:53:01 +09:00
syuilo 1ba5e433e5 New Crowdin updates (#7822)
* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Esperanto)
2021-09-22 22:46:45 +09:00
syuilo 5bf4f569e4 enhance(client): アップデートが利用可能な場合エラー表示およびダイアログ表示しないように 2021-09-22 22:45:10 +09:00
syuilo 5a11844eff Update CHANGELOG.md 2021-09-22 22:36:20 +09:00
tamaina 14795b68f2 refactor: PackedHoge型をPacked<'Hoge'>型に書き換える (#7792)
* packedNotificationSchemaを更新

* read:gallery, write:gallery, read:gallery-likes, write:gallery-likesに翻訳を追加

* fix

* add header, choice, invitation

* test

* fix

* yatta

* remove no longer needed "as PackedUser/PackedNote"

* clean up

* add simple-schema

* fix lint

* define items in full Schema

* revert https://github.com/misskey-dev/misskey/pull/7772#discussion_r706627736

* user packとnote packの型不整合を修正

* add prelude/types.ts

* emoji

* signin

* game

* matching

* fix

* add emoji schema

* add reversiGame

* add reversiMatching

* remove signin schema (use Signin entity)

* add Packed type

* note-reaction

* user

* user-group

* user-list

* note

* app, messaging-message

* notification

* drive-file

* drive-folder

* following

* muting

* blocking

* hashtag

* page

* app (with modifying schema)

* import user?

* channel

* antenna

* clip

* gallery-post

* emoji

* Packed

* reversi-matching

* add changelog

* add changelog

* revert fix
2021-09-22 22:35:55 +09:00
syuilo bea42f5804 New Crowdin updates (#7764)
* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Chinese Simplified)

* New translations ja-JP.yml (Chinese Simplified)

* New translations apps.md (Chinese Simplified)

* New translations links.md (Chinese Simplified)

* New translations changelog.md (Chinese Simplified)

* New translations ja-JP.yml (Esperanto)

* New translations report-issue.md (Chinese Simplified)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations mfm.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations glossary.md (Esperanto)

* New translations timeline.md (Chinese Simplified)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations mfm.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations mfm.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations glossary.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations aiscript.md (English)

* New translations ja-JP.yml (Esperanto)

* New translations aiscript.md (English)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations links.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations keyboard-shortcut.md (Esperanto)

* New translations keyboard-shortcut.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations keyboard-shortcut.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations note.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations keyboard-shortcut.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations keyboard-shortcut.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations note.md (Esperanto)

* New translations keyboard-shortcut.md (Esperanto)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (English)

* New translations faq.md (Korean)

* New translations faq.md (Korean)

* New translations misskey.md (Korean)

* New translations faq.md (Korean)

* New translations disable-timelines.md (Korean)

* New translations disable-timelines.md (Korean)

* New translations disable-timelines.md (Korean)

* New translations aiscript.md (Korean)

* New translations misskey.md (Korean)

* New translations aiscript.md (Korean)

* New translations changelog.md (Korean)

* New translations misskey.md (Korean)

* New translations misskey.md (Korean)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations keyboard-shortcut.md (Esperanto)

* New translations glossary.md (Esperanto)

* New translations glossary.md (Esperanto)

* New translations glossary.md (Esperanto)

* New translations glossary.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations keyboard-shortcut.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations misskey.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations faq.md (Korean)

* New translations misskey.md (Korean)

* New translations apps.md (Korean)

* New translations faq.md (Korean)

* New translations misskey.md (Korean)

* New translations faq.md (Korean)

* New translations glossary.md (Korean)

* New translations faq.md (Korean)

* New translations glossary.md (Korean)

* New translations glossary.md (Korean)

* New translations glossary.md (Korean)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations create-plugin.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations keyboard-shortcut.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations keyboard-shortcut.md (Esperanto)

* New translations ja-JP.yml (Japanese, Kansai)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Chinese Simplified)

* New translations create-plugin.md (Chinese Simplified)

* New translations develop-bot.md (Chinese Simplified)

* New translations reversi-bot.md (Chinese Simplified)

* New translations ja-JP.yml (Japanese, Kansai)

* New translations reversi-bot.md (Chinese Simplified)

* New translations stream.md (Chinese Simplified)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Esperanto)

* New translations glossary.md (Esperanto)

* New translations glossary.md (Esperanto)

* New translations glossary.md (Esperanto)

* New translations reversi-bot.md (Chinese Simplified)

* New translations develop-bot.md (Chinese Simplified)

* New translations reversi-bot.md (Chinese Simplified)

* New translations reversi-bot.md (Chinese Simplified)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations troubleshooting.md (Esperanto)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations timeline.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations timeline.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations glossary.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations glossary.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations note.md (Esperanto)

* New translations glossary.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations glossary.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Esperanto)

* New translations reversi-bot.md (Chinese Simplified)

* New translations reversi-bot.md (Chinese Simplified)

* New translations reversi-bot.md (Chinese Simplified)

* New translations stream.md (Chinese Simplified)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations glossary.md (Korean)

* New translations glossary.md (Korean)

* New translations glossary.md (Korean)

* New translations glossary.md (Korean)

* New translations links.md (Korean)

* New translations links.md (Korean)

* New translations ja-JP.yml (Korean)
2021-09-22 22:31:22 +09:00
syuilo fbbce302bc enhance(client): 非ログイン自は更新ダイアログを出さないように
Resolve #7756
2021-09-22 22:18:08 +09:00
syuilo 4b9c605477 #7813の修正 2021-09-22 22:12:10 +09:00
Skehmatics a499ad6879 feat: MFM Sparkle animation (#7813)
* Add sparkle mfm animation 

* Cleanup sparkle effect

+ spaces -> tabs and other codestyle
+ use proper image
+ listen for resizes
+ use font-size to determine particle size (for fun with x2/3/4 stacking)
2021-09-22 22:09:23 +09:00
syuilo 76c5dc8999 fix(client): fix #7774 2021-09-22 21:58:08 +09:00
syuilo b985e14b13 update deps 2021-09-22 21:51:24 +09:00
syuilo 61de9cdbd4 🎨 2021-09-22 21:42:07 +09:00
syuilo 9208825975 feat(server): 管理者用アカウント削除API実装
動作確認済み
Resolve #7735
2021-09-22 17:34:48 +09:00
syuilo 72a49f334a enhance(client): リスト、アンテナタイムラインを個別ページとして分割 2021-09-21 21:04:59 +09:00
syuilo b35ca3b739 🎨 2021-09-21 04:13:54 +09:00
syuilo 85950f17fa 🎨 2021-09-21 04:09:28 +09:00
syuilo 78f95b5910 🎨 2021-09-21 02:01:25 +09:00
syuilo 909a09a0c0 Update CONTRIBUTING.md 2021-09-20 23:26:43 +09:00
syuilo bb9fc56cc1 Merge branch 'develop' of https://github.com/misskey-dev/misskey into develop 2021-09-20 23:24:10 +09:00
syuilo 9f3b4ccd14 update contribution guide 2021-09-20 23:24:07 +09:00
tamaina 90bf976fe2 enhance: ノートヘッダーにflex-shrinkを設定し、Acctを優先的に縮小して見栄えをよくするように (#7752)
* MAKE NOTE HEADER FLEX AGAIN

* span => div

* remove submodules
2021-09-20 22:14:49 +09:00
MeiMei 388de9dc96 chore, perf: Reduce redis memory (#7816)
* Reduce redis memory

* CHANGELOG

* a
2021-09-20 21:55:19 +09:00
syuilo 8a0a46b1c9 test: improve e2e test 2021-09-19 14:27:16 +09:00
syuilo 186163ec3f refactor 2021-09-19 02:58:25 +09:00
syuilo 91171c559a Update .gitignore 2021-09-19 02:58:17 +09:00
syuilo 36b483d04d Update .gitignore 2021-09-19 02:43:39 +09:00
syuilo 54e0a7f8a8 feat: 凍結された場合のダイアログを実装 (#7811)
* feat: 凍結された場合のダイアログを実装

* Update CHANGELOG.md

* Update basic.js

* improve error handling

* cypressなんもわからん

* Update basic.js
2021-09-19 02:23:12 +09:00
syuilo 6d4e96dea2 fix style 2021-09-18 21:26:31 +09:00
syuilo a6958da091 enhance(server): アカウントが凍結されたときのエラーを判定しやすく 2021-09-18 17:58:37 +09:00
syuilo 502bde5567 Update CHANGELOG.md 2021-09-18 15:45:45 +09:00
nullobsi d5702f9d51 add resolver check for blocked instance (#7777)
* add resolver check for blocked instance

* lint

* Update note.ts
2021-09-18 15:45:02 +09:00
syuilo 5141afe476 fix(client): タイムラインでリストとかなかったの修正 2021-09-18 15:39:01 +09:00
tamaina 4422219be7 fix: アンテナが既読にならないのを修正 (#7809) 2021-09-18 15:31:32 +09:00
syuilo 4b2afec108 Update CHANGELOG.md 2021-09-18 13:31:09 +09:00
sousuke0422 07bb8067ae fix: アンテナの既読 (#7803)
from: https://gitlab.com/xianon/misskey/-/commit/a89742319caea378f9cdd70c8ebd83bdf2178ff6
2021-09-18 13:30:28 +09:00
syuilo 4f63eb0c7e add sponsors section 2021-09-18 03:26:52 +09:00
syuilo 4ea7b2dd63 fix(server): fix #7786 2021-09-18 03:26:36 +09:00
tamaina e8189f7c69 Merge branch 'develop' of https://github.com/misskey-dev/misskey into develop 2021-09-17 22:58:29 +09:00
tamaina 23c054caec fix: add vanilla-tilt 2021-09-17 22:58:26 +09:00
syuilo a084c8b344 Update CHANGELOG.md 2021-09-17 22:39:55 +09:00
syuilo 361069314f Refine UI (#7806)
* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* Update default.vue

* wip
2021-09-17 22:39:15 +09:00
NoriDev d252514a39 popupで設定ページを表示すると、アカウントの削除ページにアクセスすることができない問題を修正 (#7797) 2021-09-17 20:00:31 +09:00
syuilo 31d1edc0fb update deps 2021-09-16 22:04:47 +09:00
sousuke0422 987474726c chore: .configをdockerイメージに入れないように (#7625)
* .configをdockerイメージに入れないように

* Update docker-compose.yml

Co-authored-by: tamaina <tamaina@hotmail.co.jp>

Co-authored-by: MeiMei <30769358+mei23@users.noreply.github.com>
Co-authored-by: tamaina <tamaina@hotmail.co.jp>
2021-09-13 20:07:39 +09:00
MeiMei 4beea63d3f GitHub Actionsを使用してDocker Hubへpushする方法 の説明 (#7790)
* Create push-docker-hub.ja.md

* remove space
2021-09-12 22:43:54 +09:00
tamaina 53f3b779bf refactor: Expand schema (#7772)
* packedNotificationSchemaを更新

* read:gallery, write:gallery, read:gallery-likes, write:gallery-likesに翻訳を追加

* fix

* add header, choice, invitation

* test

* fix

* yatta

* remove no longer needed "as PackedUser/PackedNote"

* clean up

* add simple-schema

* fix lint

* define items in full Schema

* revert https://github.com/misskey-dev/misskey/pull/7772#discussion_r706627736

* user packとnote packの型不整合を修正
2021-09-12 01:12:23 +09:00
tamaina f59f424795 Revert "fix: use master branch when build docker image"
This reverts commit c63ba5470a.
2021-09-11 11:37:35 +09:00
tamaina c63ba5470a fix: use master branch when build docker image 2021-09-11 11:32:47 +09:00
tamaina 935d6473ed chore: APIドキュメントの修正 (#7771)
* packedNotificationSchemaを更新

* read:gallery, write:gallery, read:gallery-likes, write:gallery-likesに翻訳を追加

* fix

* add header, choice, invitation
2021-09-09 20:23:31 +09:00
syuilo 0faa4470fb GitHub ActionsでDocker Hubへのpushを行うように (#7782)
* Create docker.yml

* Update .github/workflows/docker.yml

Co-authored-by: tamaina <tamaina@hotmail.co.jp>

* add workflow_dispatch

* Multi-platform image

* Revert "Multi-platform image"

This reverts commit e5bac66329.

Co-authored-by: tamaina <tamaina@hotmail.co.jp>
2021-09-09 19:28:02 +09:00
syuilo 0281bdd90c Update CHANGELOG.md 2021-09-05 23:36:20 +09:00
MeiMei 608ff73907 feat: リモートからユーザー削除が飛んできたら削除するように (#7768)
* Delete Actor

* Update src/remote/activitypub/kernel/delete/actor.ts

Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>

Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
2021-09-05 23:35:48 +09:00
syuilo c82ce9233b Merge branch 'develop' 2021-09-05 16:26:34 +09:00
syuilo cc75620976 12.90.1 2021-09-05 16:26:24 +09:00
syuilo 1cd8bfaded fix(server): ノート翻訳時に公開範囲が考慮されていない問題を修正 2021-09-05 16:25:30 +09:00
Jun Kurihara 65d9c304df fix Dockerfile (#7763)
* fix Dockerfile

* remove unnecessary change

* add misskey-assets in .dockerignore
2021-09-05 02:18:12 +09:00
syuilo 4b48ba4e8c Merge branch 'develop' 2021-09-04 20:38:20 +09:00
syuilo bf7bacceab 12.90.0 2021-09-04 20:38:09 +09:00
syuilo a56f461895 New Crowdin updates (#7693)
* New translations ja-JP.yml (English)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Indonesian)

* New translations disable-timelines.md (Indonesian)

* New translations faq.md (Indonesian)

* New translations misskey.md (Indonesian)

* New translations disable-timelines.md (Indonesian)

* New translations faq.md (Indonesian)

* New translations misskey.md (Indonesian)

* New translations faq.md (Indonesian)

* New translations glossary.md (Indonesian)

* New translations misskey.md (Indonesian)

* New translations changelog.md (Indonesian)

* New translations glossary.md (Indonesian)

* New translations glossary.md (Indonesian)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations api.md (Esperanto)

* New translations mfm.md (Esperanto)

* New translations ja-JP.yml (Chinese Simplified)

* New translations keyboard-shortcut.md (Chinese Simplified)

* New translations mfm.md (Chinese Simplified)

* New translations note.md (Chinese Simplified)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations glossary.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations misskey.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations timeline.md (Portuguese)

* New translations timeline.md (Portuguese)

* New translations timeline.md (Portuguese)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations keyboard-shortcut.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations keyboard-shortcut.md (Esperanto)

* New translations note.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations note.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations timeline.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations favorite.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations misskey.md (Russian)

* New translations misskey.md (Russian)

* New translations misskey.md (Russian)

* New translations misskey.md (Russian)

* New translations misskey.md (Russian)

* New translations misskey.md (Russian)

* New translations links.md (Russian)

* New translations glossary.md (Russian)

* New translations links.md (Russian)

* New translations glossary.md (Russian)

* New translations glossary.md (Russian)

* New translations glossary.md (Russian)

* New translations glossary.md (Russian)

* New translations glossary.md (Russian)

* New translations glossary.md (Russian)

* New translations glossary.md (Russian)

* New translations glossary.md (Russian)

* New translations glossary.md (Russian)

* New translations glossary.md (Russian)

* New translations glossary.md (Russian)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations develop-bot.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations troubleshooting.md (Russian)

* New translations troubleshooting.md (Russian)

* New translations troubleshooting.md (Russian)

* New translations troubleshooting.md (Russian)

* New translations troubleshooting.md (Russian)

* New translations troubleshooting.md (Russian)

* New translations troubleshooting.md (Russian)

* New translations troubleshooting.md (Russian)

* New translations troubleshooting.md (Russian)

* New translations troubleshooting.md (Russian)

* New translations ja-JP.yml (Chinese Simplified)

* New translations report-issue.md (Russian)

* New translations faq.md (Russian)

* New translations report-issue.md (Russian)

* New translations faq.md (Russian)

* New translations faq.md (Russian)

* New translations faq.md (Russian)

* New translations faq.md (Russian)

* New translations apps.md (Russian)

* New translations faq.md (Russian)

* New translations changelog.md (Russian)

* New translations ja-JP.yml (French)

* New translations mfm.md (Russian)

* New translations ja-JP.yml (French)

* New translations mfm.md (Russian)

* New translations ja-JP.yml (French)

* New translations mfm.md (Russian)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations troubleshooting.md (French)

* New translations troubleshooting.md (French)

* New translations ja-JP.yml (Kabyle)

* New translations api.md (French)

* New translations ja-JP.yml (Esperanto)

* New translations note.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations note.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations note.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations apps.md (Arabic)

* New translations api.md (French)

* New translations ja-JP.yml (Esperanto)

* New translations mute-and-block.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations glossary.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations note.md (Esperanto)

* New translations timeline.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations misskey.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations links.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations glossary.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations glossary.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations glossary.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations glossary.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Indonesian)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Chinese Simplified)

* New translations ja-JP.yml (Russian)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Chinese Simplified)

* New translations reversi-bot.md (Chinese Simplified)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations word-mute.md (Esperanto)
2021-09-04 20:37:43 +09:00
MeiMei e21ff916b0 ファイルサイズのハードリミット (#7760)
* maxFileSize

* CHANGELOG
2021-09-04 20:33:14 +09:00
syuilo da20675ada Update CHANGELOG.md 2021-09-04 19:50:07 +09:00
Johann150 7364fb84ef fix missing strings (#7674)
* fix sort menu in federation panel

* add missing strings in report menu

* change i18n key too
2021-09-04 18:21:45 +09:00
tamaina 48f46333f8 サインアップ・ログアウト周りの怪しい挙動を修正 (#7750)
* fix #7749

* fix

* fix logout behavior when there is no push subscription

* fix logout behavior when there is no push subscription 2

* clean up service worker registration

* fix lint

* remove submodules
2021-09-04 18:09:53 +09:00
syuilo 8407702b38 藍モード (#7687)
* wip

* wip

* シンボリックリンクやめた

* install lib dependency

* bring live2d assets from misskey-dev/assets

* refactor

* nanka iroiro

* コミット忘れ

* random motion

* wip

* run git submodule update --init

* コミット忘れ

* refactor

* fix bug

* Update misskey-assets

* lint

* lint

* lint

* 藍モード修正 (#7702)

* lazy load live2d script

* fix typo

* lazy load also widget

* hot link to cubism core

* https://github.com/misskey-dev/misskey/pull/7702/files#r695623821

* fix lint

* remove live2d stuff

* use iframe

* update

* Update gulpfile.ts

* update

* Update .gitattributes

* update

Co-authored-by: tamaina <tamaina@hotmail.co.jp>
2021-09-04 17:54:24 +09:00
MeiMei e1a8b158e0 Tune download (#2)
* s2-2

* allowedPrivateNetworks

* style

* Proxyの間にあると誤解しそうなのでconfigの記述順を変更

* Fix error handler
2021-09-03 21:13:06 +09:00
syuilo 7e30910ab8 Update CONTRIBUTING.md 2021-08-30 20:11:22 +09:00
syuilo 7fbee704ec Update CONTRIBUTING.en.md 2021-08-30 20:09:26 +09:00
syuilo b1f94c7bc6 Update CONTRIBUTING.en.md 2021-08-30 20:04:59 +09:00
syuilo 90411967d6 Update CONTRIBUTING.md
linterで担保させれば済むため、コーディングスタイルなどのセクションを削除
2021-08-30 20:00:31 +09:00
syuilo 5719c623a4 Update CONTRIBUTING.md 2021-08-30 19:56:28 +09:00
syuilo e210ec782a Update CONTRIBUTING.en.md 2021-08-30 19:53:51 +09:00
syuilo 229780f6ff Update CONTRIBUTING.en.md 2021-08-30 19:50:50 +09:00
syuilo 6490a9829b fix(client): fix button style 2021-08-29 16:44:15 +09:00
syuilo 6384d0708d update contribution guides 2021-08-28 15:42:27 +09:00
syuilo db1fde2956 Update PULL_REQUEST_TEMPLATE.md 2021-08-26 14:56:47 +09:00
syuilo c86720a331 Update CHANGELOG.md 2021-08-24 20:53:18 +09:00
Johann150 2af158be26 add setting to keep content warning (#7682) 2021-08-24 20:52:33 +09:00
syuilo 7115bd46ff Merge branch 'develop' 2021-08-24 14:40:22 +09:00
syuilo f84483896e 12.89.2 2021-08-24 14:40:01 +09:00
syuilo fe7bc174fb Fix #7689 2021-08-24 14:39:42 +09:00
syuilo e967d9ded3 Merge branch 'develop' 2021-08-24 13:20:30 +09:00
syuilo c3b55b6849 12.89.1 2021-08-24 13:20:20 +09:00
syuilo 3e193c9864 Merge branch 'develop' of https://github.com/misskey-dev/misskey into develop 2021-08-24 13:19:28 +09:00
syuilo d64e25e449 fix: support DeepL pro account
Fix #7648
2021-08-24 13:19:21 +09:00
syuilo c4707c612d New Crowdin updates (#7679)
* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations create-plugin.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Chinese Simplified)

* New translations ja-JP.yml (Chinese Simplified)

* New translations ja-JP.yml (Esperanto)

* New translations keyboard-shortcut.md (Esperanto)

* New translations timeline.md (Esperanto)

* New translations glossary.md (Esperanto)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Esperanto)

* New translations keyboard-shortcut.md (Esperanto)

* New translations timeline.md (Esperanto)

* New translations glossary.md (Esperanto)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Korean)
2021-08-24 13:08:58 +09:00
syuilo 9d3448c880 fix(server): use csp to imporve security 2021-08-24 13:08:20 +09:00
syuilo dad6a77645 refactoring 2021-08-22 22:22:53 +09:00
syuilo f64d3942d7 🎨 2021-08-22 16:18:53 +09:00
syuilo 45fe754759 🎨 2021-08-22 16:15:40 +09:00
syuilo 98f1d93628 refactor 2021-08-22 13:16:23 +09:00
syuilo 8785e1c3a4 enhance(client): ユーザー名についてのヒントを追加 2021-08-22 13:16:15 +09:00
syuilo f00ceedae4 Merge branch 'develop' 2021-08-21 17:59:29 +09:00
syuilo 7387e010c2 12.89.0 2021-08-21 17:59:13 +09:00
syuilo a59dfff12f New Crowdin updates (#7646)
* New translations mute-and-block.md (Ukrainian)

* New translations mute-and-block.md (Czech)

* New translations mute-and-block.md (Danish)

* New translations mute-and-block.md (German)

* New translations mute-and-block.md (Italian)

* New translations mute-and-block.md (Korean)

* New translations mute-and-block.md (Dutch)

* New translations mute-and-block.md (Norwegian)

* New translations mute-and-block.md (Polish)

* New translations mute-and-block.md (Portuguese)

* New translations mute-and-block.md (Russian)

* New translations mute-and-block.md (Chinese Simplified)

* New translations mute-and-block.md (Spanish)

* New translations mute-and-block.md (Chinese Traditional)

* New translations mute-and-block.md (English)

* New translations mute-and-block.md (Indonesian)

* New translations mute-and-block.md (Thai)

* New translations mute-and-block.md (Esperanto)

* New translations mute-and-block.md (Uyghur)

* New translations mute-and-block.md (Lojban)

* New translations mute-and-block.md (Kannada)

* New translations mute-and-block.md (Haitian Creole)

* New translations mute-and-block.md (Kabyle)

* New translations mute-and-block.md (Arabic)

* New translations mute-and-block.md (French)

* New translations mute-and-block.md (Japanese, Kansai)

* New translations glossary.md (German)

* New translations links.md (German)

* New translations links.md (English)

* New translations report-issue.md (German)

* New translations changelog.md (German)

* New translations apps.md (German)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations disable-timelines.md (Japanese, Kansai)

* New translations disable-timelines.md (Japanese, Kansai)

* New translations faq.md (Japanese, Kansai)

* New translations aiscript.md (Japanese, Kansai)

* New translations faq.md (Japanese, Kansai)

* New translations misskey.md (Japanese, Kansai)

* New translations aiscript.md (Japanese, Kansai)

* New translations reaction.md (Japanese, Kansai)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations glossary.md (Japanese, Kansai)

* New translations glossary.md (Kabyle)

* New translations glossary.md (Haitian Creole)

* New translations glossary.md (Kannada)

* New translations glossary.md (Lojban)

* New translations glossary.md (Uyghur)

* New translations glossary.md (Esperanto)

* New translations glossary.md (Indonesian)

* New translations misskey.md (English)

* New translations glossary.md (Thai)

* New translations glossary.md (English)

* New translations glossary.md (Chinese Traditional)

* New translations glossary.md (Dutch)

* New translations glossary.md (Chinese Simplified)

* New translations glossary.md (Ukrainian)

* New translations glossary.md (Russian)

* New translations glossary.md (Portuguese)

* New translations glossary.md (Polish)

* New translations glossary.md (Norwegian)

* New translations glossary.md (Korean)

* New translations glossary.md (French)

* New translations glossary.md (Italian)

* New translations glossary.md (German)

* New translations glossary.md (Danish)

* New translations glossary.md (Czech)

* New translations glossary.md (Arabic)

* New translations glossary.md (Spanish)

* New translations note.md (French)

* New translations glossary.md (Chinese Simplified)

* New translations faq.md (French)

* New translations faq.md (Chinese Simplified)

* New translations faq.md (Kabyle)

* New translations faq.md (Haitian Creole)

* New translations faq.md (Kannada)

* New translations faq.md (Lojban)

* New translations faq.md (Uyghur)

* New translations faq.md (Esperanto)

* New translations faq.md (Thai)

* New translations faq.md (Indonesian)

* New translations faq.md (English)

* New translations faq.md (Chinese Traditional)

* New translations faq.md (Ukrainian)

* New translations faq.md (Spanish)

* New translations faq.md (Russian)

* New translations faq.md (Portuguese)

* New translations faq.md (Polish)

* New translations faq.md (Norwegian)

* New translations faq.md (Dutch)

* New translations faq.md (Korean)

* New translations faq.md (Italian)

* New translations faq.md (German)

* New translations faq.md (Danish)

* New translations faq.md (Czech)

* New translations faq.md (Arabic)

* New translations faq.md (Japanese, Kansai)

* New translations faq.md (French)

* New translations misskey.md (French)

* New translations faq.md (French)

* New translations misskey.md (French)

* New translations faq.md (French)

* New translations troubleshooting.md (French)

* New translations troubleshooting.md (French)

* New translations troubleshooting.md (French)

* New translations troubleshooting.md (French)

* New translations troubleshooting.md (French)

* New translations troubleshooting.md (French)

* New translations troubleshooting.md (French)

* New translations word-mute.md (Ukrainian)

* New translations word-mute.md (Czech)

* New translations word-mute.md (Danish)

* New translations word-mute.md (German)

* New translations word-mute.md (Italian)

* New translations word-mute.md (Korean)

* New translations word-mute.md (Dutch)

* New translations word-mute.md (Norwegian)

* New translations word-mute.md (Polish)

* New translations word-mute.md (Portuguese)

* New translations word-mute.md (Russian)

* New translations word-mute.md (Chinese Simplified)

* New translations word-mute.md (Spanish)

* New translations word-mute.md (Chinese Traditional)

* New translations word-mute.md (English)

* New translations word-mute.md (Indonesian)

* New translations word-mute.md (Thai)

* New translations word-mute.md (Esperanto)

* New translations word-mute.md (Uyghur)

* New translations word-mute.md (Lojban)

* New translations word-mute.md (Kannada)

* New translations word-mute.md (Haitian Creole)

* New translations word-mute.md (Kabyle)

* New translations word-mute.md (Arabic)

* New translations word-mute.md (French)

* New translations word-mute.md (Japanese, Kansai)

* New translations glossary.md (English)

* New translations glossary.md (English)

* New translations glossary.md (English)

* New translations glossary.md (English)

* New translations faq.md (English)

* New translations faq.md (English)

* New translations glossary.md (English)

* New translations word-mute.md (English)

* New translations word-mute.md (English)

* New translations word-mute.md (English)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (English)
2021-08-21 17:58:32 +09:00
syuilo f6128dd3ff 🎨 2021-08-21 17:40:15 +09:00
syuilo eeff88ece2 Update CHANGELOG.md 2021-08-21 14:52:41 +09:00
syuilo bae1282f74 clean up 2021-08-21 14:47:39 +09:00
tamaina d2007add75 feat: Implement api sw/unregister (#7611)
* Implement api sw/unregister

* remove all mode

* add changelog

Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
2021-08-21 14:47:18 +09:00
okpierre 802db92d98 Update setup.en.md (#7675)
Updated PostgreSQL version to 12  

See https://github.com/misskey-dev/misskey/issues/7632#issuecomment-901653826
2021-08-21 14:24:03 +09:00
syuilo a53e1e4ec3 enhance: Improve account deletion experience 2021-08-21 12:48:50 +09:00
syuilo fd1ef4a62d enhance(server): Use job queue for account delete (#7668)
* enhance(server): Use job queue for account delete

Fix #5336

* ジョブをひとつに

* remove done call

* clean up

* add User.isDeleted

* コミット忘れ

* Update 1629512953000-user-is-deleted.ts

* show dialog

* lint

* Update 1629512953000-user-is-deleted.ts
2021-08-21 12:41:56 +09:00
syuilo 8ab9068d8e fix bug 2021-08-21 11:51:46 +09:00
syuilo 47dd30d3b2 fix(client): ノートの「削除して編集」をするとアンケートの選択肢が[object Object]になる問題を修正
Fix #7037
2021-08-21 11:16:56 +09:00
syuilo fcdd042b02 Merge branch 'develop' of https://github.com/misskey-dev/misskey into develop 2021-08-21 10:29:30 +09:00
syuilo 04855f9201 enhance(client): Improve emoji autocomplete behaviour
cherry picked from https://github.com/kat-atat/misskey/commit/4b2c215e25a0bae47f4375b296d1f5d07a179f88
2021-08-21 10:29:26 +09:00
dependabot[bot] cf0a5d5735 Bump @redocly/openapi-core from 1.0.0-beta.44 to 1.0.0-beta.54 (#7665)
Bumps [@redocly/openapi-core](https://github.com/Redocly/openapi-cli) from 1.0.0-beta.44 to 1.0.0-beta.54.
- [Release notes](https://github.com/Redocly/openapi-cli/releases)
- [Changelog](https://github.com/Redocly/openapi-cli/blob/master/docs/changelog.md)
- [Commits](https://github.com/Redocly/openapi-cli/compare/v1.0.0-beta.44...v1.0.0-beta.54)

---
updated-dependencies:
- dependency-name: "@redocly/openapi-core"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-08-20 23:15:17 +09:00
MeiMei bb2db1cf76 perf: Tune AP job queue timings (#7635)
* perf: Tune AP job queue timings

* CHANGELOG

* chore: add reference

Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
2021-08-20 21:59:03 +09:00
tamaina 0e69091455 doc: add features/word-mute (#7672) 2021-08-20 21:40:45 +09:00
syuilo 3cb5ed167a fix: meta.jsonをimportしないように
Fix #7671
2021-08-20 21:34:56 +09:00
Johann150 1ffee15b83 fix: use correct query generate function (#7657)
Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
2021-08-20 20:55:12 +09:00
tamaina 75b9f31acf fix: import syslog-pro 2021-08-20 20:18:24 +09:00
tamaina fc56b12690 refactor: localStorageのaccountsはindexedDBで保持するように (#7609)
* accountsストアはindexedDBで保持するように

* fix lint

* fix indexeddb available detection

* remove debugging code

* fix lint

* resolve https://github.com/misskey-dev/misskey/pull/7609/files/ba756204b77ce6e1189b8443e9641f2d02119621#diff-f565878e8202f0037b830c780b7c0932dc1bb5fd3d05ede14d72d10efbc3740c
Firefoxでの動作を改善

* fix lint

* fix lint

* add changelog
2021-08-20 19:38:16 +09:00
syuilo 60e768436e Create dependabot.yml 2021-08-20 00:22:29 +09:00
syuilo 84f2192cde update deps 2021-08-19 22:40:39 +09:00
syuilo 97f2675d40 refactor: use path alias to improve readability 2021-08-19 22:04:15 +09:00
syuilo 6d881d4570 fix import 2021-08-19 21:57:36 +09:00
syuilo 42cc93dd0f fix: mochaが動かないため拡張子なしに戻した 2021-08-19 21:55:45 +09:00
syuilo e9f34a0f09 Merge branch 'develop' of https://github.com/misskey-dev/misskey into develop 2021-08-19 18:33:59 +09:00
syuilo b9cb6d1c10 refactor: refactoring imports
将来ESMに移行しやすいように
Related: #7658

なんかmochaが起動しなくなってるけど理由不明
すぐ直したい
2021-08-19 18:33:41 +09:00
rinsuki 7bf517e990 Remove unused packages (#7661)
* Remove unused packages

* Remove unused babel things

* Remove more unused packages
2021-08-19 18:07:32 +09:00
rinsuki ab54e147f2 Remove is-root dependencies (#7660) 2021-08-19 16:27:12 +09:00
syuilo e677540fd6 Update faq.md 2021-08-19 15:42:53 +09:00
syuilo 31e3aaeda0 Update glossary.md 2021-08-19 11:35:42 +09:00
syuilo 938fc317c9 Update glossary.md 2021-08-19 11:32:25 +09:00
syuilo 4c431c5432 refactor 2021-08-19 11:26:26 +09:00
MeiMei 881b914c6a チャンネルを作成しているとアカウントを削除できないのを修正 (#7653)
* チャンネルを作成しているとアカウントを削除できないのを修正

* CHANGELOG

* nullable
2021-08-18 22:04:04 +09:00
syuilo df67836c1a Merge branch 'develop' 2021-08-17 22:01:46 +09:00
syuilo 6a3a8ba4d0 Merge branch 'develop' of https://github.com/misskey-dev/misskey into develop 2021-08-17 22:01:12 +09:00
syuilo 9e535c341e 12.88.0 2021-08-17 22:00:52 +09:00
syuilo 17fa4ba804 update vue 2021-08-17 22:00:39 +09:00
syuilo dd9a3c91fc New Crowdin updates (#7622)
* New translations create-plugin.md (Chinese Simplified)

* New translations ja-JP.yml (German)

* New translations glossary.md (Esperanto)

* New translations glossary.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations glossary.md (Esperanto)

* New translations misskey.md (Esperanto)

* New translations misskey.md (Esperanto)

* New translations misskey.md (Esperanto)

* New translations misskey.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations misskey.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations glossary.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations keyboard-shortcut.md (Esperanto)

* New translations timeline.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations keyboard-shortcut.md (Esperanto)

* New translations timeline.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations disable-timelines.md (Esperanto)

* New translations glossary.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations note.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Indonesian)

* New translations troubleshooting.md (Indonesian)

* New translations ja-JP.yml (Indonesian)

* New translations ja-JP.yml (German)

* New translations faq.md (French)

* New translations faq.md (French)

* New translations misskey.md (French)

* New translations faq.md (French)

* New translations faq.md (French)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations misskey.md (Russian)

* New translations misskey.md (Russian)

* New translations misskey.md (Russian)

* New translations misskey.md (Russian)

* New translations misskey.md (Russian)

* New translations misskey.md (Russian)

* New translations misskey.md (Russian)

* New translations misskey.md (Russian)

* New translations ja-JP.yml (Russian)

* New translations misskey.md (Russian)

* New translations misskey.md (Russian)

* New translations misskey.md (Russian)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations misskey.md (Esperanto)

* New translations misskey.md (Esperanto)

* New translations misskey.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Chinese Simplified)

* New translations antenna.md (French)

* New translations antenna.md (French)

* New translations changelog.md (French)

* New translations report-issue.md (French)

* New translations changelog.md (French)

* New translations links.md (French)

* New translations report-issue.md (French)

* New translations links.md (French)

* New translations links.md (French)

* New translations links.md (French)

* New translations misskey.md (Russian)

* New translations misskey.md (Russian)

* New translations links.md (French)

* New translations links.md (French)

* New translations apps.md (French)

* New translations links.md (French)

* New translations troubleshooting.md (French)

* New translations ja-JP.yml (French)

* New translations report-issue.md (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (French)

* New translations glossary.md (French)

* New translations misskey.md (Ukrainian)

* New translations misskey.md (Czech)

* New translations misskey.md (Danish)

* New translations misskey.md (German)

* New translations misskey.md (Italian)

* New translations misskey.md (Korean)

* New translations misskey.md (Dutch)

* New translations misskey.md (Norwegian)

* New translations misskey.md (Polish)

* New translations misskey.md (Portuguese)

* New translations misskey.md (Russian)

* New translations misskey.md (Chinese Simplified)

* New translations misskey.md (Spanish)

* New translations misskey.md (Chinese Traditional)

* New translations misskey.md (Indonesian)

* New translations misskey.md (Thai)

* New translations misskey.md (Esperanto)

* New translations misskey.md (Uyghur)

* New translations misskey.md (Lojban)

* New translations misskey.md (Kannada)

* New translations misskey.md (Haitian Creole)

* New translations misskey.md (Kabyle)

* New translations misskey.md (Arabic)

* New translations misskey.md (French)

* New translations glossary.md (Spanish)

* New translations glossary.md (Russian)

* New translations glossary.md (Arabic)

* New translations glossary.md (Czech)

* New translations glossary.md (Danish)

* New translations glossary.md (German)

* New translations glossary.md (Italian)

* New translations glossary.md (Korean)

* New translations glossary.md (Dutch)

* New translations glossary.md (Norwegian)

* New translations glossary.md (Polish)

* New translations glossary.md (Portuguese)

* New translations glossary.md (Ukrainian)

* New translations glossary.md (Japanese, Kansai)

* New translations glossary.md (Chinese Simplified)

* New translations glossary.md (Chinese Traditional)

* New translations glossary.md (Indonesian)

* New translations glossary.md (Thai)

* New translations glossary.md (Uyghur)

* New translations glossary.md (Lojban)

* New translations glossary.md (Kannada)

* New translations glossary.md (Haitian Creole)

* New translations glossary.md (Kabyle)

* New translations misskey.md (Japanese, Kansai)

* New translations ja-JP.yml (Esperanto)

* New translations note.md (Esperanto)

* New translations note.md (Esperanto)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (Esperanto)

* New translations api.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations drive.md (Esperanto)

* New translations glossary.md (Esperanto)

* New translations report-issue.md (French)

* New translations troubleshooting.md (French)

* New translations faq.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations faq.md (Esperanto)

* New translations troubleshooting.md (French)

* New translations ja-JP.yml (Esperanto)

* New translations misskey.md (Esperanto)

* New translations troubleshooting.md (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations troubleshooting.md (French)

* New translations misskey.md (Russian)

* New translations misskey.md (Russian)

* New translations misskey.md (Russian)

* New translations misskey.md (Russian)

* New translations misskey.md (Russian)

* New translations faq.md (French)

* New translations faq.md (Spanish)

* New translations faq.md (Russian)

* New translations faq.md (Arabic)

* New translations faq.md (Czech)

* New translations faq.md (Danish)

* New translations faq.md (German)

* New translations faq.md (Italian)

* New translations faq.md (Korean)

* New translations faq.md (Dutch)

* New translations faq.md (Norwegian)

* New translations faq.md (Polish)

* New translations faq.md (Portuguese)

* New translations faq.md (Ukrainian)

* New translations faq.md (Japanese, Kansai)

* New translations faq.md (Chinese Simplified)

* New translations faq.md (Chinese Traditional)

* New translations faq.md (English)

* New translations faq.md (Indonesian)

* New translations faq.md (Thai)

* New translations faq.md (Esperanto)

* New translations faq.md (Uyghur)

* New translations faq.md (Lojban)

* New translations faq.md (Kannada)

* New translations faq.md (Haitian Creole)

* New translations faq.md (Kabyle)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Japanese, Kansai)

* New translations antenna.md (Esperanto)

* New translations glossary.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations apps.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations deck.md (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Japanese, Kansai)

* New translations ja-JP.yml (Esperanto)

* New translations ja-JP.yml (Esperanto)

* New translations antenna.md (Japanese, Kansai)

* New translations ja-JP.yml (Esperanto)

* New translations antenna.md (Japanese, Kansai)

* New translations ja-JP.yml (Esperanto)

* New translations api.md (Esperanto)

* New translations custom-emoji.md (Japanese, Kansai)

* New translations ja-JP.yml (Esperanto)

* New translations deck.md (Japanese, Kansai)

* New translations deck.md (Japanese, Kansai)

* New translations faq.md (French)

* New translations faq.md (English)

* New translations faq.md (English)

* New translations faq.md (English)

* New translations faq.md (English)

* New translations faq.md (French)

* New translations misskey.md (French)

* New translations faq.md (French)

* New translations faq.md (French)

* New translations faq.md (English)

* New translations faq.md (French)

* New translations faq.md (French)

* New translations faq.md (French)

* New translations faq.md (French)

* New translations faq.md (Chinese Simplified)
2021-08-17 21:51:23 +09:00
syuilo 7015df37e3 enhance(server): Improve user block (#7640)
* enhance(server): Improve user block

* Update CHANGELOG.md

* ユーザーリスト対応

* 相手から見れなくなるように

* Update 1629004542760-chart-reindex.ts

https://github.com/misskey-dev/misskey/commit/2365761ba5445f26c8b66b3b20ef4be44e70d549#commitcomment-54919821

* update test

* add test

* add todos

* Update 1629004542760-chart-reindex.ts
2021-08-17 21:48:59 +09:00
MeiMei 7ebdd4739a Fix truncate (#7642) 2021-08-17 17:25:19 +09:00
syuilo c4bcb31a00 Update 1629004542760-chart-reindex.ts 2021-08-17 13:40:15 +09:00
syuilo 0a18ee24ac Update 1629004542760-chart-reindex.ts
https://github.com/misskey-dev/misskey/commit/2365761ba5445f26c8b66b3b20ef4be44e70d549#commitcomment-54919821
2021-08-17 13:37:16 +09:00
syuilo 37d10b108e Update faq.md 2021-08-17 11:52:27 +09:00
syuilo b5cadeca2e fix(client): コントロールパネルでファイルを削除した際の表示を修正
Fix #7631
2021-08-16 20:07:54 +09:00
syuilo c8e93054bc fix(client): タッチ操作でウィンドウを閉じることができない問題を修正 2021-08-16 18:11:15 +09:00
MeiMei def32107af perf: Improve network request performance (#7636)
* perf: Improve fetch

* CHANGELOG

* lifo
2021-08-16 17:44:43 +09:00
MeiMei 1b84ae9f3f chore: yarn.lockがおかしかったらCIでコケるように (#7634) 2021-08-16 16:33:45 +09:00
syuilo 73ce1f61a8 Tweak client style 2021-08-16 15:21:58 +09:00
syuilo 8661cd1ee7 Renoteされた時刻が投稿された時刻のように表示される問題を修正
Fix #7620
2021-08-16 15:20:23 +09:00
syuilo 53f55defda fix typo 2021-08-16 12:28:12 +09:00
syuilo d60dc60bc9 fix(server): use insert instead of save 2021-08-15 22:10:05 +09:00
syuilo bf1d7e6252 fix(server): ja-JPのような形式にDeepLが対応してない 2021-08-15 21:52:58 +09:00
syuilo c96b2767b9 fix typo 2021-08-15 21:44:00 +09:00
syuilo 6c1f03eefd enhance(client): Improve stability of version comparison 2021-08-15 20:34:06 +09:00
syuilo cced83024b feat: ノートの翻訳機能
Resolve #5213
2021-08-15 20:26:44 +09:00
MeiMei 1cd6ba3c1d chore: Remove vips from Dockerfile (#7633) 2021-08-15 18:12:46 +09:00
syuilo 2365761ba5 perf(server): Optimize db indexes of chart tables 2021-08-15 17:13:23 +09:00
syuilo d3b4b70bfc 🎨 2021-08-14 22:35:15 +09:00
syuilo f95d5701a2 feat(client): ジョブキューウィジェットに警報音を鳴らす設定を追加 2021-08-14 18:36:22 +09:00
syuilo a8c56afd0f add sound 2021-08-14 18:19:25 +09:00
syuilo 4de30aa47e Update CHANGELOG.md 2021-08-14 18:13:41 +09:00
Johann150 f05f7c920e fix: truncate user information if it is too long (#7629)
* truncate user information if it is too long

Some AP software allows for user names or summaries to be very long.
Misskey can not handle this and the profile page can not be opened and
no activities from such users can be seen.

Instead, the user name and summary are cut off after the maximum length
so misskey can still process the activities of the profile.

Co-authored-by: Toast <toast@toast.cafe>

* fix code style

Co-authored-by: Toast <toast@toast.cafe>
Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
2021-08-14 18:11:47 +09:00
syuilo 5f86509abc Merge branch 'develop' of https://github.com/misskey-dev/misskey into develop 2021-08-13 17:59:57 +09:00
syuilo 1561391293 feat(client): Misskey更新時にダイアログを表示するように 2021-08-13 17:59:54 +09:00
syuilo 60553a8a5e Update PULL_REQUEST_TEMPLATE.md 2021-08-12 23:46:13 +09:00
syuilo e656074de4 Update PULL_REQUEST_TEMPLATE.md 2021-08-12 23:45:46 +09:00
syuilo b81ff340b1 Introduce e2e test 2021-08-12 19:05:07 +09:00
syuilo 77456ae0bc Create config.yml 2021-08-12 15:44:16 +09:00
syuilo 9fd0e90850 Merge branch 'develop' 2021-08-12 12:48:58 +09:00
syuilo ab01cf1881 12.87.0 2021-08-12 12:48:53 +09:00
syuilo 0d10ca02db New Crowdin updates (#7619)
* New translations disable-timelines.md (Chinese Simplified)

* New translations api.md (Chinese Simplified)

* New translations api.md (Chinese Simplified)

* New translations ja-JP.yml (Chinese Simplified)

* New translations api.md (Chinese Simplified)

* New translations api.md (Chinese Simplified)

* New translations api.md (Chinese Simplified)

* New translations create-plugin.md (Chinese Simplified)

* New translations stream.md (Chinese Simplified)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (English)

* New translations note.md (English)

* New translations links.md (English)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Russian)

* New translations troubleshooting.md (Russian)

* New translations ja-JP.yml (Russian)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Chinese Simplified)
2021-08-12 12:48:24 +09:00
syuilo 0627df8116 improve(client): Improve emoji autocomplete 2021-08-12 12:41:57 +09:00
syuilo c88ea7150c fix(client): 更新時にテーマキャッシュをクリアするように 2021-08-12 12:02:41 +09:00
syuilo 555954c71e Improve about-misskey page 2021-08-12 11:48:06 +09:00
syuilo f231f02329 Update vue-loader 2021-08-12 11:38:21 +09:00
syuilo b8af5dfde0 Merge branch 'develop' of https://github.com/misskey-dev/misskey into develop 2021-08-12 11:33:03 +09:00
syuilo ef3710fdc2 Update deps 2021-08-12 11:33:00 +09:00
syuilo bde114ad13 Update node 2021-08-12 11:28:51 +09:00
syuilo 9d138aa282 Update CHANGELOG.md 2021-08-11 22:40:58 +09:00
928 changed files with 10960 additions and 5393 deletions
-13
View File
@@ -1,13 +0,0 @@
{
"plugins": [
[
"@babel/plugin-transform-runtime",
{
"corejs": {
"version": 3,
"proposals": true
}
}
]
]
}
+7
View File
@@ -157,3 +157,10 @@ id: 'aid'
# Sign to ActivityPub GET request (default: false)
#signToActivityPubGet: true
#allowedPrivateNetworks: [
# '127.0.0.1/32'
#]
# Upload or download file size limits (bytes)
#maxFileSize: 262144000
+2 -1
View File
@@ -1,8 +1,8 @@
.autogen
.git
.github
.travis
.vscode
.config
Dockerfile
build/
built/
@@ -12,3 +12,4 @@ elasticsearch/
node_modules/
redis/
files/
misskey-assets/
+7
View File
@@ -0,0 +1,7 @@
contact_links:
- name: 👪 Misskey Forum
url: https://forum.misskey.io/
about: Ask questions and share knowledge
- name: 💬 Misskey official Discord
url: https://discord.gg/Wp8gVStHW3
about: Chat freely about Misskey
+4 -16
View File
@@ -1,22 +1,10 @@
<!-- お読みください
PRありがとうございます! PRを作成する前に、以下をご確認ください:
可能であればタイトルに、以下で示すようなPRの種類が分かるキーワードをプリフィクスしてください。
fix / refactor / feat / enhance / perf / chore
また、PRの粒度が適切であることを確認してください。ひとつのPRに複数の種類の変更や関心を含めることは避けてください。
このPRによって解決されるIssueがある場合は、そのIssue IDを本文内に記入してください。
CHANGELOG.mdに変更点を追記してください。リファクタリングなど、利用者に影響を与えない変更についてはこの限りではありません。
機能追加やバグ修正をした場合は、可能であればテストケースを追加してください。
ご協力ありがとうございます🤗
PRありがとうございます! PRを作成する前に、コントリビューションガイドをご確認ください:
https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md
-->
<!-- README
Thank you for your PR! Before creating a PR, please check the following:
If possible, prefix the title with a keyword that identifies the type of this PR, as shown below.
fix / refactor / feat / enhance / perf / chore
Also, make sure that the granularity of this PR is appropriate. Please do not include more than one type of change or interest in a single PR.
If there is an issue to be resolved by this PR, please include the Issue ID in the text.
Please add the summary of the changes to CHANGELOG.md. However, this is not necessary for changes that do not affect the users, such as refactoring.
If you have added a feature or fixed a bug, please add a test case if possible.
Thanks for your cooperation 🤗
Thank you for your PR! Before creating a PR, please check the contribution guide:
https://github.com/misskey-dev/misskey/blob/develop/docs/CONTRIBUTING.en.md
-->
# What
+11
View File
@@ -0,0 +1,11 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
- package-ecosystem: "npm" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "daily"
+32
View File
@@ -0,0 +1,32 @@
name: Publish Docker image
on:
release:
types: [published]
workflow_dispatch:
jobs:
push_to_registry:
name: Push Docker image to Docker Hub
runs-on: ubuntu-latest
steps:
- name: Check out the repo
uses: actions/checkout@v2
- name: Docker meta
id: meta
uses: docker/metadata-action@v3
with:
images: misskey/misskey
- name: Log in to Docker Hub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and Push to Docker Hub
uses: docker/build-push-action@v2
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
+6
View File
@@ -29,12 +29,16 @@ jobs:
steps:
- uses: actions/checkout@v2
with:
submodules: true
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: Install dependencies
run: yarn install
- name: Check yarn.lock
run: git diff --exit-code yarn.lock
- name: Copy Configure
run: cp .circleci/misskey/*.yml .config
- name: Build
@@ -46,6 +50,8 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
submodules: true
- uses: actions/setup-node@v1
with:
node-version: 12.x
+4
View File
@@ -9,6 +9,10 @@
/node_modules
report.*.json
# Cypress
cypress/screenshots
cypress/videos
# config
/.config/*
!/.config/example.yml
+3
View File
@@ -0,0 +1,3 @@
[submodule "misskey-assets"]
path = misskey-assets
url = https://github.com/misskey-dev/assets.git
+1 -1
View File
@@ -1 +1 @@
v16.2.0
v16.6.2
+123 -1
View File
@@ -1,3 +1,125 @@
<!--
## 12.x.x (unreleased)
### Improvements
### Bugfixes
-->
## 12.91.0 (2021/09/22)
### Improvements
- ActivityPub: リモートユーザーのDeleteアクティビティに対応
- ActivityPub: add resolver check for blocked instance
- ActivityPub: deliverキューのメモリ使用量を削減
- API: 管理者用アカウント削除APIを実装(/admin/accounts/delete)
- リモートユーザーの削除も可能に
- アカウントが凍結された場合に、凍結された旨を表示してからログアウトするように
- 凍結されたアカウントにログインしようとしたときに、凍結されている旨を表示するように
- リスト、アンテナタイムラインを個別ページとして分割
- UIの改善
- MFMにsparklesエフェクトを追加
- 非ログイン自は更新ダイアログを出さないように
- クライアント起動時、アップデートが利用可能な場合エラー表示およびダイアログ表示しないように
### Bugfixes
- アカウントデータのエクスポート/インポート処理ができない問題を修正
- アンテナの既読が付かない問題を修正
- popupで設定ページを表示すると、アカウントの削除ページにアクセスすることができない問題を修正
- "問題が発生しました"ウィンドウを開くと☓ボタンがなくて閉じれない問題を修正
## 12.90.1 (2021/09/05)
### Bugfixes
- Dockerfileを修正
- ノート翻訳時に公開範囲が考慮されていない問題を修正
## 12.90.0 (2021/09/04)
### Improvements
- 藍モード、および藍ウィジェット
- クライアントに藍ちゃんを召喚することができるようになりました。
- URLからのアップロード, APの添付ファイル, 外部ファイルのプロキシ等では、Privateアドレス等へのリクエストは拒否されるようになりました。
- developmentで動作している場合は、この制限は適用されません。
- Proxy使用時には、この制限は適用されません。
Proxy使用時に同等の制限を行いたい場合は、Proxy側で設定を行う必要があります。
- `default.yml`にて`allowedPrivateNetworks`にCIDRを追加することにより、宛先ネットワークを指定してこの制限から除外することが出来ます。
- アップロード, ダウンロード出来るファイルサイズにハードリミットが適用されるようになりました。(約250MB)
- `default.yml`にて`maxFileSize`を変更することにより、制限値を変更することが出来ます。
### Bugfixes
- 管理者が最初にサインアップするページでログインされないのを修正
- CWを維持する設定を復活
- クライアントの表示を修正
## 12.89.2 (2021/08/24)
### Bugfixes
- カスタムCSSを有効にしているとエラーになる問題を修正
## 12.89.1 (2021/08/24)
### Improvements
- クライアントのデザインの調整
### Bugfixes
- 翻訳でDeepLのProアカウントに対応していない問題を修正
- インスタンス設定でDeepLのAuth Keyが空で表示される問題を修正
- セキュリティの向上
## 12.89.0 (2021/08/21)
### Improvements
- アカウント削除の安定性を向上
- 絵文字オートコンプリートの挙動を改修
- localStorageのaccountsはindexedDBで保持するように
- ActivityPub: ジョブキューの試行タイミングを調整 (#7635)
- API: sw/unregisterを追加
- ワードミュートのドキュメントを追加
- クライアントのデザインの調整
- 依存関係の更新
### Bugfixes
- チャンネルを作成しているとアカウントを削除できないのを修正
- ノートの「削除して編集」をするとアンケートの選択肢が[object Object]になる問題を修正
## 12.88.0 (2021/08/17)
### Features
- ノートの翻訳機能を追加
- 有効にするには、サーバー管理者がDeepLの無料アカウントを登録し、取得した認証キーを「インスタンス設定 > その他 > DeepL Auth Key」に設定する必要があります。
- Misskey更新時にダイアログを表示するように
- ジョブキューウィジェットに警報音を鳴らす設定を追加
### Improvements
- ブロックの挙動を改修
- ブロックされたユーザーがブロックしたユーザーに対してアクション出来ないようになりました。詳細はドキュメントをご確認ください。
- UIデザインの調整
- データベースのインデックスを最適化
- Proxy使用時にKeep-Aliveをサポート
- DNSキャッシュでネガティブキャッシュをサポート
- 依存関係の更新
### Bugfixes
- タッチ操作でウィンドウを閉じることができない問題を修正
- Renoteされた時刻が投稿された時刻のように表示される問題を修正
- コントロールパネルでファイルを削除した際の表示を修正
- ActivityPub: 長いユーザーの名前や自己紹介の対応
## 12.87.0 (2021/08/12)
### Improvements
- 絵文字オートコンプリートで一文字目は最近使った絵文字をサジェストするように
- 絵文字オートコンプリートのパフォーマンスを改善
- about-misskeyページにドキュメントへのリンクを追加
- Docker: Node.jsを16.6.2に
- 依存関係の更新
- 翻訳の更新
### Bugfixes
- Misskey更新時、テーマキャッシュの影響でスタイルがおかしくなる問題を修正
## 12.86.0 (2021/08/11)
### Improvements
@@ -9,4 +131,4 @@
### Bugfixes
- ハッシュタグ入力が空のときに#が付くのを修正
- フォロー通知のEメール通知を修正
- フォローリクエストのEメール通知を修正
+53 -121
View File
@@ -1,22 +1,43 @@
# Contribution guide
:v: Thanks for your contributions :v:
We're glad you're interested in contributing Misskey! In this document you will find the information you need to contribute to the project.
## When you contribute...
- 任意のIssueについて、せっかく実装してくださっても、実装方法や設計の認識が揃ってないとマージできない/しないことになりかねないので、初めにそのIssue上で着手することを宣言し、必要に応じて他メンバーと実装方法や設計のすり合わせを行ってください。宣言することは作業が他の人と被るのを防止する効果もあります。
- 設計に迷った時はプロジェクトリーダーの判断を仰いでください。
- 時間や優先度の都合上、提出してくださったPRが長期間放置されることもありますがご理解ください。
- 温度感高めで見てほしいものは責付いてください。
**️ Important:** This project uses Japanese as its major language, **but you do not need to translate and write the Issues/PRs in Japanese.**
Also, you might receive comments on your Issue/PR in Japanese, but you do not need to reply to them in Japanese as well.\
The accuracy of translation into Japanese is not high, so it will be easier for us to understand if you write it in the original language.
It will also allow the reader to use the translation tool of their preference if necessary.
## Issues
Feature suggestions and bug reports are filed in https://github.com/misskey-dev/misskey/issues .
Before creating an issue, please check the following:
- To avoid duplication, please search for similar issues before creating a new issue.
- Do not use Issues as a question.
- Issues should only be used to feature requests, suggestions, and report problems.
- Please ask questions in the [Misskey Forum](https://forum.misskey.io/) or [Discord](https://discord.gg/Wp8gVStHW3).
* Please search existing issues to avoid duplication. If your issue is already filed, please add your reaction or comment to the existing one.
* If you have multiple independent issues, please submit them separately.
## Before implementation
When you want to add a feature or fix a bug, **first have the design and policy reviewed in an Issue** (if it is not there, please make one). Without this step, there is a high possibility that the PR will not be merged even if it is implemented.
## Branches
* **master** branch is tracking the latest release and used for production purposes.
* **develop** branch is where we work for the next release.
* **l10n_develop** branch is reserved for localization management.
Also, when you start implementation, assign yourself to the Issue (if you cannot do it yourself, ask another member to assign you). By expressing your intention to work the Issue, you can prevent conflicts in the work.
## Well-known branches
- **`master`** branch is tracking the latest release and used for production purposes.
- **`develop`** branch is where we work for the next release.
- When you create a PR, basically target it to this branch.
- **`l10n_develop`** branch is reserved for localization management.
## Creating a PR
Thank you for your PR! Before creating a PR, please check the following:
- If possible, prefix the title with a keyword that identifies the type of this PR, as shown below.
- `fix` / `refactor` / `feat` / `enhance` / `perf` / `chore` etc
- Also, make sure that the granularity of this PR is appropriate. Please do not include more than one type of change or interest in a single PR.
- If there is an Issue which will be resolved by this PR, please include a reference to the Issue in the text.
- Please add the summary of the changes to [`CHANGELOG.md`](/CHANGELOG.md). However, this is not necessary for changes that do not affect the users, such as refactoring.
- Check if there are any documents that need to be created or updated due to this change.
- If you have added a feature or fixed a bug, please add a test case if possible.
- Please make sure that tests and Lint are passed in advance.
- You can run it with `npm run test` and `npm run lint`. [See more info](#testing)
- If this PR includes UI changes, please attach a screenshot in the text.
Thanks for your cooperation 🤗
## Localization (l10n)
Misskey uses [Crowdin](https://crowdin.com/project/misskey) for localization management.
@@ -32,8 +53,21 @@ If your language is not listed in Crowdin, please open an issue.
* Documents for instance admins are located in [`/docs`](/docs).
* Documents for end users are located in [`/src/docs`](/src/docs).
## Test
* Test codes are located in [`/test`](/test).
## Testing
- Test codes are located in [`/test`](/test).
### Run test
```
npm run test
```
#### Run specify test
```
npx cross-env TS_NODE_FILES=true TS_NODE_TRANSPILE_ONLY=true TS_NODE_PROJECT="./test/tsconfig.json" npx mocha test/foo.ts --require ts-node/register
```
### e2e tests
TODO
## Continuous integration
Misskey uses GitHub Actions for executing automated tests.
@@ -50,116 +84,11 @@ Configuration files are located in [`/.github/workflows`](/.github/workflows).
If you have no experience on 3D modeling, we suggest to use the free 3DCG software [Blender](https://www.blender.org/).
You can find information on glTF 2.0 at [glTF 2.0 — Blender Manual]( https://docs.blender.org/manual/en/dev/addons/io_scene_gltf2.html).
## FAQ
## Notes
### How to resolve conflictions occurred at yarn.lock?
Just execute `yarn` to fix it.
## Glossary
### AP
Stands for _**A**ctivity**P**ub_.
### MFM
Stands for _**M**isskey **F**lavored **M**arkdown_.
### Mk
Stands for _**M**iss**k**ey_.
### SW
Stands for _**S**ervice**W**orker_.
### Nyaize
Convert な(na) to にゃ(nya)
#### Denyaize
Revert Nyaize
## TypeScript Coding Style
### Do not omit semicolons
This is to avoid Automatic Semicolon Insertion (ASI) hazard.
Ref:
* https://www.ecma-international.org/ecma-262/#sec-automatic-semicolon-insertion
* https://github.com/tc39/ecma262/pull/1062
### Do not omit curly brackets
Bad:
``` ts
if (foo)
bar;
else
baz;
```
Good:
``` ts
if (foo) {
bar;
} else {
baz;
}
```
As a special case, you can omit the curly brackets if
* the body of the `if`-statement have only one statement and,
* the `if`-statement does not have `else`-clause.
Good:
``` ts
if (foo) bar;
```
Make sure that the condition and the body statement are on the same line.
### Do not use `==` when it can simply be replaced with `===`.
🥰
### Use only boolean (or null related) values in the condition of an `if`-statement.
Bad:
``` ts
if (foo.length)
```
Good:
``` ts
if (foo.length > 0)
```
### Do not use `export default`
This is because the current language support does not work well with `export default`.
Ref:
* https://basarat.gitbooks.io/typescript/docs/tips/defaultIsBad.html
* https://gfx.hatenablog.com/entry/2017/11/24/135343
Bad:
``` ts
export default function(foo: string): string {
```
Good:
``` ts
export function something(foo: string): string {
```
## Directory structure
```
src ... Source code
@types ... Type definitions
prelude ... Independence utils for coding JavaScript without side effects
misc ... Independence utils for Misskey without side effects
service ... Common functions with side effects
queue ... Job queues and Jobs
server ... Web Server
client ... Client
mfm ... MFM
test ... Test code
```
## Notes
### placeholder
SQLをクエリビルダで組み立てる際、使用するプレースホルダは重複してはならない
例えば
@@ -245,6 +174,9 @@ npx ts-node ./node_modules/typeorm/cli.js migration:generate -n 変更の名前
### コネクションには`markRaw`せよ
**Vueのコンポーネントのdataオプションとして**misskey.jsのコネクションを設定するとき、必ず`markRaw`でラップしてください。インスタンスが不必要にリアクティブ化されることで、misskey.js内の処理で不具合が発生するとともに、パフォーマンス上の問題にも繋がる。なお、Composition APIを使う場合はこの限りではない(リアクティブ化はマニュアルなため)。
### JSONのimportに気を付けよう
TypeScriptでjsonをimportすると、tscでコンパイルするときにそのjsonファイルも一緒にdistディレクトリに吐き出されてしまう。この挙動により、意図せずファイルの書き換えが発生することがあるので、jsonをimportするときは書き換えられても良いものかどうか確認すること。書き換えされて欲しくない場合は、importで読み込むのではなく、`fs.readFileSync`などの関数を使って読み込むようにすればよい。
## その他
### HTMLのクラス名で follow という単語は使わない
広告ブロッカーで誤ってブロックされる
+11 -22
View File
@@ -1,38 +1,26 @@
FROM node:16.2.0-alpine3.13 AS base
FROM node:16.6.2-alpine3.13 AS base
ENV NODE_ENV=production
WORKDIR /misskey
ENV BUILD_DEPS autoconf automake file g++ gcc libc-dev libtool make nasm pkgconfig python3 zlib-dev git
FROM base AS builder
RUN apk add --no-cache \
autoconf \
automake \
file \
g++ \
gcc \
libc-dev \
libtool \
make \
nasm \
pkgconfig \
python3 \
zlib-dev \
vips-dev \
vips
COPY package.json yarn.lock .yarnrc ./
RUN yarn install
COPY . ./
RUN yarn build
RUN apk add --no-cache $BUILD_DEPS && \
git submodule update --init && \
yarn install && \
yarn build && \
rm -rf .git
FROM base AS runner
RUN apk add --no-cache \
ffmpeg \
tini \
vips
tini
ENTRYPOINT ["/sbin/tini", "--"]
@@ -41,3 +29,4 @@ COPY --from=builder /misskey/built ./built
COPY . ./
CMD ["npm", "run", "migrateandstart"]
+6
View File
@@ -104,6 +104,12 @@ Related projects
- [misskey.js](https://github.com/misskey-dev/misskey.js) - Misskey SDK for JavaScript
- [mfm.js](https://github.com/misskey-dev/mfm.js) - MFM parser
Sponsors
----------------------------------------------------------------
<div align="center">
<a class="rss3" title="RSS3" href="https://rss3.io/" target="_blank" style="display: inline-block;"><img src="https://rss3.io/assets/images/Logo.svg" alt="RSS3" style="display: inline-block; height: 60px;"></a>
</div>
:heart: Backers
----------------------------------------------------------------
<!-- PATREON_START -->
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 185 B

+3
View File
@@ -0,0 +1,3 @@
{
"baseUrl": "http://localhost"
}
+5
View File
@@ -0,0 +1,5 @@
{
"name": "Using fixtures to represent data",
"email": "hello@cypress.io",
"body": "Fixtures are a great way to mock data for responses to routes"
}
+189
View File
@@ -0,0 +1,189 @@
describe('Before setup instance', () => {
beforeEach(() => {
cy.request('POST', '/api/reset-db').as('reset');
cy.get('@reset').its('status').should('equal', 204);
cy.reload(true);
});
afterEach(() => {
// テスト終了直前にページ遷移するようなテストケース(例えばアカウント作成)だと、たぶんCypressのバグでブラウザの内容が次のテストケースに引き継がれてしまう(例えばアカウントが作成し終わった段階からテストが始まる)。
// waitを入れることでそれを防止できる
cy.wait(1000);
});
it('successfully loads', () => {
cy.visit('/');
});
it('setup instance', () => {
cy.visit('/');
cy.intercept('POST', '/api/admin/accounts/create').as('signup');
cy.get('[data-cy-admin-username] input').type('admin');
cy.get('[data-cy-admin-password] input').type('admin1234');
cy.get('[data-cy-admin-ok]').click();
// なぜか動かない
//cy.wait('@signup').should('have.property', 'response.statusCode');
cy.wait('@signup');
});
});
describe('After setup instance', () => {
beforeEach(() => {
cy.request('POST', '/api/reset-db').as('reset');
cy.get('@reset').its('status').should('equal', 204);
cy.reload(true);
// インスタンス初期セットアップ
cy.request('POST', '/api/admin/accounts/create', {
username: 'admin',
password: 'pass',
}).its('body').as('admin');
cy.get('@admin');
});
afterEach(() => {
// テスト終了直前にページ遷移するようなテストケース(例えばアカウント作成)だと、たぶんCypressのバグでブラウザの内容が次のテストケースに引き継がれてしまう(例えばアカウントが作成し終わった段階からテストが始まる)。
// waitを入れることでそれを防止できる
cy.wait(1000);
});
it('successfully loads', () => {
cy.visit('/');
});
it('signup', () => {
cy.visit('/');
cy.intercept('POST', '/api/signup').as('signup');
cy.get('[data-cy-signup]').click();
cy.get('[data-cy-signup-username] input').type('alice');
cy.get('[data-cy-signup-password] input').type('alice1234');
cy.get('[data-cy-signup-password-retype] input').type('alice1234');
cy.get('[data-cy-signup-submit]').click();
cy.wait('@signup');
});
});
describe('After user signup', () => {
beforeEach(() => {
cy.request('POST', '/api/reset-db').as('reset');
cy.get('@reset').its('status').should('equal', 204);
cy.reload(true);
// インスタンス初期セットアップ
cy.request('POST', '/api/admin/accounts/create', {
username: 'admin',
password: 'pass',
}).its('body').as('admin');
cy.get('@admin').then(() => {
// ユーザー作成
cy.request('POST', '/api/signup', {
username: 'alice',
password: 'alice1234',
}).its('body').as('alice');
});
cy.get('@alice');
});
afterEach(() => {
// テスト終了直前にページ遷移するようなテストケース(例えばアカウント作成)だと、たぶんCypressのバグでブラウザの内容が次のテストケースに引き継がれてしまう(例えばアカウントが作成し終わった段階からテストが始まる)。
// waitを入れることでそれを防止できる
cy.wait(1000);
});
it('successfully loads', () => {
cy.visit('/');
});
it('signin', () => {
cy.visit('/');
cy.intercept('POST', '/api/signin').as('signin');
cy.get('[data-cy-signin]').click();
cy.get('[data-cy-signin-username] input').type('alice');
// Enterキーでサインインできるかの確認も兼ねる
cy.get('[data-cy-signin-password] input').type('alice1234{enter}');
cy.wait('@signin');
});
it('suspend', function() {
cy.request('POST', '/api/admin/suspend-user', {
i: this.admin.token,
userId: this.alice.id,
});
cy.visit('/');
cy.get('[data-cy-signin]').click();
cy.get('[data-cy-signin-username] input').type('alice');
cy.get('[data-cy-signin-password] input').type('alice1234{enter}');
cy.contains('アカウントが凍結されています');
});
});
describe('After user singed in', () => {
beforeEach(() => {
cy.request('POST', '/api/reset-db').as('reset');
cy.get('@reset').its('status').should('equal', 204);
cy.reload(true);
// インスタンス初期セットアップ
cy.request('POST', '/api/admin/accounts/create', {
username: 'admin',
password: 'pass',
}).its('body').as('admin');
cy.get('@admin').then(() => {
// ユーザー作成
cy.request('POST', '/api/signup', {
username: 'alice',
password: 'alice1234',
}).its('body').as('alice');
});
cy.get('@alice').then(() => {
cy.visit('/');
cy.intercept('POST', '/api/signin').as('signin');
cy.get('[data-cy-signin]').click();
cy.get('[data-cy-signin-username] input').type('alice');
cy.get('[data-cy-signin-password] input').type('alice1234{enter}');
cy.wait('@signin').as('signedIn');
});
cy.get('@signedIn');
});
afterEach(() => {
// テスト終了直前にページ遷移するようなテストケース(例えばアカウント作成)だと、たぶんCypressのバグでブラウザの内容が次のテストケースに引き継がれてしまう(例えばアカウントが作成し終わった段階からテストが始まる)。
// waitを入れることでそれを防止できる
cy.wait(1000);
});
it('successfully loads', () => {
cy.visit('/');
});
it('note', () => {
cy.visit('/');
cy.get('[data-cy-open-post-form]').click();
cy.get('[data-cy-post-form-text]').type('Hello, Misskey!');
cy.get('[data-cy-open-post-form-submit]').click();
cy.contains('Hello, Misskey!');
});
});
+22
View File
@@ -0,0 +1,22 @@
/// <reference types="cypress" />
// ***********************************************************
// This example plugins/index.js can be used to load plugins
//
// You can change the location of this file or turn off loading
// the plugins file with the 'pluginsFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/plugins-guide
// ***********************************************************
// This function is called when a project is opened or re-opened (e.g. due to
// the project's config changing)
/**
* @type {Cypress.PluginConfig}
*/
// eslint-disable-next-line no-unused-vars
module.exports = (on, config) => {
// `on` is used to hook into various events Cypress emits
// `config` is the resolved Cypress config
}
+25
View File
@@ -0,0 +1,25 @@
// ***********************************************
// This example commands.js shows you how to
// create various custom commands and overwrite
// existing commands.
//
// For more comprehensive examples of custom
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************
//
//
// -- This is a parent command --
// Cypress.Commands.add('login', (email, password) => { ... })
//
//
// -- This is a child command --
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
//
//
// -- This is a dual command --
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
//
//
// -- This will overwrite an existing command --
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
+20
View File
@@ -0,0 +1,20 @@
// ***********************************************************
// This example support/index.js is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************
// Import commands.js using ES2015 syntax:
import './commands'
// Alternatively you can use CommonJS syntax:
// require('./commands')
+1
View File
@@ -15,6 +15,7 @@ services:
- external_network
volumes:
- ./files:/misskey/files
- ./.config:/misskey/.config:ro
redis:
restart: always
+5 -4
View File
@@ -83,10 +83,11 @@ Just `docker-compose up -d`. GLHF!
1. `git stash`
2. `git checkout master`
3. `git pull`
4. `git stash pop`
5. `docker-compose build`
6. Check [ChangeLog](../CHANGELOG.md) for migration information
7. `docker-compose stop && docker-compose up -d`
4. `git submodule update --init`
5. `git stash pop`
6. `docker-compose build`
7. Check [ChangeLog](../CHANGELOG.md) for migration information
8. `docker-compose stop && docker-compose up -d`
### How to execute [cli commands](manage.en.md):
`docker-compose run --rm web node built/tools/mark-admin @example`
+5 -4
View File
@@ -50,10 +50,11 @@ Utilisez la commande `docker-compose up -d`. GLHF!
1. `git stash`
2. `git checkout master`
3. `git pull`
4. `git stash pop`
5. `docker-compose build`
6. Consultez le [ChangeLog](../CHANGELOG.md) pour avoir les éventuelles informations de migration
7. `docker-compose stop && docker-compose up -d`
4. `git submodule update --init`
5. `git stash pop`
6. `docker-compose build`
7. Consultez le [ChangeLog](../CHANGELOG.md) pour avoir les éventuelles informations de migration
8. `docker-compose stop && docker-compose up -d`
### Comment exécuter des [commandes](manage.fr.md)
`docker-compose run --rm web node built/tools/mark-admin @example`
+5 -4
View File
@@ -83,10 +83,11 @@ docker-compose run --rm web yarn run init
1. `git stash`
2. `git checkout master`
3. `git pull`
4. `git stash pop`
5. `docker-compose build`
6. [ChangeLog](../CHANGELOG.md)でマイグレーション情報を確認する
7. `docker-compose stop && docker-compose up -d`
4. `git submodule update --init`
5. `git stash pop`
6. `docker-compose build`
7. [ChangeLog](../CHANGELOG.md)でマイグレーション情報を確認する
8. `docker-compose stop && docker-compose up -d`
### cliコマンドを実行する方法:
+5 -4
View File
@@ -83,10 +83,11 @@ docker-compose run --rm web yarn run init
1. `git stash`
2. `git checkout master`
3. `git pull`
4. `git stash pop`
5. `docker-compose build`
6. 检查 [更新日志](../CHANGELOG.md) 以获取升级迁移信息。
7. `docker-compose stop && docker-compose up -d`
4. `git submodule update --init`
5. `git stash pop`
6. `docker-compose build`
7. 检查 [更新日志](../CHANGELOG.md) 以获取升级迁移信息。
8. `docker-compose stop && docker-compose up -d`
### 如何执行 [控制台指令](manage.zh.md):
`docker-compose run --rm web node built/tools/mark-admin @example`
+28
View File
@@ -0,0 +1,28 @@
GitHub Actionsを使用してDocker Hubへpushする方法
================================================================
[/.github/workflows/docker.yml](/.github/workflows/docker.yml) に
GitHub ActionによりDocker Hubへpushするワークフローが記述されています。
オリジナルリポジトリでは、リリースされたタイミングで `latest`, `<リリース名>` それぞれのタグでDocker Hubにpushされます。
※ Docker Hub に`<ブランチ名>`のようなタグがあるかもしれませんが、こちらは自動push対象ではありません。
Fork先でこのワークフローを実行すると失敗します。
以下では、Fork先で自分のDocker Hubリポジトリにpushするようにする方法を記述します。
## 自分のDocker Hubリポジトリにpushするように設定する方法
1. Docker Hubでリポジトリを作成します。
2. ワークフローファイルの [images](https://github.com/misskey-dev/misskey/blob/53f3b779bf16abcda4f6e026c51384f3b8fbcc62/.github/workflows/docker.yml#L20) を作成したリポジトリに置き換えます。
3. GitHubにて [暗号化されたシークレット](https://docs.github.com/ja/actions/reference/encrypted-secrets#creating-encrypted-secrets-for-a-repository) を作成します。
作成が必要なのは `DOCKER_USERNAME``DOCKER_PASSWORD` で、それぞれDocker Hubのユーザーとパスワードになります。
## pushする方法
上記設定によりリリース時に自動的にDocker Hubにpushされるようになります。
具体的には、GitHubのリリース機能でリリースしたタイミングで `latest`, `<リリース名>` それぞれのタグでDocker Hubにpushされます。
また、GitHub上から手動でpushすることも出来ます。
それを行うには、Actions => Publish Docker image => Run workflow からbranchを選択してワークフローを実行します。
ただし、この場合作成されるタグは`<ブランチ名>`になります。
+7 -6
View File
@@ -24,7 +24,7 @@ Please install and setup these softwares:
#### Dependencies :package:
* **[Node.js](https://nodejs.org/en/)** (12.x, 14.x)
* **[PostgreSQL](https://www.postgresql.org/)** (>= 10)
* **[PostgreSQL](https://www.postgresql.org/)** (12.x / 13.x is preferred)
* **[Redis](https://redis.io/)**
##### Optional
@@ -131,11 +131,12 @@ You can check if the service is running with `systemctl status misskey`.
### How to update your Misskey server to the latest version
1. `git checkout master`
2. `git pull`
3. `yarn install`
4. `NODE_ENV=production yarn build`
5. `yarn migrate`
6. Restart your Misskey process to apply changes
7. Enjoy
3. `git submodule update --init`
4. `yarn install`
5. `NODE_ENV=production yarn build`
6. `yarn migrate`
7. Restart your Misskey process to apply changes
8. Enjoy
If you encounter any problems with updating, please try the following:
1. `yarn clean` or `yarn cleanall`
+4 -3
View File
@@ -126,9 +126,10 @@ Vous pouvez vérifier si le service a démarré en utilisant la commande `system
### Méthode de mise à jour vers la plus récente version de Misskey
1. `git checkout master`
2. `git pull`
3. `yarn install`
4. `NODE_ENV=production yarn build`
5. `yarn migrate`
3. `git submodule update --init`
4. `yarn install`
5. `NODE_ENV=production yarn build`
6. `yarn migrate`
----------------------------------------------------------------
+4 -3
View File
@@ -133,9 +133,10 @@ yarn run init
### Misskeyを最新バージョンにアップデートする方法:
1. `git checkout master`
2. `git pull`
3. `yarn install`
4. `NODE_ENV=production yarn build`
5. `yarn migrate`
3. `git submodule update --init`
4. `yarn install`
5. `NODE_ENV=production yarn build`
6. `yarn migrate`
なにか問題が発生した場合は、`yarn clean`または`yarn cleanall`すると直る場合があります。
+6 -5
View File
@@ -131,11 +131,12 @@ yarn run init
### 如何将您的 Misskey 服务器升级至最新版本
1. `git checkout master`
2. `git pull`
3. `yarn install`
4. `NODE_ENV=production yarn build`
5. `yarn migrate`
6. 重启您的 Misskey 进程来应用改变。
7. 尽情享受吧!
3. `git submodule update --init`
4. `yarn install`
5. `NODE_ENV=production yarn build`
6. `yarn migrate`
7. 重启您的 Misskey 进程来应用改变。
8. 尽情享受吧!
如果您在更新时遇到任何问题,请尝试以下操作:
1. `yarn clean` 或是 `yarn cleanall`
+10
View File
@@ -1,3 +1,13 @@
/*
import * as fs from 'fs';
if (fs.existsSync('./built')) {
import('./built/index.js').then(built => built());
} else {
console.log('Built code is not found. Probably an error occurred during a build or you just forgot to build.');
}
*/
const fs = require('fs');
if (fs.existsSync('./built')) {
+64 -36
View File
@@ -1,14 +1,14 @@
---
_lang_: "Deutsch"
headlineMisskey: "Ein durch Notizen verbundenes Netzwerk"
introMisskey: "Willkommen! Misskey ist eine dezentralisierte Open-Source Microblogging-Platform.\nVerfasse \"Notizen\" um mitzuteilen, was gerade passiert oder um Ereignisse mit Anderen zu teilen. 📡\nMit \"Reaktionen\" kannst du außerdem schnell deine Gefühle über Notizen anderer Benutzer zum Ausdruck bringen. 👍\nErforsche eine neue Welt! 🚀"
monthAndDay: "{day}/{month}"
introMisskey: "Willkommen! Misskey ist eine dezentralisierte Open-Source Microblogging-Platform.\nVerfasse Notizen um mitzuteilen, was gerade passiert oder um Ereignisse mit anderen zu teilen. 📡\nMit Reaktionen kannst du außerdem schnell deine Gefühle über Notizen anderer Benutzer zum Ausdruck bringen. 👍\nEine neue Welt wartet auf dich! 🚀"
monthAndDay: "{day}.{month}."
search: "Suchen"
notifications: "Benachrichtigungen"
username: "Benutzername"
password: "Passwort"
forgotPassword: "Passwort vergessen"
fetchingAsApObject: "Wird aus dem Fediverse angefragt..."
fetchingAsApObject: "Wird aus dem Fediverse angefragt"
ok: "OK"
gotIt: "Verstanden!"
cancel: "Abbrechen"
@@ -25,10 +25,10 @@ profile: "Profil"
timeline: "Chronik"
noAccountDescription: "Dieser Nutzer hat seine Profilbeschreibung noch nicht ausgefüllt."
login: "Anmelden"
loggingIn: "Du wirst angemeldet..."
loggingIn: "Du wirst angemeldet"
logout: "Abmelden"
signup: "Registrieren"
uploading: "Wird hochgeladen..."
uploading: "Wird hochgeladen"
save: "Speichern"
users: "Benutzer"
addUser: "Benutzer hinzufügen"
@@ -63,7 +63,7 @@ import: "Import"
export: "Export"
files: "Dateien"
download: "Herunterladen"
driveFileDeleteConfirm: "Möchtest du die Datei \"{name}\" wirklich löschen? Die zugehörige Notiz wird ebenso verschwinden."
driveFileDeleteConfirm: "Möchtest du die Datei {name} wirklich löschen? Die zugehörige Notiz wird ebenso verschwinden."
unfollowConfirm: "Möchtest du {name} nicht mehr folgen?"
exportRequested: "Du hast einen Export angefragt. Dies kann etwas Zeit in Anspruch nehmen. Sobald der Export abgeschlossen ist, wird er deiner Drive hinzugefügt."
importRequested: "Du hast einen Import angefragt. Dies kann etwas Zeit in Anspruch nehmen."
@@ -80,7 +80,7 @@ error: "Fehler"
somethingHappened: "Ein Fehler ist aufgetreten"
retry: "Wiederholen"
pageLoadError: "Laden der Seite fehlgeschlagen."
pageLoadErrorDescription: "Dieser Fehler wird meist durch Netzwerkfehler oder den Browser-Cache verursacht. Versuche bitte den Browser-Cache zu leeren und es nach kurzer Zeit noch einmal zu probieren."
pageLoadErrorDescription: "Dieser Fehler wird meist durch Netzwerkfehler oder den Browser-Cache verursacht. Bitte leere den Cache oder versuche es nach einiger Zeit erneut."
enterListName: "Name der Liste eingeben"
privacy: "Privatsphäre"
makeFollowManuallyApprove: "Follow-Anfragen benötigen Bestätigung"
@@ -105,7 +105,7 @@ sensitive: "NSFW"
add: "Hinzufügen"
reaction: "Reaktionen"
reactionSettingDescription: "Wähle die Reaktionen aus, die in der Reaktionsauswahl angezeigt werden sollen."
reactionSettingDescription2: "Ziehe zum Anordnen, Klicke zum Löschen, Drücke \"+\" zum Hinzufügen"
reactionSettingDescription2: "Ziehe zum Anordnen, klicke zum Löschen, drücke + zum Hinzufügen"
rememberNoteVisibility: "Notizsichtbarkeit merken"
attachCancel: "Anhang entfernen"
markAsSensitive: "Als NSFW markieren"
@@ -129,14 +129,14 @@ editWidgetsExit: "Fertig"
customEmojis: "Benutzerdefinierte Emojis"
emoji: "Emojis"
emojis: "Emojis"
emojiName: "Emojiname"
emojiName: "Emoji-Name"
emojiUrl: "Emoji-URL"
addEmoji: "Emoji hinzufügen"
settingGuide: "Empfohlene Einstellung"
cacheRemoteFiles: "Dateien von fremden Instanzen im Cache speichern"
cacheRemoteFilesDescription: "Ist diese Einstellung deaktiviert, so werden Dateien fremder Instanzen direkt von dort geladen. Hierdurch wird Speicherplatz auf dem Server gespart, aber durch fehlende Generierung von Vorschaubildern mehr Bandbreite verwendet."
flagAsBot: "Als Bot markieren"
flagAsBotDescription: "Aktiviere diese Option, falls dieses Benutzerkonto durch ein Programm gesteuert wird. Falls aktiviert, agiert es als Flag für andere Entwickler zur Verhinderung von endlosen Kettenreaktionen mit anderen Bots und lässt Misskey's interne Systeme dieses Benutzerkonto als Bot behandeln."
flagAsBotDescription: "Aktiviere diese Option, falls dieses Benutzerkonto durch ein Programm gesteuert wird. Falls aktiviert, agiert es als Flag für andere Entwickler zur Verhinderung von endlosen Kettenreaktionen mit anderen Bots und lässt Misskeys interne Systeme dieses Benutzerkonto als Bot behandeln."
flagAsCat: "Als Katze markieren"
flagAsCatDescription: "Aktiviere diese Option, um dieses Benutzerkonto als Katze zu markieren."
autoAcceptFollowed: "Follow-Anfragen von Benutzern, denen du folgst, automatisch akzeptieren"
@@ -196,7 +196,7 @@ noteDeleteConfirm: "Möchtest du diese Notiz wirklich löschen?"
pinLimitExceeded: "Es können nicht noch mehr Notizen angeheftet werden"
intro: "Misskey Installation abgeschlossen! Lass uns nun ein Administratorkonto erstellen."
done: "Fertig"
processing: "In Bearbeitung..."
processing: "In Bearbeitung"
preview: "Vorschau"
default: "Standard"
noCustomEmojis: "Keine benutzerdefinierten Emojis vorhanden"
@@ -227,8 +227,8 @@ announcements: "Ankündigungen"
imageUrl: "Bild-URL"
remove: "Löschen"
removed: "Erfolgreich gelöscht"
removeAreYouSure: "Möchtest du \"{x}\" wirklich entfernen?"
deleteAreYouSure: "Möchtest du \"{x}\" wirklich löschen?"
removeAreYouSure: "Möchtest du {x} wirklich entfernen?"
deleteAreYouSure: "Möchtest du {x} wirklich löschen?"
resetAreYouSure: "Wirklich zurücksetzen?"
saved: "Gespeichert"
messaging: "Chat"
@@ -240,7 +240,7 @@ uploadFromUrlDescription: "URL der hochzuladenden Datei"
uploadFromUrlRequested: "Upload angefordert"
uploadFromUrlMayTakeTime: "Es kann eine Weile dauern, bis das Hochladen abgeschlossen ist."
explore: "Erkunden"
games: "Misskey Spiele"
games: "Misskey-Spiele"
messageRead: "Gelesen"
noMoreHistory: "Kein weiterer Verlauf vorhanden"
startMessaging: "Neuen Chat erstellen"
@@ -256,14 +256,14 @@ birthday: "Geburtstag"
yearsOld: "{age} Jahre alt"
registeredDate: "Registrationsdatum"
location: "Ort"
theme: "Farbthemen"
themeForLightMode: "Farbthema, das im Hellmodus genutzt wird"
themeForDarkMode: "Farbthema, das im Dunkelmodus genutzt wird"
theme: "Farbschema"
themeForLightMode: "Helles Farbschema"
themeForDarkMode: "Dunkles Farbschema"
light: "Hell"
dark: "Dunkel"
lightThemes: "Helle Farbthemen"
darkThemes: "Dunkle Farbthemen"
syncDeviceDarkMode: "Dunkelmodus mit den Einstellungen deines Gerätes synchronisieren"
lightThemes: "Helle Farbschemata"
darkThemes: "Dunkle Farbschemata"
syncDeviceDarkMode: "Einstellung deines Geräts übernehmen"
drive: "Drive"
fileName: "Dateiname"
selectFile: "Datei auswählen"
@@ -293,7 +293,7 @@ whenServerDisconnected: "Bei Verbindungsverlust zum Server"
disconnectedFromServer: "Verbindung zum Server wurde getrennt"
reload: "Aktualisieren"
doNothing: "Ignorieren"
reloadConfirm: "Möchtest du die Chronik aktualisieren?"
reloadConfirm: "Seite neu laden?"
watch: "Beobachten"
unwatch: "Nicht mehr beobachten"
accept: "Akzeptieren"
@@ -302,10 +302,10 @@ normal: "Normal"
instanceName: "Name der Instanz"
instanceDescription: "Beschreibung der Instanz"
maintainerName: "Betreiber"
maintainerEmail: "Betreiber-Email"
maintainerEmail: "Betreiber-E-Mail"
tosUrl: "URL der Nutzungsbedingungen"
thisYear: "Dieses Jahr"
thisMonth: "Dieser Monat"
thisYear: "Jahr"
thisMonth: "Monat"
today: "Heute"
dayX: "{day}"
monthX: "{month}"
@@ -522,13 +522,15 @@ scratchpadDescription: "Die Testumgebung bietet eine Umgebung für AiScript-Expe
output: "Ausgabe"
script: "Skript"
disablePagesScript: "AiScript auf Seiten deaktivieren"
updateRemoteUser: "Informationen über Benutzer fremder Instanzen aktualisieren"
updateRemoteUser: "Benutzerinformationen aktualisieren"
deleteAllFiles: "Alle Dateien löschen"
deleteAllFilesConfirm: "Möchtest du wirklich alle Dateien löschen?"
removeAllFollowing: "Allen gefolgten Benutzern entfolgen"
removeAllFollowingDescription: "Dies entfolgt allen Benutzerkonten von {host}. Bitte führe dies durch, falls diese Instanz z.B. nicht mehr existiert."
userSuspended: "Dieser Benutzer wurde gesperrt."
userSilenced: "Dieser Benutzer wurde instanzweit stummgeschaltet."
yourAccountSuspendedTitle: "Dieses Benutzerkonto ist gesperrt"
yourAccountSuspendedDescription: "Dieses Benutzerkonto wurde gesperrt, da es gegen die Nutzungsbedingungen dieses Servers verstoßen hat. Trete mit dem Betreiber in Kontakt, falls du weitere Details erfahren möchtest. Bitte erstelle kein neues Benutzerkonto."
menu: "Menü"
divider: "Trenner"
addItem: "Element hinzufügen"
@@ -715,7 +717,7 @@ inChannelSearch: "In Kanal suchen"
useReactionPickerForContextMenu: "Reaktionsauswahl durch Rechtsklick öffnen"
typingUsers: "{users} ist/sind am schreiben..."
jumpToSpecifiedDate: "Zu bestimmtem Datum springen"
showingPastTimeline: "Momentan wird eine alte Chronik angezeigt"
showingPastTimeline: "Es wird eine alte Chronik angezeigt"
clear: "Zurückkehren"
markAllAsRead: "Alle als gelesen markieren"
goBack: "Zurück"
@@ -748,7 +750,7 @@ switch: "Wechseln"
noMaintainerInformationWarning: "Betreiberinformationen sind nicht konfiguriert."
noBotProtectionWarning: "Bot-Schutz ist nicht konfiguriert."
configure: "Konfigurieren"
postToGallery: "Beitrag zu Galerie hinzufügen"
postToGallery: "Neuen Galerie-Beitrag erstellen"
gallery: "Galerie"
recentPosts: "Neue Beiträge"
popularPosts: "Beliebte Beiträge"
@@ -771,6 +773,27 @@ received: "Erhalten"
searchResult: "Suchergebnisse"
hashtags: "Hashtags"
troubleshooting: "Problembehandlung"
useBlurEffect: "Weichzeichnungseffekt in der Benutzeroberfläche verwenden"
learnMore: "Mehr erfahren"
misskeyUpdated: "Misskey wurde aktualisiert!"
whatIsNew: "Änderungen anzeigen"
translate: "Übersetzen"
translatedFrom: "Aus {x} übersetzt"
accountDeletionInProgress: "Löschung des Benutzerkontos momentan in Bearbeitung"
usernameInfo: "Ein Name, durch den dein Benutzerkonto auf diesem Server identifiziert werden kann. Du kannst das Alphabet (a~z, A~Z), Ziffern (0~9) oder Unterstriche (_) verwenden. Benutzernamen können später nicht geändert werden."
aiChanMode: "Ai Modus"
keepCw: "Inhaltswarnung beibehalten"
pubSub: "Pub/Sub Benutzerkonten"
lastCommunication: "Letzte Kommunikation"
resolved: "Gelöst"
unresolved: "Ungelöst"
_accountDelete:
accountDelete: "Benutzerkonto löschen"
mayTakeTime: "Da die Löschung eines Benutzerkontos ein aufwendiger Prozess ist, kann dessen Dauer davon abhängen, wie viel Inhalt in diesem erstellt wurde oder wie viele Dateien hochgeladen wurden."
sendEmail: "Sobald die Löschung abgeschlossen ist, wird an die mit ihm verknüpfte Email-Adresse eine Benachrichtigung versendet."
requestAccountDelete: "Löschung des Benutzerkontos anfordern"
started: "Löschung wurde eingeleitet."
inProgress: "Löschung in Bearbeitung"
_docs:
continueReading: "Mehr lesen"
features: "Funktionen"
@@ -792,7 +815,7 @@ _gallery:
unlike: "\"Gefällt mir\" entfernen"
_email:
_follow:
title: "ist dir gefolgt"
title: "Du hast einen neuen Follower"
_receiveFollowRequest:
title: "Du hast eine Follow-Anfrage erhalten"
_plugin:
@@ -853,19 +876,19 @@ _mfm:
flip: "Spiegelung"
flipDescription: "Inhalt horizontal oder vertikal gespiegelt anzeigen."
jelly: "Animation (Dehnen)"
jellyDescription: "Verleiht eine sich dehnende Animation."
jellyDescription: "Verleiht dem Inhalt eine sich dehnende Animation."
tada: "Animation (Tada)"
tadaDescription: "Verleiht eine Animation mit \"Tada!\"-Gefühl"
jump: "Animation (Sprung)"
jumpDescription: "Verleiht eine springende Animation."
jumpDescription: "Verleiht dem Inhalt eine springende Animation."
bounce: "Animation (Federn)"
bounceDescription: "Verleiht eine federnde Animation."
bounceDescription: "Verleiht dem Inhalt eine federnde Animation."
shake: "Animation (Zittern)"
shakeDescription: "Verleiht eine zitternde Animation."
shakeDescription: "Verleiht dem Inhalt eine zitternde Animation."
twitch: "Animation (Zucken)"
twitchDescription: "Verleiht eine sehr stark zuckende Animation."
twitchDescription: "Verleiht dem Inhalt eine sehr stark zuckende Animation."
spin: "Animation (Rotieren)"
spinDescription: "Verleiht eine rotierende Animation."
spinDescription: "Verleiht dem Inhalt eine rotierende Animation."
x2: "Groß"
x2Description: "Inhalte größer anzeigen."
x3: "Sehr groß"
@@ -1046,7 +1069,7 @@ _time:
_tutorial:
title: "Wie du Misskey verwendest"
step1_1: "Willkommen!"
step1_2: "Diese Seite ist die \"Chronik\". Sie zeigt dir deine geschrieben \"Notizen\" sowie die aller Benutzer, denen du \"folgst\", in chronologischer Reihenfolge."
step1_2: "Diese Seite ist die Chronik. Sie zeigt dir deine geschrieben Notizen sowie die aller Benutzer, denen du folgst, in chronologischer Reihenfolge."
step1_3: "Deine Chronik sollte momentan leer sein, da du bis jetzt noch keine Notizen geschrieben hast und auch noch keinen Benutzern folgst."
step2_1: "Lass uns zuerst dein Profil vervollständigen, bevor du Notizen schreibst oder jemandem folgst."
step2_2: "Informationen darüber, was für eine Person du bist, macht es anderen leichter zu wissen, ob sie deine Notizen sehen wollen und ob sie dir folgen möchten."
@@ -1055,7 +1078,7 @@ _tutorial:
step3_3: "Fülle das Fenster aus und drücke auf den Knopf oben rechts zum Senden."
step3_4: "Fällt dir nichts ein, das du schreiben möchtest? Versuch's mit \"Hallo Misskey!\""
step4_1: "Fertig mit dem Senden deiner ersten Notiz?"
step4_2: "Falls deine Notiz nun auf deiner Chronik auftaucht, hast du alles richtig gemacht."
step4_2: "Falls deine Notiz nun in deiner Chronik auftaucht, hast du alles richtig gemacht."
step5_1: "Lass uns nun deiner Chronik etwas mehr Leben einhauchen, indem du einigen anderen Benutzern folgst."
step5_2: "{featured} zeigt dir beliebte Notizen dieser Instanz. In {explore} kannst du beliebte Benutzer finden. Schau dort, ob du Benutzer findest, die dich interessieren."
step5_3: "Klicke zum Anzeigen des Profils eines Benutzers auf dessen Profilbild und dann auf den \"Folgen\"-Knopf, um diesem zu folgen."
@@ -1104,6 +1127,10 @@ _permissions:
"write:user-groups": "Benutzergruppen bearbeiten oder löschen"
"read:channels": "Kanäle lesen"
"write:channels": "Kanäle bedienen"
"read:gallery": "Beiträge deiner Galerie lesen"
"write:gallery": "Deine Galerie bearbeiten"
"read:gallery-likes": "Liste deiner mit \"Gefällt mir\" markierten Galerie-Beiträge lesen"
"write:gallery-likes": "Liste deiner mit \"Gefällt mir\" markierten Galerie-Beiträge bearbeiten"
_auth:
shareAccess: "Möchtest du \"{name}\" authorisieren, auf dieses Benuzerkonto zugreifen zu können?"
shareAccessAsk: "Bist du dir sicher, dass du diese Anwendung authorisieren möchtest, auf dein Benutzerkonto zugreifen zu können?"
@@ -1144,6 +1171,7 @@ _widgets:
jobQueue: "Job-Warteschlange"
serverMetric: "Servermetriken"
aiscript: "AiScript-Konsole"
aichan: "Ai"
_cw:
hide: "Verbergen"
show: "Inhalt anzeigen"
+74 -44
View File
@@ -1,7 +1,7 @@
---
_lang_: "English"
headlineMisskey: "A network connected by notes"
introMisskey: "Welcome! Misskey is an open source, decentralized microblogging service.\nCreate \"notes\" to share what is happening now, or to share it with everyone around you. 📡\nWith \"reactions\", you can also quickly express your feelings about everyone's notes. 👍\nLet's explore a new world! 🚀"
introMisskey: "Welcome! Misskey is an open source, decentralized microblogging service.\nCreate \"notes\" to share what your thoughts with everyone around you. 📡\nWith \"reactions\", you can also quickly express your feelings about everyone's notes. 👍\nLet's explore a new world! 🚀"
monthAndDay: "{month}/{day}"
search: "Search"
notifications: "Notifications"
@@ -92,7 +92,7 @@ unfollow: "Unfollow"
followRequestPending: "Pending follow request"
enterEmoji: "Enter an emoji"
renote: "Renote"
unrenote: "Take back Renote"
unrenote: "Take back renote"
renoted: "Renoted."
cantRenote: "This post can't be renoted."
cantReRenote: "A renote can't be renoted."
@@ -136,7 +136,7 @@ settingGuide: "Recommended settings"
cacheRemoteFiles: "Cache remote files"
cacheRemoteFilesDescription: "When this setting is disabled, remote files are loaded directly from the remote instance. Disabling this will decrease storage usage, but increase traffic, as thumbnails will not be generated."
flagAsBot: "Mark this account as as bot"
flagAsBotDescription: "Enable this option if this account is controlled by a program. If enabled, it will act as flag for other developers to prevent endless interaction chains with other bots and adjust Misskey's internal systems to treat this account as a bot."
flagAsBotDescription: "Enable this option if this account is controlled by a program. If enabled, it will act as a flag for other developers to prevent endless interaction chains with other bots and adjust Misskey's internal systems to treat this account as a bot."
flagAsCat: "Mark this account as a cat"
flagAsCatDescription: "Enable this option to mark this account as a cat."
autoAcceptFollowed: "Automatically approve follow requests from users you're following"
@@ -199,7 +199,7 @@ done: "Done"
processing: "Processing..."
preview: "Preview"
default: "Default"
noCustomEmojis: "There are no emojis"
noCustomEmojis: "There are no emoji"
noJobs: "There are no jobs"
federating: "Federating"
blocked: "Blocked"
@@ -213,7 +213,7 @@ instanceFollowers: "Followers of instance"
instanceUsers: "Users of this instance"
changePassword: "Change password"
security: "Security"
retypedNotMatch: "The inputs does not match."
retypedNotMatch: "The inputs do not match."
currentPassword: "Current password"
newPassword: "New password"
newPasswordRetype: "Retype new password"
@@ -249,7 +249,7 @@ agreeTo: "I agree to {0}"
tos: "Terms of Service"
start: "Begin"
home: "Home"
remoteUserCaution: "As this user is from a renote instance, the shown information may be incomplete."
remoteUserCaution: "As this user is from a remote instance, the shown information may be incomplete."
activity: "Activity"
images: "Images"
birthday: "Birthday"
@@ -429,7 +429,7 @@ invitationCode: "Invitation code"
checking: "Checking..."
available: "Available"
unavailable: "Not available"
usernameInvalidFormat: "You can use upper- and lowercase letters, numbers as well as underscores."
usernameInvalidFormat: "You can use upper- and lowercase letters, numbers, and underscores."
tooShort: "Too short"
tooLong: "Too long"
weakPassword: "Weak password"
@@ -445,7 +445,7 @@ language: "Language"
uiLanguage: "User interface language"
groupInvited: "You've been invited to a group"
aboutX: "About {x}"
useOsNativeEmojis: "Use OS native Emojis"
useOsNativeEmojis: "Use OS native Emoji"
youHaveNoGroups: "You have no groups"
joinOrCreateGroup: "Get invited to a group or create your own."
noHistory: "No history available"
@@ -482,7 +482,7 @@ objectStorageBaseUrlDesc: "URL used as reference. Specify the URL of your CDN or
objectStorageBucket: "Bucket"
objectStorageBucketDesc: "Please specify the bucket name used at your provider."
objectStoragePrefix: "Prefix"
objectStoragePrefixDesc: "Files will stored under directories with this prefix."
objectStoragePrefixDesc: "Files will be stored under directories with this prefix."
objectStorageEndpoint: "Endpoint"
objectStorageEndpointDesc: "Leave this empty if you are using AWS S3, otherwise specify the endpoint as '<host>' or '<host>:<port>', depending on the service you are using."
objectStorageRegion: "Region"
@@ -529,6 +529,8 @@ removeAllFollowing: "Unfollow all followed users"
removeAllFollowingDescription: "Executing this unfollows all accounts from {host}. Please run this if the instance e.g. no longer exists."
userSuspended: "This user has been suspended."
userSilenced: "This user has been silenced."
yourAccountSuspendedTitle: "This account is suspended"
yourAccountSuspendedDescription: "This account has been suspended due to breaking the server's terms of services or similar. Contact the administrator if you would like to know a more detailed reason. Please do not create a new account."
menu: "Menu"
divider: "Divider"
addItem: "Add Item"
@@ -606,7 +608,7 @@ useGlobalSettingDesc: "If turned on, your account's notification settings will b
other: "Other"
regenerateLoginToken: "Regenerate login token"
regenerateLoginTokenDescription: "Regenerate the token used internally during login. Normally this action is not necessary. If regenerated, all devices will be logged out."
setMultipleBySeparatingWithSpace: "You can set multiple by separating them with spaces."
setMultipleBySeparatingWithSpace: "Separate multiple entries with spaces."
fileIdOrUrl: "File-ID or URL"
chatOpenBehavior: "Behavior of the chat window when opened"
behavior: "Behavior"
@@ -649,7 +651,7 @@ pollVotesCount: "Number of sent poll votes"
pollVotedCount: "Number of received poll votes"
yes: "Yes"
no: "No"
driveFilesCount: "Number of drive files"
driveFilesCount: "Number of Drive files"
driveUsage: "Drive space usage"
noCrawle: "Reject crawler indexing"
noCrawleDescription: "Ask search engines to not index your profile page, notes, Pages, etc."
@@ -657,7 +659,7 @@ lockedAccountInfo: "Unless you set your note visiblity to \"Followers only\", yo
alwaysMarkSensitive: "Mark as NSFW by default"
loadRawImages: "Load original images instead of showing thumbnails"
disableShowingAnimatedImages: "Don't play animated images"
verificationEmailSent: "A verification email has been sent. Please access the included link to complete verification."
verificationEmailSent: "A verification email has been sent. Please follow the included link to complete verification."
notSet: "Not set"
emailVerified: "Email has been verified"
noteFavoritesCount: "Number of favorite notes"
@@ -688,7 +690,7 @@ sendErrorReportsDescription: "When turned on, detailed error information will be
myTheme: "My theme"
backgroundColor: "Background color"
accentColor: "Accent color"
textColor: "Textfarbe"
textColor: "Text color"
saveAs: "Save as..."
advanced: "Advanced"
value: "Value"
@@ -724,7 +726,7 @@ fullView: "Full view"
quitFullView: "Exit full view"
addDescription: "Add description"
userPagePinTip: "You can display notes here by selecting \"Pin to profile\" from the menu of individual notes."
notSpecifiedMentionWarning: "This note contains mentions of users not included as recipient"
notSpecifiedMentionWarning: "This note contains mentions of users not included as recipients"
info: "About"
userInfo: "User information"
unknown: "Unknown"
@@ -748,7 +750,7 @@ switch: "Switch"
noMaintainerInformationWarning: "Maintainer information is not configured."
noBotProtectionWarning: "Bot protection is not configured."
configure: "Configure"
postToGallery: "Post to Gallery"
postToGallery: "Create new gallery post"
gallery: "Gallery"
recentPosts: "Recent posts"
popularPosts: "Popular posts"
@@ -771,6 +773,27 @@ received: "Received"
searchResult: "Search results"
hashtags: "Hashtags"
troubleshooting: "Troubleshooting"
useBlurEffect: "Use blur effects in the UI"
learnMore: "Learn more"
misskeyUpdated: "Misskey has been updated!"
whatIsNew: "Show changes"
translate: "Translate"
translatedFrom: "Translated from {x}"
accountDeletionInProgress: "Account deletion is currently in progress"
usernameInfo: "A name that identifies your account from others on this server. You can use the alphabet (a~z, A~Z), digits (0~9) or underscores (_). Usernames cannot be changed later."
aiChanMode: "Ai Mode"
keepCw: "Keep Content Warning"
pubSub: "Pub/Sub Accounts"
lastCommunication: "Last communication"
resolved: "Resolved"
unresolved: "Unresolved"
_accountDelete:
accountDelete: "Delete Account"
mayTakeTime: "As account deletion is a resource-heavy process, it may take some time to complete depending on how much content you have created and how many files you have uploaded."
sendEmail: "Once account deletion has been completed, an email will be sent to the email address registered to this account."
requestAccountDelete: "Request account deletion"
started: "Deletion has been started."
inProgress: "Deletion is currently in progress"
_docs:
continueReading: "Read more"
features: "Features"
@@ -789,7 +812,7 @@ _gallery:
my: "My Gallery"
liked: "Liked Posts"
like: "Like"
unlike: "Undo like"
unlike: "Remove like"
_email:
_follow:
title: "You've got a new follower"
@@ -829,11 +852,11 @@ _mfm:
url: "URL"
urlDescription: "URLs can be displayed."
link: "Link"
linkDescription: "Specific parts of text can be displayed as an URL."
linkDescription: "Specific parts of text can be displayed as a URL."
bold: "Bold"
boldDescription: "Highlights letters by making them thicker."
small: "Small"
smallDescription: "Displays contents small and thin."
smallDescription: "Displays content small and thin."
center: "Center"
centerDescription: "Displays content centered."
inlineCode: "Code (In-line)"
@@ -845,7 +868,7 @@ _mfm:
blockMath: "Math (Block)"
blockMathDescription: "Display multi-line Math formulas (KaTeX) in a block"
quote: "Quote"
quoteDescription: "Displays content as quote."
quoteDescription: "Displays content as a quote."
emoji: "Custom Emoji"
emojiDescription: "By surrounding a custom emoji name with colons, custom emoji can be displayed."
search: "Search"
@@ -875,9 +898,11 @@ _mfm:
blur: "Blur"
blurDescription: "Content can be blurred via this effect. It will be displayed clearly when hovered over."
font: "Font"
fontDescription: "Sets the font to display contents in."
fontDescription: "Sets the font to display content in."
rainbow: "Rainbow"
rainbowDescription: "Makes the content appear in rainbow colors."
sparkle: "Sparkle"
sparkleDescription: "Gives content a sparkling particle effect."
_reversi:
reversi: "Reversi"
gameSettings: "Game settings"
@@ -937,8 +962,8 @@ _menuDisplay:
_wordMute:
muteWords: "Muted words"
muteWordsDescription: "Separate with spaces for an AND condition or with line breaks for an OR condition."
muteWordsDescription2: "Surround keywords by slashes to use regular expressions."
softDescription: "Hides notes fulfilling the set conditions from the timeline."
muteWordsDescription2: "Surround keywords with slashes to use regular expressions."
softDescription: "Hide notes that fulfil the set conditions from the timeline."
hardDescription: "Prevents notes fulfilling the set conditions from being added to the timeline. In addition, these notes will not be added to the timeline even if the conditions are changed."
soft: "Soft"
hard: "Hard"
@@ -996,7 +1021,7 @@ _theme:
divider: "Divider"
scrollbarHandle: "Scrollbar handle"
scrollbarHandleHover: "Scrollbar handle (Hover)"
dateLabelFg: "Text of date labels"
dateLabelFg: "Date label text"
infoBg: "Information background"
infoFg: "Information text"
infoWarnBg: "Warning background"
@@ -1069,19 +1094,19 @@ _tutorial:
_2fa:
alreadyRegistered: "You have already registered a 2-factor authentication device."
registerDevice: "Register a new device"
registerKey: "Register a new Security Key"
registerKey: "Register a security key"
step1: "First, install an authentication app (such as {a} or {b}) on your device."
step2: "Then, scan the QR code displayed on this screen."
step3: "Enter the token provided by your app to finish setup."
step4: "From now, any future login attempts will ask for such a login token."
securityKeyInfo: "Besides fingerprint or PIN authentication, you can also setup authentication via hardware security keys that support FIDO2 to further secure your login process."
step4: "From now on, any future login attempts will ask for such a login token."
securityKeyInfo: "Besides fingerprint or PIN authentication, you can also setup authentication via hardware security keys that support FIDO2 to further secure your account."
_permissions:
"read:account": "View your account information"
"write:account": "Edit your account information"
"read:blocks": "View the list of people you blocked"
"read:blocks": "View your list of blocked users"
"write:blocks": "Edit your list of blocked users"
"read:drive": "Access your drive files and folders"
"write:drive": "Edit or delete your drive files and folders"
"read:drive": "Access your Drive files and folders"
"write:drive": "Edit or delete your Drive files and folders"
"read:favorites": "View your list of favorites"
"write:favorites": "Edit your list of favorites"
"read:following": "View information on who you follow"
@@ -1104,6 +1129,10 @@ _permissions:
"write:user-groups": "Edit or delete your user groups"
"read:channels": "Read your channels"
"write:channels": "Modify your channels"
"read:gallery": "View your gallery"
"write:gallery": "Edit your gallery"
"read:gallery-likes": "View list of liked gallery posts"
"write:gallery-likes": "Edit list of liked gallery posts"
_auth:
shareAccess: "Would you like to authorize \"{name}\" to access this account?"
shareAccessAsk: "Are you sure you want to authorize this application to access your account?"
@@ -1144,6 +1173,7 @@ _widgets:
jobQueue: "Job Queue"
serverMetric: "Server metrics"
aiscript: "AiScript console"
aichan: "Ai"
_cw:
hide: "Hide"
show: "Show content"
@@ -1305,23 +1335,23 @@ _rooms:
doll-ai: "Ai doll"
banknote: "Pile of money"
_pages:
newPage: "Create a page"
editPage: "Edit this page"
newPage: "Create a new Page"
editPage: "Edit this Page"
readPage: "Source view activated"
created: "Page successfully created"
updated: "Page successfully edited"
deleted: "Page successfully deleted"
pageSetting: "Page settings"
nameAlreadyExists: "The specified page URL already exists"
invalidNameTitle: "The specified page URL is invalid"
invalidNameText: "Make sure the page title is not empty"
editThisPage: "Edit this page"
nameAlreadyExists: "The specified Page URL already exists"
invalidNameTitle: "The specified Page URL is invalid"
invalidNameText: "Make sure the Page title is not empty"
editThisPage: "Edit this Page"
viewSource: "View source"
viewPage: "View your pages"
viewPage: "View your Pages"
like: "Like"
unlike: "Undo like"
my: "My pages"
liked: "Liked pages"
unlike: "Remove like"
my: "My Pages"
liked: "Liked Pages"
featured: "Featured"
inspector: "Inspector"
contents: "Contents"
@@ -1331,10 +1361,10 @@ _pages:
url: "Page URL"
summary: "Page summary"
alignCenter: "Center elements"
hideTitleWhenPinned: "Hide page title when pinned to profile"
hideTitleWhenPinned: "Hide Page title when pinned to profile"
font: "Font"
fontSerif: "Serif"
fontSansSerif: "Sans serif"
fontSansSerif: "Sans Serif"
eyeCatchingImageSet: "Set thumbnail"
eyeCatchingImageRemove: "Delete thumbnail"
chooseBlock: "Add a block"
@@ -1549,7 +1579,7 @@ _pages:
seedRandomPick: "Randomly choose from list (with seed)"
_seedRandomPick:
arg1: "Seed"
arg2: "Liste"
arg2: "List"
DRPWPM: "Randomly choose from weighted list (Changes once a day for each user)"
_DRPWPM:
arg1: "Text list"
@@ -1629,8 +1659,8 @@ _deck:
columnMargin: "Margin between columns"
columnHeaderHeight: "Column header height"
addColumn: "Add column"
swapLeft: "Swap to left"
swapRight: "Swap to right"
swapLeft: "Swap left"
swapRight: "Swap right"
swapUp: "Swap with above"
swapDown: "Swap with below"
stackLeft: "Stack on left column"
+507 -153
View File
File diff suppressed because it is too large Load Diff
+39 -9
View File
@@ -91,11 +91,11 @@ followRequests: "Demandes dabonnement"
unfollow: "Se désabonner"
followRequestPending: "Demande d'abonnement en attente de confirmation"
enterEmoji: "Insérer un émoji"
renote: "Partager"
unrenote: "Annuler le partage"
renoted: "Republié !"
cantRenote: "Ce message ne peut pas être republié."
cantReRenote: "Impossible de repartager un partage."
renote: "Renoter"
unrenote: "Annuler la Renote"
renoted: "Renoté !"
cantRenote: "Ce message ne peut pas être renoté."
cantReRenote: "Impossible de renoter une Renote."
quote: "Citer"
pinnedNote: "Note épinglée"
pinned: "Épingler sur le profil"
@@ -429,7 +429,7 @@ invitationCode: "Code dinvitation"
checking: "Vérification en cours..."
available: "Disponible"
unavailable: "Non disponible"
usernameInvalidFormat: "Le nom d'utilisateur peut contenir uniquement des lettres, des chiffres et des _"
usernameInvalidFormat: "Le nom d'utilisateur peut contenir uniquement des lettres (minuscules et/ou majuscules), des chiffres et des _"
tooShort: "Trop court"
tooLong: "Trop long"
weakPassword: "Mot de passe faible"
@@ -529,6 +529,7 @@ removeAllFollowing: "Retenir tous les abonnements"
removeAllFollowingDescription: "Se désabonner de tous les comptes de {host}. Veuillez lancer cette action uniquement si linstance nexiste plus."
userSuspended: "Cet·te utilisateur·rice a été suspendu·e."
userSilenced: "Cette utilisateur·trice a été mis·e en sourdine."
yourAccountSuspendedTitle: "Ce compte est suspendu"
menu: "Menu"
divider: "Séparateur"
addItem: "Ajouter un élément"
@@ -638,9 +639,9 @@ manageAccessTokens: "Gérer les jetons d'accès"
accountInfo: " Informations du compte "
notesCount: "Nombre de notes"
repliesCount: "Nombre de réponses envoyées"
renotesCount: "Nombre de notes repartagées"
renotesCount: "Nombre de notes que vous avez renotées"
repliedCount: "Nombre de réponses reçues"
renotedCount: "Nombre de Renotes"
renotedCount: "Nombre de vos notes renotées"
followingCount: "Nombre de comptes suivis"
followersCount: "Nombre d'abonnés"
sentReactionsCount: "Nombre de réactions envoyées"
@@ -767,14 +768,38 @@ customCssWarn: "Utilisez cette fonctionnalité uniquement si vous savez exacteme
global: "Global"
squareAvatars: "Avatars carrés"
sent: "Envoyer"
received: "Reçu"
searchResult: "Résultats de la recherche"
hashtags: "Hashtags"
troubleshooting: "Résolution de problèmes"
useBlurEffect: "Utiliser des effets de flou dans l'interface"
learnMore: "Plus d'informations"
misskeyUpdated: "Misskey a été mis à jour !"
whatIsNew: "Voir les derniers changements"
translate: "Traduire"
translatedFrom: "Traduit depuis {x}"
accountDeletionInProgress: "La suppression de votre compte est en cours"
usernameInfo: "C'est un nom qui identifie votre compte sur l'instance de manière unique. Vous pouvez utiliser des lettres de l'alphabet (minuscules et majuscules), des chiffres (de 0 à 9), ou bien le tiret « _ ». Vous ne pourrez pas modifier votre nom d'utilisateur·rice par la suite."
aiChanMode: "Mode Ai"
keepCw: "Garder le CW"
pubSub: "Comptes Pub/Sub"
lastCommunication: "Dernière communication"
resolved: "Résolu"
unresolved: "En attente"
_accountDelete:
accountDelete: "Supprimer le compte"
mayTakeTime: "La suppression de compte nécessitant beaucoup de ressources, l'exécution du processus peut prendre du temps, en fonction de la quantité de contenus que vous avez créés et du nombre de fichiers que vous avez téléversés."
sendEmail: "Une fois la suppression de votre compte effectuée, un courriel sera envoyé à l'adresse que vous aviez enregistrée."
requestAccountDelete: "Demander la suppression de votre compte"
started: "La procédure de suppression a commencé."
inProgress: "Suppression en cours"
_docs:
continueReading: "Lire plus"
features: "Fonctionnalités"
generalTopics: "Sujets généraux"
advancedTopics: "Sujets avancés"
admin: "Gestion"
translateWarn: "Ceci est une traduction dont le contenu peut différer du texte original."
_ad:
back: "Retour"
reduceFrequencyOfThisAd: "Voir cette publicité moins souvent"
@@ -988,7 +1013,7 @@ _theme:
hashtag: "Hashtags"
mention: "Mentionner"
mentionMe: "Mentions (Moi)"
renote: "Partager"
renote: "Renoter"
modalBg: "Modal d'arrière-plan"
divider: "Séparateur"
scrollbarHandle: "Poignée de la barre de navigation"
@@ -1101,6 +1126,10 @@ _permissions:
"write:user-groups": "Éditer les groupes des utilisateur·rice·s"
"read:channels": "Lire les canaux"
"write:channels": "Gérer les canaux"
"read:gallery": "Voir la galerie"
"write:gallery": "Éditer la galerie"
"read:gallery-likes": "Voir les mentions « J'aime » dans la galerie"
"write:gallery-likes": "Gérer les mentions « J'aime » dans la galerie"
_auth:
shareAccess: "Autoriser \"{name}\" à accéder à votre compte ?"
shareAccessAsk: "Voulez-vous vraiment autoriser cette application à accéder à votre compte?"
@@ -1141,6 +1170,7 @@ _widgets:
jobQueue: "File dattente"
serverMetric: "Statistiques du serveur"
aiscript: "Console AiScript"
aichan: "Ai"
_cw:
hide: "Masquer"
show: "Afficher plus …"
+27
View File
@@ -767,9 +767,33 @@ customCssWarn: "Pengaturan ini seharusnya digunakan jika kamu tahu cara kerjanya
global: "Global"
squareAvatars: "Tampilkan avatar sebagai persegi"
sent: "Kirim"
received: "Diterima"
searchResult: "Hasil Penelusuran"
hashtags: "Tagar"
troubleshooting: "Penyelesaian Masalah"
useBlurEffect: "Gunakan efek blur pada antarmuka"
learnMore: "Pelajari lebih lanjut"
misskeyUpdated: "Misskey telah dimutakhirkan!"
whatIsNew: "Lihat perubahan pemutakhiran"
translate: "Terjemahkan"
translatedFrom: "Terjemahkan dari {x}"
accountDeletionInProgress: "Penghapusan akun sedang dalam proses"
usernameInfo: "Nama yang mengidentifikasikan akun kamu dari yang lain pada server ini. Kamu dapat menggunakan alfabet (a~z, A~Z), digit (0~9) atau garis bawah (_). Username tidak dapat diubah setelahnya."
keepCw: "Biarkan Peringatan Konten"
_accountDelete:
accountDelete: "Hapus akun"
mayTakeTime: "Karena penghapusan akun merupakan proses yang berat dan intensif, kemungkinan dapat membutuhkan waktu untuk menyelesaikan tergantung daripada berapa banyak konten yang kamu buat dan berapa banyak berkas yang telah kamu unggah."
sendEmail: "Setelah penghapusan akun selesai, pemberitahuan akan dikirimkan ke alamat surel yang terdaftarkan pada akun ini."
requestAccountDelete: "Minta penghapusan akun"
started: "Penghapusan telah dimulai"
inProgress: "Penghapusan sedang dalam proses"
_docs:
continueReading: "Baca lebih lanjut"
features: "Fitur"
generalTopics: "Topik umum"
advancedTopics: "Topik tingkat lanjut"
admin: "Manajemen"
translateWarn: "Ini merupakan dokumen terjemahan. Konten di dalamnya kemungkinan dapat berbeda dari yang aslinya."
_ad:
back: "Kembali"
reduceFrequencyOfThisAd: "Tampilkan iklan ini lebih sedikit"
@@ -868,6 +892,8 @@ _mfm:
blurDescription: "Konten dapat diburamkan dengan efek ini. Konten dapat ditampilkan dengan jelas dengan melayangkan kursor tetikus di atasnya."
font: "Font"
fontDescription: "Setel font yang ditampilkan untuk konten."
rainbow: "Pelangi"
rainbowDescription: "Membuat konten muncul dalam warna pelangi."
_reversi:
reversi: "Reversi"
gameSettings: "Pengaturan permainan"
@@ -1134,6 +1160,7 @@ _widgets:
jobQueue: "Antrian kerja"
serverMetric: "Statistik server"
aiscript: "Konsol AiScript"
aichan: "Ai"
_cw:
hide: "Sembunyikan"
show: "Lihat konten"
+30
View File
@@ -529,6 +529,8 @@ removeAllFollowing: "フォローを全解除"
removeAllFollowingDescription: "{host}からのフォローをすべて解除します。そのインスタンスがもう存在しなくなった場合などに実行してください。"
userSuspended: "このユーザーは凍結されています。"
userSilenced: "このユーザーはサイレンスされています。"
yourAccountSuspendedTitle: "アカウントが凍結されています"
yourAccountSuspendedDescription: "このアカウントは、サーバーの利用規約に違反したなどの理由により、凍結されています。詳細については管理者までお問い合わせください。新しいアカウントを作らないでください。"
menu: "メニュー"
divider: "分割線"
addItem: "項目を追加"
@@ -772,6 +774,27 @@ searchResult: "検索結果"
hashtags: "ハッシュタグ"
troubleshooting: "トラブルシューティング"
useBlurEffect: "UIにぼかし効果を使用"
learnMore: "詳しく"
misskeyUpdated: "Misskeyが更新されました!"
whatIsNew: "更新情報を見る"
translate: "翻訳"
translatedFrom: "{x}から翻訳"
accountDeletionInProgress: "アカウントの削除が進行中です"
usernameInfo: "サーバー上であなたのアカウントを一意に識別するための名前。アルファベット(a~z, A~Z)、数字(0~9)、およびアンダーバー(_)が使用できます。ユーザー名は後から変更することは出来ません。"
aiChanMode: "藍モード"
keepCw: "CWを維持する"
pubSub: "Pub/Subのアカウント"
lastCommunication: "直近の通信"
resolved: "解決済み"
unresolved: "未解決"
_accountDelete:
accountDelete: "アカウントの削除"
mayTakeTime: "アカウントの削除は負荷のかかる処理であるため、作成したコンテンツの数やアップロードしたファイルの数が多いと完了までに時間がかかることがあります。"
sendEmail: "アカウントの削除が完了する際は、登録してあったメールアドレス宛に通知を送信します。"
requestAccountDelete: "アカウント削除をリクエスト"
started: "削除処理が開始されました。"
inProgress: "削除が進行中"
_docs:
continueReading: "続きを読む"
@@ -889,6 +912,8 @@ _mfm:
fontDescription: "内容のフォントを指定することができます。"
rainbow: "レインボー"
rainbowDescription: "内容をレインボーにします。"
sparkle: "キラキラ"
sparkleDescription: "キラキラしたパーティクルのエフェクトを追加します。"
_reversi:
reversi: "リバーシ"
@@ -1129,6 +1154,10 @@ _permissions:
"write:user-groups": "ユーザーグループを操作する"
"read:channels": "チャンネルを見る"
"write:channels": "チャンネルを操作する"
"read:gallery": "ギャラリーを見る"
"write:gallery": "ギャラリーを操作する"
"read:gallery-likes": "ギャラリーのいいねを見る"
"write:gallery-likes": "ギャラリーのいいねを操作する"
_auth:
shareAccess: "「{name}」がアカウントにアクセスすることを許可しますか?"
@@ -1173,6 +1202,7 @@ _widgets:
jobQueue: "ジョブキュー"
serverMetric: "サーバーメトリクス"
aiscript: "AiScriptコンソール"
aichan: "藍"
_cw:
hide: "隠す"
+5 -2
View File
@@ -7,6 +7,7 @@ search: "探す"
notifications: "通知"
username: "ユーザー名"
password: "パスワード"
forgotPassword: "パスワード忘れてん"
fetchingAsApObject: "今ちと連合に照会しとるで"
ok: "OKや"
gotIt: "ほい"
@@ -139,6 +140,7 @@ flagAsBotDescription: "もしこのアカウントがプログラムによって
flagAsCat: "Catやで"
flagAsCatDescription: "ワレ、猫ちゃんならこのフラグをつけてみ?"
autoAcceptFollowed: "フォローしとるユーザーからのフォローリクエストを勝手に許可しとく"
addAccount: "アカウントを追加"
loginFailed: "ログインに失敗してしもうた…"
showOnRemote: "リモートで見る"
general: "全般"
@@ -243,7 +245,7 @@ messageRead: "もう読んだ"
noMoreHistory: "これより過去の履歴はあらへんで"
startMessaging: "チャットやるで"
nUsersRead: "{n}人が読んでもうた"
agreeTo: "{0}はええで"
agreeTo: "{0}に同意したで"
tos: "利用規約"
start: "始める"
home: "ホーム"
@@ -278,6 +280,7 @@ emptyDrive: "ドライブにはなんも残っとらん"
emptyFolder: "ふぉろだーにはなんも残っとらん"
unableToDelete: "消そうおもってんけどな、あかんかったわ"
inputNewFileName: "今度のファイル名は何にするん?"
inputNewDescription: "新しいキャプションを入力しましょ"
inputNewFolderName: "今度のフォルダ名は何にするん?"
circularReferenceFolder: "移動先のフォルダーは、移動するフォルダーのサブフォルダーや。"
hasChildFilesOrFolders: "このフォルダ、まだなんか入っとるから消されへん"
@@ -343,7 +346,7 @@ antennaSource: "受信ソース(このソースは食われへん)"
antennaKeywords: "受信キーワード"
antennaExcludeKeywords: "除外キーワード"
antennaKeywordsDescription: "スペースで区切ったるとAND指定で、改行で区切ったるとOR指定や"
notifyAntenna: "新しいノートを追加すんで"
notifyAntenna: "新しいノートを通知すんで"
withFileAntenna: "なんか添付されたノートだけ"
enableServiceworker: "ServiceWorkerをつこて"
antennaUsersDescription: "ユーザー名を改行で区切ったってな"
+1
View File
@@ -36,6 +36,7 @@ selectList: "Fren tabdart"
youHaveNoLists: "Ulac ɣur-k·m ula d yiwet n tabdart"
security: "Taɣellist"
remove: "Kkes"
connectService: "Qqen"
userList: "Tibdarin"
securityKey: "Tasarutt n tɣellist"
securityKeyName: "Isem n tsarutt"
+32 -3
View File
@@ -529,6 +529,8 @@ removeAllFollowing: "모든 팔로잉 해제"
removeAllFollowingDescription: "{host}(으)로부터 모든 팔로잉을 해제합니다. 해당 인스턴스가 더 이상 존재하지 않게 된 경우 등에 실행해 주세요."
userSuspended: "이 계정은 정지된 상태입니다."
userSilenced: "이 계정은 사일런스된 상태입니다."
yourAccountSuspendedTitle: "계정이 정지되었습니다"
yourAccountSuspendedDescription: "이 계정은 서버의 이용 약관을 위반하거나, 기타 다른 이유로 인해 정지되었습니다. 자세한 사항은 관리자에게 문의해 주십시오. 계정을 새로 생성하지 마십시오."
menu: "메뉴"
divider: "구분선"
addItem: "항목 추가"
@@ -770,13 +772,35 @@ sent: "전송"
received: "수신"
searchResult: "검색 결과"
hashtags: "해시태그"
troubleshooting: "트러블 슈팅"
troubleshooting: "문제 해결"
useBlurEffect: "UI에 흐림 효과 사용"
learnMore: "자세히"
misskeyUpdated: "Misskey가 업데이트 되었습니다!"
whatIsNew: "패치 정보 보기"
translate: "번역"
translatedFrom: "{x}에서 번역"
accountDeletionInProgress: "계정 삭제 작업을 진행하고 있습니다"
usernameInfo: "서버상에서 계정을 식별하기 위한 이름. 알파벳(a~z, A~Z), 숫자(0~9) 및 언더바(_)를 사용할 수 있습니다. 사용자명은 나중에 변경할 수 없습니다."
aiChanMode: "아이 모드"
keepCw: "CW 유지하기"
pubSub: "Pub/Sub 계정"
lastCommunication: "마지막 통신"
resolved: "해결됨"
unresolved: "해결되지 않음"
_accountDelete:
accountDelete: "계정 삭제"
mayTakeTime: "계정 삭제는 서버에 부하를 가하기 때문에, 작성한 콘텐츠나 업로드한 파일의 수가 많으면 완료까지 시간이 걸릴 수 있습니다."
sendEmail: "계정 삭제가 완료되면 등록된 이메일 주소로 알림을 보냅니다."
requestAccountDelete: "계정 삭제 요청"
started: "삭제 작업이 시작되었습니다."
inProgress: "삭제 진행 중"
_docs:
continueReading: "계속 읽기"
features: "기능"
generalTopics: "일반 주제"
advancedTopics: "심화 주제"
admin: "관리"
translateWarn: "이 문서는 번역되었기 때문에 원본과는 내용이 다를 수 있습니다."
_ad:
back: "뒤로"
reduceFrequencyOfThisAd: "이 광고의 표시 빈도 낮추기"
@@ -1098,11 +1122,15 @@ _permissions:
"read:pages": "페이지를 봅니다"
"write:pages": "페이지를 수정합니다"
"read:page-likes": "페이지의 좋아요를 확인합니다"
"write:page-likes": "페이지 좋아요를 추가하거나 삭제합니다"
"write:page-likes": "페이지 좋아요를 추가하거나 취소합니다"
"read:user-groups": "유저 그룹을 조회합니다"
"write:user-groups": "유저 그룹을 만들거나, 초대하거나, 이름을 변경하거나, 양도하거나, 삭제합니다"
"read:channels": "채널을 보기"
"write:channels": "채널을 변경하기"
"write:channels": "채널을 추가하거나 삭제합니다"
"read:gallery": "갤러리를 봅니다"
"write:gallery": "갤러리를 추가하거나 삭제합니다"
"read:gallery-likes": "갤러리의 좋아요를 확인합니다"
"write:gallery-likes": "갤러리에 좋아요를 추가하거나 취소합니다"
_auth:
shareAccess: "\"{name}\" 이 계정에 접근하는 것을 허용하시겠습니까?"
shareAccessAsk: "이 애플리케이션이 계정에 접근하는 것을 허용하시겠습니까?"
@@ -1143,6 +1171,7 @@ _widgets:
jobQueue: "작업 대기열"
serverMetric: "서버 통계"
aiscript: "AiScript 콘솔"
aichan: "아이"
_cw:
hide: "숨기기"
show: "더 보기"
+13
View File
@@ -529,6 +529,7 @@ removeAllFollowing: "Удалить всех подписчиков"
removeAllFollowingDescription: "Отменить все подписки с домена {host}? Пожалуйста, применяйте это действие, если инстанс больше не существует."
userSuspended: "Эта учётная запись заморожена"
userSilenced: "Этот пользователь был заглушен"
menu: "Меню"
divider: "Линия-разделитель"
addItem: "Добавить элемент"
rooms: "Комната"
@@ -761,15 +762,26 @@ middle: "Средне"
low: "Низкий"
emailNotConfiguredWarning: "Не указан адрес электронной почты"
ratio: "Соотношение"
customCss: "Индивидуальный CSS"
customCssWarn: "Используйте эту настройку только если знаете, что делаете. Ошибки здесь чреваты тем, что сайт перестанет нормально работать у вас."
global: "Всеобщая"
squareAvatars: "Квадратные аватарки"
sent: "Отправить"
received: "Получено"
searchResult: "Результаты поиска"
hashtags: "Хэштег"
troubleshooting: "Разрешение проблем"
useBlurEffect: "Размытие в интерфейсе"
learnMore: "Подробнее"
misskeyUpdated: "Misskey обновился!"
whatIsNew: "Что новенького?"
_docs:
continueReading: "Читать подробнее"
features: "Возможности"
generalTopics: "Основные темы"
advancedTopics: "Дополнительные темы"
admin: "Управление"
translateWarn: "Это перевод документа. Он может неточно отражать содержимое оригинала."
_ad:
back: "Выход"
reduceFrequencyOfThisAd: "Реже показывать эту рекламу"
@@ -1136,6 +1148,7 @@ _widgets:
jobQueue: "Очередь заданий"
serverMetric: "Показатели сервера"
aiscript: "Консоль AiScript"
aichan: "Ай"
_cw:
hide: "Спрятать"
show: "Показать еще"
+28
View File
@@ -529,6 +529,8 @@ removeAllFollowing: "取消所有关注"
removeAllFollowingDescription: "取消{host}的所有关注者。当实例不存在时执行。"
userSuspended: "该用户已被冻结。"
userSilenced: "该用户已被禁言。"
yourAccountSuspendedTitle: "账户已被冻结"
yourAccountSuspendedDescription: "由于违反了服务器的服务条款或其他原因,该账户已被冻结。 您可以与管理员联系以了解更多信息。 请不要创建一个新的帐户。"
menu: "菜单"
divider: "分割线"
addItem: "添加项目"
@@ -771,6 +773,27 @@ received: "收取"
searchResult: "搜索结果"
hashtags: "话题标签"
troubleshooting: "故障排除"
useBlurEffect: "在UI上使用模糊效果"
learnMore: "更多信息"
misskeyUpdated: "Misskey更新完成!"
whatIsNew: "显示更新信息"
translate: "翻译"
translatedFrom: "从 {x} 翻译"
accountDeletionInProgress: "正在删除账户"
usernameInfo: "在服务器上唯一标识您的帐户的名称。您可以使用字母 (a ~ z, A ~ Z)、数字 (0 ~ 9) 和下划线 (_)。用户名以后不能更改。"
aiChanMode: "小蓝模式"
keepCw: "保留CW"
pubSub: "Pub/Sub账户"
lastCommunication: "最近通信"
resolved: "已解决"
unresolved: "未解决"
_accountDelete:
accountDelete: "删除帐户"
mayTakeTime: "删除账号是一个性能损耗较大的处理,如果账号持有的内容数量和上传的文件数量较多的话,完成需要花费一段时间。"
sendEmail: "账户删除完成后,将向注册的电子邮件地址发送通知。"
requestAccountDelete: "请求删除账户"
started: "账户删除过程已开始。"
inProgress: "正在删除"
_docs:
continueReading: "继续阅读"
features: "特性"
@@ -1104,6 +1127,10 @@ _permissions:
"write:user-groups": "操作用户组"
"read:channels": "查看频道"
"write:channels": "管理频道"
"read:gallery": "浏览图库"
"write:gallery": "操作图库"
"read:gallery-likes": "读取喜欢的图片"
"write:gallery-likes": "操作喜欢的图片"
_auth:
shareAccess: "您要授权允许“{name}”访问您的帐户吗?"
shareAccessAsk: "您确定要授权此应用程序访问您的帐户吗?"
@@ -1144,6 +1171,7 @@ _widgets:
jobQueue: "作业队列"
serverMetric: "服务器监控"
aiscript: "AiScript控制台"
aichan: "小蓝"
_cw:
hide: "隐藏"
show: "查看更多"
+182
View File
@@ -0,0 +1,182 @@
import {MigrationInterface, QueryRunner} from "typeorm";
export class chartReindex1629004542760 implements MigrationInterface {
name = 'chartReindex1629004542760'
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`DELETE FROM "__chart__active_users" a USING "__chart__active_users" b WHERE a.id < b.id AND ((a.group IS NULL AND b.group IS NULL) OR a.group = b.group) AND a.date = b.date;`);
await queryRunner.query(`DELETE FROM "__chart__drive" a USING "__chart__drive" b WHERE a.id < b.id AND ((a.group IS NULL AND b.group IS NULL) OR a.group = b.group) AND a.date = b.date;`);
await queryRunner.query(`DELETE FROM "__chart__federation" a USING "__chart__federation" b WHERE a.id < b.id AND ((a.group IS NULL AND b.group IS NULL) OR a.group = b.group) AND a.date = b.date;`);
await queryRunner.query(`DELETE FROM "__chart__hashtag" a USING "__chart__hashtag" b WHERE a.id < b.id AND ((a.group IS NULL AND b.group IS NULL) OR a.group = b.group) AND a.date = b.date;`);
await queryRunner.query(`DELETE FROM "__chart__instance" a USING "__chart__instance" b WHERE a.id < b.id AND ((a.group IS NULL AND b.group IS NULL) OR a.group = b.group) AND a.date = b.date;`);
await queryRunner.query(`DELETE FROM "__chart__network" a USING "__chart__network" b WHERE a.id < b.id AND ((a.group IS NULL AND b.group IS NULL) OR a.group = b.group) AND a.date = b.date;`);
await queryRunner.query(`DELETE FROM "__chart__notes" a USING "__chart__notes" b WHERE a.id < b.id AND ((a.group IS NULL AND b.group IS NULL) OR a.group = b.group) AND a.date = b.date;`);
await queryRunner.query(`DELETE FROM "__chart__per_user_drive" a USING "__chart__per_user_drive" b WHERE a.id < b.id AND ((a.group IS NULL AND b.group IS NULL) OR a.group = b.group) AND a.date = b.date;`);
await queryRunner.query(`DELETE FROM "__chart__per_user_following" a USING "__chart__per_user_following" b WHERE a.id < b.id AND ((a.group IS NULL AND b.group IS NULL) OR a.group = b.group) AND a.date = b.date;`);
await queryRunner.query(`DELETE FROM "__chart__per_user_notes" a USING "__chart__per_user_notes" b WHERE a.id < b.id AND ((a.group IS NULL AND b.group IS NULL) OR a.group = b.group) AND a.date = b.date;`);
await queryRunner.query(`DELETE FROM "__chart__per_user_reaction" a USING "__chart__per_user_reaction" b WHERE a.id < b.id AND ((a.group IS NULL AND b.group IS NULL) OR a.group = b.group) AND a.date = b.date;`);
await queryRunner.query(`DELETE FROM "__chart__test_grouped" a USING "__chart__test_grouped" b WHERE a.id < b.id AND ((a.group IS NULL AND b.group IS NULL) OR a.group = b.group) AND a.date = b.date;`);
await queryRunner.query(`DELETE FROM "__chart__test_unique" a USING "__chart__test_unique" b WHERE a.id < b.id AND ((a.group IS NULL AND b.group IS NULL) OR a.group = b.group) AND a.date = b.date;`);
await queryRunner.query(`DELETE FROM "__chart__users" a USING "__chart__users" b WHERE a.id < b.id AND ((a.group IS NULL AND b.group IS NULL) OR a.group = b.group) AND a.date = b.date;`);
await queryRunner.query(`DROP INDEX "IDX_0ad37b7ef50f4ddc84363d7ccc"`);
await queryRunner.query(`DROP INDEX "IDX_00ed5f86db1f7efafb1978bf21"`);
await queryRunner.query(`DROP INDEX "IDX_9a3ed15a30ab7e3a37702e6e08"`);
await queryRunner.query(`DROP INDEX "IDX_13565815f618a1ff53886c5b28"`);
await queryRunner.query(`DROP INDEX "IDX_7a170f67425e62a8fabb76c872"`);
await queryRunner.query(`DROP INDEX "IDX_3313d7288855ec105b5bbf6c21"`);
await queryRunner.query(`DROP INDEX "IDX_36cb699c49580d4e6c2e6159f9"`);
await queryRunner.query(`DROP INDEX "IDX_76e87c7bfc5d925fcbba405d84"`);
await queryRunner.query(`DROP INDEX "IDX_dd907becf76104e4b656659e6b"`);
await queryRunner.query(`DROP INDEX "IDX_07747a1038c05f532a718fe1de"`);
await queryRunner.query(`DROP INDEX "IDX_99a7d2faaef84a6f728d714ad6"`);
await queryRunner.query(`DROP INDEX "IDX_25a97c02003338124b2b75fdbc"`);
await queryRunner.query(`DROP INDEX "IDX_6b8f34a1a64b06014b6fb66824"`);
await queryRunner.query(`DROP INDEX "IDX_da8a46ba84ca1d8bb5a29bfb63"`);
await queryRunner.query(`DROP INDEX "IDX_39ee857ab2f23493037c6b6631"`);
await queryRunner.query(`DROP INDEX "IDX_a1efd3e0048a5f2793a47360dc"`);
await queryRunner.query(`DROP INDEX "IDX_7b5da130992ec9df96712d4290"`);
await queryRunner.query(`DROP INDEX "IDX_0a905b992fecd2b5c3fb98759e"`);
await queryRunner.query(`DROP INDEX "IDX_42eb716a37d381cdf566192b2b"`);
await queryRunner.query(`DROP INDEX "IDX_7036f2957151588b813185c794"`);
await queryRunner.query(`DROP INDEX "IDX_f09d543e3acb16c5976bdb31fa"`);
await queryRunner.query(`DROP INDEX "IDX_5f86db6492274e07c1a3cdf286"`);
await queryRunner.query(`DROP INDEX "IDX_e496ca8096d28f6b9b509264dc"`);
await queryRunner.query(`DROP INDEX "IDX_30bf67687f483ace115c5ca642"`);
await queryRunner.query(`DROP INDEX "IDX_7af07790712aa3438ff6773f3b"`);
await queryRunner.query(`DROP INDEX "IDX_4b3593098b6edc9c5afe36b18b"`);
await queryRunner.query(`DROP INDEX "IDX_b77d4dd9562c3a899d9a286fcd"`);
await queryRunner.query(`DROP INDEX "IDX_84234bd1abb873f07329681c83"`);
await queryRunner.query(`DROP INDEX "IDX_55bf20f366979f2436de99206b"`);
await queryRunner.query(`DROP INDEX "IDX_5048e9daccbbbc6d567bb142d3"`);
await queryRunner.query(`DROP INDEX "IDX_f7bf4c62059764c2c2bb40fdab"`);
await queryRunner.query(`DROP INDEX "IDX_8cf3156fd7a6b15c43459c6e3b"`);
await queryRunner.query(`DROP INDEX "IDX_229a41ad465f9205f1f5703291"`);
await queryRunner.query(`DROP INDEX "IDX_0c641990ecf47d2545df4edb75"`);
await queryRunner.query(`DROP INDEX "IDX_234dff3c0b56a6150b95431ab9"`);
await queryRunner.query(`DROP INDEX "IDX_b14489029e4b3aaf4bba5fb524"`);
await queryRunner.query(`DROP INDEX "IDX_437bab3c6061d90f6bb65fd2cc"`);
await queryRunner.query(`DROP INDEX "IDX_bbfa573a8181018851ed0b6357"`);
await queryRunner.query(`DROP INDEX "IDX_a0cd75442dd10d0643a17c4a49"`);
await queryRunner.query(`DROP INDEX "IDX_b070a906db04b44c67c6c2144d"`);
await queryRunner.query(`DROP INDEX "IDX_d41cce6aee1a50bfc062038f9b"`);
await queryRunner.query(`DROP INDEX "IDX_a319e5dbf47e8a17497623beae"`);
await queryRunner.query(`DROP INDEX "IDX_845254b3eaf708ae8a6cac3026"`);
await queryRunner.query(`DROP INDEX "IDX_ed9b95919c672a13008e9487ee"`);
await queryRunner.query(`DROP INDEX "IDX_337e9599f278bd7537fe30876f"`);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_9a3ed15a30ab7e3a37702e6e08" ON "__chart__active_users" ("date", "group") `);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_60c5c6e7e538c09aa274ecd1cf" ON "__chart__active_users" ("date") WHERE "group" IS NULL`);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_3313d7288855ec105b5bbf6c21" ON "__chart__drive" ("date", "group") `);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_ceab80a6729f8e2e6f5b8a1a3d" ON "__chart__drive" ("date") WHERE "group" IS NULL`);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_dd907becf76104e4b656659e6b" ON "__chart__federation" ("date", "group") `);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_eddfed8fb40305a04c6f941050" ON "__chart__federation" ("date") WHERE "group" IS NULL`);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_25a97c02003338124b2b75fdbc" ON "__chart__hashtag" ("date", "group") `);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_53a3604b939e2b479eb2cfaac8" ON "__chart__hashtag" ("date") WHERE "group" IS NULL`);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_39ee857ab2f23493037c6b6631" ON "__chart__instance" ("date", "group") `);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_8111b817b9818c04d7eb8475b1" ON "__chart__instance" ("date") WHERE "group" IS NULL`);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_0a905b992fecd2b5c3fb98759e" ON "__chart__network" ("date", "group") `);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_2082327b2699ce924fa654afc5" ON "__chart__network" ("date") WHERE "group" IS NULL`);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_f09d543e3acb16c5976bdb31fa" ON "__chart__notes" ("date", "group") `);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_e60c358aaced5aab8900a4af31" ON "__chart__notes" ("date") WHERE "group" IS NULL`);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_30bf67687f483ace115c5ca642" ON "__chart__per_user_drive" ("date", "group") `);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_a9a806d466b314f253a1a611c4" ON "__chart__per_user_drive" ("date") WHERE "group" IS NULL`);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_b77d4dd9562c3a899d9a286fcd" ON "__chart__per_user_following" ("date", "group") `);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_dabbb38a51ab86ee3cab291326" ON "__chart__per_user_following" ("date") WHERE "group" IS NULL`);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_5048e9daccbbbc6d567bb142d3" ON "__chart__per_user_notes" ("date", "group") `);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_583a157ed0cf0ed1b5ec2a833f" ON "__chart__per_user_notes" ("date") WHERE "group" IS NULL`);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_229a41ad465f9205f1f5703291" ON "__chart__per_user_reaction" ("date", "group") `);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_3b7697a96f522d0478972e6d6f" ON "__chart__per_user_reaction" ("date") WHERE "group" IS NULL`);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_b14489029e4b3aaf4bba5fb524" ON "__chart__test_grouped" ("date", "group") `);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_da522b4008a9f5d7743b87ad55" ON "__chart__test_grouped" ("date") WHERE "group" IS NULL`);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_a0cd75442dd10d0643a17c4a49" ON "__chart__test_unique" ("date", "group") `);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_16effb2e888f6763673b579f80" ON "__chart__test_unique" ("date") WHERE "group" IS NULL`);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_a319e5dbf47e8a17497623beae" ON "__chart__test" ("date", "group") `);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_dab383a36f3c9db4a0c9b02cf3" ON "__chart__test" ("date") WHERE "group" IS NULL`);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_337e9599f278bd7537fe30876f" ON "__chart__users" ("date", "group") `);
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_66feba81e1795d176d06c0b1e6" ON "__chart__users" ("date") WHERE "group" IS NULL`);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`DROP INDEX "IDX_66feba81e1795d176d06c0b1e6"`);
await queryRunner.query(`DROP INDEX "IDX_337e9599f278bd7537fe30876f"`);
await queryRunner.query(`DROP INDEX "IDX_dab383a36f3c9db4a0c9b02cf3"`);
await queryRunner.query(`DROP INDEX "IDX_a319e5dbf47e8a17497623beae"`);
await queryRunner.query(`DROP INDEX "IDX_16effb2e888f6763673b579f80"`);
await queryRunner.query(`DROP INDEX "IDX_a0cd75442dd10d0643a17c4a49"`);
await queryRunner.query(`DROP INDEX "IDX_da522b4008a9f5d7743b87ad55"`);
await queryRunner.query(`DROP INDEX "IDX_b14489029e4b3aaf4bba5fb524"`);
await queryRunner.query(`DROP INDEX "IDX_3b7697a96f522d0478972e6d6f"`);
await queryRunner.query(`DROP INDEX "IDX_229a41ad465f9205f1f5703291"`);
await queryRunner.query(`DROP INDEX "IDX_583a157ed0cf0ed1b5ec2a833f"`);
await queryRunner.query(`DROP INDEX "IDX_5048e9daccbbbc6d567bb142d3"`);
await queryRunner.query(`DROP INDEX "IDX_dabbb38a51ab86ee3cab291326"`);
await queryRunner.query(`DROP INDEX "IDX_b77d4dd9562c3a899d9a286fcd"`);
await queryRunner.query(`DROP INDEX "IDX_a9a806d466b314f253a1a611c4"`);
await queryRunner.query(`DROP INDEX "IDX_30bf67687f483ace115c5ca642"`);
await queryRunner.query(`DROP INDEX "IDX_e60c358aaced5aab8900a4af31"`);
await queryRunner.query(`DROP INDEX "IDX_f09d543e3acb16c5976bdb31fa"`);
await queryRunner.query(`DROP INDEX "IDX_2082327b2699ce924fa654afc5"`);
await queryRunner.query(`DROP INDEX "IDX_0a905b992fecd2b5c3fb98759e"`);
await queryRunner.query(`DROP INDEX "IDX_8111b817b9818c04d7eb8475b1"`);
await queryRunner.query(`DROP INDEX "IDX_39ee857ab2f23493037c6b6631"`);
await queryRunner.query(`DROP INDEX "IDX_53a3604b939e2b479eb2cfaac8"`);
await queryRunner.query(`DROP INDEX "IDX_25a97c02003338124b2b75fdbc"`);
await queryRunner.query(`DROP INDEX "IDX_eddfed8fb40305a04c6f941050"`);
await queryRunner.query(`DROP INDEX "IDX_dd907becf76104e4b656659e6b"`);
await queryRunner.query(`DROP INDEX "IDX_ceab80a6729f8e2e6f5b8a1a3d"`);
await queryRunner.query(`DROP INDEX "IDX_3313d7288855ec105b5bbf6c21"`);
await queryRunner.query(`DROP INDEX "IDX_60c5c6e7e538c09aa274ecd1cf"`);
await queryRunner.query(`DROP INDEX "IDX_9a3ed15a30ab7e3a37702e6e08"`);
await queryRunner.query(`DROP INDEX "IDX_a9021cc2e1feb5f72d3db6e9f5"`);
await queryRunner.query(`DROP INDEX "IDX_f22169eb10657bded6d875ac8f"`);
await queryRunner.query(`DROP INDEX "IDX_c8cc87bd0f2f4487d17c651fbf"`);
await queryRunner.query(`DROP INDEX "IDX_754499f9b2642336433769518d"`);
await queryRunner.query(`DROP INDEX "IDX_315c779174fe8247ab324f036e"`);
await queryRunner.query(`DROP INDEX "IDX_c5d46cbfda48b1c33ed852e21b"`);
await queryRunner.query(`CREATE INDEX "IDX_337e9599f278bd7537fe30876f" ON "__chart__users" ("date", "group") `);
await queryRunner.query(`CREATE INDEX "IDX_ed9b95919c672a13008e9487ee" ON "__chart__users" ("group") `);
await queryRunner.query(`CREATE INDEX "IDX_845254b3eaf708ae8a6cac3026" ON "__chart__users" ("date") `);
await queryRunner.query(`CREATE INDEX "IDX_a319e5dbf47e8a17497623beae" ON "__chart__test" ("date", "group") `);
await queryRunner.query(`CREATE INDEX "IDX_d41cce6aee1a50bfc062038f9b" ON "__chart__test" ("group") `);
await queryRunner.query(`CREATE INDEX "IDX_b070a906db04b44c67c6c2144d" ON "__chart__test" ("date") `);
await queryRunner.query(`CREATE INDEX "IDX_a0cd75442dd10d0643a17c4a49" ON "__chart__test_unique" ("date", "group") `);
await queryRunner.query(`CREATE INDEX "IDX_bbfa573a8181018851ed0b6357" ON "__chart__test_unique" ("group") `);
await queryRunner.query(`CREATE INDEX "IDX_437bab3c6061d90f6bb65fd2cc" ON "__chart__test_unique" ("date") `);
await queryRunner.query(`CREATE INDEX "IDX_b14489029e4b3aaf4bba5fb524" ON "__chart__test_grouped" ("date", "group") `);
await queryRunner.query(`CREATE INDEX "IDX_234dff3c0b56a6150b95431ab9" ON "__chart__test_grouped" ("group") `);
await queryRunner.query(`CREATE INDEX "IDX_0c641990ecf47d2545df4edb75" ON "__chart__test_grouped" ("date") `);
await queryRunner.query(`CREATE INDEX "IDX_229a41ad465f9205f1f5703291" ON "__chart__per_user_reaction" ("date", "group") `);
await queryRunner.query(`CREATE INDEX "IDX_8cf3156fd7a6b15c43459c6e3b" ON "__chart__per_user_reaction" ("group") `);
await queryRunner.query(`CREATE INDEX "IDX_f7bf4c62059764c2c2bb40fdab" ON "__chart__per_user_reaction" ("date") `);
await queryRunner.query(`CREATE INDEX "IDX_5048e9daccbbbc6d567bb142d3" ON "__chart__per_user_notes" ("date", "group") `);
await queryRunner.query(`CREATE INDEX "IDX_55bf20f366979f2436de99206b" ON "__chart__per_user_notes" ("group") `);
await queryRunner.query(`CREATE INDEX "IDX_84234bd1abb873f07329681c83" ON "__chart__per_user_notes" ("date") `);
await queryRunner.query(`CREATE INDEX "IDX_b77d4dd9562c3a899d9a286fcd" ON "__chart__per_user_following" ("date", "group") `);
await queryRunner.query(`CREATE INDEX "IDX_4b3593098b6edc9c5afe36b18b" ON "__chart__per_user_following" ("group") `);
await queryRunner.query(`CREATE INDEX "IDX_7af07790712aa3438ff6773f3b" ON "__chart__per_user_following" ("date") `);
await queryRunner.query(`CREATE INDEX "IDX_30bf67687f483ace115c5ca642" ON "__chart__per_user_drive" ("date", "group") `);
await queryRunner.query(`CREATE INDEX "IDX_e496ca8096d28f6b9b509264dc" ON "__chart__per_user_drive" ("group") `);
await queryRunner.query(`CREATE INDEX "IDX_5f86db6492274e07c1a3cdf286" ON "__chart__per_user_drive" ("date") `);
await queryRunner.query(`CREATE INDEX "IDX_f09d543e3acb16c5976bdb31fa" ON "__chart__notes" ("date", "group") `);
await queryRunner.query(`CREATE INDEX "IDX_7036f2957151588b813185c794" ON "__chart__notes" ("group") `);
await queryRunner.query(`CREATE INDEX "IDX_42eb716a37d381cdf566192b2b" ON "__chart__notes" ("date") `);
await queryRunner.query(`CREATE INDEX "IDX_0a905b992fecd2b5c3fb98759e" ON "__chart__network" ("date", "group") `);
await queryRunner.query(`CREATE INDEX "IDX_7b5da130992ec9df96712d4290" ON "__chart__network" ("group") `);
await queryRunner.query(`CREATE INDEX "IDX_a1efd3e0048a5f2793a47360dc" ON "__chart__network" ("date") `);
await queryRunner.query(`CREATE INDEX "IDX_39ee857ab2f23493037c6b6631" ON "__chart__instance" ("date", "group") `);
await queryRunner.query(`CREATE INDEX "IDX_da8a46ba84ca1d8bb5a29bfb63" ON "__chart__instance" ("group") `);
await queryRunner.query(`CREATE INDEX "IDX_6b8f34a1a64b06014b6fb66824" ON "__chart__instance" ("date") `);
await queryRunner.query(`CREATE INDEX "IDX_25a97c02003338124b2b75fdbc" ON "__chart__hashtag" ("date", "group") `);
await queryRunner.query(`CREATE INDEX "IDX_99a7d2faaef84a6f728d714ad6" ON "__chart__hashtag" ("group") `);
await queryRunner.query(`CREATE INDEX "IDX_07747a1038c05f532a718fe1de" ON "__chart__hashtag" ("date") `);
await queryRunner.query(`CREATE INDEX "IDX_dd907becf76104e4b656659e6b" ON "__chart__federation" ("date", "group") `);
await queryRunner.query(`CREATE INDEX "IDX_76e87c7bfc5d925fcbba405d84" ON "__chart__federation" ("group") `);
await queryRunner.query(`CREATE INDEX "IDX_36cb699c49580d4e6c2e6159f9" ON "__chart__federation" ("date") `);
await queryRunner.query(`CREATE INDEX "IDX_3313d7288855ec105b5bbf6c21" ON "__chart__drive" ("date", "group") `);
await queryRunner.query(`CREATE INDEX "IDX_7a170f67425e62a8fabb76c872" ON "__chart__drive" ("group") `);
await queryRunner.query(`CREATE INDEX "IDX_13565815f618a1ff53886c5b28" ON "__chart__drive" ("date") `);
await queryRunner.query(`CREATE INDEX "IDX_9a3ed15a30ab7e3a37702e6e08" ON "__chart__active_users" ("date", "group") `);
await queryRunner.query(`CREATE INDEX "IDX_00ed5f86db1f7efafb1978bf21" ON "__chart__active_users" ("group") `);
await queryRunner.query(`CREATE INDEX "IDX_0ad37b7ef50f4ddc84363d7ccc" ON "__chart__active_users" ("date") `);
}
}
@@ -0,0 +1,14 @@
import {MigrationInterface, QueryRunner} from "typeorm";
export class deeplIntegration1629024377804 implements MigrationInterface {
name = 'deeplIntegration1629024377804'
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "meta" ADD "deeplAuthKey" character varying(128)`);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "deeplAuthKey"`);
}
}
@@ -0,0 +1,14 @@
import {MigrationInterface, QueryRunner} from "typeorm";
export class fixChannelUserId1629288472000 implements MigrationInterface {
name = 'fixChannelUserId1629288472000'
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "channel" ALTER COLUMN "userId" DROP NOT NULL;`);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "channel" ALTER COLUMN "userId" SET NOT NULL;`);
}
}
@@ -0,0 +1,15 @@
import {MigrationInterface, QueryRunner} from "typeorm";
export class isUserDeleted1629512953000 implements MigrationInterface {
name = 'isUserDeleted1629512953000'
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "user" ADD "isDeleted" boolean NOT NULL DEFAULT false`);
await queryRunner.query(`COMMENT ON COLUMN "user"."isDeleted" IS 'Whether the User is deleted.'`);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "isDeleted"`);
}
}
@@ -0,0 +1,14 @@
import {MigrationInterface, QueryRunner} from "typeorm";
export class deeplIntegration21629778475000 implements MigrationInterface {
name = 'deeplIntegration21629778475000'
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "meta" ADD "deeplIsPro" boolean NOT NULL DEFAULT false`);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "deeplIsPro"`);
}
}
+1
Submodule misskey-assets added at 0179793ec8
+73 -80
View File
@@ -1,7 +1,7 @@
{
"name": "misskey",
"author": "syuilo <syuilotan@yahoo.co.jp>",
"version": "12.86.0",
"version": "12.91.0",
"codename": "indigo",
"repository": {
"type": "git",
@@ -10,7 +10,8 @@
"main": "./index.js",
"private": true,
"scripts": {
"start": "node ./index.js",
"start": "node --experimental-json-modules ./index.js",
"start:test": "cross-env NODE_ENV=test node --experimental-json-modules ./index.js",
"init": "npm run migrate",
"ormconfig": "node ./built/ormconfig.js",
"migrate": "ts-node ./node_modules/typeorm/cli.js migration:run",
@@ -26,6 +27,9 @@
"clean": "gulp clean",
"cleanall": "gulp cleanall",
"lint": "tslint 'src/**/*.ts'",
"cy:open": "cypress open",
"cy:run": "cypress run",
"e2e": "start-server-and-test start:test http://localhost cy:run",
"test": "cross-env TS_NODE_FILES=true TS_NODE_TRANSPILE_ONLY=true TS_NODE_PROJECT=\"./test/tsconfig.json\" mocha",
"format": "gulp format"
},
@@ -34,7 +38,6 @@
"lodash": "^4.17.21"
},
"dependencies": {
"@babel/plugin-transform-runtime": "7.14.5",
"@elastic/elasticsearch": "7.11.0",
"@koa/cors": "3.1.0",
"@koa/multer": "3.0.0",
@@ -44,7 +47,7 @@
"@sinonjs/fake-timers": "7.1.2",
"@syuilo/aiscript": "0.11.1",
"@types/bcryptjs": "2.4.2",
"@types/bull": "3.15.2",
"@types/bull": "3.15.4",
"@types/cbor": "6.0.0",
"@types/dateformat": "3.0.1",
"@types/escape-regexp": "0.0.0",
@@ -52,26 +55,26 @@
"@types/gulp": "4.0.9",
"@types/gulp-rename": "2.0.1",
"@types/is-url": "1.2.30",
"@types/js-yaml": "4.0.2",
"@types/js-yaml": "4.0.3",
"@types/jsdom": "16.2.13",
"@types/jsonld": "1.5.6",
"@types/katex": "0.11.1",
"@types/koa": "2.13.4",
"@types/koa-bodyparser": "4.3.2",
"@types/koa-cors": "0.0.1",
"@types/koa-bodyparser": "4.3.3",
"@types/koa-cors": "0.0.2",
"@types/koa-favicon": "2.0.21",
"@types/koa-logger": "3.1.1",
"@types/koa-mount": "4.0.0",
"@types/koa-mount": "4.0.1",
"@types/koa-send": "4.1.3",
"@types/koa-views": "7.0.0",
"@types/koa__cors": "3.0.3",
"@types/koa__multer": "2.0.3",
"@types/koa__router": "8.0.7",
"@types/markdown-it": "12.0.3",
"@types/matter-js": "0.17.3",
"@types/koa__router": "8.0.8",
"@types/markdown-it": "12.2.1",
"@types/matter-js": "0.17.5",
"@types/mocha": "8.2.3",
"@types/node": "16.3.3",
"@types/node-fetch": "2.5.11",
"@types/node": "16.9.6",
"@types/node-fetch": "2.5.12",
"@types/nodemailer": "6.4.4",
"@types/nprogress": "0.2.0",
"@types/oauth": "0.9.1",
@@ -83,13 +86,13 @@
"@types/qrcode": "1.4.1",
"@types/random-seed": "0.3.3",
"@types/ratelimiter": "3.4.2",
"@types/redis": "2.8.31",
"@types/redis": "2.8.32",
"@types/rename": "1.0.4",
"@types/request-stats": "3.0.0",
"@types/rimraf": "3.0.1",
"@types/rimraf": "3.0.2",
"@types/seedrandom": "2.4.28",
"@types/sharp": "0.28.4",
"@types/sinonjs__fake-timers": "6.0.3",
"@types/sharp": "0.29.2",
"@types/sinonjs__fake-timers": "6.0.4",
"@types/speakeasy": "2.0.6",
"@types/throttle-debounce": "2.1.0",
"@types/tinycolor2": "1.4.3",
@@ -98,40 +101,40 @@
"@types/web-push": "3.3.2",
"@types/webpack": "5.28.0",
"@types/webpack-stream": "3.2.12",
"@types/websocket": "1.0.3",
"@types/ws": "7.4.6",
"@typescript-eslint/parser": "4.28.3",
"@vue/compiler-sfc": "3.2.1",
"@types/websocket": "1.0.4",
"@types/ws": "7.4.7",
"@typescript-eslint/parser": "4.31.2",
"@vue/compiler-sfc": "3.2.13",
"abort-controller": "3.0.0",
"apexcharts": "3.27.2",
"apexcharts": "3.28.3",
"autobind-decorator": "2.4.0",
"autosize": "4.0.4",
"autwh": "0.1.0",
"aws-sdk": "2.948.0",
"aws-sdk": "2.992.0",
"bcryptjs": "2.4.3",
"blurhash": "1.1.3",
"broadcast-channel": "3.7.0",
"bull": "3.26.0",
"blurhash": "1.1.4",
"broadcast-channel": "4.2.0",
"bull": "3.29.2",
"cacheable-lookup": "6.0.1",
"cafy": "15.2.1",
"cbor": "7.0.6",
"chalk": "4.1.1",
"cbor": "8.0.0",
"chalk": "4.1.2",
"chart.js": "2.9.4",
"cli-highlight": "2.1.11",
"commander": "7.2.0",
"concurrently": "6.2.0",
"commander": "8.1.0",
"compare-versions": "3.6.0",
"concurrently": "6.2.1",
"content-disposition": "0.5.3",
"core-js": "3.15.2",
"crc-32": "1.2.0",
"css-loader": "6.0.0",
"cssnano": "5.0.6",
"css-loader": "6.3.0",
"cssnano": "5.0.8",
"dateformat": "4.5.1",
"diskusage": "1.1.3",
"escape-regexp": "0.0.1",
"eslint": "7.30.0",
"eslint-plugin-vue": "7.13.0",
"eslint": "7.32.0",
"eslint-plugin-vue": "7.18.0",
"eventemitter3": "4.0.7",
"feed": "4.2.2",
"file-type": "16.5.1",
"file-type": "16.5.3",
"fluent-ffmpeg": "2.1.2",
"glob": "7.1.7",
"got": "11.8.2",
@@ -141,22 +144,19 @@
"gulp-replace": "1.1.3",
"gulp-terser": "2.0.1",
"gulp-tslint": "8.1.4",
"hard-source-webpack-plugin": "0.13.1",
"html-minifier": "4.0.0",
"http-proxy-agent": "4.0.1",
"hpagent": "0.1.2",
"http-signature": "1.3.5",
"https-proxy-agent": "5.0.0",
"idb-keyval": "5.0.6",
"idb-keyval": "5.1.3",
"insert-text-at-cursor": "0.3.0",
"is-root": "2.1.0",
"ip-cidr": "3.0.4",
"is-svg": "4.3.1",
"js-yaml": "4.1.0",
"jsdom": "16.6.0",
"jsdom": "16.7.0",
"json5": "2.2.0",
"json5-loader": "4.0.1",
"jsonld": "5.2.0",
"jsrsasign": "8.0.20",
"katex": "0.13.11",
"katex": "0.13.18",
"koa": "2.13.1",
"koa-bodyparser": "4.3.0",
"koa-favicon": "2.1.0",
@@ -167,98 +167,91 @@
"koa-slow": "2.1.0",
"koa-views": "7.0.1",
"langmap": "0.0.16",
"lookup-dns-cache": "2.1.0",
"markdown-it": "12.1.0",
"markdown-it": "12.2.0",
"markdown-it-anchor": "7.1.0",
"matter-js": "0.17.1",
"mfm-js": "0.19.0",
"misskey-js": "0.0.6",
"mocha": "8.4.0",
"moji": "0.5.1",
"ms": "2.1.3",
"multer": "1.4.2",
"multer": "1.4.3",
"nested-property": "4.0.0",
"node-fetch": "2.6.1",
"nodemailer": "6.6.3",
"object-assign-deep": "0.4.0",
"os-utils": "0.0.14",
"parse5": "6.0.1",
"pg": "8.6.0",
"pg": "8.7.1",
"portscanner": "2.2.0",
"postcss": "8.3.5",
"postcss": "8.3.7",
"postcss-loader": "6.1.1",
"prismjs": "1.24.1",
"prismjs": "1.25.0",
"private-ip": "2.2.1",
"probe-image-size": "7.2.1",
"promise-limit": "2.7.0",
"promise-sequential": "1.1.1",
"pug": "3.0.2",
"punycode": "2.1.1",
"pureimage": "0.3.2",
"pureimage": "0.3.5",
"qrcode": "1.4.4",
"random-seed": "0.3.0",
"ratelimiter": "3.4.1",
"re2": "1.16.0",
"reconnecting-websocket": "4.4.0",
"redis": "3.1.2",
"redis-lock": "0.1.4",
"reflect-metadata": "0.1.13",
"regenerator-runtime": "0.13.7",
"rename": "1.0.4",
"request-stats": "3.0.0",
"require-all": "3.0.0",
"rimraf": "3.0.2",
"rndstr": "1.0.0",
"s-age": "1.1.2",
"sass": "1.35.2",
"sass": "1.42.1",
"sass-loader": "12.1.0",
"seedrandom": "3.0.5",
"sharp": "0.28.3",
"sharp": "0.29.1",
"speakeasy": "2.0.0",
"stringz": "2.1.0",
"style-loader": "3.1.0",
"summaly": "2.4.0",
"style-loader": "3.3.0",
"summaly": "2.4.1",
"syslog-pro": "1.0.0",
"systeminformation": "5.7.7",
"systeminformation": "5.9.3",
"syuilo-password-strength": "0.0.1",
"textarea-caret": "3.1.0",
"three": "0.117.1",
"throttle-debounce": "3.0.1",
"tinycolor2": "1.4.2",
"tmp": "0.2.1",
"ts-loader": "9.2.3",
"ts-node": "10.1.0",
"tsc-alias": "1.3.7",
"tsconfig-paths": "3.10.1",
"ts-loader": "9.2.6",
"ts-node": "10.2.1",
"tsc-alias": "1.3.9",
"tsconfig-paths": "3.11.0",
"tslint": "6.1.3",
"tslint-sonarts": "1.9.0",
"twemoji-parser": "13.1.0",
"typeorm": "0.2.32",
"typescript": "4.3.5",
"typeorm": "0.2.37",
"typescript": "4.4.3",
"ulid": "2.3.0",
"uuid": "8.3.2",
"v-debounce": "0.1.2",
"vanilla-tilt": "1.7.0",
"vue": "3.2.1",
"vue-color": "2.8.1",
"vue-json-pretty": "1.8.1",
"vue-loader": "16.3.1",
"vanilla-tilt": "1.7.2",
"vue": "3.2.13",
"vue-loader": "16.7.0",
"vue-prism-editor": "2.0.0-alpha.2",
"vue-router": "4.0.5",
"vue-style-loader": "4.1.3",
"vue-svg-loader": "0.17.0-beta.2",
"vuedraggable": "4.0.1",
"web-push": "3.4.5",
"webpack": "5.45.1",
"webpack-cli": "4.7.2",
"webpack": "5.53.0",
"webpack-cli": "4.8.0",
"websocket": "1.0.34",
"ws": "7.5.3",
"ws": "8.2.2",
"xev": "2.0.1"
},
"devDependencies": {
"@redocly/openapi-core": "1.0.0-beta.44",
"@types/chai": "4.2.16",
"@redocly/openapi-core": "1.0.0-beta.54",
"@types/fluent-ffmpeg": "2.1.17",
"chai": "4.3.4",
"cross-env": "7.0.3"
"cross-env": "7.0.3",
"cypress": "8.4.1",
"start-server-and-test": "1.14.0"
}
}
-7
View File
@@ -1,7 +0,0 @@
declare module 'is-root' {
function isRoot(): boolean;
namespace isRoot {} // Hack
export = isRoot;
}
-9
View File
@@ -1,9 +0,0 @@
declare module 'lookup-dns-cache' {
import { LookupOneOptions, LookupAllOptions, LookupOptions, LookupAddress } from 'dns';
function lookup(hostname: string, family: number, callback: (err: NodeJS.ErrnoException | null, address: string, family: number) => void): void;
function lookup(hostname: string, options: LookupOneOptions, callback: (err: NodeJS.ErrnoException | null, address: string, family: number) => void): void;
function lookup(hostname: string, options: LookupAllOptions, callback: (err: NodeJS.ErrnoException | null, addresses: LookupAddress[]) => void): void;
function lookup(hostname: string, options: LookupOptions, callback: (err: NodeJS.ErrnoException | null, address: string | LookupAddress[], family: number) => void): void;
function lookup(hostname: string, callback: (err: NodeJS.ErrnoException | null, address: string, family: number) => void): void;
}
+13 -14
View File
@@ -1,24 +1,23 @@
import { Command } from 'commander';
import config from '@/config';
import config from '@/config/index';
const program = new Command();
program
.version(config.version)
.option('--no-daemons', 'Disable daemon processes (for debbuging)')
.option('--disable-clustering', 'Disable clustering')
.option('--only-server', 'Run server only (without job queue processing)')
.option('--only-queue', 'Pocessing job queue only (without server)')
.option('--quiet', 'Suppress all logs')
.option('--verbose', 'Enable all logs')
.option('--with-log-time', 'Include timestamp for each logs')
.option('--slow', 'Delay all requests (for debbuging)')
.option('--color', 'This option is a dummy for some external program\'s (e.g. forever) issue.')
.parse(process.argv);
program.version(config.version);
program.option('--no-daemons', 'Disable daemon processes (for debbuging)');
program.option('--disable-clustering', 'Disable clustering');
program.option('--only-server', 'Run server only (without job queue processing)');
program.option('--only-queue', 'Pocessing job queue only (without server)');
program.option('--quiet', 'Suppress all logs');
program.option('--verbose', 'Enable all logs');
program.option('--with-log-time', 'Include timestamp for each logs');
program.option('--slow', 'Delay all requests (for debbuging)');
program.option('--color', 'This option is a dummy for some external program\'s (e.g. forever) issue.');
program.parse(process.argv);
if (process.env.MK_ONLY_QUEUE) program.onlyQueue = true;
if (process.env.NODE_ENV === 'test') program.disableClustering = true;
if (process.env.NODE_ENV === 'test') program.quiet = true;
//if (process.env.NODE_ENV === 'test') program.quiet = true;
if (process.env.NODE_ENV === 'test') program.noDaemons = true;
export { program };
+1 -1
View File
@@ -2,7 +2,7 @@ import * as cluster from 'cluster';
import * as chalk from 'chalk';
import Xev from 'xev';
import Logger from '../services/logger';
import Logger from '@/services/logger';
import { program } from '../argv';
// for typeorm
+16 -4
View File
@@ -1,18 +1,25 @@
import * as fs from 'fs';
import { fileURLToPath } from 'url';
import { dirname } from 'path';
import * as os from 'os';
import * as cluster from 'cluster';
import * as chalk from 'chalk';
import * as portscanner from 'portscanner';
import * as isRoot from 'is-root';
import { getConnection } from 'typeorm';
import Logger from '../services/logger';
import Logger from '@/services/logger';
import loadConfig from '@/config/load';
import { Config } from '@/config/types';
import { lessThan } from '../prelude/array';
import { lessThan } from '@/prelude/array';
import { program } from '../argv';
import { showMachineInfo } from '@/misc/show-machine-info';
import { initDb } from '../db/postgre';
const meta = require('../meta.json');
//const _filename = fileURLToPath(import.meta.url);
const _filename = __filename;
const _dirname = dirname(_filename);
const meta = JSON.parse(fs.readFileSync(`${_dirname}/../meta.json`, 'utf-8'));
const logger = new Logger('core', 'cyan');
const bootLogger = logger.createSubLogger('boot', 'magenta', false);
@@ -39,6 +46,11 @@ function greet() {
bootLogger.info(`Misskey v${meta.version}`, null, true);
}
function isRoot() {
// maybe process.getuid will be undefined under not POSIX environment (e.g. Windows)
return process.getuid != null && process.getuid() === 0;
}
/**
* Init master process
*/
+70 -22
View File
@@ -1,7 +1,9 @@
import { del, get, set } from '@client/scripts/idb-proxy';
import { reactive } from 'vue';
import { apiUrl } from '@client/config';
import { waiting } from '@client/os';
import { unisonReload } from '@client/scripts/unison-reload';
import { unisonReload, reloadChannel } from '@client/scripts/unison-reload';
import { showSuspendedDialog } from './scripts/show-suspended-dialog';
// TODO: 他のタブと永続化されたstateを同期
@@ -10,6 +12,7 @@ type Account = {
token: string;
isModerator: boolean;
isAdmin: boolean;
isDeleted: boolean;
};
const data = localStorage.getItem('account');
@@ -17,22 +20,57 @@ const data = localStorage.getItem('account');
// TODO: 外部からはreadonlyに
export const $i = data ? reactive(JSON.parse(data) as Account) : null;
export function signout() {
export async function signout() {
waiting();
localStorage.removeItem('account');
//#region Remove account
const accounts = await getAccounts();
accounts.splice(accounts.findIndex(x => x.id === $i.id), 1);
if (accounts.length > 0) await set('accounts', accounts);
else await del('accounts');
//#endregion
//#region Remove service worker registration
try {
if (navigator.serviceWorker.controller) {
const registration = await navigator.serviceWorker.ready;
const push = await registration.pushManager.getSubscription();
if (push) {
await fetch(`${apiUrl}/sw/unregister`, {
method: 'POST',
body: JSON.stringify({
i: $i.token,
endpoint: push.endpoint,
}),
});
}
}
if (accounts.length === 0) {
await navigator.serviceWorker.getRegistrations()
.then(registrations => {
return Promise.all(registrations.map(registration => registration.unregister()));
});
}
} catch (e) {}
//#endregion
document.cookie = `igi=; path=/`;
location.href = '/';
if (accounts.length > 0) login(accounts[0].token);
else unisonReload();
}
export function getAccounts() {
const accountsData = localStorage.getItem('accounts');
const accounts: { id: Account['id'], token: Account['token'] }[] = accountsData ? JSON.parse(accountsData) : [];
return accounts;
export async function getAccounts(): Promise<{ id: Account['id'], token: Account['token'] }[]> {
return (await get('accounts')) || [];
}
export function addAccount(id: Account['id'], token: Account['token']) {
const accounts = getAccounts();
export async function addAccount(id: Account['id'], token: Account['token']) {
const accounts = await getAccounts();
if (!accounts.some(x => x.id === id)) {
localStorage.setItem('accounts', JSON.stringify(accounts.concat([{ id, token }])));
await set('accounts', accounts.concat([{ id, token }]));
}
}
@@ -45,17 +83,20 @@ function fetchAccount(token): Promise<Account> {
i: token
})
})
.then(res => res.json())
.then(res => {
// When failed to authenticate user
if (res.status >= 400 && res.status < 500) {
return signout();
if (res.error) {
if (res.error.id === 'a8c724b3-6e9c-4b46-b1a8-bc3ed6258370') {
showSuspendedDialog().then(() => {
signout();
});
} else {
signout();
}
} else {
res.token = token;
done(res);
}
// Parse response
res.json().then(i => {
i.token = token;
done(i);
});
})
.catch(fail);
});
@@ -69,15 +110,22 @@ export function updateAccount(data) {
}
export function refreshAccount() {
fetchAccount($i.token).then(updateAccount);
return fetchAccount($i.token).then(updateAccount);
}
export async function login(token: Account['token']) {
export async function login(token: Account['token'], redirect?: string) {
waiting();
if (_DEV_) console.log('logging as token ', token);
const me = await fetchAccount(token);
localStorage.setItem('account', JSON.stringify(me));
addAccount(me.id, token);
await addAccount(me.id, token);
if (redirect) {
reloadChannel.postMessage('reload');
location.href = redirect;
return;
}
unisonReload();
}
+43 -39
View File
@@ -35,6 +35,7 @@ import { twemojiSvgBase } from '@/misc/twemoji-base';
import { getStaticImageUrl } from '@client/scripts/get-static-image-url';
import { acct } from '@client/filters/user';
import * as os from '@client/os';
import { instance } from '@client/instance';
type EmojiDef = {
emoji: string;
@@ -75,6 +76,36 @@ for (const x of lib) {
emjdb.sort((a, b) => a.name.length - b.name.length);
//#region Construct Emoji DB
const customEmojis = instance.emojis;
const emojiDefinitions: EmojiDef[] = [];
for (const x of customEmojis) {
emojiDefinitions.push({
name: x.name,
emoji: `:${x.name}:`,
url: x.url,
isCustomEmoji: true
});
if (x.aliases) {
for (const alias of x.aliases) {
emojiDefinitions.push({
name: alias,
aliasOf: x.name,
emoji: `:${x.name}:`,
url: x.url,
isCustomEmoji: true
});
}
}
}
emojiDefinitions.sort((a, b) => a.name.length - b.name.length);
const emojiDb = markRaw(emojiDefinitions.concat(emjdb));
//#endregion
export default defineComponent({
props: {
type: {
@@ -124,7 +155,6 @@ export default defineComponent({
emojis: [],
items: [],
select: -1,
emojiDb: [] as EmojiDef[]
}
},
@@ -144,36 +174,6 @@ export default defineComponent({
mounted() {
this.setPosition();
//#region Construct Emoji DB
const customEmojis = this.$instance.emojis;
const emojiDefinitions: EmojiDef[] = [];
for (const x of customEmojis) {
emojiDefinitions.push({
name: x.name,
emoji: `:${x.name}:`,
url: x.url,
isCustomEmoji: true
});
if (x.aliases) {
for (const alias of x.aliases) {
emojiDefinitions.push({
name: alias,
aliasOf: x.name,
emoji: `:${x.name}:`,
url: x.url,
isCustomEmoji: true
});
}
}
}
emojiDefinitions.sort((a, b) => a.name.length - b.name.length);
this.emojiDb = markRaw(emojiDefinitions.concat(emjdb));
//#endregion
this.textarea.addEventListener('keydown', this.onKeydown);
for (const el of Array.from(document.querySelectorAll('body *'))) {
@@ -203,6 +203,13 @@ export default defineComponent({
complete(type, value) {
this.$emit('done', { type, value });
this.$emit('closed');
if (type === 'emoji') {
let recents = this.$store.state.recentlyUsedEmojis;
recents = recents.filter((e: any) => e !== value);
recents.unshift(value);
this.$store.set('recentlyUsedEmojis', recents.splice(0, 32));
}
},
setPosition() {
@@ -281,29 +288,26 @@ export default defineComponent({
}
} else if (this.type == 'emoji') {
if (this.q == null || this.q == '') {
this.emojis = this.emojiDb.filter(x => x.isCustomEmoji && !x.aliasOf).sort((a, b) => {
var textA = a.name.toUpperCase();
var textB = b.name.toUpperCase();
return (textA < textB) ? -1 : (textA > textB) ? 1 : 0;
});
// 使
this.emojis = this.$store.state.recentlyUsedEmojis.map(emoji => emojiDb.find(e => e.emoji == emoji)).filter(x => x != null);
return;
}
const matched = [];
const max = 30;
this.emojiDb.some(x => {
emojiDb.some(x => {
if (x.name.startsWith(this.q) && !x.aliasOf && !matched.some(y => y.emoji == x.emoji)) matched.push(x);
return matched.length == max;
});
if (matched.length < max) {
this.emojiDb.some(x => {
emojiDb.some(x => {
if (x.name.startsWith(this.q) && !matched.some(y => y.emoji == x.emoji)) matched.push(x);
return matched.length == max;
});
}
if (matched.length < max) {
this.emojiDb.some(x => {
emojiDb.some(x => {
if (x.name.includes(this.q) && !matched.some(y => y.emoji == x.emoji)) matched.push(x);
return matched.length == max;
});
@@ -93,13 +93,13 @@ export default defineComponent({
});
return h(this.$store.state.animation ? TransitionGroup : 'div', this.$store.state.animation ? {
class: 'sqadhkmv' + (this.noGap ? ' noGap _block' : ''),
class: 'sqadhkmv' + (this.noGap ? ' noGap' : ''),
name: 'list',
tag: 'div',
'data-direction': this.direction,
'data-reversed': this.reversed ? 'true' : 'false',
} : {
class: 'sqadhkmv' + (this.noGap ? ' noGap _block' : ''),
class: 'sqadhkmv' + (this.noGap ? ' noGap' : ''),
}, {
default: renderChildren
});
+26
View File
@@ -73,6 +73,22 @@ export default defineComponent({
</script>
<style lang="scss" scoped>
@keyframes earwiggleleft {
from { transform: rotate(37.6deg) skew(30deg); }
25% { transform: rotate(10deg) skew(30deg); }
50% { transform: rotate(20deg) skew(30deg); }
75% { transform: rotate(0deg) skew(30deg); }
to { transform: rotate(37.6deg) skew(30deg); }
}
@keyframes earwiggleright {
from { transform: rotate(-37.6deg) skew(-30deg); }
30% { transform: rotate(-10deg) skew(-30deg); }
55% { transform: rotate(-20deg) skew(-30deg); }
75% { transform: rotate(0deg) skew(-30deg); }
to { transform: rotate(-37.6deg) skew(-30deg); }
}
.eiwwqkts {
position: relative;
display: inline-block;
@@ -132,6 +148,16 @@ export default defineComponent({
border-radius: 75% 0 75% 75%;
transform: rotate(-37.5deg) skew(-30deg);
}
&:hover {
&:before {
animation: earwiggleleft 1s infinite;
}
&:after {
animation: earwiggleright 1s infinite;
}
}
}
}
</style>
+16 -16
View File
@@ -1,5 +1,5 @@
<template>
<div class="yxspomdl" :class="{ inline, colored }">
<div class="yxspomdl" :class="{ inline, colored, mini }">
<div class="ring"></div>
</div>
</template>
@@ -18,7 +18,12 @@ export default defineComponent({
type: Boolean,
required: false,
default: true
}
},
mini: {
type: Boolean,
required: false,
default: false
},
}
});
</script>
@@ -38,6 +43,8 @@ export default defineComponent({
text-align: center;
cursor: wait;
--size: 48px;
&.colored {
color: var(--accent);
}
@@ -45,19 +52,12 @@ export default defineComponent({
&.inline {
display: inline;
padding: 0;
--size: 32px;
}
> .ring:after {
width: 32px;
height: 32px;
}
> .ring {
&:before,
&:after {
width: 32px;
height: 32px;
}
}
&.mini {
padding: 16px;
--size: 32px;
}
> .ring {
@@ -70,8 +70,8 @@ export default defineComponent({
content: " ";
display: block;
box-sizing: border-box;
width: 48px;
height: 48px;
width: var(--size);
height: var(--size);
border-radius: 50%;
border: solid 4px;
}
+14
View File
@@ -8,6 +8,7 @@ import { concat } from '@client/../prelude/array';
import MkFormula from '@client/components/formula.vue';
import MkCode from '@client/components/code.vue';
import MkGoogle from '@client/components/google.vue';
import MkSparkle from '@client/components/sparkle.vue';
import MkA from '@client/components/global/a.vue';
import { host } from '@client/config';
@@ -169,6 +170,19 @@ export default defineComponent({
style = this.$store.state.animatedMfm ? 'animation: mfm-rainbow 1s linear infinite;' : '';
break;
}
case 'sparkle': {
if (!this.$store.state.animatedMfm) {
return genEl(token.children);
}
let count = token.props.args.count ? parseInt(token.props.args.count) : 10;
if (count > 100) {
count = 100;
}
const speed = token.props.args.speed ? parseFloat(token.props.args.speed) : 1;
return h(MkSparkle, {
count, speed,
}, genEl(token.children));
}
}
if (style == null) {
return h('span', {}, ['[', token.props.name, ...genEl(token.children), ']']);
+36 -4
View File
@@ -1,6 +1,6 @@
<template>
<div
class="note _block"
class="lxwezrsl _block"
v-if="!muted"
v-show="!isDeleted"
:tabindex="!isDeleted ? '-1' : null"
@@ -67,6 +67,13 @@
<MkA class="reply" v-if="appearNote.replyId" :to="`/notes/${appearNote.replyId}`"><i class="fas fa-reply"></i></MkA>
<Mfm v-if="appearNote.text" :text="appearNote.text" :author="appearNote.user" :i="$i" :custom-emojis="appearNote.emojis"/>
<a class="rp" v-if="appearNote.renote != null">RN:</a>
<div class="translation" v-if="translating || translation">
<MkLoading v-if="translating" mini/>
<div class="translated" v-else>
<b>{{ $t('translatedFrom', { x: translation.sourceLang }) }}:</b>
{{ translation.text }}
</div>
</div>
</div>
<div class="files" v-if="appearNote.files.length > 0">
<XMediaList :media-list="appearNote.files"/>
@@ -79,8 +86,8 @@
</div>
<footer class="footer">
<div class="info">
<span class="mobile" v-if="note.viaMobile"><i class="fas fa-mobile-alt"></i></span>
<MkTime class="created-at" :time="note.createdAt" mode="detail"/>
<span class="mobile" v-if="appearNote.viaMobile"><i class="fas fa-mobile-alt"></i></span>
<MkTime class="created-at" :time="appearNote.createdAt" mode="detail"/>
</div>
<XReactionsViewer :note="appearNote" ref="reactionsViewer"/>
<button @click="reply()" class="button _button">
@@ -178,6 +185,8 @@ export default defineComponent({
showContent: false,
isDeleted: false,
muted: false,
translation: null,
translating: false,
};
},
@@ -619,6 +628,11 @@ export default defineComponent({
text: this.$ts.share,
action: this.share
},
this.$instance.translatorAvailable ? {
icon: 'fas fa-language',
text: this.$ts.translate,
action: this.translate
} : undefined,
null,
statePromise.then(state => state.isFavorited ? {
icon: 'fas fa-star',
@@ -852,6 +866,17 @@ export default defineComponent({
});
},
async translate() {
if (this.translation != null) return;
this.translating = true;
const res = await os.api('notes/translate', {
noteId: this.appearNote.id,
targetLang: localStorage.getItem('lang') || navigator.language,
});
this.translating = false;
this.translation = res;
},
focus() {
this.$el.focus();
},
@@ -874,7 +899,7 @@ export default defineComponent({
</script>
<style lang="scss" scoped>
.note {
.lxwezrsl {
position: relative;
transition: box-shadow 0.1s ease;
overflow: hidden;
@@ -1050,6 +1075,13 @@ export default defineComponent({
font-style: oblique;
color: var(--renote);
}
> .translation {
border: solid 0.5px var(--divider);
border-radius: var(--radius);
padding: 12px;
margin-top: 8px;
}
}
> .url-preview {
+8 -4
View File
@@ -3,10 +3,10 @@
<MkA class="name" :to="userPage(note.user)" v-user-preview="note.user.id">
<MkUserName :user="note.user"/>
</MkA>
<span class="is-bot" v-if="note.user.isBot">bot</span>
<span class="username"><MkAcct :user="note.user"/></span>
<span class="admin" v-if="note.user.isAdmin"><i class="fas fa-bookmark"></i></span>
<span class="moderator" v-if="!note.user.isAdmin && note.user.isModerator"><i class="far fa-bookmark"></i></span>
<div class="is-bot" v-if="note.user.isBot">bot</div>
<div class="username"><MkAcct :user="note.user"/></div>
<div class="admin" v-if="note.user.isAdmin"><i class="fas fa-bookmark"></i></div>
<div class="moderator" v-if="!note.user.isAdmin && note.user.isModerator"><i class="far fa-bookmark"></i></div>
<div class="info">
<span class="mobile" v-if="note.viaMobile"><i class="fas fa-mobile-alt"></i></span>
<MkA class="created-at" :to="notePage(note)">
@@ -55,6 +55,7 @@ export default defineComponent({
white-space: nowrap;
> .name {
flex-shrink: 1;
display: block;
margin: 0 .5em 0 0;
padding: 0;
@@ -81,17 +82,20 @@ export default defineComponent({
> .admin,
> .moderator {
flex-shrink: 0;
margin-right: 0.5em;
color: var(--badge);
}
> .username {
flex-shrink: 9999999;
margin: 0 .5em 0 0;
overflow: hidden;
text-overflow: ellipsis;
}
> .info {
flex-shrink: 0;
margin-left: auto;
font-size: 0.9em;
+32
View File
@@ -51,6 +51,13 @@
<MkA class="reply" v-if="appearNote.replyId" :to="`/notes/${appearNote.replyId}`"><i class="fas fa-reply"></i></MkA>
<Mfm v-if="appearNote.text" :text="appearNote.text" :author="appearNote.user" :i="$i" :custom-emojis="appearNote.emojis"/>
<a class="rp" v-if="appearNote.renote != null">RN:</a>
<div class="translation" v-if="translating || translation">
<MkLoading v-if="translating" mini/>
<div class="translated" v-else>
<b>{{ $t('translatedFrom', { x: translation.sourceLang }) }}:</b>
{{ translation.text }}
</div>
</div>
</div>
<div class="files" v-if="appearNote.files.length > 0">
<XMediaList :media-list="appearNote.files"/>
@@ -164,6 +171,8 @@ export default defineComponent({
collapsed: false,
isDeleted: false,
muted: false,
translation: null,
translating: false,
};
},
@@ -594,6 +603,11 @@ export default defineComponent({
text: this.$ts.share,
action: this.share
},
this.$instance.translatorAvailable ? {
icon: 'fas fa-language',
text: this.$ts.translate,
action: this.translate
} : undefined,
null,
statePromise.then(state => state.isFavorited ? {
icon: 'fas fa-star',
@@ -827,6 +841,17 @@ export default defineComponent({
});
},
async translate() {
if (this.translation != null) return;
this.translating = true;
const res = await os.api('notes/translate', {
noteId: this.appearNote.id,
targetLang: localStorage.getItem('lang') || navigator.language,
});
this.translating = false;
this.translation = res;
},
focus() {
this.$el.focus();
},
@@ -1053,6 +1078,13 @@ export default defineComponent({
font-style: oblique;
color: var(--renote);
}
> .translation {
border: solid 0.5px var(--divider);
border-radius: var(--radius);
padding: 12px;
margin-top: 8px;
}
}
> .url-preview {
+22 -3
View File
@@ -9,7 +9,7 @@
<div>{{ $ts.noNotes }}</div>
</div>
<div v-else>
<div v-else class="giivymft" :class="{ noGap }">
<div v-show="more && reversed" style="margin-bottom: var(--margin);">
<MkButton style="margin: 0 auto;" @click="fetchMoreFeature" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }">
<template v-if="!moreFetching">{{ $ts.loadMore }}</template>
@@ -17,8 +17,8 @@
</MkButton>
</div>
<XList ref="notes" :items="notes" v-slot="{ item: note }" :direction="reversed ? 'up' : 'down'" :reversed="reversed" :no-gap="noGap" :ad="true">
<XNote :note="note" class="_block" @update:note="updated(note, $event)" :key="note._featuredId_ || note._prId_ || note.id"/>
<XList ref="notes" :items="notes" v-slot="{ item: note }" :direction="reversed ? 'up' : 'down'" :reversed="reversed" :no-gap="noGap" :ad="true" class="notes">
<XNote class="qtqtichx" :note="note" @update:note="updated(note, $event)" :key="note._featuredId_ || note._prId_ || note.id"/>
</XList>
<div v-show="more && !reversed" style="margin-top: var(--margin);">
@@ -108,4 +108,23 @@ export default defineComponent({
.fade-leave-to {
opacity: 0;
}
.giivymft {
&.noGap {
> .notes {
background: var(--panel);
}
}
&:not(.noGap) {
> .notes {
background: var(--bg);
.qtqtichx {
background: var(--panel);
border-radius: var(--radius);
}
}
}
}
</style>
+5 -1
View File
@@ -7,7 +7,7 @@
<p class="mfcuwfyp" v-else-if="empty">{{ $ts.noNotifications }}</p>
<div v-else>
<XList class="notifications" :items="items" v-slot="{ item: notification }" :no-gap="true">
<XList class="elsfgstc" :items="items" v-slot="{ item: notification }" :no-gap="true">
<XNote v-if="['reply', 'quote', 'mention'].includes(notification.type)" :note="notification.note" @update:note="noteUpdated(notification.note, $event)" :key="notification.id"/>
<XNotification v-else :notification="notification" :with-time="true" :full="true" class="_panel notification" :key="notification.id"/>
</XList>
@@ -141,4 +141,8 @@ export default defineComponent({
text-align: center;
color: var(--fg);
}
.elsfgstc {
background: var(--panel);
}
</style>
+1 -1
View File
@@ -8,7 +8,7 @@
@closed="$emit('closed')"
>
<template #header>
<XHeader :info="pageInfo" :back-button="history.length > 0" @back="back()" :close-button="true" @close="close()"/>
<XHeader :info="pageInfo" :back-button="history.length > 0" @back="back()" :close-button="true" @close="close()" :title-only="true"/>
</template>
<div class="yrolvcoq _flat_">
<component :is="component" v-bind="props" :ref="changePage"/>
+8 -3
View File
@@ -17,7 +17,7 @@
<span v-if="visibility === 'followers'"><i class="fas fa-unlock"></i></span>
<span v-if="visibility === 'specified'"><i class="fas fa-envelope"></i></span>
</button>
<button class="submit _buttonPrimary" :disabled="!canPost" @click="post">{{ submitText }}<i :class="reply ? 'fas fa-reply' : renote ? 'fas fa-quote-right' : 'fas fa-paper-plane'"></i></button>
<button class="submit _buttonPrimary" :disabled="!canPost" @click="post" data-cy-open-post-form-submit>{{ submitText }}<i :class="reply ? 'fas fa-reply' : renote ? 'fas fa-quote-right' : 'fas fa-paper-plane'"></i></button>
</div>
</header>
<div class="form" :class="{ fixed }">
@@ -36,7 +36,7 @@
</div>
<MkInfo warn v-if="hasNotSpecifiedMentions" class="hasNotSpecifiedMentions">{{ $ts.notSpecifiedMentionWarning }} - <button class="_textButton" @click="addMissingMention()">{{ $ts.add }}</button></MkInfo>
<input v-show="useCw" ref="cw" class="cw" v-model="cw" :placeholder="$ts.annotation" @keydown="onKeydown">
<textarea v-model="text" class="text" :class="{ withCw: useCw }" ref="text" :disabled="posting" :placeholder="placeholder" @keydown="onKeydown" @paste="onPaste" @compositionupdate="onCompositionUpdate" @compositionend="onCompositionEnd" />
<textarea v-model="text" class="text" :class="{ withCw: useCw }" ref="text" :disabled="posting" :placeholder="placeholder" @keydown="onKeydown" @paste="onPaste" @compositionupdate="onCompositionUpdate" @compositionend="onCompositionEnd" data-cy-post-form-text/>
<input v-show="withHashtags" ref="hashtags" class="hashtags" v-model="hashtags" :placeholder="$ts.hashtags" list="hashtags">
<XPostFormAttaches class="attaches" :files="files" @updated="updateFiles" @detach="detachFile" @changeSensitive="updateFileSensitive" @changeName="updateFileName"/>
<XPollEditor v-if="poll" :poll="poll" @destroyed="poll = null" @updated="onPollUpdate"/>
@@ -339,7 +339,12 @@ export default defineComponent({
this.cw = init.cw;
this.useCw = init.cw != null;
if (init.poll) {
this.poll = init.poll;
this.poll = {
choices: init.poll.choices.map(x => x.text),
multiple: init.poll.multiple,
expiresAt: init.poll.expiresAt,
expiredAfter: init.poll.expiredAfter,
};
}
this.visibility = init.visibility;
this.localOnly = init.localOnly;
+34 -17
View File
@@ -3,11 +3,11 @@
<div class="auth _section">
<div class="avatar" :style="{ backgroundImage: user ? `url('${ user.avatarUrl }')` : null }" v-show="withAvatar"></div>
<div class="normal-signin" v-if="!totpLogin">
<MkInput v-model="username" :placeholder="$ts.username" type="text" pattern="^[a-zA-Z0-9_]+$" spellcheck="false" autofocus required @update:modelValue="onUsernameChange">
<MkInput v-model="username" :placeholder="$ts.username" type="text" pattern="^[a-zA-Z0-9_]+$" spellcheck="false" autofocus required @update:modelValue="onUsernameChange" data-cy-signin-username>
<template #prefix>@</template>
<template #suffix>@{{ host }}</template>
</MkInput>
<MkInput v-model="password" :placeholder="$ts.password" type="password" :with-password-toggle="true" v-if="!user || user && !user.usePasswordLessLogin" required>
<MkInput v-model="password" :placeholder="$ts.password" type="password" :with-password-toggle="true" v-if="!user || user && !user.usePasswordLessLogin" required data-cy-signin-password>
<template #prefix><i class="fas fa-lock"></i></template>
<template #caption><button class="_textButton" @click="resetPassword" type="button">{{ $ts.forgotPassword }}</button></template>
</MkInput>
@@ -54,6 +54,7 @@ import { apiUrl, host } from '@client/config';
import { byteify, hexify } from '@client/scripts/2fa';
import * as os from '@client/os';
import { login } from '@client/account';
import { showSuspendedDialog } from '../scripts/show-suspended-dialog';
export default defineComponent({
components: {
@@ -111,7 +112,9 @@ export default defineComponent({
onLogin(res) {
if (this.autoSet) {
login(res.i);
return login(res.i);
} else {
return;
}
},
@@ -144,7 +147,7 @@ export default defineComponent({
});
}).then(res => {
this.$emit('login', res);
this.onLogin(res);
return this.onLogin(res);
}).catch(err => {
if (err === null) return;
os.dialog({
@@ -167,15 +170,7 @@ export default defineComponent({
this.signing = false;
this.challengeData = res;
return this.queryKey();
}).catch(() => {
os.dialog({
type: 'error',
text: this.$ts.signinFailed
});
this.challengeData = null;
this.totpLogin = false;
this.signing = false;
});
}).catch(this.loginFailed);
} else {
this.totpLogin = true;
this.signing = false;
@@ -188,14 +183,36 @@ export default defineComponent({
}).then(res => {
this.$emit('login', res);
this.onLogin(res);
}).catch(() => {
}).catch(this.loginFailed);
}
},
loginFailed(err) {
switch (err.id) {
case '6cc579cc-885d-43d8-95c2-b8c7fc963280': {
os.dialog({
type: 'error',
text: this.$ts.loginFailed
title: this.$ts.loginFailed,
text: this.$ts.noSuchUser
});
this.signing = false;
});
break;
}
case 'e03a5f46-d309-4865-9b69-56282d94e1eb': {
showSuspendedDialog();
break;
}
default: {
os.dialog({
type: 'error',
title: this.$ts.loginFailed,
text: JSON.stringify(err)
});
}
}
this.challengeData = null;
this.totpLogin = false;
this.signing = false;
},
resetPassword() {
+10 -10
View File
@@ -1,12 +1,12 @@
<template>
<form class="mk-signup" @submit.prevent="onSubmit" :autocomplete="Math.random()">
<form class="qlvuhzng" @submit.prevent="onSubmit" :autocomplete="Math.random()">
<template v-if="meta">
<MkInput v-if="meta.disableRegistration" v-model="invitationCode" type="text" :autocomplete="Math.random()" spellcheck="false" required>
<MkInput class="_inputNoTopMargin" v-if="meta.disableRegistration" v-model="invitationCode" type="text" :autocomplete="Math.random()" spellcheck="false" required>
<template #label>{{ $ts.invitationCode }}</template>
<template #prefix><i class="fas fa-key"></i></template>
</MkInput>
<MkInput v-model="username" type="text" pattern="^[a-zA-Z0-9_]{1,20}$" :autocomplete="Math.random()" spellcheck="false" required @update:modelValue="onChangeUsername">
<template #label>{{ $ts.username }}</template>
<MkInput class="_inputNoTopMargin" v-model="username" type="text" pattern="^[a-zA-Z0-9_]{1,20}$" :autocomplete="Math.random()" spellcheck="false" required @update:modelValue="onChangeUsername" data-cy-signup-username>
<template #label>{{ $ts.username }} <div class="_button _help" v-tooltip:dialog="$ts.usernameInfo"><i class="far fa-question-circle"></i></div></template>
<template #prefix>@</template>
<template #suffix>@{{ host }}</template>
<template #caption>
@@ -19,7 +19,7 @@
<span v-if="usernameState == 'max-range'" style="color: var(--error)"><i class="fas fa-exclamation-triangle fa-fw"></i> {{ $ts.tooLong }}</span>
</template>
</MkInput>
<MkInput v-model="password" type="password" :autocomplete="Math.random()" required @update:modelValue="onChangePassword">
<MkInput v-model="password" type="password" :autocomplete="Math.random()" required @update:modelValue="onChangePassword" data-cy-signup-password>
<template #label>{{ $ts.password }}</template>
<template #prefix><i class="fas fa-lock"></i></template>
<template #caption>
@@ -28,7 +28,7 @@
<span v-if="passwordStrength == 'high'" style="color: var(--success)"><i class="fas fa-check fa-fw"></i> {{ $ts.strongPassword }}</span>
</template>
</MkInput>
<MkInput v-model="retypedPassword" type="password" :autocomplete="Math.random()" required @update:modelValue="onChangePasswordRetype">
<MkInput v-model="retypedPassword" type="password" :autocomplete="Math.random()" required @update:modelValue="onChangePasswordRetype" data-cy-signup-password-retype>
<template #label>{{ $ts.password }} ({{ $ts.retype }})</template>
<template #prefix><i class="fas fa-lock"></i></template>
<template #caption>
@@ -46,7 +46,7 @@
</label>
<captcha v-if="meta.enableHcaptcha" class="captcha" provider="hcaptcha" ref="hcaptcha" v-model:value="hCaptchaResponse" :sitekey="meta.hcaptchaSiteKey"/>
<captcha v-if="meta.enableRecaptcha" class="captcha" provider="recaptcha" ref="recaptcha" v-model:value="reCaptchaResponse" :sitekey="meta.recaptchaSiteKey"/>
<MkButton type="submit" :disabled="shouldDisableSubmitting" primary>{{ $ts.start }}</MkButton>
<MkButton type="submit" :disabled="shouldDisableSubmitting" primary data-cy-signup-submit>{{ $ts.start }}</MkButton>
</template>
</form>
</template>
@@ -178,14 +178,14 @@ export default defineComponent({
'hcaptcha-response': this.hCaptchaResponse,
'g-recaptcha-response': this.reCaptchaResponse,
}).then(() => {
os.api('signin', {
return os.api('signin', {
username: this.username,
password: this.password
}).then(res => {
this.$emit('signup', res);
if (this.autoSet) {
login(res.i);
return login(res.i);
}
});
}).catch(() => {
@@ -204,7 +204,7 @@ export default defineComponent({
</script>
<style lang="scss" scoped>
.mk-signup {
.qlvuhzng {
.captcha {
margin: 16px 0;
}
+180
View File
@@ -0,0 +1,180 @@
<template>
<span class="mk-sparkle">
<span ref="content">
<slot></slot>
</span>
<canvas ref="canvas"></canvas>
</span>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import * as os from '@client/os';
const sprite = new Image();
sprite.src = "/static-assets/client/sparkle-spritesheet.png";
export default defineComponent({
props: {
count: {
type: Number,
required: true,
},
speed: {
type: Number,
required: true,
},
},
data() {
return {
sprites: [0,6,13,20],
particles: [],
anim: null,
ctx: null,
};
},
methods: {
createSparkles(w, h, count) {
var holder = [];
for (var i = 0; i < count; i++) {
const color = '#' + ('000000' + Math.floor(Math.random() * 16777215).toString(16)).slice(-6);
holder[i] = {
position: {
x: Math.floor(Math.random() * w),
y: Math.floor(Math.random() * h)
},
style: this.sprites[ Math.floor(Math.random() * 4) ],
delta: {
x: Math.floor(Math.random() * 1000) - 500,
y: Math.floor(Math.random() * 1000) - 500
},
color: color,
opacity: Math.random(),
};
}
return holder;
},
draw(time) {
this.ctx.clearRect(0, 0, this.$refs.canvas.width, this.$refs.canvas.height);
this.ctx.beginPath();
const particleSize = Math.floor(this.fontSize / 2);
this.particles.forEach((particle) => {
var modulus = Math.floor(Math.random()*7);
if (Math.floor(time) % modulus === 0) {
particle.style = this.sprites[ Math.floor(Math.random()*4) ];
}
this.ctx.save();
this.ctx.globalAlpha = particle.opacity;
this.ctx.drawImage(sprite, particle.style, 0, 7, 7, particle.position.x, particle.position.y, particleSize, particleSize);
this.ctx.globalCompositeOperation = "source-atop";
this.ctx.globalAlpha = 0.5;
this.ctx.fillStyle = particle.color;
this.ctx.fillRect(particle.position.x, particle.position.y, particleSize, particleSize);
this.ctx.restore();
});
this.ctx.stroke();
},
tick() {
this.anim = window.requestAnimationFrame((time) => {
if (!this.$refs.canvas) {
return;
}
this.particles.forEach((particle) => {
if (!particle) {
return;
}
var randX = Math.random() > Math.random() * 2;
var randY = Math.random() > Math.random() * 3;
if (randX) {
particle.position.x += (particle.delta.x * this.speed) / 1500;
}
if (!randY) {
particle.position.y -= (particle.delta.y * this.speed) / 800;
}
if( particle.position.x > this.$refs.canvas.width ) {
particle.position.x = -7;
} else if (particle.position.x < -7) {
particle.position.x = this.$refs.canvas.width;
}
if (particle.position.y > this.$refs.canvas.height) {
particle.position.y = -7;
particle.position.x = Math.floor(Math.random() * this.$refs.canvas.width);
} else if (particle.position.y < -7) {
particle.position.y = this.$refs.canvas.height;
particle.position.x = Math.floor(Math.random() * this.$refs.canvas.width);
}
particle.opacity -= 0.005;
if (particle.opacity <= 0) {
particle.opacity = 1;
}
});
this.draw(time);
this.tick();
});
},
resize() {
if (this.$refs.content) {
const contentRect = this.$refs.content.getBoundingClientRect();
this.fontSize = parseFloat(getComputedStyle(this.$refs.content).fontSize);
const padding = this.fontSize * 0.2;
this.$refs.canvas.width = parseInt(contentRect.width + padding);
this.$refs.canvas.height = parseInt(contentRect.height + padding);
this.particles = this.createSparkles(this.$refs.canvas.width, this.$refs.canvas.height, this.count);
}
},
},
mounted() {
this.ctx = this.$refs.canvas.getContext('2d');
new ResizeObserver(this.resize).observe(this.$refs.content);
this.resize();
this.tick();
},
updated() {
this.resize();
},
destroyed() {
window.cancelAnimationFrame(this.anim);
},
});
</script>
<style lang="scss" scoped>
.mk-sparkle {
position: relative;
display: inline-block;
> span {
display: inline-block;
}
> canvas {
position: absolute;
top: -0.1em;
left: -0.1em;
pointer-events: none;
}
}
</style>
+2 -1
View File
@@ -99,7 +99,8 @@ export default defineComponent({
z-index: 10;
position: sticky;
top: var(--stickyTop, 0px);
background: var(--panel);
padding: var(--x-padding);
background: var(--x-header, var(--panel));
/* TODO panel
background: var(--X17);
-webkit-backdrop-filter: var(--blur, blur(8px));
+1 -1
View File
@@ -245,7 +245,7 @@ export default defineComponent({
font-size: 1em;
color: var(--fg);
background: var(--panel);
border: solid 1px var(--inputBorder);
border: solid 0.5px var(--inputBorder);
border-radius: 6px;
outline: none;
box-shadow: none;
+19 -14
View File
@@ -41,7 +41,7 @@
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
import { defineComponent, ref, unref } from 'vue';
import { focusPrev, focusNext } from '@client/scripts/focus';
import contains from '@client/scripts/contains';
@@ -79,21 +79,26 @@ export default defineComponent({
};
},
},
created() {
const items = ref(this.items.filter(item => item !== undefined));
watch: {
items: {
handler() {
const items = ref(unref(this.items).filter(item => item !== undefined));
for (let i = 0; i < items.value.length; i++) {
const item = items.value[i];
if (item && item.then) { // if item is Promise
items.value[i] = { type: 'pending' };
item.then(actualItem => {
items.value[i] = actualItem;
});
}
for (let i = 0; i < items.value.length; i++) {
const item = items.value[i];
if (item && item.then) { // if item is Promise
items.value[i] = { type: 'pending' };
item.then(actualItem => {
items.value[i] = actualItem;
});
}
}
this._items = items;
},
immediate: true
}
this._items = items;
},
mounted() {
if (this.viaKeyboard) {
+1 -1
View File
@@ -1,5 +1,5 @@
<template>
<transition :name="$store.state.animation ? 'popup-menu' : ''" :duration="$store.state.animation ? 300 : 0" appear @after-leave="onClosed" @enter="$emit('opening')" @after-enter="childRendered">
<transition :name="$store.state.animation ? 'popup-menu' : ''" appear @after-leave="onClosed" @enter="$emit('opening')" @after-enter="childRendered">
<div v-show="manualShowing != null ? manualShowing : showing" class="ccczpooj" :class="{ front, fixed, top: position === 'top' }" ref="content" :style="{ pointerEvents: (manualShowing != null ? manualShowing : showing) ? 'auto' : 'none', '--transformOrigin': transformOrigin }">
<slot :point="point"></slot>
</div>
+1 -1
View File
@@ -212,7 +212,7 @@ export default defineComponent({
font-size: 1em;
color: var(--fg);
background: var(--panel);
border: solid 1px var(--inputBorder);
border: solid 0.5px var(--inputBorder);
border-radius: 6px;
outline: none;
box-shadow: none;
+58
View File
@@ -0,0 +1,58 @@
<template>
<MkModal ref="modal" @click="$refs.modal.close()" @closed="$emit('closed')">
<div class="ewlycnyt">
<div class="title">{{ $ts.misskeyUpdated }}</div>
<div class="version">{{ version }}🚀</div>
<MkButton full @click="whatIsNew">{{ $ts.whatIsNew }}</MkButton>
<MkButton primary full @click="$refs.modal.close()">{{ $ts.gotIt }}</MkButton>
</div>
</MkModal>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import MkModal from '@client/components/ui/modal.vue';
import MkButton from '@client/components/ui/button.vue';
import { version } from '@client/config';
export default defineComponent({
components: {
MkModal,
MkButton,
},
data() {
return {
version: version,
};
},
methods: {
whatIsNew() {
this.$refs.modal.close();
this.$router.push('/docs/general/changelog');
}
}
});
</script>
<style lang="scss" scoped>
.ewlycnyt {
position: relative;
padding: 32px;
min-width: 320px;
max-width: 480px;
box-sizing: border-box;
text-align: center;
background: var(--panel);
border-radius: var(--radius);
> .title {
font-weight: bold;
}
> .version {
margin: 1em 0;
}
}
</style>
+13 -1
View File
@@ -1,6 +1,6 @@
import { Directive, ref } from 'vue';
import { isDeviceTouch } from '@client/scripts/is-device-touch';
import { popup } from '@client/os';
import { popup, dialog } from '@client/os';
const start = isDeviceTouch ? 'touchstart' : 'mouseover';
const end = isDeviceTouch ? 'touchend' : 'mouseleave';
@@ -24,6 +24,18 @@ export default {
}
};
if (binding.arg === 'dialog') {
el.addEventListener('click', (ev) => {
ev.preventDefault();
ev.stopPropagation();
dialog({
type: 'info',
text: binding.value,
});
return false;
});
}
const show = e => {
if (!document.body.contains(el)) return;
if (self._close) return;
+42 -6
View File
@@ -4,9 +4,19 @@
import '@client/style.scss';
//#region account indexedDB migration
import { set } from '@client/scripts/idb-proxy';
if (localStorage.getItem('accounts') != null) {
set('accounts', JSON.parse(localStorage.getItem('accounts')));
localStorage.removeItem('accounts');
}
//#endregion
import * as Sentry from '@sentry/browser';
import { Integrations } from '@sentry/tracing';
import { computed, createApp, watch, markRaw } from 'vue';
import { computed, createApp, watch, markRaw, version as vueVersion } from 'vue';
import compareVersions from 'compare-versions';
import widgets from '@client/widgets';
import directives from '@client/directives';
@@ -16,7 +26,7 @@ import { router } from '@client/router';
import { applyTheme } from '@client/scripts/theme';
import { isDeviceDarkmode } from '@client/scripts/is-device-darkmode';
import { i18n } from '@client/i18n';
import { stream, dialog, post } from '@client/os';
import { stream, dialog, post, popup } from '@client/os';
import * as sound from '@client/scripts/sound';
import { $i, refreshAccount, login, updateAccount, signout } from '@client/account';
import { defaultStore, ColdDeviceStorage } from '@client/store';
@@ -37,6 +47,8 @@ window.onunhandledrejection = null;
if (_DEV_) {
console.warn('Development mode!!!');
console.info(`vue ${vueVersion}`);
(window as any).$i = $i;
(window as any).$store = defaultStore;
@@ -91,15 +103,12 @@ window.addEventListener('resize', () => {
});
//#endregion
// Get the <head> element
const head = document.getElementsByTagName('head')[0];
// If mobile, insert the viewport meta tag
if (isMobile || window.innerWidth <= 1024) {
const viewport = document.getElementsByName('viewport').item(0);
viewport.setAttribute('content',
`${viewport.getAttribute('content')},minimum-scale=1,maximum-scale=1,user-scalable=no`);
head.appendChild(viewport);
document.head.appendChild(viewport);
}
//#region Set lang attr
@@ -198,6 +207,26 @@ if (splash) {
splash.style.pointerEvents = 'none';
}
// クライアントが更新されたか?
const lastVersion = localStorage.getItem('lastVersion');
if (lastVersion !== version) {
localStorage.setItem('lastVersion', version);
// テーマリビルドするため
localStorage.removeItem('theme');
try { // 変なバージョン文字列来るとcompareVersionsでエラーになるため
if (lastVersion != null && compareVersions(version, lastVersion) === 1) {
// ログインしてる場合だけ
if ($i) {
popup(import('@client/components/updated.vue'), {}, {}, 'closed');
}
}
} catch (e) {
}
}
// NOTE: この処理は必ず↑のクライアント更新時処理より後に来ること(テーマ再構築のため)
watch(defaultStore.reactiveState.darkMode, (darkMode) => {
applyTheme(darkMode ? ColdDeviceStorage.get('darkTheme') : ColdDeviceStorage.get('lightTheme'));
}, { immediate: localStorage.theme == null });
@@ -283,6 +312,13 @@ for (const plugin of ColdDeviceStorage.get('plugins').filter(p => p.active)) {
}
if ($i) {
if ($i.isDeleted) {
dialog({
type: 'warning',
text: i18n.locale.accountDeletionInProgress,
});
}
if ('Notification' in window) {
// 許可を得ていなかったらリクエスト
if (Notification.permission === 'default') {
+2
View File
@@ -25,6 +25,7 @@ export async function fetchInstance() {
}
export const emojiCategories = computed(() => {
if (instance.emojis == null) return [];
const categories = new Set();
for (const emoji of instance.emojis) {
categories.add(emoji.category);
@@ -33,6 +34,7 @@ export const emojiCategories = computed(() => {
});
export const emojiTags = computed(() => {
if (instance.emojis == null) return [];
const tags = new Set();
for (const emoji of instance.emojis) {
for (const tag of emoji.aliases) {
+42 -3
View File
@@ -1,9 +1,10 @@
import { computed } from 'vue';
import { computed, ref } from 'vue';
import { search } from '@client/scripts/search';
import * as os from '@client/os';
import { i18n } from '@client/i18n';
import { $i } from './account';
import { unisonReload } from '@client/scripts/unison-reload';
import { router } from './router';
export const menuDef = {
notifications: {
@@ -58,7 +59,26 @@ export const menuDef = {
title: 'lists',
icon: 'fas fa-list-ul',
show: computed(() => $i != null),
to: '/my/lists',
active: computed(() => router.currentRoute.value.path.startsWith('/timeline/list/') || router.currentRoute.value.path === '/my/lists' || router.currentRoute.value.path.startsWith('/my/lists/')),
action: (ev) => {
const items = ref([{
type: 'pending'
}]);
os.api('users/lists/list').then(lists => {
const _items = [...lists.map(list => ({
type: 'link',
text: list.name,
to: `/timeline/list/${list.id}`
})), null, {
type: 'link',
to: '/my/lists',
text: i18n.locale.manageLists,
icon: 'fas fa-cog',
}];
items.value = _items;
});
os.popupMenu(items, ev.currentTarget || ev.target);
},
},
groups: {
title: 'groups',
@@ -70,7 +90,26 @@ export const menuDef = {
title: 'antennas',
icon: 'fas fa-satellite',
show: computed(() => $i != null),
to: '/my/antennas',
active: computed(() => router.currentRoute.value.path.startsWith('/timeline/antenna/') || router.currentRoute.value.path === '/my/antennas' || router.currentRoute.value.path.startsWith('/my/antennas/')),
action: (ev) => {
const items = ref([{
type: 'pending'
}]);
os.api('antennas/list').then(antennas => {
const _items = [...antennas.map(antenna => ({
type: 'link',
text: antenna.name,
to: `/timeline/antenna/${antenna.id}`
})), null, {
type: 'link',
to: '/my/antennas',
text: i18n.locale.manageAntennas,
icon: 'fas fa-cog',
}];
items.value = _items;
});
os.popupMenu(items, ev.currentTarget || ev.target);
},
},
mentions: {
title: 'mentions',
+6 -2
View File
@@ -214,7 +214,11 @@ export function modalPageWindow(path: string) {
}, {}, 'closed');
}
export function dialog(props: Record<string, any>) {
export function dialog(props: {
type: 'error' | 'info' | 'success' | 'warning' | 'waiting';
title?: string | null;
text?: string | null;
}) {
return new Promise((resolve, reject) => {
popup(import('@client/components/dialog.vue'), props, {
done: result => {
@@ -368,7 +372,7 @@ export async function openEmojiPicker(src?: HTMLElement, opts, initialTextarea:
});
}
export function popupMenu(items: any[], src?: HTMLElement, options?: { align?: string; viaKeyboard?: boolean }) {
export function popupMenu(items: any[] | Ref<any[]>, src?: HTMLElement, options?: { align?: string; viaKeyboard?: boolean }) {
return new Promise((resolve, reject) => {
let dispose;
popup(import('@client/components/ui/popup-menu.vue'), {
+4 -16
View File
@@ -4,14 +4,14 @@
<div id="debug"></div>
<section class="_formItem about">
<div class="_formPanel panel" :class="{ playing: easterEggEngine != null }" ref="about">
<img src="/static-assets/client/about-icon.png" alt="" class="icon" ref="icon" @load="iconLoaded" draggable="false"/>
<img src="/static-assets/client/about-icon.png" alt="" class="icon" @load="iconLoaded" draggable="false" @click="gravity"/>
<div class="misskey">Misskey</div>
<div class="version">v{{ version }}</div>
<span class="emoji" v-for="emoji in easterEggEmojis" :key="emoji.id" :data-physics-x="emoji.left" :data-physics-y="emoji.top" :class="{ _physics_circle_: !emoji.emoji.startsWith(':') }"><MkEmoji class="emoji" :emoji="emoji.emoji" :custom-emojis="$instance.emojis" :is-reaction="false" :normal="true" :no-style="true"/></span>
</div>
</section>
<section class="_formItem" style="text-align: center; padding: 0 16px;" @click="gravity">
{{ $ts._aboutMisskey.about }}
<section class="_formItem" style="text-align: center; padding: 0 16px;">
{{ $ts._aboutMisskey.about }}<br><MkA class="_link" to="/docs/general/misskey">{{ $ts.learnMore }}</MkA>
</section>
<FormGroup>
<FormLink to="https://github.com/misskey-dev/misskey" external>
@@ -54,15 +54,13 @@
<script lang="ts">
import { defineComponent } from 'vue';
import VanillaTilt from 'vanilla-tilt';
import { version } from '@client/config';
import FormLink from '@client/components/form/link.vue';
import FormBase from '@client/components/form/base.vue';
import FormGroup from '@client/components/form/group.vue';
import FormKeyValueView from '@client/components/form/key-value-view.vue';
import MkLink from '@client/components/link.vue';
import { physics } from '@client/scripts/physics.ts';
import * as os from '@client/os';
import { physics } from '@client/scripts/physics';
import * as symbols from '@client/symbols';
const patrons = [
@@ -145,15 +143,6 @@ export default defineComponent({
}
},
mounted() {
VanillaTilt.init(this.$refs.icon, {
max: 30,
perspective: 500,
scale: 1.125,
speed: 1000,
});
},
beforeUnmount() {
if (this.easterEggEngine) {
this.easterEggEngine.stop();
@@ -181,7 +170,6 @@ export default defineComponent({
gravity() {
if (!this.easterEggReady) return;
this.easterEggReady = false;
this.$refs.icon.vanillaTilt.destroy();
this.easterEggEngine = physics(this.$refs.about);
}
}
+147
View File
@@ -0,0 +1,147 @@
<template>
<div class="tqmomfks" v-hotkey.global="keymap" v-size="{ min: [800] }">
<div class="new" v-if="queue > 0"><button class="_buttonPrimary" @click="top()">{{ $ts.newNoteRecived }}</button></div>
<div class="tl _block">
<XTimeline ref="tl" class="tl"
:key="antennaId"
src="antenna"
:antenna="antennaId"
:sound="true"
@before="before()"
@after="after()"
@queue="queueUpdated"
/>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent, defineAsyncComponent, computed } from 'vue';
import Progress from '@client/scripts/loading';
import XTimeline from '@client/components/timeline.vue';
import { scroll } from '@client/scripts/scroll';
import * as os from '@client/os';
import * as symbols from '@client/symbols';
export default defineComponent({
components: {
XTimeline,
},
props: {
antennaId: {
type: String,
required: true
}
},
data() {
return {
antenna: null,
queue: 0,
[symbols.PAGE_INFO]: computed(() => this.antenna ? {
title: this.antenna.name,
icon: 'fas fa-satellite',
bg: 'var(--bg)',
actions: [{
icon: 'fas fa-calendar-alt',
text: this.$ts.jumpToSpecifiedDate,
handler: this.timetravel
}, {
icon: 'fas fa-cog',
text: this.$ts.settings,
handler: this.settings
}],
} : null),
};
},
computed: {
keymap(): any {
return {
't': this.focus
};
},
},
watch: {
antennaId: {
async handler() {
this.antenna = await os.api('antennas/show', {
antennaId: this.antennaId
});
},
immediate: true
}
},
methods: {
before() {
Progress.start();
},
after() {
Progress.done();
},
queueUpdated(q) {
this.queue = q;
},
top() {
scroll(this.$el, 0);
},
async timetravel() {
const { canceled, result: date } = await os.dialog({
title: this.$ts.date,
input: {
type: 'date'
}
});
if (canceled) return;
this.$refs.tl.timetravel(new Date(date));
},
settings() {
this.$router.push(`/my/antennas/${this.antennaId}`);
},
focus() {
(this.$refs.tl as any).focus();
}
}
});
</script>
<style lang="scss" scoped>
.tqmomfks {
padding: var(--margin);
> .new {
position: sticky;
top: calc(var(--stickyTop, 0px) + 16px);
z-index: 1000;
width: 100%;
> button {
display: block;
margin: var(--margin) auto 0 auto;
padding: 8px 16px;
border-radius: 32px;
}
}
> .tl {
background: var(--bg);
border-radius: var(--radius);
overflow: clip;
}
&.min-width_800px {
max-width: 800px;
margin: 0 auto;
}
}
</style>
+1 -1
View File
@@ -1,7 +1,7 @@
<template>
<div class="_root">
<div class="_block" style="padding: 24px;">
<MkInput v-model="endpoint" :datalist="endpoints" @update:modelValue="onEndpointChange()">
<MkInput v-model="endpoint" :datalist="endpoints" @update:modelValue="onEndpointChange()" class="_inputNoTopMargin">
<template #label>Endpoint</template>
</MkInput>
<MkTextarea v-model="body" code>
+86 -73
View File
@@ -1,50 +1,54 @@
<template>
<div class="vtaihdtm">
<div class="search">
<MkInput v-model="query" :debounce="true" type="search" class="_inputNoTopMargin _inputNoBottomMargin" :placeholder="$ts.search">
<template #prefix><i class="fas fa-search"></i></template>
</MkInput>
<div class="body">
<div class="search">
<MkInput v-model="query" :debounce="true" type="search" class="_inputNoTopMargin _inputNoBottomMargin" :placeholder="$ts.search">
<template #prefix><i class="fas fa-search"></i></template>
</MkInput>
</div>
<div class="list">
<MkFolder>
<template #header>{{ $ts._docs.generalTopics }}</template>
<div class="docs">
<MkA v-for="doc in docs.filter(doc => doc.path.startsWith('general/'))" :key="doc.path" :to="`/docs/${doc.path}`" class="doc">
<div class="title">{{ doc.title }}</div>
<div class="summary">{{ doc.summary }}</div>
<div class="read">{{ $ts._docs.continueReading }}</div>
</MkA>
</div>
</MkFolder>
<MkFolder>
<template #header>{{ $ts._docs.features }}</template>
<div class="docs">
<MkA v-for="doc in docs.filter(doc => doc.path.startsWith('features/'))" :key="doc.path" :to="`/docs/${doc.path}`" class="doc">
<div class="title">{{ doc.title }}</div>
<div class="summary">{{ doc.summary }}</div>
<div class="read">{{ $ts._docs.continueReading }}</div>
</MkA>
</div>
</MkFolder>
<MkFolder>
<template #header>{{ $ts._docs.advancedTopics }}</template>
<div class="docs">
<MkA v-for="doc in docs.filter(doc => doc.path.startsWith('advanced/'))" :key="doc.path" :to="`/docs/${doc.path}`" class="doc">
<div class="title">{{ doc.title }}</div>
<div class="summary">{{ doc.summary }}</div>
<div class="read">{{ $ts._docs.continueReading }}</div>
</MkA>
</div>
</MkFolder>
<MkFolder>
<template #header>{{ $ts._docs.admin }}</template>
<div class="docs">
<MkA v-for="doc in docs.filter(doc => doc.path.startsWith('admin/'))" :key="doc.path" :to="`/docs/${doc.path}`" class="doc">
<div class="title">{{ doc.title }}</div>
<div class="summary">{{ doc.summary }}</div>
<div class="read">{{ $ts._docs.continueReading }}</div>
</MkA>
</div>
</MkFolder>
</div>
</div>
<MkFolder>
<template #header>{{ $ts._docs.generalTopics }}</template>
<div class="docs">
<MkA v-for="doc in docs.filter(doc => doc.path.startsWith('general/'))" :key="doc.path" :to="`/docs/${doc.path}`" class="doc">
<div class="title">{{ doc.title }}</div>
<div class="summary">{{ doc.summary }}</div>
<div class="read">{{ $ts._docs.continueReading }}</div>
</MkA>
</div>
</MkFolder>
<MkFolder>
<template #header>{{ $ts._docs.features }}</template>
<div class="docs">
<MkA v-for="doc in docs.filter(doc => doc.path.startsWith('features/'))" :key="doc.path" :to="`/docs/${doc.path}`" class="doc">
<div class="title">{{ doc.title }}</div>
<div class="summary">{{ doc.summary }}</div>
<div class="read">{{ $ts._docs.continueReading }}</div>
</MkA>
</div>
</MkFolder>
<MkFolder>
<template #header>{{ $ts._docs.advancedTopics }}</template>
<div class="docs">
<MkA v-for="doc in docs.filter(doc => doc.path.startsWith('advanced/'))" :key="doc.path" :to="`/docs/${doc.path}`" class="doc">
<div class="title">{{ doc.title }}</div>
<div class="summary">{{ doc.summary }}</div>
<div class="read">{{ $ts._docs.continueReading }}</div>
</MkA>
</div>
</MkFolder>
<MkFolder>
<template #header>{{ $ts._docs.admin }}</template>
<div class="docs">
<MkA v-for="doc in docs.filter(doc => doc.path.startsWith('admin/'))" :key="doc.path" :to="`/docs/${doc.path}`" class="doc">
<div class="title">{{ doc.title }}</div>
<div class="summary">{{ doc.summary }}</div>
<div class="read">{{ $ts._docs.continueReading }}</div>
</MkA>
</div>
</MkFolder>
</div>
</template>
@@ -97,41 +101,50 @@ export default defineComponent({
.vtaihdtm {
background: var(--panel);
> .search {
padding: 16px;
}
> .body {
max-width: 900px;
margin: 0 auto;
.docs {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(270px, 1fr));
grid-gap: 12px;
margin: 0 16px 16px 16px;
> .doc {
display: inline-block;
> .search {
padding: 16px;
border: solid 1px var(--divider);
border-radius: 6px;
}
&:hover {
border: solid 1px var(--accent);
text-decoration: none;
}
> .list {
padding: 0 16px;
> .title {
font-weight: bold;
}
.docs {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(270px, 1fr));
grid-gap: 12px;
margin: 0 0 16px 0;
> .summary {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
font-size: 0.9em;
}
> .doc {
display: inline-block;
padding: 16px;
border: solid 1px var(--divider);
border-radius: 6px;
> .read {
color: var(--link);
font-size: 0.9em;
&:hover {
border: solid 1px var(--accent);
text-decoration: none;
}
> .title {
font-weight: bold;
}
> .summary {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
font-size: 0.9em;
}
> .read {
color: var(--link);
font-size: 0.9em;
}
}
}
}
}
+134
View File
@@ -0,0 +1,134 @@
<template>
<div class="driuhtrh">
<div class="query">
<MkInput v-model="q" class="_inputNoTopMargin _inputNoBottomMargin" :placeholder="$ts.search">
<template #prefix><i class="fas fa-search"></i></template>
</MkInput>
<div class="tags">
<span class="tag _button" v-for="tag in tags" :class="{ active: selectedTags.has(tag) }" @click="toggleTag(tag)">{{ tag }}</span>
</div>
</div>
<MkFolder class="emojis" v-if="searchEmojis">
<template #header>{{ $ts.searchResult }}</template>
<div class="zuvgdzyt">
<XEmoji v-for="emoji in searchEmojis" :key="emoji.name" class="emoji" :emoji="emoji"/>
</div>
</MkFolder>
<MkFolder class="emojis" v-for="category in customEmojiCategories" :key="category">
<template #header>{{ category || $ts.other }}</template>
<div class="zuvgdzyt">
<XEmoji v-for="emoji in customEmojis.filter(e => e.category === category)" :key="emoji.name" class="emoji" :emoji="emoji"/>
</div>
</MkFolder>
</div>
</template>
<script lang="ts">
import { defineComponent, computed } from 'vue';
import MkButton from '@client/components/ui/button.vue';
import MkInput from '@client/components/ui/input.vue';
import MkSelect from '@client/components/ui/select.vue';
import MkFolder from '@client/components/ui/folder.vue';
import MkTab from '@client/components/tab.vue';
import * as os from '@client/os';
import * as symbols from '@client/symbols';
import { emojiCategories, emojiTags } from '@client/instance';
import XEmoji from './emojis.emoji.vue';
export default defineComponent({
components: {
MkButton,
MkInput,
MkSelect,
MkFolder,
MkTab,
XEmoji,
},
data() {
return {
q: '',
customEmojiCategories: emojiCategories,
customEmojis: this.$instance.emojis,
tags: emojiTags,
selectedTags: new Set(),
searchEmojis: null,
}
},
watch: {
q() { this.search(); },
selectedTags: {
handler() {
this.search();
},
deep: true
},
},
methods: {
search() {
if ((this.q === '' || this.q == null) && this.selectedTags.size === 0) {
this.searchEmojis = null;
return;
}
if (this.selectedTags.size === 0) {
this.searchEmojis = this.customEmojis.filter(e => e.name.includes(this.q) || e.aliases.includes(this.q));
} else {
this.searchEmojis = this.customEmojis.filter(e => (e.name.includes(this.q) || e.aliases.includes(this.q)) && [...this.selectedTags].every(t => e.aliases.includes(t)));
}
},
toggleTag(tag) {
if (this.selectedTags.has(tag)) {
this.selectedTags.delete(tag);
} else {
this.selectedTags.add(tag);
}
}
}
});
</script>
<style lang="scss" scoped>
.driuhtrh {
background: var(--bg);
> .query {
background: var(--bg);
padding: 16px;
> .tags {
> .tag {
display: inline-block;
margin: 8px 8px 0 0;
padding: 4px 8px;
font-size: 0.9em;
background: var(--accentedBg);
border-radius: 5px;
&.active {
background: var(--accent);
color: var(--fgOnAccent);
}
}
}
}
> .emojis {
--x-header: var(--bg);
--x-padding: 0 16px;
.zuvgdzyt {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
grid-gap: 12px;
margin: 0 var(--margin) var(--margin) var(--margin);
}
}
}
</style>
+92
View File
@@ -0,0 +1,92 @@
<template>
<button class="zuvgdzyu _button" @click="menu">
<img :src="emoji.url" class="img" :alt="emoji.name"/>
<div class="body">
<div class="name _monospace">{{ emoji.name }}</div>
<div class="info">{{ emoji.aliases.join(' ') }}</div>
</div>
</button>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import * as os from '@client/os';
import copyToClipboard from '@client/scripts/copy-to-clipboard';
import VanillaTilt from 'vanilla-tilt';
export default defineComponent({
props: {
emoji: {
type: Object,
required: true,
}
},
mounted() {
VanillaTilt.init(this.$el, {
reverse: true,
gyroscope: false,
scale: 1.1,
speed: 500,
});
},
methods: {
menu(ev) {
os.popupMenu([{
type: 'label',
text: ':' + this.emoji.name + ':',
}, {
text: this.$ts.copy,
icon: 'fas fa-copy',
action: () => {
copyToClipboard(`:${this.emoji.name}:`);
os.success();
}
}], ev.currentTarget || ev.target);
}
}
});
</script>
<style lang="scss" scoped>
.zuvgdzyu {
display: flex;
align-items: center;
padding: 12px;
text-align: left;
background: var(--panel);
border-radius: 8px;
transform-style: preserve-3d;
transform: perspective(1000px);
&:hover {
border-color: var(--accent);
}
> .img {
width: 42px;
height: 42px;
transform: translateZ(20px);
}
> .body {
padding: 0 0 0 8px;
white-space: nowrap;
overflow: hidden;
transform: translateZ(10px);
> .name {
text-overflow: ellipsis;
overflow: hidden;
}
> .info {
opacity: 0.5;
font-size: 0.9em;
text-overflow: ellipsis;
overflow: hidden;
}
}
}
</style>
+14 -129
View File
@@ -1,151 +1,36 @@
<template>
<div class="driuhtrh">
<div class="query">
<MkInput v-model="q" class="_inputNoTopMargin _inputNoBottomMargin" :placeholder="$ts.search">
<template #prefix><i class="fas fa-search"></i></template>
</MkInput>
</div>
<div class="emojis">
<MkFolder v-if="searchEmojis">
<template #header>{{ $ts.searchResult }}</template>
<div class="zuvgdzyt">
<button v-for="emoji in searchEmojis" :key="emoji.name" class="emoji _button" @click="menu(emoji, $event)">
<img :src="emoji.url" class="img" :alt="emoji.name"/>
<div class="body">
<div class="name _monospace">{{ emoji.name }}</div>
<div class="info">{{ emoji.aliases.join(' ') }}</div>
</div>
</button>
</div>
</MkFolder>
<MkFolder v-for="category in customEmojiCategories" :key="category">
<template #header>{{ category || $ts.other }}</template>
<div class="zuvgdzyt">
<button v-for="emoji in customEmojis.filter(e => e.category === category)" :key="emoji.name" class="emoji _button" @click="menu(emoji, $event)">
<img :src="emoji.url" class="img" :alt="emoji.name"/>
<div class="body">
<div class="name _monospace">{{ emoji.name }}</div>
<div class="info">{{ emoji.aliases.join(' ') }}</div>
</div>
</button>
</div>
</MkFolder>
</div>
<div :class="$style.root">
<XCategory v-if="tab === 'category'"/>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import MkButton from '@client/components/ui/button.vue';
import MkInput from '@client/components/ui/input.vue';
import MkSelect from '@client/components/ui/select.vue';
import MkFolder from '@client/components/ui/folder.vue';
import { defineComponent, computed } from 'vue';
import * as os from '@client/os';
import * as symbols from '@client/symbols';
import { emojiCategories } from '@client/instance';
import copyToClipboard from '@client/scripts/copy-to-clipboard';
import XCategory from './emojis.category.vue';
export default defineComponent({
components: {
MkButton,
MkInput,
MkSelect,
MkFolder,
XCategory,
},
data() {
return {
[symbols.PAGE_INFO]: {
[symbols.PAGE_INFO]: computed(() => ({
title: this.$ts.customEmojis,
icon: 'fas fa-laugh'
},
q: '',
customEmojiCategories: emojiCategories,
customEmojis: this.$instance.emojis,
searchEmojis: null,
icon: 'fas fa-laugh',
bg: 'var(--bg)',
})),
tab: 'category',
}
},
watch: {
q() {
if (this.q === '' || this.q == null) {
this.searchEmojis = null;
return;
}
this.searchEmojis = this.customEmojis.filter(e => e.name.includes(this.q) || e.aliases.includes(this.q));
}
},
methods: {
menu(emoji, ev) {
os.popupMenu([{
type: 'label',
text: ':' + emoji.name + ':',
}, {
text: this.$ts.copy,
icon: 'fas fa-copy',
action: () => {
copyToClipboard(`:${emoji.name}:`);
os.success();
}
}], ev.currentTarget || ev.target);
}
}
});
</script>
<style lang="scss" scoped>
.driuhtrh {
> .query {
background: var(--bg);
padding: 16px;
}
> .emojis {
.zuvgdzyt {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
grid-gap: 12px;
margin: 0 var(--margin) var(--margin) var(--margin);
> .emoji {
display: flex;
align-items: center;
padding: 12px;
text-align: left;
border: solid 1px var(--divider);
border-radius: 8px;
&:hover {
border-color: var(--accent);
}
> .img {
width: 42px;
height: 42px;
}
> .body {
padding: 0 0 0 8px;
white-space: nowrap;
overflow: hidden;
> .name {
text-overflow: ellipsis;
overflow: hidden;
}
> .info {
opacity: 0.5;
font-size: 0.9em;
text-overflow: ellipsis;
overflow: hidden;
}
}
}
}
}
<style lang="scss" module>
.root {
max-width: 1000px;
margin: 0 auto;
}
</style>
+19 -3
View File
@@ -1,6 +1,8 @@
<template>
<div class="_section">
<XNotes class="_content" :pagination="pagination" :detail="true" :prop="'note'" @before="before()" @after="after()"/>
<div class="jmelgwjh">
<div class="body">
<XNotes class="notes" :pagination="pagination" :detail="true" :prop="'note'" @before="before()" @after="after()"/>
</div>
</div>
</template>
@@ -20,7 +22,8 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: {
title: this.$ts.favorites,
icon: 'fas fa-star'
icon: 'fas fa-star',
bg: 'var(--bg)',
},
pagination: {
endpoint: 'i/favorites',
@@ -42,3 +45,16 @@ export default defineComponent({
}
});
</script>
<style lang="scss" scoped>
.jmelgwjh {
background: var(--bg);
> .body {
box-sizing: border-box;
max-width: 800px;
margin: 0 auto;
padding: 16px;
}
}
</style>
+6 -6
View File
@@ -28,14 +28,14 @@
<option value="-following">{{ $ts.following }} ({{ $ts.ascendingOrder }})</option>
<option value="+followers">{{ $ts.followers }} ({{ $ts.descendingOrder }})</option>
<option value="-followers">{{ $ts.followers }} ({{ $ts.ascendingOrder }})</option>
<option value="+caughtAt">{{ $ts.caughtAt }} ({{ $ts.descendingOrder }})</option>
<option value="-caughtAt">{{ $ts.caughtAt }} ({{ $ts.ascendingOrder }})</option>
<option value="+lastCommunicatedAt">{{ $ts.lastCommunicatedAt }} ({{ $ts.descendingOrder }})</option>
<option value="-lastCommunicatedAt">{{ $ts.lastCommunicatedAt }} ({{ $ts.ascendingOrder }})</option>
<option value="+caughtAt">{{ $ts.registeredAt }} ({{ $ts.descendingOrder }})</option>
<option value="-caughtAt">{{ $ts.registeredAt }} ({{ $ts.ascendingOrder }})</option>
<option value="+lastCommunicatedAt">{{ $ts.lastCommunication }} ({{ $ts.descendingOrder }})</option>
<option value="-lastCommunicatedAt">{{ $ts.lastCommunication }} ({{ $ts.ascendingOrder }})</option>
<option value="+driveUsage">{{ $ts.driveUsage }} ({{ $ts.descendingOrder }})</option>
<option value="-driveUsage">{{ $ts.driveUsage }} ({{ $ts.ascendingOrder }})</option>
<option value="+driveFiles">{{ $ts.driveFiles }} ({{ $ts.descendingOrder }})</option>
<option value="-driveFiles">{{ $ts.driveFiles }} ({{ $ts.ascendingOrder }})</option>
<option value="+driveFiles">{{ $ts.driveFilesCount }} ({{ $ts.descendingOrder }})</option>
<option value="-driveFiles">{{ $ts.driveFilesCount }} ({{ $ts.ascendingOrder }})</option>
</MkSelect>
</div>
</div>
+1 -3
View File
@@ -93,10 +93,8 @@ export default defineComponent({
});
if (canceled) return;
os.api('drive/files/delete', {
os.apiWithDialog('drive/files/delete', {
fileId: this.file.id
}).then(() => {
this.$refs.files.removeItem(x => x.id === this.file.id);
});
},
+15 -1
View File
@@ -7,7 +7,15 @@
Summaly Proxy URL
</FormInput>
</FormGroup>
<FormGroup>
<FormInput v-model:value="deeplAuthKey">
<template #prefix><i class="fas fa-key"></i></template>
DeepL Auth Key
</FormInput>
<FormSwitch v-model:value="deeplIsPro">
Pro account
</FormSwitch>
</FormGroup>
<FormButton @click="save" primary><i class="fas fa-save"></i> {{ $ts.save }}</FormButton>
</FormSuspense>
</FormBase>
@@ -44,6 +52,8 @@ export default defineComponent({
icon: 'fas fa-cogs'
},
summalyProxy: '',
deeplAuthKey: '',
deeplIsPro: false,
}
},
@@ -55,10 +65,14 @@ export default defineComponent({
async init() {
const meta = await os.api('meta', { detail: true });
this.summalyProxy = meta.summalyProxy;
this.deeplAuthKey = meta.deeplAuthKey;
this.deeplIsPro = meta.deeplIsPro;
},
save() {
os.apiWithDialog('admin/update-meta', {
summalyProxy: this.summalyProxy,
deeplAuthKey: this.deeplAuthKey,
deeplIsPro: this.deeplIsPro,
}).then(() => {
fetchInstance();
});
+12 -1
View File
@@ -271,6 +271,16 @@
</div>
</div>
</div>
<div class="section _block">
<div class="title">{{ $ts._mfm.sparkle }}</div>
<div class="content">
<p>{{ $ts._mfm.sparkleDescription }}</p>
<div class="preview">
<Mfm :text="preview_sparkle"/>
<MkTextarea v-model="preview_sparkle"><span>MFM</span></MkTextarea>
</div>
</div>
</div>
</div>
</template>
@@ -294,7 +304,7 @@ export default defineComponent({
preview_hashtag: '#test',
preview_url: `https://example.com`,
preview_link: `[${this.$ts._mfm.dummy}](https://example.com)`,
preview_emoji: `:${this.$instance.emojis[0].name}:`,
preview_emoji: this.$instance.emojis.length ? `:${this.$instance.emojis[0].name}:` : `:emojiname:`,
preview_bold: `**${this.$ts._mfm.dummy}**`,
preview_small: `<small>${this.$ts._mfm.dummy}</small>`,
preview_center: `<center>${this.$ts._mfm.dummy}</center>`,
@@ -317,6 +327,7 @@ export default defineComponent({
preview_x4: `$[x4 🍮]`,
preview_blur: `$[blur ${this.$ts._mfm.dummy}]`,
preview_rainbow: `$[rainbow 🍮]`,
preview_sparkle: `$[sparkle 🍮]`,
}
},
});
+80 -65
View File
@@ -1,37 +1,39 @@
<template>
<div class="fcuexfpr _root">
<transition name="fade" mode="out-in">
<div v-if="note" class="note">
<div class="_gap" v-if="showNext">
<XNotes class="_content" :pagination="next" :no-gap="true"/>
</div>
<div class="main _gap">
<MkButton v-if="!showNext && hasNext" class="load next" @click="showNext = true"><i class="fas fa-chevron-up"></i></MkButton>
<div class="_content _gap">
<MkRemoteCaution v-if="note.user.host != null" :href="note.url || note.uri" class="_gap"/>
<XNoteDetailed v-model:note="note" :key="note.id" class="_gap"/>
<div class="fcuexfpr">
<div class="_root">
<transition name="fade" mode="out-in">
<div v-if="note" class="note">
<div class="_gap" v-if="showNext">
<XNotes class="_content" :pagination="next" :no-gap="true"/>
</div>
<div class="_content clips _gap" v-if="clips && clips.length > 0">
<div class="title">{{ $ts.clip }}</div>
<MkA v-for="item in clips" :key="item.id" :to="`/clips/${item.id}`" class="item _panel _gap">
<b>{{ item.name }}</b>
<div v-if="item.description" class="description">{{ item.description }}</div>
<div class="user">
<MkAvatar :user="item.user" class="avatar" :show-indicator="true"/> <MkUserName :user="item.user" :nowrap="false"/>
</div>
</MkA>
</div>
<MkButton v-if="!showPrev && hasPrev" class="load prev" @click="showPrev = true"><i class="fas fa-chevron-down"></i></MkButton>
</div>
<div class="_gap" v-if="showPrev">
<XNotes class="_content" :pagination="prev" :no-gap="true"/>
<div class="main _gap">
<MkButton v-if="!showNext && hasNext" class="load next" @click="showNext = true"><i class="fas fa-chevron-up"></i></MkButton>
<div class="note _gap">
<MkRemoteCaution v-if="note.user.host != null" :href="note.url || note.uri" class="_isolated"/>
<XNoteDetailed v-model:note="note" :key="note.id" class="_isolated note"/>
</div>
<div class="_content clips _gap" v-if="clips && clips.length > 0">
<div class="title">{{ $ts.clip }}</div>
<MkA v-for="item in clips" :key="item.id" :to="`/clips/${item.id}`" class="item _panel _gap">
<b>{{ item.name }}</b>
<div v-if="item.description" class="description">{{ item.description }}</div>
<div class="user">
<MkAvatar :user="item.user" class="avatar" :show-indicator="true"/> <MkUserName :user="item.user" :nowrap="false"/>
</div>
</MkA>
</div>
<MkButton v-if="!showPrev && hasPrev" class="load prev" @click="showPrev = true"><i class="fas fa-chevron-down"></i></MkButton>
</div>
<div class="_gap" v-if="showPrev">
<XNotes class="_content" :pagination="prev" :no-gap="true"/>
</div>
</div>
</div>
<MkError v-else-if="error" @retry="fetch()"/>
<MkLoading v-else/>
</transition>
<MkError v-else-if="error" @retry="fetch()"/>
<MkLoading v-else/>
</transition>
</div>
</div>
</template>
@@ -63,12 +65,14 @@ export default defineComponent({
return {
[symbols.PAGE_INFO]: computed(() => this.note ? {
title: this.$ts.note,
subtitle: new Date(this.note.createdAt).toLocaleString(),
avatar: this.note.user,
path: `/notes/${this.note.id}`,
share: {
title: this.$t('noteOf', { user: this.note.user.name }),
text: this.note.text,
},
bg: 'var(--bg)',
} : null),
note: null,
clips: null,
@@ -108,6 +112,7 @@ export default defineComponent({
os.api('notes/show', {
noteId: this.noteId
}).then(note => {
this.note = note;
Promise.all([
os.api('notes/clips', {
noteId: note.id,
@@ -126,7 +131,6 @@ export default defineComponent({
this.clips = clips;
this.hasPrev = prev.length !== 0;
this.hasNext = next.length !== 0;
this.note = note;
});
}).catch(e => {
this.error = e;
@@ -147,45 +151,56 @@ export default defineComponent({
}
.fcuexfpr {
> .note {
> .main {
> .load {
min-width: 0;
margin: 0 auto;
border-radius: 999px;
background: var(--bg);
&.next {
margin-bottom: var(--margin);
}
> ._root {
> .note {
> .main {
> .load {
min-width: 0;
margin: 0 auto;
border-radius: 999px;
&.prev {
margin-top: var(--margin);
}
}
> .clips {
> .title {
font-weight: bold;
padding: 12px;
}
> .item {
display: block;
padding: 16px;
> .description {
padding: 8px 0;
&.next {
margin-bottom: var(--margin);
}
> .user {
$height: 32px;
padding-top: 16px;
border-top: solid 0.5px var(--divider);
line-height: $height;
&.prev {
margin-top: var(--margin);
}
}
> .avatar {
width: $height;
height: $height;
> .note {
> .note {
border-radius: var(--radius);
background: var(--panel);
}
}
> .clips {
> .title {
font-weight: bold;
padding: 12px;
}
> .item {
display: block;
padding: 16px;
> .description {
padding: 8px 0;
}
> .user {
$height: 32px;
padding-top: 16px;
border-top: solid 0.5px var(--divider);
line-height: $height;
> .avatar {
width: $height;
height: $height;
}
}
}
}
+17 -2
View File
@@ -1,6 +1,6 @@
<template>
<div class="_root">
<XNotifications class="_content" @before="before" @after="after" page/>
<div class="clupoqwt" v-size="{ min: [800] }">
<XNotifications class="notifications" @before="before" @after="after" page/>
</div>
</template>
@@ -21,6 +21,7 @@ export default defineComponent({
[symbols.PAGE_INFO]: {
title: this.$ts.notifications,
icon: 'fas fa-bell',
bg: 'var(--bg)',
actions: [{
text: this.$ts.markAllAsRead,
icon: 'fas fa-check',
@@ -43,3 +44,17 @@ export default defineComponent({
}
});
</script>
<style lang="scss" scoped>
.clupoqwt {
&.min-width_800px {
background: var(--bg);
padding: 32px 0;
> .notifications {
max-width: 800px;
margin: 0 auto;
}
}
}
</style>
+5 -5
View File
@@ -48,10 +48,10 @@ export default defineComponent({
title: this.$ts.accounts,
icon: 'fas fa-users',
},
storedAccounts: getAccounts().filter(x => x.id !== this.$i.id),
storedAccounts: getAccounts().then(accounts => accounts.filter(x => x.id !== this.$i.id)),
accounts: null,
init: () => os.api('users/show', {
userIds: this.storedAccounts.map(x => x.id)
init: async () => os.api('users/show', {
userIds: (await this.storedAccounts).map(x => x.id)
}).then(accounts => {
this.accounts = accounts;
}),
@@ -104,8 +104,8 @@ export default defineComponent({
}, 'closed');
},
switchAccount(account: any) {
const storedAccounts = getAccounts();
async switchAccount(account: any) {
const storedAccounts = await getAccounts();
const token = storedAccounts.find(x => x.id === account.id).token;
this.switchAccountWithToken(token);
},
@@ -0,0 +1,67 @@
<template>
<FormBase>
<FormInfo warn>{{ $ts._accountDelete.mayTakeTime }}</FormInfo>
<FormInfo>{{ $ts._accountDelete.sendEmail }}</FormInfo>
<FormButton @click="deleteAccount" danger v-if="!$i.isDeleted">{{ $ts._accountDelete.requestAccountDelete }}</FormButton>
<FormButton disabled v-else>{{ $ts._accountDelete.inProgress }}</FormButton>
</FormBase>
</template>
<script lang="ts">
import { defineAsyncComponent, defineComponent } from 'vue';
import FormInfo from '@client/components/form/info.vue';
import FormBase from '@client/components/form/base.vue';
import FormGroup from '@client/components/form/group.vue';
import FormButton from '@client/components/form/button.vue';
import * as os from '@client/os';
import { debug } from '@client/config';
import { signout } from '@client/account';
import * as symbols from '@client/symbols';
export default defineComponent({
components: {
FormBase,
FormButton,
FormGroup,
FormInfo,
},
emits: ['info'],
data() {
return {
[symbols.PAGE_INFO]: {
title: this.$ts._accountDelete.accountDelete,
icon: 'fas fa-exclamation-triangle'
},
debug,
}
},
mounted() {
this.$emit('info', this[symbols.PAGE_INFO]);
},
methods: {
async deleteAccount() {
const { canceled, result: password } = await os.dialog({
title: this.$ts.password,
input: {
type: 'password'
}
});
if (canceled) return;
await os.apiWithDialog('i/delete-account', {
password: password
});
await os.dialog({
title: this.$ts._accountDelete.started,
});
signout();
}
}
});
</script>

Some files were not shown because too many files have changed in this diff Show More