同步数据
This commit is contained in:
@@ -21,7 +21,8 @@
|
|||||||
"OAuth" : {},
|
"OAuth" : {},
|
||||||
"Payment" : {},
|
"Payment" : {},
|
||||||
"Share" : {},
|
"Share" : {},
|
||||||
"SQLite" : {}
|
"SQLite" : {},
|
||||||
|
"VideoPlayer" : {}
|
||||||
},
|
},
|
||||||
/* 应用发布信息 */
|
/* 应用发布信息 */
|
||||||
"distribute" : {
|
"distribute" : {
|
||||||
|
|||||||
@@ -393,6 +393,13 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/im/private/call",
|
||||||
|
"name": "imPrivateCall",
|
||||||
|
"style": {
|
||||||
|
"navigationStyle": "custom"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "pages/im/private/setting",
|
"path": "pages/im/private/setting",
|
||||||
"name": "imPrivateSetting",
|
"name": "imPrivateSetting",
|
||||||
|
|||||||
20
pages/im/friends/group/index.vue
Normal file
20
pages/im/friends/group/index.vue
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<u-button @click="toIndex">会首页</u-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
methods: {
|
||||||
|
toIndex() {
|
||||||
|
uni.switchTab({
|
||||||
|
url: '/pages/im/index'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
</style>
|
||||||
@@ -2,10 +2,10 @@
|
|||||||
<view class="content">
|
<view class="content">
|
||||||
<!-- 用户信息 -->
|
<!-- 用户信息 -->
|
||||||
<view class="info-flex">
|
<view class="info-flex">
|
||||||
<u-avatar :src="userInfo.portraitUrl" shape="square" size="50" bg-color="#fff" />
|
<u-avatar :src="userInfo.portraitUrl" shape="square" size="50" bg-color="#fff"></u-avatar>
|
||||||
<view class="info-text">
|
<view class="info-text">
|
||||||
<view class="nickname">{{ userInfo.name }}</view>
|
<view class="nickname">{{userInfo.name}}</view>
|
||||||
<view class="address" @longpress="copyAddress">地址:{{ userInfo.address }}</view>
|
<view class="address" @longpress="copyAddress">地址:{{userInfo.address}}</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<!-- 用户资料 -->
|
<!-- 用户资料 -->
|
||||||
@@ -20,15 +20,15 @@
|
|||||||
|
|
||||||
<block v-if="userInfo.is_friend">
|
<block v-if="userInfo.is_friend">
|
||||||
<view class="info-btns">
|
<view class="info-btns">
|
||||||
<view class="item" @click="setRemark">
|
<view class="item u-border-bottom" @click="setRemark">
|
||||||
<label>设置备注</label>
|
<label>设置备注</label>
|
||||||
<u-icon name="arrow-right" color="#999" size="16" />
|
<u-icon name="arrow-right" color="#999" size="16"></u-icon>
|
||||||
</view>
|
</view>
|
||||||
<view class="item" @click="setRemark">
|
<view class="item u-border-bottom" @click="setRemark">
|
||||||
<label>设置标签</label>
|
<label>设置标签</label>
|
||||||
<u-icon name="arrow-right" color="#999" size="16" />
|
<u-icon name="arrow-right" color="#999" size="16"></u-icon>
|
||||||
</view>
|
</view>
|
||||||
<view class="item">
|
<view class="item u-border-bottom">
|
||||||
<label>聊天免打扰</label>
|
<label>聊天免打扰</label>
|
||||||
<u-switch size="22" v-model="status" activeColor="#34CE98" @change="setStatus"></u-switch>
|
<u-switch size="22" v-model="status" activeColor="#34CE98" @change="setStatus"></u-switch>
|
||||||
</view>
|
</view>
|
||||||
@@ -39,15 +39,21 @@
|
|||||||
</view>
|
</view>
|
||||||
<view class="footer">
|
<view class="footer">
|
||||||
<view class="footer-item" @click="deleteFriend">
|
<view class="footer-item" @click="deleteFriend">
|
||||||
<view class="icon"><u-icon class="icon-u" name="close-circle-fill" color="#fff" size="26" /></view>
|
<view class="icon">
|
||||||
|
<u-icon class="icon-u" name="close-circle-fill" color="#fff" size="26"></u-icon>
|
||||||
|
</view>
|
||||||
<view class="text">删除好友</view>
|
<view class="text">删除好友</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="footer-item" @click="toPrivate">
|
<view class="footer-item" @click="toPrivate">
|
||||||
<view class="icon"><u-icon class="icon-u" name="chat-fill" color="#fff" size="26" /></view>
|
<view class="icon">
|
||||||
|
<u-icon class="icon-u" name="chat-fill" color="#fff" size="26"></u-icon>
|
||||||
|
</view>
|
||||||
<view class="text">发送消息</view>
|
<view class="text">发送消息</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="footer-item" @click="toPrivate">
|
<view class="footer-item" @click="callShow = true">
|
||||||
<view class="icon"><u-icon class="icon-u" name="camera-fill" color="#fff" size="26" /></view>
|
<view class="icon">
|
||||||
|
<u-icon class="icon-u" name="camera-fill" color="#fff" size="26"></u-icon>
|
||||||
|
</view>
|
||||||
<view class="text">视频通话</view>
|
<view class="text">视频通话</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -55,55 +61,68 @@
|
|||||||
<block v-else>
|
<block v-else>
|
||||||
<view class="footer">
|
<view class="footer">
|
||||||
<view class="footer-item" @click="toBeFriend">
|
<view class="footer-item" @click="toBeFriend">
|
||||||
<view class="icon"><u-icon class="icon-u" name="plus-people-fill" color="#fff" size="26" /></view>
|
<view class="icon">
|
||||||
|
<u-icon class="icon-u" name="plus-people-fill" color="#fff" size="26"></u-icon>
|
||||||
|
</view>
|
||||||
<view class="text">申请好友</view>
|
<view class="text">申请好友</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</block>
|
</block>
|
||||||
|
<u-action-sheet :actions="callActions" cancelText="取消" @close="callShow = false" @select="singleCall"
|
||||||
|
:show="callShow">
|
||||||
|
</u-action-sheet>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { getFriendInfo, pedingFriend, deleteFriend } from '@/apis/interfaces/im.js';
|
import {
|
||||||
import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index';
|
getFriendInfo,
|
||||||
|
pedingFriend,
|
||||||
|
deleteFriend
|
||||||
|
} from '@/apis/interfaces/im.js'
|
||||||
|
import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
|
||||||
|
import * as CallLib from '@/uni_modules/RongCloud-CallWrapper/lib/index'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
targetId: '',
|
targetId: '',
|
||||||
userInfo: {},
|
userInfo: {},
|
||||||
status: false, // 0 是免打扰,1是正常通知
|
status: false, // 0 是免打扰,1是正常通知
|
||||||
isTop: false,
|
isTop: false,
|
||||||
block: false,
|
block: false,
|
||||||
conversationType: 1
|
conversationType: 1,
|
||||||
};
|
callActions: [{
|
||||||
},
|
type: 0,
|
||||||
onLoad(e) {
|
name: '语音通话'
|
||||||
this.targetId = e.targetId;
|
},
|
||||||
getFriendInfo(e.targetId).then(res => {
|
{
|
||||||
this.userInfo = res;
|
type: 1,
|
||||||
uni.setNavigationBarTitle({
|
name: '视频通话'
|
||||||
title: res.name
|
}
|
||||||
});
|
],
|
||||||
});
|
callShow: false
|
||||||
RongIMLib.getConversationNotificationStatus(this.conversationType, this.targetId, ({ status }) => {
|
|
||||||
this.status = !Boolean(status);
|
|
||||||
});
|
|
||||||
RongIMLib.getConversation(this.conversationType, this.targetId, ({ code, conversation }) => {
|
|
||||||
if (code == 0) {
|
|
||||||
this.isTop = conversation.isTop;
|
|
||||||
}
|
}
|
||||||
});
|
},
|
||||||
},
|
onLoad(e) {
|
||||||
methods: {
|
this.targetId = e.targetId
|
||||||
copyAddress() {
|
getFriendInfo(e.targetId).then(res => {
|
||||||
uni.setClipboardData({
|
this.userInfo = res
|
||||||
data: this.userInfo.address,
|
uni.setNavigationBarTitle({
|
||||||
success: () => {
|
title: res.name
|
||||||
uni.showToast({
|
})
|
||||||
icon: 'none',
|
})
|
||||||
title: '复制区块链成功'
|
RongIMLib.getConversationNotificationStatus(this.conversationType, this.targetId, ({
|
||||||
});
|
status
|
||||||
|
}) => {
|
||||||
|
this.status = !Boolean(status)
|
||||||
|
})
|
||||||
|
RongIMLib.getConversation(this.conversationType, this.targetId, ({
|
||||||
|
code,
|
||||||
|
conversation
|
||||||
|
}) => {
|
||||||
|
if (code == 0) {
|
||||||
|
this.isTop = conversation.isTop
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@@ -120,156 +139,212 @@ export default {
|
|||||||
},
|
},
|
||||||
deleteFriend() {
|
deleteFriend() {
|
||||||
uni.showModal({
|
uni.showModal({
|
||||||
title: '删除确认',
|
title: '删除确认',
|
||||||
content: '确认删除后不可恢复',
|
content: '确认删除后不可恢复',
|
||||||
success: e => {
|
success: e => {
|
||||||
if (e.confirm) {
|
if (e.confirm) {
|
||||||
deleteFriend(this.targetId).then(res => {
|
deleteFriend(this.targetId).then(res => {
|
||||||
// 删除聊天记录
|
// 删除聊天记录
|
||||||
RongIMLib.deleteMessages(1, this.targetId);
|
RongIMLib.deleteMessages(1, this.targetId);
|
||||||
RongIMLib.removeConversation(1, this.targetId);
|
RongIMLib.removeConversation(1, this.targetId);
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
icon: 'none',
|
icon: 'none',
|
||||||
title: '好友删除成功',
|
title: '好友删除成功',
|
||||||
success() {
|
success() {
|
||||||
uni.switchTab({
|
uni.switchTab({
|
||||||
url: '/pages/im/index'
|
url: '/pages/im/index'
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
});
|
||||||
});
|
}
|
||||||
});
|
})
|
||||||
}
|
},
|
||||||
}
|
toPrivate() {
|
||||||
});
|
uni.redirectTo({
|
||||||
},
|
url: '/pages/im/private/index?conversationType=1&targetId=' + this.targetId
|
||||||
setStatus() {
|
})
|
||||||
RongIMLib.setConversationNotificationStatus(this.conversationType, this.targetId, this.status, ({ status }) => {
|
},
|
||||||
this.status = !Boolean(status);
|
setRemark() {
|
||||||
});
|
|
||||||
},
|
|
||||||
setTop() {
|
|
||||||
RongIMLib.setConversationToTop(this.conversationType, this.targetId, this.isTop, res => {
|
|
||||||
RongIMLib.getConversation(this.conversationType, this.targetId, ({ conversation }) => {
|
|
||||||
this.isTop = conversation.isTop;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
setBlock() {},
|
|
||||||
// 申请好友
|
|
||||||
toBeFriend() {
|
|
||||||
pedingFriend(this.targetId)
|
|
||||||
.then(res => {
|
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: '申请成功',
|
title: '开发中',
|
||||||
icon: 'none'
|
icon: 'none'
|
||||||
});
|
})
|
||||||
})
|
},
|
||||||
.catch(err => {
|
deleteFriend() {
|
||||||
uni.showToast({
|
uni.showModal({
|
||||||
icon: 'error',
|
title: '删除确认',
|
||||||
title: err.message,
|
content: '确认删除后不可恢复',
|
||||||
duration: 2000
|
success: (e) => {
|
||||||
});
|
if (e.confirm) {
|
||||||
});
|
deleteFriend(this.targetId).then(res => {
|
||||||
|
// 删除聊天记录
|
||||||
|
RongIMLib.deleteMessages(1, this.targetId)
|
||||||
|
RongIMLib.removeConversation(1, this.targetId)
|
||||||
|
uni.showToast({
|
||||||
|
icon: 'none',
|
||||||
|
title: '好友删除成功',
|
||||||
|
success() {
|
||||||
|
uni.switchTab({
|
||||||
|
url: '/pages/im/index'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
setStatus() {
|
||||||
|
RongIMLib.setConversationNotificationStatus(this.conversationType, this.targetId, this.status, ({
|
||||||
|
status
|
||||||
|
}) => {
|
||||||
|
this.status = !Boolean(status)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
setTop() {
|
||||||
|
RongIMLib.setConversationToTop(this.conversationType, this.targetId, this.isTop, (res) => {
|
||||||
|
RongIMLib.getConversation(this.conversationType, this.targetId, ({
|
||||||
|
conversation
|
||||||
|
}) => {
|
||||||
|
this.isTop = conversation.isTop
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 申请好友
|
||||||
|
toBeFriend() {
|
||||||
|
pedingFriend(this.targetId).then(res => {
|
||||||
|
uni.showToast({
|
||||||
|
title: '申请成功',
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
uni.showToast({
|
||||||
|
icon: 'error',
|
||||||
|
title: err.message,
|
||||||
|
duration: 2000
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
singleCall(e) {
|
||||||
|
CallLib.startSingleCall(this.targetId, e.type, '');
|
||||||
|
uni.redirectTo({
|
||||||
|
url: '/pages/im/private/call',
|
||||||
|
success: (err) => {
|
||||||
|
console.log('跳转视频通话成功');
|
||||||
|
},
|
||||||
|
fail: (err) => {
|
||||||
|
console.log('跳转视频页失败', err);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.content {
|
.content {
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
background: $window-color;
|
background: $window-color;
|
||||||
padding-top: $padding;
|
padding-top: $padding;
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 用户信息
|
|
||||||
.info-flex {
|
|
||||||
padding: $padding;
|
|
||||||
margin: 0 $margin;
|
|
||||||
display: flex;
|
|
||||||
background: white;
|
|
||||||
border-radius: $radius;
|
|
||||||
.info-text {
|
|
||||||
width: calc(100% - 50px);
|
|
||||||
padding-left: $padding;
|
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
.nickname {
|
|
||||||
line-height: 30px;
|
|
||||||
font-size: $title-size + 6;
|
|
||||||
color: $text-color;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
.address {
|
|
||||||
line-height: 20px;
|
|
||||||
font-size: $title-size-sm;
|
|
||||||
color: $text-gray;
|
|
||||||
text-align: left;
|
|
||||||
@extend .nowrap;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// footer
|
// 用户信息
|
||||||
.footer {
|
.info-flex {
|
||||||
position: fixed;
|
padding: $padding;
|
||||||
bottom: 0;
|
margin: 0 $margin;
|
||||||
left: 0;
|
display: flex;
|
||||||
right: 0;
|
background: white;
|
||||||
padding: $padding * 2 $padding;
|
border-radius: $radius;
|
||||||
display: flex;
|
|
||||||
justify-content: space-around;
|
.info-text {
|
||||||
.footer-item {
|
width: calc(100% - 50px);
|
||||||
margin: 0 $margin/2;
|
padding-left: $padding;
|
||||||
text-align: center;
|
box-sizing: border-box;
|
||||||
.icon {
|
|
||||||
background: $main-color;
|
.nickname {
|
||||||
width: 88rpx;
|
line-height: 30px;
|
||||||
height: 88rpx;
|
font-size: $title-size + 6;
|
||||||
line-height: 88rpx;
|
color: $text-color;
|
||||||
display: inline-block;
|
text-align: left;
|
||||||
border-radius: 50%;
|
}
|
||||||
.icon-u {
|
|
||||||
margin-top: calc((88rpx / 2) - 13px);
|
.address {
|
||||||
margin-left: calc((88rpx / 2) - 13px);
|
line-height: 20px;
|
||||||
|
font-size: $title-size-sm;
|
||||||
|
color: $text-gray;
|
||||||
|
text-align: left;
|
||||||
|
@extend .nowrap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.text {
|
|
||||||
color: $main-color;
|
|
||||||
font-size: $title-size-m;
|
|
||||||
text-align: center;
|
|
||||||
padding-top: 10rpx;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// btns
|
// footer
|
||||||
|
.footer {
|
||||||
.info-btns {
|
position: fixed;
|
||||||
background: white;
|
bottom: 0;
|
||||||
margin: $margin;
|
left: 0;
|
||||||
border-radius: $radius;
|
right: 0;
|
||||||
.item {
|
padding: $padding*2 $padding;
|
||||||
line-height: 100rpx;
|
|
||||||
border-bottom: solid 1rpx $border-color;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
justify-content: space-around;
|
||||||
padding: 0 $padding;
|
|
||||||
justify-content: space-between;
|
.footer-item {
|
||||||
font-size: $title-size-lg;
|
margin: 0 $margin/2;
|
||||||
&:last-child {
|
text-align: center;
|
||||||
border-bottom: none;
|
|
||||||
}
|
.icon {
|
||||||
label {
|
background: $main-color;
|
||||||
width: 200rpx;
|
width: 88rpx;
|
||||||
}
|
height: 88rpx;
|
||||||
.text {
|
line-height: 88rpx;
|
||||||
width: calc(100% - 200rpx);
|
display: inline-block;
|
||||||
color: $text-gray-m;
|
border-radius: 50%;
|
||||||
text-align: right;
|
|
||||||
@extend .nowrap;
|
.icon-u {
|
||||||
|
margin-top: calc((88rpx/2) - 13px);
|
||||||
|
margin-left: calc((88rpx/2) - 13px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.text {
|
||||||
|
color: $main-color;
|
||||||
|
font-size: $title-size-m;
|
||||||
|
text-align: center;
|
||||||
|
padding-top: 10rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// btns
|
||||||
|
|
||||||
|
.info-btns {
|
||||||
|
background: white;
|
||||||
|
margin: $margin;
|
||||||
|
border-radius: $radius;
|
||||||
|
|
||||||
|
.item {
|
||||||
|
line-height: 100rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0 $padding;
|
||||||
|
justify-content: space-between;
|
||||||
|
font-size: $title-size-lg;
|
||||||
|
|
||||||
|
label {
|
||||||
|
width: 200rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text {
|
||||||
|
width: calc(100% - 200rpx);
|
||||||
|
color: $text-gray-m;
|
||||||
|
text-align: right;
|
||||||
|
@extend .nowrap;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,19 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<view class="">
|
||||||
<u-button @click="toIndex">会首页</u-button>
|
|
||||||
</div>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
|
||||||
methods: {
|
|
||||||
toIndex() {
|
|
||||||
uni.switchTab({
|
|
||||||
url: '/pages/im/index'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|||||||
219
pages/im/private/call.nvue
Normal file
219
pages/im/private/call.nvue
Normal file
@@ -0,0 +1,219 @@
|
|||||||
|
<template>
|
||||||
|
<view class="call-page">
|
||||||
|
<view class="video">
|
||||||
|
<RongCloud-Call-RCUniCallView ref="bigVideoView" :style="{width:windowWidth+'px',height:windowHeight+'px'}"
|
||||||
|
class="bigVideoView">
|
||||||
|
</RongCloud-Call-RCUniCallView>
|
||||||
|
<RongCloud-Call-RCUniCallView ref="smallVideoView" class="smallVideoView">
|
||||||
|
</RongCloud-Call-RCUniCallView>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="status" v-if="!connected">
|
||||||
|
<view class="call-user">
|
||||||
|
<u-avatar :src="userInfo.portraitUrl" size="150" bg-color="#fff"></u-avatar>
|
||||||
|
<view class="nickname">{{userInfo.name}}</view>
|
||||||
|
<view v-if="remoteRinging" class="mediaType">等待对方接听</view>
|
||||||
|
<view v-if="connected" class="mediaType">已接通 {{ connected }}</view>
|
||||||
|
<view v-else class="mediaType">{{ mediaType == 0 ? '邀请您语音通话' : '邀请您视频通话' }}</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="buttons">
|
||||||
|
<view class="btn" v-if="connected" @click="changeMicrophone"><text class="white">麦克风</text></view>
|
||||||
|
<view class="btn hangup" @click="hangup"><text class="white">挂断</text></view>
|
||||||
|
<view class="btn" v-if="!connected" @click="accept"><text class="white">接听</text></view>
|
||||||
|
<view class="btn" v-if="connected" @click="changeSpeaker"><text class="white">扬声器</text></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {
|
||||||
|
getFriendInfo
|
||||||
|
} from '@/apis/interfaces/im.js'
|
||||||
|
import * as CallLib from '@/uni_modules/RongCloud-CallWrapper/lib/index'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
targetId: '',
|
||||||
|
mediaType: 0, // 0 语音 1 视频
|
||||||
|
users: [],
|
||||||
|
userInfo: {},
|
||||||
|
isOut: false,
|
||||||
|
connected: false,
|
||||||
|
micStatus: false,
|
||||||
|
speStatus: false,
|
||||||
|
remoteRinging: false,
|
||||||
|
innerAudioContext: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onLoad(e) {
|
||||||
|
this.targetId = e.targetId || 10051
|
||||||
|
this.mediaType = e.mediaType
|
||||||
|
getFriendInfo(this.targetId).then(res => {
|
||||||
|
this.userInfo = res
|
||||||
|
})
|
||||||
|
this.startRing()
|
||||||
|
// 监听通话链接状态
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
CallLib.setVideoView(10047, this.$refs.bigVideoView.ref, 0, false)
|
||||||
|
}, 200)
|
||||||
|
|
||||||
|
uni.$on('onCallConnected', () => {
|
||||||
|
console.log('OnCallConnected');
|
||||||
|
this.connected = true
|
||||||
|
this.stopRing()
|
||||||
|
})
|
||||||
|
uni.$on('onCallDisconnected', () => {
|
||||||
|
this.hangup()
|
||||||
|
})
|
||||||
|
uni.$on('onRemoteUserRinging', () => {
|
||||||
|
this.remoteRinging = true
|
||||||
|
})
|
||||||
|
uni.$on('onRemoteUserJoined', () => {
|
||||||
|
this.remoteRinging = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
uni.$off('onCallConnected')
|
||||||
|
uni.$off('onCallDisconnected')
|
||||||
|
uni.$off('onRemoteUserRinging')
|
||||||
|
uni.$off('onRemoteUserJoined')
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
windowWidth() {
|
||||||
|
return uni.getSystemInfoSync().windowWidth
|
||||||
|
},
|
||||||
|
windowHeight() {
|
||||||
|
return uni.getSystemInfoSync().windowHeight
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
changeMicrophone() {
|
||||||
|
CallLib.enableMicrophone(this.micStatus)
|
||||||
|
this.micStatus = !this.micStatus
|
||||||
|
},
|
||||||
|
changeSpeaker() {
|
||||||
|
CallLib.enableSpeaker(this.speStatus)
|
||||||
|
this.speStatus = !this.speStatus
|
||||||
|
},
|
||||||
|
accept() {
|
||||||
|
CallLib.accept()
|
||||||
|
// 视频通话,才开摄像头
|
||||||
|
if (this.mediaType == 1) {
|
||||||
|
const session = CallLib.getCurrentCallSession()
|
||||||
|
this.users = session.users
|
||||||
|
setTimeout(() => {
|
||||||
|
CallLib.setVideoView(session.targetId, this.$refs.bigVideoView.ref, 0,
|
||||||
|
false)
|
||||||
|
CallLib.setVideoView(session.mine.userId, this.$refs.smallVideoView.ref, 0,
|
||||||
|
true)
|
||||||
|
}, 200)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
hangup() {
|
||||||
|
CallLib.hangup()
|
||||||
|
this.stopRing()
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
this.downRing()
|
||||||
|
uni.navigateBack()
|
||||||
|
// uni.redirectTo({
|
||||||
|
// url: '/pages/im/private/index?targetId=' + this.targetId + '&conversationType=1'
|
||||||
|
// })
|
||||||
|
}, 500);
|
||||||
|
},
|
||||||
|
toHome() {
|
||||||
|
uni.switchTab({
|
||||||
|
url: '/pages/im/index'
|
||||||
|
})
|
||||||
|
},
|
||||||
|
startRing() {
|
||||||
|
const innerAudioContext = uni.createInnerAudioContext()
|
||||||
|
this.innerAudioContext = innerAudioContext
|
||||||
|
innerAudioContext.autoplay = true
|
||||||
|
innerAudioContext.loop = true
|
||||||
|
innerAudioContext.src = '/static/im/sounds/call-ring.mp3'
|
||||||
|
innerAudioContext.onEnded(() => {
|
||||||
|
innerAudioContext.destroy()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
stopRing() {
|
||||||
|
this.innerAudioContext.stop()
|
||||||
|
},
|
||||||
|
downRing() {
|
||||||
|
const innerAudioContext = uni.createInnerAudioContext()
|
||||||
|
innerAudioContext.autoplay = true
|
||||||
|
innerAudioContext.src = '/static/im/sounds/call-down.mp3'
|
||||||
|
innerAudioContext.onEnded(() => {
|
||||||
|
innerAudioContext.destroy()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.call-page {
|
||||||
|
flex: 1;
|
||||||
|
flex-direction: column;
|
||||||
|
position: relative;
|
||||||
|
background: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bigVideoView {
|
||||||
|
background: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.smallVideoView {
|
||||||
|
position: absolute;
|
||||||
|
right: 100rpx;
|
||||||
|
top: 100rpx;
|
||||||
|
width: 180rpx;
|
||||||
|
height: 320rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.buttons {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 100rpx;
|
||||||
|
width: 750rpx;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-around;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
background: #34CE98;
|
||||||
|
width: 132rpx;
|
||||||
|
height: 132rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn .white {
|
||||||
|
color: #FFFFFF;
|
||||||
|
font-size: 32rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn.hangup {
|
||||||
|
background: #dd524d;
|
||||||
|
}
|
||||||
|
|
||||||
|
.call-user {
|
||||||
|
flex: 1;
|
||||||
|
position: fixed;
|
||||||
|
width: 750rpx;
|
||||||
|
top: 200rpx;
|
||||||
|
left: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nickname {
|
||||||
|
margin: 30rpx;
|
||||||
|
font-size: 40rpx;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -5,21 +5,24 @@
|
|||||||
<!-- 聊天窗口 -->
|
<!-- 聊天窗口 -->
|
||||||
<view class="chat-item" v-for="(item,index) in messages" :key="index">
|
<view class="chat-item" v-for="(item,index) in messages" :key="index">
|
||||||
<view class="chat-item-article" :class="item.messageDirection == 1 ? 'right' : 'left'">
|
<view class="chat-item-article" :class="item.messageDirection == 1 ? 'right' : 'left'">
|
||||||
<view class="chat-msg">
|
<view class="chat-msg">
|
||||||
<!-- 文字消息 -->
|
<!-- 文字消息 -->
|
||||||
<view class="chat-msg-text">{{ item.content.content }}</view>
|
<view class="chat-msg-text">{{ item.content.content }}</view>
|
||||||
<!-- 语音消息 -->
|
<!-- 语音消息 -->
|
||||||
<view class="chat-msg-audio" @click="onPlayMsg()">
|
<view class="chat-msg-audio" @click="onPlayMsg()">
|
||||||
<image v-if="item.messageDirection == 0" src="@/static/icon/audio_ green.png" mode="widthFix"></image>
|
<image v-if="item.messageDirection == 0" src="@/static/icon/audio_ green.png"
|
||||||
10"
|
mode="widthFix"></image>
|
||||||
<image v-if="item.messageDirection == 1" src="@/static/icon/audio_white.png" mode="widthFix"></image>
|
10"
|
||||||
|
<image v-if="item.messageDirection == 1" src="@/static/icon/audio_white.png"
|
||||||
|
mode="widthFix"></image>
|
||||||
</view>
|
</view>
|
||||||
<!-- 预留一些图片,语音表情包等位置 -->
|
<!-- 预留一些图片,语音表情包等位置 -->
|
||||||
</view>
|
</view>
|
||||||
<view class="chat-status" :class="{'hide': item.sentStatus == 50}"
|
<view class="chat-status" :class="{'hide': item.sentStatus == 50}"
|
||||||
v-if="item.messageDirection == 1">{{targetId}}{{ item.sentStatus == 50 ? '已读': '未读'}}</view>
|
v-if="item.messageDirection == 1">{{targetId}}{{ item.sentStatus == 50 ? '已读': '未读'}}</view>
|
||||||
<view class="chat-avatar" @click="showFriend(targetId, item.messageDirection)">
|
<view class="chat-avatar" @click="showFriend(targetId, item.messageDirection)">
|
||||||
<u-avatar v-if="item.messageDirection == 2" shape="square" bg-color="#ffffff" :src="userInfo.portraitUrl"></u-avatar>
|
<u-avatar v-if="item.messageDirection == 2" shape="square" bg-color="#ffffff"
|
||||||
|
:src="userInfo.portraitUrl"></u-avatar>
|
||||||
<u-avatar v-else shape="square" bg-color="#ffffff" :src="$store.getters.sender.portraitUrl" />
|
<u-avatar v-else shape="square" bg-color="#ffffff" :src="$store.getters.sender.portraitUrl" />
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -29,34 +32,36 @@
|
|||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
|
|
||||||
<view class="chat-footer">
|
<view class="chat-footer">
|
||||||
<view class="msg-type" @click="msgType">
|
<view class="msg-type" @click="msgType">
|
||||||
<image src="@/static/icon/key-icon.png" v-if="importTabs === 0" mode="widthFix"></image>
|
<image src="@/static/icon/key-icon.png" v-if="importTabs === 0" mode="widthFix"></image>
|
||||||
<image src="@/static/icon/msg-icon.png" v-if="importTabs === 1" mode="widthFix"></image>
|
<image src="@/static/icon/msg-icon.png" v-if="importTabs === 1" mode="widthFix"></image>
|
||||||
</view>
|
</view>
|
||||||
<block v-if="importTabs === 0">
|
<block v-if="importTabs === 0">
|
||||||
<button type="default" class="chat-mp3" hover-class="chat-hover" @touchstart="startAudio" @touchend="chendAudio">按住 说话</button>
|
<button type="default" class="chat-mp3" hover-class="chat-hover" @touchstart="startAudio"
|
||||||
</block>
|
@touchend="chendAudio">按住 说话</button>
|
||||||
<block v-if="importTabs === 1">
|
</block>
|
||||||
<input class="chat-input" type="text" v-model="inputTxt" confirm-type="发送" @confirm="send" cursor-spacing="10" />
|
<block v-if="importTabs === 1">
|
||||||
</block>
|
<input class="chat-input" type="text" v-model="inputTxt" confirm-type="发送" @confirm="send"
|
||||||
|
cursor-spacing="10" />
|
||||||
|
</block>
|
||||||
<button class="chat-push" :disabled="disabled" size="mini" @click="send">发送</button>
|
<button class="chat-push" :disabled="disabled" size="mini" @click="send">发送</button>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 录音中提示 -->
|
<!-- 录音中提示 -->
|
||||||
<view class="audio-transcribe" v-if="showAudioTranscribe">
|
<view class="audio-transcribe" v-if="showAudioTranscribe">
|
||||||
<image src="@/static/icon/record-icon.png" mode="widthFix"></image>
|
<image src="@/static/icon/record-icon.png" mode="widthFix"></image>
|
||||||
<view class="text">录音中 {{transcribeTime}} s</view>
|
<view class="text">录音中 {{transcribeTime}} s</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import * as RongIMLib from "@/uni_modules/RongCloud-IMWrapper/js_sdk/index"
|
import * as RongIMLib from "@/uni_modules/RongCloud-IMWrapper/js_sdk/index"
|
||||||
import im from '@/utils/im/index.js'
|
import im from '@/utils/im/index.js'
|
||||||
import permision from "@/js_sdk/wa-permission/permission.js"
|
import permision from "@/js_sdk/wa-permission/permission.js"
|
||||||
|
|
||||||
var transcribe
|
var transcribe
|
||||||
var recorderManager = uni.getRecorderManager()
|
var recorderManager = uni.getRecorderManager()
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@@ -72,11 +77,11 @@
|
|||||||
name: '',
|
name: '',
|
||||||
userId: '',
|
userId: '',
|
||||||
portraitUrl: ''
|
portraitUrl: ''
|
||||||
},
|
},
|
||||||
importTabs: 0,
|
importTabs: 0,
|
||||||
showAudioTranscribe:false,
|
showAudioTranscribe: false,
|
||||||
transcribeTime: 60,
|
transcribeTime: 60,
|
||||||
audioSrc: '',
|
audioSrc: '',
|
||||||
audioContextPaused: true
|
audioContextPaused: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -104,18 +109,19 @@
|
|||||||
this.getMessageList()
|
this.getMessageList()
|
||||||
|
|
||||||
// 监听消息回执
|
// 监听消息回执
|
||||||
RongIMLib.addReadReceiptReceivedListener((result) => {
|
RongIMLib.addReadReceiptReceivedListener(({
|
||||||
const res = result.data.message
|
data
|
||||||
if (res.targetId == this.targetId) {
|
}) => {
|
||||||
|
if (data.targetId == this.targetId) {
|
||||||
this.getMessageList()
|
this.getMessageList()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// 监听录音结束
|
// 监听录音结束
|
||||||
recorderManager.onStop(res => {
|
recorderManager.onStop(res => {
|
||||||
if(res.tempFilePath) this.audioSrc = res.tempFilePath
|
if (res.tempFilePath) this.audioSrc = res.tempFilePath
|
||||||
console.log('------------------获取到了录音的临时路径---------------')
|
console.log('------------------获取到了录音的临时路径---------------')
|
||||||
console.log(res.tempFilePath)
|
console.log(res.tempFilePath)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
onUnload() {
|
onUnload() {
|
||||||
@@ -155,66 +161,66 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// 播放语音消息
|
// 播放语音消息
|
||||||
onPlayMsg(){
|
onPlayMsg() {
|
||||||
let innerAudioContext = uni.createInnerAudioContext()
|
let innerAudioContext = uni.createInnerAudioContext()
|
||||||
innerAudioContext.src = this.audioSrc
|
innerAudioContext.src = this.audioSrc
|
||||||
if(this.audioContextPaused){
|
if (this.audioContextPaused) {
|
||||||
innerAudioContext.play()
|
innerAudioContext.play()
|
||||||
this.audioContextPaused = false
|
this.audioContextPaused = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
innerAudioContext.stop()
|
innerAudioContext.stop()
|
||||||
innerAudioContext.onStop(resStop => {
|
innerAudioContext.onStop(resStop => {
|
||||||
this.audioContextPaused = true
|
this.audioContextPaused = true
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
// 检查安卓录制权限
|
// 检查安卓录制权限
|
||||||
async getAndroidPermission(){
|
async getAndroidPermission() {
|
||||||
return await permision.requestAndroidPermission('android.permission.RECORD_AUDIO')
|
return await permision.requestAndroidPermission('android.permission.RECORD_AUDIO')
|
||||||
},
|
},
|
||||||
// 切换聊天信息
|
// 切换聊天信息
|
||||||
msgType(){
|
msgType() {
|
||||||
this.importTabs = this.importTabs === 1 ? 0: 1
|
this.importTabs = this.importTabs === 1 ? 0 : 1
|
||||||
},
|
},
|
||||||
// 录制语音消息
|
// 录制语音消息
|
||||||
startAudio(e){
|
startAudio(e) {
|
||||||
this.getAndroidPermission().then(code => {
|
this.getAndroidPermission().then(code => {
|
||||||
switch (code){
|
switch (code) {
|
||||||
case 1:
|
case 1:
|
||||||
this.showAudioTranscribe = true
|
this.showAudioTranscribe = true
|
||||||
recorderManager.start()
|
recorderManager.start()
|
||||||
transcribe = setInterval(() => {
|
transcribe = setInterval(() => {
|
||||||
this.transcribeTime -= 1
|
this.transcribeTime -= 1
|
||||||
if(this.transcribeTime === 0){
|
if (this.transcribeTime === 0) {
|
||||||
this.chendAudio()
|
this.chendAudio()
|
||||||
}
|
}
|
||||||
},1000)
|
}, 1000)
|
||||||
break;
|
break;
|
||||||
case 0:
|
case 0:
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: '暂无麦克风权限,请前往应用设置开启麦克风',
|
title: '暂无麦克风权限,请前往应用设置开启麦克风',
|
||||||
icon : 'none'
|
icon: 'none'
|
||||||
})
|
})
|
||||||
break;
|
break;
|
||||||
case -1:
|
case -1:
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: '应用权限错误',
|
title: '应用权限错误',
|
||||||
icon : 'none'
|
icon: 'none'
|
||||||
})
|
})
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
// 结束录音
|
// 结束录音
|
||||||
chendAudio(e){
|
chendAudio(e) {
|
||||||
if(!this.showAudioTranscribe) return
|
if (!this.showAudioTranscribe) return
|
||||||
recorderManager.stop()
|
recorderManager.stop()
|
||||||
clearInterval(transcribe)
|
clearInterval(transcribe)
|
||||||
this.transcribeTime = 60
|
this.transcribeTime = 60
|
||||||
this.showAudioTranscribe = false
|
this.showAudioTranscribe = false
|
||||||
},
|
},
|
||||||
getMessageList() {
|
getMessageList() {
|
||||||
// 获取消息列表
|
// 获取消息列表
|
||||||
const objectNames = [
|
const objectNames = [
|
||||||
@@ -253,10 +259,12 @@
|
|||||||
this.inputTxt = ''
|
this.inputTxt = ''
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
showFriend(targetId, type) {
|
showFriend(targetId, type) {
|
||||||
this.$Router.push({
|
this.$Router.push({
|
||||||
name: type === 1 ? 'imFriendsMine' : 'imFriendsInfo',
|
name: type === 1 ? 'imFriendsMine' : 'imFriendsInfo',
|
||||||
params: {targetId}
|
params: {
|
||||||
|
targetId
|
||||||
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
scrollBottom() {
|
scrollBottom() {
|
||||||
@@ -285,31 +293,33 @@
|
|||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.chat-content {
|
.chat-content {
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
background: $window-color;
|
background: $window-color;
|
||||||
|
|
||||||
.audio-transcribe{
|
.audio-transcribe {
|
||||||
background: rgba($color: #000000, $alpha: .6);
|
background: rgba($color: #000000, $alpha: .6);
|
||||||
position: fixed;
|
position: fixed;
|
||||||
height: 200rpx;
|
height: 200rpx;
|
||||||
width: 300rpx;
|
width: 300rpx;
|
||||||
border-radius: $radius;
|
border-radius: $radius;
|
||||||
color: white;
|
color: white;
|
||||||
z-index: 99;
|
z-index: 99;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
margin-top: -200rpx;
|
margin-top: -200rpx;
|
||||||
margin-left: -150rpx;
|
margin-left: -150rpx;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
image{
|
|
||||||
width: 88rpx;
|
image {
|
||||||
height: 88rpx;
|
width: 88rpx;
|
||||||
}
|
height: 88rpx;
|
||||||
.text{
|
}
|
||||||
font-size: $title-size-m;
|
|
||||||
}
|
.text {
|
||||||
|
font-size: $title-size-m;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-scrool {
|
.chat-scrool {
|
||||||
@@ -341,22 +351,25 @@
|
|||||||
|
|
||||||
.chat-msg {
|
.chat-msg {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
.chat-msg-text {
|
.chat-msg-text {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding: ($padding - 10) $padding;
|
padding: ($padding - 10) $padding;
|
||||||
color: $text-color;
|
color: $text-color;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
font-size: $title-size-lg;
|
font-size: $title-size-lg;
|
||||||
}
|
}
|
||||||
.chat-msg-audio{
|
|
||||||
@extend .chat-msg-text;
|
.chat-msg-audio {
|
||||||
width: 50%;
|
@extend .chat-msg-text;
|
||||||
image{
|
width: 50%;
|
||||||
width: 38rpx;
|
|
||||||
height: 38rpx;
|
image {
|
||||||
margin: 0;
|
width: 38rpx;
|
||||||
vertical-align: middle;
|
height: 38rpx;
|
||||||
}
|
margin: 0;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -372,15 +385,16 @@
|
|||||||
|
|
||||||
.chat-avatar {
|
.chat-avatar {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
background: white;
|
background: white;
|
||||||
border-radius: $radius-m;
|
border-radius: $radius-m;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.left {
|
&.left {
|
||||||
.chat-avatar {
|
.chat-avatar {
|
||||||
left: $margin;
|
left: $margin;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-msg {
|
.chat-msg {
|
||||||
.chat-msg-text {
|
.chat-msg-text {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
@@ -396,6 +410,7 @@
|
|||||||
|
|
||||||
.chat-msg {
|
.chat-msg {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
|
|
||||||
.chat-msg-text {
|
.chat-msg-text {
|
||||||
border-radius: $radius*2 0 $radius*2 $radius*2;
|
border-radius: $radius*2 0 $radius*2 $radius*2;
|
||||||
background: $main-color;
|
background: $main-color;
|
||||||
@@ -417,18 +432,21 @@
|
|||||||
background: white;
|
background: white;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
z-index: 99;
|
z-index: 99;
|
||||||
.msg-type{
|
|
||||||
position: absolute;
|
.msg-type {
|
||||||
top: 20rpx;
|
position: absolute;
|
||||||
left: $padding;
|
top: 20rpx;
|
||||||
line-height: 80rpx;
|
left: $padding;
|
||||||
image{
|
line-height: 80rpx;
|
||||||
width: 64rpx;
|
|
||||||
height: 64rpx;
|
image {
|
||||||
vertical-align: middle;
|
width: 64rpx;
|
||||||
margin-bottom: 10rpx;
|
height: 64rpx;
|
||||||
}
|
vertical-align: middle;
|
||||||
|
margin-bottom: 10rpx;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-input {
|
.chat-input {
|
||||||
background: $window-color;
|
background: $window-color;
|
||||||
height: 80rpx;
|
height: 80rpx;
|
||||||
@@ -436,23 +454,24 @@
|
|||||||
font-size: $title-size-m;
|
font-size: $title-size-m;
|
||||||
padding: 0 $padding;
|
padding: 0 $padding;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-mp3{
|
.chat-mp3 {
|
||||||
background: $window-color;
|
background: $window-color;
|
||||||
line-height: 80rpx;
|
line-height: 80rpx;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
border-radius: $radius-lg;
|
border-radius: $radius-lg;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #333;
|
color: #333;
|
||||||
font-size: $title-size-m;
|
font-size: $title-size-m;
|
||||||
&::after{
|
|
||||||
display: none;
|
&::after {
|
||||||
}
|
display: none;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
.chat-hover{
|
|
||||||
opacity: .5;
|
.chat-hover {
|
||||||
|
opacity: .5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-push[size='mini'] {
|
.chat-push[size='mini'] {
|
||||||
|
|||||||
@@ -1,24 +1,36 @@
|
|||||||
import { RouterMount, createRouter } from 'uni-simple-router';
|
import {
|
||||||
import store from '@/store/index'
|
RouterMount,
|
||||||
|
createRouter
|
||||||
|
} from 'uni-simple-router';
|
||||||
|
import store from '@/store/index'
|
||||||
|
|
||||||
|
// #ifdef APP-NVUE
|
||||||
|
// CALL 页面,必须是nvue,但是NVUE 不支持webpack的 ROUTES 注入
|
||||||
|
// https://github.com/SilurianYang/uni-read-pages/issues/20
|
||||||
|
const ROUTES = [{
|
||||||
|
'path': '/pages/im/private/call',
|
||||||
|
'name': 'imPrivateCall'
|
||||||
|
}]
|
||||||
|
// #endif
|
||||||
|
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
platform: process.env.VUE_APP_PLATFORM,
|
platform: process.env.VUE_APP_PLATFORM,
|
||||||
routes: [...ROUTES]
|
routes: [...ROUTES]
|
||||||
});
|
});
|
||||||
|
|
||||||
// console.log(...ROUTES)
|
// console.log(...ROUTES)
|
||||||
|
|
||||||
//全局路由前置守卫
|
//全局路由前置守卫
|
||||||
router.beforeEach((to, from, next) => {
|
router.beforeEach((to, from, next) => {
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
|
|
||||||
// 全局路由后置守卫
|
// 全局路由后置守卫
|
||||||
router.afterEach((to, from) => {
|
router.afterEach((to, from) => {
|
||||||
// console.log('跳转结束')
|
// console.log('跳转结束')
|
||||||
})
|
})
|
||||||
|
|
||||||
export {
|
export {
|
||||||
router,
|
router,
|
||||||
RouterMount
|
RouterMount
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
static/im/sounds/call-down.mp3
Normal file
BIN
static/im/sounds/call-down.mp3
Normal file
Binary file not shown.
BIN
static/im/sounds/call-ring.mp3
Normal file
BIN
static/im/sounds/call-ring.mp3
Normal file
Binary file not shown.
BIN
static/im/sounds/new-msg.mp3
Normal file
BIN
static/im/sounds/new-msg.mp3
Normal file
Binary file not shown.
BIN
utils/im/.DS_Store
vendored
Normal file
BIN
utils/im/.DS_Store
vendored
Normal file
Binary file not shown.
@@ -1,4 +1,5 @@
|
|||||||
import * as RongIMLib from "@/uni_modules/RongCloud-IMWrapper/js_sdk/index"
|
import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
|
||||||
|
import * as CallLib from '@/uni_modules/RongCloud-CallWrapper/lib/index'
|
||||||
import store from '@/store/index.js'
|
import store from '@/store/index.js'
|
||||||
import {
|
import {
|
||||||
getFriends,
|
getFriends,
|
||||||
@@ -7,6 +8,7 @@ import {
|
|||||||
|
|
||||||
const initIm = (KEY) => {
|
const initIm = (KEY) => {
|
||||||
RongIMLib.init(KEY)
|
RongIMLib.init(KEY)
|
||||||
|
CallLib.init()
|
||||||
addListeners()
|
addListeners()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,8 +40,8 @@ const setNotifyBadge = () => {
|
|||||||
*/
|
*/
|
||||||
const connect = (token, userInfo, callback) => {
|
const connect = (token, userInfo, callback) => {
|
||||||
RongIMLib.connect(token, res => {
|
RongIMLib.connect(token, res => {
|
||||||
console.log('连接结果', res);
|
console.log('连接结果', res);
|
||||||
|
|
||||||
callback(res)
|
callback(res)
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -58,23 +60,23 @@ const connect = (token, userInfo, callback) => {
|
|||||||
|
|
||||||
const disconnect = () => {
|
const disconnect = () => {
|
||||||
RongIMLib.disconnect()
|
RongIMLib.disconnect()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 允许通知的消息类型,触发更新消息列表操作
|
// 允许通知的消息类型,触发更新消息列表操作
|
||||||
const notifyMsgTypes = [
|
const notifyMsgTypes = [
|
||||||
'RC:TxtMsg',
|
'RC:TxtMsg',
|
||||||
'RC:VcMsg',
|
'RC:VcMsg',
|
||||||
'RC:HQVCMsg',
|
'RC:HQVCMsg',
|
||||||
'RC:ImgMsg',
|
'RC:ImgMsg',
|
||||||
'RC:GIFMsg',
|
'RC:GIFMsg',
|
||||||
'RC:ImgTextMsg',
|
'RC:ImgTextMsg',
|
||||||
'RC:FileMsg',
|
'RC:FileMsg',
|
||||||
'RC:LBSMsg',
|
'RC:LBSMsg',
|
||||||
'RC:SightMsg',
|
'RC:SightMsg',
|
||||||
'RC:ReferenceMsg',
|
'RC:ReferenceMsg',
|
||||||
'RC:CombineMsg',
|
'RC:CombineMsg',
|
||||||
]
|
]
|
||||||
|
|
||||||
function inArray(search, array) {
|
function inArray(search, array) {
|
||||||
for (var i in array) {
|
for (var i in array) {
|
||||||
if (array[i] == search) {
|
if (array[i] == search) {
|
||||||
@@ -82,22 +84,56 @@ function inArray(search, array) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const addListeners = () => {
|
const addListeners = () => {
|
||||||
// 添加连接状态监听函数
|
// 添加连接状态监听函数
|
||||||
RongIMLib.addConnectionStatusListener((res) => {
|
RongIMLib.addConnectionStatusListener((res) => {
|
||||||
console.log('连接状态监', res.data.status);
|
console.log('连接状态监', res.data.status);
|
||||||
store.dispatch('updateConnectionStatus', res.data.status)
|
store.dispatch('updateConnectionStatus', res.data.status)
|
||||||
})
|
})
|
||||||
// 添加消息监听函数
|
// 添加消息监听函数
|
||||||
RongIMLib.addReceiveMessageListener((res) => {
|
RongIMLib.addReceiveMessageListener((res) => {
|
||||||
console.log('收到消息', res.data.message);
|
console.log('收到消息', res.data.message);
|
||||||
const message = res.data.message
|
const message = res.data.message
|
||||||
if (inArray(message.objectName, notifyMsgTypes)) {
|
if (inArray(message.objectName, notifyMsgTypes)) {
|
||||||
newMessage(message)
|
newMessage(message)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
// 监听通话呼入
|
||||||
|
CallLib.onCallReceived((res) => {
|
||||||
|
console.log("Engine:OnCallReceived=>" + "监听通话呼入, 目标id=>", res.data.targetId);
|
||||||
|
console.log('RES', res);
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages/im/private/call?targetId=' + res.data.targetId + '&mediaType=' +
|
||||||
|
res.data.mediaType,
|
||||||
|
success: (err) => {
|
||||||
|
console.log('跳转视频通话成功');
|
||||||
|
},
|
||||||
|
fail: (err) => {
|
||||||
|
console.log('跳转视频页失败', err);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
CallLib.onCallConnected((res) => {
|
||||||
|
uni.$emit('onCallConnected');
|
||||||
|
})
|
||||||
|
CallLib.onCallOutgoing((res) => {
|
||||||
|
uni.$emit('onCallOutgoing');
|
||||||
|
})
|
||||||
|
CallLib.onRemoteUserRinging((res) => {
|
||||||
|
uni.$emit('onRemoteUserRinging');
|
||||||
|
})
|
||||||
|
CallLib.onRemoteUserJoined((res) => {
|
||||||
|
uni.$emit('onRemoteUserJoined');
|
||||||
|
})
|
||||||
|
CallLib.onCallDisconnected((res) => {
|
||||||
|
uni.$emit('onCallDisconnected');
|
||||||
|
})
|
||||||
|
CallLib.onRemoteUserLeft((res) => {
|
||||||
|
uni.$emit('onCallDisconnected');
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 维护消息列表
|
// 维护消息列表
|
||||||
@@ -135,7 +171,7 @@ const triTone = () => {
|
|||||||
if (tipState == false) {
|
if (tipState == false) {
|
||||||
const innerAudioContext = uni.createInnerAudioContext()
|
const innerAudioContext = uni.createInnerAudioContext()
|
||||||
innerAudioContext.autoplay = true
|
innerAudioContext.autoplay = true
|
||||||
innerAudioContext.src = '/static/tri-tone.mp3'
|
innerAudioContext.src = '/utils/im/sounds/new-msg.mp3'
|
||||||
innerAudioContext.onPlay(() => {
|
innerAudioContext.onPlay(() => {
|
||||||
tipState = true
|
tipState = true
|
||||||
})
|
})
|
||||||
@@ -194,6 +230,6 @@ export default {
|
|||||||
connect,
|
connect,
|
||||||
sendMsg,
|
sendMsg,
|
||||||
setNotifyBadge,
|
setNotifyBadge,
|
||||||
syncFriends,
|
syncFriends,
|
||||||
syncUserInfo
|
syncUserInfo
|
||||||
}
|
}
|
||||||
|
|||||||
51
utils/im/视频呼入.json
Normal file
51
utils/im/视频呼入.json
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
{
|
||||||
|
"type": "Engine:OnCallReceived",
|
||||||
|
"module": "RongCloud-Call-RCUniCall",
|
||||||
|
"data": {
|
||||||
|
"endTime": 0,
|
||||||
|
"users": [{
|
||||||
|
"userId": "10051",
|
||||||
|
"enableCamera": false,
|
||||||
|
"mediaId": "420111350",
|
||||||
|
"mediaType": 1,
|
||||||
|
"userType": 0,
|
||||||
|
"enableMicrophone": false
|
||||||
|
}, {
|
||||||
|
"userId": "10047",
|
||||||
|
"enableCamera": false,
|
||||||
|
"mediaType": 1,
|
||||||
|
"userType": 0,
|
||||||
|
"enableMicrophone": false
|
||||||
|
}],
|
||||||
|
"inviter": {
|
||||||
|
"userId": "10051",
|
||||||
|
"enableCamera": false,
|
||||||
|
"mediaId": "420111350",
|
||||||
|
"mediaType": 1,
|
||||||
|
"userType": 0,
|
||||||
|
"enableMicrophone": false
|
||||||
|
},
|
||||||
|
"caller": {
|
||||||
|
"userId": "10051",
|
||||||
|
"enableCamera": false,
|
||||||
|
"mediaId": "420111350",
|
||||||
|
"mediaType": 1,
|
||||||
|
"userType": 0,
|
||||||
|
"enableMicrophone": false
|
||||||
|
},
|
||||||
|
"connectedTime": 0,
|
||||||
|
"extra": "",
|
||||||
|
"startTime": 0,
|
||||||
|
"mediaType": 1,
|
||||||
|
"callId": "c28cb9d8-6581-474c-bfa5-9872a4824b65",
|
||||||
|
"targetId": "10051",
|
||||||
|
"callType": 0,
|
||||||
|
"mine": {
|
||||||
|
"userId": "10047",
|
||||||
|
"enableCamera": false,
|
||||||
|
"mediaType": 1,
|
||||||
|
"userType": 0,
|
||||||
|
"enableMicrophone": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
51
utils/im/语音呼入.json
Normal file
51
utils/im/语音呼入.json
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
{
|
||||||
|
"type": "Engine:OnCallReceived",
|
||||||
|
"module": "RongCloud-Call-RCUniCall",
|
||||||
|
"data": {
|
||||||
|
"endTime": 0,
|
||||||
|
"users": [{
|
||||||
|
"userId": "10051",
|
||||||
|
"enableCamera": false,
|
||||||
|
"mediaId": "420068630",
|
||||||
|
"mediaType": 0,
|
||||||
|
"userType": 0,
|
||||||
|
"enableMicrophone": false
|
||||||
|
}, {
|
||||||
|
"userId": "10047",
|
||||||
|
"enableCamera": true,
|
||||||
|
"mediaType": 0,
|
||||||
|
"userType": 0,
|
||||||
|
"enableMicrophone": false
|
||||||
|
}],
|
||||||
|
"inviter": {
|
||||||
|
"userId": "10051",
|
||||||
|
"enableCamera": false,
|
||||||
|
"mediaId": "420068630",
|
||||||
|
"mediaType": 0,
|
||||||
|
"userType": 0,
|
||||||
|
"enableMicrophone": false
|
||||||
|
},
|
||||||
|
"caller": {
|
||||||
|
"userId": "10051",
|
||||||
|
"enableCamera": false,
|
||||||
|
"mediaId": "420068630",
|
||||||
|
"mediaType": 0,
|
||||||
|
"userType": 0,
|
||||||
|
"enableMicrophone": false
|
||||||
|
},
|
||||||
|
"connectedTime": 0,
|
||||||
|
"extra": "",
|
||||||
|
"startTime": 0,
|
||||||
|
"mediaType": 0,
|
||||||
|
"callId": "1a1462b8-b63b-40a9-bf95-963e810ac49a",
|
||||||
|
"targetId": "10051",
|
||||||
|
"callType": 0,
|
||||||
|
"mine": {
|
||||||
|
"userId": "10047",
|
||||||
|
"enableCamera": true,
|
||||||
|
"mediaType": 0,
|
||||||
|
"userType": 0,
|
||||||
|
"enableMicrophone": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user