uni-app 162初始化会话列表功能

Posted 2019ab

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了uni-app 162初始化会话列表功能相关的知识,希望对你有一定的参考价值。

/pages/chat/chat/chat.vue

<template>
	<view>

		<!-- 导航栏 -->
		<free-nav-bar :title="detail.name" :noreadnum="totalNoreadnum" showBack>
			<free-icon-button slot="right" @click="openChatSet"><text class="iconfont font-lg">&#xe6fd;</text>
			</free-icon-button>
		</free-nav-bar>

		<!-- 聊天内容区域 -->
		<scroll-view scroll-y class="bg-light position-fixed left-0 right-0 px-3"
			style="bottom: 105rpx;box-sizing: border-box;" :style="chatBodyBottom" :show-scrollbar="false"
			:scroll-into-view="scrollIntoView" :scroll-with-animation="true" @click="clickPage">

			<!-- 聊天信息列表组件 -->
			<view v-for="(item,index) in list" :key="index" :id="'chatItem_'+index">
				<free-chat-item :item="item" :index="index" ref="chatItem"
					:pretime=" index > 0 ? list[index-1].create_time : 0" @long="long" @preview="previewImage"
					:shownickname="currentChatItem.shownickname"></free-chat-item>
			</view>

		</scroll-view>

		<!-- #ifdef APP-PLUS-NVUE -->
		<div v-if="mode === 'action' || mode === 'emoticon'" class="position-fixed top-0 right-0 left-0"
			:style="'bottom:'+maskBottom+'px;'" @click="clickPage"></div>
		<!-- #endif -->

		<!-- 底部输入框 -->
		<view class="position-fixed left-0 right-0 border-top flex align-center"
			style="background-color: #F7F7F6;height: 105rpx;" :style="'bottom:'+KeyboardHeight+'px;'">
			<free-icon-button v-if="mode === 'audio'" @click="changeVoiceOrText"><text
					class="iconfont font-lg">&#xe607;</text></free-icon-button>
			<free-icon-button v-else @click="changeVoiceOrText"><text class="iconfont font-lg">&#xe606;</text>
			</free-icon-button>
			<view class="flex-1">
				<view v-if="mode === 'audio'" class="rounded flex align-center justify-center" style="height: 80rpx;"
					:class="isRecording?'bg-hover-light':'bg-white'" @touchstart="voiceTouchStart"
					@touchend="voiceTouchEnd" @touchcancel="voiceTouchCancel" @touchmove="voiceTouchMove">
					<text class="font">isRecording ? '松开 结束':'按住 说话'</text>
				</view>

				<textarea v-else fixed class="bg-white rounded p-2 font-md" style="height: 50rpx;max-width: 450rpx;"
					:adjust-position="false" v-model="text" @focus="mode = 'text'" />
			</view>
			<!-- 表情 -->
			<free-icon-button @click="openActionOrEmoticon('emoticon')"><text class="iconfont font-lg">&#xe605;</text>
			</free-icon-button>
			<template v-if="text.length === 0">
				<!-- 扩展菜单 -->
				<free-icon-button @click="openActionOrEmoticon('action')"><text class="iconfont font-lg">&#xe603;</text>
				</free-icon-button>
			</template>
			<view v-else class="flex-shrink">
				<!-- 发送按钮 -->
				<free-main-button name="发送" @click="send('text')"></free-main-button>
			</view>

		</view>

		<!-- 扩展菜单 -->
		<free-popup ref="action" bottom transformOrigin="center bottom" @hide="KeyboardHeight = 0" :mask="false">
			<view style="height: 580rpx;" class="border-top border-light-secondary bg-light">
				<swiper :indicator-dots="emoticonOrActionList.length > 1" style="height: 510rpx;">
					<swiper-item class="row" v-for="(item,index) in emoticonOrActionList" :key="index">
						<view class="col-3 flex flex-column align-center justify-center" style="height: 255rpx;"
							v-for="(item2,index2) in item" :key="index2" @click="actionEvent(item2)">
							<image :src="item2.icon" mode="widthFix" style="width: 100rpx;height: 100rpx;"></image>
							<text class="font-sm text-muted mt-2">item2.name</text>
						</view>
					</swiper-item>
				</swiper>
			</view>
		</free-popup>


		<!-- 弹出层 -->
		<free-popup ref="extend" :bodyWidth="240" :bodyHeight="450" :tabbarHeight="105">
			<view class="flex flex-column" style="width: 240rpx;" :style="getMenusStyle">
				<view class="flex-1 flex align-center" hover-class="bg-light" v-for="(item,index) in menusList"
					:key="index" @click="clickEvent(item.event)">
					<text class="font-md pl-3">item.name</text>
				</view>
			</view>
		</free-popup>


		<!-- 录音提示 -->
		<view v-if="isRecording" class="position-fixed top-0 left-0 right-0 flex align-center justify-center"
			style="bottom: 105rpx;">
			<view style="width: 360rpx;height: 360rpx;background-color: rgba(0,0,0,0.5);"
				class="rounded flex flex-column align-center justify-center">
				<image src="/static/images/audio/audio/recording.gif" style="width: 150rpx;height: 150rpx;"></image>
				<text class="font text-white mt-3">unRecord ? '松开手指,取消发送':'手指上滑,取消发送'</text>
			</view>
		</view>

	</view>
