Compare commits
100 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
48dc56e834 | ||
![]() |
2c33bd6e31 | ||
![]() |
b6524616bc | ||
![]() |
7e2b70f912 | ||
![]() |
4f071a66b6 | ||
![]() |
39f2303429 | ||
![]() |
cacf072027 | ||
![]() |
6ab1fdfe1a | ||
![]() |
6e5c93f926 | ||
![]() |
1670737075 | ||
![]() |
fee235c4e4 | ||
![]() |
7a39d489f2 | ||
![]() |
7c634218d1 | ||
![]() |
2704c5be73 | ||
![]() |
489b51ba9f | ||
![]() |
21807c29f1 | ||
![]() |
3bc62fe3eb | ||
![]() |
ba0e3c4a5f | ||
![]() |
9ec1fb5e37 | ||
![]() |
d708409462 | ||
![]() |
07d05d4f86 | ||
![]() |
bbdb2ebb40 | ||
![]() |
f7908ba098 | ||
![]() |
f2fda3075e | ||
![]() |
1338a68979 | ||
![]() |
e7da505fb3 | ||
![]() |
5a9228372f | ||
![]() |
c4a6ba9097 | ||
![]() |
d5871b408b | ||
![]() |
7b3338e373 | ||
![]() |
d18ee12d2f | ||
![]() |
ca9cc97940 | ||
![]() |
a70070ac7d | ||
![]() |
069d99b320 | ||
![]() |
37d350dcad | ||
![]() |
8653e09b59 | ||
![]() |
7cd2d59576 | ||
![]() |
a0839de38f | ||
![]() |
b7c5c71c6f | ||
![]() |
adab0adbdd | ||
![]() |
2faa58928f | ||
![]() |
ffb80efe21 | ||
![]() |
6f959218ef | ||
![]() |
be1125dcb9 | ||
![]() |
9ab34c2301 | ||
![]() |
0166d81d9e | ||
![]() |
0b26efbd2f | ||
![]() |
2cbaedf946 | ||
![]() |
b66924fbe8 | ||
![]() |
8c91148954 | ||
![]() |
be0eff3dda | ||
![]() |
85903ac9c6 | ||
![]() |
dbdd778dc7 | ||
![]() |
fc50dfd8d5 | ||
![]() |
f444e132ee | ||
![]() |
68f562c323 | ||
![]() |
820ea69613 | ||
![]() |
6f4b3853a1 | ||
![]() |
a706ad0e80 | ||
![]() |
820116affc | ||
![]() |
52650342be | ||
![]() |
85ddabdc65 | ||
![]() |
0730cc4fa4 | ||
![]() |
17b6ab0ef0 | ||
![]() |
4e208b85bb | ||
![]() |
00f8b29f6d | ||
![]() |
9cf0fcadb1 | ||
![]() |
c595efeead | ||
![]() |
b56c6793a1 | ||
![]() |
ebceffba1e | ||
![]() |
3ae42d9b85 | ||
![]() |
796237b3c6 | ||
![]() |
cb7a97ee4c | ||
![]() |
0cf758b6d1 | ||
![]() |
d28fca320e | ||
![]() |
8bd17703c3 | ||
![]() |
a78eebc43f | ||
![]() |
79fb5246df | ||
![]() |
458b8c78dc | ||
![]() |
64e0cbd6fc | ||
![]() |
7fe937026b | ||
![]() |
656cec65b9 | ||
![]() |
8045bbff1c | ||
![]() |
c1a7a21746 | ||
![]() |
f3ee63fcbe | ||
![]() |
7645c212a3 | ||
![]() |
8b38e2ea58 | ||
![]() |
c9eb6a8919 | ||
![]() |
9a41fd4734 | ||
![]() |
70d96ee076 | ||
![]() |
3b6fb3959b | ||
![]() |
484d705320 | ||
![]() |
786031be66 | ||
![]() |
bc0027ce43 | ||
![]() |
3e7c6d9bdc | ||
![]() |
5463e3e55e | ||
![]() |
84a880086e | ||
![]() |
89419b7136 | ||
![]() |
9106ec74f7 | ||
![]() |
ebf9a0921d |
17
CHANGELOG.md
17
CHANGELOG.md
@@ -1,6 +1,23 @@
|
|||||||
ChangeLog
|
ChangeLog
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
10.64.2
|
||||||
|
-------
|
||||||
|
* UIの動きを減らすオプションが一部のアニメーションに適用されなかったのを修正
|
||||||
|
|
||||||
|
10.64.1
|
||||||
|
-------
|
||||||
|
* レートリミットの調整
|
||||||
|
* アニメーションの調整
|
||||||
|
|
||||||
|
10.64.0
|
||||||
|
-------
|
||||||
|
* いくつかのアニメーションを追加
|
||||||
|
* OGP向けにインスタンスのバナー画像を提供するように
|
||||||
|
* 管理者ページでドライブのファイルを表示できるように
|
||||||
|
* ユーザビリティの強化
|
||||||
|
* バグ修正
|
||||||
|
|
||||||
10.63.1
|
10.63.1
|
||||||
-------
|
-------
|
||||||
* メンションの表示を改善
|
* メンションの表示を改善
|
||||||
|
16
README.md
16
README.md
@@ -3,9 +3,9 @@
|
|||||||
[](https://misskey.xyz/)
|
[](https://misskey.xyz/)
|
||||||
================================================================
|
================================================================
|
||||||
|
|
||||||
[](https://circleci.com/gh/syuilo/misskey)
|
[](https://circleci.com/gh/syuilo/misskey)
|
||||||
[![][dependencies-badge]][dependencies-link]
|
[](https://david-dm.org/syuilo/misskey)
|
||||||
[](http://makeapullrequest.com)
|
[](http://makeapullrequest.com)
|
||||||
|
|
||||||
**Sophisticated microblogging platform, evolving forever.**
|
**Sophisticated microblogging platform, evolving forever.**
|
||||||
|
|
||||||
@@ -77,7 +77,7 @@ Please see [Contribution guide](./CONTRIBUTING.md).
|
|||||||
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/13376668/71f3cf87ec6c4393a44b1b9df5ee3d12/1?token-time=2145916800&token-hash=7pSmWqgMfMSJHVIEcNsuuQoKeU3TRluew5p0EGTzWA4%3D" alt="Arctic"></td>
|
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/13376668/71f3cf87ec6c4393a44b1b9df5ee3d12/1?token-time=2145916800&token-hash=7pSmWqgMfMSJHVIEcNsuuQoKeU3TRluew5p0EGTzWA4%3D" alt="Arctic"></td>
|
||||||
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/12731202/0995c46cdcb54153ab5f073f5869b70a/1?token-time=2145916800&token-hash=Yd60FK_SWfQO56SeiJpy1tDHOnCV4xdEywQe8gn5_Wo%3D" alt="negao"></td>
|
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/12731202/0995c46cdcb54153ab5f073f5869b70a/1?token-time=2145916800&token-hash=Yd60FK_SWfQO56SeiJpy1tDHOnCV4xdEywQe8gn5_Wo%3D" alt="negao"></td>
|
||||||
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/12913507/f7181eacafe8469a93033d85f5969c29/2?token-time=2145916800&token-hash=mgPdX9TqZxEg4TTPuc477dxhIgYk9246qafjWZEqZ7g%3D" alt="Melilot"></td>
|
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/12913507/f7181eacafe8469a93033d85f5969c29/2?token-time=2145916800&token-hash=mgPdX9TqZxEg4TTPuc477dxhIgYk9246qafjWZEqZ7g%3D" alt="Melilot"></td>
|
||||||
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/12999811/5f349fafcce44dd1824a8b1ebbec4564/2?token-time=2145916800&token-hash=rwZ8qvbm_kpA4ib3kc07tVKupXeySpY5ATQFGxfL9v0%3D" alt="Xeltica"></td>
|
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/12999811/5f349fafcce44dd1824a8b1ebbec4564/3?token-time=2145916800&token-hash=ybYtxfpte1b-rGg6Zecpys2ZdZDtwR_UNJHQjt-3eoU%3D" alt="Xeltica"></td>
|
||||||
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/3384329/8b713330cb27404ea6e9fac50ff96efe/1?token-time=2145916800&token-hash=0eu4-m1gTWA9PhptVZt6rdKcusqcD7RB87rJT23VVFI%3D" alt="べすれい"></td>
|
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/3384329/8b713330cb27404ea6e9fac50ff96efe/1?token-time=2145916800&token-hash=0eu4-m1gTWA9PhptVZt6rdKcusqcD7RB87rJT23VVFI%3D" alt="べすれい"></td>
|
||||||
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/12021162/963128bb8d14476dbd8407943db8f31a/1?token-time=2145916800&token-hash=GgJ_NmUB6_nnRNLVGUWjV-WX91On7BOu59LKncYV9fE%3D" alt="gutfuckllc"></td>
|
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/12021162/963128bb8d14476dbd8407943db8f31a/1?token-time=2145916800&token-hash=GgJ_NmUB6_nnRNLVGUWjV-WX91On7BOu59LKncYV9fE%3D" alt="gutfuckllc"></td>
|
||||||
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/11357794/923ce94cd8c44ba788ee931907881839/1?token-time=2145916800&token-hash=I8lJVM8LeW6TSo5W6uIIRZ42cw83zp1wK_FsbzY0mcQ%3D" alt="mydarkstar"></td>
|
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/11357794/923ce94cd8c44ba788ee931907881839/1?token-time=2145916800&token-hash=I8lJVM8LeW6TSo5W6uIIRZ42cw83zp1wK_FsbzY0mcQ%3D" alt="mydarkstar"></td>
|
||||||
@@ -86,7 +86,7 @@ Please see [Contribution guide](./CONTRIBUTING.md).
|
|||||||
<td><a href="https://www.patreon.com/user?u=13376668">Arctic</a></td>
|
<td><a href="https://www.patreon.com/user?u=13376668">Arctic</a></td>
|
||||||
<td><a href="https://www.patreon.com/negao">negao</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=12913507">Melilot</a></td>
|
||||||
<td><a href="https://www.patreon.com/AxellaMC">Xeltica</a></td>
|
<td><a href="https://www.patreon.com/Xeltica">Xeltica</a></td>
|
||||||
<td><a href="https://www.patreon.com/user?u=3384329">べすれい</a></td>
|
<td><a href="https://www.patreon.com/user?u=3384329">べすれい</a></td>
|
||||||
<td><a href="https://www.patreon.com/gutfuckllc">gutfuckllc</a></td>
|
<td><a href="https://www.patreon.com/gutfuckllc">gutfuckllc</a></td>
|
||||||
<td><a href="https://www.patreon.com/mydarkstar">mydarkstar</a></td>
|
<td><a href="https://www.patreon.com/mydarkstar">mydarkstar</a></td>
|
||||||
@@ -118,7 +118,7 @@ Please see [Contribution guide](./CONTRIBUTING.md).
|
|||||||
<td><a href="https://www.patreon.com/user?u=12531784">Takashi Shibuya</a></td>
|
<td><a href="https://www.patreon.com/user?u=12531784">Takashi Shibuya</a></td>
|
||||||
</tr></table>
|
</tr></table>
|
||||||
|
|
||||||
**Last updated:** Thu, 06 Dec 2018 14:22:05 UTC
|
**Last updated:** Sun, 16 Dec 2018 18:32:06 UTC
|
||||||
<!-- PATREON_END -->
|
<!-- PATREON_END -->
|
||||||
|
|
||||||
:four_leaf_clover: Copyright
|
:four_leaf_clover: Copyright
|
||||||
@@ -130,9 +130,7 @@ Misskey is an open-source software licensed under the [GNU AGPLv3](LICENSE).
|
|||||||
[![][agpl-3.0-badge]][AGPL-3.0]
|
[![][agpl-3.0-badge]][AGPL-3.0]
|
||||||
|
|
||||||
[agpl-3.0]: https://www.gnu.org/licenses/agpl-3.0.en.html
|
[agpl-3.0]: https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||||
[agpl-3.0-badge]: https://img.shields.io/badge/license-AGPL--3.0-444444.svg?style=flat-square
|
[agpl-3.0-badge]: https://img.shields.io/badge/license-AGPL--3.0-444444.svg?style=for-the-badge
|
||||||
[dependencies-link]: https://david-dm.org/syuilo/misskey
|
|
||||||
[dependencies-badge]: https://img.shields.io/david/syuilo/misskey.svg?style=flat-square
|
|
||||||
|
|
||||||
[backer-url]: #backers
|
[backer-url]: #backers
|
||||||
[backer-badge]: https://opencollective.com/misskey/backers/badge.svg
|
[backer-badge]: https://opencollective.com/misskey/backers/badge.svg
|
||||||
|
52
gulpfile.ts
52
gulpfile.ts
@@ -11,14 +11,12 @@ import tslint from 'gulp-tslint';
|
|||||||
const cssnano = require('gulp-cssnano');
|
const cssnano = require('gulp-cssnano');
|
||||||
const stylus = require('gulp-stylus');
|
const stylus = require('gulp-stylus');
|
||||||
import * as uglifyComposer from 'gulp-uglify/composer';
|
import * as uglifyComposer from 'gulp-uglify/composer';
|
||||||
import pug = require('gulp-pug');
|
|
||||||
import * as rimraf from 'rimraf';
|
import * as rimraf from 'rimraf';
|
||||||
import chalk from 'chalk';
|
import chalk from 'chalk';
|
||||||
const imagemin = require('gulp-imagemin');
|
const imagemin = require('gulp-imagemin');
|
||||||
import * as rename from 'gulp-rename';
|
import * as rename from 'gulp-rename';
|
||||||
import * as mocha from 'gulp-mocha';
|
import * as mocha from 'gulp-mocha';
|
||||||
import * as replace from 'gulp-replace';
|
import * as replace from 'gulp-replace';
|
||||||
import * as htmlmin from 'gulp-htmlmin';
|
|
||||||
const uglifyes = require('uglify-es');
|
const uglifyes = require('uglify-es');
|
||||||
|
|
||||||
const locales = require('./locales');
|
const locales = require('./locales');
|
||||||
@@ -34,8 +32,6 @@ if (isDebug) {
|
|||||||
console.warn(chalk.yellow.bold(' built script will not be compressed.'));
|
console.warn(chalk.yellow.bold(' built script will not be compressed.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
const constants = require('./src/const.json');
|
|
||||||
|
|
||||||
gulp.task('build', [
|
gulp.task('build', [
|
||||||
'build:ts',
|
'build:ts',
|
||||||
'build:copy',
|
'build:copy',
|
||||||
@@ -109,7 +105,7 @@ gulp.task('default', ['build']);
|
|||||||
gulp.task('build:client', [
|
gulp.task('build:client', [
|
||||||
'build:ts',
|
'build:ts',
|
||||||
'build:client:script',
|
'build:client:script',
|
||||||
'build:client:pug',
|
'build:client:styles',
|
||||||
'copy:client'
|
'copy:client'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@@ -148,52 +144,6 @@ gulp.task('copy:client', [
|
|||||||
.pipe(gulp.dest('./built/client/assets/'))
|
.pipe(gulp.dest('./built/client/assets/'))
|
||||||
);
|
);
|
||||||
|
|
||||||
gulp.task('build:client:pug', [
|
|
||||||
'copy:client',
|
|
||||||
'build:client:script',
|
|
||||||
'build:client:styles'
|
|
||||||
], () =>
|
|
||||||
gulp.src('./src/client/app/base.pug')
|
|
||||||
.pipe(pug({
|
|
||||||
locals: {
|
|
||||||
themeColor: constants.themeColor
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
.pipe(htmlmin({
|
|
||||||
// 真理値属性の簡略化 e.g.
|
|
||||||
// <input value="foo" readonly="readonly"> to
|
|
||||||
// <input value="foo" readonly>
|
|
||||||
collapseBooleanAttributes: true,
|
|
||||||
|
|
||||||
// テキストの一部かもしれない空白も削除する e.g.
|
|
||||||
// <div> <p> foo </p> </div> to
|
|
||||||
// <div><p>foo</p></div>
|
|
||||||
collapseWhitespace: true,
|
|
||||||
|
|
||||||
// タグ間の改行を保持する
|
|
||||||
preserveLineBreaks: true,
|
|
||||||
|
|
||||||
// (できる場合は)属性のクォーテーション削除する e.g.
|
|
||||||
// <p class="foo-bar" id="moo" title="blah blah">foo</p> to
|
|
||||||
// <p class=foo-bar id=moo title="blah blah">foo</p>
|
|
||||||
removeAttributeQuotes: true,
|
|
||||||
|
|
||||||
// 省略可能なタグを省略する e.g.
|
|
||||||
// <html><p>yo</p></html> ro
|
|
||||||
// <p>yo</p>
|
|
||||||
removeOptionalTags: true,
|
|
||||||
|
|
||||||
// 属性の値がデフォルトと同じなら省略する e.g.
|
|
||||||
// <input type="text"> to
|
|
||||||
// <input>
|
|
||||||
removeRedundantAttributes: true,
|
|
||||||
|
|
||||||
// CSSも圧縮する
|
|
||||||
minifyCSS: true
|
|
||||||
}))
|
|
||||||
.pipe(gulp.dest('./built/client/app/'))
|
|
||||||
);
|
|
||||||
|
|
||||||
gulp.task('locales', () =>
|
gulp.task('locales', () =>
|
||||||
gulp.src('./locales/*.yml')
|
gulp.src('./locales/*.yml')
|
||||||
.pipe(yaml({ schema: 'DEFAULT_SAFE_SCHEMA' }))
|
.pipe(yaml({ schema: 'DEFAULT_SAFE_SCHEMA' }))
|
||||||
|
@@ -111,7 +111,6 @@ common:
|
|||||||
i-like-sushi: "私は(プリンよりむしろ)寿司が好き"
|
i-like-sushi: "私は(プリンよりむしろ)寿司が好き"
|
||||||
show-reversi-board-labels: "リバーシのボードの行と列のラベルを表示"
|
show-reversi-board-labels: "リバーシのボードの行と列のラベルを表示"
|
||||||
use-white-black-reversi-stones: "リバーシに白黒の石を使う"
|
use-white-black-reversi-stones: "リバーシに白黒の石を使う"
|
||||||
use-contrast-reversi-stones: "リバーシのアイコンにコントラストを付ける"
|
|
||||||
verified-user: "公式アカウント"
|
verified-user: "公式アカウント"
|
||||||
disable-animated-mfm: "投稿内の動きのあるテキストを無効にする"
|
disable-animated-mfm: "投稿内の動きのあるテキストを無効にする"
|
||||||
suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する"
|
suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する"
|
||||||
@@ -165,6 +164,7 @@ common:
|
|||||||
hashtags: "ハッシュタグ"
|
hashtags: "ハッシュタグ"
|
||||||
dev: "アプリの作成に失敗しました。再度お試しください。"
|
dev: "アプリの作成に失敗しました。再度お試しください。"
|
||||||
ai-chan-kawaii: "藍ちゃかわいい"
|
ai-chan-kawaii: "藍ちゃかわいい"
|
||||||
|
you: "あなた"
|
||||||
auth/views/form.vue:
|
auth/views/form.vue:
|
||||||
share-access: "<i>{name}</i>があなたのアカウントにアクセスすることを許可しますか?"
|
share-access: "<i>{name}</i>があなたのアカウントにアクセスすることを許可しますか?"
|
||||||
permission-ask: "このアプリは次の権限を要求しています:"
|
permission-ask: "このアプリは次の権限を要求しています:"
|
||||||
@@ -1054,6 +1054,20 @@ admin/views/charts.vue:
|
|||||||
network-requests: "リクエスト"
|
network-requests: "リクエスト"
|
||||||
network-time: "応答時間"
|
network-time: "応答時間"
|
||||||
network-usage: "通信量"
|
network-usage: "通信量"
|
||||||
|
admin/views/drive.vue:
|
||||||
|
sort:
|
||||||
|
title: "ソート"
|
||||||
|
createdAtAsc: "アップロード日時が古い順"
|
||||||
|
createdAtDesc: "アップロード日時が新しい順"
|
||||||
|
sizeAsc: "サイズが小さい順"
|
||||||
|
sizeDesc: "サイズが大きい順"
|
||||||
|
origin:
|
||||||
|
title: "オリジン"
|
||||||
|
combined: "ローカル+リモート"
|
||||||
|
local: "ローカル"
|
||||||
|
remote: "リモート"
|
||||||
|
delete: "削除"
|
||||||
|
deleted: "削除しました"
|
||||||
admin/views/users.vue:
|
admin/views/users.vue:
|
||||||
operation: "操作"
|
operation: "操作"
|
||||||
username-or-userid: "ユーザー名またはユーザーID"
|
username-or-userid: "ユーザー名またはユーザーID"
|
||||||
|
@@ -111,7 +111,6 @@ common:
|
|||||||
i-like-sushi: "Ich bevorzuge Sushi anstelle von Pudding"
|
i-like-sushi: "Ich bevorzuge Sushi anstelle von Pudding"
|
||||||
show-reversi-board-labels: "リバーシのボードの行と列のラベルを表示"
|
show-reversi-board-labels: "リバーシのボードの行と列のラベルを表示"
|
||||||
use-white-black-reversi-stones: "リバーシに白黒の石を使う"
|
use-white-black-reversi-stones: "リバーシに白黒の石を使う"
|
||||||
use-contrast-reversi-stones: "リバーシのアイコンにコントラストを付ける"
|
|
||||||
verified-user: "Verifizierter Benutzer"
|
verified-user: "Verifizierter Benutzer"
|
||||||
disable-animated-mfm: "投稿内の動きのあるテキストを無効にする"
|
disable-animated-mfm: "投稿内の動きのあるテキストを無効にする"
|
||||||
suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する"
|
suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する"
|
||||||
@@ -165,6 +164,7 @@ common:
|
|||||||
hashtags: "Hashtags"
|
hashtags: "Hashtags"
|
||||||
dev: "Fehler beim Erstellen der Applikation. Bitte versuche es erneut."
|
dev: "Fehler beim Erstellen der Applikation. Bitte versuche es erneut."
|
||||||
ai-chan-kawaii: "藍ちゃかわいい"
|
ai-chan-kawaii: "藍ちゃかわいい"
|
||||||
|
you: "あなた"
|
||||||
auth/views/form.vue:
|
auth/views/form.vue:
|
||||||
share-access: "<i>{name}</i>があなたのアカウントにアクセスすることを許可しますか?"
|
share-access: "<i>{name}</i>があなたのアカウントにアクセスすることを許可しますか?"
|
||||||
permission-ask: "このアプリは次の権限を要求しています:"
|
permission-ask: "このアプリは次の権限を要求しています:"
|
||||||
@@ -1054,6 +1054,20 @@ admin/views/charts.vue:
|
|||||||
network-requests: "リクエスト"
|
network-requests: "リクエスト"
|
||||||
network-time: "応答時間"
|
network-time: "応答時間"
|
||||||
network-usage: "通信量"
|
network-usage: "通信量"
|
||||||
|
admin/views/drive.vue:
|
||||||
|
sort:
|
||||||
|
title: "ソート"
|
||||||
|
createdAtAsc: "アップロード日時が古い順"
|
||||||
|
createdAtDesc: "アップロード日時が新しい順"
|
||||||
|
sizeAsc: "サイズが小さい順"
|
||||||
|
sizeDesc: "サイズが大きい順"
|
||||||
|
origin:
|
||||||
|
title: "オリジン"
|
||||||
|
combined: "ローカル+リモート"
|
||||||
|
local: "ローカル"
|
||||||
|
remote: "リモート"
|
||||||
|
delete: "削除"
|
||||||
|
deleted: "削除しました"
|
||||||
admin/views/users.vue:
|
admin/views/users.vue:
|
||||||
operation: "操作"
|
operation: "操作"
|
||||||
username-or-userid: "ユーザー名またはユーザーID"
|
username-or-userid: "ユーザー名またはユーザーID"
|
||||||
|
@@ -111,7 +111,6 @@ common:
|
|||||||
i-like-sushi: "I prefer sushi rather than pudding"
|
i-like-sushi: "I prefer sushi rather than pudding"
|
||||||
show-reversi-board-labels: "Show row and column labels in Reversi"
|
show-reversi-board-labels: "Show row and column labels in Reversi"
|
||||||
use-white-black-reversi-stones: "Use white-black stone in reversi"
|
use-white-black-reversi-stones: "Use white-black stone in reversi"
|
||||||
use-contrast-reversi-stones: "Make the stone color clear in reversi"
|
|
||||||
verified-user: "Verified account"
|
verified-user: "Verified account"
|
||||||
disable-animated-mfm: "Disable animated texts in a post"
|
disable-animated-mfm: "Disable animated texts in a post"
|
||||||
suggest-recent-hashtags: "Suggest recently used hashtags within the post composition area"
|
suggest-recent-hashtags: "Suggest recently used hashtags within the post composition area"
|
||||||
@@ -165,6 +164,7 @@ common:
|
|||||||
hashtags: "Hashtags"
|
hashtags: "Hashtags"
|
||||||
dev: "Failed to create the application. Please try again."
|
dev: "Failed to create the application. Please try again."
|
||||||
ai-chan-kawaii: "Ai-chan kawaii!"
|
ai-chan-kawaii: "Ai-chan kawaii!"
|
||||||
|
you: "You"
|
||||||
auth/views/form.vue:
|
auth/views/form.vue:
|
||||||
share-access: "Would you allow <i>{name}</i> to access your account?"
|
share-access: "Would you allow <i>{name}</i> to access your account?"
|
||||||
permission-ask: "This application requires the following permissions:"
|
permission-ask: "This application requires the following permissions:"
|
||||||
@@ -1054,6 +1054,20 @@ admin/views/charts.vue:
|
|||||||
network-requests: "Requests"
|
network-requests: "Requests"
|
||||||
network-time: "Response time"
|
network-time: "Response time"
|
||||||
network-usage: "Traffic"
|
network-usage: "Traffic"
|
||||||
|
admin/views/drive.vue:
|
||||||
|
sort:
|
||||||
|
title: "Sort"
|
||||||
|
createdAtAsc: "アップロード日時が古い順"
|
||||||
|
createdAtDesc: "アップロード日時が新しい順"
|
||||||
|
sizeAsc: "サイズが小さい順"
|
||||||
|
sizeDesc: "サイズが大きい順"
|
||||||
|
origin:
|
||||||
|
title: "Origin"
|
||||||
|
combined: "Local + Remote"
|
||||||
|
local: "Local"
|
||||||
|
remote: "Remote"
|
||||||
|
delete: "Delete"
|
||||||
|
deleted: "Deleted successfully"
|
||||||
admin/views/users.vue:
|
admin/views/users.vue:
|
||||||
operation: "Operations"
|
operation: "Operations"
|
||||||
username-or-userid: "Username or user ID"
|
username-or-userid: "Username or user ID"
|
||||||
|
@@ -111,7 +111,6 @@ common:
|
|||||||
i-like-sushi: "Prefiero sushi a pudín"
|
i-like-sushi: "Prefiero sushi a pudín"
|
||||||
show-reversi-board-labels: "Mostrar etiquetas de filas y columnas en Reversi"
|
show-reversi-board-labels: "Mostrar etiquetas de filas y columnas en Reversi"
|
||||||
use-white-black-reversi-stones: "リバーシに白黒の石を使う"
|
use-white-black-reversi-stones: "リバーシに白黒の石を使う"
|
||||||
use-contrast-reversi-stones: "Hacer el color de la piedra claro en Reversi"
|
|
||||||
verified-user: "Cuenta verificada"
|
verified-user: "Cuenta verificada"
|
||||||
disable-animated-mfm: "Desactivar texto animado en una publicación"
|
disable-animated-mfm: "Desactivar texto animado en una publicación"
|
||||||
suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する"
|
suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する"
|
||||||
@@ -165,6 +164,7 @@ common:
|
|||||||
hashtags: "Etiquetas"
|
hashtags: "Etiquetas"
|
||||||
dev: "アプリの作成に失敗しました。再度お試しください。"
|
dev: "アプリの作成に失敗しました。再度お試しください。"
|
||||||
ai-chan-kawaii: "藍ちゃかわいい"
|
ai-chan-kawaii: "藍ちゃかわいい"
|
||||||
|
you: "あなた"
|
||||||
auth/views/form.vue:
|
auth/views/form.vue:
|
||||||
share-access: "<i>{name}</i>があなたのアカウントにアクセスすることを許可しますか?"
|
share-access: "<i>{name}</i>があなたのアカウントにアクセスすることを許可しますか?"
|
||||||
permission-ask: "La aplicación requiere los siguientes permisos:"
|
permission-ask: "La aplicación requiere los siguientes permisos:"
|
||||||
@@ -1054,6 +1054,20 @@ admin/views/charts.vue:
|
|||||||
network-requests: "リクエスト"
|
network-requests: "リクエスト"
|
||||||
network-time: "応答時間"
|
network-time: "応答時間"
|
||||||
network-usage: "通信量"
|
network-usage: "通信量"
|
||||||
|
admin/views/drive.vue:
|
||||||
|
sort:
|
||||||
|
title: "ソート"
|
||||||
|
createdAtAsc: "アップロード日時が古い順"
|
||||||
|
createdAtDesc: "アップロード日時が新しい順"
|
||||||
|
sizeAsc: "サイズが小さい順"
|
||||||
|
sizeDesc: "サイズが大きい順"
|
||||||
|
origin:
|
||||||
|
title: "オリジン"
|
||||||
|
combined: "ローカル+リモート"
|
||||||
|
local: "ローカル"
|
||||||
|
remote: "リモート"
|
||||||
|
delete: "削除"
|
||||||
|
deleted: "削除しました"
|
||||||
admin/views/users.vue:
|
admin/views/users.vue:
|
||||||
operation: "操作"
|
operation: "操作"
|
||||||
username-or-userid: "ユーザー名またはユーザーID"
|
username-or-userid: "ユーザー名またはユーザーID"
|
||||||
|
@@ -47,11 +47,11 @@ common:
|
|||||||
seconds_ago: "Il y a {} seconde·s"
|
seconds_ago: "Il y a {} seconde·s"
|
||||||
minutes_ago: "Il y a {} min"
|
minutes_ago: "Il y a {} min"
|
||||||
hours_ago: "Il y a {} h"
|
hours_ago: "Il y a {} h"
|
||||||
days_ago: "Il y a {} jours"
|
days_ago: "Il y a {} j"
|
||||||
weeks_ago: "Il y a {} semaines·s"
|
weeks_ago: "Il y a {} semaines"
|
||||||
months_ago: "Il y a {} mois"
|
months_ago: "Il y a {} mois"
|
||||||
years_ago: "Il y a {} an·s"
|
years_ago: "Il y a {} an·s"
|
||||||
month-and-day: "{day}/{month}"
|
month-and-day: "{day}-{month}"
|
||||||
trash: "Corbeille"
|
trash: "Corbeille"
|
||||||
drive: "Drive"
|
drive: "Drive"
|
||||||
messaging: "Conversations"
|
messaging: "Conversations"
|
||||||
@@ -111,7 +111,6 @@ common:
|
|||||||
i-like-sushi: "Je préfère les sushis plutôt que le pudding"
|
i-like-sushi: "Je préfère les sushis plutôt que le pudding"
|
||||||
show-reversi-board-labels: "Afficher les étiquettes des lignes et colonnes dans Reversi"
|
show-reversi-board-labels: "Afficher les étiquettes des lignes et colonnes dans Reversi"
|
||||||
use-white-black-reversi-stones: "Jouer avec des pions noirs et blancs sur Reversi"
|
use-white-black-reversi-stones: "Jouer avec des pions noirs et blancs sur Reversi"
|
||||||
use-contrast-reversi-stones: "Icône avec contraste sur Reversi"
|
|
||||||
verified-user: "Compte vérifié"
|
verified-user: "Compte vérifié"
|
||||||
disable-animated-mfm: "Désactiver les textes animés dans les publications"
|
disable-animated-mfm: "Désactiver les textes animés dans les publications"
|
||||||
suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する"
|
suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する"
|
||||||
@@ -165,6 +164,7 @@ common:
|
|||||||
hashtags: "Hashtags"
|
hashtags: "Hashtags"
|
||||||
dev: "Échec lors de la création de l’application. Veuillez réessayer."
|
dev: "Échec lors de la création de l’application. Veuillez réessayer."
|
||||||
ai-chan-kawaii: "Ai-Chan est mignonne !"
|
ai-chan-kawaii: "Ai-Chan est mignonne !"
|
||||||
|
you: "Vous"
|
||||||
auth/views/form.vue:
|
auth/views/form.vue:
|
||||||
share-access: "Désirez-vous autoriser <i>{name}</i> à avoir accès à votre compte ?"
|
share-access: "Désirez-vous autoriser <i>{name}</i> à avoir accès à votre compte ?"
|
||||||
permission-ask: "Cette application nécessite les autorisations suivantes :"
|
permission-ask: "Cette application nécessite les autorisations suivantes :"
|
||||||
@@ -478,7 +478,7 @@ common/views/widgets/broadcast.vue:
|
|||||||
next: "Suivant"
|
next: "Suivant"
|
||||||
common/views/widgets/calendar.vue:
|
common/views/widgets/calendar.vue:
|
||||||
year: "Année {}"
|
year: "Année {}"
|
||||||
month: "Mois {}"
|
month: "{},"
|
||||||
day: "{}"
|
day: "{}"
|
||||||
today: "Aujourd’hui :"
|
today: "Aujourd’hui :"
|
||||||
this-month: "Ce mois-ci :"
|
this-month: "Ce mois-ci :"
|
||||||
@@ -515,7 +515,7 @@ common/views/widgets/tips.vue:
|
|||||||
tips-line10: "タイムマシンウィジェットを利用すると、簡単に過去のタイムラインに遡れます"
|
tips-line10: "タイムマシンウィジェットを利用すると、簡単に過去のタイムラインに遡れます"
|
||||||
tips-line11: "Vous pouvez épingler des notes sur votre page en cliquant sur « … »"
|
tips-line11: "Vous pouvez épingler des notes sur votre page en cliquant sur « … »"
|
||||||
tips-line13: "Tous les fichiers attachés à cette publication sont sauvegardés dans le Drive"
|
tips-line13: "Tous les fichiers attachés à cette publication sont sauvegardés dans le Drive"
|
||||||
tips-line14: "ホームのカスタマイズ中、ウィジェットを右クリックしてデザインを変更できます"
|
tips-line14: "Lorsque vous personnalisez la disposition de votre page d’accueil, vous pouvez effectuer un clique droit sur un widget pour changer son apparence."
|
||||||
tips-line17: "Vous pouvez mettre un texte en surbrillance en le mettant entre ** **"
|
tips-line17: "Vous pouvez mettre un texte en surbrillance en le mettant entre ** **"
|
||||||
tips-line19: "Plusieurs fenêtres peuvent être détachées en dehors du navigateur."
|
tips-line19: "Plusieurs fenêtres peuvent être détachées en dehors du navigateur."
|
||||||
tips-line20: "Pourcentage sur le widget calendrier qui indique le pourcentage de temps passé"
|
tips-line20: "Pourcentage sur le widget calendrier qui indique le pourcentage de temps passé"
|
||||||
@@ -524,7 +524,7 @@ common/views/widgets/tips.vue:
|
|||||||
tips-line24: "Misskey est fonctionnel depuis 2014"
|
tips-line24: "Misskey est fonctionnel depuis 2014"
|
||||||
tips-line25: "Vous pouvez recevoir les notifications de Misskey dans un navigateur web compatible"
|
tips-line25: "Vous pouvez recevoir les notifications de Misskey dans un navigateur web compatible"
|
||||||
common/views/pages/404.vue:
|
common/views/pages/404.vue:
|
||||||
page-not-found: "ページが見つかりませんでした"
|
page-not-found: "La page demandée est introuvable !"
|
||||||
common/views/pages/follow.vue:
|
common/views/pages/follow.vue:
|
||||||
signed-in-as: "Connecté·e en tant que {}"
|
signed-in-as: "Connecté·e en tant que {}"
|
||||||
following: "Suit"
|
following: "Suit"
|
||||||
@@ -553,7 +553,7 @@ desktop/views/components/activity.vue:
|
|||||||
title: "Activité"
|
title: "Activité"
|
||||||
toggle: "Afficher les vues"
|
toggle: "Afficher les vues"
|
||||||
desktop/views/components/calendar.vue:
|
desktop/views/components/calendar.vue:
|
||||||
title: "{month} / {year}"
|
title: "{month} - {year}"
|
||||||
prev: "Mois précédent"
|
prev: "Mois précédent"
|
||||||
next: "Mois suivant"
|
next: "Mois suivant"
|
||||||
go: "Cliquez pour naviguer"
|
go: "Cliquez pour naviguer"
|
||||||
@@ -877,7 +877,7 @@ common/views/components/password-settings.vue:
|
|||||||
enter-new-password-again: "Entrez à nouveau le nouveau mot de passe"
|
enter-new-password-again: "Entrez à nouveau le nouveau mot de passe"
|
||||||
not-match: "Les nouveaux mots de passe ne sont pas identiques"
|
not-match: "Les nouveaux mots de passe ne sont pas identiques"
|
||||||
changed: "Mot de passe modifié avec succès"
|
changed: "Mot de passe modifié avec succès"
|
||||||
failed: "パスワード変更に失敗しました"
|
failed: "Échec lors de la modification du mot de passe"
|
||||||
desktop/views/components/sub-note-content.vue:
|
desktop/views/components/sub-note-content.vue:
|
||||||
private: "cette publication est privée"
|
private: "cette publication est privée"
|
||||||
deleted: "cette publication a été supprimée"
|
deleted: "cette publication a été supprimée"
|
||||||
@@ -970,7 +970,7 @@ admin/views/instance.vue:
|
|||||||
instance-description: "Description de l’instance"
|
instance-description: "Description de l’instance"
|
||||||
host: "Hôte"
|
host: "Hôte"
|
||||||
banner-url: "Url de l’image de la bannière"
|
banner-url: "Url de l’image de la bannière"
|
||||||
error-image-url: "エラー画像URL"
|
error-image-url: "URL de l’image d’erreur"
|
||||||
languages: "Langue de l’instance"
|
languages: "Langue de l’instance"
|
||||||
languages-desc: "Vous pouvez en définir plus d’une, séparées par des espaces."
|
languages-desc: "Vous pouvez en définir plus d’une, séparées par des espaces."
|
||||||
maintainer-config: "Informations de l’administrateur"
|
maintainer-config: "Informations de l’administrateur"
|
||||||
@@ -1054,6 +1054,20 @@ admin/views/charts.vue:
|
|||||||
network-requests: "Requêtes"
|
network-requests: "Requêtes"
|
||||||
network-time: "Temps de réponse"
|
network-time: "Temps de réponse"
|
||||||
network-usage: "Traffic"
|
network-usage: "Traffic"
|
||||||
|
admin/views/drive.vue:
|
||||||
|
sort:
|
||||||
|
title: "Tri"
|
||||||
|
createdAtAsc: "アップロード日時が古い順"
|
||||||
|
createdAtDesc: "アップロード日時が新しい順"
|
||||||
|
sizeAsc: "Taille - Ascendant"
|
||||||
|
sizeDesc: "Taille - Volumineux en premier"
|
||||||
|
origin:
|
||||||
|
title: "Origine"
|
||||||
|
combined: "Locaux et distants combinés"
|
||||||
|
local: "Local"
|
||||||
|
remote: "Distant"
|
||||||
|
delete: "Supprimer"
|
||||||
|
deleted: "Supprimé"
|
||||||
admin/views/users.vue:
|
admin/views/users.vue:
|
||||||
operation: "Actions"
|
operation: "Actions"
|
||||||
username-or-userid: "Nom d’utilisateur·rice ou ID utilisateur"
|
username-or-userid: "Nom d’utilisateur·rice ou ID utilisateur"
|
||||||
@@ -1076,7 +1090,7 @@ admin/views/users.vue:
|
|||||||
createdAtAsc: "Date d’inscription (Ascendant)"
|
createdAtAsc: "Date d’inscription (Ascendant)"
|
||||||
createdAtDesc: "Date d’inscription (Descendant)"
|
createdAtDesc: "Date d’inscription (Descendant)"
|
||||||
updatedAtAsc: "Mis à jour récemment (Ascendant)"
|
updatedAtAsc: "Mis à jour récemment (Ascendant)"
|
||||||
updatedAtDesc: "更新日時が新しい順"
|
updatedAtDesc: "Mis à jour récemment (descendant)"
|
||||||
origin:
|
origin:
|
||||||
title: "Origine"
|
title: "Origine"
|
||||||
combined: "Locaux + distants"
|
combined: "Locaux + distants"
|
||||||
@@ -1189,7 +1203,7 @@ desktop/views/pages/user/user.header.vue:
|
|||||||
years-old: "{age} ans"
|
years-old: "{age} ans"
|
||||||
year: "/"
|
year: "/"
|
||||||
month: "/"
|
month: "/"
|
||||||
day: "/"
|
day: "-"
|
||||||
desktop/views/pages/user/user.timeline.vue:
|
desktop/views/pages/user/user.timeline.vue:
|
||||||
default: "Publications"
|
default: "Publications"
|
||||||
with-replies: "Publications et réponses"
|
with-replies: "Publications et réponses"
|
||||||
@@ -1349,7 +1363,7 @@ mobile/views/pages/welcome.vue:
|
|||||||
signup: "S'enregistrer"
|
signup: "S'enregistrer"
|
||||||
mobile/views/pages/widgets.vue:
|
mobile/views/pages/widgets.vue:
|
||||||
dashboard: "Tableau de bord"
|
dashboard: "Tableau de bord"
|
||||||
widgets-hints: "ウィジェットを追加/削除したり並べ替えたりできます。ウィジェットを移動するには「三」をドラッグします。ウィジェットを削除するには「x」をタップします。いくつかのウィジェットはタップすることで表示を変更できます。"
|
widgets-hints: "Vous pouvez ajouter, supprimer et réaranger les widgets. Faites glisser « 三 » pour déplacer le widget. Appuyez sur « x » pour supprimer le widget. Certains widgets peuvent changer d’apparence en cliquant dessus."
|
||||||
add-widget: "Ajouter"
|
add-widget: "Ajouter"
|
||||||
customization-tips: "Conseils de personnalisation"
|
customization-tips: "Conseils de personnalisation"
|
||||||
mobile/views/pages/widgets/activity.vue:
|
mobile/views/pages/widgets/activity.vue:
|
||||||
|
@@ -111,7 +111,6 @@ common:
|
|||||||
i-like-sushi: "私は(プリンよりむしろ)寿司が好き"
|
i-like-sushi: "私は(プリンよりむしろ)寿司が好き"
|
||||||
show-reversi-board-labels: "リバーシのボードの行と列のラベルを表示"
|
show-reversi-board-labels: "リバーシのボードの行と列のラベルを表示"
|
||||||
use-white-black-reversi-stones: "リバーシに白黒の石を使う"
|
use-white-black-reversi-stones: "リバーシに白黒の石を使う"
|
||||||
use-contrast-reversi-stones: "リバーシのアイコンにコントラストを付ける"
|
|
||||||
verified-user: "公式アカウント"
|
verified-user: "公式アカウント"
|
||||||
disable-animated-mfm: "投稿内の動きのあるテキストを無効にする"
|
disable-animated-mfm: "投稿内の動きのあるテキストを無効にする"
|
||||||
suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する"
|
suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する"
|
||||||
@@ -165,6 +164,7 @@ common:
|
|||||||
hashtags: "ハッシュタグ"
|
hashtags: "ハッシュタグ"
|
||||||
dev: "アプリの作成に失敗しました。再度お試しください。"
|
dev: "アプリの作成に失敗しました。再度お試しください。"
|
||||||
ai-chan-kawaii: "藍ちゃかわいい"
|
ai-chan-kawaii: "藍ちゃかわいい"
|
||||||
|
you: "あなた"
|
||||||
auth/views/form.vue:
|
auth/views/form.vue:
|
||||||
share-access: "<i>{name}</i>があなたのアカウントにアクセスすることを許可しますか?"
|
share-access: "<i>{name}</i>があなたのアカウントにアクセスすることを許可しますか?"
|
||||||
permission-ask: "このアプリは次の権限を要求しています:"
|
permission-ask: "このアプリは次の権限を要求しています:"
|
||||||
@@ -1054,6 +1054,20 @@ admin/views/charts.vue:
|
|||||||
network-requests: "リクエスト"
|
network-requests: "リクエスト"
|
||||||
network-time: "応答時間"
|
network-time: "応答時間"
|
||||||
network-usage: "通信量"
|
network-usage: "通信量"
|
||||||
|
admin/views/drive.vue:
|
||||||
|
sort:
|
||||||
|
title: "ソート"
|
||||||
|
createdAtAsc: "アップロード日時が古い順"
|
||||||
|
createdAtDesc: "アップロード日時が新しい順"
|
||||||
|
sizeAsc: "サイズが小さい順"
|
||||||
|
sizeDesc: "サイズが大きい順"
|
||||||
|
origin:
|
||||||
|
title: "オリジン"
|
||||||
|
combined: "ローカル+リモート"
|
||||||
|
local: "ローカル"
|
||||||
|
remote: "リモート"
|
||||||
|
delete: "削除"
|
||||||
|
deleted: "削除しました"
|
||||||
admin/views/users.vue:
|
admin/views/users.vue:
|
||||||
operation: "操作"
|
operation: "操作"
|
||||||
username-or-userid: "ユーザー名またはユーザーID"
|
username-or-userid: "ユーザー名またはユーザーID"
|
||||||
|
@@ -119,7 +119,6 @@ common:
|
|||||||
i-like-sushi: "私は(プリンよりむしろ)寿司が好き"
|
i-like-sushi: "私は(プリンよりむしろ)寿司が好き"
|
||||||
show-reversi-board-labels: "リバーシのボードの行と列のラベルを表示"
|
show-reversi-board-labels: "リバーシのボードの行と列のラベルを表示"
|
||||||
use-white-black-reversi-stones: "リバーシに白黒の石を使う"
|
use-white-black-reversi-stones: "リバーシに白黒の石を使う"
|
||||||
use-contrast-reversi-stones: "リバーシのアイコンにコントラストを付ける"
|
|
||||||
verified-user: "公式アカウント"
|
verified-user: "公式アカウント"
|
||||||
disable-animated-mfm: "投稿内の動きのあるテキストを無効にする"
|
disable-animated-mfm: "投稿内の動きのあるテキストを無効にする"
|
||||||
suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する"
|
suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する"
|
||||||
@@ -1184,6 +1183,21 @@ admin/views/charts.vue:
|
|||||||
network-time: "応答時間"
|
network-time: "応答時間"
|
||||||
network-usage: "通信量"
|
network-usage: "通信量"
|
||||||
|
|
||||||
|
admin/views/drive.vue:
|
||||||
|
sort:
|
||||||
|
title: "ソート"
|
||||||
|
createdAtAsc: "アップロード日時が古い順"
|
||||||
|
createdAtDesc: "アップロード日時が新しい順"
|
||||||
|
sizeAsc: "サイズが小さい順"
|
||||||
|
sizeDesc: "サイズが大きい順"
|
||||||
|
origin:
|
||||||
|
title: "オリジン"
|
||||||
|
combined: "ローカル+リモート"
|
||||||
|
local: "ローカル"
|
||||||
|
remote: "リモート"
|
||||||
|
delete: "削除"
|
||||||
|
deleted: "削除しました"
|
||||||
|
|
||||||
admin/views/users.vue:
|
admin/views/users.vue:
|
||||||
operation: "操作"
|
operation: "操作"
|
||||||
username-or-userid: "ユーザー名またはユーザーID"
|
username-or-userid: "ユーザー名またはユーザーID"
|
||||||
|
@@ -111,7 +111,6 @@ common:
|
|||||||
i-like-sushi: "寿司(のほうがプリンよりむしろ)ウマい、タコ焼きはあらへんけど。"
|
i-like-sushi: "寿司(のほうがプリンよりむしろ)ウマい、タコ焼きはあらへんけど。"
|
||||||
show-reversi-board-labels: "リバーシのボードの行と列のラベルを表示や!"
|
show-reversi-board-labels: "リバーシのボードの行と列のラベルを表示や!"
|
||||||
use-white-black-reversi-stones: "リバーシに白黒の石を使う"
|
use-white-black-reversi-stones: "リバーシに白黒の石を使う"
|
||||||
use-contrast-reversi-stones: "リバーシのアイコンにコントラストをつけんで!"
|
|
||||||
verified-user: "アメちゃん付きアカウント"
|
verified-user: "アメちゃん付きアカウント"
|
||||||
disable-animated-mfm: "投稿内のちょろちょろ動いてんのを止める"
|
disable-animated-mfm: "投稿内のちょろちょろ動いてんのを止める"
|
||||||
suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する"
|
suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する"
|
||||||
@@ -165,6 +164,7 @@ common:
|
|||||||
hashtags: "ハッシュタグ"
|
hashtags: "ハッシュタグ"
|
||||||
dev: "アプリの作成あかんかったわ。もっぺんやってみて。"
|
dev: "アプリの作成あかんかったわ。もっぺんやってみて。"
|
||||||
ai-chan-kawaii: "藍ちゃめっさべっぴんさんや"
|
ai-chan-kawaii: "藍ちゃめっさべっぴんさんや"
|
||||||
|
you: "あなた"
|
||||||
auth/views/form.vue:
|
auth/views/form.vue:
|
||||||
share-access: "あんたのアカウントに<i>{name}</i>がアクセスしようとしてるで?ええか?"
|
share-access: "あんたのアカウントに<i>{name}</i>がアクセスしようとしてるで?ええか?"
|
||||||
permission-ask: "このアプリは次の権限を要求してんで:"
|
permission-ask: "このアプリは次の権限を要求してんで:"
|
||||||
@@ -1054,6 +1054,20 @@ admin/views/charts.vue:
|
|||||||
network-requests: "リクエスト"
|
network-requests: "リクエスト"
|
||||||
network-time: "応答時間"
|
network-time: "応答時間"
|
||||||
network-usage: "通信量"
|
network-usage: "通信量"
|
||||||
|
admin/views/drive.vue:
|
||||||
|
sort:
|
||||||
|
title: "ソート"
|
||||||
|
createdAtAsc: "アップロード日時が古い順"
|
||||||
|
createdAtDesc: "アップロード日時が新しい順"
|
||||||
|
sizeAsc: "サイズが小さい順"
|
||||||
|
sizeDesc: "サイズが大きい順"
|
||||||
|
origin:
|
||||||
|
title: "オリジン"
|
||||||
|
combined: "ローカル+リモート"
|
||||||
|
local: "ローカル"
|
||||||
|
remote: "リモート"
|
||||||
|
delete: "削除"
|
||||||
|
deleted: "削除しました"
|
||||||
admin/views/users.vue:
|
admin/views/users.vue:
|
||||||
operation: "操作"
|
operation: "操作"
|
||||||
username-or-userid: "ユーザー名またはユーザーID"
|
username-or-userid: "ユーザー名またはユーザーID"
|
||||||
|
@@ -111,7 +111,6 @@ common:
|
|||||||
i-like-sushi: "저는 (푸딩보다 차라리) 초밥이 좋아요"
|
i-like-sushi: "저는 (푸딩보다 차라리) 초밥이 좋아요"
|
||||||
show-reversi-board-labels: "리버시 보드의 행과 열 레이블을 표시"
|
show-reversi-board-labels: "리버시 보드의 행과 열 레이블을 표시"
|
||||||
use-white-black-reversi-stones: "리버시에 흑백 돌을 사용"
|
use-white-black-reversi-stones: "리버시에 흑백 돌을 사용"
|
||||||
use-contrast-reversi-stones: "리버시 아이콘의 대비를 높이기"
|
|
||||||
verified-user: "공식 계정"
|
verified-user: "공식 계정"
|
||||||
disable-animated-mfm: "글의 문자 애니메이션을 비활성화"
|
disable-animated-mfm: "글의 문자 애니메이션을 비활성화"
|
||||||
suggest-recent-hashtags: "최근 해시태그를 글 작성란에 표시"
|
suggest-recent-hashtags: "최근 해시태그를 글 작성란에 표시"
|
||||||
@@ -165,6 +164,7 @@ common:
|
|||||||
hashtags: "해시태그"
|
hashtags: "해시태그"
|
||||||
dev: "앱을 만드는 데 실패했습니다. 다시 시도하시기 바랍니다."
|
dev: "앱을 만드는 데 실패했습니다. 다시 시도하시기 바랍니다."
|
||||||
ai-chan-kawaii: "아이쨩 귀여워"
|
ai-chan-kawaii: "아이쨩 귀여워"
|
||||||
|
you: "당신"
|
||||||
auth/views/form.vue:
|
auth/views/form.vue:
|
||||||
share-access: "<i>{name}</i>가 당신의 계정에 엑세스하도록 허용하시겠습니까?"
|
share-access: "<i>{name}</i>가 당신의 계정에 엑세스하도록 허용하시겠습니까?"
|
||||||
permission-ask: "이 앱은 다음의 권한을 요청합니다:"
|
permission-ask: "이 앱은 다음의 권한을 요청합니다:"
|
||||||
@@ -1054,6 +1054,20 @@ admin/views/charts.vue:
|
|||||||
network-requests: "요청"
|
network-requests: "요청"
|
||||||
network-time: "응답시간"
|
network-time: "응답시간"
|
||||||
network-usage: "통신량"
|
network-usage: "통신량"
|
||||||
|
admin/views/drive.vue:
|
||||||
|
sort:
|
||||||
|
title: "정렬"
|
||||||
|
createdAtAsc: "업로드 날짜 오랜 순"
|
||||||
|
createdAtDesc: "업로드 날짜 최신순"
|
||||||
|
sizeAsc: "크기가 작은 순"
|
||||||
|
sizeDesc: "크기가 큰 순"
|
||||||
|
origin:
|
||||||
|
title: "출처"
|
||||||
|
combined: "로컬 + 리모트"
|
||||||
|
local: "로컬"
|
||||||
|
remote: "리모트"
|
||||||
|
delete: "삭제"
|
||||||
|
deleted: "삭제하였습니다"
|
||||||
admin/views/users.vue:
|
admin/views/users.vue:
|
||||||
operation: "작업"
|
operation: "작업"
|
||||||
username-or-userid: "사용자명 혹은 사용자 ID"
|
username-or-userid: "사용자명 혹은 사용자 ID"
|
||||||
|
@@ -111,7 +111,6 @@ common:
|
|||||||
i-like-sushi: "私は(プリンよりむしろ)寿司が好き"
|
i-like-sushi: "私は(プリンよりむしろ)寿司が好き"
|
||||||
show-reversi-board-labels: "リバーシのボードの行と列のラベルを表示"
|
show-reversi-board-labels: "リバーシのボードの行と列のラベルを表示"
|
||||||
use-white-black-reversi-stones: "リバーシに白黒の石を使う"
|
use-white-black-reversi-stones: "リバーシに白黒の石を使う"
|
||||||
use-contrast-reversi-stones: "リバーシのアイコンにコントラストを付ける"
|
|
||||||
verified-user: "公式アカウント"
|
verified-user: "公式アカウント"
|
||||||
disable-animated-mfm: "投稿内の動きのあるテキストを無効にする"
|
disable-animated-mfm: "投稿内の動きのあるテキストを無効にする"
|
||||||
suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する"
|
suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する"
|
||||||
@@ -165,6 +164,7 @@ common:
|
|||||||
hashtags: "ハッシュタグ"
|
hashtags: "ハッシュタグ"
|
||||||
dev: "アプリの作成に失敗しました。再度お試しください。"
|
dev: "アプリの作成に失敗しました。再度お試しください。"
|
||||||
ai-chan-kawaii: "藍ちゃかわいい"
|
ai-chan-kawaii: "藍ちゃかわいい"
|
||||||
|
you: "あなた"
|
||||||
auth/views/form.vue:
|
auth/views/form.vue:
|
||||||
share-access: "<i>{name}</i>があなたのアカウントにアクセスすることを許可しますか?"
|
share-access: "<i>{name}</i>があなたのアカウントにアクセスすることを許可しますか?"
|
||||||
permission-ask: "このアプリは次の権限を要求しています:"
|
permission-ask: "このアプリは次の権限を要求しています:"
|
||||||
@@ -1054,6 +1054,20 @@ admin/views/charts.vue:
|
|||||||
network-requests: "リクエスト"
|
network-requests: "リクエスト"
|
||||||
network-time: "応答時間"
|
network-time: "応答時間"
|
||||||
network-usage: "通信量"
|
network-usage: "通信量"
|
||||||
|
admin/views/drive.vue:
|
||||||
|
sort:
|
||||||
|
title: "ソート"
|
||||||
|
createdAtAsc: "アップロード日時が古い順"
|
||||||
|
createdAtDesc: "アップロード日時が新しい順"
|
||||||
|
sizeAsc: "サイズが小さい順"
|
||||||
|
sizeDesc: "サイズが大きい順"
|
||||||
|
origin:
|
||||||
|
title: "オリジン"
|
||||||
|
combined: "ローカル+リモート"
|
||||||
|
local: "ローカル"
|
||||||
|
remote: "リモート"
|
||||||
|
delete: "削除"
|
||||||
|
deleted: "削除しました"
|
||||||
admin/views/users.vue:
|
admin/views/users.vue:
|
||||||
operation: "操作"
|
operation: "操作"
|
||||||
username-or-userid: "ユーザー名またはユーザーID"
|
username-or-userid: "ユーザー名またはユーザーID"
|
||||||
|
@@ -111,7 +111,6 @@ common:
|
|||||||
i-like-sushi: "私は(プリンよりむしろ)寿司が好き"
|
i-like-sushi: "私は(プリンよりむしろ)寿司が好き"
|
||||||
show-reversi-board-labels: "リバーシのボードの行と列のラベルを表示"
|
show-reversi-board-labels: "リバーシのボードの行と列のラベルを表示"
|
||||||
use-white-black-reversi-stones: "リバーシに白黒の石を使う"
|
use-white-black-reversi-stones: "リバーシに白黒の石を使う"
|
||||||
use-contrast-reversi-stones: "リバーシのアイコンにコントラストを付ける"
|
|
||||||
verified-user: "公式アカウント"
|
verified-user: "公式アカウント"
|
||||||
disable-animated-mfm: "投稿内の動きのあるテキストを無効にする"
|
disable-animated-mfm: "投稿内の動きのあるテキストを無効にする"
|
||||||
suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する"
|
suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する"
|
||||||
@@ -165,6 +164,7 @@ common:
|
|||||||
hashtags: "ハッシュタグ"
|
hashtags: "ハッシュタグ"
|
||||||
dev: "アプリの作成に失敗しました。再度お試しください。"
|
dev: "アプリの作成に失敗しました。再度お試しください。"
|
||||||
ai-chan-kawaii: "藍ちゃかわいい"
|
ai-chan-kawaii: "藍ちゃかわいい"
|
||||||
|
you: "あなた"
|
||||||
auth/views/form.vue:
|
auth/views/form.vue:
|
||||||
share-access: "<i>{name}</i>があなたのアカウントにアクセスすることを許可しますか?"
|
share-access: "<i>{name}</i>があなたのアカウントにアクセスすることを許可しますか?"
|
||||||
permission-ask: "このアプリは次の権限を要求しています:"
|
permission-ask: "このアプリは次の権限を要求しています:"
|
||||||
@@ -1054,6 +1054,20 @@ admin/views/charts.vue:
|
|||||||
network-requests: "リクエスト"
|
network-requests: "リクエスト"
|
||||||
network-time: "応答時間"
|
network-time: "応答時間"
|
||||||
network-usage: "通信量"
|
network-usage: "通信量"
|
||||||
|
admin/views/drive.vue:
|
||||||
|
sort:
|
||||||
|
title: "ソート"
|
||||||
|
createdAtAsc: "アップロード日時が古い順"
|
||||||
|
createdAtDesc: "アップロード日時が新しい順"
|
||||||
|
sizeAsc: "サイズが小さい順"
|
||||||
|
sizeDesc: "サイズが大きい順"
|
||||||
|
origin:
|
||||||
|
title: "オリジン"
|
||||||
|
combined: "ローカル+リモート"
|
||||||
|
local: "ローカル"
|
||||||
|
remote: "リモート"
|
||||||
|
delete: "削除"
|
||||||
|
deleted: "削除しました"
|
||||||
admin/views/users.vue:
|
admin/views/users.vue:
|
||||||
operation: "操作"
|
operation: "操作"
|
||||||
username-or-userid: "ユーザー名またはユーザーID"
|
username-or-userid: "ユーザー名またはユーザーID"
|
||||||
|
@@ -111,15 +111,14 @@ common:
|
|||||||
i-like-sushi: "Wolę sushi od puddingu"
|
i-like-sushi: "Wolę sushi od puddingu"
|
||||||
show-reversi-board-labels: "Pokazuj podpisy wierszy i kolumn w Reversi"
|
show-reversi-board-labels: "Pokazuj podpisy wierszy i kolumn w Reversi"
|
||||||
use-white-black-reversi-stones: "リバーシに白黒の石を使う"
|
use-white-black-reversi-stones: "リバーシに白黒の石を使う"
|
||||||
use-contrast-reversi-stones: "リバーシのアイコンにコントラストを付ける"
|
verified-user: "Zweryfikowane konto"
|
||||||
verified-user: "公式アカウント"
|
|
||||||
disable-animated-mfm: "Wyłącz animowany tekst we wpisach"
|
disable-animated-mfm: "Wyłącz animowany tekst we wpisach"
|
||||||
suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する"
|
suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する"
|
||||||
always-show-nsfw: "常に閲覧注意のメディアを表示する"
|
always-show-nsfw: "Zawszę pokazuj zawartość NSFW"
|
||||||
always-mark-nsfw: "Zawsze oznaczaj posty z multimediami jako NSFW"
|
always-mark-nsfw: "Zawsze oznaczaj posty z multimediami jako NSFW"
|
||||||
show-full-acct: "ユーザー名のホストを省略しない"
|
show-full-acct: "ユーザー名のホストを省略しない"
|
||||||
show-via: "viaを表示する"
|
show-via: "viaを表示する"
|
||||||
reduce-motion: "UIの動きを減らす"
|
reduce-motion: "Zredukuj ruch w UI"
|
||||||
this-setting-is-this-device-only: "このデバイスのみ"
|
this-setting-is-this-device-only: "このデバイスのみ"
|
||||||
use-os-default-emojis: "Użyj domyślnych Emoji systemowych"
|
use-os-default-emojis: "Użyj domyślnych Emoji systemowych"
|
||||||
do-not-use-in-production: 'これは開発ビルドです。本番環境で使用しないでください。'
|
do-not-use-in-production: 'これは開発ビルドです。本番環境で使用しないでください。'
|
||||||
@@ -165,6 +164,7 @@ common:
|
|||||||
hashtags: "Hashtagi"
|
hashtags: "Hashtagi"
|
||||||
dev: "アプリの作成に失敗しました。再度お試しください。"
|
dev: "アプリの作成に失敗しました。再度お試しください。"
|
||||||
ai-chan-kawaii: "藍ちゃかわいい"
|
ai-chan-kawaii: "藍ちゃかわいい"
|
||||||
|
you: "Ty"
|
||||||
auth/views/form.vue:
|
auth/views/form.vue:
|
||||||
share-access: "<i>{name}</i>があなたのアカウントにアクセスすることを許可しますか?"
|
share-access: "<i>{name}</i>があなたのアカウントにアクセスすることを許可しますか?"
|
||||||
permission-ask: "Ta aplikacja wymaga następujących uprawnień:"
|
permission-ask: "Ta aplikacja wymaga następujących uprawnień:"
|
||||||
@@ -298,7 +298,7 @@ common/views/components/cw-button.vue:
|
|||||||
hide: "Ukryj"
|
hide: "Ukryj"
|
||||||
show: "Pokaż więcej"
|
show: "Pokaż więcej"
|
||||||
chars: "{count} znaków"
|
chars: "{count} znaków"
|
||||||
files: "{count}ファイル"
|
files: "{count} plików"
|
||||||
common/views/components/messaging.vue:
|
common/views/components/messaging.vue:
|
||||||
search-user: "Znajdź użytkownika"
|
search-user: "Znajdź użytkownika"
|
||||||
you: "Ty"
|
you: "Ty"
|
||||||
@@ -576,7 +576,7 @@ desktop/views/components/drive-window.vue:
|
|||||||
desktop/views/components/drive.file.vue:
|
desktop/views/components/drive.file.vue:
|
||||||
avatar: "Awatar"
|
avatar: "Awatar"
|
||||||
banner: "Baner"
|
banner: "Baner"
|
||||||
nsfw: "閲覧注意"
|
nsfw: "NSFW"
|
||||||
contextmenu:
|
contextmenu:
|
||||||
rename: "Zmień nazwę"
|
rename: "Zmień nazwę"
|
||||||
mark-as-sensitive: "Oznacz jako zawartość wrażliwą"
|
mark-as-sensitive: "Oznacz jako zawartość wrażliwą"
|
||||||
@@ -662,7 +662,7 @@ desktop/views/components/note-detail.vue:
|
|||||||
add-reaction: "Dodaj reakcję"
|
add-reaction: "Dodaj reakcję"
|
||||||
desktop/views/components/note.vue:
|
desktop/views/components/note.vue:
|
||||||
reply: "Odpowiedz"
|
reply: "Odpowiedz"
|
||||||
renote: "Renote"
|
renote: "Udostępnij"
|
||||||
add-reaction: "Dodaj reakcję"
|
add-reaction: "Dodaj reakcję"
|
||||||
detail: "Szczegóły"
|
detail: "Szczegóły"
|
||||||
private: "この投稿は非公開です"
|
private: "この投稿は非公開です"
|
||||||
@@ -729,7 +729,7 @@ desktop/views/components/settings.vue:
|
|||||||
notification: "Powiadomienia"
|
notification: "Powiadomienia"
|
||||||
apps: "Aplikacje"
|
apps: "Aplikacje"
|
||||||
tags: "Hashtagi"
|
tags: "Hashtagi"
|
||||||
mute-and-block: "ミュート/ブロック"
|
mute-and-block: "Wycisz / Zablokuj"
|
||||||
blocking: "ブロック"
|
blocking: "ブロック"
|
||||||
security: "Bezpieczeństwo"
|
security: "Bezpieczeństwo"
|
||||||
signin: "Historia logowań"
|
signin: "Historia logowań"
|
||||||
@@ -753,14 +753,14 @@ desktop/views/components/settings.vue:
|
|||||||
api-via-stream-desc: "この設定をオンにすると、websocket接続を経由してAPIリクエストが行われます(パフォーマンス向上が期待できます)。オフにすると、ネイティブの fetch APIが利用されます。この設定はこのデバイスのみ有効です。"
|
api-via-stream-desc: "この設定をオンにすると、websocket接続を経由してAPIリクエストが行われます(パフォーマンス向上が期待できます)。オフにすると、ネイティブの fetch APIが利用されます。この設定はこのデバイスのみ有効です。"
|
||||||
deck-nav: "デッキ内ナビゲーション"
|
deck-nav: "デッキ内ナビゲーション"
|
||||||
deck-nav-desc: "デッキを使用しているとき、ナビゲーションが発生する際にページ遷移を行わずに一時的なカラムで受けるようにします。"
|
deck-nav-desc: "デッキを使用しているとき、ナビゲーションが発生する際にページ遷移を行わずに一時的なカラムで受けるようにします。"
|
||||||
deck-default: "デッキをデフォルトのUIにする"
|
deck-default: "Użyj Talię jako domyślne UI"
|
||||||
display: "Wygląd i wyświetlanie"
|
display: "Wygląd i wyświetlanie"
|
||||||
customize: "Dostosuj stronę główną"
|
customize: "Dostosuj stronę główną"
|
||||||
wallpaper: "Tapeta"
|
wallpaper: "Tapeta"
|
||||||
choose-wallpaper: "Wybierz tło"
|
choose-wallpaper: "Wybierz tło"
|
||||||
delete-wallpaper: "Usuń tło"
|
delete-wallpaper: "Usuń tło"
|
||||||
dark-mode: "Tryb ciemny"
|
dark-mode: "Tryb ciemny"
|
||||||
use-shadow: "UIに影を使用"
|
use-shadow: "Użyj cieni w UI"
|
||||||
rounded-corners: "Zaokrąglaj rogi w UI"
|
rounded-corners: "Zaokrąglaj rogi w UI"
|
||||||
circle-icons: "Używaj okrągłych ikon"
|
circle-icons: "Używaj okrągłych ikon"
|
||||||
contrasted-acct: "ユーザー名にコントラストを付ける"
|
contrasted-acct: "ユーザー名にコントラストを付ける"
|
||||||
@@ -769,20 +769,20 @@ desktop/views/components/settings.vue:
|
|||||||
show-reply-target: "Pokazuj cel odpowiedzi"
|
show-reply-target: "Pokazuj cel odpowiedzi"
|
||||||
timeline: "Oś czasu"
|
timeline: "Oś czasu"
|
||||||
show-my-renotes: "Pokazuj moje udostępnienia na osi czasu"
|
show-my-renotes: "Pokazuj moje udostępnienia na osi czasu"
|
||||||
show-renoted-my-notes: "自分の投稿のRenoteをタイムラインに表示する"
|
show-renoted-my-notes: "Pokazuj moje udostępnione wpisy na osi czasu"
|
||||||
show-local-renotes: "ローカルの投稿のRenoteをタイムラインに表示する"
|
show-local-renotes: "ローカルの投稿のRenoteをタイムラインに表示する"
|
||||||
show-maps: "Automatycznie pokazuj mapę"
|
show-maps: "Automatycznie pokazuj mapę"
|
||||||
remain-deleted-note: "削除された投稿を表示し続ける"
|
remain-deleted-note: "削除された投稿を表示し続ける"
|
||||||
deck-column-align: "デッキのカラムの配置"
|
deck-column-align: "デッキのカラムの配置"
|
||||||
deck-column-align-center: "中央"
|
deck-column-align-center: "中央"
|
||||||
deck-column-align-left: "左"
|
deck-column-align-left: "Lewo"
|
||||||
deck-column-align-flexible: "Elastyczne"
|
deck-column-align-flexible: "Elastyczne"
|
||||||
deck-column-width: "Szerokość kolumn w talii"
|
deck-column-width: "Szerokość kolumn w talii"
|
||||||
deck-column-width-narrow: "wąskie"
|
deck-column-width-narrow: "Wąska"
|
||||||
deck-column-width-narrower: "やや狭"
|
deck-column-width-narrower: "Trochę wąska"
|
||||||
deck-column-width-normal: "Normalny"
|
deck-column-width-normal: "Normalna"
|
||||||
deck-column-width-wider: "やや広"
|
deck-column-width-wider: "Trochę szeroka"
|
||||||
deck-column-width-wide: "szeroki"
|
deck-column-width-wide: "Szeroka"
|
||||||
sound: "Dźwięk"
|
sound: "Dźwięk"
|
||||||
enable-sounds: "Włącz dźwięk"
|
enable-sounds: "Włącz dźwięk"
|
||||||
enable-sounds-desc: "Odtwarzaj dźwięk przy wstawianiu wpisów, wysyłaniu lub otrzymywaniu wiadomości. Opcja ta jest zapamiętywana przez przeglądarkę."
|
enable-sounds-desc: "Odtwarzaj dźwięk przy wstawianiu wpisów, wysyłaniu lub otrzymywaniu wiadomości. Opcja ta jest zapamiętywana przez przeglądarkę."
|
||||||
@@ -817,10 +817,10 @@ desktop/views/components/settings.vue:
|
|||||||
tools: "Narzędzia"
|
tools: "Narzędzia"
|
||||||
task-manager: "Menedżer zadań"
|
task-manager: "Menedżer zadań"
|
||||||
third-parties: "Autorzy trzeci"
|
third-parties: "Autorzy trzeci"
|
||||||
navbar-position: "ナビゲーションバーの位置"
|
navbar-position: "Pozycja paska nawigacji"
|
||||||
navbar-position-top: "上"
|
navbar-position-top: "Góra"
|
||||||
navbar-position-left: "左"
|
navbar-position-left: "Lewo"
|
||||||
navbar-position-right: "右"
|
navbar-position-right: "Prawo"
|
||||||
desktop/views/components/settings.2fa.vue:
|
desktop/views/components/settings.2fa.vue:
|
||||||
intro: "Jeżeli skonfigurujesz uwierzytelnianie dwuetapowe, aby zablokować się będziesz potrzebować (oprócz hasła) kodu ze skonfigurowanego urządzenia (np. smartfonu), co zwiększy bezpieczeństwo."
|
intro: "Jeżeli skonfigurujesz uwierzytelnianie dwuetapowe, aby zablokować się będziesz potrzebować (oprócz hasła) kodu ze skonfigurowanego urządzenia (np. smartfonu), co zwiększy bezpieczeństwo."
|
||||||
detail: "Zobacz szczegóły…"
|
detail: "Zobacz szczegóły…"
|
||||||
@@ -840,7 +840,7 @@ desktop/views/components/settings.2fa.vue:
|
|||||||
failed: "Nie udało się skonfigurować uwierzytelniania dwuetapowego, upewnij się że wprowadziłeś prawidłowy token."
|
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."
|
info: "Od teraz, wprowadzaj token wyświetlany na urządzeniu przy każdym logowaniu do Misskey."
|
||||||
common/views/components/api-settings.vue:
|
common/views/components/api-settings.vue:
|
||||||
intro: "APIを利用するには、上記のトークンを「i」というキーでパラメータに付加してリクエストします。"
|
intro: "Aby uzyskać dostęp do API, ustaw ten token jako klucz 'i' parametrów żądań."
|
||||||
caution: "アカウントを不正利用される可能性があるため、このトークンは第三者に教えないでください(アプリなどにも入力しないでください)。"
|
caution: "アカウントを不正利用される可能性があるため、このトークンは第三者に教えないでください(アプリなどにも入力しないでください)。"
|
||||||
regeneration-of-token: "W przypadku wycieku tokenu, możesz wygenerować nowy."
|
regeneration-of-token: "W przypadku wycieku tokenu, możesz wygenerować nowy."
|
||||||
regenerate-token: "Wygeneruj nowy token"
|
regenerate-token: "Wygeneruj nowy token"
|
||||||
@@ -863,11 +863,11 @@ common/views/components/drive-settings.vue:
|
|||||||
common/views/components/mute-and-block.vue:
|
common/views/components/mute-and-block.vue:
|
||||||
mute-and-block: "Wycisz / Zablokuj"
|
mute-and-block: "Wycisz / Zablokuj"
|
||||||
mute: "Wycisz"
|
mute: "Wycisz"
|
||||||
block: "ブロック"
|
block: "Zablokuj"
|
||||||
no-muted-users: "Brak wyciszonych użytkowników"
|
no-muted-users: "Brak wyciszonych użytkowników"
|
||||||
no-blocked-users: "Brak zablokowanych użytkowników"
|
no-blocked-users: "Brak zablokowanych użytkowników"
|
||||||
word-mute: "Wyciszenie słowa"
|
word-mute: "Wyciszenie słowa"
|
||||||
muted-words: "ミュートされたキーワード"
|
muted-words: "Wyciszone słowa kluczowe"
|
||||||
muted-words-description: "スペースで区切るとAND指定になり、改行で区切るとOR指定になります"
|
muted-words-description: "スペースで区切るとAND指定になり、改行で区切るとOR指定になります"
|
||||||
save: "Zapisz"
|
save: "Zapisz"
|
||||||
common/views/components/password-settings.vue:
|
common/views/components/password-settings.vue:
|
||||||
@@ -884,7 +884,7 @@ desktop/views/components/sub-note-content.vue:
|
|||||||
media-count: "{}zawartości multimedialnej"
|
media-count: "{}zawartości multimedialnej"
|
||||||
poll: "Ankieta"
|
poll: "Ankieta"
|
||||||
desktop/views/components/settings.tags.vue:
|
desktop/views/components/settings.tags.vue:
|
||||||
title: "タグ"
|
title: "Tagi"
|
||||||
query: "クエリ (省略可)"
|
query: "クエリ (省略可)"
|
||||||
add: "Dodaj"
|
add: "Dodaj"
|
||||||
save: "Zapisz"
|
save: "Zapisz"
|
||||||
@@ -899,8 +899,8 @@ desktop/views/components/timeline.vue:
|
|||||||
messages: "Wiadomości"
|
messages: "Wiadomości"
|
||||||
list: "Listy"
|
list: "Listy"
|
||||||
hashtag: "Hashtag"
|
hashtag: "Hashtag"
|
||||||
add-tag-timeline: "ハッシュタグを追加"
|
add-tag-timeline: "Dodaj hashtag"
|
||||||
add-list: "リストを追加"
|
add-list: "Dodaj listę"
|
||||||
list-name: "リスト名"
|
list-name: "リスト名"
|
||||||
desktop/views/components/ui.header.vue:
|
desktop/views/components/ui.header.vue:
|
||||||
welcome-back: "Witaj ponownie,"
|
welcome-back: "Witaj ponownie,"
|
||||||
@@ -1054,6 +1054,20 @@ admin/views/charts.vue:
|
|||||||
network-requests: "Żądania"
|
network-requests: "Żądania"
|
||||||
network-time: "Czas reakcji"
|
network-time: "Czas reakcji"
|
||||||
network-usage: "通信量"
|
network-usage: "通信量"
|
||||||
|
admin/views/drive.vue:
|
||||||
|
sort:
|
||||||
|
title: "ソート"
|
||||||
|
createdAtAsc: "アップロード日時が古い順"
|
||||||
|
createdAtDesc: "アップロード日時が新しい順"
|
||||||
|
sizeAsc: "サイズが小さい順"
|
||||||
|
sizeDesc: "サイズが大きい順"
|
||||||
|
origin:
|
||||||
|
title: "Źródło"
|
||||||
|
combined: "ローカル+リモート"
|
||||||
|
local: "ローカル"
|
||||||
|
remote: "リモート"
|
||||||
|
delete: "Usuń"
|
||||||
|
deleted: "削除しました"
|
||||||
admin/views/users.vue:
|
admin/views/users.vue:
|
||||||
operation: "操作"
|
operation: "操作"
|
||||||
username-or-userid: "ユーザー名またはユーザーID"
|
username-or-userid: "ユーザー名またはユーザーID"
|
||||||
@@ -1237,14 +1251,14 @@ mobile/views/components/drive-file-chooser.vue:
|
|||||||
mobile/views/components/drive-folder-chooser.vue:
|
mobile/views/components/drive-folder-chooser.vue:
|
||||||
select-folder: "Wybierz katalog"
|
select-folder: "Wybierz katalog"
|
||||||
mobile/views/components/drive.file.vue:
|
mobile/views/components/drive.file.vue:
|
||||||
nsfw: "閲覧注意"
|
nsfw: "NSFW"
|
||||||
mobile/views/components/drive.file-detail.vue:
|
mobile/views/components/drive.file-detail.vue:
|
||||||
download: "Pobierz"
|
download: "Pobierz"
|
||||||
rename: "Zmień nazwę"
|
rename: "Zmień nazwę"
|
||||||
move: "Przenieś"
|
move: "Przenieś"
|
||||||
hash: "Hash (md5)"
|
hash: "Hash (md5)"
|
||||||
exif: "EXIF"
|
exif: "EXIF"
|
||||||
nsfw: "閲覧注意"
|
nsfw: "NSFW"
|
||||||
mark-as-sensitive: "閲覧注意に設定"
|
mark-as-sensitive: "閲覧注意に設定"
|
||||||
unmark-as-sensitive: "閲覧注意を解除"
|
unmark-as-sensitive: "閲覧注意を解除"
|
||||||
mobile/views/components/media-image.vue:
|
mobile/views/components/media-image.vue:
|
||||||
@@ -1384,7 +1398,7 @@ mobile/views/pages/settings.vue:
|
|||||||
timeline: "Oś czasu"
|
timeline: "Oś czasu"
|
||||||
show-reply-target: "Pokazuj cel odpowiedzi"
|
show-reply-target: "Pokazuj cel odpowiedzi"
|
||||||
show-my-renotes: "Pokazuj moje udostępnienia"
|
show-my-renotes: "Pokazuj moje udostępnienia"
|
||||||
show-renoted-my-notes: "自分の投稿のRenoteを表示する"
|
show-renoted-my-notes: "Pokazuj moje udostępnione wpisy"
|
||||||
show-local-renotes: "ローカルの投稿のRenoteを表示する"
|
show-local-renotes: "ローカルの投稿のRenoteを表示する"
|
||||||
post-style: "Styl wpisów"
|
post-style: "Styl wpisów"
|
||||||
post-style-standard: "Standardowy"
|
post-style-standard: "Standardowy"
|
||||||
@@ -1465,7 +1479,7 @@ deck:
|
|||||||
list: "Listy"
|
list: "Listy"
|
||||||
swap-left: "Przesuń w lewo"
|
swap-left: "Przesuń w lewo"
|
||||||
swap-right: "Przesuń w prawo"
|
swap-right: "Przesuń w prawo"
|
||||||
swap-up: "上に移動"
|
swap-up: "Przenieś w górę"
|
||||||
swap-down: "下に移動"
|
swap-down: "下に移動"
|
||||||
remove: "Usuń"
|
remove: "Usuń"
|
||||||
add-column: "Dodaj kolumnę"
|
add-column: "Dodaj kolumnę"
|
||||||
|
@@ -111,7 +111,6 @@ common:
|
|||||||
i-like-sushi: "Eu prefiro sushi a pudim"
|
i-like-sushi: "Eu prefiro sushi a pudim"
|
||||||
show-reversi-board-labels: "Mostrar etiquetas de colunas e linhas no Reversi"
|
show-reversi-board-labels: "Mostrar etiquetas de colunas e linhas no Reversi"
|
||||||
use-white-black-reversi-stones: "リバーシに白黒の石を使う"
|
use-white-black-reversi-stones: "リバーシに白黒の石を使う"
|
||||||
use-contrast-reversi-stones: "リバーシのアイコンにコントラストを付ける"
|
|
||||||
verified-user: "Conta verificada"
|
verified-user: "Conta verificada"
|
||||||
disable-animated-mfm: "Desativar texto animado nas publicações"
|
disable-animated-mfm: "Desativar texto animado nas publicações"
|
||||||
suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する"
|
suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する"
|
||||||
@@ -165,6 +164,7 @@ common:
|
|||||||
hashtags: "Hashtags"
|
hashtags: "Hashtags"
|
||||||
dev: "アプリの作成に失敗しました。再度お試しください。"
|
dev: "アプリの作成に失敗しました。再度お試しください。"
|
||||||
ai-chan-kawaii: "藍ちゃかわいい"
|
ai-chan-kawaii: "藍ちゃかわいい"
|
||||||
|
you: "あなた"
|
||||||
auth/views/form.vue:
|
auth/views/form.vue:
|
||||||
share-access: "<i>{name}</i>があなたのアカウントにアクセスすることを許可しますか?"
|
share-access: "<i>{name}</i>があなたのアカウントにアクセスすることを許可しますか?"
|
||||||
permission-ask: "Este aplicativo precisa das seguintes permissões:"
|
permission-ask: "Este aplicativo precisa das seguintes permissões:"
|
||||||
@@ -1054,6 +1054,20 @@ admin/views/charts.vue:
|
|||||||
network-requests: "リクエスト"
|
network-requests: "リクエスト"
|
||||||
network-time: "応答時間"
|
network-time: "応答時間"
|
||||||
network-usage: "通信量"
|
network-usage: "通信量"
|
||||||
|
admin/views/drive.vue:
|
||||||
|
sort:
|
||||||
|
title: "ソート"
|
||||||
|
createdAtAsc: "アップロード日時が古い順"
|
||||||
|
createdAtDesc: "アップロード日時が新しい順"
|
||||||
|
sizeAsc: "サイズが小さい順"
|
||||||
|
sizeDesc: "サイズが大きい順"
|
||||||
|
origin:
|
||||||
|
title: "オリジン"
|
||||||
|
combined: "ローカル+リモート"
|
||||||
|
local: "ローカル"
|
||||||
|
remote: "リモート"
|
||||||
|
delete: "削除"
|
||||||
|
deleted: "削除しました"
|
||||||
admin/views/users.vue:
|
admin/views/users.vue:
|
||||||
operation: "操作"
|
operation: "操作"
|
||||||
username-or-userid: "ユーザー名またはユーザーID"
|
username-or-userid: "ユーザー名またはユーザーID"
|
||||||
|
@@ -111,7 +111,6 @@ common:
|
|||||||
i-like-sushi: "私は(プリンよりむしろ)寿司が好き"
|
i-like-sushi: "私は(プリンよりむしろ)寿司が好き"
|
||||||
show-reversi-board-labels: "リバーシのボードの行と列のラベルを表示"
|
show-reversi-board-labels: "リバーシのボードの行と列のラベルを表示"
|
||||||
use-white-black-reversi-stones: "リバーシに白黒の石を使う"
|
use-white-black-reversi-stones: "リバーシに白黒の石を使う"
|
||||||
use-contrast-reversi-stones: "リバーシのアイコンにコントラストを付ける"
|
|
||||||
verified-user: "公式アカウント"
|
verified-user: "公式アカウント"
|
||||||
disable-animated-mfm: "Отключить анимированный текст в постах"
|
disable-animated-mfm: "Отключить анимированный текст в постах"
|
||||||
suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する"
|
suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する"
|
||||||
@@ -165,6 +164,7 @@ common:
|
|||||||
hashtags: "Хэштеги"
|
hashtags: "Хэштеги"
|
||||||
dev: "Не удалось создать приложение. Пожалуйста, попробуйте ещё раз."
|
dev: "Не удалось создать приложение. Пожалуйста, попробуйте ещё раз."
|
||||||
ai-chan-kawaii: "Ai-chan kawaii!"
|
ai-chan-kawaii: "Ai-chan kawaii!"
|
||||||
|
you: "あなた"
|
||||||
auth/views/form.vue:
|
auth/views/form.vue:
|
||||||
share-access: "Вы разрешаете <i>{name}</i> получить доступ к вашему аккаунту?"
|
share-access: "Вы разрешаете <i>{name}</i> получить доступ к вашему аккаунту?"
|
||||||
permission-ask: "このアプリは次の権限を要求しています:"
|
permission-ask: "このアプリは次の権限を要求しています:"
|
||||||
@@ -1054,6 +1054,20 @@ admin/views/charts.vue:
|
|||||||
network-requests: "リクエスト"
|
network-requests: "リクエスト"
|
||||||
network-time: "応答時間"
|
network-time: "応答時間"
|
||||||
network-usage: "通信量"
|
network-usage: "通信量"
|
||||||
|
admin/views/drive.vue:
|
||||||
|
sort:
|
||||||
|
title: "ソート"
|
||||||
|
createdAtAsc: "アップロード日時が古い順"
|
||||||
|
createdAtDesc: "アップロード日時が新しい順"
|
||||||
|
sizeAsc: "サイズが小さい順"
|
||||||
|
sizeDesc: "サイズが大きい順"
|
||||||
|
origin:
|
||||||
|
title: "オリジン"
|
||||||
|
combined: "ローカル+リモート"
|
||||||
|
local: "ローカル"
|
||||||
|
remote: "リモート"
|
||||||
|
delete: "削除"
|
||||||
|
deleted: "削除しました"
|
||||||
admin/views/users.vue:
|
admin/views/users.vue:
|
||||||
operation: "操作"
|
operation: "操作"
|
||||||
username-or-userid: "ユーザー名またはユーザーID"
|
username-or-userid: "ユーザー名またはユーザーID"
|
||||||
|
@@ -111,7 +111,6 @@ common:
|
|||||||
i-like-sushi: "相比于布丁来说, 我更喜欢寿司。"
|
i-like-sushi: "相比于布丁来说, 我更喜欢寿司。"
|
||||||
show-reversi-board-labels: "在 Reversi 中显示行和列表签"
|
show-reversi-board-labels: "在 Reversi 中显示行和列表签"
|
||||||
use-white-black-reversi-stones: "リバーシに白黒の石を使う"
|
use-white-black-reversi-stones: "リバーシに白黒の石を使う"
|
||||||
use-contrast-reversi-stones: "Make the stone color clear in Reversi"
|
|
||||||
verified-user: "认证用户"
|
verified-user: "认证用户"
|
||||||
disable-animated-mfm: "在帖子中禁用动画文本"
|
disable-animated-mfm: "在帖子中禁用动画文本"
|
||||||
suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する"
|
suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する"
|
||||||
@@ -165,6 +164,7 @@ common:
|
|||||||
hashtags: "标签"
|
hashtags: "标签"
|
||||||
dev: "构建应用程序失败,请再试一次。"
|
dev: "构建应用程序失败,请再试一次。"
|
||||||
ai-chan-kawaii: "Ai-chan kawaii!"
|
ai-chan-kawaii: "Ai-chan kawaii!"
|
||||||
|
you: "あなた"
|
||||||
auth/views/form.vue:
|
auth/views/form.vue:
|
||||||
share-access: "您要允许<i>{name}</i>来访问您的账户吗?"
|
share-access: "您要允许<i>{name}</i>来访问您的账户吗?"
|
||||||
permission-ask: "这个应用程序需要以下权限:"
|
permission-ask: "这个应用程序需要以下权限:"
|
||||||
@@ -1054,6 +1054,20 @@ admin/views/charts.vue:
|
|||||||
network-requests: "请求"
|
network-requests: "请求"
|
||||||
network-time: "响应时间"
|
network-time: "响应时间"
|
||||||
network-usage: "网络流量"
|
network-usage: "网络流量"
|
||||||
|
admin/views/drive.vue:
|
||||||
|
sort:
|
||||||
|
title: "ソート"
|
||||||
|
createdAtAsc: "アップロード日時が古い順"
|
||||||
|
createdAtDesc: "アップロード日時が新しい順"
|
||||||
|
sizeAsc: "サイズが小さい順"
|
||||||
|
sizeDesc: "サイズが大きい順"
|
||||||
|
origin:
|
||||||
|
title: "オリジン"
|
||||||
|
combined: "ローカル+リモート"
|
||||||
|
local: "ローカル"
|
||||||
|
remote: "リモート"
|
||||||
|
delete: "削除"
|
||||||
|
deleted: "削除しました"
|
||||||
admin/views/users.vue:
|
admin/views/users.vue:
|
||||||
operation: "操作"
|
operation: "操作"
|
||||||
username-or-userid: "用户名或用户ID"
|
username-or-userid: "用户名或用户ID"
|
||||||
|
12
package.json
12
package.json
@@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"name": "misskey",
|
"name": "misskey",
|
||||||
"author": "syuilo <i@syuilo.com>",
|
"author": "syuilo <i@syuilo.com>",
|
||||||
"version": "10.63.1",
|
"version": "10.64.2",
|
||||||
"clientVersion": "2.0.12696",
|
"clientVersion": "2.0.12796",
|
||||||
"codename": "nighthike",
|
"codename": "nighthike",
|
||||||
"main": "./built/index.js",
|
"main": "./built/index.js",
|
||||||
"private": true,
|
"private": true,
|
||||||
@@ -37,7 +37,6 @@
|
|||||||
"@types/elasticsearch": "5.0.29",
|
"@types/elasticsearch": "5.0.29",
|
||||||
"@types/file-type": "5.2.2",
|
"@types/file-type": "5.2.2",
|
||||||
"@types/gulp": "3.8.36",
|
"@types/gulp": "3.8.36",
|
||||||
"@types/gulp-htmlmin": "1.3.32",
|
|
||||||
"@types/gulp-mocha": "0.0.32",
|
"@types/gulp-mocha": "0.0.32",
|
||||||
"@types/gulp-rename": "0.0.33",
|
"@types/gulp-rename": "0.0.33",
|
||||||
"@types/gulp-replace": "0.0.31",
|
"@types/gulp-replace": "0.0.31",
|
||||||
@@ -88,7 +87,7 @@
|
|||||||
"@types/websocket": "0.0.40",
|
"@types/websocket": "0.0.40",
|
||||||
"@types/ws": "6.0.1",
|
"@types/ws": "6.0.1",
|
||||||
"animejs": "2.2.0",
|
"animejs": "2.2.0",
|
||||||
"apexcharts": "2.2.4",
|
"apexcharts": "2.4.2",
|
||||||
"autobind-decorator": "2.4.0",
|
"autobind-decorator": "2.4.0",
|
||||||
"autosize": "4.0.2",
|
"autosize": "4.0.2",
|
||||||
"autwh": "0.1.0",
|
"autwh": "0.1.0",
|
||||||
@@ -120,10 +119,8 @@
|
|||||||
"fuckadblock": "3.2.1",
|
"fuckadblock": "3.2.1",
|
||||||
"gulp": "3.9.1",
|
"gulp": "3.9.1",
|
||||||
"gulp-cssnano": "2.1.3",
|
"gulp-cssnano": "2.1.3",
|
||||||
"gulp-htmlmin": "5.0.1",
|
|
||||||
"gulp-imagemin": "4.1.0",
|
"gulp-imagemin": "4.1.0",
|
||||||
"gulp-mocha": "6.0.0",
|
"gulp-mocha": "6.0.0",
|
||||||
"gulp-pug": "4.0.1",
|
|
||||||
"gulp-rename": "1.4.0",
|
"gulp-rename": "1.4.0",
|
||||||
"gulp-replace": "1.0.0",
|
"gulp-replace": "1.0.0",
|
||||||
"gulp-sourcemaps": "2.6.4",
|
"gulp-sourcemaps": "2.6.4",
|
||||||
@@ -158,7 +155,7 @@
|
|||||||
"koa-views": "6.1.4",
|
"koa-views": "6.1.4",
|
||||||
"langmap": "0.0.16",
|
"langmap": "0.0.16",
|
||||||
"loader-utils": "1.1.0",
|
"loader-utils": "1.1.0",
|
||||||
"minio": "7.0.1",
|
"minio": "7.0.2",
|
||||||
"mkdirp": "0.5.1",
|
"mkdirp": "0.5.1",
|
||||||
"mocha": "5.2.0",
|
"mocha": "5.2.0",
|
||||||
"moji": "0.5.1",
|
"moji": "0.5.1",
|
||||||
@@ -228,6 +225,7 @@
|
|||||||
"vue-loader": "15.4.2",
|
"vue-loader": "15.4.2",
|
||||||
"vue-marquee-text-component": "1.1.0",
|
"vue-marquee-text-component": "1.1.0",
|
||||||
"vue-router": "3.0.2",
|
"vue-router": "3.0.2",
|
||||||
|
"vue-sequential-entrance": "1.1.3",
|
||||||
"vue-style-loader": "4.1.2",
|
"vue-style-loader": "4.1.2",
|
||||||
"vue-svg-inline-loader": "1.2.4",
|
"vue-svg-inline-loader": "1.2.4",
|
||||||
"vue-template-compiler": "2.5.17",
|
"vue-template-compiler": "2.5.17",
|
||||||
|
@@ -64,7 +64,7 @@ export default abstract class Chart<T> {
|
|||||||
const keys = {
|
const keys = {
|
||||||
span: -1,
|
span: -1,
|
||||||
date: -1
|
date: -1
|
||||||
} as any;
|
} as { [key: string]: 1 | -1; };
|
||||||
if (grouped) keys.group = -1;
|
if (grouped) keys.group = -1;
|
||||||
this.collection.createIndex(keys, { unique: true });
|
this.collection.createIndex(keys, { unique: true });
|
||||||
}
|
}
|
||||||
|
175
src/client/app/admin/views/drive.vue
Normal file
175
src/client/app/admin/views/drive.vue
Normal file
@@ -0,0 +1,175 @@
|
|||||||
|
<template>
|
||||||
|
<div class="pwnqwyet">
|
||||||
|
<ui-card>
|
||||||
|
<div slot="title"><fa :icon="faCloud"/> {{ $t('@.drive') }}</div>
|
||||||
|
<section class="fit-top">
|
||||||
|
<ui-horizon-group inputs>
|
||||||
|
<ui-select v-model="sort">
|
||||||
|
<span slot="label">{{ $t('sort.title') }}</span>
|
||||||
|
<option value="-createdAt">{{ $t('sort.createdAtAsc') }}</option>
|
||||||
|
<option value="+createdAt">{{ $t('sort.createdAtDesc') }}</option>
|
||||||
|
<option value="-size">{{ $t('sort.sizeAsc') }}</option>
|
||||||
|
<option value="+size">{{ $t('sort.sizeDesc') }}</option>
|
||||||
|
</ui-select>
|
||||||
|
<ui-select v-model="origin">
|
||||||
|
<span slot="label">{{ $t('origin.title') }}</span>
|
||||||
|
<option value="combined">{{ $t('origin.combined') }}</option>
|
||||||
|
<option value="local">{{ $t('origin.local') }}</option>
|
||||||
|
<option value="remote">{{ $t('origin.remote') }}</option>
|
||||||
|
</ui-select>
|
||||||
|
</ui-horizon-group>
|
||||||
|
<sequential-entrance animation="entranceFromTop" delay="25">
|
||||||
|
<div class="kidvdlkg" v-for="file in files">
|
||||||
|
<div @click="file._open = !file._open">
|
||||||
|
<div>
|
||||||
|
<div class="thumbnail" :style="thumbnail(file)"></div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<header>
|
||||||
|
<b>{{ file.name }}</b>
|
||||||
|
<span class="username">@{{ file.user | acct }}</span>
|
||||||
|
</header>
|
||||||
|
<div>
|
||||||
|
<div>
|
||||||
|
<span style="margin-right:16px;">{{ file.type }}</span>
|
||||||
|
<span>{{ file.datasize | bytes }}</span>
|
||||||
|
</div>
|
||||||
|
<div><mk-time :time="file.createdAt" mode="detail"/></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-show="file._open">
|
||||||
|
<ui-button @click="del(file)"><fa :icon="faTrashAlt"/> {{ $t('delete') }}</ui-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</sequential-entrance>
|
||||||
|
<ui-button v-if="existMore" @click="fetch">{{ $t('@.load-more') }}</ui-button>
|
||||||
|
</section>
|
||||||
|
</ui-card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import Vue from 'vue';
|
||||||
|
import i18n from '../../i18n';
|
||||||
|
import { faCloud } from '@fortawesome/free-solid-svg-icons';
|
||||||
|
import { faTrashAlt } from '@fortawesome/free-regular-svg-icons';
|
||||||
|
|
||||||
|
export default Vue.extend({
|
||||||
|
i18n: i18n('admin/views/drive.vue'),
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
sort: '+createdAt',
|
||||||
|
origin: 'combined',
|
||||||
|
limit: 10,
|
||||||
|
offset: 0,
|
||||||
|
files: [],
|
||||||
|
existMore: false,
|
||||||
|
faCloud, faTrashAlt
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
sort() {
|
||||||
|
this.files = [];
|
||||||
|
this.offset = 0;
|
||||||
|
this.fetch();
|
||||||
|
},
|
||||||
|
|
||||||
|
origin() {
|
||||||
|
this.files = [];
|
||||||
|
this.offset = 0;
|
||||||
|
this.fetch();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
this.fetch();
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
fetch() {
|
||||||
|
this.$root.api('admin/drive/files', {
|
||||||
|
origin: this.origin,
|
||||||
|
sort: this.sort,
|
||||||
|
offset: this.offset,
|
||||||
|
limit: this.limit + 1
|
||||||
|
}).then(files => {
|
||||||
|
if (files.length == this.limit + 1) {
|
||||||
|
files.pop();
|
||||||
|
this.existMore = true;
|
||||||
|
} else {
|
||||||
|
this.existMore = false;
|
||||||
|
}
|
||||||
|
for (const x of files) {
|
||||||
|
x._open = false;
|
||||||
|
}
|
||||||
|
this.files = this.files.concat(files);
|
||||||
|
this.offset += this.limit;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
thumbnail(file: any): any {
|
||||||
|
return {
|
||||||
|
'background-color': file.properties.avgColor && file.properties.avgColor.length == 3 ? `rgb(${file.properties.avgColor.join(',')})` : 'transparent',
|
||||||
|
'background-image': `url(${file.thumbnailUrl})`
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
async del(file: any) {
|
||||||
|
const process = async () => {
|
||||||
|
await this.$root.api('drive/files/delete', { fileId: file.id });
|
||||||
|
this.$root.dialog({
|
||||||
|
type: 'success',
|
||||||
|
text: this.$t('deleted')
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
await process().catch(e => {
|
||||||
|
this.$root.dialog({
|
||||||
|
type: 'error',
|
||||||
|
text: e.toString()
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="stylus" scoped>
|
||||||
|
.pwnqwyet
|
||||||
|
@media (min-width 500px)
|
||||||
|
padding 16px
|
||||||
|
|
||||||
|
.kidvdlkg
|
||||||
|
padding 16px 0
|
||||||
|
border-top solid 1px var(--faceDivider)
|
||||||
|
|
||||||
|
> div:first-child
|
||||||
|
display flex
|
||||||
|
cursor pointer
|
||||||
|
|
||||||
|
> div:nth-child(1)
|
||||||
|
> .thumbnail
|
||||||
|
display block
|
||||||
|
width 64px
|
||||||
|
height 64px
|
||||||
|
background-size cover
|
||||||
|
background-position center center
|
||||||
|
|
||||||
|
> div:nth-child(2)
|
||||||
|
flex 1
|
||||||
|
padding-left 16px
|
||||||
|
|
||||||
|
@media (max-width 500px)
|
||||||
|
font-size 14px
|
||||||
|
|
||||||
|
> header
|
||||||
|
word-break break-word
|
||||||
|
|
||||||
|
> .username
|
||||||
|
margin-left 8px
|
||||||
|
opacity 0.7
|
||||||
|
|
||||||
|
</style>
|
@@ -24,24 +24,28 @@
|
|||||||
|
|
||||||
<ui-card>
|
<ui-card>
|
||||||
<div slot="title"><fa :icon="faGrin"/> {{ $t('emojis.title') }}</div>
|
<div slot="title"><fa :icon="faGrin"/> {{ $t('emojis.title') }}</div>
|
||||||
<section v-for="emoji in emojis">
|
<section v-for="emoji in emojis" class="oryfrbft">
|
||||||
<img :src="emoji.url" :alt="emoji.name" style="width: 64px;"/>
|
<div>
|
||||||
<ui-horizon-group inputs>
|
<img :src="emoji.url" :alt="emoji.name" style="width: 64px;"/>
|
||||||
<ui-input v-model="emoji.name">
|
</div>
|
||||||
<span>{{ $t('add-emoji.name') }}</span>
|
<div>
|
||||||
|
<ui-horizon-group>
|
||||||
|
<ui-input v-model="emoji.name">
|
||||||
|
<span>{{ $t('add-emoji.name') }}</span>
|
||||||
|
</ui-input>
|
||||||
|
<ui-input v-model="emoji.aliases">
|
||||||
|
<span>{{ $t('add-emoji.aliases') }}</span>
|
||||||
|
</ui-input>
|
||||||
|
</ui-horizon-group>
|
||||||
|
<ui-input v-model="emoji.url">
|
||||||
|
<i slot="icon"><fa icon="link"/></i>
|
||||||
|
<span>{{ $t('add-emoji.url') }}</span>
|
||||||
</ui-input>
|
</ui-input>
|
||||||
<ui-input v-model="emoji.aliases">
|
<ui-horizon-group class="fit-bottom">
|
||||||
<span>{{ $t('add-emoji.aliases') }}</span>
|
<ui-button @click="updateEmoji(emoji)"><fa :icon="['far', 'save']"/> {{ $t('emojis.update') }}</ui-button>
|
||||||
</ui-input>
|
<ui-button @click="removeEmoji(emoji)"><fa :icon="['far', 'trash-alt']"/> {{ $t('emojis.remove') }}</ui-button>
|
||||||
</ui-horizon-group>
|
</ui-horizon-group>
|
||||||
<ui-input v-model="emoji.url">
|
</div>
|
||||||
<i slot="icon"><fa icon="link"/></i>
|
|
||||||
<span>{{ $t('add-emoji.url') }}</span>
|
|
||||||
</ui-input>
|
|
||||||
<ui-horizon-group class="fit-bottom">
|
|
||||||
<ui-button @click="updateEmoji(emoji)"><fa :icon="['far', 'save']"/> {{ $t('emojis.update') }}</ui-button>
|
|
||||||
<ui-button @click="removeEmoji(emoji)"><fa :icon="['far', 'trash-alt']"/> {{ $t('emojis.remove') }}</ui-button>
|
|
||||||
</ui-horizon-group>
|
|
||||||
</section>
|
</section>
|
||||||
</ui-card>
|
</ui-card>
|
||||||
</div>
|
</div>
|
||||||
@@ -150,4 +154,21 @@ export default Vue.extend({
|
|||||||
@media (min-width 500px)
|
@media (min-width 500px)
|
||||||
padding 16px
|
padding 16px
|
||||||
|
|
||||||
|
.oryfrbft
|
||||||
|
@media (min-width 500px)
|
||||||
|
display flex
|
||||||
|
|
||||||
|
> div:first-child
|
||||||
|
@media (max-width 500px)
|
||||||
|
padding-bottom 16px
|
||||||
|
|
||||||
|
> img
|
||||||
|
vertical-align bottom
|
||||||
|
|
||||||
|
> div:last-child
|
||||||
|
flex 1
|
||||||
|
|
||||||
|
@media (min-width 500px)
|
||||||
|
padding-left 16px
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
@@ -22,12 +22,11 @@
|
|||||||
<li @click="nav('instance')" :class="{ active: page == 'instance' }"><fa icon="cog" fixed-width/>{{ $t('instance') }}</li>
|
<li @click="nav('instance')" :class="{ active: page == 'instance' }"><fa icon="cog" fixed-width/>{{ $t('instance') }}</li>
|
||||||
<li @click="nav('moderators')" :class="{ active: page == 'moderators' }"><fa :icon="faHeadset" fixed-width/>{{ $t('moderators') }}</li>
|
<li @click="nav('moderators')" :class="{ active: page == 'moderators' }"><fa :icon="faHeadset" fixed-width/>{{ $t('moderators') }}</li>
|
||||||
<li @click="nav('users')" :class="{ active: page == 'users' }"><fa icon="users" fixed-width/>{{ $t('users') }}</li>
|
<li @click="nav('users')" :class="{ active: page == 'users' }"><fa icon="users" fixed-width/>{{ $t('users') }}</li>
|
||||||
|
<li @click="nav('drive')" :class="{ active: page == 'drive' }"><fa icon="cloud" fixed-width/>{{ $t('@.drive') }}</li>
|
||||||
<!-- <li @click="nav('federation')" :class="{ active: page == 'federation' }"><fa :icon="faShareAlt" fixed-width/>{{ $t('federation') }}</li> -->
|
<!-- <li @click="nav('federation')" :class="{ active: page == 'federation' }"><fa :icon="faShareAlt" fixed-width/>{{ $t('federation') }}</li> -->
|
||||||
<li @click="nav('emoji')" :class="{ active: page == 'emoji' }"><fa :icon="faGrin" fixed-width/>{{ $t('emoji') }}</li>
|
<li @click="nav('emoji')" :class="{ active: page == 'emoji' }"><fa :icon="faGrin" fixed-width/>{{ $t('emoji') }}</li>
|
||||||
<li @click="nav('announcements')" :class="{ active: page == 'announcements' }"><fa icon="broadcast-tower" fixed-width/>{{ $t('announcements') }}</li>
|
<li @click="nav('announcements')" :class="{ active: page == 'announcements' }"><fa icon="broadcast-tower" fixed-width/>{{ $t('announcements') }}</li>
|
||||||
<li @click="nav('hashtags')" :class="{ active: page == 'hashtags' }"><fa icon="hashtag" fixed-width/>{{ $t('hashtags') }}</li>
|
<li @click="nav('hashtags')" :class="{ active: page == 'hashtags' }"><fa icon="hashtag" fixed-width/>{{ $t('hashtags') }}</li>
|
||||||
|
|
||||||
<!-- <li @click="nav('drive')" :class="{ active: page == 'drive' }"><fa icon="cloud" fixed-width/>{{ $t('@.drive') }}</li> -->
|
|
||||||
</ul>
|
</ul>
|
||||||
<div class="back-to-misskey">
|
<div class="back-to-misskey">
|
||||||
<a href="/"><fa :icon="faArrowLeft"/> {{ $t('back-to-misskey') }}</a>
|
<a href="/"><fa :icon="faArrowLeft"/> {{ $t('back-to-misskey') }}</a>
|
||||||
@@ -45,7 +44,7 @@
|
|||||||
<div v-if="page == 'emoji'"><x-emoji/></div>
|
<div v-if="page == 'emoji'"><x-emoji/></div>
|
||||||
<div v-if="page == 'announcements'"><x-announcements/></div>
|
<div v-if="page == 'announcements'"><x-announcements/></div>
|
||||||
<div v-if="page == 'hashtags'"><x-hashtags/></div>
|
<div v-if="page == 'hashtags'"><x-hashtags/></div>
|
||||||
<div v-if="page == 'drive'"></div>
|
<div v-if="page == 'drive'"><x-drive/></div>
|
||||||
<div v-if="page == 'update'"></div>
|
<div v-if="page == 'update'"></div>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
@@ -63,6 +62,7 @@ import XEmoji from "./emoji.vue";
|
|||||||
import XAnnouncements from "./announcements.vue";
|
import XAnnouncements from "./announcements.vue";
|
||||||
import XHashtags from "./hashtags.vue";
|
import XHashtags from "./hashtags.vue";
|
||||||
import XUsers from "./users.vue";
|
import XUsers from "./users.vue";
|
||||||
|
import XDrive from "./drive.vue";
|
||||||
import { faHeadset, faArrowLeft, faShareAlt } from '@fortawesome/free-solid-svg-icons';
|
import { faHeadset, faArrowLeft, faShareAlt } from '@fortawesome/free-solid-svg-icons';
|
||||||
import { faGrin } from '@fortawesome/free-regular-svg-icons';
|
import { faGrin } from '@fortawesome/free-regular-svg-icons';
|
||||||
|
|
||||||
@@ -79,7 +79,8 @@ export default Vue.extend({
|
|||||||
XEmoji,
|
XEmoji,
|
||||||
XAnnouncements,
|
XAnnouncements,
|
||||||
XHashtags,
|
XHashtags,
|
||||||
XUsers
|
XUsers,
|
||||||
|
XDrive,
|
||||||
},
|
},
|
||||||
provide: {
|
provide: {
|
||||||
isMobile
|
isMobile
|
||||||
|
@@ -32,8 +32,10 @@
|
|||||||
<header><fa :icon="faShieldAlt"/> {{ $t('recaptcha-config') }}</header>
|
<header><fa :icon="faShieldAlt"/> {{ $t('recaptcha-config') }}</header>
|
||||||
<ui-switch v-model="enableRecaptcha">{{ $t('enable-recaptcha') }}</ui-switch>
|
<ui-switch v-model="enableRecaptcha">{{ $t('enable-recaptcha') }}</ui-switch>
|
||||||
<ui-info>{{ $t('recaptcha-info') }}</ui-info>
|
<ui-info>{{ $t('recaptcha-info') }}</ui-info>
|
||||||
<ui-input v-model="recaptchaSiteKey" :disabled="!enableRecaptcha"><i slot="icon"><fa icon="key"/></i>{{ $t('recaptcha-site-key') }}</ui-input>
|
<ui-horizon-group inputs>
|
||||||
<ui-input v-model="recaptchaSecretKey" :disabled="!enableRecaptcha"><i slot="icon"><fa icon="key"/></i>{{ $t('recaptcha-secret-key') }}</ui-input>
|
<ui-input v-model="recaptchaSiteKey" :disabled="!enableRecaptcha"><i slot="icon"><fa icon="key"/></i>{{ $t('recaptcha-site-key') }}</ui-input>
|
||||||
|
<ui-input v-model="recaptchaSecretKey" :disabled="!enableRecaptcha"><i slot="icon"><fa icon="key"/></i>{{ $t('recaptcha-secret-key') }}</ui-input>
|
||||||
|
</ui-horizon-group>
|
||||||
</section>
|
</section>
|
||||||
<section>
|
<section>
|
||||||
<header><fa :icon="faGhost"/> {{ $t('proxy-account-config') }}</header>
|
<header><fa :icon="faGhost"/> {{ $t('proxy-account-config') }}</header>
|
||||||
@@ -82,9 +84,11 @@
|
|||||||
<div slot="title"><fa :icon="['fab', 'twitter']"/> {{ $t('twitter-integration-config') }}</div>
|
<div slot="title"><fa :icon="['fab', 'twitter']"/> {{ $t('twitter-integration-config') }}</div>
|
||||||
<section>
|
<section>
|
||||||
<ui-switch v-model="enableTwitterIntegration">{{ $t('enable-twitter-integration') }}</ui-switch>
|
<ui-switch v-model="enableTwitterIntegration">{{ $t('enable-twitter-integration') }}</ui-switch>
|
||||||
|
<ui-horizon-group>
|
||||||
|
<ui-input v-model="twitterConsumerKey" :disabled="!enableTwitterIntegration"><i slot="icon"><fa icon="key"/></i>{{ $t('twitter-integration-consumer-key') }}</ui-input>
|
||||||
|
<ui-input v-model="twitterConsumerSecret" :disabled="!enableTwitterIntegration"><i slot="icon"><fa icon="key"/></i>{{ $t('twitter-integration-consumer-secret') }}</ui-input>
|
||||||
|
</ui-horizon-group>
|
||||||
<ui-info>{{ $t('twitter-integration-info', { url: `${url}/api/tw/cb` }) }}</ui-info>
|
<ui-info>{{ $t('twitter-integration-info', { url: `${url}/api/tw/cb` }) }}</ui-info>
|
||||||
<ui-input v-model="twitterConsumerKey" :disabled="!enableTwitterIntegration"><i slot="icon"><fa icon="key"/></i>{{ $t('twitter-integration-consumer-key') }}</ui-input>
|
|
||||||
<ui-input v-model="twitterConsumerSecret" :disabled="!enableTwitterIntegration"><i slot="icon"><fa icon="key"/></i>{{ $t('twitter-integration-consumer-secret') }}</ui-input>
|
|
||||||
<ui-button @click="updateMeta">{{ $t('save') }}</ui-button>
|
<ui-button @click="updateMeta">{{ $t('save') }}</ui-button>
|
||||||
</section>
|
</section>
|
||||||
</ui-card>
|
</ui-card>
|
||||||
@@ -93,9 +97,11 @@
|
|||||||
<div slot="title"><fa :icon="['fab', 'github']"/> {{ $t('github-integration-config') }}</div>
|
<div slot="title"><fa :icon="['fab', 'github']"/> {{ $t('github-integration-config') }}</div>
|
||||||
<section>
|
<section>
|
||||||
<ui-switch v-model="enableGithubIntegration">{{ $t('enable-github-integration') }}</ui-switch>
|
<ui-switch v-model="enableGithubIntegration">{{ $t('enable-github-integration') }}</ui-switch>
|
||||||
|
<ui-horizon-group>
|
||||||
|
<ui-input v-model="githubClientId" :disabled="!enableGithubIntegration"><i slot="icon"><fa icon="key"/></i>{{ $t('github-integration-client-id') }}</ui-input>
|
||||||
|
<ui-input v-model="githubClientSecret" :disabled="!enableGithubIntegration"><i slot="icon"><fa icon="key"/></i>{{ $t('github-integration-client-secret') }}</ui-input>
|
||||||
|
</ui-horizon-group>
|
||||||
<ui-info>{{ $t('github-integration-info', { url: `${url}/api/gh/cb` }) }}</ui-info>
|
<ui-info>{{ $t('github-integration-info', { url: `${url}/api/gh/cb` }) }}</ui-info>
|
||||||
<ui-input v-model="githubClientId" :disabled="!enableGithubIntegration"><i slot="icon"><fa icon="key"/></i>{{ $t('github-integration-client-id') }}</ui-input>
|
|
||||||
<ui-input v-model="githubClientSecret" :disabled="!enableGithubIntegration"><i slot="icon"><fa icon="key"/></i>{{ $t('github-integration-client-secret') }}</ui-input>
|
|
||||||
<ui-button @click="updateMeta">{{ $t('save') }}</ui-button>
|
<ui-button @click="updateMeta">{{ $t('save') }}</ui-button>
|
||||||
</section>
|
</section>
|
||||||
</ui-card>
|
</ui-card>
|
||||||
@@ -104,9 +110,11 @@
|
|||||||
<div slot="title"><fa :icon="['fab', 'discord']"/> {{ $t('discord-integration-config') }}</div>
|
<div slot="title"><fa :icon="['fab', 'discord']"/> {{ $t('discord-integration-config') }}</div>
|
||||||
<section>
|
<section>
|
||||||
<ui-switch v-model="enableDiscordIntegration">{{ $t('enable-discord-integration') }}</ui-switch>
|
<ui-switch v-model="enableDiscordIntegration">{{ $t('enable-discord-integration') }}</ui-switch>
|
||||||
|
<ui-horizon-group>
|
||||||
|
<ui-input v-model="discordClientId" :disabled="!enableDiscordIntegration"><i slot="icon"><fa icon="key"/></i>{{ $t('discord-integration-client-id') }}</ui-input>
|
||||||
|
<ui-input v-model="discordClientSecret" :disabled="!enableDiscordIntegration"><i slot="icon"><fa icon="key"/></i>{{ $t('discord-integration-client-secret') }}</ui-input>
|
||||||
|
</ui-horizon-group>
|
||||||
<ui-info>{{ $t('discord-integration-info', { url: `${url}/api/dc/cb` }) }}</ui-info>
|
<ui-info>{{ $t('discord-integration-info', { url: `${url}/api/dc/cb` }) }}</ui-info>
|
||||||
<ui-input v-model="discordClientId" :disabled="!enableDiscordIntegration"><i slot="icon"><fa icon="key"/></i>{{ $t('discord-integration-client-id') }}</ui-input>
|
|
||||||
<ui-input v-model="discordClientSecret" :disabled="!enableDiscordIntegration"><i slot="icon"><fa icon="key"/></i>{{ $t('discord-integration-client-secret') }}</ui-input>
|
|
||||||
<ui-button @click="updateMeta">{{ $t('save') }}</ui-button>
|
<ui-button @click="updateMeta">{{ $t('save') }}</ui-button>
|
||||||
</section>
|
</section>
|
||||||
</ui-card>
|
</ui-card>
|
||||||
|
@@ -38,25 +38,27 @@
|
|||||||
<option value="remote">{{ $t('users.origin.remote') }}</option>
|
<option value="remote">{{ $t('users.origin.remote') }}</option>
|
||||||
</ui-select>
|
</ui-select>
|
||||||
</ui-horizon-group>
|
</ui-horizon-group>
|
||||||
<div class="kofvwchc" v-for="user in users">
|
<sequential-entrance animation="entranceFromTop" delay="25">
|
||||||
<div>
|
<div class="kofvwchc" v-for="user in users">
|
||||||
<a :href="user | userPage(null, true)">
|
|
||||||
<mk-avatar class="avatar" :user="user" :disable-link="true"/>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<header>
|
|
||||||
<b><mk-user-name :user="user"/></b>
|
|
||||||
<span class="username">@{{ user | acct }}</span>
|
|
||||||
</header>
|
|
||||||
<div>
|
<div>
|
||||||
<span>{{ $t('users.updatedAt') }}: <mk-time :time="user.updatedAt" mode="detail"/></span>
|
<a :href="user | userPage(null, true)">
|
||||||
|
<mk-avatar class="avatar" :user="user" :disable-link="true"/>
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<span>{{ $t('users.createdAt') }}: <mk-time :time="user.createdAt" mode="detail"/></span>
|
<header>
|
||||||
|
<b><mk-user-name :user="user"/></b>
|
||||||
|
<span class="username">@{{ user | acct }}</span>
|
||||||
|
</header>
|
||||||
|
<div>
|
||||||
|
<span>{{ $t('users.updatedAt') }}: <mk-time :time="user.updatedAt" mode="detail"/></span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span>{{ $t('users.createdAt') }}: <mk-time :time="user.createdAt" mode="detail"/></span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</sequential-entrance>
|
||||||
<ui-button v-if="existMore" @click="fetchUsers">{{ $t('@.load-more') }}</ui-button>
|
<ui-button v-if="existMore" @click="fetchUsers">{{ $t('@.load-more') }}</ui-button>
|
||||||
</section>
|
</section>
|
||||||
</ui-card>
|
</ui-card>
|
||||||
@@ -274,6 +276,9 @@ export default Vue.extend({
|
|||||||
flex 1
|
flex 1
|
||||||
padding-left 16px
|
padding-left 16px
|
||||||
|
|
||||||
|
@media (max-width 500px)
|
||||||
|
font-size 14px
|
||||||
|
|
||||||
> header
|
> header
|
||||||
> .username
|
> .username
|
||||||
margin-left 8px
|
margin-left 8px
|
||||||
|
@@ -10,3 +10,19 @@
|
|||||||
opacity: 0;
|
opacity: 0;
|
||||||
transform: scaleY(0);
|
transform: scaleY(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.entranceFromTop {
|
||||||
|
animation-duration: 0.5s;
|
||||||
|
animation-name: entranceFromTop;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes entranceFromTop {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(-64px);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
25
src/client/app/common/scripts/format-uptime.ts
Normal file
25
src/client/app/common/scripts/format-uptime.ts
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
/**
|
||||||
|
* Format like the uptime command
|
||||||
|
*/
|
||||||
|
export default function(sec) {
|
||||||
|
if (!sec) return sec;
|
||||||
|
|
||||||
|
const day = Math.floor(sec / 86400);
|
||||||
|
const tod = sec % 86400;
|
||||||
|
|
||||||
|
// Days part in string: 2 days, 1 day, null
|
||||||
|
const d = day >= 2 ? `${day} days` : day >= 1 ? `${day} day` : null;
|
||||||
|
|
||||||
|
// Time part in string: 1 sec, 1 min, 1:01
|
||||||
|
const t
|
||||||
|
= tod < 60 ? `${Math.floor(tod)} sec`
|
||||||
|
: tod < 3600 ? `${Math.floor(tod / 60)} min`
|
||||||
|
: `${Math.floor(tod / 60 / 60)}:${Math.floor((tod / 60) % 60).toString().padStart(2, "0")}`;
|
||||||
|
|
||||||
|
let str = '';
|
||||||
|
if (d) str += `${d}, `;
|
||||||
|
str += t;
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}
|
@@ -32,7 +32,7 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import { themeColor } from '../../../config';
|
import * as tinycolor from 'tinycolor2';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
props: {
|
props: {
|
||||||
@@ -75,7 +75,7 @@ export default Vue.extend({
|
|||||||
return this.dark ? '#fff' : '#777';
|
return this.dark ? '#fff' : '#777';
|
||||||
},
|
},
|
||||||
hHandColor(): string {
|
hHandColor(): string {
|
||||||
return themeColor;
|
return tinycolor(getComputedStyle(document.documentElement).getPropertyValue('--themeColor')).toHexString();
|
||||||
},
|
},
|
||||||
|
|
||||||
ms(): number {
|
ms(): number {
|
||||||
|
@@ -31,8 +31,8 @@
|
|||||||
@click="set(i)"
|
@click="set(i)"
|
||||||
:title="`${String.fromCharCode(65 + o.transformPosToXy(i)[0])}${o.transformPosToXy(i)[1] + 1}`">
|
:title="`${String.fromCharCode(65 + o.transformPosToXy(i)[0])}${o.transformPosToXy(i)[1] + 1}`">
|
||||||
<template v-if="!$store.state.settings.games.reversi.useWhiteBlackStones">
|
<template v-if="!$store.state.settings.games.reversi.useWhiteBlackStones">
|
||||||
<img v-if="stone === true" :src="blackUser.avatarUrl" alt="black" :class="{ contrast: $store.state.settings.games.reversi.useContrastStones }">
|
<img v-if="stone === true" :src="blackUser.avatarUrl" alt="black">
|
||||||
<img v-if="stone === false" :src="whiteUser.avatarUrl" alt="white" :class="{ contrast: $store.state.settings.games.reversi.useContrastStones }">
|
<img v-if="stone === false" :src="whiteUser.avatarUrl" alt="white">
|
||||||
</template>
|
</template>
|
||||||
<template v-if="$store.state.settings.games.reversi.useWhiteBlackStones">
|
<template v-if="$store.state.settings.games.reversi.useWhiteBlackStones">
|
||||||
<fa v-if="stone === true" :icon="fasCircle"/>
|
<fa v-if="stone === true" :icon="fasCircle"/>
|
||||||
@@ -430,13 +430,6 @@ export default Vue.extend({
|
|||||||
width 100%
|
width 100%
|
||||||
height 100%
|
height 100%
|
||||||
|
|
||||||
&.contrast
|
|
||||||
&[alt="black"]
|
|
||||||
filter brightness(.5)
|
|
||||||
|
|
||||||
&[alt="white"]
|
|
||||||
filter brightness(2)
|
|
||||||
|
|
||||||
> .graph
|
> .graph
|
||||||
display grid
|
display grid
|
||||||
grid-template-columns repeat(61, 1fr)
|
grid-template-columns repeat(61, 1fr)
|
||||||
|
@@ -60,7 +60,7 @@
|
|||||||
|
|
||||||
<div>
|
<div>
|
||||||
<template v-for="item in form">
|
<template v-for="item in form">
|
||||||
<ui-switch v-if="item.type == 'switch'" v-model="item.value" :key="item.id" :text="item.label" @change="onChangeForm(item)">{{ item.desc || '' }}</ui-switch>
|
<ui-switch v-if="item.type == 'switch'" v-model="item.value" :key="item.id" @change="onChangeForm(item)">{{ item.label || item.desc || '' }}</ui-switch>
|
||||||
|
|
||||||
<div class="card" v-if="item.type == 'radio'" :key="item.id">
|
<div class="card" v-if="item.type == 'radio'" :key="item.id">
|
||||||
<header>
|
<header>
|
||||||
|
@@ -1,22 +1,22 @@
|
|||||||
<template>
|
<template>
|
||||||
<ui-card>
|
<ui-card v-if="enableTwitterIntegration || enableDiscordIntegration || enableGithubIntegration">
|
||||||
<div slot="title"><fa icon="share-alt"/> {{ $t('title') }}</div>
|
<div slot="title"><fa icon="share-alt"/> {{ $t('title') }}</div>
|
||||||
|
|
||||||
<section>
|
<section v-if="enableTwitterIntegration">
|
||||||
<header><fa :icon="['fab', 'twitter']"/> Twitter</header>
|
<header><fa :icon="['fab', 'twitter']"/> Twitter</header>
|
||||||
<p v-if="$store.state.i.twitter">{{ $t('connected-to') }}: <a :href="`https://twitter.com/${$store.state.i.twitter.screenName}`" target="_blank">@{{ $store.state.i.twitter.screenName }}</a></p>
|
<p v-if="$store.state.i.twitter">{{ $t('connected-to') }}: <a :href="`https://twitter.com/${$store.state.i.twitter.screenName}`" target="_blank">@{{ $store.state.i.twitter.screenName }}</a></p>
|
||||||
<ui-button v-if="$store.state.i.twitter" @click="disconnectTwitter">{{ $t('disconnect') }}</ui-button>
|
<ui-button v-if="$store.state.i.twitter" @click="disconnectTwitter">{{ $t('disconnect') }}</ui-button>
|
||||||
<ui-button v-else @click="connectTwitter">{{ $t('connect') }}</ui-button>
|
<ui-button v-else @click="connectTwitter">{{ $t('connect') }}</ui-button>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section>
|
<section v-if="enableDiscordIntegration">
|
||||||
<header><fa :icon="['fab', 'discord']"/> Discord</header>
|
<header><fa :icon="['fab', 'discord']"/> Discord</header>
|
||||||
<p v-if="$store.state.i.discord">{{ $t('connected-to') }}: <a :href="`https://discordapp.com/users/${$store.state.i.discord.id}`" target="_blank">@{{ $store.state.i.discord.username }}#{{ $store.state.i.discord.discriminator }}</a></p>
|
<p v-if="$store.state.i.discord">{{ $t('connected-to') }}: <a :href="`https://discordapp.com/users/${$store.state.i.discord.id}`" target="_blank">@{{ $store.state.i.discord.username }}#{{ $store.state.i.discord.discriminator }}</a></p>
|
||||||
<ui-button v-if="$store.state.i.discord" @click="disconnectDiscord">{{ $t('disconnect') }}</ui-button>
|
<ui-button v-if="$store.state.i.discord" @click="disconnectDiscord">{{ $t('disconnect') }}</ui-button>
|
||||||
<ui-button v-else @click="connectDiscord">{{ $t('connect') }}</ui-button>
|
<ui-button v-else @click="connectDiscord">{{ $t('connect') }}</ui-button>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section>
|
<section v-if="enableGithubIntegration">
|
||||||
<header><fa :icon="['fab', 'github']"/> GitHub</header>
|
<header><fa :icon="['fab', 'github']"/> GitHub</header>
|
||||||
<p v-if="$store.state.i.github">{{ $t('connected-to') }}: <a :href="`https://github.com/${$store.state.i.github.login}`" target="_blank">@{{ $store.state.i.github.login }}</a></p>
|
<p v-if="$store.state.i.github">{{ $t('connected-to') }}: <a :href="`https://github.com/${$store.state.i.github.login}`" target="_blank">@{{ $store.state.i.github.login }}</a></p>
|
||||||
<ui-button v-if="$store.state.i.github" @click="disconnectGithub">{{ $t('disconnect') }}</ui-button>
|
<ui-button v-if="$store.state.i.github" @click="disconnectGithub">{{ $t('disconnect') }}</ui-button>
|
||||||
@@ -39,9 +39,20 @@ export default Vue.extend({
|
|||||||
twitterForm: null,
|
twitterForm: null,
|
||||||
discordForm: null,
|
discordForm: null,
|
||||||
githubForm: null,
|
githubForm: null,
|
||||||
|
enableTwitterIntegration: false,
|
||||||
|
enableDiscordIntegration: false,
|
||||||
|
enableGithubIntegration: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
created() {
|
||||||
|
this.$root.getMeta().then(meta => {
|
||||||
|
this.enableTwitterIntegration = meta.enableTwitterIntegration;
|
||||||
|
this.enableDiscordIntegration = meta.enableDiscordIntegration;
|
||||||
|
this.enableGithubIntegration = meta.enableGithubIntegration;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
document.cookie = `i=${this.$store.state.i.token}`;
|
document.cookie = `i=${this.$store.state.i.token}`;
|
||||||
this.$watch('$store.state.i', () => {
|
this.$watch('$store.state.i', () => {
|
||||||
|
@@ -9,7 +9,7 @@
|
|||||||
@keypress="onKeypress"
|
@keypress="onKeypress"
|
||||||
@paste="onPaste"
|
@paste="onPaste"
|
||||||
:placeholder="$t('input-message-here')"
|
:placeholder="$t('input-message-here')"
|
||||||
v-autocomplete="'text'"
|
v-autocomplete="{ model: 'text' }"
|
||||||
></textarea>
|
></textarea>
|
||||||
<div class="file" @click="file = null" v-if="file">{{ file.name }}</div>
|
<div class="file" @click="file = null" v-if="file">{{ file.name }}</div>
|
||||||
<mk-uploader ref="uploader" @uploaded="onUploaded"/>
|
<mk-uploader ref="uploader" @uploaded="onUploaded"/>
|
||||||
|
53
src/client/app/common/views/components/particle.vue
Normal file
53
src/client/app/common/views/components/particle.vue
Normal file
File diff suppressed because one or more lines are too long
@@ -4,16 +4,16 @@
|
|||||||
<div class="popover" :class="{ compact, big }" ref="popover">
|
<div class="popover" :class="{ compact, big }" ref="popover">
|
||||||
<p v-if="!compact">{{ title }}</p>
|
<p v-if="!compact">{{ title }}</p>
|
||||||
<div ref="buttons" :class="{ showFocus }">
|
<div ref="buttons" :class="{ showFocus }">
|
||||||
<button @click="react('like')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="1" :title="$t('@.reactions.like')"><mk-reaction-icon reaction='like'/></button>
|
<button @click="react('like')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="1" :title="$t('@.reactions.like')" v-particle><mk-reaction-icon reaction="like"/></button>
|
||||||
<button @click="react('love')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="2" :title="$t('@.reactions.love')"><mk-reaction-icon reaction='love'/></button>
|
<button @click="react('love')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="2" :title="$t('@.reactions.love')" v-particle><mk-reaction-icon reaction="love"/></button>
|
||||||
<button @click="react('laugh')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="3" :title="$t('@.reactions.laugh')"><mk-reaction-icon reaction='laugh'/></button>
|
<button @click="react('laugh')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="3" :title="$t('@.reactions.laugh')" v-particle><mk-reaction-icon reaction="laugh"/></button>
|
||||||
<button @click="react('hmm')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="4" :title="$t('@.reactions.hmm')"><mk-reaction-icon reaction='hmm'/></button>
|
<button @click="react('hmm')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="4" :title="$t('@.reactions.hmm')" v-particle><mk-reaction-icon reaction="hmm"/></button>
|
||||||
<button @click="react('surprise')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="5" :title="$t('@.reactions.surprise')"><mk-reaction-icon reaction='surprise'/></button>
|
<button @click="react('surprise')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="5" :title="$t('@.reactions.surprise')" v-particle><mk-reaction-icon reaction="surprise"/></button>
|
||||||
<button @click="react('congrats')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="6" :title="$t('@.reactions.congrats')"><mk-reaction-icon reaction='congrats'/></button>
|
<button @click="react('congrats')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="6" :title="$t('@.reactions.congrats')" v-particle><mk-reaction-icon reaction="congrats"/></button>
|
||||||
<button @click="react('angry')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="7" :title="$t('@.reactions.angry')"><mk-reaction-icon reaction='angry'/></button>
|
<button @click="react('angry')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="7" :title="$t('@.reactions.angry')" v-particle><mk-reaction-icon reaction="angry"/></button>
|
||||||
<button @click="react('confused')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="8" :title="$t('@.reactions.confused')"><mk-reaction-icon reaction='confused'/></button>
|
<button @click="react('confused')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="8" :title="$t('@.reactions.confused')" v-particle><mk-reaction-icon reaction="confused"/></button>
|
||||||
<button @click="react('rip')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="9" :title="$t('@.reactions.rip')"><mk-reaction-icon reaction='rip'/></button>
|
<button @click="react('rip')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="9" :title="$t('@.reactions.rip')" v-particle><mk-reaction-icon reaction="rip"/></button>
|
||||||
<button @click="react('pudding')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="10" :title="$t('@.reactions.pudding')"><mk-reaction-icon reaction='pudding'/></button>
|
<button @click="react('pudding')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="10" :title="$t('@.reactions.pudding')" v-particle><mk-reaction-icon reaction="pudding"/></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -1,36 +1,106 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="mk-reactions-viewer">
|
<div class="mk-reactions-viewer">
|
||||||
<template v-if="reactions">
|
<template v-if="reactions">
|
||||||
<span :class="{ reacted: note.myReaction == 'like' }" @click="react('like')" v-if="reactions.like"><mk-reaction-icon reaction="like"/><span>{{ reactions.like }}</span></span>
|
<span :class="{ reacted: note.myReaction == 'like' }" @click="react('like')" v-if="reactions.like" v-particle><mk-reaction-icon reaction="like" ref="like"/><span>{{ reactions.like }}</span></span>
|
||||||
<span :class="{ reacted: note.myReaction == 'love' }" @click="react('love')" v-if="reactions.love"><mk-reaction-icon reaction="love"/><span>{{ reactions.love }}</span></span>
|
<span :class="{ reacted: note.myReaction == 'love' }" @click="react('love')" v-if="reactions.love" v-particle><mk-reaction-icon reaction="love" ref="love"/><span>{{ reactions.love }}</span></span>
|
||||||
<span :class="{ reacted: note.myReaction == 'laugh' }" @click="react('laugh')" v-if="reactions.laugh"><mk-reaction-icon reaction="laugh"/><span>{{ reactions.laugh }}</span></span>
|
<span :class="{ reacted: note.myReaction == 'laugh' }" @click="react('laugh')" v-if="reactions.laugh" v-particle><mk-reaction-icon reaction="laugh" ref="laugh"/><span>{{ reactions.laugh }}</span></span>
|
||||||
<span :class="{ reacted: note.myReaction == 'hmm' }" @click="react('hmm')" v-if="reactions.hmm"><mk-reaction-icon reaction="hmm"/><span>{{ reactions.hmm }}</span></span>
|
<span :class="{ reacted: note.myReaction == 'hmm' }" @click="react('hmm')" v-if="reactions.hmm" v-particle><mk-reaction-icon reaction="hmm" ref="hmm"/><span>{{ reactions.hmm }}</span></span>
|
||||||
<span :class="{ reacted: note.myReaction == 'surprise' }" @click="react('surprise')" v-if="reactions.surprise"><mk-reaction-icon reaction="surprise"/><span>{{ reactions.surprise }}</span></span>
|
<span :class="{ reacted: note.myReaction == 'surprise' }" @click="react('surprise')" v-if="reactions.surprise" v-particle><mk-reaction-icon reaction="surprise" ref="surprise"/><span>{{ reactions.surprise }}</span></span>
|
||||||
<span :class="{ reacted: note.myReaction == 'congrats' }" @click="react('congrats')" v-if="reactions.congrats"><mk-reaction-icon reaction="congrats"/><span>{{ reactions.congrats }}</span></span>
|
<span :class="{ reacted: note.myReaction == 'congrats' }" @click="react('congrats')" v-if="reactions.congrats" v-particle><mk-reaction-icon reaction="congrats" ref="congrats"/><span>{{ reactions.congrats }}</span></span>
|
||||||
<span :class="{ reacted: note.myReaction == 'angry' }" @click="react('angry')" v-if="reactions.angry"><mk-reaction-icon reaction="angry"/><span>{{ reactions.angry }}</span></span>
|
<span :class="{ reacted: note.myReaction == 'angry' }" @click="react('angry')" v-if="reactions.angry" v-particle><mk-reaction-icon reaction="angry" ref="angry"/><span>{{ reactions.angry }}</span></span>
|
||||||
<span :class="{ reacted: note.myReaction == 'confused' }" @click="react('confused')" v-if="reactions.confused"><mk-reaction-icon reaction="confused"/><span>{{ reactions.confused }}</span></span>
|
<span :class="{ reacted: note.myReaction == 'confused' }" @click="react('confused')" v-if="reactions.confused" v-particle><mk-reaction-icon reaction="confused" ref="confused"/><span>{{ reactions.confused }}</span></span>
|
||||||
<span :class="{ reacted: note.myReaction == 'rip' }" @click="react('rip')" v-if="reactions.rip"><mk-reaction-icon reaction="rip"/><span>{{ reactions.rip }}</span></span>
|
<span :class="{ reacted: note.myReaction == 'rip' }" @click="react('rip')" v-if="reactions.rip" v-particle><mk-reaction-icon reaction="rip" ref="rip"/><span>{{ reactions.rip }}</span></span>
|
||||||
<span :class="{ reacted: note.myReaction == 'pudding' }" @click="react('pudding')" v-if="reactions.pudding"><mk-reaction-icon reaction="pudding"/><span>{{ reactions.pudding }}</span></span>
|
<span :class="{ reacted: note.myReaction == 'pudding' }" @click="react('pudding')" v-if="reactions.pudding" v-particle><mk-reaction-icon reaction="pudding" ref="pudding"/><span>{{ reactions.pudding }}</span></span>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
|
import Icon from './reaction-icon.vue';
|
||||||
|
import * as anime from 'animejs';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
props: ['note'],
|
props: ['note'],
|
||||||
computed: {
|
computed: {
|
||||||
reactions(): number {
|
reactions(): any {
|
||||||
return this.note.reactionCounts;
|
return this.note.reactionCounts;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
watch: {
|
||||||
|
'reactions.like'() {
|
||||||
|
this.anime('like');
|
||||||
|
},
|
||||||
|
'reactions.love'() {
|
||||||
|
this.anime('love');
|
||||||
|
},
|
||||||
|
'reactions.laugh'() {
|
||||||
|
this.anime('laugh');
|
||||||
|
},
|
||||||
|
'reactions.hmm'() {
|
||||||
|
this.anime('hmm');
|
||||||
|
},
|
||||||
|
'reactions.surprise'() {
|
||||||
|
this.anime('surprise');
|
||||||
|
},
|
||||||
|
'reactions.congrats'() {
|
||||||
|
this.anime('congrats');
|
||||||
|
},
|
||||||
|
'reactions.angry'() {
|
||||||
|
this.anime('angry');
|
||||||
|
},
|
||||||
|
'reactions.confused'() {
|
||||||
|
this.anime('confused');
|
||||||
|
},
|
||||||
|
'reactions.rip'() {
|
||||||
|
this.anime('rip');
|
||||||
|
},
|
||||||
|
'reactions.pudding'() {
|
||||||
|
this.anime('pudding');
|
||||||
|
}
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
react(reaction: string) {
|
react(reaction: string) {
|
||||||
this.$root.api('notes/reactions/create', {
|
this.$root.api('notes/reactions/create', {
|
||||||
noteId: this.note.id,
|
noteId: this.note.id,
|
||||||
reaction: reaction
|
reaction: reaction
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
anime(reaction: string) {
|
||||||
|
if (this.$store.state.device.reduceMotion) return;
|
||||||
|
|
||||||
|
this.$nextTick(() => {
|
||||||
|
const rect = this.$refs[reaction].$el.getBoundingClientRect();
|
||||||
|
|
||||||
|
const x = rect.left;
|
||||||
|
const y = rect.top;
|
||||||
|
|
||||||
|
const icon = new Icon({
|
||||||
|
parent: this,
|
||||||
|
propsData: {
|
||||||
|
reaction: reaction
|
||||||
|
}
|
||||||
|
}).$mount();
|
||||||
|
|
||||||
|
icon.$el.style.position = 'absolute';
|
||||||
|
icon.$el.style.zIndex = 100;
|
||||||
|
icon.$el.style.top = (y + window.scrollY) + 'px';
|
||||||
|
icon.$el.style.left = (x + window.scrollX) + 'px';
|
||||||
|
icon.$el.style.fontSize = window.getComputedStyle(this.$refs[reaction].$el).fontSize;
|
||||||
|
|
||||||
|
document.body.appendChild(icon.$el);
|
||||||
|
|
||||||
|
anime({
|
||||||
|
targets: icon.$el,
|
||||||
|
opacity: [1, 0],
|
||||||
|
translateY: [0, -64],
|
||||||
|
duration: 1000,
|
||||||
|
easing: 'linear',
|
||||||
|
complete: () => {
|
||||||
|
icon.destroyDom();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<component class="dmtdnykelhudezerjlfpbhgovrgnqqgr"
|
<component class="dmtdnykelhudezerjlfpbhgovrgnqqgr"
|
||||||
:is="link ? 'a' : 'button'"
|
:is="link ? 'a' : 'button'"
|
||||||
:class="[styl, { inline, primary }]"
|
:class="{ inline, primary, wait }"
|
||||||
:type="type"
|
:type="type"
|
||||||
@click="$emit('click')"
|
@click="$emit('click')"
|
||||||
@mousedown="onMousedown"
|
@mousedown="onMousedown"
|
||||||
@@ -48,11 +48,11 @@ export default Vue.extend({
|
|||||||
required: false,
|
required: false,
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
},
|
wait: {
|
||||||
data() {
|
type: Boolean,
|
||||||
return {
|
required: false,
|
||||||
styl: 'fill'
|
default: false
|
||||||
};
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
if (this.autofocus) {
|
if (this.autofocus) {
|
||||||
@@ -121,6 +121,24 @@ export default Vue.extend({
|
|||||||
box-shadow none
|
box-shadow none
|
||||||
text-decoration none
|
text-decoration none
|
||||||
user-select none
|
user-select none
|
||||||
|
color var(--text)
|
||||||
|
background var(--buttonBg)
|
||||||
|
|
||||||
|
&:not(:disabled):hover
|
||||||
|
background var(--buttonHoverBg)
|
||||||
|
|
||||||
|
&:not(:disabled):active
|
||||||
|
background var(--buttonActiveBg)
|
||||||
|
|
||||||
|
&.primary
|
||||||
|
color var(--primaryForeground)
|
||||||
|
background var(--primary)
|
||||||
|
|
||||||
|
&:not(:disabled):hover
|
||||||
|
background var(--primaryLighten5)
|
||||||
|
|
||||||
|
&:not(:disabled):active
|
||||||
|
background var(--primaryDarken5)
|
||||||
|
|
||||||
*
|
*
|
||||||
pointer-events none
|
pointer-events none
|
||||||
@@ -152,35 +170,25 @@ export default Vue.extend({
|
|||||||
&.primary
|
&.primary
|
||||||
font-weight bold
|
font-weight bold
|
||||||
|
|
||||||
&.fill
|
&.wait
|
||||||
color var(--text)
|
background linear-gradient(
|
||||||
background var(--buttonBg)
|
45deg,
|
||||||
|
var(--primaryDarken10) 25%,
|
||||||
|
var(--primary) 25%,
|
||||||
|
var(--primary) 50%,
|
||||||
|
var(--primaryDarken10) 50%,
|
||||||
|
var(--primaryDarken10) 75%,
|
||||||
|
var(--primary) 75%,
|
||||||
|
var(--primary)
|
||||||
|
)
|
||||||
|
background-size 32px 32px
|
||||||
|
animation stripe-bg 1.5s linear infinite
|
||||||
|
opacity 0.7
|
||||||
|
cursor wait
|
||||||
|
|
||||||
&:not(:disabled):hover
|
@keyframes stripe-bg
|
||||||
background var(--buttonHoverBg)
|
from {background-position: 0 0;}
|
||||||
|
to {background-position: -64px 32px;}
|
||||||
&:not(:disabled):active
|
|
||||||
background var(--buttonActiveBg)
|
|
||||||
|
|
||||||
&.primary
|
|
||||||
color var(--primaryForeground)
|
|
||||||
background var(--primary)
|
|
||||||
|
|
||||||
&:not(:disabled):hover
|
|
||||||
background var(--primaryLighten5)
|
|
||||||
|
|
||||||
&:not(:disabled):active
|
|
||||||
background var(--primaryDarken5)
|
|
||||||
|
|
||||||
&:not(.fill)
|
|
||||||
color var(--primary)
|
|
||||||
background none
|
|
||||||
|
|
||||||
&:not(:disabled):hover
|
|
||||||
color var(--primaryDarken5)
|
|
||||||
|
|
||||||
&:not(:disabled):active
|
|
||||||
background var(--primaryAlpha03)
|
|
||||||
|
|
||||||
> .ripples
|
> .ripples
|
||||||
position absolute
|
position absolute
|
||||||
|
@@ -170,6 +170,9 @@ export default Vue.extend({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (url.hostname === 'music.youtube.com')
|
||||||
|
url.hostname = 'youtube.com';
|
||||||
|
|
||||||
fetch(`/url?url=${encodeURIComponent(this.url)}`).then(res => {
|
fetch(`/url?url=${encodeURIComponent(this.url)}`).then(res => {
|
||||||
res.json().then(info => {
|
res.json().then(info => {
|
||||||
if (info.url == null) return;
|
if (info.url == null) return;
|
||||||
|
@@ -21,21 +21,23 @@ class Autocomplete {
|
|||||||
private suggestion: any;
|
private suggestion: any;
|
||||||
private textarea: any;
|
private textarea: any;
|
||||||
private vm: any;
|
private vm: any;
|
||||||
private model: any;
|
|
||||||
private currentType: string;
|
private currentType: string;
|
||||||
|
private opts: {
|
||||||
|
model: string;
|
||||||
|
};
|
||||||
|
|
||||||
private get text(): string {
|
private get text(): string {
|
||||||
return this.vm[this.model];
|
return this.vm[this.opts.model];
|
||||||
}
|
}
|
||||||
|
|
||||||
private set text(text: string) {
|
private set text(text: string) {
|
||||||
this.vm[this.model] = text;
|
this.vm[this.opts.model] = text;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 対象のテキストエリアを与えてインスタンスを初期化します。
|
* 対象のテキストエリアを与えてインスタンスを初期化します。
|
||||||
*/
|
*/
|
||||||
constructor(textarea, vm, model) {
|
constructor(textarea, vm, opts) {
|
||||||
//#region BIND
|
//#region BIND
|
||||||
this.onInput = this.onInput.bind(this);
|
this.onInput = this.onInput.bind(this);
|
||||||
this.complete = this.complete.bind(this);
|
this.complete = this.complete.bind(this);
|
||||||
@@ -45,7 +47,7 @@ class Autocomplete {
|
|||||||
this.suggestion = null;
|
this.suggestion = null;
|
||||||
this.textarea = textarea;
|
this.textarea = textarea;
|
||||||
this.vm = vm;
|
this.vm = vm;
|
||||||
this.model = model;
|
this.opts = opts;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -1,5 +1,7 @@
|
|||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
|
|
||||||
import autocomplete from './autocomplete';
|
import autocomplete from './autocomplete';
|
||||||
|
import particle from './particle';
|
||||||
|
|
||||||
Vue.directive('autocomplete', autocomplete);
|
Vue.directive('autocomplete', autocomplete);
|
||||||
|
Vue.directive('particle', particle);
|
||||||
|
24
src/client/app/common/views/directives/particle.ts
Normal file
24
src/client/app/common/views/directives/particle.ts
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import Particle from '../components/particle.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
bind(el, binding, vn) {
|
||||||
|
if (vn.context.$store.state.device.reduceMotion) return;
|
||||||
|
|
||||||
|
el.addEventListener('click', () => {
|
||||||
|
const rect = el.getBoundingClientRect();
|
||||||
|
|
||||||
|
const x = rect.left + (el.clientWidth / 2);
|
||||||
|
const y = rect.top + (el.clientHeight / 2);
|
||||||
|
|
||||||
|
const particle = new Particle({
|
||||||
|
parent: vn.context,
|
||||||
|
propsData: {
|
||||||
|
x,
|
||||||
|
y
|
||||||
|
}
|
||||||
|
}).$mount();
|
||||||
|
|
||||||
|
document.body.appendChild(particle.$el);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
@@ -1,13 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="uptimes">
|
<div class="uptimes">
|
||||||
<p>Uptimes</p>
|
<p>Uptimes</p>
|
||||||
<p>Process: {{ process ? process.toFixed(0) : '---' }}s</p>
|
<p>Process: {{ process }}</p>
|
||||||
<p>OS: {{ os ? os.toFixed(0) : '---' }}s</p>
|
<p>OS: {{ os }}</p>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
|
import formatUptime from '../../scripts/format-uptime';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
props: ['connection'],
|
props: ['connection'],
|
||||||
@@ -25,8 +26,8 @@ export default Vue.extend({
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
onStats(stats) {
|
onStats(stats) {
|
||||||
this.process = stats.process_uptime;
|
this.process = formatUptime(stats.process_uptime);
|
||||||
this.os = stats.os_uptime;
|
this.os = formatUptime(stats.os_uptime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@@ -16,7 +16,6 @@ export const wsUrl = url.replace('http://', 'ws://').replace('https://', 'wss://
|
|||||||
export const lang = window.lang;
|
export const lang = window.lang;
|
||||||
export const langs = _LANGS_;
|
export const langs = _LANGS_;
|
||||||
export const locale = JSON.parse(localStorage.getItem('locale'));
|
export const locale = JSON.parse(localStorage.getItem('locale'));
|
||||||
export const themeColor = _THEME_COLOR_;
|
|
||||||
export const copyright = _COPYRIGHT_;
|
export const copyright = _COPYRIGHT_;
|
||||||
export const version = _VERSION_;
|
export const version = _VERSION_;
|
||||||
export const clientVersion = _CLIENT_VERSION_;
|
export const clientVersion = _CLIENT_VERSION_;
|
||||||
|
@@ -16,13 +16,13 @@
|
|||||||
<b>{{ $t('recent-tags') }}:</b>
|
<b>{{ $t('recent-tags') }}:</b>
|
||||||
<a v-for="tag in recentHashtags.slice(0, 5)" @click="addTag(tag)" :title="$t('click-to-tagging')">#{{ tag }}</a>
|
<a v-for="tag in recentHashtags.slice(0, 5)" @click="addTag(tag)" :title="$t('click-to-tagging')">#{{ tag }}</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="local-only" v-if="this.localOnly == true">{{ $t('local-only-message') }}</div>
|
<div class="local-only" v-if="localOnly == true">{{ $t('local-only-message') }}</div>
|
||||||
<input v-show="useCw" ref="cw" v-model="cw" :placeholder="$t('annotations')" v-autocomplete="'cw'">
|
<input v-show="useCw" ref="cw" v-model="cw" :placeholder="$t('annotations')" v-autocomplete="{ model: 'cw' }">
|
||||||
<div class="textarea">
|
<div class="textarea">
|
||||||
<textarea :class="{ with: (files.length != 0 || poll) }"
|
<textarea :class="{ with: (files.length != 0 || poll) }"
|
||||||
ref="text" v-model="text" :disabled="posting"
|
ref="text" v-model="text" :disabled="posting"
|
||||||
@keydown="onKeydown" @paste="onPaste" :placeholder="placeholder"
|
@keydown="onKeydown" @paste="onPaste" :placeholder="placeholder"
|
||||||
v-autocomplete="'text'"
|
v-autocomplete="{ model: 'text' }"
|
||||||
></textarea>
|
></textarea>
|
||||||
<button class="emoji" @click="emoji" ref="emoji">
|
<button class="emoji" @click="emoji" ref="emoji">
|
||||||
<fa :icon="['far', 'laugh']"/>
|
<fa :icon="['far', 'laugh']"/>
|
||||||
@@ -54,9 +54,9 @@
|
|||||||
<span v-if="visibility === 'private'"><fa icon="lock"/></span>
|
<span v-if="visibility === 'private'"><fa icon="lock"/></span>
|
||||||
</button>
|
</button>
|
||||||
<p class="text-count" :class="{ over: trimmedLength(text) > maxNoteTextLength }">{{ maxNoteTextLength - trimmedLength(text) }}</p>
|
<p class="text-count" :class="{ over: trimmedLength(text) > maxNoteTextLength }">{{ maxNoteTextLength - trimmedLength(text) }}</p>
|
||||||
<button :class="{ posting }" class="submit" :disabled="!canPost" @click="post">
|
<ui-button primary :wait="posting" class="submit" :disabled="!canPost" @click="post">
|
||||||
{{ posting ? $t('posting') : submitText }}<mk-ellipsis v-if="posting"/>
|
{{ posting ? $t('posting') : submitText }}<mk-ellipsis v-if="posting"/>
|
||||||
</button>
|
</ui-button>
|
||||||
<input ref="file" type="file" multiple="multiple" tabindex="-1" @change="onChangeFile"/>
|
<input ref="file" type="file" multiple="multiple" tabindex="-1" @change="onChangeFile"/>
|
||||||
<div class="dropzone" v-if="draghover"></div>
|
<div class="dropzone" v-if="draghover"></div>
|
||||||
</div>
|
</div>
|
||||||
@@ -684,62 +684,8 @@ export default Vue.extend({
|
|||||||
position absolute
|
position absolute
|
||||||
bottom 16px
|
bottom 16px
|
||||||
right 16px
|
right 16px
|
||||||
cursor pointer
|
|
||||||
padding 0
|
|
||||||
margin 0
|
|
||||||
width 110px
|
width 110px
|
||||||
height 40px
|
height 40px
|
||||||
font-size 1em
|
|
||||||
color var(--primaryForeground)
|
|
||||||
background var(--primary)
|
|
||||||
outline none
|
|
||||||
border none
|
|
||||||
border-radius 4px
|
|
||||||
|
|
||||||
&:not(:disabled)
|
|
||||||
font-weight bold
|
|
||||||
|
|
||||||
&:hover:not(:disabled)
|
|
||||||
background var(--primaryLighten5)
|
|
||||||
|
|
||||||
&:active:not(:disabled)
|
|
||||||
background var(--primaryDarken5)
|
|
||||||
|
|
||||||
&:focus
|
|
||||||
&:after
|
|
||||||
content ""
|
|
||||||
pointer-events none
|
|
||||||
position absolute
|
|
||||||
top -5px
|
|
||||||
right -5px
|
|
||||||
bottom -5px
|
|
||||||
left -5px
|
|
||||||
border 2px solid var(--primaryAlpha03)
|
|
||||||
border-radius 8px
|
|
||||||
|
|
||||||
&:disabled
|
|
||||||
opacity 0.7
|
|
||||||
cursor default
|
|
||||||
|
|
||||||
&.wait
|
|
||||||
background linear-gradient(
|
|
||||||
45deg,
|
|
||||||
var(--primaryDarken10) 25%,
|
|
||||||
var(--primary) 25%,
|
|
||||||
var(--primary) 50%,
|
|
||||||
var(--primaryDarken10) 50%,
|
|
||||||
var(--primaryDarken10) 75%,
|
|
||||||
var(--primary) 75%,
|
|
||||||
var(--primary)
|
|
||||||
)
|
|
||||||
background-size 32px 32px
|
|
||||||
animation stripe-bg 1.5s linear infinite
|
|
||||||
opacity 0.7
|
|
||||||
cursor wait
|
|
||||||
|
|
||||||
@keyframes stripe-bg
|
|
||||||
from {background-position: 0 0;}
|
|
||||||
to {background-position: -64px 32px;}
|
|
||||||
|
|
||||||
> .text-count
|
> .text-count
|
||||||
pointer-events none
|
pointer-events none
|
||||||
|
@@ -137,7 +137,6 @@
|
|||||||
<section>
|
<section>
|
||||||
<ui-switch v-model="games_reversi_showBoardLabels">{{ $t('@.show-reversi-board-labels') }}</ui-switch>
|
<ui-switch v-model="games_reversi_showBoardLabels">{{ $t('@.show-reversi-board-labels') }}</ui-switch>
|
||||||
<ui-switch v-model="games_reversi_useWhiteBlackStones">{{ $t('@.use-white-black-reversi-stones') }}</ui-switch>
|
<ui-switch v-model="games_reversi_useWhiteBlackStones">{{ $t('@.use-white-black-reversi-stones') }}</ui-switch>
|
||||||
<ui-switch v-model="games_reversi_useContrastStones">{{ $t('@.use-contrast-reversi-stones') }}</ui-switch>
|
|
||||||
</section>
|
</section>
|
||||||
</ui-card>
|
</ui-card>
|
||||||
|
|
||||||
@@ -511,11 +510,6 @@ export default Vue.extend({
|
|||||||
set(value) { this.$store.dispatch('settings/set', { key: 'games.reversi.useWhiteBlackStones', value }); }
|
set(value) { this.$store.dispatch('settings/set', { key: 'games.reversi.useWhiteBlackStones', value }); }
|
||||||
},
|
},
|
||||||
|
|
||||||
games_reversi_useContrastStones: {
|
|
||||||
get() { return this.$store.state.settings.games.reversi.useContrastStones; },
|
|
||||||
set(value) { this.$store.dispatch('settings/set', { key: 'games.reversi.useContrastStones', value }); }
|
|
||||||
},
|
|
||||||
|
|
||||||
disableAnimatedMfm: {
|
disableAnimatedMfm: {
|
||||||
get() { return this.$store.state.settings.disableAnimatedMfm; },
|
get() { return this.$store.state.settings.disableAnimatedMfm; },
|
||||||
set(value) { this.$store.dispatch('settings/set', { key: 'disableAnimatedMfm', value }); }
|
set(value) { this.$store.dispatch('settings/set', { key: 'disableAnimatedMfm', value }); }
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<form class="search" @submit.prevent="onSubmit">
|
<form class="wlvfdpkp" @submit.prevent="onSubmit">
|
||||||
<i><fa icon="search"/></i>
|
<i><fa icon="search"/></i>
|
||||||
<input v-model="q" type="search" :placeholder="$t('placeholder')"/>
|
<input v-model="q" type="search" :placeholder="$t('placeholder')" v-autocomplete="{ model: 'q' }"/>
|
||||||
<div class="result"></div>
|
<div class="result"></div>
|
||||||
</form>
|
</form>
|
||||||
</template>
|
</template>
|
||||||
@@ -19,10 +19,13 @@ export default Vue.extend({
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
onSubmit() {
|
onSubmit() {
|
||||||
if (this.q.startsWith('#')) {
|
const q = this.q.trim();
|
||||||
this.$router.push(`/tags/${encodeURIComponent(this.q.substr(1))}`);
|
if (q.startsWith('@')) {
|
||||||
|
this.$router.push(`/${q}`);
|
||||||
|
} else if (q.startsWith('#')) {
|
||||||
|
this.$router.push(`/tags/${encodeURIComponent(q.substr(1))}`);
|
||||||
} else {
|
} else {
|
||||||
this.$router.push(`/search?q=${encodeURIComponent(this.q)}`);
|
this.$router.push(`/search?q=${encodeURIComponent(q)}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -30,7 +33,7 @@ export default Vue.extend({
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="stylus" scoped>
|
<style lang="stylus" scoped>
|
||||||
.search
|
.wlvfdpkp
|
||||||
@media (max-width 800px)
|
@media (max-width 800px)
|
||||||
display none !important
|
display none !important
|
||||||
|
|
||||||
|
@@ -11,7 +11,7 @@
|
|||||||
<mk-error v-if="!fetching && requestInitPromise != null" @retry="resolveInitPromise"/>
|
<mk-error v-if="!fetching && requestInitPromise != null" @retry="resolveInitPromise"/>
|
||||||
|
|
||||||
<!-- トランジションを有効にするとなぜかメモリリークする -->
|
<!-- トランジションを有効にするとなぜかメモリリークする -->
|
||||||
<transition-group name="mk-notes" class="transition notes" ref="notes">
|
<transition-group name="mk-notes" class="transition notes" ref="notes" tag="div">
|
||||||
<template v-for="(note, i) in _notes">
|
<template v-for="(note, i) in _notes">
|
||||||
<x-note
|
<x-note
|
||||||
:note="note"
|
:note="note"
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- トランジションを有効にするとなぜかメモリリークする -->
|
<!-- トランジションを有効にするとなぜかメモリリークする -->
|
||||||
<component :is="!$store.state.device.reduceMotion ? 'transition-group' : 'div'" name="mk-notifications" class="transition notifications">
|
<component :is="!$store.state.device.reduceMotion ? 'transition-group' : 'div'" name="mk-notifications" class="transition notifications" tag="div">
|
||||||
<template v-for="(notification, i) in _notifications">
|
<template v-for="(notification, i) in _notifications">
|
||||||
<x-notification class="notification" :notification="notification" :key="notification.id"/>
|
<x-notification class="notification" :notification="notification" :key="notification.id"/>
|
||||||
<p class="date" v-if="i != notifications.length - 1 && notification._date != _notifications[i + 1]._date" :key="notification.id + '-time'">
|
<p class="date" v-if="i != notifications.length - 1 && notification._date != _notifications[i + 1]._date" :key="notification.id + '-time'">
|
||||||
|
@@ -1,9 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<mk-ui>
|
<mk-ui>
|
||||||
<main v-if="!fetching">
|
<main v-if="!fetching">
|
||||||
<template v-for="favorite in favorites">
|
<sequential-entrance animation="entranceFromTop" delay="25">
|
||||||
<mk-note-detail class="post" :note="favorite.note" :key="favorite.note.id"/>
|
<template v-for="favorite in favorites">
|
||||||
</template>
|
<mk-note-detail class="post" :note="favorite.note" :key="favorite.note.id"/>
|
||||||
|
</template>
|
||||||
|
</sequential-entrance>
|
||||||
<div class="more" v-if="existMore">
|
<div class="more" v-if="existMore">
|
||||||
<ui-button inline @click="more">{{ $t('@.load-more') }}</ui-button>
|
<ui-button inline @click="more">{{ $t('@.load-more') }}</ui-button>
|
||||||
</div>
|
</div>
|
||||||
@@ -75,7 +77,7 @@ main
|
|||||||
padding 16px
|
padding 16px
|
||||||
max-width 700px
|
max-width 700px
|
||||||
|
|
||||||
> .post
|
> * > .post
|
||||||
margin-bottom 16px
|
margin-bottom 16px
|
||||||
|
|
||||||
> .more
|
> .more
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
@paste="onPaste"
|
@paste="onPaste"
|
||||||
:placeholder="placeholder"
|
:placeholder="placeholder"
|
||||||
ref="text"
|
ref="text"
|
||||||
v-autocomplete="'text'"
|
v-autocomplete="{ model: 'text' }"
|
||||||
></textarea>
|
></textarea>
|
||||||
<button class="emoji" @click="emoji" ref="emoji">
|
<button class="emoji" @click="emoji" ref="emoji">
|
||||||
<fa :icon="['far', 'laugh']"/>
|
<fa :icon="['far', 'laugh']"/>
|
||||||
|
@@ -8,6 +8,7 @@ import VueRouter from 'vue-router';
|
|||||||
import VAnimateCss from 'v-animate-css';
|
import VAnimateCss from 'v-animate-css';
|
||||||
import VModal from 'vue-js-modal';
|
import VModal from 'vue-js-modal';
|
||||||
import VueI18n from 'vue-i18n';
|
import VueI18n from 'vue-i18n';
|
||||||
|
import SequentialEntrance from 'vue-sequential-entrance';
|
||||||
|
|
||||||
import VueHotkey from './common/hotkey';
|
import VueHotkey from './common/hotkey';
|
||||||
import App from './app.vue';
|
import App from './app.vue';
|
||||||
@@ -287,6 +288,7 @@ Vue.use(VAnimateCss);
|
|||||||
Vue.use(VModal);
|
Vue.use(VModal);
|
||||||
Vue.use(VueHotkey);
|
Vue.use(VueHotkey);
|
||||||
Vue.use(VueI18n);
|
Vue.use(VueI18n);
|
||||||
|
Vue.use(SequentialEntrance);
|
||||||
|
|
||||||
Vue.component('fa', FontAwesomeIcon);
|
Vue.component('fa', FontAwesomeIcon);
|
||||||
|
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- トランジションを有効にするとなぜかメモリリークする -->
|
<!-- トランジションを有効にするとなぜかメモリリークする -->
|
||||||
<component :is="!$store.state.device.reduceMotion ? 'transition-group' : 'div'" name="mk-notifications" class="transition notifications">
|
<component :is="!$store.state.device.reduceMotion ? 'transition-group' : 'div'" name="mk-notifications" class="transition notifications" tag="div">
|
||||||
<template v-for="(notification, i) in _notifications">
|
<template v-for="(notification, i) in _notifications">
|
||||||
<mk-notification :notification="notification" :key="notification.id"/>
|
<mk-notification :notification="notification" :key="notification.id"/>
|
||||||
<p class="date" :key="notification.id + '_date'" v-if="i != notifications.length - 1 && notification._date != _notifications[i + 1]._date">
|
<p class="date" :key="notification.id + '_date'" v-if="i != notifications.length - 1 && notification._date != _notifications[i + 1]._date">
|
||||||
|
@@ -19,8 +19,8 @@
|
|||||||
</span>
|
</span>
|
||||||
<a @click="addVisibleUser">+{{ $t('add-visible-user') }}</a>
|
<a @click="addVisibleUser">+{{ $t('add-visible-user') }}</a>
|
||||||
</div>
|
</div>
|
||||||
<input v-show="useCw" ref="cw" v-model="cw" :placeholder="$t('annotations')" v-autocomplete="'cw'">
|
<input v-show="useCw" ref="cw" v-model="cw" :placeholder="$t('annotations')" v-autocomplete="{ model: 'cw' }">
|
||||||
<textarea v-model="text" ref="text" :disabled="posting" :placeholder="placeholder" v-autocomplete="'text'"></textarea>
|
<textarea v-model="text" ref="text" :disabled="posting" :placeholder="placeholder" v-autocomplete="{ model: 'text' }"></textarea>
|
||||||
<div class="attaches" v-show="files.length != 0">
|
<div class="attaches" v-show="files.length != 0">
|
||||||
<x-draggable class="files" :list="files" :options="{ animation: 150 }">
|
<x-draggable class="files" :list="files" :options="{ animation: 150 }">
|
||||||
<div class="file" v-for="file in files" :key="file.id">
|
<div class="file" v-for="file in files" :key="file.id">
|
||||||
|
@@ -100,7 +100,15 @@ export default Vue.extend({
|
|||||||
input: true
|
input: true
|
||||||
}).then(({ canceled, result: query }) => {
|
}).then(({ canceled, result: query }) => {
|
||||||
if (canceled) return;
|
if (canceled) return;
|
||||||
this.$router.push(`/search?q=${encodeURIComponent(query)}`);
|
|
||||||
|
const q = query.trim();
|
||||||
|
if (q.startsWith('@')) {
|
||||||
|
this.$router.push(`/${q}`);
|
||||||
|
} else if (q.startsWith('#')) {
|
||||||
|
this.$router.push(`/tags/${encodeURIComponent(q.substr(1))}`);
|
||||||
|
} else {
|
||||||
|
this.$router.push(`/search?q=${encodeURIComponent(q)}`);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@@ -3,9 +3,11 @@
|
|||||||
<span slot="header"><span style="margin-right:4px;"><fa icon="star"/></span>{{ $t('title') }}</span>
|
<span slot="header"><span style="margin-right:4px;"><fa icon="star"/></span>{{ $t('title') }}</span>
|
||||||
|
|
||||||
<main>
|
<main>
|
||||||
<template v-for="favorite in favorites">
|
<sequential-entrance animation="entranceFromTop" delay="25">
|
||||||
<mk-note-detail class="post" :note="favorite.note" :key="favorite.note.id"/>
|
<template v-for="favorite in favorites">
|
||||||
</template>
|
<mk-note-detail class="post" :note="favorite.note" :key="favorite.note.id"/>
|
||||||
|
</template>
|
||||||
|
</sequential-entrance>
|
||||||
<ui-button v-if="existMore" @click="more">{{ $t('@.load-more') }}</ui-button>
|
<ui-button v-if="existMore" @click="more">{{ $t('@.load-more') }}</ui-button>
|
||||||
</main>
|
</main>
|
||||||
</mk-ui>
|
</mk-ui>
|
||||||
@@ -79,13 +81,13 @@ main
|
|||||||
margin 0 auto
|
margin 0 auto
|
||||||
padding 8px
|
padding 8px
|
||||||
|
|
||||||
> .post
|
> * > .post
|
||||||
margin-bottom 8px
|
margin-bottom 8px
|
||||||
|
|
||||||
@media (min-width 500px)
|
@media (min-width 500px)
|
||||||
padding 16px
|
padding 16px
|
||||||
|
|
||||||
> .post
|
> * > .post
|
||||||
margin-bottom 16px
|
margin-bottom 16px
|
||||||
|
|
||||||
@media (min-width 600px)
|
@media (min-width 600px)
|
||||||
|
@@ -33,7 +33,7 @@
|
|||||||
|
|
||||||
<section>
|
<section>
|
||||||
<ui-switch v-model="games_reversi_showBoardLabels">{{ $t('@.show-reversi-board-labels') }}</ui-switch>
|
<ui-switch v-model="games_reversi_showBoardLabels">{{ $t('@.show-reversi-board-labels') }}</ui-switch>
|
||||||
<ui-switch v-model="games_reversi_useContrastStones">{{ $t('@.use-contrast-reversi-stones') }}</ui-switch>
|
<ui-switch v-model="games_reversi_useWhiteBlackStones">{{ $t('@.use-white-black-reversi-stones') }}</ui-switch>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
@@ -287,9 +287,9 @@ export default Vue.extend({
|
|||||||
set(value) { this.$store.dispatch('settings/set', { key: 'games.reversi.showBoardLabels', value }); }
|
set(value) { this.$store.dispatch('settings/set', { key: 'games.reversi.showBoardLabels', value }); }
|
||||||
},
|
},
|
||||||
|
|
||||||
games_reversi_useContrastStones: {
|
games_reversi_useWhiteBlackStones: {
|
||||||
get() { return this.$store.state.settings.games.reversi.useContrastStones; },
|
get() { return this.$store.state.settings.games.reversi.useWhiteBlackStones; },
|
||||||
set(value) { this.$store.dispatch('settings/set', { key: 'games.reversi.useContrastStones', value }); }
|
set(value) { this.$store.dispatch('settings/set', { key: 'games.reversi.useWhiteBlackStones', value }); }
|
||||||
},
|
},
|
||||||
|
|
||||||
disableAnimatedMfm: {
|
disableAnimatedMfm: {
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
// Detect an old browser
|
// Detect an old browser
|
||||||
if (!('fetch' in window)) {
|
if (!('fetch' in window)) {
|
||||||
alert(
|
alert(
|
||||||
'お使いのブラウザ(またはOS)が古いためMisskeyを動作させることができません。' +
|
'お使いのブラウザ(またはOS)のバージョンが旧式のため、Misskeyを動作させることができません。' +
|
||||||
'バージョンを最新のものに更新するか、別のブラウザをお試しください。' +
|
'バージョンを最新のものに更新するか、別のブラウザをお試しください。' +
|
||||||
'\n\n' +
|
'\n\n' +
|
||||||
'Your browser (or your OS) seems outdated. ' +
|
'Your browser (or your OS) seems outdated. ' +
|
||||||
|
@@ -40,8 +40,7 @@ const defaultSettings = {
|
|||||||
games: {
|
games: {
|
||||||
reversi: {
|
reversi: {
|
||||||
showBoardLabels: false,
|
showBoardLabels: false,
|
||||||
useWhileBlackStones: false,
|
useWhiteBlackStones: false,
|
||||||
useContrastStones: false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
{
|
{
|
||||||
"copyright": "Copyright (c) 2014-2018 syuilo",
|
"copyright": "Copyright (c) 2014-2018 syuilo"
|
||||||
"themeColor": "#fb4e4e",
|
|
||||||
"themeColorForeground": "#fff"
|
|
||||||
}
|
}
|
||||||
|
@@ -124,7 +124,7 @@ type: `switch`
|
|||||||
スイッチを表示します。何かの機能をオン/オフさせたい場合に有用です。
|
スイッチを表示します。何かの機能をオン/オフさせたい場合に有用です。
|
||||||
|
|
||||||
##### プロパティ
|
##### プロパティ
|
||||||
`desc` ... スイッチの詳細な説明。
|
`label` ... スイッチに表記するテキスト。
|
||||||
|
|
||||||
#### ラジオボタン
|
#### ラジオボタン
|
||||||
type: `radio`
|
type: `radio`
|
||||||
|
@@ -103,8 +103,18 @@ export default (tokens: Node[], mentionedRemoteUsers: INote['mentionedRemoteUser
|
|||||||
mention(token) {
|
mention(token) {
|
||||||
const a = doc.createElement('a');
|
const a = doc.createElement('a');
|
||||||
const { username, host, acct } = token.props;
|
const { username, host, acct } = token.props;
|
||||||
const remoteUserInfo = mentionedRemoteUsers.find(remoteUser => remoteUser.username === username && remoteUser.host === host);
|
switch (host) {
|
||||||
a.href = remoteUserInfo ? remoteUserInfo.uri : `${config.url}/${acct}`;
|
case 'github.com':
|
||||||
|
a.href = `https://github.com/${username}`;
|
||||||
|
break;
|
||||||
|
case 'twitter.com':
|
||||||
|
a.href = `https://twitter.com/${username}`;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
const remoteUserInfo = mentionedRemoteUsers.find(remoteUser => remoteUser.username === username && remoteUser.host === host);
|
||||||
|
a.href = remoteUserInfo ? remoteUserInfo.uri : `${config.url}/${acct}`;
|
||||||
|
break;
|
||||||
|
}
|
||||||
a.textContent = acct;
|
a.textContent = acct;
|
||||||
return a;
|
return a;
|
||||||
},
|
},
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
import * as mongo from 'mongodb';
|
import * as mongo from 'mongodb';
|
||||||
const deepcopy = require('deepcopy');
|
const deepcopy = require('deepcopy');
|
||||||
import { pack as packFolder } from './drive-folder';
|
import { pack as packFolder } from './drive-folder';
|
||||||
|
import { pack as packUser } from './user';
|
||||||
import monkDb, { nativeDbConn } from '../db/mongodb';
|
import monkDb, { nativeDbConn } from '../db/mongodb';
|
||||||
import isObjectId from '../misc/is-objectid';
|
import isObjectId from '../misc/is-objectid';
|
||||||
import getDriveFileUrl, { getOriginalUrl } from '../misc/get-drive-file-url';
|
import getDriveFileUrl, { getOriginalUrl } from '../misc/get-drive-file-url';
|
||||||
@@ -131,6 +132,7 @@ export const packMany = (
|
|||||||
options?: {
|
options?: {
|
||||||
detail?: boolean
|
detail?: boolean
|
||||||
self?: boolean,
|
self?: boolean,
|
||||||
|
withUser?: boolean,
|
||||||
}
|
}
|
||||||
) => {
|
) => {
|
||||||
return Promise.all(files.map(f => pack(f, options)));
|
return Promise.all(files.map(f => pack(f, options)));
|
||||||
@@ -144,6 +146,7 @@ export const pack = (
|
|||||||
options?: {
|
options?: {
|
||||||
detail?: boolean,
|
detail?: boolean,
|
||||||
self?: boolean,
|
self?: boolean,
|
||||||
|
withUser?: boolean,
|
||||||
}
|
}
|
||||||
) => new Promise<any>(async (resolve, reject) => {
|
) => new Promise<any>(async (resolve, reject) => {
|
||||||
const opts = Object.assign({
|
const opts = Object.assign({
|
||||||
@@ -208,6 +211,11 @@ export const pack = (
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (opts.withUser) {
|
||||||
|
// Populate user
|
||||||
|
_target.user = await packUser(_file.metadata.userId);
|
||||||
|
}
|
||||||
|
|
||||||
delete _target.withoutChunks;
|
delete _target.withoutChunks;
|
||||||
delete _target.storage;
|
delete _target.storage;
|
||||||
delete _target.storageProps;
|
delete _target.storageProps;
|
||||||
|
@@ -43,7 +43,7 @@ export default async (user: ILocalUser) => {
|
|||||||
attachment.push({
|
attachment.push({
|
||||||
type: 'PropertyValue',
|
type: 'PropertyValue',
|
||||||
name: 'Discord',
|
name: 'Discord',
|
||||||
value: `<a href="https://discordapp.com/users/${user.discord.id}" rel="me nofollow noopener" target="_blank"><span>@${user.discord.username}#${user.discord.discriminator}</span></a>`
|
value: `<a href="https://discordapp.com/users/${user.discord.id}" rel="me nofollow noopener" target="_blank"><span>${user.discord.username}#${user.discord.discriminator}</span></a>`
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import * as mongo from 'mongodb';
|
import { ObjectID } from 'mongodb';
|
||||||
import * as Router from 'koa-router';
|
import * as Router from 'koa-router';
|
||||||
const json = require('koa-json-body');
|
const json = require('koa-json-body');
|
||||||
const httpSignature = require('http-signature');
|
const httpSignature = require('http-signature');
|
||||||
@@ -64,8 +64,13 @@ router.post('/users/:user/inbox', json(), inbox);
|
|||||||
router.get('/notes/:note', async (ctx, next) => {
|
router.get('/notes/:note', async (ctx, next) => {
|
||||||
if (!isActivityPubReq(ctx)) return await next();
|
if (!isActivityPubReq(ctx)) return await next();
|
||||||
|
|
||||||
|
if (!ObjectID.isValid(ctx.params.note)) {
|
||||||
|
ctx.status = 404;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const note = await Note.findOne({
|
const note = await Note.findOne({
|
||||||
_id: new mongo.ObjectID(ctx.params.note),
|
_id: new ObjectID(ctx.params.note),
|
||||||
visibility: { $in: ['public', 'home'] },
|
visibility: { $in: ['public', 'home'] },
|
||||||
localOnly: { $ne: true }
|
localOnly: { $ne: true }
|
||||||
});
|
});
|
||||||
@@ -82,8 +87,13 @@ router.get('/notes/:note', async (ctx, next) => {
|
|||||||
|
|
||||||
// note activity
|
// note activity
|
||||||
router.get('/notes/:note/activity', async ctx => {
|
router.get('/notes/:note/activity', async ctx => {
|
||||||
|
if (!ObjectID.isValid(ctx.params.note)) {
|
||||||
|
ctx.status = 404;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const note = await Note.findOne({
|
const note = await Note.findOne({
|
||||||
_id: new mongo.ObjectID(ctx.params.note),
|
_id: new ObjectID(ctx.params.note),
|
||||||
visibility: { $in: ['public', 'home'] },
|
visibility: { $in: ['public', 'home'] },
|
||||||
localOnly: { $ne: true }
|
localOnly: { $ne: true }
|
||||||
});
|
});
|
||||||
@@ -112,7 +122,12 @@ router.get('/users/:user/collections/featured', Featured);
|
|||||||
|
|
||||||
// publickey
|
// publickey
|
||||||
router.get('/users/:user/publickey', async ctx => {
|
router.get('/users/:user/publickey', async ctx => {
|
||||||
const userId = new mongo.ObjectID(ctx.params.user);
|
if (!ObjectID.isValid(ctx.params.user)) {
|
||||||
|
ctx.status = 404;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const userId = new ObjectID(ctx.params.user);
|
||||||
|
|
||||||
const user = await User.findOne({
|
const user = await User.findOne({
|
||||||
_id: userId,
|
_id: userId,
|
||||||
@@ -146,7 +161,12 @@ async function userInfo(ctx: Router.IRouterContext, user: IUser) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
router.get('/users/:user', async ctx => {
|
router.get('/users/:user', async ctx => {
|
||||||
const userId = new mongo.ObjectID(ctx.params.user);
|
if (!ObjectID.isValid(ctx.params.user)) {
|
||||||
|
ctx.status = 404;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const userId = new ObjectID(ctx.params.user);
|
||||||
|
|
||||||
const user = await User.findOne({
|
const user = await User.findOne({
|
||||||
_id: userId,
|
_id: userId,
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import * as mongo from 'mongodb';
|
import { ObjectID } from 'mongodb';
|
||||||
import * as Router from 'koa-router';
|
import * as Router from 'koa-router';
|
||||||
import config from '../../config';
|
import config from '../../config';
|
||||||
import User from '../../models/user';
|
import User from '../../models/user';
|
||||||
@@ -9,7 +9,12 @@ import Note from '../../models/note';
|
|||||||
import renderNote from '../../remote/activitypub/renderer/note';
|
import renderNote from '../../remote/activitypub/renderer/note';
|
||||||
|
|
||||||
export default async (ctx: Router.IRouterContext) => {
|
export default async (ctx: Router.IRouterContext) => {
|
||||||
const userId = new mongo.ObjectID(ctx.params.user);
|
if (!ObjectID.isValid(ctx.params.user)) {
|
||||||
|
ctx.status = 404;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const userId = new ObjectID(ctx.params.user);
|
||||||
|
|
||||||
// Verify user
|
// Verify user
|
||||||
const user = await User.findOne({
|
const user = await User.findOne({
|
||||||
@@ -24,7 +29,7 @@ export default async (ctx: Router.IRouterContext) => {
|
|||||||
|
|
||||||
const pinnedNoteIds = user.pinnedNoteIds || [];
|
const pinnedNoteIds = user.pinnedNoteIds || [];
|
||||||
|
|
||||||
const pinnedNotes = await Promise.all(pinnedNoteIds.map(id => Note.findOne({ _id: id })));
|
const pinnedNotes = await Promise.all(pinnedNoteIds.filter(ObjectID.isValid).map(id => Note.findOne({ _id: id })));
|
||||||
|
|
||||||
const renderedNotes = await Promise.all(pinnedNotes.map(note => renderNote(note)));
|
const renderedNotes = await Promise.all(pinnedNotes.map(note => renderNote(note)));
|
||||||
|
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import * as mongo from 'mongodb';
|
import { ObjectID } from 'mongodb';
|
||||||
import * as Router from 'koa-router';
|
import * as Router from 'koa-router';
|
||||||
import config from '../../config';
|
import config from '../../config';
|
||||||
import $ from 'cafy'; import ID, { transform } from '../../misc/cafy-id';
|
import $ from 'cafy'; import ID, { transform } from '../../misc/cafy-id';
|
||||||
@@ -11,7 +11,12 @@ import renderFollowUser from '../../remote/activitypub/renderer/follow-user';
|
|||||||
import { setResponseType } from '../activitypub';
|
import { setResponseType } from '../activitypub';
|
||||||
|
|
||||||
export default async (ctx: Router.IRouterContext) => {
|
export default async (ctx: Router.IRouterContext) => {
|
||||||
const userId = new mongo.ObjectID(ctx.params.user);
|
if (!ObjectID.isValid(ctx.params.user)) {
|
||||||
|
ctx.status = 404;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const userId = new ObjectID(ctx.params.user);
|
||||||
|
|
||||||
// Get 'cursor' parameter
|
// Get 'cursor' parameter
|
||||||
const [cursor = null, cursorErr] = $.type(ID).optional.get(ctx.request.query.cursor);
|
const [cursor = null, cursorErr] = $.type(ID).optional.get(ctx.request.query.cursor);
|
||||||
|
@@ -1,7 +1,8 @@
|
|||||||
import * as mongo from 'mongodb';
|
import { ObjectID } from 'mongodb';
|
||||||
import * as Router from 'koa-router';
|
import * as Router from 'koa-router';
|
||||||
import config from '../../config';
|
import config from '../../config';
|
||||||
import $ from 'cafy'; import ID, { transform } from '../../misc/cafy-id';
|
import $ from 'cafy';
|
||||||
|
import ID, { transform } from '../../misc/cafy-id';
|
||||||
import User from '../../models/user';
|
import User from '../../models/user';
|
||||||
import Following from '../../models/following';
|
import Following from '../../models/following';
|
||||||
import pack from '../../remote/activitypub/renderer';
|
import pack from '../../remote/activitypub/renderer';
|
||||||
@@ -11,7 +12,12 @@ import renderFollowUser from '../../remote/activitypub/renderer/follow-user';
|
|||||||
import { setResponseType } from '../activitypub';
|
import { setResponseType } from '../activitypub';
|
||||||
|
|
||||||
export default async (ctx: Router.IRouterContext) => {
|
export default async (ctx: Router.IRouterContext) => {
|
||||||
const userId = new mongo.ObjectID(ctx.params.user);
|
if (!ObjectID.isValid(ctx.params.user)) {
|
||||||
|
ctx.status = 404;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const userId = new ObjectID(ctx.params.user);
|
||||||
|
|
||||||
// Get 'cursor' parameter
|
// Get 'cursor' parameter
|
||||||
const [cursor = null, cursorErr] = $.type(ID).optional.get(ctx.request.query.cursor);
|
const [cursor = null, cursorErr] = $.type(ID).optional.get(ctx.request.query.cursor);
|
||||||
|
@@ -1,7 +1,8 @@
|
|||||||
import * as mongo from 'mongodb';
|
import { ObjectID } from 'mongodb';
|
||||||
import * as Router from 'koa-router';
|
import * as Router from 'koa-router';
|
||||||
import config from '../../config';
|
import config from '../../config';
|
||||||
import $ from 'cafy'; import ID, { transform } from '../../misc/cafy-id';
|
import $ from 'cafy';
|
||||||
|
import ID, { transform } from '../../misc/cafy-id';
|
||||||
import User from '../../models/user';
|
import User from '../../models/user';
|
||||||
import pack from '../../remote/activitypub/renderer';
|
import pack from '../../remote/activitypub/renderer';
|
||||||
import renderOrderedCollection from '../../remote/activitypub/renderer/ordered-collection';
|
import renderOrderedCollection from '../../remote/activitypub/renderer/ordered-collection';
|
||||||
@@ -15,7 +16,12 @@ import renderAnnounce from '../../remote/activitypub/renderer/announce';
|
|||||||
import { countIf } from '../../prelude/array';
|
import { countIf } from '../../prelude/array';
|
||||||
|
|
||||||
export default async (ctx: Router.IRouterContext) => {
|
export default async (ctx: Router.IRouterContext) => {
|
||||||
const userId = new mongo.ObjectID(ctx.params.user);
|
if (!ObjectID.isValid(ctx.params.user)) {
|
||||||
|
ctx.status = 404;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const userId = new ObjectID(ctx.params.user);
|
||||||
|
|
||||||
// Get 'sinceId' parameter
|
// Get 'sinceId' parameter
|
||||||
const [sinceId, sinceIdErr] = $.type(ID).optional.get(ctx.request.query.since_id);
|
const [sinceId, sinceIdErr] = $.type(ID).optional.get(ctx.request.query.since_id);
|
||||||
|
81
src/server/api/endpoints/admin/drive/files.ts
Normal file
81
src/server/api/endpoints/admin/drive/files.ts
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
import $ from 'cafy';
|
||||||
|
import File, { packMany } from '../../../../../models/drive-file';
|
||||||
|
import define from '../../../define';
|
||||||
|
|
||||||
|
export const meta = {
|
||||||
|
requireCredential: false,
|
||||||
|
requireModerator: true,
|
||||||
|
|
||||||
|
params: {
|
||||||
|
limit: {
|
||||||
|
validator: $.num.optional.range(1, 100),
|
||||||
|
default: 10
|
||||||
|
},
|
||||||
|
|
||||||
|
offset: {
|
||||||
|
validator: $.num.optional.min(0),
|
||||||
|
default: 0
|
||||||
|
},
|
||||||
|
|
||||||
|
sort: {
|
||||||
|
validator: $.str.optional.or([
|
||||||
|
'+createdAt',
|
||||||
|
'-createdAt',
|
||||||
|
'+size',
|
||||||
|
'-size',
|
||||||
|
]),
|
||||||
|
},
|
||||||
|
|
||||||
|
origin: {
|
||||||
|
validator: $.str.optional.or([
|
||||||
|
'combined',
|
||||||
|
'local',
|
||||||
|
'remote',
|
||||||
|
]),
|
||||||
|
default: 'local'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default define(meta, (ps, me) => new Promise(async (res, rej) => {
|
||||||
|
let _sort;
|
||||||
|
if (ps.sort) {
|
||||||
|
if (ps.sort == '+createdAt') {
|
||||||
|
_sort = {
|
||||||
|
uploadDate: -1
|
||||||
|
};
|
||||||
|
} else if (ps.sort == '-createdAt') {
|
||||||
|
_sort = {
|
||||||
|
uploadDate: 1
|
||||||
|
};
|
||||||
|
} else if (ps.sort == '+size') {
|
||||||
|
_sort = {
|
||||||
|
length: -1
|
||||||
|
};
|
||||||
|
} else if (ps.sort == '+size') {
|
||||||
|
_sort = {
|
||||||
|
length: -1
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_sort = {
|
||||||
|
_id: -1
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const q = {
|
||||||
|
'metadata.deletedAt': { $exists: false },
|
||||||
|
} as any;
|
||||||
|
|
||||||
|
if (ps.origin == 'local') q['metadata._user.host'] = null;
|
||||||
|
if (ps.origin == 'remote') q['metadata._user.host'] = { $ne: null };
|
||||||
|
|
||||||
|
const files = await File
|
||||||
|
.find(q, {
|
||||||
|
limit: ps.limit,
|
||||||
|
sort: _sort,
|
||||||
|
skip: ps.offset
|
||||||
|
});
|
||||||
|
|
||||||
|
res(await packMany(files, { detail: true, withUser: true }));
|
||||||
|
}));
|
@@ -32,14 +32,17 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
|||||||
// Fetch file
|
// Fetch file
|
||||||
const file = await DriveFile
|
const file = await DriveFile
|
||||||
.findOne({
|
.findOne({
|
||||||
_id: ps.fileId,
|
_id: ps.fileId
|
||||||
'metadata.userId': user._id
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (file === null) {
|
if (file === null) {
|
||||||
return rej('file-not-found');
|
return rej('file-not-found');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!user.isAdmin && !user.isModerator && !file.metadata.userId.equals(user._id)) {
|
||||||
|
return rej('access denied');
|
||||||
|
}
|
||||||
|
|
||||||
// Delete
|
// Delete
|
||||||
await del(file);
|
await del(file);
|
||||||
|
|
||||||
|
@@ -3,6 +3,7 @@ import Note from '../../../../models/note';
|
|||||||
import deleteNote from '../../../../services/note/delete';
|
import deleteNote from '../../../../services/note/delete';
|
||||||
import User from '../../../../models/user';
|
import User from '../../../../models/user';
|
||||||
import define from '../../define';
|
import define from '../../define';
|
||||||
|
const ms = require('ms');
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
stability: 'stable',
|
stability: 'stable',
|
||||||
@@ -16,6 +17,12 @@ export const meta = {
|
|||||||
|
|
||||||
kind: 'note-write',
|
kind: 'note-write',
|
||||||
|
|
||||||
|
limit: {
|
||||||
|
duration: ms('1hour'),
|
||||||
|
max: 300,
|
||||||
|
minInterval: ms('1sec')
|
||||||
|
},
|
||||||
|
|
||||||
params: {
|
params: {
|
||||||
noteId: {
|
noteId: {
|
||||||
validator: $.type(ID),
|
validator: $.type(ID),
|
||||||
|
@@ -15,7 +15,7 @@ import parseAcct from '../../misc/acct/parse';
|
|||||||
import config from '../../config';
|
import config from '../../config';
|
||||||
import Note, { pack as packNote } from '../../models/note';
|
import Note, { pack as packNote } from '../../models/note';
|
||||||
import getNoteSummary from '../../misc/get-note-summary';
|
import getNoteSummary from '../../misc/get-note-summary';
|
||||||
const consts = require('../../const.json');
|
import fetchMeta from '../../misc/fetch-meta';
|
||||||
|
|
||||||
const client = `${__dirname}/../../client/`;
|
const client = `${__dirname}/../../client/`;
|
||||||
|
|
||||||
@@ -26,8 +26,7 @@ const app = new Koa();
|
|||||||
app.use(views(__dirname + '/views', {
|
app.use(views(__dirname + '/views', {
|
||||||
extension: 'pug',
|
extension: 'pug',
|
||||||
options: {
|
options: {
|
||||||
config,
|
config
|
||||||
themeColor: consts.themeColor
|
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -120,10 +119,11 @@ router.get('/notes/:note', async ctx => {
|
|||||||
|
|
||||||
// Render base html for all requests
|
// Render base html for all requests
|
||||||
router.get('*', async ctx => {
|
router.get('*', async ctx => {
|
||||||
await send(ctx, `app/base.html`, {
|
const meta = await fetchMeta();
|
||||||
root: client,
|
await ctx.render('base', {
|
||||||
maxage: ms('5m')
|
img: meta.bannerUrl
|
||||||
});
|
});
|
||||||
|
ctx.set('Cache-Control', 'public, max-age=86400');
|
||||||
});
|
});
|
||||||
|
|
||||||
// Register router
|
// Register router
|
||||||
|
@@ -9,7 +9,6 @@ html
|
|||||||
head
|
head
|
||||||
meta(charset='utf-8')
|
meta(charset='utf-8')
|
||||||
meta(name='application-name' content='Misskey')
|
meta(name='application-name' content='Misskey')
|
||||||
meta(name='theme-color' content=themeColor)
|
|
||||||
meta(name='referrer' content='origin')
|
meta(name='referrer' content='origin')
|
||||||
meta(property='og:site_name' content='Misskey')
|
meta(property='og:site_name' content='Misskey')
|
||||||
link(rel='manifest' href='/manifest.json')
|
link(rel='manifest' href='/manifest.json')
|
||||||
@@ -23,16 +22,16 @@ html
|
|||||||
|
|
||||||
block meta
|
block meta
|
||||||
|
|
||||||
|
block og
|
||||||
|
meta(property='og:image' content=img)
|
||||||
|
|
||||||
style
|
style
|
||||||
include ./../../../built/client/assets/init.css
|
include ./../../../../built/client/assets/init.css
|
||||||
script
|
script
|
||||||
include ./../../../built/client/assets/boot.js
|
include ./../../../../built/client/assets/boot.js
|
||||||
|
|
||||||
script
|
script
|
||||||
include ./../../../built/client/assets/safe.js
|
include ./../../../../built/client/assets/safe.js
|
||||||
|
|
||||||
//- FontAwesome style
|
|
||||||
style #{facss}
|
|
||||||
|
|
||||||
body
|
body
|
||||||
noscript: p
|
noscript: p
|
||||||
@@ -41,5 +40,5 @@ html
|
|||||||
| Please turn on your JavaScript
|
| Please turn on your JavaScript
|
||||||
div#ini.
|
div#ini.
|
||||||
<svg viewBox="0 0 50 50">
|
<svg viewBox="0 0 50 50">
|
||||||
<path fill=#{themeColor} d="M25.251,6.461c-10.318,0-18.683,8.365-18.683,18.683h4.068c0-8.071,6.543-14.615,14.615-14.615V6.461z" />
|
<path fill=#fb4e4e d="M25.251,6.461c-10.318,0-18.683,8.365-18.683,18.683h4.068c0-8.071,6.543-14.615,14.615-14.615V6.461z" />
|
||||||
</svg>
|
</svg>
|
@@ -1,4 +1,4 @@
|
|||||||
extends ../../../../src/client/app/base
|
extends ./base
|
||||||
|
|
||||||
block vars
|
block vars
|
||||||
- const user = note.user;
|
- const user = note.user;
|
||||||
@@ -11,14 +11,19 @@ block title
|
|||||||
block desc
|
block desc
|
||||||
meta(name='description' content= summary)
|
meta(name='description' content= summary)
|
||||||
|
|
||||||
block meta
|
block og
|
||||||
meta(name='twitter:card' content='summary')
|
|
||||||
meta(property='og:type' content='article')
|
meta(property='og:type' content='article')
|
||||||
meta(property='og:title' content= title)
|
meta(property='og:title' content= title)
|
||||||
meta(property='og:description' content= summary)
|
meta(property='og:description' content= summary)
|
||||||
meta(property='og:url' content= url)
|
meta(property='og:url' content= url)
|
||||||
meta(property='og:image' content= user.avatarUrl)
|
meta(property='og:image' content= user.avatarUrl)
|
||||||
|
|
||||||
|
block meta
|
||||||
|
meta(name='twitter:card' content='summary')
|
||||||
|
|
||||||
|
if user.twitter
|
||||||
|
meta(name='twitter:creator' content=`@${user.twitter.screenName}`)
|
||||||
|
|
||||||
if note.prev
|
if note.prev
|
||||||
link(rel='prev' href=`${config.url}/notes/${note.prev}`)
|
link(rel='prev' href=`${config.url}/notes/${note.prev}`)
|
||||||
if note.next
|
if note.next
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
extends ../../../../src/client/app/base
|
extends ./base
|
||||||
|
|
||||||
block vars
|
block vars
|
||||||
- const title = user.name ? `${user.name} (@${user.username})` : `@${user.username}`;
|
- const title = user.name ? `${user.name} (@${user.username})` : `@${user.username}`;
|
||||||
@@ -11,14 +11,19 @@ block title
|
|||||||
block desc
|
block desc
|
||||||
meta(name='description' content= user.description)
|
meta(name='description' content= user.description)
|
||||||
|
|
||||||
block meta
|
block og
|
||||||
meta(name='twitter:card' content='summary')
|
|
||||||
meta(property='og:type' content='blog')
|
meta(property='og:type' content='blog')
|
||||||
meta(property='og:title' content= title)
|
meta(property='og:title' content= title)
|
||||||
meta(property='og:description' content= user.description)
|
meta(property='og:description' content= user.description)
|
||||||
meta(property='og:url' content= url)
|
meta(property='og:url' content= url)
|
||||||
meta(property='og:image' content= img)
|
meta(property='og:image' content= img)
|
||||||
|
|
||||||
|
block meta
|
||||||
|
meta(name='twitter:card' content='summary')
|
||||||
|
|
||||||
|
if user.twitter
|
||||||
|
meta(name='twitter:creator' content=`@${user.twitter.screenName}`)
|
||||||
|
|
||||||
if !user.host
|
if !user.host
|
||||||
link(rel='alternate' href=`${config.url}/users/${user._id}` type='application/activity+json')
|
link(rel='alternate' href=`${config.url}/users/${user._id}` type='application/activity+json')
|
||||||
if user.uri
|
if user.uri
|
||||||
|
@@ -114,7 +114,6 @@ module.exports = {
|
|||||||
clear: false
|
clear: false
|
||||||
}),
|
}),
|
||||||
new webpack.DefinePlugin({
|
new webpack.DefinePlugin({
|
||||||
_THEME_COLOR_: JSON.stringify(constants.themeColor),
|
|
||||||
_COPYRIGHT_: JSON.stringify(constants.copyright),
|
_COPYRIGHT_: JSON.stringify(constants.copyright),
|
||||||
_VERSION_: JSON.stringify(meta.version),
|
_VERSION_: JSON.stringify(meta.version),
|
||||||
_CLIENT_VERSION_: JSON.stringify(version),
|
_CLIENT_VERSION_: JSON.stringify(version),
|
||||||
|
Reference in New Issue
Block a user