|
|
<template>
|
|
|
<div class="conversation-wrapper">
|
|
|
<!-- 页面初始化的过程中,sessionList编译到小程序和h5出现sessionList为undefined的情况,即使给了默认值为空数组,故在此处进行判断 -->
|
|
|
<div class="conversation-list-wrapper" v-if="conversationList && conversationList.length > 0">
|
|
|
<!-- 此处的key如果用session.id,会在ios上渲染存在问题,会出现会话列表显示undefined -->
|
|
|
<div v-for="(conversation, index) in conversationList" :key="conversation.renderKey">
|
|
|
<ConversationItem :key="conversation.renderKey" :loading="loading" :showMoreActions="currentMoveSessionId === conversation.conversationId" :conversation="conversation" @delete="handleSessionItemDeleteClick" :heihei="'mmp'+index" @stickyToTop="handleSessionItemStickTopChange" @click="handleSessionItemClick" @leftSlide="handleSessionItemLeftSlide" />
|
|
|
</div>
|
|
|
</div>
|
|
|
<div style="height: 48px; background-color: #ededed" v-if="conversationList && conversationList.length > 0"></div>
|
|
|
<div v-if="conversationList.length == 0" style='padding-top: 130px;background-color: #ededed;'>
|
|
|
<g-empty text="暂无会话" style="margin-top: 0px" />
|
|
|
</div>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script lang="ts" setup>
|
|
|
import { onUnmounted, ref, defineExpose } from "../../../utils/transformVue";
|
|
|
import { autorun } from "mobx";
|
|
|
import { onHide } from "@dcloudio/uni-app";
|
|
|
import Icon from "../../../components/Icon.vue";
|
|
|
import NetworkAlert from "../../../components/NetworkAlert.vue";
|
|
|
import Empty from "../../../components/Empty.vue";
|
|
|
import ConversationItem from "./conversation-item.vue";
|
|
|
import { setContactTabUnread, setTabUnread } from "../../../utils/msg";
|
|
|
import { t } from "../../../utils/i18n";
|
|
|
import { customNavigateTo } from "../../../utils/customNavigate";
|
|
|
import { deepClone } from "../../../utils";
|
|
|
import { V2NIMConversation } from "nim-web-sdk-ng/dist/v2/NIM_UNIAPP_SDK/V2NIMConversationService";
|
|
|
const corpUserFlag = ref(uni.getStorageSync("apply-userinfo").corpUserFlag);
|
|
|
|
|
|
const conversationList = ref<V2NIMConversation[]>([]);
|
|
|
defineExpose({
|
|
|
conversationList,
|
|
|
});
|
|
|
const addDropdownVisible = ref(false);
|
|
|
const loading = ref(false);
|
|
|
|
|
|
const currentMoveSessionId = ref("");
|
|
|
|
|
|
let buttonClass = "button-box";
|
|
|
// #ifdef MP
|
|
|
buttonClass = "button-box-mp";
|
|
|
// #endif
|
|
|
|
|
|
const handleSessionItemLeftSlide = (conversation: V2NIMConversation | null) => {
|
|
|
// 微信小程序点击也会触发左滑事件,但此时 conversation 为 null
|
|
|
if (conversation) {
|
|
|
currentMoveSessionId.value = conversation.conversationId;
|
|
|
} else {
|
|
|
currentMoveSessionId.value = "";
|
|
|
}
|
|
|
};
|
|
|
|
|
|
let flag = false;
|
|
|
// 点击会话
|
|
|
const handleSessionItemClick = async (conversation: V2NIMConversation) => {
|
|
|
if (flag) return;
|
|
|
currentMoveSessionId.value = "";
|
|
|
try {
|
|
|
flag = true;
|
|
|
|
|
|
await uni.$UIKitStore.uiStore.selectConversation(conversation.conversationId);
|
|
|
customNavigateTo({
|
|
|
url: "/pages/Chat/index",
|
|
|
});
|
|
|
} catch {
|
|
|
uni.showToast({
|
|
|
title: t("selectSessionFailText"),
|
|
|
icon: "error",
|
|
|
});
|
|
|
} finally {
|
|
|
flag = false;
|
|
|
}
|
|
|
};
|
|
|
// 删除会话
|
|
|
const handleSessionItemDeleteClick = async (conversation: V2NIMConversation) => {
|
|
|
try {
|
|
|
await uni.$UIKitStore.conversationStore.deleteConversationActive(conversation.conversationId);
|
|
|
} catch {
|
|
|
uni.showToast({
|
|
|
title: t("deleteSessionFailText"),
|
|
|
icon: "error",
|
|
|
});
|
|
|
}
|
|
|
};
|
|
|
// 置顶会话
|
|
|
const handleSessionItemStickTopChange = async (conversation: V2NIMConversation) => {
|
|
|
if (conversation.stickTop) {
|
|
|
try {
|
|
|
await uni.$UIKitStore.conversationStore.stickTopConversationActive(conversation.conversationId, false);
|
|
|
} catch {
|
|
|
uni.showToast({
|
|
|
title: t("deleteStickTopFailText"),
|
|
|
icon: "error",
|
|
|
});
|
|
|
}
|
|
|
} else {
|
|
|
try {
|
|
|
await uni.$UIKitStore.conversationStore.stickTopConversationActive(conversation.conversationId, true);
|
|
|
} catch {
|
|
|
uni.showToast({
|
|
|
title: t("addStickTopFailText"),
|
|
|
icon: "error",
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
};
|
|
|
|
|
|
const showAddDropdown = () => {
|
|
|
addDropdownVisible.value = true;
|
|
|
};
|
|
|
|
|
|
const hideAddDropdown = () => {
|
|
|
addDropdownVisible.value = false;
|
|
|
};
|
|
|
|
|
|
const onDropdownClick = (urlType: "addFriend" | "createGroup") => {
|
|
|
const urlMap = {
|
|
|
// 添加好友
|
|
|
addFriend: "/pages/Friend/add-friend/index",
|
|
|
// 创建群聊
|
|
|
createGroup: "/pages/Group/group-create/index",
|
|
|
};
|
|
|
addDropdownVisible.value = false;
|
|
|
customNavigateTo({
|
|
|
url: urlMap[urlType],
|
|
|
});
|
|
|
};
|
|
|
|
|
|
const jumpToSearch = () => {
|
|
|
customNavigateTo({
|
|
|
url: "/pages/Conversation/conversation-search/index",
|
|
|
});
|
|
|
};
|
|
|
|
|
|
onHide(() => {
|
|
|
addDropdownVisible.value = false;
|
|
|
});
|
|
|
|
|
|
const conversationListWatch = autorun(() => {
|
|
|
const conversations = deepClone(uni.$UIKitStore?.uiStore?.conversations) || [];
|
|
|
|
|
|
// 添加 renderKey
|
|
|
const conversationsWithKey = conversations.map((conversation: V2NIMConversation) => ({
|
|
|
...conversation,
|
|
|
renderKey: conversation.conversationId,
|
|
|
}));
|
|
|
|
|
|
// 分割为置顶和非置顶
|
|
|
const stickyList = conversationsWithKey.filter((conv: V2NIMConversation) => conv.stickTop);
|
|
|
const normalList = conversationsWithKey.filter((conv: V2NIMConversation) => !conv.stickTop);
|
|
|
|
|
|
// console.log("stickyList", stickyList);
|
|
|
// console.log("normalList", normalList);
|
|
|
|
|
|
|
|
|
|
|
|
// 排序函数
|
|
|
const sortStickyList = (list: V2NIMConversation[]) =>
|
|
|
list.sort((a, b) => new Date(b.updateTime).getTime() - new Date(a.updateTime).getTime());
|
|
|
|
|
|
const sortNormalList = (list: V2NIMConversation[]) =>
|
|
|
list.sort((a, b) => new Date(b.lastMessage?.messageRefer.createTime || b.updateTime).getTime() - new Date(a.lastMessage?.messageRefer.createTime || a.updateTime).getTime());
|
|
|
|
|
|
// 排序并合并
|
|
|
conversationList.value = [...sortStickyList(stickyList), ...sortNormalList(normalList)];
|
|
|
|
|
|
setTimeout(() => {
|
|
|
loading.value = false;
|
|
|
}, 2000);
|
|
|
|
|
|
console.log("conversationListWatch", conversationList.value);
|
|
|
setTabUnread();
|
|
|
});
|
|
|
// const conversationListWatch = autorun(() => {
|
|
|
// const conversations = deepClone(uni.$UIKitStore?.uiStore?.conversations) || [];
|
|
|
|
|
|
// // 添加 renderKey
|
|
|
// const conversationsWithKey = conversations.map((conversation: V2NIMConversation) => ({
|
|
|
// ...conversation,
|
|
|
// renderKey: conversation.conversationId,
|
|
|
// }));
|
|
|
|
|
|
// // 分割为置顶和非置顶
|
|
|
// const stickyList = conversationsWithKey.filter((conv: V2NIMConversation) => conv.stickTop);
|
|
|
// const normalList = conversationsWithKey.filter((conv: V2NIMConversation) => !conv.stickTop);
|
|
|
|
|
|
|
|
|
|
|
|
// // 按 updateTime 倒序排序
|
|
|
// const sortList = (list: V2NIMConversation[]) => list.sort((a: V2NIMConversation, b: V2NIMConversation) => new Date(b.updateTime).getTime() - new Date(a.updateTime).getTime()); //打印list
|
|
|
// // 排序并合并
|
|
|
// conversationList.value = [...sortList(stickyList), ...sortList(normalList)];
|
|
|
// setTimeout(() => {
|
|
|
// loading.value = false;
|
|
|
// }, 2000);
|
|
|
// console.log("conversationListWatch", conversationList.value);
|
|
|
// setTabUnread();
|
|
|
// });
|
|
|
|
|
|
const getTotalUnreadMsgsCountWatch = autorun(() => {
|
|
|
// 为了监听会触发得留着这个 console
|
|
|
console.log(
|
|
|
"unreadSysMsgCount:",
|
|
|
|
|
|
uni.$UIKitStore?.sysMsgStore?.getTotalUnreadMsgsCount()
|
|
|
);
|
|
|
setContactTabUnread();
|
|
|
});
|
|
|
onUnmounted(() => {
|
|
|
conversationListWatch();
|
|
|
getTotalUnreadMsgsCountWatch();
|
|
|
});
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
|
|
|
|
|
.conversation-wrapper {
|
|
|
overflow: hidden;
|
|
|
}
|
|
|
|
|
|
.navigation-bar {
|
|
|
position: fixed;
|
|
|
// height: 60px;
|
|
|
// border-bottom: 1rpx solid #e9eff5;
|
|
|
// padding: 0 20px;
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
justify-content: space-between;
|
|
|
// padding-top: var(--status-bar-height);
|
|
|
background-color: #fff;
|
|
|
width: 100%;
|
|
|
opacity: 1;
|
|
|
z-index: 999;
|
|
|
}
|
|
|
.conversation-search {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
height: 54px;
|
|
|
box-sizing: border-box;
|
|
|
overflow: hidden;
|
|
|
padding: 10px;
|
|
|
}
|
|
|
.search-input-wrapper {
|
|
|
flex: 1;
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
height: 34px;
|
|
|
overflow: hidden;
|
|
|
box-sizing: border-box;
|
|
|
padding: 8px 10px;
|
|
|
background: #f3f5f7;
|
|
|
border-radius: 5px;
|
|
|
}
|
|
|
.search-input {
|
|
|
margin-left: 5px;
|
|
|
color: #999999;
|
|
|
}
|
|
|
.search-icon-wrapper {
|
|
|
height: 22px;
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
}
|
|
|
.block {
|
|
|
height: 60px;
|
|
|
width: 100%;
|
|
|
display: block;
|
|
|
padding-top: var(--status-bar-height);
|
|
|
}
|
|
|
|
|
|
.conversation-list-wrapper {
|
|
|
// height: calc(100% - 60px - var(--status-bar-height));
|
|
|
min-height: 85vh;
|
|
|
background-color: #ededed;
|
|
|
box-sizing: border-box;
|
|
|
width: 100%;
|
|
|
overflow-y: auto;
|
|
|
overflow-x: hidden;
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
.logo-box {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
font-size: 20px;
|
|
|
font-weight: 500;
|
|
|
|
|
|
.logo-img {
|
|
|
width: 32px;
|
|
|
height: 32px;
|
|
|
margin-right: 10px;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.button-icon-add {
|
|
|
position: relative;
|
|
|
right: 20px;
|
|
|
}
|
|
|
|
|
|
.dropdown-mark {
|
|
|
position: fixed;
|
|
|
top: 0;
|
|
|
left: 0;
|
|
|
right: 0;
|
|
|
bottom: 0;
|
|
|
z-index: 1;
|
|
|
}
|
|
|
|
|
|
.dropdown-container {
|
|
|
position: absolute;
|
|
|
top: -70px;
|
|
|
right: 30px;
|
|
|
min-width: 122px;
|
|
|
min-height: 40px;
|
|
|
background-color: #fff;
|
|
|
border: 1rpx solid #eee;
|
|
|
box-shadow: 0px 4px 7px rgba(133, 136, 140, 0.25);
|
|
|
border-radius: 8px;
|
|
|
z-index: 99;
|
|
|
}
|
|
|
|
|
|
.add-menu-list {
|
|
|
padding: 15px 10px;
|
|
|
|
|
|
.add-menu-item {
|
|
|
white-space: nowrap;
|
|
|
font-size: 16px;
|
|
|
padding-left: 5px;
|
|
|
margin-bottom: 10px;
|
|
|
height: 30px;
|
|
|
line-height: 30px;
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
|
|
|
&:last-child {
|
|
|
margin-bottom: 0;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.conversation-block {
|
|
|
width: 100%;
|
|
|
height: 72px;
|
|
|
}
|
|
|
</style>
|