<template>
	<view class="chat-box">
		<view class="chat-tips" v-if="postData.loading">
			{{postData.loadText}}
		</view>
		<view class="chat-list">
			<view :id="`msg-${item.time}`" v-for="(item,index) in chatList" :key="index">
				<view class="chat-item" :class="item.from == `workark${nowUserId}` ? 'push':'pull' ">
					<image :src="item.fromUserInfo.avatarUrl" mode="aspectFill" class="avatar"></image>
					<view class="content-box">
						<view class="content" v-if="item.type === 'text'">{{item.body.text}}</view>
						<image :src="item.body.thumbnailUrl" mode="aspectFill"
							@tap="previewImage(item.body.originalUrl)" :class="[returnImageClass(item.body)]" v-else>
						</image>
					</view>
					<text class="date">
						{{$uv.timeFormat(item.time,'yyyy-mm-dd hh:MM')}}
					</text>
				</view>
			</view>
			<uv-safe-bottom></uv-safe-bottom>
		</view>
		<view class="chat-submit">
			<input type="text" class="message-content" v-model="message" placeholder="请输入聊天内容"
				placeholder-class="message-placeholder" :cursor-spacing="6" />
			<view class="send-image send-button" @tap="sendImage">
				<uv-icon name="photo-fill" color="#8c8c8c" size="48"></uv-icon>
			</view>
			<view class="send-submit send-button" @tap="send">
				<uv-icon name="checkbox-mark" color="#fff" size="48"></uv-icon>
			</view>
		</view>
	</view>
</template>

<script>
	import {
		YeIMUniSDK,
		YeIMUniSDKDefines
	} from '@/uni_modules/wzJun1-YeIM-Uni-SDK/js_sdk/yeim-uni-sdk.min.js'
	export default {
		data() {
			return {
				message: '',
				chatList: [],
				postData: {
					rows: 10, //每页数量
					page: 1, //页码
					flag: true, // 请求开关
					loading: true, // 加载中
					loadText: '正在获取消息...'
				},
				nextMessageId: '',
				nowUserId: ''
			}
		},
		onUnload() {
			YeIMUniSDK.getInstance().removeEventListener(YeIMUniSDKDefines.EVENT.MESSAGE_RECEIVED, this.onMessage);
		},
		onLoad(body) {
			YeIMUniSDK.getInstance().addEventListener(YeIMUniSDKDefines.EVENT.MESSAGE_RECEIVED, this.onMessage);
			uni.setNavigationBarTitle({
				title: body.userName
			});
			this.nowUserId = this.$store.getters.user.userId;
			this.userId = body.userId;
			this.getHistoryMsg();
		},
		onPageScroll(e) {
			if (e.scrollTop < 5) {
				this.getHistoryMsg();
			}
		},
		methods: {
			returnImageClass(item) {
				let w = item.thumbnailWidth,
					h = item.thumbnailHeight;
				let str = ''
				if (w > h) str = 'image-width';
				if (w == h) str = 'image-width-height';
				if (w < h) str = 'image-height';
				return str + ' image-box';
			},
			onMessage(e) {
				let message = e;
				if (this.userId != message.conversationId) return;
				this.insertMessage(message);
				this.$chat.clearConversationUnread(this.userId);
			},
			insertMessage(message) {
				try {
					this.chatList.push(message);
					setTimeout(() => {
						uni.pageScrollTo({
							scrollTop: 99999999, // -30 为多显示出大半个消息的高度，示意上面还有信息。
							duration: 0
						});
					}, 200)
				} catch (e) {
					console.log(e)
				}
			},
			getHistoryMsg() {
				if (!this.postData.flag || this.nextMessageId === 'null') {
					return; //
				}
				// 此处用到 ES7 的 async/await 知识，为使代码更加优美。不懂的请自行学习。
				let get = async () => {
					this.toggleTips();
					this.postData.flag = false;
					let data = await this.joinHistoryMsg();
					// 获取待滚动元素选择器，解决插入数据后，滚动条定位时使用
					let selector = '';
					if (this.postData.page > 1) {
						// 非第一页，则取历史消息数据的第一条信息元素
						selector = `#msg-${this.chatList[0].time}`;
					} else {
						if (data.length > 0) {
							// 第一页，则取当前消息数据的最后一条信息元素
							selector = `#msg-${data[data.length-1].time}`;
						}
					}
					// 将获取到的消息数据合并到消息数组中
					this.chatList = [...data, ...this.chatList];
					// 数据挂载后执行，不懂的请自行阅读 Vue.js 文档对 Vue.nextTick 函数说明。
					this.$nextTick(() => {
						// 设置当前滚动的位置
						this.setPageScrollTo(selector);
						this.toggleTips(true);
						if (data.length < this.postData.rows) {
							// 当前消息数据条数小于请求要求条数时，则无更多消息，不再允许请求。
							// 可在此处编写无更多消息数据时的逻辑
							this.postData.flag = true;
						} else {
							this.postData.page++;
							// 延迟 200ms ，以保证设置窗口滚动已完成
							setTimeout(() => {
								this.postData.flag = true;
							}, 200)
						}

					})
				}
				get();
			},
			// 设置页面滚动位置
			setPageScrollTo(selector) {
				if (!selector) return;
				let view = uni.createSelectorQuery().in(this).select(selector);
				view.boundingClientRect((res) => {
					uni.pageScrollTo({
						scrollTop: res.top - 30, // -30 为多显示出大半个消息的高度，示意上面还有信息。
						duration: 0
					});
				}).exec();
			},
			toggleTips(flag) {
				if (flag) {
					this.postData.loadText = '消息获取成功';
					setTimeout(() => {
						this.postData.loading = false;
					}, 300);
				} else {
					this.postData.loading = true;
					this.postData.loadText = '正在获取消息...';
				}
			},
			joinHistoryMsg() {
				return new Promise((done, fail) => {
					this.$chat.getHistoryMessageList(this.nextMessageId, this.userId, res => {
						this.nextMessageId = res.data.nextMessageId || 'null';
						done(!res.data ? [] : res.data.list);
					}, () => {
						done([]);
					});
				})
			},
			previewImage(url) {
				// 预览图片
				uni.previewImage({
					urls: [url]
				});
			},
			sendImage() {
				this.$chat.sendImage(this.userId, this.sendSuccess);
			},
			// 发送信息
			send() {
				if (!this.message) return this.$toast('内容不能为空');
				uni.showLoading();
				this.$chat.sendText(this.userId, this.message, this.sendSuccess);
			},
			sendSuccess(res) {
				this.chatList.push(res.data);
				this.message = '';
				uni.hideLoading();
				setTimeout(() => {
					uni.pageScrollTo({
						scrollTop: 99999999, // -30 为多显示出大半个消息的高度，示意上面还有信息。
						duration: 0
					});
				}, 200)
			}
		},
	}
