Skip to content

Commit e8acc57

Browse files
committed
sync with vue-pc-chat
1 parent 3d70a5d commit e8acc57

12 files changed

+109
-19
lines changed

src/main.js

+3
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ app.use(CoolLightBox)
7070
subWindowLoadDataOptions.loadFriendList = true
7171
subWindowLoadDataOptions.loadDefaultConversationList = true
7272
}
73+
if ( path.startsWith('/workspace')) {
74+
subWindowLoadDataOptions.loadFriendList = true
75+
}
7376
store.init(false, subWindowLoadDataOptions);
7477
}
7578
// web

src/store.js

+9-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import Vue from 'vue'
33
import wfc from "./wfc/client/wfc";
44
import EventType from "./wfc/client/wfcEvent";
55
import ConversationType from "./wfc/model/conversationType";
6-
import {eq, gt, numberValue} from "./wfc/util/longUtil";
6+
import {eq, gt, lt, numberValue} from "./wfc/util/longUtil";
77
import helper from "./ui/util/helper";
88
import convert from './vendor/pinyin'
99
import GroupType from "./wfc/model/groupType";
@@ -249,8 +249,14 @@ let store = {
249249
if (msgIndex > -1) {
250250
// FYI: https://v2.vuejs.org/v2/guide/reactivity#Change-Detection-Caveats
251251
conversationState.currentConversationMessageList.splice(msgIndex, 1, msg);
252-
console.log('msg duplicate')
252+
console.log('msg duplicate, update message')
253253
return;
254+
} else {
255+
let firstMsg = conversationState.currentConversationMessageList[0];
256+
if(firstMsg && lt(msg.timestamp, firstMsg.timestamp)) {
257+
console.log('msg timestamp is less than first msg, maybe update old message content, ignore')
258+
return;
259+
}
254260
}
255261

256262
conversationState.currentConversationMessageList.push(msg);
@@ -592,11 +598,11 @@ let store = {
592598

593599
if (conversationState.currentConversationInfo && conversationState.currentConversationInfo.conversation.equal(conversation)) {
594600
let isClearConversationMessageHistory = !conversationInfo.lastMessage && !!conversationState.currentConversationInfo.lastMessage;
595-
conversationState.currentConversationInfo = conversationInfo;
596601
// 清除聊天记录
597602
if (isClearConversationMessageHistory) {
598603
conversationState.currentConversationMessageList = [];
599604
}
605+
conversationState.currentConversationInfo = conversationInfo;
600606
}
601607

602608
// sort

src/ui/common/Alert.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ export default {
2424
this.$modal.show(
2525
AlertView,
2626
{
27+
name: options.name ? options.name : 'alert-modal',
2728
showIcon: showIcon,
2829
title: options.title,
2930
content: options.content,
@@ -32,7 +33,7 @@ export default {
3233
},
3334
null,
3435
{
35-
name: 'alert-modal',
36+
name: options.name ? options.name : 'alert-modal',
3637
clickToClose: true,
3738
adaptive: true,
3839
width: 260,

src/ui/common/AlertView.vue

+7-2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@
1616
export default {
1717
name: "AlertView",
1818
props: {
19+
name: {
20+
type: String,
21+
required: true,
22+
default: '',
23+
},
1924
showIcon: {
2025
type: Boolean,
2126
required: false,
@@ -53,11 +58,11 @@ export default {
5358
},
5459
methods: {
5560
cancel() {
56-
this.$modal.hide('alert-modal', {cancel: true})
61+
this.$modal.hide(this.name, {cancel: true})
5762
},
5863
5964
confirm() {
60-
this.$modal.hide('alert-modal', {confirm: true})
65+
this.$modal.hide(this.name, {confirm: true})
6166
},
6267
}
6368
}

src/ui/main/conversation/MessageInputView.vue

+22
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@
5353
<li v-if="!inputOptions['disableVideoCall']">
5454
<i @click="startVideoCall" class="icon-ion-ios-videocam"/>
5555
</li>
56+
<li v-if="sharedMiscState.isElectron && !inputOptions['disableVideoCall'] && conversationInfo.conversation.type === 0">
57+
<i @click="requestRemoteControl" class="icon-ion-android-desktop"/>
58+
</li>
5659
</template>
5760
<li v-if="!inputOptions['disableChannelMenu'] && conversationInfo.conversation.type === 3 && conversationInfo.conversation._target.menus && conversationInfo.conversation._target.menus.length">
5861
<i @click="toggleChannelMenu" class="icon-ion-android-menu"/>
@@ -133,6 +136,8 @@ import TypingMessageContent from "../../../wfc/messages/typingMessageContent";
133136
import {currentWindow, fs} from "../../../platform";
134137
import {vOnClickOutside} from '@vueuse/components'
135138
import SendMixMediaMessageView from "../view/SendMixMediaMessageView.vue";
139+
import avenginekitproxy from "../../../wfc/av/engine/avenginekitproxy";
140+
import avenginekit from "../../../wfc/av/internal/engine.min";
136141
137142
export default {
138143
name: "MessageInputView",
@@ -557,6 +562,23 @@ export default {
557562
this.$startVoipCall({audioOnly: false, conversation: conversation});
558563
},
559564
565+
requestRemoteControl(){
566+
if(avenginekit.startConference){
567+
if(process.platform === 'linux'){
568+
this.$notify({
569+
text:'远程协助,目前只支持 Windows 和 macOS',
570+
type:'error',
571+
})
572+
return
573+
}
574+
avenginekitproxy.requestRemoteControl(this.conversationInfo.conversation);
575+
}else {
576+
this.$notify({
577+
text:'需要高级版音视频才支持远程协助',
578+
type:'error',
579+
})
580+
}
581+
},
560582
toggleChannelMenu(toggle = true) {
561583
if (toggle) {
562584
this.$parent.$refs['conversationMessageList'].style.flexGrow = 1;

src/ui/voip/ScreenOrWindowPicker.vue

+20-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<template>
22
<section class="screen-window-picker-container" ref="contentContainer">
3-
<h2 class="title">选择要分享什么</h2>
4-
<p class="desc">WFC想分享您屏幕上的内容</p>
3+
<h2 class="title">{{ title }}</h2>
4+
<p class="desc">{{ desc }}</p>
55
<div class="category-container">
66
<div class="category" v-bind:class="{active:this.currentCategory === 'screen'}"
77
@click="setCategory('screen')">
@@ -48,6 +48,23 @@ import IpcEventType from "../../ipcEventType";
4848

4949
export default {
5050
name: "ScreenOrWindowPicker",
51+
props: {
52+
title: {
53+
type: String,
54+
required: false,
55+
default: "选择要分享什么"
56+
},
57+
desc: {
58+
type: String,
59+
required: false,
60+
default: "WFC想分享您屏幕上的内容"
61+
},
62+
types: {
63+
type: Array,
64+
required: false,
65+
default: ['screen', 'window']
66+
}
67+
},
5168
data() {
5269
return {
5370
currentCategory: 'screen', // window
@@ -95,8 +112,7 @@ export default {
95112
},
96113

97114
mounted() {
98-
let types = ['screen', 'window'];
99-
ipcRenderer.invoke(IpcEventType.GET_SOURCE, {types: types, thumbnailSize: {width: 200, height: 200}, fetchWindowIcons: true})
115+
ipcRenderer.invoke(IpcEventType.GET_SOURCE, {types: this.types, thumbnailSize: {width: 200, height: 200}, fetchWindowIcons: true})
100116
.then(sources => {
101117
this.screenSources = sources.filter(source => source.id.startsWith('screen'))
102118
this.windowSources = sources.filter(source => source.id.startsWith('window'))

src/ui/voip/ScreenShareControlView.vue

+15-2
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@
1919
<p>开启视频</p>
2020
</div>
2121
<div class="action">
22-
<img @click="stopScreenShare" class="action-img" src='@/assets/images/av_video_answer.png'/>
23-
<p>结束共享</p>
22+
<img @click="stopScreenShare" class="action-img" src='@/assets/images/av_hang_up.png'/>
23+
<p>{{ stopScreenShareTitle}}</p>
2424
</div>
2525
</div>
2626

@@ -38,6 +38,15 @@ export default {
3838
type: String,
3939
default: null,
4040
},
41+
stopScreenShareTitle: {
42+
type: String,
43+
required: false,
44+
default: '结束共享',
45+
},
46+
stopScreenShareFunc: {
47+
type: Function,
48+
required: false,
49+
}
4150
},
4251
data() {
4352
return {
@@ -88,6 +97,10 @@ export default {
8897
},
8998
9099
stopScreenShare() {
100+
if (this.stopScreenShareFunc) {
101+
this.stopScreenShareFunc();
102+
return
103+
}
91104
console.log('stopScreenShare', this.session);
92105
this.session.stopScreenShare();
93106
console.log('stopScreenShare', this.session.videoMuted, this.session.audioMuted);

src/wfc/av/engine/avenginekit.js

+11
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ export default class WfcAVEngineKit {
3333
*/
3434
static SCREEN_SHARING_REPLACE_MODE = true;
3535

36+
/**
37+
* 是否启用 datachannel
38+
* @type {boolean}
39+
*/
40+
static ENABLE_DATA_CHANNEL = false
41+
3642
/**
3743
禁止双流模式下,小流低帧率。默认为false,小流的帧率为8fps。当为true时使用 {@link SMALL_STREAM_FPS}, 或者使用同大流一样的帧率
3844
*/
@@ -67,6 +73,11 @@ export default class WfcAVEngineKit {
6773
*/
6874

6975
static FORCE_MEDIA_OVER_TCP = false;
76+
/**
77+
* 没有麦克风和音频输出设备时,是否允许发起或参加音视频通话
78+
* @type {boolean}
79+
*/
80+
static ENABLE_VOIP_WHEN_NO_MIC_AND_SPEAKER= true;
7081

7182
/**
7283
* 高级版音视频 SDK 有效

src/wfc/av/engine/avenginekitproxy.js

+14-4
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ export class AvEngineKitProxy {
8686
let content = message.content;
8787

8888
let msg = wfc.getMessageByUid(messageUid);
89+
if (!msg) {
90+
return
91+
}
8992
let orgContent = msg.messageContent;
9093
orgContent.connectTime = content.connectTime ? content.connectTime : orgContent.connectTime;
9194
orgContent.endTime = content.endTime ? content.endTime : orgContent.endTime;
@@ -169,6 +172,10 @@ export class AvEngineKitProxy {
169172
console.log('not enable multi call ');
170173
return;
171174
}
175+
if (!isElectron() && msg.messageContent === MessageContentType.VOIP_REMOTE_CONTROL_REQUEST) {
176+
console.log('only pc support remote control');
177+
return;
178+
}
172179
let now = (new Date()).valueOf();
173180
let delta = wfc.getServerDeltaTime();
174181
if (now - (numberValue(msg.timestamp) - delta) >= 90 * 1000) {
@@ -193,7 +200,7 @@ export class AvEngineKitProxy {
193200
this.onVoipCallErrorCallback && this.onVoipCallErrorCallback(-1);
194201
}
195202
}
196-
if (!this.isSupportVoip || !this.hasMicrophone || !this.hasSpeaker) {
203+
if (!this.isSupportVoip || (!WfcAVEngineKit.ENABLE_VOIP_WHEN_NO_MIC_AND_SPEAKER && (!this.hasSpeaker || !this.hasMicrophone))) {
197204
this.onVoipCallErrorCallback && this.onVoipCallErrorCallback(-2);
198205
return;
199206
}
@@ -241,6 +248,9 @@ export class AvEngineKitProxy {
241248
}
242249
if (!this.callWin) {
243250
if (this.conversation) {
251+
msg.participantUserInfos = participantUserInfos;
252+
msg.selfUserInfo = selfUserInfo;
253+
msg.timestamp = longValue(numberValue(msg.timestamp) - delta)
244254
this.showCallUI(msg.conversation, false, {
245255
event: 'message',
246256
args: msg
@@ -369,7 +379,7 @@ export class AvEngineKitProxy {
369379
return;
370380
}
371381
console.log(`startCall speaker、microphone、webcam检测结果分别为:${this.hasSpeaker} , ${this.hasMicrophone}, ${this.hasWebcam},如果不全为true,请检查硬件设备是否正常,否则通话可能存在异常`)
372-
if (!this.isSupportVoip || !this.hasSpeaker || !this.hasMicrophone) {
382+
if (!this.isSupportVoip || (!WfcAVEngineKit.ENABLE_VOIP_WHEN_NO_MIC_AND_SPEAKER && (!this.hasSpeaker || !this.hasMicrophone))) {
373383
console.log('not support voip', this.isSupportVoip, this.hasSpeaker, this.hasMicrophone, this.hasWebcam);
374384
this.onVoipCallErrorCallback && this.onVoipCallErrorCallback(-2);
375385
return;
@@ -428,7 +438,7 @@ export class AvEngineKitProxy {
428438
this.onVoipCallErrorCallback && this.onVoipCallErrorCallback(-1);
429439
return;
430440
}
431-
if (!this.isSupportVoip || !this.hasSpeaker || !this.hasMicrophone) {
441+
if (!this.isSupportVoip || (!WfcAVEngineKit.ENABLE_VOIP_WHEN_NO_MIC_AND_SPEAKER && (!this.hasSpeaker || !this.hasMicrophone))) {
432442
console.log('not support voip', this.isSupportVoip, this.hasSpeaker);
433443
this.onVoipCallErrorCallback && this.onVoipCallErrorCallback(-2);
434444
return;
@@ -488,7 +498,7 @@ export class AvEngineKitProxy {
488498
this.onVoipCallErrorCallback && this.onVoipCallErrorCallback(-1);
489499
return;
490500
}
491-
if (!this.isSupportVoip || !this.hasSpeaker || !this.hasMicrophone) {
501+
if (!this.isSupportVoip || (!WfcAVEngineKit.ENABLE_VOIP_WHEN_NO_MIC_AND_SPEAKER && (!this.hasSpeaker || !this.hasMicrophone))) {
492502
console.log('not support voip', this.isSupportVoip, this.hasSpeaker, this.hasMicrophone);
493503
this.onVoipCallErrorCallback && this.onVoipCallErrorCallback(-2);
494504
return;

src/wfc/av/engine/subscriber.js

+3
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ export default class Subscriber {
1414
audience = false;
1515
currentVideoType;
1616

17+
// 单向,只能用来对方发送来的数据,需要向其他人发送数据时,需要使用 publisherImpl.dataChannel
18+
dataChannel
19+
1720
constructor (userId) {
1821
this.userId = userId;
1922
}

src/wfc/av/internal/engine-conference.min.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/wfc/client/wfc.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -1950,7 +1950,7 @@ export class WfcManager {
19501950

19511951
/**
19521952
*
1953-
* 群里面是否开启了已送达报告和已读报告功能
1953+
* 是否开启了群组已读报告功能
19541954
* @return {boolean}
19551955
*/
19561956
isGroupReceiptEnabled() {
@@ -2010,7 +2010,7 @@ export class WfcManager {
20102010
}
20112011

20122012
/**
2013-
*
2013+
* 获取会话的阅读状态。
20142014
* @param conversation
20152015
* @return {Map<string, Long>}
20162016
*/

0 commit comments

Comments
 (0)