Compare commits
159 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6f97142b59 | ||
|
|
b31d1ce61d | ||
|
|
b07cd37a16 | ||
|
|
69b74a46b9 | ||
|
|
882d829558 | ||
|
|
532821d503 | ||
|
|
522ce67498 | ||
|
|
0e046faf4a | ||
|
|
d9092dc81f | ||
|
|
92a4e90026 | ||
|
|
07dccad5b1 | ||
|
|
146b0d2889 | ||
|
|
388565fb10 | ||
|
|
da4ba51a74 | ||
|
|
1edcd136a4 | ||
|
|
9883c751da | ||
|
|
f78b28b995 | ||
|
|
54d40420ad | ||
|
|
ba1492f977 | ||
|
|
efd0368e56 | ||
|
|
a766a57af9 | ||
|
|
3bdd8a2d90 | ||
|
|
7ef1205f8b | ||
|
|
e8db63e788 | ||
|
|
0bcef2453c | ||
|
|
b9f549135c | ||
|
|
87b0017386 | ||
|
|
cc8ff556d4 | ||
|
|
021f74da54 | ||
|
|
f9389802d7 | ||
|
|
18dd172c97 | ||
|
|
1d5a54ff6f | ||
|
|
03e2c7eec6 | ||
|
|
0902727d1c | ||
|
|
496895634d | ||
|
|
9414e9e258 | ||
|
|
357528d139 | ||
|
|
c4efbdf4c7 | ||
|
|
fb4a921cd9 | ||
|
|
683b242215 | ||
|
|
a5660d6c82 | ||
|
|
f632ec50c1 | ||
|
|
a55d15214b | ||
|
|
f1709a2cc2 | ||
|
|
effa542958 | ||
|
|
e8bf742c87 | ||
|
|
2e6652edce | ||
|
|
230c204b48 | ||
|
|
3755c600b1 | ||
|
|
24513fc0a3 | ||
|
|
0a79a6564a | ||
|
|
562bb5842b | ||
|
|
ec3ca3032e | ||
|
|
890770c275 | ||
|
|
9ed58a1b4e | ||
|
|
08984be2fe | ||
|
|
e3ade148ca | ||
|
|
34c0eff89f | ||
|
|
40aba47a47 | ||
|
|
6736f51134 | ||
|
|
9d826d6e52 | ||
|
|
902d9bc7a5 | ||
|
|
b6c86e2845 | ||
|
|
34dffdfc8f | ||
|
|
a56f3f1d89 | ||
|
|
88dc4c83cb | ||
|
|
5a28dc0198 | ||
|
|
40d2650d49 | ||
|
|
545e83efb1 | ||
|
|
d4b00a5482 | ||
|
|
c2b1bbeec5 | ||
|
|
8c8f165a6e | ||
|
|
04553de230 | ||
|
|
2776934728 | ||
|
|
0064dbb010 | ||
|
|
d52e671adf | ||
|
|
6017dc2dff | ||
|
|
937f7cbd60 | ||
|
|
f8b3f66904 | ||
|
|
9d5701f35a | ||
|
|
dff65810c6 | ||
|
|
6752cf1d64 | ||
|
|
8336910a59 | ||
|
|
957a1149e0 | ||
|
|
e8719ff6e6 | ||
|
|
28b63298e5 | ||
|
|
dd4dee8095 | ||
|
|
c47818fed4 | ||
|
|
e53c383908 | ||
|
|
55c9c0436b | ||
|
|
66b79e5e24 | ||
|
|
514b830910 | ||
|
|
e4f799bf1d | ||
|
|
b383427d3d | ||
|
|
e969518139 | ||
|
|
113fe294bd | ||
|
|
a4d92f781f | ||
|
|
414cac49c3 | ||
|
|
95b157ac3e | ||
|
|
8e3d884081 | ||
|
|
9def6fcadd | ||
|
|
7837bd44fc | ||
|
|
a6c3663155 | ||
|
|
0b5afadbb8 | ||
|
|
43864f0da4 | ||
|
|
6a0d9d70ed | ||
|
|
63c6dce68e | ||
|
|
53422ffcb2 | ||
|
|
38ca514f53 | ||
|
|
caea0f0376 | ||
|
|
25a8b26977 | ||
|
|
bcaefe8d62 | ||
|
|
46f1e8c599 | ||
|
|
16230f320e | ||
|
|
ace6419aef | ||
|
|
77fb9eb2be | ||
|
|
aa7fc7c893 | ||
|
|
8fc170109f | ||
|
|
ad12d00d7e | ||
|
|
fa5ea45726 | ||
|
|
4b6c113251 | ||
|
|
3548290ff2 | ||
|
|
b165b90c40 | ||
|
|
4ffe9c908b | ||
|
|
a135f75e71 | ||
|
|
cbc61ba03d | ||
|
|
5aa58da918 | ||
|
|
b083430011 | ||
|
|
a8946b0404 | ||
|
|
0303bccc61 | ||
|
|
f3ce8564ea | ||
|
|
52c3f9e98c | ||
|
|
6c8b4184fe | ||
|
|
a0979f8435 | ||
|
|
faba21d003 | ||
|
|
d82c5dff71 | ||
|
|
59fbc5b054 | ||
|
|
2c1a7f4392 | ||
|
|
769e6182d8 | ||
|
|
88176a17a3 | ||
|
|
fc660e869f | ||
|
|
dc04869650 | ||
|
|
93c3f34813 | ||
|
|
1282eed192 | ||
|
|
962b3ca78e | ||
|
|
62d17c9266 | ||
|
|
f5b928a537 | ||
|
|
c8811894b5 | ||
|
|
e579b49228 | ||
|
|
9561908ad3 | ||
|
|
fac7ebf4f6 | ||
|
|
a0769d65e3 | ||
|
|
d17aa4b24e | ||
|
|
310371658b | ||
|
|
7ca073aafd | ||
|
|
7216d0fb1f | ||
|
|
22a9e950c7 | ||
|
|
6683d50bae | ||
|
|
8f26176273 |
@@ -2,6 +2,11 @@ version: 2.1
|
||||
|
||||
executors:
|
||||
default:
|
||||
working_directory: /tmp/workspace
|
||||
docker:
|
||||
- image: misskey/ci:latest
|
||||
- image: circleci/mongo:latest
|
||||
with-redis:
|
||||
working_directory: /tmp/workspace
|
||||
docker:
|
||||
- image: misskey/ci:latest
|
||||
@@ -11,20 +16,8 @@ executors:
|
||||
working_directory: /tmp/workspace
|
||||
docker:
|
||||
- image: docker:latest
|
||||
alpine:
|
||||
working_directory: /tmp/workspace
|
||||
docker:
|
||||
- image: alpine:latest
|
||||
|
||||
jobs:
|
||||
ok:
|
||||
executor: alpine
|
||||
steps:
|
||||
- run:
|
||||
name: OK
|
||||
command: |
|
||||
echo -e '\033[0;32mOK\033[0;39m'
|
||||
|
||||
build:
|
||||
executor: default
|
||||
steps:
|
||||
@@ -60,18 +53,19 @@ jobs:
|
||||
key: yarn-v1-arch-{{ arch }}-env-{{ .Environment.variableName }}-package-{{ checksum "package.json" }}-lock-{{ checksum "yarn.lock" }}
|
||||
paths:
|
||||
- node_modules
|
||||
# - store_artifacts:
|
||||
# path: built
|
||||
- persist_to_workspace:
|
||||
root: .
|
||||
paths:
|
||||
- .
|
||||
test:
|
||||
parameters:
|
||||
without_redis:
|
||||
executor:
|
||||
type: string
|
||||
default: ""
|
||||
executor: default
|
||||
default: "default"
|
||||
without_redis:
|
||||
type: boolean
|
||||
default: false
|
||||
executor: <<parameters.executor>>
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: /tmp/workspace
|
||||
@@ -94,12 +88,11 @@ jobs:
|
||||
key: yarn-v1-arch-{{ arch }}-env-{{ .Environment.variableName }}-package-{{ checksum "package.json" }}-lock-{{ checksum "yarn.lock" }}
|
||||
paths:
|
||||
- node_modules
|
||||
|
||||
docker:
|
||||
parameters:
|
||||
with_deploy:
|
||||
type: string
|
||||
default: ""
|
||||
type: boolean
|
||||
default: false
|
||||
executor: docker
|
||||
steps:
|
||||
- checkout
|
||||
@@ -126,51 +119,76 @@ jobs:
|
||||
|
||||
workflows:
|
||||
version: 2
|
||||
build-and-test:
|
||||
nodejs:
|
||||
jobs:
|
||||
- ok:
|
||||
- hold:
|
||||
name: manual-build-trigger
|
||||
type: approval
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- l10n_develop
|
||||
- imgbot
|
||||
- patch-autogen
|
||||
ignore: master
|
||||
- build:
|
||||
filters:
|
||||
branches:
|
||||
ignore:
|
||||
- l10n_develop
|
||||
- imgbot
|
||||
- patch-autogen
|
||||
- test:
|
||||
name: manual-build
|
||||
requires:
|
||||
- build
|
||||
- manual-build-trigger
|
||||
filters:
|
||||
branches:
|
||||
ignore:
|
||||
# - master
|
||||
- l10n_develop
|
||||
- imgbot
|
||||
- patch-autogen
|
||||
- test:
|
||||
without_redis: "true"
|
||||
requires:
|
||||
- build
|
||||
filters:
|
||||
# branches:
|
||||
# only: master
|
||||
branches:
|
||||
ignore:
|
||||
# - master
|
||||
- l10n_develop
|
||||
- imgbot
|
||||
- patch-autogen
|
||||
# - docker:
|
||||
# filters:
|
||||
# branches:
|
||||
# ignore: master
|
||||
- docker:
|
||||
with_deploy: "true"
|
||||
ignore: master
|
||||
- build:
|
||||
name: auto-build
|
||||
filters:
|
||||
branches:
|
||||
only: master
|
||||
- test:
|
||||
name: manual-test-with-redis
|
||||
executor: with-redis
|
||||
requires:
|
||||
- manual-build
|
||||
filters:
|
||||
branches:
|
||||
ignore: master
|
||||
- test:
|
||||
name: auto-test-without-redis
|
||||
executor: with-redis
|
||||
requires:
|
||||
- auto-build
|
||||
filters:
|
||||
branches:
|
||||
only: master
|
||||
- test:
|
||||
name: manual-test-with-redis
|
||||
without_redis: true
|
||||
requires:
|
||||
- manual-build
|
||||
filters:
|
||||
branches:
|
||||
ignore: master
|
||||
- test:
|
||||
name: auto-test-without-redis
|
||||
without_redis: true
|
||||
requires:
|
||||
- auto-build
|
||||
filters:
|
||||
branches:
|
||||
only: master
|
||||
docker:
|
||||
jobs:
|
||||
- hold:
|
||||
name: manual-build-trigger
|
||||
type: approval
|
||||
filters:
|
||||
branches:
|
||||
ignore: master
|
||||
- docker:
|
||||
name: manual-build
|
||||
requires:
|
||||
- manual-build-trigger
|
||||
filters:
|
||||
branches:
|
||||
ignore: master
|
||||
- docker:
|
||||
name: auto-build
|
||||
with_deploy: true
|
||||
filters:
|
||||
branches:
|
||||
only: master
|
||||
|
||||
82
CHANGELOG.md
82
CHANGELOG.md
@@ -1,6 +1,88 @@
|
||||
ChangeLog
|
||||
=========
|
||||
|
||||
10.87.3
|
||||
----------
|
||||
* 開発モードでビルドしてもスクリプトが404になる問題を修正
|
||||
* 拡張子判別だとアイコンやバナー設定で対応していないと表示される問題を修正
|
||||
* フォローリクエスト数がおかしい場合の応急処置APIを追加
|
||||
* デザインの調整
|
||||
|
||||
10.87.2
|
||||
----------
|
||||
* みつけるの人気のタグを第2ソートで連合含めたユーザー数にしたりユーザーのタグ以外は除外するように
|
||||
* デザインの調整
|
||||
|
||||
10.87.1
|
||||
----------
|
||||
* ハッシュタグ検索で大文字小文字が区別されてしまう問題を修正
|
||||
|
||||
10.87.0
|
||||
----------
|
||||
* ハッシュタグでユーザー検索できるように
|
||||
* Exploreページに新規ユーザー一覧を追加
|
||||
* デッキ使用中にホーム扱いで開かれた時にタイムラインボタン等がない問題を修正
|
||||
* デッキ使用中に / 以外でリロードした際にホームモードになる問題を修正
|
||||
|
||||
10.86.2
|
||||
----------
|
||||
* 別タブでルートより下を開いたときにはデッキにしないように
|
||||
* 横のナビゲーションバーの改善
|
||||
* MIDIファイルがオーディオ扱いになる問題を修正
|
||||
* ミュートワードで正規表現を使えるように
|
||||
* デッキで無効になったタイムラインに警告を表示するように
|
||||
* デザインの調整
|
||||
* その他細かな修正
|
||||
|
||||
10.86.1
|
||||
----------
|
||||
* ナビゲーションバーの「ホーム」を「タイムライン」に改称
|
||||
* モバイル版でユーザーページが二重に描画される問題を修正
|
||||
* ユーザー一覧の「もっと読み込む」の動作がおかしい問題を修正
|
||||
* デザインの調整
|
||||
|
||||
10.86.0
|
||||
----------
|
||||
* Exploreページを実装
|
||||
* UIを改良
|
||||
* その他細かな修正
|
||||
|
||||
10.85.2
|
||||
----------
|
||||
* デッキから フォロー/フォロワー ページに行けるように
|
||||
* ナビゲーションが発生したときに最上部までスクロールように
|
||||
* 検索結果でページ遷移が発生する問題を修正
|
||||
* デザインの調整
|
||||
|
||||
10.85.1
|
||||
----------
|
||||
* ローカルのみ投稿をログイン画面のタイムラインに表示しないように
|
||||
* ナビゲーションバーを横にしてるとデッキに行けない問題を修正
|
||||
|
||||
10.85.0
|
||||
----------
|
||||
* デスクトップ版のUIを改良
|
||||
* 投稿ハイライトページを実装
|
||||
* 無効化されているタイムラインのフォールバック
|
||||
* 既にフォローされている場合はフォローリクエストを生成しないように
|
||||
* その他細かな修正
|
||||
|
||||
10.84.2
|
||||
----------
|
||||
* GIF画像にGIFバッジを表示
|
||||
* よく話すユーザーからサスペンドされたユーザーを隠すなど
|
||||
* nodeinfoが重い問題を修正
|
||||
* ハッシュタグクラウド取得が重い問題を軽減
|
||||
|
||||
10.84.1
|
||||
----------
|
||||
* deckにフォローされていますマークを追加
|
||||
* URLプレビューのサムネイルの調整
|
||||
* 管理画面でサイレンスされているユーザーを一覧できるように
|
||||
* ドキュメントにアクセスできない問題を修正
|
||||
* ジョブキューを無効化
|
||||
* 軽微なバグ修正
|
||||
|
||||
10.84.0
|
||||
----------
|
||||
* インスタンス管理の強化
|
||||
|
||||
13
Dockerfile
13
Dockerfile
@@ -8,7 +8,6 @@ WORKDIR /misskey
|
||||
|
||||
FROM base AS builder
|
||||
|
||||
RUN unlink /usr/bin/free
|
||||
RUN apk add --no-cache \
|
||||
autoconf \
|
||||
automake \
|
||||
@@ -20,24 +19,20 @@ RUN apk add --no-cache \
|
||||
make \
|
||||
nasm \
|
||||
pkgconfig \
|
||||
procps \
|
||||
python \
|
||||
zlib-dev
|
||||
RUN npm i -g node-gyp
|
||||
|
||||
COPY ./package.json ./
|
||||
RUN npm i
|
||||
RUN npm i -g yarn
|
||||
|
||||
COPY . ./
|
||||
RUN node-gyp configure \
|
||||
&& node-gyp build \
|
||||
&& npm run build
|
||||
RUN yarn install
|
||||
RUN yarn build
|
||||
|
||||
FROM base AS runner
|
||||
|
||||
RUN apk add --no-cache \
|
||||
ffmpeg \
|
||||
tini
|
||||
RUN npm i -g web-push
|
||||
ENTRYPOINT ["/sbin/tini", "--"]
|
||||
|
||||
COPY --from=builder /misskey/node_modules ./node_modules
|
||||
|
||||
14
README.md
14
README.md
@@ -3,9 +3,9 @@
|
||||
[](https://misskey.xyz/)
|
||||
================================================================
|
||||
|
||||
[](https://circleci.com/gh/syuilo/misskey)
|
||||
[](https://david-dm.org/syuilo/misskey)
|
||||
[](http://makeapullrequest.com)
|
||||
[](https://circleci.com/gh/syuilo/misskey)
|
||||
[](https://david-dm.org/syuilo/misskey)
|
||||
[](http://makeapullrequest.com)
|
||||
|
||||
**A forever evolving, sophisticated microblogging platform.**
|
||||
|
||||
@@ -94,7 +94,7 @@ Please see the [Contribution Guide](./CONTRIBUTING.md).
|
||||
<!-- PATREON_START -->
|
||||
<table><tr>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/12190916/fb7fa7983c14425f890369535b1506a4/1?token-time=2145916800&token-hash=WeuDzzz24cRXJogyIkU-mxARqkdyms-rcZKbO-GpGjw%3D" alt="weep" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/12731202/0995c46cdcb54153ab5f073f5869b70a/1?token-time=2145916800&token-hash=prtYqPOiSHBulhM7NU0VzMaWx39-9ntdq25b6kafDNA%3D" alt="negao" width="100"></td>
|
||||
<td><img src="https://c8.patreon.com/2/200/12059069" alt="naga_rus" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/12913507/f7181eacafe8469a93033d85f5969c29/3?token-time=2145916800&token-hash=c8HeVqLtmdgH-gSBJg8i10gmOcwllM87MDHeznl3el0%3D" alt="Melilot" width="100"></td>
|
||||
<td><img src="https://c8.patreon.com/2/200/16869916" alt="見当かなみ" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/12999811/5f349fafcce44dd1824a8b1ebbec4564/3?token-time=2145916800&token-hash=LtV2lRi3L2jOWMLwccr9qWYfPrFlzIo2jYZHKzHEb6k%3D" alt="Xeltica" width="100"></td>
|
||||
@@ -102,7 +102,7 @@ Please see the [Contribution Guide](./CONTRIBUTING.md).
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/12021162/963128bb8d14476dbd8407943db8f31a/1?token-time=2145916800&token-hash=1FlxS9MEgmNGH_RHUVHbO5hIXB5I1z0lvA33CTvYvjA%3D" alt="gutfuckllc" width="100"></td>
|
||||
</tr><tr>
|
||||
<td><a href="https://www.patreon.com/weepjp">weep</a></td>
|
||||
<td><a href="https://www.patreon.com/negao">negao</a></td>
|
||||
<td><a href="https://www.patreon.com/user?u=12059069">naga_rus</a></td>
|
||||
<td><a href="https://www.patreon.com/user?u=12913507">Melilot</a></td>
|
||||
<td><a href="https://www.patreon.com/user?u=16869916">見当かなみ</a></td>
|
||||
<td><a href="https://www.patreon.com/Xeltica">Xeltica</a></td>
|
||||
@@ -115,6 +115,7 @@ Please see the [Contribution Guide](./CONTRIBUTING.md).
|
||||
<td><img src="https://c8.patreon.com/2/200/16542964" alt="Takumi Sugita" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/13039004/509d0c412eb14ae08d6a812a3054f7d6/1?token-time=2145916800&token-hash=2PsbFNw0tnubZzgSXD01R6hIgncfiElG7H7HX2Y3dyo%3D" alt="nemu" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/5881381/6235ca5d3fb04c8e95ef5b4ff2abcc18/3?token-time=2145916800&token-hash=9JtETp0X8gI280Ne1E8bxn6j4Lw5o2k4mJkICx97V_k%3D" alt="YUKIMOCHI" width="100"></td>
|
||||
<td><img src="https://c8.patreon.com/2/200/17463605" alt="Sampot" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/17195955/be45e5e14c3e48b2bee0456c84e19df4/4?token-time=2145916800&token-hash=SbdZeN5SmsuT9stD6v0jN1z0hftg0FmRiCTxysU0Ihw%3D" alt="Damillora" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/8241184/39e18850e87a449e9c9a71acb3310ebd/3?token-time=2145916800&token-hash=gMq30aylxu5v3G8pRhWR5jeRBbYWEoRKjGbNeiCQz5g%3D" alt="Acid Chicken" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/4389829/9f709180ac714651a70f74a82f3ffdb9/2?token-time=2145916800&token-hash=zcwFxb2zopzWwksKVU1YpfAEjsl4yKT02aQ6yiAFRiQ%3D" alt="natalie" width="100"></td>
|
||||
@@ -125,6 +126,7 @@ Please see the [Contribution Guide](./CONTRIBUTING.md).
|
||||
<td><a href="https://www.patreon.com/user?u=16542964">Takumi Sugita</a></td>
|
||||
<td><a href="https://www.patreon.com/user?u=13039004">nemu</a></td>
|
||||
<td><a href="https://www.patreon.com/yukimochi">YUKIMOCHI</a></td>
|
||||
<td><a href="https://www.patreon.com/user?u=17463605">Sampot</a></td>
|
||||
<td><a href="https://www.patreon.com/damillora">Damillora</a></td>
|
||||
<td><a href="https://www.patreon.com/acid_chicken">Acid Chicken</a></td>
|
||||
<td><a href="https://www.patreon.com/user?u=4389829">natalie</a></td>
|
||||
@@ -142,7 +144,7 @@ Please see the [Contribution Guide](./CONTRIBUTING.md).
|
||||
<td><a href="https://www.patreon.com/user?u=12531784">Takashi Shibuya</a></td>
|
||||
</tr></table>
|
||||
|
||||
**Last updated:** Wed, 06 Feb 2019 18:18:05 UTC
|
||||
**Last updated:** Fri, 15 Feb 2019 19:12:06 UTC
|
||||
<!-- PATREON_END -->
|
||||
|
||||
:four_leaf_clover: Copyright
|
||||
|
||||
@@ -122,6 +122,8 @@ CentOSで1024以下のポートを使用してMisskeyを使用する場合は`Ex
|
||||
4. `npm run build`
|
||||
5. [ChangeLog](../CHANGELOG.md)でマイグレーション情報を確認する
|
||||
|
||||
なにか問題が発生した場合は、`npm run clean`すると直る場合があります。
|
||||
|
||||
----------------------------------------------------------------
|
||||
|
||||
なにかお困りのことがありましたらお気軽にご連絡ください。
|
||||
|
||||
@@ -1186,6 +1186,7 @@ admin/views/users.vue:
|
||||
moderator: "モデレーター"
|
||||
adminOrModerator: "管理者+モデレーター"
|
||||
verified: "公式アカウント"
|
||||
silenced: "サイレンス済み"
|
||||
suspended: "凍結済み"
|
||||
origin:
|
||||
title: "オリジン"
|
||||
@@ -1590,13 +1591,13 @@ mobile/views/pages/user/home.vue:
|
||||
activity: "アクティビティ"
|
||||
keywords: "キーワード"
|
||||
domains: "頻出ドメイン"
|
||||
frequently-replied-users: "よく会話するユーザー"
|
||||
frequently-replied-users: "よく話すユーザー"
|
||||
followers-you-know: "知り合いのフォロワー"
|
||||
last-used-at: "最終ログイン"
|
||||
mobile/views/pages/user/home.followers-you-know.vue:
|
||||
no-users: "知り合いのユーザーはいません"
|
||||
mobile/views/pages/user/home.friends.vue:
|
||||
no-users: "よく会話するユーザーはいません"
|
||||
no-users: "よく話すユーザーはいません"
|
||||
mobile/views/pages/user/home.notes.vue:
|
||||
no-notes: "投稿はありません"
|
||||
mobile/views/pages/user/home.photos.vue:
|
||||
@@ -1626,6 +1627,7 @@ deck/deck.tl-column.vue:
|
||||
is-media-view: "メディアビュー"
|
||||
edit: "オプション"
|
||||
deck/deck.user-column.vue:
|
||||
follows-you: "フォローされています"
|
||||
posts: "投稿"
|
||||
following: "フォロー"
|
||||
followers: "フォロワー"
|
||||
|
||||
@@ -1186,6 +1186,7 @@ admin/views/users.vue:
|
||||
moderator: "モデレーター"
|
||||
adminOrModerator: "管理者+モデレーター"
|
||||
verified: "公式アカウント"
|
||||
silenced: "サイレンス済み"
|
||||
suspended: "凍結済み"
|
||||
origin:
|
||||
title: "オリジン"
|
||||
@@ -1590,13 +1591,13 @@ mobile/views/pages/user/home.vue:
|
||||
activity: "アクティビティ"
|
||||
keywords: "Schlagwörter"
|
||||
domains: "頻出ドメイン"
|
||||
frequently-replied-users: "よく会話するユーザー"
|
||||
frequently-replied-users: "よく話すユーザー"
|
||||
followers-you-know: "知り合いのフォロワー"
|
||||
last-used-at: "最終ログイン"
|
||||
mobile/views/pages/user/home.followers-you-know.vue:
|
||||
no-users: "知り合いのユーザーはいません"
|
||||
mobile/views/pages/user/home.friends.vue:
|
||||
no-users: "よく会話するユーザーはいません"
|
||||
no-users: "よく話すユーザーはいません"
|
||||
mobile/views/pages/user/home.notes.vue:
|
||||
no-notes: "投稿はありません"
|
||||
mobile/views/pages/user/home.photos.vue:
|
||||
@@ -1626,6 +1627,7 @@ deck/deck.tl-column.vue:
|
||||
is-media-view: "メディアビュー"
|
||||
edit: "オプション"
|
||||
deck/deck.user-column.vue:
|
||||
follows-you: "フォローされています"
|
||||
posts: "投稿"
|
||||
following: "フォロー"
|
||||
followers: "フォロワー"
|
||||
|
||||
@@ -1118,7 +1118,7 @@ admin/views/charts.vue:
|
||||
users: "The number of users: increase/decrease"
|
||||
users-total: "Total users"
|
||||
active-users: "Active users"
|
||||
drive: "Capacity used as the storage: increase/decrease"
|
||||
drive: "Increase and decrease in storage capacity use"
|
||||
drive-total: "Total usage of Drive"
|
||||
drive-files: "The number of files on the storage: increase/decrease"
|
||||
drive-files-total: "Total number of files on Drive"
|
||||
@@ -1186,6 +1186,7 @@ admin/views/users.vue:
|
||||
moderator: "Moderator"
|
||||
adminOrModerator: "Admin/Moderator"
|
||||
verified: "Verified account"
|
||||
silenced: "Already silenced"
|
||||
suspended: "Suspended"
|
||||
origin:
|
||||
title: "Origin"
|
||||
@@ -1244,7 +1245,7 @@ admin/views/federation.vue:
|
||||
latest-request-sent-at: "Time of last request sent"
|
||||
latest-request-received-at: "Last request received at"
|
||||
remove-all-following: "Withold all followers"
|
||||
remove-all-following-info: "{host}からのフォローをすべて解除します。そのインスタンスがもう存在しなくなった場合などに実行してください。"
|
||||
remove-all-following-info: "Unfollow all accounts from {host}. Please run this if the instance no longer exists."
|
||||
block: "Block"
|
||||
marked-as-closed: "Marked as closed"
|
||||
lookup: "Look up"
|
||||
@@ -1254,8 +1255,8 @@ admin/views/federation.vue:
|
||||
sorts:
|
||||
caughtAtAsc: "Date of discovery (Ascending)"
|
||||
caughtAtDesc: "Date of discovery (Descending)"
|
||||
lastCommunicatedAtAsc: "最後にやり取りした日時が古い順"
|
||||
lastCommunicatedAtDesc: "最後にやり取りした日時が新しい順"
|
||||
lastCommunicatedAtAsc: "The date and time of the older interactions"
|
||||
lastCommunicatedAtDesc: "The date and time of the newer interactions"
|
||||
notesAsc: "Order by least Notes posted"
|
||||
notesDesc: "Order by most Notes posted"
|
||||
usersAsc: "Less followers"
|
||||
@@ -1264,10 +1265,10 @@ admin/views/federation.vue:
|
||||
followingDesc: "Has more followers"
|
||||
followersAsc: "Sort by having less followers"
|
||||
followersDesc: "Sort by the larger number of followers"
|
||||
driveUsageAsc: "ドライブ使用量が少ない順"
|
||||
driveUsageDesc: "ドライブ使用量が多い順"
|
||||
driveFilesAsc: "ドライブのファイル数が少ない順"
|
||||
driveFilesDesc: "ドライブのファイル数が多い順"
|
||||
driveUsageAsc: "Least storage used"
|
||||
driveUsageDesc: "Most storage used"
|
||||
driveFilesAsc: "By the smallest number of files stored on Drive"
|
||||
driveFilesDesc: "By the largest number of files stored on Drive"
|
||||
state: "Status"
|
||||
states:
|
||||
all: "All"
|
||||
@@ -1282,12 +1283,12 @@ admin/views/federation.vue:
|
||||
users-total: "Total number of users"
|
||||
notes: "Increase, or decrease in the number of notes"
|
||||
notes-total: "Total number of notes"
|
||||
ff: "フォロー/フォロワーの増減"
|
||||
ff-total: "フォロー/フォロワーの積算"
|
||||
drive-usage: "ドライブ使用量の増減"
|
||||
drive-usage-total: "ドライブ使用量の積算"
|
||||
drive-files: "ドライブファイル数の増減"
|
||||
drive-files-total: "ドライブファイル数の積算"
|
||||
ff: "Increase of followers"
|
||||
ff-total: "Total number of follows accumulated"
|
||||
drive-usage: "Increase and decrease in storage use"
|
||||
drive-usage-total: "Total usage of the Drive"
|
||||
drive-files: "Increase, or decrease in the number of files stored on Drive"
|
||||
drive-files-total: "The number of files accumulated on Drive"
|
||||
chart-spans:
|
||||
hour: "Hourly"
|
||||
day: "Daily"
|
||||
@@ -1626,6 +1627,7 @@ deck/deck.tl-column.vue:
|
||||
is-media-view: "Media view"
|
||||
edit: "Options"
|
||||
deck/deck.user-column.vue:
|
||||
follows-you: "Follows you"
|
||||
posts: "Posts"
|
||||
following: "Following"
|
||||
followers: "Followers"
|
||||
|
||||
@@ -1186,6 +1186,7 @@ admin/views/users.vue:
|
||||
moderator: "モデレーター"
|
||||
adminOrModerator: "管理者+モデレーター"
|
||||
verified: "公式アカウント"
|
||||
silenced: "サイレンス済み"
|
||||
suspended: "凍結済み"
|
||||
origin:
|
||||
title: "オリジン"
|
||||
@@ -1590,13 +1591,13 @@ mobile/views/pages/user/home.vue:
|
||||
activity: "アクティビティ"
|
||||
keywords: "キーワード"
|
||||
domains: "頻出ドメイン"
|
||||
frequently-replied-users: "よく会話するユーザー"
|
||||
frequently-replied-users: "よく話すユーザー"
|
||||
followers-you-know: "知り合いのフォロワー"
|
||||
last-used-at: "最終ログイン"
|
||||
mobile/views/pages/user/home.followers-you-know.vue:
|
||||
no-users: "知り合いのユーザーはいません"
|
||||
mobile/views/pages/user/home.friends.vue:
|
||||
no-users: "よく会話するユーザーはいません"
|
||||
no-users: "よく話すユーザーはいません"
|
||||
mobile/views/pages/user/home.notes.vue:
|
||||
no-notes: "投稿はありません"
|
||||
mobile/views/pages/user/home.photos.vue:
|
||||
@@ -1626,6 +1627,7 @@ deck/deck.tl-column.vue:
|
||||
is-media-view: "メディアビュー"
|
||||
edit: "オプション"
|
||||
deck/deck.user-column.vue:
|
||||
follows-you: "フォローされています"
|
||||
posts: "投稿"
|
||||
following: "フォロー"
|
||||
followers: "フォロワー"
|
||||
|
||||
@@ -1186,6 +1186,7 @@ admin/views/users.vue:
|
||||
moderator: "Modérateur"
|
||||
adminOrModerator: "Administrateur/Modérateur"
|
||||
verified: "Compte vérifié"
|
||||
silenced: "サイレンス済み"
|
||||
suspended: "Suspendu"
|
||||
origin:
|
||||
title: "Origine"
|
||||
@@ -1626,6 +1627,7 @@ deck/deck.tl-column.vue:
|
||||
is-media-view: "Vue média"
|
||||
edit: "Option"
|
||||
deck/deck.user-column.vue:
|
||||
follows-you: "フォローされています"
|
||||
posts: "Notes"
|
||||
following: "Suit"
|
||||
followers: "Abonnés"
|
||||
|
||||
6
locales/index.d.ts
vendored
6
locales/index.d.ts
vendored
@@ -1,5 +1,3 @@
|
||||
type Locale = { [key: string]: string };
|
||||
declare const locales: { [lang: string]: any };
|
||||
|
||||
declare const locales: { [lang: string]: Locale };
|
||||
|
||||
export default locales;
|
||||
export = locales;
|
||||
|
||||
@@ -1186,6 +1186,7 @@ admin/views/users.vue:
|
||||
moderator: "モデレーター"
|
||||
adminOrModerator: "管理者+モデレーター"
|
||||
verified: "公式アカウント"
|
||||
silenced: "サイレンス済み"
|
||||
suspended: "凍結済み"
|
||||
origin:
|
||||
title: "オリジン"
|
||||
@@ -1590,13 +1591,13 @@ mobile/views/pages/user/home.vue:
|
||||
activity: "アクティビティ"
|
||||
keywords: "キーワード"
|
||||
domains: "頻出ドメイン"
|
||||
frequently-replied-users: "よく会話するユーザー"
|
||||
frequently-replied-users: "よく話すユーザー"
|
||||
followers-you-know: "知り合いのフォロワー"
|
||||
last-used-at: "最終ログイン"
|
||||
mobile/views/pages/user/home.followers-you-know.vue:
|
||||
no-users: "知り合いのユーザーはいません"
|
||||
mobile/views/pages/user/home.friends.vue:
|
||||
no-users: "よく会話するユーザーはいません"
|
||||
no-users: "よく話すユーザーはいません"
|
||||
mobile/views/pages/user/home.notes.vue:
|
||||
no-notes: "投稿はありません"
|
||||
mobile/views/pages/user/home.photos.vue:
|
||||
@@ -1626,6 +1627,7 @@ deck/deck.tl-column.vue:
|
||||
is-media-view: "メディアビュー"
|
||||
edit: "オプション"
|
||||
deck/deck.user-column.vue:
|
||||
follows-you: "フォローされています"
|
||||
posts: "投稿"
|
||||
following: "フォロー"
|
||||
followers: "フォロワー"
|
||||
|
||||
@@ -28,6 +28,8 @@ common:
|
||||
load-more: "もっと読み込む"
|
||||
enter-password: "パスワードを入力してください"
|
||||
2fa: "二段階認証"
|
||||
customize-home: "ホームをカスタマイズ"
|
||||
featured-notes: "ハイライト"
|
||||
|
||||
got-it: "わかった"
|
||||
customization-tips:
|
||||
@@ -58,6 +60,15 @@ common:
|
||||
trash: "ゴミ箱"
|
||||
drive: "ドライブ"
|
||||
messaging: "トーク"
|
||||
deck: "デッキ"
|
||||
timeline: "タイムライン"
|
||||
explore: "みつける"
|
||||
following: "フォロー中"
|
||||
followers: "フォロワー"
|
||||
|
||||
empty-timeline-info:
|
||||
follow-users-to-make-your-timeline: "ユーザーをフォローすると投稿がタイムラインに表示されます。"
|
||||
explore: "ユーザーを探索する"
|
||||
|
||||
weekday-short:
|
||||
sunday: "日"
|
||||
@@ -213,6 +224,19 @@ auth/views/index.vue:
|
||||
error: "セッションが存在しません。"
|
||||
sign-in: "サインインしてください"
|
||||
|
||||
common/views/pages/explore.vue:
|
||||
verified-users: "公式アカウント"
|
||||
popular-users: "人気のユーザー"
|
||||
recently-updated-users: "最近投稿したユーザー"
|
||||
recently-registered-users: "新規ユーザー"
|
||||
popular-tags: "人気のタグ"
|
||||
federated: "連合"
|
||||
explore: "{host}を探索"
|
||||
users-info: "現在{users}ユーザーが登録されています"
|
||||
|
||||
common/views/components/user-list.vue:
|
||||
no-users: "ユーザーがいません"
|
||||
|
||||
common/views/components/games/reversi/reversi.vue:
|
||||
matching:
|
||||
waiting-for: "{}を待っています"
|
||||
@@ -761,13 +785,6 @@ desktop/views/components/following-window.vue:
|
||||
desktop/views/components/following.vue:
|
||||
empty: "フォロー中のユーザーはいないようです。"
|
||||
|
||||
desktop/views/components/friends-maker.vue:
|
||||
title: "気になるユーザーをフォロー:"
|
||||
empty: "おすすめのユーザーは見つかりませんでした。"
|
||||
fetching: "読み込んでいます"
|
||||
refresh: "もっと見る"
|
||||
close: "閉じる"
|
||||
|
||||
desktop/views/components/game-window.vue:
|
||||
game: "リバーシ"
|
||||
|
||||
@@ -862,6 +879,9 @@ desktop/views/components/renote-form.vue:
|
||||
desktop/views/components/renote-form-window.vue:
|
||||
title: "この投稿をRenoteしますか?"
|
||||
|
||||
desktop/views/components/timeline.core.vue:
|
||||
empty: "投稿がありません"
|
||||
|
||||
desktop/views/pages/user-following-or-followers.vue:
|
||||
following: "{user}のフォロー"
|
||||
followers: "{user}のフォロワー"
|
||||
@@ -893,14 +913,10 @@ desktop/views/components/settings.vue:
|
||||
web-search-engine-desc: "例: https://www.google.com/?#q={{query}}"
|
||||
auto-popout: "ウィンドウの自動ポップアウト"
|
||||
auto-popout-desc: "ウィンドウが開かれるとき、ポップアウト(ブラウザ外に切り離す)可能なら自動でポップアウトします。この設定はブラウザに記憶されます。"
|
||||
deck-nav: "デッキ内ナビゲーション"
|
||||
deck-nav-desc: "デッキを使用しているとき、ナビゲーションが発生する際にページ遷移を行わずに一時的なカラムで受けるようにします。"
|
||||
keep-cw: "CW保持"
|
||||
keep-cw-desc: "投稿にリプライする際、リプライ元の投稿にCWが設定されていたとき、デフォルトで同じCWを設定するようにします。"
|
||||
deck-default: "デッキをデフォルトのUIにする"
|
||||
|
||||
display: "デザインと表示"
|
||||
customize: "ホームをカスタマイズ"
|
||||
wallpaper: "壁紙"
|
||||
choose-wallpaper: "壁紙を選択"
|
||||
delete-wallpaper: "壁紙を削除"
|
||||
@@ -1076,15 +1092,12 @@ desktop/views/components/ui.header.account.vue:
|
||||
favorites: "お気に入り"
|
||||
lists: "リスト"
|
||||
follow-requests: "フォロー申請"
|
||||
customize: "ホームのカスタマイズ"
|
||||
admin: "管理"
|
||||
settings: "設定"
|
||||
signout: "サインアウト"
|
||||
dark: "闇に飲まれる"
|
||||
|
||||
desktop/views/components/ui.header.nav.vue:
|
||||
home: "ホーム"
|
||||
deck: "デッキ"
|
||||
game: "ゲーム"
|
||||
|
||||
desktop/views/components/ui.header.notifications.vue:
|
||||
@@ -1319,6 +1332,7 @@ admin/views/users.vue:
|
||||
moderator: "モデレーター"
|
||||
adminOrModerator: "管理者+モデレーター"
|
||||
verified: "公式アカウント"
|
||||
silenced: "サイレンス済み"
|
||||
suspended: "凍結済み"
|
||||
origin:
|
||||
title: "オリジン"
|
||||
@@ -1446,9 +1460,6 @@ desktop/views/pages/welcome.vue:
|
||||
desktop/views/pages/drive.vue:
|
||||
title: "Misskey Drive"
|
||||
|
||||
desktop/views/pages/home-customize.vue:
|
||||
title: "ホームのカスタマイズ"
|
||||
|
||||
desktop/views/pages/note.vue:
|
||||
prev: "前の投稿"
|
||||
next: "次の投稿"
|
||||
@@ -1489,10 +1500,6 @@ desktop/views/pages/user/user.photos.vue:
|
||||
loading: "読み込み中"
|
||||
no-photos: "写真はありません"
|
||||
|
||||
desktop/views/pages/user/user.profile.vue:
|
||||
follows-you: "フォローされています"
|
||||
menu: "メニュー"
|
||||
|
||||
desktop/views/pages/user/user.header.vue:
|
||||
posts: "投稿"
|
||||
following: "フォロー"
|
||||
@@ -1502,6 +1509,7 @@ desktop/views/pages/user/user.header.vue:
|
||||
year: "年"
|
||||
month: "月"
|
||||
day: "日"
|
||||
follows-you: "フォローされています"
|
||||
|
||||
desktop/views/pages/user/user.timeline.vue:
|
||||
default: "投稿"
|
||||
@@ -1585,13 +1593,6 @@ common/views/components/follow-button.vue:
|
||||
follow-processing: "フォロー処理中"
|
||||
follow-request: "フォロー申請"
|
||||
|
||||
mobile/views/components/friends-maker.vue:
|
||||
title: "気になるユーザーをフォロー"
|
||||
empty: "おすすめのユーザーは見つかりませんでした。"
|
||||
fetching: "読み込んでいます"
|
||||
refresh: "もっと見る"
|
||||
close: "閉じる"
|
||||
|
||||
mobile/views/components/note.vue:
|
||||
private: "この投稿は非公開です"
|
||||
deleted: "この投稿は削除されました"
|
||||
@@ -1660,10 +1661,6 @@ mobile/views/components/user-timeline.vue:
|
||||
no-notes: "このユーザーは投稿していないようです。"
|
||||
no-notes-with-media: "メディア付き投稿はありません。"
|
||||
|
||||
mobile/views/components/users-list.vue:
|
||||
all: "すべて"
|
||||
known: "知り合い"
|
||||
|
||||
mobile/views/pages/favorites.vue:
|
||||
title: "お気に入り"
|
||||
|
||||
@@ -1688,6 +1685,9 @@ mobile/views/pages/home.vue:
|
||||
mentions: "あなた宛て"
|
||||
messages: "メッセージ"
|
||||
|
||||
mobile/views/pages/home.timeline.vue:
|
||||
empty: "投稿がありません"
|
||||
|
||||
mobile/views/pages/tag.vue:
|
||||
no-posts-found: "ハッシュタグ「{q}」が付けられた投稿は見つかりませんでした。"
|
||||
|
||||
@@ -1790,7 +1790,7 @@ mobile/views/pages/user/home.vue:
|
||||
activity: "アクティビティ"
|
||||
keywords: "キーワード"
|
||||
domains: "頻出ドメイン"
|
||||
frequently-replied-users: "よく会話するユーザー"
|
||||
frequently-replied-users: "よく話すユーザー"
|
||||
followers-you-know: "知り合いのフォロワー"
|
||||
last-used-at: "最終ログイン"
|
||||
|
||||
@@ -1798,7 +1798,7 @@ mobile/views/pages/user/home.followers-you-know.vue:
|
||||
no-users: "知り合いのユーザーはいません"
|
||||
|
||||
mobile/views/pages/user/home.friends.vue:
|
||||
no-users: "よく会話するユーザーはいません"
|
||||
no-users: "よく話すユーザーはいません"
|
||||
|
||||
mobile/views/pages/user/home.notes.vue:
|
||||
no-notes: "投稿はありません"
|
||||
@@ -1826,6 +1826,9 @@ deck:
|
||||
rename: "名前を変更"
|
||||
stack-left: "左に重ねる"
|
||||
pop-right: "右に出す"
|
||||
disabled-timeline:
|
||||
title: "無効化されたタイムライン"
|
||||
description: "サーバーの運営者により、このタイムラインは使用できない状態に設定されています。"
|
||||
|
||||
deck/deck.tl-column.vue:
|
||||
is-media-only: "メディア投稿のみ"
|
||||
@@ -1833,6 +1836,7 @@ deck/deck.tl-column.vue:
|
||||
edit: "オプション"
|
||||
|
||||
deck/deck.user-column.vue:
|
||||
follows-you: "フォローされています"
|
||||
posts: "投稿"
|
||||
following: "フォロー"
|
||||
followers: "フォロワー"
|
||||
|
||||
@@ -1186,6 +1186,7 @@ admin/views/users.vue:
|
||||
moderator: "モデレーター"
|
||||
adminOrModerator: "管理者+モデレーター"
|
||||
verified: "公式アカウント"
|
||||
silenced: "サイレンス済み"
|
||||
suspended: "凍結済み"
|
||||
origin:
|
||||
title: "オリジン"
|
||||
@@ -1626,6 +1627,7 @@ deck/deck.tl-column.vue:
|
||||
is-media-view: "メディアビュー"
|
||||
edit: "オプション"
|
||||
deck/deck.user-column.vue:
|
||||
follows-you: "フォローされています"
|
||||
posts: "投稿"
|
||||
following: "フォロー"
|
||||
followers: "フォロワー"
|
||||
|
||||
@@ -113,7 +113,7 @@ common:
|
||||
use-avatar-reversi-stones: "리버시의 돌로 아바타를 사용"
|
||||
verified-user: "공식 계정"
|
||||
disable-animated-mfm: "글의 문자 애니메이션을 비활성화"
|
||||
disable-showing-animated-images: "アニメーション画像を再生しない"
|
||||
disable-showing-animated-images: "움직이는 이미지를 자동으로 재생하지 않음"
|
||||
suggest-recent-hashtags: "최근 해시태그를 글 작성란에 표시"
|
||||
always-show-nsfw: "항상 열람주의 미디어를 표시"
|
||||
always-mark-nsfw: "항상 미디어를 열람주의로 설정하여 게시"
|
||||
@@ -345,8 +345,8 @@ common/views/components/note-menu.vue:
|
||||
copy-link: "링크 복사"
|
||||
favorite: "이 노트 즐겨찾기"
|
||||
unfavorite: "즐겨찾기에서 제거"
|
||||
watch: "ウォッチ"
|
||||
unwatch: "ウォッチ解除"
|
||||
watch: "지켜보기"
|
||||
unwatch: "지켜보기 해제"
|
||||
pin: "프로필에 고정"
|
||||
unpin: "프로필에서 고정 해제"
|
||||
delete: "삭제"
|
||||
@@ -509,13 +509,13 @@ common/views/components/profile-editor.vue:
|
||||
email-address: "메일 주소"
|
||||
email-verified: "매일 주소가 확인되었습니다"
|
||||
email-not-verified: "메일 주소가 확인되지 않았습니다. 받은 편지함을 확인하여 주시기 바랍니다."
|
||||
export: "エクスポート"
|
||||
export: "내보내기"
|
||||
export-targets:
|
||||
all-notes: "すべての投稿データ"
|
||||
following-list: "フォロー"
|
||||
mute-list: "ミュート"
|
||||
blocking-list: "ブロック"
|
||||
export-requested: "エクスポートをリクエストしました。これには時間がかかる場合があります。エクスポートが終わると、ドライブにファイルが追加されます。"
|
||||
all-notes: "모든 글 데이터"
|
||||
following-list: "팔로잉"
|
||||
mute-list: "뮤트"
|
||||
blocking-list: "차단"
|
||||
export-requested: "내보내기를 요청하였습니다. 이 작업은 시간이 걸릴 수 있습니다. 내보내기가 완료되면 드라이브에 파일이 추가됩니다."
|
||||
common/views/components/user-list-editor.vue:
|
||||
users: "사용자"
|
||||
rename: "리스트 이름 바꾸기"
|
||||
@@ -1007,7 +1007,7 @@ admin/views/index.vue:
|
||||
announcements: "공지사항"
|
||||
hashtags: "해시태그"
|
||||
abuse: "스팸 신고"
|
||||
queue: "ジョブキュー"
|
||||
queue: "작업 대기열"
|
||||
back-to-misskey: "Misskey로 돌아가기"
|
||||
admin/views/dashboard.vue:
|
||||
dashboard: "대시보드"
|
||||
@@ -1018,8 +1018,8 @@ admin/views/dashboard.vue:
|
||||
this-instance: "이 인스턴스"
|
||||
federated: "연합"
|
||||
admin/views/queue.vue:
|
||||
operation: "操作"
|
||||
remove-all-jobs: "すべてのジョブをクリア"
|
||||
operation: "동작"
|
||||
remove-all-jobs: "모든 작업 제거"
|
||||
admin/views/abuse.vue:
|
||||
title: "스팸 신고"
|
||||
target: "대상"
|
||||
@@ -1114,7 +1114,7 @@ admin/views/charts.vue:
|
||||
notes: "글 증감 (통합)"
|
||||
local-notes: "글 증감 (로컬)"
|
||||
remote-notes: "글 증감 (원격)"
|
||||
notes-total: "글 누적 수"
|
||||
notes-total: "글 누적"
|
||||
users: "사용자 증감"
|
||||
users-total: "사용자 누적"
|
||||
active-users: "활성 사용자 수"
|
||||
@@ -1186,6 +1186,7 @@ admin/views/users.vue:
|
||||
moderator: "모더레이터"
|
||||
adminOrModerator: "관리자+모더레이터"
|
||||
verified: "공식 계정"
|
||||
silenced: "침묵됨"
|
||||
suspended: "정지됨"
|
||||
origin:
|
||||
title: "위치 (오리진)"
|
||||
@@ -1234,63 +1235,63 @@ admin/views/announcements.vue:
|
||||
admin/views/hashtags.vue:
|
||||
hided-tags: "Hidden Tags"
|
||||
admin/views/federation.vue:
|
||||
federation: "連合"
|
||||
host: "ホスト"
|
||||
notes: "投稿"
|
||||
users: "ユーザー"
|
||||
following: "フォロー中"
|
||||
followers: "フォロワー"
|
||||
status: "ステータス"
|
||||
latest-request-sent-at: "直近のリクエスト送信"
|
||||
latest-request-received-at: "直近のリクエスト受信"
|
||||
remove-all-following: "フォローを全解除"
|
||||
remove-all-following-info: "{host}からのフォローをすべて解除します。そのインスタンスがもう存在しなくなった場合などに実行してください。"
|
||||
block: "ブロック"
|
||||
marked-as-closed: "閉鎖されているとマーク"
|
||||
lookup: "照会"
|
||||
instances: "インスタンス"
|
||||
instance-not-registered: "そのインスタンスは登録されていません"
|
||||
sort: "ソート"
|
||||
federation: "연합"
|
||||
host: "호스트"
|
||||
notes: "글"
|
||||
users: "사용자"
|
||||
following: "팔로우 중"
|
||||
followers: "팔로워"
|
||||
status: "상태"
|
||||
latest-request-sent-at: "마지막으로 요청을 전송한 시간"
|
||||
latest-request-received-at: "마지막으로 요청을 받은 시간"
|
||||
remove-all-following: "모든 팔로잉 해제"
|
||||
remove-all-following-info: "{host}(으)로부터 모든 팔로잉을 해제합니다. 해당 인스턴스가 더 이상 존재하지 않게 된 경우 등에 실행하십시오."
|
||||
block: "차단"
|
||||
marked-as-closed: "폐쇄된 것으로 표시"
|
||||
lookup: "조회"
|
||||
instances: "인스턴스"
|
||||
instance-not-registered: "해당 인스턴스가 등록되어 있지 않습니다"
|
||||
sort: "정렬"
|
||||
sorts:
|
||||
caughtAtAsc: "登録日時が古い順"
|
||||
caughtAtDesc: "登録日時が新しい順"
|
||||
lastCommunicatedAtAsc: "最後にやり取りした日時が古い順"
|
||||
lastCommunicatedAtDesc: "最後にやり取りした日時が新しい順"
|
||||
notesAsc: "投稿が少ない順"
|
||||
notesDesc: "投稿が多い順"
|
||||
usersAsc: "ユーザーが少ない順"
|
||||
usersDesc: "ユーザーが多い順"
|
||||
followingAsc: "フォローが少ない順"
|
||||
followingDesc: "フォローが多い順"
|
||||
followersAsc: "フォロワーが少ない順"
|
||||
followersDesc: "フォロワーが多い順"
|
||||
driveUsageAsc: "ドライブ使用量が少ない順"
|
||||
driveUsageDesc: "ドライブ使用量が多い順"
|
||||
driveFilesAsc: "ドライブのファイル数が少ない順"
|
||||
driveFilesDesc: "ドライブのファイル数が多い順"
|
||||
state: "状態"
|
||||
caughtAtAsc: "등록일이 오래된 순"
|
||||
caughtAtDesc: "등록일이 최신인 순"
|
||||
lastCommunicatedAtAsc: "마지막으로 요청을 주고받은 일시가 오래된 순"
|
||||
lastCommunicatedAtDesc: "마지막으로 요청을 주고받은 일시가 빠른 순"
|
||||
notesAsc: "글이 적은 순"
|
||||
notesDesc: "글이 많은 순"
|
||||
usersAsc: "사용자가 적은 순"
|
||||
usersDesc: "사용자가 많은 순"
|
||||
followingAsc: "팔로잉이 적은 순"
|
||||
followingDesc: "팔로잉이 많은 순"
|
||||
followersAsc: "팔로워가 적은 순"
|
||||
followersDesc: "팔로워가 많은 순"
|
||||
driveUsageAsc: "드라이브 사용량이 적은 순"
|
||||
driveUsageDesc: "드라이브 사용량이 많은 순"
|
||||
driveFilesAsc: "드라이브 파일 수가 적은 순"
|
||||
driveFilesDesc: "드라이브 파일 수가 많은 순"
|
||||
state: "상태"
|
||||
states:
|
||||
all: "すべて"
|
||||
blocked: "ブロック"
|
||||
not-responding: "応答なし"
|
||||
marked-as-closed: "閉鎖とマーク済み"
|
||||
result-is-truncated: "上位{n}件を表示しています。"
|
||||
charts: "チャート"
|
||||
all: "모두"
|
||||
blocked: "차단됨"
|
||||
not-responding: "응답 없음"
|
||||
marked-as-closed: "폐쇄된 것으로 표시됨"
|
||||
result-is-truncated: "상위 {n}개를 표시하고 있습니다."
|
||||
charts: "차트"
|
||||
chart-srcs:
|
||||
requests: "リクエスト"
|
||||
users: "ユーザーの増減"
|
||||
users-total: "ユーザーの積算"
|
||||
notes: "投稿の増減"
|
||||
notes-total: "投稿の積算"
|
||||
ff: "フォロー/フォロワーの増減"
|
||||
ff-total: "フォロー/フォロワーの積算"
|
||||
drive-usage: "ドライブ使用量の増減"
|
||||
drive-usage-total: "ドライブ使用量の積算"
|
||||
drive-files: "ドライブファイル数の増減"
|
||||
drive-files-total: "ドライブファイル数の積算"
|
||||
requests: "요청"
|
||||
users: "사용자 증감"
|
||||
users-total: "사용자 누적"
|
||||
notes: "글 증감"
|
||||
notes-total: "글 누적"
|
||||
ff: "팔로잉/팔로워 증감"
|
||||
ff-total: "팔로잉/팔로워 누적"
|
||||
drive-usage: "드라이브 사용량 증감"
|
||||
drive-usage-total: "드라이브 사용량 누적"
|
||||
drive-files: "드라이브 파일 수 증감"
|
||||
drive-files-total: "드라이브 파일 수 누적"
|
||||
chart-spans:
|
||||
hour: "1時間ごと"
|
||||
day: "1日ごと"
|
||||
hour: "1시간마다"
|
||||
day: "1일마다"
|
||||
desktop/views/pages/welcome.vue:
|
||||
about: "자세히..."
|
||||
gotit: "알겠습니다"
|
||||
@@ -1626,6 +1627,7 @@ deck/deck.tl-column.vue:
|
||||
is-media-view: "미디어 보기"
|
||||
edit: "옵션"
|
||||
deck/deck.user-column.vue:
|
||||
follows-you: "당신을 팔로우합니다"
|
||||
posts: "글"
|
||||
following: "팔로잉"
|
||||
followers: "팔로워"
|
||||
|
||||
@@ -1186,6 +1186,7 @@ admin/views/users.vue:
|
||||
moderator: "モデレーター"
|
||||
adminOrModerator: "管理者+モデレーター"
|
||||
verified: "公式アカウント"
|
||||
silenced: "サイレンス済み"
|
||||
suspended: "凍結済み"
|
||||
origin:
|
||||
title: "オリジン"
|
||||
@@ -1626,6 +1627,7 @@ deck/deck.tl-column.vue:
|
||||
is-media-view: "メディアビュー"
|
||||
edit: "オプション"
|
||||
deck/deck.user-column.vue:
|
||||
follows-you: "フォローされています"
|
||||
posts: "投稿"
|
||||
following: "フォロー"
|
||||
followers: "フォロワー"
|
||||
|
||||
@@ -1186,6 +1186,7 @@ admin/views/users.vue:
|
||||
moderator: "モデレーター"
|
||||
adminOrModerator: "管理者+モデレーター"
|
||||
verified: "公式アカウント"
|
||||
silenced: "サイレンス済み"
|
||||
suspended: "凍結済み"
|
||||
origin:
|
||||
title: "オリジン"
|
||||
@@ -1590,13 +1591,13 @@ mobile/views/pages/user/home.vue:
|
||||
activity: "アクティビティ"
|
||||
keywords: "Nøkkelord"
|
||||
domains: "頻出ドメイン"
|
||||
frequently-replied-users: "よく会話するユーザー"
|
||||
frequently-replied-users: "よく話すユーザー"
|
||||
followers-you-know: "知り合いのフォロワー"
|
||||
last-used-at: "最終ログイン"
|
||||
mobile/views/pages/user/home.followers-you-know.vue:
|
||||
no-users: "知り合いのユーザーはいません"
|
||||
mobile/views/pages/user/home.friends.vue:
|
||||
no-users: "よく会話するユーザーはいません"
|
||||
no-users: "よく話すユーザーはいません"
|
||||
mobile/views/pages/user/home.notes.vue:
|
||||
no-notes: "投稿はありません"
|
||||
mobile/views/pages/user/home.photos.vue:
|
||||
@@ -1626,6 +1627,7 @@ deck/deck.tl-column.vue:
|
||||
is-media-view: "メディアビュー"
|
||||
edit: "オプション"
|
||||
deck/deck.user-column.vue:
|
||||
follows-you: "フォローされています"
|
||||
posts: "投稿"
|
||||
following: "フォロー"
|
||||
followers: "フォロワー"
|
||||
|
||||
@@ -1186,6 +1186,7 @@ admin/views/users.vue:
|
||||
moderator: "モデレーター"
|
||||
adminOrModerator: "管理者+モデレーター"
|
||||
verified: "公式アカウント"
|
||||
silenced: "サイレンス済み"
|
||||
suspended: "凍結済み"
|
||||
origin:
|
||||
title: "Źródło"
|
||||
@@ -1626,6 +1627,7 @@ deck/deck.tl-column.vue:
|
||||
is-media-view: "Widok multimediów"
|
||||
edit: "Opcje"
|
||||
deck/deck.user-column.vue:
|
||||
follows-you: "フォローされています"
|
||||
posts: "Wpisy"
|
||||
following: "Śledzeni"
|
||||
followers: "Śledzący"
|
||||
|
||||
@@ -1186,6 +1186,7 @@ admin/views/users.vue:
|
||||
moderator: "モデレーター"
|
||||
adminOrModerator: "管理者+モデレーター"
|
||||
verified: "公式アカウント"
|
||||
silenced: "サイレンス済み"
|
||||
suspended: "凍結済み"
|
||||
origin:
|
||||
title: "オリジン"
|
||||
@@ -1596,7 +1597,7 @@ mobile/views/pages/user/home.vue:
|
||||
mobile/views/pages/user/home.followers-you-know.vue:
|
||||
no-users: "知り合いのユーザーはいません"
|
||||
mobile/views/pages/user/home.friends.vue:
|
||||
no-users: "よく会話するユーザーはいません"
|
||||
no-users: "よく話すユーザーはいません"
|
||||
mobile/views/pages/user/home.notes.vue:
|
||||
no-notes: "Nenhuma mensagem"
|
||||
mobile/views/pages/user/home.photos.vue:
|
||||
@@ -1626,6 +1627,7 @@ deck/deck.tl-column.vue:
|
||||
is-media-view: "メディアビュー"
|
||||
edit: "オプション"
|
||||
deck/deck.user-column.vue:
|
||||
follows-you: "フォローされています"
|
||||
posts: "投稿"
|
||||
following: "フォロー"
|
||||
followers: "フォロワー"
|
||||
|
||||
@@ -1186,6 +1186,7 @@ admin/views/users.vue:
|
||||
moderator: "モデレーター"
|
||||
adminOrModerator: "管理者+モデレーター"
|
||||
verified: "公式アカウント"
|
||||
silenced: "サイレンス済み"
|
||||
suspended: "凍結済み"
|
||||
origin:
|
||||
title: "オリジン"
|
||||
@@ -1590,13 +1591,13 @@ mobile/views/pages/user/home.vue:
|
||||
activity: "アクティビティ"
|
||||
keywords: "キーワード"
|
||||
domains: "頻出ドメイン"
|
||||
frequently-replied-users: "よく会話するユーザー"
|
||||
frequently-replied-users: "よく話すユーザー"
|
||||
followers-you-know: "知り合いのフォロワー"
|
||||
last-used-at: "最終ログイン"
|
||||
mobile/views/pages/user/home.followers-you-know.vue:
|
||||
no-users: "知り合いのユーザーはいません"
|
||||
mobile/views/pages/user/home.friends.vue:
|
||||
no-users: "よく会話するユーザーはいません"
|
||||
no-users: "よく話すユーザーはいません"
|
||||
mobile/views/pages/user/home.notes.vue:
|
||||
no-notes: "投稿はありません"
|
||||
mobile/views/pages/user/home.photos.vue:
|
||||
@@ -1626,6 +1627,7 @@ deck/deck.tl-column.vue:
|
||||
is-media-view: "メディアビュー"
|
||||
edit: "オプション"
|
||||
deck/deck.user-column.vue:
|
||||
follows-you: "フォローされています"
|
||||
posts: "投稿"
|
||||
following: "フォロー"
|
||||
followers: "フォロワー"
|
||||
|
||||
@@ -1186,6 +1186,7 @@ admin/views/users.vue:
|
||||
moderator: "版主"
|
||||
adminOrModerator: "管理员+版主"
|
||||
verified: "官方认证账户"
|
||||
silenced: "已禁言"
|
||||
suspended: "已冻结"
|
||||
origin:
|
||||
title: "源自"
|
||||
@@ -1626,6 +1627,7 @@ deck/deck.tl-column.vue:
|
||||
is-media-view: "媒体视图"
|
||||
edit: "选项"
|
||||
deck/deck.user-column.vue:
|
||||
follows-you: "关注您"
|
||||
posts: "帖子"
|
||||
following: "关注中"
|
||||
followers: "关注者"
|
||||
|
||||
24
package.json
24
package.json
@@ -1,8 +1,7 @@
|
||||
{
|
||||
"name": "misskey",
|
||||
"author": "syuilo <i@syuilo.com>",
|
||||
"version": "10.84.0",
|
||||
"clientVersion": "2.0.14224",
|
||||
"version": "10.87.3",
|
||||
"codename": "nighthike",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -23,9 +22,6 @@
|
||||
"test": "gulp test",
|
||||
"format": "gulp format"
|
||||
},
|
||||
"resolutions": {
|
||||
"terser": "3.14.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-svg-core": "1.2.14",
|
||||
"@fortawesome/free-brands-svg-icons": "5.7.1",
|
||||
@@ -70,7 +66,7 @@
|
||||
"@types/mkdirp": "0.5.2",
|
||||
"@types/mocha": "5.2.5",
|
||||
"@types/mongodb": "3.1.19",
|
||||
"@types/node": "10.12.21",
|
||||
"@types/node": "10.12.24",
|
||||
"@types/nodemailer": "4.6.5",
|
||||
"@types/nprogress": "0.0.29",
|
||||
"@types/oauth": "0.9.1",
|
||||
@@ -86,7 +82,7 @@
|
||||
"@types/request-stats": "3.0.0",
|
||||
"@types/rimraf": "2.0.2",
|
||||
"@types/seedrandom": "2.4.27",
|
||||
"@types/sharp": "0.21.1",
|
||||
"@types/sharp": "0.21.2",
|
||||
"@types/showdown": "1.9.2",
|
||||
"@types/speakeasy": "2.0.3",
|
||||
"@types/systeminformation": "3.23.1",
|
||||
@@ -99,21 +95,21 @@
|
||||
"@types/websocket": "0.0.40",
|
||||
"@types/ws": "6.0.1",
|
||||
"animejs": "3.0.1",
|
||||
"apexcharts": "3.2.2",
|
||||
"apexcharts": "3.3.0",
|
||||
"autobind-decorator": "2.4.0",
|
||||
"autosize": "4.0.2",
|
||||
"autwh": "0.1.0",
|
||||
"bcryptjs": "2.4.3",
|
||||
"bee-queue": "1.2.2",
|
||||
"bootstrap-vue": "2.0.0-rc.11",
|
||||
"cafy": "12.1.0",
|
||||
"cafy": "14.0.1",
|
||||
"chai": "4.2.0",
|
||||
"chai-http": "4.2.1",
|
||||
"chalk": "2.4.2",
|
||||
"commander": "2.19.0",
|
||||
"crc-32": "1.2.0",
|
||||
"css-loader": "2.1.0",
|
||||
"cssnano": "4.1.8",
|
||||
"cssnano": "4.1.10",
|
||||
"dateformat": "3.0.3",
|
||||
"deep-equal": "1.0.1",
|
||||
"deepcopy": "0.6.3",
|
||||
@@ -144,7 +140,7 @@
|
||||
"hard-source-webpack-plugin": "0.13.1",
|
||||
"html-minifier": "3.5.21",
|
||||
"http-signature": "1.2.0",
|
||||
"insert-text-at-cursor": "0.1.1",
|
||||
"insert-text-at-cursor": "0.1.2",
|
||||
"is-root": "2.0.0",
|
||||
"is-svg": "3.0.0",
|
||||
"js-yaml": "3.12.1",
|
||||
@@ -232,11 +228,11 @@
|
||||
"uuid": "3.3.2",
|
||||
"v-animate-css": "0.0.3",
|
||||
"video-thumbnail-generator": "1.1.3",
|
||||
"vue": "2.6.4",
|
||||
"vue": "2.6.6",
|
||||
"vue-color": "2.7.0",
|
||||
"vue-content-loading": "1.5.3",
|
||||
"vue-cropperjs": "3.0.0",
|
||||
"vue-i18n": "8.8.0",
|
||||
"vue-i18n": "8.8.1",
|
||||
"vue-js-modal": "1.3.28",
|
||||
"vue-loader": "15.6.2",
|
||||
"vue-marquee-text-component": "1.1.1",
|
||||
@@ -245,7 +241,7 @@
|
||||
"vue-sequential-entrance": "1.1.3",
|
||||
"vue-style-loader": "4.1.2",
|
||||
"vue-svg-inline-loader": "1.2.10",
|
||||
"vue-template-compiler": "2.6.4",
|
||||
"vue-template-compiler": "2.6.6",
|
||||
"vuedraggable": "2.17.0",
|
||||
"vuewordcloud": "18.7.11",
|
||||
"vuex": "3.1.0",
|
||||
|
||||
@@ -5,9 +5,9 @@ program
|
||||
.version(pkg.version)
|
||||
.option('--no-daemons', 'Disable daemon processes (for debbuging)')
|
||||
.option('--disable-clustering', 'Disable clustering')
|
||||
.option('--disable-ap-queue', 'Disable creating job queue related to ap')
|
||||
.option('--disable-queue', 'Disable job queue processing')
|
||||
.option('--only-queue', 'Pocessing job queue only')
|
||||
.option('--only-server', 'Run server only (without job queue)')
|
||||
.option('--only-queue', 'Pocessing job queue only (without server)')
|
||||
.option('--quiet', 'Suppress all logs')
|
||||
.option('--verbose', 'Enable all logs')
|
||||
.option('--with-log-time', 'Include timestamp for each logs')
|
||||
@@ -15,8 +15,7 @@ program
|
||||
.option('--color', 'This option is a dummy for some external program\'s (e.g. forever) issue.')
|
||||
.parse(process.argv);
|
||||
|
||||
/*if (process.env.MK_DISABLE_AP_QUEUE)*/ program.disableApQueue = true;
|
||||
if (process.env.MK_DISABLE_QUEUE) program.disableQueue = true;
|
||||
/*if (process.env.MK_DISABLE_QUEUE)*/ program.disableQueue = true;
|
||||
if (process.env.MK_ONLY_QUEUE) program.onlyQueue = true;
|
||||
|
||||
export { program };
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<ui-card>
|
||||
<div slot="title"><fa :icon="faExclamationCircle"/> {{ $t('title') }}</div>
|
||||
<template #title><fa :icon="faExclamationCircle"/> {{ $t('title') }}</template>
|
||||
<section class="fit-top">
|
||||
<sequential-entrance animation="entranceFromTop" delay="25">
|
||||
<div v-for="report in userReports" :key="report.id" class="haexwsjc">
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<ui-card>
|
||||
<div slot="title"><fa icon="broadcast-tower"/> {{ $t('announcements') }}</div>
|
||||
<template #title><fa icon="broadcast-tower"/> {{ $t('announcements') }}</template>
|
||||
<section v-for="(announcement, i) in announcements" class="fit-top">
|
||||
<ui-input v-model="announcement.title" @change="save">
|
||||
<span>{{ $t('title') }}</span>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<ui-card>
|
||||
<div slot="title"><fa :icon="faTerminal"/> {{ $t('operation') }}</div>
|
||||
<template #title><fa :icon="faTerminal"/> {{ $t('operation') }}</template>
|
||||
<section class="fit-top">
|
||||
<ui-input v-model="target" type="text">
|
||||
<span>{{ $t('fileid-or-url') }}</span>
|
||||
@@ -17,18 +17,18 @@
|
||||
</ui-card>
|
||||
|
||||
<ui-card>
|
||||
<div slot="title"><fa :icon="faCloud"/> {{ $t('@.drive') }}</div>
|
||||
<template #title><fa :icon="faCloud"/> {{ $t('@.drive') }}</template>
|
||||
<section class="fit-top">
|
||||
<ui-horizon-group inputs>
|
||||
<ui-select v-model="sort">
|
||||
<span slot="label">{{ $t('sort.title') }}</span>
|
||||
<template #label>{{ $t('sort.title') }}</template>
|
||||
<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>
|
||||
<template #label>{{ $t('origin.title') }}</template>
|
||||
<option value="combined">{{ $t('origin.combined') }}</option>
|
||||
<option value="local">{{ $t('origin.local') }}</option>
|
||||
<option value="remote">{{ $t('origin.remote') }}</option>
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
<template>
|
||||
<div>
|
||||
<ui-card>
|
||||
<div slot="title"><fa icon="plus"/> {{ $t('add-emoji.title') }}</div>
|
||||
<template #title><fa icon="plus"/> {{ $t('add-emoji.title') }}</template>
|
||||
<section class="fit-top">
|
||||
<ui-horizon-group inputs>
|
||||
<ui-input v-model="name">
|
||||
<span>{{ $t('add-emoji.name') }}</span>
|
||||
<span slot="desc">{{ $t('add-emoji.name-desc') }}</span>
|
||||
<template #desc>{{ $t('add-emoji.name-desc') }}</template>
|
||||
</ui-input>
|
||||
<ui-input v-model="aliases">
|
||||
<span>{{ $t('add-emoji.aliases') }}</span>
|
||||
<span slot="desc">{{ $t('add-emoji.aliases-desc') }}</span>
|
||||
<template #desc>{{ $t('add-emoji.aliases-desc') }}</template>
|
||||
</ui-input>
|
||||
</ui-horizon-group>
|
||||
<ui-input v-model="url">
|
||||
<i slot="icon"><fa icon="link"/></i>
|
||||
<template #icon><fa icon="link"/></template>
|
||||
<span>{{ $t('add-emoji.url') }}</span>
|
||||
</ui-input>
|
||||
<ui-info>{{ $t('add-emoji.info') }}</ui-info>
|
||||
@@ -23,7 +23,7 @@
|
||||
</ui-card>
|
||||
|
||||
<ui-card>
|
||||
<div slot="title"><fa :icon="faGrin"/> {{ $t('emojis.title') }}</div>
|
||||
<template #title><fa :icon="faGrin"/> {{ $t('emojis.title') }}</template>
|
||||
<section v-for="emoji in emojis" class="oryfrbft">
|
||||
<div>
|
||||
<img :src="emoji.url" :alt="emoji.name" style="width: 64px;"/>
|
||||
@@ -38,7 +38,7 @@
|
||||
</ui-input>
|
||||
</ui-horizon-group>
|
||||
<ui-input v-model="emoji.url">
|
||||
<i slot="icon"><fa icon="link"/></i>
|
||||
<template #icon><fa icon="link"/></template>
|
||||
<span>{{ $t('add-emoji.url') }}</span>
|
||||
</ui-input>
|
||||
<ui-horizon-group class="fit-bottom">
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<ui-card>
|
||||
<div slot="title"><fa :icon="faTerminal"/> {{ $t('federation') }}</div>
|
||||
<template #title><fa :icon="faTerminal"/> {{ $t('federation') }}</template>
|
||||
<section class="fit-top">
|
||||
<ui-input class="target" v-model="target" type="text" @enter="showInstance()">
|
||||
<span>{{ $t('host') }}</span>
|
||||
@@ -74,11 +74,11 @@
|
||||
</ui-card>
|
||||
|
||||
<ui-card>
|
||||
<div slot="title"><fa :icon="faServer"/> {{ $t('instances') }}</div>
|
||||
<template #title><fa :icon="faServer"/> {{ $t('instances') }}</template>
|
||||
<section class="fit-top">
|
||||
<ui-horizon-group inputs>
|
||||
<ui-select v-model="sort">
|
||||
<span slot="label">{{ $t('sort') }}</span>
|
||||
<template #label>{{ $t('sort') }}</template>
|
||||
<option value="-caughtAt">{{ $t('sorts.caughtAtAsc') }}</option>
|
||||
<option value="+caughtAt">{{ $t('sorts.caughtAtDesc') }}</option>
|
||||
<option value="-lastCommunicatedAt">{{ $t('sorts.lastCommunicatedAtAsc') }}</option>
|
||||
@@ -97,7 +97,7 @@
|
||||
<option value="+driveFiles">{{ $t('sorts.driveFilesDesc') }}</option>
|
||||
</ui-select>
|
||||
<ui-select v-model="state">
|
||||
<span slot="label">{{ $t('state') }}</span>
|
||||
<template #label>{{ $t('state') }}</template>
|
||||
<option value="all">{{ $t('states.all') }}</option>
|
||||
<option value="blocked">{{ $t('states.blocked') }}</option>
|
||||
<option value="notResponding">{{ $t('states.not-responding') }}</option>
|
||||
@@ -148,7 +148,7 @@ export default Vue.extend({
|
||||
return {
|
||||
instance: null,
|
||||
target: null,
|
||||
sort: '+caughtAt',
|
||||
sort: '+lastCommunicatedAt',
|
||||
state: 'all',
|
||||
limit: 50,
|
||||
instances: [],
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<ui-card>
|
||||
<div slot="title">{{ $t('hided-tags') }}</div>
|
||||
<template #title>{{ $t('hided-tags') }}</template>
|
||||
<section>
|
||||
<textarea class="jdnqwkzlnxcfftthoybjxrebyolvoucw" v-model="hidedTags"></textarea>
|
||||
<ui-button @click="save">{{ $t('save') }}</ui-button>
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
<template>
|
||||
<div>
|
||||
<ui-card>
|
||||
<div slot="title"><fa icon="cog"/> {{ $t('instance') }}</div>
|
||||
<template #title><fa icon="cog"/> {{ $t('instance') }}</template>
|
||||
<section class="fit-top fit-bottom">
|
||||
<ui-input :value="host" readonly>{{ $t('host') }}</ui-input>
|
||||
<ui-input v-model="name">{{ $t('instance-name') }}</ui-input>
|
||||
<ui-textarea v-model="description">{{ $t('instance-description') }}</ui-textarea>
|
||||
<ui-input v-model="mascotImageUrl"><i slot="icon"><fa icon="link"/></i>{{ $t('logo-url') }}</ui-input>
|
||||
<ui-input v-model="bannerUrl"><i slot="icon"><fa icon="link"/></i>{{ $t('banner-url') }}</ui-input>
|
||||
<ui-input v-model="errorImageUrl"><i slot="icon"><fa icon="link"/></i>{{ $t('error-image-url') }}</ui-input>
|
||||
<ui-input v-model="languages"><i slot="icon"><fa icon="language"/></i>{{ $t('languages') }}<span slot="desc">{{ $t('languages-desc') }}</span></ui-input>
|
||||
<ui-input v-model="mascotImageUrl"><template #icon><fa icon="link"/></template>{{ $t('logo-url') }}</ui-input>
|
||||
<ui-input v-model="bannerUrl"><template #icon><fa icon="link"/></template>{{ $t('banner-url') }}</ui-input>
|
||||
<ui-input v-model="errorImageUrl"><template #icon><fa icon="link"/></template>{{ $t('error-image-url') }}</ui-input>
|
||||
<ui-input v-model="languages"><template #icon><fa icon="language"/></template>{{ $t('languages') }}<template #desc>{{ $t('languages-desc') }}</template></ui-input>
|
||||
</section>
|
||||
<section class="fit-bottom">
|
||||
<header><fa :icon="faHeadset"/> {{ $t('maintainer-config') }}</header>
|
||||
<ui-input v-model="maintainerName">{{ $t('maintainer-name') }}</ui-input>
|
||||
<ui-input v-model="maintainerEmail" type="email"><i slot="icon"><fa :icon="farEnvelope"/></i>{{ $t('maintainer-email') }}</ui-input>
|
||||
<ui-input v-model="maintainerEmail" type="email"><template #icon><fa :icon="farEnvelope"/></template>{{ $t('maintainer-email') }}</ui-input>
|
||||
</section>
|
||||
<section class="fit-top fit-bottom">
|
||||
<ui-input v-model="maxNoteTextLength">{{ $t('max-note-text-length') }}</ui-input>
|
||||
@@ -27,28 +27,28 @@
|
||||
</section>
|
||||
<section class="fit-bottom">
|
||||
<header><fa icon="cloud"/> {{ $t('drive-config') }}</header>
|
||||
<ui-switch v-model="cacheRemoteFiles">{{ $t('cache-remote-files') }}<span slot="desc">{{ $t('cache-remote-files-desc') }}</span></ui-switch>
|
||||
<ui-input v-model="localDriveCapacityMb" type="number">{{ $t('local-drive-capacity-mb') }}<span slot="suffix">MB</span><span slot="desc">{{ $t('mb') }}</span></ui-input>
|
||||
<ui-input v-model="remoteDriveCapacityMb" type="number" :disabled="!cacheRemoteFiles">{{ $t('remote-drive-capacity-mb') }}<span slot="suffix">MB</span><span slot="desc">{{ $t('mb') }}</span></ui-input>
|
||||
<ui-switch v-model="cacheRemoteFiles">{{ $t('cache-remote-files') }}<template #desc>{{ $t('cache-remote-files-desc') }}</template></ui-switch>
|
||||
<ui-input v-model="localDriveCapacityMb" type="number">{{ $t('local-drive-capacity-mb') }}<template #suffix>MB</template><template #desc>{{ $t('mb') }}</template></ui-input>
|
||||
<ui-input v-model="remoteDriveCapacityMb" type="number" :disabled="!cacheRemoteFiles">{{ $t('remote-drive-capacity-mb') }}<template #suffix>MB</template><template #desc>{{ $t('mb') }}</template></ui-input>
|
||||
</section>
|
||||
<section class="fit-bottom">
|
||||
<header><fa :icon="faShieldAlt"/> {{ $t('recaptcha-config') }}</header>
|
||||
<ui-switch v-model="enableRecaptcha">{{ $t('enable-recaptcha') }}</ui-switch>
|
||||
<ui-info>{{ $t('recaptcha-info') }}</ui-info>
|
||||
<ui-horizon-group inputs>
|
||||
<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-input v-model="recaptchaSiteKey" :disabled="!enableRecaptcha"><template #icon><fa icon="key"/></template>{{ $t('recaptcha-site-key') }}</ui-input>
|
||||
<ui-input v-model="recaptchaSecretKey" :disabled="!enableRecaptcha"><template #icon><fa icon="key"/></template>{{ $t('recaptcha-secret-key') }}</ui-input>
|
||||
</ui-horizon-group>
|
||||
</section>
|
||||
<section>
|
||||
<header><fa :icon="faGhost"/> {{ $t('proxy-account-config') }}</header>
|
||||
<ui-info>{{ $t('proxy-account-info') }}</ui-info>
|
||||
<ui-input v-model="proxyAccount"><span slot="prefix">@</span>{{ $t('proxy-account-username') }}<span slot="desc">{{ $t('proxy-account-username-desc') }}</span></ui-input>
|
||||
<ui-input v-model="proxyAccount"><template #prefix>@</template>{{ $t('proxy-account-username') }}<template #desc>{{ $t('proxy-account-username-desc') }}</template></ui-input>
|
||||
<ui-info warn>{{ $t('proxy-account-warn') }}</ui-info>
|
||||
</section>
|
||||
<section>
|
||||
<header><fa :icon="farEnvelope"/> {{ $t('email-config') }}</header>
|
||||
<ui-switch v-model="enableEmail">{{ $t('enable-email') }}<span slot="desc">{{ $t('email-config-info') }}</span></ui-switch>
|
||||
<ui-switch v-model="enableEmail">{{ $t('enable-email') }}<template #desc>{{ $t('email-config-info') }}</template></ui-switch>
|
||||
<ui-input v-model="email" type="email" :disabled="!enableEmail">{{ $t('email') }}</ui-input>
|
||||
<ui-horizon-group inputs>
|
||||
<ui-input v-model="smtpHost" :disabled="!enableEmail">{{ $t('smtp-host') }}</ui-input>
|
||||
@@ -58,15 +58,15 @@
|
||||
<ui-input v-model="smtpUser" :disabled="!enableEmail">{{ $t('smtp-user') }}</ui-input>
|
||||
<ui-input v-model="smtpPass" type="password" :withPasswordToggle="true" :disabled="!enableEmail">{{ $t('smtp-pass') }}</ui-input>
|
||||
</ui-horizon-group>
|
||||
<ui-switch v-model="smtpSecure" :disabled="!enableEmail">{{ $t('smtp-secure') }}<span slot="desc">{{ $t('smtp-secure-info') }}</span></ui-switch>
|
||||
<ui-switch v-model="smtpSecure" :disabled="!enableEmail">{{ $t('smtp-secure') }}<template #desc>{{ $t('smtp-secure-info') }}</template></ui-switch>
|
||||
</section>
|
||||
<section>
|
||||
<header><fa :icon="faBolt"/> {{ $t('serviceworker-config') }}</header>
|
||||
<ui-switch v-model="enableServiceWorker">{{ $t('enable-serviceworker') }}<span slot="desc">{{ $t('serviceworker-info') }}</span></ui-switch>
|
||||
<ui-switch v-model="enableServiceWorker">{{ $t('enable-serviceworker') }}<template #desc>{{ $t('serviceworker-info') }}</template></ui-switch>
|
||||
<ui-info>{{ $t('vapid-info') }}<br><code>npm i web-push -g<br>web-push generate-vapid-keys</code></ui-info>
|
||||
<ui-horizon-group inputs class="fit-bottom">
|
||||
<ui-input v-model="swPublicKey" :disabled="!enableServiceWorker"><i slot="icon"><fa icon="key"/></i>{{ $t('vapid-publickey') }}</ui-input>
|
||||
<ui-input v-model="swPrivateKey" :disabled="!enableServiceWorker"><i slot="icon"><fa icon="key"/></i>{{ $t('vapid-privatekey') }}</ui-input>
|
||||
<ui-input v-model="swPublicKey" :disabled="!enableServiceWorker"><template #icon><fa icon="key"/></template>{{ $t('vapid-publickey') }}</ui-input>
|
||||
<ui-input v-model="swPrivateKey" :disabled="!enableServiceWorker"><template #icon><fa icon="key"/></template>{{ $t('vapid-privatekey') }}</ui-input>
|
||||
</ui-horizon-group>
|
||||
</section>
|
||||
<section>
|
||||
@@ -76,8 +76,8 @@
|
||||
<section>
|
||||
<header><fa :icon="faUserPlus"/> {{ $t('user-recommendation-config') }}</header>
|
||||
<ui-switch v-model="enableExternalUserRecommendation">{{ $t('enable-external-user-recommendation') }}</ui-switch>
|
||||
<ui-input v-model="externalUserRecommendationEngine" :disabled="!enableExternalUserRecommendation">{{ $t('external-user-recommendation-engine') }}<span slot="desc">{{ $t('external-user-recommendation-engine-desc') }}</span></ui-input>
|
||||
<ui-input v-model="externalUserRecommendationTimeout" type="number" :disabled="!enableExternalUserRecommendation">{{ $t('external-user-recommendation-timeout') }}<span slot="suffix">ms</span><span slot="desc">{{ $t('external-user-recommendation-timeout-desc') }}</span></ui-input>
|
||||
<ui-input v-model="externalUserRecommendationEngine" :disabled="!enableExternalUserRecommendation">{{ $t('external-user-recommendation-engine') }}<template #desc>{{ $t('external-user-recommendation-engine-desc') }}</template></ui-input>
|
||||
<ui-input v-model="externalUserRecommendationTimeout" type="number" :disabled="!enableExternalUserRecommendation">{{ $t('external-user-recommendation-timeout') }}<template #suffix>ms</template><template #desc>{{ $t('external-user-recommendation-timeout-desc') }}</template></ui-input>
|
||||
</section>
|
||||
<section>
|
||||
<ui-button @click="updateMeta">{{ $t('save') }}</ui-button>
|
||||
@@ -85,7 +85,7 @@
|
||||
</ui-card>
|
||||
|
||||
<ui-card>
|
||||
<div slot="title">{{ $t('invite') }}</div>
|
||||
<template #title>{{ $t('invite') }}</template>
|
||||
<section>
|
||||
<ui-button @click="invite">{{ $t('invite') }}</ui-button>
|
||||
<p v-if="inviteCode">Code: <code>{{ inviteCode }}</code></p>
|
||||
@@ -93,12 +93,12 @@
|
||||
</ui-card>
|
||||
|
||||
<ui-card>
|
||||
<div slot="title"><fa :icon="['fab', 'twitter']"/> {{ $t('twitter-integration-config') }}</div>
|
||||
<template #title><fa :icon="['fab', 'twitter']"/> {{ $t('twitter-integration-config') }}</template>
|
||||
<section>
|
||||
<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-input v-model="twitterConsumerKey" :disabled="!enableTwitterIntegration"><template #icon><fa icon="key"/></template>{{ $t('twitter-integration-consumer-key') }}</ui-input>
|
||||
<ui-input v-model="twitterConsumerSecret" :disabled="!enableTwitterIntegration"><template #icon><fa icon="key"/></template>{{ $t('twitter-integration-consumer-secret') }}</ui-input>
|
||||
</ui-horizon-group>
|
||||
<ui-info>{{ $t('twitter-integration-info', { url: `${url}/api/tw/cb` }) }}</ui-info>
|
||||
<ui-button @click="updateMeta">{{ $t('save') }}</ui-button>
|
||||
@@ -106,12 +106,12 @@
|
||||
</ui-card>
|
||||
|
||||
<ui-card>
|
||||
<div slot="title"><fa :icon="['fab', 'github']"/> {{ $t('github-integration-config') }}</div>
|
||||
<template #title><fa :icon="['fab', 'github']"/> {{ $t('github-integration-config') }}</template>
|
||||
<section>
|
||||
<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-input v-model="githubClientId" :disabled="!enableGithubIntegration"><template #icon><fa icon="key"/></template>{{ $t('github-integration-client-id') }}</ui-input>
|
||||
<ui-input v-model="githubClientSecret" :disabled="!enableGithubIntegration"><template #icon><fa icon="key"/></template>{{ $t('github-integration-client-secret') }}</ui-input>
|
||||
</ui-horizon-group>
|
||||
<ui-info>{{ $t('github-integration-info', { url: `${url}/api/gh/cb` }) }}</ui-info>
|
||||
<ui-button @click="updateMeta">{{ $t('save') }}</ui-button>
|
||||
@@ -119,12 +119,12 @@
|
||||
</ui-card>
|
||||
|
||||
<ui-card>
|
||||
<div slot="title"><fa :icon="['fab', 'discord']"/> {{ $t('discord-integration-config') }}</div>
|
||||
<template #title><fa :icon="['fab', 'discord']"/> {{ $t('discord-integration-config') }}</template>
|
||||
<section>
|
||||
<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-input v-model="discordClientId" :disabled="!enableDiscordIntegration"><template #icon><fa icon="key"/></template>{{ $t('discord-integration-client-id') }}</ui-input>
|
||||
<ui-input v-model="discordClientSecret" :disabled="!enableDiscordIntegration"><template #icon><fa icon="key"/></template>{{ $t('discord-integration-client-secret') }}</ui-input>
|
||||
</ui-horizon-group>
|
||||
<ui-info>{{ $t('discord-integration-info', { url: `${url}/api/dc/cb` }) }}</ui-info>
|
||||
<ui-button @click="updateMeta">{{ $t('save') }}</ui-button>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<template>
|
||||
<div>
|
||||
<ui-card>
|
||||
<div slot="title"><fa icon="plus"/> {{ $t('add-moderator.title') }}</div>
|
||||
<template #title><fa icon="plus"/> {{ $t('add-moderator.title') }}</template>
|
||||
<section class="fit-top">
|
||||
<ui-input v-model="username" type="text">
|
||||
<span slot="prefix">@</span>
|
||||
<template #prefix>@</template>
|
||||
</ui-input>
|
||||
<ui-horizon-group>
|
||||
<ui-button @click="add" :disabled="changing">{{ $t('add-moderator.add') }}</ui-button>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<ui-card>
|
||||
<div slot="title">{{ $t('operation') }}</div>
|
||||
<template #title>{{ $t('operation') }}</template>
|
||||
<section>
|
||||
<ui-button @click="removeAllJobs">{{ $t('remove-all-jobs') }}</ui-button>
|
||||
</section>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<ui-card>
|
||||
<div slot="title"><fa :icon="faTerminal"/> {{ $t('operation') }}</div>
|
||||
<template #title><fa :icon="faTerminal"/> {{ $t('operation') }}</template>
|
||||
<section class="fit-top">
|
||||
<ui-input class="target" v-model="target" type="text" @enter="showUser">
|
||||
<span>{{ $t('username-or-userid') }}</span>
|
||||
@@ -32,26 +32,27 @@
|
||||
</ui-card>
|
||||
|
||||
<ui-card>
|
||||
<div slot="title"><fa :icon="faUsers"/> {{ $t('users.title') }}</div>
|
||||
<template #title><fa :icon="faUsers"/> {{ $t('users.title') }}</template>
|
||||
<section class="fit-top">
|
||||
<ui-horizon-group inputs>
|
||||
<ui-select v-model="sort">
|
||||
<span slot="label">{{ $t('users.sort.title') }}</span>
|
||||
<template #label>{{ $t('users.sort.title') }}</template>
|
||||
<option value="-createdAt">{{ $t('users.sort.createdAtAsc') }}</option>
|
||||
<option value="+createdAt">{{ $t('users.sort.createdAtDesc') }}</option>
|
||||
<option value="-updatedAt">{{ $t('users.sort.updatedAtAsc') }}</option>
|
||||
<option value="+updatedAt">{{ $t('users.sort.updatedAtDesc') }}</option>
|
||||
</ui-select>
|
||||
<ui-select v-model="state">
|
||||
<span slot="label">{{ $t('users.state.title') }}</span>
|
||||
<template #label>{{ $t('users.state.title') }}</template>
|
||||
<option value="all">{{ $t('users.state.all') }}</option>
|
||||
<option value="admin">{{ $t('users.state.admin') }}</option>
|
||||
<option value="moderator">{{ $t('users.state.moderator') }}</option>
|
||||
<option value="verified">{{ $t('users.state.verified') }}</option>
|
||||
<option value="silenced">{{ $t('users.state.silenced') }}</option>
|
||||
<option value="suspended">{{ $t('users.state.suspended') }}</option>
|
||||
</ui-select>
|
||||
<ui-select v-model="origin">
|
||||
<span slot="label">{{ $t('users.origin.title') }}</span>
|
||||
<template #label>{{ $t('users.origin.title') }}</template>
|
||||
<option value="combined">{{ $t('users.origin.combined') }}</option>
|
||||
<option value="local">{{ $t('users.origin.local') }}</option>
|
||||
<option value="remote">{{ $t('users.origin.remote') }}</option>
|
||||
@@ -89,7 +90,7 @@ export default Vue.extend({
|
||||
unsuspending: false,
|
||||
sort: '+createdAt',
|
||||
state: 'all',
|
||||
origin: 'combined',
|
||||
origin: 'local',
|
||||
limit: 10,
|
||||
offset: 0,
|
||||
users: [],
|
||||
@@ -129,16 +130,25 @@ export default Vue.extend({
|
||||
const usernamePromise = this.$root.api('users/show', parseAcct(this.target));
|
||||
const idPromise = this.$root.api('users/show', { userId: this.target });
|
||||
|
||||
usernamePromise.then(res);
|
||||
idPromise.then(res);
|
||||
|
||||
idPromise.catch(e => {
|
||||
if (e == 'user not found') {
|
||||
let _notFound = false;
|
||||
const notFound = () => {
|
||||
if (_notFound) {
|
||||
this.$root.dialog({
|
||||
type: 'error',
|
||||
text: this.$t('user-not-found')
|
||||
});
|
||||
} else {
|
||||
_notFound = true;
|
||||
}
|
||||
};
|
||||
|
||||
usernamePromise.then(res).catch(e => {
|
||||
if (e == 'user not found') {
|
||||
notFound();
|
||||
}
|
||||
});
|
||||
idPromise.then(res).catch(e => {
|
||||
notFound();
|
||||
});
|
||||
});
|
||||
},
|
||||
@@ -329,7 +339,7 @@ export default Vue.extend({
|
||||
});
|
||||
|
||||
return !confirm.canceled;
|
||||
}
|
||||
},
|
||||
|
||||
fetchUsers() {
|
||||
this.$root.api('admin/show-users', {
|
||||
|
||||
@@ -138,8 +138,8 @@
|
||||
const meta = await res.json();
|
||||
|
||||
// Compare versions
|
||||
if (meta.clientVersion != ver) {
|
||||
localStorage.setItem('v', meta.clientVersion);
|
||||
if (meta.version != ver) {
|
||||
localStorage.setItem('v', meta.version);
|
||||
|
||||
alert(
|
||||
'Misskeyの新しいバージョンがあります。ページを再度読み込みします。' +
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { clientVersion as current } from '../../config';
|
||||
import { version as current } from '../../config';
|
||||
|
||||
export default async function($root: any, force = false, silent = false) {
|
||||
const meta = await $root.getMeta(force);
|
||||
const newer = meta.clientVersion;
|
||||
const newer = meta.version;
|
||||
|
||||
if (newer != current) {
|
||||
localStorage.setItem('should-refresh', 'true');
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import { url as instanceUrl } from '../../config';
|
||||
import * as url from '../../../../prelude/url';
|
||||
|
||||
export function getStaticImageUrl(url: string): string {
|
||||
const u = new URL(url);
|
||||
export function getStaticImageUrl(baseUrl: string): string {
|
||||
const u = new URL(baseUrl);
|
||||
const dummy = `${u.host}${u.pathname}`; // 拡張子がないとキャッシュしてくれないCDNがあるので
|
||||
let result = `${instanceUrl}/proxy/${dummy}?url=${encodeURIComponent(u.href)}`;
|
||||
result += '&static=1';
|
||||
return result;
|
||||
return `${instanceUrl}/proxy/${dummy}?${url.query({
|
||||
url: u.href,
|
||||
static: '1'
|
||||
})}`;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,8 @@ export default function(me, settings, note) {
|
||||
|
||||
const includesMutedWords = (text: string) =>
|
||||
text
|
||||
? settings.mutedWords.some(q => q.length > 0 && !q.some(word => !text.includes(word)))
|
||||
? settings.mutedWords.some(q => q.length > 0 && !q.some(word =>
|
||||
word.startsWith('/') && word.endsWith('/') ? !(new RegExp(word.substr(1, word.length - 2)).test(text)) : !text.includes(word)))
|
||||
: false;
|
||||
|
||||
return (
|
||||
|
||||
18
src/client/app/common/size.ts
Normal file
18
src/client/app/common/size.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
export default {
|
||||
install(Vue) {
|
||||
Vue.directive('size', {
|
||||
inserted(el, binding) {
|
||||
const query = binding.value;
|
||||
const width = el.clientWidth;
|
||||
for (const q of query) {
|
||||
if (q.lt && (width <= q.lt)) {
|
||||
el.classList.add(q.class);
|
||||
}
|
||||
if (q.gt && (width >= q.gt)) {
|
||||
el.classList.add(q.class);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="mk-activity">
|
||||
<div>
|
||||
<div ref="chart"></div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -9,7 +9,17 @@ import Vue from 'vue';
|
||||
import ApexCharts from 'apexcharts';
|
||||
|
||||
export default Vue.extend({
|
||||
props: ['user'],
|
||||
props: {
|
||||
user: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
limit: {
|
||||
type: Number,
|
||||
required: false,
|
||||
default: 21
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
fetching: true,
|
||||
@@ -21,7 +31,7 @@ export default Vue.extend({
|
||||
this.$root.api('charts/user/notes', {
|
||||
userId: this.user.id,
|
||||
span: 'day',
|
||||
limit: 21
|
||||
limit: this.limit
|
||||
}).then(stats => {
|
||||
const normal = [];
|
||||
const reply = [];
|
||||
@@ -32,7 +42,7 @@ export default Vue.extend({
|
||||
const m = now.getMonth();
|
||||
const d = now.getDate();
|
||||
|
||||
for (let i = 0; i < 21; i++) {
|
||||
for (let i = 0; i < this.limit; i++) {
|
||||
const x = new Date(y, m, d - i);
|
||||
normal.push([
|
||||
x,
|
||||
@@ -99,10 +109,3 @@ export default Vue.extend({
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
.mk-activity
|
||||
max-width 600px
|
||||
margin 0 auto
|
||||
|
||||
</style>
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<ui-card>
|
||||
<div slot="title"><fa icon="key"/> API</div>
|
||||
<template #title><fa icon="key"/> API</template>
|
||||
|
||||
<section class="fit-top">
|
||||
<ui-input :value="$store.state.i.token" readonly>
|
||||
@@ -19,7 +19,7 @@
|
||||
</ui-input>
|
||||
<ui-textarea v-model="body">
|
||||
<span>{{ $t('console.parameter') }} (JSON or JSON5)</span>
|
||||
<span slot="desc">{{ $t('console.credential-info') }}</span>
|
||||
<template #desc>{{ $t('console.credential-info') }}</template>
|
||||
</ui-textarea>
|
||||
<ui-button @click="send" :disabled="sending">
|
||||
<template v-if="sending">{{ $t('console.sending') }}</template>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<header v-if="title" v-html="title"></header>
|
||||
<div class="body" v-if="text" v-html="text"></div>
|
||||
<ui-input v-if="input" v-model="inputValue" autofocus :type="input.type || 'text'" :placeholder="input.placeholder" @keydown="onInputKeydown"></ui-input>
|
||||
<ui-input v-if="user" v-model="userInputValue" autofocus @keydown="onInputKeydown"><span slot="prefix">@</span></ui-input>
|
||||
<ui-input v-if="user" v-model="userInputValue" autofocus @keydown="onInputKeydown"><template #prefix>@</template></ui-input>
|
||||
<ui-select v-if="select" v-model="selectedValue">
|
||||
<option v-for="item in select.items" :value="item.value">{{ item.text }}</option>
|
||||
</ui-select>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<ui-card>
|
||||
<div slot="title"><fa icon="cloud"/> {{ $t('@.drive') }}</div>
|
||||
<template #title><fa icon="cloud"/> {{ $t('@.drive') }}</template>
|
||||
|
||||
<section v-if="!fetching" class="juakhbxthdewydyreaphkepoxgxvfogn">
|
||||
<div class="meter"><div :style="meterStyle"></div></div>
|
||||
|
||||
11
src/client/app/common/views/components/dummy.vue
Normal file
11
src/client/app/common/views/components/dummy.vue
Normal file
@@ -0,0 +1,11 @@
|
||||
<template>
|
||||
<div>
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
export default Vue.extend({
|
||||
});
|
||||
</script>
|
||||
@@ -1,8 +1,9 @@
|
||||
<template>
|
||||
<button class="wfliddvnhxvyusikowhxozkyxyenqxqr"
|
||||
:class="{ wait, block, mini, active: isFollowing || hasPendingFollowRequestFromYou }"
|
||||
:class="{ wait, block, inline, mini, active: isFollowing || hasPendingFollowRequestFromYou }"
|
||||
@click="onClick"
|
||||
:disabled="wait"
|
||||
:inline="inline"
|
||||
>
|
||||
<template v-if="!wait">
|
||||
<fa :icon="iconAndText[0]"/> <template v-if="!mini">{{ iconAndText[1] }}</template>
|
||||
@@ -28,6 +29,11 @@ export default Vue.extend({
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
inline: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
mini: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
@@ -128,6 +134,9 @@ export default Vue.extend({
|
||||
border solid 1px var(--primary)
|
||||
border-radius 36px
|
||||
|
||||
&.inline
|
||||
display inline-block
|
||||
|
||||
&.mini
|
||||
padding 0
|
||||
min-width 0
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import Vue from 'vue';
|
||||
|
||||
import dummy from './dummy.vue';
|
||||
import userName from './user-name.vue';
|
||||
import followButton from './follow-button.vue';
|
||||
import error from './error.vue';
|
||||
@@ -32,6 +33,7 @@ import urlPreview from './url-preview.vue';
|
||||
import fileTypeIcon from './file-type-icon.vue';
|
||||
import emoji from './emoji.vue';
|
||||
import welcomeTimeline from './welcome-timeline.vue';
|
||||
import userList from './user-list.vue';
|
||||
import uiInput from './ui/input.vue';
|
||||
import uiButton from './ui/button.vue';
|
||||
import uiHorizonGroup from './ui/horizon-group.vue';
|
||||
@@ -46,6 +48,7 @@ import formButton from './ui/form/button.vue';
|
||||
import formRadio from './ui/form/radio.vue';
|
||||
|
||||
Vue.component('mfm', misskeyFlavoredMarkdown);
|
||||
Vue.component('mk-dummy', dummy);
|
||||
Vue.component('mk-user-name', userName);
|
||||
Vue.component('mk-follow-button', followButton);
|
||||
Vue.component('mk-error', error);
|
||||
@@ -77,6 +80,7 @@ Vue.component('mk-url-preview', urlPreview);
|
||||
Vue.component('mk-file-type-icon', fileTypeIcon);
|
||||
Vue.component('mk-emoji', emoji);
|
||||
Vue.component('mk-welcome-timeline', welcomeTimeline);
|
||||
Vue.component('mk-user-list', userList);
|
||||
Vue.component('ui-input', uiInput);
|
||||
Vue.component('ui-button', uiButton);
|
||||
Vue.component('ui-horizon-group', uiHorizonGroup);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<ui-card v-if="enableTwitterIntegration || enableDiscordIntegration || enableGithubIntegration">
|
||||
<div slot="title"><fa icon="share-alt"/> {{ $t('title') }}</div>
|
||||
<template #title><fa icon="share-alt"/> {{ $t('title') }}</template>
|
||||
|
||||
<section v-if="enableTwitterIntegration">
|
||||
<header><fa :icon="['fab', 'twitter']"/> Twitter</header>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<ui-card>
|
||||
<div slot="title"><fa icon="language"/> {{ $t('title') }}</div>
|
||||
<template #title><fa icon="language"/> {{ $t('title') }}</template>
|
||||
|
||||
<section class="fit-top">
|
||||
<ui-select v-model="lang" :placeholder="$t('pick-language')">
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<b>{{ $t('sensitive') }}</b>
|
||||
<span>{{ $t('click-to-show') }}</span>
|
||||
</div>
|
||||
<div class="audio" v-else-if="media.type.startsWith('audio')">
|
||||
<div class="audio" v-else-if="media.type.startsWith('audio') && media.type !== 'audio/midi'">
|
||||
<audio class="audio"
|
||||
:src="media.url"
|
||||
:title="media.name"
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
:style="style"
|
||||
:title="image.name"
|
||||
@click.prevent="onClick"
|
||||
></a>
|
||||
>
|
||||
<div v-if="image.type === 'image/gif'">GIF</div>
|
||||
</a>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
@@ -76,6 +78,20 @@ export default Vue.extend({
|
||||
background-size contain
|
||||
background-repeat no-repeat
|
||||
|
||||
> div
|
||||
background-color var(--text)
|
||||
border-radius var(--round)
|
||||
color var(--secondary)
|
||||
display inline-block
|
||||
font-size 14px
|
||||
font-weight bold
|
||||
left 12px
|
||||
opacity .5
|
||||
padding 0 6px
|
||||
text-align center
|
||||
top 12px
|
||||
pointer-events none
|
||||
|
||||
.qjewsnkgzzxlxtzncydssfbgjibiehcy
|
||||
display flex
|
||||
justify-content center
|
||||
|
||||
@@ -40,7 +40,11 @@ export default Vue.component('misskey-flavored-markdown', {
|
||||
},
|
||||
customEmojis: {
|
||||
required: false,
|
||||
}
|
||||
},
|
||||
isNote: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
},
|
||||
|
||||
render(createElement) {
|
||||
@@ -204,7 +208,7 @@ export default Vue.component('misskey-flavored-markdown', {
|
||||
return [createElement('router-link', {
|
||||
key: Math.random(),
|
||||
attrs: {
|
||||
to: `/tags/${encodeURIComponent(token.node.props.hashtag)}`,
|
||||
to: this.isNote ? `/tags/${encodeURIComponent(token.node.props.hashtag)}` : `/explore/tags/${encodeURIComponent(token.node.props.hashtag)}`,
|
||||
style: 'color:var(--mfmHashtag);'
|
||||
}
|
||||
}, `#${token.node.props.hashtag}`)];
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<ui-card>
|
||||
<div slot="title"><fa icon="ban"/> {{ $t('mute-and-block') }}</div>
|
||||
<template #title><fa icon="ban"/> {{ $t('mute-and-block') }}</template>
|
||||
|
||||
<section>
|
||||
<header>{{ $t('mute') }}</header>
|
||||
@@ -25,7 +25,7 @@
|
||||
<section>
|
||||
<header>{{ $t('word-mute') }}</header>
|
||||
<ui-textarea v-model="mutedWords">
|
||||
{{ $t('muted-words') }}<span slot="desc">{{ $t('muted-words-description') }}</span>
|
||||
{{ $t('muted-words') }}<template #desc>{{ $t('muted-words-description') }}</template>
|
||||
</ui-textarea>
|
||||
<ui-button @click="save">{{ $t('save') }}</ui-button>
|
||||
</section>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<ui-card>
|
||||
<div slot="title"><fa :icon="['far', 'bell']"/> {{ $t('title') }}</div>
|
||||
<template #title><fa :icon="['far', 'bell']"/> {{ $t('title') }}</template>
|
||||
<section>
|
||||
<ui-switch v-model="$store.state.i.settings.autoWatch" @change="onChangeAutoWatch">
|
||||
{{ $t('auto-watch') }}<span slot="desc">{{ $t('auto-watch-desc') }}</span>
|
||||
{{ $t('auto-watch') }}<template #desc>{{ $t('auto-watch-desc') }}</template>
|
||||
</ui-switch>
|
||||
<section>
|
||||
<ui-button @click="readAllNotifications">{{ $t('mark-as-read-all-notifications') }}</ui-button>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<ui-card>
|
||||
<div slot="title"><fa icon="user"/> {{ $t('title') }}</div>
|
||||
<template #title><fa icon="user"/> {{ $t('title') }}</template>
|
||||
|
||||
<section class="esokaraujimuwfttfzgocmutcihewscl">
|
||||
<div class="header" :style="bannerStyle">
|
||||
@@ -14,41 +14,41 @@
|
||||
|
||||
<ui-input v-model="username" readonly>
|
||||
<span>{{ $t('account') }}</span>
|
||||
<span slot="prefix">@</span>
|
||||
<span slot="suffix">@{{ host }}</span>
|
||||
<template #prefix>@</template>
|
||||
<template #suffix>@{{ host }}</template>
|
||||
</ui-input>
|
||||
|
||||
<ui-input v-model="location">
|
||||
<span>{{ $t('location') }}</span>
|
||||
<span slot="prefix"><fa icon="map-marker-alt"/></span>
|
||||
<template #prefix><fa icon="map-marker-alt"/></template>
|
||||
</ui-input>
|
||||
|
||||
<ui-input v-model="birthday" type="date">
|
||||
<span slot="title">{{ $t('birthday') }}</span>
|
||||
<span slot="prefix"><fa icon="birthday-cake"/></span>
|
||||
<template #title>{{ $t('birthday') }}</template>
|
||||
<template #prefix><fa icon="birthday-cake"/></template>
|
||||
</ui-input>
|
||||
|
||||
<ui-textarea v-model="description" :max="500">
|
||||
<span>{{ $t('description') }}</span>
|
||||
<span slot="desc">{{ $t('you-can-include-hashtags') }}</span>
|
||||
<template #desc>{{ $t('you-can-include-hashtags') }}</template>
|
||||
</ui-textarea>
|
||||
|
||||
<ui-select v-model="lang">
|
||||
<span slot="label">{{ $t('language') }}</span>
|
||||
<span slot="icon"><fa icon="language"/></span>
|
||||
<template #label>{{ $t('language') }}</template>
|
||||
<template #icon><fa icon="language"/></template>
|
||||
<option v-for="lang in unique(Object.values(langmap).map(x => x.nativeName)).map(name => Object.keys(langmap).find(k => langmap[k].nativeName == name))" :value="lang" :key="lang">{{ langmap[lang].nativeName }}</option>
|
||||
</ui-select>
|
||||
|
||||
<ui-input type="file" @change="onAvatarChange">
|
||||
<span>{{ $t('avatar') }}</span>
|
||||
<span slot="icon"><fa icon="image"/></span>
|
||||
<span slot="desc" v-if="avatarUploading">{{ $t('uploading') }}<mk-ellipsis/></span>
|
||||
<template #icon><fa icon="image"/></template>
|
||||
<template #desc v-if="avatarUploading">{{ $t('uploading') }}<mk-ellipsis/></template>
|
||||
</ui-input>
|
||||
|
||||
<ui-input type="file" @change="onBannerChange">
|
||||
<span>{{ $t('banner') }}</span>
|
||||
<span slot="icon"><fa icon="image"/></span>
|
||||
<span slot="desc" v-if="bannerUploading">{{ $t('uploading') }}<mk-ellipsis/></span>
|
||||
<template #icon><fa icon="image"/></template>
|
||||
<template #desc v-if="bannerUploading">{{ $t('uploading') }}<mk-ellipsis/></template>
|
||||
</ui-input>
|
||||
|
||||
<ui-button @click="save(true)">{{ $t('save') }}</ui-button>
|
||||
|
||||
@@ -3,16 +3,16 @@
|
||||
<div class="avatar" :style="{ backgroundImage: user ? `url('${ user.avatarUrl }')` : null }" v-show="withAvatar"></div>
|
||||
<ui-input v-model="username" type="text" pattern="^[a-zA-Z0-9_]+$" spellcheck="false" autofocus required @input="onUsernameChange" styl="fill">
|
||||
<span>{{ $t('username') }}</span>
|
||||
<span slot="prefix">@</span>
|
||||
<span slot="suffix">@{{ host }}</span>
|
||||
<template #prefix>@</template>
|
||||
<template #suffix>@{{ host }}</template>
|
||||
</ui-input>
|
||||
<ui-input v-model="password" type="password" :with-password-toggle="true" required styl="fill">
|
||||
<span>{{ $t('password') }}</span>
|
||||
<span slot="prefix"><fa icon="lock"/></span>
|
||||
<template #prefix><fa icon="lock"/></template>
|
||||
</ui-input>
|
||||
<ui-input v-if="user && user.twoFactorEnabled" v-model="token" type="number" required styl="fill">
|
||||
<span>{{ $t('@.2fa') }}</span>
|
||||
<span slot="prefix"><fa icon="gavel"/></span>
|
||||
<template #prefix><fa icon="gavel"/></template>
|
||||
</ui-input>
|
||||
<ui-button type="submit" :disabled="signing">{{ signing ? $t('signing-in') : $t('signin') }}</ui-button>
|
||||
<p v-if="meta && meta.enableTwitterIntegration" style="margin: 8px 0;"><a :href="`${apiUrl}/signin/twitter`">{{ $t('signin-with-twitter') }}</a></p>
|
||||
|
||||
@@ -3,37 +3,37 @@
|
||||
<template v-if="meta">
|
||||
<ui-input v-if="meta.disableRegistration" v-model="invitationCode" type="text" :autocomplete="Math.random()" spellcheck="false" required styl="fill">
|
||||
<span>{{ $t('invitation-code') }}</span>
|
||||
<span slot="prefix"><fa icon="id-card-alt"/></span>
|
||||
<p slot="desc" v-html="this.$t('invitation-info').replace('{}', 'mailto:' + meta.maintainer.email)"></p>
|
||||
<template #prefix><fa icon="id-card-alt"/></template>
|
||||
<template #desc v-html="this.$t('invitation-info').replace('{}', 'mailto:' + meta.maintainer.email)"></template>
|
||||
</ui-input>
|
||||
<ui-input v-model="username" type="text" pattern="^[a-zA-Z0-9_]{1,20}$" :autocomplete="Math.random()" spellcheck="false" required @input="onChangeUsername" styl="fill">
|
||||
<span>{{ $t('username') }}</span>
|
||||
<span slot="prefix">@</span>
|
||||
<span slot="suffix">@{{ host }}</span>
|
||||
<p slot="desc" v-if="usernameState == 'wait'" style="color:#999"><fa icon="spinner" pulse fixed-width/> {{ $t('checking') }}</p>
|
||||
<p slot="desc" v-if="usernameState == 'ok'" style="color:#3CB7B5"><fa icon="check" fixed-width/> {{ $t('available') }}</p>
|
||||
<p slot="desc" v-if="usernameState == 'unavailable'" style="color:#FF1161"><fa icon="exclamation-triangle" fixed-width/> {{ $t('unavailable') }}</p>
|
||||
<p slot="desc" v-if="usernameState == 'error'" style="color:#FF1161"><fa icon="exclamation-triangle" fixed-width/> {{ $t('error') }}</p>
|
||||
<p slot="desc" v-if="usernameState == 'invalid-format'" style="color:#FF1161"><fa icon="exclamation-triangle" fixed-width/> {{ $t('invalid-format') }}</p>
|
||||
<p slot="desc" v-if="usernameState == 'min-range'" style="color:#FF1161"><fa icon="exclamation-triangle" fixed-width/> {{ $t('too-short') }}</p>
|
||||
<p slot="desc" v-if="usernameState == 'max-range'" style="color:#FF1161"><fa icon="exclamation-triangle" fixed-width/> {{ $t('too-long') }}</p>
|
||||
<template #prefix>@</template>
|
||||
<template #suffix>@{{ host }}</template>
|
||||
<template #desc v-if="usernameState == 'wait'" style="color:#999"><fa icon="spinner" pulse fixed-width/> {{ $t('checking') }}</template>
|
||||
<template #desc v-if="usernameState == 'ok'" style="color:#3CB7B5"><fa icon="check" fixed-width/> {{ $t('available') }}</template>
|
||||
<template #desc v-if="usernameState == 'unavailable'" style="color:#FF1161"><fa icon="exclamation-triangle" fixed-width/> {{ $t('unavailable') }}</template>
|
||||
<template #desc v-if="usernameState == 'error'" style="color:#FF1161"><fa icon="exclamation-triangle" fixed-width/> {{ $t('error') }}</template>
|
||||
<template #desc v-if="usernameState == 'invalid-format'" style="color:#FF1161"><fa icon="exclamation-triangle" fixed-width/> {{ $t('invalid-format') }}</template>
|
||||
<template #desc v-if="usernameState == 'min-range'" style="color:#FF1161"><fa icon="exclamation-triangle" fixed-width/> {{ $t('too-short') }}</template>
|
||||
<template #desc v-if="usernameState == 'max-range'" style="color:#FF1161"><fa icon="exclamation-triangle" fixed-width/> {{ $t('too-long') }}</template>
|
||||
</ui-input>
|
||||
<ui-input v-model="password" type="password" :autocomplete="Math.random()" required @input="onChangePassword" :with-password-meter="true" styl="fill">
|
||||
<span>{{ $t('password') }}</span>
|
||||
<span slot="prefix"><fa icon="lock"/></span>
|
||||
<div slot="desc">
|
||||
<template #prefix><fa icon="lock"/></template>
|
||||
<template #desc>
|
||||
<p v-if="passwordStrength == 'low'" style="color:#FF1161"><fa icon="exclamation-triangle" fixed-width/> {{ $t('weak-password') }}</p>
|
||||
<p v-if="passwordStrength == 'medium'" style="color:#3CB7B5"><fa icon="check" fixed-width/> {{ $t('normal-password') }}</p>
|
||||
<p v-if="passwordStrength == 'high'" style="color:#3CB7B5"><fa icon="check" fixed-width/> {{ $t('strong-password') }}</p>
|
||||
</div>
|
||||
</template>
|
||||
</ui-input>
|
||||
<ui-input v-model="retypedPassword" type="password" :autocomplete="Math.random()" required @input="onChangePasswordRetype" styl="fill">
|
||||
<span>{{ $t('password') }} ({{ $t('retype') }})</span>
|
||||
<span slot="prefix"><fa icon="lock"/></span>
|
||||
<div slot="desc">
|
||||
<template #prefix><fa icon="lock"/></template>
|
||||
<template #desc>
|
||||
<p v-if="passwordRetypeState == 'match'" style="color:#3CB7B5"><fa icon="check" fixed-width/> {{ $t('password-matched') }}</p>
|
||||
<p v-if="passwordRetypeState == 'not-match'" style="color:#FF1161"><fa icon="exclamation-triangle" fixed-width/> {{ $t('password-not-matched') }}</p>
|
||||
</div>
|
||||
</template>
|
||||
</ui-input>
|
||||
<div v-if="meta.enableRecaptcha" class="g-recaptcha" :data-sitekey="meta.recaptchaSiteKey" style="margin: 16px 0;"></div>
|
||||
<ui-button type="submit">{{ $t('create') }}</ui-button>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<template>
|
||||
<ui-card>
|
||||
<div slot="title"><fa icon="palette"/> {{ $t('theme') }}</div>
|
||||
<template #title><fa icon="palette"/> {{ $t('theme') }}</template>
|
||||
<section class="nicnklzforebnpfgasiypmpdaaglujqm fit-top">
|
||||
<label>
|
||||
<ui-select v-model="light" :placeholder="$t('light-theme')">
|
||||
<span slot="label"><fa :icon="faSun"/> {{ $t('light-theme') }}</span>
|
||||
<template #label><fa :icon="faSun"/> {{ $t('light-theme') }}</template>
|
||||
<optgroup :label="$t('light-themes')">
|
||||
<option v-for="x in lightThemes" :value="x.id" :key="x.id">{{ x.name }}</option>
|
||||
</optgroup>
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
<label>
|
||||
<ui-select v-model="dark" :placeholder="$t('dark-theme')">
|
||||
<span slot="label"><fa :icon="faMoon"/> {{ $t('dark-theme') }}</span>
|
||||
<template #label><fa :icon="faMoon"/> {{ $t('dark-theme') }}</template>
|
||||
<optgroup :label="$t('dark-themes')">
|
||||
<option v-for="x in darkThemes" :value="x.id" :key="x.id">{{ x.name }}</option>
|
||||
</optgroup>
|
||||
|
||||
@@ -359,7 +359,7 @@ root(fill)
|
||||
display none
|
||||
|
||||
> *
|
||||
display block
|
||||
display inline-block
|
||||
min-width 16px
|
||||
max-width 150px
|
||||
overflow hidden
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="cudqjmnl">
|
||||
<ui-card>
|
||||
<div slot="title"><fa :icon="faList"/> {{ list.title }}</div>
|
||||
<template #title><fa :icon="faList"/> {{ list.title }}</template>
|
||||
|
||||
<section>
|
||||
<ui-button @click="rename"><fa :icon="faICursor"/> {{ $t('rename') }}</ui-button>
|
||||
@@ -10,7 +10,7 @@
|
||||
</ui-card>
|
||||
|
||||
<ui-card>
|
||||
<div slot="title"><fa :icon="faUsers"/> {{ $t('users') }}</div>
|
||||
<template #title><fa :icon="faUsers"/> {{ $t('users') }}</template>
|
||||
|
||||
<section>
|
||||
<sequential-entrance animation="entranceFromTop" delay="25">
|
||||
|
||||
171
src/client/app/common/views/components/user-list.vue
Normal file
171
src/client/app/common/views/components/user-list.vue
Normal file
@@ -0,0 +1,171 @@
|
||||
<template>
|
||||
<ui-container :body-togglable="true">
|
||||
<template #header><slot></slot></template>
|
||||
|
||||
<mk-error v-if="!fetching && !inited" @retry="init()"/>
|
||||
|
||||
<div class="efvhhmdq" v-size="[{ lt: 500, class: 'narrow' }]">
|
||||
<div class="no-users" v-if="inited && us.length == 0">
|
||||
<p>{{ $t('no-users') }}</p>
|
||||
</div>
|
||||
<div class="user" v-for="user in us">
|
||||
<mk-avatar class="avatar" :user="user"/>
|
||||
<div class="body">
|
||||
<div class="name">
|
||||
<router-link class="name" :to="user | userPage" v-user-preview="user.id"><mk-user-name :user="user"/></router-link>
|
||||
<p class="username">@{{ user | acct }}</p>
|
||||
</div>
|
||||
<div class="description" v-if="user.description" :title="user.description">
|
||||
<mfm :text="user.description" :is-note="false" :author="user" :i="$store.state.i" :custom-emojis="user.emojis" :should-break="false"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button class="more" :class="{ fetching: fetchingMoreUsers }" v-if="cursor != null" @click="fetchMoreUsers()" :disabled="fetchingMoreUsers">
|
||||
<template v-if="fetchingMoreUsers"><fa icon="spinner" pulse fixed-width/></template>{{ fetchingMoreUsers ? $t('@.loading') : $t('@.load-more') }}
|
||||
</button>
|
||||
</div>
|
||||
</ui-container>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import i18n from '../../../i18n';
|
||||
|
||||
export default Vue.extend({
|
||||
i18n: i18n('common/views/components/user-list.vue'),
|
||||
|
||||
props: {
|
||||
makePromise: {
|
||||
required: true
|
||||
},
|
||||
iconOnly: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
fetching: true,
|
||||
fetchingMoreUsers: false,
|
||||
us: [],
|
||||
inited: false,
|
||||
cursor: null
|
||||
};
|
||||
},
|
||||
|
||||
created() {
|
||||
this.init();
|
||||
},
|
||||
|
||||
methods: {
|
||||
init() {
|
||||
this.fetching = true;
|
||||
this.makePromise().then(x => {
|
||||
if (Array.isArray(x)) {
|
||||
this.us = x;
|
||||
} else {
|
||||
this.us = x.users;
|
||||
this.cursor = x.cursor;
|
||||
}
|
||||
this.inited = true;
|
||||
this.fetching = false;
|
||||
}, e => {
|
||||
this.fetching = false;
|
||||
});
|
||||
},
|
||||
|
||||
fetchMoreUsers() {
|
||||
this.fetchingMoreUsers = true;
|
||||
this.makePromise(this.cursor).then(x => {
|
||||
this.us = this.us.concat(x.users);
|
||||
this.cursor = x.cursor;
|
||||
this.fetchingMoreUsers = false;
|
||||
}, e => {
|
||||
this.fetchingMoreUsers = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
.efvhhmdq
|
||||
&.narrow
|
||||
> .user > .body > .name
|
||||
width 100%
|
||||
|
||||
> .user > .body > .description
|
||||
display none
|
||||
|
||||
> .no-users
|
||||
text-align center
|
||||
color var(--text)
|
||||
|
||||
> .user
|
||||
display flex
|
||||
padding 16px
|
||||
border-bottom solid 1px var(--faceDivider)
|
||||
|
||||
&:last-child
|
||||
border-bottom none
|
||||
|
||||
> .avatar
|
||||
display block
|
||||
flex-shrink 0
|
||||
margin 0 12px 0 0
|
||||
width 42px
|
||||
height 42px
|
||||
border-radius 8px
|
||||
|
||||
> .body
|
||||
display flex
|
||||
width calc(100% - 54px)
|
||||
|
||||
> .name
|
||||
width 45%
|
||||
|
||||
> .name
|
||||
margin 0
|
||||
font-size 16px
|
||||
line-height 24px
|
||||
color var(--text)
|
||||
|
||||
> .username
|
||||
display block
|
||||
margin 0
|
||||
font-size 15px
|
||||
line-height 16px
|
||||
color var(--text)
|
||||
opacity 0.7
|
||||
|
||||
> .description
|
||||
width 55%
|
||||
color var(--text)
|
||||
line-height 42px
|
||||
white-space nowrap
|
||||
overflow hidden
|
||||
text-overflow ellipsis
|
||||
opacity 0.7
|
||||
font-size 14px
|
||||
|
||||
> .more
|
||||
display block
|
||||
width 100%
|
||||
padding 16px
|
||||
color var(--text)
|
||||
border-top solid var(--lineWidth) rgba(#000, 0.05)
|
||||
|
||||
&:hover
|
||||
background rgba(#000, 0.025)
|
||||
|
||||
&:active
|
||||
background rgba(#000, 0.05)
|
||||
|
||||
&.fetching
|
||||
cursor wait
|
||||
|
||||
> [data-icon]
|
||||
margin-right 4px
|
||||
|
||||
</style>
|
||||
@@ -76,6 +76,7 @@ export default Vue.extend({
|
||||
if (note.replyId != null) return;
|
||||
if (note.renoteId != null) return;
|
||||
if (note.poll != null) return;
|
||||
if (note.localOnly) return;
|
||||
|
||||
this.notes.unshift(note);
|
||||
},
|
||||
|
||||
181
src/client/app/common/views/pages/explore.vue
Normal file
181
src/client/app/common/views/pages/explore.vue
Normal file
@@ -0,0 +1,181 @@
|
||||
<template>
|
||||
<div>
|
||||
<ui-container :show-header="false">
|
||||
<div class="kpdsmpnk" :style="{ backgroundImage: meta.bannerUrl ? `url(${meta.bannerUrl})` : null }">
|
||||
<div>
|
||||
<b>{{ $t('explore', { host: meta.name }) }}</b>
|
||||
<span>{{ $t('users-info', { users: num(stats.originalUsersCount) }) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</ui-container>
|
||||
|
||||
<mk-user-list v-if="tag != null" :make-promise="tagUsers" :key="`${tag}-local`">
|
||||
<fa :icon="faHashtag" fixed-width/>{{ tag }}
|
||||
</mk-user-list>
|
||||
<mk-user-list v-if="tag != null" :make-promise="tagRemoteUsers" :key="`${tag}-remote`">
|
||||
<fa :icon="faHashtag" fixed-width/>{{ tag }} ({{ $t('federated') }})
|
||||
</mk-user-list>
|
||||
|
||||
<ui-container :body-togglable="true">
|
||||
<template #header><fa :icon="faHashtag" fixed-width/>{{ $t('popular-tags') }}</template>
|
||||
|
||||
<div class="vxjfqztj">
|
||||
<router-link v-for="tag in tagsLocal" :to="`/explore/tags/${tag.tag}`" :key="tag.tag" class="local">{{ tag.tag }}</router-link>
|
||||
<router-link v-for="tag in tagsRemote" :to="`/explore/tags/${tag.tag}`" :key="tag.tag">{{ tag.tag }}</router-link>
|
||||
</div>
|
||||
</ui-container>
|
||||
|
||||
<template v-if="tag == null">
|
||||
<mk-user-list :make-promise="verifiedUsers">
|
||||
<fa :icon="faBookmark" fixed-width/>{{ $t('verified-users') }}
|
||||
</mk-user-list>
|
||||
<mk-user-list :make-promise="popularUsers">
|
||||
<fa :icon="faChartLine" fixed-width/>{{ $t('popular-users') }}
|
||||
</mk-user-list>
|
||||
<mk-user-list :make-promise="recentlyUpdatedUsers">
|
||||
<fa :icon="faCommentAlt" fixed-width/>{{ $t('recently-updated-users') }}
|
||||
</mk-user-list>
|
||||
<mk-user-list :make-promise="recentlyRegisteredUsers">
|
||||
<fa :icon="faPlus" fixed-width/>{{ $t('recently-registered-users') }}
|
||||
</mk-user-list>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import i18n from '../../../i18n';
|
||||
import { faChartLine, faPlus, faHashtag } from '@fortawesome/free-solid-svg-icons';
|
||||
import { faBookmark, faCommentAlt } from '@fortawesome/free-regular-svg-icons';
|
||||
|
||||
export default Vue.extend({
|
||||
i18n: i18n('common/views/pages/explore.vue'),
|
||||
|
||||
props: {
|
||||
tag: {
|
||||
type: String,
|
||||
required: false
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
verifiedUsers: () => this.$root.api('users', {
|
||||
state: 'verified',
|
||||
origin: 'local',
|
||||
sort: '+follower',
|
||||
limit: 10
|
||||
}),
|
||||
popularUsers: () => this.$root.api('users', {
|
||||
state: 'alive',
|
||||
origin: 'local',
|
||||
sort: '+follower',
|
||||
limit: 10
|
||||
}),
|
||||
recentlyUpdatedUsers: () => this.$root.api('users', {
|
||||
origin: 'local',
|
||||
sort: '+updatedAt',
|
||||
limit: 10
|
||||
}),
|
||||
recentlyRegisteredUsers: () => this.$root.api('users', {
|
||||
origin: 'local',
|
||||
state: 'alive',
|
||||
sort: '+createdAt',
|
||||
limit: 10
|
||||
}),
|
||||
tagsLocal: [],
|
||||
tagsRemote: [],
|
||||
stats: null,
|
||||
meta: null,
|
||||
num: Vue.filter('number'),
|
||||
faBookmark, faChartLine, faCommentAlt, faPlus, faHashtag
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
tagUsers(): () => Promise<any> {
|
||||
return () => this.$root.api('hashtags/users', {
|
||||
tag: this.tag,
|
||||
state: 'alive',
|
||||
origin: 'local',
|
||||
sort: '+follower',
|
||||
limit: 30
|
||||
});
|
||||
},
|
||||
|
||||
tagRemoteUsers(): () => Promise<any> {
|
||||
return () => this.$root.api('hashtags/users', {
|
||||
tag: this.tag,
|
||||
state: 'alive',
|
||||
origin: 'remote',
|
||||
sort: '+follower',
|
||||
limit: 30
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
created() {
|
||||
this.$root.api('hashtags/list', {
|
||||
sort: '+attachedLocalUsers',
|
||||
attachedToLocalUserOnly: true,
|
||||
limit: 30
|
||||
}).then(tags => {
|
||||
this.tagsLocal = tags;
|
||||
});
|
||||
this.$root.api('hashtags/list', {
|
||||
sort: '+attachedRemoteUsers',
|
||||
attachedToRemoteUserOnly: true,
|
||||
limit: 30
|
||||
}).then(tags => {
|
||||
this.tagsRemote = tags;
|
||||
});
|
||||
this.$root.api('stats').then(stats => {
|
||||
this.stats = stats;
|
||||
});
|
||||
this.$root.getMeta().then(meta => {
|
||||
this.meta = meta;
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
.vxjfqztj
|
||||
padding 16px
|
||||
|
||||
> *
|
||||
margin-right 16px
|
||||
|
||||
&.local
|
||||
font-weight bold
|
||||
|
||||
.kpdsmpnk
|
||||
min-height 100px
|
||||
padding 16px
|
||||
background-position center
|
||||
background-size cover
|
||||
|
||||
&:before
|
||||
content ""
|
||||
display block
|
||||
position absolute
|
||||
top 0
|
||||
left 0
|
||||
width 100%
|
||||
height 100%
|
||||
background rgba(0, 0, 0, 0.3)
|
||||
|
||||
> div
|
||||
color #fff
|
||||
text-shadow 0 0 8px #00
|
||||
|
||||
> b
|
||||
display block
|
||||
font-size 20px
|
||||
font-weight bold
|
||||
|
||||
> span
|
||||
font-size 14px
|
||||
opacity 0.8
|
||||
|
||||
</style>
|
||||
@@ -12,7 +12,7 @@
|
||||
</router-link>
|
||||
<span class="username">@{{ user | acct }}</span>
|
||||
<div class="description">
|
||||
<mfm v-if="user.description" :text="user.description" :author="user" :i="$store.state.i" :custom-emojis="user.emojis"/>
|
||||
<mfm v-if="user.description" :text="user.description" :is-note="false" :author="user" :i="$store.state.i" :custom-emojis="user.emojis"/>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
30
src/client/app/common/views/pages/followers.vue
Normal file
30
src/client/app/common/views/pages/followers.vue
Normal file
@@ -0,0 +1,30 @@
|
||||
<template>
|
||||
<div>
|
||||
<mk-user-list :make-promise="makePromise">{{ $t('@.followers') }}</mk-user-list>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import parseAcct from '../../../../../misc/acct/parse';
|
||||
import i18n from '../../../i18n';
|
||||
|
||||
export default Vue.extend({
|
||||
i18n: i18n(''),
|
||||
|
||||
data() {
|
||||
return {
|
||||
makePromise: cursor => this.$root.api('users/followers', {
|
||||
...parseAcct(this.$route.params.user),
|
||||
limit: 30,
|
||||
cursor: cursor ? cursor : undefined
|
||||
}).then(x => {
|
||||
return {
|
||||
users: x.users,
|
||||
cursor: x.next
|
||||
};
|
||||
}),
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
27
src/client/app/common/views/pages/following.vue
Normal file
27
src/client/app/common/views/pages/following.vue
Normal file
@@ -0,0 +1,27 @@
|
||||
<template>
|
||||
<div>
|
||||
<mk-user-list :make-promise="makePromise">{{ $t('@.following') }}</mk-user-list>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import parseAcct from '../../../../../misc/acct/parse';
|
||||
|
||||
export default Vue.extend({
|
||||
data() {
|
||||
return {
|
||||
makePromise: cursor => this.$root.api('users/following', {
|
||||
...parseAcct(this.$route.params.user),
|
||||
limit: 30,
|
||||
cursor: cursor ? cursor : undefined
|
||||
}).then(x => {
|
||||
return {
|
||||
users: x.users,
|
||||
cursor: x.next
|
||||
};
|
||||
}),
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
@@ -1,10 +1,10 @@
|
||||
<template>
|
||||
<div class="mkw-analog-clock">
|
||||
<mk-widget-container :naked="props.style % 2 === 0" :show-header="false">
|
||||
<ui-container :naked="props.style % 2 === 0" :show-header="false">
|
||||
<div class="mkw-analog-clock--body">
|
||||
<mk-analog-clock :dark="$store.state.device.darkmode" :smooth="props.style < 2"/>
|
||||
</div>
|
||||
</mk-widget-container>
|
||||
</ui-container>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="anltbovirfeutcigvwgmgxipejaeozxi">
|
||||
<mk-widget-container :show-header="false" :naked="props.design == 1">
|
||||
<ui-container :show-header="false" :naked="props.design == 1">
|
||||
<div class="anltbovirfeutcigvwgmgxipejaeozxi-body"
|
||||
:data-found="announcements && announcements.length != 0"
|
||||
:data-melt="props.design == 1"
|
||||
@@ -23,7 +23,7 @@
|
||||
</p>
|
||||
<a v-if="announcements.length > 1" @click="next">{{ $t('next') }} >></a>
|
||||
</div>
|
||||
</mk-widget-container>
|
||||
</ui-container>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="mkw-calendar" :data-special="special" :data-mobile="platform == 'mobile'">
|
||||
<mk-widget-container :naked="props.design == 1" :show-header="false">
|
||||
<ui-container :naked="props.design == 1" :show-header="false">
|
||||
<div class="mkw-calendar--body">
|
||||
<div class="calendar" :data-is-holiday="isHoliday">
|
||||
<p class="month-and-year">
|
||||
@@ -31,7 +31,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</mk-widget-container>
|
||||
</ui-container>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<template>
|
||||
<div class="mkw-hashtags">
|
||||
<mk-widget-container :show-header="!props.compact">
|
||||
<template slot="header"><fa icon="hashtag"/>{{ $t('title') }}</template>
|
||||
<ui-container :show-header="!props.compact">
|
||||
<template #header><fa icon="hashtag"/>{{ $t('title') }}</template>
|
||||
|
||||
<div class="mkw-hashtags--body" :data-mobile="platform == 'mobile'">
|
||||
<mk-trends/>
|
||||
</div>
|
||||
</mk-widget-container>
|
||||
</ui-container>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ import wSlideshow from './slideshow.vue';
|
||||
import wTips from './tips.vue';
|
||||
import wNav from './nav.vue';
|
||||
import wHashtags from './hashtags.vue';
|
||||
import wInstance from './instance.vue';
|
||||
|
||||
Vue.component('mkw-analog-clock', wAnalogClock);
|
||||
Vue.component('mkw-nav', wNav);
|
||||
@@ -27,3 +28,4 @@ Vue.component('mkw-memo', wMemo);
|
||||
Vue.component('mkw-rss', wRss);
|
||||
Vue.component('mkw-version', wVersion);
|
||||
Vue.component('mkw-hashtags', wHashtags);
|
||||
Vue.component('mkw-instance', wInstance);
|
||||
|
||||
14
src/client/app/common/views/widgets/instance.vue
Normal file
14
src/client/app/common/views/widgets/instance.vue
Normal file
@@ -0,0 +1,14 @@
|
||||
<template>
|
||||
<div class="mkw-instance">
|
||||
<ui-container>
|
||||
<mk-instance/>
|
||||
</ui-container>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import define from '../../../common/define-widget';
|
||||
export default define({
|
||||
name: 'instance'
|
||||
});
|
||||
</script>
|
||||
@@ -1,13 +1,13 @@
|
||||
<template>
|
||||
<div class="mkw-memo">
|
||||
<mk-widget-container :show-header="!props.compact">
|
||||
<template slot="header"><fa :icon="['far', 'sticky-note']"/>{{ $t('title') }}</template>
|
||||
<ui-container :show-header="!props.compact">
|
||||
<template #header><fa :icon="['far', 'sticky-note']"/>{{ $t('title') }}</template>
|
||||
|
||||
<div class="mkw-memo--body">
|
||||
<textarea v-model="text" :placeholder="$t('placeholder')" @input="onChange"></textarea>
|
||||
<button @click="saveMemo" :disabled="!changed">{{ $t('save') }}</button>
|
||||
</div>
|
||||
</mk-widget-container>
|
||||
</ui-container>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<template>
|
||||
<div class="mkw-nav">
|
||||
<mk-widget-container>
|
||||
<ui-container>
|
||||
<div class="mkw-nav--body">
|
||||
<mk-nav/>
|
||||
</div>
|
||||
</mk-widget-container>
|
||||
</ui-container>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="mkw-photo-stream" :class="$style.root" :data-melt="props.design == 2">
|
||||
<mk-widget-container :show-header="props.design == 0" :naked="props.design == 2">
|
||||
<template slot="header"><fa icon="camera"/>{{ $t('title') }}</template>
|
||||
<ui-container :show-header="props.design == 0" :naked="props.design == 2">
|
||||
<template #header><fa icon="camera"/>{{ $t('title') }}</template>
|
||||
|
||||
<p :class="$style.fetching" v-if="fetching"><fa icon="spinner" pulse fixed-width/>{{ $t('@.loading') }}<mk-ellipsis/></p>
|
||||
<div :class="$style.stream" v-if="!fetching && images.length > 0">
|
||||
@@ -13,7 +13,7 @@
|
||||
></div>
|
||||
</div>
|
||||
<p :class="$style.empty" v-if="!fetching && images.length == 0">{{ $t('no-photos') }}</p>
|
||||
</mk-widget-container>
|
||||
</ui-container>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<div class="mkw-posts-monitor">
|
||||
<mk-widget-container :show-header="props.design == 0" :naked="props.design == 2">
|
||||
<template slot="header"><fa icon="chart-line"/>{{ $t('title') }}</template>
|
||||
<button slot="func" @click="toggle" :title="$t('toggle')"><fa icon="sort"/></button>
|
||||
<ui-container :show-header="props.design == 0" :naked="props.design == 2">
|
||||
<template #header><fa icon="chart-line"/>{{ $t('title') }}</template>
|
||||
<template #func><button @click="toggle" :title="$t('toggle')"><fa icon="sort"/></button></template>
|
||||
|
||||
<div class="qpdmibaztplkylerhdbllwcokyrfxeyj" :class="{ dual: props.view == 0 }">
|
||||
<svg :viewBox="`0 0 ${ viewBoxX } ${ viewBoxY }`" v-show="props.view != 2">
|
||||
@@ -64,7 +64,7 @@
|
||||
<text x="1" y="5">Fedi</text>
|
||||
</svg>
|
||||
</div>
|
||||
</mk-widget-container>
|
||||
</ui-container>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<div class="mkw-rss">
|
||||
<mk-widget-container :show-header="!props.compact">
|
||||
<template slot="header"><fa icon="rss-square"/>RSS</template>
|
||||
<button slot="func" title="設定" @click="setting"><fa icon="cog"/></button>
|
||||
<ui-container :show-header="!props.compact">
|
||||
<template #header><fa icon="rss-square"/>RSS</template>
|
||||
<template #func><button title="設定" @click="setting"><fa icon="cog"/></button></template>
|
||||
|
||||
<div class="mkw-rss--body" :data-mobile="platform == 'mobile'">
|
||||
<p class="fetching" v-if="fetching"><fa icon="spinner" pulse fixed-width/>{{ $t('@.loading') }}<mk-ellipsis/></p>
|
||||
@@ -10,7 +10,7 @@
|
||||
<a v-for="item in items" :href="item.link" target="_blank">{{ item.title }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</mk-widget-container>
|
||||
</ui-container>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<div class="mkw-server">
|
||||
<mk-widget-container :show-header="props.design == 0" :naked="props.design == 2">
|
||||
<template slot="header"><fa icon="server"/>{{ $t('title') }}</template>
|
||||
<button slot="func" @click="toggle" :title="$t('toggle')"><fa icon="sort"/></button>
|
||||
<ui-container :show-header="props.design == 0" :naked="props.design == 2">
|
||||
<template #header><fa icon="server"/>{{ $t('title') }}</template>
|
||||
<template #func><button @click="toggle" :title="$t('toggle')"><fa icon="sort"/></button></template>
|
||||
|
||||
<p :class="$style.fetching" v-if="fetching"><fa icon="spinner" pulse fixed-width/>{{ $t('@.loading') }}<mk-ellipsis/></p>
|
||||
<template v-if="!fetching">
|
||||
@@ -13,7 +13,7 @@
|
||||
<x-uptimes v-show="props.view == 4" :connection="connection"/>
|
||||
<x-info v-show="props.view == 5" :connection="connection" :meta="meta"/>
|
||||
</template>
|
||||
</mk-widget-container>
|
||||
</ui-container>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { clientVersion as version, codename } from '../../../config';
|
||||
import { version, codename } from '../../../config';
|
||||
import define from '../../../common/define-widget';
|
||||
export default define({
|
||||
name: 'version'
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
declare const _LANGS_: string[];
|
||||
declare const _COPYRIGHT_: string;
|
||||
declare const _VERSION_: string;
|
||||
declare const _CLIENT_VERSION_: string;
|
||||
declare const _CODENAME_: string;
|
||||
declare const _ENV_: string;
|
||||
|
||||
@@ -17,6 +16,5 @@ export const langs = _LANGS_;
|
||||
export const locale = JSON.parse(localStorage.getItem('locale'));
|
||||
export const copyright = _COPYRIGHT_;
|
||||
export const version = _VERSION_;
|
||||
export const clientVersion = _CLIENT_VERSION_;
|
||||
export const codename = _CODENAME_;
|
||||
export const env = _ENV_;
|
||||
|
||||
@@ -1,20 +1,10 @@
|
||||
import { apiUrl, locale } from '../../config';
|
||||
import CropWindow from '../views/components/crop-window.vue';
|
||||
import ProgressDialog from '../views/components/progress-dialog.vue';
|
||||
|
||||
export default ($root: any) => {
|
||||
|
||||
const cropImage = file => new Promise((resolve, reject) => {
|
||||
|
||||
const regex = RegExp('\.(jpg|jpeg|png|gif|webp|bmp|tiff)$');
|
||||
if (!regex.test(file.name) ) {
|
||||
$root.dialog({
|
||||
title: locale['desktop']['invalid-filetype'],
|
||||
text: null
|
||||
});
|
||||
return reject('invalid-filetype');
|
||||
}
|
||||
|
||||
const cropImage = file => new Promise(async (resolve, reject) => {
|
||||
const CropWindow = await import('../views/components/crop-window.vue').then(x => x.default);
|
||||
const w = $root.new(CropWindow, {
|
||||
image: file,
|
||||
title: locale['desktop']['avatar-crop-title'],
|
||||
|
||||
@@ -1,20 +1,10 @@
|
||||
import { apiUrl, locale } from '../../config';
|
||||
import CropWindow from '../views/components/crop-window.vue';
|
||||
import ProgressDialog from '../views/components/progress-dialog.vue';
|
||||
|
||||
export default ($root: any) => {
|
||||
|
||||
const cropImage = file => new Promise((resolve, reject) => {
|
||||
|
||||
const regex = RegExp('\.(jpg|jpeg|png|gif|webp|bmp|tiff)$');
|
||||
if (!regex.test(file.name) ) {
|
||||
$root.dialog({
|
||||
title: locale['desktop']['invalid-filetype'],
|
||||
text: null
|
||||
});
|
||||
return reject('invalid-filetype');
|
||||
}
|
||||
|
||||
const cropImage = file => new Promise(async (resolve, reject) => {
|
||||
const CropWindow = await import('../views/components/crop-window.vue').then(x => x.default);
|
||||
const w = $root.new(CropWindow, {
|
||||
image: file,
|
||||
title: locale['desktop']['banner-crop-title'],
|
||||
|
||||
@@ -12,19 +12,12 @@ import init from '../init';
|
||||
import fuckAdBlock from '../common/scripts/fuck-ad-block';
|
||||
import composeNotification from '../common/scripts/compose-notification';
|
||||
|
||||
import MkIndex from './views/pages/index.vue';
|
||||
import MkHome from './views/pages/home.vue';
|
||||
import MkDeck from './views/pages/deck/deck.vue';
|
||||
import MkUser from './views/pages/user/user.vue';
|
||||
import MkHome from './views/home/home.vue';
|
||||
import MkDeck from './views/deck/deck.vue';
|
||||
import MkUserFollowingOrFollowers from './views/pages/user-following-or-followers.vue';
|
||||
import MkFavorites from './views/pages/favorites.vue';
|
||||
import MkSelectDrive from './views/pages/selectdrive.vue';
|
||||
import MkDrive from './views/pages/drive.vue';
|
||||
import MkHomeCustomize from './views/pages/home-customize.vue';
|
||||
import MkMessagingRoom from './views/pages/messaging-room.vue';
|
||||
import MkNote from './views/pages/note.vue';
|
||||
import MkSearch from './views/pages/search.vue';
|
||||
import MkTag from './views/pages/tag.vue';
|
||||
import MkReversi from './views/pages/games/reversi.vue';
|
||||
import MkShare from './views/pages/share.vue';
|
||||
import MkFollow from '../common/views/pages/follow.vue';
|
||||
@@ -36,6 +29,7 @@ import PostFormWindow from './views/components/post-form-window.vue';
|
||||
import RenoteFormWindow from './views/components/renote-form-window.vue';
|
||||
import MkChooseFileFromDriveWindow from './views/components/choose-file-from-drive-window.vue';
|
||||
import MkChooseFolderFromDriveWindow from './views/components/choose-folder-from-drive-window.vue';
|
||||
import MkHomeTimeline from './views/home/timeline.vue';
|
||||
import Notification from './views/components/ui-notification.vue';
|
||||
|
||||
import { url } from '../config';
|
||||
@@ -44,7 +38,7 @@ import MiOS from '../mios';
|
||||
/**
|
||||
* init
|
||||
*/
|
||||
init(async (launch) => {
|
||||
init(async (launch, os) => {
|
||||
Vue.mixin({
|
||||
methods: {
|
||||
$contextmenu(e, menu, opts?) {
|
||||
@@ -130,35 +124,64 @@ init(async (launch) => {
|
||||
require('./views/components');
|
||||
require('./views/widgets');
|
||||
|
||||
os.store.commit('device/set', {
|
||||
key: 'inDeckMode',
|
||||
value: os.store.getters.isSignedIn && os.store.state.device.deckMode
|
||||
&& (document.location.pathname === '/' || window.performance.navigation.type === 1)
|
||||
});
|
||||
|
||||
// Init router
|
||||
const router = new VueRouter({
|
||||
mode: 'history',
|
||||
routes: [
|
||||
{ path: '/', name: 'index', component: MkIndex },
|
||||
{ path: '/home', name: 'home', component: MkHome },
|
||||
{ path: '/deck', name: 'deck', component: MkDeck },
|
||||
{ path: '/i/customize-home', component: MkHomeCustomize },
|
||||
{ path: '/i/favorites', component: MkFavorites },
|
||||
os.store.state.device.inDeckMode
|
||||
? { path: '/', name: 'index', component: MkDeck, children: [
|
||||
{ path: '/@:user', component: () => import('./views/deck/deck.user-column.vue').then(m => m.default), children: [
|
||||
{ path: '', name: 'user', component: () => import('./views/deck/deck.user-column.home.vue').then(m => m.default) },
|
||||
{ path: 'following', component: () => import('../common/views/pages/following.vue').then(m => m.default) },
|
||||
{ path: 'followers', component: () => import('../common/views/pages/followers.vue').then(m => m.default) },
|
||||
]},
|
||||
{ path: '/notes/:note', name: 'note', component: () => import('./views/deck/deck.note-column.vue').then(m => m.default) },
|
||||
{ path: '/search', component: () => import('./views/deck/deck.search-column.vue').then(m => m.default) },
|
||||
{ path: '/tags/:tag', name: 'tag', component: () => import('./views/deck/deck.hashtag-column.vue').then(m => m.default) },
|
||||
{ path: '/featured', name: 'featured', component: () => import('./views/deck/deck.featured-column.vue').then(m => m.default) },
|
||||
{ path: '/explore', name: 'explore', component: () => import('./views/deck/deck.explore-column.vue').then(m => m.default) },
|
||||
{ path: '/explore/tags/:tag', name: 'explore-tag', props: true, component: () => import('./views/deck/deck.explore-column.vue').then(m => m.default) },
|
||||
{ path: '/i/favorites', component: () => import('./views/deck/deck.favorites-column.vue').then(m => m.default) }
|
||||
]}
|
||||
: { path: '/', component: MkHome, children: [
|
||||
{ path: '', name: 'index', component: MkHomeTimeline },
|
||||
{ path: '/@:user', component: () => import('./views/home/user/index.vue').then(m => m.default), children: [
|
||||
{ path: '', name: 'user', component: () => import('./views/home/user/user.home.vue').then(m => m.default) },
|
||||
{ path: 'following', component: () => import('../common/views/pages/following.vue').then(m => m.default) },
|
||||
{ path: 'followers', component: () => import('../common/views/pages/followers.vue').then(m => m.default) },
|
||||
]},
|
||||
{ path: '/notes/:note', name: 'note', component: () => import('./views/home/note.vue').then(m => m.default) },
|
||||
{ path: '/search', component: () => import('./views/home/search.vue').then(m => m.default) },
|
||||
{ path: '/tags/:tag', name: 'tag', component: () => import('./views/home/tag.vue').then(m => m.default) },
|
||||
{ path: '/featured', name: 'featured', component: () => import('./views/home/featured.vue').then(m => m.default) },
|
||||
{ path: '/explore', name: 'explore', component: () => import('../common/views/pages/explore.vue').then(m => m.default) },
|
||||
{ path: '/explore/tags/:tag', name: 'explore-tag', props: true, component: () => import('../common/views/pages/explore.vue').then(m => m.default) },
|
||||
{ path: '/i/favorites', component: () => import('./views/home/favorites.vue').then(m => m.default) },
|
||||
]},
|
||||
{ path: '/i/messaging/:user', component: MkMessagingRoom },
|
||||
{ path: '/i/drive', component: MkDrive },
|
||||
{ path: '/i/drive/folder/:folder', component: MkDrive },
|
||||
{ path: '/i/settings', component: MkSettings },
|
||||
{ path: '/selectdrive', component: MkSelectDrive },
|
||||
{ path: '/search', component: MkSearch },
|
||||
{ path: '/tags/:tag', name: 'tag', component: MkTag },
|
||||
{ path: '/share', component: MkShare },
|
||||
{ path: '/games/reversi/:game?', component: MkReversi },
|
||||
{ path: '/@:user', name: 'user', component: MkUser },
|
||||
{ path: '/@:user/following', name: 'userFollowing', component: MkUserFollowingOrFollowers },
|
||||
{ path: '/@:user/followers', name: 'userFollowers', component: MkUserFollowingOrFollowers },
|
||||
{ path: '/notes/:note', name: 'note', component: MkNote },
|
||||
{ path: '/authorize-follow', component: MkFollow },
|
||||
{ path: '/deck', redirect: '/' },
|
||||
{ path: '*', component: MkNotFound }
|
||||
]
|
||||
],
|
||||
scrollBehavior(to, from, savedPosition) {
|
||||
return { x: 0, y: 0 };
|
||||
}
|
||||
});
|
||||
|
||||
// Launch the app
|
||||
const [app, os] = launch(router);
|
||||
const [app, _] = launch(router);
|
||||
|
||||
if (os.store.getters.isSignedIn) {
|
||||
/**
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
<template>
|
||||
<div class="mk-activity">
|
||||
<mk-widget-container :show-header="design == 0" :naked="design == 2">
|
||||
<template slot="header"><fa icon="chart-bar"/>{{ $t('title') }}</template>
|
||||
<button slot="func" :title="$t('toggle')" @click="toggle"><fa icon="sort"/></button>
|
||||
<ui-container :show-header="design == 0" :naked="design == 2">
|
||||
<template #header><fa icon="chart-bar"/>{{ $t('title') }}</template>
|
||||
<template #func><button :title="$t('toggle')" @click="toggle"><fa icon="sort"/></button></template>
|
||||
|
||||
<p :class="$style.fetching" v-if="fetching"><fa icon="spinner" pulse fixed-width/>{{ $t('@.loading') }}<mk-ellipsis/></p>
|
||||
<template v-else>
|
||||
<x-calendar v-show="view == 0" :data="[].concat(activity)"/>
|
||||
<x-chart v-show="view == 1" :data="[].concat(activity)"/>
|
||||
</template>
|
||||
</mk-widget-container>
|
||||
</ui-container>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
<template>
|
||||
<mk-window ref="window" is-modal width="800px" height="500px" @closed="destroyDom">
|
||||
<span slot="header" class="jqiaciqv">
|
||||
<span class="title">{{ $t('choose-prompt') }}</span>
|
||||
<span class="count" v-if="multiple && files.length > 0">({{ $t('chosen-files', { count: files.length }) }})</span>
|
||||
</span>
|
||||
<template #header>
|
||||
<span class="jqiaciqv">
|
||||
<span class="title">{{ $t('choose-prompt') }}</span>
|
||||
<span class="count" v-if="multiple && files.length > 0">({{ $t('chosen-files', { count: files.length }) }})</span>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<div class="rqsvbumu">
|
||||
<x-drive
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<mk-window ref="window" is-modal width="800px" height="500px" @closed="destroyDom">
|
||||
<span slot="header">
|
||||
<template #header>
|
||||
<span>{{ $t('choose-prompt') }}</span>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<div class="hllkpxxu">
|
||||
<x-drive
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<mk-window ref="window" is-modal width="800px" :can-close="false">
|
||||
<span slot="header"><fa icon="crop"/>{{ title }}</span>
|
||||
<template #header><fa icon="crop"/>{{ title }}</template>
|
||||
<div class="body">
|
||||
<vue-cropper ref="cropper"
|
||||
:src="image.url"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<mk-window ref="window" @closed="destroyDom" width="800px" height="500px" :popout-url="popout">
|
||||
<template slot="header">
|
||||
<template #header>
|
||||
<p v-if="usage" :class="$style.info"><b>{{ usage.toFixed(1) }}%</b> {{ $t('used') }}</p>
|
||||
<span :class="$style.title"><fa icon="cloud"/>{{ $t('@.drive') }}</span>
|
||||
</template>
|
||||
|
||||
@@ -1,165 +0,0 @@
|
||||
<template>
|
||||
<div class="mk-friends-maker">
|
||||
<p class="title">{{ $t('title') }}</p>
|
||||
<div class="users" v-if="!fetching && users.length > 0">
|
||||
<div class="user" v-for="user in users" :key="user.id">
|
||||
<mk-avatar class="avatar" :user="user" target="_blank"/>
|
||||
<div class="body">
|
||||
<router-link class="name" :to="user | userPage" v-user-preview="user.id">
|
||||
<mk-user-name :user="user"/>
|
||||
</router-link>
|
||||
<p class="username">@{{ user | acct }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="empty" v-if="!fetching && users.length == 0">{{ $t('empty') }}</p>
|
||||
<p class="fetching" v-if="fetching"><fa icon="spinner" pulse fixed-width/>{{ $t('fetching') }}<mk-ellipsis/></p>
|
||||
<a class="refresh" @click="refresh">{{ $t('refresh') }}</a>
|
||||
<button class="close" @click="destroyDom()" :title="$t('title')"><fa icon="times"/></button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import i18n from '../../../i18n';
|
||||
|
||||
export default Vue.extend({
|
||||
i18n: i18n('desktop/views/components/friends-maker.vue'),
|
||||
data() {
|
||||
return {
|
||||
users: [],
|
||||
fetching: true,
|
||||
limit: 6,
|
||||
page: 0
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.fetch();
|
||||
},
|
||||
methods: {
|
||||
fetch() {
|
||||
this.fetching = true;
|
||||
this.users = [];
|
||||
|
||||
this.$root.api('users/recommendation', {
|
||||
limit: this.limit,
|
||||
offset: this.limit * this.page
|
||||
}).then(users => {
|
||||
this.users = users;
|
||||
this.fetching = false;
|
||||
});
|
||||
},
|
||||
refresh() {
|
||||
if (this.users.length < this.limit) {
|
||||
this.page = 0;
|
||||
} else {
|
||||
this.page++;
|
||||
}
|
||||
this.fetch();
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
.mk-friends-maker
|
||||
padding 24px
|
||||
|
||||
> .title
|
||||
margin 0 0 12px 0
|
||||
font-size 1em
|
||||
font-weight bold
|
||||
color #888
|
||||
|
||||
> .users
|
||||
&:after
|
||||
content ""
|
||||
display block
|
||||
clear both
|
||||
|
||||
> .user
|
||||
padding 16px
|
||||
width 238px
|
||||
float left
|
||||
|
||||
&:after
|
||||
content ""
|
||||
display block
|
||||
clear both
|
||||
|
||||
> .avatar
|
||||
display block
|
||||
float left
|
||||
margin 0 12px 0 0
|
||||
width 42px
|
||||
height 42px
|
||||
border-radius 8px
|
||||
|
||||
> .body
|
||||
float left
|
||||
width calc(100% - 54px)
|
||||
|
||||
> .name
|
||||
margin 0
|
||||
font-size 16px
|
||||
line-height 24px
|
||||
color #555
|
||||
|
||||
> .username
|
||||
margin 0
|
||||
font-size 15px
|
||||
line-height 16px
|
||||
color #ccc
|
||||
|
||||
> .mk-follow-button
|
||||
position absolute
|
||||
top 16px
|
||||
right 16px
|
||||
|
||||
> .empty
|
||||
margin 0
|
||||
padding 16px
|
||||
text-align center
|
||||
color var(--text)
|
||||
|
||||
> .fetching
|
||||
margin 0
|
||||
padding 16px
|
||||
text-align center
|
||||
color var(--text)
|
||||
|
||||
> [data-icon]
|
||||
margin-right 4px
|
||||
|
||||
> .refresh
|
||||
display block
|
||||
margin 0 8px 0 0
|
||||
text-align right
|
||||
font-size 0.9em
|
||||
color #999
|
||||
|
||||
> .close
|
||||
cursor pointer
|
||||
display block
|
||||
position absolute
|
||||
top 6px
|
||||
right 6px
|
||||
z-index 1
|
||||
margin 0
|
||||
padding 0
|
||||
font-size 1.2em
|
||||
color #999
|
||||
border none
|
||||
outline none
|
||||
background transparent
|
||||
|
||||
&:hover
|
||||
color #555
|
||||
|
||||
&:active
|
||||
color #222
|
||||
|
||||
> [data-icon]
|
||||
padding 14px
|
||||
|
||||
</style>
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<mk-window ref="window" width="500px" height="560px" :popout-url="popout" @closed="destroyDom">
|
||||
<span slot="header" :class="$style.header"><fa icon="gamepad"/>{{ $t('game') }}</span>
|
||||
<template #header><fa icon="gamepad"/> {{ $t('game') }}</template>
|
||||
<x-reversi :class="$style.content" @gamed="g => game = g"/>
|
||||
</mk-window>
|
||||
</template>
|
||||
@@ -31,10 +31,6 @@ export default Vue.extend({
|
||||
</script>
|
||||
|
||||
<style lang="stylus" module>
|
||||
.header
|
||||
> [data-icon]
|
||||
margin-right 4px
|
||||
|
||||
.content
|
||||
height 100%
|
||||
overflow auto
|
||||
|
||||
@@ -1,396 +0,0 @@
|
||||
<template>
|
||||
<div class="mk-home" :data-customize="customize">
|
||||
<div class="customize" v-if="customize">
|
||||
<router-link to="/"><fa icon="check"/>{{ $t('done') }}</router-link>
|
||||
<div>
|
||||
<div class="adder">
|
||||
<p>{{ $t('add-widget') }}</p>
|
||||
<select v-model="widgetAdderSelected">
|
||||
<option value="profile">{{ $t('@.widgets.profile') }}</option>
|
||||
<option value="analog-clock">{{ $t('@.widgets.analog-clock') }}</option>
|
||||
<option value="calendar">{{ $t('@.widgets.calendar') }}</option>
|
||||
<option value="timemachine">{{ $t('@.widgets.timemachine') }}</option>
|
||||
<option value="activity">{{ $t('@.widgets.activity') }}</option>
|
||||
<option value="rss">{{ $t('@.widgets.rss') }}</option>
|
||||
<option value="trends">{{ $t('@.widgets.trends') }}</option>
|
||||
<option value="photo-stream">{{ $t('@.widgets.photo-stream') }}</option>
|
||||
<option value="slideshow">{{ $t('@.widgets.slideshow') }}</option>
|
||||
<option value="version">{{ $t('@.widgets.version') }}</option>
|
||||
<option value="broadcast">{{ $t('@.widgets.broadcast') }}</option>
|
||||
<option value="notifications">{{ $t('@.widgets.notifications') }}</option>
|
||||
<option value="users">{{ $t('@.widgets.users') }}</option>
|
||||
<option value="polls">{{ $t('@.widgets.polls') }}</option>
|
||||
<option value="post-form">{{ $t('@.widgets.post-form') }}</option>
|
||||
<option value="messaging">{{ $t('@.widgets.messaging') }}</option>
|
||||
<option value="memo">{{ $t('@.widgets.memo') }}</option>
|
||||
<option value="hashtags">{{ $t('@.widgets.hashtags') }}</option>
|
||||
<option value="posts-monitor">{{ $t('@.widgets.posts-monitor') }}</option>
|
||||
<option value="server">{{ $t('@.widgets.server') }}</option>
|
||||
<option value="nav">{{ $t('@.widgets.nav') }}</option>
|
||||
<option value="tips">{{ $t('@.widgets.tips') }}</option>
|
||||
</select>
|
||||
<button @click="addWidget">{{ $t('add') }}</button>
|
||||
</div>
|
||||
<div class="trash">
|
||||
<x-draggable v-model="trash" :options="{ group: 'x' }" @add="onTrash"></x-draggable>
|
||||
<p>{{ $t('@.trash') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="main" :class="{ side: widgets.left.length == 0 || widgets.right.length == 0 }">
|
||||
<template v-if="customize">
|
||||
<x-draggable v-for="place in ['left', 'right']"
|
||||
:list="widgets[place]"
|
||||
:class="place"
|
||||
:data-place="place"
|
||||
:options="{ group: 'x', animation: 150 }"
|
||||
@sort="onWidgetSort"
|
||||
:key="place"
|
||||
>
|
||||
<div v-for="widget in widgets[place]" class="customize-container" :key="widget.id" @contextmenu.stop.prevent="onWidgetContextmenu(widget.id)">
|
||||
<component :is="`mkw-${widget.name}`" :widget="widget" :ref="widget.id" :is-customize-mode="true" platform="desktop"/>
|
||||
</div>
|
||||
</x-draggable>
|
||||
<div class="main">
|
||||
<a @click="hint">{{ $t('@.customization-tips.title') }}</a>
|
||||
<div>
|
||||
<mk-post-form v-if="$store.state.settings.showPostFormOnTopOfTl"/>
|
||||
<mk-timeline ref="tl" @loaded="onTlLoaded"/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div v-for="place in ['left', 'right']" :class="place">
|
||||
<component v-for="widget in widgets[place]" :is="`mkw-${widget.name}`" :key="widget.id" :ref="widget.id" :widget="widget" @chosen="warp" platform="desktop"/>
|
||||
</div>
|
||||
<div class="main">
|
||||
<mk-post-form class="form" v-if="$store.state.settings.showPostFormOnTopOfTl"/>
|
||||
<mk-timeline class="tl" ref="tl" @loaded="onTlLoaded" v-if="mode == 'timeline'"/>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import i18n from '../../../i18n';
|
||||
import * as XDraggable from 'vuedraggable';
|
||||
import * as uuid from 'uuid';
|
||||
|
||||
const defaultDesktopHomeWidgets = {
|
||||
left: [
|
||||
'profile',
|
||||
'calendar',
|
||||
'activity',
|
||||
'rss',
|
||||
'hashtags',
|
||||
'photo-stream',
|
||||
'version'
|
||||
],
|
||||
right: [
|
||||
'broadcast',
|
||||
'notifications',
|
||||
'users',
|
||||
'polls',
|
||||
'server',
|
||||
'nav',
|
||||
'tips'
|
||||
]
|
||||
};
|
||||
|
||||
//#region Construct home data
|
||||
const _defaultDesktopHomeWidgets = [];
|
||||
|
||||
for (const widget of defaultDesktopHomeWidgets.left) {
|
||||
_defaultDesktopHomeWidgets.push({
|
||||
name: widget,
|
||||
id: uuid(),
|
||||
place: 'left',
|
||||
data: {}
|
||||
});
|
||||
}
|
||||
|
||||
for (const widget of defaultDesktopHomeWidgets.right) {
|
||||
_defaultDesktopHomeWidgets.push({
|
||||
name: widget,
|
||||
id: uuid(),
|
||||
place: 'right',
|
||||
data: {}
|
||||
});
|
||||
}
|
||||
//#endregion
|
||||
|
||||
export default Vue.extend({
|
||||
i18n: i18n('desktop/views/components/home.vue'),
|
||||
components: {
|
||||
XDraggable
|
||||
},
|
||||
|
||||
props: {
|
||||
customize: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
mode: {
|
||||
type: String,
|
||||
default: 'timeline'
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
connection: null,
|
||||
widgetAdderSelected: null,
|
||||
trash: []
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
home(): any[] {
|
||||
return this.$store.state.settings.home || [];
|
||||
},
|
||||
left(): any[] {
|
||||
return this.home.filter(w => w.place == 'left');
|
||||
},
|
||||
right(): any[] {
|
||||
return this.home.filter(w => w.place == 'right');
|
||||
},
|
||||
widgets(): any {
|
||||
return {
|
||||
left: this.left,
|
||||
right: this.right
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
if (this.$store.state.settings.home == null) {
|
||||
this.$root.api('i/update_home', {
|
||||
home: _defaultDesktopHomeWidgets
|
||||
}).then(() => {
|
||||
this.$store.commit('settings/setHome', _defaultDesktopHomeWidgets);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.connection = this.$root.stream.useSharedConnection('main');
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
this.connection.dispose();
|
||||
},
|
||||
|
||||
methods: {
|
||||
hint() {
|
||||
this.$root.dialog({
|
||||
title: this.$t('@.customization-tips.title'),
|
||||
text: this.$t('@.customization-tips.paragraph')
|
||||
});
|
||||
},
|
||||
|
||||
onTlLoaded() {
|
||||
this.$emit('loaded');
|
||||
},
|
||||
|
||||
onWidgetContextmenu(widgetId) {
|
||||
const w = (this.$refs[widgetId] as any)[0];
|
||||
if (w.func) w.func();
|
||||
},
|
||||
|
||||
onWidgetSort() {
|
||||
this.saveHome();
|
||||
},
|
||||
|
||||
onTrash(evt) {
|
||||
this.saveHome();
|
||||
},
|
||||
|
||||
addWidget() {
|
||||
this.$store.dispatch('settings/addHomeWidget', {
|
||||
name: this.widgetAdderSelected,
|
||||
id: uuid(),
|
||||
place: 'left',
|
||||
data: {}
|
||||
});
|
||||
},
|
||||
|
||||
saveHome() {
|
||||
const left = this.widgets.left;
|
||||
const right = this.widgets.right;
|
||||
this.$store.commit('settings/setHome', left.concat(right));
|
||||
for (const w of left) w.place = 'left';
|
||||
for (const w of right) w.place = 'right';
|
||||
this.$root.api('i/update_home', {
|
||||
home: this.home
|
||||
});
|
||||
},
|
||||
|
||||
warp(date) {
|
||||
(this.$refs.tl as any).warp(date);
|
||||
},
|
||||
|
||||
focus() {
|
||||
(this.$refs.tl as any).focus();
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
.mk-home
|
||||
display block
|
||||
|
||||
&[data-customize]
|
||||
padding-top 48px
|
||||
background-image url('/assets/desktop/grid.svg')
|
||||
|
||||
> .main > .main
|
||||
> a
|
||||
display block
|
||||
margin-bottom 8px
|
||||
text-align center
|
||||
|
||||
> div
|
||||
cursor not-allowed !important
|
||||
|
||||
> *
|
||||
pointer-events none
|
||||
|
||||
&:not([data-customize])
|
||||
> .main > *:empty
|
||||
display none
|
||||
|
||||
> .customize
|
||||
position fixed
|
||||
z-index 1000
|
||||
top 0
|
||||
left 0
|
||||
width 100%
|
||||
height 48px
|
||||
color var(--text)
|
||||
background var(--desktopHeaderBg)
|
||||
box-shadow 0 1px 1px rgba(#000, 0.075)
|
||||
|
||||
> a
|
||||
display block
|
||||
position absolute
|
||||
z-index 1001
|
||||
top 0
|
||||
right 0
|
||||
padding 0 16px
|
||||
line-height 48px
|
||||
text-decoration none
|
||||
color var(--primaryForeground)
|
||||
background var(--primary)
|
||||
transition background 0.1s ease
|
||||
|
||||
&:hover
|
||||
background var(--primaryLighten10)
|
||||
|
||||
&:active
|
||||
background var(--primaryDarken10)
|
||||
transition background 0s ease
|
||||
|
||||
> [data-icon]
|
||||
margin-right 8px
|
||||
|
||||
> div
|
||||
display flex
|
||||
margin 0 auto
|
||||
max-width 1220px - 32px
|
||||
|
||||
> div
|
||||
width 50%
|
||||
|
||||
&.adder
|
||||
> p
|
||||
display inline
|
||||
line-height 48px
|
||||
|
||||
&.trash
|
||||
border-left solid 1px var(--faceDivider)
|
||||
|
||||
> div
|
||||
width 100%
|
||||
height 100%
|
||||
|
||||
> p
|
||||
position absolute
|
||||
top 0
|
||||
left 0
|
||||
width 100%
|
||||
line-height 48px
|
||||
margin 0
|
||||
text-align center
|
||||
pointer-events none
|
||||
|
||||
> .main
|
||||
display flex
|
||||
justify-content center
|
||||
margin 0 auto
|
||||
max-width 1240px
|
||||
|
||||
> *
|
||||
.customize-container
|
||||
cursor move
|
||||
border-radius 6px
|
||||
|
||||
&:hover
|
||||
box-shadow 0 0 8px rgba(64, 120, 200, 0.3)
|
||||
|
||||
> *
|
||||
pointer-events none
|
||||
|
||||
> .main
|
||||
padding 16px
|
||||
width calc(100% - 280px * 2)
|
||||
order 2
|
||||
|
||||
> .form
|
||||
margin-bottom 16px
|
||||
box-shadow var(--shadow)
|
||||
border-radius var(--round)
|
||||
|
||||
&.side
|
||||
> .main
|
||||
width calc(100% - 280px)
|
||||
max-width 680px
|
||||
|
||||
> *:not(.main)
|
||||
width 280px
|
||||
padding 16px 0 16px 0
|
||||
|
||||
> *:not(:last-child)
|
||||
margin-bottom 16px
|
||||
|
||||
> .left
|
||||
padding-left 16px
|
||||
order 1
|
||||
|
||||
> .right
|
||||
padding-right 16px
|
||||
order 3
|
||||
|
||||
&.side
|
||||
@media (max-width 1000px)
|
||||
> *:not(.main)
|
||||
display none
|
||||
|
||||
> .main
|
||||
width 100%
|
||||
max-width 700px
|
||||
margin 0 auto
|
||||
|
||||
&:not(.side)
|
||||
@media (max-width 1200px)
|
||||
> *:not(.main)
|
||||
display none
|
||||
|
||||
> .main
|
||||
width 100%
|
||||
max-width 700px
|
||||
margin 0 auto
|
||||
|
||||
</style>
|
||||
@@ -2,8 +2,6 @@ import Vue from 'vue';
|
||||
|
||||
import ui from './ui.vue';
|
||||
import uiNotification from './ui-notification.vue';
|
||||
import home from './home.vue';
|
||||
import timeline from './timeline.vue';
|
||||
import notes from './notes.vue';
|
||||
import subNoteContent from './sub-note-content.vue';
|
||||
import window from './window.vue';
|
||||
@@ -17,15 +15,12 @@ import notePreview from './note-preview.vue';
|
||||
import noteDetail from './note-detail.vue';
|
||||
import calendar from './calendar.vue';
|
||||
import activity from './activity.vue';
|
||||
import friendsMaker from './friends-maker.vue';
|
||||
import userCard from './user-card.vue';
|
||||
import userListTimeline from './user-list-timeline.vue';
|
||||
import widgetContainer from './widget-container.vue';
|
||||
import uiContainer from './ui-container.vue';
|
||||
|
||||
Vue.component('mk-ui', ui);
|
||||
Vue.component('mk-ui-notification', uiNotification);
|
||||
Vue.component('mk-home', home);
|
||||
Vue.component('mk-timeline', timeline);
|
||||
Vue.component('mk-notes', notes);
|
||||
Vue.component('mk-sub-note-content', subNoteContent);
|
||||
Vue.component('mk-window', window);
|
||||
@@ -39,7 +34,6 @@ Vue.component('mk-note-preview', notePreview);
|
||||
Vue.component('mk-note-detail', noteDetail);
|
||||
Vue.component('mk-calendar', calendar);
|
||||
Vue.component('mk-activity', activity);
|
||||
Vue.component('mk-friends-maker', friendsMaker);
|
||||
Vue.component('mk-user-card', userCard);
|
||||
Vue.component('mk-user-list-timeline', userListTimeline);
|
||||
Vue.component('mk-widget-container', widgetContainer);
|
||||
Vue.component('ui-container', uiContainer);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<mk-window ref="window" width="500px" height="560px" :popout-url="popout" @closed="destroyDom">
|
||||
<span slot="header" :class="$style.header"><fa icon="comments"/>{{ $t('title') }} <mk-user-name :user="user"/></span>
|
||||
<template #header><fa icon="comments"/> {{ $t('title') }} <mk-user-name :user="user"/></template>
|
||||
<x-messaging-room :user="user" :class="$style.content"/>
|
||||
</mk-window>
|
||||
</template>
|
||||
@@ -26,10 +26,6 @@ export default Vue.extend({
|
||||
</script>
|
||||
|
||||
<style lang="stylus" module>
|
||||
.header
|
||||
> [data-icon]
|
||||
margin-right 4px
|
||||
|
||||
.content
|
||||
height 100%
|
||||
overflow auto
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<mk-window ref="window" width="500px" height="560px" @closed="destroyDom">
|
||||
<span slot="header" :class="$style.header"><fa icon="comments"/>{{ $t('title') }}</span>
|
||||
<template #header :class="$style.header"><fa icon="comments"/>{{ $t('title') }}</template>
|
||||
<x-messaging :class="$style.content" @navigate="navigate"/>
|
||||
</mk-window>
|
||||
</template>
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
<template>
|
||||
<div class="mk-notes">
|
||||
<slot name="header"></slot>
|
||||
|
||||
<div class="newer-indicator" :style="{ top: $store.state.uiHeaderHeight + 'px' }" v-show="queue.length > 0"></div>
|
||||
|
||||
<slot name="empty" v-if="notes.length == 0 && !fetching && requestInitPromise == null"></slot>
|
||||
<slot name="empty" v-if="notes.length == 0 && !fetching && inited"></slot>
|
||||
|
||||
<mk-error v-if="!fetching && requestInitPromise != null" @retry="resolveInitPromise"/>
|
||||
<mk-error v-if="!fetching && !inited" @retry="init()"/>
|
||||
|
||||
<div class="placeholder" v-if="fetching">
|
||||
<template v-for="i in 10">
|
||||
@@ -23,8 +25,8 @@
|
||||
</template>
|
||||
</component>
|
||||
|
||||
<footer v-if="more">
|
||||
<button @click="loadMore" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }">
|
||||
<footer v-if="cursor != null">
|
||||
<button @click="more" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }">
|
||||
<template v-if="!moreFetching">{{ $t('@.load-more') }}</template>
|
||||
<template v-if="moreFetching"><fa icon="spinner" pulse fixed-width/></template>
|
||||
</button>
|
||||
@@ -43,24 +45,25 @@ const displayLimit = 30;
|
||||
|
||||
export default Vue.extend({
|
||||
i18n: i18n(),
|
||||
|
||||
components: {
|
||||
XNote
|
||||
},
|
||||
|
||||
props: {
|
||||
more: {
|
||||
type: Function,
|
||||
required: false
|
||||
makePromise: {
|
||||
required: true
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
requestInitPromise: null as () => Promise<any[]>,
|
||||
notes: [],
|
||||
queue: [],
|
||||
fetching: true,
|
||||
moreFetching: false
|
||||
moreFetching: false,
|
||||
inited: false,
|
||||
cursor: null
|
||||
};
|
||||
},
|
||||
|
||||
@@ -76,6 +79,10 @@ export default Vue.extend({
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
this.init();
|
||||
},
|
||||
|
||||
mounted() {
|
||||
window.addEventListener('scroll', this.onScroll, { passive: true });
|
||||
},
|
||||
@@ -97,27 +104,41 @@ export default Vue.extend({
|
||||
Vue.set((this as any).notes, i, note);
|
||||
},
|
||||
|
||||
init(promiseGenerator: () => Promise<any[]>) {
|
||||
this.requestInitPromise = promiseGenerator;
|
||||
this.resolveInitPromise();
|
||||
},
|
||||
|
||||
resolveInitPromise() {
|
||||
reload() {
|
||||
this.queue = [];
|
||||
this.notes = [];
|
||||
this.init();
|
||||
},
|
||||
|
||||
init() {
|
||||
this.fetching = true;
|
||||
|
||||
const promise = this.requestInitPromise();
|
||||
|
||||
promise.then(notes => {
|
||||
this.notes = notes;
|
||||
this.requestInitPromise = null;
|
||||
this.makePromise().then(x => {
|
||||
if (Array.isArray(x)) {
|
||||
this.notes = x;
|
||||
} else {
|
||||
this.notes = x.notes;
|
||||
this.cursor = x.cursor;
|
||||
}
|
||||
this.inited = true;
|
||||
this.fetching = false;
|
||||
this.$emit('inited');
|
||||
}, e => {
|
||||
this.fetching = false;
|
||||
});
|
||||
},
|
||||
|
||||
more() {
|
||||
if (this.cursor == null || this.moreFetching) return;
|
||||
this.moreFetching = true;
|
||||
this.makePromise(this.cursor).then(x => {
|
||||
this.notes = this.notes.concat(x.notes);
|
||||
this.cursor = x.cursor;
|
||||
this.moreFetching = false;
|
||||
}, e => {
|
||||
this.moreFetching = false;
|
||||
});
|
||||
},
|
||||
|
||||
prepend(note, silent = false) {
|
||||
// 弾く
|
||||
if (shouldMuteNote(this.$store.state.i, this.$store.state.settings, note)) return;
|
||||
@@ -151,10 +172,6 @@ export default Vue.extend({
|
||||
this.notes.push(note);
|
||||
},
|
||||
|
||||
tail() {
|
||||
return this.notes[this.notes.length - 1];
|
||||
},
|
||||
|
||||
releaseQueue() {
|
||||
for (const n of this.queue) {
|
||||
this.prepend(n, true);
|
||||
@@ -162,15 +179,6 @@ export default Vue.extend({
|
||||
this.queue = [];
|
||||
},
|
||||
|
||||
async loadMore() {
|
||||
if (this.more == null) return;
|
||||
if (this.moreFetching) return;
|
||||
|
||||
this.moreFetching = true;
|
||||
await this.more();
|
||||
this.moreFetching = false;
|
||||
},
|
||||
|
||||
onScroll() {
|
||||
if (this.isScrollTop()) {
|
||||
this.releaseQueue();
|
||||
@@ -178,7 +186,7 @@ export default Vue.extend({
|
||||
|
||||
if (this.$store.state.settings.fetchOnScroll !== false) {
|
||||
const current = window.scrollY + window.innerHeight;
|
||||
if (current > document.body.offsetHeight - 8) this.loadMore();
|
||||
if (current > document.body.offsetHeight - 8) this.more();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -187,6 +195,11 @@ export default Vue.extend({
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
.mk-notes
|
||||
background var(--face)
|
||||
box-shadow var(--shadow)
|
||||
border-radius var(--round)
|
||||
overflow hidden
|
||||
|
||||
.transition
|
||||
.mk-notes-enter
|
||||
.mk-notes-leave-to
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
<template>
|
||||
<mk-window class="mk-post-form-window" ref="window" is-modal @closed="onWindowClosed" :animation="animation">
|
||||
<span slot="header" class="mk-post-form-window--header">
|
||||
<span class="icon" v-if="geo"><fa icon="map-marker-alt"/></span>
|
||||
<span v-if="!reply">{{ $t('note') }}</span>
|
||||
<span v-if="reply">{{ $t('reply') }}</span>
|
||||
<span class="count" v-if="files.length != 0">{{ this.$t('attaches').replace('{}', files.length) }}</span>
|
||||
<span class="count" v-if="uploadings.length != 0">{{ this.$t('uploading-media').replace('{}', uploadings.length) }}<mk-ellipsis/></span>
|
||||
</span>
|
||||
<template #header>
|
||||
<span class="mk-post-form-window--header">
|
||||
<span class="icon" v-if="geo"><fa icon="map-marker-alt"/></span>
|
||||
<span v-if="!reply">{{ $t('note') }}</span>
|
||||
<span v-if="reply">{{ $t('reply') }}</span>
|
||||
<span class="count" v-if="files.length != 0">{{ this.$t('attaches').replace('{}', files.length) }}</span>
|
||||
<span class="count" v-if="uploadings.length != 0">{{ this.$t('uploading-media').replace('{}', uploadings.length) }}<mk-ellipsis/></span>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<div class="mk-post-form-window--body">
|
||||
<mk-note-preview v-if="reply" class="notePreview" :note="reply"/>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user