wip
This commit is contained in:
		
							parent
							
								
									0d8c83f27c
								
							
						
					
					
						commit
						69b5de3346
					
				
					 11 changed files with 505 additions and 163 deletions
				
			
		| 
						 | 
					@ -1,6 +1,7 @@
 | 
				
			||||||
import Vue from 'vue';
 | 
					import Vue from 'vue';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import analogClock from './analog-clock.vue';
 | 
					import analogClock from './analog-clock.vue';
 | 
				
			||||||
 | 
					import menu from './menu.vue';
 | 
				
			||||||
import signin from './signin.vue';
 | 
					import signin from './signin.vue';
 | 
				
			||||||
import signup from './signup.vue';
 | 
					import signup from './signup.vue';
 | 
				
			||||||
import forkit from './forkit.vue';
 | 
					import forkit from './forkit.vue';
 | 
				
			||||||
| 
						 | 
					@ -29,6 +30,7 @@ import Othello from './othello.vue';
 | 
				
			||||||
import welcomeTimeline from './welcome-timeline.vue';
 | 
					import welcomeTimeline from './welcome-timeline.vue';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Vue.component('mk-analog-clock', analogClock);
 | 
					Vue.component('mk-analog-clock', analogClock);
 | 
				
			||||||
 | 
					Vue.component('mk-menu', menu);
 | 
				
			||||||
Vue.component('mk-signin', signin);
 | 
					Vue.component('mk-signin', signin);
 | 
				
			||||||
Vue.component('mk-signup', signup);
 | 
					Vue.component('mk-signup', signup);
 | 
				
			||||||
