Compare commits

...

42 Commits

Author SHA1 Message Date
38e2853dcf 10.5.0 2018-10-10 03:38:39 +09:00
ba5a540ca3 Log misskey version 2018-10-10 03:37:51 +09:00
fb1e05c2e9 ストリーミングAPIでチャンネルに接続したときにconnectedメッセージを返すように 2018-10-10 03:28:11 +09:00
aba84612a7 Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2018-10-10 03:24:18 +09:00
9bebbf4e03 Add alias 2018-10-10 03:24:09 +09:00
e41b3f9c10 Merge pull request #2873 from mei23/mei-1010-pull-recquery
Fix users recommendation query
2018-10-10 02:18:31 +09:00
890dc05022 lint fix 2018-10-10 02:08:26 +09:00
375f86ec82 Fix users recommendation query 2018-10-10 02:04:16 +09:00
db248a69c8 10.4.0 2018-10-09 23:02:38 +09:00
5951288159 Merge pull request #2863 from syuilo/l10n_develop
New Crowdin translations
2018-10-09 23:01:51 +09:00
17b92c9db2 Fix bug 2018-10-09 22:48:45 +09:00
962d1060d9 New translations ja-JP.yml (Korean) 2018-10-09 22:32:14 +09:00
cb2640d961 New translations ja-JP.yml (Korean) 2018-10-09 22:11:31 +09:00
29aeb0f082 fix(package): update @types/webpack to version 4.4.15 (#2868) 2018-10-09 15:14:22 +09:00
990347f856 Fix 2018-10-09 15:13:06 +09:00
7a406c1f13 Docker (#2867)
* Dockerize Misskey

* Add a new line at EOF

* Add support Elasticsearch

* /

* Add setup document for docker

* Add english document

* Edit docs

* docker -> Docker

* Arrange format

* Update docker.en.md

* Modify title
2018-10-09 15:09:50 +09:00
9432af2ab5 10.3.0 2018-10-09 15:09:24 +09:00
136b13e7ca Fix bug and refactor 2018-10-09 15:08:31 +09:00
ba1c823fb1 🎨 2018-10-09 14:58:37 +09:00
f1301a4780 fix(package): update @types/redis to version 2.8.7 (#2866) 2018-10-09 09:38:47 +09:00
7957cd4963 fix(package): update @types/node to version 10.11.5 (#2865) 2018-10-09 09:38:40 +09:00
ee6590d03f fix(package): update @types/mongodb to version 3.1.11 (#2864) 2018-10-09 09:38:31 +09:00
f2a1238b20 fix(package): update commander to version 2.19.0 (#2862) 2018-10-09 09:38:21 +09:00
e9ce84f368 New translations ja-JP.yml (Norwegian) 2018-10-09 07:04:09 +09:00
52e84decb4 New translations ja-JP.yml (Dutch) 2018-10-09 07:04:03 +09:00
e893002bb6 New translations ja-JP.yml (Japanese, Kansai) 2018-10-09 07:03:59 +09:00
3792103e80 New translations ja-JP.yml (Spanish) 2018-10-09 07:03:54 +09:00
7a861c9481 New translations ja-JP.yml (Russian) 2018-10-09 07:03:47 +09:00
942b565224 New translations ja-JP.yml (Portuguese) 2018-10-09 07:03:43 +09:00
88390d7a9a New translations ja-JP.yml (Polish) 2018-10-09 07:03:39 +09:00
966fc4c5d7 New translations ja-JP.yml (Korean) 2018-10-09 07:03:34 +09:00
84dbdf1196 New translations ja-JP.yml (Italian) 2018-10-09 07:03:29 +09:00
211e7f90d9 New translations ja-JP.yml (German) 2018-10-09 07:03:23 +09:00
e54b8e3fb2 New translations ja-JP.yml (French) 2018-10-09 07:03:18 +09:00
836c89ed33 New translations ja-JP.yml (English) 2018-10-09 07:03:12 +09:00
c7c73afea1 New translations ja-JP.yml (Chinese Simplified) 2018-10-09 07:03:06 +09:00
7b9ca63b1e New translations ja-JP.yml (Catalan) 2018-10-09 07:02:59 +09:00
c464183329 Improve theme manager 2018-10-09 06:46:52 +09:00
389f420cad Update src/tools/move-drive-files.ts 2018-10-09 05:46:21 +09:00
6b2888383c 10.2.1 2018-10-09 05:36:39 +09:00
3c38a867b4 Fix bug 2018-10-09 05:35:40 +09:00
7f5a69f4d8 Fix bug 2018-10-09 05:31:26 +09:00
43 changed files with 497 additions and 205 deletions

View File

@ -0,0 +1,13 @@
var user = {
user: 'example-misskey-user',
pwd: 'example-misskey-pass',
roles: [
{
role: 'readWrite',
db: 'misskey'
}
]
};
db.createUser(user);

12
.dockerignore Executable file
View File

@ -0,0 +1,12 @@
.autogen
.git
.github
.travis
.vscode
Dockerfile
build/
docker-compose.yml
node_modules/
mongo/
redis/
elasticsearch/

4
.gitignore vendored
View File

@ -1,5 +1,6 @@
/.config/* /.config/*
!/.config/example.yml !/.config/example.yml
!/.config/mongo_initdb_example.js
/.vscode /.vscode
/node_modules /node_modules
/build /build
@ -12,3 +13,6 @@ npm-debug.log
run.bat run.bat
api-docs.json api-docs.json
*.log *.log
/redis
/mongo
/elasticsearch

28
Dockerfile Normal file
View File

@ -0,0 +1,28 @@
FROM alpine:latest AS base
ENV NODE_ENV=production
RUN apk add --no-cache nodejs nodejs-npm
RUN apk add vips fftw --update-cache --repository https://dl-3.alpinelinux.org/alpine/edge/testing/
WORKDIR /misskey
COPY . ./
FROM base AS builder
RUN apk add --no-cache gcc g++ python autoconf automake file make nasm
RUN apk add vips-dev fftw-dev --update-cache --repository https://dl-3.alpinelinux.org/alpine/edge/testing/
RUN npm install \
&& npm install -g node-gyp \
&& node-gyp configure \
&& node-gyp build \
&& npm run build
FROM base AS runner
COPY --from=builder /misskey/built ./built
COPY --from=builder /misskey/node_modules ./node_modules
RUN apk add --no-cache tini
ENTRYPOINT ["/sbin/tini", "--"]
CMD ["npm", "start"]

52
docker-compose.yml Normal file
View File

@ -0,0 +1,52 @@
version: "3"
services:
web:
build: .
restart: always
links:
- mongo
- redis
# - es
ports:
- "127.0.0.1:3000:3000"
networks:
- internal_network
- external_network
redis:
restart: always
image: redis:4.0-alpine
networks:
- internal_network
### Uncomment to enable Redis persistance
# volumes:
# - ./redis:/data
mongo:
restart: always
image: mongo:4.1-bionic
networks:
- internal_network
environment:
MONGO_INITDB_DATABASE: "misskey"
volumes:
- ./.config/mongo_initdb.js:/docker-entrypoint-initdb.d/mongo_initdb.js:ro
### Uncomment to enable MongoDB persistance
# - ./mongo:/data
# es:
# restart: always
# image: docker.elastic.co/elasticsearch/elasticsearch-oss:6.4.2
# environment:
# - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
# networks:
# - internal_network
#### Uncomment to enable ES persistence
## volumes:
## - ./elasticsearch:/usr/share/elasticsearch/data
networks:
internal_network:
internal: true
external_network:

47
docs/docker.en.md Normal file
View File

@ -0,0 +1,47 @@
Docker Guide
================================================================
This guide describes how to install and setup Misskey with Docker.
[Japanese version also available - 日本語版もあります](./docker.ja.md)
----------------------------------------------------------------
*1.* Make configuration files
----------------------------------------------------------------
1. `cp .config/example.yml .config/default.yml` Copy the `.config/example.yml` and rename it to `default.yml`.
2. `cp .config/mongo_initdb_example.js .config/mongo_initdb.js` Copy the `.config/mongo_initdb_example.js` and rename it to `mongo_initdb.js`.
2. Edit `default.yml` and `mongo_initdb.js`.
*2.* Configure Docker
----------------------------------------------------------------
Edit `docker-compose.yml`.
*3.* Build Misskey
----------------------------------------------------------------
Build misskey with the following:
`docker-compose build`
*4.* That is it.
----------------------------------------------------------------
Well done! Now, you have an environment that run to Misskey.
### Launch normally
Just `docker-compose up -d`. GLHF!
### Way to Update to latest version of your Misskey
1. `git fetch`
2. `git stash`
3. `git checkout $(git tag -l | grep -v 'rc[0-9]*$' | sort -V | tail -n 1)`
4. `git stash pop`
5. `docker-compose build`
6. Check [ChangeLog](../CHANGELOG.md) for migration information
7. `docker-compose stop && docker-compose up -d`
### Way to execute cli command:
`docker-compose run --rm web node cli/mark-admin @example`
----------------------------------------------------------------
If you have any questions or troubles, feel free to contact us!

48
docs/docker.ja.md Normal file
View File

@ -0,0 +1,48 @@
Dockerを使ったMisskey構築方法
================================================================
このガイドはDockerを使ったMisskeyセットアップ方法について解説します。
[英語版もあります - English version also available](./docker.en.md)
----------------------------------------------------------------
*1.* 設定ファイルを作成する
----------------------------------------------------------------
1. `cp .config/example.yml .config/default.yml` `.config/example.yml`をコピーし名前を`default.yml`にする
2. `cp .config/mongo_initdb_example.js .config/mongo_initdb.js` `.config/mongo_initdb_example.js`をコピーし名前を`mongo_initdb.js`にする
3. `default.yml``mongo_initdb.js`を編集する
*2.* Dockerの設定
----------------------------------------------------------------
`docker-compose.yml`を編集してください。
*3.* Misskeyのビルド
----------------------------------------------------------------
次のコマンドでMisskeyをビルドしてください:
`docker-compose build`
*4.* 以上です!
----------------------------------------------------------------
お疲れ様でした。これでMisskeyを動かす準備は整いました。
### 通常起動
`docker-compose up -d`するだけです。GLHF!
### Misskeyを最新バージョンにアップデートする方法:
1. `git fetch`
2. `git stash`
3. `git checkout $(git tag -l | grep -v 'rc[0-9]*$' | sort -V | tail -n 1)`
4. `git stash pop`
5. `docker-compose build`
6. [ChangeLog](../CHANGELOG.md)でマイグレーション情報を確認する
7. `docker-compose stop && docker-compose up -d`
### cliコマンドを実行する方法:
`docker-compose run --rm web node cli/mark-admin @example`
----------------------------------------------------------------
なにかお困りのことがありましたらお気軽にご連絡ください。

View File

@ -286,6 +286,9 @@ common/views/components/theme.vue:
invalid-theme: "テーマが正しくありません。" invalid-theme: "テーマが正しくありません。"
already-installed: "既にそのテーマはインストールされています。" already-installed: "既にそのテーマはインストールされています。"
saved: "保存しました" saved: "保存しました"
manage-themes: "テーマの管理"
builtin-themes: "標準テーマ"
my-themes: "マイテーマ"
installed-themes: "インストールされたテーマ" installed-themes: "インストールされたテーマ"
select-theme: "テーマを選択してください" select-theme: "テーマを選択してください"
uninstall: "アンインストール" uninstall: "アンインストール"

View File

@ -286,6 +286,9 @@ common/views/components/theme.vue:
invalid-theme: "テーマが正しくありません。" invalid-theme: "テーマが正しくありません。"
already-installed: "既にそのテーマはインストールされています。" already-installed: "既にそのテーマはインストールされています。"
saved: "保存しました" saved: "保存しました"
manage-themes: "テーマの管理"
builtin-themes: "標準テーマ"
my-themes: "マイテーマ"
installed-themes: "インストールされたテーマ" installed-themes: "インストールされたテーマ"
select-theme: "テーマを選択してください" select-theme: "テーマを選択してください"
uninstall: "アンインストール" uninstall: "アンインストール"

View File

@ -286,6 +286,9 @@ common/views/components/theme.vue:
invalid-theme: "テーマが正しくありません。" invalid-theme: "テーマが正しくありません。"
already-installed: "既にそのテーマはインストールされています。" already-installed: "既にそのテーマはインストールされています。"
saved: "保存しました" saved: "保存しました"
manage-themes: "テーマの管理"
builtin-themes: "標準テーマ"
my-themes: "マイテーマ"
installed-themes: "インストールされたテーマ" installed-themes: "インストールされたテーマ"
select-theme: "テーマを選択してください" select-theme: "テーマを選択してください"
uninstall: "アンインストール" uninstall: "アンインストール"

View File

@ -286,6 +286,9 @@ common/views/components/theme.vue:
invalid-theme: "テーマが正しくありません。" invalid-theme: "テーマが正しくありません。"
already-installed: "既にそのテーマはインストールされています。" already-installed: "既にそのテーマはインストールされています。"
saved: "保存しました" saved: "保存しました"
manage-themes: "テーマの管理"
builtin-themes: "標準テーマ"
my-themes: "マイテーマ"
installed-themes: "インストールされたテーマ" installed-themes: "インストールされたテーマ"
select-theme: "テーマを選択してください" select-theme: "テーマを選択してください"
uninstall: "アンインストール" uninstall: "アンインストール"

View File

@ -286,6 +286,9 @@ common/views/components/theme.vue:
invalid-theme: "Thème nest pas valide." invalid-theme: "Thème nest pas valide."
already-installed: "Le thème est déjà installé." already-installed: "Le thème est déjà installé."
saved: "enregistré" saved: "enregistré"
manage-themes: "テーマの管理"
builtin-themes: "標準テーマ"
my-themes: "マイテーマ"
installed-themes: "Thèmes installés" installed-themes: "Thèmes installés"
select-theme: "Veuillez sélectionner un thème" select-theme: "Veuillez sélectionner un thème"
uninstall: "Désinstaller" uninstall: "Désinstaller"

View File

@ -286,6 +286,9 @@ common/views/components/theme.vue:
invalid-theme: "テーマが正しくありません。" invalid-theme: "テーマが正しくありません。"
already-installed: "既にそのテーマはインストールされています。" already-installed: "既にそのテーマはインストールされています。"
saved: "保存しました" saved: "保存しました"
manage-themes: "テーマの管理"
builtin-themes: "標準テーマ"
my-themes: "マイテーマ"
installed-themes: "インストールされたテーマ" installed-themes: "インストールされたテーマ"
select-theme: "テーマを選択してください" select-theme: "テーマを選択してください"
uninstall: "アンインストール" uninstall: "アンインストール"

View File

@ -307,6 +307,9 @@ common/views/components/theme.vue:
invalid-theme: "テーマが正しくありません。" invalid-theme: "テーマが正しくありません。"
already-installed: "既にそのテーマはインストールされています。" already-installed: "既にそのテーマはインストールされています。"
saved: "保存しました" saved: "保存しました"
manage-themes: "テーマの管理"
builtin-themes: "標準テーマ"
my-themes: "マイテーマ"
installed-themes: "インストールされたテーマ" installed-themes: "インストールされたテーマ"
select-theme: "テーマを選択してください" select-theme: "テーマを選択してください"
uninstall: "アンインストール" uninstall: "アンインストール"

View File

@ -286,6 +286,9 @@ common/views/components/theme.vue:
invalid-theme: "テーマが正しくありません。" invalid-theme: "テーマが正しくありません。"
already-installed: "既にそのテーマはインストールされています。" already-installed: "既にそのテーマはインストールされています。"
saved: "保存しました" saved: "保存しました"
manage-themes: "テーマの管理"
builtin-themes: "標準テーマ"
my-themes: "マイテーマ"
installed-themes: "インストールされたテーマ" installed-themes: "インストールされたテーマ"
select-theme: "テーマを選択してください" select-theme: "テーマを選択してください"
uninstall: "アンインストール" uninstall: "アンインストール"

View File

@ -3,20 +3,20 @@ meta:
lang: "한국어" lang: "한국어"
divider: "" divider: ""
common: common:
misskey: "A ⭐ of fediverse" misskey: "연합우주의 ⭐"
about-title: "A ⭐ of fediverse." about-title: "연합우주의 ⭐."
about: "Misskey를 찾아 주셔서 감사합니다. Misskey은 지구에서 태어난 <b>분산 마이크로 블로그 SNS </b> 입니다. Fediverse (다양한 SNS로 구성되는 우주)에 존재하는 다른 SNS와 상호 연결되어 있습니다. 잠시 도시의 번잡함에서 벗어나 새로운 인터넷에 다이브 해 보지 않겠습니까." about: "Misskey를 찾아 주셔서 감사합니다. Misskey은 지구에서 태어난 <b>분산 마이크로 블로그 SNS </b> 입니다. Fediverse (다양한 SNS로 구성되는 우주)에 존재하는 다른 SNS와 상호 연결되어 있습니다. 잠시 도시의 번잡함에서 벗어나 새로운 인터넷에 다이브 해 보지 않겠습니까."
intro: intro:
title: "Misskeyって?" title: "Misskey란?"
about: "Misskeyはオープンソースの<b>分散型マイクロブログSNS</b>です。リッチで高度にカスタマイズできるUI、投稿へのリアクション、ファイルを一元管理できるドライブなど、先進的な機能を揃えています。また、Fediverseと呼ばれるネットワークに接続できるため、他のSNSともやり取りできます。例えば、あなたが何か投稿すると、その投稿はMisskeyだけでなく他のSNSにも伝わります。ちょうどある惑星から他の惑星に電波を発信している様子をイメージしてください。" about: "Misskeyはオープンソースの<b>分散型マイクロブログSNS</b>です。リッチで高度にカスタマイズできるUI、投稿へのリアクション、ファイルを一元管理できるドライブなど、先進的な機能を揃えています。また、Fediverseと呼ばれるネットワークに接続できるため、他のSNSともやり取りできます。例えば、あなたが何か投稿すると、その投稿はMisskeyだけでなく他のSNSにも伝わります。ちょうどある惑星から他の惑星に電波を発信している様子をイメージしてください。"
features: "特徴" features: "특징"
rich-contents: "投稿" rich-contents: "게시"
rich-contents-desc: "自分の考え、話題の出来事、皆と共有したいことについて発信してください。必要であれば、様々な構文を使って投稿を装飾したり、好きな画像、動画などのファイルやアンケートを添付することもできます。" rich-contents-desc: "自分の考え、話題の出来事、皆と共有したいことについて発信してください。必要であれば、様々な構文を使って投稿を装飾したり、好きな画像、動画などのファイルやアンケートを添付することもできます。"
reaction: "リアクション" reaction: "반응"
reaction-desc: "あなたの気持ちを伝える最も簡単な方法です。Misskeyは、他のユーザーの投稿に様々なリアクションを付けることができます。いちどMisskeyのリアクション機能を体験してしまうと、もう「いいね」の概念しか存在しないSNSには戻れなくなるかもしれません。" reaction-desc: "あなたの気持ちを伝える最も簡単な方法です。Misskeyは、他のユーザーの投稿に様々なリアクションを付けることができます。いちどMisskeyのリアクション機能を体験してしまうと、もう「いいね」の概念しか存在しないSNSには戻れなくなるかもしれません。"
ui: "インターフェース" ui: "인터페이스"
ui-desc: "どのようなUIが使いやすいかは人それぞれです。だから、Misskeyは自由度の高いUIを持っています。レイアウトやデザインを調整したり、カスタマイズ可能な様々なウィジェットを配置したりして、自分だけのホームを作ってください。" ui-desc: "どのようなUIが使いやすいかは人それぞれです。だから、Misskeyは自由度の高いUIを持っています。レイアウトやデザインを調整したり、カスタマイズ可能な様々なウィジェットを配置したりして、自分だけのホームを作ってください。"
drive: "ドライブ" drive: "드라이브"
drive-desc: "以前投稿したことのある画像をまた投稿したくなったことはありませんかもしくは、アップロードしたファイルをフォルダ分けして整理したくなったことはありませんかMisskeyの根幹に組み込まれたドライブ機能によってそれらが解決します。ファイルの共有も簡単です。" drive-desc: "以前投稿したことのある画像をまた投稿したくなったことはありませんかもしくは、アップロードしたファイルをフォルダ分けして整理したくなったことはありませんかMisskeyの根幹に組み込まれたドライブ機能によってそれらが解決します。ファイルの共有も簡単です。"
outro: "他にもMisskeyにしかない機能はまだまだあるので、ぜひあなた自身の目で確かめてください。Misskeyは分散型SNSなので、このインスタンスが気に入らなければ他のインスタンスを試すこともできます。それでは、GLHF!" outro: "他にもMisskeyにしかない機能はまだまだあるので、ぜひあなた自身の目で確かめてください。Misskeyは分散型SNSなので、このインスタンスが気に入らなければ他のインスタンスを試すこともできます。それでは、GLHF!"
adblock: adblock:
@ -71,7 +71,7 @@ common:
friday: "금요일" friday: "금요일"
saturday: "토요일" saturday: "토요일"
reactions: reactions:
like: "いいね" like: "좋아요"
love: "좋아" love: "좋아"
laugh: "크크" laugh: "크크"
hmm: "음..." hmm: "음..."
@ -82,14 +82,14 @@ common:
rip: "RIP" rip: "RIP"
pudding: "Pudding" pudding: "Pudding"
note-visibility: note-visibility:
public: "公開" public: "공개"
home: "ホーム" home: ""
home-desc: "ホームタイムラインにのみ公開" home-desc: "홈 타임라인에만 공개"
followers: "フォロワー" followers: "팔로워"
followers-desc: "自分のフォロワーにのみ公開" followers-desc: "자신의 팔로워에게만 공개"
specified: "ダイレクト" specified: "다이렉트"
specified-desc: "指定したユーザーにのみ公開" specified-desc: "지정한 사용자에게만 공개"
private: "非公開" private: "비공개"
note-placeholders: note-placeholders:
a: "지금 어떻게하고있어?" a: "지금 어떻게하고있어?"
b: "뭔가 있었습니까?" b: "뭔가 있었습니까?"
@ -107,14 +107,14 @@ common:
i-like-sushi: "나는(푸딩보다 오히려)스시가 좋아" i-like-sushi: "나는(푸딩보다 오히려)스시가 좋아"
show-reversi-board-labels: "리버시 보드의 행과 열 레이블을 표시" show-reversi-board-labels: "리버시 보드의 행과 열 레이블을 표시"
use-contrast-reversi-stones: "リバーシのアイコンにコントラストを付ける" use-contrast-reversi-stones: "リバーシのアイコンにコントラストを付ける"
verified-user: "公式アカウント" verified-user: "공식 계정"
disable-animated-mfm: "게시물의 문자 애니메이션을 비활성화 할" disable-animated-mfm: "게시물의 문자 애니메이션을 비활성화 할"
always-show-nsfw: "常に閲覧注意のメディアを表示する" always-show-nsfw: "항상 열람주의 미디어를 표시"
always-mark-nsfw: "常にメディアを閲覧注意として投稿" always-mark-nsfw: "항상 미디어를 열람주의로 설정하여 게시"
show-full-acct: "ユーザー名のホストを省略しない" show-full-acct: "ユーザー名のホストを省略しない"
reduce-motion: "UIの動きを減らす" reduce-motion: "UIの動きを減らす"
this-setting-is-this-device-only: "このデバイスのみ" this-setting-is-this-device-only: "이 장치만"
do-not-use-in-production: 'これは開発ビルドです。本番環境で使用しないでください。' do-not-use-in-production: '이것은 개발 빌드입니다. 프로덕션 환경에서 사용하지 마십시오.'
reversi: reversi:
drawn: "무승부" drawn: "무승부"
my-turn: "당신의 차례입니다" my-turn: "당신의 차례입니다"
@ -155,19 +155,19 @@ common:
home: "홈" home: "홈"
local: "로컬" local: "로컬"
hybrid: "소셜" hybrid: "소셜"
hashtag: "ハッシュタグ" hashtag: "해시태그"
global: "글로벌" global: "글로벌"
mentions: "あなた宛て" mentions: "あなた宛て"
direct: "ダイレクト投稿" direct: "ダイレクト投稿"
notifications: "통지" notifications: "통지"
list: "목록" list: "목록"
swap-left: "左に移動" swap-left: "왼쪽으로 이동"
swap-right: "右に移動" swap-right: "오른쪽으로 이동"
swap-up: "上に移動" swap-up: "위로 이동"
swap-down: "下に移動" swap-down: "아래로 이동"
remove: "カラムを削除" remove: "칼럼 제거"
add-column: "カラムを追加" add-column: "칼럼 추가"
rename: "名前を変更" rename: "이름 변경"
stack-left: "左に重ねる" stack-left: "左に重ねる"
pop-right: "右に出す" pop-right: "右に出す"
auth/views/form.vue: auth/views/form.vue:
@ -248,44 +248,47 @@ common/views/components/connect-failed.troubleshooter.vue:
checking-network: "ネットワーク接続を確認中" checking-network: "ネットワーク接続を確認中"
internet: "インターネット接続" internet: "インターネット接続"
checking-internet: "インターネット接続を確認中" checking-internet: "インターネット接続を確認中"
server: "サーバー接続" server: "서버 연결"
checking-server: "サーバー接続を確認中" checking-server: "サーバー接続を確認中"
finding: "問題を調べています" finding: "問題を調べています"
no-network: "ネットワークに接続されていません" no-network: "ネットワークに接続されていません"
no-network-desc: "お使いのPCのネットワーク接続が正常か確認してください。" no-network-desc: "お使いのPCのネットワーク接続が正常か確認してください。"
no-internet: "インターネットに接続されていません" no-internet: "インターネットに接続されていません"
no-internet-desc: "ネットワークには接続されていますが、インターネットには接続されていないようです。お使いのPCのインターネット接続が正常か確認してください。" no-internet-desc: "ネットワークには接続されていますが、インターネットには接続されていないようです。お使いのPCのインターネット接続が正常か確認してください。"
no-server: "Misskeyのサーバーに接続できません" no-server: "Misskey 서버에 연결할 수 없습니다."
no-server-desc: "お使いのPCのインターネット接続は正常ですが、Misskeyのサーバーには接続できませんでした。サーバーがダウンまたはメンテナンスしている可能性があるので、しばらくしてから再度御アクセスください。" no-server-desc: "お使いのPCのインターネット接続は正常ですが、Misskeyのサーバーには接続できませんでした。サーバーがダウンまたはメンテナンスしている可能性があるので、しばらくしてから再度御アクセスください。"
success: "Misskeyのサーバーに接続できました" success: "Misskeyのサーバーに接続できました"
success-desc: "正常に接続できるようです。ページを再度読み込みしてください。" success-desc: "正常に接続できるようです。ページを再度読み込みしてください。"
flush: "キャッシュの削除" flush: "캐시 삭제"
set-version: "バージョン指定" set-version: "버전 지정"
common/views/components/media-banner.vue: common/views/components/media-banner.vue:
sensitive: "閲覧注意" sensitive: "열람주의"
click-to-show: "クリックして表示" click-to-show: "클릭하여 표시"
common/views/components/theme.vue: common/views/components/theme.vue:
light-theme: "非ダークモード時に使用するテーマ" light-theme: "非ダークモード時に使用するテーマ"
dark-theme: "ダークモード時に使用するテーマ" dark-theme: "ダークモード時に使用するテーマ"
light-themes: "明るいテーマ" light-themes: "밝은 테마"
dark-themes: "暗いテーマ" dark-themes: "어두운 테마"
install-a-theme: "テーマのインストール" install-a-theme: "테마 설치"
theme-code: "テーマコード" theme-code: "테마 코드"
install: "インストール" install: "설치"
installed: "「{}」をインストールしました" installed: "「{}」をインストールしました"
create-a-theme: "テーマの作成" create-a-theme: "테마 만들기"
save-created-theme: "テーマを保存" save-created-theme: "테마 저장"
primary-color: "プライマリ カラー" primary-color: "기본 색"
secondary-color: "セカンダリ カラー" secondary-color: "보조 색"
text-color: "文字色" text-color: "글자 색상"
base-theme: "ベーステーマ" base-theme: "ベーステーマ"
base-theme-light: "Light" base-theme-light: "Light"
base-theme-dark: "Dark" base-theme-dark: "Dark"
theme-name: "テーマ名" theme-name: "테마명"
preview-created-theme: "プレビュー" preview-created-theme: "미리보기"
invalid-theme: "テーマが正しくありません。" invalid-theme: "テーマが正しくありません。"
already-installed: "既にそのテーマはインストールされています。" already-installed: "既にそのテーマはインストールされています。"
saved: "保存しました" saved: "保存しました"
manage-themes: "テーマの管理"
builtin-themes: "標準テーマ"
my-themes: "マイテーマ"
installed-themes: "インストールされたテーマ" installed-themes: "インストールされたテーマ"
select-theme: "テーマを選択してください" select-theme: "テーマを選択してください"
uninstall: "アンインストール" uninstall: "アンインストール"
@ -305,7 +308,7 @@ common/views/components/messaging.vue:
no-history: "履歴はありません" no-history: "履歴はありません"
common/views/components/messaging-room.vue: common/views/components/messaging-room.vue:
empty: "このユーザーと話したことはありません" empty: "このユーザーと話したことはありません"
more: "もっと読む" more: "더 보기"
no-history: "これより過去の履歴はありません" no-history: "これより過去の履歴はありません"
resize-form: "ドラッグしてフォームの広さを調整" resize-form: "ドラッグしてフォームの広さを調整"
new-message: "新しいメッセージがあります" new-message: "新しいメッセージがあります"
@ -320,17 +323,17 @@ common/views/components/messaging-room.message.vue:
is-read: "읽음" is-read: "읽음"
deleted: "このメッセージは削除されました" deleted: "このメッセージは削除されました"
common/views/components/nav.vue: common/views/components/nav.vue:
about: "Misskeyについて" about: "Misskey에 대하여"
stats: "統計" stats: "통계"
status: "ステータス" status: "ステータス"
wiki: "Wiki" wiki: "Wiki"
donors: "ドナー" donors: "기증자"
repository: "リポジトリ" repository: "저장소"
develop: "開発者" develop: "개발자"
feedback: "フィードバック" feedback: "피드백"
common/views/components/note-menu.vue: common/views/components/note-menu.vue:
detail: "詳細" detail: "詳細"
copy-link: "リンクをコピー" copy-link: "링크 복사"
favorite: "お気に入り" favorite: "お気に入り"
pin: "ピン留め" pin: "ピン留め"
unpin: "ピン留め解除" unpin: "ピン留め解除"

View File

@ -286,6 +286,9 @@ common/views/components/theme.vue:
invalid-theme: "テーマが正しくありません。" invalid-theme: "テーマが正しくありません。"
already-installed: "既にそのテーマはインストールされています。" already-installed: "既にそのテーマはインストールされています。"
saved: "保存しました" saved: "保存しました"
manage-themes: "テーマの管理"
builtin-themes: "標準テーマ"
my-themes: "マイテーマ"
installed-themes: "インストールされたテーマ" installed-themes: "インストールされたテーマ"
select-theme: "テーマを選択してください" select-theme: "テーマを選択してください"
uninstall: "アンインストール" uninstall: "アンインストール"

View File

@ -286,6 +286,9 @@ common/views/components/theme.vue:
invalid-theme: "テーマが正しくありません。" invalid-theme: "テーマが正しくありません。"
already-installed: "既にそのテーマはインストールされています。" already-installed: "既にそのテーマはインストールされています。"
saved: "保存しました" saved: "保存しました"
manage-themes: "テーマの管理"
builtin-themes: "標準テーマ"
my-themes: "マイテーマ"
installed-themes: "インストールされたテーマ" installed-themes: "インストールされたテーマ"
select-theme: "テーマを選択してください" select-theme: "テーマを選択してください"
uninstall: "アンインストール" uninstall: "アンインストール"

View File

@ -286,6 +286,9 @@ common/views/components/theme.vue:
invalid-theme: "テーマが正しくありません。" invalid-theme: "テーマが正しくありません。"
already-installed: "既にそのテーマはインストールされています。" already-installed: "既にそのテーマはインストールされています。"
saved: "保存しました" saved: "保存しました"
manage-themes: "テーマの管理"
builtin-themes: "標準テーマ"
my-themes: "マイテーマ"
installed-themes: "インストールされたテーマ" installed-themes: "インストールされたテーマ"
select-theme: "テーマを選択してください" select-theme: "テーマを選択してください"
uninstall: "アンインストール" uninstall: "アンインストール"

View File

@ -286,6 +286,9 @@ common/views/components/theme.vue:
invalid-theme: "テーマが正しくありません。" invalid-theme: "テーマが正しくありません。"
already-installed: "既にそのテーマはインストールされています。" already-installed: "既にそのテーマはインストールされています。"
saved: "保存しました" saved: "保存しました"
manage-themes: "テーマの管理"
builtin-themes: "標準テーマ"
my-themes: "マイテーマ"
installed-themes: "インストールされたテーマ" installed-themes: "インストールされたテーマ"
select-theme: "テーマを選択してください" select-theme: "テーマを選択してください"
uninstall: "アンインストール" uninstall: "アンインストール"

View File

@ -286,6 +286,9 @@ common/views/components/theme.vue:
invalid-theme: "テーマが正しくありません。" invalid-theme: "テーマが正しくありません。"
already-installed: "既にそのテーマはインストールされています。" already-installed: "既にそのテーマはインストールされています。"
saved: "保存しました" saved: "保存しました"
manage-themes: "テーマの管理"
builtin-themes: "標準テーマ"
my-themes: "マイテーマ"
installed-themes: "インストールされたテーマ" installed-themes: "インストールされたテーマ"
select-theme: "テーマを選択してください" select-theme: "テーマを選択してください"
uninstall: "アンインストール" uninstall: "アンインストール"

View File

@ -286,6 +286,9 @@ common/views/components/theme.vue:
invalid-theme: "テーマが正しくありません。" invalid-theme: "テーマが正しくありません。"
already-installed: "既にそのテーマはインストールされています。" already-installed: "既にそのテーマはインストールされています。"
saved: "保存しました" saved: "保存しました"
manage-themes: "テーマの管理"
builtin-themes: "標準テーマ"
my-themes: "マイテーマ"
installed-themes: "インストールされたテーマ" installed-themes: "インストールされたテーマ"
select-theme: "テーマを選択してください" select-theme: "テーマを選択してください"
uninstall: "アンインストール" uninstall: "アンインストール"

View File

@ -1,8 +1,8 @@
{ {
"name": "misskey", "name": "misskey",
"author": "syuilo <i@syuilo.com>", "author": "syuilo <i@syuilo.com>",
"version": "10.2.0", "version": "10.5.0",
"clientVersion": "1.0.10362", "clientVersion": "1.0.10405",
"codename": "nighthike", "codename": "nighthike",
"main": "./built/index.js", "main": "./built/index.js",
"private": true, "private": true,
@ -58,14 +58,14 @@
"@types/minio": "7.0.0", "@types/minio": "7.0.0",
"@types/mkdirp": "0.5.2", "@types/mkdirp": "0.5.2",
"@types/mocha": "5.2.3", "@types/mocha": "5.2.3",
"@types/mongodb": "3.1.10", "@types/mongodb": "3.1.11",
"@types/ms": "0.7.30", "@types/ms": "0.7.30",
"@types/node": "10.11.4", "@types/node": "10.11.5",
"@types/portscanner": "2.1.0", "@types/portscanner": "2.1.0",
"@types/pug": "2.0.4", "@types/pug": "2.0.4",
"@types/qrcode": "1.3.0", "@types/qrcode": "1.3.0",
"@types/ratelimiter": "2.1.28", "@types/ratelimiter": "2.1.28",
"@types/redis": "2.8.6", "@types/redis": "2.8.7",
"@types/request": "2.47.1", "@types/request": "2.47.1",
"@types/request-promise-native": "1.0.15", "@types/request-promise-native": "1.0.15",
"@types/rimraf": "2.0.2", "@types/rimraf": "2.0.2",
@ -78,7 +78,7 @@
"@types/tinycolor2": "1.4.1", "@types/tinycolor2": "1.4.1",
"@types/tmp": "0.0.33", "@types/tmp": "0.0.33",
"@types/uuid": "3.4.4", "@types/uuid": "3.4.4",
"@types/webpack": "4.4.14", "@types/webpack": "4.4.15",
"@types/webpack-stream": "3.2.10", "@types/webpack-stream": "3.2.10",
"@types/websocket": "0.0.40", "@types/websocket": "0.0.40",
"@types/ws": "6.0.1", "@types/ws": "6.0.1",
@ -92,7 +92,7 @@
"cafy": "11.3.0", "cafy": "11.3.0",
"chalk": "2.4.1", "chalk": "2.4.1",
"chart.js": "2.7.2", "chart.js": "2.7.2",
"commander": "2.17.1", "commander": "2.19.0",
"crc-32": "1.2.0", "crc-32": "1.2.0",
"css-loader": "1.0.0", "css-loader": "1.0.0",
"dateformat": "3.0.3", "dateformat": "3.0.3",
@ -219,6 +219,7 @@
"vue-router": "3.0.1", "vue-router": "3.0.1",
"vue-style-loader": "4.1.2", "vue-style-loader": "4.1.2",
"vue-svg-inline-loader": "1.2.0", "vue-svg-inline-loader": "1.2.0",
"vue-sweetalert2": "1.5.5",
"vue-template-compiler": "2.5.17", "vue-template-compiler": "2.5.17",
"vuedraggable": "2.16.0", "vuedraggable": "2.16.0",
"vuewordcloud": "18.7.11", "vuewordcloud": "18.7.11",

View File

@ -130,3 +130,16 @@ pre
[data-fa] [data-fa]
display inline-block display inline-block
.swal2-popup
background var(--face) !important
.swal-icon-only
width 180px !important
> .swal2-header
> .swal2-icon
margin 1.25em auto 1.875em
> .swal2-title
display none

View File

@ -91,7 +91,11 @@ export default prop => ({
Vue.set(this.$_ns_target, 'reactionCounts', {}); Vue.set(this.$_ns_target, 'reactionCounts', {});
} }
this.$_ns_target.reactionCounts[reaction] = (this.$_ns_target.reactionCounts[reaction] || 0) + 1; if (this.$_ns_target.reactionCounts[reaction] == null) {
Vue.set(this.$_ns_target.reactionCounts, reaction, 0);
}
this.$_ns_target.reactionCounts[reaction]++;
if (body.userId == this.$store.state.i.id) { if (body.userId == this.$store.state.i.id) {
Vue.set(this.$_ns_target, 'myReaction', reaction); Vue.set(this.$_ns_target, 'myReaction', reaction);

View File

@ -26,92 +26,6 @@ export default class Stream extends EventEmitter {
this.stream.addEventListener('open', this.onOpen); this.stream.addEventListener('open', this.onOpen);
this.stream.addEventListener('close', this.onClose); this.stream.addEventListener('close', this.onClose);
this.stream.addEventListener('message', this.onMessage); this.stream.addEventListener('message', this.onMessage);
if (user) {
const main = this.useSharedConnection('main');
// 自分の情報が更新されたとき
main.on('meUpdated', i => {
os.store.dispatch('mergeMe', i);
});
main.on('readAllNotifications', () => {
os.store.dispatch('mergeMe', {
hasUnreadNotification: false
});
});
main.on('unreadNotification', () => {
os.store.dispatch('mergeMe', {
hasUnreadNotification: true
});
});
main.on('readAllMessagingMessages', () => {
os.store.dispatch('mergeMe', {
hasUnreadMessagingMessage: false
});
});
main.on('unreadMessagingMessage', () => {
os.store.dispatch('mergeMe', {
hasUnreadMessagingMessage: true
});
});
main.on('unreadMention', () => {
os.store.dispatch('mergeMe', {
hasUnreadMentions: true
});
});
main.on('readAllUnreadMentions', () => {
os.store.dispatch('mergeMe', {
hasUnreadMentions: false
});
});
main.on('unreadSpecifiedNote', () => {
os.store.dispatch('mergeMe', {
hasUnreadSpecifiedNotes: true
});
});
main.on('readAllUnreadSpecifiedNotes', () => {
os.store.dispatch('mergeMe', {
hasUnreadSpecifiedNotes: false
});
});
main.on('clientSettingUpdated', x => {
os.store.commit('settings/set', {
key: x.key,
value: x.value
});
});
main.on('homeUpdated', x => {
os.store.commit('settings/setHome', x);
});
main.on('mobileHomeUpdated', x => {
os.store.commit('settings/setMobileHome', x);
});
main.on('widgetUpdated', x => {
os.store.commit('settings/setWidget', {
id: x.id,
data: x.data
});
});
// トークンが再生成されたとき
// このままではMisskeyが利用できないので強制的にサインアウトさせる
main.on('myTokenRegenerated', () => {
alert('%i18n:common.my-token-regenerated%');
os.signout();
});
}
} }
public useSharedConnection = (channel: string): SharedConnection => { public useSharedConnection = (channel: string): SharedConnection => {
@ -256,14 +170,14 @@ abstract class Connection extends EventEmitter {
const type = payload === undefined ? typeOrPayload.type : typeOrPayload; const type = payload === undefined ? typeOrPayload.type : typeOrPayload;
const body = payload === undefined ? typeOrPayload.body : payload; const body = payload === undefined ? typeOrPayload.body : payload;
this.stream.send('channel', { this.stream.send('ch', {
id: this.id, id: this.id,
type: type, type: type,
body: body body: body
}); });
} }
public abstract dispose: () => void; public abstract dispose(): void;
} }
class SharedConnection extends Connection { class SharedConnection extends Connection {

View File

@ -71,8 +71,7 @@ export default Vue.extend({
this.pingClock = setInterval(() => { this.pingClock = setInterval(() => {
if (this.matching) { if (this.matching) {
this.connection.send({ this.connection.send('ping', {
type: 'ping',
id: this.matching.id id: this.matching.id
}); });
} }

View File

@ -103,6 +103,12 @@ export default Vue.extend({
(this as any).api('notes/favorites/create', { (this as any).api('notes/favorites/create', {
noteId: this.note.id noteId: this.note.id
}).then(() => { }).then(() => {
this.$swal({
type: 'success',
showConfirmButton: false,
timer: 1250,
customClass: 'swal-icon-only'
});
this.destroyDom(); this.destroyDom();
}); });
}, },

View File

@ -67,22 +67,30 @@
</details> </details>
<details> <details>
<summary>%fa:folder-open% %i18n:@installed-themes%</summary> <summary>%fa:folder-open% %i18n:@manage-themes%</summary>
<ui-select v-model="selectedInstalledThemeId" placeholder="%i18n:@select-theme%"> <ui-select v-model="selectedThemeId" placeholder="%i18n:@select-theme%">
<option v-for="x in installedThemes" :value="x.id" :key="x.id">{{ x.name }}</option> <optgroup label="%i18n:@builtin-themes%">
<option v-for="x in builtinThemes" :value="x.id" :key="x.id">{{ x.name }}</option>
</optgroup>
<optgroup label="%i18n:@my-themes%">
<option v-for="x in installedThemes.filter(t => t.author == this.$store.state.i.username)" :value="x.id" :key="x.id">{{ x.name }}</option>
</optgroup>
<optgroup label="%i18n:@installed-themes%">
<option v-for="x in installedThemes.filter(t => t.author != this.$store.state.i.username)" :value="x.id" :key="x.id">{{ x.name }}</option>
</optgroup>
</ui-select> </ui-select>
<template v-if="selectedInstalledTheme"> <template v-if="selectedTheme">
<ui-input readonly :value="selectedInstalledTheme.author"> <ui-input readonly :value="selectedTheme.author">
<span>%i18n:@author%</span> <span>%i18n:@author%</span>
</ui-input> </ui-input>
<ui-textarea v-if="selectedInstalledTheme.desc" readonly :value="selectedInstalledTheme.desc"> <ui-textarea v-if="selectedTheme.desc" readonly :value="selectedTheme.desc">
<span>%i18n:@desc%</span> <span>%i18n:@desc%</span>
</ui-textarea> </ui-textarea>
<ui-textarea readonly :value="selectedInstalledThemeCode"> <ui-textarea readonly :value="selectedThemeCode">
<span>%i18n:@theme-code%</span> <span>%i18n:@theme-code%</span>
</ui-textarea> </ui-textarea>
<ui-button @click="export_()" link :download="`${selectedInstalledTheme.name}.misskeytheme`" ref="export">%fa:box% %i18n:@export%</ui-button> <ui-button @click="export_()" link :download="`${selectedTheme.name}.misskeytheme`" ref="export">%fa:box% %i18n:@export%</ui-button>
<ui-button @click="uninstall()">%fa:trash-alt R% %i18n:@uninstall%</ui-button> <ui-button @click="uninstall()" v-if="!builtinThemes.some(t => t.id == selectedTheme.id)">%fa:trash-alt R% %i18n:@uninstall%</ui-button>
</template> </template>
</details> </details>
</div> </div>
@ -117,8 +125,9 @@ export default Vue.extend({
data() { data() {
return { return {
builtinThemes: builtinThemes,
installThemeCode: null, installThemeCode: null,
selectedInstalledThemeId: null, selectedThemeId: null,
myThemeBase: 'light', myThemeBase: 'light',
myThemeName: '', myThemeName: '',
myThemeDesc: '', myThemeDesc: '',
@ -155,14 +164,14 @@ export default Vue.extend({
set(value) { this.$store.commit('device/set', { key: 'darkTheme', value }); } set(value) { this.$store.commit('device/set', { key: 'darkTheme', value }); }
}, },
selectedInstalledTheme() { selectedTheme() {
if (this.selectedInstalledThemeId == null) return null; if (this.selectedThemeId == null) return null;
return this.installedThemes.find(x => x.id == this.selectedInstalledThemeId); return this.themes.find(x => x.id == this.selectedThemeId);
}, },
selectedInstalledThemeCode() { selectedThemeCode() {
if (this.selectedInstalledTheme == null) return null; if (this.selectedTheme == null) return null;
return JSON5.stringify(this.selectedInstalledTheme, null, '\t'); return JSON5.stringify(this.selectedTheme, null, '\t');
}, },
myTheme(): any { myTheme(): any {
@ -238,7 +247,7 @@ export default Vue.extend({
}, },
uninstall() { uninstall() {
const theme = this.selectedInstalledTheme; const theme = this.selectedTheme;
const themes = this.$store.state.device.themes.filter(t => t.id != theme.id); const themes = this.$store.state.device.themes.filter(t => t.id != theme.id);
this.$store.commit('device/set', { this.$store.commit('device/set', {
key: 'themes', value: themes key: 'themes', value: themes
@ -251,7 +260,7 @@ export default Vue.extend({
} }
export_() { export_() {
const blob = new Blob([this.selectedInstalledThemeCode], { const blob = new Blob([this.selectedThemeCode], {
type: 'application/json5' type: 'application/json5'
}); });
this.$refs.export.$el.href = window.URL.createObjectURL(blob); this.$refs.export.$el.href = window.URL.createObjectURL(blob);

View File

@ -113,8 +113,7 @@ export default define({
this.connection.on('stats', this.onStats); this.connection.on('stats', this.onStats);
this.connection.on('statsLog', this.onStatsLog); this.connection.on('statsLog', this.onStatsLog);
this.connection.send({ this.connection.send('requestLog',{
type: 'requestLog',
id: Math.random().toString() id: Math.random().toString()
}); });
}, },

View File

@ -91,8 +91,7 @@ export default Vue.extend({
mounted() { mounted() {
this.connection.on('stats', this.onStats); this.connection.on('stats', this.onStats);
this.connection.on('statsLog', this.onStatsLog); this.connection.on('statsLog', this.onStatsLog);
this.connection.send({ this.connection.send('requestLog', {
type: 'requestLog',
id: Math.random().toString() id: Math.random().toString()
}); });
}, },

View File

@ -181,8 +181,7 @@ export default Vue.extend({
onNotification(notification) { onNotification(notification) {
// TODO: ユーザーが画面を見てないと思われるとき(ブラウザやタブがアクティブじゃないなど)は送信しない // TODO: ユーザーが画面を見てないと思われるとき(ブラウザやタブがアクティブじゃないなど)は送信しない
this.connection.send({ (this as any).os.stream.send('readNotification', {
type: 'readNotification',
id: notification.id id: notification.id
}); });

View File

@ -77,8 +77,7 @@ export default Vue.extend({
mounted() { mounted() {
this.connection.on('stats', this.onStats); this.connection.on('stats', this.onStats);
this.connection.on('statsLog', this.onStatsLog); this.connection.on('statsLog', this.onStatsLog);
this.connection.send({ this.connection.send('requestLog', {
type: 'requestLog',
id: Math.random().toString(), id: Math.random().toString(),
length: 200 length: 200
}); });

View File

@ -113,8 +113,7 @@ export default Vue.extend({
onNotification(notification) { onNotification(notification) {
// TODO: ユーザーが画面を見てないと思われるとき(ブラウザやタブがアクティブじゃないなど)は送信しない // TODO: ユーザーが画面を見てないと思われるとき(ブラウザやタブがアクティブじゃないなど)は送信しない
this.connection.send({ (this as any).os.stream.send('readNotification', {
type: 'readNotification',
id: notification.id id: notification.id
}); });

View File

@ -8,6 +8,7 @@ import VueRouter from 'vue-router';
import * as TreeView from 'vue-json-tree-view'; import * as TreeView from 'vue-json-tree-view';
import VAnimateCss from 'v-animate-css'; import VAnimateCss from 'v-animate-css';
import VModal from 'vue-js-modal'; import VModal from 'vue-js-modal';
import VueSweetalert2 from 'vue-sweetalert2';
import VueHotkey from './common/hotkey'; import VueHotkey from './common/hotkey';
import App from './app.vue'; import App from './app.vue';
@ -26,6 +27,7 @@ Vue.use(TreeView);
Vue.use(VAnimateCss); Vue.use(VAnimateCss);
Vue.use(VModal); Vue.use(VModal);
Vue.use(VueHotkey); Vue.use(VueHotkey);
Vue.use(VueSweetalert2);
// Register global directives // Register global directives
require('./common/views/directives'); require('./common/views/directives');

View File

@ -212,7 +212,7 @@ export default class MiOS extends EventEmitter {
const fetched = () => { const fetched = () => {
this.emit('signedin'); this.emit('signedin');
this.stream = new Stream(this); this.initStream();
// Finish init // Finish init
callback(); callback();
@ -247,12 +247,103 @@ export default class MiOS extends EventEmitter {
// Finish init // Finish init
callback(); callback();
this.stream = new Stream(this); this.initStream();
} }
}); });
} }
} }
@autobind
private initStream() {
this.stream = new Stream(this);
if (this.store.getters.isSignedIn) {
const main = this.stream.useSharedConnection('main');
// 自分の情報が更新されたとき
main.on('meUpdated', i => {
this.store.dispatch('mergeMe', i);
});
main.on('readAllNotifications', () => {
this.store.dispatch('mergeMe', {
hasUnreadNotification: false
});
});
main.on('unreadNotification', () => {
this.store.dispatch('mergeMe', {
hasUnreadNotification: true
});
});
main.on('readAllMessagingMessages', () => {
this.store.dispatch('mergeMe', {
hasUnreadMessagingMessage: false
});
});
main.on('unreadMessagingMessage', () => {
this.store.dispatch('mergeMe', {
hasUnreadMessagingMessage: true
});
});
main.on('unreadMention', () => {
this.store.dispatch('mergeMe', {
hasUnreadMentions: true
});
});
main.on('readAllUnreadMentions', () => {
this.store.dispatch('mergeMe', {
hasUnreadMentions: false
});
});
main.on('unreadSpecifiedNote', () => {
this.store.dispatch('mergeMe', {
hasUnreadSpecifiedNotes: true
});
});
main.on('readAllUnreadSpecifiedNotes', () => {
this.store.dispatch('mergeMe', {
hasUnreadSpecifiedNotes: false
});
});
main.on('clientSettingUpdated', x => {
this.store.commit('settings/set', {
key: x.key,
value: x.value
});
});
main.on('homeUpdated', x => {
this.store.commit('settings/setHome', x);
});
main.on('mobileHomeUpdated', x => {
this.store.commit('settings/setMobileHome', x);
});
main.on('widgetUpdated', x => {
this.store.commit('settings/setWidget', {
id: x.id,
data: x.data
});
});
// トークンが再生成されたとき
// このままではMisskeyが利用できないので強制的にサインアウトさせる
main.on('myTokenRegenerated', () => {
alert('%i18n:common.my-token-regenerated%');
this.signout();
});
}
}
/** /**
* Register service worker * Register service worker
*/ */

View File

@ -77,6 +77,8 @@ export default Vue.extend({
methods: { methods: {
fetchMoreNotifications() { fetchMoreNotifications() {
if (this.fetchingMoreNotifications) return;
this.fetchingMoreNotifications = true; this.fetchingMoreNotifications = true;
const max = 30; const max = 30;
@ -98,8 +100,7 @@ export default Vue.extend({
onNotification(notification) { onNotification(notification) {
// TODO: ユーザーが画面を見てないと思われるとき(ブラウザやタブがアクティブじゃないなど)は送信しない // TODO: ユーザーが画面を見てないと思われるとき(ブラウザやタブがアクティブじゃないなど)は送信しない
this.connection.send({ (this as any).os.stream.send('readNotification', {
type: 'readNotification',
id: notification.id id: notification.id
}); });

View File

@ -58,8 +58,7 @@ export default Vue.extend({
methods: { methods: {
onNotification(notification) { onNotification(notification) {
// TODO: ユーザーが画面を見てないと思われるとき(ブラウザやタブがアクティブじゃないなど)は送信しない // TODO: ユーザーが画面を見てないと思われるとき(ブラウザやタブがアクティブじゃないなど)は送信しない
this.connection.send({ (this as any).os.stream.send('readNotification', {
type: 'readNotification',
id: notification.id id: notification.id
}); });

View File

@ -111,6 +111,7 @@ async function workerMain() {
*/ */
async function init(): Promise<Config> { async function init(): Promise<Config> {
Logger.info('Welcome to Misskey!'); Logger.info('Welcome to Misskey!');
Logger.info(`<<< Misskey v${pkg.version} >>>`);
new Logger('Deps').info(`Node.js ${process.version}`); new Logger('Deps').info(`Node.js ${process.version}`);
MachineInfo.show(); MachineInfo.show();

View File

@ -17,7 +17,7 @@ const summarize = (note: any): string => {
summary += note.text ? note.text : ''; summary += note.text ? note.text : '';
// ファイルが添付されているとき // ファイルが添付されているとき
if (note.files.length != 0) { if ((note.files || []).length != 0) {
summary += ` (${note.files.length}つのファイル)`; summary += ` (${note.files.length}つのファイル)`;
} }

View File

@ -3,8 +3,8 @@ import $ from 'cafy';
import User, { pack, ILocalUser } from '../../../../models/user'; import User, { pack, ILocalUser } from '../../../../models/user';
import { getFriendIds } from '../../common/get-friends'; import { getFriendIds } from '../../common/get-friends';
import Mute from '../../../../models/mute'; import Mute from '../../../../models/mute';
import * as request from 'request' import * as request from 'request';
import config from '../../../../config' import config from '../../../../config';
export const meta = { export const meta = {
desc: { desc: {
@ -18,18 +18,19 @@ export const meta = {
export default (params: any, me: ILocalUser) => new Promise(async (res, rej) => { export default (params: any, me: ILocalUser) => new Promise(async (res, rej) => {
if (config.user_recommendation && config.user_recommendation.external) { if (config.user_recommendation && config.user_recommendation.external) {
const userName = me.username const userName = me.username;
const hostName = config.hostname const hostName = config.hostname;
const limit = params.limit const limit = params.limit;
const offset = params.offset const offset = params.offset;
const timeout = config.user_recommendation.timeout const timeout = config.user_recommendation.timeout;
const engine = config.user_recommendation.engine const engine = config.user_recommendation.engine;
const url = engine const url = engine
.replace('{{host}}', hostName) .replace('{{host}}', hostName)
.replace('{{user}}', userName) .replace('{{user}}', userName)
.replace('{{limit}}', limit) .replace('{{limit}}', limit)
.replace('{{offset}}', offset) .replace('{{offset}}', offset);
request(
request(
{ {
url: url, url: url,
timeout: timeout, timeout: timeout,
@ -39,12 +40,12 @@ export default (params: any, me: ILocalUser) => new Promise(async (res, rej) =>
}, },
(error: any, response: any, body: any) => { (error: any, response: any, body: any) => {
if (!error && response.statusCode == 200) { if (!error && response.statusCode == 200) {
res(body) res(body);
} else { } else {
res([]) res([]);
} }
} }
) );
} else { } else {
// Get 'limit' parameter // Get 'limit' parameter
const [limit = 10, limitErr] = $.num.optional.range(1, 100).get(params.limit); const [limit = 10, limitErr] = $.num.optional.range(1, 100).get(params.limit);
@ -67,7 +68,7 @@ export default (params: any, me: ILocalUser) => new Promise(async (res, rej) =>
_id: { _id: {
$nin: followingIds.concat(mutedUserIds) $nin: followingIds.concat(mutedUserIds)
}, },
isLocked: false, isLocked: { $ne: true },
$or: [{ $or: [{
lastUsedAt: { lastUsedAt: {
$gte: new Date(Date.now() - ms('7days')) $gte: new Date(Date.now() - ms('7days'))

View File

@ -58,6 +58,7 @@ export default class Connection {
case 'connect': this.onChannelConnectRequested(body); break; case 'connect': this.onChannelConnectRequested(body); break;
case 'disconnect': this.onChannelDisconnectRequested(body); break; case 'disconnect': this.onChannelDisconnectRequested(body); break;
case 'channel': this.onChannelMessageRequested(body); break; case 'channel': this.onChannelMessageRequested(body); break;
case 'ch': this.onChannelMessageRequested(body); break; // alias
} }
} }
@ -180,6 +181,9 @@ export default class Connection {
const channel = new channelClass(id, this); const channel = new channelClass(id, this);
this.channels.push(channel); this.channels.push(channel);
channel.init(params); channel.init(params);
this.sendMessageToWs('connected', {
id: id
});
} }
/** /**

View File

@ -1,5 +1,6 @@
import * as Minio from 'minio'; import * as Minio from 'minio';
import * as uuid from 'uuid'; import * as uuid from 'uuid';
const sequential = require('promise-sequential');
import DriveFile, { DriveFileChunk, getDriveFileBucket } from '../models/drive-file'; import DriveFile, { DriveFileChunk, getDriveFileBucket } from '../models/drive-file';
import DriveFileThumbnail, { DriveFileThumbnailChunk } from '../models/drive-file-thumbnail'; import DriveFileThumbnail, { DriveFileThumbnailChunk } from '../models/drive-file-thumbnail';
import config from '../config'; import config from '../config';
@ -11,7 +12,7 @@ DriveFile.find({
withoutChunks: false withoutChunks: false
}] }]
}).then(async files => { }).then(async files => {
files.forEach(async file => { await sequential(files.map(file => async () => {
const minio = new Minio.Client(config.drive.config); const minio = new Minio.Client(config.drive.config);
const keyDir = `${config.drive.prefix}/${uuid.v4()}`; const keyDir = `${config.drive.prefix}/${uuid.v4()}`;
@ -60,5 +61,7 @@ DriveFile.find({
await DriveFileThumbnail.remove({ _id: thumbnail._id }); await DriveFileThumbnail.remove({ _id: thumbnail._id });
} }
//#endregion //#endregion
});
console.log('done', file._id);
}));
}); });