Compare commits

...

158 Commits

Author SHA1 Message Date
54961235a4 12.64.0 2020-12-28 22:03:14 +09:00
17eca2a18f Update physics.ts 2020-12-28 21:59:59 +09:00
137f3ee609 Bump @fortawesome/vue-fontawesome from 3.0.0-2 to 3.0.0-3 (#6971)
Bumps [@fortawesome/vue-fontawesome](https://github.com/FortAwesome/vue-fontawesome) from 3.0.0-2 to 3.0.0-3.
- [Release notes](https://github.com/FortAwesome/vue-fontawesome/releases)
- [Changelog](https://github.com/FortAwesome/vue-fontawesome/blob/3.0.0-3/CHANGELOG.md)
- [Commits](https://github.com/FortAwesome/vue-fontawesome/commits/3.0.0-3)

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

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-12-28 21:47:48 +09:00
498f6e9be2 New Crowdin updates (#6964)
* New translations theme.md (Arabic)

* New translations timelines.md (Arabic)

* New translations aiscript.md (Czech)

* New translations api.md (Czech)

* New translations create-plugin.md (Czech)

* New translations custom-emoji.md (Czech)

* New translations follow.md (Czech)

* New translations keyboard-shortcut.md (Czech)

* New translations timelines.md (Spanish)

* New translations stream.md (Spanish)

* New translations pages.md (Czech)

* New translations theme.md (French)

* New translations api.md (French)

* New translations create-plugin.md (French)

* New translations custom-emoji.md (French)

* New translations follow.md (French)

* New translations keyboard-shortcut.md (French)

* New translations mute.md (French)

* New translations pages.md (French)

* New translations reaction.md (French)

* New translations reversi-bot.md (French)

* New translations stream.md (French)

* New translations create-plugin.md (Dutch)

* New translations reversi-bot.md (Spanish)

* New translations aiscript.md (Spanish)

* New translations api.md (Spanish)

* New translations create-plugin.md (Spanish)

* New translations custom-emoji.md (Spanish)

* New translations follow.md (Spanish)

* New translations keyboard-shortcut.md (Spanish)

* New translations mute.md (Spanish)

* New translations pages.md (Spanish)

* New translations reaction.md (Spanish)

* New translations mute.md (Czech)

* New translations timelines.md (French)

* New translations reaction.md (Czech)

* New translations follow.md (Korean)

* New translations reaction.md (German)

* New translations reversi-bot.md (German)

* New translations stream.md (German)

* New translations theme.md (German)

* New translations timelines.md (German)

* New translations aiscript.md (Korean)

* New translations api.md (Korean)

* New translations create-plugin.md (Korean)

* New translations custom-emoji.md (Korean)

* New translations keyboard-shortcut.md (Korean)

* New translations mute.md (German)

* New translations mute.md (Korean)

* New translations pages.md (Korean)

* New translations reaction.md (Korean)

* New translations stream.md (Korean)

* New translations theme.md (Korean)

* New translations timelines.md (Korean)

* New translations aiscript.md (Dutch)

* New translations api.md (Dutch)

* New translations reversi-bot.md (Czech)

* New translations pages.md (German)

* New translations reversi-bot.md (Korean)

* New translations keyboard-shortcut.md (German)

* New translations mute.md (Danish)

* New translations stream.md (Czech)

* New translations follow.md (German)

* New translations theme.md (Czech)

* New translations timelines.md (Czech)

* New translations api.md (Danish)

* New translations create-plugin.md (Danish)

* New translations custom-emoji.md (Danish)

* New translations follow.md (Danish)

* New translations keyboard-shortcut.md (Danish)

* New translations aiscript.md (Danish)

* New translations pages.md (Danish)

* New translations ja-JP.yml (German)

* New translations reaction.md (Danish)

* New translations custom-emoji.md (German)

* New translations api.md (German)

* New translations aiscript.md (German)

* New translations timelines.md (Danish)

* New translations theme.md (Danish)

* New translations stream.md (Danish)

* New translations reversi-bot.md (Danish)

* New translations create-plugin.md (German)

* New translations follow.md (Kabyle)

* New translations keyboard-shortcut.md (Kabyle)

* New translations custom-emoji.md (Kabyle)

* New translations create-plugin.md (Kabyle)

* New translations api.md (Kabyle)

* New translations aiscript.md (Kabyle)

* New translations reversi-bot.md (Kannada)

* New translations timelines.md (Kannada)

* New translations theme.md (Kannada)

* New translations stream.md (Kannada)

* New translations reaction.md (Kannada)

* New translations pages.md (Kannada)

* New translations mute.md (Kannada)

* New translations pages.md (Kabyle)

* New translations keyboard-shortcut.md (Kannada)

* New translations mute.md (Kabyle)

* New translations keyboard-shortcut.md (Japanese, Kansai)

* New translations reaction.md (Kabyle)

* New translations follow.md (Japanese, Kansai)

* New translations custom-emoji.md (Kannada)

* New translations theme.md (Japanese, Kansai)

* New translations stream.md (Japanese, Kansai)

* New translations reversi-bot.md (Japanese, Kansai)

* New translations reaction.md (Japanese, Kansai)

* New translations pages.md (Japanese, Kansai)

* New translations mute.md (Japanese, Kansai)

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

* New translations reversi-bot.md (Kabyle)

* New translations create-plugin.md (Japanese, Kansai)

* New translations api.md (Japanese, Kansai)

* New translations aiscript.md (Japanese, Kansai)

* New translations timelines.md (Kabyle)

* New translations theme.md (Kabyle)

* New translations stream.md (Kabyle)

* New translations follow.md (Kannada)

* New translations keyboard-shortcut.md (English)

* New translations create-plugin.md (Kannada)

* New translations aiscript.md (English)

* New translations reaction.md (English)

* New translations pages.md (English)

* New translations mute.md (English)

* New translations follow.md (English)

* New translations custom-emoji.md (English)

* New translations create-plugin.md (English)

* New translations api.md (English)

* New translations stream.md (English)

* New translations timelines.md (Chinese Traditional)

* New translations theme.md (Chinese Traditional)

* New translations stream.md (Chinese Traditional)

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

* New translations reaction.md (Chinese Traditional)

* New translations pages.md (Chinese Traditional)

* New translations mute.md (Chinese Traditional)

* New translations reversi-bot.md (English)

* New translations theme.md (English)

* New translations api.md (Kannada)

* New translations pages.md (Uyghur)

* New translations aiscript.md (Kannada)

* New translations timelines.md (Uyghur)

* New translations theme.md (Uyghur)

* New translations stream.md (Uyghur)

* New translations reversi-bot.md (Uyghur)

* New translations reaction.md (Uyghur)

* New translations mute.md (Uyghur)

* New translations timelines.md (English)

* New translations keyboard-shortcut.md (Uyghur)

* New translations follow.md (Uyghur)

* New translations custom-emoji.md (Uyghur)

* New translations create-plugin.md (Uyghur)

* New translations api.md (Uyghur)

* New translations aiscript.md (Uyghur)

* New translations timelines.md (Japanese, Kansai)

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

* New translations ja-JP.yml (French)

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

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

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Russian)

* New translations ja-JP.yml (Ukrainian)

* New translations ja-JP.yml (Spanish)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Korean)

* New translations aiscript.md (Chinese Simplified)

* New translations api.md (Chinese Simplified)

* New translations api.md (Chinese Simplified)

* New translations api.md (Chinese Simplified)

* New translations api.md (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 create-plugin.md (Chinese Simplified)

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

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

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

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

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

* New translations mfm.md (Ukrainian)

* New translations mfm.md (Korean)

* New translations deck.md (Dutch)

* New translations mfm.md (Dutch)

* New translations deck.md (Norwegian)

* New translations mfm.md (Norwegian)

* New translations deck.md (Polish)

* New translations mfm.md (Polish)

* New translations deck.md (Portuguese)

* New translations mfm.md (Portuguese)

* New translations deck.md (Russian)

* New translations mfm.md (Russian)

* New translations deck.md (Ukrainian)

* New translations deck.md (Chinese Simplified)

* New translations mfm.md (German)

* New translations mfm.md (Chinese Simplified)

* New translations deck.md (Chinese Traditional)

* New translations mfm.md (Chinese Traditional)

* New translations deck.md (English)

* New translations mfm.md (English)

* New translations deck.md (Uyghur)

* New translations mfm.md (Uyghur)

* New translations deck.md (Kannada)

* New translations mfm.md (Kannada)

* New translations deck.md (Kabyle)

* New translations mfm.md (Kabyle)

* New translations deck.md (Japanese, Kansai)

* New translations deck.md (Korean)

* New translations deck.md (German)

* New translations mfm.md (Danish)

* New translations deck.md (French)

* New translations mfm.md (French)

* New translations deck.md (Spanish)

* New translations mfm.md (Spanish)

* New translations deck.md (Arabic)

* New translations mfm.md (Arabic)

* New translations deck.md (Czech)

* New translations mfm.md (Czech)

* New translations deck.md (Danish)

* New translations mfm.md (Japanese, Kansai)

* New translations aiscript.md (Chinese Traditional)

* New translations api.md (Chinese Traditional)

* New translations timelines.md (Chinese Traditional)

* New translations api.md (Chinese Traditional)

* New translations api.md (Chinese Traditional)

* New translations api.md (Chinese Traditional)

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

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

* New translations stream.md (Chinese Traditional)

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

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

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

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

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

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

* New translations aiscript.md (Chinese Traditional)

* New translations follow.md (Chinese Traditional)

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

* New translations follow.md (Chinese Traditional)

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

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

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

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

* New translations custom-emoji.md (Chinese Simplified)

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

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

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

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

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

* New translations ja-JP.yml (Chinese Traditional)
2020-12-28 21:45:08 +09:00
a5e841f59c 🎨 2020-12-28 21:44:38 +09:00
9adab1e85e 🎨 2020-12-28 20:28:42 +09:00
4288a843cb Update style.scss 2020-12-28 20:08:57 +09:00
1669f5b265 fix deck 2020-12-28 19:57:09 +09:00
1157298eb8 リロード確認ダイアログ表示 2020-12-28 17:18:13 +09:00
948a65bf39 some fixes 2020-12-28 17:00:31 +09:00
20c076b369 細かい修正など 2020-12-28 13:58:57 +09:00
b67ed64116 add doc 2020-12-28 12:01:53 +09:00
1da3777bfb デッキ周り改修など 2020-12-28 11:56:42 +09:00
ea6aa40b09 Add button widget 2020-12-27 23:13:01 +09:00
b002651194 Update crowdin.yml 2020-12-27 22:07:53 +09:00
1452512daf Update crowdin.yml 2020-12-27 21:53:59 +09:00
0e7778bebf refactor 2020-12-27 21:49:39 +09:00
698fbdf88b fix doc 2020-12-27 21:36:36 +09:00
7b738deabf Improve usability 2020-12-27 21:16:51 +09:00
3c65e7b76e fix deck navigation 2020-12-27 18:13:50 +09:00
3fc427b699 nanka iroiro 2020-12-27 17:04:41 +09:00
03667e1fe6 Delete const.json 2020-12-27 12:10:17 +09:00
5cfd000a7d デッキのカラムがドラッグできない問題を修正 2020-12-27 11:07:26 +09:00
fa66eac096 サイドバーの表示設定がリアルタイム反映されない問題を修正 2020-12-27 10:46:00 +09:00
70eb75b7e6 Update webpack.config.ts 2020-12-27 10:42:47 +09:00
2f6187a26a モバイルで投稿ボタン復活するなど 2020-12-27 10:42:38 +09:00
167da988da 2020-12-26 23:18:51 +09:00
6935e647a6 add note 2020-12-26 22:56:01 +09:00
743eca4a95 Improve deck 2020-12-26 22:41:00 +09:00
78598a92f9 Improve deck 2020-12-26 18:33:54 +09:00
94598ab555 Refactoring 2020-12-26 15:38:51 +09:00
c5bdee086d フォローリクエストがなくてもフォロー承認が出来てしまうのを修正 (#7013)
* フォローリクエストがなくてもフォロー承認が出来てしまうのを修正

* プロキシアカウントがDB処理をせずにフォローを飛ばしているのを修正
2020-12-26 15:31:28 +09:00
c6cfc3f908 fix locale handling 2020-12-26 15:27:39 +09:00
84b488a912 翻訳ファイルをランタイムで読み込み 2020-12-26 15:13:25 +09:00
ec4d5857d8 Fix service worker generation 2020-12-26 14:11:08 +09:00
4576641105 Add note 2020-12-26 14:00:55 +09:00
572e475b39 clean up 2020-12-26 13:57:25 +09:00
882a30fabe clean up 2020-12-26 11:02:57 +09:00
feec35bf4f Update boot.js 2020-12-26 10:58:59 +09:00
c9fea5a7a0 Update boot.js 2020-12-26 10:55:12 +09:00
00f3a1e1ec wip 2020-12-26 10:51:00 +09:00
5a8cc7851b wip 2020-12-26 10:47:36 +09:00
9d81d06853 wip 2020-12-26 10:01:32 +09:00
4fce5d8066 Showusers order by updateAt NULL considered as max (#7015) 2020-12-24 22:15:34 +09:00
329e367bda Merge pull request #7000 from syuilo/dependabot/npm_and_yarn/eslint-plugin-vue-7.3.0 2020-12-21 20:42:36 +00:00
ce056bf936 Bump eslint-plugin-vue from 7.2.0 to 7.3.0
Bumps [eslint-plugin-vue](https://github.com/vuejs/eslint-plugin-vue) from 7.2.0 to 7.3.0.
- [Release notes](https://github.com/vuejs/eslint-plugin-vue/releases)
- [Commits](https://github.com/vuejs/eslint-plugin-vue/compare/v7.2.0...v7.3.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-21 20:35:26 +00:00
c6ab5faba6 Merge pull request #7001 from syuilo/dependabot/npm_and_yarn/nodemailer-6.4.17 2020-12-21 20:33:07 +00:00
6ce0804b43 Bump nodemailer from 6.4.16 to 6.4.17
Bumps [nodemailer](https://github.com/nodemailer/nodemailer) from 6.4.16 to 6.4.17.
- [Release notes](https://github.com/nodemailer/nodemailer/releases)
- [Changelog](https://github.com/nodemailer/nodemailer/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodemailer/nodemailer/compare/v6.4.16...v6.4.17)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-21 20:25:09 +00:00
a7a6563281 Merge pull request #6998 from syuilo/dependabot/npm_and_yarn/eslint-7.16.0 2020-12-21 20:23:59 +00:00
0a084a3363 Bump eslint from 7.15.0 to 7.16.0
Bumps [eslint](https://github.com/eslint/eslint) from 7.15.0 to 7.16.0.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/master/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v7.15.0...v7.16.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-21 20:15:25 +00:00
beeb8de6da 🎨 2020-12-20 17:19:18 +09:00
e73297f260 Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2020-12-20 10:52:58 +09:00
b408ef5ba5 Update migration 2020-12-20 10:52:41 +09:00
50539099ab Remove a meaningless event (#6996)
* Remove a meaningless event

* Remove a meaningless event
2020-12-20 10:46:09 +09:00
9a3a77cff0 Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2020-12-19 21:41:04 +09:00
cdc07945af Pageの複製を実装 2020-12-19 21:41:00 +09:00
9f9194ab5c Fix type of Hpml.pageVarUpdatedCallback (#6995) 2020-12-19 21:09:23 +09:00
136a087ae7 pageの選択肢が動作していない問題を修正 2020-12-19 21:04:41 +09:00
b9e91afa26 Fix bug 2020-12-19 18:38:03 +09:00
f943e39c89 🎨 2020-12-19 13:23:40 +09:00
75bdbff36d fix bug 2020-12-19 11:12:02 +09:00
43930e6a84 Storage improve (#6976)
* wip

* wip

* wip

* wip

* wip

* Update storage.ts

* wip

* wip

* wip

* wip

* Update storage.ts

* Update storage.ts

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* Update storage.ts

* wip

* wip

* wip

* wip

* 🍕

* wip

* wip

* wip

* wip

* wip

* wip

* Update deck-storage.ts

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* Update store.ts

* wip

* wip

* wip

* wip

* Update init.ts

* wip

* wip

* Update pizzax.ts

* wip

* wip

* Update timeline.vue

* Update init.ts

* wip

* wip

* Update init.ts
2020-12-19 10:55:52 +09:00
57d0c19a98 Bump vue-i18n from 9.0.0-beta.7 to 9.0.0-beta.14 (#6993)
Bumps [vue-i18n](https://github.com/kazupon/vue-i18n) from 9.0.0-beta.7 to 9.0.0-beta.14.
- [Release notes](https://github.com/kazupon/vue-i18n/releases)
- [Changelog](https://github.com/kazupon/vue-i18n/blob/v8.x/CHANGELOG.md)
- [Commits](https://github.com/kazupon/vue-i18n/commits)

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

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-12-19 09:55:57 +09:00
66a11378d2 Add delete page button (#6992) 2020-12-19 09:53:50 +09:00
62b680cadd CIでDockerイメージのpushが正しく行われるよう修正 (#6990)
* fix docker command on CI to push the image tagged with the version

* fix docker cli version on CI for future-proofing
2020-12-19 09:53:12 +09:00
1e1ac13999 Merge pull request #6989 from syuilo/dependabot/npm_and_yarn/systeminformation-4.31.1 2020-12-16 19:51:23 +00:00
d27c454674 [Security] Bump systeminformation from 4.31.0 to 4.31.1
Bumps [systeminformation](https://github.com/sebhildebrandt/systeminformation) from 4.31.0 to 4.31.1. **This update includes a security fix.**
- [Release notes](https://github.com/sebhildebrandt/systeminformation/releases)
- [Changelog](https://github.com/sebhildebrandt/systeminformation/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sebhildebrandt/systeminformation/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-16 19:43:47 +00:00
3263eaec32 Merge pull request #6979 from syuilo/dependabot/npm_and_yarn/types/node-14.14.13 2020-12-15 01:33:31 +00:00
de4e9a857c Merge pull request #6980 from syuilo/dependabot/npm_and_yarn/webpack-5.10.1 2020-12-14 20:32:45 +00:00
d838876ab1 Bump webpack from 5.10.0 to 5.10.1
Bumps [webpack](https://github.com/webpack/webpack) from 5.10.0 to 5.10.1.
- [Release notes](https://github.com/webpack/webpack/releases)
- [Commits](https://github.com/webpack/webpack/compare/v5.10.0...v5.10.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-14 20:24:41 +00:00
03336f01b5 Bump @types/node from 14.14.11 to 14.14.13
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 14.14.11 to 14.14.13.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-14 20:24:36 +00:00
d212d693a4 Merge pull request #6978 from syuilo/dependabot/npm_and_yarn/typescript-eslint/parser-4.10.0 2020-12-14 20:22:10 +00:00
d17fcd8e48 Bump @typescript-eslint/parser from 4.9.1 to 4.10.0
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 4.9.1 to 4.10.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v4.10.0/packages/parser)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-14 20:13:45 +00:00
49b3ee36bd Update vetur.config.js (#6975) 2020-12-12 23:24:50 +09:00
100d7adc3d Update tsconfig.json 2020-12-12 21:41:08 +09:00
68b1fea6bb 🎨 2020-12-12 13:09:40 +09:00
4de6e1e28a respect reduce animation settings in list 2020-12-12 13:06:26 +09:00
84f8c34e90 コミット忘れ 2020-12-12 12:13:27 +09:00
77567cf114 Fix style 2020-12-12 12:12:01 +09:00
3cf8e1917c Merge pull request #6972 from syuilo/dependabot/npm_and_yarn/vue-and-vue/compiler-sfc-3.0.4 2020-12-11 20:45:30 +00:00
84cbabec29 Bump vue and @vue/compiler-sfc
Bumps [vue](https://github.com/vuejs/vue) and [@vue/compiler-sfc](https://github.com/vuejs/vue-next/tree/HEAD/packages/compiler-sfc). These dependencies needed to be updated together.

Updates `vue` from 3.0.3 to 3.0.4
- [Release notes](https://github.com/vuejs/vue/releases)
- [Commits](https://github.com/vuejs/vue/commits)

Updates `@vue/compiler-sfc` from 3.0.3 to 3.0.4
- [Release notes](https://github.com/vuejs/vue-next/releases)
- [Changelog](https://github.com/vuejs/vue-next/blob/master/CHANGELOG.md)
- [Commits](https://github.com/vuejs/vue-next/commits/v3.0.4/packages/compiler-sfc)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-11 20:37:45 +00:00
b88c65ab67 Merge pull request #6974 from syuilo/dependabot/npm_and_yarn/got-11.8.1 2020-12-11 20:37:30 +00:00
10782822de Merge pull request #6973 from syuilo/dependabot/npm_and_yarn/typescript-eslint/parser-4.9.1 2020-12-11 20:35:18 +00:00
5457172aa5 Bump got from 11.8.0 to 11.8.1
Bumps [got](https://github.com/sindresorhus/got) from 11.8.0 to 11.8.1.
- [Release notes](https://github.com/sindresorhus/got/releases)
- [Commits](https://github.com/sindresorhus/got/compare/v11.8.0...v11.8.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-11 20:23:40 +00:00
d20a2c7080 Bump @typescript-eslint/parser from 4.6.1 to 4.9.1
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 4.6.1 to 4.9.1.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v4.9.1/packages/parser)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-11 20:23:14 +00:00
c01098de16 Merge pull request #6968 from syuilo/dependabot/npm_and_yarn/uuid-8.3.2 2020-12-11 20:22:59 +00:00
0b14a57d55 Merge pull request #6969 from syuilo/dependabot/npm_and_yarn/aws-sdk-2.809.0 2020-12-11 20:22:39 +00:00
405d104208 Merge pull request #6967 from syuilo/dependabot/npm_and_yarn/ms-2.1.3 2020-12-11 20:22:22 +00:00
83e3316f06 Merge pull request #6966 from syuilo/dependabot/npm_and_yarn/cross-env-7.0.3 2020-12-11 20:21:45 +00:00
2037d4c21d Bump aws-sdk from 2.806.0 to 2.809.0
Bumps [aws-sdk](https://github.com/aws/aws-sdk-js) from 2.806.0 to 2.809.0.
- [Release notes](https://github.com/aws/aws-sdk-js/releases)
- [Changelog](https://github.com/aws/aws-sdk-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js/compare/v2.806.0...v2.809.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-11 20:15:47 +00:00
6cabf052b1 Bump uuid from 8.3.1 to 8.3.2
Bumps [uuid](https://github.com/uuidjs/uuid) from 8.3.1 to 8.3.2.
- [Release notes](https://github.com/uuidjs/uuid/releases)
- [Changelog](https://github.com/uuidjs/uuid/blob/master/CHANGELOG.md)
- [Commits](https://github.com/uuidjs/uuid/compare/v8.3.1...v8.3.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-11 20:15:09 +00:00
359e1b2e6e Bump ms from 2.1.2 to 2.1.3
Bumps [ms](https://github.com/vercel/ms) from 2.1.2 to 2.1.3.
- [Release notes](https://github.com/vercel/ms/releases)
- [Commits](https://github.com/vercel/ms/compare/2.1.2...2.1.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-11 20:14:41 +00:00
7b553b13ac Bump cross-env from 7.0.2 to 7.0.3
Bumps [cross-env](https://github.com/kentcdodds/cross-env) from 7.0.2 to 7.0.3.
- [Release notes](https://github.com/kentcdodds/cross-env/releases)
- [Changelog](https://github.com/kentcdodds/cross-env/blob/master/CHANGELOG.md)
- [Commits](https://github.com/kentcdodds/cross-env/compare/v7.0.2...v7.0.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-11 20:14:14 +00:00
79872ec3e8 12.63.0 2020-12-11 22:40:11 +09:00
e9df7265fa New Crowdin updates (#6932)
* New translations ja-JP.yml (Ukrainian)

* New translations ja-JP.yml (Ukrainian)

* New translations ja-JP.yml (Ukrainian)

* New translations ja-JP.yml (Ukrainian)

* New translations ja-JP.yml (Ukrainian)

* New translations ja-JP.yml (Ukrainian)

* New translations ja-JP.yml (Ukrainian)

* New translations ja-JP.yml (Ukrainian)

* New translations ja-JP.yml (Ukrainian)

* New translations ja-JP.yml (Ukrainian)

* New translations ja-JP.yml (Ukrainian)

* New translations ja-JP.yml (Ukrainian)

* New translations ja-JP.yml (Ukrainian)

* New translations ja-JP.yml (Ukrainian)

* New translations ja-JP.yml (Ukrainian)

* New translations ja-JP.yml (Ukrainian)

* New translations ja-JP.yml (Ukrainian)

* New translations ja-JP.yml (Ukrainian)

* New translations ja-JP.yml (Ukrainian)

* New translations ja-JP.yml (Ukrainian)

* New translations ja-JP.yml (Ukrainian)

* New translations ja-JP.yml (Ukrainian)

* New translations ja-JP.yml (Ukrainian)

* New translations ja-JP.yml (Ukrainian)

* New translations ja-JP.yml (Ukrainian)

* New translations ja-JP.yml (Ukrainian)

* New translations ja-JP.yml (Ukrainian)

* New translations ja-JP.yml (Ukrainian)

* New translations ja-JP.yml (Ukrainian)

* New translations ja-JP.yml (Ukrainian)

* New translations ja-JP.yml (Ukrainian)

* New translations ja-JP.yml (Ukrainian)

* New translations ja-JP.yml (Ukrainian)

* New translations ja-JP.yml (Ukrainian)

* New translations ja-JP.yml (Ukrainian)

* New translations ja-JP.yml (Ukrainian)

* New translations ja-JP.yml (Ukrainian)

* New translations ja-JP.yml (Ukrainian)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (German)
2020-12-11 22:39:38 +09:00
1ade89be35 タイムラインのノートを話して表示するオプション 2020-12-11 22:36:57 +09:00
3356f7113f Update vue.d.ts 2020-12-11 22:15:47 +09:00
e6495ea6e2 Update vue.d.ts 2020-12-11 21:52:57 +09:00
629991443a Update vetur 2020-12-11 21:43:28 +09:00
6848f05ea5 ショートカットからお気に入りとRenote時にダイアログを表示 (#6921)
* お気に入りとRenote時にダイアログを表示

* Fix error handling

* Fix error handling on renote
2020-12-11 21:22:41 +09:00
e58dd71829 Bump @types/matter-js from 0.14.7 to 0.14.8 (#6951)
Bumps [@types/matter-js](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/matter-js) from 0.14.7 to 0.14.8.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/matter-js)

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

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-12-11 21:17:50 +09:00
1afa2f1202 Bump vue-router from 4.0.0-rc.6 to 4.0.1 (#6953)
Bumps [vue-router](https://github.com/vuejs/vue-router) from 4.0.0-rc.6 to 4.0.1.
- [Release notes](https://github.com/vuejs/vue-router/releases)
- [Changelog](https://github.com/vuejs/vue-router/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/vuejs/vue-router/commits)

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

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-12-11 21:17:36 +09:00
f322cb444a Bump dateformat from 3.0.3 to 4.3.1 (#6936)
Bumps [dateformat](https://github.com/felixge/node-dateformat) from 3.0.3 to 4.3.1.
- [Release notes](https://github.com/felixge/node-dateformat/releases)
- [Commits](https://github.com/felixge/node-dateformat/commits/v4.3.1)

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

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-12-11 21:17:11 +09:00
69c3c4e3dc Resolve #6806 (#6935)
* ✌️

* ✌️

* Update privacy.vue
2020-12-11 21:16:20 +09:00
488e6feed9 Merge pull request #6960 from syuilo/dependabot/npm_and_yarn/ws-7.4.1 2020-12-10 20:41:12 +00:00
40891aca48 Bump ws from 7.4.0 to 7.4.1
Bumps [ws](https://github.com/websockets/ws) from 7.4.0 to 7.4.1.
- [Release notes](https://github.com/websockets/ws/releases)
- [Commits](https://github.com/websockets/ws/compare/7.4.0...7.4.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-10 20:33:40 +00:00
cd0e557991 Merge pull request #6961 from syuilo/dependabot/npm_and_yarn/webpack-5.10.0 2020-12-10 20:31:18 +00:00
679f8ad614 Merge pull request #6959 from syuilo/dependabot/npm_and_yarn/core-js-3.8.1 2020-12-10 20:28:23 +00:00
00c647c736 Bump webpack from 5.9.0 to 5.10.0
Bumps [webpack](https://github.com/webpack/webpack) from 5.9.0 to 5.10.0.
- [Release notes](https://github.com/webpack/webpack/releases)
- [Commits](https://github.com/webpack/webpack/compare/v5.9.0...v5.10.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-10 20:22:24 +00:00
1ac6af6ad1 Merge pull request #6957 from syuilo/dependabot/npm_and_yarn/types/koa-2.11.6 2020-12-10 20:21:23 +00:00
a5d7099a3c Bump core-js from 3.7.0 to 3.8.1
Bumps [core-js](https://github.com/zloirock/core-js) from 3.7.0 to 3.8.1.
- [Release notes](https://github.com/zloirock/core-js/releases)
- [Changelog](https://github.com/zloirock/core-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/zloirock/core-js/compare/v3.7.0...v3.8.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-10 20:21:13 +00:00
e9c8a0f5d5 Merge pull request #6956 from syuilo/dependabot/npm_and_yarn/postcss-8.2.1 2020-12-10 20:20:42 +00:00
adcda0889e Bump @types/koa from 2.11.3 to 2.11.6
Bumps [@types/koa](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/koa) from 2.11.3 to 2.11.6.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/koa)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-10 20:13:46 +00:00
95cbcdd379 Bump postcss from 8.1.14 to 8.2.1
Bumps [postcss](https://github.com/postcss/postcss) from 8.1.14 to 8.2.1.
- [Release notes](https://github.com/postcss/postcss/releases)
- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/postcss/postcss/compare/8.1.14...8.2.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-10 20:13:17 +00:00
a5e8eb4b7b Merge pull request #6955 from syuilo/dependabot/npm_and_yarn/ini-1.3.7 2020-12-10 19:45:15 +00:00
ed440f80f3 [Security] Bump ini from 1.3.5 to 1.3.7
Bumps [ini](https://github.com/isaacs/ini) from 1.3.5 to 1.3.7. **This update includes a security fix.**
- [Release notes](https://github.com/isaacs/ini/releases)
- [Commits](https://github.com/isaacs/ini/compare/v1.3.5...v1.3.7)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-10 19:37:41 +00:00
4e2ef94107 Merge pull request #6952 from syuilo/dependabot/npm_and_yarn/types/chai-4.2.14 2020-12-10 01:33:56 +00:00
de690e0622 Merge pull request #6954 from syuilo/dependabot/npm_and_yarn/typescript-4.1.2 2020-12-09 20:41:47 +00:00
062e1a4940 Bump typescript from 4.0.5 to 4.1.2
Bumps [typescript](https://github.com/Microsoft/TypeScript) from 4.0.5 to 4.1.2.
- [Release notes](https://github.com/Microsoft/TypeScript/releases)
- [Commits](https://github.com/Microsoft/TypeScript/compare/v4.0.5...v4.1.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-09 20:33:24 +00:00
cc3779b197 Merge pull request #6950 from syuilo/dependabot/npm_and_yarn/websocket-1.0.33 2020-12-09 20:32:30 +00:00
92dc34b51a Merge pull request #6949 from syuilo/dependabot/npm_and_yarn/apexcharts-3.22.3 2020-12-09 20:32:18 +00:00
f8ee615640 Bump @types/chai from 4.2.11 to 4.2.14
Bumps [@types/chai](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/chai) from 4.2.11 to 4.2.14.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/chai)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-09 20:25:12 +00:00
5dde8b4bdc Bump websocket from 1.0.32 to 1.0.33
Bumps [websocket](https://github.com/theturtle32/WebSocket-Node) from 1.0.32 to 1.0.33.
- [Release notes](https://github.com/theturtle32/WebSocket-Node/releases)
- [Changelog](https://github.com/theturtle32/WebSocket-Node/blob/master/CHANGELOG.md)
- [Commits](https://github.com/theturtle32/WebSocket-Node/compare/v1.0.32...v1.0.33)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-09 20:24:21 +00:00
2c70055a87 Bump apexcharts from 3.22.2 to 3.22.3
Bumps [apexcharts](https://github.com/apexcharts/apexcharts.js) from 3.22.2 to 3.22.3.
- [Release notes](https://github.com/apexcharts/apexcharts.js/releases)
- [Commits](https://github.com/apexcharts/apexcharts.js/compare/v3.22.2...v3.22.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-09 20:24:00 +00:00
db8ab8b890 Bump @types/sharp from 0.26.0 to 0.26.1 (#6913)
Bumps [@types/sharp](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/sharp) from 0.26.0 to 0.26.1.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/sharp)

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

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-12-10 02:44:35 +09:00
28da5c5a31 Merge pull request #6945 from syuilo/dependabot/npm_and_yarn/ts-loader-8.0.11 2020-12-08 20:38:31 +00:00
b345aad52c Merge pull request #6944 from syuilo/dependabot/npm_and_yarn/aws-sdk-2.806.0 2020-12-08 20:30:57 +00:00
aa5af89dfc Bump ts-loader from 8.0.9 to 8.0.11
Bumps [ts-loader](https://github.com/TypeStrong/ts-loader) from 8.0.9 to 8.0.11.
- [Release notes](https://github.com/TypeStrong/ts-loader/releases)
- [Changelog](https://github.com/TypeStrong/ts-loader/blob/master/CHANGELOG.md)
- [Commits](https://github.com/TypeStrong/ts-loader/compare/v8.0.9...v8.0.11)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-08 20:30:39 +00:00
9a3a74db34 Merge pull request #6943 from syuilo/dependabot/npm_and_yarn/eslint-plugin-vue-7.2.0 2020-12-08 20:30:20 +00:00
328619f1fc Bump aws-sdk from 2.787.0 to 2.806.0
Bumps [aws-sdk](https://github.com/aws/aws-sdk-js) from 2.787.0 to 2.806.0.
- [Release notes](https://github.com/aws/aws-sdk-js/releases)
- [Changelog](https://github.com/aws/aws-sdk-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js/compare/v2.787.0...v2.806.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-08 20:23:35 +00:00
121e12785f Merge pull request #6941 from syuilo/dependabot/npm_and_yarn/types/parsimmon-1.10.6 2020-12-08 20:23:17 +00:00
cc3f0737a2 Bump eslint-plugin-vue from 7.1.0 to 7.2.0
Bumps [eslint-plugin-vue](https://github.com/vuejs/eslint-plugin-vue) from 7.1.0 to 7.2.0.
- [Release notes](https://github.com/vuejs/eslint-plugin-vue/releases)
- [Commits](https://github.com/vuejs/eslint-plugin-vue/compare/v7.1.0...v7.2.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-08 20:22:51 +00:00
bc3714139f Merge pull request #6942 from syuilo/dependabot/npm_and_yarn/types/node-14.14.11 2020-12-08 20:22:29 +00:00
9200379997 Bump @types/node from 14.0.22 to 14.14.11
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 14.0.22 to 14.14.11.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-08 20:14:43 +00:00
0ee664db2b Bump @types/parsimmon from 1.10.5 to 1.10.6
Bumps [@types/parsimmon](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/parsimmon) from 1.10.5 to 1.10.6.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/parsimmon)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-08 20:14:16 +00:00
86487e6f66 Merge pull request #6940 from syuilo/dependabot/npm_and_yarn/eslint-7.15.0 2020-12-07 20:31:45 +00:00
adc2bcc59b Merge pull request #6939 from syuilo/dependabot/npm_and_yarn/bull-3.20.0 2020-12-07 20:30:59 +00:00
21a54f559a Bump eslint from 7.14.0 to 7.15.0
Bumps [eslint](https://github.com/eslint/eslint) from 7.14.0 to 7.15.0.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/master/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v7.14.0...v7.15.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-07 20:23:33 +00:00
145e16c266 Bump bull from 3.18.1 to 3.20.0
Bumps [bull](https://github.com/OptimalBits/bull) from 3.18.1 to 3.20.0.
- [Release notes](https://github.com/OptimalBits/bull/releases)
- [Changelog](https://github.com/OptimalBits/bull/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/OptimalBits/bull/compare/v3.18.1...v3.20.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-07 20:23:04 +00:00
68f4edd0ee Merge pull request #6938 from syuilo/dependabot/npm_and_yarn/types/koa__cors-3.0.2 2020-12-07 20:22:52 +00:00
7fd6a134d1 Merge pull request #6937 from syuilo/dependabot/npm_and_yarn/systeminformation-4.31.0 2020-12-07 20:22:39 +00:00
0db8d566e2 Bump @types/koa__cors from 3.0.1 to 3.0.2
Bumps [@types/koa__cors](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/koa__cors) from 3.0.1 to 3.0.2.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/koa__cors)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-07 20:15:02 +00:00
c6f6291fc0 Bump systeminformation from 4.30.7 to 4.31.0
Bumps [systeminformation](https://github.com/sebhildebrandt/systeminformation) from 4.30.7 to 4.31.0.
- [Release notes](https://github.com/sebhildebrandt/systeminformation/releases)
- [Changelog](https://github.com/sebhildebrandt/systeminformation/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sebhildebrandt/systeminformation/compare/v4.30.7...v4.31.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-07 20:14:26 +00:00
c2d79450ea Pagesで変数削除するとそれ以外の変数が複製されるみたいなバグを修正 2020-12-08 00:32:00 +09:00
d58ae601f7 🎨 2020-12-08 00:24:59 +09:00
3ad73ad7d9 リファクタ等 2020-12-06 23:54:58 +09:00
f0c4df1cc5 12.62.2 2020-12-06 22:52:18 +09:00
839784bc8c Fix #6926 2020-12-06 22:49:31 +09:00
b758ec96ef Fix #6929 2020-12-06 22:47:51 +09:00
2f8ceb9d22 Better physics 2020-12-06 17:35:21 +09:00
e05ae5ebc2 12.62.1 2020-12-06 13:02:36 +09:00
ebc43be4b3 Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2020-12-06 13:02:26 +09:00
8543278ce3 Update about-misskey.vue 2020-12-06 13:02:01 +09:00
9a98de7bd8 Fix #6924 2020-12-06 13:00:17 +09:00
e1d69fb4ad Update about-misskey.vue 2020-12-06 12:57:36 +09:00
946f9b4a2b New Crowdin updates (#6920)
* New translations ja-JP.yml (Russian)

* 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 (Ukrainian)

* New translations ja-JP.yml (Ukrainian)

* New translations ja-JP.yml (Ukrainian)

* New translations ja-JP.yml (Ukrainian)

* New translations ja-JP.yml (Ukrainian)

* New translations ja-JP.yml (Ukrainian)
2020-12-06 12:52:27 +09:00
9a270e59a4 ㊙️ 2020-12-06 12:51:00 +09:00
2112fb3896 Add slideshow widget 2020-12-05 22:29:55 +09:00
632 changed files with 23588 additions and 4417 deletions

View File

@ -4,7 +4,7 @@ executors:
docker:
working_directory: /tmp/workspace
docker:
- image: docker:latest
- image: docker:12.10.1
jobs:
docker:
@ -32,7 +32,7 @@ jobs:
apk update && apk add jq
docker tag misskey/misskey misskey/misskey:$(cat package.json | jq -r .version)
docker login -u $DOCKERHUB_USERNAME -p $DOCKERHUB_PASSWORD
docker push misskey/misskey
docker push -a misskey/misskey
else
echo -e '\033[0;33mAborted deploying to Docker Hub\033[0;39m'
fi

View File

@ -1,3 +1,7 @@
files:
- source: /locales/ja-JP.yml
translation: /locales/%locale%.yml
update_option: update_as_unapproved
- source: /src/docs/ja-JP/*.md
translation: /src/docs/%locale%/%original_file_name%
update_option: update_as_unapproved

View File

@ -7,6 +7,9 @@ import * as gulp from 'gulp';
import * as ts from 'gulp-typescript';
import * as rimraf from 'rimraf';
import * as rename from 'gulp-rename';
import * as replace from 'gulp-replace';
const terser = require('gulp-terser');
const cssnano = require('gulp-cssnano');
const locales: { [x: string]: any } = require('./locales');
const meta = require('./package.json');
@ -25,6 +28,10 @@ gulp.task('build:copy:views', () =>
gulp.src('./src/server/web/views/**/*').pipe(gulp.dest('./built/server/web/views'))
);
gulp.task('build:copy:fonts', () =>
gulp.src('./node_modules/three/examples/fonts/**/*').pipe(gulp.dest('./built/client/assets/fonts/'))
);
gulp.task('build:copy:locales', cb => {
fs.mkdirSync('./built/client/assets/locales', { recursive: true });
@ -37,11 +44,23 @@ gulp.task('build:copy:locales', cb => {
cb();
});
gulp.task('build:copy:fonts', () =>
gulp.src('./node_modules/three/examples/fonts/**/*').pipe(gulp.dest('./built/client/assets/fonts/'))
);
gulp.task('build:client:script', () => {
return gulp.src(['./src/server/web/boot.js'])
.pipe(replace('VERSION', JSON.stringify(meta.version)))
.pipe(replace('LANGS', JSON.stringify(Object.keys(locales))))
.pipe(terser({
toplevel: true
}))
.pipe(gulp.dest('./built/server/web/'));
});
gulp.task('build:copy', gulp.parallel('build:copy:views', 'build:copy:locales', 'build:copy:fonts', () =>
gulp.task('build:client:style', () => {
return gulp.src(['./src/server/web/style.css'])
.pipe(cssnano())
.pipe(gulp.dest('./built/server/web/'));
});
gulp.task('build:copy', gulp.parallel('build:copy:locales', 'build:copy:views', 'build:client:script', 'build:client:style', 'build:copy:fonts', () =>
gulp.src([
'./src/emojilist.json',
'./src/server/web/views/**/*',

View File

@ -33,6 +33,9 @@ addUser: "Benutzer hinzufügen"
favorite: "Zu Favoriten hinzufügen"
favorites: "Favoriten"
unfavorite: "Aus Favoriten entfernen"
favorited: "Zu Favoriten hinzugefügt."
alreadyFavorited: "Bereits zu den Favoriten hinzugefügt."
cantFavorite: "Hinzufügen zu Favoriten fehlgeschlagen."
pin: "Anheften"
unpin: "Lösen"
copyContent: "Inhalt kopieren"
@ -87,6 +90,9 @@ followRequestPending: "Ausstehende Follow-Anfrage"
enterEmoji: "Gib ein Emoji ein"
renote: "Renote"
unrenote: "Renote zurücknehmen"
renoted: "Renote getätigt."
cantRenote: "Renote dieses Beitrags nicht möglich."
cantReRenote: "Renote einer Renote nicht möglich."
quote: "Zitieren"
pinnedNote: "Angepinnte Notiz"
you: "Du"
@ -237,7 +243,7 @@ nUsersRead: "Von {n} gelesen"
agreeTo: "Ich stimme {0} zu"
tos: "Nutzungsbedingungen"
start: "Anfangen"
home: "Startseite"
home: "Home"
remoteUserCaution: "Diese Informationen sind möglicherweise veraltet, da der Benutzer von einer anderen Instanz stammt."
activity: "Aktivität"
images: "Bilder"
@ -655,6 +661,15 @@ useSystemFont: "Standardschriftart des Systems verwenden"
clips: "Clips"
experimentalFeatures: "Experimentelle Funktionalitäten"
developer: "Entwickler"
makeExplorable: "Benutzerkonto in \"Erkunden\" sichtbar machen"
makeExplorableDescription: "Wenn diese Option deaktiviert ist, ist dein Benutzerkonto nicht im \"Erkunden\"-Bereich sichtbar."
showGapBetweenNotesInTimeline: "Abstände zwischen Notizen auf der Chronik anzeigen"
duplicate: "Duplizieren"
left: "Links"
center: "Mitte"
wide: "Breit"
narrow: "Schmal"
reloadToApplySetting: "Einstellungen treten nach einer Aktualisierung der Seite in Kraft. Jetzt aktualisieren?"
_aboutMisskey:
about: "Misskey ist Open-Source-Software die von syuilo seit 2014 entwickelt wird."
contributors: "Hauptmitwirkende"
@ -974,6 +989,8 @@ _widgets:
digitalClock: "Digitaluhr"
federation: "Föderation"
postForm: "Neue Notiz anfertigen"
slideshow: "Diashow"
button: "Knopf"
_cw:
hide: "Ausblenden"
show: "Mehr anzeigen"
@ -1456,6 +1473,8 @@ _notification:
_deck:
alwaysShowMainColumn: "Hauptspalte immer zeigen"
columnAlign: "Spalten ausrichten"
columnMargin: "Spaltenabstand"
columnHeaderHeight: "Spaltenkopfhöhe"
addColumn: "Spalte hinzufügen"
swapLeft: "Nach links verschieben"
swapRight: "Nach rechts verschieben"
@ -1464,6 +1483,7 @@ _deck:
stackLeft: "Nach links stapeln"
popRight: "Nach rechts vom Stapel nehmen"
_columns:
main: "Hauptspalte"
widgets: "Widgets"
notifications: "Benachrichtigungen"
tl: "Chronik"

View File

@ -33,6 +33,9 @@ addUser: "Add a user"
favorite: "Favorite"
favorites: "Favorites"
unfavorite: "Unfavorite"
favorited: "Added to favorites."
alreadyFavorited: "Already added to favorites."
cantFavorite: "Couldn't add to favorites."
pin: "Pin to profile"
unpin: "Unpin from profile"
copyContent: "Copy contents"
@ -87,6 +90,9 @@ followRequestPending: "Pending follow request"
enterEmoji: "Enter an emoji"
renote: "Renote"
unrenote: "Unrenote"
renoted: "Renoted."
cantRenote: "This post can't be renoted."
cantReRenote: "A renote can't be renoted."
quote: "Quote"
pinnedNote: "Pinned note"
you: "You"
@ -655,6 +661,15 @@ useSystemFont: "Use the system's default font"
clips: "Clips"
experimentalFeatures: "Experimental features"
developer: "Developer"
makeExplorable: "Make account visible in \"Explore\""
makeExplorableDescription: "If you turn this off, your account will not show up in the \"Explore\" section."
showGapBetweenNotesInTimeline: "Show a gap between posts on the timeline"
duplicate: "Duplicate"
left: "Left"
center: "Center"
wide: "Wide"
narrow: "Narrow"
reloadToApplySetting: "Settings will be applied upon page reload. Reload now?"
_aboutMisskey:
about: "Misskey is open-source software being developed by syuilo since 2014."
contributors: "Main contributors"
@ -974,6 +989,8 @@ _widgets:
digitalClock: "Digital clock"
federation: "Federation"
postForm: "Compose a note"
slideshow: "Slideshow"
button: "Button"
_cw:
hide: "Hide"
show: "Load more"
@ -1456,6 +1473,8 @@ _notification:
_deck:
alwaysShowMainColumn: "Always show main column"
columnAlign: "Align columns"
columnMargin: "Margin between columns"
columnHeaderHeight: " Column header height"
addColumn: "Add column"
swapLeft: "Swap to left"
swapRight: "Swap to right"
@ -1464,6 +1483,7 @@ _deck:
stackLeft: "Stack on the left"
popRight: "Pop to the right"
_columns:
main: "Main"
widgets: "Widgets"
notifications: "Notifications"
tl: "Timeline"

View File

@ -33,6 +33,9 @@ addUser: "Agregar usuario"
favorite: "Favorito"
favorites: "Favoritos"
unfavorite: "Quitar de favoritos"
favorited: "Añadido a favoritos"
alreadyFavorited: "Ya había sido añadido a favoritos"
cantFavorite: "No fue añadido a favoritos"
pin: "Fijar"
unpin: "Desfijar"
copyContent: "Copiar contenido"
@ -87,6 +90,9 @@ followRequestPending: "Solicitudes de seguimiento pendientes"
enterEmoji: "Ingresar emojis"
renote: "Renotar"
unrenote: "Quitar renota"
renoted: "Renotado"
cantRenote: "No se puede renotar este post"
cantReRenote: "No se puede renotar una renota"
quote: "Citar"
pinnedNote: "Nota fijada"
you: "Tú"
@ -95,6 +101,7 @@ sensitive: "Marcado como sensible"
add: "Agregar"
reaction: "Reacción"
reactionSettingDescription: "Asigne sus reacción favoritas que desean anclar en el selector de reacciones."
reactionSettingDescription2: "Arrastre para reordenar, click para borrar, apriete la tecla + para añadir."
rememberNoteVisibility: "Recordar visibilidad"
attachCancel: "Quitar adjunto"
markAsSensitive: "Marcar como sensible"
@ -124,7 +131,9 @@ settingGuide: "Configuración sugerida"
cacheRemoteFiles: "Mantener en cache los archivos remotos"
cacheRemoteFilesDescription: "Si desactiva esta configuración, Los archivos remotos se cargarán desde el link directo sin usar la caché. Con eso se puede ahorrar almacenamiento del servidor, pero eso aumentará el tráfico al no crear miniaturas."
flagAsBot: "Esta cuenta es un bot"
flagAsBotDescription: "En caso de que esta cuenta fuera usada por un programa, active esta opción. Al hacerlo, esta opción servirá para otros desarrolladores para evitar cadenas infinitas de reacciones, y ajustará los sistemas internos de Misskey para que trate a esta cuenta como un bot."
flagAsCat: "Esta cuenta es un gato"
flagAsCatDescription: "En caso de que declare que esta cuenta es de un gato, active esta opción."
autoAcceptFollowed: "Aceptar automáticamente las solicitudes de seguimiento de los usuarios que sigues"
addAcount: "Agregar cuenta"
loginFailed: "Error al iniciar sesión."
@ -215,6 +224,7 @@ remove: "Borrar"
removed: "Borrado"
removeAreYouSure: "¿Desea borrar \"{x}\"?"
deleteAreYouSure: "¿Desea borrar \"{x}\"?"
resetAreYouSure: "¿Desea reestablecer?"
saved: "Guardado"
messaging: "Chat"
upload: "Subir"
@ -314,6 +324,9 @@ bannerUrl: "URL de la imagen del banner"
basicInfo: "Información básica"
pinnedUsers: "Usuarios fijados"
pinnedUsersDescription: "Describir los usuarios que quiere fijar en la página \"Descubrir\" separados por una linea nueva"
pinnedPages: "Páginas fijadas"
pinnedPagesDescription: "Describa las rutas de las páginas que desea fijar a la página principal de la instancia, separadas por lineas nuevas"
pinnedClipId: "Id del clip fijado"
pinnedNotes: "Nota fijada"
hcaptcha: "hCaptcha"
enableHcaptcha: "Habilitar hCaptcha"
@ -429,6 +442,7 @@ useOsNativeEmojis: "Usa los emojis nativos de la plataforma"
youHaveNoGroups: "Sin grupos"
joinOrCreateGroup: "Obtenga una invitación para unirse al grupos o puede crear su propio grupo."
noHistory: "No hay datos en el historial"
signinHistory: "Historial de ingresos"
disableAnimatedMfm: "Deshabilitar MFM que tiene animaciones"
doing: "Voy en camino"
category: "Categoría"
@ -481,6 +495,7 @@ none: "Ninguna"
showInPage: "Mostrar en la página"
popout: "Popout"
volume: "Volumen"
masterVolume: "Volumen principal"
details: "Detalles"
chooseEmoji: "Elije un emoji"
unableToProcess: "La operación no se puede llevar a cabo"
@ -538,6 +553,9 @@ useBlurEffectForModal: "Usar efecto borroso en modales"
useFullReactionPicker: "Reacción"
width: "Ancho"
height: "Altura"
large: "Grande"
medium: "Mediano"
small: "Pequeño"
generateAccessToken: "Generar token de acceso"
permission: "Permisos"
enableAll: "Activar todo"
@ -550,6 +568,8 @@ useStarForReactionFallback: "En caso de que los emojis de reacciones no sean cla
emailConfig: "Configuración del servidor de correos"
enableEmail: "Activar el envío de correos electrónicos"
emailConfigInfo: "Usar en caso de validación de correo electrónico y pedido de contraseña"
email: "Correo"
emailAddress: "Correo electrónico"
smtpConfig: "Configuración del servidor SMTP"
smtpHost: "Host"
smtpPort: "Puerto"
@ -581,6 +601,7 @@ regenerateLoginTokenDescription: "Regenerar el token usado internamente durante
setMultipleBySeparatingWithSpace: "Puedes añadir mas de uno, separado por espacios."
fileIdOrUrl: "Id del archivo o URL"
chatOpenBehavior: "Comportamiento al abrir el chat"
behavior: "Comportamiento"
sample: "Muestra"
abuseReports: "Reportes"
reportAbuse: "Reportar"
@ -599,7 +620,32 @@ random: "Aleatorio"
system: "Sistema"
switchUi: "Cambiar interfaz de usuario"
desktop: "Escritorio"
clip: "Clip"
createNew: "Crear"
optional: "Opcional"
createNewClip: "Crear clip nuevo"
public: "Público"
i18nInfo: "Misskey está siendo traducido a varios idiomas gracias a voluntarios. Se puede colaborar traduciendo en {link}"
manageAccessTokens: "Administrar tokens de acceso"
accountInfo: "Información de la Cuenta"
notesCount: "Cantidad de notas"
repliesCount: "Cantidad de respuestas hechas"
renotesCount: "Cantidad de renotas hechas"
repliedCount: "Cantidad de respuestas recibidas"
renotedCount: "Cantidad de renotas recibidas"
followingCount: "Cantidad de seguidos"
followersCount: "Cantidad de seguidores"
sentReactionsCount: "Cantidad de reacciones hechas"
receivedReactionsCount: "Cantidad de reacciones recibidas"
pollVotesCount: "Cantidad de votaciones hechas"
pollVotedCount: "Cantidad de votaciones recibidas"
yes: "Si"
no: "No"
driveFilesCount: "Cantidad de archivos en el drive"
driveUsage: "Uso del drive"
noCrawle: "Rechazar indexación del crawler"
noCrawleDescription: "Pedir a los motores de búsqueda que no indexen tu perfil, notas, páginas, etc."
clips: "Clip"
_mfm:
cheatSheet: "Hoja de referencia de MFM"
intro: "MFM es un lenguaje de marcado dedicado que se puede usar en varios lugares dentro de Misskey. Aquí puede ver una lista de sintaxis disponibles en MFM."
@ -871,6 +917,7 @@ _widgets:
digitalClock: "Reloj digital"
federation: "Federación"
postForm: "Formulario"
button: "Botón"
_cw:
hide: "Ocultar"
show: "Ver más"

View File

@ -762,6 +762,7 @@ _widgets:
digitalClock: "Horloge numérique"
federation: "Fédération"
postForm: "Formulaire à publier"
button: "Bouton"
_cw:
hide: "Masquer"
show: "Afficher plus …"

View File

@ -33,6 +33,9 @@ addUser: "ユーザーを追加"
favorite: "お気に入り"
favorites: "お気に入り"
unfavorite: "お気に入り解除"
favorited: "お気に入りに登録しました。"
alreadyFavorited: "既にお気に入りに登録されています。"
cantFavorite: "お気に入りに登録できませんでした。"
pin: "ピン留め"
unpin: "ピン留め解除"
copyContent: "内容をコピー"
@ -87,6 +90,9 @@ followRequestPending: "フォロー許可待ち"
enterEmoji: "絵文字を入力"
renote: "Renote"
unrenote: "Renote解除"
renoted: "Renoteしました。"
cantRenote: "この投稿はRenoteできません。"
cantReRenote: "RenoteをRenoteすることはできません。"
quote: "引用"
pinnedNote: "ピン留めされたノート"
you: "あなた"
@ -655,6 +661,15 @@ useSystemFont: "システムのデフォルトのフォントを使う"
clips: "クリップ"
experimentalFeatures: "実験的機能"
developer: "開発者"
makeExplorable: "アカウントを見つけやすくする"
makeExplorableDescription: "オフにすると、「みつける」にアカウントが載らなくなります。"
showGapBetweenNotesInTimeline: "タイムラインのノートを離して表示"
duplicate: "複製"
left: "左"
center: "中央"
wide: "広い"
narrow: "狭い"
reloadToApplySetting: "設定はページリロード後に反映されます。今すぐリロードしますか?"
_aboutMisskey:
about: "Misskeyはsyuiloによって2014年から開発されている、オープンソースのソフトウェアです。"
@ -995,6 +1010,8 @@ _widgets:
digitalClock: "デジタル時計"
federation: "連合"
postForm: "投稿フォーム"
slideshow: "スライドショー"
button: "ボタン"
_cw:
hide: "隠す"
@ -1504,6 +1521,8 @@ _notification:
_deck:
alwaysShowMainColumn: "常にメインカラムを表示"
columnAlign: "カラムの寄せ"
columnMargin: "カラム間のマージン"
columnHeaderHeight: "カラムのヘッダー幅"
addColumn: "カラムを追加"
swapLeft: "左に移動"
swapRight: "右に移動"
@ -1513,6 +1532,7 @@ _deck:
popRight: "右に出す"
_columns:
main: "メイン"
widgets: "ウィジェット"
notifications: "通知"
tl: "タイムライン"

View File

@ -33,6 +33,9 @@ addUser: "ユーザーを追加や"
favorite: "お気に入り"
favorites: "お気に入り"
unfavorite: "やっぱ気に入らん"
favorited: "お気に入りに登録したで"
alreadyFavorited: "もうお気に入りに入れとるがな。"
cantFavorite: "アカン、お気に入り登録できへんかったで。"
pin: "ピン留めしとく"
unpin: "やっぱピン留めせん"
copyContent: "内容をコピー"
@ -87,6 +90,9 @@ followRequestPending: "フォロー許してくれるん待っとる"
enterEmoji: "絵文字を入れてや"
renote: "Renote"
unrenote: "Renoteやめる"
renoted: "Renoteしたで。"
cantRenote: "この投稿はRenoteできへんらしい。"
cantReRenote: "すまん、今このRenoteにRenoteはできへんのや。"
quote: "引用"
pinnedNote: "ピン留めされとるノート"
you: "あんた"
@ -95,6 +101,7 @@ sensitive: "ちょっとアカンやつやで"
add: "増やす"
reaction: "リアクション"
reactionSettingDescription: "リアクションピッカーに出しとくリアクションを選んでや。"
reactionSettingDescription2: "ドラッグして並び替え、クリックして削除、+を押すと追加できるで。"
rememberNoteVisibility: "公開範囲覚えといて"
attachCancel: "やっぱ添付やめてくれん?"
markAsSensitive: "ちょっとこれはアカン"
@ -124,7 +131,9 @@ settingGuide: "ええ感じの設定"
cacheRemoteFiles: "リモートのファイルをキャッシュする"
cacheRemoteFilesDescription: "この設定を切っとくと、リモートファイルをキャッシュせず直リンクするようになってしまうんやで? サーバーのストレージは節約できるんやけど、かわりにサムネイルが作られんくなるから通信量が増えるで?"
flagAsBot: "Botやで"
flagAsBotDescription: "もしこのアカウントがプログラムによって運用されるんやったら、このフラグをオンにしてたのむで。オンにすると、反応の連鎖を防ぐためのフラグとして他の開発者に役立ったり、Misskeyのシステム上での扱いがBotに合ったもんになるんやで。"
flagAsCat: "Catやで"
flagAsCatDescription: "ワレ、猫ちゃんならこのフラグをつけてみ?"
autoAcceptFollowed: "フォローしとるユーザーからのフォローリクエストには勝手に許可しとくで。"
addAcount: "アカウント追加"
loginFailed: "ログインに失敗してしもうた…"
@ -215,6 +224,7 @@ remove: "ほかす"
removed: "削除したで!"
removeAreYouSure: "「{x}」はなおしてしもてええか?"
deleteAreYouSure: "「{x}」はなおしてしもてええか?"
resetAreYouSure: "リセットしてええん?"
saved: "保存したで!"
messaging: "チャット"
upload: "アップロード"
@ -314,6 +324,7 @@ bannerUrl: "バナー画像のURL"
basicInfo: "基本情報"
pinnedUsers: "ピン留めしたユーザー"
pinnedUsersDescription: "「みつける」ページとかにピン留めしたいユーザーをここに書けばええんやで。他ん人との名前は改行で区切ればええんやで。"
pinnedPages: "ピン留めページ"
pinnedNotes: "ピン留めされとるノート"
hcaptcha: "hCaptchaキャプチャ"
enableHcaptcha: "hCaptchaキャプチャをつけとく"
@ -404,9 +415,42 @@ quoteQuestion: "引用として添付してもええか?"
noMessagesYet: "まだチャットはあらへんで"
newMessageExists: "新しいメッセージがきたで"
onlyOneFileCanBeAttached: "すまん、メッセージに添付できるファイルはひとつだけなんや。"
signinRequired: "ログインしてくれへん?"
invitations: "来てや"
invitationCode: "招待コード"
checking: "確認しとるで"
available: "利用できる\n"
unavailable: "利用できん"
usernameInvalidFormat: "a~z、A~Z、0~9、_が使えるで"
tooShort: "短すぎやろ!"
tooLong: "長すぎやろ!"
weakPassword: "弱いパスワード"
normalPassword: "普通のパスワード"
strongPassword: "ええ感じのパスワード"
passwordMatched: "よし!一致や!"
passwordNotMatched: "一致しとらんで?"
signinWith: "{x}でログイン"
or: "それか"
uiLanguage: "UIの表示言語"
groupInvited: "グループに招待されとるで"
aboutX: "{x}について"
useOsNativeEmojis: "OSネイティブの絵文字を使う"
youHaveNoGroups: "グループがあらへんねぇ。"
noHistory: "履歴はあらへんねぇ。"
signinHistory: "ログイン履歴"
doing: "やっとるがな"
category: "カテゴリ"
tags: "タグ"
docSource: "このドキュメントのソース"
createAccount: "アカウントを作成"
existingAcount: "既存のアカウント"
regenerate: "再生成"
fontSize: "フォントサイズ"
noFollowRequests: "フォロー申請はあらへんで"
openImageInNewTab: "画像を新しいタブで開く"
dashboard: "ダッシュボード"
local: "ローカル"
remote: "リモート"
smtpHost: "ホスト"
smtpUser: "ユーザー名"
smtpPass: "パスワード"
@ -501,6 +545,7 @@ _pages:
array: "リスト"
_notification:
youWereFollowed: "フォローされたで"
youWereInvitedToGroup: "グループに招待されとるで"
_types:
follow: "フォロー"
mention: "メンション"

View File

@ -834,6 +834,7 @@ _widgets:
digitalClock: "디지털 시계"
federation: "연합"
postForm: "글 입력란"
button: "버튼"
_cw:
hide: "숨기기"
show: "더 보기"

View File

@ -33,6 +33,9 @@ addUser: "Добавить пользователя"
favorite: "В избранное"
favorites: "Избранное"
unfavorite: "Убрать из избранного"
favorited: "Добавлено в избранное."
alreadyFavorited: "Уже есть в избранном."
cantFavorite: "Не удалось добавить в избранное."
pin: "Закрепить в профиле"
unpin: "Открепить от профиля"
copyContent: "Скопировать содержимое"
@ -87,6 +90,9 @@ followRequestPending: "Нерассмотренный запрос на подп
enterEmoji: "Введите эмодзи"
renote: "Репост"
unrenote: "Отмена репоста"
renoted: "Репост совершён."
cantRenote: "Это нельзя репостить."
cantReRenote: "Невозможно репостить репост."
quote: "Цитата"
pinnedNote: "Закреплённая заметка"
you: "Вы"
@ -95,6 +101,7 @@ sensitive: "Содержимое не для всех"
add: "Добавить"
reaction: "Реакции"
reactionSettingDescription: "Подберите, что будет у вас в палитре реакций"
reactionSettingDescription2: "Расставляйте перетаскиванием, удаляйте нажатием, добавляйте кнопкой «+»."
rememberNoteVisibility: "Запоминать видимость заметок"
attachCancel: "Удалить вложение"
markAsSensitive: "Отметить как «не для всех»"
@ -319,6 +326,7 @@ pinnedUsers: "Прикреплённый пользователь"
pinnedUsersDescription: "Перечислите по одному имени пользователя в строке. Пользователи, перечисленные здесь, будут привязаны к закладке \"Изучение\"."
pinnedPages: "Закрепленные страницы"
pinnedPagesDescription: "Если хотите закрепить страницы на главной сайта, сюда можно добавить пути к ним, каждый в отдельной строке."
pinnedClipId: "Идентификатор закреплённой памятки"
pinnedNotes: "Закреплённая заметка"
hcaptcha: "hCaptcha"
enableHcaptcha: "Включить hCaptcha"
@ -653,6 +661,12 @@ useSystemFont: "Использовать шрифт, предлагаемый с
clips: "Памятки"
experimentalFeatures: "Экспериментальные функции"
developer: "Разработчик"
makeExplorable: "Опубликовать профиль в «Обзоре»."
makeExplorableDescription: "Если выключить, ваш профиль не будет показан в разделе «Обзор»."
showGapBetweenNotesInTimeline: "Показывать разделитель между заметками в ленте"
duplicate: "Дубликат"
left: "Влево"
center: "По центру"
_aboutMisskey:
about: "Misskey — программа с открытым исходным кодом, которую разрабатывает syuilo с 2014 года."
contributors: "Основные соавторы"
@ -972,6 +986,8 @@ _widgets:
digitalClock: "Цифровые часы"
federation: "Федерация"
postForm: "Форма отправки"
slideshow: "Показ слайдов"
button: "Кнопка"
_cw:
hide: "Спрятать"
show: "Показать еще"
@ -1454,6 +1470,8 @@ _notification:
_deck:
alwaysShowMainColumn: "Всегда показывать главную колонку"
columnAlign: "Выравнивание колонок"
columnMargin: "Расстояние между колонками"
columnHeaderHeight: "Высота заголовка колонки"
addColumn: "Добавить колонку"
swapLeft: "Переставить левее"
swapRight: "Переставить правее"
@ -1462,6 +1480,7 @@ _deck:
stackLeft: "В столбик влево"
popRight: "Из столбика вправо"
_columns:
main: "Основная"
widgets: "Виджеты"
notifications: "Уведомления"
tl: "Лента"

View File

@ -82,7 +82,7 @@ defaultNoteVisibility: "Видимість за замовчуванням"
follow: "Підписка"
followRequest: "Запит на підписку"
followRequests: "Запити на підписку"
unfollow: "Відписатися"
unfollow: "Відписатись"
followRequestPending: "Очікуючі запити на підписку"
enterEmoji: "Введіть емодзі"
renote: "Поширити"
@ -143,7 +143,7 @@ recipient: "Кому"
annotation: "Коментар"
federation: "Федіверс"
instances: "Інстанс"
registeredAt: "Приєднався(-лась)"
registeredAt: "Приєднався(лась)"
latestRequestSentAt: "Останній запит надіслано"
latestRequestReceivedAt: "Останній запит прийнято"
latestStatus: "Останній статус"
@ -239,7 +239,7 @@ activity: "Активність"
images: "Зображення"
birthday: "День народження"
yearsOld: "{age} років"
registeredDate: "Приєднався(-лась)"
registeredDate: "Приєднався(лась)"
location: "Локація"
theme: "Тема"
themeForLightMode: "Світла тема"
@ -717,6 +717,8 @@ _wordMute:
hard: "Жорстко"
mutedNotes: "Заблоковані нотатки"
_theme:
defaultValue: "Значення за замовчуванням"
func: "Функції"
keys:
accent: "Акцент"
bg: "Фон"
@ -739,8 +741,10 @@ _theme:
divider: "Розділювач"
_sfx:
note: "Нотатки"
noteMy: "Мої нотатки"
notification: "Сповіщення"
chat: "Чати"
chatBg: "Чати (фон)"
_ago:
unknown: "Невідомо"
future: "Майбутнє"
@ -765,86 +769,500 @@ _tutorial:
_2fa:
registerKey: "Зареєструвати новий ключ безпеки"
_permissions:
"read:account": "Переглядати дані профілю"
"write:account": "Змінити дані акаунту"
"read:blocks": "Переглянути список заблокованих"
"write:blocks": "Редагувати список заблокованих"
"read:drive": "Переглянути вміст Диска"
"write:drive": "Змінювати вміст Диска"
"read:favorites": "Переглядати обране"
"write:favorites": "Змінювати обране"
"read:following": "Переглядати підписки"
"write:following": "Змінювати підписки"
"read:messaging": "Переглядати повідомлення"
"write:messaging": "Створювати та видаляти повідомлення"
"read:mutes": "Переглядати список ігнорованих"
"write:mutes": "Змінювати список ігнорованих"
"write:notes": "Писати і видаляти нотатки"
"read:notifications": "Переглядати сповіщення"
"read:reactions": "Переглядати реакції"
"write:reactions": "Змінювати реакції"
"write:votes": "Голосувати в опитуваннях"
"read:pages": "Переглядати сторінки"
"write:pages": "Змінювати і видаляти сторінки"
"read:page-likes": "Переглядати вподобання сторінок"
"write:page-likes": "Змінювати вподобання сторінок"
"read:user-groups": "Переглядати групи користувача"
"write:user-groups": "Змінювати групи користувача"
"read:channels": "Переглядати канали"
"write:channels": "Змінювати канали"
_auth:
shareAccess: "Ви хочете надати \"{name}\" доступ до цього акаунту?"
shareAccessAsk: "Ви впевнені, що хочете надати цій програмі доступ до вашого акаунту?"
denied: "У доступі відмовлено"
_antennaSources:
all: "Всі нотатки"
homeTimeline: "Нотатки тих, на кого ви підписані"
_weekday:
sunday: "Неділя"
monday: "Понеділок"
tuesday: "Вівторок"
wednesday: "Середа"
thursday: "Четвер"
friday: "П'ятниця"
saturday: "Субота"
_widgets:
notifications: "Сповіщення"
timeline: "Стрічка"
calendar: "Календар"
trends: "Тенденції"
clock: "Годинник"
rss: "RSS-читач"
activity: "Активність"
photos: "Фото"
digitalClock: "Цифровий годинник"
federation: "Федіверс"
postForm: "Створення нотатки"
slideshow: "Слайд-шоу"
button: "Кнопка"
_cw:
hide: "Сховати"
show: "Показати більше"
chars: "{count} символів"
files: "{count} файлів"
_poll:
noOnlyOneChoice: "Потрібні принаймні два варіанти."
noMore: "Більше варіантів додати не можна"
canMultipleVote: "Можна вибрати кілька варіантів"
expiration: "Опитування закінчується"
infinite: "Ніколи"
deadlineDate: "Дата закінчення"
deadlineTime: "г"
duration: "Тривалість"
votesCount: "{n} голосів"
totalVotes: "Всього {n} голосів"
vote: "Голосувати"
showResult: "Переглянути результати"
voted: "Проголосовано"
closed: "Завершено"
remainingDays: "Залишилось {d} днів {h} годин"
remainingHours: "Залишилось {h} годин {m} хвилин"
remainingMinutes: "Залишилось {m} хвилин {s} секунд"
remainingSeconds: "Залишилось {s} секунд"
_visibility:
public: "Публічний"
publicDescription: "Для всіх користувачів"
home: "Домівка"
homeDescription: "Лише на домашній стрічці"
followers: "Підписники"
localOnly: "Лише локально"
followersDescription: "Тільки для підписників"
specified: "Особисто"
specifiedDescription: "Лише для певних користувачів"
localOnly: "Локально"
localOnlyDescription: "Приховано для віддалених користувачів"
_postForm:
replyPlaceholder: "Відповідь на цю нотатку..."
quotePlaceholder: "Прокоментуйте цю нотатку..."
channelPlaceholder: "Опублікувати в каналі"
_placeholders:
a: "Чим займаєтесь?"
b: "Що відбувається навколо вас?"
c: "Що у вас на думці?"
d: "Що ви хочете висловити?"
e: "Напишіть тут, будь ласка..."
f: "Чекаю коли ви напишете..."
_profile:
name: "Ім'я"
username: "Ім'я користувача"
description: "Про себе"
youCanIncludeHashtags: "Ви також можете включити хештеги у свій опис."
metadata: "Додаткова інформація"
metadataEdit: "Редагувати додаткову інформацію"
metadataDescription: "Ви можете вказати до чотирьох пунктів додаткової інформації у своєму профілі."
metadataLabel: "Назва"
metadataContent: "Вміст"
changeAvatar: "Змінити аватар"
changeBanner: "Змінити банер"
_exportOrImport:
allNotes: "Всі нотатки"
followingList: "Підписки"
muteList: "Ігнорувати"
blockingList: "Заблокувати"
userLists: "Списки"
_charts:
federationInstancesTotal: "Загальна кількість федеративних інстансів"
usersTotal: "Загальна кількість користувачів"
activeUsers: "Активні користувачі"
notesTotal: "Загальна кількість нотаток"
filesIncDec: "Зміни кількості файлів"
filesTotal: "Загальна кількість файлів"
_instanceCharts:
requests: "Запити"
usersTotal: "Сумарна кількість користувачів"
notesTotal: "Сумарна кількість нотаток"
cacheSizeTotal: "Сумарний розмір кешу"
filesTotal: "Сумарна кількість файлів"
_timelines:
home: "Домівка"
local: "Локальна"
social: "Соціальна"
global: "Глобальна"
_rooms:
roomOf: "Кімната {user}"
addFurniture: "Розмістити меблі"
translate: "Пересунути"
rotate: "Обертати"
exit: "Назад"
remove: "Видалити"
clear: "Видалити все"
leaveConfirm: "Є незбережені зміни. Ви дійсно хочете вийти?"
chooseImage: "Виберіть зображення"
roomType: "Тип кімнати"
carpetColor: "Колір килима"
_roomType:
default: "За умовчанням"
default: "За замовчуванням"
washitsu: "В японському стилі"
_furnitures:
milk: "Пакет молока"
bed: "Ліжко"
low-table: "Журнальний стіл"
desk: "Письмовий стіл"
chair: "Стілець"
chair2: "Стілець 2"
fan: "Вентилятор"
pc: "Комп’ютер"
plant: "Кімнатна рослина"
plant2: "Кімнатна рослина 2"
eraser: "Ластик"
pencil: "Олівець"
pudding: "Пудинг"
cardboard-box: "Картонна коробка"
cardboard-box2: "Картонна коробка 2"
cardboard-box3: "Картонна коробка 3"
book: "Книга"
book2: "Книга 2"
piano: "Піаніно"
facial-tissue: "Серветки"
server: "Сервер"
moon: "Місяць"
corkboard: "Коркова дошка"
mousepad: "Килимок для миші"
monitor: "Монітор"
keyboard: "Клавіатура"
carpet-stripe: "Смугастий килим"
mat: "Мат"
color-box: "Книжкова полиця"
wall-clock: "Настінний годинник"
photoframe: "Фоторамка"
cube: "Куб"
tv: "Телевізор"
pinguin: "Пінгвін"
rubik-cube: "Кубик Рубіка"
poster-h: "Плакат (горизонтальний)"
poster-v: "Плакат (вертикальний)"
sofa: "Диван"
spiral: "Гвинтові сходи"
bin: "Смітник"
holo-display: "Голографічний дисплей"
energy-drink: "Енергетичний напій"
doll-ai: "Лялька Аі-тян"
banknote: "Пачка грошей"
_pages:
newPage: "Створити сторінку"
editPage: "Редагувати сторінку"
readPage: "Перегляд вихідного коду"
created: "Сторінка успішно створена."
updated: "Сторінка успішно оновлена."
deleted: "Сторінку видалено"
pageSetting: "Налаштування сторінки"
nameAlreadyExists: "Вказана адреса сторінки вже існує."
invalidNameTitle: "Вказана адреса сторінки неприпустима."
invalidNameText: "Переконайтеся, що не залишили порожнім."
editThisPage: "Редагувати цю сторінку"
viewSource: "Переглянути вихідний код"
viewPage: "Переглянути свої сторінки"
like: "Вподобати"
unlike: "Не вподобати"
my: "Мої сторінки"
liked: "Вподобані сторінки"
featured: "Популярні"
inspector: "Інспектор"
contents: "Вміст"
variables: "Змінні"
title: "Заголовок"
url: "URL сторінки"
summary: "Короткий зміст"
alignCenter: "Рівняти елементи по центру"
hideTitleWhenPinned: "Приховати заголовок сторінки при закріпленні в профілі"
font: "Шрифт"
fontSerif: "Serif"
fontSansSerif: "Sans serif"
eyeCatchingImageSet: "Встановити привабливе зображення"
eyeCatchingImageRemove: "Видалити привабливе зображення"
chooseBlock: "Додати блок"
selectType: "Виберіть тип"
enterVariableName: "Введіть назву для змінної"
contentBlocks: "Контент"
inputBlocks: "Ввід"
specialBlocks: "Особливе"
blocks:
text: "Текст"
textarea: "Текстова область"
section: "Розділ"
image: "Зображення"
button: "Кнопка"
if: "Якщо"
_if:
variable: "Змінні"
post: "Створення нотатки"
_post:
text: "Вміст"
textInput: "Введення тексту"
_textInput:
name: "Ім'я змінної"
text: "Назва"
default: "Значення за замовчуванням"
textareaInput: "Багаторядкове введення тексту"
_textareaInput:
name: "Ім'я змінної"
text: "Назва"
default: "Значення за замовчуванням"
numberInput: "Числове введення"
_numberInput:
name: "Ім'я змінної"
text: "Назва"
default: "Значення за замовчуванням"
_canvas:
width: "Ширина"
height: "Висота"
note: "Вбудована нотатка"
_note:
id: "Ідентифікатор нотатки"
idDescription: "Також можна вказати посилання на нотатку"
detailed: "Детальний вигляд"
switch: "Перемикач"
_switch:
name: "Ім'я змінної"
text: "Назва"
default: "Значення за замовчуванням"
counter: "Лічильник"
_counter:
name: "Ім'я змінної"
text: "Назва"
inc: "Збільшити на"
_button:
text: "Напис"
_action:
_dialog:
content: "Вміст"
resetRandom: "Скидання генератора випадковості"
pushEvent: "Надіслати подію"
_pushEvent:
event: "Назві події"
message: "Повідомлення для відображення при активації"
variable: "Змінна для надсилання"
no-variable: "Відсутньо"
callAiScript: "Виклик AiScript"
_callAiScript:
functionName: "Ім'я функції"
radioButton: "Вибір"
_radioButton:
name: "Ім'я змінної"
title: "Напис"
values: "Варіанти, розділені розривами рядків"
default: "Значення за замовчуванням"
script:
categories:
flow: "Керування потоком"
logical: "Логічні операції"
operation: "Обчислення"
comparison: "Порівняння"
random: "Випадковість"
value: "Значення"
fn: "Функції"
text: "Дії з текстом"
convert: "Перетворення"
list: "Списки"
blocks:
text: "Текст"
multiLineText: "Текст (багаторядковий)"
textList: "Текстовий список"
strLen: "Довжина тексту"
_strLen:
arg1: "Текст"
_strPick:
arg1: "Текст"
strReplace: "Заміна тексту"
_strReplace:
arg1: "Текст"
arg2: "Текст, який потрібно замінити"
arg3: "Заміняти на"
strReverse: "Перевернути текст"
_strReverse:
arg1: "Текст"
join: "Конкатенація тексту"
_join:
arg1: "Списки"
arg2: "Розділювач"
add: "Додати"
_add:
arg1: "A"
arg2: "B"
subtract: "Відняти"
_subtract:
arg1: "A"
arg2: "B"
multiply: "Помножити"
_multiply:
arg1: "A"
arg2: "B"
divide: "Поділити"
_divide:
arg1: "A"
arg2: "B"
mod: "Остача"
_mod:
arg1: "A"
arg2: "B"
round: "Десяткове округлення"
_round:
arg1: "Число"
eq: "A дорівнює B"
_eq:
arg1: "A"
arg2: "B"
notEq: "A не дорівнює B"
_notEq:
arg1: "A"
arg2: "B"
and: "А І Б"
_and:
arg1: "A"
arg2: "B"
or: "A АБО B"
_or:
arg1: "A"
arg2: "B"
lt: "< A менше, ніж B"
_lt:
arg1: "A"
arg2: "B"
gt: "> A більше, ніж B"
_gt:
arg1: "A"
arg2: "B"
ltEq: "<= A менше або дорівнює B"
_ltEq:
arg1: "A"
arg2: "B"
gtEq: ">= A більше або дорівнює B"
_gtEq:
arg1: "A"
arg2: "B"
if: "Умова"
_if:
arg1: "Якщо"
arg2: "Якщо так"
arg3: "Якщо ні"
not: "НЕ"
_not:
arg1: "НЕ"
random: "Випадково"
_random:
arg1: "Імовірність"
rannum: "Випадкове число"
_rannum:
arg1: "Мінімальне значення"
arg2: "Максимальне значення"
randomPick: "Випадковий вибір зі списку"
_randomPick:
arg1: "Списки"
dailyRandom: "Випадково (триває добу)"
_dailyRandom:
arg1: "Імовірність"
dailyRannum: "Випадкове число (триває добу)"
_dailyRannum:
arg1: "Мінімальне значення"
arg2: "Максимальне значення"
dailyRandomPick: "Випадково вибрати зі списку (триває добу)"
_dailyRandomPick:
arg1: "Списки"
seedRandom: "Випадковість (з насінням)"
_seedRandom:
arg1: "Насіння"
arg2: "Імовірність"
seedRannum: "Випадкове число (з насінням)"
_seedRannum:
arg1: "Насіння"
arg2: "Мінімальне значення"
arg3: "Максимальне значення"
seedRandomPick: "Випадково вибрати зі списку (з насінням)"
_seedRandomPick:
arg1: "Насіння"
arg2: "Списки"
DRPWPM: "Випадково вибрати зі зваженого списку (триває добу)"
_DRPWPM:
arg1: "Текстовий список"
pick: "Вибір зі списку"
_pick:
arg1: "Списки"
arg2: "Позиція"
listLen: "Отримати довжину списку"
_listLen:
arg1: "Списки"
number: "Число"
stringToNumber: "Текст на число"
_stringToNumber:
arg1: "Текст"
numberToString: "Число на текст"
_numberToString:
arg1: "Число"
splitStrByLine: "Розбиття тексту на рядки"
_splitStrByLine:
arg1: "Текст"
ref: "Змінні"
aiScriptVar: "Змінна AiScript"
fn: "Функції"
_fn:
arg1: "Вихід"
arg1: "Вивід"
for: "Повторення"
_for:
arg1: "Кількість повторень"
arg2: "Дія"
types:
string: "Текст"
number: "Число"
boolean: "Прапорець"
array: "Списки"
stringArray: "Текстовий список"
_relayStatus:
requesting: "Очікує затвердження"
accepted: "Затверджено"
rejected: "Відхилено"
_notification:
fileUploaded: "Файл успішно завантажено"
youGotMention: "{name} згадує вас"
youGotReply: "{name} відповідає"
youGotQuote: "{name} цитує вас"
youRenoted: "{name} поширює"
youGotPoll: "{name} бере участь в опитуванні"
youGotMessagingMessageFromUser: "Повідомлення від {name}"
youGotMessagingMessageFromGroup: "Нове повідомлення в групі {name}"
youWereFollowed: "Новий підписник"
youReceivedFollowRequest: "Ви отримали запит на підписку"
yourFollowRequestAccepted: "Запит на підписку прийнято"
youWereInvitedToGroup: "Запрошення до групи"
_types:
all: "Все"
follow: "Підписки"
mention: "Згадка"
renote: "Поширити"
quote: "Цитата"
reply: "Відповіді"
renote: "Поширення"
quote: "Цитування"
reaction: "Реакції"
pollVote: "Опитування"
receiveFollowRequest: "Запит на підписку"
followRequestAccepted: "Прийнята підписка"
receiveFollowRequest: "Запити на підписку"
followRequestAccepted: "Прийняті підписки"
groupInvited: "Запрошення до груп"
app: "Сповіщення від додатків"
_deck:

View File

@ -11,7 +11,7 @@ ok: "OK"
gotIt: "我明白了"
cancel: "取消"
enterUsername: "输入用户名"
renotedBy: "{user} 转了"
renotedBy: "{user} 转了"
noNotes: "没有帖文"
noNotifications: "无通知"
instance: "实例"
@ -33,6 +33,9 @@ addUser: "添加用户"
favorite: "收藏"
favorites: "收藏"
unfavorite: "取消收藏"
favorited: "已加入收藏夹。"
alreadyFavorited: "收藏夹中已存在。"
cantFavorite: "无法添加到收藏夹。"
pin: "置顶"
unpin: "取消置顶"
copyContent: "复制内容"
@ -87,6 +90,9 @@ followRequestPending: "发送关注申请"
enterEmoji: "输入表情符号"
renote: "转发"
unrenote: "取消转发"
renoted: "已转发。"
cantRenote: "该帖子无法转发。"
cantReRenote: "转发无法被再次转发。"
quote: "引用"
pinnedNote: "已置顶的帖子"
you: "您"
@ -116,7 +122,7 @@ selectAntenna: "天线选择"
selectWidget: "选择小工具"
editWidgets: "编辑小工具"
editWidgetsExit: "完成编辑"
customEmojis: "自定义Emoji"
customEmojis: "自定义表情符号"
emoji: "表情符号"
emojiName: "表情符号名称"
emojiUrl: "表情符号地址"
@ -533,7 +539,7 @@ poll: "调查问卷"
useCw: "隐藏内容"
enablePlayer: "打开播放器"
disablePlayer: "关闭播放器"
expandTweet: "展开文"
expandTweet: "展开文"
themeEditor: "主题编辑器"
description: "描述"
author: "作者"
@ -655,6 +661,15 @@ useSystemFont: "使用系统默认字体"
clips: "片段"
experimentalFeatures: "实验性功能"
developer: "开发者"
makeExplorable: "使账号可见。"
makeExplorableDescription: "关闭时,账号不会显示在\"发现\"中。"
showGapBetweenNotesInTimeline: "时间线上的帖子分开显示。"
duplicate: "复制"
left: "左"
center: "中央"
wide: "宽"
narrow: "窄"
reloadToApplySetting: "页面刷新后设置才会生效。是否现在刷新页面?"
_aboutMisskey:
about: "Misskey是由syuilo于2014年开发的开源软件。"
contributors: "主要贡献者"
@ -775,7 +790,7 @@ _wordMute:
muteWords: "禁用词"
muteWordsDescription: "使用空格分隔表示AND逻辑使用换行符分隔表示OR逻辑。"
muteWordsDescription2: "将关键字用斜线括起来表示正则表达式。"
softDescription: "隐藏时间中指定条件的帖文。"
softDescription: "隐藏时间线中指定条件的帖文。"
hardDescription: "防止将具有指定条件的帖文添加到时间线。 即使您更改条件,未添加的帖文也会被排除在外。"
soft: "软屏蔽"
hard: "硬屏蔽"
@ -974,6 +989,8 @@ _widgets:
digitalClock: "数字时钟"
federation: "联邦宇宙"
postForm: "投稿窗口"
slideshow: "幻灯片展示"
button: "按钮"
_cw:
hide: "隐藏"
show: "查看更多"
@ -1456,6 +1473,8 @@ _notification:
_deck:
alwaysShowMainColumn: "总是显示主列"
columnAlign: "列对齐"
columnMargin: "列间距"
columnHeaderHeight: "列标题高度"
addColumn: "添加列"
swapLeft: "向左移动"
swapRight: "向右移动"
@ -1464,6 +1483,7 @@ _deck:
stackLeft: "向左折叠"
popRight: "向右弹出"
_columns:
main: "主列"
widgets: "小工具"
notifications: "通知"
tl: "时间线"

View File

@ -12,7 +12,7 @@ gotIt: "知道了"
cancel: "取消"
enterUsername: "輸入使用者名稱"
renotedBy: "{user} 轉發了"
noNotes: "文不可用。"
noNotes: "文不可用。"
noNotifications: "沒有通知"
instance: "實例"
settings: "設定"
@ -63,8 +63,8 @@ exportRequested: "已請求匯出。這可能會花一點時間。結束後檔
importRequested: "已請求匯入。這可能會花一點時間"
lists: "清單"
noLists: "沒有清單"
note: "文"
notes: "筆記"
note: "文"
notes: "箋文"
following: "追隨中"
followers: "追隨者"
followsYou: "追隨你的人"
@ -86,6 +86,7 @@ followRequestPending: "追隨許可批准中"
enterEmoji: "輸入表情符號"
renote: "轉發貼文"
unrenote: "取消轉發貼文"
renoted: "轉發成功"
quote: "引用"
pinnedNote: "已置頂的貼文"
you: "您"
@ -289,7 +290,7 @@ tosUrl: "服務條款URL"
thisYear: "今年"
thisMonth: "本月"
today: "本日"
dayX: "{day}"
dayX: "{day}"
monthX: "{month}月"
yearX: "{year}年"
pages: "頁面"
@ -330,6 +331,7 @@ antennaKeywords: "包含關鍵字"
antennaExcludeKeywords: "排除關鍵字"
antennaKeywordsDescription: "用空格分隔指定AND、用換行符分隔指定OR"
notifyAntenna: "通知我有新的貼文"
withFileAntenna: "僅帶有附件的箋文"
serviceworker: "ServiceWorker"
enableServiceworker: "開啟 ServiceWorker"
antennaUsersDescription: "指定用換行符分隔的用戶名"
@ -393,7 +395,7 @@ text: "文字"
enable: "啟用"
next: "下一步"
retype: "重新輸入"
noteOf: "{user}的文"
noteOf: "{user}的文"
inviteToGroup: "邀請至群組"
maxNoteTextLength: "貼文的字數限制"
quoteAttached: "引用"
@ -459,7 +461,9 @@ objectStorageUseSSL: "使用SSL"
objectStorageUseProxy: "使用網路代理"
serverLogs: "伺服器日誌"
deleteAll: "刪除所有記錄"
newNoteRecived: "有新的箋文"
sounds: "音效"
listen: "聆聽"
none: "無"
showInPage: "在頁面中顯示"
volume: "音量"
@ -515,6 +519,9 @@ deck: "多欄模式"
undeck: "取消多欄模式"
width: "寬度"
height: "高度"
large: "大"
medium: "中"
small: "小"
permission: "權限"
enableAll: "啟用全部"
disableAll: "停用全部"
@ -525,6 +532,8 @@ useStarForReactionFallback: "以★代替未知的表情符號"
emailConfig: "電子郵件伺服器設定"
enableEmail: "啟用發送電郵功能"
emailConfigInfo: "用於確認電郵地址及密碼重置"
email: "電子郵件"
emailAddress: "電郵地址"
smtpConfig: "SMTP伺服器設定"
smtpHost: "主機"
smtpPort: "端口"
@ -545,19 +554,46 @@ create: "新增"
notificationSetting: "通知設定"
other: "其他"
regenerateLoginTokenDescription: "再生用於登入的內部權杖。一般情況下是不需要這樣做的。一旦再生,所有裝置將會被登出。"
behavior: "行為"
sample: "範例 "
abuseReports: "檢舉"
reportAbuse: "檢舉"
reportAbuseOf: "檢舉{name}"
fillAbuseReportDescription: "請填寫檢舉的詳細理由。可以的話請附上針對的URL網址。"
send: "發送"
openInNewTab: "在新分頁中開啟"
instanceTicker: "箋文的實例資訊"
random: "隨機"
system: "系統"
switchUi: "切換界面"
optional: "可選"
public: "公開"
notesCount: "箋文數量"
repliesCount: "回覆數量\n"
renotesCount: "轉發數量"
repliedCount: "回覆數量"
yes: "確定"
no: "取消"
driveFilesCount: "雲端硬碟檔案數量"
driveUsage: "雲端硬碟使用量"
noCrawleDescription: "請求網路搜尋引擎不要索引你的個人資料頁、箋文及頁面等。"
lockedAccountInfo: "即使你通過了追隨者請求,除非你將筆記的公開範圍設定為 「追隨者」,否則任何人都能看見你的箋文。"
noteFavoritesCount: "收藏箋文的數目"
contact: "聯絡人"
clips: "標籤"
experimentalFeatures: "測試中的功能"
developer: "開發者"
showGapBetweenNotesInTimeline: "分開顯示時間線上的箋文。"
_aboutMisskey:
about: "Misskey是由syuilo於2014年開發的開源軟件。"
contributors: "主要貢獻者"
_mfm:
mention: "提及"
hashtag: "#tag"
url: "URL"
link: "鏈接"
bold: "粗體"
center: "置中"
quote: "引用"
emoji: "自訂表情符號"
search: "搜尋"
@ -598,7 +634,8 @@ _sidebar:
hide: "隱藏"
_wordMute:
muteWords: "加入靜音文字"
mutedNotes: "已靜音的貼文"
softDescription: "隱藏時間軸中指定條件的箋文。"
mutedNotes: "已靜音的箋文"
_theme:
constant: "常數"
defaultValue: "預設值"
@ -623,8 +660,8 @@ _theme:
infoWarnBg: "警告背景"
infoWarnFg: "警告字元"
_sfx:
note: "文"
noteMy: "我的文"
note: "文"
noteMy: "我的文"
notification: "通知"
chat: "傳送訊息"
channel: "頻道通知"
@ -643,7 +680,7 @@ _time:
second: "秒"
minute: "分鐘"
hour: "小時"
day: ""
day: ""
_tutorial:
title: "Misskey使用方法"
step1_1: "歡迎!"
@ -656,7 +693,7 @@ _tutorial:
step3_3: "輸入完內容後,按視窗右上角的按鈕來發文"
step3_4: "不知道該寫什麼內容嗎試試看「開始使用Misskey了」如何。"
step4_1: "筆記發出去了嗎?"
step4_2: "如果你的貼文有顯示在時間軸上,就代表已經發文成功。"
step4_2: "如果你的箋文出現在時間軸上,就代表發文成功。"
step5_1: "現在試試看追隨其他人來讓你的時間軸變得更生動吧。"
step5_2: "你可以在{featured}上看到受歡迎的貼文,你也可以選擇從列表中追隨你喜歡的人,或者在{explore}上找到熱門使用者。"
step5_3: "想要追隨其他人,只要點擊他們的頭像並按「追隨」即可。"
@ -680,7 +717,7 @@ _permissions:
"write:messaging": "撰寫或刪除私人訊息"
"read:mutes": "顯示已靜音列表"
"write:mutes": "編輯已靜音列表"
"write:notes": "撰寫或刪除文"
"write:notes": "撰寫或刪除文"
"read:notifications": "查看通知"
"write:notifications": "編輯通知"
"read:reactions": "查看反應"
@ -697,11 +734,11 @@ _permissions:
_auth:
shareAccess: "要授權「“{name}”」存取您的帳戶嗎?"
_antennaSources:
all: "全部文"
homeTimeline: "來自已追隨使用者的文"
users: "來自特定使用者的文"
userList: "來自特定清單中的文"
userGroup: "來自特定群組的文"
all: "全部文"
homeTimeline: "來自已追隨使用者的文"
users: "來自特定使用者的文"
userList: "來自特定清單中的文"
userGroup: "來自特定群組的文"
_weekday:
sunday: "週日"
monday: "週一"
@ -722,6 +759,7 @@ _widgets:
photos: "照片"
digitalClock: "電子時鐘"
federation: "聯邦宇宙"
button: "按鈕"
_cw:
hide: "隱藏"
show: "瀏覽更多"
@ -751,7 +789,7 @@ _visibility:
localOnly: "僅限本地"
localOnlyDescription: "對遠端使用者隱藏"
_postForm:
replyPlaceholder: "回覆此文..."
replyPlaceholder: "回覆此文..."
quotePlaceholder: "引用此貼文..."
channelPlaceholder: "發佈到頻道"
_placeholders:
@ -769,7 +807,7 @@ _profile:
metadataLabel: "標籤"
metadataContent: "内容"
_exportOrImport:
allNotes: "全部文"
allNotes: "全部文"
followingList: "追隨中"
muteList: "靜音"
blockingList: "封鎖"
@ -778,10 +816,10 @@ _charts:
usersIncDec: "使用者増減"
usersTotal: "使用者合共"
activeUsers: "活躍使用者"
notesIncDec: "文増減"
localNotesIncDec: "本地文増減"
remoteNotesIncDec: "非本地貼文的數目增减"
notesTotal: "文合共"
notesIncDec: "文増減"
localNotesIncDec: "本地文増減"
remoteNotesIncDec: "遠端箋文數目增减"
notesTotal: "文合共"
filesIncDec: "檔案増減"
filesTotal: "累計檔案"
storageUsageIncDec: "儲存空間的増減"
@ -790,8 +828,8 @@ _instanceCharts:
requests: "請求"
users: "使用者増減"
usersTotal: "總計使用者"
notes: "文増減"
notesTotal: "累計文"
notes: "文増減"
notesTotal: "累計文"
ff: "追隨/追隨者的増減"
ffTotal: "追隨/追隨者累計"
cacheSize: "增加或減少快取用量"
@ -904,6 +942,10 @@ _pages:
id: "畫布ID"
width: "寬度"
height: "高度"
note: "嵌式箋文"
_note:
id: "箋文ID"
detailed: "顯示詳細內容"
switch: "開關"
_switch:
name: "變數名稱"

View File

@ -0,0 +1,18 @@
import {MigrationInterface, QueryRunner} from "typeorm";
export class isExplorable1607353487793 implements MigrationInterface {
name = 'isExplorable1607353487793'
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "user" ADD "isExplorable" boolean NOT NULL DEFAULT true`);
await queryRunner.query(`COMMENT ON COLUMN "user"."isExplorable" IS 'Whether the User is explorable.'`);
await queryRunner.query(`CREATE INDEX "IDX_d5a1b83c7cab66f167e6888188" ON "user" ("isExplorable") `);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`DROP INDEX "IDX_d5a1b83c7cab66f167e6888188"`);
await queryRunner.query(`COMMENT ON COLUMN "user"."isExplorable" IS 'Whether the User is explorable.'`);
await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "isExplorable"`);
}
}

View File

@ -1,7 +1,7 @@
{
"name": "misskey",
"author": "syuilo <syuilotan@yahoo.co.jp>",
"version": "12.62.0",
"version": "12.64.0",
"codename": "indigo",
"repository": {
"type": "git",
@ -41,7 +41,7 @@
"@fortawesome/free-brands-svg-icons": "5.15.1",
"@fortawesome/free-regular-svg-icons": "5.15.1",
"@fortawesome/free-solid-svg-icons": "5.15.1",
"@fortawesome/vue-fontawesome": "3.0.0-2",
"@fortawesome/vue-fontawesome": "3.0.0-3",
"@koa/cors": "3.1.0",
"@koa/multer": "3.0.0",
"@koa/router": "9.0.1",
@ -62,7 +62,7 @@
"@types/jsdom": "16.2.5",
"@types/jsonld": "1.5.1",
"@types/katex": "0.11.0",
"@types/koa": "2.11.3",
"@types/koa": "2.11.6",
"@types/koa-bodyparser": "4.3.0",
"@types/koa-cors": "0.0.0",
"@types/koa-favicon": "2.0.19",
@ -70,18 +70,19 @@
"@types/koa-mount": "4.0.0",
"@types/koa-send": "4.1.2",
"@types/koa-views": "2.0.4",
"@types/koa__cors": "3.0.1",
"@types/koa__cors": "3.0.2",
"@types/koa__multer": "2.0.2",
"@types/koa__router": "8.0.2",
"@types/markdown-it": "10.0.3",
"@types/matter-js": "0.14.8",
"@types/mocha": "7.0.2",
"@types/node": "14.0.22",
"@types/node": "14.14.13",
"@types/node-fetch": "2.5.7",
"@types/nodemailer": "6.4.0",
"@types/nprogress": "0.2.0",
"@types/oauth": "0.9.1",
"@types/parse5": "5.0.3",
"@types/parsimmon": "1.10.5",
"@types/parsimmon": "1.10.6",
"@types/portscanner": "2.1.0",
"@types/pug": "2.0.4",
"@types/qrcode": "1.3.5",
@ -92,7 +93,7 @@
"@types/request-stats": "3.0.0",
"@types/rimraf": "3.0.0",
"@types/seedrandom": "2.4.28",
"@types/sharp": "0.26.0",
"@types/sharp": "0.26.1",
"@types/sinonjs__fake-timers": "6.0.1",
"@types/speakeasy": "2.0.5",
"@types/tinycolor2": "1.4.2",
@ -103,17 +104,17 @@
"@types/webpack-stream": "3.2.11",
"@types/websocket": "1.0.1",
"@types/ws": "7.4.0",
"@typescript-eslint/parser": "4.6.1",
"@typescript-eslint/parser": "4.10.0",
"@vue/compiler-sfc": "3.0.3",
"abort-controller": "3.0.0",
"apexcharts": "3.22.2",
"apexcharts": "3.22.3",
"autobind-decorator": "2.4.0",
"autosize": "4.0.2",
"autwh": "0.1.0",
"aws-sdk": "2.787.0",
"aws-sdk": "2.809.0",
"bcryptjs": "2.4.3",
"blurhash": "1.1.3",
"bull": "3.18.1",
"bull": "3.20.0",
"cafy": "15.2.1",
"cbor": "5.1.0",
"chalk": "4.1.0",
@ -121,28 +122,30 @@
"cli-highlight": "2.1.9",
"commander": "4.1.1",
"content-disposition": "0.5.3",
"core-js": "3.7.0",
"core-js": "3.8.1",
"crc-32": "1.2.0",
"css-loader": "5.0.1",
"cssnano": "4.1.10",
"dateformat": "3.0.3",
"dateformat": "4.3.1",
"deep-entries": "3.1.0",
"diskusage": "1.1.3",
"double-ended-queue": "2.1.0-0",
"escape-regexp": "0.0.1",
"eslint": "7.14.0",
"eslint-plugin-vue": "7.1.0",
"eslint": "7.16.0",
"eslint-plugin-vue": "7.3.0",
"eventemitter3": "4.0.7",
"feed": "4.2.1",
"fibers": "5.0.0",
"file-type": "16.0.1",
"fluent-ffmpeg": "2.1.2",
"glob": "7.1.6",
"got": "11.8.0",
"got": "11.8.1",
"gulp": "4.0.2",
"gulp-cssnano": "2.1.3",
"gulp-rename": "2.0.0",
"gulp-replace": "1.0.0",
"gulp-sourcemaps": "2.6.5",
"gulp-terser": "2.0.0",
"gulp-tslint": "8.1.4",
"gulp-typescript": "6.0.0-alpha.1",
"hard-source-webpack-plugin": "0.13.1",
@ -151,7 +154,6 @@
"http-proxy-agent": "4.0.1",
"http-signature": "1.3.5",
"https-proxy-agent": "5.0.0",
"idb-keyval": "3.2.0",
"insert-text-at-cursor": "0.3.0",
"is-root": "2.1.0",
"is-svg": "4.2.1",
@ -175,13 +177,14 @@
"lookup-dns-cache": "2.1.0",
"markdown-it": "11.0.1",
"markdown-it-anchor": "6.0.1",
"matter-js": "0.14.2",
"mocha": "8.2.1",
"moji": "0.5.1",
"ms": "2.1.2",
"ms": "2.1.3",
"multer": "1.4.2",
"nested-property": "4.0.0",
"node-fetch": "2.6.1",
"nodemailer": "6.4.16",
"nodemailer": "6.4.17",
"object-assign-deep": "0.4.0",
"os-utils": "0.0.14",
"p-cancelable": "2.0.0",
@ -189,7 +192,7 @@
"parsimmon": "1.16.0",
"pg": "8.5.1",
"portscanner": "2.2.0",
"postcss": "8.1.14",
"postcss": "8.2.1",
"postcss-loader": "4.1.0",
"prismjs": "1.22.0",
"probe-image-size": "6.0.0",
@ -223,45 +226,42 @@
"style-loader": "2.0.0",
"summaly": "2.4.0",
"syslog-pro": "1.0.0",
"systeminformation": "4.30.7",
"systeminformation": "4.31.1",
"syuilo-password-strength": "0.0.1",
"textarea-caret": "3.1.0",
"three": "0.117.1",
"tinycolor2": "1.4.2",
"tmp": "0.2.1",
"ts-loader": "8.0.9",
"ts-loader": "8.0.11",
"ts-node": "9.1.0",
"tslint": "6.1.3",
"tslint-sonarts": "1.9.0",
"typeorm": "0.2.29",
"typescript": "4.0.5",
"typescript": "4.1.2",
"ulid": "2.3.0",
"url-loader": "4.1.1",
"uuid": "8.3.1",
"uuid": "8.3.2",
"v-debounce": "0.1.2",
"vanilla-tilt": "1.7.0",
"vue": "3.0.3",
"vue-color": "2.7.1",
"vue-i18n": "9.0.0-beta.7",
"vue-json-pretty": "1.7.1",
"vue-loader": "16.0.0",
"vue-prism-editor": "2.0.0-alpha.2",
"vue-router": "4.0.0-rc.6",
"vue-router": "4.0.1",
"vue-style-loader": "4.1.2",
"vuedraggable": "4.0.1",
"vuex": "4.0.0-rc.2",
"vuex-persistedstate": "3.1.0",
"web-push": "3.4.4",
"webpack": "5.9.0",
"webpack": "5.10.1",
"webpack-cli": "4.2.0",
"websocket": "1.0.32",
"ws": "7.4.0",
"websocket": "1.0.33",
"ws": "7.4.1",
"xev": "2.0.1"
},
"devDependencies": {
"@types/chai": "4.2.11",
"@types/chai": "4.2.14",
"@types/fluent-ffmpeg": "2.1.16",
"chai": "4.2.0",
"cross-env": "7.0.2"
"cross-env": "7.0.3"
}
}

View File

@ -1,4 +1,4 @@
declare const _LANGS_: string[];
declare const _LANGS_: string[][];
declare const _VERSION_: string;
declare const _ENV_: string;
declare const _DEV_: boolean;

View File

@ -1,5 +1,5 @@
declare module '*.vue' {
import { defineComponent } from 'vue';
const component: ReturnType<typeof defineComponent>;
import type { DefineComponent } from 'vue';
const component: DefineComponent<{}, {}, any>;
export default component;
}

View File

@ -1,12 +0,0 @@
import { ComponentCustomProperties } from 'vue';
import { Store } from 'vuex';
declare module '@vue/runtime-core' {
// tslint:disable-next-line:no-empty-interface
interface State {
}
interface ComponentCustomProperties {
$store: Store<State>;
}
}

86
src/client/account.ts Normal file
View File

@ -0,0 +1,86 @@
import { reactive } from 'vue';
import { apiUrl } from '@/config';
import { waiting } from '@/os';
// TODO: 他のタブと永続化されたstateを同期
type Account = {
id: string;
token: string;
clientData: Record<string, any>;
};
const data = localStorage.getItem('account');
// TODO: 外部からはreadonlyに
export const $i = data ? reactive(JSON.parse(data) as Account) : null;
export function signout() {
localStorage.removeItem('account');
document.cookie = `igi=; path=/`;
location.href = '/';
}
export function getAccounts() {
const accountsData = localStorage.getItem('accounts');
const accounts: { id: Account['id'], token: Account['token'] }[] = accountsData ? JSON.parse(accountsData) : [];
return accounts;
}
export function addAccount(id: Account['id'], token: Account['token']) {
const accounts = getAccounts();
if (!accounts.some(x => x.id === id)) {
localStorage.setItem('accounts', JSON.stringify(accounts.concat([{ id, token }])));
}
}
function fetchAccount(token): Promise<Account> {
return new Promise((done, fail) => {
// Fetch user
fetch(`${apiUrl}/i`, {
method: 'POST',
body: JSON.stringify({
i: token
})
})
.then(res => {
// When failed to authenticate user
if (res.status !== 200 && res.status < 500) {
return signout();
}
// Parse response
res.json().then(i => {
i.token = token;
done(i);
});
})
.catch(fail);
});
}
export function updateAccount(data) {
for (const [key, value] of Object.entries(data)) {
$i[key] = value;
}
}
export function refreshAccount() {
fetchAccount($i.token).then(updateAccount);
}
export async function login(token: Account['token']) {
waiting();
if (_DEV_) console.log('logging as token ', token);
const me = await fetchAccount(token);
localStorage.setItem('account', JSON.stringify(me));
addAccount(me.id, token);
location.reload();
}
// このファイルに書きたくないけどここに書かないと何故かVeturが認識しない
declare module '@vue/runtime-core' {
interface ComponentCustomProperties {
$i: typeof $i;
}
}

View File

@ -1,34 +0,0 @@
// 常にメモリにロードしておく必要がないような設定情報を保管するストレージ
const PREFIX = 'miux:';
export const defaultDeviceSettings = {
sound_masterVolume: 0.3,
sound_note: { type: 'syuilo/down', volume: 1 },
sound_noteMy: { type: 'syuilo/up', volume: 1 },
sound_notification: { type: 'syuilo/pope2', volume: 1 },
sound_chat: { type: 'syuilo/pope1', volume: 1 },
sound_chatBg: { type: 'syuilo/waon', volume: 1 },
sound_antenna: { type: 'syuilo/triple', volume: 1 },
sound_channel: { type: 'syuilo/square-pico', volume: 1 },
sound_reversiPutBlack: { type: 'syuilo/kick', volume: 0.3 },
sound_reversiPutWhite: { type: 'syuilo/snare', volume: 0.3 },
};
export const device = {
get<T extends keyof typeof defaultDeviceSettings>(key: T): typeof defaultDeviceSettings[T] {
// TODO: indexedDBにする
// ただしその際はnullチェックではなくキー存在チェックにしないとダメ
// (indexedDBはnullを保存できるため、ユーザーが意図してnullを格納した可能性がある)
const value = localStorage.getItem(PREFIX + key);
if (value == null) {
return defaultDeviceSettings[key];
} else {
return JSON.parse(value);
}
},
set(key: keyof typeof defaultDeviceSettings, value: any): any {
localStorage.setItem(PREFIX + key, JSON.stringify(value));
},
};

View File

@ -2,24 +2,24 @@
<XWindow ref="window" :initial-width="400" :initial-height="500" :can-resize="true" @closed="$emit('closed')">
<template #header>
<Fa :icon="faExclamationCircle" style="margin-right: 0.5em;"/>
<i18n-t keypath="reportAbuseOf" tag="span">
<I18n :src="$ts.reportAbuseOf" tag="span">
<template #name>
<b><MkAcct :user="user"/></b>
</template>
</i18n-t>
</I18n>
</template>
<div class="dpvffvvy">
<div class="_section">
<div class="_content">
<MkTextarea v-model:value="comment">
<span>{{ $t('details') }}</span>
<template #desc>{{ $t('fillAbuseReportDescription') }}</template>
<span>{{ $ts.details }}</span>
<template #desc>{{ $ts.fillAbuseReportDescription }}</template>
</MkTextarea>
</div>
</div>
<div class="_section">
<div class="_content">
<MkButton @click="send" primary full :disabled="comment.length === 0">{{ $t('send') }}</MkButton>
<MkButton @click="send" primary full :disabled="comment.length === 0">{{ $ts.send }}</MkButton>
</div>
</div>
</div>
@ -69,7 +69,7 @@ export default defineComponent({
}, undefined, res => {
os.dialog({
type: 'success',
text: this.$t('abuseReported')
text: this.$ts.abuseReported
});
this.$refs.window.close();
});

View File

@ -116,16 +116,6 @@ export default defineComponent({
}
};
update();
this.$store.subscribe((mutation, state) => {
if (mutation.type !== 'device/set') return;
if (mutation?.payload?.key !== 'theme') return;
setTimeout(() => {
this.computedStyle = getComputedStyle(document.documentElement);
}, 250);
});
},
beforeUnmount() {

View File

@ -8,7 +8,7 @@
</span>
<span class="username">@{{ acct(user) }}</span>
</li>
<li @click="chooseUser()" @keydown="onKeydown" tabindex="-1" class="choose">{{ $t('selectUser') }}</li>
<li @click="chooseUser()" @keydown="onKeydown" tabindex="-1" class="choose">{{ $ts.selectUser }}</li>
</ol>
<ol class="hashtags" ref="suggests" v-if="hashtags.length > 0">
<li v-for="hashtag in hashtags" @click="complete(type, hashtag)" @keydown="onKeydown" tabindex="-1">
@ -17,8 +17,8 @@
</ol>
<ol class="emojis" ref="suggests" v-if="emojis.length > 0">
<li v-for="emoji in emojis" @click="complete(type, emoji.emoji)" @keydown="onKeydown" tabindex="-1">
<span class="emoji" v-if="emoji.isCustomEmoji"><img :src="$store.state.device.disableShowingAnimatedImages ? getStaticImageUrl(emoji.url) : emoji.url" :alt="emoji.emoji"/></span>
<span class="emoji" v-else-if="!useOsNativeEmojis"><img :src="emoji.url" :alt="emoji.emoji"/></span>
<span class="emoji" v-if="emoji.isCustomEmoji"><img :src="$store.state.disableShowingAnimatedImages ? getStaticImageUrl(emoji.url) : emoji.url" :alt="emoji.emoji"/></span>
<span class="emoji" v-else-if="!$store.state.useOsNativeEmojis"><img :src="emoji.url" :alt="emoji.emoji"/></span>
<span class="emoji" v-else>{{ emoji.emoji }}</span>
<span class="name" v-html="emoji.name.replace(q, `<b>${q}</b>`)"></span>
<span class="alias" v-if="emoji.aliasOf">({{ emoji.aliasOf }})</span>
@ -128,12 +128,6 @@ export default defineComponent({
}
},
computed: {
useOsNativeEmojis(): boolean {
return this.$store.state.device.useOsNativeEmojis;
}
},
watch: {
showing() {
if (!this.showing) {
@ -151,7 +145,7 @@ export default defineComponent({
this.setPosition();
//#region Construct Emoji DB
const customEmojis = this.$store.state.instance.meta.emojis;
const customEmojis = this.$instance.emojis;
const emojiDefinitions: EmojiDef[] = [];
for (const x of customEmojis) {

View File

@ -1,6 +1,6 @@
<template>
<div>
<span v-if="!available">{{ $t('waiting') }}<MkEllipsis/></span>
<span v-if="!available">{{ $ts.waiting }}<MkEllipsis/></span>
<div ref="captcha"></div>
</div>
</template>
@ -28,7 +28,6 @@ declare global {
interface Window extends CaptchaContainer {
}
}
import * as os from '@/os';
export default defineComponent({
props: {
@ -101,7 +100,7 @@ export default defineComponent({
if (this.captcha.render && this.$refs.captcha instanceof Element) {
this.captcha.render(this.$refs.captcha, {
sitekey: this.sitekey,
theme: this.$store.state.device.darkMode ? 'dark' : 'light',
theme: this.$store.state.darkMode ? 'dark' : 'light',
callback: this.callback,
'expired-callback': this.callback,
'error-callback': this.callback,

View File

@ -6,14 +6,14 @@
>
<template v-if="!wait">
<template v-if="isFollowing">
<span v-if="full">{{ $t('unfollow') }}</span><Fa :icon="faMinus"/>
<span v-if="full">{{ $ts.unfollow }}</span><Fa :icon="faMinus"/>
</template>
<template v-else>
<span v-if="full">{{ $t('follow') }}</span><Fa :icon="faPlus"/>
<span v-if="full">{{ $ts.follow }}</span><Fa :icon="faPlus"/>
</template>
</template>
<template v-else>
<span v-if="full">{{ $t('processing') }}</span><Fa :icon="faSpinner" pulse fixed-width/>
<span v-if="full">{{ $ts.processing }}</span><Fa :icon="faSpinner" pulse fixed-width/>
</template>
</button>
</template>

View File

@ -6,19 +6,19 @@
<div class="status">
<div>
<Fa :icon="faUsers" fixed-width/>
<i18n-t keypath="_channel.usersCount" tag="span" style="margin-left: 4px;">
<I18n :src="$ts._channel.usersCount" tag="span" style="margin-left: 4px;">
<template #n>
<b>{{ channel.usersCount }}</b>
</template>
</i18n-t>
</I18n>
</div>
<div>
<Fa :icon="faPencilAlt" fixed-width/>
<i18n-t keypath="_channel.notesCount" tag="span" style="margin-left: 4px;">
<I18n :src="$ts._channel.notesCount" tag="span" style="margin-left: 4px;">
<template #n>
<b>{{ channel.notesCount }}</b>
</template>
</i18n-t>
</I18n>
</div>
</div>
</div>
@ -27,7 +27,7 @@
</article>
<footer>
<span v-if="channel.lastNotedAt">
{{ $t('updatedAt') }}: <MkTime :time="channel.lastNotedAt"/>
{{ $ts.updatedAt }}: <MkTime :time="channel.lastNotedAt"/>
</span>
</footer>
</MkA>

View File

@ -1,6 +1,6 @@
<template>
<button class="nrvgflfu _button" @click="toggle">
<b>{{ value ? $t('_cw.hide') : $t('_cw.show') }}</b>
<b>{{ value ? $ts._cw.hide : $ts._cw.show }}</b>
<span v-if="!value">{{ label }}</span>
</button>
</template>
@ -27,7 +27,7 @@ export default defineComponent({
return concat([
this.note.text ? [this.$t('_cw.chars', { count: length(this.note.text) })] : [],
this.note.files && this.note.files.length !== 0 ? [this.$t('_cw.files', { count: this.note.files.length }) ] : [],
this.note.poll != null ? [this.$t('poll')] : []
this.note.poll != null ? [this.$ts.poll] : []
] as string[][]).join(' / ');
}
},

View File

@ -1,20 +1,7 @@
<template>
<transition-group class="sqadhkmv _list_" name="list" tag="div" :data-direction="direction" :data-reversed="reversed ? 'true' : 'false'">
<template v-for="(item, i) in items">
<slot :item="item"></slot>
<div class="separator" v-if="showDate(i, item)" :key="item.id + '_date'">
<p class="date">
<span><Fa class="icon" :icon="faAngleUp"/>{{ getDateText(item.createdAt) }}</span>
<span>{{ getDateText(items[i + 1].createdAt) }}<Fa class="icon" :icon="faAngleDown"/></span>
</p>
</div>
</template>
</transition-group>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { defineComponent, h, TransitionGroup } from 'vue';
import { faAngleUp, faAngleDown } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
export default defineComponent({
props: {
@ -34,36 +21,72 @@ export default defineComponent({
}
},
data() {
return {
faAngleUp, faAngleDown
};
methods: {
focus() {
this.$slots.default[0].elm.focus();
}
},
methods: {
getDateText(time: string) {
render() {
const getDateText = (time: string) => {
const date = new Date(time).getDate();
const month = new Date(time).getMonth() + 1;
return this.$t('monthAndDay', {
month: month.toString(),
day: date.toString()
});
},
}
showDate(i, item) {
return (
return h(this.$store.state.animation ? TransitionGroup : 'div', this.$store.state.animation ? {
class: 'sqadhkmv _list_',
name: 'list',
tag: 'div',
'data-direction': this.direction,
'data-reversed': this.reversed ? 'true' : 'false',
} : {
class: 'sqadhkmv _list_',
}, this.items.map((item, i) => {
const el = this.$slots.default({
item: item
})[0];
el.key = item.id;
if (
i != this.items.length - 1 &&
new Date(item.createdAt).getDate() != new Date(this.items[i + 1].createdAt).getDate() &&
!item._prId_ &&
!this.items[i + 1]._prId_ &&
!item._featuredId_ &&
!this.items[i + 1]._featuredId_);
},
!this.items[i + 1]._featuredId_
) {
const separator = h('div', {
class: 'separator',
key: item.id + ':separator',
}, h('p', {
class: 'date'
}, [
h('span', [
h(FontAwesomeIcon, {
class: 'icon',
icon: faAngleUp,
}),
getDateText(item.createdAt)
]),
h('span', [
getDateText(this.items[i + 1].createdAt),
h(FontAwesomeIcon, {
class: 'icon',
icon: faAngleDown,
})
])
]));
focus() {
this.$slots.default[0].elm.focus();
}
return [el, separator];
} else {
return el;
}
}));
},
});
</script>
@ -97,7 +120,7 @@ export default defineComponent({
}
</style>
<style lang="scss" scoped>
<style lang="scss">
.sqadhkmv {
> .separator {
text-align: center;

View File

@ -26,8 +26,8 @@
</template>
</MkSelect>
<div class="buttons" v-if="(showOkButton || showCancelButton) && !actions">
<MkButton inline @click="ok" v-if="showOkButton" primary :autofocus="!input && !select">{{ (showCancelButton || input || select) ? $t('ok') : $t('gotIt') }}</MkButton>
<MkButton inline @click="cancel" v-if="showCancelButton || input || select">{{ $t('cancel') }}</MkButton>
<MkButton inline @click="ok" v-if="showOkButton" primary :autofocus="!input && !select">{{ (showCancelButton || input || select) ? $ts.ok : $ts.gotIt }}</MkButton>
<MkButton inline @click="cancel" v-if="showCancelButton || input || select">{{ $ts.cancel }}</MkButton>
</div>
<div class="buttons" v-if="actions">
<MkButton v-for="action in actions" inline @click="() => { action.callback(); close(); }" :primary="action.primary" :key="action.text">{{ action.text }}</MkButton>

View File

@ -27,6 +27,7 @@ import {
faFilm
} from '@fortawesome/free-solid-svg-icons';
import ImgWithBlurhash from './img-with-blurhash.vue';
import { ColdDeviceStorage } from '@/store';
export default defineComponent({
components: {
@ -89,12 +90,12 @@ export default defineComponent({
},
mounted() {
const audioTag = this.$refs.volumectrl as HTMLAudioElement;
if (audioTag) audioTag.volume = this.$store.state.device.mediaVolume;
if (audioTag) audioTag.volume = ColdDeviceStorage.get('mediaVolume');
},
methods: {
volumechange() {
const audioTag = this.$refs.volumectrl as HTMLAudioElement;
this.$store.commit('device/set', { key: 'mediaVolume', value: audioTag.volume });
ColdDeviceStorage.set('mediaVolume', audioTag.volume);
}
}
});

View File

@ -10,7 +10,7 @@
@closed="$emit('closed')"
>
<template #header>
{{ multiple ? ((type === 'file') ? $t('selectFiles') : $t('selectFolders')) : ((type === 'file') ? $t('selectFile') : $t('selectFolder')) }}
{{ multiple ? ((type === 'file') ? $ts.selectFiles : $ts.selectFolders) : ((type === 'file') ? $ts.selectFile : $ts.selectFolder) }}
<span v-if="selected.length > 0" style="margin-left: 8px; opacity: 0.5;">({{ number(selected.length) }})</span>
</template>
<XDrive :multiple="multiple" @changeSelection="onChangeSelection" @selected="ok()" :select="type"/>

View File

@ -6,7 +6,7 @@
@closed="$emit('closed')"
>
<template #header>
{{ $t('drive') }}
{{ $ts.drive }}
</template>
<XDrive :initial-folder="initialFolder"/>
</XWindow>

View File

@ -8,17 +8,17 @@
@dragend="onDragend"
:title="title"
>
<div class="label" v-if="$store.state.i.avatarId == file.id">
<div class="label" v-if="$i.avatarId == file.id">
<img src="/assets/label.svg"/>
<p>{{ $t('avatar') }}</p>
<p>{{ $ts.avatar }}</p>
</div>
<div class="label" v-if="$store.state.i.bannerId == file.id">
<div class="label" v-if="$i.bannerId == file.id">
<img src="/assets/label.svg"/>
<p>{{ $t('banner') }}</p>
<p>{{ $ts.banner }}</p>
</div>
<div class="label red" v-if="file.isSensitive">
<img src="/assets/label-red.svg"/>
<p>{{ $t('nsfw') }}</p>
<p>{{ $ts.nsfw }}</p>
</div>
<MkDriveFileThumbnail class="thumbnail" :file="file" fit="contain"/>
@ -82,26 +82,26 @@ export default defineComponent({
methods: {
getMenu() {
return [{
text: this.$t('rename'),
text: this.$ts.rename,
icon: faICursor,
action: this.rename
}, {
text: this.file.isSensitive ? this.$t('unmarkAsSensitive') : this.$t('markAsSensitive'),
text: this.file.isSensitive ? this.$ts.unmarkAsSensitive : this.$ts.markAsSensitive,
icon: this.file.isSensitive ? faEye : faEyeSlash,
action: this.toggleSensitive
}, null, {
text: this.$t('copyUrl'),
text: this.$ts.copyUrl,
icon: faLink,
action: this.copyUrl
}, {
type: 'a',
href: this.file.url,
target: '_blank',
text: this.$t('download'),
text: this.$ts.download,
icon: faDownload,
download: this.file.name
}, null, {
text: this.$t('delete'),
text: this.$ts.delete,
icon: faTrashAlt,
danger: true,
action: this.deleteFile
@ -137,9 +137,9 @@ export default defineComponent({
rename() {
os.dialog({
title: this.$t('renameFile'),
title: this.$ts.renameFile,
input: {
placeholder: this.$t('inputNewFileName'),
placeholder: this.$ts.inputNewFileName,
default: this.file.name,
allowEmpty: false
}

View File

@ -19,8 +19,8 @@
<template v-if="!hover"><Fa :icon="faFolder" fixed-width/></template>
{{ folder.name }}
</p>
<p class="upload" v-if="$store.state.settings.uploadFolder == folder.id">
{{ $t('uploadFolder') }}
<p class="upload" v-if="$store.state.uploadFolder == folder.id">
{{ $ts.uploadFolder }}
</p>
<button v-if="selectMode" class="checkbox _button" :class="{ checked: isSelected }" @click.prevent.stop="checkboxClicked"></button>
</div>
@ -155,14 +155,14 @@ export default defineComponent({
switch (err) {
case 'detected-circular-definition':
os.dialog({
title: this.$t('unableToProcess'),
text: this.$t('circularReferenceFolder')
title: this.$ts.unableToProcess,
text: this.$ts.circularReferenceFolder
});
break;
default:
os.dialog({
type: 'error',
text: this.$t('somethingHappened')
text: this.$ts.somethingHappened
});
}
});
@ -195,9 +195,9 @@ export default defineComponent({
rename() {
os.dialog({
title: this.$t('renameFolder'),
title: this.$ts.renameFolder,
input: {
placeholder: this.$t('inputNewFolderName'),
placeholder: this.$ts.inputNewFolderName,
default: this.folder.name
}
}).then(({ canceled, result: name }) => {
@ -213,40 +213,34 @@ export default defineComponent({
os.api('drive/folders/delete', {
folderId: this.folder.id
}).then(() => {
if (this.$store.state.settings.uploadFolder === this.folder.id) {
this.$store.dispatch('settings/set', {
key: 'uploadFolder',
value: null
});
if (this.$store.state.uploadFolder === this.folder.id) {
this.$store.set('uploadFolder', null);
}
}).catch(err => {
switch(err.id) {
case 'b0fc8a17-963c-405d-bfbc-859a487295e1':
os.dialog({
type: 'error',
title: this.$t('unableToDelete'),
text: this.$t('hasChildFilesOrFolders')
title: this.$ts.unableToDelete,
text: this.$ts.hasChildFilesOrFolders
});
break;
default:
os.dialog({
type: 'error',
text: this.$t('unableToDelete')
text: this.$ts.unableToDelete
});
}
});
},
setAsUploadFolder() {
this.$store.dispatch('settings/set', {
key: 'uploadFolder',
value: this.folder.id
});
this.$store.set('uploadFolder', this.folder.id);
},
onContextmenu(e) {
os.contextMenu([{
text: this.$t('openInWindow'),
text: this.$ts.openInWindow,
icon: faWindowRestore,
action: () => {
os.popup(import('./drive-window.vue'), {
@ -255,11 +249,11 @@ export default defineComponent({
}, 'closed');
}
}, null, {
text: this.$t('rename'),
text: this.$ts.rename,
icon: faICursor,
action: this.rename
}, null, {
text: this.$t('delete'),
text: this.$ts.delete,
icon: faTrashAlt,
danger: true,
action: this.deleteFolder

View File

@ -8,7 +8,7 @@
@drop.stop="onDrop"
>
<i v-if="folder == null"><Fa :icon="faCloud"/></i>
<span>{{ folder == null ? $t('drive') : folder.name }}</span>
<span>{{ folder == null ? $ts.drive : folder.name }}</span>
</div>
</template>

View File

@ -24,18 +24,18 @@
<XFolder v-for="f in folders" :key="f.id" class="folder" :folder="f" :select-mode="select === 'folder'" :is-selected="selectedFolders.some(x => x.id === f.id)" @chosen="chooseFolder"/>
<!-- SEE: https://stackoverflow.com/questions/18744164/flex-box-align-last-row-to-grid -->
<div class="padding" v-for="(n, i) in 16" :key="i"></div>
<MkButton ref="moreFolders" v-if="moreFolders">{{ $t('loadMore') }}</MkButton>
<MkButton ref="moreFolders" v-if="moreFolders">{{ $ts.loadMore }}</MkButton>
</div>
<div class="files" ref="filesContainer" v-show="files.length > 0">
<XFile v-for="file in files" :key="file.id" class="file" :file="file" :select-mode="select === 'file'" :is-selected="selectedFiles.some(x => x.id === file.id)" @chosen="chooseFile"/>
<!-- SEE: https://stackoverflow.com/questions/18744164/flex-box-align-last-row-to-grid -->
<div class="padding" v-for="(n, i) in 16" :key="i"></div>
<MkButton ref="loadMoreFiles" @click="fetchMoreFiles" v-show="moreFiles">{{ $t('loadMore') }}</MkButton>
<MkButton ref="loadMoreFiles" @click="fetchMoreFiles" v-show="moreFiles">{{ $ts.loadMore }}</MkButton>
</div>
<div class="empty" v-if="files.length == 0 && folders.length == 0 && !fetching">
<p v-if="draghover">{{ $t('empty-draghover') }}</p>
<p v-if="!draghover && folder == null"><strong>{{ $t('emptyDrive') }}</strong><br/>{{ $t('empty-drive-description') }}</p>
<p v-if="!draghover && folder != null">{{ $t('emptyFolder') }}</p>
<p v-if="!draghover && folder == null"><strong>{{ $ts.emptyDrive }}</strong><br/>{{ $t('empty-drive-description') }}</p>
<p v-if="!draghover && folder != null">{{ $ts.emptyFolder }}</p>
</div>
</div>
<MkLoading v-if="fetching"/>
@ -136,7 +136,7 @@ export default defineComponent({
},
mounted() {
if (this.$store.state.device.enableInfiniteScroll && this.$refs.loadMoreFiles) {
if (this.$store.state.enableInfiniteScroll && this.$refs.loadMoreFiles) {
this.$nextTick(() => {
this.ilFilesObserver.observe((this.$refs.loadMoreFiles as Vue).$el)
});
@ -159,7 +159,7 @@ export default defineComponent({
},
activated() {
if (this.$store.state.device.enableInfiniteScroll) {
if (this.$store.state.enableInfiniteScroll) {
this.$nextTick(() => {
this.ilFilesObserver.observe((this.$refs.loadMoreFiles as Vue).$el)
});
@ -277,14 +277,14 @@ export default defineComponent({
switch (err) {
case 'detected-circular-definition':
os.dialog({
title: this.$t('unableToProcess'),
text: this.$t('circularReferenceFolder')
title: this.$ts.unableToProcess,
text: this.$ts.circularReferenceFolder
});
break;
default:
os.dialog({
type: 'error',
text: this.$t('somethingHappened')
text: this.$ts.somethingHappened
});
}
});
@ -298,9 +298,9 @@ export default defineComponent({
urlUpload() {
os.dialog({
title: this.$t('uploadFromUrl'),
title: this.$ts.uploadFromUrl,
input: {
placeholder: this.$t('uploadFromUrlDescription')
placeholder: this.$ts.uploadFromUrlDescription
}
}).then(({ canceled, result: url }) => {
if (canceled) return;
@ -310,17 +310,17 @@ export default defineComponent({
});
os.dialog({
title: this.$t('uploadFromUrlRequested'),
text: this.$t('uploadFromUrlMayTakeTime')
title: this.$ts.uploadFromUrlRequested,
text: this.$ts.uploadFromUrlMayTakeTime
});
});
},
createFolder() {
os.dialog({
title: this.$t('createFolder'),
title: this.$ts.createFolder,
input: {
placeholder: this.$t('folderName')
placeholder: this.$ts.folderName
}
}).then(({ canceled, result: name }) => {
if (canceled) return;
@ -335,9 +335,9 @@ export default defineComponent({
renameFolder(folder) {
os.dialog({
title: this.$t('renameFolder'),
title: this.$ts.renameFolder,
input: {
placeholder: this.$t('inputNewFolderName'),
placeholder: this.$ts.inputNewFolderName,
default: folder.name
}
}).then(({ canceled, result: name }) => {
@ -363,14 +363,14 @@ export default defineComponent({
case 'b0fc8a17-963c-405d-bfbc-859a487295e1':
os.dialog({
type: 'error',
title: this.$t('unableToDelete'),
text: this.$t('hasChildFilesOrFolders')
title: this.$ts.unableToDelete,
text: this.$ts.hasChildFilesOrFolders
});
break;
default:
os.dialog({
type: 'error',
text: this.$t('unableToDelete')
text: this.$ts.unableToDelete
});
}
});
@ -602,29 +602,29 @@ export default defineComponent({
getMenu() {
return [{
text: this.$t('addFile'),
text: this.$ts.addFile,
type: 'label'
}, {
text: this.$t('upload'),
text: this.$ts.upload,
icon: faUpload,
action: () => { this.selectLocalFile(); }
}, {
text: this.$t('fromUrl'),
text: this.$ts.fromUrl,
icon: faLink,
action: () => { this.urlUpload(); }
}, null, {
text: this.folder ? this.folder.name : this.$t('drive'),
text: this.folder ? this.folder.name : this.$ts.drive,
type: 'label'
}, this.folder ? {
text: this.$t('renameFolder'),
text: this.$ts.renameFolder,
icon: faICursor,
action: () => { this.renameFolder(this.folder); }
} : undefined, this.folder ? {
text: this.$t('deleteFolder'),
text: this.$ts.deleteFolder,
icon: faTrashAlt,
action: () => { this.deleteFolder(this.folder); }
} : undefined, {
text: this.$t('createFolder'),
text: this.$ts.createFolder,
icon: faFolderPlus,
action: () => { this.createFolder(); }
}];

View File

@ -1,7 +1,7 @@
<template>
<MkModal ref="modal" :src="src" @click="$refs.modal.close()" @closed="$emit('closed')">
<div class="omfetrab _popup" :class="['w' + width, 'h' + height, { big }]">
<input ref="search" class="search" :class="{ filled: q != null && q != '' }" v-model.trim="q" :placeholder="$t('search')" @paste.stop="paste" @keyup.enter="done()">
<input ref="search" class="search" :class="{ filled: q != null && q != '' }" v-model.trim="q" :placeholder="$ts.search" @paste.stop="paste" @keyup.enter="done()">
<div class="emojis">
<section class="result">
<div v-if="searchResultCustom.length > 0">
@ -13,7 +13,7 @@
tabindex="0"
>
<MkEmoji v-if="emoji.char != null" :emoji="emoji.char"/>
<img v-else :src="$store.state.device.disableShowingAnimatedImages ? getStaticImageUrl(emoji.url) : emoji.url"/>
<img v-else :src="$store.state.disableShowingAnimatedImages ? getStaticImageUrl(emoji.url) : emoji.url"/>
</button>
</div>
<div v-if="searchResultUnicode.length > 0">
@ -43,9 +43,9 @@
</section>
<section>
<header class="_acrylic"><Fa :icon="faClock" fixed-width/> {{ $t('recentUsed') }}</header>
<header class="_acrylic"><Fa :icon="faClock" fixed-width/> {{ $ts.recentUsed }}</header>
<div>
<button v-for="emoji in $store.state.device.recentlyUsedEmojis"
<button v-for="emoji in $store.state.recentlyUsedEmojis"
class="_button"
@click="chosen(emoji, $event)"
:key="emoji"
@ -59,7 +59,7 @@
</div>
<section v-for="category in customEmojiCategories" :key="'custom:' + category" class="custom">
<header class="_acrylic" v-appear="() => visibleCategories[category] = true">{{ category || $t('other') }}</header>
<header class="_acrylic" v-appear="() => visibleCategories[category] = true">{{ category || $ts.other }}</header>
<div v-if="visibleCategories[category]">
<button v-for="emoji in customEmojis.filter(e => e.category === category)"
class="_button"
@ -67,7 +67,7 @@
@click="chosen(emoji, $event)"
:key="emoji.name"
>
<img :src="$store.state.device.disableShowingAnimatedImages ? getStaticImageUrl(emoji.url) : emoji.url"/>
<img :src="$store.state.disableShowingAnimatedImages ? getStaticImageUrl(emoji.url) : emoji.url"/>
</button>
</div>
</section>
@ -100,6 +100,7 @@ import MkModal from '@/components/ui/modal.vue';
import Particle from '@/components/particle.vue';
import * as os from '@/os';
import { isDeviceTouch } from '../scripts/is-device-touch';
import { emojiCategories } from '@/instance';
export default defineComponent({
components: {
@ -125,12 +126,12 @@ export default defineComponent({
return {
emojilist: markRaw(emojilist),
getStaticImageUrl,
pinned: this.$store.state.settings.reactions,
width: this.asReactionPicker ? this.$store.state.device.reactionPickerWidth : 3,
height: this.asReactionPicker ? this.$store.state.device.reactionPickerHeight : 2,
pinned: this.$store.state.reactions,
width: this.asReactionPicker ? this.$store.state.reactionPickerWidth : 3,
height: this.asReactionPicker ? this.$store.state.reactionPickerHeight : 2,
big: this.asReactionPicker ? isDeviceTouch : false,
customEmojiCategories: this.$store.getters['instance/emojiCategories'],
customEmojis: this.$store.state.instance.meta.emojis,
customEmojiCategories: emojiCategories,
customEmojis: this.$instance.emojis,
visibleCategories: {},
q: null,
searchResultCustom: [],
@ -346,10 +347,10 @@ export default defineComponent({
// 最近使った絵文字更新
if (!this.pinned.includes(key)) {
let recents = this.$store.state.device.recentlyUsedEmojis;
let recents = this.$store.state.recentlyUsedEmojis;
recents = recents.filter((e: any) => e !== key);
recents.unshift(key);
this.$store.commit('device/set', { key: 'recentlyUsedEmojis', value: recents.splice(0, 16) });
this.$store.set('recentlyUsedEmojis', recents.splice(0, 16));
}
},

View File

@ -6,23 +6,23 @@
>
<template v-if="!wait">
<template v-if="hasPendingFollowRequestFromYou && user.isLocked">
<span v-if="full">{{ $t('followRequestPending') }}</span><Fa :icon="faHourglassHalf"/>
<span v-if="full">{{ $ts.followRequestPending }}</span><Fa :icon="faHourglassHalf"/>
</template>
<template v-else-if="hasPendingFollowRequestFromYou && !user.isLocked"> <!-- つまりリモートフォローの場合 -->
<span v-if="full">{{ $t('processing') }}</span><Fa :icon="faSpinner" pulse/>
<span v-if="full">{{ $ts.processing }}</span><Fa :icon="faSpinner" pulse/>
</template>
<template v-else-if="isFollowing">
<span v-if="full">{{ $t('unfollow') }}</span><Fa :icon="faMinus"/>
<span v-if="full">{{ $ts.unfollow }}</span><Fa :icon="faMinus"/>
</template>
<template v-else-if="!isFollowing && user.isLocked">
<span v-if="full">{{ $t('followRequest') }}</span><Fa :icon="faPlus"/>
<span v-if="full">{{ $ts.followRequest }}</span><Fa :icon="faPlus"/>
</template>
<template v-else-if="!isFollowing && !user.isLocked">
<span v-if="full">{{ $t('follow') }}</span><Fa :icon="faPlus"/>
<span v-if="full">{{ $ts.follow }}</span><Fa :icon="faPlus"/>
</template>
</template>
<template v-else>
<span v-if="full">{{ $t('processing') }}</span><Fa :icon="faSpinner" pulse fixed-width/>
<span v-if="full">{{ $ts.processing }}</span><Fa :icon="faSpinner" pulse fixed-width/>
</template>
</button>
</template>

View File

@ -15,15 +15,15 @@
<FormBase class="xkpnjxcv">
<template v-for="item in Object.keys(form).filter(item => !form[item].hidden)">
<FormInput v-if="form[item].type === 'number'" v-model:value="values[item]" type="number" :step="form[item].step || 1">
<span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $t('optional') }})</span>
<span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $ts.optional }})</span>
<template v-if="form[item].description" #desc>{{ form[item].description }}</template>
</FormInput>
<FormInput v-else-if="form[item].type === 'string' && !form[item].multiline" v-model:value="values[item]" type="text">
<span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $t('optional') }})</span>
<span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $ts.optional }})</span>
<template v-if="form[item].description" #desc>{{ form[item].description }}</template>
</FormInput>
<FormTextarea v-else-if="form[item].type === 'string' && form[item].multiline" v-model:value="values[item]">
<span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $t('optional') }})</span>
<span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $ts.optional }})</span>
<template v-if="form[item].description" #desc>{{ form[item].description }}</template>
</FormTextarea>
<FormSwitch v-else-if="form[item].type === 'boolean'" v-model:value="values[item]">
@ -31,11 +31,11 @@
<template v-if="form[item].description" #desc>{{ form[item].description }}</template>
</FormSwitch>
<FormSelect v-else-if="form[item].type === 'enum'" v-model:value="values[item]">
<template #label><span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $t('optional') }})</span></template>
<template #label><span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $ts.optional }})</span></template>
<option v-for="item in form[item].enum" :value="item.value" :key="item.value">{{ item.label }}</option>
</FormSelect>
<FormRange v-else-if="form[item].type === 'range'" v-model:value="values[item]" :min="form[item].mim" :max="form[item].max" :step="form[item].step">
<template #label><span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $t('optional') }})</span></template>
<template #label><span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $ts.optional }})</span></template>
<template v-if="form[item].description" #desc>{{ form[item].description }}</template>
</FormRange>
<FormButton v-else-if="form[item].type === 'button'" @click="form[item].action($event, values)">

View File

@ -4,7 +4,7 @@
&._formClickable {
&:hover {
background: var(--panelHighlight);
//background: var(--panelHighlight);
}
}
}
@ -12,6 +12,7 @@
._formLabel {
font-size: 80%;
padding: 0 16px 8px 16px;
opacity: 0.8;
&:empty {
display: none;
@ -21,6 +22,7 @@
._formCaption {
font-size: 80%;
padding: 8px 16px 0 16px;
opacity: 0.8;
&:empty {
display: none;

View File

@ -44,7 +44,7 @@
</datalist>
<div class="suffix" ref="suffixEl"><slot name="suffix"></slot></div>
</div>
<button class="save _textButton" v-if="save && changed" @click="() => { changed = false; save(); }">{{ $t('save') }}</button>
<button class="save _textButton" v-if="save && changed" @click="() => { changed = false; save(); }">{{ $ts.save }}</button>
<div class="_formCaption"><slot name="desc"></slot></div>
</div>
</template>

View File

@ -6,7 +6,7 @@
<slot name="empty"></slot>
</div>
<FormButton v-show="more" class="button" @click="fetchMore" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }" primary>
<template v-if="!moreFetching">{{ $t('loadMore') }}</template>
<template v-if="!moreFetching">{{ $ts.loadMore }}</template>
<template v-if="moreFetching"><MkLoading inline/></template>
</FormButton>
</FormGroup>

View File

@ -14,7 +14,7 @@
@blur="focused = false"
></textarea>
</div>
<button class="save _textButton" v-if="save && changed" @click="() => { changed = false; save(); }">{{ $t('save') }}</button>
<button class="save _textButton" v-if="save && changed" @click="() => { changed = false; save(); }">{{ $ts.save }}</button>
<div class="_formCaption"><slot name="desc"></slot></div>
</div>
</template>

View File

@ -10,8 +10,9 @@ import { faExpandAlt, faColumns, faExternalLinkAlt, faLink, faWindowMaximize } f
import * as os from '@/os';
import copyToClipboard from '@/scripts/copy-to-clipboard';
import { router } from '@/router';
import { ui, url } from '@/config';
import { url } from '@/config';
import { popout } from '@/scripts/popout';
import { ColdDeviceStorage } from '@/store';
export default defineComponent({
inject: {
@ -57,31 +58,31 @@ export default defineComponent({
text: this.to,
}, {
icon: faWindowMaximize,
text: this.$t('openInWindow'),
text: this.$ts.openInWindow,
action: () => {
os.pageWindow(this.to);
}
}, this.sideViewHook ? {
icon: faColumns,
text: this.$t('openInSideView'),
text: this.$ts.openInSideView,
action: () => {
this.sideViewHook(this.to);
}
} : undefined, {
icon: faExpandAlt,
text: this.$t('showInPage'),
text: this.$ts.showInPage,
action: () => {
this.$router.push(this.to);
}
}, null, {
icon: faExternalLinkAlt,
text: this.$t('openInNewTab'),
text: this.$ts.openInNewTab,
action: () => {
window.open(this.to, '_blank');
}
}, {
icon: faLink,
text: this.$t('copyLink'),
text: this.$ts.copyLink,
action: () => {
copyToClipboard(`${url}${this.to}`);
}
@ -98,8 +99,8 @@ export default defineComponent({
nav() {
if (this.to.startsWith('/my/messaging')) {
if (this.$store.state.device.chatOpenBehavior === 'window') return this.window();
if (this.$store.state.device.chatOpenBehavior === 'popout') return this.popout();
if (ColdDeviceStorage.get('chatOpenBehavior') === 'window') return this.window();
if (ColdDeviceStorage.get('chatOpenBehavior') === 'popout') return this.popout();
}
if (this.behavior) {
@ -111,15 +112,9 @@ export default defineComponent({
if (this.navHook) {
this.navHook(this.to);
} else {
if (this.$store.state.device.defaultSideView && this.sideViewHook && this.to !== '/') {
if (this.$store.state.defaultSideView && this.sideViewHook && this.to !== '/') {
return this.sideViewHook(this.to);
}
if (this.$store.state.device.deckNavWindow && (ui === 'deck') && this.to !== '/') {
return this.window();
}
if (ui === 'desktop') {
return this.window();
}
if (this.$router.currentRoute.value.path === this.to) {
window.scroll({ top: 0, behavior: 'smooth' });

View File

@ -1,7 +1,7 @@
<template>
<span class="mk-acct" v-once>
<span class="name">@{{ user.username }}</span>
<span class="host" v-if="user.host || detail || $store.state.settings.showFullAcct">@{{ user.host || host }}</span>
<span class="host" v-if="user.host || detail || $store.state.showFullAcct">@{{ user.host || host }}</span>
</span>
</template>

View File

@ -1,9 +1,9 @@
<template>
<span class="eiwwqkts" :class="{ cat }" :title="acct(user)" v-if="disableLink" v-user-preview="disablePreview ? undefined : user.id" @click="onClick">
<img class="inner" :src="url"/>
<img class="inner" :src="url" decoding="async"/>
</span>
<MkA class="eiwwqkts" :class="{ cat }" :to="userPage(user)" :title="acct(user)" :target="target" v-else v-user-preview="disablePreview ? undefined : user.id">
<img class="inner" :src="url"/>
<img class="inner" :src="url" decoding="async"/>
</MkA>
</template>
@ -11,7 +11,7 @@
import { defineComponent } from 'vue';
import { getStaticImageUrl } from '@/scripts/get-static-image-url';
import { extractAvgColorFromBlurhash } from '@/scripts/extract-avg-color-from-blurhash';
import { acct, userPage } from '../filters/user';
import { acct, userPage } from '@/filters/user';
export default defineComponent({
props: {
@ -38,7 +38,7 @@ export default defineComponent({
return this.user.isCat;
},
url(): string {
return this.$store.state.device.disableShowingAnimatedImages
return this.$store.state.disableShowingAnimatedImages
? getStaticImageUrl(this.user.avatarUrl)
: this.user.avatarUrl;
},

View File

@ -1,6 +1,6 @@
<template>
<img v-if="customEmoji" class="mk-emoji custom" :class="{ normal, noStyle }" :src="url" :alt="alt" :title="alt"/>
<img v-else-if="char && !useOsNativeEmojis" class="mk-emoji" :src="url" :alt="alt" :title="alt"/>
<img v-if="customEmoji" class="mk-emoji custom" :class="{ normal, noStyle }" :src="url" :alt="alt" :title="alt" decoding="async"/>
<img v-else-if="char && !useOsNativeEmojis" class="mk-emoji" :src="url" :alt="alt" :title="alt" decoding="async"/>
<span v-else-if="char && useOsNativeEmojis">{{ char }}</span>
<span v-else>{{ emoji }}</span>
</template>
@ -8,7 +8,7 @@
<script lang="ts">
import { defineComponent } from 'vue';
import { getStaticImageUrl } from '@/scripts/get-static-image-url';
import { twemojiSvgBase } from '../../misc/twemoji-base';
import { twemojiSvgBase } from '@/../misc/twemoji-base';
export default defineComponent({
props: {
@ -54,13 +54,13 @@ export default defineComponent({
},
useOsNativeEmojis(): boolean {
return this.$store.state.device.useOsNativeEmojis && !this.isReaction;
return this.$store.state.useOsNativeEmojis && !this.isReaction;
},
ce() {
let ce = [];
if (this.customEmojis) ce = ce.concat(this.customEmojis);
if (this.$store.state.instance.meta && this.$store.state.instance.meta.emojis) ce = ce.concat(this.$store.state.instance.meta.emojis);
if (this.$instance && this.$instance.emojis) ce = ce.concat(this.$instance.emojis);
return ce;
}
},
@ -72,7 +72,7 @@ export default defineComponent({
const customEmoji = this.ce.find(x => x.name === this.emoji.substr(1, this.emoji.length - 2));
if (customEmoji) {
this.customEmoji = customEmoji;
this.url = this.$store.state.device.disableShowingAnimatedImages
this.url = this.$store.state.disableShowingAnimatedImages
? getStaticImageUrl(customEmoji.url)
: customEmoji.url;
}

View File

@ -1,9 +1,9 @@
<template>
<transition :name="$store.state.device.animation ? 'zoom' : ''" appear>
<transition :name="$store.state.animation ? 'zoom' : ''" appear>
<div class="mjndxjcg">
<img src="https://xn--931a.moe/assets/error.jpg" class="_ghost"/>
<p><Fa :icon="faExclamationTriangle"/> {{ $t('somethingHappened') }}</p>
<MkButton @click="() => $emit('retry')" class="button">{{ $t('retry') }}</MkButton>
<p><Fa :icon="faExclamationTriangle"/> {{ $ts.somethingHappened }}</p>
<MkButton @click="() => $emit('retry')" class="button">{{ $ts.retry }}</MkButton>
</div>
</transition>
</template>
@ -11,7 +11,7 @@
<script lang="ts">
import { defineComponent } from 'vue';
import { faExclamationTriangle } from '@fortawesome/free-solid-svg-icons';
import MkButton from './ui/button.vue';
import MkButton from '@/components/ui/button.vue';
export default defineComponent({
components: {

View File

@ -0,0 +1,37 @@
import { h, defineComponent } from 'vue';
export default defineComponent({
props: {
src: {
type: String,
required: true,
},
tag: {
type: String,
required: false,
default: 'span',
},
},
render() {
let str = this.src;
const parsed = [] as (string | { arg: string; })[];
while (true) {
const nextBracketOpen = str.indexOf('{');
const nextBracketClose = str.indexOf('}');
if (nextBracketOpen === -1) {
parsed.push(str);
break;
} else {
if (nextBracketOpen > 0) parsed.push(str.substr(0, nextBracketOpen));
parsed.push({
arg: str.substring(nextBracketOpen + 1, nextBracketClose)
});
}
str = str.substr(nextBracketClose + 1);
}
return h(this.tag, parsed.map(x => typeof x === 'string' ? x : this.$slots[x.arg]()));
}
});

View File

@ -4,7 +4,7 @@
<script lang="ts">
import { defineComponent } from 'vue';
import MfmCore from './mfm';
import MfmCore from '@/components/mfm';
export default defineComponent({
components: {

View File

@ -44,9 +44,9 @@ export default defineComponent({
ago >= 3600 ? this.$t('_ago.hoursAgo', { n: (~~(ago / 3600)).toString() }) :
ago >= 60 ? this.$t('_ago.minutesAgo', { n: (~~(ago / 60)).toString() }) :
ago >= 10 ? this.$t('_ago.secondsAgo', { n: (~~(ago % 60)).toString() }) :
ago >= -1 ? this.$t('_ago.justNow') :
ago < -1 ? this.$t('_ago.future') :
this.$t('_ago.unknown'));
ago >= -1 ? this.$ts._ago.justNow :
ago < -1 ? this.$ts._ago.future :
this.$ts._ago.unknown);
}
},
created() {

View File

@ -1,7 +1,7 @@
<template>
<div class="mk-google">
<input type="search" v-model="query" :placeholder="q">
<button @click="search"><Fa :icon="faSearch"/> {{ $t('search') }}</button>
<button @click="search"><Fa :icon="faSearch"/> {{ $ts.search }}</button>
</div>
</template>
@ -23,7 +23,7 @@ export default defineComponent({
},
methods: {
search() {
const engine = this.$store.state.settings.webSearchEngine ||
const engine = this.$store.state.webSearchEngine ||
'https://www.google.com/search?q={{query}}';
const url = engine.replace('{{query}}', this.query)
window.open(url, '_blank');

View File

@ -1,16 +1,17 @@
import { App } from 'vue';
import mfm from './misskey-flavored-markdown.vue';
import a from './ui/a.vue';
import acct from './acct.vue';
import avatar from './avatar.vue';
import emoji from './emoji.vue';
import userName from './user-name.vue';
import ellipsis from './ellipsis.vue';
import time from './time.vue';
import url from './url.vue';
import loading from './loading.vue';
import error from './error.vue';
import mfm from './global/misskey-flavored-markdown.vue';
import a from './global/a.vue';
import acct from './global/acct.vue';
import avatar from './global/avatar.vue';
import emoji from './global/emoji.vue';
import userName from './global/user-name.vue';
import ellipsis from './global/ellipsis.vue';
import time from './global/time.vue';
import url from './global/url.vue';
import i18n from './global/i18n';
import loading from './global/loading.vue';
import error from './global/error.vue';
export default function(app: App) {
app.component('Mfm', mfm);
@ -24,4 +25,5 @@ export default function(app: App) {
app.component('MkUrl', url);
app.component('MkLoading', loading);
app.component('MkError', error);
app.component('I18n', i18n);
}

View File

@ -3,80 +3,80 @@
<div class="stats" v-if="info">
<div class="_panel">
<div>
<b><Fa :icon="faUser"/>{{ $t('users') }}</b>
<small>{{ $t('local') }}</small>
<b><Fa :icon="faUser"/>{{ $ts.users }}</b>
<small>{{ $ts.local }}</small>
</div>
<div>
<dl class="total">
<dt>{{ $t('total') }}</dt>
<dt>{{ $ts.total }}</dt>
<dd>{{ number(info.originalUsersCount) }}</dd>
</dl>
<dl class="diff" :class="{ inc: usersLocalDoD > 0 }">
<dt>{{ $t('dayOverDayChanges') }}</dt>
<dt>{{ $ts.dayOverDayChanges }}</dt>
<dd>{{ number(usersLocalDoD) }}</dd>
</dl>
<dl class="diff" :class="{ inc: usersLocalWoW > 0 }">
<dt>{{ $t('weekOverWeekChanges') }}</dt>
<dt>{{ $ts.weekOverWeekChanges }}</dt>
<dd>{{ number(usersLocalWoW) }}</dd>
</dl>
</div>
</div>
<div class="_panel">
<div>
<b><Fa :icon="faUser"/>{{ $t('users') }}</b>
<small>{{ $t('remote') }}</small>
<b><Fa :icon="faUser"/>{{ $ts.users }}</b>
<small>{{ $ts.remote }}</small>
</div>
<div>
<dl class="total">
<dt>{{ $t('total') }}</dt>
<dt>{{ $ts.total }}</dt>
<dd>{{ number((info.usersCount - info.originalUsersCount)) }}</dd>
</dl>
<dl class="diff" :class="{ inc: usersRemoteDoD > 0 }">
<dt>{{ $t('dayOverDayChanges') }}</dt>
<dt>{{ $ts.dayOverDayChanges }}</dt>
<dd>{{ number(usersRemoteDoD) }}</dd>
</dl>
<dl class="diff" :class="{ inc: usersRemoteWoW > 0 }">
<dt>{{ $t('weekOverWeekChanges') }}</dt>
<dt>{{ $ts.weekOverWeekChanges }}</dt>
<dd>{{ number(usersRemoteWoW) }}</dd>
</dl>
</div>
</div>
<div class="_panel">
<div>
<b><Fa :icon="faPencilAlt"/>{{ $t('notes') }}</b>
<small>{{ $t('local') }}</small>
<b><Fa :icon="faPencilAlt"/>{{ $ts.notes }}</b>
<small>{{ $ts.local }}</small>
</div>
<div>
<dl class="total">
<dt>{{ $t('total') }}</dt>
<dt>{{ $ts.total }}</dt>
<dd>{{ number(info.originalNotesCount) }}</dd>
</dl>
<dl class="diff" :class="{ inc: notesLocalDoD > 0 }">
<dt>{{ $t('dayOverDayChanges') }}</dt>
<dt>{{ $ts.dayOverDayChanges }}</dt>
<dd>{{ number(notesLocalDoD) }}</dd>
</dl>
<dl class="diff" :class="{ inc: notesLocalWoW > 0 }">
<dt>{{ $t('weekOverWeekChanges') }}</dt>
<dt>{{ $ts.weekOverWeekChanges }}</dt>
<dd>{{ number(notesLocalWoW) }}</dd>
</dl>
</div>
</div>
<div class="_panel">
<div>
<b><Fa :icon="faPencilAlt"/>{{ $t('notes') }}</b>
<small>{{ $t('remote') }}</small>
<b><Fa :icon="faPencilAlt"/>{{ $ts.notes }}</b>
<small>{{ $ts.remote }}</small>
</div>
<div>
<dl class="total">
<dt>{{ $t('total') }}</dt>
<dt>{{ $ts.total }}</dt>
<dd>{{ number((info.notesCount - info.originalNotesCount)) }}</dd>
</dl>
<dl class="diff" :class="{ inc: notesRemoteDoD > 0 }">
<dt>{{ $t('dayOverDayChanges') }}</dt>
<dt>{{ $ts.dayOverDayChanges }}</dt>
<dd>{{ number(notesRemoteDoD) }}</dd>
</dl>
<dl class="diff" :class="{ inc: notesRemoteWoW > 0 }">
<dt>{{ $t('weekOverWeekChanges') }}</dt>
<dt>{{ $ts.weekOverWeekChanges }}</dt>
<dd>{{ number(notesRemoteWoW) }}</dd>
</dl>
</div>
@ -84,35 +84,35 @@
</div>
<section class="_card">
<div class="_title" style="position: relative;"><Fa :icon="faChartBar"/> {{ $t('statistics') }}<button @click="fetchChart" class="_button" style="position: absolute; right: 0; bottom: 0; top: 0; padding: inherit;"><Fa :icon="faSync"/></button></div>
<div class="_title" style="position: relative;"><Fa :icon="faChartBar"/> {{ $ts.statistics }}<button @click="fetchChart" class="_button" style="position: absolute; right: 0; bottom: 0; top: 0; padding: inherit;"><Fa :icon="faSync"/></button></div>
<div class="_content" style="margin-top: -8px;">
<div class="selects" style="display: flex;">
<MkSelect v-model:value="chartSrc" style="margin: 0; flex: 1;">
<optgroup :label="$t('federation')">
<option value="federation-instances">{{ $t('_charts.federationInstancesIncDec') }}</option>
<option value="federation-instances-total">{{ $t('_charts.federationInstancesTotal') }}</option>
<optgroup :label="$ts.federation">
<option value="federation-instances">{{ $ts._charts.federationInstancesIncDec }}</option>
<option value="federation-instances-total">{{ $ts._charts.federationInstancesTotal }}</option>
</optgroup>
<optgroup :label="$t('users')">
<option value="users">{{ $t('_charts.usersIncDec') }}</option>
<option value="users-total">{{ $t('_charts.usersTotal') }}</option>
<option value="active-users">{{ $t('_charts.activeUsers') }}</option>
<optgroup :label="$ts.users">
<option value="users">{{ $ts._charts.usersIncDec }}</option>
<option value="users-total">{{ $ts._charts.usersTotal }}</option>
<option value="active-users">{{ $ts._charts.activeUsers }}</option>
</optgroup>
<optgroup :label="$t('notes')">
<option value="notes">{{ $t('_charts.notesIncDec') }}</option>
<option value="local-notes">{{ $t('_charts.localNotesIncDec') }}</option>
<option value="remote-notes">{{ $t('_charts.remoteNotesIncDec') }}</option>
<option value="notes-total">{{ $t('_charts.notesTotal') }}</option>
<optgroup :label="$ts.notes">
<option value="notes">{{ $ts._charts.notesIncDec }}</option>
<option value="local-notes">{{ $ts._charts.localNotesIncDec }}</option>
<option value="remote-notes">{{ $ts._charts.remoteNotesIncDec }}</option>
<option value="notes-total">{{ $ts._charts.notesTotal }}</option>
</optgroup>
<optgroup :label="$t('drive')">
<option value="drive-files">{{ $t('_charts.filesIncDec') }}</option>
<option value="drive-files-total">{{ $t('_charts.filesTotal') }}</option>
<option value="drive">{{ $t('_charts.storageUsageIncDec') }}</option>
<option value="drive-total">{{ $t('_charts.storageUsageTotal') }}</option>
<optgroup :label="$ts.drive">
<option value="drive-files">{{ $ts._charts.filesIncDec }}</option>
<option value="drive-files-total">{{ $ts._charts.filesTotal }}</option>
<option value="drive">{{ $ts._charts.storageUsageIncDec }}</option>
<option value="drive-total">{{ $ts._charts.storageUsageTotal }}</option>
</optgroup>
</MkSelect>
<MkSelect v-model:value="chartSpan" style="margin: 0;">
<option value="hour">{{ $t('perHour') }}</option>
<option value="day">{{ $t('perDay') }}</option>
<option value="hour">{{ $ts.perHour }}</option>
<option value="day">{{ $ts.perDay }}</option>
</MkSelect>
</div>
<canvas ref="chart"></canvas>
@ -278,7 +278,7 @@ export default defineComponent({
}
// TODO: var(--panel)の色が暗いか明るいかで判定する
const gridColor = this.$store.state.device.darkMode ? 'rgba(255, 255, 255, 0.1)' : 'rgba(0, 0, 0, 0.1)';
const gridColor = this.$store.state.darkMode ? 'rgba(255, 255, 255, 0.1)' : 'rgba(0, 0, 0, 0.1)';
Chart.defaults.global.defaultFontColor = getComputedStyle(document.documentElement).getPropertyValue('--fg');
this.chartInstance = markRaw(new Chart(this.$refs.chart, {

View File

@ -18,7 +18,7 @@
<div class="sub">
<MkA to="/docs" @click.passive="close()">
<Fa :icon="faQuestionCircle" class="icon"/>
<div class="text">{{ $t('help') }}</div>
<div class="text">{{ $ts.help }}</div>
</MkA>
<MkA to="/about" @click.passive="close()">
<Fa :icon="faInfoCircle" class="icon"/>
@ -26,7 +26,7 @@
</MkA>
<MkA to="/about-misskey" @click.passive="close()">
<Fa :icon="faInfoCircle" class="icon"/>
<div class="text">{{ $t('aboutMisskey') }}</div>
<div class="text">{{ $ts.aboutMisskey }}</div>
</MkA>
</div>
</div>
@ -58,14 +58,14 @@ export default defineComponent({
computed: {
menu(): string[] {
return this.$store.state.deviceUser.menu;
return this.$store.state.menu;
},
},
created() {
this.items = Object.keys(this.menuDef).filter(k => !this.menu.includes(k)).map(k => this.menuDef[k]).filter(def => def.show == null ? true : def.show).map(def => ({
type: def.to ? 'link' : 'button',
text: this.$t(def.title),
text: this.$ts[def.title],
icon: def.icon,
to: def.to,
action: def.action,

View File

@ -2,8 +2,8 @@
<div class="mk-media-banner">
<div class="sensitive" v-if="media.isSensitive && hide" @click="hide = false">
<span class="icon"><Fa :icon="faExclamationTriangle"/></span>
<b>{{ $t('sensitive') }}</b>
<span>{{ $t('clickToShow') }}</span>
<b>{{ $ts.sensitive }}</b>
<span>{{ $ts.clickToShow }}</span>
</div>
<div class="audio" v-else-if="media.type.startsWith('audio') && media.type !== 'audio/midi'">
<audio class="audio"
@ -29,6 +29,7 @@
import { defineComponent } from 'vue';
import { faExclamationTriangle } from '@fortawesome/free-solid-svg-icons';
import * as os from '@/os';
import { ColdDeviceStorage } from '@/store';
export default defineComponent({
props: {
@ -45,12 +46,12 @@ export default defineComponent({
},
mounted() {
const audioTag = this.$refs.audio as HTMLAudioElement;
if (audioTag) audioTag.volume = this.$store.state.device.mediaVolume;
if (audioTag) audioTag.volume = ColdDeviceStorage.get('mediaVolume');
},
methods: {
volumechange() {
const audioTag = this.$refs.audio as HTMLAudioElement;
this.$store.commit('device/set', { key: 'mediaVolume', value: audioTag.volume });
ColdDeviceStorage.set('mediaVolume', audioTag.volume);
},
},
})

View File

@ -3,8 +3,8 @@
<ImgWithBlurhash class="bg" :hash="image.blurhash" :title="image.name"/>
<div class="text">
<div>
<b><Fa :icon="faExclamationTriangle"/> {{ $t('sensitive') }}</b>
<span>{{ $t('clickToShow') }}</span>
<b><Fa :icon="faExclamationTriangle"/> {{ $ts.sensitive }}</b>
<span>{{ $ts.clickToShow }}</span>
</div>
</div>
</div>
@ -52,13 +52,11 @@ export default defineComponent({
},
computed: {
url(): any {
let url = this.$store.state.device.disableShowingAnimatedImages
let url = this.$store.state.disableShowingAnimatedImages
? getStaticImageUrl(this.image.thumbnailUrl)
: this.image.thumbnailUrl;
if (this.$store.state.device.loadRemoteMedia) {
url = null;
} else if (this.raw || this.$store.state.device.loadRawImages) {
if (this.raw || this.$store.state.loadRawImages) {
url = this.image.url;
}
@ -68,7 +66,7 @@ export default defineComponent({
created() {
// Plugin:register_note_view_interruptor を使って書き換えられる可能性があるためwatchする
this.$watch('image', () => {
this.hide = (this.$store.state.device.nsfw === 'force') ? true : this.image.isSensitive && (this.$store.state.device.nsfw !== 'ignore');
this.hide = (this.$store.state.nsfw === 'force') ? true : this.image.isSensitive && (this.$store.state.nsfw !== 'ignore');
if (this.image.blurhash) {
this.color = extractAvgColorFromBlurhash(this.image.blurhash);
}
@ -79,7 +77,7 @@ export default defineComponent({
},
methods: {
onClick() {
if (this.$store.state.device.imageNewTab) {
if (this.$store.state.imageNewTab) {
window.open(this.image.url, '_blank');
} else {
os.popup(ImageViewer, {

View File

@ -1,8 +1,8 @@
<template>
<div class="icozogqfvdetwohsdglrbswgrejoxbdj" v-if="hide" @click="hide = false">
<div>
<b><Fa :icon="faExclamationTriangle"/> {{ $t('sensitive') }}</b>
<span>{{ $t('clickToShow') }}</span>
<b><Fa :icon="faExclamationTriangle"/> {{ $ts.sensitive }}</b>
<span>{{ $ts.clickToShow }}</span>
</div>
</div>
<div class="kkjnbbplepmiyuadieoenjgutgcmtsvu" v-else>
@ -48,7 +48,7 @@ export default defineComponent({
}
},
created() {
this.hide = (this.$store.state.device.nsfw === 'force') ? true : this.video.isSensitive && (this.$store.state.device.nsfw !== 'ignore');
this.hide = (this.$store.state.nsfw === 'force') ? true : this.video.isSensitive && (this.$store.state.nsfw !== 'ignore');
},
});
</script>

View File

@ -1,9 +1,9 @@
<template>
<MkA class="ldlomzub" :class="{ isMe }" :to="url" v-user-preview="canonical" v-if="url.startsWith('/')">
<span class="me" v-if="isMe">{{ $t('you') }}</span>
<span class="me" v-if="isMe">{{ $ts.you }}</span>
<span class="main">
<span class="username">@{{ username }}</span>
<span class="host" v-if="(host != localHost) || $store.state.settings.showFullAcct">@{{ toUnicode(host) }}</span>
<span class="host" v-if="(host != localHost) || $store.state.showFullAcct">@{{ toUnicode(host) }}</span>
</span>
</MkA>
<a class="ldlomzub" :href="url" target="_blank" rel="noopener" v-else>
@ -50,8 +50,8 @@ export default defineComponent({
return this.host === localHost ? `@${this.username}` : `@${this.username}@${toUnicode(this.host)}`;
},
isMe(): boolean {
return this.$store.getters.isSignedIn && (
`@${this.username}@${toUnicode(this.host)}` === `@${this.$store.state.i.username}@${toUnicode(localHost)}`.toLowerCase()
return this.$i && (
`@${this.username}@${toUnicode(this.host)}` === `@${this.$i.username}@${toUnicode(localHost)}`.toLowerCase()
);
}
},

View File

@ -1,15 +1,15 @@
import { VNode, defineComponent, h } from 'vue';
import { MfmForest } from '../../mfm/prelude';
import { parse, parsePlain } from '../../mfm/parse';
import MkUrl from './url.vue';
import MkLink from './link.vue';
import MkMention from './mention.vue';
import MkEmoji from './emoji.vue';
import { concat } from '../../prelude/array';
import MkFormula from './formula.vue';
import MkCode from './code.vue';
import MkGoogle from './google.vue';
import MkA from './ui/a.vue';
import { MfmForest } from '@/../mfm/prelude';
import { parse, parsePlain } from '@/../mfm/parse';
import MkUrl from '@/components/global/url.vue';
import MkLink from '@/components/link.vue';
import MkMention from '@/components/mention.vue';
import MkEmoji from '@/components/global/emoji.vue';
import { concat } from '@/../prelude/array';
import MkFormula from '@/components/formula.vue';
import MkCode from '@/components/code.vue';
import MkGoogle from '@/components/google.vue';
import MkA from '@/components/global/a.vue';
import { host } from '@/config';
export default defineComponent({
@ -82,22 +82,22 @@ export default defineComponent({
let style;
switch (token.node.props.name) {
case 'tada': {
style = `font-size: 150%;` + (this.$store.state.device.animatedMfm ? 'animation: tada 1s linear infinite both;' : '');
style = `font-size: 150%;` + (this.$store.state.animatedMfm ? 'animation: tada 1s linear infinite both;' : '');
break;
}
case 'jelly': {
const speed = token.node.props.args.speed || '1s';
style = (this.$store.state.device.animatedMfm ? `animation: mfm-rubberBand ${speed} linear infinite both;` : '');
style = (this.$store.state.animatedMfm ? `animation: mfm-rubberBand ${speed} linear infinite both;` : '');
break;
}
case 'twitch': {
const speed = token.node.props.args.speed || '0.5s';
style = this.$store.state.device.animatedMfm ? `animation: mfm-twitch ${speed} ease infinite;` : '';
style = this.$store.state.animatedMfm ? `animation: mfm-twitch ${speed} ease infinite;` : '';
break;
}
case 'shake': {
const speed = token.node.props.args.speed || '0.5s';
style = this.$store.state.device.animatedMfm ? `animation: mfm-shake ${speed} ease infinite;` : '';
style = this.$store.state.animatedMfm ? `animation: mfm-shake ${speed} ease infinite;` : '';
break;
}
case 'spin': {
@ -110,15 +110,15 @@ export default defineComponent({
token.node.props.args.y ? 'mfm-spinY' :
'mfm-spin';
const speed = token.node.props.args.speed || '1.5s';
style = this.$store.state.device.animatedMfm ? `animation: ${anime} ${speed} linear infinite; animation-direction: ${direction};` : '';
style = this.$store.state.animatedMfm ? `animation: ${anime} ${speed} linear infinite; animation-direction: ${direction};` : '';
break;
}
case 'jump': {
style = this.$store.state.device.animatedMfm ? 'animation: mfm-jump 0.75s linear infinite;' : '';
style = this.$store.state.animatedMfm ? 'animation: mfm-jump 0.75s linear infinite;' : '';
break;
}
case 'bounce': {
style = this.$store.state.device.animatedMfm ? 'animation: mfm-bounce 0.75s linear infinite; transform-origin: center bottom;' : '';
style = this.$store.state.animatedMfm ? 'animation: mfm-bounce 0.75s linear infinite; transform-origin: center bottom;' : '';
break;
}
case 'flip': {

View File

@ -6,7 +6,7 @@
<XNoteHeader class="header" :note="note" :mini="true"/>
<div class="body">
<p v-if="note.cw != null" class="cw">
<Mfm v-if="note.cw != ''" class="text" :text="note.cw" :author="note.user" :i="$store.state.i" :custom-emojis="note.emojis" />
<Mfm v-if="note.cw != ''" class="text" :text="note.cw" :author="note.user" :i="$i" :custom-emojis="note.emojis" />
<XCwButton v-model:value="showContent" :note="note"/>
</p>
<div class="content" v-show="note.cw == null || showContent">

View File

@ -10,19 +10,19 @@
>
<XSub v-for="note in conversation" class="reply-to-more" :key="note.id" :note="note"/>
<XSub :note="appearNote.reply" class="reply-to" v-if="appearNote.reply"/>
<div class="info" v-if="pinned"><Fa :icon="faThumbtack"/> {{ $t('pinnedNote') }}</div>
<div class="info" v-if="appearNote._prId_"><Fa :icon="faBullhorn"/> {{ $t('promotion') }}<button class="_textButton hide" @click="readPromo()">{{ $t('hideThisNote') }} <Fa :icon="faTimes"/></button></div>
<div class="info" v-if="appearNote._featuredId_"><Fa :icon="faBolt"/> {{ $t('featured') }}</div>
<div class="info" v-if="pinned"><Fa :icon="faThumbtack"/> {{ $ts.pinnedNote }}</div>
<div class="info" v-if="appearNote._prId_"><Fa :icon="faBullhorn"/> {{ $ts.promotion }}<button class="_textButton hide" @click="readPromo()">{{ $ts.hideThisNote }} <Fa :icon="faTimes"/></button></div>
<div class="info" v-if="appearNote._featuredId_"><Fa :icon="faBolt"/> {{ $ts.featured }}</div>
<div class="renote" v-if="isRenote">
<MkAvatar class="avatar" :user="note.user"/>
<Fa :icon="faRetweet"/>
<i18n-t keypath="renotedBy" tag="span">
<I18n :src="$ts.renotedBy" tag="span">
<template #user>
<MkA class="name" :to="userPage(note.user)" v-user-preview="note.userId">
<MkUserName :user="note.user"/>
</MkA>
</template>
</i18n-t>
</I18n>
<div class="info">
<button class="_button time" @click="showRenoteMenu()" ref="renoteTime">
<Fa class="dropdownIcon" v-if="isMyRenote" :icon="faEllipsisH"/>
@ -43,14 +43,14 @@
<MkInstanceTicker v-if="showTicker" class="ticker" :instance="appearNote.user.instance"/>
<div class="body">
<p v-if="appearNote.cw != null" class="cw">
<Mfm v-if="appearNote.cw != ''" class="text" :text="appearNote.cw" :author="appearNote.user" :i="$store.state.i" :custom-emojis="appearNote.emojis"/>
<Mfm v-if="appearNote.cw != ''" class="text" :text="appearNote.cw" :author="appearNote.user" :i="$i" :custom-emojis="appearNote.emojis"/>
<XCwButton v-model:value="showContent" :note="appearNote"/>
</p>
<div class="content" v-show="appearNote.cw == null || showContent">
<div class="text">
<span v-if="appearNote.isHidden" style="opacity: 0.5">({{ $t('private') }})</span>
<span v-if="appearNote.isHidden" style="opacity: 0.5">({{ $ts.private }})</span>
<MkA class="reply" v-if="appearNote.replyId" :to="`/notes/${appearNote.replyId}`"><Fa :icon="faReply"/></MkA>
<Mfm v-if="appearNote.text" :text="appearNote.text" :author="appearNote.user" :i="$store.state.i" :custom-emojis="appearNote.emojis"/>
<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>
<div class="files" v-if="appearNote.files.length > 0">
@ -90,13 +90,13 @@
<XSub v-for="note in replies" :key="note.id" :note="note" class="reply" :detail="true"/>
</div>
<div v-else class="_panel muted" @click="muted = false">
<i18n-t keypath="userSaysSomething" tag="small">
<I18n :src="$ts.userSaysSomething" tag="small">
<template #name>
<MkA class="name" :to="userPage(appearNote.user)" v-user-preview="appearNote.userId">
<MkUserName :user="appearNote.user"/>
</MkA>
</template>
</i18n-t>
</I18n>
</div>
</template>
@ -182,7 +182,7 @@ export default defineComponent({
computed: {
rs() {
return this.$store.state.settings.reactions;
return this.$store.state.reactions;
},
keymap(): any {
return {
@ -222,11 +222,11 @@ export default defineComponent({
},
isMyNote(): boolean {
return this.$store.getters.isSignedIn && (this.$store.state.i.id === this.appearNote.userId);
return this.$i && (this.$i.id === this.appearNote.userId);
},
isMyRenote(): boolean {
return this.$store.getters.isSignedIn && (this.$store.state.i.id === this.note.userId);
return this.$i && (this.$i.id === this.note.userId);
},
canRenote(): boolean {
@ -262,14 +262,14 @@ export default defineComponent({
},
showTicker() {
if (this.$store.state.device.instanceTicker === 'always') return true;
if (this.$store.state.device.instanceTicker === 'remote' && this.appearNote.user.instance) return true;
if (this.$store.state.instanceTicker === 'always') return true;
if (this.$store.state.instanceTicker === 'remote' && this.appearNote.user.instance) return true;
return false;
}
},
async created() {
if (this.$store.getters.isSignedIn) {
if (this.$i) {
this.connection = os.stream;
}
@ -282,7 +282,7 @@ export default defineComponent({
this.$emit('update:note', Object.freeze(result));
}
this.muted = await checkWordMute(this.appearNote, this.$store.state.i, this.$store.state.settings.mutedWords);
this.muted = await checkWordMute(this.appearNote, this.$i, this.$store.state.mutedWords);
if (this.detail) {
os.api('notes/children', {
@ -305,7 +305,7 @@ export default defineComponent({
mounted() {
this.capture(true);
if (this.$store.getters.isSignedIn) {
if (this.$i) {
this.connection.on('_connected_', this.onStreamConnected);
}
},
@ -313,7 +313,7 @@ export default defineComponent({
beforeUnmount() {
this.decapture(true);
if (this.$store.getters.isSignedIn) {
if (this.$i) {
this.connection.off('_connected_', this.onStreamConnected);
}
},
@ -340,14 +340,14 @@ export default defineComponent({
},
capture(withHandler = false) {
if (this.$store.getters.isSignedIn) {
if (this.$i) {
this.connection.send(document.body.contains(this.$el) ? 'sn' : 's', { id: this.appearNote.id });
if (withHandler) this.connection.on('noteUpdated', this.onStreamNoteUpdated);
}
},
decapture(withHandler = false) {
if (this.$store.getters.isSignedIn) {
if (this.$i) {
this.connection.send('un', {
id: this.appearNote.id
});
@ -389,7 +389,7 @@ export default defineComponent({
[reaction]: currentCount + 1
};
if (body.userId === this.$store.state.i.id) {
if (body.userId === this.$i.id) {
n.myReaction = reaction;
}
@ -414,7 +414,7 @@ export default defineComponent({
[reaction]: Math.max(0, currentCount - 1)
};
if (body.userId === this.$store.state.i.id) {
if (body.userId === this.$i.id) {
n.myReaction = null;
}
@ -434,7 +434,7 @@ export default defineComponent({
choices[choice] = {
...choices[choice],
votes: choices[choice].votes + 1,
...(body.userId === this.$store.state.i.id ? {
...(body.userId === this.$i.id ? {
isVoted: true
} : {})
};
@ -469,7 +469,7 @@ export default defineComponent({
pleaseLogin();
this.blur();
os.modalMenu([{
text: this.$t('renote'),
text: this.$ts.renote,
icon: faRetweet,
action: () => {
os.api('notes/create', {
@ -477,7 +477,7 @@ export default defineComponent({
});
}
}, {
text: this.$t('quote'),
text: this.$ts.quote,
icon: faQuoteRight,
action: () => {
os.post({
@ -490,8 +490,25 @@ export default defineComponent({
},
renoteDirectly() {
os.api('notes/create', {
os.apiWithDialog('notes/create', {
renoteId: this.appearNote.id
}, undefined, (res: any) => {
os.dialog({
type: 'success',
text: this.$ts.renoted,
});
}, (e: Error) => {
if (e.id === 'b5c90186-4ab0-49c8-9bba-a1f76c282ba4') {
os.dialog({
type: 'error',
text: this.$ts.cantRenote,
});
} else if (e.id === 'fd4cc33e-2a37-48dd-99cc-9b806eb2031a') {
os.dialog({
type: 'error',
text: this.$ts.cantReRenote,
});
}
});
},
@ -533,13 +550,30 @@ export default defineComponent({
pleaseLogin();
os.apiWithDialog('notes/favorites/create', {
noteId: this.appearNote.id
}, undefined, (res: any) => {
os.dialog({
type: 'success',
text: this.$ts.favorited,
});
}, (e: Error) => {
if (e.id === 'a402c12b-34dd-41d2-97d8-4d2ffd96a1a6') {
os.dialog({
type: 'error',
text: this.$ts.alreadyFavorited,
});
} else if (e.id === '6dd26674-e060-4816-909a-45ba3f4da458') {
os.dialog({
type: 'error',
text: this.$ts.cantFavorite,
});
}
});
},
del() {
os.dialog({
type: 'warning',
text: this.$t('noteDeleteConfirm'),
text: this.$ts.noteDeleteConfirm,
showCancelButton: true
}).then(({ canceled }) => {
if (canceled) return;
@ -553,7 +587,7 @@ export default defineComponent({
delEdit() {
os.dialog({
type: 'warning',
text: this.$t('deleteAndEditConfirm'),
text: this.$ts.deleteAndEditConfirm,
showCancelButton: true
}).then(({ canceled }) => {
if (canceled) return;
@ -580,22 +614,22 @@ export default defineComponent({
getMenu() {
let menu;
if (this.$store.getters.isSignedIn) {
if (this.$i) {
const statePromise = os.api('notes/state', {
noteId: this.appearNote.id
});
menu = [{
icon: faCopy,
text: this.$t('copyContent'),
text: this.$ts.copyContent,
action: this.copyContent
}, {
icon: faLink,
text: this.$t('copyLink'),
text: this.$ts.copyLink,
action: this.copyLink
}, (this.appearNote.url || this.appearNote.uri) ? {
icon: faExternalLinkSquareAlt,
text: this.$t('showOnRemote'),
text: this.$ts.showOnRemote,
action: () => {
window.open(this.appearNote.url || this.appearNote.uri, '_blank');
}
@ -603,50 +637,50 @@ export default defineComponent({
null,
statePromise.then(state => state.isFavorited ? {
icon: faStar,
text: this.$t('unfavorite'),
text: this.$ts.unfavorite,
action: () => this.toggleFavorite(false)
} : {
icon: faStar,
text: this.$t('favorite'),
text: this.$ts.favorite,
action: () => this.toggleFavorite(true)
}),
{
icon: faPaperclip,
text: this.$t('clip'),
text: this.$ts.clip,
action: () => this.clip()
},
(this.appearNote.userId != this.$store.state.i.id) ? statePromise.then(state => state.isWatching ? {
(this.appearNote.userId != this.$i.id) ? statePromise.then(state => state.isWatching ? {
icon: faEyeSlash,
text: this.$t('unwatch'),
text: this.$ts.unwatch,
action: () => this.toggleWatch(false)
} : {
icon: faEye,
text: this.$t('watch'),
text: this.$ts.watch,
action: () => this.toggleWatch(true)
}) : undefined,
this.appearNote.userId == this.$store.state.i.id ? (this.$store.state.i.pinnedNoteIds || []).includes(this.appearNote.id) ? {
this.appearNote.userId == this.$i.id ? (this.$i.pinnedNoteIds || []).includes(this.appearNote.id) ? {
icon: faThumbtack,
text: this.$t('unpin'),
text: this.$ts.unpin,
action: () => this.togglePin(false)
} : {
icon: faThumbtack,
text: this.$t('pin'),
text: this.$ts.pin,
action: () => this.togglePin(true)
} : undefined,
...(this.$store.state.i.isModerator || this.$store.state.i.isAdmin ? [
...(this.$i.isModerator || this.$i.isAdmin ? [
null,
{
icon: faBullhorn,
text: this.$t('promote'),
text: this.$ts.promote,
action: this.promote
}]
: []
),
...(this.appearNote.userId != this.$store.state.i.id ? [
...(this.appearNote.userId != this.$i.id ? [
null,
{
icon: faExclamationCircle,
text: this.$t('reportAbuse'),
text: this.$ts.reportAbuse,
action: () => {
const u = `${url}/notes/${this.appearNote.id}`;
os.popup(import('@/components/abuse-report-window.vue'), {
@ -657,16 +691,16 @@ export default defineComponent({
}]
: []
),
...(this.appearNote.userId == this.$store.state.i.id || this.$store.state.i.isModerator || this.$store.state.i.isAdmin ? [
...(this.appearNote.userId == this.$i.id || this.$i.isModerator || this.$i.isAdmin ? [
null,
this.appearNote.userId == this.$store.state.i.id ? {
this.appearNote.userId == this.$i.id ? {
icon: faEdit,
text: this.$t('deleteAndEdit'),
text: this.$ts.deleteAndEdit,
action: this.delEdit
} : undefined,
{
icon: faTrashAlt,
text: this.$t('delete'),
text: this.$ts.delete,
danger: true,
action: this.del
}]
@ -676,15 +710,15 @@ export default defineComponent({
} else {
menu = [{
icon: faCopy,
text: this.$t('copyContent'),
text: this.$ts.copyContent,
action: this.copyContent
}, {
icon: faLink,
text: this.$t('copyLink'),
text: this.$ts.copyLink,
action: this.copyLink
}, (this.appearNote.url || this.appearNote.uri) ? {
icon: faExternalLinkSquareAlt,
text: this.$t('showOnRemote'),
text: this.$ts.showOnRemote,
action: () => {
window.open(this.appearNote.url || this.appearNote.uri, '_blank');
}
@ -726,7 +760,7 @@ export default defineComponent({
showRenoteMenu(viaKeyboard = false) {
if (!this.isMyRenote) return;
os.modalMenu([{
text: this.$t('unrenote'),
text: this.$ts.unrenote,
icon: faTrashAlt,
danger: true,
action: () => {
@ -761,7 +795,7 @@ export default defineComponent({
if (e.id === '72dab508-c64d-498f-8740-a8eec1ba385a') {
os.dialog({
type: 'error',
text: this.$t('pinLimitExceeded')
text: this.$ts.pinLimitExceeded
});
}
});
@ -771,22 +805,22 @@ export default defineComponent({
const clips = await os.api('clips/list');
os.modalMenu([{
icon: faPlus,
text: this.$t('createNew'),
text: this.$ts.createNew,
action: async () => {
const { canceled, result } = await os.form(this.$t('createNewClip'), {
const { canceled, result } = await os.form(this.$ts.createNewClip, {
name: {
type: 'string',
label: this.$t('name')
label: this.$ts.name
},
description: {
type: 'string',
required: false,
multiline: true,
label: this.$t('description')
label: this.$ts.description
},
isPublic: {
type: 'boolean',
label: this.$t('public'),
label: this.$ts.public,
default: false
}
});
@ -807,7 +841,7 @@ export default defineComponent({
async promote() {
const { canceled, result: days } = await os.dialog({
title: this.$t('numberOfDays'),
title: this.$ts.numberOfDays,
input: { type: 'number' }
});
@ -847,6 +881,14 @@ export default defineComponent({
overflow: hidden;
contain: content;
// これらの指定はパフォーマンス向上には有効だが、ノートの高さは一定でないため、
// 下の方までスクロールすると上のノートの高さがここで決め打ちされたものに変化し、表示しているノートの位置が変わってしまう
// ノートがマウントされたときに自身の高さを取得し contain-intrinsic-size を設定しなおせばほぼ解決できそうだが、
// 今度はその処理自体がパフォーマンス低下の原因にならないか懸念される。また、被リアクションでも高さは変化するため、やはり多少のズレは生じる
// 一度レンダリングされた要素はブラウザがよしなにサイズを覚えておいてくれるような実装になるまで待った方が良さそう(なるのか?)
//content-visibility: auto;
//contain-intrinsic-size: 0 128px;
&:focus {
outline: none;

View File

@ -2,14 +2,14 @@
<div class="_list_">
<div class="_fullinfo" v-if="empty">
<img src="https://xn--931a.moe/assets/info.jpg" class="_ghost"/>
<div>{{ $t('noNotes') }}</div>
<div>{{ $ts.noNotes }}</div>
</div>
<MkError v-if="error" @retry="init()"/>
<div v-show="more && reversed" style="margin-bottom: var(--margin);">
<button class="_loadMore" @click="fetchMore" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }">
<template v-if="!moreFetching">{{ $t('loadMore') }}</template>
<template v-if="!moreFetching">{{ $ts.loadMore }}</template>
<template v-if="moreFetching"><MkLoading inline/></template>
</button>
</div>
@ -19,8 +19,8 @@
</XList>
<div v-show="more && !reversed" style="margin-top: var(--margin);">
<button class="_loadMore" v-appear="$store.state.device.enableInfiniteScroll ? fetchMore : null" @click="fetchMore" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }">
<template v-if="!moreFetching">{{ $t('loadMore') }}</template>
<button class="_loadMore" v-appear="$store.state.enableInfiniteScroll ? fetchMore : null" @click="fetchMore" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }">
<template v-if="!moreFetching">{{ $ts.loadMore }}</template>
<template v-if="moreFetching"><MkLoading inline/></template>
</button>
</div>

View File

@ -8,17 +8,17 @@
@close="$refs.dialog.close()"
@closed="$emit('closed')"
>
<template #header>{{ $t('notificationSetting') }}</template>
<template #header>{{ $ts.notificationSetting }}</template>
<div v-if="showGlobalToggle" class="_section">
<MkSwitch v-model:value="useGlobalSetting">
{{ $t('useGlobalSetting') }}
<template #desc>{{ $t('useGlobalSettingDesc') }}</template>
{{ $ts.useGlobalSetting }}
<template #desc>{{ $ts.useGlobalSettingDesc }}</template>
</MkSwitch>
</div>
<div v-if="!useGlobalSetting" class="_section">
<MkInfo>{{ $t('notificationSettingDesc') }}</MkInfo>
<MkButton inline @click="disableAll">{{ $t('disableAll') }}</MkButton>
<MkButton inline @click="enableAll">{{ $t('enableAll') }}</MkButton>
<MkInfo>{{ $ts.notificationSettingDesc }}</MkInfo>
<MkButton inline @click="disableAll">{{ $ts.disableAll }}</MkButton>
<MkButton inline @click="enableAll">{{ $ts.enableAll }}</MkButton>
<MkSwitch v-for="type in notificationTypes" :key="type" v-model:value="typesMap[type]">{{ $t(`_notification._types.${type}`) }}</MkSwitch>
</div>
</XModalWindow>

View File

@ -46,10 +46,10 @@
<Mfm :text="getNoteSummary(notification.note)" :plain="true" :nowrap="!full" :custom-emojis="notification.note.emojis"/>
<Fa :icon="faQuoteRight"/>
</MkA>
<span v-if="notification.type === 'follow'" class="text" style="opacity: 0.6;">{{ $t('youGotNewFollower') }}<div v-if="full"><MkFollowButton :user="notification.user" :full="true"/></div></span>
<span v-if="notification.type === 'followRequestAccepted'" class="text" style="opacity: 0.6;">{{ $t('followRequestAccepted') }}</span>
<span v-if="notification.type === 'receiveFollowRequest'" class="text" style="opacity: 0.6;">{{ $t('receiveFollowRequest') }}<div v-if="full && !followRequestDone"><button class="_textButton" @click="acceptFollowRequest()">{{ $t('accept') }}</button> | <button class="_textButton" @click="rejectFollowRequest()">{{ $t('reject') }}</button></div></span>
<span v-if="notification.type === 'groupInvited'" class="text" style="opacity: 0.6;">{{ $t('groupInvited') }}: <b>{{ notification.invitation.group.name }}</b><div v-if="full && !groupInviteDone"><button class="_textButton" @click="acceptGroupInvitation()">{{ $t('accept') }}</button> | <button class="_textButton" @click="rejectGroupInvitation()">{{ $t('reject') }}</button></div></span>
<span v-if="notification.type === 'follow'" class="text" style="opacity: 0.6;">{{ $ts.youGotNewFollower }}<div v-if="full"><MkFollowButton :user="notification.user" :full="true"/></div></span>
<span v-if="notification.type === 'followRequestAccepted'" class="text" style="opacity: 0.6;">{{ $ts.followRequestAccepted }}</span>
<span v-if="notification.type === 'receiveFollowRequest'" class="text" style="opacity: 0.6;">{{ $ts.receiveFollowRequest }}<div v-if="full && !followRequestDone"><button class="_textButton" @click="acceptFollowRequest()">{{ $ts.accept }}</button> | <button class="_textButton" @click="rejectFollowRequest()">{{ $ts.reject }}</button></div></span>
<span v-if="notification.type === 'groupInvited'" class="text" style="opacity: 0.6;">{{ $ts.groupInvited }}: <b>{{ notification.invitation.group.name }}</b><div v-if="full && !groupInviteDone"><button class="_textButton" @click="acceptGroupInvitation()">{{ $ts.accept }}</button> | <button class="_textButton" @click="rejectGroupInvitation()">{{ $ts.reject }}</button></div></span>
<span v-if="notification.type === 'app'" class="text">
<Mfm :text="notification.body" :nowrap="!full"/>
</span>

View File

@ -5,12 +5,12 @@
<XNotification v-else :notification="notification" :with-time="true" :full="true" class="_panel notification" :key="notification.id"/>
</XList>
<button class="_loadMore" v-appear="$store.state.device.enableInfiniteScroll ? fetchMore : null" @click="fetchMore" v-show="more" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }">
<template v-if="!moreFetching">{{ $t('loadMore') }}</template>
<button class="_loadMore" v-appear="$store.state.enableInfiniteScroll ? fetchMore : null" @click="fetchMore" v-show="more" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }">
<template v-if="!moreFetching">{{ $ts.loadMore }}</template>
<template v-if="moreFetching"><MkLoading inline/></template>
</button>
<p class="empty" v-if="empty">{{ $t('noNotifications') }}</p>
<p class="empty" v-if="empty">{{ $ts.noNotifications }}</p>
<MkError v-if="error" @retry="init()"/>
</div>
@ -59,7 +59,7 @@ export default defineComponent({
computed: {
allIncludeTypes() {
return this.includeTypes ?? notificationTypes.filter(x => !this.$store.state.i.mutingNotificationTypes.includes(x));
return this.includeTypes ?? notificationTypes.filter(x => !this.$i.mutingNotificationTypes.includes(x));
}
},
@ -70,9 +70,9 @@ export default defineComponent({
},
deep: true
},
// TODO: vue/vuexのバグか仕様かは不明なものの、プロフィール更新するなどして $store.state.i が更新されると、
// TODO: vue/vuexのバグか仕様かは不明なものの、プロフィール更新するなどして $i が更新されると、
// mutingNotificationTypes に変化が無くてもこのハンドラーが呼び出され無駄なリロードが発生するのを直す
'$store.state.i.mutingNotificationTypes': {
'$i.mutingNotificationTypes': {
handler() {
if (this.includeTypes === null) {
this.reload();

View File

@ -90,29 +90,29 @@ export default defineComponent({
text: this.path,
}, {
icon: faExpandAlt,
text: this.$t('showInPage'),
text: this.$ts.showInPage,
action: this.expand
}, this.sideViewHook ? {
icon: faColumns,
text: this.$t('openInSideView'),
text: this.$ts.openInSideView,
action: () => {
this.sideViewHook(this.path);
this.$refs.window.close();
}
} : undefined, {
icon: faExternalLinkAlt,
text: this.$t('popout'),
text: this.$ts.popout,
action: this.popout
}, null, {
icon: faExternalLinkAlt,
text: this.$t('openInNewTab'),
text: this.$ts.openInNewTab,
action: () => {
window.open(this.url, '_blank');
this.$refs.window.close();
}
}, {
icon: faLink,
text: this.$t('copyLink'),
text: this.$ts.copyLink,
action: () => {
copyToClipboard(this.url);
}

View File

@ -49,9 +49,9 @@ export default defineComponent({
canvas.toBlob(blob => {
const data = new FormData();
data.append('file', blob);
data.append('i', this.$store.state.i.token);
if (this.$store.state.settings.uploadFolder) {
data.append('folderId', this.$store.state.settings.uploadFolder);
data.append('i', this.$i.token);
if (this.$store.state.uploadFolder) {
data.append('folderId', this.$store.state.uploadFolder);
}
fetch(apiUrl + '/drive/files/create', {

View File

@ -1,7 +1,7 @@
<template>
<div>
<div>{{ hpml.interpolate(value.title) }}</div>
<MkRadio v-for="x in value.values" v-model:value="v" :value="x" :key="x">{{ x }}</MkRadio>
<MkRadio v-for="x in value.values" v-model="v" :value="x" :key="x">{{ x }}</MkRadio>
</div>
</template>

View File

@ -1,6 +1,6 @@
<template>
<div class="mrdgzndn">
<Mfm :text="text" :is-note="false" :i="$store.state.i" :key="text"/>
<Mfm :text="text" :is-note="false" :i="$i" :key="text"/>
<MkUrlPreview v-for="url in urls" :url="url" :key="url" class="url"/>
</div>
</template>

View File

@ -1,6 +1,6 @@
<template>
<div class="iroscrza" :class="{ center: page.alignCenter, serif: page.font === 'serif' }" v-if="hpml">
<XBlock v-for="child in page.content" :value="child" @update:value="v => updateBlock(v)" :page="page" :hpml="hpml" :key="child.id" :h="2"/>
<XBlock v-for="child in page.content" :value="child" :page="page" :hpml="hpml" :key="child.id" :h="2"/>
</div>
</template>
@ -35,9 +35,9 @@ export default defineComponent({
created() {
this.hpml = new Hpml(this.page, {
randomSeed: Math.random(),
visitor: this.$store.state.i,
visitor: this.$i,
url: url,
enableAiScript: !this.$store.state.device.disablePagesScript
enableAiScript: !this.$store.state.disablePagesScript
});
},

View File

@ -1,7 +1,7 @@
<template>
<div class="zmdxowus">
<p class="caution" v-if="choices.length < 2">
<Fa :icon="faExclamationTriangle"/>{{ $t('_poll.noOnlyOneChoice') }}
<Fa :icon="faExclamationTriangle"/>{{ $ts._poll.noOnlyOneChoice }}
</p>
<ul ref="choices">
<li v-for="(choice, i) in choices" :key="i">
@ -13,34 +13,34 @@
</button>
</li>
</ul>
<MkButton class="add" v-if="choices.length < 10" @click="add">{{ $t('add') }}</MkButton>
<MkButton class="add" v-else disabled>{{ $t('_poll.noMore') }}</MkButton>
<MkButton class="add" v-if="choices.length < 10" @click="add">{{ $ts.add }}</MkButton>
<MkButton class="add" v-else disabled>{{ $ts._poll.noMore }}</MkButton>
<section>
<MkSwitch v-model:value="multiple">{{ $t('_poll.canMultipleVote') }}</MkSwitch>
<MkSwitch v-model:value="multiple">{{ $ts._poll.canMultipleVote }}</MkSwitch>
<div>
<MkSelect v-model:value="expiration">
<template #label>{{ $t('_poll.expiration') }}</template>
<option value="infinite">{{ $t('_poll.infinite') }}</option>
<option value="at">{{ $t('_poll.at') }}</option>
<option value="after">{{ $t('_poll.after') }}</option>
<template #label>{{ $ts._poll.expiration }}</template>
<option value="infinite">{{ $ts._poll.infinite }}</option>
<option value="at">{{ $ts._poll.at }}</option>
<option value="after">{{ $ts._poll.after }}</option>
</MkSelect>
<section v-if="expiration === 'at'">
<MkInput v-model:value="atDate" type="date" class="input">
<span>{{ $t('_poll.deadlineDate') }}</span>
<span>{{ $ts._poll.deadlineDate }}</span>
</MkInput>
<MkInput v-model:value="atTime" type="time" class="input">
<span>{{ $t('_poll.deadlineTime') }}</span>
<span>{{ $ts._poll.deadlineTime }}</span>
</MkInput>
</section>
<section v-if="expiration === 'after'">
<MkInput v-model:value="after" type="number" class="input">
<span>{{ $t('_poll.duration') }}</span>
<span>{{ $ts._poll.duration }}</span>
</MkInput>
<MkSelect v-model:value="unit">
<option value="second">{{ $t('_time.second') }}</option>
<option value="minute">{{ $t('_time.minute') }}</option>
<option value="hour">{{ $t('_time.hour') }}</option>
<option value="day">{{ $t('_time.day') }}</option>
<option value="second">{{ $ts._time.second }}</option>
<option value="minute">{{ $ts._time.minute }}</option>
<option value="hour">{{ $ts._time.hour }}</option>
<option value="day">{{ $ts._time.day }}</option>
</MkSelect>
</section>
</div>

View File

@ -13,9 +13,9 @@
<p>
<span>{{ $t('_poll.totalVotes', { n: total }) }}</span>
<span> · </span>
<a v-if="!closed && !isVoted" @click="toggleShowResult">{{ showResult ? $t('_poll.vote') : $t('_poll.showResult') }}</a>
<span v-if="isVoted">{{ $t('_poll.voted') }}</span>
<span v-else-if="closed">{{ $t('_poll.closed') }}</span>
<a v-if="!closed && !isVoted" @click="toggleShowResult">{{ showResult ? $ts._poll.vote : $ts._poll.showResult }}</a>
<span v-if="isVoted">{{ $ts._poll.voted }}</span>
<span v-else-if="closed">{{ $ts._poll.closed }}</span>
<span v-if="remaining > 0"> · {{ timer }}</span>
</p>
</div>

View File

@ -77,7 +77,7 @@ export default defineComponent({
},
async rename(file) {
const { canceled, result } = await os.dialog({
title: this.$t('enterFileName'),
title: this.$ts.enterFileName,
input: {
default: file.name
},
@ -95,15 +95,15 @@ export default defineComponent({
showFileMenu(file, ev: MouseEvent) {
if (this.menu) return;
this.menu = os.modalMenu([{
text: this.$t('renameFile'),
text: this.$ts.renameFile,
icon: faICursor,
action: () => { this.rename(file) }
}, {
text: file.isSensitive ? this.$t('unmarkAsSensitive') : this.$t('markAsSensitive'),
text: file.isSensitive ? this.$ts.unmarkAsSensitive : this.$ts.markAsSensitive,
icon: file.isSensitive ? faEyeSlash : faEye,
action: () => { this.toggleSensitive(file) }
}, {
text: this.$t('attachCancel'),
text: this.$ts.attachCancel,
icon: faTimesCircle,
action: () => { this.detachMedia(file.id) }
}], ev.currentTarget || ev.target).then(() => this.menu = null);

View File

@ -11,7 +11,7 @@
<div>
<span class="text-count" :class="{ over: trimmedLength(text) > max }">{{ max - trimmedLength(text) }}</span>
<span class="local-only" v-if="localOnly"><Fa :icon="faBiohazard"/></span>
<button class="_button visibility" @click="setVisibility" ref="visibilityButton" v-tooltip="$t('visibility')" :disabled="channel != null">
<button class="_button visibility" @click="setVisibility" ref="visibilityButton" v-tooltip="$ts.visibility" :disabled="channel != null">
<span v-if="visibility === 'public'"><Fa :icon="faGlobe"/></span>
<span v-if="visibility === 'home'"><Fa :icon="faHome"/></span>
<span v-if="visibility === 'followers'"><Fa :icon="faUnlock"/></span>
@ -23,9 +23,9 @@
<div class="form" :class="{ fixed }">
<XNotePreview class="preview" v-if="reply" :note="reply"/>
<XNotePreview class="preview" v-if="renote" :note="renote"/>
<div class="with-quote" v-if="quoteId"><Fa icon="quote-left"/> {{ $t('quoteAttached') }}<button @click="quoteId = null"><Fa icon="times"/></button></div>
<div class="with-quote" v-if="quoteId"><Fa icon="quote-left"/> {{ $ts.quoteAttached }}<button @click="quoteId = null"><Fa icon="times"/></button></div>
<div v-if="visibility === 'specified'" class="to-specified">
<span style="margin-right: 8px;">{{ $t('recipient') }}</span>
<span style="margin-right: 8px;">{{ $ts.recipient }}</span>
<div class="visibleUsers">
<span v-for="u in visibleUsers" :key="u.id">
<MkAcct :user="u"/>
@ -34,17 +34,17 @@
<button @click="addVisibleUser" class="_buttonPrimary"><Fa :icon="faPlus" fixed-width/></button>
</div>
</div>
<input v-show="useCw" ref="cw" class="cw" v-model="cw" :placeholder="$t('annotation')" @keydown="onKeydown">
<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"></textarea>
<XPostFormAttaches class="attaches" :files="files" @updated="updateFiles" @detach="detachFile" @changeSensitive="updateFileSensitive" @changeName="updateFileName"/>
<XPollEditor v-if="poll" :poll="poll" @destroyed="poll = null" @updated="onPollUpdate"/>
<footer>
<button class="_button" @click="chooseFileFrom" v-tooltip="$t('attachFile')"><Fa :icon="faPhotoVideo"/></button>
<button class="_button" @click="togglePoll" :class="{ active: poll }" v-tooltip="$t('poll')"><Fa :icon="faPollH"/></button>
<button class="_button" @click="useCw = !useCw" :class="{ active: useCw }" v-tooltip="$t('useCw')"><Fa :icon="faEyeSlash"/></button>
<button class="_button" @click="insertMention" v-tooltip="$t('mention')"><Fa :icon="faAt"/></button>
<button class="_button" @click="insertEmoji" v-tooltip="$t('emoji')"><Fa :icon="faLaughSquint"/></button>
<button class="_button" @click="showActions" v-tooltip="$t('plugin')" v-if="postFormActions.length > 0"><Fa :icon="faPlug"/></button>
<button class="_button" @click="chooseFileFrom" v-tooltip="$ts.attachFile"><Fa :icon="faPhotoVideo"/></button>
<button class="_button" @click="togglePoll" :class="{ active: poll }" v-tooltip="$ts.poll"><Fa :icon="faPollH"/></button>
<button class="_button" @click="useCw = !useCw" :class="{ active: useCw }" v-tooltip="$ts.useCw"><Fa :icon="faEyeSlash"/></button>
<button class="_button" @click="insertMention" v-tooltip="$ts.mention"><Fa :icon="faAt"/></button>
<button class="_button" @click="insertEmoji" v-tooltip="$ts.emoji"><Fa :icon="faLaughSquint"/></button>
<button class="_button" @click="showActions" v-tooltip="$ts.plugin" v-if="postFormActions.length > 0"><Fa :icon="faPlug"/></button>
</footer>
</div>
</div>
@ -135,8 +135,8 @@ export default defineComponent({
poll: null,
useCw: false,
cw: null,
localOnly: this.$store.state.settings.rememberNoteVisibility ? this.$store.state.deviceUser.localOnly : this.$store.state.settings.defaultNoteLocalOnly,
visibility: this.$store.state.settings.rememberNoteVisibility ? this.$store.state.deviceUser.visibility : this.$store.state.settings.defaultNoteVisibility,
localOnly: this.$store.state.rememberNoteVisibility ? this.$store.state.localOnly : this.$store.state.defaultNoteLocalOnly,
visibility: this.$store.state.rememberNoteVisibility ? this.$store.state.visibility : this.$store.state.defaultNoteVisibility,
visibleUsers: [],
autocomplete: null,
draghover: false,
@ -164,19 +164,19 @@ export default defineComponent({
placeholder(): string {
if (this.renote) {
return this.$t('_postForm.quotePlaceholder');
return this.$ts._postForm.quotePlaceholder;
} else if (this.reply) {
return this.$t('_postForm.replyPlaceholder');
return this.$ts._postForm.replyPlaceholder;
} else if (this.channel) {
return this.$t('_postForm.channelPlaceholder');
return this.$ts._postForm.channelPlaceholder;
} else {
const xs = [
this.$t('_postForm._placeholders.a'),
this.$t('_postForm._placeholders.b'),
this.$t('_postForm._placeholders.c'),
this.$t('_postForm._placeholders.d'),
this.$t('_postForm._placeholders.e'),
this.$t('_postForm._placeholders.f')
this.$ts._postForm._placeholders.a,
this.$ts._postForm._placeholders.b,
this.$ts._postForm._placeholders.c,
this.$ts._postForm._placeholders.d,
this.$ts._postForm._placeholders.e,
this.$ts._postForm._placeholders.f
];
return xs[Math.floor(Math.random() * xs.length)];
}
@ -184,10 +184,10 @@ export default defineComponent({
submitText(): string {
return this.renote
? this.$t('quote')
? this.$ts.quote
: this.reply
? this.$t('reply')
: this.$t('note');
? this.$ts.reply
: this.$ts.note;
},
canPost(): boolean {
@ -198,7 +198,7 @@ export default defineComponent({
},
max(): number {
return this.$store.state.instance.meta ? this.$store.state.instance.meta.maxNoteTextLength : 1000;
return this.$instance ? this.$instance.maxNoteTextLength : 1000;
}
},
@ -223,8 +223,8 @@ export default defineComponent({
const mention = x.host ? `@${x.username}@${toASCII(x.host)}` : `@${x.username}`;
// 自分は除外
if (this.$store.state.i.username == x.username && x.host == null) continue;
if (this.$store.state.i.username == x.username && x.host == host) continue;
if (this.$i.username == x.username && x.host == null) continue;
if (this.$i.username == x.username && x.host == host) continue;
// 重複は除外
if (this.text.indexOf(`${mention} `) != -1) continue;
@ -243,12 +243,12 @@ export default defineComponent({
this.visibility = this.reply.visibility;
if (this.reply.visibility === 'specified') {
os.api('users/show', {
userIds: this.reply.visibleUserIds.filter(uid => uid !== this.$store.state.i.id && uid !== this.reply.userId)
userIds: this.reply.visibleUserIds.filter(uid => uid !== this.$i.id && uid !== this.reply.userId)
}).then(users => {
this.visibleUsers.push(...users);
});
if (this.reply.userId !== this.$store.state.i.id) {
if (this.reply.userId !== this.$i.id) {
os.api('users/show', { userId: this.reply.userId }).then(user => {
this.visibleUsers.push(user);
});
@ -262,7 +262,7 @@ export default defineComponent({
}
// keep cw when reply
if (this.$store.state.settings.keepCw && this.reply && this.reply.cw) {
if (this.$store.keepCw && this.reply && this.reply.cw) {
this.useCw = true;
this.cw = this.reply.cw;
}
@ -352,7 +352,7 @@ export default defineComponent({
},
chooseFileFrom(ev) {
selectFile(ev.currentTarget || ev.target, this.$t('attachFile'), true).then(files => {
selectFile(ev.currentTarget || ev.target, this.$ts.attachFile, true).then(files => {
for (const file of files) {
this.files.push(file);
}
@ -376,7 +376,7 @@ export default defineComponent({
},
upload(file: File, name?: string) {
os.upload(file, this.$store.state.settings.uploadFolder, name).then(res => {
os.upload(file, this.$store.state.uploadFolder, name).then(res => {
this.files.push(res);
});
},
@ -399,14 +399,14 @@ export default defineComponent({
}, {
changeVisibility: visibility => {
this.visibility = visibility;
if (this.$store.state.settings.rememberNoteVisibility) {
this.$store.commit('deviceUser/setVisibility', visibility);
if (this.$store.state.rememberNoteVisibility) {
this.$store.set('visibility', visibility);
}
},
changeLocalOnly: localOnly => {
this.localOnly = localOnly;
if (this.$store.state.settings.rememberNoteVisibility) {
this.$store.commit('deviceUser/setLocalOnly', localOnly);
if (this.$store.state.rememberNoteVisibility) {
this.$store.set('localOnly', localOnly);
}
}
}, 'closed');
@ -440,7 +440,7 @@ export default defineComponent({
const file = item.getAsFile();
const lio = file.name.lastIndexOf('.');
const ext = lio >= 0 ? file.name.slice(lio) : '';
const formatted = `${formatTimeString(new Date(file.lastModified), this.$store.state.settings.pastedFileName).replace(/{{number}}/g, `${i + 1}`)}${ext}`;
const formatted = `${formatTimeString(new Date(file.lastModified), this.$store.state.pastedFileName).replace(/{{number}}/g, `${i + 1}`)}${ext}`;
this.upload(file, formatted);
}
}
@ -452,7 +452,7 @@ export default defineComponent({
os.dialog({
type: 'info',
text: this.$t('quoteQuestion'),
text: this.$ts.quoteQuestion,
showCancelButton: true
}).then(({ canceled }) => {
if (canceled) {

View File

@ -53,7 +53,7 @@ export default defineComponent({
},
computed: {
canToggle(): boolean {
return !this.reaction.match(/@\w/) && this.$store.getters.isSignedIn;
return !this.reaction.match(/@\w/) && this.$i;
},
},
watch: {

View File

@ -25,7 +25,7 @@ export default defineComponent({
},
computed: {
isMe(): boolean {
return this.$store.getters.isSignedIn && this.$store.state.i.id === this.note.userId;
return this.$i && this.$i.id === this.note.userId;
},
},
});

View File

@ -1,5 +1,5 @@
<template>
<div class="jmgmzlwq _panel"><Fa :icon="faExclamationTriangle" style="margin-right: 8px;"/>{{ $t('remoteUserCaution') }}<a :href="href" rel="nofollow noopener" target="_blank">{{ $t('showOnRemote') }}</a></div>
<div class="jmgmzlwq _panel"><Fa :icon="faExclamationTriangle" style="margin-right: 8px;"/>{{ $ts.remoteUserCaution }}<a :href="href" rel="nofollow noopener" target="_blank">{{ $ts.showOnRemote }}</a></div>
</template>
<script lang="ts">

View File

@ -51,7 +51,7 @@ export default defineComponent({
text: '',
flag: false,
radio: 'misskey',
mfm: `Hello world! This is an @example mention. BTW you are @${this.$store.state.i.username}.\nAlso, here is ${config.url} and [example link](${config.url}). for more details, see https://example.com.\nAs you know #misskey is open-source software.`
mfm: `Hello world! This is an @example mention. BTW you are @${this.$i.username}.\nAlso, here is ${config.url} and [example link](${config.url}). for more details, see https://example.com.\nAs you know #misskey is open-source software.`
}
},

View File

@ -12,29 +12,32 @@
<nav class="nav" :class="{ iconOnly, hidden }" v-show="showing">
<div>
<button class="item _button account" @click="openAccountMenu">
<MkAvatar :user="$store.state.i" class="avatar"/><MkAcct class="text" :user="$store.state.i"/>
<MkAvatar :user="$i" class="avatar"/><MkAcct class="text" :user="$i"/>
</button>
<MkA class="item index" active-class="active" to="/" exact>
<Fa :icon="faHome" fixed-width/><span class="text">{{ $t('timeline') }}</span>
<Fa :icon="faHome" fixed-width/><span class="text">{{ $ts.timeline }}</span>
</MkA>
<template v-for="item in menu">
<div v-if="item === '-'" class="divider"></div>
<component v-else-if="menuDef[item] && (menuDef[item].show !== false)" :is="menuDef[item].to ? 'MkA' : 'button'" class="item _button" :class="item" active-class="active" v-on="menuDef[item].action ? { click: menuDef[item].action } : {}" :to="menuDef[item].to">
<Fa :icon="menuDef[item].icon" fixed-width/><span class="text">{{ $t(menuDef[item].title) }}</span>
<Fa :icon="menuDef[item].icon" fixed-width/><span class="text">{{ $ts[menuDef[item].title] }}</span>
<i v-if="menuDef[item].indicated"><Fa :icon="faCircle"/></i>
</component>
</template>
<div class="divider"></div>
<button class="item _button" :class="{ active: $route.path === '/instance' || $route.path.startsWith('/instance/') }" v-if="$store.state.i.isAdmin || $store.state.i.isModerator" @click="oepnInstanceMenu">
<Fa :icon="faServer" fixed-width/><span class="text">{{ $t('instance') }}</span>
<button class="item _button" :class="{ active: $route.path === '/instance' || $route.path.startsWith('/instance/') }" v-if="$i.isAdmin || $i.isModerator" @click="oepnInstanceMenu">
<Fa :icon="faServer" fixed-width/><span class="text">{{ $ts.instance }}</span>
</button>
<button class="item _button" @click="more">
<Fa :icon="faEllipsisH" fixed-width/><span class="text">{{ $t('more') }}</span>
<Fa :icon="faEllipsisH" fixed-width/><span class="text">{{ $ts.more }}</span>
<i v-if="otherNavItemIndicated"><Fa :icon="faCircle"/></i>
</button>
<MkA class="item" active-class="active" to="/settings">
<Fa :icon="faCog" fixed-width/><span class="text">{{ $t('settings') }}</span>
<Fa :icon="faCog" fixed-width/><span class="text">{{ $ts.settings }}</span>
</MkA>
<button class="item _button post" @click="post">
<Fa :icon="faPencilAlt" fixed-width/><span class="text">{{ $ts.note }}</span>
</button>
</div>
</nav>
</transition>
@ -49,6 +52,7 @@ import { host } from '@/config';
import { search } from '@/scripts/search';
import * as os from '@/os';
import { sidebarDef } from '@/sidebar';
import { getAccounts, addAccount, login } from '@/account';
export default defineComponent({
data() {
@ -67,7 +71,7 @@ export default defineComponent({
computed: {
menu(): string[] {
return this.$store.state.deviceUser.menu;
return this.$store.state.menu;
},
otherNavItemIndicated(): boolean {
@ -84,7 +88,7 @@ export default defineComponent({
this.showing = false;
},
'$store.state.device.sidebarDisplay'() {
'$store.reactiveState.sidebarDisplay.value'() {
this.calcViewState();
},
@ -108,19 +112,23 @@ export default defineComponent({
methods: {
calcViewState() {
this.iconOnly = (window.innerWidth <= 1279) || (this.$store.state.device.sidebarDisplay === 'icon');
this.hidden = (window.innerWidth <= 650) || (this.$store.state.device.sidebarDisplay === 'hide');
this.iconOnly = (window.innerWidth <= 1279) || (this.$store.state.sidebarDisplay === 'icon');
this.hidden = (window.innerWidth <= 650);
},
show() {
this.showing = true;
},
post() {
os.post();
},
search() {
if (this.searching) return;
os.dialog({
title: this.$t('search'),
title: this.$ts.search,
input: true
}).then(async ({ canceled, result: query }) => {
if (canceled || query == null || query === '') return;
@ -133,7 +141,8 @@ export default defineComponent({
},
async openAccountMenu(ev) {
const accounts = (await os.api('users/show', { userIds: this.$store.state.device.accounts.map(x => x.id) })).filter(x => x.id !== this.$store.state.i.id);
const storedAccounts = getAccounts();
const accounts = (await os.api('users/show', { userIds: storedAccounts.map(x => x.id) })).filter(x => x.id !== this.$i.id);
const accountItems = accounts.map(account => ({
type: 'user',
@ -143,18 +152,18 @@ export default defineComponent({
os.modalMenu([...[{
type: 'link',
text: this.$t('profile'),
to: `/@${ this.$store.state.i.username }`,
avatar: this.$store.state.i,
text: this.$ts.profile,
to: `/@${ this.$i.username }`,
avatar: this.$i,
}, null, ...accountItems, {
icon: faPlus,
text: this.$t('addAcount'),
text: this.$ts.addAcount,
action: () => {
os.modalMenu([{
text: this.$t('existingAcount'),
text: this.$ts.existingAcount,
action: () => { this.addAcount(); },
}, {
text: this.$t('createAccount'),
text: this.$ts.createAccount,
action: () => { this.createAccount(); },
}], ev.currentTarget || ev.target);
},
@ -166,57 +175,57 @@ export default defineComponent({
oepnInstanceMenu(ev) {
os.modalMenu([{
type: 'link',
text: this.$t('dashboard'),
text: this.$ts.dashboard,
to: '/instance',
icon: faTachometerAlt,
}, null, this.$store.state.i.isAdmin ? {
}, null, this.$i.isAdmin ? {
type: 'link',
text: this.$t('settings'),
text: this.$ts.settings,
to: '/instance/settings',
icon: faCog,
} : undefined, {
type: 'link',
text: this.$t('customEmojis'),
text: this.$ts.customEmojis,
to: '/instance/emojis',
icon: faLaugh,
}, {
type: 'link',
text: this.$t('users'),
text: this.$ts.users,
to: '/instance/users',
icon: faUsers,
}, {
type: 'link',
text: this.$t('files'),
text: this.$ts.files,
to: '/instance/files',
icon: faCloud,
}, {
type: 'link',
text: this.$t('jobQueue'),
text: this.$ts.jobQueue,
to: '/instance/queue',
icon: faExchangeAlt,
}, {
type: 'link',
text: this.$t('federation'),
text: this.$ts.federation,
to: '/instance/federation',
icon: faGlobe,
}, {
type: 'link',
text: this.$t('relays'),
text: this.$ts.relays,
to: '/instance/relays',
icon: faProjectDiagram,
}, {
type: 'link',
text: this.$t('announcements'),
text: this.$ts.announcements,
to: '/instance/announcements',
icon: faBroadcastTower,
}, {
type: 'link',
text: this.$t('abuseReports'),
text: this.$ts.abuseReports,
to: '/instance/abuses',
icon: faExclamationCircle,
}, {
type: 'link',
text: this.$t('logs'),
text: this.$ts.logs,
to: '/instance/logs',
icon: faStream,
}], ev.currentTarget || ev.target);
@ -230,7 +239,7 @@ export default defineComponent({
addAcount() {
os.popup(import('./signin-dialog.vue'), {}, {
done: res => {
this.$store.dispatch('addAcount', res);
addAccount(res.id, res.i);
os.success();
},
}, 'closed');
@ -239,30 +248,20 @@ export default defineComponent({
createAccount() {
os.popup(import('./signup-dialog.vue'), {}, {
done: res => {
this.$store.dispatch('addAcount', res);
addAccount(res.id, res.i);
this.switchAccountWithToken(res.i);
},
}, 'closed');
},
switchAccount(account: any) {
const token = this.$store.state.device.accounts.find((x: any) => x.id === account.id).token;
const storedAccounts = getAccounts();
const token = storedAccounts.find(x => x.id === account.id).token;
this.switchAccountWithToken(token);
},
switchAccountWithToken(token: string) {
os.waiting();
os.api('i', {}, token).then((i: any) => {
this.$store.dispatch('switchAccount', {
...i,
token: token
}).then(() => {
this.$nextTick(() => {
location.reload();
});
});
});
login(token);
},
}
});
@ -294,7 +293,7 @@ export default defineComponent({
.mvcprjjd {
$ui-font-size: 1em; // TODO: どこかに集約したい
$nav-width: 250px;
$nav-icon-only-width: 80px;
$nav-icon-only-width: 86px;
> .nav-back {
z-index: 1001;
@ -360,7 +359,6 @@ export default defineComponent({
z-index: 1001;
> div {
> .index,
> .notifications {
display: none;
}
@ -382,7 +380,6 @@ export default defineComponent({
box-sizing: border-box;
overflow: auto;
background: var(--navBg);
border-right: solid 1px var(--divider);
> .divider {
margin: 16px 0;

View File

@ -5,7 +5,7 @@
@close="$refs.dialog.close()"
@closed="$emit('closed')"
>
<template #header>{{ $t('login') }}</template>
<template #header>{{ $ts.login }}</template>
<MkSignin :auto-set="autoSet" @login="onLogin"/>
</XModalWindow>

View File

@ -4,37 +4,37 @@
<div class="avatar" :style="{ backgroundImage: user ? `url('${ user.avatarUrl }')` : null }" v-show="withAvatar"></div>
<div class="normal-signin" v-if="!totpLogin">
<MkInput v-model:value="username" type="text" pattern="^[a-zA-Z0-9_]+$" spellcheck="false" autofocus required @update:value="onUsernameChange">
<span>{{ $t('username') }}</span>
<span>{{ $ts.username }}</span>
<template #prefix>@</template>
<template #suffix>@{{ host }}</template>
</MkInput>
<MkInput v-model:value="password" type="password" :with-password-toggle="true" v-if="!user || user && !user.usePasswordLessLogin" required>
<span>{{ $t('password') }}</span>
<span>{{ $ts.password }}</span>
<template #prefix><Fa :icon="faLock"/></template>
</MkInput>
<MkButton type="submit" primary :disabled="signing" style="margin: 0 auto;">{{ signing ? $t('loggingIn') : $t('login') }}</MkButton>
<MkButton type="submit" primary :disabled="signing" style="margin: 0 auto;">{{ signing ? $ts.loggingIn : $ts.login }}</MkButton>
</div>
<div class="2fa-signin" v-if="totpLogin" :class="{ securityKeys: user && user.securityKeys }">
<div v-if="user && user.securityKeys" class="twofa-group tap-group">
<p>{{ $t('tapSecurityKey') }}</p>
<p>{{ $ts.tapSecurityKey }}</p>
<MkButton @click="queryKey" v-if="!queryingKey">
{{ $t('retry') }}
{{ $ts.retry }}
</MkButton>
</div>
<div class="or-hr" v-if="user && user.securityKeys">
<p class="or-msg">{{ $t('or') }}</p>
<p class="or-msg">{{ $ts.or }}</p>
</div>
<div class="twofa-group totp-group">
<p style="margin-bottom:0;">{{ $t('twoStepAuthentication') }}</p>
<p style="margin-bottom:0;">{{ $ts.twoStepAuthentication }}</p>
<MkInput v-model:value="password" type="password" :with-password-toggle="true" v-if="user && user.usePasswordLessLogin" required>
<span>{{ $t('password') }}</span>
<span>{{ $ts.password }}</span>
<template #prefix><Fa :icon="faLock"/></template>
</MkInput>
<MkInput v-model:value="token" type="text" pattern="^[0-9]{6}$" autocomplete="off" spellcheck="false" required>
<span>{{ $t('token') }}</span>
<span>{{ $ts.token }}</span>
<template #prefix><Fa :icon="faGavel"/></template>
</MkInput>
<MkButton type="submit" :disabled="signing" primary style="margin: 0 auto;">{{ signing ? $t('loggingIn') : $t('login') }}</MkButton>
<MkButton type="submit" :disabled="signing" primary style="margin: 0 auto;">{{ signing ? $ts.loggingIn : $ts.login }}</MkButton>
</div>
</div>
</div>
@ -56,6 +56,7 @@ import MkInput from './ui/input.vue';
import { apiUrl, host } from '@/config';
import { byteify, hexify } from '@/scripts/2fa';
import * as os from '@/os';
import { login } from '@/account';
export default defineComponent({
components: {
@ -97,7 +98,7 @@ export default defineComponent({
computed: {
meta() {
return this.$store.state.instance.meta;
return this.$instance;
},
},
@ -114,8 +115,7 @@ export default defineComponent({
onLogin(res) {
if (this.autoSet) {
localStorage.setItem('i', res.i);
location.reload();
login(res.i);
}
},
@ -153,7 +153,7 @@ export default defineComponent({
if (err === null) return;
os.dialog({
type: 'error',
text: this.$t('signinFailed')
text: this.$ts.signinFailed
});
this.signing = false;
});
@ -174,7 +174,7 @@ export default defineComponent({
}).catch(() => {
os.dialog({
type: 'error',
text: this.$t('signinFailed')
text: this.$ts.signinFailed
});
this.challengeData = null;
this.totpLogin = false;
@ -195,7 +195,7 @@ export default defineComponent({
}).catch(() => {
os.dialog({
type: 'error',
text: this.$t('loginFailed')
text: this.$ts.loginFailed
});
this.signing = false;
});

View File

@ -5,7 +5,7 @@
@close="$refs.dialog.close()"
@closed="$emit('closed')"
>
<template #header>{{ $t('signup') }}</template>
<template #header>{{ $ts.signup }}</template>
<div class="_section">
<XSignup :auto-set="autoSet" @signup="onSignup"/>

View File

@ -2,49 +2,51 @@
<form class="mk-signup" @submit.prevent="onSubmit" :autocomplete="Math.random()">
<template v-if="meta">
<MkInput v-if="meta.disableRegistration" v-model:value="invitationCode" type="text" :autocomplete="Math.random()" spellcheck="false" required>
<span>{{ $t('invitationCode') }}</span>
<span>{{ $ts.invitationCode }}</span>
<template #prefix><Fa :icon="faKey"/></template>
</MkInput>
<MkInput v-model:value="username" type="text" pattern="^[a-zA-Z0-9_]{1,20}$" :autocomplete="Math.random()" spellcheck="false" required @update:value="onChangeUsername">
<span>{{ $t('username') }}</span>
<span>{{ $ts.username }}</span>
<template #prefix>@</template>
<template #suffix>@{{ host }}</template>
<template #desc>
<span v-if="usernameState == 'wait'" style="color:#999"><Fa :icon="faSpinner" pulse fixed-width/> {{ $t('checking') }}</span>
<span v-if="usernameState == 'ok'" style="color:#3CB7B5"><Fa :icon="faCheck" fixed-width/> {{ $t('available') }}</span>
<span v-if="usernameState == 'unavailable'" style="color:#FF1161"><Fa :icon="faExclamationTriangle" fixed-width/> {{ $t('unavailable') }}</span>
<span v-if="usernameState == 'error'" style="color:#FF1161"><Fa :icon="faExclamationTriangle" fixed-width/> {{ $t('error') }}</span>
<span v-if="usernameState == 'invalid-format'" style="color:#FF1161"><Fa :icon="faExclamationTriangle" fixed-width/> {{ $t('usernameInvalidFormat') }}</span>
<span v-if="usernameState == 'min-range'" style="color:#FF1161"><Fa :icon="faExclamationTriangle" fixed-width/> {{ $t('tooShort') }}</span>
<span v-if="usernameState == 'max-range'" style="color:#FF1161"><Fa :icon="faExclamationTriangle" fixed-width/> {{ $t('tooLong') }}</span>
<span v-if="usernameState == 'wait'" style="color:#999"><Fa :icon="faSpinner" pulse fixed-width/> {{ $ts.checking }}</span>
<span v-if="usernameState == 'ok'" style="color:#3CB7B5"><Fa :icon="faCheck" fixed-width/> {{ $ts.available }}</span>
<span v-if="usernameState == 'unavailable'" style="color:#FF1161"><Fa :icon="faExclamationTriangle" fixed-width/> {{ $ts.unavailable }}</span>
<span v-if="usernameState == 'error'" style="color:#FF1161"><Fa :icon="faExclamationTriangle" fixed-width/> {{ $ts.error }}</span>
<span v-if="usernameState == 'invalid-format'" style="color:#FF1161"><Fa :icon="faExclamationTriangle" fixed-width/> {{ $ts.usernameInvalidFormat }}</span>
<span v-if="usernameState == 'min-range'" style="color:#FF1161"><Fa :icon="faExclamationTriangle" fixed-width/> {{ $ts.tooShort }}</span>
<span v-if="usernameState == 'max-range'" style="color:#FF1161"><Fa :icon="faExclamationTriangle" fixed-width/> {{ $ts.tooLong }}</span>
</template>
</MkInput>
<MkInput v-model:value="password" type="password" :autocomplete="Math.random()" required @update:value="onChangePassword">
<span>{{ $t('password') }}</span>
<span>{{ $ts.password }}</span>
<template #prefix><Fa :icon="faLock"/></template>
<template #desc>
<p v-if="passwordStrength == 'low'" style="color:#FF1161"><Fa :icon="faExclamationTriangle" fixed-width/> {{ $t('weakPassword') }}</p>
<p v-if="passwordStrength == 'medium'" style="color:#3CB7B5"><Fa :icon="faCheck" fixed-width/> {{ $t('normalPassword') }}</p>
<p v-if="passwordStrength == 'high'" style="color:#3CB7B5"><Fa :icon="faCheck" fixed-width/> {{ $t('strongPassword') }}</p>
<p v-if="passwordStrength == 'low'" style="color:#FF1161"><Fa :icon="faExclamationTriangle" fixed-width/> {{ $ts.weakPassword }}</p>
<p v-if="passwordStrength == 'medium'" style="color:#3CB7B5"><Fa :icon="faCheck" fixed-width/> {{ $ts.normalPassword }}</p>
<p v-if="passwordStrength == 'high'" style="color:#3CB7B5"><Fa :icon="faCheck" fixed-width/> {{ $ts.strongPassword }}</p>
</template>
</MkInput>
<MkInput v-model:value="retypedPassword" type="password" :autocomplete="Math.random()" required @update:value="onChangePasswordRetype">
<span>{{ $t('password') }} ({{ $t('retype') }})</span>
<span>{{ $ts.password }} ({{ $ts.retype }})</span>
<template #prefix><Fa :icon="faLock"/></template>
<template #desc>
<p v-if="passwordRetypeState == 'match'" style="color:#3CB7B5"><Fa :icon="faCheck" fixed-width/> {{ $t('passwordMatched') }}</p>
<p v-if="passwordRetypeState == 'not-match'" style="color:#FF1161"><Fa :icon="faExclamationTriangle" fixed-width/> {{ $t('passwordNotMatched') }}</p>
<p v-if="passwordRetypeState == 'match'" style="color:#3CB7B5"><Fa :icon="faCheck" fixed-width/> {{ $ts.passwordMatched }}</p>
<p v-if="passwordRetypeState == 'not-match'" style="color:#FF1161"><Fa :icon="faExclamationTriangle" fixed-width/> {{ $ts.passwordNotMatched }}</p>
</template>
</MkInput>
<label v-if="meta.tosUrl" class="tou">
<input type="checkbox" v-model="ToSAgreement">
<i18n-t keypath="agreeTo">
<a :href="meta.tosUrl" class="_link" target="_blank">{{ $t('tos') }}</a>
</i18n-t>
<I18n :src="$ts.agreeTo">
<template #0>
<a :href="meta.tosUrl" class="_link" target="_blank">{{ $ts.tos }}</a>
</template>
</I18n>
</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="grecaptcha" ref="recaptcha" v-model:value="reCaptchaResponse" :sitekey="meta.recaptchaSiteKey"/>
<MkButton type="submit" :disabled="shouldDisableSubmitting" primary>{{ $t('start') }}</MkButton>
<MkButton type="submit" :disabled="shouldDisableSubmitting" primary>{{ $ts.start }}</MkButton>
</template>
</form>
</template>
@ -59,6 +61,7 @@ import MkButton from './ui/button.vue';
import MkInput from './ui/input.vue';
import MkSwitch from './ui/switch.vue';
import * as os from '@/os';
import { login } from '@/account';
export default defineComponent({
components: {
@ -99,7 +102,7 @@ export default defineComponent({
computed: {
meta() {
return this.$store.state.instance.meta;
return this.$instance;
},
shouldDisableSubmitting(): boolean {
@ -184,8 +187,7 @@ export default defineComponent({
this.$emit('signup', res);
if (this.autoSet) {
localStorage.setItem('i', res.i);
location.reload();
login(res.i);
}
});
}).catch(() => {
@ -195,7 +197,7 @@ export default defineComponent({
os.dialog({
type: 'error',
text: this.$t('somethingHappened')
text: this.$ts.somethingHappened
});
});
}

View File

@ -1,10 +1,10 @@
<template>
<div class="wrmlmaau">
<div class="body">
<span v-if="note.isHidden" style="opacity: 0.5">({{ $t('private') }})</span>
<span v-if="note.deletedAt" style="opacity: 0.5">({{ $t('deleted') }})</span>
<span v-if="note.isHidden" style="opacity: 0.5">({{ $ts.private }})</span>
<span v-if="note.deletedAt" style="opacity: 0.5">({{ $ts.deleted }})</span>
<MkA class="reply" v-if="note.replyId" :to="`/notes/${note.replyId}`"><Fa :icon="faReply"/></MkA>
<Mfm v-if="note.text" :text="note.text" :author="note.user" :i="$store.state.i" :custom-emojis="note.emojis"/>
<Mfm v-if="note.text" :text="note.text" :author="note.user" :i="$i" :custom-emojis="note.emojis"/>
<MkA class="rp" v-if="note.renoteId" :to="`/notes/${note.renoteId}`">RN: ...</MkA>
</div>
<details v-if="note.files.length > 0">
@ -12,7 +12,7 @@
<XMediaList :media-list="note.files"/>
</details>
<details v-if="note.poll">
<summary>{{ $t('poll') }}</summary>
<summary>{{ $ts.poll }}</summary>
<XPoll :note="note"/>
</details>
</div>

View File

@ -1,5 +1,5 @@
<template>
<XNotes ref="tl" :pagination="pagination" @before="$emit('before')" @after="e => $emit('after', e)" @queue="$emit('queue', $event)"/>
<XNotes :class="{ _noGap_: !$store.state.showGapBetweenNotesInTimeline }" ref="tl" :pagination="pagination" @before="$emit('before')" @after="e => $emit('after', e)" @queue="$emit('queue', $event)"/>
</template>
<script lang="ts">
@ -51,9 +51,9 @@ export default defineComponent({
connection2: null,
pagination: null,
baseQuery: {
includeMyRenotes: this.$store.state.settings.showMyRenotes,
includeRenotedMyNotes: this.$store.state.settings.showRenotedMyNotes,
includeLocalRenotes: this.$store.state.settings.showLocalRenotes
includeMyRenotes: this.$store.state.showMyRenotes,
includeRenotedMyNotes: this.$store.state.showRenotedMyNotes,
includeLocalRenotes: this.$store.state.showLocalRenotes
},
query: {},
};
@ -66,7 +66,7 @@ export default defineComponent({
this.$emit('note');
if (this.sound) {
sound.play(note.userId === this.$store.state.i.id ? 'noteMy' : 'note');
sound.play(note.userId === this.$i.id ? 'noteMy' : 'note');
}
};

View File

@ -9,17 +9,17 @@
@closed="$emit('closed')"
@ok="ok()"
>
<template #header>{{ title || $t('generateAccessToken') }}</template>
<template #header>{{ title || $ts.generateAccessToken }}</template>
<div v-if="information" class="_section">
<MkInfo warn>{{ information }}</MkInfo>
</div>
<div class="_section">
<MkInput v-model:value="name">{{ $t('name') }}</MkInput>
<MkInput v-model:value="name">{{ $ts.name }}</MkInput>
</div>
<div class="_section">
<div style="margin-bottom: 16px;"><b>{{ $t('permission') }}</b></div>
<MkButton inline @click="disableAll">{{ $t('disableAll') }}</MkButton>
<MkButton inline @click="enableAll">{{ $t('enableAll') }}</MkButton>
<div style="margin-bottom: 16px;"><b>{{ $ts.permission }}</b></div>
<MkButton inline @click="disableAll">{{ $ts.disableAll }}</MkButton>
<MkButton inline @click="enableAll">{{ $ts.enableAll }}</MkButton>
<MkSwitch v-for="kind in (initialPermissions || kinds)" :key="kind" v-model:value="permissions[kind]">{{ $t(`_permissions.${kind}`) }}</MkSwitch>
</div>
</XModalWindow>

View File

@ -123,7 +123,7 @@ export default defineComponent({
box-shadow: none;
text-decoration: none;
background: var(--buttonBg);
border-radius: 6px;
border-radius: 8px;
overflow: hidden;
&:not(:disabled):hover {

View File

@ -1,5 +1,5 @@
<template>
<transition :name="$store.state.device.animation ? 'fade' : ''" appear>
<transition :name="$store.state.animation ? 'fade' : ''" appear>
<div class="nvlagfpb" @contextmenu.prevent.stop="() => {}">
<MkMenu :items="items" @close="$emit('closed')" class="_popup _shadow" :align="'left'"/>
</div>

View File

@ -48,7 +48,7 @@
</datalist>
<div class="suffix" ref="suffixEl"><slot name="suffix"></slot></div>
</div>
<button class="save _textButton" v-if="save && changed" @click="() => { changed = false; save(); }">{{ $t('save') }}</button>
<button class="save _textButton" v-if="save && changed" @click="() => { changed = false; save(); }">{{ $ts.save }}</button>
<div class="desc _caption"><slot name="desc"></slot></div>
</div>
</template>

View File

@ -35,7 +35,7 @@
</button>
</template>
<span v-if="_items.length === 0" class="none item">
<span>{{ $t('none') }}</span>
<span>{{ $ts.none }}</span>
</span>
</div>
</template>

View File

@ -1,10 +1,10 @@
<template>
<div class="mk-modal" v-hotkey.global="keymap" :style="{ pointerEvents: showing ? 'auto' : 'none', '--transformOrigin': transformOrigin }">
<transition :name="$store.state.device.animation ? 'modal-bg' : ''" appear>
<transition :name="$store.state.animation ? 'modal-bg' : ''" appear>
<div class="bg _modalBg" v-if="showing" @click="onBgClick"></div>
</transition>
<div class="content" :class="{ popup, fixed, top: position === 'top' }" @click.self="onBgClick" ref="content">
<transition :name="$store.state.device.animation ? popup ? 'modal-popup-content' : 'modal-content' : ''" appear @after-leave="$emit('closed')" @after-enter="childRendered">
<transition :name="$store.state.animation ? popup ? 'modal-popup-content' : 'modal-content' : ''" appear @after-leave="$emit('closed')" @after-enter="childRendered">
<slot v-if="showing"></slot>
</transition>
</div>

View File

@ -5,8 +5,8 @@
<slot name="empty"></slot>
</div>
<div class="more" v-show="more" key="_more_">
<MkButton class="button" v-appear="$store.state.device.enableInfiniteScroll ? fetchMore : null" @click="fetchMore" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }" primary>
<template v-if="!moreFetching">{{ $t('loadMore') }}</template>
<MkButton class="button" v-appear="$store.state.enableInfiniteScroll ? fetchMore : null" @click="fetchMore" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }" primary>
<template v-if="!moreFetching">{{ $ts.loadMore }}</template>
<template v-if="moreFetching"><MkLoading inline/></template>
</MkButton>
</div>

View File

@ -14,7 +14,7 @@
@blur="focused = false"
></textarea>
</div>
<button class="save _textButton" v-if="save && changed" @click="() => { changed = false; save(); }">{{ $t('save') }}</button>
<button class="save _textButton" v-if="save && changed" @click="() => { changed = false; save(); }">{{ $ts.save }}</button>
<div class="desc _caption"><slot name="desc"></slot></div>
</div>
</template>

View File

@ -1,5 +1,5 @@
<template>
<transition :name="$store.state.device.animation ? 'window' : ''" appear @after-leave="$emit('closed')">
<transition :name="$store.state.animation ? 'window' : ''" appear @after-leave="$emit('closed')">
<div class="ebkgocck" v-if="showing">
<div class="body _popup _shadow _narrow_" @mousedown="onBodyMousedown" @keydown="onKeydown">
<div class="header" @contextmenu.prevent.stop="onContextmenu">
@ -401,7 +401,6 @@ export default defineComponent({
position: relative;
z-index: 1;
flex-shrink: 0;
box-shadow: 0px 1px var(--divider);
user-select: none;
height: $height;

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