You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

220 lines
4.7 KiB

<template>
<view class="tab-page">
<view v-if="loading" class="chat-loading">
<loading :size="50" :mask="false">
<view>消息接收中...</view>
</loading>
</view>
<view class="nav-bar">
<view class="nav-search">
<uni-search-bar radius="100" v-model="searchText" cancelButton="none" placeholder="搜索"></uni-search-bar>
</view>
</view>
<view class="chat-tip" v-if="!loading && chatStore.chats.length==0">
2 years ago
温馨提示您现在还没有任何聊天消息快跟您的好友发起聊天吧~
</view>
<scroll-view class="scroll-bar" v-else scroll-with-animation="true" scroll-y="true">
<view v-for="(chatPos,i) in chatsPos" :key="i">
<chat-item v-if="isShowChat(chatStore.chats[chatPos.idx])" :chat="chatStore.chats[chatPos.idx]"
:active="menu.chatIdx==chatPos.idx" :index="chatPos.idx"
@longpress.native="onShowMenu($event,chatPos.idx)"></chat-item>
</view>
</scroll-view>
2 years ago
<pop-menu v-show="menu.show" :menu-style="menu.style" :items="menu.items" @close="onCloseMenu()"
@select="onSelectMenu"></pop-menu>
</view>
</template>
<script>
export default {
data() {
return {
searchText: "",
menu: {
show: false,
style: "",
chatIdx: -1,
items: [{
key: 'DELETE',
name: '删除该聊天',
icon: 'trash',
color: '#e64e4e'
},
{
key: 'TOP',
name: '置顶该聊天',
icon: 'arrow-up'
}
]
}
}
},
methods: {
onSelectMenu(item) {
switch (item.key) {
case 'DELETE':
2 years ago
this.removeChat(this.menu.chatIdx);
break;
case 'TOP':
this.moveToTop(this.menu.chatIdx);
2 years ago
break;
default:
break;
}
2 years ago
this.menu.show = false;
},
2 years ago
onShowMenu(e, chatIdx) {
this.menu.chatIdx = chatIdx;
uni.getSystemInfo({
success: (res) => {
let touches = e.touches[0];
let style = "";
/* 因 非H5端不兼容 style 属性绑定 Object ,所以拼接字符 */
if (touches.clientY > (res.windowHeight / 2)) {
style = `bottom:${res.windowHeight-touches.clientY}px;`;
} else {
style = `top:${touches.clientY}px;`;
}
if (touches.clientX > (res.windowWidth / 2)) {
style += `right:${res.windowWidth-touches.clientX}px;`;
} else {
style += `left:${touches.clientX}px;`;
}
this.menu.style = style;
this.menu.chatIdx = chatIdx;
//
this.$nextTick(() => {
this.menu.show = true;
});
}
})
},
onCloseMenu() {
this.menu.chatIdx = -1;
this.menu.show = false;
},
removeChat(chatIdx) {
this.$store.commit("removeChat", chatIdx);
},
moveToTop(chatIdx) {
this.$store.commit("moveTop", chatIdx);
},
isShowChat(chat){
if(chat.delete){
return false;
}
return !this.searchText || chat.showName.includes(this.searchText)
},
refreshUnreadBadge() {
if (this.unreadCount > 0) {
uni.setTabBarBadge({
index: 0,
text: this.unreadCount + ""
})
} else {
uni.removeTabBarBadge({
index: 0,
2 years ago
complete: () => {}
})
}
}
},
computed: {
chatsPos() {
// 计算会话的顺序
let chatsPos = [];
let chats = this.chatStore.chats;
chats.forEach((chat, idx) => {
chatsPos.push({
idx: idx,
sendTime: chat.lastSendTime
})
})
chatsPos.sort((chatPos1, chatPos2) => {
return chatPos2.sendTime - chatPos1.sendTime;
});
return chatsPos;
},
chatStore() {
return this.$store.state.chatStore;
},
unreadCount() {
let count = 0;
this.chatStore.chats.forEach(chat => {
if (!chat.delete) {
count += chat.unreadCount;
}
})
return count;
},
loading() {
return this.chatStore.loadingGroupMsg || this.chatStore.loadingPrivateMsg
}
},
2 years ago
watch: {
unreadCount(newCount, oldCount) {
2 years ago
this.refreshUnreadBadge();
}
},
onShow() {
this.refreshUnreadBadge();
}
}
</script>
2 years ago
<style scoped lang="scss">
.tab-page {
position: relative;
border: #dddddd solid 1px;
display: flex;
flex-direction: column;
.nav-bar {
padding: 2rpx 20rpx;
display: flex;
align-items: center;
background-color: white;
border-bottom: 1px solid #ddd;
height: 110rpx;
.nav-search {
flex: 1;
height: 110rpx;
}
}
.chat-tip {
position: absolute;
top: 400rpx;
padding: 50rpx;
line-height: 50rpx;
text-align: left;
color: darkblue;
font-size: 30rpx;
}
.chat-loading {
display: block;
width: 100%;
height: 100rpx;
background: white;
position: relative;
color: blue;
.loading-box {
position: relative;
}
}
.scroll-bar {
flex: 1;
height: 100%;
}
}
</style>