</script>

<style lang="scss">
	.chat-box {
		.chat-tips {
			position: fixed;
			left: 0;
			top: 0;
			width: 100%;
			z-index: 9;
			background-color: $uv-primary;
			height: 72rpx;
			line-height: 72rpx;
			color: #fff;
			text-align: center;
			opacity: 0.9;
		}

		.chat-list {
			width: 100%;
			height: auto;
			padding-bottom: 120rpx;
			box-sizing: content-box;

			.chat-item {
				display: flex;
				padding: 20rpx;
				align-items: flex-start;
				align-content: flex-start;
				position: relative;

				.date {
					position: absolute;
					bottom: -5rpx;
					font-size: 20rpx;
					color: $uv-content-color;
				}

				.avatar {
					width: 80rpx;
					height: 80rpx;
					border-radius: 50%;
					border: #fff solid 1px;
				}

				.content-box {
					flex: 1;
					width: 0;
					display: flex;
				}

				.image-box {
					border-radius: 16rpx;
					padding-bottom: 4rpx;
				}

				.image-width {
					width: 280rpx;
					height: 200rpx;
				}

				.image-height {
					width: 200rpx;
					height: 280rpx;
				}

				.image-width-height {
					width: 200rpx;
					height: 200rpx;
				}

				.content {
					padding: 20rpx 30rpx;
					border-radius: 16rpx;
					word-break: break-all;
					line-height: 42rpx;
					position: relative;
					font-weight: 300;
				}

				/* 收到的消息 */
				&.pull {
					.content-box {
						margin-right: 100rpx;
					}

					.image-box {
						margin-left: 20rpx;
					}

					.content {
						margin-left: 20rpx;
						background-color: #fff;
					}

					.date {
						left: 124rpx;
					}
				}

				/* 发出的消息 */
				&.push {
					/* 主轴为水平方向，起点在右端。使不修改DOM结构，也能改变元素排列顺序 */
					flex-direction: row-reverse;

					.content-box {
						flex-direction: row-reverse;
						margin-left: 100rpx;
					}

					.image-box {
						margin-right: 20rpx;
					}

					.content {
						margin-right: 20rpx;
						background-color: $uv-primary;
						color: #fff;
						box-shadow: 0px 1px 12px rgba(3, 3, 3, 0.08);
					}

					.date {
						right: 124rpx;
					}
				}
			}
		}

		.chat-submit {
			position: fixed;
			left: 0;
			width: 100%;
			bottom: 0;
			height: 100rpx;
			z-index: 2;
			background-color: #fff;
			box-shadow: 0px 2px 10px rgba(3, 3, 3, 0.1);
			/* 兼容iPhoneX */
			padding-bottom: 0;
			padding-bottom: constant(safe-area-inset-bottom);
			padding-bottom: env(safe-area-inset-bottom);
			display: flex;
			align-items: center;

			.message-content {
				flex: 1;
				margin: 0 30rpx;
				border: 1px solid $uv-border-color;
				border-radius: 68rpx;
				height: 68rpx;
				padding: 0 20rpx;
			}

			.message-placeholder {
				color: #8c8c8c;
				font-weight: 300;
			}

			.send-button {
				width: 68rpx;
				height: 68rpx;
				border-radius: 50%;
				display: flex;
				align-items: center;
				justify-content: center;

				&.send-image {
					border: 1px solid $uv-border-color;
					margin-right: 20rpx;
				}

				&.send-submit {
					background: $uv-primary;
					margin-right: 30rpx;
				}
			}
		}
	}
</style>