summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsyuilo <syuilotan@yahoo.co.jp>2018-06-08 04:21:06 +0900
committersyuilo <syuilotan@yahoo.co.jp>2018-06-08 04:21:06 +0900
commit79d592b4318d0a9d69a3469db8a0ef8b35c3af90 (patch)
tree3959b39f5dc8db460b5d074430a1235f1a328ea4
parent2.29.1 (diff)
downloadmisskey-79d592b4318d0a9d69a3469db8a0ef8b35c3af90.tar.gz
misskey-79d592b4318d0a9d69a3469db8a0ef8b35c3af90.tar.bz2
misskey-79d592b4318d0a9d69a3469db8a0ef8b35c3af90.zip
MisskeyDeck: カラムをスタックできるように
-rw-r--r--locales/ja.yml2
-rw-r--r--src/client/app/common/views/components/menu.vue33
-rw-r--r--src/client/app/desktop/views/pages/deck/deck.column-core.vue48
-rw-r--r--src/client/app/desktop/views/pages/deck/deck.column.vue61
-rw-r--r--src/client/app/desktop/views/pages/deck/deck.notifications-column.vue17
-rw-r--r--src/client/app/desktop/views/pages/deck/deck.tl-column.vue39
-rw-r--r--src/client/app/desktop/views/pages/deck/deck.vue58
-rw-r--r--src/client/app/desktop/views/pages/deck/deck.widgets-column.vue107
-rw-r--r--src/client/app/store.ts53
9 files changed, 275 insertions, 143 deletions
diff --git a/locales/ja.yml b/locales/ja.yml
index 320da8e777..3161040ec8 100644
--- a/locales/ja.yml
+++ b/locales/ja.yml
@@ -88,6 +88,8 @@ common:
remove: "カラムを削除"
add-column: "カラムを追加"
rename: "名前を変更"
+ stack-left: "左に重ねる"
+ pop-right: "右に出す"
common/views/components/connect-failed.vue:
title: "サーバーに接続できません"
diff --git a/src/client/app/common/views/components/menu.vue b/src/client/app/common/views/components/menu.vue
index 73c8403ad3..8874e4c49b 100644
--- a/src/client/app/common/views/components/menu.vue
+++ b/src/client/app/common/views/components/menu.vue
@@ -1,7 +1,7 @@
<template>
<div class="mk-menu">
<div class="backdrop" ref="backdrop" @click="close"></div>
- <div class="popover" :class="{ compact }" ref="popover">
+ <div class="popover" :class="{ hukidasi }" ref="popover">
<template v-for="item in items">
<div v-if="item == null"></div>
<button v-else @click="clicked(item.onClick)" v-html="item.content"></button>
@@ -16,6 +16,11 @@ import * as anime from 'animejs';
export default Vue.extend({
props: ['source', 'compact', 'items'],
+ data() {
+ return {
+ hukidasi: !this.compact
+ };
+ },
mounted() {
this.$nextTick(() => {
const popover = this.$refs.popover as any;
@@ -24,18 +29,34 @@ export default Vue.extend({
const width = popover.offsetWidth;
const height = popover.offsetHeight;
+ let left;
+ let top;
+
if (this.compact) {
const x = rect.left + window.pageXOffset + (this.source.offsetWidth / 2);
const y = rect.top + window.pageYOffset + (this.source.offsetHeight / 2);
- popover.style.left = (x - (width / 2)) + 'px';
- popover.style.top = (y - (height / 2)) + 'px';
+ left = (x - (width / 2));
+ top = (y - (height / 2));
} else {
const x = rect.left + window.pageXOffset + (this.source.offsetWidth / 2);
const y = rect.top + window.pageYOffset + this.source.offsetHeight;
- popover.style.left = (x - (width / 2)) + 'px';
- popover.style.top = y + 'px';
+ left = (x - (width / 2));
+ top = y;
+ }
+
+ if (left + width > window.innerWidth) {
+ left = window.innerWidth - width;
+ this.hukidasi = false;
}
+ if (top + height > window.innerHeight) {
+ top = window.innerHeight - height;
+ this.hukidasi = false;
+ }
+
+ popover.style.left = left + 'px';
+ popover.style.top = top + 'px';
+
anime({
targets: this.$refs.backdrop,
opacity: 1,
@@ -113,7 +134,7 @@ $border-color = rgba(27, 31, 35, 0.15)
$balloon-size = 16px
- &:not(.compact)
+ &.hukidasi
margin-top $balloon-size
transform-origin center -($balloon-size)
diff --git a/src/client/app/desktop/views/pages/deck/deck.column-core.vue b/src/client/app/desktop/views/pages/deck/deck.column-core.vue
new file mode 100644
index 0000000000..836ce3ac9e
--- /dev/null
+++ b/src/client/app/desktop/views/pages/deck/deck.column-core.vue
@@ -0,0 +1,48 @@
+<template>
+<x-widgets-column v-if="column.type == 'widgets'"/>
+<x-notifications-column v-else-if="column.type == 'notifications'"/>
+<x-tl-column v-else-if="column.type == 'home'"/>
+<x-tl-column v-else-if="column.type == 'local'"/>
+<x-tl-column v-else-if="column.type == 'global'"/>
+<x-tl-column v-else-if="column.type == 'list'"/>
+</template>
+
+<script lang="ts">
+import Vue from 'vue';
+import XTlColumn from './deck.tl-column.vue';
+import XNotificationsColumn from './deck.notifications-column.vue';
+import XWidgetsColumn from './deck.widgets-column.vue';
+
+export default Vue.extend({
+ components: {
+ XTlColumn,
+ XNotificationsColumn,
+ XWidgetsColumn
+ },
+
+ props: {
+ column: {
+ type: Object,
+ required: true
+ },
+ isStacked: {
+ type: Boolean,
+ required: false,
+ default: false
+ },
+ isActive: {
+ type: Boolean,
+ required: false,
+ default: true
+ }
+ },
+
+ provide() {
+ return {
+ column: this.column,
+ isStacked: this.isStacked,
+ isActive: this.isActive
+ };
+ }
+});
+</script>
diff --git a/src/client/app/desktop/views/pages/deck/deck.column.vue b/src/client/app/desktop/views/pages/deck/deck.column.vue
index 4e37c3cbdb..172880df6e 100644
--- a/src/client/app/desktop/views/pages/deck/deck.column.vue
+++ b/src/client/app/desktop/views/pages/deck/deck.column.vue
@@ -1,10 +1,10 @@
<template>
-<div class="dnpfarvgbnfmyzbdquhhzyxcmstpdqzs" :class="{ naked, narrow }">
- <header :class="{ indicate }">
+<div class="dnpfarvgbnfmyzbdquhhzyxcmstpdqzs" :class="{ naked, narrow, isActive, isStacked }">
+ <header :class="{ indicate }" @click="toggleActive">
<slot name="header"></slot>
- <button ref="menu" @click="showMenu">%fa:caret-down%</button>
+ <button ref="menu" @click.stop="showMenu">%fa:caret-down%</button>
</header>
- <div ref="body">
+ <div ref="body" v-show="isActive">
<slot></slot>
</div>
</div>
@@ -16,17 +16,14 @@ import Menu from '../../../../common/views/components/menu.vue';
export default Vue.extend({
props: {
- id: {
- type: String,
- required: false
- },
name: {
type: String,
required: false
},
menu: {
type: Array,
- required: false
+ required: false,
+ default: null
},
naked: {
type: Boolean,
@@ -40,9 +37,17 @@ export default Vue.extend({
}
},
+ inject: {
+ column: { from: 'column' },
+ _isActive: { from: 'isActive' },
+ isStacked: { from: 'isStacked' },
+ getColumnVm: { from: 'getColumnVm' }
+ },
+
data() {
return {
- indicate: false
+ indicate: false,
+ isActive: this._isActive
};
},
@@ -62,6 +67,13 @@ export default Vue.extend({
},
methods: {
+ toggleActive() {
+ if (!this.isStacked) return;
+ const vms = this.$store.state.settings.deck.layout.find(ids => ids.indexOf(this.column.id) != -1).map(id => this.getColumnVm(id));
+ if (this.isActive && vms.filter(vm => vm.$el.classList.contains('isActive')).length == 1) return;
+ this.isActive = !this.isActive;
+ },
+
isScrollTop() {
return this.$refs.body.scrollTop == 0;
},
@@ -86,23 +98,33 @@ export default Vue.extend({
default: this.name,
allowEmpty: false
}).then(name => {
- this.$store.dispatch('settings/renameDeckColumn', { id: this.id, name });
+ this.$store.dispatch('settings/renameDeckColumn', { id: this.column.id, name });
});
}
}, null, {
content: '%fa:arrow-left% %i18n:common.deck.swap-left%',
onClick: () => {
- this.$store.dispatch('settings/swapLeftDeckColumn', this.id);
+ this.$store.dispatch('settings/swapLeftDeckColumn', this.column.id);
}
}, {
content: '%fa:arrow-right% %i18n:common.deck.swap-right%',
onClick: () => {
- this.$store.dispatch('settings/swapRightDeckColumn', this.id);
+ this.$store.dispatch('settings/swapRightDeckColumn', this.column.id);
+ }
+ }, null, {
+ content: '%fa:window-restore R% %i18n:common.deck.stack-left%',
+ onClick: () => {
+ this.$store.dispatch('settings/stackLeftDeckColumn', this.column.id);
+ }
+ }, {
+ content: '%fa:window-restore R% %i18n:common.deck.pop-right%',
+ onClick: () => {
+ this.$store.dispatch('settings/popRightDeckColumn', this.column.id);
}
}, null, {
content: '%fa:trash-alt R% %i18n:common.deck.remove%',
onClick: () => {
- this.$store.dispatch('settings/removeDeckColumn', this.id);
+ this.$store.dispatch('settings/removeDeckColumn', this.column.id);
}
}];
@@ -128,14 +150,20 @@ root(isDark)
$header-height = 42px
width 330px
+ min-width 330px
height 100%
background isDark ? #282C37 : #fff
border-radius 6px
box-shadow 0 2px 16px rgba(#000, 0.1)
overflow hidden
- &.narrow
+ &:not(.isActive)
+ flex-basis $header-height
+ min-height $header-height
+
+ &:not(.isStacked).narrow
width 285px
+ min-width 285px
&.naked
background rgba(#000, isDark ? 0.25 : 0.1)
@@ -157,6 +185,9 @@ root(isDark)
background isDark ? #313543 : #fff
box-shadow 0 1px rgba(#000, 0.15)
+ &, *
+ user-select none
+
&.indicate
box-shadow 0 3px 0 0 $theme-color
diff --git a/src/client/app/desktop/views/pages/deck/deck.notifications-column.vue b/src/client/app/desktop/views/pages/deck/deck.notifications-column.vue
index e01f91c24d..87f16211fc 100644
--- a/src/client/app/desktop/views/pages/deck/deck.notifications-column.vue
+++ b/src/client/app/desktop/views/pages/deck/deck.notifications-column.vue
@@ -1,11 +1,9 @@
<template>
-<div>
- <x-column :id="column.id" :name="name">
- <span slot="header">%fa:bell R%{{ name }}</span>
+<x-column :name="name">
+ <span slot="header">%fa:bell R%{{ name }}</span>
- <x-notifications/>
- </x-column>
-</div>
+ <x-notifications/>
+</x-column>
</template>
<script lang="ts">
@@ -19,12 +17,7 @@ export default Vue.extend({
XNotifications
},
- props: {
- column: {
- type: Object,
- required: true
- }
- },
+ inject: ['column'],
computed: {
name(): string {
diff --git a/src/client/app/desktop/views/pages/deck/deck.tl-column.vue b/src/client/app/desktop/views/pages/deck/deck.tl-column.vue
index 1a5075396b..46d56bb055 100644
--- a/src/client/app/desktop/views/pages/deck/deck.tl-column.vue
+++ b/src/client/app/desktop/views/pages/deck/deck.tl-column.vue
@@ -1,22 +1,20 @@
<template>
-<div>
- <x-column :id="column.id" :menu="menu" :name="name">
- <span slot="header">
- <template v-if="column.type == 'home'">%fa:home%</template>
- <template v-if="column.type == 'local'">%fa:R comments%</template>
- <template v-if="column.type == 'global'">%fa:globe%</template>
- <template v-if="column.type == 'list'">%fa:list%</template>
- <span>{{ name }}</span>
- </span>
+<x-column :menu="menu" :name="name">
+ <span slot="header">
+ <template v-if="column.type == 'home'">%fa:home%</template>
+ <template v-if="column.type == 'local'">%fa:R comments%</template>
+ <template v-if="column.type == 'global'">%fa:globe%</template>
+ <template v-if="column.type == 'list'">%fa:list%</template>
+ <span>{{ name }}</span>
+ </span>
- <div class="editor" v-if="edit">
- <mk-switch v-model="column.isMediaOnly" @change="onChangeSettings" text="%i18n:@is-media-only%"/>
- <mk-switch v-model="column.isMediaView" @change="onChangeSettings" text="%i18n:@is-media-view%"/>
- </div>
- <x-list-tl v-if="column.type == 'list'" :list="column.list" :media-only="column.isMediaOnly"/>
- <x-tl v-else :src="column.type" :media-only="column.isMediaOnly"/>
- </x-column>
-</div>
+ <div class="editor" v-if="edit">
+ <mk-switch v-model="column.isMediaOnly" @change="onChangeSettings" text="%i18n:@is-media-only%"/>
+ <mk-switch v-model="column.isMediaView" @change="onChangeSettings" text="%i18n:@is-media-view%"/>
+ </div>
+ <x-list-tl v-if="column.type == 'list'" :list="column.list" :media-only="column.isMediaOnly"/>
+ <x-tl v-else :src="column.type" :media-only="column.isMediaOnly"/>
+</x-column>
</template>
<script lang="ts">
@@ -32,12 +30,7 @@ export default Vue.extend({
XListTl
},
- props: {
- column: {
- type: Object,
- required: true
- }
- },
+ inject: ['column'],
data() {
return {
diff --git a/src/client/app/desktop/views/pages/deck/deck.vue b/src/client/app/desktop/views/pages/deck/deck.vue
index 57ec214c3a..fa2d90ed0e 100644
--- a/src/client/app/desktop/views/pages/deck/deck.vue
+++ b/src/client/app/desktop/views/pages/deck/deck.vue
@@ -1,13 +1,13 @@
<template>
<mk-ui :class="$style.root">
<div class="qlvquzbjribqcaozciifydkngcwtyzje" :data-darkmode="$store.state.device.darkmode">
- <template v-for="column in columns">
- <x-widgets-column v-if="column.type == 'widgets'" :key="column.id" :column="column"/>
- <x-notifications-column v-if="column.type == 'notifications'" :key="column.id" :column="column"/>
- <x-tl-column v-if="column.type == 'home'" :key="column.id" :column="column"/>
- <x-tl-column v-if="column.type == 'local'" :key="column.id" :column="column"/>
- <x-tl-column v-if="column.type == 'global'" :key="column.id" :column="column"/>
- <x-tl-column v-if="column.type == 'list'" :key="column.id" :column="column"/>
+ <template v-for="ids in layout">
+ <div v-if="ids.length > 1" class="folder">
+ <template v-for="id, i in ids">
+ <x-column-core :ref="id" :key="id" :column="columns.find(c => c.id == id)" :is-stacked="true" :is-active="i == 0"/>
+ </template>
+ </div>
+ <x-column-core v-else :ref="ids[0]" :key="ids[0]" :column="columns.find(c => c.id == ids[0])"/>
</template>
<button ref="add" @click="add" title="%i18n:common.deck.add-column%">%fa:plus%</button>
</div>
@@ -16,27 +16,34 @@
<script lang="ts">
import Vue from 'vue';
-import XTlColumn from './deck.tl-column.vue';
-import XNotificationsColumn from './deck.notifications-column.vue';
-import XWidgetsColumn from './deck.widgets-column.vue';
+import XColumnCore from './deck.column-core.vue';
import Menu from '../../../../common/views/components/menu.vue';
import MkUserListsWindow from '../../components/user-lists-window.vue';
import * as uuid from 'uuid';
export default Vue.extend({
components: {
- XTlColumn,
- XNotificationsColumn,
- XWidgetsColumn
+ XColumnCore
},
computed: {
- columns() {
+ columns(): any[] {
if (this.$store.state.settings.deck == null) return [];
return this.$store.state.settings.deck.columns;
+ },
+ layout(): any[] {
+ if (this.$store.state.settings.deck == null) return [];
+ if (this.$store.state.settings.deck.layout == null) return this.$store.state.settings.deck.columns.map(c => [c.id]);
+ return this.$store.state.settings.deck.layout;
}
},
+ provide() {
+ return {
+ getColumnVm: this.getColumnVm
+ };
+ },
+
created() {
if (this.$store.state.settings.deck == null) {
const deck = {
@@ -58,11 +65,23 @@ export default Vue.extend({
}]
};
+ deck.layout = deck.columns.map(c => [c.id]);
+
this.$store.dispatch('settings/set', {
key: 'deck',
value: deck
});
}
+
+ // 互換性のため
+ if (this.$store.state.settings.deck != null && this.$store.state.settings.deck.layout == null) {
+ this.$store.dispatch('settings/set', {
+ key: 'deck',
+ value: Object.assign({}, this.$store.state.settings.deck, {
+ layout: this.$store.state.settings.deck.columns.map(c => [c.id])
+ })
+ });
+ }
},
mounted() {
@@ -74,6 +93,10 @@ export default Vue.extend({
},
methods: {
+ getColumnVm(id) {
+ return this.$refs[id][0];
+ },
+
add() {
this.os.new(Menu, {
source: this.$refs.add,
@@ -159,6 +182,13 @@ root(isDark)
&:last-of-type
margin-right 0
+ &.folder
+ display flex
+ flex-direction column
+
+ > *:not(:last-child)
+ margin-bottom 8px
+
> *
&:first-child
margin-left auto
diff --git a/src/client/app/desktop/views/pages/deck/deck.widgets-column.vue b/src/client/app/desktop/views/pages/deck/deck.widgets-column.vue
index 6bcebd07cc..1f8fd8a9bf 100644
--- a/src/client/app/desktop/views/pages/deck/deck.widgets-column.vue
+++ b/src/client/app/desktop/views/pages/deck/deck.widgets-column.vue
@@ -1,57 +1,55 @@
<template>
-<div class="wtdtxvecapixsepjtcupubtsmometobz">
- <x-column :id="column.id" :menu="menu" :naked="true" :narrow="true" :name="name">
- <span slot="header">%fa:calculator%{{ name }}</span>
+<x-column :menu="menu" :naked="true" :narrow="true" :name="name" class="wtdtxvecapixsepjtcupubtsmometobz">
+ <span slot="header">%fa:calculator%{{ name }}</span>
- <div class="gqpwvtwtprsbmnssnbicggtwqhmylhnq">
- <template v-if="edit">
- <header>
- <select v-model="widgetAdderSelected">
- <option value="profile">%i18n:common.widgets.profile%</option>
- <option value="analog-clock">%i18n:common.widgets.analog-clock%</option>
- <option value="calendar">%i18n:common.widgets.calendar%</option>
- <option value="timemachine">%i18n:common.widgets.timemachine%</option>
- <option value="activity">%i18n:common.widgets.activity%</option>
- <option value="rss">%i18n:common.widgets.rss%</option>
- <option value="trends">%i18n:common.widgets.trends%</option>
- <option value="photo-stream">%i18n:common.widgets.photo-stream%</option>
- <option value="slideshow">%i18n:common.widgets.slideshow%</option>
- <option value="version">%i18n:common.widgets.version%</option>
- <option value="broadcast">%i18n:common.widgets.broadcast%</option>
- <option value="notifications">%i18n:common.widgets.notifications%</option>
- <option value="users">%i18n:common.widgets.users%</option>
- <option value="polls">%i18n:common.widgets.polls%</option>
- <option value="post-form">%i18n:common.widgets.post-form%</option>
- <option value="messaging">%i18n:common.widgets.messaging%</option>
- <option value="memo">%i18n:common.widgets.memo%</option>
- <option value="server">%i18n:common.widgets.server%</option>
- <option value="donation">%i18n:common.widgets.donation%</option>
- <option value="nav">%i18n:common.widgets.nav%</option>
- <option value="tips">%i18n:common.widgets.tips%</option>
- </select>
- <button @click="addWidget">%i18n:@add%</button>
- </header>
- <x-draggable
- :list="column.widgets"
- :options="{ handle: '.handle', animation: 150 }"
- @sort="onWidgetSort"
- >
- <div v-for="widget in column.widgets" class="customize-container" :key="widget.id">
- <header>
- <span class="handle">%fa:bars%</span>{{ widget.name }}<button class="remove" @click="removeWidget(widget)">%fa:times%</button>
- </header>
- <div @click="widgetFunc(widget.id)">
- <component :is="`mkw-${widget.name}`" :widget="widget" :ref="widget.id" :is-customize-mode="true" platform="deck"/>
- </div>
+ <div class="gqpwvtwtprsbmnssnbicggtwqhmylhnq">
+ <template v-if="edit">
+ <header>
+ <select v-model="widgetAdderSelected">
+ <option value="profile">%i18n:common.widgets.profile%</option>
+ <option value="analog-clock">%i18n:common.widgets.analog-clock%</option>
+ <option value="calendar">%i18n:common.widgets.calendar%</option>
+ <option value="timemachine">%i18n:common.widgets.timemachine%</option>
+ <option value="activity">%i18n:common.widgets.activity%</option>
+ <option value="rss">%i18n:common.widgets.rss%</option>
+ <option value="trends">%i18n:common.widgets.trends%</option>
+ <option value="photo-stream">%i18n:common.widgets.photo-stream%</option>
+ <option value="slideshow">%i18n:common.widgets.slideshow%</option>
+ <option value="version">%i18n:common.widgets.version%</option>
+ <option value="broadcast">%i18n:common.widgets.broadcast%</option>
+ <option value="notifications">%i18n:common.widgets.notifications%</option>
+ <option value="users">%i18n:common.widgets.users%</option>
+ <option value="polls">%i18n:common.widgets.polls%</option>
+ <option value="post-form">%i18n:common.widgets.post-form%</option>
+ <option value="messaging">%i18n:common.widgets.messaging%</option>
+ <option value="memo">%i18n:common.widgets.memo%</option>
+ <option value="server">%i18n:common.widgets.server%</option>
+ <option value="donation">%i18n:common.widgets.donation%</option>
+ <option value="nav">%i18n:common.widgets.nav%</option>
+ <option value="tips">%i18n:common.widgets.tips%</option>
+ </select>
+ <button @click="addWidget">%i18n:@add%</button>
+ </header>
+ <x-draggable
+ :list="column.widgets"
+ :options="{ handle: '.handle', animation: 150 }"
+ @sort="onWidgetSort"
+ >
+ <div v-for="widget in column.widgets" class="customize-container" :key="widget.id">
+ <header>
+ <span class="handle">%fa:bars%</span>{{ widget.name }}<button class="remove" @click="removeWidget(widget)">%fa:times%</button>
+ </header>
+ <div @click="widgetFunc(widget.id)">
+ <component :is="`mkw-${widget.name}`" :widget="widget" :ref="widget.id" :is-customize-mode="true" platform="deck"/>
</div>
- </x-draggable>
- </template>
- <template v-else>
- <component class="widget" v-for="widget in column.widgets" :is="`mkw-${widget.name}`" :key="widget.id" :ref="widget.id" :widget="widget" platform="deck"/>
- </template>
- </div>
- </x-column>
-</div>
+ </div>
+ </x-draggable>
+ </template>
+ <template v-else>
+ <component class="widget" v-for="widget in column.widgets" :is="`mkw-${widget.name}`" :key="widget.id" :ref="widget.id" :widget="widget" platform="deck"/>
+ </template>
+ </div>
+</x-column>
</template>
<script lang="ts">
@@ -66,12 +64,7 @@ export default Vue.extend({
XDraggable
},
- props: {
- column: {
- type: Object,
- required: true
- }
- },
+ inject: ['column'],
data() {
return {
diff --git a/src/client/app/store.ts b/src/client/app/store.ts
index d51a3abad1..e78d941d8c 100644
--- a/src/client/app/store.ts
+++ b/src/client/app/store.ts
@@ -173,23 +173,22 @@ export default (os: MiOS) => new Vuex.Store({
},
addDeckColumn(state, column) {
- if (state.deck.columns == null) state.deck.columns = [];
state.deck.columns.push(column);
+ state.deck.layout.push([column.id]);
},
removeDeckColumn(state, id) {
- if (state.deck.columns == null) return;
state.deck.columns = state.deck.columns.filter(c => c.id != id);
+ state.deck.layout = state.deck.layout.map(ids => ids.filter(x => x != id));
},
swapLeftDeckColumn(state, id) {
- if (state.deck.columns == null) return;
- state.deck.columns.some((c, i) => {
- if (c.id == id) {
- const left = state.deck.columns[i - 1];
+ state.deck.layout.some((ids, i) => {
+ if (ids.indexOf(id) != -1) {
+ const left = state.deck.layout[i - 1];
if (left) {
- state.deck.columns[i - 1] = state.deck.columns[i];
- state.deck.columns[i] = left;
+ state.deck.layout[i - 1] = state.deck.layout[i];
+ state.deck.layout[i] = left;
}
return true;
}
@@ -197,28 +196,40 @@ export default (os: MiOS) => new Vuex.Store({
},
swapRightDeckColumn(state, id) {
- if (state.deck.columns == null) return;
- state.deck.columns.some((c, i) => {
- if (c.id == id) {
- const right = state.deck.columns[i + 1];
+ state.deck.layout.some((ids, i) => {
+ if (ids.indexOf(id) != -1) {
+ const right = state.deck.layout[i + 1];
if (right) {
- state.deck.columns[i + 1] = state.deck.columns[i];
- state.deck.columns[i] = right;
+ state.deck.layout[i + 1] = state.deck.layout[i];
+ state.deck.layout[i] = right;
}
return true;
}
});
},
+ stackLeftDeckColumn(state, id) {
+ const i = state.deck.layout.findIndex(ids => ids.indexOf(id) != -1);
+ state.deck.layout = state.deck.layout.map(ids => ids.filter(x => x != id));
+ 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 => ids.filter(x => x != id));
+ state.deck.layout.splice(i + 1, 0, [id]);
+ state.deck.layout = state.deck.layout.filter(ids => ids.length > 0);
+ },
+
addDeckWidget(state, x) {
- if (state.deck.columns == null) return;
const column = state.deck.columns.find(c => c.id == x.id);
if (column == null) return;
column.widgets.unshift(x.widget);
},
removeDeckWidget(state, x) {
- if (state.deck.columns == null) return;
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);
@@ -277,6 +288,16 @@ export default (os: MiOS) => new Vuex.Store({
ctx.dispatch('saveDeck');
},
+ stackLeftDeckColumn(ctx, id) {
+ ctx.commit('stackLeftDeckColumn', id);
+ ctx.dispatch('saveDeck');
+ },
+
+ popRightDeckColumn(ctx, id) {
+ ctx.commit('popRightDeckColumn', id);
+ ctx.dispatch('saveDeck');
+ },
+
addDeckWidget(ctx, x) {
ctx.commit('addDeckWidget', x);
ctx.dispatch('saveDeck');