移动app
This commit is contained in:
565
uni-im示例/uni_modules/uni-im/pages/index/index.nvue
Normal file
565
uni-im示例/uni_modules/uni-im/pages/index/index.nvue
Normal file
@@ -0,0 +1,565 @@
|
||||
<template>
|
||||
<view id="page">
|
||||
|
||||
<!-- 底部版权声明栏 -->
|
||||
<view id="about" v-if="isWidescreen" space="nbsp">
|
||||
<text>欢迎体验uni-im ​</text>
|
||||
<uni-link href="https://ext.dcloud.net.cn/plugin?id=9711" text="[点此下载插件]"></uni-link>
|
||||
</view>
|
||||
|
||||
<!-- #ifdef H5 -->
|
||||
<!-- 布局最左侧 菜单栏 -->
|
||||
<view id="left-view" v-if="isWidescreen" @click="chatInfoIsShow = false;">
|
||||
<cloud-image class="user-avatar" @click="toUcenter" :src="avatarUrl" width="40px" height="40px"
|
||||
borderRadius="100px"></cloud-image>
|
||||
<!-- {{currentUserInfo.username}} -->
|
||||
<uni-badge size="small" :text="unreadMsgCount" absolute="rightTop" type="error">
|
||||
<uni-icons class="chat-icon" @click="showContactsView = false"
|
||||
:color="showContactsView?'#c5c5c5':'#5fc08e'" size="32" type="chatbubble-filled"></uni-icons>
|
||||
</uni-badge>
|
||||
<uni-badge size="small" :text="unreadnotificationCount" absolute="rightTop" type="error">
|
||||
<uni-icons @click="showContactsView = true" :color="showContactsView?'#5fc08e':'#c5c5c5'" size="32"
|
||||
type="staff-filled"></uni-icons>
|
||||
</uni-badge>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
|
||||
<!-- 会话列表 -->
|
||||
<view id="center-view">
|
||||
<!-- #ifdef H5 -->
|
||||
<!-- 搜索会话用户、聊天记录... -->
|
||||
<view id="search-bar-box" v-if="isWidescreen" @click="clickSearchBarBox">
|
||||
<uni-search-bar :readonly="true" id="search-bar" radius="5" placeholder="搜索" clearButton="auto" cancelButton="none"
|
||||
></uni-search-bar>
|
||||
<uni-icons color="#848386" size="26" type="plus"></uni-icons>
|
||||
</view>
|
||||
<view id="uni-im-contacts-box" v-show="isWidescreen && showContactsView">
|
||||
<uni-im-contacts @clickMenu="clickMenu" id="uni-im-contacts"></uni-im-contacts>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
|
||||
<!-- #ifdef H5 -->
|
||||
<scroll-view id="user-list-box" scroll-y="true" @scrolltolower="loadMore()">
|
||||
<!-- #endif -->
|
||||
<!-- 会话用户列表 -->
|
||||
<uni-list class="user-list" :style="{'height':wHeight,'width':'750rpx'}" :border="false">
|
||||
|
||||
<uni-list-chat @contextmenu.prevent.native="toChat(item.id)"
|
||||
v-for="(item,index) in conversationList" :key="item.id" :showBadge="item.unread_count>0"
|
||||
:badgeText="item.unread_count" link :title="item.title" class="user-list-item"
|
||||
:class="{activeConversation:currentConversationId==item.id}" :note="item.last_msg_note"
|
||||
:avatar="item.avatar_file&&item.avatar_file.url ? item.avatar_file.url : '/uni_modules/uni-im/static/avatarUrl.png'"
|
||||
@click="toChat(item.id)" direction="column" :time="friendlyTime(item.update_time)"
|
||||
:hasCallMe="item.call_list.length">
|
||||
<template v-slot:header>
|
||||
<text class="group-icon" v-if="item.group_id">群</text>
|
||||
</template>
|
||||
</uni-list-chat>
|
||||
<!-- #ifdef APP-NVUE -->
|
||||
<!-- nvue端appear(元素一旦显示在可视窗口中)就触发加载更多。-->
|
||||
<cell v-if="conversationList.length" @appear="loadMore()"></cell>
|
||||
<!-- #endif -->
|
||||
<uni-list-item :customStyle="{backgroundColor:'#f5f5f5',padding:0}">
|
||||
<template v-slot:body>
|
||||
<uni-load-more class="tip" :contentText="loadMoreContentText"
|
||||
:status="conversationHasMore?'loading':'noMore'"></uni-load-more>
|
||||
</template>
|
||||
</uni-list-item>
|
||||
</uni-list>
|
||||
<!-- #ifdef H5 -->
|
||||
</scroll-view>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
|
||||
<!-- #ifdef H5 -->
|
||||
<view id="right-view" v-if="isWidescreen">
|
||||
<!-- 聊天窗口 -->
|
||||
<view id="chat-view-box">
|
||||
<template v-if="!showContactsView && currentConversationId">
|
||||
<view id="chat-header" v-if="!showContactsView">
|
||||
<!-- 群标题 -->
|
||||
<text :selectable="true">{{currentConversation.title}}</text>
|
||||
<uni-icons @click="showChatInfo" class="more" type="more-filled" size="20"></uni-icons>
|
||||
</view>
|
||||
<view id="chat-view">
|
||||
<chat-view ref="chat-view"></chat-view>
|
||||
</view>
|
||||
<view v-if="chatInfoIsShow" class="chatInfoBox" @click.stop="chatInfoIsShow = false">
|
||||
<uni-im-group-info @click.native.stop v-if="currentConversation.group_id"
|
||||
:conversation_id="currentConversation.id"></uni-im-group-info>
|
||||
<uni-im-chat-info @click.native.stop v-else
|
||||
:conversation_id="currentConversation.id"></uni-im-chat-info>
|
||||
</view>
|
||||
</template>
|
||||
<view v-else id="ccid-is-null-tip">
|
||||
未选择会话对象
|
||||
</view>
|
||||
</view>
|
||||
<view id="dynamic-component-box" v-show="showContactsView">
|
||||
<view class="dynamic-component-title">{{view2Title}}</view>
|
||||
<component ref="dynamicComponent" :is="dynamicComponentName"></component>
|
||||
</view>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const db = uniCloud.database();
|
||||
// #ifdef H5
|
||||
import chatView from '@/uni_modules/uni-im/pages/chat/chat';
|
||||
// #endif
|
||||
import uniImUtils from '@/uni_modules/uni-im/common/utils.js';
|
||||
|
||||
import {
|
||||
store as uniIdStore,
|
||||
mutations as uniIdMutations
|
||||
} from '@/uni_modules/uni-id-pages/common/store.js';
|
||||
|
||||
import uniIm from '@/uni_modules/uni-im/lib/main.js';
|
||||
|
||||
import contacts from '@/uni_modules/uni-im/pages/contacts/contacts';
|
||||
|
||||
// #ifdef H5
|
||||
import notification from '@/uni_modules/uni-im/pages/contacts/notification/notification';
|
||||
import addPeopleGroups from '@/uni_modules/uni-im/pages/contacts/addPeopleGroups/addPeopleGroups';
|
||||
import groupList from '@/uni_modules/uni-im/pages/contacts/groupList/groupList';
|
||||
import createGroup from '@/uni_modules/uni-im/pages/contacts/createGroup/createGroup';
|
||||
import chatInfo from '@/uni_modules/uni-im/pages/chat/info';
|
||||
import groupInfo from '@/uni_modules/uni-im/pages/group/info';
|
||||
|
||||
import {version} from '@/uni_modules/uni-im/package.json'
|
||||
// #endif
|
||||
|
||||
let lastConversationId = false
|
||||
|
||||
let sortIndex = 0
|
||||
|
||||
export default {
|
||||
// #ifdef H5
|
||||
components: {
|
||||
chatView,
|
||||
"uni-im-contacts": contacts,
|
||||
"uni-im-notification": notification,
|
||||
"uni-im-addPeopleGroups": addPeopleGroups,
|
||||
"uni-im-groupList": groupList,
|
||||
"uni-im-createGroup": createGroup,
|
||||
"uni-im-chat-info": chatInfo,
|
||||
"uni-im-group-info": groupInfo
|
||||
},
|
||||
// #endif
|
||||
data() {
|
||||
return {
|
||||
wHeight: 'auto',
|
||||
userInfo: {},
|
||||
dynamicComponentName: 'uni-im-addPeopleGroups', //通过动态组件引入页面在pc端显示
|
||||
view2Title: '加人/加群',
|
||||
showContactsView: false,
|
||||
chatInfoIsShow: false,
|
||||
currentConversation: {}
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
conversationList(){
|
||||
sortIndex ++
|
||||
// console.log('根据会话时间排序',uniIm.conversation.dataList,sortIndex)
|
||||
let conversationList = uniIm.conversation.dataList
|
||||
setTimeout(()=> {
|
||||
sortIndex = 0
|
||||
}, 1000);
|
||||
if(sortIndex > 6){
|
||||
return conversationList
|
||||
}
|
||||
return conversationList.sort(function(a, b) {
|
||||
if(b.id == uniIm.currentConversationId) {
|
||||
// 当前会话正在输入时,不需要重新排序避免change频繁触发导致排序频繁
|
||||
return 0
|
||||
}
|
||||
// 如果该会话的输入框已经输入了内容未发就排在前面
|
||||
if(b.chatText){
|
||||
b.update_time = Date.now()
|
||||
}
|
||||
|
||||
let a_update_time = a.update_time || 0
|
||||
let b_update_time = b.update_time || 0
|
||||
|
||||
let aml = a.msgList.length
|
||||
let bml = b.msgList.length
|
||||
|
||||
if (aml) {
|
||||
let create_time = a.msgList[aml - 1].create_time
|
||||
if (create_time > a_update_time) {
|
||||
a_update_time = create_time
|
||||
}
|
||||
}
|
||||
if (bml) {
|
||||
let create_time = b.msgList[bml - 1].create_time
|
||||
if (create_time > b_update_time) {
|
||||
b_update_time = create_time
|
||||
}
|
||||
}
|
||||
return b_update_time - a_update_time
|
||||
})
|
||||
},
|
||||
loadMoreContentText() {
|
||||
return {
|
||||
contentrefresh: "正在加载...",
|
||||
contentnomore: (this.conversationList.length ? "没有更多数据了" : "没有会话数据")
|
||||
}
|
||||
},
|
||||
conversationHasMore() {
|
||||
return uniIm.conversation.hasMore
|
||||
},
|
||||
// 导入uniIm响应式数据,支持别名:比如:['a as b']
|
||||
...uniIm.mapState(['currentConversationId', 'isWidescreen']),
|
||||
unreadMsgCount() {
|
||||
return uniIm.conversation.unreadCount()
|
||||
},
|
||||
unreadnotificationCount() {
|
||||
return uniIm.notification.unreadCount()
|
||||
},
|
||||
currentUserInfo() {
|
||||
return uniIdStore.userInfo
|
||||
},
|
||||
avatarUrl() {
|
||||
if (this.currentUserInfo.avatar_file && this.currentUserInfo.avatar_file.url) {
|
||||
return this.currentUserInfo.avatar_file.url
|
||||
}
|
||||
return '/uni_modules/uni-im/static/avatarUrl.png'
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
unreadMsgCount(unreadMsgCount) {
|
||||
console.log({
|
||||
unreadMsgCount
|
||||
});
|
||||
|
||||
// #ifdef APP
|
||||
plus.runtime.setBadgeNumber(unreadMsgCount)
|
||||
// #endif
|
||||
|
||||
if (unreadMsgCount == 0) {
|
||||
uni.removeTabBarBadge({
|
||||
index: 0,
|
||||
complete: (e) => {
|
||||
console.log(e)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
uni.setTabBarBadge({
|
||||
index: 0,
|
||||
text: unreadMsgCount + '',
|
||||
complete: (e) => {
|
||||
// console.log(e)
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
showContactsView(showContactsView) {
|
||||
if (showContactsView) {
|
||||
lastConversationId = this.currentConversationId
|
||||
uniIm.currentConversationId = false
|
||||
} else {
|
||||
if (lastConversationId) {
|
||||
uniIm.currentConversationId = lastConversationId
|
||||
this.$nextTick(() => {
|
||||
this.toChat(lastConversationId)
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
async currentConversationId(id) {
|
||||
this.currentConversation = await uniIm.conversation.get(id)
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// #ifdef APP-NVUE
|
||||
this.wHeight = uni.getSystemInfoSync().windowHeight + 'px'
|
||||
// #endif
|
||||
},
|
||||
async onLoad(param) {
|
||||
let {
|
||||
token,
|
||||
user_id,
|
||||
conversation_id,
|
||||
joinGroup
|
||||
} = param
|
||||
|
||||
let version = "2023-05-22-01"
|
||||
// 发布新版本后,清理旧版本下的storage避免脏数据引发问题
|
||||
let lastVersion = uni.getStorageSync('uni-im-storage-version')
|
||||
if (lastVersion && lastVersion != version) {
|
||||
uni.setStorageSync('uni-im-storage-version', version)
|
||||
uni.clearStorage()
|
||||
}
|
||||
|
||||
let {
|
||||
tokenExpired
|
||||
} = uniCloud.getCurrentUserInfo()
|
||||
if (!tokenExpired || tokenExpired < Date.now()) {
|
||||
console.info('当前用户的登录状态无效,将自动跳转至登录页面。', param)
|
||||
let url = '/uni_modules/uni-id-pages/pages/login/login-withpwd?uniIdRedirectUrl='
|
||||
let paramString = '/uni_modules/uni-im/pages/index/index?'
|
||||
for (let key in param) {
|
||||
paramString += `${key}=${param[key]}&`
|
||||
}
|
||||
paramString = paramString.substring(0, paramString.length - 1) //携带参数,实现登录成功后 跳回首页时传回
|
||||
url += encodeURIComponent(paramString)
|
||||
return uni.reLaunch({
|
||||
url
|
||||
})
|
||||
}
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.init({
|
||||
user_id,
|
||||
conversation_id
|
||||
})
|
||||
})
|
||||
|
||||
this.onLoginSuccess = async () => {
|
||||
this.init({
|
||||
user_id,
|
||||
conversation_id
|
||||
})
|
||||
}
|
||||
|
||||
uni.$on('uni-id-pages-login-success', this.onLoginSuccess)
|
||||
uni.$on('uni-im-toChat', param => {
|
||||
if (param) {
|
||||
// 关闭最后一次的会话id,防止切回后重新显示最后一次会话,而邮箱指定显示到某个会话
|
||||
lastConversationId = false
|
||||
this.toChat(param)
|
||||
}
|
||||
this.showContactsView = false
|
||||
})
|
||||
|
||||
/**
|
||||
* 在本页面链接传递参数 joinGroup=group_id即可申请加入群,
|
||||
* 比如:http://localhost:8082/#/uni_modules/uni-im/pages/index/index?joinGroup=xxx
|
||||
*/
|
||||
if(joinGroup){
|
||||
let group_id = joinGroup
|
||||
// #ifdef H5
|
||||
//删除地址栏的token,且不刷新页面
|
||||
history.pushState({}, '', '/#/');
|
||||
// #endif
|
||||
console.log('group_id',group_id);
|
||||
db.collection('uni-im-group-join').add({
|
||||
group_id,
|
||||
"message":''
|
||||
}).then((res) => {
|
||||
console.log("res: ",res);
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
title: '已申请'
|
||||
})
|
||||
}).catch((err) => {
|
||||
uni.showModal({
|
||||
content: err.message || '请求服务失败',
|
||||
showCancel: false
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
async onReady() {
|
||||
// #ifdef H5
|
||||
let systemInfo = uni.getSystemInfoSync()
|
||||
uniIm.systemInfo = systemInfo
|
||||
// console.log('systemInfo',systemInfo);
|
||||
if (!['edge', 'chrome', 'safari'].includes(systemInfo.browserName)) {
|
||||
let newElement = document.createElement('div')
|
||||
newElement.innerHTML = `
|
||||
<div style="background: #fff9ea;color: #ff9a43;position: fixed;top: 0;left: 0;width: 100vw;padding: 15px;font-size: 18px;">
|
||||
注意:本系统仅兼容chrome、edge、safari浏览器
|
||||
</div>
|
||||
`
|
||||
document.body.appendChild(newElement)
|
||||
}
|
||||
// #endif
|
||||
},
|
||||
onUnload() {
|
||||
uni.$off('uni-id-pages-login-success', this.onLoginSuccess)
|
||||
},
|
||||
onHide() {},
|
||||
methods: {
|
||||
clickSearchBarBox(){
|
||||
uni.showToast({
|
||||
title: '暂不支持',
|
||||
icon: 'none'
|
||||
});
|
||||
},
|
||||
async loadMore() {
|
||||
let data = await uniIm.conversation.loadMore()
|
||||
return data
|
||||
},
|
||||
clickMenu(data) {
|
||||
// console.log('79879789798898798978789', data);
|
||||
this.dynamicComponentName = data.componentName
|
||||
|
||||
if (data.title) {
|
||||
this.view2Title = data.title
|
||||
}
|
||||
|
||||
if (data.param) {
|
||||
this.$nextTick(() => {
|
||||
this.$refs.dynamicComponent.setParam(data.param)
|
||||
})
|
||||
}
|
||||
// console.log('data.componentName----',data.componentName);
|
||||
if (data.componentName == 'uni-im-createGroup') {
|
||||
this.$nextTick(() => {
|
||||
this.$refs.dynamicComponent.getFriendsData()
|
||||
})
|
||||
}
|
||||
},
|
||||
readQrCode() {
|
||||
uni.scanCode({
|
||||
complete: (e) => {
|
||||
// console.log(e);
|
||||
try {
|
||||
let data = JSON.parse(e.result)
|
||||
// console.log(data);
|
||||
if (data.type == 'uni-im' && data.subType == "groupInfo") {
|
||||
|
||||
}
|
||||
} catch (e) {
|
||||
//TODO handle the exception
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
async init({
|
||||
conversation_id,
|
||||
user_id
|
||||
}) {
|
||||
// 初始化会话列表
|
||||
// console.log('初始化会话列表',{
|
||||
// conversation_id,
|
||||
// user_id,
|
||||
// });
|
||||
|
||||
await this.loadMore()
|
||||
if (conversation_id) {
|
||||
// console.log('conversation_id', conversation_id);
|
||||
this.toChat(conversation_id)
|
||||
} else if (user_id) {
|
||||
//创建会话
|
||||
const currentConversation = await uniIm.conversation.get({
|
||||
friend_uid: user_id
|
||||
})
|
||||
// console.log('currentConversation', currentConversation);
|
||||
// 当前用户给对方发个消息
|
||||
this.toChat(currentConversation.id)
|
||||
} else {
|
||||
if (this.isWidescreen) {
|
||||
let [firstConversation] = this.conversationList
|
||||
if (firstConversation) {
|
||||
this.currentConversation = await uniIm.conversation.get(firstConversation.id)
|
||||
this.toChat(firstConversation.id)
|
||||
} else {
|
||||
// uni.showModal({
|
||||
// content: '没有任何会话,请先到用户列表选择用户',
|
||||
// showCancel: false
|
||||
// });
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
search(e) {
|
||||
// console.log("search-e: " + JSON.stringify(e));
|
||||
uni.showToast({
|
||||
title: '加好友功能入口,暂时在左侧菜单的通讯录中',
|
||||
icon: 'none',
|
||||
duration: 3000
|
||||
});
|
||||
},
|
||||
addUser() {
|
||||
uni.showToast({
|
||||
title: '加好友功能入口,暂时在左侧菜单的通讯录中',
|
||||
icon: 'none',
|
||||
duration: 3000
|
||||
});
|
||||
},
|
||||
async toChat(param) {
|
||||
this.chatInfoIsShow = false;
|
||||
// console.log('param',param);
|
||||
let conversation_id = ''
|
||||
if (typeof param == 'string') {
|
||||
conversation_id = param
|
||||
} else {
|
||||
if (param.conversation_id) {
|
||||
conversation_id = param.conversation_id
|
||||
} else if (param.group_id) {
|
||||
conversation_id = 'group_' + param.group_id
|
||||
} else if (param.user_id || param.friend_uid) {
|
||||
conversation_id = uniImUtils.getConversationId(param.user_id || param.friend_uid)
|
||||
// console.log('conversation_id',conversation_id)
|
||||
} else {
|
||||
throw new Error("toChat param is error")
|
||||
}
|
||||
}
|
||||
uniIm.currentConversationId = conversation_id
|
||||
if (this.isWidescreen) { //若为宽屏,则触发右侧详情页的自定义事件,通知右侧窗体刷新详情
|
||||
this.$nextTick(() => {
|
||||
let chatViewRef = this.$refs['chat-view']
|
||||
if (chatViewRef) {
|
||||
chatViewRef.load(conversation_id)
|
||||
}
|
||||
})
|
||||
} else { // 若为窄屏,则打开新窗体,在新窗体打开详情页面
|
||||
uni.navigateTo({
|
||||
url: '/uni_modules/uni-im/pages/chat/chat?conversation_id=' + conversation_id,
|
||||
animationDuration: 300
|
||||
})
|
||||
}
|
||||
},
|
||||
showChatInfo() {
|
||||
this.chatInfoIsShow = !this.chatInfoIsShow
|
||||
},
|
||||
toUcenter() {
|
||||
uni.navigateTo({
|
||||
url: '/uni_modules/uni-id-pages/pages/userinfo/userinfo?showLoginManage=true',
|
||||
complete(e) {
|
||||
console.log("e: " + JSON.stringify(e));
|
||||
}
|
||||
})
|
||||
},
|
||||
friendlyTime(timestamp) {
|
||||
return uniImUtils.toFriendlyTime(timestamp)
|
||||
},
|
||||
},
|
||||
async onReachBottom() {
|
||||
await this.loadMore()
|
||||
},
|
||||
onNavigationBarButtonTap(e) {
|
||||
// console.log(e);
|
||||
if (e.index) {
|
||||
let data = uni.getStorageInfoSync();
|
||||
// console.log('data.keys', JSON.stringify(data.keys));
|
||||
data.keys.forEach(item => {
|
||||
if (item.includes('uni-im-msg:') || item.includes('uni-im-conversation')) {
|
||||
// console.log(item);
|
||||
uni.removeStorageSync(item);
|
||||
// console.log(uni.getStorageSync(item));
|
||||
}
|
||||
});
|
||||
uni.showToast({
|
||||
title: 'clear storage ok',
|
||||
icon: 'none'
|
||||
});
|
||||
} else {
|
||||
uni.navigateTo({
|
||||
url: '/uni_modules/uni-id-pages/pages/userinfo/userinfo?showLoginManage=true',
|
||||
complete: e => {
|
||||
console.log(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import url("./index.scss");
|
||||
</style>
|
||||
Reference in New Issue
Block a user