Compare commits

..

191 Commits

Author SHA1 Message Date
syuilo
e1fb4f23f0 10.81.0 2019-02-03 18:41:41 +09:00
syuilo
452fb8e496 Improve usability 2019-02-03 18:40:50 +09:00
Acid Chicken (硫酸鶏)
6758b0f133 Update Dockerfile (#4090)
* Update Dockerfile

* Fix indent
2019-02-03 18:30:47 +09:00
syuilo
35e509850f Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2019-02-03 18:17:05 +09:00
syuilo
0868c3517f Use internal logger instead of debug/console for logging
Resolve #4104
Resolve #1966
Resolve #1937
2019-02-03 18:16:57 +09:00
Acid Chicken (硫酸鶏)
1cd839215b Fix typo 2019-02-03 18:03:58 +09:00
Acid Chicken (硫酸鶏)
42be09ad33 Fix typo 2019-02-03 18:01:09 +09:00
Acid Chicken (硫酸鶏)
bcb7ee8d2a Hotfix build fails
refs: https://github.com/vuejs/vue-cli/issues/3407#issuecomment-459985313
2019-02-03 18:00:56 +09:00
syuilo
3a5867b324 Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2019-02-03 17:14:02 +09:00
syuilo
efe2a6be14 Better logging 2019-02-03 17:09:16 +09:00
Acid Chicken (硫酸鶏)
11f30b0444 Use yarn instead of npm 2019-02-03 16:57:36 +09:00
syuilo
75558add17 Better logging 2019-02-03 16:45:13 +09:00
syuilo
ca91709801 Revert "Revert "Merge pull request #4098 from syuilo/dependabot/npm_and_yarn/@fortawesome/fontawesome-svg-core-1.2.14""
This reverts commit 45b905df6a.
2019-02-03 14:55:58 +09:00
syuilo
45b905df6a Revert "Merge pull request #4098 from syuilo/dependabot/npm_and_yarn/@fortawesome/fontawesome-svg-core-1.2.14"
This reverts commit 7f6bb75f95, reversing
changes made to cefecd7903.
2019-02-03 14:49:41 +09:00
syuilo
32a0cd4b13 Display Misskey logo when misskey launched 🎨 2019-02-03 14:05:01 +09:00
syuilo
0b2571858f More logs 2019-02-03 13:52:21 +09:00
syuilo
08eb3851da Merge branches 'develop' and 'develop' of https://github.com/syuilo/misskey into develop 2019-02-03 13:51:32 +09:00
syuilo
0bd0fb9fbf Include worker information for each logs 2019-02-03 13:51:24 +09:00
syuilo
9beab05a30 Make more importance for env log 2019-02-03 13:51:00 +09:00
syuilo
3b3ef20e0a New Crowdin translations (#4105)
* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (French)

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

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

* New translations ja-JP.yml (Chinese Simplified)
2019-02-03 13:22:39 +09:00
syuilo
3441acf56c Improve usability 2019-02-03 05:06:23 +09:00
syuilo
189f9f6592 Close #4093 2019-02-03 04:50:40 +09:00
syuilo
6071fc7077 Better log 2019-02-03 04:43:43 +09:00
Acid Chicken (硫酸鶏)
2f215ea34c Use is syntax (#4079) 2019-02-03 04:31:03 +09:00
syuilo
c44c777976 Update CHANGELOG.md 2019-02-03 04:27:45 +09:00
MeiMei
7d2f0a1f31 Fix: URLプレビューのthumbnailで()を含むURLを提示されると表示できない (#4103)
* Fix: URLプレビューのthumbnailで()を含むURLを提示されると表示できない

* remove debug
2019-02-03 04:26:58 +09:00
syuilo
15eca04bc4 🎨 2019-02-03 04:20:35 +09:00
syuilo
238c6a428b [Server] Use logger for logging 2019-02-03 04:18:27 +09:00
syuilo
110eeb89f1 Clean up 2019-02-03 04:18:09 +09:00
syuilo
278e43e9ba [Server] Use logger for logging 2019-02-03 04:04:57 +09:00
syuilo
d55277e57e Better logging 2019-02-03 02:01:06 +09:00
syuilo
f53a93ea13 Better logger 2019-02-03 01:39:42 +09:00
syuilo
a3e37294e5 Better logs 2019-02-03 01:33:34 +09:00
syuilo
05baa89508 Refactoring of logger 2019-02-03 01:24:59 +09:00
syuilo
80aa45372a Better logger 2019-02-03 01:20:21 +09:00
syuilo
a91f95451a Fix logger 2019-02-03 01:07:14 +09:00
syuilo
122ef23e0f Remove unnecessary log 2019-02-03 01:04:38 +09:00
syuilo
cd9d67389a Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2019-02-03 01:01:54 +09:00
syuilo
52d6ec2138 Refatoring of logger 2019-02-03 01:01:40 +09:00
dependabot[bot]
a5725c1d04 Merge pull request #4102 from syuilo/dependabot/npm_and_yarn/gulp-imagemin-5.0.3 2019-02-02 15:59:21 +00:00
dependabot[bot]
db8ad3c035 Merge pull request #4101 from syuilo/dependabot/npm_and_yarn/vue-i18n-8.8.0 2019-02-02 15:56:02 +00:00
dependabot[bot]
a0957f2e50 Merge pull request #4100 from syuilo/dependabot/npm_and_yarn/systeminformation-3.54.0 2019-02-02 15:47:56 +00:00
dependabot[bot]
301b8f5e13 Update elasticsearch requirement from 15.3.0 to 15.3.1 (#4085)
Updates the requirements on [elasticsearch](https://github.com/elastic/elasticsearch-js) to permit the latest version.
- [Release notes](https://github.com/elastic/elasticsearch-js/releases)
- [Changelog](https://github.com/elastic/elasticsearch-js/blob/v15.3.1/docs/changelog.asciidoc)
- [Commits](https://github.com/elastic/elasticsearch-js/commits/v15.3.1)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-03 00:45:18 +09:00
dependabot[bot]
7f6bb75f95 Merge pull request #4098 from syuilo/dependabot/npm_and_yarn/@fortawesome/fontawesome-svg-core-1.2.14 2019-02-02 15:44:00 +00:00
dependabot[bot]
9be47df10e Update gulp-imagemin requirement from 4.1.0 to 5.0.3
Updates the requirements on [gulp-imagemin](https://github.com/sindresorhus/gulp-imagemin) to permit the latest version.
- [Release notes](https://github.com/sindresorhus/gulp-imagemin/releases)
- [Commits](https://github.com/sindresorhus/gulp-imagemin/commits/v5.0.3)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-02 15:40:08 +00:00
dependabot[bot]
bec014da4a Update vue-i18n requirement from 8.7.0 to 8.8.0
Updates the requirements on [vue-i18n](https://github.com/kazupon/vue-i18n) to permit the latest version.
- [Release notes](https://github.com/kazupon/vue-i18n/releases)
- [Changelog](https://github.com/kazupon/vue-i18n/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/kazupon/vue-i18n/commits/v8.8.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-02 15:39:47 +00:00
dependabot[bot]
cefecd7903 Update cafy requirement from 12.0.0 to 12.1.0 (#4099)
Updates the requirements on [cafy](https://github.com/syuilo/cafy) to permit the latest version.
- [Release notes](https://github.com/syuilo/cafy/releases)
- [Changelog](https://github.com/syuilo/cafy/blob/master/CHANGELOG.md)
- [Commits](https://github.com/syuilo/cafy/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-03 00:35:30 +09:00
dependabot[bot]
52cb043185 Update sharp requirement from 0.21.1 to 0.21.3 (#4097)
Updates the requirements on [sharp](https://github.com/lovell/sharp) to permit the latest version.
- [Release notes](https://github.com/lovell/sharp/releases)
- [Changelog](https://github.com/lovell/sharp/blob/master/docs/changelog.md)
- [Commits](https://github.com/lovell/sharp/commits/v0.21.3)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-03 00:35:03 +09:00
dependabot[bot]
3a440dd116 Update systeminformation requirement from 3.52.2 to 3.54.0
Updates the requirements on [systeminformation](https://github.com/sebhildebrandt/systeminformation) to permit the latest version.
- [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[bot] <support@dependabot.com>
2019-02-02 15:33:49 +00:00
dependabot[bot]
8ae1039c77 Update @fortawesome/fontawesome-svg-core requirement
Updates the requirements on [@fortawesome/fontawesome-svg-core](https://github.com/FortAwesome/Font-Awesome) to permit the latest version.
- [Release notes](https://github.com/FortAwesome/Font-Awesome/releases)
- [Changelog](https://github.com/FortAwesome/Font-Awesome/blob/master/CHANGELOG.md)
- [Commits](https://github.com/FortAwesome/Font-Awesome/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-02 15:30:23 +00:00
syuilo
190eb0601f New Crowdin translations (#4096)
* New translations ja-JP.yml (Catalan)

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

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Italian)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (Portuguese)

* New translations ja-JP.yml (Russian)

* New translations ja-JP.yml (Spanish)

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

* New translations ja-JP.yml (Dutch)

* New translations ja-JP.yml (Norwegian)

* New translations ja-JP.yml (English)
2019-02-03 00:15:50 +09:00
MeiMei
84931003ea Fix video thumbnails (#4095)
* Fix video thumbnails

* Fix import
2019-02-02 23:30:34 +09:00
syuilo
2b0cb6d728 [Client] Resolve #3226 2019-02-02 23:20:40 +09:00
syuilo
4ea7e711ce [Client] Improve usability
Resolve #4094
2019-02-02 22:59:11 +09:00
syuilo
2a50997a75 Fallback en-US 2019-02-02 16:16:31 +09:00
syuilo
d692d531d1 Fix indent 2019-02-02 13:57:26 +09:00
syuilo
e325410649 [Server] Remove unnecessarily property 2019-02-02 13:50:41 +09:00
syuilo
eea2b97ae5 Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2019-02-02 13:47:26 +09:00
syuilo
6b53e9ed29 [Client] Fix #4086 2019-02-02 13:47:12 +09:00
syuilo
9ae3e7bdab New translations ja-JP.yml (Chinese Simplified) (#4087) 2019-02-02 13:42:34 +09:00
syuilo
3905129eae New Crowdin translations (#4044)
* New translations ja-JP.yml (Catalan)

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

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Italian)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (Portuguese)

* New translations ja-JP.yml (Russian)

* New translations ja-JP.yml (Spanish)

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

* New translations ja-JP.yml (Dutch)

* New translations ja-JP.yml (Norwegian)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (Polish)

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

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

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

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

* New translations ja-JP.yml (Korean)

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

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

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

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

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

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

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

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

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

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

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (Catalan)

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

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Italian)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (Portuguese)

* New translations ja-JP.yml (Russian)

* New translations ja-JP.yml (Spanish)

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

* New translations ja-JP.yml (Dutch)

* New translations ja-JP.yml (Norwegian)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (English)

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

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

* New translations ja-JP.yml (Catalan)

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

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Italian)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (Portuguese)

* New translations ja-JP.yml (Russian)

* New translations ja-JP.yml (Spanish)

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

* New translations ja-JP.yml (Dutch)

* New translations ja-JP.yml (Norwegian)

* New translations ja-JP.yml (English)

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

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

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

* New translations ja-JP.yml (Chinese Simplified)
2019-02-02 13:39:48 +09:00
syuilo
6b4e417cc7 Update CHANGELOG.md 2019-02-02 13:24:41 +09:00
MeiMei
3040700005 Generate video thumbnails (#4084)
* Generate video thumbnails

* import order
2019-02-02 13:22:09 +09:00
syuilo
170b1bb4cc Downgrade webpack to avoid build error
See https://github.com/webpack/webpack/issues/8656
2019-02-02 02:00:00 +09:00
Acid Chicken (硫酸鶏)
da1a238be3 Create new type definition for 'ms' (#4057)
* Create new type definition for 'ms'

* Follow lint
2019-02-02 00:16:27 +09:00
MeiMei
9c106022ae Fix #3871 (#4082) 2019-02-01 21:37:34 +09:00
Acid Chicken (硫酸鶏)
bab1dc1d97 Create type definition for 'koa-json-body' (#4056)
* Create type definition for 'koa-json-body'

* Follow lint
2019-02-01 21:08:58 +09:00
Acid Chicken (硫酸鶏)
3b30ad5404 Create type definition for 'nested-property' (#4004)
* Create type definition for 'nested-property'

* Follow lint
2019-02-01 21:08:49 +09:00
dependabot[bot]
27268fd6b7 Update @fortawesome/free-regular-svg-icons requirement (#4076)
Updates the requirements on [@fortawesome/free-regular-svg-icons](https://github.com/FortAwesome/Font-Awesome) to permit the latest version.
- [Release notes](https://github.com/FortAwesome/Font-Awesome/releases)
- [Changelog](https://github.com/FortAwesome/Font-Awesome/blob/master/CHANGELOG.md)
- [Commits](https://github.com/FortAwesome/Font-Awesome/commits/5.7.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-01 20:03:11 +09:00
Acid Chicken (硫酸鶏)
00f9c824d1 リモートの外部サービス認証情報を表示する (#4047)
* Update user.vue

* Update ja-JP.yml

* Fix path

refs: 7e3a8d56e6

* Update user.vue

* Update ja-JP.yml

* Re-fix path

refs: 4bb4903ee5, 7e3a8d56e6

* Update user.vue

* Update ja-JP.yml

* Update ja-JP.yml

* Fix sentence a little
2019-02-01 20:02:10 +09:00
Acid Chicken (硫酸鶏)
40e177fa96 Create type definition for 'http-signature' (#4049)
* Create type definition for 'http-signature'

* Follow lint
2019-02-01 19:59:12 +09:00
Acid Chicken (硫酸鶏)
2f72c38516 Create type definition for 'deepcopy' (#4000) 2019-02-01 19:56:16 +09:00
Acid Chicken (硫酸鶏)
2dc4696b0a Module '@koa/cors' as import syntax (#4060) 2019-02-01 19:46:18 +09:00
Acid Chicken (硫酸鶏)
723d5baed5 Module 'parse5' as import syntax (#4015) 2019-02-01 19:41:13 +09:00
dependabot[bot]
341838b502 Update webpack requirement from 4.28.4 to 4.29.0 (#4077)
Updates the requirements on [webpack](https://github.com/webpack/webpack) to permit the latest version.
- [Release notes](https://github.com/webpack/webpack/releases)
- [Commits](https://github.com/webpack/webpack/commits/v4.29.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-02-01 12:17:15 +09:00
syuilo
72efa278b3 Update CHANGELOG.md 2019-02-01 10:02:02 +09:00
syuilo
5fe9f2baee Improve performance 2019-02-01 10:00:36 +09:00
MeiMei
c7ebf6f990 Hide suspended users (#4075) 2019-02-01 09:57:51 +09:00
syuilo
9bf9519b8f Fix path 2019-02-01 00:17:15 +09:00
syuilo
6c57690359 Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2019-02-01 00:09:36 +09:00
syuilo
3a03010ee2 Refactoring 2019-02-01 00:09:28 +09:00
Acid Chicken (硫酸鶏)
ba4dcc40da Create type definition for '*/meta.json' (#4073) 2019-02-01 00:00:54 +09:00
syuilo
1b0601b421 Update CHANGELOG.md 2019-01-31 23:53:20 +09:00
Acid Chicken (硫酸鶏)
e2bf0067b2 Module 'request-stats' as import syntax (#4071) 2019-01-31 23:46:15 +09:00
Acid Chicken (硫酸鶏)
6d004fde7c Module 'uuid' as import syntax (#4070) 2019-01-31 23:45:12 +09:00
Acid Chicken (硫酸鶏)
f35547f3b8 API modules as import syntax (#4069) 2019-01-31 23:32:58 +09:00
MeiMei
c34a278533 おすすめのアンケートでミュートユーザーのものは表示しない (#4067) 2019-01-31 23:14:45 +09:00
syuilo
6d3408ae73 [Client] Add information 2019-01-31 20:55:40 +09:00
MeiMei
a6e7bbc306 send/receive user hashtags via AP (#4064) 2019-01-31 20:42:45 +09:00
dependabot[bot]
d140548784 Update @types/koa-router requirement from 7.0.38 to 7.0.39 (#4052)
Updates the requirements on [@types/koa-router](https://github.com/DefinitelyTyped/DefinitelyTyped) to permit the latest version.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-31 17:54:19 +09:00
Acid Chicken (硫酸鶏)
76569bfb08 Create type definition for 'lookup-dns-cache' (#4051) 2019-01-31 17:53:49 +09:00
Acid Chicken (硫酸鶏)
bbcdf1bb8a Create type definition for 'promise-any' (#4055) 2019-01-31 17:52:27 +09:00
Acid Chicken (硫酸鶏)
6439a6c63f Create type definition for 'webfinger.js' (#4054) 2019-01-31 17:52:17 +09:00
dependabot[bot]
76fe1c21c3 Update gulp-yaml requirement from 2.0.2 to 2.0.3 (#4053)
Updates the requirements on [gulp-yaml](https://github.com/crissdev/gulp-yaml) to permit the latest version.
- [Release notes](https://github.com/crissdev/gulp-yaml/releases)
- [Changelog](https://github.com/crissdev/gulp-yaml/blob/master/CHANGELOG.md)
- [Commits](https://github.com/crissdev/gulp-yaml/commits/2.0.3)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-31 17:46:42 +09:00
syuilo
4f99b98ed8 Revert b515cc90e9 2019-01-31 17:42:36 +09:00
syuilo
7cb38f5525 Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2019-01-31 17:38:24 +09:00
syuilo
734277d9f6 [Server] Resolve #4062 2019-01-31 17:37:57 +09:00
Acid Chicken (硫酸鶏)
960d4e2e7b Close #3380 (#4061)
* Delete index.ts

* Delete emoji.ts

* Update index.ts
2019-01-31 17:30:56 +09:00
syuilo
33eb91c0f0 [Test] Disable some tests temporary 2019-01-31 17:15:14 +09:00
syuilo
6f1e47f0b3 [Test] Better tests 2019-01-31 15:19:59 +09:00
syuilo
0a8488a78c Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2019-01-31 15:10:33 +09:00
syuilo
57ab640221 Fix typo 2019-01-31 15:10:27 +09:00
Acid Chicken (硫酸鶏)
3c4682782c Add 'src/@types' to typeRoots 2019-01-31 14:40:06 +09:00
syuilo
dc820ffba6 Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2019-01-31 14:31:31 +09:00
syuilo
e4c745bccd [Test] Add MFM test 2019-01-31 14:31:25 +09:00
Acid Chicken (硫酸鶏)
a05c94437c Make type definition for 'is-root' better 2019-01-31 13:42:13 +09:00
syuilo
fdcc994291 10.80.0 2019-01-31 12:27:44 +09:00
syuilo
f54363076c Update CHANGELOG.md 2019-01-31 12:26:56 +09:00
syuilo
ec016e5a95 🎨 2019-01-31 12:24:21 +09:00
syuilo
bbdb2496a4 [Client] MFMの制限を緩和 2019-01-31 12:24:14 +09:00
syuilo
b515cc90e9 [MFM] Better syntax parsing
Allow nesting by same tag
2019-01-31 12:23:45 +09:00
syuilo
bb92158dff [MFM] Make some syntax block
Resolve #3508
2019-01-31 12:10:48 +09:00
Aya Morisawa
c652add16a Simplify MFM (#4046) 2019-01-31 12:06:13 +09:00
MeiMei
b8a7468c4a Do not import as pack from AP renderer (#4048)
* Do not import as pack from AP renderer

* rename
2019-01-31 02:29:35 +09:00
Acid Chicken (硫酸鶏)
e220ef3e75 Re-fix path
refs: 4bb4903ee5, 7e3a8d56e6
2019-01-31 01:38:52 +09:00
Acid Chicken (硫酸鶏)
4bb4903ee5 Fix path
refs: 7e3a8d56e6
2019-01-31 01:26:11 +09:00
Acid Chicken (硫酸鶏)
9487840ae3 Create type definition for 'is-root' (#4001)
* Update @types/sharp requirement from 0.21.0 to 0.21.1

Updates the requirements on [@types/sharp](https://github.com/DefinitelyTyped/DefinitelyTyped) to permit the latest version.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits)

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

* Add multiline math syntax

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

* New translations ja-JP.yml (Catalan)

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

* New translations ja-JP.yml (English)

* New translations ja-JP.yml (French)

* New translations ja-JP.yml (German)

* New translations ja-JP.yml (Italian)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Polish)

* New translations ja-JP.yml (Portuguese)

* New translations ja-JP.yml (Russian)

* New translations ja-JP.yml (Spanish)

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

* New translations ja-JP.yml (Dutch)

* New translations ja-JP.yml (Norwegian)

* New translations ja-JP.yml (English)

* Create type definition for 'is-root'

* [MFM] Add spin syntax

Resolve #4003

* [MFM] Add flip syntax

Resolve #4002

* Fix test

* Update CHANGELOG.md

* 10.79.0

* Update @fortawesome/free-regular-svg-icons requirement (#3963)

Updates the requirements on [@fortawesome/free-regular-svg-icons](https://github.com/FortAwesome/Font-Awesome) to permit the latest version.
- [Release notes](https://github.com/FortAwesome/Font-Awesome/releases)
- [Changelog](https://github.com/FortAwesome/Font-Awesome/blob/master/CHANGELOG.md)
- [Commits](https://github.com/FortAwesome/Font-Awesome/commits/5.6.3)

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

* Update @types/webpack requirement from 4.4.21 to 4.4.24 (#3976)

Updates the requirements on [@types/webpack](https://github.com/DefinitelyTyped/DefinitelyTyped) to permit the latest version.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits)

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

* Update @types/js-yaml requirement from 3.11.4 to 3.12.0 (#3977)

Updates the requirements on [@types/js-yaml](https://github.com/DefinitelyTyped/DefinitelyTyped) to permit the latest version.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits)

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

* Update debug requirement from 4.1.0 to 4.1.1 (#3964)

Updates the requirements on [debug](https://github.com/visionmedia/debug) to permit the latest version.
- [Release notes](https://github.com/visionmedia/debug/releases)
- [Commits](https://github.com/visionmedia/debug/commits/4.1.1)

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

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (Korean)

* New translations ja-JP.yml (French)

* [MFM] spinの中でflipを使えるように

* Add jump syntax (#4007)

* Add jump syntax

* Fix typo: spin -> jump

* Fix typo

* [MFM] Resolve #4009

* Module 'nprogress' as import syntax (#4012)

* 🎨

* [Client] Fix #4008

* Use yarn instead of npm on CircleCI

* touch yarn.lock

* [Client] Resolve #3638

* 10.79.1

* New translations ja-JP.yml (Korean)

* Add missing semicolon

* Remove file-loader from dependencies (#4025)

* Update README.md [AUTOGEN] (#4028)

* Update README.md [AUTOGEN] (#4030)

* Add visibility test (#4029)

* Update ws requirement from 6.1.2 to 6.1.3 (#4027)

Updates the requirements on [ws](https://github.com/websockets/ws) to permit the latest version.
- [Release notes](https://github.com/websockets/ws/releases)
- [Commits](https://github.com/websockets/ws/commits/6.1.3)

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

* Module 'web-push' as import syntax (#4017)

* Fix visibility test (#4031)

* Upgrade gulp version to 4.0.0

* Prevent typescript errors from crashing

* Remove duplicated dependencies

* Use parallel and task to specify dependencies

* Sort tasks by topological ordering

* リプライ/メンションされていれば非フォロワーへのフォロワー限定でも参照可能に (#4033)

* 非メンション/リプライ投稿がmentionsにあるかどうかはvisibilityと関係ないので削除

* リプライ/メンションされていれば非フォロワーでも参照可能に

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

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

* Fix #4034 (#4037)

* Fix #4034

* improve

* Module 'crypto' as import syntax (#4011)

* Extract MFM normalize function

* Extract MFM types

* Rename html to toHtml

* Rename html-to-mfm to fromHtml

* Merge plainParser into mfm

* Extract parsePlain function

* Rename analyze to parse in MFM tests

* Update @types/mongodb requirement from 3.1.18 to 3.1.19 (#4041)

Updates the requirements on [@types/mongodb](https://github.com/DefinitelyTyped/DefinitelyTyped) to permit the latest version.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits)

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

* Update vue-svg-inline-loader requirement from 1.2.7 to 1.2.10 (#4040)

Updates the requirements on [vue-svg-inline-loader](https://github.com/oliverfindl/vue-svg-inline-loader) to permit the latest version.
- [Release notes](https://github.com/oliverfindl/vue-svg-inline-loader/releases)
- [Commits](https://github.com/oliverfindl/vue-svg-inline-loader/commits/v1.2.10)

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

* Avoid export default

* Rename parser to language

* Fix import

* Introduce silence (#4043)

* Introduce silence

* Fix icon

* Update is-root.d.ts

* Update index.ts

* Create type definition for 'is-root'

* Update is-root.d.ts

* Update index.ts
2019-01-31 01:09:52 +09:00
Acid Chicken (硫酸鶏)
7e3a8d56e6 Update index.ts 2019-01-31 01:09:36 +09:00
Acid Chicken (硫酸鶏)
e909eac296 Create type definition for '*/package.json' (#4014)
* Create type definition for '*/package.json'

* Update tsconfig.json
2019-01-31 01:08:43 +09:00
syuilo
8dc7f28744 [ActivityPub] Use microformats on mentions
To avoid pointless link previews.
see: https://misskey.xyz/notes/5c51ab5c2d85f2003248eddc
2019-01-30 22:57:32 +09:00
syuilo
a4b1e8ca26 Update CHANGELOG.md 2019-01-30 22:44:36 +09:00
MeiMei
79b0cc6785 delete unnecessary key (#4045)
* delete unnecessary key

* Add note
2019-01-30 21:31:45 +09:00
syuilo
00b134ce1e Introduce silence (#4043)
* Introduce silence

* Fix icon
2019-01-30 17:25:56 +09:00
Aya Morisawa
b3fc4dc00f Fix import 2019-01-30 17:15:12 +09:00
Aya Morisawa
d06fbbe3ea Rename parser to language 2019-01-30 17:04:49 +09:00
Aya Morisawa
28bfb45426 Avoid export default 2019-01-30 16:56:27 +09:00
dependabot[bot]
1c60a49c96 Update vue-svg-inline-loader requirement from 1.2.7 to 1.2.10 (#4040)
Updates the requirements on [vue-svg-inline-loader](https://github.com/oliverfindl/vue-svg-inline-loader) to permit the latest version.
- [Release notes](https://github.com/oliverfindl/vue-svg-inline-loader/releases)
- [Commits](https://github.com/oliverfindl/vue-svg-inline-loader/commits/v1.2.10)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-30 16:06:45 +09:00
dependabot[bot]
3ae8ff083b Update @types/mongodb requirement from 3.1.18 to 3.1.19 (#4041)
Updates the requirements on [@types/mongodb](https://github.com/DefinitelyTyped/DefinitelyTyped) to permit the latest version.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-30 16:06:28 +09:00
Aya Morisawa
c12ccb2a15 Rename analyze to parse in MFM tests 2019-01-30 15:30:05 +09:00
Aya Morisawa
e3b1d00e4c Extract parsePlain function 2019-01-30 15:27:54 +09:00
Aya Morisawa
98795aad9a Merge plainParser into mfm 2019-01-30 15:12:48 +09:00
Aya Morisawa
ca26edbfce Rename html-to-mfm to fromHtml 2019-01-30 15:00:05 +09:00
Aya Morisawa
3058e8f354 Rename html to toHtml 2019-01-30 14:57:13 +09:00
Aya Morisawa
4c9b66b0f0 Extract MFM types 2019-01-30 14:51:30 +09:00
Aya Morisawa
6eb9ba31bf Extract MFM normalize function 2019-01-30 14:21:36 +09:00
Acid Chicken (硫酸鶏)
5bbf4187e6 Module 'crypto' as import syntax (#4011) 2019-01-30 11:51:29 +09:00
syuilo
f2425f71c2 Merge pull request #4020 from syuilo/l10n_develop
New Crowdin translations
2019-01-30 11:50:55 +09:00
MeiMei
b0e00da2f7 Fix #4034 (#4037)
* Fix #4034

* improve
2019-01-29 20:33:28 +09:00
syuilo
215472cd17 New translations ja-JP.yml (Chinese Simplified) 2019-01-29 18:33:13 +09:00
syuilo
072fd4455e New translations ja-JP.yml (Chinese Simplified) 2019-01-29 18:22:34 +09:00
MeiMei
2ed9e26a4f リプライ/メンションされていれば非フォロワーへのフォロワー限定でも参照可能に (#4033)
* 非メンション/リプライ投稿がmentionsにあるかどうかはvisibilityと関係ないので削除

* リプライ/メンションされていれば非フォロワーでも参照可能に
2019-01-29 17:34:43 +09:00
Aya Morisawa
8a3e26cdb8 Sort tasks by topological ordering 2019-01-29 17:10:16 +09:00
Aya Morisawa
7301671962 Use parallel and task to specify dependencies 2019-01-29 17:10:16 +09:00
Aya Morisawa
0d0f25818e Remove duplicated dependencies 2019-01-29 17:10:16 +09:00
Aya Morisawa
7850d68dc2 Prevent typescript errors from crashing 2019-01-29 17:10:16 +09:00
Aya Morisawa
f0f5b32300 Upgrade gulp version to 4.0.0 2019-01-29 17:10:16 +09:00
MeiMei
1ca0976e85 Fix visibility test (#4031) 2019-01-29 15:16:11 +09:00
Acid Chicken (硫酸鶏)
7fbfd17896 Module 'web-push' as import syntax (#4017) 2019-01-29 14:36:24 +09:00
dependabot[bot]
3d04f7db62 Update ws requirement from 6.1.2 to 6.1.3 (#4027)
Updates the requirements on [ws](https://github.com/websockets/ws) to permit the latest version.
- [Release notes](https://github.com/websockets/ws/releases)
- [Commits](https://github.com/websockets/ws/commits/6.1.3)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-29 14:35:34 +09:00
MeiMei
e301630c9d Add visibility test (#4029) 2019-01-29 13:46:24 +09:00
Acid Chicken (硫酸鶏)
afbccaae41 Update README.md [AUTOGEN] (#4030) 2019-01-29 13:42:28 +09:00
Acid Chicken (硫酸鶏)
893c01c207 Update README.md [AUTOGEN] (#4028) 2019-01-29 05:55:21 +09:00
Aya Morisawa
41c80097ce Remove file-loader from dependencies (#4025) 2019-01-28 18:04:30 +09:00
Aya Morisawa
250933fff3 Add missing semicolon 2019-01-28 17:49:20 +09:00
syuilo
bc9454f67c New translations ja-JP.yml (Korean) 2019-01-28 00:51:55 +09:00
syuilo
377a7fdf3e 10.79.1 2019-01-27 23:25:20 +09:00
syuilo
645f661911 [Client] Resolve #3638 2019-01-27 22:04:50 +09:00
Acid Chicken (硫酸鶏)
db7c83c8ff touch yarn.lock 2019-01-27 20:19:24 +09:00
Acid Chicken (硫酸鶏)
97385db5b5 Use yarn instead of npm on CircleCI 2019-01-27 20:13:06 +09:00
syuilo
c69d57a064 Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2019-01-27 20:09:03 +09:00
syuilo
a488d6e2d6 [Client] Fix #4008 2019-01-27 20:05:03 +09:00
syuilo
85e8b1fbf4 🎨 2019-01-27 20:03:58 +09:00
Acid Chicken (硫酸鶏)
78763116c3 Module 'nprogress' as import syntax (#4012) 2019-01-27 19:41:41 +09:00
syuilo
103fe8b91d [MFM] Resolve #4009 2019-01-27 19:32:35 +09:00
syuilo
311e67047d Merge pull request #3998 from syuilo/l10n_develop
New Crowdin translations
2019-01-27 19:14:49 +09:00
Aya Morisawa
62d41023e1 Add jump syntax (#4007)
* Add jump syntax

* Fix typo: spin -> jump

* Fix typo
2019-01-27 19:12:45 +09:00
syuilo
5fac7c1718 [MFM] spinの中でflipを使えるように 2019-01-27 19:12:08 +09:00
syuilo
ade01139ca New translations ja-JP.yml (French) 2019-01-27 17:54:13 +09:00
syuilo
5ea8e9c787 New translations ja-JP.yml (Korean) 2019-01-27 17:01:41 +09:00
syuilo
e5cfdbf372 New translations ja-JP.yml (Korean) 2019-01-27 16:51:42 +09:00
dependabot[bot]
d2cc5c3b63 Update debug requirement from 4.1.0 to 4.1.1 (#3964)
Updates the requirements on [debug](https://github.com/visionmedia/debug) to permit the latest version.
- [Release notes](https://github.com/visionmedia/debug/releases)
- [Commits](https://github.com/visionmedia/debug/commits/4.1.1)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-27 16:46:41 +09:00
Aya Morisawa
7cdd90db09 Update @types/sharp requirement from 0.21.0 to 0.21.1 (#3982)
Updates the requirements on [@types/sharp](https://github.com/DefinitelyTyped/DefinitelyTyped) to permit the latest version.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-27 16:46:11 +09:00
dependabot[bot]
aad1b8c12e Update @types/js-yaml requirement from 3.11.4 to 3.12.0 (#3977)
Updates the requirements on [@types/js-yaml](https://github.com/DefinitelyTyped/DefinitelyTyped) to permit the latest version.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-27 16:45:55 +09:00
dependabot[bot]
2519abdd39 Update @types/webpack requirement from 4.4.21 to 4.4.24 (#3976)
Updates the requirements on [@types/webpack](https://github.com/DefinitelyTyped/DefinitelyTyped) to permit the latest version.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-27 16:45:48 +09:00
dependabot[bot]
e8d0568a11 Update @fortawesome/free-regular-svg-icons requirement (#3963)
Updates the requirements on [@fortawesome/free-regular-svg-icons](https://github.com/FortAwesome/Font-Awesome) to permit the latest version.
- [Release notes](https://github.com/FortAwesome/Font-Awesome/releases)
- [Changelog](https://github.com/FortAwesome/Font-Awesome/blob/master/CHANGELOG.md)
- [Commits](https://github.com/FortAwesome/Font-Awesome/commits/5.6.3)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-27 16:45:36 +09:00
syuilo
5621113d1f New translations ja-JP.yml (English) 2019-01-27 15:02:03 +09:00
syuilo
e4c0c8869e New translations ja-JP.yml (Norwegian) 2019-01-27 13:33:03 +09:00
syuilo
405f98d6d1 New translations ja-JP.yml (Dutch) 2019-01-27 13:32:58 +09:00
syuilo
870ab3d3b6 New translations ja-JP.yml (Japanese, Kansai) 2019-01-27 13:32:54 +09:00
syuilo
9ac2913afc New translations ja-JP.yml (Spanish) 2019-01-27 13:32:50 +09:00
syuilo
171651484a New translations ja-JP.yml (Russian) 2019-01-27 13:32:45 +09:00
syuilo
bfadb4026d New translations ja-JP.yml (Portuguese) 2019-01-27 13:32:40 +09:00
syuilo
3940a9a447 New translations ja-JP.yml (Polish) 2019-01-27 13:32:34 +09:00
syuilo
714446fb46 New translations ja-JP.yml (Korean) 2019-01-27 13:32:27 +09:00
syuilo
e806f33f9f New translations ja-JP.yml (Italian) 2019-01-27 13:32:23 +09:00
syuilo
65ee1711e5 New translations ja-JP.yml (German) 2019-01-27 13:32:16 +09:00
syuilo
ef92578555 New translations ja-JP.yml (French) 2019-01-27 13:32:11 +09:00
syuilo
0352fd0acd New translations ja-JP.yml (English) 2019-01-27 13:32:07 +09:00
syuilo
fffce73d3e New translations ja-JP.yml (Chinese Simplified) 2019-01-27 13:32:03 +09:00
syuilo
717f66b4a6 New translations ja-JP.yml (Catalan) 2019-01-27 13:31:58 +09:00
dependabot[bot]
7017d3ae07 Update @types/sharp requirement from 0.21.0 to 0.21.1
Updates the requirements on [@types/sharp](https://github.com/DefinitelyTyped/DefinitelyTyped) to permit the latest version.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-01-24 20:28:05 +00:00
197 changed files with 2692 additions and 1604 deletions

View File

@@ -30,22 +30,21 @@ jobs:
steps:
- checkout
- run:
name: Ensure package-lock.json
name: Ensure yarn.lock
command: |
[ ! -e package-lock.json ] && echo '{}' > package-lock.json
touch yarn.lock
- restore_cache:
name: Restore npm package caches
keys:
- npm-v1-arch-{{ arch }}-env-{{ .Environment.variableName }}-package-{{ checksum "package.json" }}-lock-{{ checksum "package-lock.json" }}-
- npm-v1-arch-{{ arch }}-env-{{ .Environment.variableName }}-package-{{ checksum "package.json" }}-
- npm-v1-arch-{{ arch }}-env-{{ .Environment.variableName }}-
- npm-v1-arch-{{ arch }}-
- npm-v1-
- yarn-v1-arch-{{ arch }}-env-{{ .Environment.variableName }}-package-{{ checksum "package.json" }}-lock-{{ checksum "yarn.lock" }}
- yarn-v1-arch-{{ arch }}-env-{{ .Environment.variableName }}-package-{{ checksum "package.json" }}-
- yarn-v1-arch-{{ arch }}-env-{{ .Environment.variableName }}-
- yarn-v1-arch-{{ arch }}-
- yarn-v1-
- run:
name: Install Dependencies
command: |
npm install
npm prune
yarn install
- run:
name: Configure
command: |
@@ -54,13 +53,11 @@ jobs:
- run:
name: Build
command: |
node-gyp configure
node-gyp build
npm run build || (echo -e '\033[0;34mRebuild modules\033[0;39m' && ls -1A node_modules | grep '^[^@]' | xargs npm rebuild && ls -1A node_modules | grep '^@' | xargs -I%1 sh -c 'ls -1A node_modules/'%1' | xargs -P0 -I%2 npm rebuild node_modules/'%1'/%2' && npm run build)
ls -1ARl node_modules > ls
yarn build
touch yarn.lock
- save_cache:
name: Cache npm packages
key: npm-v1-arch-{{ arch }}-env-{{ .Environment.variableName }}-package-{{ checksum "package.json" }}-lock-{{ checksum "package-lock.json" }}-ls-{{ checksum "ls" }}
key: yarn-v1-arch-{{ arch }}-env-{{ .Environment.variableName }}-package-{{ checksum "package.json" }}-lock-{{ checksum "yarn.lock" }}
paths:
- node_modules
# - store_artifacts:
@@ -90,11 +87,11 @@ jobs:
- run:
name: Test
command: |
npm run test
ls -1ARl node_modules > ls
yarn test
touch yarn.lock
- save_cache:
name: Cache npm packages
key: npm-v1-arch-{{ arch }}-env-{{ .Environment.variableName }}-package-{{ checksum "package.json" }}-lock-{{ checksum "package-lock.json" }}-ls-{{ checksum "ls" }}
key: yarn-v1-arch-{{ arch }}-env-{{ .Environment.variableName }}-package-{{ checksum "package.json" }}-lock-{{ checksum "yarn.lock" }}
paths:
- node_modules

View File

@@ -1,6 +1,34 @@
ChangeLog
=========
10.81.0
----------
* 動画のサムネイルを作成するように
* リモートの外部サービス認証情報を表示するように
* public の Renote/Reply/Quote先 が public以外 だったら、public => homeに
* ユーザーページから管理者/モデレーターがアカウントのサイレンス/凍結をできるように
* 凍結されたユーザーをタイムライン等に表示しないように
* おすすめのアンケートでミュートユーザーのものは表示しないように
* おすすめのアンケートで凍結済みユーザーのものは表示しないように
* 画像でないファイルのサムネイルとしてオリジナルファイルを返してしまうのを修正
* URLプレビューのサムネイルが表示されない場合がある問題を修正
* ダークモードで読みにくいボタンがあるのを修正
10.80.0
----------
* サイレンス機能の追加
* リプライ/メンションされていれば非フォロワーへのフォロワー限定でも参照可能に
* MFMの解析を強化
* Misskey以外のインスタンスからMisskeyの投稿を見たときに改行が多い問題を修正
* Misskey以外のインスタンスからMisskeyの投稿を見たときにメンションのURLが展開されるのを修正
10.79.1
----------
* jump構文の追加
* MFMで左回転、往復回転を行えるように
* MFMに関する制限を若干緩和
* シンタックスハイライトに関するバグ修正
10.79.0
----------
* 返信するときにCWを維持するかどうか設定できるように

View File

@@ -12,6 +12,7 @@ RUN unlink /usr/bin/free
RUN apk add --no-cache \
autoconf \
automake \
ffmpeg \
file \
g++ \
gcc \

View File

@@ -93,6 +93,7 @@ Please see the [Contribution Guide](./CONTRIBUTING.md).
<td><img src="https://c8.patreon.com/2/200/12059069" alt="naga_rus" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/12731202/0995c46cdcb54153ab5f073f5869b70a/1?token-time=2145916800&token-hash=prtYqPOiSHBulhM7NU0VzMaWx39-9ntdq25b6kafDNA%3D" alt="negao" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/12913507/f7181eacafe8469a93033d85f5969c29/3?token-time=2145916800&token-hash=c8HeVqLtmdgH-gSBJg8i10gmOcwllM87MDHeznl3el0%3D" alt="Melilot" width="100"></td>
<td><img src="https://c8.patreon.com/2/200/16869916" alt="見当かなみ" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/12999811/5f349fafcce44dd1824a8b1ebbec4564/3?token-time=2145916800&token-hash=LtV2lRi3L2jOWMLwccr9qWYfPrFlzIo2jYZHKzHEb6k%3D" alt="Xeltica" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/3384329/8b713330cb27404ea6e9fac50ff96efe/1?token-time=2145916800&token-hash=Ch3iF81ZGP0LMo894Y9ajpLisgtE91SnxtZE7fxsgrM%3D" alt="べすれい" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/12021162/963128bb8d14476dbd8407943db8f31a/1?token-time=2145916800&token-hash=1FlxS9MEgmNGH_RHUVHbO5hIXB5I1z0lvA33CTvYvjA%3D" alt="gutfuckllc" width="100"></td>
@@ -101,6 +102,7 @@ Please see the [Contribution Guide](./CONTRIBUTING.md).
<td><a href="https://www.patreon.com/user?u=12059069">naga_rus</a></td>
<td><a href="https://www.patreon.com/negao">negao</a></td>
<td><a href="https://www.patreon.com/user?u=12913507">Melilot</a></td>
<td><a href="https://www.patreon.com/user?u=16869916">見当かなみ</a></td>
<td><a href="https://www.patreon.com/Xeltica">Xeltica</a></td>
<td><a href="https://www.patreon.com/user?u=3384329">べすれい</a></td>
<td><a href="https://www.patreon.com/gutfuckllc">gutfuckllc</a></td>
@@ -114,7 +116,6 @@ Please see the [Contribution Guide](./CONTRIBUTING.md).
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/8241184/39e18850e87a449e9c9a71acb3310ebd/3?token-time=2145916800&token-hash=gMq30aylxu5v3G8pRhWR5jeRBbYWEoRKjGbNeiCQz5g%3D" alt="Acid Chicken" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/4389829/9f709180ac714651a70f74a82f3ffdb9/2?token-time=2145916800&token-hash=zcwFxb2zopzWwksKVU1YpfAEjsl4yKT02aQ6yiAFRiQ%3D" alt="natalie" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/13034746/c711c7f58e204ecfbc2fd646bc8a4eee/1?token-time=2145916800&token-hash=5T8XcaAf9Zyzfg3QubR06s_kJZkArVEM2dwObrBVAU4%3D" alt="Hiratake" width="100"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/10789744/97175095d8f04c0f86225ff47cb98d40/1?token-time=2145916800&token-hash=ubVARikVOg3v7NW6LDhtG-ClE1LTU3I2TJ3js2-5xDs%3D" alt="Naoki Hirayama" width="100"></td>
</tr><tr>
<td><a href="https://www.patreon.com/mydarkstar">mydarkstar</a></td>
<td><a href="https://www.patreon.com/user?u=12718187">Peter G.</a></td>
@@ -124,7 +125,6 @@ Please see the [Contribution Guide](./CONTRIBUTING.md).
<td><a href="https://www.patreon.com/acid_chicken">Acid Chicken</a></td>
<td><a href="https://www.patreon.com/user?u=4389829">natalie</a></td>
<td><a href="https://www.patreon.com/hiratake">Hiratake</a></td>
<td><a href="https://www.patreon.com/spinlock">Naoki Hirayama</a></td>
</tr></table>
<table><tr>
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/4503830/ccf2cc867ea64de0b524bb2e24b9a1cb/1?token-time=2145916800&token-hash=Ksk_2l3gjPDbnzMUOCSW1E-hdPJsNs2tSR4_RAakRK8%3D" alt="dansup" width="100"></td>
@@ -138,7 +138,7 @@ Please see the [Contribution Guide](./CONTRIBUTING.md).
<td><a href="https://www.patreon.com/user?u=12531784">Takashi Shibuya</a></td>
</tr></table>
**Last updated:** Mon, 21 Jan 2019 06:45:06 UTC
**Last updated:** Tue, 29 Jan 2019 04:42:06 UTC
<!-- PATREON_END -->
:four_leaf_clover: Copyright

View File

@@ -35,9 +35,8 @@ Please install and setup these softwares:
As root:
1. `mongo` Go to the mongo shell
2. `use misskey` Use the misskey database
3. `db.users.save( {dummy:"dummy"} )` Write dummy data to initialize the db.
4. `db.createUser( { user: "misskey", pwd: "<password>", roles: [ { role: "readWrite", db: "misskey" } ] } )` Create the misskey user.
5. `exit` You're done !
3. `db.createUser( { user: "misskey", pwd: "<password>", roles: [ { role: "readWrite", db: "misskey" } ] } )` Create the misskey user.
4. `exit` You're done!
*4.* Install Misskey
----------------------------------------------------------------

View File

@@ -35,9 +35,8 @@ Installez les paquets suivants :
En root :
1. `mongo` Ouvrez le shell mongo
2. `use misskey` Utilisez la base de données misskey
3. `db.users.save( {dummy:"dummy"} )` Écrivez une donnée factice pour initialiser la base de données.
4. `db.createUser( { user: "misskey", pwd: "<password>", roles: [ { role: "readWrite", db: "misskey" } ] } )` Créez l'utilisateur misskey.
5. `exit` Vous avez terminé !
3. `db.createUser( { user: "misskey", pwd: "<password>", roles: [ { role: "readWrite", db: "misskey" } ] } )` Créez l'utilisateur misskey.
4. `exit` Vous avez terminé !
*4.* Installation de Misskey
----------------------------------------------------------------

View File

@@ -41,9 +41,8 @@ adduser --disabled-password --disabled-login misskey
ルートで:
1. `mongo` mongoシェルを起動
2. `use misskey` misskeyデータベースを使用
3. `db.users.save( {dummy:"dummy"} )` ダミーデータを書き込みDBを初期化
4. `db.createUser( { user: "misskey", pwd: "<password>", roles: [ { role: "readWrite", db: "misskey" } ] } )` misskeyユーザーを作成
5. `exit` mongoシェルを終了
3. `db.createUser( { user: "misskey", pwd: "<password>", roles: [ { role: "readWrite", db: "misskey" } ] } )` misskeyユーザーを作成
4. `exit` mongoシェルを終了
*4.* Misskeyのインストール
----------------------------------------------------------------

View File

@@ -32,14 +32,6 @@ if (isDebug) {
console.warn(chalk.yellow.bold(' built script will not be compressed.'));
}
gulp.task('build', [
'build:ts',
'build:copy',
'build:client',
'locales',
'doc'
]);
gulp.task('build:ts', () => {
const tsProject = ts.createProject('./tsconfig.json');
@@ -47,6 +39,7 @@ gulp.task('build:ts', () => {
.src()
.pipe(sourcemaps.init())
.pipe(tsProject())
.on('error', () => {})
.pipe(sourcemaps.write('.', { includeContent: false, sourceRoot: '../built' }))
.pipe(gulp.dest('./built/'));
});
@@ -55,7 +48,7 @@ gulp.task('build:copy:views', () =>
gulp.src('./src/server/web/views/**/*').pipe(gulp.dest('./built/server/web/views'))
);
gulp.task('build:copy', ['build:copy:views'], () =>
gulp.task('build:copy', gulp.parallel('build:copy:views', () =>
gulp.src([
'./build/Release/crypto_key.node',
'./src/const.json',
@@ -63,9 +56,7 @@ gulp.task('build:copy', ['build:copy:views'], () =>
'./src/**/assets/**/*',
'!./src/client/app/**/assets/**/*'
]).pipe(gulp.dest('./built/'))
);
gulp.task('test', ['mocha']);
));
gulp.task('lint', () =>
gulp.src('./src/**/*.ts')
@@ -92,22 +83,15 @@ gulp.task('mocha', () =>
} as any))
);
gulp.task('test', gulp.task('mocha'));
gulp.task('clean', cb =>
rimraf('./built', cb)
);
gulp.task('cleanall', ['clean'], cb =>
gulp.task('cleanall', gulp.parallel('clean', cb =>
rimraf('./node_modules', cb)
);
gulp.task('default', ['build']);
gulp.task('build:client', [
'build:ts',
'build:client:script',
'build:client:styles',
'copy:client'
]);
));
gulp.task('build:client:script', () => {
const client = require('./built/client/meta.json');
@@ -129,9 +113,7 @@ gulp.task('build:client:styles', () =>
.pipe(gulp.dest('./built/client/assets/'))
);
gulp.task('copy:client', [
'build:client:script'
], () =>
gulp.task('copy:client', () =>
gulp.src([
'./assets/**/*',
'./src/client/assets/**/*',
@@ -156,3 +138,19 @@ gulp.task('doc', () =>
.pipe((cssnano as any)())
.pipe(gulp.dest('./built/docs/assets/'))
);
gulp.task('build:client', gulp.parallel(
'build:client:script',
'build:client:styles',
'copy:client'
));
gulp.task('build', gulp.parallel(
'build:ts',
'build:copy',
'build:client',
'locales',
'doc'
));
gulp.task('default', gulp.task('build'));

View File

@@ -129,7 +129,7 @@ common:
show-password: "パスワードを表示する"
do-not-use-in-production: "これは開発ビルドです。本番環境で使用しないでください。"
user-suspended: "このユーザーは凍結されています。"
is-remote-user: "このユーザー情報はコピーです。"
is-remote-user: "このユーザー情報は不正確な可能性があります。"
is-remote-post: "この投稿情報はコピーです。"
view-on-remote: "正確な情報を見る"
renoted-by: "{user}がRenote"
@@ -360,6 +360,10 @@ common/views/components/user-menu.vue:
report-abuse: "スパムを報告"
report-abuse-detail: "どのような迷惑行為を行っていますか?"
report-abuse-reported: "管理者に報告されました。ご協力ありがとうございました。"
silence: "サイレンス"
unsilence: "サイレンス解除"
suspend: "凍結"
unsuspend: "凍結解除"
common/views/components/poll.vue:
vote-to: "「{}」に投票する"
vote-count: "{}票"
@@ -482,6 +486,7 @@ common/views/components/profile-editor.vue:
account: "アカウント"
location: "場所"
description: "自己紹介"
you-can-include-hashtags: "ハッシュタグを含めることができます。"
language: "言語"
birthday: "誕生日"
avatar: "アイコン"
@@ -658,9 +663,6 @@ desktop/views/components/drive.vue:
create-folder: "フォルダーを作成"
upload: "ファイルをアップロード"
url-upload: "URLからアップロード"
desktop/views/components/media-image.vue:
sensitive: "閲覧注意"
click-to-show: "クリックして表示"
desktop/views/components/media-video.vue:
sensitive: "閲覧注意"
click-to-show: "クリックして表示"
@@ -875,6 +877,9 @@ desktop/views/components/settings.2fa.vue:
success: "設定が完了しました!"
failed: "設定に失敗しました。トークンに誤りがないかご確認ください。"
info: "次回サインインからは、同様にパスワードに加えてデバイスに表示されているトークンを入力します。"
common/views/components/media-image.vue:
sensitive: "閲覧注意"
click-to-show: "クリックして表示"
common/views/components/api-settings.vue:
intro: "APIを利用するには、上記のトークンを「i」というキーでパラメータに付加してリクエストします。"
caution: "アカウントを不正利用される可能性があるため、このトークンは第三者に教えないでください(アプリなどにも入力しないでください)。"
@@ -1142,6 +1147,8 @@ admin/views/users.vue:
unsuspend: "凍結の解除"
unsuspend-confirm: "凍結を解除しますか?"
unsuspended: "凍結を解除しました"
make-silence: "サイレンス"
unmake-silence: "サイレンスの解除"
verify: "公式アカウントにする"
verify-confirm: "公式アカウントにしますか?"
verified: "公式アカウントにしました"
@@ -1329,9 +1336,6 @@ mobile/views/components/drive.file-detail.vue:
nsfw: "閲覧注意"
mark-as-sensitive: "閲覧注意に設定"
unmark-as-sensitive: "閲覧注意を解除"
mobile/views/components/media-image.vue:
sensitive: "閲覧注意"
click-to-show: "クリックして表示"
mobile/views/components/media-video.vue:
sensitive: "閲覧注意"
click-to-show: "クリックして表示"

View File

@@ -129,7 +129,7 @@ common:
show-password: "パスワードを表示する"
do-not-use-in-production: "Dies ist eine Entwicklungsversion. Nicht in einer Produktionsumgebung verwenden."
user-suspended: "このユーザーは凍結されています。"
is-remote-user: "このユーザー情報はコピーです。"
is-remote-user: "このユーザー情報は不正確な可能性があります。"
is-remote-post: "この投稿情報はコピーです。"
view-on-remote: "正確な情報を見る"
renoted-by: "{user}がRenote"
@@ -360,6 +360,10 @@ common/views/components/user-menu.vue:
report-abuse: "スパムを報告"
report-abuse-detail: "どのような迷惑行為を行っていますか?"
report-abuse-reported: "管理者に報告されました。ご協力ありがとうございました。"
silence: "サイレンス"
unsilence: "サイレンス解除"
suspend: "凍結"
unsuspend: "凍結解除"
common/views/components/poll.vue:
vote-to: "Stimme für '{}'"
vote-count: "{} Stimmen"
@@ -482,6 +486,7 @@ common/views/components/profile-editor.vue:
account: "アカウント"
location: "場所"
description: "自己紹介"
you-can-include-hashtags: "ハッシュタグを含めることができます。"
language: "言語"
birthday: "誕生日"
avatar: "アイコン"
@@ -658,9 +663,6 @@ desktop/views/components/drive.vue:
create-folder: "Ein Verzeichnis erstellen"
upload: "Eine Datei hochladen"
url-upload: "Von einer URL hochladen"
desktop/views/components/media-image.vue:
sensitive: "閲覧注意"
click-to-show: "クリックして表示"
desktop/views/components/media-video.vue:
sensitive: "閲覧注意"
click-to-show: "クリックして表示"
@@ -875,6 +877,9 @@ desktop/views/components/settings.2fa.vue:
success: "設定が完了しました!"
failed: "設定に失敗しました。トークンに誤りがないかご確認ください。"
info: "次回サインインからは、同様にパスワードに加えてデバイスに表示されているトークンを入力します。"
common/views/components/media-image.vue:
sensitive: "閲覧注意"
click-to-show: "クリックして表示"
common/views/components/api-settings.vue:
intro: "APIを利用するには、上記のトークンを「i」というキーでパラメータに付加してリクエストします。"
caution: "アカウントを不正利用される可能性があるため、このトークンは第三者に教えないでください(アプリなどにも入力しないでください)。"
@@ -1142,6 +1147,8 @@ admin/views/users.vue:
unsuspend: "凍結の解除"
unsuspend-confirm: "凍結を解除しますか?"
unsuspended: "凍結を解除しました"
make-silence: "サイレンス"
unmake-silence: "サイレンスの解除"
verify: "公式アカウントにする"
verify-confirm: "公式アカウントにしますか?"
verified: "公式アカウントにしました"
@@ -1329,9 +1336,6 @@ mobile/views/components/drive.file-detail.vue:
nsfw: "閲覧注意"
mark-as-sensitive: "閲覧注意に設定"
unmark-as-sensitive: "閲覧注意を解除"
mobile/views/components/media-image.vue:
sensitive: "閲覧注意"
click-to-show: "クリックして表示"
mobile/views/components/media-video.vue:
sensitive: "閲覧注意"
click-to-show: "クリックして表示"

View File

@@ -129,7 +129,7 @@ common:
show-password: "Show Password"
do-not-use-in-production: "This is a development build. Do not use in production."
user-suspended: "This user has been suspended."
is-remote-user: "This user's information is mirrored."
is-remote-user: "The information about this user may not be entirely complete."
is-remote-post: "These post contents are mirrored."
view-on-remote: "For completion, view it remotely."
renoted-by: "Renoted by {user}"
@@ -360,6 +360,10 @@ common/views/components/user-menu.vue:
report-abuse: "Report abuse"
report-abuse-detail: "What kind of nuisance did you encounter?"
report-abuse-reported: "The issue has been reported to the administrator. Your cooperation is much appreciated."
silence: "Make Silence"
unsilence: "Unsilence"
suspend: "Suspend"
unsuspend: "Unsuspend"
common/views/components/poll.vue:
vote-to: "Vote for '{}'"
vote-count: "{} votes"
@@ -482,6 +486,7 @@ common/views/components/profile-editor.vue:
account: "Account"
location: "Location"
description: "About me"
you-can-include-hashtags: "You can also include hashtags in your profile description."
language: "Language"
birthday: "Birthday"
avatar: "Icon"
@@ -658,9 +663,6 @@ desktop/views/components/drive.vue:
create-folder: "Create a folder"
upload: "Upload a file"
url-upload: "Upload from a URL"
desktop/views/components/media-image.vue:
sensitive: "NSFW"
click-to-show: "Click to show"
desktop/views/components/media-video.vue:
sensitive: "The content is NSFW"
click-to-show: "Click to show"
@@ -875,6 +877,9 @@ desktop/views/components/settings.2fa.vue:
success: "Settings saved!"
failed: "Failed to setup. Please ensure that the token is correct."
info: "From the next time you sign in to Misskey, the token displayed on your device will be necessary too, as well as the password."
common/views/components/media-image.vue:
sensitive: "NSFW"
click-to-show: "Click to show"
common/views/components/api-settings.vue:
intro: "To access the API, set this token as the key 'i' of request parameters."
caution: "Do not enter this token to any apps nor tell this token to others otherwise your account may get compromised."
@@ -1012,7 +1017,6 @@ admin/views/instance.vue:
instance-name: "Instance name"
instance-description: "Instance description"
host: "Host"
logo-url: "Logo image URL"
banner-url: "Banner image URL"
error-image-url: "Error image URL"
languages: "Language of this instance"
@@ -1143,6 +1147,8 @@ admin/views/users.vue:
unsuspend: "Unsuspend"
unsuspend-confirm: "Are you sure you want to unsuspend this account?"
unsuspended: "The user has successfully unsuspended."
make-silence: "Make Silence"
unmake-silence: "Unmake Silence"
verify: "Verify account"
verify-confirm: "Do you want this to be a verified account?"
verified: "The account is now being verified"
@@ -1330,9 +1336,6 @@ mobile/views/components/drive.file-detail.vue:
nsfw: "NSFW"
mark-as-sensitive: "Mark as 'sensitive'"
unmark-as-sensitive: "Unmark as 'sensitive'"
mobile/views/components/media-image.vue:
sensitive: "NSFW"
click-to-show: "Click to show"
mobile/views/components/media-video.vue:
sensitive: "The content is NSFW"
click-to-show: "Click to show"

View File

@@ -129,7 +129,7 @@ common:
show-password: "パスワードを表示する"
do-not-use-in-production: "Esto está en desarrollo, no usarlo para producción."
user-suspended: "このユーザーは凍結されています。"
is-remote-user: "このユーザー情報はコピーです。"
is-remote-user: "このユーザー情報は不正確な可能性があります。"
is-remote-post: "この投稿情報はコピーです。"
view-on-remote: "正確な情報を見る"
renoted-by: "{user}がRenote"
@@ -360,6 +360,10 @@ common/views/components/user-menu.vue:
report-abuse: "スパムを報告"
report-abuse-detail: "どのような迷惑行為を行っていますか?"
report-abuse-reported: "管理者に報告されました。ご協力ありがとうございました。"
silence: "サイレンス"
unsilence: "サイレンス解除"
suspend: "凍結"
unsuspend: "凍結解除"
common/views/components/poll.vue:
vote-to: "'{}' para votar"
vote-count: "{} votos"
@@ -482,6 +486,7 @@ common/views/components/profile-editor.vue:
account: "Cuenta"
location: "場所"
description: "自己紹介"
you-can-include-hashtags: "ハッシュタグを含めることができます。"
language: "言語"
birthday: "誕生日"
avatar: "Avatar"
@@ -658,9 +663,6 @@ desktop/views/components/drive.vue:
create-folder: "Crear una carpeta"
upload: "Subir fichero"
url-upload: "Subir desde una URL"
desktop/views/components/media-image.vue:
sensitive: "El contenido es NSFW (no seguro para ver en el trabajo, 'not safe for work')"
click-to-show: "Click para mostrar"
desktop/views/components/media-video.vue:
sensitive: "Este contenido no es apropiado para ver en el trabajo"
click-to-show: "Click para mostrar"
@@ -875,6 +877,9 @@ desktop/views/components/settings.2fa.vue:
success: "¡Configuraciones guardadas!"
failed: "Error al configurar. Por favor asegúrate de que el token es correcto."
info: "Desde ahora, ingresa el token que se muestra en tu dispositivo adicionalmente a tu contraseña cuando inicies sesión en Misskey"
common/views/components/media-image.vue:
sensitive: "閲覧注意"
click-to-show: "クリックして表示"
common/views/components/api-settings.vue:
intro: "APIを利用するには、上記のトークンを「i」というキーでパラメータに付加してリクエストします。"
caution: "アカウントを不正利用される可能性があるため、このトークンは第三者に教えないでください(アプリなどにも入力しないでください)。"
@@ -1142,6 +1147,8 @@ admin/views/users.vue:
unsuspend: "凍結の解除"
unsuspend-confirm: "凍結を解除しますか?"
unsuspended: "凍結を解除しました"
make-silence: "サイレンス"
unmake-silence: "サイレンスの解除"
verify: "公式アカウントにする"
verify-confirm: "公式アカウントにしますか?"
verified: "公式アカウントにしました"
@@ -1329,9 +1336,6 @@ mobile/views/components/drive.file-detail.vue:
nsfw: "閲覧注意"
mark-as-sensitive: "閲覧注意に設定"
unmark-as-sensitive: "閲覧注意を解除"
mobile/views/components/media-image.vue:
sensitive: "閲覧注意"
click-to-show: "クリックして表示"
mobile/views/components/media-video.vue:
sensitive: "閲覧注意"
click-to-show: "クリックして表示"

View File

@@ -129,7 +129,7 @@ common:
show-password: "Afficher le mot de passe"
do-not-use-in-production: "Il sagit dune version de développement. Ne pas utiliser dans un environnement de production."
user-suspended: "Cet·te utilisateur·trice a été suspendu·e"
is-remote-user: "Ces informations appartiennent à un utilisateur distant."
is-remote-user: "このユーザー情報は不正確な可能性があります。"
is-remote-post: "Ceci est une publication distante."
view-on-remote: " Consulter le profil complet"
renoted-by: "Renoté par {user}"
@@ -333,7 +333,7 @@ common/views/components/nav.vue:
stats: "Statistiques"
status: "Statut"
wiki: "Wiki"
donors: "Donateurs"
donors: "Donateur·rice·s"
repository: "Dépôt"
develop: "Développeurs"
feedback: "Suggestions"
@@ -360,10 +360,14 @@ common/views/components/user-menu.vue:
report-abuse: "Signaler un abus"
report-abuse-detail: "Détail du signalement"
report-abuse-reported: "Transmit à ladministrateur. Merci de votre collaboration."
silence: "サイレンス"
unsilence: "サイレンス解除"
suspend: "Suspendre"
unsuspend: "凍結解除"
common/views/components/poll.vue:
vote-to: "Voter pour '{}'"
vote-count: "{} votes"
total-users: "{} utilisateurs ont voté"
total-users: "{} utilisateur·rice·s ont voté"
vote: "Vote"
show-result: "Montrer les résultats"
voted: "Voté"
@@ -386,7 +390,7 @@ common/views/components/emoji-picker.vue:
symbols: "Symboles"
flags: "Drapeaux"
common/views/components/signin.vue:
username: "Nom d'utilisateur"
username: "Nom d'utilisateur·rice"
password: "Mot de passe"
token: "Jeton"
signing-in: "Connexion…"
@@ -399,7 +403,7 @@ common/views/components/signin.vue:
common/views/components/signup.vue:
invitation-code: "Code dinvitation"
invitation-info: "Si vous navez pas de code dinvitation, contactez un <a href=\"{}\">administrateur</a>."
username: "Nom d'utilisateur"
username: "Nom d'utilisateur·rice"
checking: "Vérification…"
available: "Disponible"
unavailable: "Non disponible"
@@ -432,7 +436,7 @@ common/views/components/notification-settings.vue:
mark-as-read-all-unread-notes: "Marquer toutes les notes comme lues"
mark-as-read-all-talk-messages: "Marquer toutes les conversations comme lues"
auto-watch: "投稿の自動ウォッチ"
auto-watch-desc: "リアクションしたり返信したりした投稿に関する通知を自動的に受け取るようにします。"
auto-watch-desc: "Recevoir automatiquement des notifications à propos des publications auxquelles vous avez réagi ou répondu"
common/views/components/integration-settings.vue:
title: "Intégrations"
connect: "Connecter"
@@ -458,8 +462,8 @@ common/views/components/visibility-chooser.vue:
public: "Public"
home: "Accueil"
home-desc: "Publier sur le fil dAccueil uniquement"
followers: "Abonnés"
followers-desc: "Publier à vos abonnés uniquement"
followers: "Abonné·e·s"
followers-desc: "Publier à vos abonné·e·s uniquement"
specified: "Direct"
specified-desc: "Publier uniquement aux utilisateurs mentionnés"
local-public: "Local (Public)"
@@ -482,6 +486,7 @@ common/views/components/profile-editor.vue:
account: "Compte"
location: "Lieu"
description: "À propos de moi"
you-can-include-hashtags: "Vous pouvez également inclure un hashtag sur votre description de profile."
language: "Langue"
birthday: "Date de naissance"
avatar: "Avatar"
@@ -502,7 +507,7 @@ common/views/components/profile-editor.vue:
email-verified: "Ladresse du courrier électronique a été vérifiée."
email-not-verified: "Adresse de courriel nest pas confirmée. Veuillez vérifier votre boite de réception."
common/views/components/user-list-editor.vue:
users: "Utilisateur"
users: "Utilisateur·rice"
rename: "Renommer la liste"
delete: "Supprimer la liste"
remove-user: "Retirer de cette liste"
@@ -658,23 +663,20 @@ desktop/views/components/drive.vue:
create-folder: "Créer un dossier"
upload: "Téléverser un fichier"
url-upload: "Téléverser à partir dune URL"
desktop/views/components/media-image.vue:
sensitive: "Le contenu est NSFW"
click-to-show: "Cliquer pour afficher"
desktop/views/components/media-video.vue:
sensitive: "Le contenu est NSFW"
click-to-show: "Cliquer pour afficher"
desktop/views/components/followers-window.vue:
followers: "{} abonnés"
followers: "{} abonné·e·s"
desktop/views/components/followers.vue:
empty: "Il semble que vous n'avez pas encore d'abonnés."
empty: "Il semble que vous navez pas encore dabonné·e·s."
desktop/views/components/following-window.vue:
following: "Suit {}"
desktop/views/components/following.vue:
empty: "Vous ne suivez aucun compte."
desktop/views/components/friends-maker.vue:
title: "Utilisateurs recommandés :"
empty: "Impossible de trouver des utilisateurs à recommander."
title: "Utilisateur·rice·s recommandé·e·s :"
empty: "Impossible de trouver des utilisateur·trice·s à recommander."
fetching: "Chargement"
refresh: "Plus"
close: "Fermer"
@@ -875,6 +877,9 @@ desktop/views/components/settings.2fa.vue:
success: "Sauvegarde des paramètres avec succès !"
failed: "Lopération a échoué. Veuillez vous assurer que le jeton a été saisi correctement."
info: "À partir de maintenant, à chaque fois que vous vous connectez entrez votre mot de passe ainsi que le jeton généré sur votre appareil."
common/views/components/media-image.vue:
sensitive: "Contenu sensible"
click-to-show: "Cliquer pour afficher"
common/views/components/api-settings.vue:
intro: "Pour accéder à l'API, définissez ce jeton comme la clé de « i » dans les paramètres de requête."
caution: "Merci de ne pas introduire ce jeton dans aucune application ou le divulguer à quiconque. Ceci risque de compromettre votre compte."
@@ -972,7 +977,7 @@ desktop/views/components/user-lists-window.vue:
desktop/views/components/user-preview.vue:
notes: "Publications"
following: "Abonné à"
followers: "Abonnés"
followers: "Abonné·e·s"
desktop/views/components/users-list.vue:
all: "Tout"
iknow: "Vous connaissez"
@@ -1134,7 +1139,7 @@ admin/views/users.vue:
user-not-found: "Utilisateur non trouvé"
lookup: "Recherche"
reset-password: "Réinitialiser mot de passe"
reset-password-confirm: "パスワードをリセットしますか?"
reset-password-confirm: "Souhaitez-vous réinitialiser votre mot de passe ?"
password-updated: "Le mot de passe est « {password} »"
suspend: "Suspendre"
suspend-confirm: "Désirez-vous suspendre ce compte ?"
@@ -1142,6 +1147,8 @@ admin/views/users.vue:
unsuspend: "Suspension levée"
unsuspend-confirm: "Souhaiteriez-vous ne plus suspendre ce compte ?"
unsuspended: "La suspension de lutilisateur a été levée avec succès"
make-silence: "サイレンス"
unmake-silence: "サイレンスの解除"
verify: "Vérification du compte"
verify-confirm: "Souhaiteriez-vous rendre votre compte comme étant un compte vérifié ?"
verified: "Le compte a été vérifié"
@@ -1244,11 +1251,11 @@ desktop/views/pages/share.vue:
desktop/views/pages/tag.vue:
no-posts-found: "Aucune publication contenant « {q} » na été trouvée."
desktop/views/pages/user-list.users.vue:
users: "Utilisateurs"
users: "Utilisateur·rice·s"
add-user: "Ajouter un utilisateur"
username: "Nom d'utilisateur"
desktop/views/pages/user/user.followers-you-know.vue:
title: "Abonnés que vous connaissez"
title: "Abonné·e·s que vous connaissez"
loading: "Chargement en cours"
no-users: "Aucun abonné connu"
desktop/views/pages/user/user.friends.vue:
@@ -1265,7 +1272,7 @@ desktop/views/pages/user/user.profile.vue:
desktop/views/pages/user/user.header.vue:
posts: "Notes"
following: "Suit"
followers: "Abonnés"
followers: "Abonné·e·s"
is-bot: "Ce compte est un Bot"
years-old: "{age} ans"
year: "/"
@@ -1297,7 +1304,7 @@ desktop/views/widgets/trends.vue:
refresh: "Afficher d'autres"
nothing: "Rien"
desktop/views/widgets/users.vue:
title: "Utilisateurs"
title: "Utilisateurs·rices"
refresh: "Afficher d'autres"
no-one: "Personne"
mobile/views/components/drive.vue:
@@ -1329,9 +1336,6 @@ mobile/views/components/drive.file-detail.vue:
nsfw: "CW"
mark-as-sensitive: "Marquer comme sensible"
unmark-as-sensitive: "Ne pas marquer comme sensible"
mobile/views/components/media-image.vue:
sensitive: "Le contenu est NSFW"
click-to-show: "Cliquer pour afficher"
mobile/views/components/media-video.vue:
sensitive: "Le contenu est NSFW"
click-to-show: "Cliquer pour afficher"
@@ -1343,7 +1347,7 @@ common/views/components/follow-button.vue:
follow-request: "Demande dabonnement"
mobile/views/components/friends-maker.vue:
title: "Abonnez-vous à"
empty: "Impossible de trouver des utilisateurs à recommander."
empty: "Impossible de trouver des utilisateurs·trices à recommander."
fetching: "Chargement"
refresh: "Voir plus"
close: "Fermer"
@@ -1457,7 +1461,7 @@ mobile/views/pages/search.vue:
mobile/views/pages/selectdrive.vue:
select-file: "Choisissez un fichier"
mobile/views/pages/settings.vue:
signed-in-as: "Connecté en tant que {}"
signed-in-as: "Connecté·e en tant que {}"
design: "Affichage et design"
dark-mode: "Mode nuit"
i-am-under-limited-internet: "J'ai un accès Internet limité"
@@ -1502,7 +1506,7 @@ mobile/views/pages/settings.vue:
mobile/views/pages/user.vue:
follows-you: "Vous suit"
following: "Abonnements"
followers: "Abonnés"
followers: "Abonné·e·s"
notes: "Notes"
overview: "Aperçu"
timeline: "Fil dactualité"
@@ -1515,10 +1519,10 @@ mobile/views/pages/user/home.vue:
keywords: "Mot clés"
domains: "Domaines"
frequently-replied-users: "Utilisateurs mentionnés souvent"
followers-you-know: "Abonnés que vous connaissez"
followers-you-know: "Abonné·e·s que vous connaissez"
last-used-at: "Dernière connexion il y a"
mobile/views/pages/user/home.followers-you-know.vue:
no-users: "Aucun utilisateur connu"
no-users: "Aucun utilisateur·rice connu·e"
mobile/views/pages/user/home.friends.vue:
no-users: "Aucun utilisateur connu"
mobile/views/pages/user/home.notes.vue:

View File

@@ -129,7 +129,7 @@ common:
show-password: "パスワードを表示する"
do-not-use-in-production: "これは開発ビルドです。本番環境で使用しないでください。"
user-suspended: "このユーザーは凍結されています。"
is-remote-user: "このユーザー情報はコピーです。"
is-remote-user: "このユーザー情報は不正確な可能性があります。"
is-remote-post: "この投稿情報はコピーです。"
view-on-remote: "正確な情報を見る"
renoted-by: "{user}がRenote"
@@ -360,6 +360,10 @@ common/views/components/user-menu.vue:
report-abuse: "スパムを報告"
report-abuse-detail: "どのような迷惑行為を行っていますか?"
report-abuse-reported: "管理者に報告されました。ご協力ありがとうございました。"
silence: "サイレンス"
unsilence: "サイレンス解除"
suspend: "凍結"
unsuspend: "凍結解除"
common/views/components/poll.vue:
vote-to: "「{}」に投票する"
vote-count: "{}票"
@@ -482,6 +486,7 @@ common/views/components/profile-editor.vue:
account: "アカウント"
location: "場所"
description: "自己紹介"
you-can-include-hashtags: "ハッシュタグを含めることができます。"
language: "言語"
birthday: "誕生日"
avatar: "アイコン"
@@ -658,9 +663,6 @@ desktop/views/components/drive.vue:
create-folder: "フォルダーを作成"
upload: "ファイルをアップロード"
url-upload: "URLからアップロード"
desktop/views/components/media-image.vue:
sensitive: "閲覧注意"
click-to-show: "クリックして表示"
desktop/views/components/media-video.vue:
sensitive: "閲覧注意"
click-to-show: "クリックして表示"
@@ -875,6 +877,9 @@ desktop/views/components/settings.2fa.vue:
success: "設定が完了しました!"
failed: "設定に失敗しました。トークンに誤りがないかご確認ください。"
info: "次回サインインからは、同様にパスワードに加えてデバイスに表示されているトークンを入力します。"
common/views/components/media-image.vue:
sensitive: "閲覧注意"
click-to-show: "クリックして表示"
common/views/components/api-settings.vue:
intro: "APIを利用するには、上記のトークンを「i」というキーでパラメータに付加してリクエストします。"
caution: "アカウントを不正利用される可能性があるため、このトークンは第三者に教えないでください(アプリなどにも入力しないでください)。"
@@ -1142,6 +1147,8 @@ admin/views/users.vue:
unsuspend: "凍結の解除"
unsuspend-confirm: "凍結を解除しますか?"
unsuspended: "凍結を解除しました"
make-silence: "サイレンス"
unmake-silence: "サイレンスの解除"
verify: "公式アカウントにする"
verify-confirm: "公式アカウントにしますか?"
verified: "公式アカウントにしました"
@@ -1329,9 +1336,6 @@ mobile/views/components/drive.file-detail.vue:
nsfw: "閲覧注意"
mark-as-sensitive: "閲覧注意に設定"
unmark-as-sensitive: "閲覧注意を解除"
mobile/views/components/media-image.vue:
sensitive: "閲覧注意"
click-to-show: "クリックして表示"
mobile/views/components/media-video.vue:
sensitive: "閲覧注意"
click-to-show: "クリックして表示"

View File

@@ -138,7 +138,7 @@ common:
do-not-use-in-production: "これは開発ビルドです。本番環境で使用しないでください。"
user-suspended: "このユーザーは凍結されています。"
is-remote-user: "このユーザー情報はコピーです。"
is-remote-user: "このユーザー情報は不正確な可能性があります。"
is-remote-post: "この投稿情報はコピーです。"
view-on-remote: "正確な情報を見る"
renoted-by: "{user}がRenote"
@@ -391,6 +391,10 @@ common/views/components/user-menu.vue:
report-abuse: "スパムを報告"
report-abuse-detail: "どのような迷惑行為を行っていますか?"
report-abuse-reported: "管理者に報告されました。ご協力ありがとうございました。"
silence: "サイレンス"
unsilence: "サイレンス解除"
suspend: "凍結"
unsuspend: "凍結解除"
common/views/components/poll.vue:
vote-to: "「{}」に投票する"
@@ -530,6 +534,7 @@ common/views/components/profile-editor.vue:
account: "アカウント"
location: "場所"
description: "自己紹介"
you-can-include-hashtags: "ハッシュタグを含めることができます。"
language: "言語"
birthday: "誕生日"
avatar: "アイコン"
@@ -1274,6 +1279,8 @@ admin/views/users.vue:
unsuspend: "凍結の解除"
unsuspend-confirm: "凍結を解除しますか?"
unsuspended: "凍結を解除しました"
make-silence: "サイレンス"
unmake-silence: "サイレンスの解除"
verify: "公式アカウントにする"
verify-confirm: "公式アカウントにしますか?"
verified: "公式アカウントにしました"

View File

@@ -129,7 +129,7 @@ common:
show-password: "パスワードを表示する"
do-not-use-in-production: "開発ビルドや。本番環境で使わんといて!知らんで!"
user-suspended: "このユーザーは凍結されています。"
is-remote-user: "このユーザー情報はコピーです。"
is-remote-user: "このユーザー情報は不正確な可能性があります。"
is-remote-post: "この投稿情報はコピーです。"
view-on-remote: "ちゃんとした情報見せてや!"
renoted-by: "{user}がRenote"
@@ -360,6 +360,10 @@ common/views/components/user-menu.vue:
report-abuse: "スパムを報告"
report-abuse-detail: "どのような迷惑行為を行っていますか?"
report-abuse-reported: "管理者に報告されました。ご協力ありがとうございました。"
silence: "サイレンス"
unsilence: "サイレンス解除"
suspend: "凍結"
unsuspend: "凍結解除"
common/views/components/poll.vue:
vote-to: "「{}」に投票や!"
vote-count: "{}票"
@@ -482,6 +486,7 @@ common/views/components/profile-editor.vue:
account: "アカウント"
location: "場所"
description: "自己紹介"
you-can-include-hashtags: "ハッシュタグを含めることができます。"
language: "言語"
birthday: "誕生日"
avatar: "アイコン"
@@ -658,9 +663,6 @@ desktop/views/components/drive.vue:
create-folder: "フォルダー作る"
upload: "ファイル上げる"
url-upload: "URLつこうて上げる"
desktop/views/components/media-image.vue:
sensitive: "ちょっと見せられへんわ"
click-to-show: "クリックして見せるで"
desktop/views/components/media-video.vue:
sensitive: "ちょっと見せられへんわ"
click-to-show: "クリックして見せるで"
@@ -875,6 +877,9 @@ desktop/views/components/settings.2fa.vue:
success: "設定が完了したで!"
failed: "なんか設定に失敗したで。トークンを間違えとらんか確認してや。"
info: "次のサインインからは、パスワードに加えてデバイスに出とるトークンを入力してな。"
common/views/components/media-image.vue:
sensitive: "閲覧注意"
click-to-show: "クリックして表示"
common/views/components/api-settings.vue:
intro: "API使うんやったらこのトークンを「i」っちゅうパラメータにくっつけてリクエストできるで。"
caution: "アカウント勝手にいじられるかも知れんから、このトークンは教えたらあかんし、アプリにも書いたらあかんで(これはフリちゃうで)"
@@ -1142,6 +1147,8 @@ admin/views/users.vue:
unsuspend: "凍結の解除"
unsuspend-confirm: "凍結を解除しますか?"
unsuspended: "凍結を解除しました"
make-silence: "サイレンス"
unmake-silence: "サイレンスの解除"
verify: "公式アカウントにする"
verify-confirm: "公式アカウントにしますか?"
verified: "公式アカウントにしました"
@@ -1329,9 +1336,6 @@ mobile/views/components/drive.file-detail.vue:
nsfw: "ちょっと見せられへんわ"
mark-as-sensitive: "見たらあかん感じにしとく"
unmark-as-sensitive: "やっぱ見せたるわ"
mobile/views/components/media-image.vue:
sensitive: "見たらあかんで"
click-to-show: "押してみ、見せたるわ"
mobile/views/components/media-video.vue:
sensitive: "ちょっと見せられへんわ"
click-to-show: "押してみ、見せたるわ"

View File

@@ -129,7 +129,7 @@ common:
show-password: "비밀번호 표시"
do-not-use-in-production: "이것은 개발 빌드입니다. 프로덕션 환경에서 사용하지 마십시오."
user-suspended: "이 사용자는 정지된 상태입니다."
is-remote-user: "이 유저 정보는 복사본입니다."
is-remote-user: "このユーザー情報は不正確な可能性があります。"
is-remote-post: "이 글 정보는 복사본입니다."
view-on-remote: "정확한 정보 보기"
renoted-by: "{user}이(가) 리노트"
@@ -360,6 +360,10 @@ common/views/components/user-menu.vue:
report-abuse: "스팸 신고"
report-abuse-detail: "어떤 스팸 행위를 하고 있습니까?"
report-abuse-reported: "관리자에게 보고되었습니다. 협조해주셔서 감사합니다."
silence: "サイレンス"
unsilence: "サイレンス解除"
suspend: "凍結"
unsuspend: "凍結解除"
common/views/components/poll.vue:
vote-to: "\"{}\"에 투표하기"
vote-count: "{}표"
@@ -482,6 +486,7 @@ common/views/components/profile-editor.vue:
account: "계정"
location: "장소"
description: "자기소개"
you-can-include-hashtags: "해시 태그를 포함할 수 있습니다."
language: "언어"
birthday: "생일"
avatar: "아바타"
@@ -593,7 +598,7 @@ desktop/views/components/calendar.vue:
title: "{year}년 {month}월"
prev: "이전 달"
next: "다음 달"
go: "클릭여 시간 회귀"
go: "클릭여 시간역행"
desktop/views/components/choose-file-from-drive-window.vue:
chosen-files: "{count} 파일 선택중"
upload: "PC에서 드라이브에 파일을 업로드"
@@ -658,9 +663,6 @@ desktop/views/components/drive.vue:
create-folder: "폴더 만들기"
upload: "파일 업로드"
url-upload: "URL에서 업로드"
desktop/views/components/media-image.vue:
sensitive: "열람주의"
click-to-show: "클릭하여 표시"
desktop/views/components/media-video.vue:
sensitive: "열람주의"
click-to-show: "클릭하여 표시"
@@ -788,8 +790,8 @@ desktop/views/components/settings.vue:
auto-popout-desc: "창이 열릴 때 팝아웃 (브라우저 밖으로 분리) 이 가능한 경우 자동으로 팝아웃합니다. 이 설정은 브라우저에 저장됩니다."
deck-nav: "덱 내 탐색"
deck-nav-desc: "덱을 사용중일 때, 내비게이션이 발생하였을 경우 페이지를 이동하지 않고 일시적으로 임시 칼럼을 생성하도록 합니다."
keep-cw: "CW保持"
keep-cw-desc: "投稿にリプライする際、リプライ元の投稿にCWが設定されていたとき、デフォルトで同じCWを設定するようにします。"
keep-cw: "CW 유지"
keep-cw-desc: "글에 답글을 달 때, 답글할 글에 CW가 설정되어 있는 경우 기본값으로 동일한 CW를 설정하도록 합니다."
deck-default: "덱을 기본 UI로 설정"
display: "디자인 및 표시"
customize: "홈 커스터마이징"
@@ -875,6 +877,9 @@ desktop/views/components/settings.2fa.vue:
success: "설정이 완료되었습니다!"
failed: "설정에 실패했습니다. 토큰이 잘못되었는지 확인해주십시오."
info: "다음 로그인부터는 이와 동일하게 비밀번호에 더해 장치에 표시된 토큰을 입력합니다."
common/views/components/media-image.vue:
sensitive: "열람주의"
click-to-show: "클릭하여 보기"
common/views/components/api-settings.vue:
intro: "API를 사용하려면 위의 토큰을 \"i\" 라는 키의 값으로 매개변수를 추가하여 요청합니다."
caution: "계정을 부정 사용할 가능성이 있으므로, 이 토큰은 제 3자에게 알려주지 마십시오 (앱 등에 붙여넣지 마십시오)."
@@ -1065,7 +1070,7 @@ admin/views/instance.vue:
external-user-recommendation-timeout: "타임 아웃"
external-user-recommendation-timeout-desc: "밀리초 (예: 300000)"
email-config: "메일 서버 설정"
email-config-info: "메일 주소 확인 혹은 호 재설정에 사용 됩니다."
email-config-info: "메일 주소 확인 혹은 비밀번호 재설정에 사용 됩니다."
enable-email: "메일 발신 활성화"
email: "메일 주소"
smtp-secure: "SMTP 연결에 암시적으로 SSL/TLS를 사용"
@@ -1133,23 +1138,25 @@ admin/views/users.vue:
username-or-userid: "사용자명 혹은 사용자 ID"
user-not-found: "사용자를 찾을 수 없습니다"
lookup: "조회"
reset-password: "호 재설정"
reset-password-confirm: "パスワードをリセットしますか?"
password-updated: "호는 현재 \"{password}\" 입니다"
reset-password: "비밀번호 재설정"
reset-password-confirm: "비밀번호를 재설정하시겠습니까?"
password-updated: "비밀번호는 현재 \"{password}\" 입니다"
suspend: "정지"
suspend-confirm: "凍結しますか?"
suspend-confirm: "정지하시겠습니까?"
suspended: "정지하였습니다"
unsuspend: "정지 해제"
unsuspend-confirm: "凍結を解除しますか?"
unsuspend-confirm: "정지를 해제하시겠습니까?"
unsuspended: "정지를 해제하였습니다"
make-silence: "침묵"
unmake-silence: "침묵 해제"
verify: "공식 계정으로 설정"
verify-confirm: "公式アカウントにしますか?"
verify-confirm: "공식 계정으로 설정하시겠습니까?"
verified: "공식 계정으로 설정하였습니다"
unverify: "공식 계정 해제"
unverify-confirm: "公式アカウントを解除しますか?"
unverify-confirm: "공식 계정을 해제하시겠습니까?"
unverified: "공식 계정을 해제하였습니다"
update-remote-user: "リモートユーザー情報の更新"
remote-user-updated: "リモートユーザー情報を更新しました"
update-remote-user: "원격 사용자 정보 갱신"
remote-user-updated: "원격 사용자 정보를 갱신하였습니다"
users:
title: "사용자"
sort:
@@ -1329,9 +1336,6 @@ mobile/views/components/drive.file-detail.vue:
nsfw: "열람주의"
mark-as-sensitive: "열람주의로 설정"
unmark-as-sensitive: "열람주의 해제"
mobile/views/components/media-image.vue:
sensitive: "열람주의"
click-to-show: "클릭하여 표시"
mobile/views/components/media-video.vue:
sensitive: "열람주의"
click-to-show: "클릭하여 표시"
@@ -1476,7 +1480,7 @@ mobile/views/pages/settings.vue:
notification-position-top: "위"
behavior: "동작"
fetch-on-scroll: "스크롤하여 자동으로 불러오기"
keep-cw: "CW保持"
keep-cw: "CW 유지"
note-visibility: "게시물의 공개 범위"
default-note-visibility: "기본 공개 범위"
remember-note-visibility: "글의 공개 범위를 기억하기"

View File

@@ -129,7 +129,7 @@ common:
show-password: "パスワードを表示する"
do-not-use-in-production: "これは開発ビルドです。本番環境で使用しないでください。"
user-suspended: "このユーザーは凍結されています。"
is-remote-user: "このユーザー情報はコピーです。"
is-remote-user: "このユーザー情報は不正確な可能性があります。"
is-remote-post: "この投稿情報はコピーです。"
view-on-remote: "正確な情報を見る"
renoted-by: "{user}がRenote"
@@ -360,6 +360,10 @@ common/views/components/user-menu.vue:
report-abuse: "スパムを報告"
report-abuse-detail: "どのような迷惑行為を行っていますか?"
report-abuse-reported: "管理者に報告されました。ご協力ありがとうございました。"
silence: "サイレンス"
unsilence: "サイレンス解除"
suspend: "凍結"
unsuspend: "凍結解除"
common/views/components/poll.vue:
vote-to: "Stemmen op '{}'"
vote-count: "{} stemmen"
@@ -482,6 +486,7 @@ common/views/components/profile-editor.vue:
account: "アカウント"
location: "場所"
description: "自己紹介"
you-can-include-hashtags: "ハッシュタグを含めることができます。"
language: "言語"
birthday: "誕生日"
avatar: "アイコン"
@@ -658,9 +663,6 @@ desktop/views/components/drive.vue:
create-folder: "Map creëren"
upload: "Bestand uploaden"
url-upload: "Uploaden via URL"
desktop/views/components/media-image.vue:
sensitive: "閲覧注意"
click-to-show: "クリックして表示"
desktop/views/components/media-video.vue:
sensitive: "閲覧注意"
click-to-show: "クリックして表示"
@@ -875,6 +877,9 @@ desktop/views/components/settings.2fa.vue:
success: "Instellen voltooid!"
failed: "Instellen mislukt. Zorg ervoor dat de sleutel juist is."
info: "Vanaf nu moet je ook de op je apparaat getoonde sleutel tonen bij het inloggen op Misskey."
common/views/components/media-image.vue:
sensitive: "閲覧注意"
click-to-show: "クリックして表示"
common/views/components/api-settings.vue:
intro: "APIを利用するには、上記のトークンを「i」というキーでパラメータに付加してリクエストします。"
caution: "アカウントを不正利用される可能性があるため、このトークンは第三者に教えないでください(アプリなどにも入力しないでください)。"
@@ -1142,6 +1147,8 @@ admin/views/users.vue:
unsuspend: "凍結の解除"
unsuspend-confirm: "凍結を解除しますか?"
unsuspended: "凍結を解除しました"
make-silence: "サイレンス"
unmake-silence: "サイレンスの解除"
verify: "公式アカウントにする"
verify-confirm: "公式アカウントにしますか?"
verified: "公式アカウントにしました"
@@ -1329,9 +1336,6 @@ mobile/views/components/drive.file-detail.vue:
nsfw: "閲覧注意"
mark-as-sensitive: "閲覧注意に設定"
unmark-as-sensitive: "閲覧注意を解除"
mobile/views/components/media-image.vue:
sensitive: "閲覧注意"
click-to-show: "クリックして表示"
mobile/views/components/media-video.vue:
sensitive: "閲覧注意"
click-to-show: "クリックして表示"

View File

@@ -129,7 +129,7 @@ common:
show-password: "パスワードを表示する"
do-not-use-in-production: "これは開発ビルドです。本番環境で使用しないでください。"
user-suspended: "このユーザーは凍結されています。"
is-remote-user: "このユーザー情報はコピーです。"
is-remote-user: "このユーザー情報は不正確な可能性があります。"
is-remote-post: "この投稿情報はコピーです。"
view-on-remote: "正確な情報を見る"
renoted-by: "{user}がRenote"
@@ -360,6 +360,10 @@ common/views/components/user-menu.vue:
report-abuse: "スパムを報告"
report-abuse-detail: "どのような迷惑行為を行っていますか?"
report-abuse-reported: "管理者に報告されました。ご協力ありがとうございました。"
silence: "サイレンス"
unsilence: "サイレンス解除"
suspend: "凍結"
unsuspend: "凍結解除"
common/views/components/poll.vue:
vote-to: "「{}」に投票する"
vote-count: "{} stemmer"
@@ -482,6 +486,7 @@ common/views/components/profile-editor.vue:
account: "アカウント"
location: "場所"
description: "自己紹介"
you-can-include-hashtags: "ハッシュタグを含めることができます。"
language: "言語"
birthday: "誕生日"
avatar: "アイコン"
@@ -658,9 +663,6 @@ desktop/views/components/drive.vue:
create-folder: "フォルダーを作成"
upload: "ファイルをアップロード"
url-upload: "URLからアップロード"
desktop/views/components/media-image.vue:
sensitive: "NSFW"
click-to-show: "クリックして表示"
desktop/views/components/media-video.vue:
sensitive: "Innholdet er NSFW"
click-to-show: "クリックして表示"
@@ -875,6 +877,9 @@ desktop/views/components/settings.2fa.vue:
success: "設定が完了しました!"
failed: "設定に失敗しました。トークンに誤りがないかご確認ください。"
info: "次回サインインからは、同様にパスワードに加えてデバイスに表示されているトークンを入力します。"
common/views/components/media-image.vue:
sensitive: "閲覧注意"
click-to-show: "クリックして表示"
common/views/components/api-settings.vue:
intro: "APIを利用するには、上記のトークンを「i」というキーでパラメータに付加してリクエストします。"
caution: "アカウントを不正利用される可能性があるため、このトークンは第三者に教えないでください(アプリなどにも入力しないでください)。"
@@ -1142,6 +1147,8 @@ admin/views/users.vue:
unsuspend: "凍結の解除"
unsuspend-confirm: "凍結を解除しますか?"
unsuspended: "凍結を解除しました"
make-silence: "サイレンス"
unmake-silence: "サイレンスの解除"
verify: "公式アカウントにする"
verify-confirm: "公式アカウントにしますか?"
verified: "公式アカウントにしました"
@@ -1329,9 +1336,6 @@ mobile/views/components/drive.file-detail.vue:
nsfw: "NSFW"
mark-as-sensitive: "閲覧注意に設定"
unmark-as-sensitive: "閲覧注意を解除"
mobile/views/components/media-image.vue:
sensitive: "NSFW"
click-to-show: "クリックして表示"
mobile/views/components/media-video.vue:
sensitive: "Innholdet er NSFW"
click-to-show: "クリックして表示"

View File

@@ -27,7 +27,7 @@ common:
do-not-copy-paste: "ここにコードを入力したり張り付けたりしないでください。アカウントが不正利用される可能性があります。"
load-more: "Załaduj więcej"
enter-password: "Wprowadź Hasło"
2fa: "二段階認証"
2fa: "Uwierzytelnienie dwuetapowe"
got-it: "Rozumiem!"
customization-tips:
title: "Wskazówki o dostosowywaniu"
@@ -129,7 +129,7 @@ common:
show-password: "Pokaż hasło"
do-not-use-in-production: "これは開発ビルドです。本番環境で使用しないでください。"
user-suspended: "このユーザーは凍結されています。"
is-remote-user: "Informacje o użytkowniku są kopiowane."
is-remote-user: "このユーザー情報は不正確な可能性があります。"
is-remote-post: "この投稿情報はコピーです。"
view-on-remote: "Dla dopełnienia, zobacz to zdalnie."
renoted-by: "{user} udostępnił(a)"
@@ -350,16 +350,20 @@ common/views/components/note-menu.vue:
delete-confirm: "Czy na pewno chcesz usunąć ten wpis?"
remote: "Pokaż oryginał"
common/views/components/user-menu.vue:
mention: "メンション"
mute: "ミュート"
unmute: "ミュート解除"
block: "ブロック"
unblock: "ブロック解除"
push-to-list: "リストに追加"
mention: "Wspomnij"
mute: "Wycisz"
unmute: "Cofnij wyciszenie"
block: "Zablokuj"
unblock: "Odblokuj"
push-to-list: "Dodaj do listy"
select-list: "リストを選択してください"
report-abuse: "スパムを報告"
report-abuse: "Zgłoś nadużycie"
report-abuse-detail: "どのような迷惑行為を行っていますか?"
report-abuse-reported: "管理者に報告されました。ご協力ありがとうございました。"
silence: "サイレンス"
unsilence: "サイレンス解除"
suspend: "凍結"
unsuspend: "凍結解除"
common/views/components/poll.vue:
vote-to: "Zagłosuj na '{}'"
vote-count: "{} głosów"
@@ -482,6 +486,7 @@ common/views/components/profile-editor.vue:
account: "Konto"
location: "Lokalizacja"
description: "O mnie"
you-can-include-hashtags: "ハッシュタグを含めることができます。"
language: "Język"
birthday: "Data urodzenia"
avatar: "Awatar"
@@ -658,9 +663,6 @@ desktop/views/components/drive.vue:
create-folder: "Utwórz katalog"
upload: "Wyślij plik"
url-upload: "Wyślij z adresu URL"
desktop/views/components/media-image.vue:
sensitive: "To jest zawartość NSFW"
click-to-show: "Naciśnij aby wyświetlić"
desktop/views/components/media-video.vue:
sensitive: "To jest zawartość NSFW"
click-to-show: "Naciśnij aby wyświetlić"
@@ -868,13 +870,16 @@ desktop/views/components/settings.2fa.vue:
enter-password: "Wprowadź hasło"
authenticator: "Na początek musisz zainstalować Google Authenticator na swoim urządzeniu:"
howtoinstall: "Jak zainstalować"
token: "トークン"
token: "Token"
scan: "Później, zeskanuje ten kod QR:"
done: "Wprowadź token wyświetlony na Twoim urządzeniu:"
submit: "Wyślij"
success: "Pomyślnie ukończono konfigurację!"
failed: "Nie udało się skonfigurować uwierzytelniania dwuetapowego, upewnij się że wprowadziłeś prawidłowy token."
info: "Od teraz, wprowadzaj token wyświetlany na urządzeniu przy każdym logowaniu do Misskey."
common/views/components/media-image.vue:
sensitive: "閲覧注意"
click-to-show: "クリックして表示"
common/views/components/api-settings.vue:
intro: "Aby uzyskać dostęp do API, ustaw ten token jako klucz 'i' parametrów żądań."
caution: "Nie pokazuj tego tokenu osobom trzecim (nie wprowadzaj go nigdzie indziej), aby konto nie trafiło w niepowołane ręce."
@@ -1142,6 +1147,8 @@ admin/views/users.vue:
unsuspend: "凍結の解除"
unsuspend-confirm: "凍結を解除しますか?"
unsuspended: "凍結を解除しました"
make-silence: "サイレンス"
unmake-silence: "サイレンスの解除"
verify: "公式アカウントにする"
verify-confirm: "公式アカウントにしますか?"
verified: "公式アカウントにしました"
@@ -1261,7 +1268,7 @@ desktop/views/pages/user/user.photos.vue:
no-photos: "Brak zdjęć"
desktop/views/pages/user/user.profile.vue:
follows-you: "Śledzi Cię"
menu: "メニュー"
menu: "Menu"
desktop/views/pages/user/user.header.vue:
posts: "Wpisy"
following: "Śledzeni"
@@ -1329,9 +1336,6 @@ mobile/views/components/drive.file-detail.vue:
nsfw: "NSFW"
mark-as-sensitive: "閲覧注意に設定"
unmark-as-sensitive: "閲覧注意を解除"
mobile/views/components/media-image.vue:
sensitive: "To jest zawartość NSFW"
click-to-show: "Naciśnij aby wyświetlić"
mobile/views/components/media-video.vue:
sensitive: "To jest zawartość NSFW"
click-to-show: "Naciśnij aby wyświetlić"

View File

@@ -129,7 +129,7 @@ common:
show-password: "パスワードを表示する"
do-not-use-in-production: "これは開発ビルドです。本番環境で使用しないでください。"
user-suspended: "このユーザーは凍結されています。"
is-remote-user: "このユーザー情報はコピーです。"
is-remote-user: "このユーザー情報は不正確な可能性があります。"
is-remote-post: "この投稿情報はコピーです。"
view-on-remote: "正確な情報を見る"
renoted-by: "{user}がRenote"
@@ -360,6 +360,10 @@ common/views/components/user-menu.vue:
report-abuse: "スパムを報告"
report-abuse-detail: "どのような迷惑行為を行っていますか?"
report-abuse-reported: "管理者に報告されました。ご協力ありがとうございました。"
silence: "サイレンス"
unsilence: "サイレンス解除"
suspend: "凍結"
unsuspend: "凍結解除"
common/views/components/poll.vue:
vote-to: "「{}」に投票する"
vote-count: "{}票"
@@ -482,6 +486,7 @@ common/views/components/profile-editor.vue:
account: "アカウント"
location: "場所"
description: "自己紹介"
you-can-include-hashtags: "ハッシュタグを含めることができます。"
language: "言語"
birthday: "誕生日"
avatar: "アイコン"
@@ -658,9 +663,6 @@ desktop/views/components/drive.vue:
create-folder: "フォルダーを作成"
upload: "ファイルをアップロード"
url-upload: "URLからアップロード"
desktop/views/components/media-image.vue:
sensitive: "閲覧注意"
click-to-show: "クリックして表示"
desktop/views/components/media-video.vue:
sensitive: "閲覧注意"
click-to-show: "クリックして表示"
@@ -875,6 +877,9 @@ desktop/views/components/settings.2fa.vue:
success: "設定が完了しました!"
failed: "設定に失敗しました。トークンに誤りがないかご確認ください。"
info: "次回サインインからは、同様にパスワードに加えてデバイスに表示されているトークンを入力します。"
common/views/components/media-image.vue:
sensitive: "閲覧注意"
click-to-show: "クリックして表示"
common/views/components/api-settings.vue:
intro: "APIを利用するには、上記のトークンを「i」というキーでパラメータに付加してリクエストします。"
caution: "アカウントを不正利用される可能性があるため、このトークンは第三者に教えないでください(アプリなどにも入力しないでください)。"
@@ -1142,6 +1147,8 @@ admin/views/users.vue:
unsuspend: "凍結の解除"
unsuspend-confirm: "凍結を解除しますか?"
unsuspended: "凍結を解除しました"
make-silence: "サイレンス"
unmake-silence: "サイレンスの解除"
verify: "公式アカウントにする"
verify-confirm: "公式アカウントにしますか?"
verified: "公式アカウントにしました"
@@ -1329,9 +1336,6 @@ mobile/views/components/drive.file-detail.vue:
nsfw: "閲覧注意"
mark-as-sensitive: "閲覧注意に設定"
unmark-as-sensitive: "閲覧注意を解除"
mobile/views/components/media-image.vue:
sensitive: "閲覧注意"
click-to-show: "クリックして表示"
mobile/views/components/media-video.vue:
sensitive: "閲覧注意"
click-to-show: "クリックして表示"

View File

@@ -129,7 +129,7 @@ common:
show-password: "パスワードを表示する"
do-not-use-in-production: "Эта сборка для разработчиков. Не используйте в продакшне."
user-suspended: "このユーザーは凍結されています。"
is-remote-user: "このユーザー情報はコピーです。"
is-remote-user: "このユーザー情報は不正確な可能性があります。"
is-remote-post: "この投稿情報はコピーです。"
view-on-remote: "正確な情報を見る"
renoted-by: "{user}がRenote"
@@ -360,6 +360,10 @@ common/views/components/user-menu.vue:
report-abuse: "スパムを報告"
report-abuse-detail: "どのような迷惑行為を行っていますか?"
report-abuse-reported: "管理者に報告されました。ご協力ありがとうございました。"
silence: "サイレンス"
unsilence: "サイレンス解除"
suspend: "凍結"
unsuspend: "凍結解除"
common/views/components/poll.vue:
vote-to: "「{}」に投票する"
vote-count: "{}票"
@@ -482,6 +486,7 @@ common/views/components/profile-editor.vue:
account: "アカウント"
location: "場所"
description: "自己紹介"
you-can-include-hashtags: "ハッシュタグを含めることができます。"
language: "言語"
birthday: "誕生日"
avatar: "アイコン"
@@ -658,9 +663,6 @@ desktop/views/components/drive.vue:
create-folder: "フォルダーを作成"
upload: "ファイルをアップロード"
url-upload: "URLからアップロード"
desktop/views/components/media-image.vue:
sensitive: "閲覧注意"
click-to-show: "クリックして表示"
desktop/views/components/media-video.vue:
sensitive: "閲覧注意"
click-to-show: "クリックして表示"
@@ -875,6 +877,9 @@ desktop/views/components/settings.2fa.vue:
success: "設定が完了しました!"
failed: "設定に失敗しました。トークンに誤りがないかご確認ください。"
info: "次回サインインからは、同様にパスワードに加えてデバイスに表示されているトークンを入力します。"
common/views/components/media-image.vue:
sensitive: "閲覧注意"
click-to-show: "クリックして表示"
common/views/components/api-settings.vue:
intro: "APIを利用するには、上記のトークンを「i」というキーでパラメータに付加してリクエストします。"
caution: "アカウントを不正利用される可能性があるため、このトークンは第三者に教えないでください(アプリなどにも入力しないでください)。"
@@ -1142,6 +1147,8 @@ admin/views/users.vue:
unsuspend: "凍結の解除"
unsuspend-confirm: "凍結を解除しますか?"
unsuspended: "凍結を解除しました"
make-silence: "サイレンス"
unmake-silence: "サイレンスの解除"
verify: "公式アカウントにする"
verify-confirm: "公式アカウントにしますか?"
verified: "公式アカウントにしました"
@@ -1329,9 +1336,6 @@ mobile/views/components/drive.file-detail.vue:
nsfw: "閲覧注意"
mark-as-sensitive: "閲覧注意に設定"
unmark-as-sensitive: "閲覧注意を解除"
mobile/views/components/media-image.vue:
sensitive: "閲覧注意"
click-to-show: "クリックして表示"
mobile/views/components/media-video.vue:
sensitive: "閲覧注意"
click-to-show: "クリックして表示"

View File

@@ -5,23 +5,23 @@ meta:
common:
misskey: "Fediverse中的一颗⭐"
about-title: "Fediverse中的一颗⭐"
about: "非常感谢您找到了Misskey。 Misskey是生于地球的<b>分布式微博SNS</b>。因为她处于Fediverse(由各种SNS组成的宇宙)中所以她与其他SNS相互连接。想要远离喧嚣的城市不如深入这个新的互联网来探索一下吧。"
about: "非常感谢您找到了Misskey。 Misskey是生于地球的<b>分布式微博SNS</b>。因为她处于Fediverse(由各种SNS组成的宇宙)中所以她与其他SNS相互连接。想要远离喧嚣的城市不如深入这个新的互联网来探索一下吧。"
intro:
title: "什么是 Misskey 呢?"
about: "Misskey是开源的<b>分散式微博SNS</b>。复杂的完全可定制的Ui各种各样的帖子反应提供集成管理系统和其他先进功能的免费文件存储。此外称为“Fediverse”的网络系统使我们能够与其他SNS的用户进行通信。比如如果你张贴一些东西那么你的帖子不仅会发送给Misskey还会发送到其他SNS平台。想象一下正如一颗行星和另一颗行星通过发送微波来进行通信一样。"
about: "Misskey是开源的<b>分散式微博SNS</b>。复杂的完全可定制的Ui各种各样的帖子反应提供集成管理系统和其他先进功能的免费文件存储。此外称为“Fediverse”的网络系统使我们能够与其他SNS的用户进行通信。比如如果你张贴一些东西那么你的帖子不仅会发送给Misskey还会发送到其他SNS平台。想象一下正如一颗行星和另一颗行星通过电磁波来进行通信一样。"
features: "功能"
rich-contents: "发布"
rich-contents-desc: "请分享您的想法,热门话题,以及任何您想与大家分享的内容。如果有需要的话,您可以使用各种语法来修饰文章,发布问卷调查,或者添加各种您喜欢的图像和视频等文件。"
reaction: "回应"
reaction-desc: "表达情绪的最简单方法。 Misskey允许您向其他帖子添加各种类型的回应。 一旦体验过Misskey的回应功能就再也不会想回到那些只有点赞功能的其他SNS上了。"
reaction-desc: "这是表达情绪的最简单方法。 Misskey允许您向其他帖子添加各种类型的回应。 一旦体验过Misskey的回应功能就再也不会想回到那些只有点赞功能的其他SNS上了。"
ui: "交互界面"
ui-desc: "世界上没有一个UI可以适合每一个人. 所以, Misskey 提供一个可以高度定制的UI交互界面. 您可以通过编辑, 调整布局, 放置可选择的小部件来轻松定制您的专属UI界面。"
drive: "Misskey 云盘"
drive-desc: "想要发布一张您已经上传过的照片吗? 想要组织,命名和为上传的文件创建文件夹吗? Misskey 云盘是一个最好的解决方案. "
outro: "进一步深挖 Misskey 的更多功能, 如果您感觉这个功能不适合我, 试试其他例子. 因为 Misskey 是一个分的 SNS, 这样您就可以很容易找到适合自己的一部分."
outro: "Misskey还有其他更多功能,请亲身体验一下吧。因为 Misskey 是一个分布式的 SNS,如果您感觉某个功能不适合自己,试试其他的吧。祝您玩得开心!"
adblock:
detected: "请关闭广告拦截器"
warning: "<strong>Misskey 不是广告网站</strong>如果您启用广告拦截器, 可能会导致某些功能无法正常使用。"
warning: "<strong>Misskey不会发布广告</strong>如果您启用广告拦截器, 可能会导致某些功能无法正常使用。"
application-authorization: "应用程序授权"
close: "关闭"
do-not-copy-paste: "请不要在这里输入或粘贴代码。您帐户可能会受到损害。"
@@ -30,21 +30,21 @@ common:
2fa: "双重身份验证"
got-it: "没问题"
customization-tips:
title: "客制化提示"
title: "自定义提示"
paragraph: "<p>主页定制允许您添加或删除, 拖放和重新排列小组件.</p></p>您可以通过<strong><strong>右键</strong>点击</strong>某些小部件来更改显示</p><p>若要删除小部件, 请将其拖到标头为<strong>「垃圾箱」</strong>的区域</p><p>如果您完成了定制过程,单击右上角的「完成」</p>"
gotit: "没问题!"
gotit: "明白了!"
notification:
file-uploaded: "文件已上传"
message-from: "信息来源 {}:"
message-from: "来自{}的消息:"
reversi-invited: "您已被邀请加入一场游戏"
reversi-invited-by: "被邀请 {}:"
notified-by: "通知 {}:"
reply-from: "回复 {}:"
quoted-by: "引用 {}:"
reversi-invited-by: "来自{}的邀请"
notified-by: "来自{}的通知"
reply-from: "来自{}的回复:"
quoted-by: "来自{}的引用:"
time:
unknown: "这是个啥??? 不知道哎"
unknown: "未知"
future: "未来"
just_now: "现在"
just_now: "刚刚"
seconds_ago: "{}秒前"
minutes_ago: "{}分前"
hours_ago: "{}小时前"
@@ -87,7 +87,7 @@ common:
public: "公开"
home: "首页"
home-desc: "仅发送至首页的时间线"
followers: "关注者"
followers: "粉丝"
followers-desc: "仅发送至粉丝"
specified: "指定用户"
specified-desc: "仅发送至指定用户"
@@ -95,22 +95,22 @@ common:
local-home: "首页(仅限本地)"
local-followers: "关注者(仅限本地)"
note-placeholders:
a: "你在干什么?"
a: "现在在做什么?"
b: "发生了什么?"
c: "你有什么想法?"
d: "你想要发布些什么吗?"
e: "写下来吧"
f: "等待你的书写..."
e: "写下来吧"
f: "等待您的发布..."
search: "搜索"
delete: "删除"
loading: "正在加载, 等着就好啦"
ok: "没问题"
loading: "正在加载"
ok: "OK"
update-available-title: "有可用更新"
update-available: "新的 Misskey 版本现已发布({newer}。目前版本{current}). 刷新页面以应用更新。"
my-token-regenerated: "您的 Token 已被重置, 您将自动登出。"
i-like-sushi: "相比于布丁来说, 我更喜欢寿司。"
show-reversi-board-labels: "在 Reversi 中显示行和列表签"
use-avatar-reversi-stones: "用头像作为 Reversi 中的 “石头”"
use-avatar-reversi-stones: "用头像作为黑白棋的棋子"
verified-user: "认证用户"
disable-animated-mfm: "在帖子中禁用动画文本"
suggest-recent-hashtags: "在帖子表单上显示最近流行的主题标签"
@@ -120,7 +120,7 @@ common:
show-via: "显示 via"
reduce-motion: "减弱UI中的动画效果"
this-setting-is-this-device-only: "设置仅在本设备中生效"
use-os-default-emojis: "使用设备系统默认的 emojis"
use-os-default-emojis: "使用设备系统默认的表情符号"
line-width: "线条宽度"
line-width-thin: "细"
line-width-normal: "正常"
@@ -129,48 +129,48 @@ common:
show-password: "显示密码"
do-not-use-in-production: "这是一个开发者测试版. 请勿在生产环境中使用."
user-suspended: "该用户已被冻结。"
is-remote-user: "用户信息已被复制."
is-remote-user: "用户信息可能不准确。"
is-remote-post: "该投稿已被复制."
view-on-remote: "查看准确的信息"
renoted-by: "由 {user} Renote"
error:
title: "哦不, 发生了一些问题! :("
title: "出现问题"
retry: "重试"
reversi:
drawn: "平局"
my-turn: "轮到你了"
opponent-turn: "轮到对手了"
turn-of: "{name}转折点"
turn-of: "{name}的回合"
past-turn-of: "轮到{name}的回合了"
won: "{name}获胜"
black: "黑"
white: "白"
total: "计"
this-turn: "Turn {count}"
total: "计"
this-turn: "{count}回合"
widgets:
analog-clock: "指针时钟"
profile: "简介"
analog-clock: "模拟时钟"
profile: "个人资料"
calendar: "日历"
timemachine: "时光机"
timemachine: "日历 (时间机器)"
activity: "动态"
rss: "RSS阅"
rss: "RSS阅读器"
memo: "便签"
trends: "趋势"
photo-stream: "图片轮播"
photo-stream: "照片流"
posts-monitor: "投稿图表"
slideshow: "幻灯片"
version: "版本"
broadcast: "广播"
notifications: "通知"
users: "推荐用户"
polls: "投票"
polls: "调查问卷"
post-form: "投稿形式"
server: "服务器信息"
nav: "导航"
tips: "提示"
hashtags: "标签"
dev: "构建应用程序失败,请再试一次。"
ai-chan-kawaii: "Ai-chan kawaii!"
ai-chan-kawaii: "小蓝真可爱"
you: "您"
auth/views/form.vue:
share-access: "您要允许<i>{name}</i>来访问您的账户吗?"
@@ -178,8 +178,8 @@ auth/views/form.vue:
account-read: "查看账户信息"
account-write: "修改账户信息"
note-write: "投稿。"
like-write: "评价投稿。"
following-write: "关注和不关注。"
like-write: "点赞或取消赞。"
following-write: "关注或取消关注。"
drive-read: "查看您的云盘"
drive-write: "上传/删除您云盘中的文件。"
notification-read: "查看通知。"
@@ -187,7 +187,7 @@ auth/views/form.vue:
cancel: "取消"
accept: "允许访问。"
auth/views/index.vue:
loading: "正在加载, 请耐心等待哦~"
loading: "正在加载"
denied: "已拒绝应用程序授权。"
denied-paragraph: "这个应用程序将不会访问您的账户"
already-authorized: "这个应用程序已授权。"
@@ -201,17 +201,17 @@ common/views/components/games/reversi/reversi.vue:
waiting-for: "等待 {}"
cancel: "取消"
common/views/components/games/reversi/reversi.game.vue:
surrender: "投降"
surrendered: "投降"
is-llotheo: "石头少的一方获胜"
looped-map: "环状地图"
can-put-everywhere: "可以意放置"
surrender: "认输"
surrendered: "已认输"
is-llotheo: "棋子较少一方获胜(LLoTheO规则)"
looped-map: "环形棋盘"
can-put-everywhere: "可以下在任意放置"
common/views/components/games/reversi/reversi.index.vue:
title: "Misskey Reversi"
sub-title: "和你的朋友一起玩 Reversi!"
title: "Misskey 黑白棋"
sub-title: "和其他人一起来玩Misskey黑白棋"
invite: "邀请"
rule: "游戏说明"
rule-desc: "Reversi是与对方交替地把石头放在板上把对方的石头夹在自己的颜色上最终留下的石头多的人获胜。"
rule-desc: "黑白棋是一种棋盘游戏。两人交替在棋盘上落子,并将该棋子和另一个己方棋子之间的对方棋子转换成自己的颜色。最终保留最多棋子的人获胜。"
mode-invite: "邀请"
mode-invite-desc: "邀请指定用户参加游戏"
invitations: "您收到了一则邀请!"
@@ -219,28 +219,28 @@ common/views/components/games/reversi/reversi.index.vue:
all-games: "所有游戏"
enter-username: "输入用户名"
game-state:
ended: "完成"
playing: "进行中"
ended: "结束"
playing: "游戏进行中"
common/views/components/games/reversi/reversi.room.vue:
settings-of-the-game: "游戏设置"
choose-map: "选择一个地图"
choose-map: "棋盘选择"
random: "随机"
black-or-white: "黑/白"
black-is: "{}是黑"
rules: "规则"
is-llotheo: "较少一方获胜"
looped-map: "环状地图"
can-put-everywhere: "可以意放置"
is-llotheo: "棋子较少一方获胜(LLoTheO规则)"
looped-map: "环形棋盘"
can-put-everywhere: "可以下在任意放置"
settings-of-the-bot: "机器人设定"
this-game-is-started-soon: "游戏即将在数秒后开始"
waiting-for-other: "等待对手准备"
waiting-for-me: "等待您的准备"
waiting-for-both: "准备中"
cancel: "取消"
ready: "准备好啦"
ready: "准备完成"
cancel-ready: "取消准备"
common/views/components/connect-failed.vue:
title: "无法连接服务器"
title: "无法连接服务器"
description: "您的网络连接可能出现了问题, 或是远程服务器暂时不可用. 请稍后{重试}."
thanks: "感谢您使用 Misskey"
troubleshoot: "故障排除"
@@ -256,9 +256,9 @@ common/views/components/connect-failed.troubleshooter.vue:
no-network: "无网络连接"
no-network-desc: "请确保您已连接至互联网"
no-internet: "无网络连接"
no-internet-desc: "请确保您已连接至互联网"
no-internet-desc: "网络已连接但无法连接到Internet。 请确保您的PC的Internet连接正常。"
no-server: "无法连接到 Misskey 服务器"
no-server-desc: "您设备与互联网的网络连接正常, 但是无法连接至 Misskey 服务器. 这可能是服务器暂时不可用或正在维护. 请稍后再试."
no-server-desc: "您设备与互联网的网络连接正常但是无法连接至 Misskey 服务器这可能是服务器暂时不可用或正在维护请稍后再试"
success: "成功连接至 Misskey 服务器"
success-desc: "看起来我们连接正常. 请刷新网页."
flush: "清除缓存"
@@ -268,18 +268,18 @@ common/views/components/media-banner.vue:
click-to-show: "点击以显示"
common/views/components/theme.vue:
theme: "主题"
light-theme: "主题"
dark-theme: "黑暗模式主题"
light-themes: "亮主题"
dark-themes: "暗主题"
light-theme: "亮色模式使用的主题"
dark-theme: "暗色模式使用的主题"
light-themes: "亮主题"
dark-themes: "暗主题"
install-a-theme: "安装一个主题"
theme-code: "主题代码"
install: "安装"
installed: "\"{}\" 已安装"
installed: "\"{}\" 已安装"
create-a-theme: "创建一个主题"
save-created-theme: "保存主题"
primary-color: "色"
secondary-color: "合成色"
primary-color: "主要颜色"
secondary-color: "次要颜色"
text-color: "文本颜色"
base-theme: "基础主题"
base-theme-light: "亮"
@@ -289,7 +289,7 @@ common/views/components/theme.vue:
preview-created-theme: "预览"
invalid-theme: "无效主题"
already-installed: "这个主题已经被安装。"
saved: "保存"
saved: "保存"
manage-themes: "主题管理"
builtin-themes: "标准主题"
my-themes: "我的主题"
@@ -299,14 +299,14 @@ common/views/components/theme.vue:
uninstalled: "\"{}\" 已被卸载"
author: "作者"
desc: "描述"
export: "出"
import: "入"
export: "出"
import: "入"
import-by-code: "或者粘贴代码"
theme-name-required: "必须填写主题名称"
common/views/components/cw-button.vue:
hide: "隐藏"
show: "查看更多"
chars: "{count}"
chars: "{count}个字符"
files: "{count} 个文件"
poll: "调查问卷"
common/views/components/messaging.vue:
@@ -322,20 +322,20 @@ common/views/components/messaging-room.vue:
common/views/components/messaging-room.form.vue:
input-message-here: "在此键入信息"
send: "发送"
attach-from-local: "从设备中添加文件"
attach-from-local: "从电脑中添加文件"
attach-from-drive: "从云盘中添加文件"
only-one-file-attached: "在信息中只允许添加一个附件"
common/views/components/messaging-room.message.vue:
is-read: "已"
deleted: "这条信息已被删除"
is-read: "已"
deleted: "此消息已被删除"
common/views/components/nav.vue:
about: "关于"
about: "关于 Misskey"
stats: "统计"
status: "状态"
wiki: "百科 (Wiki)"
wiki: "维基百科"
donors: "捐赠者"
repository: ""
develop: "开发"
repository: "代码库"
develop: "开发人员"
feedback: "反馈"
common/views/components/note-menu.vue:
mention: "提到"
@@ -350,16 +350,20 @@ common/views/components/note-menu.vue:
delete-confirm: "确定删除这个投稿吗?"
remote: "显示原始投稿"
common/views/components/user-menu.vue:
mention: "提"
mute: "静音"
unmute: "取消静音"
mention: "提"
mute: "免打扰"
unmute: "解除免打扰"
block: "屏蔽"
unblock: "取消屏蔽"
push-to-list: "添加至列表"
select-list: "请选择一个列表"
report-abuse: "举报垃圾邮件"
report-abuse: "举报骚扰"
report-abuse-detail: "做了什么骚扰的行为?"
report-abuse-reported: "已报告给管理员。 非常感谢你的合作。"
silence: "禁言"
unsilence: "解除禁言"
suspend: "冻结"
unsuspend: "解除冻结"
common/views/components/poll.vue:
vote-to: "为\"{}\"投票"
vote-count: "{}票"
@@ -374,16 +378,16 @@ common/views/components/poll-editor.vue:
add: "+添加一个选项"
destroy: "放弃投票"
common/views/components/reaction-picker.vue:
choose-reaction: "选择应"
choose-reaction: "选择应"
common/views/components/emoji-picker.vue:
custom-emoji: "自定义 Emoji"
custom-emoji: "自定义表情符号"
people: "人"
animals-and-nature: "动物与自然"
food-and-drink: "食物与饮品"
activity: "活动"
travel-and-places: "旅行和地点"
travel-and-places: "位置"
objects: "物品"
symbols: "标志"
symbols: "符号"
flags: "旗帜"
common/views/components/signin.vue:
username: "用户名"
@@ -395,7 +399,7 @@ common/views/components/signin.vue:
signin-with-twitter: "用 Twitter 登录"
signin-with-github: "用 GitHub 登录"
signin-with-discord: "用 Discord 登录"
login-failed: "登录失败。请确保您已输入恰当的用户名和密码。"
login-failed: "登录失败。请检查用户名和密码。"
common/views/components/signup.vue:
invitation-code: "邀请码"
invitation-info: "如果您没有邀请码,请联系<a href=\"{}\">管理员</a>。"
@@ -404,24 +408,24 @@ common/views/components/signup.vue:
available: "可用"
unavailable: "不可用"
error: "网络错误"
invalid-format: "可以用字母数字和_。"
too-short: "不可以留空哦~"
too-long: "20字以内。"
invalid-format: "可使用大小写英文字母数字和下划线。"
too-short: "请至少输入1个字符"
too-long: "请不要超过20个字符"
password: "密码"
password-placeholder: "推荐使用8个字符以上的密码。"
weak-password: "弱强度密码"
normal-password: "适中强度的密码"
strong-password: "没问题"
weak-password: "密码强度:弱"
normal-password: "密码强度:中等"
strong-password: "密码强度:强"
retype: "重新输入"
retype-placeholder: "重新入您的密码"
retype-placeholder: "重新入您的密码"
password-matched: "确认"
password-not-matched: "密码不一致"
recaptcha: "证"
recaptcha: "证"
create: "创建一个账户"
some-error: "由于某种原因,创建帐户失败。请再试一次。"
common/views/components/special-message.vue:
new-year: "新年快乐哦~"
christmas: "Merry Christmas!"
christmas: "圣诞快乐!"
common/views/components/stream-indicator.vue:
connecting: "连接中"
reconnecting: "重新连接中"
@@ -436,8 +440,8 @@ common/views/components/notification-settings.vue:
common/views/components/integration-settings.vue:
title: "服务合作"
connect: "连接"
disconnect: "连接"
connected-to: "您的账号已连接下社交账号"
disconnect: "断开连接"
connected-to: "您的账号已连接下社交账号"
common/views/components/github-setting.vue:
description: "当您用GitHub连接Misskey账户后您将能够看到有关您自己的信息并且您将能够使用GitHub登录。"
connected-to: "此账户已连接GitHub"
@@ -451,7 +455,7 @@ common/views/components/discord-setting.vue:
detail: "详细信息..."
reconnect: "重新连接"
connect: "连接您的Discord账户"
disconnect: "连接"
disconnect: "断开连接"
common/views/components/uploader.vue:
waiting: "等待中"
common/views/components/visibility-chooser.vue:
@@ -463,50 +467,51 @@ common/views/components/visibility-chooser.vue:
specified: "直接"
specified-desc: "仅发送至指定用户"
local-public: "公开(仅限本地)"
local-public-desc: "不要发布到公开"
local-public-desc: "不要公开发布"
local-home: "首页(仅限本地)"
local-followers: "关注者(仅限本地)"
common/views/components/trends.vue:
count: "{} 被提到"
empty: "没有流行的标签"
empty: "没有趋势"
common/views/components/language-settings.vue:
title: "显示语言"
pick-language: "选择一个语言"
pick-language: "选择语言"
recommended: "推荐"
auto: "自动"
specify-language: "指定语言"
info: "你需要刷新这个页面来应用更改。"
info: "更改将在刷新页面后生效。"
common/views/components/profile-editor.vue:
title: "简况"
title: "个人资料"
name: "名称"
account: "账户"
location: "位置"
description: "关于我"
description: "个人简介"
you-can-include-hashtags: "您可以包含一个哈希标签。"
language: "语言"
birthday: "生日"
avatar: "头像"
banner: "背景"
is-cat: "这个账户是 Cat"
is-bot: "个账户是机器人"
banner: "横幅背景"
is-cat: "这个账户是CAT"
is-bot: "个账户是BOT"
is-locked: "关注者请求需要批准"
careful-bot: "机器人的关注者请求需要批准"
careful-bot: "BOT的关注者请求需要批准"
auto-accept-followed: "自动同意来自您关注的人的关注申请"
advanced: "其他选项"
advanced: "其他"
privacy: "隐私"
save: "保存"
saved: "更新配置文件成功"
saved: "您的个人资料已保存"
uploading: "正在上传"
upload-failed: "上传失败"
email: "邮件设置"
email-address: "电子邮件地址"
email-verified: "电子邮件地址已验证"
email-not-verified: "电子邮件地址还没有验证哦, 请检查一下收信箱吧~"
email-not-verified: "邮件地址尚未验证。 请检查您的邮箱。"
common/views/components/user-list-editor.vue:
users: "用户"
rename: "重命名列表"
delete: "删除列表"
remove-user: "从此列表中删除"
delete-are-you-sure: "删除列表 \"$1\""
delete-are-you-sure: "删除列表“$1”"
deleted: "已删除"
common/views/widgets/broadcast.vue:
fetching: "确认中"
@@ -517,9 +522,9 @@ common/views/widgets/calendar.vue:
year: "{}年"
month: "{}月"
day: "{}日"
today: "今天:"
this-month: "本月:"
this-year: "今年:"
today: "今天"
this-month: "本月"
this-year: "今年"
common/views/widgets/photo-stream.vue:
title: "图片轮播"
no-photos: "没有图片"
@@ -557,11 +562,11 @@ common/views/widgets/tips.vue:
tips-line19: "可以在浏览器外部分离多个窗口。"
tips-line20: "日历小部件的百分比显示经过的时间百分比。"
tips-line21: "您也可以使用API开发机器人。"
tips-line23: "Ai-chan kawaii!"
tips-line23: "小蓝很可爱"
tips-line24: "Misskey自2014年开始运营。"
tips-line25: "在与通知功能兼容的浏览器中您可以在Misskey未打开的情况下接收通知"
common/views/pages/not-found.vue:
page-not-found: "啊喔, 页面走丢了..."
page-not-found: "您要找的网页不存在。"
common/views/pages/follow.vue:
signed-in-as: "用 {}登录"
following: "正在关注"
@@ -583,7 +588,7 @@ desktop:
invalid-filetype: "不接受此文件类型"
desktop/views/components/activity.chart.vue:
total: "黑 ... 总计"
notes: "蓝 ... Notes"
notes: "蓝 ... 投稿"
replies: "红 ... 回复"
renotes: "绿 ... 转发"
desktop/views/components/activity.vue:
@@ -591,9 +596,9 @@ desktop/views/components/activity.vue:
toggle: "切换显示"
desktop/views/components/calendar.vue:
title: "{year}年{month}月"
prev: "前一个月"
next: "下个月"
go: "点击已启用时间旅行"
prev: "个月"
next: "下个月"
go: "点击按时间浏览"
desktop/views/components/choose-file-from-drive-window.vue:
chosen-files: "{count}文件已被选择"
upload: "从设备中上传文件"
@@ -658,9 +663,6 @@ desktop/views/components/drive.vue:
create-folder: "创建文件夹"
upload: "上传文件"
url-upload: "从URL上传"
desktop/views/components/media-image.vue:
sensitive: "阅读注意"
click-to-show: "点击以显示"
desktop/views/components/media-video.vue:
sensitive: "阅读注意"
click-to-show: "点击以显示"
@@ -764,7 +766,7 @@ desktop/views/pages/user-following-or-followers.vue:
desktop/views/components/settings-window.vue:
settings: "设置"
desktop/views/components/settings.vue:
profile: "个人简介"
profile: "个人资料"
notification: "通知"
apps: "应用程序"
tags: "标签"
@@ -808,7 +810,7 @@ desktop/views/components/settings.vue:
show-my-renotes: "在时间表中显示Renote"
show-renoted-my-notes: "在时间线上显示我的Renote"
show-local-renotes: "在时间线中显示Local Renote(s)"
show-maps: "显示地图以显示位置"
show-maps: "自动显示地图"
remain-deleted-note: "继续显示已删除的帖子"
deck-column-align: "列对齐设置"
deck-column-align-center: "中央"
@@ -875,6 +877,9 @@ desktop/views/components/settings.2fa.vue:
success: "设置完成"
failed: "设置失败, 请确保您的密钥是正确的。"
info: "从下次登录Misskey时您的设备上显示的令牌以及密码也是必需的。"
common/views/components/media-image.vue:
sensitive: "阅读注意"
click-to-show: "点击查看"
common/views/components/api-settings.vue:
intro: "要访问API请将此标记设置为请求参数的关键字“i”。"
caution: "请勿将此令牌输入任何应用,也不要将此令牌告诉其他人,否则您的账户可能会受到损害。"
@@ -942,7 +947,7 @@ desktop/views/components/ui.header.vue:
welcome-back: "欢迎回来!"
adjective: "先生"
desktop/views/components/ui.header.account.vue:
profile: "您的个人资料"
profile: "个人资料"
favorites: "最爱"
lists: "列表"
follow-requests: "关注申请"
@@ -1126,30 +1131,32 @@ admin/views/drive.vue:
deleted: "已删除"
mark-as-sensitive: "标记为“敏感”"
unmark-as-sensitive: "取消标记为“敏感”"
marked-as-sensitive: "标记为关注"
unmarked-as-sensitive: "解除关注标记"
marked-as-sensitive: "标记为“敏感”"
unmarked-as-sensitive: "取消标记为“敏感”"
admin/views/users.vue:
operation: "操作"
username-or-userid: "用户名或用户ID"
user-not-found: "用户不存在"
lookup: "订阅"
reset-password: "密码重置"
reset-password-confirm: "パスワードをリセットしますか"
reset-password-confirm: "是否重置密码"
password-updated: "密码为「{password}」"
suspend: "被冻结"
suspend-confirm: "凍結しますか"
suspend-confirm: "是否冻结"
suspended: "成功冻结用户"
unsuspend: "已解除冻结"
unsuspend-confirm: "凍結を解除しますか"
unsuspend-confirm: "是否解除冻结"
unsuspended: "已成功解除用户冻结"
make-silence: "禁言"
unmake-silence: "解除禁言"
verify: "认证用户"
verify-confirm: "公式アカウントにしますか"
verify-confirm: "是否官方账号"
verified: "此账户已被认证"
unverify: "解除账户认证"
unverify-confirm: "公式アカウントを解除しますか"
unverify-confirm: "是否解除官方账号认证"
unverified: "该帐户未经认证"
update-remote-user: "リモートユーザー情報の更新"
remote-user-updated: "リモートユーザー情報を更新しました"
update-remote-user: "更新远程用户信息"
remote-user-updated: "远程用户信息已更新"
users:
title: "用户"
sort:
@@ -1178,7 +1185,7 @@ admin/views/moderators.vue:
title: "注册版主"
add: "注册"
added: "已注册版主。"
remove: "解除"
remove: "取消"
removed: "取消注册版主"
admin/views/emoji.vue:
add-emoji:
@@ -1192,12 +1199,12 @@ admin/views/emoji.vue:
info: "我们建议使用50KB以下的PNG图像。"
added: "Emoji 已添加"
emojis:
title: "Emojis"
title: "表情符号列表"
update: "更新"
remove: "移除"
updated: "已更新"
remove-emoji:
are-you-sure: "删除 \"%1$s\"?"
are-you-sure: "删除「$1」?"
removed: "已删除"
admin/views/announcements.vue:
announcements: "公告"
@@ -1208,7 +1215,7 @@ admin/views/announcements.vue:
text: "内容"
saved: "已保存"
_remove:
are-you-sure: "删除 \"%1$s\"?"
are-you-sure: "删除「$1」?"
removed: "已删除"
admin/views/hashtags.vue:
hided-tags: "隐藏标签"
@@ -1249,15 +1256,15 @@ desktop/views/pages/user-list.users.vue:
username: "用户名"
desktop/views/pages/user/user.followers-you-know.vue:
title: "您可能认识的关注者"
loading: "正在加载, 请耐心等待哦~"
loading: "正在加载"
no-users: "没有你知道的关注者"
desktop/views/pages/user/user.friends.vue:
title: "活跃用户"
loading: "正在加载, 等着就好啦"
loading: "正在加载"
no-users: "没有活跃用户"
desktop/views/pages/user/user.photos.vue:
title: "照片"
loading: "正在加载, 请耐心等待哦~"
loading: "正在加载"
no-photos: "没有图片"
desktop/views/pages/user/user.profile.vue:
follows-you: "关注您"
@@ -1308,7 +1315,7 @@ mobile/views/components/drive.vue:
nothing-in-drive: "云盘上没有任何东西"
folder-is-empty: "这文件夹是空的"
prompt: "您想要干什么呢?(请输入数字):<1 → 上传文件 | 2 → 从URL上传文件 | 3 → 创建新文件夹 | 4 → 更改这个文件夹的名称 | 5 → 移动这个文件夹 | 6 → 删除这个文件夹>"
deletion-alert: "抱歉! 尚未删除文件夹。"
deletion-alert: "抱歉 删除文件夹功能尚未实现。"
folder-name: "文件夹名称"
root-rename-alert: "您目前在root模式; 它无法重命名,因为它不是文件夹。 导航到要重命名的文件夹,然后重试。"
root-move-alert: "您目前在root模式; 它无法移动,因为它不是文件夹。 导航到要移动的文件夹,然后重试。"
@@ -1329,9 +1336,6 @@ mobile/views/components/drive.file-detail.vue:
nsfw: "阅读注意"
mark-as-sensitive: "标记为“敏感”"
unmark-as-sensitive: "取消标记为“敏感”"
mobile/views/components/media-image.vue:
sensitive: "阅读注意"
click-to-show: "点击以显示"
mobile/views/components/media-video.vue:
sensitive: "阅读注意"
click-to-show: "点击以显示"

View File

@@ -1,8 +1,8 @@
{
"name": "misskey",
"author": "syuilo <i@syuilo.com>",
"version": "10.79.0",
"clientVersion": "2.0.13835",
"version": "10.81.0",
"clientVersion": "2.0.14026",
"codename": "nighthike",
"main": "./built/index.js",
"private": true,
@@ -19,10 +19,13 @@
"test": "gulp test",
"format": "gulp format"
},
"resolutions": {
"terser": "3.14.1"
},
"dependencies": {
"@fortawesome/fontawesome-svg-core": "1.2.12",
"@fortawesome/fontawesome-svg-core": "1.2.14",
"@fortawesome/free-brands-svg-icons": "5.6.3",
"@fortawesome/free-regular-svg-icons": "5.5.0",
"@fortawesome/free-regular-svg-icons": "5.7.0",
"@fortawesome/free-solid-svg-icons": "5.6.3",
"@fortawesome/vue-fontawesome": "0.1.5",
"@koa/cors": "2.2.3",
@@ -31,12 +34,11 @@
"@types/bcryptjs": "2.4.2",
"@types/chai-http": "3.0.5",
"@types/dateformat": "3.0.0",
"@types/debug": "0.0.31",
"@types/deep-equal": "1.0.1",
"@types/double-ended-queue": "2.1.0",
"@types/elasticsearch": "5.0.30",
"@types/file-type": "10.6.0",
"@types/gulp": "3.8.36",
"@types/gulp": "4.0.5",
"@types/gulp-mocha": "0.0.32",
"@types/gulp-rename": "0.0.33",
"@types/gulp-replace": "0.0.31",
@@ -45,27 +47,29 @@
"@types/is-root": "1.0.0",
"@types/is-svg": "3.0.0",
"@types/is-url": "1.2.28",
"@types/js-yaml": "3.11.4",
"@types/js-yaml": "3.12.0",
"@types/katex": "0.5.0",
"@types/koa": "2.0.48",
"@types/koa-bodyparser": "5.0.2",
"@types/koa-compress": "2.0.8",
"@types/koa-cors": "0.0.0",
"@types/koa-favicon": "2.0.19",
"@types/koa-logger": "3.1.1",
"@types/koa-mount": "3.0.1",
"@types/koa-multer": "1.0.0",
"@types/koa-router": "7.0.38",
"@types/koa-router": "7.0.39",
"@types/koa-send": "4.1.1",
"@types/koa-views": "2.0.3",
"@types/koa__cors": "2.2.3",
"@types/minio": "7.0.1",
"@types/mkdirp": "0.5.2",
"@types/mocha": "5.2.5",
"@types/mongodb": "3.1.18",
"@types/ms": "0.7.30",
"@types/mongodb": "3.1.19",
"@types/node": "10.12.18",
"@types/nodemailer": "4.6.5",
"@types/nprogress": "0.0.29",
"@types/oauth": "0.9.1",
"@types/parse5": "5.0.0",
"@types/parsimmon": "1.10.0",
"@types/portscanner": "2.1.0",
"@types/pug": "2.0.4",
@@ -74,16 +78,18 @@
"@types/redis": "2.8.10",
"@types/request": "2.48.1",
"@types/request-promise-native": "1.0.15",
"@types/request-stats": "3.0.0",
"@types/rimraf": "2.0.2",
"@types/seedrandom": "2.4.27",
"@types/sharp": "0.21.0",
"@types/sharp": "0.21.1",
"@types/showdown": "1.9.2",
"@types/speakeasy": "2.0.3",
"@types/systeminformation": "3.23.1",
"@types/tinycolor2": "1.4.1",
"@types/tmp": "0.0.33",
"@types/uuid": "3.4.4",
"@types/webpack": "4.4.21",
"@types/web-push": "3.3.0",
"@types/webpack": "4.4.24",
"@types/webpack-stream": "3.2.10",
"@types/websocket": "0.0.40",
"@types/ws": "6.0.1",
@@ -95,7 +101,7 @@
"bcryptjs": "2.4.3",
"bee-queue": "1.2.2",
"bootstrap-vue": "2.0.0-rc.11",
"cafy": "12.0.0",
"cafy": "12.1.0",
"chai": "4.2.0",
"chai-http": "4.2.1",
"chalk": "2.4.2",
@@ -104,24 +110,22 @@
"css-loader": "1.0.1",
"cssnano": "4.1.8",
"dateformat": "3.0.3",
"debug": "4.1.0",
"deep-equal": "1.0.1",
"deepcopy": "0.6.3",
"diskusage": "1.0.0",
"double-ended-queue": "2.1.0-0",
"elasticsearch": "15.3.0",
"elasticsearch": "15.3.1",
"emojilib": "2.4.0",
"escape-regexp": "0.0.1",
"eslint": "5.12.0",
"eslint-plugin-vue": "5.1.0",
"eventemitter3": "3.1.0",
"feed": "2.0.2",
"file-loader": "2.0.0",
"file-type": "10.7.0",
"fuckadblock": "3.2.1",
"gulp": "3.9.1",
"gulp": "4.0.0",
"gulp-cssnano": "2.1.3",
"gulp-imagemin": "4.1.0",
"gulp-imagemin": "5.0.3",
"gulp-mocha": "6.0.0",
"gulp-rename": "1.4.0",
"gulp-replace": "1.0.0",
@@ -131,7 +135,7 @@
"gulp-typescript": "5.0.0",
"gulp-uglify": "3.0.1",
"gulp-util": "3.0.8",
"gulp-yaml": "2.0.2",
"gulp-yaml": "2.0.3",
"hard-source-webpack-plugin": "0.13.1",
"html-minifier": "3.5.21",
"http-signature": "1.2.0",
@@ -198,7 +202,7 @@
"rndstr": "1.0.0",
"s-age": "1.1.2",
"seedrandom": "2.4.4",
"sharp": "0.21.1",
"sharp": "0.21.3",
"showdown": "1.9.0",
"showdown-highlightjs-extension": "0.1.2",
"speakeasy": "2.0.0",
@@ -207,7 +211,7 @@
"stylus": "0.54.5",
"stylus-loader": "3.0.2",
"summaly": "2.2.0",
"systeminformation": "3.52.2",
"systeminformation": "3.54.0",
"syuilo-password-strength": "0.0.1",
"terser-webpack-plugin": "1.2.1",
"textarea-caret": "3.1.0",
@@ -223,11 +227,12 @@
"url-loader": "1.1.2",
"uuid": "3.3.2",
"v-animate-css": "0.0.3",
"video-thumbnail-generator": "1.1.3",
"vue": "2.5.17",
"vue-color": "2.7.0",
"vue-content-loading": "1.5.3",
"vue-cropperjs": "3.0.0",
"vue-i18n": "8.7.0",
"vue-i18n": "8.8.0",
"vue-js-modal": "1.3.28",
"vue-loader": "15.5.1",
"vue-marquee-text-component": "1.1.1",
@@ -235,7 +240,7 @@
"vue-router": "3.0.2",
"vue-sequential-entrance": "1.1.3",
"vue-style-loader": "4.1.2",
"vue-svg-inline-loader": "1.2.7",
"vue-svg-inline-loader": "1.2.10",
"vue-template-compiler": "2.5.17",
"vuedraggable": "2.17.0",
"vuewordcloud": "18.7.11",
@@ -246,7 +251,7 @@
"webpack": "4.28.4",
"webpack-cli": "3.2.1",
"websocket": "1.0.28",
"ws": "6.1.2",
"ws": "6.1.3",
"xev": "2.0.1"
}
}

17
src/@types/deepcopy.d.ts vendored Normal file
View File

@@ -0,0 +1,17 @@
declare module 'deepcopy';
declare namespace deepcopy {
type DeepcopyCustomizerValueType = 'Object';
type DeepcopyCustomizer<T> = (
value: T,
valueType: DeepcopyCustomizerValueType) => T;
interface DeepcopyOptions<T> {
customizer: DeepcopyCustomizer<T>
}
export function deepcopy<T>(
value: T,
options?: DeepcopyOptions<T> | DeepcopyCustomizer<T>): T;
}

75
src/@types/http-signature.d.ts vendored Normal file
View File

@@ -0,0 +1,75 @@
declare module 'http-signature' {
import { IncomingMessage, ClientRequest } from 'http';
interface ISignature {
keyId: string;
algorithm: string;
headers: string[];
signature: string;
}
interface IOptions {
headers?: string[];
algorithm?: string;
strict?: boolean;
authorizationHeaderName?: string;
}
interface IParseRequestOptions extends IOptions {
clockSkew?: number;
}
interface IParsedSignature {
scheme: string;
params: ISignature;
signingString: string;
}
type RequestSignerConstructorOptions =
IRequestSignerConstructorOptionsFromProperties |
IRequestSignerConstructorOptionsFromFunction;
interface IRequestSignerConstructorOptionsFromProperties {
keyId: string;
key: string | Buffer;
algorithm?: string;
}
interface IRequestSignerConstructorOptionsFromFunction {
sign?: (data: string, cb: (err: any, sig: ISignature) => void) => void;
}
class RequestSigner {
constructor(options: RequestSignerConstructorOptions);
public writeHeader(header: string, value: string): string;
public writeDateHeader(): string;
public writeTarget(method: string, path: string): void;
public sign(cb: (err: any, authz: string) => void): void;
}
interface ISignRequestOptions extends IOptions {
keyId: string;
key: string;
httpVersion?: string;
}
export function parse(request: IncomingMessage, options?: IParseRequestOptions): IParsedSignature;
export function parseRequest(request: IncomingMessage, options?: IParseRequestOptions): IParsedSignature;
export function sign(request: ClientRequest, options: ISignRequestOptions): boolean;
export function signRequest(request: ClientRequest, options: ISignRequestOptions): boolean;
export function createSigner(): RequestSigner;
export function isSigner(obj: any): obj is RequestSigner;
export function sshKeyToPEM(key: string): string;
export function sshKeyFingerprint(key: string): string;
export function pemToRsaSSHKey(pem: string, comment: string): string;
export function verify(parsedSignature: IParsedSignature, pubkey: string | Buffer): boolean;
export function verifySignature(parsedSignature: IParsedSignature, pubkey: string | Buffer): boolean;
export function verifyHMAC(parsedSignature: IParsedSignature, secret: string): boolean;
}

7
src/@types/is-root.d.ts vendored Normal file
View File

@@ -0,0 +1,7 @@
declare module 'is-root' {
function isRoot(): boolean;
namespace isRoot {} // Hack
export = isRoot;
}

15
src/@types/koa-json-body.d.ts vendored Normal file
View File

@@ -0,0 +1,15 @@
declare module 'koa-json-body' {
import { Middleware } from 'koa';
interface IKoaJsonBodyOptions {
strict: boolean;
limit: string;
fallback: boolean;
}
function koaJsonBody(opt?: IKoaJsonBodyOptions): Middleware;
namespace koaJsonBody {} // Hack
export = koaJsonBody;
}

17
src/@types/lookup-dns-cache.d.ts vendored Normal file
View File

@@ -0,0 +1,17 @@
declare module 'lookup-dns-cache' {
type IPv4 = 4;
type IPv6 = 6;
type Family = IPv4 | IPv6 | undefined;
interface IRunOptions {
family?: Family;
all?: boolean;
}
type RunCallback = (error: Error | null, address?: string | string[], family?: Family) => void;
export function lookup(hostname: string, options: IRunOptions | Family, callback: RunCallback): {} | undefined;
export function lookup(hostname: string, callback: RunCallback): {} | undefined;
}

3
src/@types/meta.json.d.ts vendored Normal file
View File

@@ -0,0 +1,3 @@
declare module '*/meta.json' {
const version: string;
}

12
src/@types/ms.d.ts vendored Normal file
View File

@@ -0,0 +1,12 @@
declare module 'ms' {
interface IMSOptions {
long: boolean;
}
function ms(value: string): number;
function ms(value: number, options?: IMSOptions): string;
namespace ms {} // Hack
export = ms;
}

19
src/@types/nested-property.d.ts vendored Normal file
View File

@@ -0,0 +1,19 @@
declare module 'nested-property' {
interface IHasNestedPropertyOptions {
own?: boolean;
}
interface IIsInNestedPropertyOptions {
validPath?: boolean;
}
export function set<T>(object: T, property: string, value: any): T;
export function get(object: object, property: string): any;
export function has(object: object, property: string, options?: IHasNestedPropertyOptions): boolean;
export function hasOwn(object: object, property: string, options?: IHasNestedPropertyOptions): boolean;
export function isIn(object: object, property: string, objectInPath: object, options?: IIsInNestedPropertyOptions): boolean;
}

3
src/@types/package.json.d.ts vendored Normal file
View File

@@ -0,0 +1,3 @@
declare module '*/package.json' {
const version: string;
}

7
src/@types/promise-any.d.ts vendored Normal file
View File

@@ -0,0 +1,7 @@
declare module 'promise-any' {
function promiseAny<T>(iterable: Iterable<T | PromiseLike<T>>): Promise<T>;
namespace promiseAny {} // Hack
export = promiseAny;
}

65
src/@types/webfinger.js.d.ts vendored Normal file
View File

@@ -0,0 +1,65 @@
declare module 'webfinger.js' {
interface IWebFingerConstructorConfig {
tls_only?: boolean;
webfist_fallback?: boolean;
uri_fallback?: boolean;
request_timeout?: number;
}
type JRDProperties = { [type: string]: string };
interface IJRDLink {
rel: string;
type?: string;
href?: string;
template?: string;
titles?: { [lang: string]: string };
properties?: JRDProperties;
}
interface IJRD {
subject?: string;
expires?: Date;
aliases?: string[];
properties?: JRDProperties;
links?: IJRDLink[];
}
interface IIDXLinks {
'avatar': IJRDLink[];
'remotestorage': IJRDLink[];
'blog': IJRDLink[];
'vcard': IJRDLink[];
'updates': IJRDLink[];
'share': IJRDLink[];
'profile': IJRDLink[];
'webfist': IJRDLink[];
'camlistore': IJRDLink[];
[type: string]: IJRDLink[];
}
interface IIDXProperties {
'name': string;
[type: string]: string;
}
interface IIDX {
links: IIDXLinks;
properties: IIDXProperties;
}
interface ILookupCallbackResult {
object: IJRD;
json: string;
idx: IIDX;
}
type LookupCallback = (err: Error | string, result?: ILookupCallbackResult) => void;
export class WebFinger {
constructor(config?: IWebFingerConstructorConfig);
public lookup(address: string, cb: LookupCallback): NodeJS.Timeout;
public lookupLink(address: string, rel: string, cb: IJRDLink): void;
}
}

View File

@@ -3,11 +3,14 @@
*/
import * as moment from 'moment';
const nestedProperty = require('nested-property');
import * as nestedProperty from 'nested-property';
import autobind from 'autobind-decorator';
import * as mongo from 'mongodb';
import db from '../db/mongodb';
import { ICollection } from 'monk';
import Logger from '../misc/logger';
const logger = new Logger('chart');
const utc = moment.utc;
@@ -58,14 +61,18 @@ type Log<T extends Obj> = {
export default abstract class Chart<T> {
protected collection: ICollection<Log<T>>;
protected abstract async getTemplate(init: boolean, latest?: T, group?: any): Promise<T>;
private name: string;
constructor(name: string, grouped = false) {
this.name = name;
this.collection = db.get<Log<T>>(`chart.${name}`);
const keys = {
span: -1,
date: -1
} as { [key: string]: 1 | -1; };
if (grouped) keys.group = -1;
this.collection.createIndex(keys, { unique: true });
}
@@ -155,6 +162,8 @@ export default abstract class Chart<T> {
// 初期ログデータを作成
data = await this.getTemplate(true, null, group);
logger.info(`${this.name}: Initial commit created`);
}
try {
@@ -172,7 +181,7 @@ export default abstract class Chart<T> {
if (e.code === 11000) {
log = await this.getLatestLog(span, group);
} else {
console.error(e);
logger.error(e);
throw e;
}
}

View File

@@ -12,6 +12,7 @@
<span class="is-admin" v-if="user.isAdmin">admin</span>
<span class="is-moderator" v-if="user.isModerator">moderator</span>
<span class="is-verified" v-if="user.isVerified" :title="$t('@.verified-user')"><fa icon="star"/></span>
<span class="is-silenced" v-if="user.isSilenced" :title="$t('@.silenced-user')"><fa :icon="faMicrophoneSlash"/></span>
<span class="is-suspended" v-if="user.isSuspended" :title="$t('@.suspended-user')"><fa :icon="faSnowflake"/></span>
</header>
<div>
@@ -27,6 +28,7 @@
<script lang="ts">
import Vue from 'vue';
import i18n from '../../i18n';
import { faMicrophoneSlash } from '@fortawesome/free-solid-svg-icons';
import { faSnowflake } from '@fortawesome/free-regular-svg-icons';
export default Vue.extend({
@@ -34,7 +36,7 @@ export default Vue.extend({
props: ['user'],
data() {
return {
faSnowflake
faSnowflake, faMicrophoneSlash
};
},
});
@@ -76,6 +78,7 @@ export default Vue.extend({
color var(--noteHeaderAdminFg)
> .is-verified
> .is-silenced
> .is-suspended
margin 0 0 0 .5em
color #4dabf7

View File

@@ -3,7 +3,7 @@
<ui-card>
<div slot="title"><fa :icon="faTerminal"/> {{ $t('operation') }}</div>
<section class="fit-top">
<ui-input class="target" v-model="target" type="text">
<ui-input class="target" v-model="target" type="text" @enter="showUser">
<span>{{ $t('username-or-userid') }}</span>
</ui-input>
<ui-button @click="showUser"><fa :icon="faSearch"/> {{ $t('lookup') }}</ui-button>
@@ -16,6 +16,10 @@
<ui-button @click="verifyUser" :disabled="verifying"><fa :icon="faCertificate"/> {{ $t('verify') }}</ui-button>
<ui-button @click="unverifyUser" :disabled="unverifying">{{ $t('unverify') }}</ui-button>
</ui-horizon-group>
<ui-horizon-group>
<ui-button @click="silenceUser"><fa :icon="faMicrophoneSlash"/> {{ $t('make-silence') }}</ui-button>
<ui-button @click="unsilenceUser">{{ $t('unmake-silence') }}</ui-button>
</ui-horizon-group>
<ui-horizon-group>
<ui-button @click="suspendUser" :disabled="suspending"><fa :icon="faSnowflake"/> {{ $t('suspend') }}</ui-button>
<ui-button @click="unsuspendUser" :disabled="unsuspending">{{ $t('unsuspend') }}</ui-button>
@@ -66,7 +70,7 @@
import Vue from 'vue';
import i18n from '../../i18n';
import parseAcct from "../../../../misc/acct/parse";
import { faCertificate, faUsers, faTerminal, faSearch, faKey, faSync } from '@fortawesome/free-solid-svg-icons';
import { faCertificate, faUsers, faTerminal, faSearch, faKey, faSync, faMicrophoneSlash } from '@fortawesome/free-solid-svg-icons';
import { faSnowflake } from '@fortawesome/free-regular-svg-icons';
import XUser from './users.user.vue';
@@ -90,7 +94,7 @@ export default Vue.extend({
offset: 0,
users: [],
existMore: false,
faTerminal, faCertificate, faUsers, faSnowflake, faSearch, faKey, faSync
faTerminal, faCertificate, faUsers, faSnowflake, faSearch, faKey, faSync, faMicrophoneSlash
};
},
@@ -120,22 +124,23 @@ export default Vue.extend({
methods: {
/** テキストエリアのユーザーを解決する */
async fetchUser() {
try {
return await this.$root.api('users/show', this.target.startsWith('@') ? parseAcct(this.target) : { userId: this.target });
} catch (e) {
if (e == 'user not found') {
this.$root.dialog({
type: 'error',
text: this.$t('user-not-found')
});
} else {
this.$root.dialog({
type: 'error',
text: e.toString()
});
}
}
fetchUser() {
return new Promise((res) => {
const usernamePromise = this.$root.api('users/show', parseAcct(this.target));
const idPromise = this.$root.api('users/show', { userId: this.target });
usernamePromise.then(res);
idPromise.then(res);
idPromise.catch(e => {
if (e == 'user not found') {
this.$root.dialog({
type: 'error',
text: this.$t('user-not-found')
});
}
});
});
},
/** テキストエリアから処理対象ユーザーを設定する */
@@ -216,6 +221,44 @@ export default Vue.extend({
this.refreshUser();
},
async silenceUser() {
const process = async () => {
await this.$root.api('admin/silence-user', { userId: this.user._id });
this.$root.dialog({
type: 'success',
splash: true
});
};
await process().catch(e => {
this.$root.dialog({
type: 'error',
text: e.toString()
});
});
this.refreshUser();
},
async unsilenceUser() {
const process = async () => {
await this.$root.api('admin/unsilence-user', { userId: this.user._id });
this.$root.dialog({
type: 'success',
splash: true
});
};
await process().catch(e => {
this.$root.dialog({
type: 'error',
text: e.toString()
});
});
this.refreshUser();
},
async suspendUser() {
if (!await this.getConfirmed(this.$t('suspend-confirm'))) return;

View File

@@ -31,3 +31,11 @@
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
@keyframes jump {
0% { transform: translateY(0); }
25% { transform: translateY(-16px); }
50% { transform: translateY(0); }
75% { transform: translateY(-8px); }
100% { transform: translateY(0); }
}

View File

@@ -69,16 +69,18 @@
window.lang = lang;
//#endregion
let locale = localStorage.getItem('locale');
//#region Fetch locale data
const cachedLocale = localStorage.getItem('locale');
const localeKey = localStorage.getItem('localeKey');
if (locale == null || localeKey != `${ver}.${lang}`) {
if (cachedLocale == null || localeKey != `${ver}.${lang}`) {
const locale = await fetch(`/assets/locales/${lang}.json?ver=${ver}`)
.then(response => response.json());
localStorage.setItem('locale', JSON.stringify(locale));
localStorage.setItem('localeKey', `${ver}.${lang}`);
localStorage.setItem('locale', JSON.stringify(locale));
localStorage.setItem('localeKey', `${ver}.${lang}`);
}
//#endregion
// Detect the user agent
const ua = navigator.userAgent.toLowerCase();

View File

@@ -1,5 +1,5 @@
// スクリプトサイズがデカい
//const crypto = require('crypto');
//import * as crypto from 'crypto';
export default (data: ArrayBuffer) => {
//const buf = new Buffer(data);

View File

@@ -1,4 +1,4 @@
const NProgress = require('nprogress');
import * as NProgress from 'nprogress';
NProgress.configure({
trickleSpeed: 500,
showSpinner: false

View File

@@ -1,4 +1,4 @@
import parse from '../../../../mfm/parse';
import { parse } from '../../../../mfm/parse';
import { sum, unique } from '../../../../prelude/array';
import shouldMuteNote from './should-mute-note';
import MkNoteMenu from '../views/components/note-menu.vue';

View File

@@ -1,11 +1,11 @@
<template>
<prism :inline="inline" :language="lang">{{ code }}</prism>
<prism :inline="inline" :language="lang || 'js'">{{ code }}</prism>
</template>
<script lang="ts">
import Vue from 'vue';
import 'prismjs';
import 'prismjs/themes/prism.css';
import 'prismjs/themes/prism-okaidia.css';
import Prism from 'vue-prism-component';
export default Vue.extend({

View File

@@ -34,7 +34,7 @@
<script lang="ts">
import Vue from 'vue';
import i18n from '../../../i18n';
import parse from '../../../../../mfm/parse';
import { parse } from '../../../../../mfm/parse';
import { unique } from '../../../../../prelude/array';
export default Vue.extend({

View File

@@ -1,7 +1,7 @@
import Vue, { VNode } from 'vue';
import { length } from 'stringz';
import { MfmForest } from '../../../../../mfm/parser';
import parse from '../../../../../mfm/parse';
import { MfmForest } from '../../../../../mfm/types';
import { parse, parsePlain } from '../../../../../mfm/parse';
import MkUrl from './url.vue';
import MkMention from './mention.vue';
import { concat, sum } from '../../../../../prelude/array';
@@ -46,7 +46,7 @@ export default Vue.component('misskey-flavored-markdown', {
render(createElement) {
if (this.text == null || this.text == '') return;
const ast = parse(this.text, this.plainText);
const ast = (this.plainText ? parsePlain : parse)(this.text);
let bigCount = 0;
let motionCount = 0;
@@ -84,7 +84,7 @@ export default Vue.component('misskey-flavored-markdown', {
case 'big': {
bigCount++;
const isLong = sumTextsLength(token.children) > 10 || countNodesF(token.children) > 5;
const isLong = sumTextsLength(token.children) > 15 || countNodesF(token.children) > 5;
const isMany = bigCount > 3;
return (createElement as any)('strong', {
attrs: {
@@ -98,7 +98,11 @@ export default Vue.component('misskey-flavored-markdown', {
}
case 'small': {
return [createElement('small', genEl(token.children))];
return [createElement('small', {
attrs: {
style: 'opacity: 0.7;'
},
}, genEl(token.children))];
}
case 'center': {
@@ -111,8 +115,8 @@ export default Vue.component('misskey-flavored-markdown', {
case 'motion': {
motionCount++;
const isLong = sumTextsLength(token.children) > 10 || countNodesF(token.children) > 5;
const isMany = motionCount > 3;
const isLong = sumTextsLength(token.children) > 15 || countNodesF(token.children) > 5;
const isMany = motionCount > 5;
return (createElement as any)('span', {
attrs: {
style: 'display: inline-block;'
@@ -126,11 +130,29 @@ export default Vue.component('misskey-flavored-markdown', {
case 'spin': {
motionCount++;
const isLong = sumTextsLength(token.children) > 5 || countNodesF(token.children) > 3;
const isMany = motionCount > 3;
const isLong = sumTextsLength(token.children) > 10 || countNodesF(token.children) > 5;
const isMany = motionCount > 5;
const direction =
token.node.props.attr == 'left' ? 'reverse' :
token.node.props.attr == 'alternate' ? 'alternate' :
'normal';
const style = (this.$store.state.settings.disableAnimatedMfm || isLong || isMany)
? ''
: `animation: spin 1.5s linear infinite; animation-direction: ${direction};`;
return (createElement as any)('span', {
attrs: {
style: (this.$store.state.settings.disableAnimatedMfm || isLong || isMany) ? 'display: inline-block;' : 'display: inline-block; animation: spin 1.5s linear infinite;'
style: 'display: inline-block;' + style
},
}, genEl(token.children));
}
case 'jump': {
motionCount++;
const isLong = sumTextsLength(token.children) > 30 || countNodesF(token.children) > 5;
const isMany = motionCount > 5;
return (createElement as any)('span', {
attrs: {
style: (this.$store.state.settings.disableAnimatedMfm || isLong || isMany) ? 'display: inline-block;' : 'display: inline-block; animation: jump 0.75s linear infinite;'
},
}, genEl(token.children));
}

View File

@@ -30,4 +30,7 @@ export default Vue.extend({
color var(--mfmQuote)
border-left solid 3px var(--mfmQuoteLine)
>>> pre code
font-size 80%
</style>

View File

@@ -30,6 +30,7 @@
<ui-textarea v-model="description" :max="500">
<span>{{ $t('description') }}</span>
<span slot="desc">{{ $t('you-can-include-hashtags') }}</span>
</ui-textarea>
<ui-select v-model="lang">

View File

@@ -184,6 +184,12 @@ export default Vue.extend({
}
}
});
this.$on('keydown', (e: KeyboardEvent) => {
if (e.code == 'Enter') {
this.$emit('enter');
}
});
},
methods: {
focus() {

View File

@@ -69,6 +69,7 @@ export default Vue.extend({
const data = new FormData();
data.append('i', this.$store.state.i.token);
data.append('force', 'true');
data.append('file', file);
if (folder) data.append('folderId', folder);

View File

@@ -9,7 +9,7 @@
</div>
<div v-else class="mk-url-preview">
<a :class="{ mini, compact }" :href="url" target="_blank" :title="url" v-if="!fetching">
<div class="thumbnail" v-if="thumbnail" :style="`background-image: url(${thumbnail})`"></div>
<div class="thumbnail" v-if="thumbnail" :style="`background-image: url('${thumbnail}')`"></div>
<article>
<header>
<h1 :title="title">{{ title }}</h1>

View File

@@ -8,7 +8,8 @@
import Vue from 'vue';
import i18n from '../../../i18n';
import copyToClipboard from '../../../common/scripts/copy-to-clipboard';
import { faExclamationCircle } from '@fortawesome/free-solid-svg-icons';
import { faExclamationCircle, faMicrophoneSlash } from '@fortawesome/free-solid-svg-icons';
import { faSnowflake } from '@fortawesome/free-regular-svg-icons';
export default Vue.extend({
i18n: i18n('common/views/components/user-menu.vue'),
@@ -40,6 +41,18 @@ export default Vue.extend({
action: this.reportAbuse
}];
if (this.$store.getters.isSignedIn && (this.$store.state.i.isAdmin || this.$store.state.i.isModerator)) {
menu = menu.concat([null, {
icon: faMicrophoneSlash,
text: this.user.isSilenced ? this.$t('unsilence') : this.$t('silence'),
action: this.toggleSilence
}, {
icon: faSnowflake,
text: this.user.isSuspended ? this.$t('unsuspend') : this.$t('suspend'),
action: this.toggleSuspend
}]);
}
return {
items: menu
};
@@ -148,6 +161,40 @@ export default Vue.extend({
text: e
});
});
},
toggleSilence() {
this.$root.api(this.user.isSilenced ? 'admin/unsilence-user' : 'admin/silence-user', {
userId: this.user.id
}).then(() => {
this.user.isSilenced = !this.user.isSilenced;
this.$root.dialog({
type: 'success',
splash: true
});
}, e => {
this.$root.dialog({
type: 'error',
text: e
});
});
},
toggleSuspend() {
this.$root.api(this.user.isSuspended ? 'admin/unsuspend-user' : 'admin/suspend-user', {
userId: this.user.id
}).then(() => {
this.user.isSuspended = !this.user.isSuspended;
this.$root.dialog({
type: 'success',
splash: true
});
}, e => {
this.$root.dialog({
type: 'error',
text: e
});
});
}
}
});

View File

@@ -30,13 +30,13 @@
<x-folder v-for="folder in folders" :key="folder.id" class="folder" :folder="folder"/>
<!-- SEE: https://stackoverflow.com/questions/18744164/flex-box-align-last-row-to-grid -->
<div class="padding" v-for="n in 16"></div>
<button v-if="moreFolders">{{ $t('@.load-more') }}</button>
<ui-button v-if="moreFolders">{{ $t('@.load-more') }}</ui-button>
</div>
<div class="files" ref="filesContainer" v-if="files.length > 0">
<x-file v-for="file in files" :key="file.id" class="file" :file="file"/>
<!-- SEE: https://stackoverflow.com/questions/18744164/flex-box-align-last-row-to-grid -->
<div class="padding" v-for="n in 16"></div>
<button v-if="moreFiles" @click="fetchMoreFiles">{{ $t('@.load-more') }}</button>
<ui-button v-if="moreFiles" @click="fetchMoreFiles">{{ $t('@.load-more') }}</ui-button>
</div>
<div class="empty" v-if="files.length == 0 && folders.length == 0 && !fetching">
<p v-if="draghover">{{ $t('empty-draghover') }}</p>

View File

@@ -41,7 +41,7 @@ export default Vue.extend({
computed: {
imageStyle(): any {
return {
'background-image': null // TODO `url(${this.video.thumbnailUrl})`
'background-image': `url(${this.video.thumbnailUrl})`
};
}
},

View File

@@ -68,7 +68,7 @@ import insertTextAtCursor from 'insert-text-at-cursor';
import * as XDraggable from 'vuedraggable';
import getFace from '../../../common/scripts/get-face';
import MkVisibilityChooser from '../../../common/views/components/visibility-chooser.vue';
import parse from '../../../../../mfm/parse';
import { parse } from '../../../../../mfm/parse';
import { host } from '../../../config';
import { erase, unique } from '../../../../../prelude/array';
import { length } from 'stringz';

View File

@@ -12,7 +12,7 @@
<div class="side">
<div class="instance" v-if="!$store.getters.isSignedIn"><mk-instance/></div>
<x-profile :user="user"/>
<x-integrations :user="user" v-if="!user.host"/>
<x-integrations :user="user"/>
<mk-calendar @chosen="warp" :start="new Date(user.createdAt)"/>
<mk-activity :user="user"/>
<x-photos :user="user"/>

View File

@@ -35,7 +35,7 @@ export default Vue.extend({
computed: {
imageStyle(): any {
return {
'background-image': null // TODO `url(${this.video.thumbnailUrl})`
'background-image': `url(${this.video.thumbnailUrl})`
};
}
}

View File

@@ -60,7 +60,7 @@ import insertTextAtCursor from 'insert-text-at-cursor';
import * as XDraggable from 'vuedraggable';
import MkVisibilityChooser from '../../../common/views/components/visibility-chooser.vue';
import getFace from '../../../common/scripts/get-face';
import parse from '../../../../../mfm/parse';
import { parse } from '../../../../../mfm/parse';
import { host } from '../../../config';
import { erase, unique } from '../../../../../prelude/array';
import { length } from 'stringz';

View File

@@ -7,10 +7,10 @@
<div class="users" v-if="!fetching && users.length != 0">
<mk-user-preview v-for="u in users" :user="u" :key="u.id"/>
</div>
<button class="more" v-if="!fetching && next != null" @click="more" :disabled="moreFetching">
<ui-button class="more" v-if="!fetching && next != null" @click="more" :disabled="moreFetching">
<span v-if="!moreFetching">{{ $t('@.load-more') }}</span>
<span v-if="moreFetching">{{ $t('@.loading') }}<mk-ellipsis/></span>
</button>
</ui-button>
<p class="no" v-if="!fetching && users.length == 0">
<slot></slot>
</p>

View File

@@ -41,7 +41,7 @@
<script lang="ts">
import Vue from 'vue';
import parse from '../../../../mfm/parse';
import { parse } from '../../../../mfm/parse';
import * as JSON5 from 'json5';
export default Vue.extend({

View File

@@ -7,7 +7,7 @@ import { URL } from 'url';
import * as yaml from 'js-yaml';
import { Source, Mixin } from './types';
import isUrl = require('is-url');
const pkg = require('../../package.json');
import * as pkg from '../../package.json';
/**
* Path of configuration directory

View File

@@ -60,7 +60,6 @@ async function usedMem() {
const data = await sysUtils.mem();
return data.active;
} catch (error) {
console.error(error);
throw error;
}
}
@@ -71,7 +70,6 @@ async function totalMem() {
const data = await sysUtils.mem();
return data.total;
} catch (error) {
console.error(error);
throw error;
}
}

View File

@@ -1,5 +1,8 @@
import * as elasticsearch from 'elasticsearch';
import config from '../config';
import Logger from '../misc/logger';
const esLogger = new Logger('es');
const index = {
settings: {
@@ -50,9 +53,9 @@ if (client) {
requestTimeout: 30000
}, error => {
if (error) {
console.error('elasticsearch is down!');
esLogger.error('elasticsearch is down!');
} else {
console.log('elasticsearch is available!');
esLogger.succ('elasticsearch is available!');
}
});

View File

@@ -18,6 +18,7 @@ export default db;
* MongoDB native module (officialy)
*/
import * as mongodb from 'mongodb';
import Logger from '../misc/logger';
let mdb: mongodb.Db;
@@ -37,3 +38,5 @@ const nativeDbConn = async (): Promise<mongodb.Db> => {
};
export { nativeDbConn };
export const dbLogger = new Logger('db');

View File

@@ -8,10 +8,9 @@ require('events').EventEmitter.defaultMaxListeners = 128;
import * as os from 'os';
import * as cluster from 'cluster';
import * as debug from 'debug';
import chalk from 'chalk';
import * as portscanner from 'portscanner';
import isRoot = require('is-root');
import * as isRoot from 'is-root';
import Xev from 'xev';
import * as program from 'commander';
import * as sysUtils from 'systeminformation';
@@ -23,21 +22,19 @@ import notesStats from './daemons/notes-stats';
import loadConfig from './config/load';
import { Config } from './config/types';
import { lessThan } from './prelude/array';
import * as pkg from '../package.json';
const clusterLog = debug('misskey:cluster');
const logger = new Logger('core', 'cyan');
const bootLogger = logger.createSubLogger('boot', 'magenta');
const clusterLog = logger.createSubLogger('cluster', 'orange');
const ev = new Xev();
if (process.env.NODE_ENV != 'production' && process.env.DEBUG == null) {
debug.enable('misskey');
}
const pkg = require('../package.json');
//#region Command line argument definitions
program
.version(pkg.version)
.option('--no-daemons', 'Disable daemon processes (for debbuging)')
.option('--disable-clustering', 'Disable clustering')
.option('--quiet', 'Suppress all logs')
.parse(process.argv);
//#endregion
@@ -71,22 +68,34 @@ function main() {
async function masterMain() {
let config: Config;
if (!program.quiet) {
//#region Misskey logo
console.log(' _____ _ _ ');
console.log('| |_|___ ___| |_ ___ _ _ ');
console.log('| | | | |_ -|_ -| \'_| -_| | |');
console.log('|_|_|_|_|___|___|_,_|___|_ |');
console.log(' |___|\n');
//#endregion
}
bootLogger.info('Welcome to Misskey!');
bootLogger.info(`Misskey v${pkg.version}`, true);
try {
// initialize app
config = await init();
} catch (e) {
console.error(e);
Logger.error('Fatal error occurred during initialization');
bootLogger.error('Fatal error occurred during initialization', true);
process.exit(1);
}
Logger.succ('Misskey initialized');
bootLogger.succ('Misskey initialized');
if (!program.disableClustering) {
await spawnWorkers(config.clusterLimit);
}
Logger.succ(`Now listening on port ${config.port} on ${config.url}`);
bootLogger.succ(`Now listening on port ${config.port} on ${config.url}`, true);
}
/**
@@ -115,7 +124,7 @@ async function isPortAvailable(port: number): Promise<boolean> {
}
async function showMachine() {
const logger = new Logger('Machine');
const logger = bootLogger.createSubLogger('machine');
logger.info(`Hostname: ${os.hostname()}`);
logger.info(`Platform: ${process.platform}`);
logger.info(`Architecture: ${process.arch}`);
@@ -128,12 +137,12 @@ async function showMachine() {
function showEnvironment(): void {
const env = process.env.NODE_ENV;
const logger = new Logger('Env');
const logger = bootLogger.createSubLogger('env');
logger.info(typeof env == 'undefined' ? 'NODE_ENV is not set' : `NODE_ENV: ${env}`);
if (env !== 'production') {
logger.warn('The environment is not in production mode');
logger.warn('Do not use for production purpose');
logger.warn('The environment is not in production mode.');
logger.warn('DO NOT USE FOR PRODUCTION PURPOSE!', true);
}
logger.info(`You ${isRoot() ? '' : 'do not '}have root privileges`);
@@ -143,20 +152,20 @@ function showEnvironment(): void {
* Init app
*/
async function init(): Promise<Config> {
Logger.info('Welcome to Misskey!');
Logger.info(`<<< Misskey v${pkg.version} >>>`);
showEnvironment();
new Logger('Nodejs').info(`Version ${runningNodejsVersion.join('.')}`);
const nodejsLogger = bootLogger.createSubLogger('nodejs');
nodejsLogger.info(`Version ${runningNodejsVersion.join('.')}`);
if (!satisfyNodejsVersion) {
new Logger('Nodejs').error(`Node.js version is less than ${requiredNodejsVersion.join('.')}. Please upgrade it.`);
nodejsLogger.error(`Node.js version is less than ${requiredNodejsVersion.join('.')}. Please upgrade it.`);
process.exit(1);
}
await showMachine();
showEnvironment();
const configLogger = new Logger('Config');
const configLogger = bootLogger.createSubLogger('config');
let config;
try {
@@ -176,17 +185,17 @@ async function init(): Promise<Config> {
configLogger.succ('Loaded');
if (config.port == null) {
Logger.error('The port is not configured. Please configure port.');
bootLogger.error('The port is not configured. Please configure port.');
process.exit(1);
}
if (process.platform === 'linux' && isWellKnownPort(config.port) && !isRoot()) {
Logger.error('You need root privileges to listen on well-known port on Linux');
bootLogger.error('You need root privileges to listen on well-known port on Linux');
process.exit(1);
}
if (!await isPortAvailable(config.port)) {
Logger.error(`Port ${config.port} is already in use`);
bootLogger.error(`Port ${config.port} is already in use`, true);
process.exit(1);
}
@@ -199,7 +208,7 @@ async function init(): Promise<Config> {
const requiredMongoDBVersion = [3, 6];
function checkMongoDB(config: Config) {
const mongoDBLogger = new Logger('MongoDB');
const mongoDBLogger = bootLogger.createSubLogger('db');
const u = config.mongodb.user ? encodeURIComponent(config.mongodb.user) : null;
const p = config.mongodb.pass ? encodeURIComponent(config.mongodb.pass) : null;
const uri = `mongodb://${u && p ? `${u}:****@` : ''}${config.mongodb.host}:${config.mongodb.port}/${config.mongodb.db}`;
@@ -222,9 +231,9 @@ function checkMongoDB(config: Config) {
async function spawnWorkers(limit: number = Infinity) {
const workers = Math.min(limit, os.cpus().length);
Logger.info(`Starting ${workers} worker${workers === 1 ? '' : 's'}...`);
bootLogger.info(`Starting ${workers} worker${workers === 1 ? '' : 's'}...`);
await Promise.all([...Array(workers)].map(spawnWorker));
Logger.succ('All workers started');
bootLogger.succ('All workers started');
}
function spawnWorker(): Promise<void> {
@@ -232,7 +241,6 @@ function spawnWorker(): Promise<void> {
const worker = cluster.fork();
worker.on('message', message => {
if (message !== 'ready') return;
Logger.succ('A worker started');
res();
});
});
@@ -242,33 +250,35 @@ function spawnWorker(): Promise<void> {
// Listen new workers
cluster.on('fork', worker => {
clusterLog(`Process forked: [${worker.id}]`);
clusterLog.info(`Process forked: [${worker.id}]`);
});
// Listen online workers
cluster.on('online', worker => {
clusterLog(`Process is now online: [${worker.id}]`);
clusterLog.succ(`Process is now online: [${worker.id}]`);
});
// Listen for dying workers
cluster.on('exit', worker => {
// Replace the dead worker,
// we're not sentimental
clusterLog(chalk.red(`[${worker.id}] died :(`));
clusterLog.error(chalk.red(`[${worker.id}] died :(`));
cluster.fork();
});
// Display detail of unhandled promise rejection
process.on('unhandledRejection', console.dir);
if (!program.quiet) {
process.on('unhandledRejection', console.dir);
}
// Display detail of uncaught exception
process.on('uncaughtException', err => {
console.error(err);
logger.error(err);
});
// Dying away...
process.on('exit', code => {
Logger.info(`The process is going to exit with code ${code}`);
logger.info(`The process is going to exit with code ${code}`);
});
//#endregion

View File

@@ -1,10 +1,10 @@
const parse5 = require('parse5');
import { parseFragment, DefaultTreeDocumentFragment } from 'parse5';
import { URL } from 'url';
export default function(html: string): string {
export function fromHtml(html: string): string {
if (html == null) return null;
const dom = parse5.parseFragment(html);
const dom = parseFragment(html) as DefaultTreeDocumentFragment;
let text = '';

File diff suppressed because one or more lines are too long

31
src/mfm/normalize.ts Normal file
View File

@@ -0,0 +1,31 @@
import * as A from '../prelude/array';
import * as S from '../prelude/string';
import { MfmForest, MfmTree } from './types';
import { createTree, createLeaf } from '../prelude/tree';
function isEmptyTextTree(t: MfmTree): boolean {
return t.node.type == 'text' && t.node.props.text === '';
}
function concatTextTrees(ts: MfmForest): MfmTree {
return createLeaf({ type: 'text', props: { text: S.concat(ts.map(x => x.node.props.text)) } });
}
function concatIfTextTrees(ts: MfmForest): MfmForest {
return ts[0].node.type === 'text' ? [concatTextTrees(ts)] : ts;
}
function concatConsecutiveTextTrees(ts: MfmForest): MfmForest {
const us = A.concat(A.groupOn(t => t.node.type, ts).map(concatIfTextTrees));
return us.map(t => createTree(t.node, concatConsecutiveTextTrees(t.children)));
}
function removeEmptyTextNodes(ts: MfmForest): MfmForest {
return ts
.filter(t => !isEmptyTextTree(t))
.map(t => createTree(t.node, removeEmptyTextNodes(t.children)));
}
export function normalize(ts: MfmForest): MfmForest {
return removeEmptyTextNodes(concatConsecutiveTextTrees(ts));
}

View File

@@ -1,36 +1,19 @@
import parser, { plainParser, MfmForest, MfmTree } from './parser';
import * as A from '../prelude/array';
import * as S from '../prelude/string';
import { createTree, createLeaf } from '../prelude/tree';
import { mfmLanguage } from './language';
import { MfmForest } from './types';
import { normalize } from './normalize';
function concatTextTrees(ts: MfmForest): MfmTree {
return createLeaf({ type: 'text', props: { text: S.concat(ts.map(x => x.node.props.text)) } });
}
function concatIfTextTrees(ts: MfmForest): MfmForest {
return ts[0].node.type === 'text' ? [concatTextTrees(ts)] : ts;
}
function concatConsecutiveTextTrees(ts: MfmForest): MfmForest {
const us = A.concat(A.groupOn(t => t.node.type, ts).map(concatIfTextTrees));
return us.map(t => createTree(t.node, concatConsecutiveTextTrees(t.children)));
}
function isEmptyTextTree(t: MfmTree): boolean {
return t.node.type == 'text' && t.node.props.text === '';
}
function removeEmptyTextNodes(ts: MfmForest): MfmForest {
return ts
.filter(t => !isEmptyTextTree(t))
.map(t => createTree(t.node, removeEmptyTextNodes(t.children)));
}
export default (source: string, plainText = false): MfmForest => {
export function parse(source: string): MfmForest {
if (source == null || source == '') {
return null;
}
const raw = plainText ? plainParser.root.tryParse(source) : parser.root.tryParse(source) as MfmForest;
return removeEmptyTextNodes(concatConsecutiveTextTrees(raw));
};
return normalize(mfmLanguage.root.tryParse(source));
}
export function parsePlain(source: string): MfmForest {
if (source == null || source == '') {
return null;
}
return normalize(mfmLanguage.plain.tryParse(source));
}

View File

@@ -3,9 +3,9 @@ const { JSDOM } = jsdom;
import config from '../config';
import { INote } from '../models/note';
import { intersperse } from '../prelude/array';
import { MfmForest, MfmTree } from './parser';
import { MfmForest, MfmTree } from './types';
export default (tokens: MfmForest, mentionedRemoteUsers: INote['mentionedRemoteUsers'] = []) => {
export function toHtml(tokens: MfmForest, mentionedRemoteUsers: INote['mentionedRemoteUsers'] = []) {
if (tokens == null) {
return null;
}
@@ -61,6 +61,12 @@ export default (tokens: MfmForest, mentionedRemoteUsers: INote['mentionedRemoteU
return el;
},
jump(token) {
const el = doc.createElement('i');
appendChildren(token.children, el);
return el;
},
flip(token) {
const el = doc.createElement('span');
appendChildren(token.children, el);
@@ -131,6 +137,7 @@ export default (tokens: MfmForest, mentionedRemoteUsers: INote['mentionedRemoteU
default:
const remoteUserInfo = mentionedRemoteUsers.find(remoteUser => remoteUser.username === username && remoteUser.host === host);
a.href = remoteUserInfo ? remoteUserInfo.uri : `${config.url}/${acct}`;
a.className = 'mention';
break;
}
a.textContent = acct;
@@ -151,7 +158,7 @@ export default (tokens: MfmForest, mentionedRemoteUsers: INote['mentionedRemoteU
text(token) {
const el = doc.createElement('span');
const nodes = (token.node.props.text as string).split('\n').map(x => doc.createTextNode(x));
const nodes = (token.node.props.text as string).split(/\r\n|\r|\n/).map(x => doc.createTextNode(x));
for (const x of intersperse('br', nodes)) {
el.appendChild(x === 'br' ? doc.createElement('br') : x);
@@ -178,4 +185,4 @@ export default (tokens: MfmForest, mentionedRemoteUsers: INote['mentionedRemoteU
appendChildren(tokens, doc.body);
return `<p>${doc.body.innerHTML}</p>`;
};
}

37
src/mfm/types.ts Normal file
View File

@@ -0,0 +1,37 @@
import { Tree } from '../prelude/tree';
import * as T from '../prelude/tree';
type Node<T, P> = { type: T, props: P };
export type MentionNode = Node<'mention', {
canonical: string,
username: string,
host: string,
acct: string
}>;
export type HashtagNode = Node<'hashtag', {
hashtag: string
}>;
export type EmojiNode = Node<'emoji', {
name: string
}>;
export type MfmNode =
MentionNode |
HashtagNode |
EmojiNode |
Node<string, any>;
export type MfmTree = Tree<MfmNode>;
export type MfmForest = MfmTree[];
export function createLeaf(type: string, props: any): MfmTree {
return T.createLeaf({ type, props });
}
export function createTree(type: string, children: MfmForest, props: any): MfmTree {
return T.createTree({ type, props }, children);
}

View File

@@ -1,4 +1,4 @@
import { EmojiNode, MfmForest } from '../mfm/parser';
import { EmojiNode, MfmForest } from '../mfm/types';
import { preorderF } from '../prelude/tree';
import { unique } from '../prelude/array';

View File

@@ -1,4 +1,4 @@
import { HashtagNode, MfmForest } from '../mfm/parser';
import { HashtagNode, MfmForest } from '../mfm/types';
import { preorderF } from '../prelude/tree';
import { unique } from '../prelude/array';

View File

@@ -1,6 +1,6 @@
// test is located in test/extract-mentions
import { MentionNode, MfmForest } from '../mfm/parser';
import { MentionNode, MfmForest } from '../mfm/types';
import { preorderF } from '../prelude/tree';
export default function(mfmForest: MfmForest): MentionNode['props'][] {

View File

@@ -4,9 +4,11 @@ import config from '../config';
export default function(file: IDriveFile, thumbnail = false): string {
if (file == null) return null;
const isImage = file.contentType && file.contentType.startsWith('image/');
if (file.metadata.withoutChunks) {
if (thumbnail) {
return file.metadata.thumbnailUrl || file.metadata.webpublicUrl || file.metadata.url;
return file.metadata.thumbnailUrl || file.metadata.webpublicUrl || (isImage ? file.metadata.url : null);
} else {
return file.metadata.webpublicUrl || file.metadata.url;
}

View File

@@ -1,3 +1,5 @@
export default function(x: any): boolean {
import { ObjectID } from 'mongodb';
export default function(x: any): x is ObjectID {
return x.hasOwnProperty('toHexString') || x.hasOwnProperty('_bsontype');
}

View File

@@ -1,53 +1,57 @@
import * as cluster from 'cluster';
import chalk from 'chalk';
import * as dateformat from 'dateformat';
const quiet = process.argv.find(x => x == '--quiet');
export default class Logger {
private domain: string;
private color?: string;
private parentLogger: Logger;
constructor(domain: string) {
constructor(domain: string, color?: string) {
this.domain = domain;
this.color = color;
}
public static log(level: string, message: string): void {
const time = dateformat(new Date(), 'HH:MM:ss');
console.log(`[${time} ${level}] ${message}`);
public createSubLogger(domain: string, color?: string): Logger {
const logger = new Logger(domain, color);
logger.parentLogger = this;
return logger;
}
public static error(message: string): void {
(new Logger('')).error(message);
public log(level: string, message: string, important = false): void {
if (quiet) return;
const domain = this.color ? chalk.keyword(this.color)(this.domain) : chalk.white(this.domain);
if (this.parentLogger) {
this.parentLogger.log(level, `[${domain}]\t${message}`, important);
} else {
const time = dateformat(new Date(), 'HH:MM:ss');
const process = cluster.isMaster ? '*' : cluster.worker.id;
const log = `${chalk.gray(time)} ${level} ${process}\t[${domain}]\t${message}`;
console.log(important ? chalk.bold(log) : log);
}
}
public static warn(message: string): void {
(new Logger('')).warn(message);
public error(message: string | Error, important = false): void { // 実行を継続できない状況で使う
this.log(chalk.red('ERR '), chalk.red(message.toString()), important);
}
public static succ(message: string): void {
(new Logger('')).succ(message);
public warn(message: string, important = false): void { // 実行を継続できるが改善すべき状況で使う
this.log(chalk.yellow('WARN'), chalk.yellow(message), important);
}
public static info(message: string): void {
(new Logger('')).info(message);
public succ(message: string, important = false): void { // 何かに成功した状況で使う
this.log(chalk.green('DONE'), chalk.green(message), important);
}
public log(level: string, message: string) {
const domain = this.domain.length > 0 ? `[${this.domain}] ` : '';
Logger.log(level, `${domain}${message}`);
public info(message: string, important = false): void { // それ以外
this.log(chalk.blue('INFO'), message, important);
}
public error(message: string): void { // 実行を継続できない状況で使う
this.log(chalk.red.bold('ERROR'), chalk.red.bold(message));
public debug(message: string, important = false): void { // デバッグ用に使う
if (process.env.NODE_ENV != 'production') {
this.log(chalk.gray('VERB'), chalk.gray(message), important);
}
}
public warn(message: string): void { // 実行を継続できるが改善すべき状況で使う
this.log(chalk.yellow.bold('WARN'), chalk.yellow.bold(message));
}
public succ(message: string): void { // 何かに成功した状況で使う
this.log(chalk.blue.bold('INFO'), chalk.green.bold(message));
}
public info(message: string): void { // それ以外
this.log(chalk.blue.bold('INFO'), message);
}
}

View File

@@ -1,5 +1,5 @@
import * as mongo from 'mongodb';
const deepcopy = require('deepcopy');
import * as deepcopy from 'deepcopy';
import db from '../db/mongodb';
import isObjectId from '../misc/is-objectid';
import { pack as packUser } from './user';

View File

@@ -1,5 +1,5 @@
import * as mongo from 'mongodb';
const deepcopy = require('deepcopy');
import * as deepcopy from 'deepcopy';
import AccessToken from './access-token';
import db from '../db/mongodb';
import isObjectId from '../misc/is-objectid';

View File

@@ -1,5 +1,5 @@
import * as mongo from 'mongodb';
const deepcopy = require('deepcopy');
import * as deepcopy from 'deepcopy';
import db from '../db/mongodb';
import isObjectId from '../misc/is-objectid';
import { pack as packApp } from './app';

View File

@@ -1,7 +1,7 @@
import * as mongo from 'mongodb';
import db from '../db/mongodb';
import isObjectId from '../misc/is-objectid';
const deepcopy = require('deepcopy');
import * as deepcopy from 'deepcopy';
import { pack as packUser, IUser } from './user';
const Blocking = db.get<IBlocking>('blocking');

View File

@@ -1,8 +1,8 @@
import * as mongo from 'mongodb';
const deepcopy = require('deepcopy');
import * as deepcopy from 'deepcopy';
import { pack as packFolder } from './drive-folder';
import { pack as packUser } from './user';
import monkDb, { nativeDbConn } from '../db/mongodb';
import monkDb, { nativeDbConn, dbLogger } from '../db/mongodb';
import isObjectId from '../misc/is-objectid';
import getDriveFileUrl, { getOriginalUrl } from '../misc/get-drive-file-url';
@@ -171,7 +171,7 @@ export const pack = (
// (データベースの欠損などで)ファイルがデータベース上に見つからなかったとき
if (_file == null) {
console.warn(`[DAMAGED DB] (missing) pkg: driveFile :: ${file}`);
dbLogger.warn(`[DAMAGED DB] (missing) pkg: driveFile :: ${file}`);
return resolve(null);
}

View File

@@ -1,5 +1,5 @@
import * as mongo from 'mongodb';
const deepcopy = require('deepcopy');
import * as deepcopy from 'deepcopy';
import db from '../db/mongodb';
import isObjectId from '../misc/is-objectid';
import DriveFile from './drive-file';

View File

@@ -1,6 +1,6 @@
import * as mongo from 'mongodb';
const deepcopy = require('deepcopy');
import db from '../db/mongodb';
import * as deepcopy from 'deepcopy';
import db, { dbLogger } from '../db/mongodb';
import isObjectId from '../misc/is-objectid';
import { pack as packNote } from './note';
@@ -56,7 +56,7 @@ export const pack = (
// (データベースの不具合などで)投稿が見つからなかったら
if (_favorite.note == null) {
console.warn(`[DAMAGED DB] (missing) pkg: favorite -> note :: ${_favorite.id} (note ${_favorite.noteId})`);
dbLogger.warn(`[DAMAGED DB] (missing) pkg: favorite -> note :: ${_favorite.id} (note ${_favorite.noteId})`);
return resolve(null);
}

View File

@@ -1,5 +1,5 @@
import * as mongo from 'mongodb';
const deepcopy = require('deepcopy');
import * as deepcopy from 'deepcopy';
import db from '../db/mongodb';
import isObjectId from '../misc/is-objectid';
import { pack as packUser } from './user';

View File

@@ -1,5 +1,5 @@
import * as mongo from 'mongodb';
const deepcopy = require('deepcopy');
import * as deepcopy from 'deepcopy';
import db from '../../../db/mongodb';
import isObjectId from '../../../misc/is-objectid';
import { IUser, pack as packUser } from '../../user';

View File

@@ -1,5 +1,5 @@
import * as mongo from 'mongodb';
const deepcopy = require('deepcopy');
import * as deepcopy from 'deepcopy';
import db from '../../../db/mongodb';
import isObjectId from '../../../misc/is-objectid';
import { IUser, pack as packUser } from '../../user';

View File

@@ -1,5 +1,5 @@
import * as mongo from 'mongodb';
const deepcopy = require('deepcopy');
import * as deepcopy from 'deepcopy';
import { pack as packUser } from './user';
import { pack as packFile } from './drive-file';
import db from '../db/mongodb';

View File

@@ -1,7 +1,7 @@
import * as mongo from 'mongodb';
import db from '../db/mongodb';
import isObjectId from '../misc/is-objectid';
const deepcopy = require('deepcopy');
import * as deepcopy from 'deepcopy';
import { pack as packUser, IUser } from './user';
const Mute = db.get<IMute>('mute');

View File

@@ -1,6 +1,6 @@
import * as mongo from 'mongodb';
import $ from 'cafy';
const deepcopy = require('deepcopy');
import * as deepcopy from 'deepcopy';
import db from '../db/mongodb';
import isObjectId from '../misc/is-objectid';
import Reaction from './note-reaction';

View File

@@ -1,7 +1,7 @@
import * as mongo from 'mongodb';
const deepcopy = require('deepcopy');
import * as deepcopy from 'deepcopy';
import rap from '@prezzemolo/rap';
import db from '../db/mongodb';
import db, { dbLogger } from '../db/mongodb';
import isObjectId from '../misc/is-objectid';
import { length } from 'stringz';
import { IUser, pack as packUser } from './user';
@@ -140,6 +140,12 @@ export const hideNote = async (packedNote: any, meId: mongo.ObjectID) => {
hide = true;
} else if (meId.equals(packedNote.userId)) {
hide = false;
} else if (packedNote.reply && meId.equals(packedNote.reply.userId)) {
// 自分の投稿に対するリプライ
hide = false;
} else if (packedNote.mentions && packedNote.mentions.some((id: any) => meId.equals(id))) {
// 自分へのメンション
hide = false;
} else {
// フォロワーかどうか
const following = await Following.findOne({
@@ -225,7 +231,7 @@ export const pack = async (
// (データベースの欠損などで)投稿がデータベース上に見つからなかったとき
if (_note == null) {
console.warn(`[DAMAGED DB] (missing) pkg: note :: ${note}`);
dbLogger.warn(`[DAMAGED DB] (missing) pkg: note :: ${note}`);
return null;
}
@@ -264,6 +270,7 @@ export const pack = async (
delete _note._renote;
delete _note._files;
delete _note._replyIds;
delete _note.mentionedRemoteUsers;
if (_note.geo) delete _note.geo.type;
@@ -360,18 +367,18 @@ export const pack = async (
//#region (データベースの欠損などで)参照しているデータがデータベース上に見つからなかったとき
if (_note.user == null) {
console.warn(`[DAMAGED DB] (missing) pkg: note -> user :: ${_note.id} (user ${_note.userId})`);
dbLogger.warn(`[DAMAGED DB] (missing) pkg: note -> user :: ${_note.id} (user ${_note.userId})`);
return null;
}
if (opts.detail) {
if (_note.replyId != null && _note.reply == null) {
console.warn(`[DAMAGED DB] (missing) pkg: note -> reply :: ${_note.id} (reply ${_note.replyId})`);
dbLogger.warn(`[DAMAGED DB] (missing) pkg: note -> reply :: ${_note.id} (reply ${_note.replyId})`);
return null;
}
if (_note.renoteId != null && _note.renote == null) {
console.warn(`[DAMAGED DB] (missing) pkg: note -> renote :: ${_note.id} (renote ${_note.renoteId})`);
dbLogger.warn(`[DAMAGED DB] (missing) pkg: note -> renote :: ${_note.id} (renote ${_note.renoteId})`);
return null;
}
}

View File

@@ -1,6 +1,6 @@
import * as mongo from 'mongodb';
const deepcopy = require('deepcopy');
import db from '../db/mongodb';
import * as deepcopy from 'deepcopy';
import db, { dbLogger } from '../db/mongodb';
import isObjectId from '../misc/is-objectid';
import { IUser, pack as packUser } from './user';
import { pack as packNote } from './note';
@@ -106,12 +106,12 @@ export const pack = (notification: any) => new Promise<any>(async (resolve, reje
// (データベースの不具合などで)投稿が見つからなかったら
if (_notification.note == null) {
console.warn(`[DAMAGED DB] (missing) pkg: notification -> note :: ${_notification.id} (note ${_notification.noteId})`);
dbLogger.warn(`[DAMAGED DB] (missing) pkg: notification -> note :: ${_notification.id} (note ${_notification.noteId})`);
return resolve(null);
}
break;
default:
console.error(`Unknown type: ${_notification.type}`);
dbLogger.error(`Unknown type: ${_notification.type}`);
break;
}

View File

@@ -1,5 +1,5 @@
import * as mongo from 'mongodb';
const deepcopy = require('deepcopy');
import * as deepcopy from 'deepcopy';
import db from '../db/mongodb';
const Signin = db.get<ISignin>('signin');

View File

@@ -1,5 +1,5 @@
import * as mongo from 'mongodb';
const deepcopy = require('deepcopy');
import * as deepcopy from 'deepcopy';
import db from '../db/mongodb';
import isObjectId from '../misc/is-objectid';

View File

@@ -1,7 +1,7 @@
import * as mongo from 'mongodb';
const deepcopy = require('deepcopy');
import * as deepcopy from 'deepcopy';
import rap from '@prezzemolo/rap';
import db from '../db/mongodb';
import db, { dbLogger } from '../db/mongodb';
import isObjectId from '../misc/is-objectid';
import { packMany as packNoteMany } from './note';
import Following from './following';
@@ -48,12 +48,18 @@ type IUserBase = {
lang?: string;
pinnedNoteIds: mongo.ObjectID[];
emojis?: string[];
tags?: string[];
/**
* 凍結されているか否か
*/
isSuspended: boolean;
/**
* サイレンスされているか否か
*/
isSilenced: boolean;
/**
* 鍵アカウントか否か
*/
@@ -280,7 +286,7 @@ export const pack = (
// (データベースの欠損などで)ユーザーがデータベース上に見つからなかったとき
if (_user == null) {
console.warn(`user not found on database: ${user}`);
dbLogger.warn(`user not found on database: ${user}`);
return resolve(null);
}
@@ -306,6 +312,7 @@ export const pack = (
delete _user.password;
delete _user.token;
delete _user.twoFactorTempSecret;
delete _user.two_factor_temp_secret; // 後方互換性のため
delete _user.twoFactorSecret;
if (_user.twitter) {
delete _user.twitter.accessToken;

View File

@@ -1,4 +1,4 @@
const push = require('web-push');
import * as push from 'web-push';
import * as mongo from 'mongodb';
import Subscription from './models/sw-subscription';
import config from './config';
@@ -44,9 +44,9 @@ export default async function(userId: mongo.ObjectID | string, type: string, bod
push.sendNotification(pushSubscription, JSON.stringify({
type, body
})).catch((err: any) => {
//console.log(err.statusCode);
//console.log(err.headers);
//console.log(err.body);
//swLogger.info(err.statusCode);
//swLogger.info(err.headers);
//swLogger.info(err.body);
if (err.statusCode == 410) {
Subscription.remove({

View File

@@ -1,5 +1,6 @@
import http from './processors/http';
import { ILocalUser } from '../models/user';
import Logger from '../misc/logger';
export function createHttpJob(data: any) {
return http({ data }, () => {});
@@ -15,3 +16,5 @@ export function deliver(user: ILocalUser, content: any, to: any) {
to
});
}
export const queueLogger = new Logger('queue');

View File

@@ -1,6 +1,7 @@
import * as bq from 'bee-queue';
import request from '../../../remote/activitypub/request';
import { queueLogger } from '../..';
export default async (job: bq.Job, done: any): Promise<void> => {
try {
@@ -13,11 +14,11 @@ export default async (job: bq.Job, done: any): Promise<void> => {
// 何回再送しても成功することはないということなのでエラーにはしないでおく
done();
} else {
console.warn(`deliver failed: ${res.statusCode} ${res.statusMessage} to=${job.data.to}`);
queueLogger.warn(`deliver failed: ${res.statusCode} ${res.statusMessage} to=${job.data.to}`);
done(res.statusMessage);
}
} else {
console.warn(`deliver failed: ${res} to=${job.data.to}`);
queueLogger.warn(`deliver failed: ${res} to=${job.data.to}`);
done();
}
}

View File

@@ -1,5 +1,6 @@
import deliver from './deliver';
import processInbox from './process-inbox';
import { queueLogger } from '../..';
const handlers: any = {
deliver,
@@ -12,7 +13,7 @@ export default (job: any, done: any) => {
if (handler) {
handler(job, done);
} else {
console.error(`Unknown job: ${job.data.type}`);
queueLogger.error(`Unknown job: ${job.data.type}`);
done();
}
};

View File

@@ -1,7 +1,5 @@
import * as bq from 'bee-queue';
import * as debug from 'debug';
const httpSignature = require('http-signature');
import * as httpSignature from 'http-signature';
import parseAcct from '../../../misc/acct/parse';
import User, { IRemoteUser } from '../../../models/user';
import perform from '../../../remote/activitypub/perform';
@@ -9,8 +7,9 @@ import { resolvePerson, updatePerson } from '../../../remote/activitypub/models/
import { toUnicode } from 'punycode';
import { URL } from 'url';
import { publishApLogStream } from '../../../stream';
import Logger from '../../../misc/logger';
const log = debug('misskey:queue:inbox');
const logger = new Logger('inbox');
// ユーザーのinboxにアクティビティが届いた時の処理
export default async (job: bq.Job, done: any): Promise<void> => {
@@ -21,7 +20,7 @@ export default async (job: bq.Job, done: any): Promise<void> => {
const info = Object.assign({}, activity);
delete info['@context'];
delete info['signature'];
log(info);
logger.info(info);
//#endregion
const keyIdLower = signature.keyId.toLowerCase();
@@ -30,7 +29,7 @@ export default async (job: bq.Job, done: any): Promise<void> => {
if (keyIdLower.startsWith('acct:')) {
const { username, host } = parseAcct(keyIdLower.slice('acct:'.length));
if (host === null) {
console.warn(`request was made by local user: @${username}`);
logger.warn(`request was made by local user: @${username}`);
done();
return;
}
@@ -39,7 +38,7 @@ export default async (job: bq.Job, done: any): Promise<void> => {
try {
ValidateActivity(activity, host);
} catch (e) {
console.warn(e.message);
logger.warn(e.message);
done();
return;
}
@@ -51,7 +50,7 @@ export default async (job: bq.Job, done: any): Promise<void> => {
try {
ValidateActivity(activity, host);
} catch (e) {
console.warn(e.message);
logger.warn(e.message);
done();
return;
}
@@ -66,9 +65,9 @@ export default async (job: bq.Job, done: any): Promise<void> => {
if (activity.type === 'Update') {
if (activity.object && activity.object.type === 'Person') {
if (user == null) {
console.warn('Update activity received, but user not registed.');
logger.warn('Update activity received, but user not registed.');
} else if (!httpSignature.verifySignature(signature, user.publicKey.publicKeyPem)) {
console.warn('Update activity received, but signature verification failed.');
logger.warn('Update activity received, but signature verification failed.');
} else {
updatePerson(activity.actor, null, activity.object);
}
@@ -88,7 +87,7 @@ export default async (job: bq.Job, done: any): Promise<void> => {
}
if (!httpSignature.verifySignature(signature, user.publicKey.publicKeyPem)) {
console.warn('signature verification failed');
logger.error('signature verification failed');
done();
return;
}

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