From 372bfaceda5bf694bf33986b5a64a56e5787104c Mon Sep 17 00:00:00 2001 From: syuilo Date: Sun, 29 Apr 2018 17:17:15 +0900 Subject: [PATCH] =?UTF-8?q?=E3=83=AA=E3=83=95=E3=82=A1=E3=82=AF=E3=82=BF?= =?UTF-8?q?=E3=83=AA=E3=83=B3=E3=82=B0=E3=81=AA=E3=81=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/client/app/common/define-widget.ts | 62 +++++++------ src/client/app/common/mios.ts | 56 +++++++----- .../app/common/scripts/streaming/home.ts | 23 ++++- .../app/common/views/components/avatar.vue | 38 ++++++++ .../app/common/views/components/index.ts | 2 + .../components/messaging-room.message.vue | 24 ++--- .../app/common/views/components/messaging.vue | 4 +- .../views/components/welcome-timeline.vue | 15 ++-- .../app/common/views/widgets/access-log.vue | 1 + .../app/common/views/widgets/broadcast.vue | 1 + .../app/common/views/widgets/calendar.vue | 1 + .../app/common/views/widgets/photo-stream.vue | 2 + src/client/app/common/views/widgets/rss.vue | 1 + .../app/common/views/widgets/server.vue | 2 + .../app/common/views/widgets/slideshow.vue | 2 + .../views/components/friends-maker.vue | 17 ++-- .../app/desktop/views/components/home.vue | 83 ++++++----------- .../views/components/note-detail.sub.vue | 17 ++-- .../desktop/views/components/note-detail.vue | 37 +++----- .../desktop/views/components/note-preview.vue | 17 ++-- .../views/components/notes.note.sub.vue | 17 ++-- .../desktop/views/components/notes.note.vue | 38 +++----- .../app/desktop/views/components/notes.vue | 6 +- .../views/components/notifications.vue | 41 +++------ .../app/desktop/views/components/settings.vue | 59 ++++++------ .../views/components/timeline.core.vue | 8 +- .../views/components/ui.header.account.vue | 2 +- .../views/components/user-list-timeline.vue | 8 +- .../desktop/views/components/user-preview.vue | 16 ++-- .../views/components/users-list.item.vue | 17 ++-- .../views/components/widget-container.vue | 4 +- .../app/desktop/views/components/window.vue | 4 +- .../desktop/views/pages/user-list.users.vue | 17 ++-- .../desktop/views/pages/user/user.friends.vue | 17 ++-- .../desktop/views/pages/user/user.header.vue | 3 +- .../app/desktop/views/pages/welcome.vue | 4 +- .../app/desktop/views/widgets/activity.vue | 2 + .../app/desktop/views/widgets/channel.vue | 1 + .../app/desktop/views/widgets/messaging.vue | 1 + .../desktop/views/widgets/notifications.vue | 1 + .../app/desktop/views/widgets/polls.vue | 1 + .../app/desktop/views/widgets/post-form.vue | 1 + .../app/desktop/views/widgets/profile.vue | 1 + .../app/desktop/views/widgets/timemachine.vue | 1 + .../app/desktop/views/widgets/trends.vue | 1 + .../app/desktop/views/widgets/users.vue | 18 ++-- src/client/app/init.ts | 28 ++---- .../views/components/note-detail.sub.vue | 17 ++-- .../mobile/views/components/note-detail.vue | 47 ++++------ .../mobile/views/components/note-preview.vue | 17 ++-- .../app/mobile/views/components/note.sub.vue | 23 ++--- .../app/mobile/views/components/note.vue | 46 ++++------ .../app/mobile/views/components/notes.vue | 6 +- .../mobile/views/components/notification.vue | 32 +++---- .../app/mobile/views/components/post-form.vue | 2 +- .../views/components/user-list-timeline.vue | 8 +- .../mobile/views/components/user-preview.vue | 25 ++---- .../app/mobile/views/pages/dashboard.vue | 20 ++--- .../app/mobile/views/pages/home.timeline.vue | 8 +- src/client/app/mobile/views/pages/welcome.vue | 4 +- .../app/mobile/views/widgets/activity.vue | 1 + src/client/app/store.ts | 90 +++++++++++++++++++ .../api/endpoints/i/update_client_setting.ts | 17 ++-- src/server/index.ts | 6 +- 64 files changed, 521 insertions(+), 570 deletions(-) create mode 100644 src/client/app/common/views/components/avatar.vue create mode 100644 src/client/app/store.ts 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(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(); + }, - this.$watch('props', newProps => { - if (this.preventSave) { - this.preventSave = false; - this.bakeProps(); - return; + methods: { + bakeProps() { + this.bakedOldProps = JSON.stringify(this.props); + }, + + 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; + 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 @@ + + + + + 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 @@