Compare commits
13 Commits
Author | SHA1 | Date | |
---|---|---|---|
7a406c1f13 | |||
9432af2ab5 | |||
136b13e7ca | |||
ba1c823fb1 | |||
f1301a4780 | |||
7957cd4963 | |||
ee6590d03f | |||
f2a1238b20 | |||
c464183329 | |||
389f420cad | |||
6b2888383c | |||
3c38a867b4 | |||
7f5a69f4d8 |
13
.config/mongo_initdb_example.js
Normal file
13
.config/mongo_initdb_example.js
Normal 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
12
.dockerignore
Executable file
@ -0,0 +1,12 @@
|
|||||||
|
.autogen
|
||||||
|
.git
|
||||||
|
.github
|
||||||
|
.travis
|
||||||
|
.vscode
|
||||||
|
Dockerfile
|
||||||
|
build/
|
||||||
|
docker-compose.yml
|
||||||
|
node_modules/
|
||||||
|
mongo/
|
||||||
|
redis/
|
||||||
|
elasticsearch/
|
4
.gitignore
vendored
4
.gitignore
vendored
@ -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
28
Dockerfile
Normal 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
52
docker-compose.yml
Normal 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
47
docs/docker.en.md
Normal 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
48
docs/docker.ja.md
Normal 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`
|
||||||
|
|
||||||
|
----------------------------------------------------------------
|
||||||
|
|
||||||
|
なにかお困りのことがありましたらお気軽にご連絡ください。
|
@ -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: "アンインストール"
|
||||||
|
13
package.json
13
package.json
@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"name": "misskey",
|
"name": "misskey",
|
||||||
"author": "syuilo <i@syuilo.com>",
|
"author": "syuilo <i@syuilo.com>",
|
||||||
"version": "10.2.0",
|
"version": "10.3.0",
|
||||||
"clientVersion": "1.0.10362",
|
"clientVersion": "1.0.10375",
|
||||||
"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",
|
||||||
@ -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",
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -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 => {
|
||||||
|
@ -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
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -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);
|
||||||
|
@ -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()
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -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()
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -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
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -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
|
||||||
});
|
});
|
||||||
|
@ -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
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -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');
|
||||||
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
@ -98,8 +98,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
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -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
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -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}つのファイル)`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
}));
|
||||||
});
|
});
|
||||||
|
Reference in New Issue
Block a user