Vue.component('mk-forkit', forkit);
 | 
					Vue.component('mk-forkit', forkit);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										153
									
								
								src/client/app/common/views/components/menu.vue
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										153
									
								
								src/client/app/common/views/components/menu.vue
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,153 @@
 | 
				
			||||||
 | 
					<template>
 | 
				
			||||||
 | 
					<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>
 | 
				
			||||||
 | 
						</div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script lang="ts">
 | 
				
			||||||
 | 
					import Vue from 'vue';
 | 
				
			||||||
 | 
					import * as anime from 'animejs';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default Vue.extend({
 | 
				
			||||||
 | 
						props: ['source', 'compact', 'items'],
 | 
				
			||||||
 | 
						mounted() {
 | 
				
			||||||
 | 
							this.$nextTick(() => {
 | 
				
			||||||
 | 
								const popover = this.$refs.popover as any;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								const rect = this.source.getBoundingClientRect();
 | 
				
			||||||
 | 
								const width = popover.offsetWidth;
 | 
				
			||||||
 | 
								const height = popover.offsetHeight;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								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';
 | 
				
			||||||
 | 
								} 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';
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								anime({
 | 
				
			||||||
 | 
									targets: this.$refs.backdrop,
 | 
				
			||||||
 | 
									opacity: 1,
 | 
				
			||||||
 | 
									duration: 100,
 | 
				
			||||||
 | 
									easing: 'linear'
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								anime({
 | 
				
			||||||
 | 
									targets: this.$refs.popover,
 | 
				
			||||||
 | 
									opacity: 1,
 | 
				
			||||||
 | 
									scale: [0.5, 1],
 | 
				
			||||||
 | 
									duration: 500
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						methods: {
 | 
				
			||||||
 | 
							clicked(fn) {
 | 
				
			||||||
 | 
								fn();
 | 
				
			||||||
 | 
								this.close();
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							close() {
 | 
				
			||||||
 | 
								(this.$refs.backdrop as any).style.pointerEvents = 'none';
 | 
				
			||||||
 | 
								anime({
 | 
				
			||||||
 | 
									targets: this.$refs.backdrop,
 | 
				
			||||||
 | 
									opacity: 0,
 | 
				
			||||||
 | 
									duration: 200,
 | 
				
			||||||
 | 
									easing: 'linear'
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								(this.$refs.popover as any).style.pointerEvents = 'none';
 | 
				
			||||||
 | 
								anime({
 | 
				
			||||||
 | 
									targets: this.$refs.popover,
 | 
				
			||||||
 | 
									opacity: 0,
 | 
				
			||||||
 | 
									scale: 0.5,
 | 
				
			||||||
 | 
									duration: 200,
 | 
				
			||||||
 | 
									easing: 'easeInBack',
 | 
				
			||||||
 | 
									complete: () => {
 | 
				
			||||||
 | 
										this.$emit('closed');
 | 
				
			||||||
 | 
										this.$destroy();
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style lang="stylus" scoped>
 | 
				
			||||||
 | 
					@import '~const.styl'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$border-color = rgba(27, 31, 35, 0.15)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.mk-menu
 | 
				
			||||||
 | 
						position initial
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						> .backdrop
 | 
				
			||||||
 | 
							position fixed
 | 
				
			||||||
 | 
							top 0
 | 
				
			||||||
 | 
							left 0
 | 
				
			||||||
 | 
							z-index 10000
 | 
				
			||||||
 | 
							width 100%
 | 
				
			||||||
 | 
							height 100%
 | 
				
			||||||
 | 
							background rgba(#000, 0.1)
 | 
				
			||||||
 | 
							opacity 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						> .popover
 | 
				
			||||||
 | 
							position absolute
 | 
				
			||||||
 | 
							z-index 10001
 | 
				
			||||||
 | 
							padding 8px 0
 | 
				
			||||||
 | 
							background #fff
 | 
				
			||||||
 | 
							border 1px solid $border-color
 | 
				
			||||||
 | 
							border-radius 4px
 | 
				
			||||||
 | 
							box-shadow 0 3px 12px rgba(27, 31, 35, 0.15)
 | 
				
			||||||
 | 
							transform scale(0.5)
 | 
				
			||||||
 | 
							opacity 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							$balloon-size = 16px
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							&:not(.compact)
 | 
				
			||||||
 | 
								margin-top $balloon-size
 | 
				
			||||||
 | 
								transform-origin center -($balloon-size)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								&:before
 | 
				
			||||||
 | 
									content ""
 | 
				
			||||||
 | 
									display block
 | 
				
			||||||
 | 
									position absolute
 | 
				
			||||||
 | 
									top -($balloon-size * 2)
 | 
				
			||||||
 | 
									left s('calc(50% - %s)', $balloon-size)
 | 
				
			||||||
 | 
									border-top solid $balloon-size transparent
 | 
				
			||||||
 | 
									border-left solid $balloon-size transparent
 | 
				
			||||||
 | 
									border-right solid $balloon-size transparent
 | 
				
			||||||
 | 
									border-bottom solid $balloon-size $border-color
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								&:after
 | 
				
			||||||
 | 
									content ""
 | 
				
			||||||
 | 
									display block
 | 
				
			||||||
 | 
									position absolute
 | 
				
			||||||
 | 
									top -($balloon-size * 2) + 1.5px
 | 
				
			||||||
 | 
									left s('calc(50% - %s)', $balloon-size)
 | 
				
			||||||
 | 
									border-top solid $balloon-size transparent
 | 
				
			||||||
 | 
									border-left solid $balloon-size transparent
 | 
				
			||||||
 | 
									border-right solid $balloon-size transparent
 | 
				
			||||||
 | 
									border-bottom solid $balloon-size #fff
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							> button
 | 
				
			||||||
 | 
								display block
 | 
				
			||||||
 | 
								padding 8px 16px
 | 
				
			||||||
 | 
								width 100%
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								&:hover
 | 
				
			||||||
 | 
									color $theme-color-foreground
 | 
				
			||||||
 | 
									background $theme-color
 | 
				
			||||||
 | 
									text-decoration none
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								&:active
 | 
				
			||||||
 | 
									color $theme-color-foreground
 | 
				
			||||||
 | 
									background darken($theme-color, 10%)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
| 
						 | 
					@ -1,55 +1,41 @@
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
<div class="mk-note-menu">
 | 
					<div class="mk-note-menu" style="position:initial">
 | 
				
			||||||
	<div class="backdrop" ref="backdrop" @click="close"></div>
 | 
						<mk-menu ref="menu" :source="source" :compact="compact" :items="items" @closed="$destroy"/>
 | 
				
			||||||
	<div class="popover" :class="{ compact }" ref="popover">
 | 
					 | 
				
			||||||
		<button @click="favorite">%i18n:@favorite%</button>
 | 
					 | 
				
			||||||
		<button v-if="note.userId == $store.state.i.id" @click="pin">%i18n:@pin%</button>
 | 
					 | 
				
			||||||
		<button v-if="note.userId == $store.state.i.id" @click="del">%i18n:@delete%</button>
 | 
					 | 
				
			||||||
		<a v-if="note.uri" :href="note.uri" target="_blank">%i18n:@remote%</a>
 | 
					 | 
				
			||||||
	</div>
 | 
					 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script lang="ts">
 | 
					<script lang="ts">
 | 
				
			||||||
import Vue from 'vue';
 | 
					import Vue from 'vue';
 | 
				
			||||||
import * as anime from 'animejs';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default Vue.extend({
 | 
					export default Vue.extend({
 | 
				
			||||||
	props: ['note', 'source', 'compact'],
 | 
						props: ['note', 'source', 'compact'],
 | 
				
			||||||
	mounted() {
 | 
						computed: {
 | 
				
			||||||
		this.$nextTick(() => {
 | 
							items() {
 | 
				
			||||||
			const popover = this.$refs.popover as any;
 | 
								const items = [];
 | 
				
			||||||
 | 
								items.push({
 | 
				
			||||||
			const rect = this.source.getBoundingClientRect();
 | 
									content: '%i18n:@favorite%',
 | 
				
			||||||
			const width = popover.offsetWidth;
 | 
									onClick: this.favorite
 | 
				
			||||||
			const height = popover.offsetHeight;
 | 
								});
 | 
				
			||||||
 | 
								if (this.note.userId == this.$store.state.i.id) {
 | 
				
			||||||
			if (this.compact) {
 | 
									items.push({
 | 
				
			||||||
				const x = rect.left + window.pageXOffset + (this.source.offsetWidth / 2);
 | 
										content: '%i18n:@pin%',
 | 
				
			||||||
				const y = rect.top + window.pageYOffset + (this.source.offsetHeight / 2);
 | 
										onClick: this.pin
 | 
				
			||||||
				popover.style.left = (x - (width / 2)) + 'px';
 | 
									});
 | 
				
			||||||
				popover.style.top = (y - (height / 2)) + 'px';
 | 
									items.push({
 | 
				
			||||||
			} else {
 | 
										content: '%i18n:@delete%',
 | 
				
			||||||
				const x = rect.left + window.pageXOffset + (this.source.offsetWidth / 2);
 | 
										onClick: this.del
 | 
				
			||||||
				const y = rect.top + window.pageYOffset + this.source.offsetHeight;
 | 
									});
 | 
				
			||||||
				popover.style.left = (x - (width / 2)) + 'px';
 | 
								}
 | 
				
			||||||
				popover.style.top = y + 'px';
 | 
								if (this.note.uri) {
 | 
				
			||||||
 | 
									items.push({
 | 
				
			||||||
 | 
										content: '%i18n:@remote%',
 | 
				
			||||||
 | 
										onClick: () => {
 | 
				
			||||||
 | 
											window.open(this.note.uri, '_blank');
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
 | 
					 | 
				
			||||||
			anime({
 | 
					 | 
				
			||||||
				targets: this.$refs.backdrop,
 | 
					 | 
				
			||||||
				opacity: 1,
 | 
					 | 
				
			||||||
				duration: 100,
 | 
					 | 
				
			||||||
				easing: 'linear'
 | 
					 | 
				
			||||||
			});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			anime({
 | 
					 | 
				
			||||||
				targets: this.$refs.popover,
 | 
					 | 
				
			||||||
				opacity: 1,
 | 
					 | 
				
			||||||
				scale: [0.5, 1],
 | 
					 | 
				
			||||||
				duration: 500
 | 
					 | 
				
			||||||
			});
 | 
					 | 
				
			||||||
				});
 | 
									});
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return items;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	methods: {
 | 
						methods: {
 | 
				
			||||||
		pin() {
 | 
							pin() {
 | 
				
			||||||
| 
						 | 
					@ -78,98 +64,8 @@ export default Vue.extend({
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		close() {
 | 
							close() {
 | 
				
			||||||
			(this.$refs.backdrop as any).style.pointerEvents = 'none';
 | 
								this.$refs.menu.close();
 | 
				
			||||||
			anime({
 | 
					 | 
				
			||||||
				targets: this.$refs.backdrop,
 | 
					 | 
				
			||||||
				opacity: 0,
 | 
					 | 
				
			||||||
				duration: 200,
 | 
					 | 
				
			||||||
				easing: 'linear'
 | 
					 | 
				
			||||||
			});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			(this.$refs.popover as any).style.pointerEvents = 'none';
 | 
					 | 
				
			||||||
			anime({
 | 
					 | 
				
			||||||
				targets: this.$refs.popover,
 | 
					 | 
				
			||||||
				opacity: 0,
 | 
					 | 
				
			||||||
				scale: 0.5,
 | 
					 | 
				
			||||||
				duration: 200,
 | 
					 | 
				
			||||||
				easing: 'easeInBack',
 | 
					 | 
				
			||||||
				complete: () => this.$destroy()
 | 
					 | 
				
			||||||
			});
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					 | 
				
			||||||
<style lang="stylus" scoped>
 | 
					 | 
				
			||||||
@import '~const.styl'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
$border-color = rgba(27, 31, 35, 0.15)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.mk-note-menu
 | 
					 | 
				
			||||||
	position initial
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	> .backdrop
 | 
					 | 
				
			||||||
		position fixed
 | 
					 | 
				
			||||||
		top 0
 | 
					 | 
				
			||||||
		left 0
 | 
					 | 
				
			||||||
		z-index 10000
 | 
					 | 
				
			||||||
		width 100%
 | 
					 | 
				
			||||||
		height 100%
 | 
					 | 
				
			||||||
		background rgba(#000, 0.1)
 | 
					 | 
				
			||||||
		opacity 0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	> .popover
 | 
					 | 
				
			||||||
		position absolute
 | 
					 | 
				
			||||||
		z-index 10001
 | 
					 | 
				
			||||||
		padding 8px 0
 | 
					 | 
				
			||||||
		background #fff
 | 
					 | 
				
			||||||
		border 1px solid $border-color
 | 
					 | 
				
			||||||
		border-radius 4px
 | 
					 | 
				
			||||||
		box-shadow 0 3px 12px rgba(27, 31, 35, 0.15)
 | 
					 | 
				
			||||||
		transform scale(0.5)
 | 
					 | 
				
			||||||
		opacity 0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		$balloon-size = 16px
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		&:not(.compact)
 | 
					 | 
				
			||||||
			margin-top $balloon-size
 | 
					 | 
				
			||||||
			transform-origin center -($balloon-size)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			&:before
 | 
					 | 
				
			||||||
				content ""
 | 
					 | 
				
			||||||
				display block
 | 
					 | 
				
			||||||
				position absolute
 | 
					 | 
				
			||||||
				top -($balloon-size * 2)
 | 
					 | 
				
			||||||
				left s('calc(50% - %s)', $balloon-size)
 | 
					 | 
				
			||||||
				border-top solid $balloon-size transparent
 | 
					 | 
				
			||||||
				border-left solid $balloon-size transparent
 | 
					 | 
				
			||||||
				border-right solid $balloon-size transparent
 | 
					 | 
				
			||||||
				border-bottom solid $balloon-size $border-color
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			&:after
 | 
					 | 
				
			||||||
				content ""
 | 
					 | 
				
			||||||
				display block
 | 
					 | 
				
			||||||
				position absolute
 | 
					 | 
				
			||||||
				top -($balloon-size * 2) + 1.5px
 | 
					 | 
				
			||||||
				left s('calc(50% - %s)', $balloon-size)
 | 
					 | 
				
			||||||
				border-top solid $balloon-size transparent
 | 
					 | 
				
			||||||
				border-left solid $balloon-size transparent
 | 
					 | 
				
			||||||
				border-right solid $balloon-size transparent
 | 
					 | 
				
			||||||
				border-bottom solid $balloon-size #fff
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		> button
 | 
					 | 
				
			||||||
		> a
 | 
					 | 
				
			||||||
			display block
 | 
					 | 
				
			||||||
			padding 8px 16px
 | 
					 | 
				
			||||||
			width 100%
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			&:hover
 | 
					 | 
				
			||||||
				color $theme-color-foreground
 | 
					 | 
				
			||||||
				background $theme-color
 | 
					 | 
				
			||||||
				text-decoration none
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			&:active
 | 
					 | 
				
			||||||
				color $theme-color-foreground
 | 
					 | 
				
			||||||
				background darken($theme-color, 10%)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
</style>
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,6 +2,7 @@
 | 
				
			||||||
<div class="dnpfarvgbnfmyzbdquhhzyxcmstpdqzs">
 | 
					<div class="dnpfarvgbnfmyzbdquhhzyxcmstpdqzs">
 | 
				
			||||||
	<header :class="{ indicate }">
 | 
						<header :class="{ indicate }">
 | 
				
			||||||
		<slot name="header"></slot>
 | 
							<slot name="header"></slot>
 | 
				
			||||||
 | 
							<button ref="menu" @click="menu">%fa:caret-down%</button>
 | 
				
			||||||
	</header>
 | 
						</header>
 | 
				
			||||||
	<div ref="body">
 | 
						<div ref="body">
 | 
				
			||||||
		<slot></slot>
 | 
							<slot></slot>
 | 
				
			||||||
| 
						 | 
					@ -11,8 +12,16 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script lang="ts">
 | 
					<script lang="ts">
 | 
				
			||||||
import Vue from 'vue';
 | 
					import Vue from 'vue';
 | 
				
			||||||
 | 
					import Menu from '../../../../common/views/components/menu.vue';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default Vue.extend({
 | 
					export default Vue.extend({
 | 
				
			||||||
 | 
						props: {
 | 
				
			||||||
 | 
							id: {
 | 
				
			||||||
 | 
								type: String,
 | 
				
			||||||
 | 
								required: false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	data() {
 | 
						data() {
 | 
				
			||||||
		return {
 | 
							return {
 | 
				
			||||||
			indicate: false
 | 
								indicate: false
 | 
				
			||||||
| 
						 | 
					@ -48,6 +57,29 @@ export default Vue.extend({
 | 
				
			||||||
				const current = this.$refs.body.scrollTop + this.$refs.body.clientHeight;
 | 
									const current = this.$refs.body.scrollTop + this.$refs.body.clientHeight;
 | 
				
			||||||
				if (current > this.$refs.body.scrollHeight - 1) this.$emit('bottom');
 | 
									if (current > this.$refs.body.scrollHeight - 1) this.$emit('bottom');
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							menu() {
 | 
				
			||||||
 | 
								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);
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}]
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
| 
						 | 
					@ -57,6 +89,8 @@ export default Vue.extend({
 | 
				
			||||||
@import '~const.styl'
 | 
					@import '~const.styl'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
root(isDark)
 | 
					root(isDark)
 | 
				
			||||||
 | 
						$header-height = 42px
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	flex 1
 | 
						flex 1
 | 
				
			||||||
	min-width 330px
 | 
						min-width 330px
 | 
				
			||||||
	max-width 330px
 | 
						max-width 330px
 | 
				
			||||||
| 
						 | 
					@ -68,7 +102,7 @@ root(isDark)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	> header
 | 
						> header
 | 
				
			||||||
		z-index 1
 | 
							z-index 1
 | 
				
			||||||
		line-height 42px
 | 
							line-height $header-height
 | 
				
			||||||
		padding 0 16px
 | 
							padding 0 16px
 | 
				
			||||||
		color isDark ? #e3e5e8 : #888
 | 
							color isDark ? #e3e5e8 : #888
 | 
				
			||||||
		background isDark ? #313543 : #fff
 | 
							background isDark ? #313543 : #fff
 | 
				
			||||||
| 
						 | 
					@ -77,8 +111,26 @@ root(isDark)
 | 
				
			||||||
		&.indicate
 | 
							&.indicate
 | 
				
			||||||
			box-shadow 0 3px 0 0 $theme-color
 | 
								box-shadow 0 3px 0 0 $theme-color
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							> span
 | 
				
			||||||
 | 
								[data-fa]
 | 
				
			||||||
 | 
									margin-right 8px
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							> button
 | 
				
			||||||
 | 
								position absolute
 | 
				
			||||||
 | 
								top 0
 | 
				
			||||||
 | 
								right 0
 | 
				
			||||||
 | 
								width $header-height
 | 
				
			||||||
 | 
								line-height $header-height
 | 
				
			||||||
 | 
								color isDark ? #9baec8 : #ccc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								&:hover
 | 
				
			||||||
 | 
									color isDark ? #b2c1d5 : #aaa
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								&:active
 | 
				
			||||||
 | 
									color isDark ? #b2c1d5 : #999
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	> div
 | 
						> div
 | 
				
			||||||
		height calc(100% - 42px)
 | 
							height calc(100% - $header-height)
 | 
				
			||||||
		overflow auto
 | 
							overflow auto
 | 
				
			||||||
		overflow-x hidden
 | 
							overflow-x hidden
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										103
									
								
								src/client/app/desktop/views/pages/deck/deck.list-tl.vue
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								src/client/app/desktop/views/pages/deck/deck.list-tl.vue
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,103 @@
 | 
				
			||||||
 | 
					<template>
 | 
				
			||||||
 | 
						<x-notes ref="timeline" :more="existMore ? more : null"/>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script lang="ts">
 | 
				
			||||||
 | 
					import Vue from 'vue';
 | 
				
			||||||
 | 
					import XNotes from './deck.notes.vue';
 | 
				
			||||||
 | 
					import { UserListStream } from '../../../../common/scripts/streaming/user-list';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const fetchLimit = 10;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default Vue.extend({
 | 
				
			||||||
 | 
						components: {
 | 
				
			||||||
 | 
							XNotes
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						props: {
 | 
				
			||||||
 | 
							list: {
 | 
				
			||||||
 | 
								type: Object,
 | 
				
			||||||
 | 
								required: true
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						data() {
 | 
				
			||||||
 | 
							return {
 | 
				
			||||||
 | 
								fetching: true,
 | 
				
			||||||
 | 
								moreFetching: false,
 | 
				
			||||||
 | 
								existMore: false,
 | 
				
			||||||
 | 
								connection: null
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mounted() {
 | 
				
			||||||
 | 
							if (this.connection) this.connection.close();
 | 
				
			||||||
 | 
							this.connection = new UserListStream((this as any).os, this.$store.state.i, this.list.id);
 | 
				
			||||||
 | 
							this.connection.on('note', this.onNote);
 | 
				
			||||||
 | 
							this.connection.on('userAdded', this.onUserAdded);
 | 
				
			||||||
 | 
							this.connection.on('userRemoved', this.onUserRemoved);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							this.fetch();
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						beforeDestroy() {
 | 
				
			||||||
 | 
							this.connection.close();
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						methods: {
 | 
				
			||||||
 | 
							fetch() {
 | 
				
			||||||
 | 
								this.fetching = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								(this.$refs.timeline as any).init(() => new Promise((res, rej) => {
 | 
				
			||||||
 | 
									(this as any).api('notes/user-list-timeline', {
 | 
				
			||||||
 | 
										listId: this.list.id,
 | 
				
			||||||
 | 
										limit: fetchLimit + 1,
 | 
				
			||||||
 | 
										includeMyRenotes: this.$store.state.settings.showMyRenotes,
 | 
				
			||||||
 | 
										includeRenotedMyNotes: this.$store.state.settings.showRenotedMyNotes
 | 
				
			||||||
 | 
									}).then(notes => {
 | 
				
			||||||
 | 
										if (notes.length == fetchLimit + 1) {
 | 
				
			||||||
 | 
											notes.pop();
 | 
				
			||||||
 | 
											this.existMore = true;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										res(notes);
 | 
				
			||||||
 | 
										this.fetching = false;
 | 
				
			||||||
 | 
										this.$emit('loaded');
 | 
				
			||||||
 | 
									}, rej);
 | 
				
			||||||
 | 
								}));
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							more() {
 | 
				
			||||||
 | 
								this.moreFetching = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								const promise = (this as any).api('notes/user-list-timeline', {
 | 
				
			||||||
 | 
									listId: this.list.id,
 | 
				
			||||||
 | 
									limit: fetchLimit + 1,
 | 
				
			||||||
 | 
									untilId: (this.$refs.timeline as any).tail().id,
 | 
				
			||||||
 | 
									includeMyRenotes: this.$store.state.settings.showMyRenotes,
 | 
				
			||||||
 | 
									includeRenotedMyNotes: this.$store.state.settings.showRenotedMyNotes
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								promise.then(notes => {
 | 
				
			||||||
 | 
									if (notes.length == fetchLimit + 1) {
 | 
				
			||||||
 | 
										notes.pop();
 | 
				
			||||||
 | 
									} else {
 | 
				
			||||||
 | 
										this.existMore = false;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									notes.forEach(n => (this.$refs.timeline as any).append(n));
 | 
				
			||||||
 | 
									this.moreFetching = false;
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								return promise;
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							onNote(note) {
 | 
				
			||||||
 | 
								// Prepend a note
 | 
				
			||||||
 | 
								(this.$refs.timeline as any).prepend(note);
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							onUserAdded() {
 | 
				
			||||||
 | 
								this.fetch();
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							onUserRemoved() {
 | 
				
			||||||
 | 
								this.fetch();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
<div>
 | 
					<div>
 | 
				
			||||||
	<x-column>
 | 
						<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-notifications/>
 | 
				
			||||||
| 
						 | 
					@ -17,6 +17,13 @@ export default Vue.extend({
 | 
				
			||||||
	components: {
 | 
						components: {
 | 
				
			||||||
		XColumn,
 | 
							XColumn,
 | 
				
			||||||
		XNotifications
 | 
							XNotifications
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						props: {
 | 
				
			||||||
 | 
							id: {
 | 
				
			||||||
 | 
								type: String,
 | 
				
			||||||
 | 
								required: true
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,13 +1,15 @@
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
<div>
 | 
					<div>
 | 
				
			||||||
	<x-column>
 | 
						<x-column :id="column.id">
 | 
				
			||||||
		<span slot="header">
 | 
							<span slot="header">
 | 
				
			||||||
			<template v-if="src == 'home'">%fa:home% %i18n:@home%</template>
 | 
								<template v-if="column.type == 'home'">%fa:home%%i18n:@home%</template>
 | 
				
			||||||
			<template v-if="src == 'local'">%fa:R comments% %i18n:@local%</template>
 | 
								<template v-if="column.type == 'local'">%fa:R comments%%i18n:@local%</template>
 | 
				
			||||||
			<template v-if="src == 'global'">%fa:globe% %i18n:@global%</template>
 | 
								<template v-if="column.type == 'global'">%fa:globe%%i18n:@global%</template>
 | 
				
			||||||
			<template v-if="src == 'list'">%fa:list% {{ list.title }}</template>
 | 
								<template v-if="column.type == 'list'">%fa:list%{{ column.list.title }}</template>
 | 
				
			||||||
		</span>
 | 
							</span>
 | 
				
			||||||
		<x-tl :src="src"/>
 | 
					
 | 
				
			||||||
 | 
							<x-list-tl v-if="column.type == 'list'" :list="column.list"/>
 | 
				
			||||||
 | 
							<x-tl v-else :src="column.type"/>
 | 
				
			||||||
	</x-column>
 | 
						</x-column>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
| 
						 | 
					@ -16,18 +18,20 @@
 | 
				
			||||||
import Vue from 'vue';
 | 
					import Vue from 'vue';
 | 
				
			||||||
import XColumn from './deck.column.vue';
 | 
					import XColumn from './deck.column.vue';
 | 
				
			||||||
import XTl from './deck.tl.vue';
 | 
					import XTl from './deck.tl.vue';
 | 
				
			||||||
 | 
					import XListTl from './deck.list-tl.vue';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default Vue.extend({
 | 
					export default Vue.extend({
 | 
				
			||||||
	components: {
 | 
						components: {
 | 
				
			||||||
		XColumn,
 | 
							XColumn,
 | 
				
			||||||
		XTl
 | 
							XTl,
 | 
				
			||||||
 | 
							XListTl
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	props: {
 | 
						props: {
 | 
				
			||||||
		src: {
 | 
							column: {
 | 
				
			||||||
			type: String,
 | 
								type: Object,
 | 
				
			||||||
			required: false
 | 
								required: true
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	},
 | 
					 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -27,9 +27,7 @@ export default Vue.extend({
 | 
				
			||||||
			moreFetching: false,
 | 
								moreFetching: false,
 | 
				
			||||||
			existMore: false,
 | 
								existMore: false,
 | 
				
			||||||
			connection: null,
 | 
								connection: null,
 | 
				
			||||||
			connectionId: null,
 | 
								connectionId: null
 | 
				
			||||||
			unreadCount: 0,
 | 
					 | 
				
			||||||
			date: null
 | 
					 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -74,17 +72,12 @@ export default Vue.extend({
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	methods: {
 | 
						methods: {
 | 
				
			||||||
		mount(root) {
 | 
					 | 
				
			||||||
			this.$refs.timeline.mount(root);
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		fetch() {
 | 
							fetch() {
 | 
				
			||||||
			this.fetching = true;
 | 
								this.fetching = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			(this.$refs.timeline as any).init(() => new Promise((res, rej) => {
 | 
								(this.$refs.timeline as any).init(() => new Promise((res, rej) => {
 | 
				
			||||||
				(this as any).api(this.endpoint, {
 | 
									(this as any).api(this.endpoint, {
 | 
				
			||||||
					limit: fetchLimit + 1,
 | 
										limit: fetchLimit + 1,
 | 
				
			||||||
					untilDate: this.date ? this.date.getTime() : undefined,
 | 
					 | 
				
			||||||
					includeMyRenotes: this.$store.state.settings.showMyRenotes,
 | 
										includeMyRenotes: this.$store.state.settings.showMyRenotes,
 | 
				
			||||||
					includeRenotedMyNotes: this.$store.state.settings.showRenotedMyNotes
 | 
										includeRenotedMyNotes: this.$store.state.settings.showRenotedMyNotes
 | 
				
			||||||
				}).then(notes => {
 | 
									}).then(notes => {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,12 +2,13 @@
 | 
				
			||||||
<mk-ui :class="$style.root">
 | 
					<mk-ui :class="$style.root">
 | 
				
			||||||
	<div class="qlvquzbjribqcaozciifydkngcwtyzje" :data-darkmode="$store.state.device.darkmode">
 | 
						<div class="qlvquzbjribqcaozciifydkngcwtyzje" :data-darkmode="$store.state.device.darkmode">
 | 
				
			||||||
		<template v-for="column in columns">
 | 
							<template v-for="column in columns">
 | 
				
			||||||
			<x-notifications-column v-if="column.type == 'notifications'" :key="column.id"/>
 | 
								<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" src="home"/>
 | 
								<x-tl-column v-if="column.type == 'home'" :key="column.id" :column="column"/>
 | 
				
			||||||
			<x-tl-column v-if="column.type == 'local'" :key="column.id" src="local"/>
 | 
								<x-tl-column v-if="column.type == 'local'" :key="column.id" :column="column"/>
 | 
				
			||||||
			<x-tl-column v-if="column.type == 'global'" :key="column.id" src="global"/>
 | 
								<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>
 | 
							</template>
 | 
				
			||||||
		<button>%fa:plus%</button>
 | 
							<button ref="add" @click="add">%fa:plus%</button>
 | 
				
			||||||
	</div>
 | 
						</div>
 | 
				
			||||||
</mk-ui>
 | 
					</mk-ui>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
| 
						 | 
					@ -16,6 +17,8 @@
 | 
				
			||||||
import Vue from 'vue';
 | 
					import Vue from 'vue';
 | 
				
			||||||
import XTlColumn from './deck.tl-column.vue';
 | 
					import XTlColumn from './deck.tl-column.vue';
 | 
				
			||||||
import XNotificationsColumn from './deck.notifications-column.vue';
 | 
					import XNotificationsColumn from './deck.notifications-column.vue';
 | 
				
			||||||
 | 
					import Menu from '../../../../common/views/components/menu.vue';
 | 
				
			||||||
 | 
					import MkUserListsWindow from '../../components/user-lists-window.vue';
 | 
				
			||||||
import * as uuid from 'uuid';
 | 
					import * as uuid from 'uuid';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default Vue.extend({
 | 
					export default Vue.extend({
 | 
				
			||||||
| 
						 | 
					@ -55,6 +58,61 @@ export default Vue.extend({
 | 
				
			||||||
				value: deck
 | 
									value: deck
 | 
				
			||||||
			});
 | 
								});
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						methods: {
 | 
				
			||||||
 | 
							add() {
 | 
				
			||||||
 | 
								this.os.new(Menu, {
 | 
				
			||||||
 | 
									source: this.$refs.add,
 | 
				
			||||||
 | 
									compact: true,
 | 
				
			||||||
 | 
									items: [{
 | 
				
			||||||
 | 
										content: '%i18n:@home%',
 | 
				
			||||||
 | 
										onClick: () => {
 | 
				
			||||||
 | 
											this.$store.dispatch('settings/addDeckColumn', {
 | 
				
			||||||
 | 
												id: uuid(),
 | 
				
			||||||
 | 
												type: 'home'
 | 
				
			||||||
 | 
											});
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}, {
 | 
				
			||||||
 | 
										content: '%i18n:@local%',
 | 
				
			||||||
 | 
										onClick: () => {
 | 
				
			||||||
 | 
											this.$store.dispatch('settings/addDeckColumn', {
 | 
				
			||||||
 | 
												id: uuid(),
 | 
				
			||||||
 | 
												type: 'local'
 | 
				
			||||||
 | 
											});
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}, {
 | 
				
			||||||
 | 
										content: '%i18n:@global%',
 | 
				
			||||||
 | 
										onClick: () => {
 | 
				
			||||||
 | 
											this.$store.dispatch('settings/addDeckColumn', {
 | 
				
			||||||
 | 
												id: uuid(),
 | 
				
			||||||
 | 
												type: 'global'
 | 
				
			||||||
 | 
											});
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}, {
 | 
				
			||||||
 | 
										content: '%i18n:@list%',
 | 
				
			||||||
 | 
										onClick: () => {
 | 
				
			||||||
 | 
											const w = (this as any).os.new(MkUserListsWindow);
 | 
				
			||||||
 | 
											w.$once('choosen', list => {
 | 
				
			||||||
 | 
												this.$store.dispatch('settings/addDeckColumn', {
 | 
				
			||||||
 | 
													id: uuid(),
 | 
				
			||||||
 | 
													type: 'list',
 | 
				
			||||||
 | 
													list: list
 | 
				
			||||||
 | 
												});
 | 
				
			||||||
 | 
												w.close();
 | 
				
			||||||
 | 
											});
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}, {
 | 
				
			||||||
 | 
										content: '%i18n:@notifications%',
 | 
				
			||||||
 | 
										onClick: () => {
 | 
				
			||||||
 | 
											this.$store.dispatch('settings/addDeckColumn', {
 | 
				
			||||||
 | 
												id: uuid(),
 | 
				
			||||||
 | 
												type: 'notifications'
 | 
				
			||||||
 | 
											});
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}]
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -73,12 +73,12 @@ export default class MiOS extends EventEmitter {
 | 
				
			||||||
	public app: Vue;
 | 
						public app: Vue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public new(vm, props) {
 | 
						public new(vm, props) {
 | 
				
			||||||
		const w = new vm({
 | 
							const x = new vm({
 | 
				
			||||||
			parent: this.app,
 | 
								parent: this.app,
 | 
				
			||||||
			propsData: props
 | 
								propsData: props
 | 
				
			||||||
		}).$mount();
 | 
							}).$mount();
 | 
				
			||||||
		document.body.appendChild(w.$el);
 | 
							document.body.appendChild(x.$el);
 | 
				
			||||||
		return w;
 | 
							return x;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -152,6 +152,44 @@ export default (os: MiOS) => new Vuex.Store({
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				removeMobileHomeWidget(state, widget) {
 | 
									removeMobileHomeWidget(state, widget) {
 | 
				
			||||||
					state.mobileHome = state.mobileHome.filter(w => w.id != widget.id);
 | 
										state.mobileHome = state.mobileHome.filter(w => w.id != widget.id);
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									addDeckColumn(state, column) {
 | 
				
			||||||
 | 
										if (state.deck.columns == null) state.deck.columns = [];
 | 
				
			||||||
 | 
										state.deck.columns.push(column);
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									removeDeckColumn(state, id) {
 | 
				
			||||||
 | 
										if (state.deck.columns == null) return;
 | 
				
			||||||
 | 
										state.deck.columns = state.deck.columns.filter(c => c.id != 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];
 | 
				
			||||||
 | 
												if (left) {
 | 
				
			||||||
 | 
													state.deck.columns[i - 1] = state.deck.columns[i];
 | 
				
			||||||
 | 
													state.deck.columns[i] = left;
 | 
				
			||||||
 | 
												}
 | 
				
			||||||
 | 
												return true;
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
										});
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									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];
 | 
				
			||||||
 | 
												if (right) {
 | 
				
			||||||
 | 
													state.deck.columns[i + 1] = state.deck.columns[i];
 | 
				
			||||||
 | 
													state.deck.columns[i] = right;
 | 
				
			||||||
 | 
												}
 | 
				
			||||||
 | 
												return true;
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
										});
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -174,6 +212,42 @@ export default (os: MiOS) => new Vuex.Store({
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									addDeckColumn(ctx, column) {
 | 
				
			||||||
 | 
										ctx.commit('addDeckColumn', column);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										os.api('i/update_client_setting', {
 | 
				
			||||||
 | 
											name: 'deck',
 | 
				
			||||||
 | 
											value: ctx.state.deck
 | 
				
			||||||
 | 
										});
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									removeDeckColumn(ctx, id) {
 | 
				
			||||||
 | 
										ctx.commit('removeDeckColumn', id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										os.api('i/update_client_setting', {
 | 
				
			||||||
 | 
											name: 'deck',
 | 
				
			||||||
 | 
											value: ctx.state.deck
 | 
				
			||||||
 | 
										});
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									swapLeftDeckColumn(ctx, id) {
 | 
				
			||||||
 | 
										ctx.commit('swapLeftDeckColumn', id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										os.api('i/update_client_setting', {
 | 
				
			||||||
 | 
											name: 'deck',
 | 
				
			||||||
 | 
											value: ctx.state.deck
 | 
				
			||||||
 | 
										});
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									swapRightDeckColumn(ctx, id) {
 | 
				
			||||||
 | 
										ctx.commit('swapRightDeckColumn', id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										os.api('i/update_client_setting', {
 | 
				
			||||||
 | 
											name: 'deck',
 | 
				
			||||||
 | 
											value: ctx.state.deck
 | 
				
			||||||
 | 
										});
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				addHomeWidget(ctx, widget) {
 | 
									addHomeWidget(ctx, widget) {
 | 
				
			||||||
					ctx.commit('addHomeWidget', widget);
 | 
										ctx.commit('addHomeWidget', widget);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue