mirror of
				https://codeberg.org/yeentown/barkey.git
				synced 2025-11-04 07:24:13 +00:00 
			
		
		
		
	Deckにウィジェットを置けるように
This commit is contained in:
		
							parent
							
								
									ed8fa59639
								
							
						
					
					
						commit
						b0f989dbac
					
				
					 20 changed files with 417 additions and 179 deletions
				
			
		| 
						 | 
				
			
			@ -9,9 +9,9 @@ export default function<T extends object>(data: {
 | 
			
		|||
			widget: {
 | 
			
		||||
				type: Object
 | 
			
		||||
			},
 | 
			
		||||
			isMobile: {
 | 
			
		||||
				type: Boolean,
 | 
			
		||||
				default: false
 | 
			
		||||
			platform: {
 | 
			
		||||
				type: String,
 | 
			
		||||
				required: true
 | 
			
		||||
			},
 | 
			
		||||
			isCustomizeMode: {
 | 
			
		||||
				type: Boolean,
 | 
			
		||||
| 
						 | 
				
			
			@ -66,17 +66,10 @@ export default function<T extends object>(data: {
 | 
			
		|||
 | 
			
		||||
				this.bakeProps();
 | 
			
		||||
 | 
			
		||||
				if (this.isMobile) {
 | 
			
		||||
					(this as any).api('i/update_mobile_home', {
 | 
			
		||||
						id: this.id,
 | 
			
		||||
						data: this.props
 | 
			
		||||
					});
 | 
			
		||||
				} else {
 | 
			
		||||
					(this as any).api('i/update_home', {
 | 
			
		||||
						id: this.id,
 | 
			
		||||
						data: this.props
 | 
			
		||||
					});
 | 
			
		||||
				}
 | 
			
		||||
				(this as any).api('i/update_widget', {
 | 
			
		||||
					id: this.id,
 | 
			
		||||
					data: this.props
 | 
			
		||||
				});
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	});
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -58,25 +58,18 @@ export class HomeStream extends Stream {
 | 
			
		|||
		});
 | 
			
		||||
 | 
			
		||||
		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
 | 
			
		||||
				});
 | 
			
		||||
			}
 | 
			
		||||
			os.store.commit('settings/setHome', x);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		this.on('mobile_home_updated', x => {
 | 
			
		||||
			if (x.home) {
 | 
			
		||||
				os.store.commit('settings/setMobileHome', x.home);
 | 
			
		||||
			} else {
 | 
			
		||||
				os.store.commit('settings/setMobileHomeWidget', {
 | 
			
		||||
					id: x.id,
 | 
			
		||||
					data: x.data
 | 
			
		||||
				});
 | 
			
		||||
			}
 | 
			
		||||
			os.store.commit('settings/setMobileHome', x);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		this.on('widgetUpdated', x => {
 | 
			
		||||
			os.store.commit('settings/setWidget', {
 | 
			
		||||
				id: x.id,
 | 
			
		||||
				data: x.data
 | 
			
		||||
			});
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		// トークンが再生成されたとき
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,7 +2,10 @@
 | 
			
		|||
<div class="mk-menu">
 | 
			
		||||
	<div class="backdrop" ref="backdrop" @click="close"></div>
 | 
			
		||||
	<div class="popover" :class="{ compact }" ref="popover">
 | 
			
		||||
		<button v-for="item in items" @click="clicked(item.onClick)" v-html="item.content"></button>
 | 
			
		||||
		<template v-for="item in items">
 | 
			
		||||
			<div v-if="item == null"></div>
 | 
			
		||||
			<button v-else @click="clicked(item.onClick)" v-html="item.content"></button>
 | 
			
		||||
		</template>
 | 
			
		||||
	</div>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
| 
						 | 
				
			
			@ -150,4 +153,9 @@ $border-color = rgba(27, 31, 35, 0.15)
 | 
			
		|||
				color $theme-color-foreground
 | 
			
		||||
				background darken($theme-color, 10%)
 | 
			
		||||
 | 
			
		||||
		> div
 | 
			
		||||
			margin 8px 0
 | 
			
		||||
			height 1px
 | 
			
		||||
			background #eee
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,7 +2,7 @@
 | 
			
		|||
<div class="mkw-broadcast"
 | 
			
		||||
	:data-found="broadcasts.length != 0"
 | 
			
		||||
	:data-melt="props.design == 1"
 | 
			
		||||
	:data-mobile="isMobile"
 | 
			
		||||
	:data-mobile="platform == 'mobile'"
 | 
			
		||||
>
 | 
			
		||||
	<div class="icon">
 | 
			
		||||
		<svg height="32" version="1.1" viewBox="0 0 32 32" width="32">
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
<template>
 | 
			
		||||
<div class="mkw-calendar" :data-special="special" :data-mobile="isMobile">
 | 
			
		||||
<div class="mkw-calendar" :data-special="special" :data-mobile="platform == 'mobile'">
 | 
			
		||||
	<mk-widget-container :naked="props.design == 1" :show-header="false">
 | 
			
		||||
		<div class="mkw-calendar--body">
 | 
			
		||||
			<div class="calendar" :data-is-holiday="isHoliday">
 | 
			
		||||
| 
						 | 
				
			
			@ -67,7 +67,7 @@ export default define({
 | 
			
		|||
	},
 | 
			
		||||
	methods: {
 | 
			
		||||
		func() {
 | 
			
		||||
			if (this.isMobile) return;
 | 
			
		||||
			if (this.platform == 'mobile') return;
 | 
			
		||||
			if (this.props.design == 2) {
 | 
			
		||||
				this.props.design = 0;
 | 
			
		||||
			} else {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
<template>
 | 
			
		||||
<div class="mkw-donation" :data-mobile="isMobile">
 | 
			
		||||
<div class="mkw-donation" :data-mobile="platform == 'mobile'">
 | 
			
		||||
	<article>
 | 
			
		||||
		<h1>%fa:heart%%i18n:@title%</h1>
 | 
			
		||||
		<p>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,7 +4,7 @@
 | 
			
		|||
		<template slot="header">%fa:rss-square%RSS</template>
 | 
			
		||||
		<button slot="func" title="設定" @click="setting">%fa:cog%</button>
 | 
			
		||||
 | 
			
		||||
		<div class="mkw-rss--body" :data-mobile="isMobile">
 | 
			
		||||
		<div class="mkw-rss--body" :data-mobile="platform == 'mobile'">
 | 
			
		||||
			<p class="fetching" v-if="fetching">%fa:spinner .pulse .fw%%i18n:common.loading%<mk-ellipsis/></p>
 | 
			
		||||
			<div class="feed" v-else>
 | 
			
		||||
				<a v-for="item in items" :href="item.link" target="_blank">{{ item.title }}</a>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
<template>
 | 
			
		||||
<div class="mkw-slideshow" :data-mobile="isMobile">
 | 
			
		||||
<div class="mkw-slideshow" :data-mobile="platform == 'mobile'">
 | 
			
		||||
	<div @click="choose">
 | 
			
		||||
		<p v-if="props.folder === undefined">
 | 
			
		||||
			<template v-if="isCustomizeMode">フォルダを指定するには、カスタマイズモードを終了してください</template>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -47,7 +47,7 @@
 | 
			
		|||
				:key="place"
 | 
			
		||||
			>
 | 
			
		||||
				<div v-for="widget in widgets[place]" class="customize-container" :key="widget.id" @contextmenu.stop.prevent="onWidgetContextmenu(widget.id)">
 | 
			
		||||
					<component :is="`mkw-${widget.name}`" :widget="widget" :ref="widget.id" :is-customize-mode="true"/>
 | 
			
		||||
					<component :is="`mkw-${widget.name}`" :widget="widget" :ref="widget.id" :is-customize-mode="true" platform="desktop"/>
 | 
			
		||||
				</div>
 | 
			
		||||
			</x-draggable>
 | 
			
		||||
			<div class="main">
 | 
			
		||||
| 
						 | 
				
			
			@ -60,7 +60,7 @@
 | 
			
		|||
		</template>
 | 
			
		||||
		<template v-else>
 | 
			
		||||
			<div v-for="place in ['left', 'right']" :class="place">
 | 
			
		||||
				<component v-for="widget in widgets[place]" :is="`mkw-${widget.name}`" :key="widget.id" :ref="widget.id" :widget="widget" @chosen="warp"/>
 | 
			
		||||
				<component v-for="widget in widgets[place]" :is="`mkw-${widget.name}`" :key="widget.id" :ref="widget.id" :widget="widget" @chosen="warp" platform="desktop"/>
 | 
			
		||||
			</div>
 | 
			
		||||
			<div class="main">
 | 
			
		||||
				<mk-post-form class="form" v-if="$store.state.settings.showPostFormOnTopOfTl"/>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,7 +36,7 @@ export default Vue.extend({
 | 
			
		|||
<style lang="stylus" scoped>
 | 
			
		||||
root(isDark)
 | 
			
		||||
	background isDark ? #282C37 : #fff
 | 
			
		||||
	border solid 1px rgba(#000, 0.075)
 | 
			
		||||
	border solid 1px rgba(#000, isDark ? 0.2 : 0.075)
 | 
			
		||||
	border-radius 6px
 | 
			
		||||
	overflow hidden
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,8 +1,8 @@
 | 
			
		|||
<template>
 | 
			
		||||
<div class="dnpfarvgbnfmyzbdquhhzyxcmstpdqzs">
 | 
			
		||||
<div class="dnpfarvgbnfmyzbdquhhzyxcmstpdqzs" :class="{ naked, narrow }">
 | 
			
		||||
	<header :class="{ indicate }">
 | 
			
		||||
		<slot name="header"></slot>
 | 
			
		||||
		<button ref="menu" @click="menu">%fa:caret-down%</button>
 | 
			
		||||
		<button ref="menu" @click="showMenu">%fa:caret-down%</button>
 | 
			
		||||
	</header>
 | 
			
		||||
	<div ref="body">
 | 
			
		||||
		<slot></slot>
 | 
			
		||||
| 
						 | 
				
			
			@ -19,6 +19,20 @@ export default Vue.extend({
 | 
			
		|||
		id: {
 | 
			
		||||
			type: String,
 | 
			
		||||
			required: false
 | 
			
		||||
		},
 | 
			
		||||
		menu: {
 | 
			
		||||
			type: Array,
 | 
			
		||||
			required: false
 | 
			
		||||
		},
 | 
			
		||||
		naked: {
 | 
			
		||||
			type: Boolean,
 | 
			
		||||
			required: false,
 | 
			
		||||
			default: false
 | 
			
		||||
		},
 | 
			
		||||
		narrow: {
 | 
			
		||||
			type: Boolean,
 | 
			
		||||
			required: false,
 | 
			
		||||
			default: false
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -59,26 +73,33 @@ export default Vue.extend({
 | 
			
		|||
			}
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		menu() {
 | 
			
		||||
		showMenu() {
 | 
			
		||||
			const items = [{
 | 
			
		||||
				content: '%fa:arrow-left% %i18n:@swap-left%',
 | 
			
		||||
				onClick: () => {
 | 
			
		||||
					this.$store.dispatch('settings/swapLeftDeckColumn', this.id);
 | 
			
		||||
				}
 | 
			
		||||
			}, {
 | 
			
		||||
				content: '%fa:arrow-right% %i18n:@swap-right%',
 | 
			
		||||
				onClick: () => {
 | 
			
		||||
					this.$store.dispatch('settings/swapRightDeckColumn', this.id);
 | 
			
		||||
				}
 | 
			
		||||
			}, {
 | 
			
		||||
				content: '%fa:trash-alt R% %i18n:@remove%',
 | 
			
		||||
				onClick: () => {
 | 
			
		||||
					this.$store.dispatch('settings/removeDeckColumn', this.id);
 | 
			
		||||
				}
 | 
			
		||||
			}];
 | 
			
		||||
 | 
			
		||||
			if (this.menu) {
 | 
			
		||||
				items.unshift(null);
 | 
			
		||||
				this.menu.reverse().forEach(i => items.unshift(i));
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			this.os.new(Menu, {
 | 
			
		||||
				source: this.$refs.menu,
 | 
			
		||||
				compact: false,
 | 
			
		||||
				items: [{
 | 
			
		||||
					content: '%fa:arrow-left% %i18n:@swap-left%',
 | 
			
		||||
					onClick: () => {
 | 
			
		||||
						this.$store.dispatch('settings/swapLeftDeckColumn', this.id);
 | 
			
		||||
					}
 | 
			
		||||
				}, {
 | 
			
		||||
					content: '%fa:arrow-right% %i18n:@swap-right%',
 | 
			
		||||
					onClick: () => {
 | 
			
		||||
						this.$store.dispatch('settings/swapRightDeckColumn', this.id);
 | 
			
		||||
					}
 | 
			
		||||
				}, {
 | 
			
		||||
					content: '%fa:trash-alt R% %i18n:@remove%',
 | 
			
		||||
					onClick: () => {
 | 
			
		||||
						this.$store.dispatch('settings/removeDeckColumn', this.id);
 | 
			
		||||
					}
 | 
			
		||||
				}]
 | 
			
		||||
				items
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -100,6 +121,21 @@ root(isDark)
 | 
			
		|||
	box-shadow 0 2px 16px rgba(#000, 0.1)
 | 
			
		||||
	overflow hidden
 | 
			
		||||
 | 
			
		||||
	&.narrow
 | 
			
		||||
		min-width 285px
 | 
			
		||||
		max-width 285px
 | 
			
		||||
 | 
			
		||||
	&.naked
 | 
			
		||||
		background rgba(#000, isDark ? 0.25 : 0.1)
 | 
			
		||||
 | 
			
		||||
		> header
 | 
			
		||||
			background transparent
 | 
			
		||||
			box-shadow none
 | 
			
		||||
 | 
			
		||||
			if !isDark
 | 
			
		||||
				> button
 | 
			
		||||
					color #bbb
 | 
			
		||||
 | 
			
		||||
	> header
 | 
			
		||||
		z-index 1
 | 
			
		||||
		line-height $header-height
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
<template>
 | 
			
		||||
<div>
 | 
			
		||||
	<x-column :id="id">
 | 
			
		||||
		<span slot="header">%fa:bell R% %i18n:@notifications%</span>
 | 
			
		||||
		<span slot="header">%fa:bell R%%i18n:@notifications%</span>
 | 
			
		||||
 | 
			
		||||
		<x-notifications/>
 | 
			
		||||
	</x-column>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,6 +2,7 @@
 | 
			
		|||
<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" :id="column.id"/>
 | 
			
		||||
			<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"/>
 | 
			
		||||
| 
						 | 
				
			
			@ -17,6 +18,7 @@
 | 
			
		|||
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 Menu from '../../../../common/views/components/menu.vue';
 | 
			
		||||
import MkUserListsWindow from '../../components/user-lists-window.vue';
 | 
			
		||||
import * as uuid from 'uuid';
 | 
			
		||||
| 
						 | 
				
			
			@ -24,7 +26,8 @@ import * as uuid from 'uuid';
 | 
			
		|||
export default Vue.extend({
 | 
			
		||||
	components: {
 | 
			
		||||
		XTlColumn,
 | 
			
		||||
		XNotificationsColumn
 | 
			
		||||
		XNotificationsColumn,
 | 
			
		||||
		XWidgetsColumn
 | 
			
		||||
	},
 | 
			
		||||
	computed: {
 | 
			
		||||
		columns() {
 | 
			
		||||
| 
						 | 
				
			
			@ -110,6 +113,15 @@ export default Vue.extend({
 | 
			
		|||
							type: 'notifications'
 | 
			
		||||
						});
 | 
			
		||||
					}
 | 
			
		||||
				}, {
 | 
			
		||||
					content: '%i18n:@widgets%',
 | 
			
		||||
					onClick: () => {
 | 
			
		||||
						this.$store.dispatch('settings/addDeckColumn', {
 | 
			
		||||
							id: uuid(),
 | 
			
		||||
							type: 'widgets',
 | 
			
		||||
							widgets: []
 | 
			
		||||
						});
 | 
			
		||||
					}
 | 
			
		||||
				}]
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										152
									
								
								src/client/app/desktop/views/pages/deck/deck.widgets-column.vue
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										152
									
								
								src/client/app/desktop/views/pages/deck/deck.widgets-column.vue
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,152 @@
 | 
			
		|||
<template>
 | 
			
		||||
<div class="wtdtxvecapixsepjtcupubtsmometobz">
 | 
			
		||||
	<x-column :id="column.id" :menu="menu" :naked="true" :narrow="true">
 | 
			
		||||
		<span slot="header">%fa:calculator%%i18n:@widgets%</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">追加</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>
 | 
			
		||||
				</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>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import XColumn from './deck.column.vue';
 | 
			
		||||
import * as XDraggable from 'vuedraggable';
 | 
			
		||||
import * as uuid from 'uuid';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	components: {
 | 
			
		||||
		XColumn,
 | 
			
		||||
		XDraggable
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	props: {
 | 
			
		||||
		column: {
 | 
			
		||||
			type: Object,
 | 
			
		||||
			required: true
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			edit: false,
 | 
			
		||||
			menu: null,
 | 
			
		||||
			widgetAdderSelected: null
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	created() {
 | 
			
		||||
		this.menu = [{
 | 
			
		||||
			content: '%fa:cog% %i18n:@edit%',
 | 
			
		||||
			onClick: () => {
 | 
			
		||||
				this.edit = !this.edit;
 | 
			
		||||
			}
 | 
			
		||||
		}];
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	methods: {
 | 
			
		||||
		widgetFunc(id) {
 | 
			
		||||
			const w = this.$refs[id][0];
 | 
			
		||||
			if (w.func) w.func();
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		onWidgetSort() {
 | 
			
		||||
			this.saveWidgets();
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		addWidget() {
 | 
			
		||||
			this.$store.dispatch('settings/addDeckWidget', {
 | 
			
		||||
				id: this.column.id,
 | 
			
		||||
				widget: {
 | 
			
		||||
					name: this.widgetAdderSelected,
 | 
			
		||||
					id: uuid(),
 | 
			
		||||
					data: {}
 | 
			
		||||
				}
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		removeWidget(widget) {
 | 
			
		||||
			this.$store.dispatch('settings/removeDeckWidget', {
 | 
			
		||||
				id: this.column.id,
 | 
			
		||||
				widget
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		saveWidgets() {
 | 
			
		||||
			this.$store.dispatch('settings/saveDeck');
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="stylus" scoped>
 | 
			
		||||
@import '~const.styl'
 | 
			
		||||
 | 
			
		||||
root(isDark)
 | 
			
		||||
	.gqpwvtwtprsbmnssnbicggtwqhmylhnq
 | 
			
		||||
		.widget, .customize-container
 | 
			
		||||
			margin 8px
 | 
			
		||||
 | 
			
		||||
			&:first-of-type
 | 
			
		||||
				margin-top 0
 | 
			
		||||
 | 
			
		||||
		.customize-container
 | 
			
		||||
			background #fff
 | 
			
		||||
 | 
			
		||||
		> header
 | 
			
		||||
			color isDark ? #fff : #000
 | 
			
		||||
 | 
			
		||||
.wtdtxvecapixsepjtcupubtsmometobz[data-darkmode]
 | 
			
		||||
	root(true)
 | 
			
		||||
 | 
			
		||||
.wtdtxvecapixsepjtcupubtsmometobz:not([data-darkmode])
 | 
			
		||||
	root(false)
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -35,13 +35,13 @@
 | 
			
		|||
						<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" :is-mobile="true"/>
 | 
			
		||||
						<component :is="`mkw-${widget.name}`" :widget="widget" :ref="widget.id" :is-customize-mode="true" platform="mobile"/>
 | 
			
		||||
					</div>
 | 
			
		||||
				</div>
 | 
			
		||||
			</x-draggable>
 | 
			
		||||
		</template>
 | 
			
		||||
		<template v-else>
 | 
			
		||||
			<component class="widget" v-for="widget in widgets" :is="`mkw-${widget.name}`" :key="widget.id" :ref="widget.id" :widget="widget" :is-mobile="true"/>
 | 
			
		||||
			<component class="widget" v-for="widget in widgets" :is="`mkw-${widget.name}`" :key="widget.id" :ref="widget.id" :widget="widget" platform="mobile"/>
 | 
			
		||||
		</template>
 | 
			
		||||
	</main>
 | 
			
		||||
</mk-ui>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -124,13 +124,6 @@ export default (os: MiOS) => new Vuex.Store({
 | 
			
		|||
					state.home = data;
 | 
			
		||||
				},
 | 
			
		||||
 | 
			
		||||
				setHomeWidget(state, x) {
 | 
			
		||||
					const w = state.home.find(w => w.id == x.id);
 | 
			
		||||
					if (w) {
 | 
			
		||||
						w.data = x.data;
 | 
			
		||||
					}
 | 
			
		||||
				},
 | 
			
		||||
 | 
			
		||||
				addHomeWidget(state, widget) {
 | 
			
		||||
					state.home.unshift(widget);
 | 
			
		||||
				},
 | 
			
		||||
| 
						 | 
				
			
			@ -139,11 +132,36 @@ export default (os: MiOS) => new Vuex.Store({
 | 
			
		|||
					state.mobileHome = data;
 | 
			
		||||
				},
 | 
			
		||||
 | 
			
		||||
				setMobileHomeWidget(state, x) {
 | 
			
		||||
					const w = state.mobileHome.find(w => w.id == x.id);
 | 
			
		||||
					if (w) {
 | 
			
		||||
						w.data = x.data;
 | 
			
		||||
				setWidget(state, x) {
 | 
			
		||||
					let w;
 | 
			
		||||
 | 
			
		||||
					//#region Decktop 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
 | 
			
		||||
 | 
			
		||||
					//#region Deck
 | 
			
		||||
					if (state.deck && state.deck.columns) {
 | 
			
		||||
						state.deck.columns.filter(c => c.type == 'widgets').forEach(c => {
 | 
			
		||||
							c.widgets.forEach(w => {
 | 
			
		||||
								if (w.id == x.id) w.data = x.data;
 | 
			
		||||
							});
 | 
			
		||||
						});
 | 
			
		||||
					}
 | 
			
		||||
					//#endregion
 | 
			
		||||
				},
 | 
			
		||||
 | 
			
		||||
				addMobileHomeWidget(state, widget) {
 | 
			
		||||
| 
						 | 
				
			
			@ -190,6 +208,20 @@ export default (os: MiOS) => new Vuex.Store({
 | 
			
		|||
							return true;
 | 
			
		||||
						}
 | 
			
		||||
					});
 | 
			
		||||
				},
 | 
			
		||||
 | 
			
		||||
				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);
 | 
			
		||||
				}
 | 
			
		||||
			},
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -212,40 +244,41 @@ export default (os: MiOS) => new Vuex.Store({
 | 
			
		|||
					}
 | 
			
		||||
				},
 | 
			
		||||
 | 
			
		||||
				addDeckColumn(ctx, column) {
 | 
			
		||||
					ctx.commit('addDeckColumn', column);
 | 
			
		||||
 | 
			
		||||
				saveDeck(ctx) {
 | 
			
		||||
					os.api('i/update_client_setting', {
 | 
			
		||||
						name: 'deck',
 | 
			
		||||
						value: ctx.state.deck
 | 
			
		||||
					});
 | 
			
		||||
				},
 | 
			
		||||
 | 
			
		||||
				addDeckColumn(ctx, column) {
 | 
			
		||||
					ctx.commit('addDeckColumn', column);
 | 
			
		||||
					ctx.dispatch('saveDeck');
 | 
			
		||||
				},
 | 
			
		||||
 | 
			
		||||
				removeDeckColumn(ctx, id) {
 | 
			
		||||
					ctx.commit('removeDeckColumn', id);
 | 
			
		||||
 | 
			
		||||
					os.api('i/update_client_setting', {
 | 
			
		||||
						name: 'deck',
 | 
			
		||||
						value: ctx.state.deck
 | 
			
		||||
					});
 | 
			
		||||
					ctx.dispatch('saveDeck');
 | 
			
		||||
				},
 | 
			
		||||
 | 
			
		||||
				swapLeftDeckColumn(ctx, id) {
 | 
			
		||||
					ctx.commit('swapLeftDeckColumn', id);
 | 
			
		||||
 | 
			
		||||
					os.api('i/update_client_setting', {
 | 
			
		||||
						name: 'deck',
 | 
			
		||||
						value: ctx.state.deck
 | 
			
		||||
					});
 | 
			
		||||
					ctx.dispatch('saveDeck');
 | 
			
		||||
				},
 | 
			
		||||
 | 
			
		||||
				swapRightDeckColumn(ctx, id) {
 | 
			
		||||
					ctx.commit('swapRightDeckColumn', id);
 | 
			
		||||
					ctx.dispatch('saveDeck');
 | 
			
		||||
				},
 | 
			
		||||
 | 
			
		||||
					os.api('i/update_client_setting', {
 | 
			
		||||
						name: 'deck',
 | 
			
		||||
						value: ctx.state.deck
 | 
			
		||||
					});
 | 
			
		||||
				addDeckWidget(ctx, x) {
 | 
			
		||||
					ctx.commit('addDeckWidget', x);
 | 
			
		||||
					ctx.dispatch('saveDeck');
 | 
			
		||||
				},
 | 
			
		||||
 | 
			
		||||
				removeDeckWidget(ctx, x) {
 | 
			
		||||
					ctx.commit('removeDeckWidget', x);
 | 
			
		||||
					ctx.dispatch('saveDeck');
 | 
			
		||||
				},
 | 
			
		||||
 | 
			
		||||
				addHomeWidget(ctx, widget) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -189,6 +189,11 @@ const endpoints: Endpoint[] = [
 | 
			
		|||
		withCredential: true,
 | 
			
		||||
		secure: true
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		name: 'i/update_widget',
 | 
			
		||||
		withCredential: true,
 | 
			
		||||
		secure: true
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		name: 'i/change_password',
 | 
			
		||||
		withCredential: true,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,3 @@
 | 
			
		|||
/**
 | 
			
		||||
 * Module dependencies
 | 
			
		||||
 */
 | 
			
		||||
import $ from 'cafy';
 | 
			
		||||
import User from '../../../../models/user';
 | 
			
		||||
import event from '../../../../publishers/stream';
 | 
			
		||||
| 
						 | 
				
			
			@ -13,50 +10,16 @@ module.exports = async (params, user) => new Promise(async (res, rej) => {
 | 
			
		|||
			.have('id', $.str)
 | 
			
		||||
			.have('place', $.str)
 | 
			
		||||
			.have('data', $.obj))
 | 
			
		||||
		.optional()
 | 
			
		||||
		.get(params.home);
 | 
			
		||||
	if (homeErr) return rej('invalid home param');
 | 
			
		||||
 | 
			
		||||
	// Get 'id' parameter
 | 
			
		||||
	const [id, idErr] = $.str.optional().get(params.id);
 | 
			
		||||
	if (idErr) return rej('invalid id param');
 | 
			
		||||
	await User.update(user._id, {
 | 
			
		||||
		$set: {
 | 
			
		||||
			'clientSettings.home': home
 | 
			
		||||
		}
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	// Get 'data' parameter
 | 
			
		||||
	const [data, dataErr] = $.obj.optional().get(params.data);
 | 
			
		||||
	if (dataErr) return rej('invalid data param');
 | 
			
		||||
	res();
 | 
			
		||||
 | 
			
		||||
	if (home) {
 | 
			
		||||
		await User.update(user._id, {
 | 
			
		||||
			$set: {
 | 
			
		||||
				'clientSettings.home': home
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		res();
 | 
			
		||||
 | 
			
		||||
		event(user._id, 'home_updated', {
 | 
			
		||||
			home
 | 
			
		||||
		});
 | 
			
		||||
	} else {
 | 
			
		||||
		if (id == null && data == null) return rej('you need to set id and data params if home param unset');
 | 
			
		||||
 | 
			
		||||
		const _home = user.clientSettings.home;
 | 
			
		||||
		const widget = _home.find(w => w.id == id);
 | 
			
		||||
 | 
			
		||||
		if (widget == null) return rej('widget not found');
 | 
			
		||||
 | 
			
		||||
		widget.data = data;
 | 
			
		||||
 | 
			
		||||
		await User.update(user._id, {
 | 
			
		||||
			$set: {
 | 
			
		||||
				'clientSettings.home': _home
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		res();
 | 
			
		||||
 | 
			
		||||
		event(user._id, 'home_updated', {
 | 
			
		||||
			id, data
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
	event(user._id, 'home_updated', home);
 | 
			
		||||
});
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,3 @@
 | 
			
		|||
/**
 | 
			
		||||
 * Module dependencies
 | 
			
		||||
 */
 | 
			
		||||
import $ from 'cafy';
 | 
			
		||||
import User from '../../../../models/user';
 | 
			
		||||
import event from '../../../../publishers/stream';
 | 
			
		||||
| 
						 | 
				
			
			@ -12,49 +9,16 @@ module.exports = async (params, user) => new Promise(async (res, rej) => {
 | 
			
		|||
			.have('name', $.str)
 | 
			
		||||
			.have('id', $.str)
 | 
			
		||||
			.have('data', $.obj))
 | 
			
		||||
		.optional().get(params.home);
 | 
			
		||||
		.get(params.home);
 | 
			
		||||
	if (homeErr) return rej('invalid home param');
 | 
			
		||||
 | 
			
		||||
	// Get 'id' parameter
 | 
			
		||||
	const [id, idErr] = $.str.optional().get(params.id);
 | 
			
		||||
	if (idErr) return rej('invalid id param');
 | 
			
		||||
	await User.update(user._id, {
 | 
			
		||||
		$set: {
 | 
			
		||||
			'clientSettings.mobileHome': home
 | 
			
		||||
		}
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	// Get 'data' parameter
 | 
			
		||||
	const [data, dataErr] = $.obj.optional().get(params.data);
 | 
			
		||||
	if (dataErr) return rej('invalid data param');
 | 
			
		||||
	res();
 | 
			
		||||
 | 
			
		||||
	if (home) {
 | 
			
		||||
		await User.update(user._id, {
 | 
			
		||||
			$set: {
 | 
			
		||||
				'clientSettings.mobileHome': home
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		res();
 | 
			
		||||
 | 
			
		||||
		event(user._id, 'mobile_home_updated', {
 | 
			
		||||
			home
 | 
			
		||||
		});
 | 
			
		||||
	} else {
 | 
			
		||||
		if (id == null && data == null) return rej('you need to set id and data params if home param unset');
 | 
			
		||||
 | 
			
		||||
		const _home = user.clientSettings.mobileHome || [];
 | 
			
		||||
		const widget = _home.find(w => w.id == id);
 | 
			
		||||
 | 
			
		||||
		if (widget == null) return rej('widget not found');
 | 
			
		||||
 | 
			
		||||
		widget.data = data;
 | 
			
		||||
 | 
			
		||||
		await User.update(user._id, {
 | 
			
		||||
			$set: {
 | 
			
		||||
				'clientSettings.mobileHome': _home
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		res();
 | 
			
		||||
 | 
			
		||||
		event(user._id, 'mobile_home_updated', {
 | 
			
		||||
			id, data
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
	event(user._id, 'mobile_home_updated', home);
 | 
			
		||||
});
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										79
									
								
								src/server/api/endpoints/i/update_widget.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								src/server/api/endpoints/i/update_widget.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,79 @@
 | 
			
		|||
import $ from 'cafy';
 | 
			
		||||
import User from '../../../../models/user';
 | 
			
		||||
import event from '../../../../publishers/stream';
 | 
			
		||||
 | 
			
		||||
module.exports = async (params, user) => new Promise(async (res, rej) => {
 | 
			
		||||
	// Get 'id' parameter
 | 
			
		||||
	const [id, idErr] = $.str.get(params.id);
 | 
			
		||||
	if (idErr) return rej('invalid id param');
 | 
			
		||||
 | 
			
		||||
	// Get 'data' parameter
 | 
			
		||||
	const [data, dataErr] = $.obj.get(params.data);
 | 
			
		||||
	if (dataErr) return rej('invalid data param');
 | 
			
		||||
 | 
			
		||||
	if (id == null && data == null) return rej('you need to set id and data params if home param unset');
 | 
			
		||||
 | 
			
		||||
	let widget;
 | 
			
		||||
 | 
			
		||||
	//#region Desktop home
 | 
			
		||||
	if (widget == null && user.clientSettings.home) {
 | 
			
		||||
		const desktopHome = user.clientSettings.home;
 | 
			
		||||
		widget = desktopHome.find(w => w.id == id);
 | 
			
		||||
		if (widget) {
 | 
			
		||||
				widget.data = data;
 | 
			
		||||
 | 
			
		||||
			await User.update(user._id, {
 | 
			
		||||
				$set: {
 | 
			
		||||
					'clientSettings.home': desktopHome
 | 
			
		||||
				}
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	//#endregion
 | 
			
		||||
 | 
			
		||||
	//#region Mobile home
 | 
			
		||||
	if (widget == null && user.clientSettings.mobileHome) {
 | 
			
		||||
		const mobileHome = user.clientSettings.mobileHome;
 | 
			
		||||
		widget = mobileHome.find(w => w.id == id);
 | 
			
		||||
		if (widget) {
 | 
			
		||||
				widget.data = data;
 | 
			
		||||
 | 
			
		||||
			await User.update(user._id, {
 | 
			
		||||
				$set: {
 | 
			
		||||
					'clientSettings.mobileHome': mobileHome
 | 
			
		||||
				}
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	//#endregion
 | 
			
		||||
 | 
			
		||||
	//#region Deck
 | 
			
		||||
	if (widget == null && user.clientSettings.deck && user.clientSettings.deck.columns) {
 | 
			
		||||
		const deck = user.clientSettings.deck;
 | 
			
		||||
		deck.columns.filter(c => c.type == 'widgets').forEach(c => {
 | 
			
		||||
			c.widgets.forEach(w => {
 | 
			
		||||
				if (w.id == id) widget = w;
 | 
			
		||||
			});
 | 
			
		||||
		});
 | 
			
		||||
		if (widget) {
 | 
			
		||||
				widget.data = data;
 | 
			
		||||
 | 
			
		||||
			await User.update(user._id, {
 | 
			
		||||
				$set: {
 | 
			
		||||
					'clientSettings.deck': deck
 | 
			
		||||
				}
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	//#endregion
 | 
			
		||||
 | 
			
		||||
	if (widget) {
 | 
			
		||||
		event(user._id, 'widgetUpdated', {
 | 
			
		||||
			id, data
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		res();
 | 
			
		||||
	} else {
 | 
			
		||||
		rej('widget not found');
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
		Loading…
	
	Add table
		
		Reference in a new issue