<template>
	<view class="slide-list">
		<view class="slide-list-item" @touchstart="touchStart" @touchend="touchEnd" @touchmove="touchMove" :style="{transform}">
			<slot></slot>
		</view>
		<view class="group-btn">
			<view class="btn-div" v-for="(btn, key) in button" :key="key" @click.stop="btnClick(btn,key)" :style="{background: btn.background}">
				<text class="btn-title">{{btn.title}}</text>
			</view>
		</view>
	</view>
</template>

<script>
	import handler from './slideHandler.js'
	/**
	 * m-slide-list 滑动操作列表
	 * @description 滑动操作列表组件
	 * @tutorial https://ext.dcloud.net.cn/plugin?id=209
	 * @property {Array} list 数据源，格式为：[{title: 'xxx', image:'xxx', surname: 'xxx',detail:'xxx', rightDetail: 'xxx', slide_x: 0},{title: 'xxx', image:'xxx', surname: 'xxx',detail:'xxx', rightDetail: 'xxx', slide_x: 0}]
	 * @property {Array} button 按钮数据源，格式为：[{title: 'xxx', background:'xxx'},{title: 'xxx', background:'xxx'}]
	 * @property {Boolean} border 边框
	 */
	export default {
		name: 'mark-slide-list',
		props: {
			button: { //按钮数据list
				type: Array,
				default () {
					return [];
				}
			}
		},
		computed: {
			windowWidth() {
				return uni.getSystemInfoSync().windowWidth;
			},
			transform() {
				return `translate3d(${ this.slide_x }px, 0, 0)`
			}
		},
		data() {
			return {
				key: null,
				moving: false,
				btnState: 'hide',
				hideLimit: 0,
				showLimit: 0,
				btnWidth: 0,
				slide_x: 0,
				handler: null
			};
		},
		mounted() {
			this.$emit('controller-reg', {
				instance:{
					show: this.show,
					hide: this.hide
				},
				cb: (key) => {
					this.key = key
				}
			})
			const cb = res => {
				this.btnWidth = res[0].width * -1;
				this.showLimit = res[0].width / 3;
				this.hideLimit = res[0].width / 3;
			}
			// 按钮宽度
			uni.createSelectorQuery().in(this).select('.group-btn').boundingClientRect().exec(cb);
		},
		methods: {
			btnClick(btn, key) {
				this.$emit(btn.clickName, {
					btn,
					key
				})
			},
			setSlideX(offset) {
				const val = offset + this.slide_x
				if (val < 0 && val >= this.btnWidth) {
					this.slide_x = val
				} else if (val > 0) {
					this.slide_x = 0
				}
			},
			// 滑动开始
			touchStart(e) {
				this.$emit('controller-moving', this.key)
				this.moving = true
				this.handler = new handler(e.timeStamp, e.touches[0].pageX, e.touches[0].pageY)
			},
			// 滑动中
			touchMove(e) {
				const slide_x = this.handler.move(e.touches[0])
				this.setSlideX(slide_x)
			},
			// 滑动结束
			touchEnd(e) {
				this.moving = false
				const endTime = e.timeStamp,
					endY = e.changedTouches[0].pageY,
					endX = e.changedTouches[0].pageX;
				const x_end_distance = this.startX - this.lastX;
				const end = this.handler.endMove(endTime, endX, endY)
				if (end.invalid) {} else if ((end.quick && end.dir === 'l') || (end.dir === 'l' && end.move > this.showLimit)) {
					this.show()
				} else if ((end.quick && end.dir === 'r') || (end.dir === 'r' && end.move > this.hideLimit)) {
					this.hide()
				} else {
					this.recover()
				}
				this.handler = null
			},
			// 点击回复原状
			recover() {
				if (this.btnState === 'show') {
					this.show()
				} else if (this.btnState === 'hide') {
					this.hide()
				}
			},
			show() {
				this.btnState = 'show'
				this.slide_x = this.btnWidth;
				this.$emit('controller-opened', this.key)
			},
			hide() {
				this.btnState = 'hide'
				this.slide_x = 0;
				this.$emit('controller-closed', this.key)
			},
		}
	};
</script>

<style lang="scss" scoped>
	.slide-list {
		position: relative;
		width: 100%;

		.slide-list-item {
			width: 100%;
			overflow: hidden;
			position: relative;
			z-index: 2;
			transition: all 100ms;
			transition-timing-function: ease-out;
		}

		.group-btn {
			position: absolute;
			top: 0;
			right: 0;
			height: 100%;
			min-width: 100rpx;
			align-items: center;
			z-index: 1;
			display: flex;
			flex-direction: row;

			.btn-div {
				height: 100%;
				color: #fff;
				text-align: center;
				padding: 0 50rpx;
				font-size: 34rpx;
				display: table;

				.btn-title {
					display: table-cell;
					vertical-align: middle;
				}
			}

			.top {
				background-color: #c4c7cd;
			}

			.removeM {
				background-color: #ff3b32;
			}
		}

	}
</style>
