diff options
| author | syuilo <syuilotan@yahoo.co.jp> | 2019-06-23 00:22:33 +0900 |
|---|---|---|
| committer | syuilo <syuilotan@yahoo.co.jp> | 2019-06-23 00:22:33 +0900 |
| commit | 73ac2632c25270e1ea5e435f62fc29af9bfb09a1 (patch) | |
| tree | 1c187f4b861ee91ae67bfcf6fd3e50183c9df442 /src | |
| parent | Merge branch 'develop' (diff) | |
| parent | 11.23.0 (diff) | |
| download | misskey-73ac2632c25270e1ea5e435f62fc29af9bfb09a1.tar.gz misskey-73ac2632c25270e1ea5e435f62fc29af9bfb09a1.tar.bz2 misskey-73ac2632c25270e1ea5e435f62fc29af9bfb09a1.zip | |
Merge branch 'develop'
Diffstat (limited to 'src')
22 files changed, 395 insertions, 242 deletions
diff --git a/src/client/app/common/define-widget.ts b/src/client/app/common/define-widget.ts index 632ddf2ed6..ba4deafe3a 100644 --- a/src/client/app/common/define-widget.ts +++ b/src/client/app/common/define-widget.ts @@ -60,9 +60,9 @@ export default function <T extends object>(data: { save() { if (this.platform == 'deck') { - this.$store.commit('device/updateDeckColumn', this.column); + this.$store.commit('updateDeckColumn', this.column); } else { - this.$store.commit('device/updateWidget', this.widget); + this.$store.commit('updateWidget', this.widget); } } } diff --git a/src/client/app/common/scripts/note-mixin.ts b/src/client/app/common/scripts/note-mixin.ts index 4b454f8800..e649680070 100644 --- a/src/client/app/common/scripts/note-mixin.ts +++ b/src/client/app/common/scripts/note-mixin.ts @@ -83,9 +83,19 @@ export default (opts: Opts = {}) => ({ if (this.appearNote.text) { const ast = parse(this.appearNote.text); // TODO: 再帰的にURL要素がないか調べる - return unique(ast + const urls = unique(ast .filter(t => ((t.node.type == 'url' || t.node.type == 'link') && t.node.props.url && !t.node.props.silent)) .map(t => t.node.props.url)); + + // unique without hash + // [ http://a/#1, http://a/#2, http://b/#3 ] => [ http://a/#1, http://b/#3 ] + const removeHash = x => x.replace(/#[^#]*$/, ''); + + return urls.reduce((array, url) => { + const removed = removeHash(url); + if (!array.map(x => removeHash(x)).includes(removed)) array.push(url); + return array; + }, []); } else { return null; } diff --git a/src/client/app/common/views/components/settings/settings.vue b/src/client/app/common/views/components/settings/settings.vue index 0cbc40da57..1254eb5e5e 100644 --- a/src/client/app/common/views/components/settings/settings.vue +++ b/src/client/app/common/views/components/settings/settings.vue @@ -132,6 +132,13 @@ </section> <section> + <header>{{ $t('@._settings.sync') }}</header> + <ui-input v-if="$root.isMobile" v-model="mobileHomeProfile" :datalist="Object.keys($store.state.settings.mobileHomeProfiles)">{{ $t('@._settings.home-profile') }}</ui-input> + <ui-input v-else v-model="homeProfile" :datalist="Object.keys($store.state.settings.homeProfiles)">{{ $t('@._settings.home-profile') }}</ui-input> + <ui-input v-model="deckProfile" :datalist="Object.keys($store.state.settings.deckProfiles)">{{ $t('@._settings.deck-profile') }}</ui-input> + </section> + + <section> <header>{{ $t('@._settings.web-search-engine') }}</header> <ui-input v-model="webSearchEngine">{{ $t('@._settings.web-search-engine') }}<template #desc>{{ $t('@._settings.web-search-engine-desc') }}</template></ui-input> </section> @@ -500,6 +507,21 @@ export default Vue.extend({ get() { return this.$store.state.device.mobileNotificationPosition; }, set(value) { this.$store.commit('device/set', { key: 'mobileNotificationPosition', value }); } }, + + homeProfile: { + get() { return this.$store.state.device.homeProfile; }, + set(value) { this.$store.commit('device/set', { key: 'homeProfile', value }); } + }, + + mobileHomeProfile: { + get() { return this.$store.state.device.mobileHomeProfile; }, + set(value) { this.$store.commit('device/set', { key: 'mobileHomeProfile', value }); } + }, + + deckProfile: { + get() { return this.$store.state.device.deckProfile; }, + set(value) { this.$store.commit('device/set', { key: 'deckProfile', value }); } + }, }, created() { this.$root.getMeta().then(meta => { diff --git a/src/client/app/common/views/components/url-preview.vue b/src/client/app/common/views/components/url-preview.vue index 9c61e46059..20fbcbb046 100644 --- a/src/client/app/common/views/components/url-preview.vue +++ b/src/client/app/common/views/components/url-preview.vue @@ -30,7 +30,7 @@ <script lang="ts"> import Vue from 'vue'; import i18n from '../../../i18n'; -import { url as local } from '../../../config'; +import { url as local, lang } from '../../../config'; export default Vue.extend({ i18n: i18n('common/views/components/url-preview.vue'), @@ -89,10 +89,10 @@ export default Vue.extend({ }, created() { - const url = new URL(this.url); + const requestUrl = new URL(this.url); - if (this.detail && url.hostname == 'twitter.com' && /^\/.+\/status(es)?\/\d+/.test(url.pathname)) { - this.tweetUrl = url; + if (this.detail && requestUrl.hostname == 'twitter.com' && /^\/.+\/status(es)?\/\d+/.test(requestUrl.pathname)) { + this.tweetUrl = requestUrl; const twttr = (window as any).twttr || {}; const loadTweet = () => twttr.widgets.load(this.$refs.tweet); @@ -113,10 +113,15 @@ export default Vue.extend({ return; } - if (url.hostname === 'music.youtube.com') - url.hostname = 'youtube.com'; + if (requestUrl.hostname === 'music.youtube.com') { + requestUrl.hostname = 'youtube.com'; + } + + const requestLang = (lang || 'ja-JP').replace('ja-KS', 'ja-JP'); + + requestUrl.hash = ''; - fetch(`/url?url=${encodeURIComponent(this.url)}`).then(res => { + fetch(`/url?url=${encodeURIComponent(requestUrl.href)}&lang=${requestLang}`).then(res => { res.json().then(info => { if (info.url == null) return; this.title = info.title; diff --git a/src/client/app/common/views/deck/deck.column.vue b/src/client/app/common/views/deck/deck.column.vue index eaa344d36f..b5c0896bba 100644 --- a/src/client/app/common/views/deck/deck.column.vue +++ b/src/client/app/common/views/deck/deck.column.vue @@ -146,7 +146,8 @@ export default Vue.extend({ toggleActive() { if (!this.isStacked) return; - const vms = this.$store.state.device.deck.layout.find(ids => ids.indexOf(this.column.id) != -1).map(id => this.getColumnVm(id)); + const deck = this.$store.state.device.deckProfile ? this.$store.state.settings.deckProfiles[this.$store.state.device.deckProfile] : this.$store.state.device.deck; + const vms = deck.layout.find(ids => ids.indexOf(this.column.id) != -1).map(id => this.getColumnVm(id)); if (this.active && countIf(vm => vm.$el.classList.contains('active'), vms) == 1) return; this.active = !this.active; }, @@ -179,50 +180,50 @@ export default Vue.extend({ } }).then(({ canceled, result: name }) => { if (canceled) return; - this.$store.commit('device/renameDeckColumn', { id: this.column.id, name }); + this.$store.commit('renameDeckColumn', { id: this.column.id, name }); }); } }, null, { icon: 'arrow-left', text: this.$t('swap-left'), action: () => { - this.$store.commit('device/swapLeftDeckColumn', this.column.id); + this.$store.commit('swapLeftDeckColumn', this.column.id); } }, { icon: 'arrow-right', text: this.$t('swap-right'), action: () => { - this.$store.commit('device/swapRightDeckColumn', this.column.id); + this.$store.commit('swapRightDeckColumn', this.column.id); } }, this.isStacked ? { icon: faArrowUp, text: this.$t('swap-up'), action: () => { - this.$store.commit('device/swapUpDeckColumn', this.column.id); + this.$store.commit('swapUpDeckColumn', this.column.id); } } : undefined, this.isStacked ? { icon: faArrowDown, text: this.$t('swap-down'), action: () => { - this.$store.commit('device/swapDownDeckColumn', this.column.id); + this.$store.commit('swapDownDeckColumn', this.column.id); } } : undefined, null, { icon: ['far', 'window-restore'], text: this.$t('stack-left'), action: () => { - this.$store.commit('device/stackLeftDeckColumn', this.column.id); + this.$store.commit('stackLeftDeckColumn', this.column.id); } }, this.isStacked ? { icon: faWindowMaximize, text: this.$t('pop-right'), action: () => { - this.$store.commit('device/popRightDeckColumn', this.column.id); + this.$store.commit('popRightDeckColumn', this.column.id); } } : undefined, null, { icon: ['far', 'trash-alt'], text: this.$t('remove'), action: () => { - this.$store.commit('device/removeDeckColumn', this.column.id); + this.$store.commit('removeDeckColumn', this.column.id); } }]; @@ -306,7 +307,7 @@ export default Vue.extend({ const id = e.dataTransfer.getData('mk-deck-column'); if (id != null && id != '') { - this.$store.commit('device/swapDeckColumn', { + this.$store.commit('swapDeckColumn', { a: this.column.id, b: id }); diff --git a/src/client/app/common/views/deck/deck.tl-column.vue b/src/client/app/common/views/deck/deck.tl-column.vue index 5ab8ccb12f..cad140ed5f 100644 --- a/src/client/app/common/views/deck/deck.tl-column.vue +++ b/src/client/app/common/views/deck/deck.tl-column.vue @@ -90,7 +90,7 @@ export default Vue.extend({ methods: { onChangeSettings(v) { - this.$store.commit('device/updateDeckColumn', this.column); + this.$store.commit('updateDeckColumn', this.column); }, focus() { diff --git a/src/client/app/common/views/deck/deck.vue b/src/client/app/common/views/deck/deck.vue index b46f2167ad..36e0f8161e 100644 --- a/src/client/app/common/views/deck/deck.vue +++ b/src/client/app/common/views/deck/deck.vue @@ -25,20 +25,25 @@ import * as uuid from 'uuid'; export default Vue.extend({ i18n: i18n('deck'), + components: { XColumnCore }, computed: { + deck() { + return this.$store.getters.deck; + }, + columns(): any[] { - if (this.$store.state.device.deck == null) return []; - return this.$store.state.device.deck.columns; + if (this.deck == null) return []; + return this.deck.columns; }, layout(): any[] { - if (this.$store.state.device.deck == null) return []; - if (this.$store.state.device.deck.layout == null) return this.$store.state.device.deck.columns.map(c => [c.id]); - return this.$store.state.device.deck.layout; + if (this.deck == null) return []; + if (this.deck.layout == null) return this.deck.columns.map(c => [c.id]); + return this.deck.layout; }, style(): any { @@ -75,7 +80,7 @@ export default Vue.extend({ }, created() { - if (this.$store.state.device.deck == null) { + if (this.deck == null) { const deck = { columns: [/*{ type: 'widgets', @@ -101,10 +106,7 @@ export default Vue.extend({ deck.layout = deck.columns.map(c => [c.id]); - this.$store.commit('device/set', { - key: 'deck', - value: deck - }); + this.$store.commit('setDeck', deck); } }, @@ -129,7 +131,7 @@ export default Vue.extend({ icon: 'home', text: this.$t('@deck.home'), action: () => { - this.$store.commit('device/addDeckColumn', { + this.$store.commit('addDeckColumn', { id: uuid(), type: 'home' }); @@ -138,7 +140,7 @@ export default Vue.extend({ icon: ['far', 'comments'], text: this.$t('@deck.local'), action: () => { - this.$store.commit('device/addDeckColumn', { + this.$store.commit('addDeckColumn', { id: uuid(), type: 'local' }); @@ -147,7 +149,7 @@ export default Vue.extend({ icon: 'share-alt', text: this.$t('@deck.hybrid'), action: () => { - this.$store.commit('device/addDeckColumn', { + this.$store.commit('addDeckColumn', { id: uuid(), type: 'hybrid' }); @@ -156,7 +158,7 @@ export default Vue.extend({ icon: 'globe', text: this.$t('@deck.global'), action: () => { - this.$store.commit('device/addDeckColumn', { + this.$store.commit('addDeckColumn', { id: uuid(), type: 'global' }); @@ -165,7 +167,7 @@ export default Vue.extend({ icon: 'at', text: this.$t('@deck.mentions'), action: () => { - this.$store.commit('device/addDeckColumn', { + this.$store.commit('addDeckColumn', { id: uuid(), type: 'mentions' }); @@ -174,7 +176,7 @@ export default Vue.extend({ icon: ['far', 'envelope'], text: this.$t('@deck.direct'), action: () => { - this.$store.commit('device/addDeckColumn', { + this.$store.commit('addDeckColumn', { id: uuid(), type: 'direct' }); @@ -195,7 +197,7 @@ export default Vue.extend({ showCancelButton: true }); if (canceled) return; - this.$store.commit('device/addDeckColumn', { + this.$store.commit('addDeckColumn', { id: uuid(), type: 'list', list: lists.find(l => l.id === listId) @@ -210,7 +212,7 @@ export default Vue.extend({ input: true }).then(({ canceled, result: title }) => { if (canceled) return; - this.$store.commit('device/addDeckColumn', { + this.$store.commit('addDeckColumn', { id: uuid(), type: 'hashtag', tagTlId: this.$store.state.settings.tagTimelines.find(x => x.title == title).id @@ -221,7 +223,7 @@ export default Vue.extend({ icon: ['far', 'bell'], text: this.$t('@deck.notifications'), action: () => { - this.$store.commit('device/addDeckColumn', { + this.$store.commit('addDeckColumn', { id: uuid(), type: 'notifications' }); @@ -230,7 +232,7 @@ export default Vue.extend({ icon: 'calculator', text: this.$t('@deck.widgets'), action: () => { - this.$store.commit('device/addDeckColumn', { + this.$store.commit('addDeckColumn', { id: uuid(), type: 'widgets', widgets: [] diff --git a/src/client/app/common/views/deck/deck.widgets-column.vue b/src/client/app/common/views/deck/deck.widgets-column.vue index f2385c8a48..dd28a3a8b3 100644 --- a/src/client/app/common/views/deck/deck.widgets-column.vue +++ b/src/client/app/common/views/deck/deck.widgets-column.vue @@ -110,7 +110,7 @@ export default Vue.extend({ }, addWidget() { - this.$store.commit('device/addDeckWidget', { + this.$store.commit('addDeckWidget', { id: this.column.id, widget: { name: this.widgetAdderSelected, @@ -123,14 +123,14 @@ export default Vue.extend({ }, removeWidget(widget) { - this.$store.commit('device/removeDeckWidget', { + this.$store.commit('removeDeckWidget', { id: this.column.id, widget }); }, saveWidgets() { - this.$store.commit('device/updateDeckColumn', this.column); + this.$store.commit('updateDeckColumn', this.column); } } }); diff --git a/src/client/app/common/views/widgets/server.info.vue b/src/client/app/common/views/widgets/server.info.vue index 41ccd23bfe..c6e0d68b11 100644 --- a/src/client/app/common/views/widgets/server.info.vue +++ b/src/client/app/common/views/widgets/server.info.vue @@ -4,6 +4,7 @@ <p>Machine: {{ meta.machine }}</p> <p>Node: {{ meta.node }}</p> <p>PSQL: {{ meta.psql }}</p> + <p>Redis: {{ meta.redis }}</p> <p>Version: {{ meta.version }} </p> </div> </template> diff --git a/src/client/app/desktop/views/home/home.vue b/src/client/app/desktop/views/home/home.vue index d4677df842..3d05bee48d 100644 --- a/src/client/app/desktop/views/home/home.vue +++ b/src/client/app/desktop/views/home/home.vue @@ -84,6 +84,7 @@ import XWelcome from '../pages/welcome.vue'; export default Vue.extend({ i18n: i18n('desktop/views/components/home.vue'), + components: { XDraggable, XWelcome @@ -102,7 +103,7 @@ export default Vue.extend({ computed: { home(): any[] { if (this.$store.getters.isSignedIn) { - return this.$store.state.device.home || []; + return this.$store.getters.home || []; } else { return [{ name: 'instance', @@ -138,7 +139,9 @@ export default Vue.extend({ }, created() { - if (this.$store.getters.isSignedIn) { + if (!this.$store.getters.isSignedIn) return; + + if (this.$store.getters.home == null) { const defaultDesktopHomeWidgets = { left: [ 'profile', @@ -183,9 +186,7 @@ export default Vue.extend({ } //#endregion - if (this.$store.state.device.home == null) { - this.$store.commit('device/setHome', _defaultDesktopHomeWidgets); - } + this.$store.commit('setHome', _defaultDesktopHomeWidgets); } }, @@ -223,7 +224,7 @@ export default Vue.extend({ }, addWidget() { - this.$store.commit('device/addHomeWidget', { + this.$store.commit('addHomeWidget', { name: this.widgetAdderSelected, id: uuid(), place: 'left', @@ -234,7 +235,7 @@ export default Vue.extend({ saveHome() { const left = this.widgets.left; const right = this.widgets.right; - this.$store.commit('device/setHome', left.concat(right)); + this.$store.commit('setHome', left.concat(right)); for (const w of left) w.place = 'left'; for (const w of right) w.place = 'right'; }, @@ -245,7 +246,7 @@ export default Vue.extend({ focus() { (this.$refs.content as any).focus(); - } + }, } }); </script> diff --git a/src/client/app/mios.ts b/src/client/app/mios.ts index ae1446b934..a73ef45c38 100644 --- a/src/client/app/mios.ts +++ b/src/client/app/mios.ts @@ -173,10 +173,9 @@ export default class MiOS extends EventEmitter { // Init service worker if (this.shouldRegisterSw) { - // #4813 - //this.getMeta().then(data => { - // this.registerSw(data.swPublickey); - //}); + this.getMeta().then(data => { + this.registerSw(data.swPublickey); + }); } }; diff --git a/src/client/app/mobile/views/pages/widgets.vue b/src/client/app/mobile/views/pages/widgets.vue index 7130fddb34..c012de1314 100644 --- a/src/client/app/mobile/views/pages/widgets.vue +++ b/src/client/app/mobile/views/pages/widgets.vue @@ -72,13 +72,13 @@ export default Vue.extend({ computed: { widgets(): any[] { - return this.$store.state.device.mobileHome; + return this.$store.getters.mobileHome || []; } }, created() { if (this.widgets.length == 0) { - this.$store.commit('device/setMobileHome', [{ + this.$store.commit('setMobileHome', [{ name: 'calendar', id: 'a', data: {} }, { @@ -98,6 +98,12 @@ export default Vue.extend({ id: 'g', data: {} }]); } + + this.$watch('$store.getters.mobileHome', () => { + this.$store.dispatch('settings/updateMobileHomeProfile'); + }, { + deep: true + }); }, mounted() { @@ -122,7 +128,7 @@ export default Vue.extend({ }, addWidget() { - this.$store.commit('device/addMobileHomeWidget', { + this.$store.commit('addMobileHomeWidget', { name: this.widgetAdderSelected, id: uuid(), data: {} @@ -130,11 +136,11 @@ export default Vue.extend({ }, removeWidget(widget) { - this.$store.commit('device/removeMobileHomeWidget', widget); + this.$store.commit('removeMobileHomeWidget', widget); }, saveHome() { - this.$store.commit('device/setMobileHome', this.widgets); + this.$store.commit('setMobileHome', this.widgets); } } }); diff --git a/src/client/app/store.ts b/src/client/app/store.ts index 6f545eb09b..852d2c393d 100644 --- a/src/client/app/store.ts +++ b/src/client/app/store.ts @@ -1,3 +1,4 @@ +import Vue from 'vue'; import Vuex from 'vuex'; import createPersistedState from 'vuex-persistedstate'; import * as nestedProperty from 'nested-property'; @@ -34,12 +35,15 @@ const defaultSettings = { gamesReversiShowBoardLabels: false, gamesReversiUseAvatarStones: true, disableAnimatedMfm: false, + homeProfiles: {}, + mobileHomeProfiles: {}, + deckProfiles: {}, }; const defaultDeviceSettings = { - home: null, - mobileHome: [], - deck: null, + homeProfile: 'Default', + mobileHomeProfile: 'Default', + deckProfile: 'Default', deckMode: false, deckColumnAlign: 'center', deckColumnWidth: 'normal', @@ -82,7 +86,13 @@ export default (os: MiOS) => new Vuex.Store({ }, getters: { - isSignedIn: state => state.i != null + isSignedIn: state => state.i != null, + + home: state => state.settings.homeProfiles[state.device.homeProfile], + + mobileHome: state => state.settings.mobileHomeProfiles[state.device.mobileHomeProfile], + + deck: state => state.settings.deckProfiles[state.device.deckProfile], }, mutations: { @@ -112,6 +122,216 @@ export default (os: MiOS) => new Vuex.Store({ clearBehindNotes(state) { state.behindNotes = []; document.title = os.instanceName; + }, + + setHome(state, data) { + Vue.set(state.settings.homeProfiles, state.device.homeProfile, data); + os.store.dispatch('settings/updateHomeProfile'); + }, + + setDeck(state, data) { + Vue.set(state.settings.deckProfiles, state.device.deckProfile, data); + os.store.dispatch('settings/updateDeckProfile'); + }, + + addHomeWidget(state, widget) { + state.settings.homeProfiles[state.device.homeProfile].unshift(widget); + os.store.dispatch('settings/updateHomeProfile'); + }, + + setMobileHome(state, data) { + Vue.set(state.settings.mobileHomeProfiles, state.device.mobileHomeProfile, data); + os.store.dispatch('settings/updateMobileHomeProfile'); + }, + + updateWidget(state, x) { + let w; + + //#region Desktop home + const home = state.settings.homeProfiles[state.device.homeProfile]; + if (home) { + w = home.find(w => w.id == x.id); + if (w) { + w.data = x.data; + os.store.dispatch('settings/updateHomeProfile'); + } + } + //#endregion + + //#region Mobile home + const mobileHome = state.settings.mobileHomeProfiles[state.device.mobileHomeProfile]; + if (mobileHome) { + w = mobileHome.find(w => w.id == x.id); + if (w) { + w.data = x.data; + os.store.dispatch('settings/updateMobileHomeProfile'); + } + } + //#endregion + }, + + addMobileHomeWidget(state, widget) { + state.settings.mobileHomeProfiles[state.device.mobileHomeProfile].unshift(widget); + os.store.dispatch('settings/updateMobileHomeProfile'); + }, + + removeMobileHomeWidget(state, widget) { + Vue.set('state.settings.mobileHomeProfiles', state.device.mobileHomeProfile, state.settings.mobileHomeProfiles[state.device.mobileHomeProfile].filter(w => w.id != widget.id)); + os.store.dispatch('settings/updateMobileHomeProfile'); + }, + + addDeckColumn(state, column) { + const deck = state.settings.deckProfiles[state.device.deckProfile]; + if (column.name == undefined) column.name = null; + deck.columns.push(column); + deck.layout.push([column.id]); + os.store.dispatch('settings/updateDeckProfile'); + }, + + removeDeckColumn(state, id) { + const deck = state.settings.deckProfiles[state.device.deckProfile]; + deck.columns = deck.columns.filter(c => c.id != id); + deck.layout = deck.layout.map(ids => erase(id, ids)); + deck.layout = deck.layout.filter(ids => ids.length > 0); + os.store.dispatch('settings/updateDeckProfile'); + }, + + swapDeckColumn(state, x) { + const deck = state.settings.deckProfiles[state.device.deckProfile]; + const a = x.a; + const b = x.b; + const aX = deck.layout.findIndex(ids => ids.indexOf(a) != -1); + const aY = deck.layout[aX].findIndex(id => id == a); + const bX = deck.layout.findIndex(ids => ids.indexOf(b) != -1); + const bY = deck.layout[bX].findIndex(id => id == b); + deck.layout[aX][aY] = b; + deck.layout[bX][bY] = a; + os.store.dispatch('settings/updateDeckProfile'); + }, + + swapLeftDeckColumn(state, id) { + const deck = state.settings.deckProfiles[state.device.deckProfile]; + deck.layout.some((ids, i) => { + if (ids.indexOf(id) != -1) { + const left = deck.layout[i - 1]; + if (left) { + // https://vuejs.org/v2/guide/list.html#Caveats + //state.deck.layout[i - 1] = state.deck.layout[i]; + //state.deck.layout[i] = left; + deck.layout.splice(i - 1, 1, deck.layout[i]); + deck.layout.splice(i, 1, left); + } + return true; + } + }); + os.store.dispatch('settings/updateDeckProfile'); + }, + + swapRightDeckColumn(state, id) { + const deck = state.settings.deckProfiles[state.device.deckProfile]; + deck.layout.some((ids, i) => { + if (ids.indexOf(id) != -1) { + const right = deck.layout[i + 1]; + if (right) { + // https://vuejs.org/v2/guide/list.html#Caveats + //state.deck.layout[i + 1] = state.deck.layout[i]; + //state.deck.layout[i] = right; + deck.layout.splice(i + 1, 1, deck.layout[i]); + deck.layout.splice(i, 1, right); + } + return true; + } + }); + os.store.dispatch('settings/updateDeckProfile'); + }, + + swapUpDeckColumn(state, id) { + const deck = state.settings.deckProfiles[state.device.deckProfile]; + const ids = deck.layout.find(ids => ids.indexOf(id) != -1); + ids.some((x, i) => { + if (x == id) { + const up = ids[i - 1]; + if (up) { + // https://vuejs.org/v2/guide/list.html#Caveats + //ids[i - 1] = id; + //ids[i] = up; + ids.splice(i - 1, 1, id); + ids.splice(i, 1, up); + } + return true; + } + }); + os.store.dispatch('settings/updateDeckProfile'); + }, + + swapDownDeckColumn(state, id) { + const deck = state.settings.deckProfiles[state.device.deckProfile]; + const ids = deck.layout.find(ids => ids.indexOf(id) != -1); + ids.some((x, i) => { + if (x == id) { + const down = ids[i + 1]; + if (down) { + // https://vuejs.org/v2/guide/list.html#Caveats + //ids[i + 1] = id; + //ids[i] = down; + ids.splice(i + 1, 1, id); + ids.splice(i, 1, down); + } + return true; + } + }); + os.store.dispatch('settings/updateDeckProfile'); + }, + + stackLeftDeckColumn(state, id) { + const deck = state.settings.deckProfiles[state.device.deckProfile]; + const i = deck.layout.findIndex(ids => ids.indexOf(id) != -1); + deck.layout = deck.layout.map(ids => erase(id, ids)); + const left = deck.layout[i - 1]; + if (left) deck.layout[i - 1].push(id); + deck.layout = deck.layout.filter(ids => ids.length > 0); + os.store.dispatch('settings/updateDeckProfile'); + }, + + popRightDeckColumn(state, id) { + const deck = state.settings.deckProfiles[state.device.deckProfile]; + const i = deck.layout.findIndex(ids => ids.indexOf(id) != -1); + deck.layout = deck.layout.map(ids => erase(id, ids)); + deck.layout.splice(i + 1, 0, [id]); + deck.layout = deck.layout.filter(ids => ids.length > 0); + os.store.dispatch('settings/updateDeckProfile'); + }, + + addDeckWidget(state, x) { + const deck = state.settings.deckProfiles[state.device.deckProfile]; + const column = deck.columns.find(c => c.id == x.id); + if (column == null) return; + column.widgets.unshift(x.widget); + os.store.dispatch('settings/updateDeckProfile'); + }, + + removeDeckWidget(state, x) { + const deck = state.settings.deckProfiles[state.device.deckProfile]; + const column = deck.columns.find(c => c.id == x.id); + if (column == null) return; + column.widgets = column.widgets.filter(w => w.id != x.widget.id); + os.store.dispatch('settings/updateDeckProfile'); + }, + + renameDeckColumn(state, x) { + const deck = state.settings.deckProfiles[state.device.deckProfile]; + const column = deck.columns.find(c => c.id == x.id); + if (column == null) return; + column.name = x.name; + os.store.dispatch('settings/updateDeckProfile'); + }, + + updateDeckColumn(state, x) { + const deck = state.settings.deckProfiles[state.device.deckProfile]; + let column = deck.columns.find(c => c.id == x.id); + if (column == null) return; + column = x; + os.store.dispatch('settings/updateDeckProfile'); } }, @@ -159,176 +379,6 @@ export default (os: MiOS) => new Vuex.Store({ setVisibility(state, visibility) { state.visibility = visibility; }, - - setHome(state, data) { - state.home = data; - }, - - addHomeWidget(state, widget) { - state.home.unshift(widget); - }, - - setMobileHome(state, data) { - state.mobileHome = data; - }, - - updateWidget(state, x) { - let w; - - //#region Desktop home - if (state.home) { - w = state.home.find(w => w.id == x.id); - if (w) { - w.data = x.data; - } - } - //#endregion - - //#region Mobile home - if (state.mobileHome) { - w = state.mobileHome.find(w => w.id == x.id); - if (w) { - w.data = x.data; - } - } - //#endregion - }, - - addMobileHomeWidget(state, widget) { - state.mobileHome.unshift(widget); - }, - - removeMobileHomeWidget(state, widget) { - state.mobileHome = state.mobileHome.filter(w => w.id != widget.id); - }, - - addDeckColumn(state, column) { - if (column.name == undefined) column.name = null; - state.deck.columns.push(column); - state.deck.layout.push([column.id]); - }, - - removeDeckColumn(state, id) { - state.deck.columns = state.deck.columns.filter(c => c.id != id); - state.deck.layout = state.deck.layout.map(ids => erase(id, ids)); - state.deck.layout = state.deck.layout.filter(ids => ids.length > 0); - }, - - swapDeckColumn(state, x) { - const a = x.a; - const b = x.b; - const aX = state.deck.layout.findIndex(ids => ids.indexOf(a) != -1); - const aY = state.deck.layout[aX].findIndex(id => id == a); - const bX = state.deck.layout.findIndex(ids => ids.indexOf(b) != -1); - const bY = state.deck.layout[bX].findIndex(id => id == b); - state.deck.layout[aX][aY] = b; - state.deck.layout[bX][bY] = a; - }, - - swapLeftDeckColumn(state, id) { - state.deck.layout.some((ids, i) => { - if (ids.indexOf(id) != -1) { - const left = state.deck.layout[i - 1]; - if (left) { - // https://vuejs.org/v2/guide/list.html#Caveats - //state.deck.layout[i - 1] = state.deck.layout[i]; - //state.deck.layout[i] = left; - state.deck.layout.splice(i - 1, 1, state.deck.layout[i]); - state.deck.layout.splice(i, 1, left); - } - return true; - } - }); - }, - - swapRightDeckColumn(state, id) { - state.deck.layout.some((ids, i) => { - if (ids.indexOf(id) != -1) { - const right = state.deck.layout[i + 1]; - if (right) { - // https://vuejs.org/v2/guide/list.html#Caveats - //state.deck.layout[i + 1] = state.deck.layout[i]; - //state.deck.layout[i] = right; - state.deck.layout.splice(i + 1, 1, state.deck.layout[i]); - state.deck.layout.splice(i, 1, right); - } - return true; - } - }); - }, - - swapUpDeckColumn(state, id) { - const ids = state.deck.layout.find(ids => ids.indexOf(id) != -1); - ids.some((x, i) => { - if (x == id) { - const up = ids[i - 1]; - if (up) { - // https://vuejs.org/v2/guide/list.html#Caveats - //ids[i - 1] = id; - //ids[i] = up; - ids.splice(i - 1, 1, id); - ids.splice(i, 1, up); - } - return true; - } - }); - }, - - swapDownDeckColumn(state, id) { - const ids = state.deck.layout.find(ids => ids.indexOf(id) != -1); - ids.some((x, i) => { - if (x == id) { - const down = ids[i + 1]; - if (down) { - // https://vuejs.org/v2/guide/list.html#Caveats - //ids[i + 1] = id; - //ids[i] = down; - ids.splice(i + 1, 1, id); - ids.splice(i, 1, down); - } - return true; - } - }); - }, - - stackLeftDeckColumn(state, id) { - const i = state.deck.layout.findIndex(ids => ids.indexOf(id) != -1); - state.deck.layout = state.deck.layout.map(ids => erase(id, ids)); - const left = state.deck.layout[i - 1]; - if (left) state.deck.layout[i - 1].push(id); - state.deck.layout = state.deck.layout.filter(ids => ids.length > 0); - }, - - popRightDeckColumn(state, id) { - const i = state.deck.layout.findIndex(ids => ids.indexOf(id) != -1); - state.deck.layout = state.deck.layout.map(ids => erase(id, ids)); - state.deck.layout.splice(i + 1, 0, [id]); - state.deck.layout = state.deck.layout.filter(ids => ids.length > 0); - }, - - addDeckWidget(state, x) { - const column = state.deck.columns.find(c => c.id == x.id); - if (column == null) return; - column.widgets.unshift(x.widget); - }, - - removeDeckWidget(state, x) { - const column = state.deck.columns.find(c => c.id == x.id); - if (column == null) return; - column.widgets = column.widgets.filter(w => w.id != x.widget.id); - }, - - renameDeckColumn(state, x) { - const column = state.deck.columns.find(c => c.id == x.id); - if (column == null) return; - column.name = x.name; - }, - - updateDeckColumn(state, x) { - let column = state.deck.columns.find(c => c.id == x.id); - if (column == null) return; - column = x; - } } }, @@ -361,6 +411,42 @@ export default (os: MiOS) => new Vuex.Store({ }); } }, + + updateHomeProfile(ctx) { + const profiles = ctx.state.homeProfiles; + ctx.commit('set', { + key: 'homeProfiles', + value: profiles + }); + os.api('i/update-client-setting', { + name: 'homeProfiles', + value: profiles + }); + }, + + updateMobileHomeProfile(ctx) { + const profiles = ctx.state.mobileHomeProfiles; + ctx.commit('set', { + key: 'mobileHomeProfiles', + value: profiles + }); + os.api('i/update-client-setting', { + name: 'mobileHomeProfiles', + value: profiles + }); + }, + + updateDeckProfile(ctx) { + const profiles = ctx.state.deckProfiles; + ctx.commit('set', { + key: 'deckProfiles', + value: profiles + }); + os.api('i/update-client-setting', { + name: 'deckProfiles', + value: profiles + }); + }, } } } diff --git a/src/mfm/language.ts b/src/mfm/language.ts index 4750ea3380..75a2baaab9 100644 --- a/src/mfm/language.ts +++ b/src/mfm/language.ts @@ -157,12 +157,14 @@ export const mfmLanguage = P.createLanguage({ let url: string; if (!match) { const match = text.match(/^<(https?:\/\/.*?)>/); - if (!match) + if (!match) { return P.makeFailure(i, 'not a url'); + } url = match[1]; i += 2; - } else + } else { url = match[0]; + } url = removeOrphanedBrackets(url); while (url.endsWith('.') || url.endsWith(',')) { if (url.endsWith('.')) url = url.substr(0, url.lastIndexOf('.')); diff --git a/src/misc/aiscript/evaluator.ts b/src/misc/aiscript/evaluator.ts index d93fcebcf7..f6165afb64 100644 --- a/src/misc/aiscript/evaluator.ts +++ b/src/misc/aiscript/evaluator.ts @@ -171,6 +171,7 @@ export class ASEvaluator { numberToString: (a: number) => a.toString(), splitStrByLine: (a: string) => a.split('\n'), pick: (list: any[], i: number) => list[i - 1], + listLen: (list: any[]) => list.length, random: (probability: number) => Math.floor(seedrandom(`${this.opts.randomSeed}:${block.id}`)() * 100) < probability, rannum: (min: number, max: number) => min + Math.floor(seedrandom(`${this.opts.randomSeed}:${block.id}`)() * (max - min + 1)), randomPick: (list: any[]) => list[Math.floor(seedrandom(`${this.opts.randomSeed}:${block.id}`)() * list.length)], diff --git a/src/misc/aiscript/index.ts b/src/misc/aiscript/index.ts index 8635399daa..3a21e9b1cc 100644 --- a/src/misc/aiscript/index.ts +++ b/src/misc/aiscript/index.ts @@ -74,6 +74,7 @@ export const funcDefs: Record<string, { in: any[]; out: any; category: string; i numberToString: { in: ['number'], out: 'string', category: 'convert', icon: faExchangeAlt, }, splitStrByLine: { in: ['string'], out: 'stringArray', category: 'convert', icon: faExchangeAlt, }, pick: { in: [null, 'number'], out: null, category: 'list', icon: faIndent, }, + listLen: { in: [null], out: 'number', category: 'list', icon: faIndent, }, rannum: { in: ['number', 'number'], out: 'number', category: 'random', icon: faDice, }, dailyRannum: { in: ['number', 'number'], out: 'number', category: 'random', icon: faDice, }, seedRannum: { in: [null, 'number', 'number'], out: 'number', category: 'random', icon: faDice, }, diff --git a/src/remote/activitypub/kernel/index.ts b/src/remote/activitypub/kernel/index.ts index d1251817fa..a0646bdd67 100644 --- a/src/remote/activitypub/kernel/index.ts +++ b/src/remote/activitypub/kernel/index.ts @@ -15,6 +15,8 @@ import block from './block'; import { apLogger } from '../logger'; const self = async (actor: IRemoteUser, activity: Object): Promise<void> => { + if (actor.isSuspended) return; + switch (activity.type) { case 'Create': await create(actor, activity); diff --git a/src/server/api/endpoints/meta.ts b/src/server/api/endpoints/meta.ts index 4da0c7476c..1aa9a855dd 100644 --- a/src/server/api/endpoints/meta.ts +++ b/src/server/api/endpoints/meta.ts @@ -7,6 +7,7 @@ import * as pkg from '../../../../package.json'; import { Emojis } from '../../../models'; import { types, bool } from '../../../misc/schema'; import { getConnection } from 'typeorm'; +import redis from '../../../db/redis'; export const meta = { stability: 'stable', @@ -116,6 +117,7 @@ export default define(meta, async (ps, me) => { os: os.platform(), node: process.version, psql: await getConnection().query('SHOW server_version').then(x => x[0].server_version), + redis: redis.server_info.redis_version, cpu: { model: os.cpus()[0].model, diff --git a/src/server/web/index.ts b/src/server/web/index.ts index c5a3497f44..8cf6a75208 100644 --- a/src/server/web/index.ts +++ b/src/server/web/index.ts @@ -20,6 +20,8 @@ import { Users, Notes, Emojis, UserProfiles, Pages } from '../../models'; import parseAcct from '../../misc/acct/parse'; import getNoteSummary from '../../misc/get-note-summary'; import { ensure } from '../../prelude/ensure'; +import { getConnection } from 'typeorm'; +import redis from '../../db/redis'; const client = `${__dirname}/../../client/`; @@ -250,6 +252,8 @@ router.get('/info', async ctx => { machine: os.hostname(), os: os.platform(), node: process.version, + psql: await getConnection().query('SHOW server_version').then(x => x[0].server_version), + redis: redis.server_info.redis_version, cpu: { model: os.cpus()[0].model, cores: os.cpus().length diff --git a/src/server/web/url-preview.ts b/src/server/web/url-preview.ts index e5b9ff6244..310cf88c02 100644 --- a/src/server/web/url-preview.ts +++ b/src/server/web/url-preview.ts @@ -12,18 +12,20 @@ module.exports = async (ctx: Koa.BaseContext) => { const meta = await fetchMeta(); logger.info(meta.summalyProxy - ? `(Proxy) Getting preview of ${ctx.query.url} ...` - : `Getting preview of ${ctx.query.url} ...`); + ? `(Proxy) Getting preview of ${ctx.query.url}@${ctx.query.lang} ...` + : `Getting preview of ${ctx.query.url}@${ctx.query.lang} ...`); try { const summary = meta.summalyProxy ? await request.get({ url: meta.summalyProxy, qs: { - url: ctx.query.url + url: ctx.query.url, + lang: ctx.query.lang || 'ja-JP' }, json: true }) : await summaly(ctx.query.url, { - followRedirects: false + followRedirects: false, + lang: ctx.query.lang || 'ja-JP' }); logger.succ(`Got preview of ${ctx.query.url}: ${summary.title}`); diff --git a/src/server/web/views/info.pug b/src/server/web/views/info.pug index c8b0bd939a..fc71e5c193 100644 --- a/src/server/web/views/info.pug +++ b/src/server/web/views/info.pug @@ -86,6 +86,12 @@ html th Node version td= node tr + th PSQL version + td= psql + tr + th Redis version + td= redis + tr th Machine td= machine tr diff --git a/src/services/following/delete.ts b/src/services/following/delete.ts index ad09f0e6d1..e3b5f8c414 100644 --- a/src/services/following/delete.ts +++ b/src/services/following/delete.ts @@ -22,7 +22,7 @@ export default async function(follower: User, followee: User, silent = false) { return; } - Followings.delete(following.id); + await Followings.delete(following.id); //#region Decrement following count Users.decrement({ id: follower.id }, 'followingCount', 1); |