</template>

<script>
	// #ifdef APP-PLUS-NVUE
	const dom = weex.requireModule('dom')
	// #endif

	import freeNavBar from "@/components/free-ui/free-nav-bar.vue"
	import freeIconButton from "@/components/free-ui/free-icon-button.vue"
	import freeChatItem from '@/components/free-ui/free-chat-item.vue';
	import freePopup from "@/components/free-ui/free-popup.vue"
	import freeMainButton from '@/components/free-ui/free-main-button.vue';


	import 
		mapState,
		mapMutations
	 from 'vuex'

	import auth from '@/common/mixin/auth.js';
	import $U from '@/common/free-lib/util.js';
	import $H from '@/common/free-lib/request.js';
	import $C from '@/common/free-lib/config.js';
	export default 
		mixins: [auth],
		components: 
			freeNavBar,
			freeIconButton,
			freeChatItem,
			freePopup,
			freeMainButton
		,
		data() 
			return 
				scrollIntoView: "",
				// 模式 text输入文字,emoticon表情,action操作,audio音频
				mode: "text",
				// 扩展菜单列表
				actionList: [
					[
						name: "相册",
						icon: "/static/images/extends/pic.png",
						event: "uploadImage"
					, 
						name: "拍摄",
						icon: "/static/images/extends/video.png",
						event: "uploadVideo"
					, 
						name: "收藏",
						icon: "/static/images/extends/shoucan.png",
						event: "openFava"
					, 
						name: "名片",
						icon: "/static/images/extends/man.png",
						event: "sendCard"
					, 
						name: "语音通话",
						icon: "/static/images/extends/phone.png",
						event: ""
					, 
						name: "位置",
						icon: "/static/images/extends/path.png",
						event: ""
					]
				],
				emoticonList: [],
				// 键盘高度
				KeyboardHeight: 0,
				menusList: [],
				navBarHeight: 0,
				list: [],
				// 当前操作的气泡索引
				propIndex: -1,
				// 输入文字
				text: "",

				// 音频录制状态
				isRecording: false,
				RecordingStartY: 0,
				// 取消录音
				unRecord: false,

				detail: 
					id: 0,
					name: "",
					avatar: "",
					chat_type: "user"
				
			
		,
		mounted() 
			var statusBarHeight = 0
			// #ifdef APP-PLUS-NVUE
			statusBarHeight = plus.navigator.getStatusbarHeight()
			// #endif
			this.navBarHeight = statusBarHeight + uni.upx2px(90)

			// 监听键盘高度变化
			uni.onKeyboardHeightChange(res => 
				if (this.mode !== 'action' && this.mode !== 'emoticon') 
					this.KeyboardHeight = res.height
				
				if (this.KeyboardHeight > 0) 
					this.pageToBottom()
				
			)


			// 注册发送音频事件
			this.regSendVoiceEvent((url) => 
				if (!this.unRecord) 
					this.send('audio', url, 
						time: this.RecordTime
					)
				
			)

			this.pageToBottom()
		,
		computed: 
			...mapState(
				chatList: state => state.user.chatList,
				RECORD: state => state.audio.RECORD,
				RecordTime: state => state.audio.RecordTime,
				chat: state => state.user.chat,
				totalNoreadnum: state => state.user.totalNoreadnum,
				user: state => state.user.user
			),
			// 当前会话配置信息
			currentChatItem() 
				let index = this.chatList.findIndex(item => item.id === this.detail.id && item.chat_type === this.detail
					.chat_type)
				if (index !== -1) 
					return this.chatList[index]
				
				return 
			,
			// 获取蒙版的位置
			maskBottom() 
				return this.KeyboardHeight + uni.upx2px(105)
			,
			// 动态获取菜单高度
			getMenusHeight() 
				let H = 100
				return this.menusList.length * H
			,
			// 获取菜单的样式
			getMenusStyle() 
				return `height: $this.getMenusHeightrpx;`
			,
			// 判断是否操作本人信息
			isdoSelf() 
				// 获取本人id(假设拿到了)
				let id = 1
				let user_id = this.propIndex > -1 ? this.list[this.propIndex].user_id : 0
				return user_id === id
			,
			// 聊天区域bottom
			chatBodyBottom() 
				return `bottom:$uni.upx2px(105) + this.KeyboardHeightpx;top:$this.navBarHeightpx;`
			,
			// 获取操作或者表情列表
			emoticonOrActionList() 
				return (this.mode === 'emoticon' || this.mode === 'action') ? this[this.mode + 'List'] : []
			,
			// 所有信息的图片地址
			imageList() 
				let arr = []
				this.list.forEach((item) => 
					if (item.type === 'emoticon' || item.type === 'image') 
						arr.push(item.data)
					
				)
				return arr
			
		,
		watch: 
			mode(newValue, oldValue) 
				if (newValue !== 'action' && newValue !== 'emoticon') 
					this.$refs.action.hide()
				
				if (newValue !== 'text') 
					uni.hideKeyboard()
				
			
		,
		onLoad(e) 
			if (!e.params) 
				return this.backToast()
			
			this.detail = JSON.parse(decodeURIComponent(e.params))
			console.log(this.detail);
			// 初始化
			this.__init()
			// 创建聊天对象
			this.chat.createChatObject(this.detail)
			// 获取历史记录
			this.list = this.chat.getChatDetail()
			// 监听接收聊天信息
			uni.$on('onMessage', this.onMessage)

			uni.$on('updateHistory', this.updateHistory)

			// 监听发送收藏和名片
			uni.$on('sendItem', this.onSendItem)
		,
		destroyed() 
			// 销毁聊天对象
			this.chat.destoryChatObject()
			// 销毁监听接收聊天消息
			uni.$off('onMessage', this.onMessage)

			uni.$off('updateHistory', this.updateHistory)

			uni.$off('sendItem', this.onSendItem)
		,
		methods: 
			...mapMutations(['regSendVoiceEvent']),
			onSendItem(e) 
				if (e.sendType === 'fava' || e.sendType === 'card') 
					this.send(euni-app 76聊天类封装-更新会话列表

uni-app 78渲染和监听聊天会话列表

uni-app.03.初始化picker下拉列表的默认值

uni-app 105删除指定会话功能

uni-app 81聊天类封装(十五)-读取会话功能

uni-app 实现数据列表(右带默认箭头)的功能(点击item 背景色改变)