summaryrefslogtreecommitdiff
path: root/src/client/app/common
diff options
context:
space:
mode:
authorsyuilo <syuilotan@yahoo.co.jp>2018-04-29 17:17:15 +0900
committersyuilo <syuilotan@yahoo.co.jp>2018-04-29 17:17:15 +0900
commit372bfaceda5bf694bf33986b5a64a56e5787104c (patch)
treec498cd9fac2f79404e2d5b74549a5d759257ddcf /src/client/app/common
parentMerge pull request #1559 from syuilo/visibility (diff)
downloadmisskey-372bfaceda5bf694bf33986b5a64a56e5787104c.tar.gz
misskey-372bfaceda5bf694bf33986b5a64a56e5787104c.tar.bz2
misskey-372bfaceda5bf694bf33986b5a64a56e5787104c.zip
リファクタリングなど
Diffstat (limited to 'src/client/app/common')
-rw-r--r--src/client/app/common/define-widget.ts62
-rw-r--r--src/client/app/common/mios.ts56
-rw-r--r--src/client/app/common/scripts/streaming/home.ts23
-rw-r--r--src/client/app/common/views/components/avatar.vue38
-rw-r--r--src/client/app/common/views/components/index.ts2
-rw-r--r--src/client/app/common/views/components/messaging-room.message.vue24
-rw-r--r--src/client/app/common/views/components/messaging.vue4
-rw-r--r--src/client/app/common/views/components/welcome-timeline.vue15
-rw-r--r--src/client/app/common/views/widgets/access-log.vue1
-rw-r--r--src/client/app/common/views/widgets/broadcast.vue1
-rw-r--r--src/client/app/common/views/widgets/calendar.vue1
-rw-r--r--src/client/app/common/views/widgets/photo-stream.vue2
-rw-r--r--src/client/app/common/views/widgets/rss.vue1
-rw-r--r--src/client/app/common/views/widgets/server.vue2
-rw-r--r--src/client/app/common/views/widgets/slideshow.vue2
15 files changed, 156 insertions, 78 deletions
diff --git a/src/client/app/common/define-widget.ts b/src/client/app/common/define-widget.ts
index 7b98c0903f..0b2bc36566 100644
--- a/src/client/app/common/define-widget.ts
+++ b/src/client/app/common/define-widget.ts
@@ -18,61 +18,65 @@ export default function<T extends object>(data: {
default: false
}
},
+
computed: {
id(): string {
return this.widget.id;
+ },
+
+ props(): T {
+ return this.widget.data;
}
},
+
data() {
return {
- props: data.props ? data.props() : {} as T,
- bakedOldProps: null,
- preventSave: false
+ bakedOldProps: null
};
},
+
created() {
- if (this.props) {
- Object.keys(this.props).forEach(prop => {
- if (this.widget.data.hasOwnProperty(prop)) {
- this.props[prop] = this.widget.data[prop];
- }
- });
- }
+ this.mergeProps();
+
+ this.$watch('props', () => {
+ this.mergeProps();
+ });
this.bakeProps();
+ },
+
+ methods: {
+ bakeProps() {
+ this.bakedOldProps = JSON.stringify(this.props);
+ },
- this.$watch('props', newProps => {
- if (this.preventSave) {
- this.preventSave = false;
- this.bakeProps();
- return;
+ mergeProps() {
+ if (data.props) {
+ const defaultProps = data.props();
+ Object.keys(defaultProps).forEach(prop => {
+ if (!this.props.hasOwnProperty(prop)) {
+ Vue.set(this.props, prop, defaultProps[prop]);
+ }
+ });
}
- if (this.bakedOldProps == JSON.stringify(newProps)) return;
+ },
+
+ save() {
+ if (this.bakedOldProps == JSON.stringify(this.props)) return;
this.bakeProps();
if (this.isMobile) {
(this as any).api('i/update_mobile_home', {
id: this.id,
- data: newProps
- }).then(() => {
- (this as any).os.i.clientSettings.mobileHome.find(w => w.id == this.id).data = newProps;
+ data: this.props
});
} else {
(this as any).api('i/update_home', {
id: this.id,
- data: newProps
- }).then(() => {
- (this as any).os.i.clientSettings.home.find(w => w.id == this.id).data = newProps;
+ data: this.props
});
}
- }, {
- deep: true
- });
- },
- methods: {
- bakeProps() {
- this.bakedOldProps = JSON.stringify(this.props);
}
}
});
diff --git a/src/client/app/common/mios.ts b/src/client/app/common/mios.ts
index 4e471cf96f..7dcae47946 100644
--- a/src/client/app/common/mios.ts
+++ b/src/client/app/common/mios.ts
@@ -3,6 +3,7 @@ import { EventEmitter } from 'eventemitter3';
import * as merge from 'object-assign-deep';
import * as uuid from 'uuid';
+import initStore from '../store';
import { hostname, apiUrl, swPublickey, version, lang, googleMapsApiKey } from '../config';
import Progress from './scripts/loading';
import Connection from './scripts/streaming/stream';
@@ -16,16 +17,6 @@ import Err from '../common/views/components/connect-failed.vue';
import { LocalTimelineStreamManager } from './scripts/streaming/local-timeline';
import { GlobalTimelineStreamManager } from './scripts/streaming/global-timeline';
-const defaultSettings = {
- fetchOnScroll: true,
- showMaps: true,
- showPostFormOnTopOfTl: false,
- gradientWindowHeader: false,
- showReplyTarget: true,
- showMyRenotes: true,
- showRenotedMyNotes: true
-};
-
//#region api requests
let spinner = null;
let pending = 0;
@@ -117,6 +108,8 @@ export default class MiOS extends EventEmitter {
return localStorage.getItem('enableSounds') == 'true';
}
+ public store: ReturnType<typeof initStore>;
+
public apis: API;
/**
@@ -232,6 +225,11 @@ export default class MiOS extends EventEmitter {
console.error.apply(null, args);
}
+ public bakeMe() {
+ // ローカルストレージにキャッシュ
+ localStorage.setItem('me', JSON.stringify(this.i));
+ }
+
public signout() {
localStorage.removeItem('me');
document.cookie = `i=; domain=${hostname}; expires=Thu, 01 Jan 1970 00:00:01 GMT;`;
@@ -243,6 +241,8 @@ export default class MiOS extends EventEmitter {
* @param callback A function that call when initialized
*/
public async init(callback) {
+ this.store = initStore(this);
+
//#region Init stream managers
this.streams.serverStream = new ServerStreamManager(this);
@@ -307,16 +307,11 @@ export default class MiOS extends EventEmitter {
// フェッチが完了したとき
const fetched = me => {
- if (me) {
- // デフォルトの設定をマージ
- me.clientSettings = Object.assign(defaultSettings, me.clientSettings);
-
- // ローカルストレージにキャッシュ
- localStorage.setItem('me', JSON.stringify(me));
- }
-
this.i = me;
+ // ローカルストレージにキャッシュ
+ this.bakeMe();
+
this.emit('signedin');
// Finish init
@@ -333,6 +328,14 @@ export default class MiOS extends EventEmitter {
// Get cached account data
const cachedMe = JSON.parse(localStorage.getItem('me'));
+ //#region キャッシュされた設定を復元
+ const cachedSettings = JSON.parse(localStorage.getItem('settings'));
+
+ if (cachedSettings) {
+ this.store.commit('settings/init', cachedSettings);
+ }
+ //#endregion
+
// キャッシュがあったとき
if (cachedMe) {
if (cachedMe.token == null) {
@@ -346,12 +349,25 @@ export default class MiOS extends EventEmitter {
// 後から新鮮なデータをフェッチ
fetchme(cachedMe.token, freshData => {
merge(cachedMe, freshData);
+
+ this.store.commit('settings/init', freshData.clientSettings);
});
} else {
// Get token from cookie
const i = (document.cookie.match(/i=(!\w+)/) || [null, null])[1];
- fetchme(i, fetched);
+ fetchme(i, me => {
+ if (me) {
+ Object.entries(me.clientSettings).forEach(([key, value]) => {
+ this.store.commit('settings/set', { key, value });
+ });
+
+ fetched(me);
+ } else {
+ // Finish init
+ callback();
+ }
+ });
}
}
@@ -456,7 +472,7 @@ export default class MiOS extends EventEmitter {
};
const promise = new Promise((resolve, reject) => {
- const viaStream = this.stream.hasConnection &&
+ const viaStream = this.stream && this.stream.hasConnection &&
(localStorage.getItem('apiViaStream') ? localStorage.getItem('apiViaStream') == 'true' : true);
if (viaStream) {
diff --git a/src/client/app/common/scripts/streaming/home.ts b/src/client/app/common/scripts/streaming/home.ts
index 73f2c5302c..ddb0d4820e 100644
--- a/src/client/app/common/scripts/streaming/home.ts
+++ b/src/client/app/common/scripts/streaming/home.ts
@@ -25,10 +25,31 @@ export class HomeStream extends Stream {
console.log('I updated:', i);
}
merge(me, i);
+
+ // キャッシュ更新
+ os.bakeMe();
+ });
+
+ this.on('clientSettingUpdated', x => {
+ os.store.commit('settings/set', {
+ key: x.key,
+ value: x.value
+ });
+ });
+
+ this.on('home_updated', x => {
+ if (x.home) {
+ os.store.commit('settings/setHome', x.home);
+ } else {
+ os.store.commit('settings/setHomeWidget', {
+ id: x.id,
+ data: x.data
+ });
+ }
});
// トークンが再生成されたとき
- // このままではAPIが利用できないので強制的にサインアウトさせる
+ // このままではMisskeyが利用できないので強制的にサインアウトさせる
this.on('my_token_regenerated', () => {
alert('%i18n:!common.my-token-regenerated%');
os.signout();
diff --git a/src/client/app/common/views/components/avatar.vue b/src/client/app/common/views/components/avatar.vue
new file mode 100644
index 0000000000..5aac9c8ba1
--- /dev/null
+++ b/src/client/app/common/views/components/avatar.vue
@@ -0,0 +1,38 @@
+<template>
+ <router-link class="mk-avatar" :to="user | userPage" :title="user | acct" :target="target" :style="{ borderRadius: clientSettings.circleIcons ? '100%' : null }">
+ <img v-if="disablePreview" :src="`${user.avatarUrl}?thumbnail&size=128`" alt=""/>
+ <img v-else :src="`${user.avatarUrl}?thumbnail&size=128`" alt="" v-user-preview="user.id"/>
+ </router-link>
+</template>
+
+<script lang="ts">
+import Vue from 'vue';
+export default Vue.extend({
+ props: {
+ user: {
+ required: true
+ },
+ target: {
+ required: false,
+ default: null
+ },
+ disablePreview: {
+ required: false,
+ default: false
+ }
+ }
+});
+</script>
+
+<style lang="stylus" scoped>
+.mk-avatar
+ display block
+
+ > img
+ display inline-block
+ width 100%
+ height 100%
+ margin 0
+ border-radius inherit
+ vertical-align bottom
+</style>
diff --git a/src/client/app/common/views/components/index.ts b/src/client/app/common/views/components/index.ts
index 6bfe43a800..69fed00c74 100644
--- a/src/client/app/common/views/components/index.ts
+++ b/src/client/app/common/views/components/index.ts
@@ -3,6 +3,7 @@ import Vue from 'vue';
import signin from './signin.vue';
import signup from './signup.vue';
import forkit from './forkit.vue';
+import avatar from './avatar.vue';
import nav from './nav.vue';
import noteHtml from './note-html';
import poll from './poll.vue';
@@ -28,6 +29,7 @@ import welcomeTimeline from './welcome-timeline.vue';
Vue.component('mk-signin', signin);
Vue.component('mk-signup', signup);
Vue.component('mk-forkit', forkit);
+Vue.component('mk-avatar', avatar);
Vue.component('mk-nav', nav);
Vue.component('mk-note-html', noteHtml);
Vue.component('mk-poll', poll);
diff --git a/src/client/app/common/views/components/messaging-room.message.vue b/src/client/app/common/views/components/messaging-room.message.vue
index 70df899f5a..ba0ab3209f 100644
--- a/src/client/app/common/views/components/messaging-room.message.vue
+++ b/src/client/app/common/views/components/messaging-room.message.vue
@@ -1,8 +1,6 @@
<template>
<div class="message" :data-is-me="isMe">
- <router-link class="avatar-anchor" :to="message.user | userPage" :title="message.user | acct" target="_blank">
- <img class="avatar" :src="`${message.user.avatarUrl}?thumbnail&size=80`" alt=""/>
- </router-link>
+ <mk-avatar class="avatar" :user="message.user" target="_blank"/>
<div class="content">
<div class="balloon" :data-no-text="message.text == null">
<p class="read" v-if="isMe && message.isRead">%i18n:@is-read%</p>
@@ -67,20 +65,14 @@ export default Vue.extend({
padding 10px 12px 10px 12px
background-color transparent
- > .avatar-anchor
+ > .avatar
display block
position absolute
top 10px
-
- > .avatar
- display block
- min-width 54px
- min-height 54px
- max-width 54px
- max-height 54px
- margin 0
- border-radius 8px
- transition all 0.1s ease
+ width 54px
+ height 54px
+ border-radius 8px
+ transition all 0.1s ease
> .content
@@ -201,7 +193,7 @@ export default Vue.extend({
margin-left 4px
&:not([data-is-me])
- > .avatar-anchor
+ > .avatar
left 12px
> .content
@@ -225,7 +217,7 @@ export default Vue.extend({
text-align left
&[data-is-me]
- > .avatar-anchor
+ > .avatar
right 12px
> .content
diff --git a/src/client/app/common/views/components/messaging.vue b/src/client/app/common/views/components/messaging.vue
index 6f8fcb3a70..11f9c366d4 100644
--- a/src/client/app/common/views/components/messaging.vue
+++ b/src/client/app/common/views/components/messaging.vue
@@ -13,7 +13,7 @@
@click="navigate(user)"
tabindex="-1"
>
- <img class="avatar" :src="`${user.avatarUrl}?thumbnail&size=32`" alt=""/>
+ <mk-avatar class="avatar" :user="user"/>
<span class="name">{{ user | userName }}</span>
<span class="username">@{{ user | acct }}</span>
</li>
@@ -31,7 +31,7 @@
:key="message.id"
>
<div>
- <img class="avatar" :src="`${isMe(message) ? message.recipient.avatarUrl : message.user.avatarUrl}?thumbnail&size=64`" alt=""/>
+ <mk-avatar class="avatar" :user="isMe(message) ? message.recipient : message.user"/>
<header>
<span class="name">{{ isMe(message) ? message.recipient : message.user | userName }}</span>
<span class="username">@{{ isMe(message) ? message.recipient : message.user | acct }}</span>
diff --git a/src/client/app/common/views/components/welcome-timeline.vue b/src/client/app/common/views/components/welcome-timeline.vue
index 3497976901..6fadb030c3 100644
--- a/src/client/app/common/views/components/welcome-timeline.vue
+++ b/src/client/app/common/views/components/welcome-timeline.vue
@@ -1,9 +1,7 @@
<template>
<div class="mk-welcome-timeline">
<div v-for="note in notes">
- <router-link class="avatar-anchor" :to="note.user | userPage" v-user-preview="note.user.id">
- <img class="avatar" :src="`${note.user.avatarUrl}?thumbnail&size=96`" alt="avatar"/>
- </router-link>
+ <mk-avatar class="avatar" :user="note.user" target="_blank"/>
<div class="body">
<header>
<router-link class="name" :to="note.user | userPage" v-user-preview="note.user.id">{{ note.user | userName }}</router-link>
@@ -69,18 +67,15 @@ export default Vue.extend({
display block
clear both
- > .avatar-anchor
+ > .avatar
display block
float left
position -webkit-sticky
position sticky
top 16px
-
- > img
- display block
- width 42px
- height 42px
- border-radius 6px
+ width 42px
+ height 42px
+ border-radius 6px
> .body
float right
diff --git a/src/client/app/common/views/widgets/access-log.vue b/src/client/app/common/views/widgets/access-log.vue
index 0b1c7fe2dd..8652e35645 100644
--- a/src/client/app/common/views/widgets/access-log.vue
+++ b/src/client/app/common/views/widgets/access-log.vue
@@ -61,6 +61,7 @@ export default define({
} else {
this.props.design++;
}
+ this.save();
}
}
});
diff --git a/src/client/app/common/views/widgets/broadcast.vue b/src/client/app/common/views/widgets/broadcast.vue
index 96d1d0ef3a..75b1d60524 100644
--- a/src/client/app/common/views/widgets/broadcast.vue
+++ b/src/client/app/common/views/widgets/broadcast.vue
@@ -68,6 +68,7 @@ export default define({
} else {
this.props.design++;
}
+ this.save();
}
}
});
diff --git a/src/client/app/common/views/widgets/calendar.vue b/src/client/app/common/views/widgets/calendar.vue
index 0bb503759c..41e9253784 100644
--- a/src/client/app/common/views/widgets/calendar.vue
+++ b/src/client/app/common/views/widgets/calendar.vue
@@ -73,6 +73,7 @@ export default define({
} else {
this.props.design++;
}
+ this.save();
},
tick() {
const now = new Date();
diff --git a/src/client/app/common/views/widgets/photo-stream.vue b/src/client/app/common/views/widgets/photo-stream.vue
index c51d932bd1..ae5924bb10 100644
--- a/src/client/app/common/views/widgets/photo-stream.vue
+++ b/src/client/app/common/views/widgets/photo-stream.vue
@@ -59,6 +59,8 @@ export default define({
} else {
this.props.design++;
}
+
+ this.save();
}
}
});
diff --git a/src/client/app/common/views/widgets/rss.vue b/src/client/app/common/views/widgets/rss.vue
index f0ba11678e..b5339add0b 100644
--- a/src/client/app/common/views/widgets/rss.vue
+++ b/src/client/app/common/views/widgets/rss.vue
@@ -40,6 +40,7 @@ export default define({
methods: {
func() {
this.props.compact = !this.props.compact;
+ this.save();
},
fetch() {
fetch(`https://api.rss2json.com/v1/api.json?rss_url=${this.url}`, {
diff --git a/src/client/app/common/views/widgets/server.vue b/src/client/app/common/views/widgets/server.vue
index 2fbc07adf0..2fdd60499b 100644
--- a/src/client/app/common/views/widgets/server.vue
+++ b/src/client/app/common/views/widgets/server.vue
@@ -68,6 +68,7 @@ export default define({
} else {
this.props.view++;
}
+ this.save();
},
func() {
if (this.props.design == 2) {
@@ -75,6 +76,7 @@ export default define({
} else {
this.props.design++;
}
+ this.save();
}
}
});
diff --git a/src/client/app/common/views/widgets/slideshow.vue b/src/client/app/common/views/widgets/slideshow.vue
index 95be4b94fd..459b24a32f 100644
--- a/src/client/app/common/views/widgets/slideshow.vue
+++ b/src/client/app/common/views/widgets/slideshow.vue
@@ -64,6 +64,7 @@ export default define({
} else {
this.props.size++;
}
+ this.save();
this.applySize();
},
@@ -111,6 +112,7 @@ export default define({
choose() {
(this as any).apis.chooseDriveFolder().then(folder => {
this.props.folder = folder ? folder.id : null;
+ this.save();
this.fetch();
});
}