mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-17 19:18:06 +00:00
FIx active speaker mode
This commit is contained in:
parent
027cb1ec2d
commit
f771bdc790
11 changed files with 366 additions and 212 deletions
|
|
@ -50,6 +50,7 @@ class TelecomManager: ObservableObject {
|
|||
@Published var isPausedByRemote: Bool = false
|
||||
@Published var refreshCallViewModel: Bool = false
|
||||
@Published var remainingCall: Bool = false
|
||||
@Published var callConnected: Bool = false
|
||||
|
||||
var actionToFulFill: CXCallAction?
|
||||
var callkitAudioSessionActivated: Bool?
|
||||
|
|
@ -155,10 +156,10 @@ class TelecomManager: ObservableObject {
|
|||
}
|
||||
}
|
||||
|
||||
func doCallWithCore(addr: Address, isVideo: Bool) {
|
||||
func doCallWithCore(addr: Address, isVideo: Bool, isConference: Bool) {
|
||||
CoreContext.shared.doOnCoreQueue { core in
|
||||
do {
|
||||
try self.startCallCallKit(core: core, addr: addr, isSas: false, isVideo: isVideo, isConference: false)
|
||||
try self.startCallCallKit(core: core, addr: addr, isSas: false, isVideo: isVideo, isConference: isConference)
|
||||
} catch {
|
||||
Log.error("[TelecomManager] unable to create address for a new outgoing call : \(addr) \(error) ")
|
||||
}
|
||||
|
|
@ -213,6 +214,7 @@ class TelecomManager: ObservableObject {
|
|||
lcallParams.mediaEncryption = .ZRTP
|
||||
}
|
||||
if isConference {
|
||||
lcallParams.videoEnabled = true
|
||||
/* if (ConferenceWaitingRoomViewModel.sharedModel.joinLayout.value! != .AudioOnly) {
|
||||
lcallParams.videoEnabled = true
|
||||
lcallParams.videoDirection = ConferenceWaitingRoomViewModel.sharedModel.isVideoEnabled.value == true ? .SendRecv : .RecvOnly
|
||||
|
|
@ -439,6 +441,10 @@ class TelecomManager: ObservableObject {
|
|||
default:
|
||||
self.isPausedByRemote = false
|
||||
}
|
||||
|
||||
if (cstate == Call.State.Connected) {
|
||||
self.callConnected = true
|
||||
}
|
||||
}
|
||||
|
||||
if call.userData == nil {
|
||||
|
|
@ -596,6 +602,7 @@ class TelecomManager: ObservableObject {
|
|||
self.callInProgress = false
|
||||
self.callDisplayed = false
|
||||
self.callStarted = false
|
||||
self.callConnected = false
|
||||
}
|
||||
} else {
|
||||
if core.calls.last != nil {
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ struct CallView: View {
|
|||
@State var maxBottomSheetHeight: CGFloat = 0.5
|
||||
@State private var pointingUp: CGFloat = 0.0
|
||||
@State private var currentOffset: CGFloat = 0.0
|
||||
@State private var viewIsDisplayed = false
|
||||
@State var displayVideo = false
|
||||
|
||||
@Binding var fullscreenVideo: Bool
|
||||
@Binding var isShowCallsListFragment: Bool
|
||||
|
|
@ -485,64 +485,10 @@ struct CallView: View {
|
|||
|
||||
Spacer()
|
||||
}
|
||||
} else {
|
||||
VStack {
|
||||
Spacer()
|
||||
ZStack {
|
||||
if callViewModel.activeSpeakerParticipant?.address != nil {
|
||||
let addressFriend = contactsManager.getFriendWithAddress(address: callViewModel.activeSpeakerParticipant!.address)
|
||||
|
||||
let contactAvatarModel = addressFriend != nil
|
||||
? ContactsManager.shared.avatarListModel.first(where: {
|
||||
($0.friend!.consolidatedPresence == .Online || $0.friend!.consolidatedPresence == .Busy)
|
||||
&& $0.friend!.name == addressFriend!.name
|
||||
&& $0.friend!.address!.asStringUriOnly() == addressFriend!.address!.asStringUriOnly()
|
||||
})
|
||||
: ContactAvatarModel(friend: nil, name: "", withPresence: false)
|
||||
|
||||
if addressFriend != nil && addressFriend!.photo != nil && !addressFriend!.photo!.isEmpty {
|
||||
if contactAvatarModel != nil {
|
||||
Avatar(contactAvatarModel: contactAvatarModel!, avatarSize: 200, hidePresence: true)
|
||||
}
|
||||
} else {
|
||||
if callViewModel.activeSpeakerParticipant!.address.displayName != nil {
|
||||
Image(uiImage: contactsManager.textToImage(
|
||||
firstName: callViewModel.activeSpeakerParticipant!.address.displayName!,
|
||||
lastName: callViewModel.activeSpeakerParticipant!.address.displayName!.components(separatedBy: " ").count > 1
|
||||
? callViewModel.activeSpeakerParticipant!.address.displayName!.components(separatedBy: " ")[1]
|
||||
: ""))
|
||||
.resizable()
|
||||
.frame(width: 200, height: 200)
|
||||
.clipShape(Circle())
|
||||
|
||||
} else {
|
||||
Image(uiImage: contactsManager.textToImage(
|
||||
firstName: callViewModel.activeSpeakerParticipant!.address.username ?? "Username Error",
|
||||
lastName: callViewModel.activeSpeakerParticipant!.address.username!.components(separatedBy: " ").count > 1
|
||||
? callViewModel.activeSpeakerParticipant!.address.username!.components(separatedBy: " ")[1]
|
||||
: ""))
|
||||
.resizable()
|
||||
.frame(width: 200, height: 200)
|
||||
.clipShape(Circle())
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
Image("profil-picture-default")
|
||||
.resizable()
|
||||
.frame(width: 200, height: 200)
|
||||
.clipShape(Circle())
|
||||
}
|
||||
}
|
||||
|
||||
Spacer()
|
||||
}
|
||||
}
|
||||
|
||||
if !callViewModel.isConference {
|
||||
|
||||
LinphoneVideoViewHolder { view in
|
||||
coreContext.doOnCoreQueue { core in
|
||||
core.nativeVideoWindowId = UnsafeMutableRawPointer(Unmanaged.passRetained(view).toOpaque())
|
||||
core.nativeVideoWindow = view
|
||||
}
|
||||
}
|
||||
.frame(
|
||||
|
|
@ -584,26 +530,80 @@ struct CallView: View {
|
|||
maxHeight: fullscreenVideo && !telecomManager.isPausedByRemote ? geometry.size.height + geometry.safeAreaInsets.top + geometry.safeAreaInsets.bottom : geometry.size.height - (minBottomSheetHeight * geometry.size.height > 80 ? minBottomSheetHeight * geometry.size.height : 78) - 40 - 20 + geometry.safeAreaInsets.bottom
|
||||
)
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
if !viewIsDisplayed {
|
||||
VStack {
|
||||
|
||||
}
|
||||
.onAppear {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
|
||||
viewIsDisplayed = true
|
||||
} else if callViewModel.isConference && !telecomManager.outgoingCallStarted && callViewModel.activeSpeakerParticipant != nil {
|
||||
VStack {
|
||||
Spacer()
|
||||
ZStack {
|
||||
if callViewModel.activeSpeakerParticipant?.address != nil {
|
||||
let addressFriend = contactsManager.getFriendWithAddress(address: callViewModel.activeSpeakerParticipant!.address)
|
||||
|
||||
let contactAvatarModel = addressFriend != nil
|
||||
? ContactsManager.shared.avatarListModel.first(where: {
|
||||
($0.friend!.consolidatedPresence == .Online || $0.friend!.consolidatedPresence == .Busy)
|
||||
&& $0.friend!.name == addressFriend!.name
|
||||
&& $0.friend!.address!.asStringUriOnly() == addressFriend!.address!.asStringUriOnly()
|
||||
})
|
||||
: ContactAvatarModel(friend: nil, name: "", withPresence: true)
|
||||
|
||||
if addressFriend != nil && addressFriend!.photo != nil && !addressFriend!.photo!.isEmpty {
|
||||
if contactAvatarModel != nil {
|
||||
Avatar(contactAvatarModel: contactAvatarModel!, avatarSize: 200, hidePresence: false)
|
||||
.onAppear {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
|
||||
displayVideo = true
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if callViewModel.activeSpeakerParticipant!.address.displayName != nil {
|
||||
Image(uiImage: contactsManager.textToImage(
|
||||
firstName: callViewModel.activeSpeakerParticipant!.address.displayName!,
|
||||
lastName: callViewModel.activeSpeakerParticipant!.address.displayName!.components(separatedBy: " ").count > 1
|
||||
? callViewModel.activeSpeakerParticipant!.address.displayName!.components(separatedBy: " ")[1]
|
||||
: ""))
|
||||
.resizable()
|
||||
.frame(width: 200, height: 200)
|
||||
.clipShape(Circle())
|
||||
.onAppear {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
|
||||
displayVideo = true
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
Image(uiImage: contactsManager.textToImage(
|
||||
firstName: callViewModel.activeSpeakerParticipant!.address.username ?? "Username Error",
|
||||
lastName: callViewModel.activeSpeakerParticipant!.address.username!.components(separatedBy: " ").count > 1
|
||||
? callViewModel.activeSpeakerParticipant!.address.username!.components(separatedBy: " ")[1]
|
||||
: ""))
|
||||
.resizable()
|
||||
.frame(width: 200, height: 200)
|
||||
.clipShape(Circle())
|
||||
.onAppear {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
|
||||
displayVideo = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
Image("profil-picture-default")
|
||||
.resizable()
|
||||
.frame(width: 200, height: 200)
|
||||
.clipShape(Circle())
|
||||
}
|
||||
}
|
||||
|
||||
Spacer()
|
||||
}
|
||||
|
||||
if viewIsDisplayed && (callViewModel.receiveVideo || telecomManager.remoteConfVideo) {
|
||||
*/
|
||||
if (callViewModel.receiveVideo || telecomManager.remoteConfVideo) && !telecomManager.outgoingCallStarted {
|
||||
if telecomManager.remoteConfVideo && !telecomManager.outgoingCallStarted && callViewModel.activeSpeakerParticipant != nil && displayVideo {
|
||||
LinphoneVideoViewHolder { view in
|
||||
coreContext.doOnCoreQueue { core in
|
||||
//core.nativeVideoWindow = view
|
||||
core.nativeVideoWindowId = UnsafeMutableRawPointer(Unmanaged.passRetained(view).toOpaque())
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
|
||||
coreContext.doOnCoreQueue { core in
|
||||
core.nativeVideoWindow = view
|
||||
}
|
||||
}
|
||||
}
|
||||
.frame(
|
||||
|
|
@ -623,35 +623,22 @@ struct CallView: View {
|
|||
fullscreenVideo.toggle()
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
HStack {
|
||||
Spacer()
|
||||
VStack {
|
||||
Spacer()
|
||||
LinphoneVideoViewHolder { view in
|
||||
coreContext.doOnCoreQueue { core in
|
||||
core.nativePreviewWindow = view
|
||||
}
|
||||
}
|
||||
.frame(width: angleDegree == 0 ? 120*1.2 : 160*1.2, height: angleDegree == 0 ? 160*1.2 : 120*1.2)
|
||||
.cornerRadius(20)
|
||||
.padding(10)
|
||||
.padding(.trailing, abs(angleDegree/2))
|
||||
}
|
||||
}
|
||||
.frame(
|
||||
maxWidth: fullscreenVideo && !telecomManager.isPausedByRemote ? geometry.size.width : geometry.size.width - 8,
|
||||
maxHeight: fullscreenVideo && !telecomManager.isPausedByRemote ? geometry.size.height + geometry.safeAreaInsets.top + geometry.safeAreaInsets.bottom : geometry.size.height - (minBottomSheetHeight * geometry.size.height > 80 ? minBottomSheetHeight * geometry.size.height : 78) - 40 - 20 + geometry.safeAreaInsets.bottom
|
||||
)
|
||||
*/
|
||||
}
|
||||
|
||||
if !telecomManager.outgoingCallStarted {
|
||||
if callViewModel.isConference {
|
||||
HStack {
|
||||
Spacer()
|
||||
VStack {
|
||||
Spacer()
|
||||
|
||||
Text(callViewModel.activeSpeakerName)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.foregroundStyle(Color.white)
|
||||
.default_text_style_500(styleSize: 20)
|
||||
.lineLimit(1)
|
||||
.padding(.horizontal, 10)
|
||||
.padding(.bottom, 6)
|
||||
|
||||
ScrollView(.horizontal) {
|
||||
HStack {
|
||||
ZStack {
|
||||
|
|
@ -664,6 +651,20 @@ struct CallView: View {
|
|||
|
||||
Spacer()
|
||||
}
|
||||
.frame(width: 140, height: 140)
|
||||
|
||||
if callViewModel.videoDisplayed {
|
||||
LinphoneVideoViewHolder { view in
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
|
||||
coreContext.doOnCoreQueue { core in
|
||||
core.nativePreviewWindow = view
|
||||
}
|
||||
}
|
||||
}
|
||||
.frame(width: angleDegree == 0 ? 120*1.2 : 160*1.2, height: angleDegree == 0 ? 160*1.2 : 120*1.2)
|
||||
.scaledToFill()
|
||||
.clipped()
|
||||
}
|
||||
|
||||
VStack(alignment: .leading) {
|
||||
Spacer()
|
||||
|
|
@ -678,44 +679,50 @@ struct CallView: View {
|
|||
.padding(.bottom, 6)
|
||||
}
|
||||
}
|
||||
.frame(maxWidth: .infinity)
|
||||
|
||||
LinphoneVideoViewHolder { view in
|
||||
coreContext.doOnCoreQueue { core in
|
||||
core.nativePreviewWindow = view
|
||||
}
|
||||
}
|
||||
.frame(width: 140, height: 140)
|
||||
}
|
||||
.frame(width: 140, height: 140)
|
||||
.background(Color.gray600)
|
||||
.cornerRadius(20)
|
||||
|
||||
ForEach(0..<callViewModel.participantList.count, id: \.self) { index in
|
||||
ZStack {
|
||||
VStack {
|
||||
Spacer()
|
||||
if callViewModel.activeSpeakerParticipant != nil && !callViewModel.participantList[index].address.equal(address2: callViewModel.activeSpeakerParticipant!.address) {
|
||||
ZStack {
|
||||
VStack {
|
||||
Spacer()
|
||||
|
||||
Avatar(contactAvatarModel: callViewModel.participantList[index].avatarModel, avatarSize: 50)
|
||||
|
||||
Spacer()
|
||||
}
|
||||
|
||||
Avatar(contactAvatarModel: callViewModel.participantList[index].avatarModel, avatarSize: 50)
|
||||
LinphoneVideoViewHolder { view in
|
||||
coreContext.doOnCoreQueue { core in
|
||||
let participantVideo = core.currentCall?.conference?.participantList.first(where: {$0.address!.equal(address2: callViewModel.participantList[index].address)})
|
||||
if participantVideo != nil && participantVideo!.devices.first != nil {
|
||||
participantVideo!.devices.first!.nativeVideoWindowId = UnsafeMutableRawPointer(Unmanaged.passRetained(view).toOpaque())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VStack(alignment: .leading) {
|
||||
Spacer()
|
||||
|
||||
Text(callViewModel.participantList[index].name)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.foregroundStyle(Color.white)
|
||||
.default_text_style_500(styleSize: 14)
|
||||
.lineLimit(1)
|
||||
.padding(.horizontal, 10)
|
||||
.padding(.bottom, 6)
|
||||
}
|
||||
.frame(maxWidth: .infinity)
|
||||
|
||||
Spacer()
|
||||
}
|
||||
|
||||
VStack(alignment: .leading) {
|
||||
Spacer()
|
||||
|
||||
Text(callViewModel.participantList[index].name)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.foregroundStyle(Color.white)
|
||||
.default_text_style_500(styleSize: 14)
|
||||
.lineLimit(1)
|
||||
.padding(.horizontal, 10)
|
||||
.padding(.bottom, 6)
|
||||
}
|
||||
.frame(maxWidth: .infinity)
|
||||
.frame(width: 140, height: 140)
|
||||
.background(Color.gray600)
|
||||
.cornerRadius(20)
|
||||
}
|
||||
.frame(width: 140, height: 140)
|
||||
.background(Color.gray600)
|
||||
.cornerRadius(20)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -726,6 +733,7 @@ struct CallView: View {
|
|||
maxHeight: fullscreenVideo && !telecomManager.isPausedByRemote ? geometry.size.height + geometry.safeAreaInsets.top + geometry.safeAreaInsets.bottom : geometry.size.height - (minBottomSheetHeight * geometry.size.height > 80 ? minBottomSheetHeight * geometry.size.height : 78) - 40 - 20 + geometry.safeAreaInsets.bottom
|
||||
)
|
||||
.padding(.bottom, 10)
|
||||
.padding(.leading, -10)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -773,6 +781,11 @@ struct CallView: View {
|
|||
|
||||
Spacer()
|
||||
}
|
||||
.onDisappear {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
||||
callViewModel.getConference()
|
||||
}
|
||||
}
|
||||
.background(.clear)
|
||||
.frame(
|
||||
maxWidth: fullscreenVideo && !telecomManager.isPausedByRemote ? geometry.size.width : geometry.size.width - 8,
|
||||
|
|
@ -1186,29 +1199,54 @@ struct CallView: View {
|
|||
}
|
||||
.frame(width: geo.size.width * 0.25, height: geo.size.width * 0.25)
|
||||
|
||||
VStack {
|
||||
Button {
|
||||
callViewModel.toggleRecording()
|
||||
} label: {
|
||||
HStack {
|
||||
Image("record-fill")
|
||||
.renderingMode(.template)
|
||||
.resizable()
|
||||
.foregroundStyle((callViewModel.isPaused || telecomManager.isPausedByRemote) ? Color.gray500 : .white)
|
||||
.frame(width: 32, height: 32)
|
||||
if !callViewModel.isConference {
|
||||
VStack {
|
||||
Button {
|
||||
callViewModel.toggleRecording()
|
||||
} label: {
|
||||
HStack {
|
||||
Image("record-fill")
|
||||
.renderingMode(.template)
|
||||
.resizable()
|
||||
.foregroundStyle((callViewModel.isPaused || telecomManager.isPausedByRemote) ? Color.gray500 : .white)
|
||||
.frame(width: 32, height: 32)
|
||||
}
|
||||
}
|
||||
.buttonStyle(PressedButtonStyle())
|
||||
.frame(width: 60, height: 60)
|
||||
.background((callViewModel.isPaused || telecomManager.isPausedByRemote) ? .white : (callViewModel.isRecording ? Color.redDanger500 : Color.gray500))
|
||||
.cornerRadius(40)
|
||||
.disabled(callViewModel.isPaused || telecomManager.isPausedByRemote)
|
||||
|
||||
Text("Record")
|
||||
.foregroundStyle(.white)
|
||||
.default_text_style(styleSize: 15)
|
||||
}
|
||||
.buttonStyle(PressedButtonStyle())
|
||||
.frame(width: 60, height: 60)
|
||||
.background((callViewModel.isPaused || telecomManager.isPausedByRemote) ? .white : (callViewModel.isRecording ? Color.redDanger500 : Color.gray500))
|
||||
.cornerRadius(40)
|
||||
.disabled(callViewModel.isPaused || telecomManager.isPausedByRemote)
|
||||
|
||||
Text("Record")
|
||||
.foregroundStyle(.white)
|
||||
.default_text_style(styleSize: 15)
|
||||
.frame(width: geo.size.width * 0.25, height: geo.size.width * 0.25)
|
||||
} else {
|
||||
VStack {
|
||||
Button {
|
||||
} label: {
|
||||
HStack {
|
||||
Image("record-fill")
|
||||
.renderingMode(.template)
|
||||
.resizable()
|
||||
.foregroundStyle(Color.gray500)
|
||||
.frame(width: 32, height: 32)
|
||||
}
|
||||
}
|
||||
.buttonStyle(PressedButtonStyle())
|
||||
.frame(width: 60, height: 60)
|
||||
.background(.white)
|
||||
.cornerRadius(40)
|
||||
.disabled(true)
|
||||
|
||||
Text("Record")
|
||||
.foregroundStyle(.white)
|
||||
.default_text_style(styleSize: 15)
|
||||
}
|
||||
.frame(width: geo.size.width * 0.25, height: geo.size.width * 0.25)
|
||||
}
|
||||
.frame(width: geo.size.width * 0.25, height: geo.size.width * 0.25)
|
||||
|
||||
VStack {
|
||||
Button {
|
||||
|
|
@ -1403,29 +1441,54 @@ struct CallView: View {
|
|||
}
|
||||
.frame(width: geo.size.width * 0.125, height: geo.size.width * 0.125)
|
||||
|
||||
VStack {
|
||||
Button {
|
||||
callViewModel.toggleRecording()
|
||||
} label: {
|
||||
HStack {
|
||||
Image("record-fill")
|
||||
.renderingMode(.template)
|
||||
.resizable()
|
||||
.foregroundStyle((callViewModel.isPaused || telecomManager.isPausedByRemote) ? Color.gray500 : .white)
|
||||
.frame(width: 32, height: 32)
|
||||
if !callViewModel.isConference {
|
||||
VStack {
|
||||
Button {
|
||||
callViewModel.toggleRecording()
|
||||
} label: {
|
||||
HStack {
|
||||
Image("record-fill")
|
||||
.renderingMode(.template)
|
||||
.resizable()
|
||||
.foregroundStyle((callViewModel.isPaused || telecomManager.isPausedByRemote) ? Color.gray500 : .white)
|
||||
.frame(width: 32, height: 32)
|
||||
}
|
||||
}
|
||||
.buttonStyle(PressedButtonStyle())
|
||||
.frame(width: 60, height: 60)
|
||||
.background((callViewModel.isPaused || telecomManager.isPausedByRemote) ? .white : (callViewModel.isRecording ? Color.redDanger500 : Color.gray500))
|
||||
.cornerRadius(40)
|
||||
.disabled(callViewModel.isPaused || telecomManager.isPausedByRemote)
|
||||
|
||||
Text("Record")
|
||||
.foregroundStyle(.white)
|
||||
.default_text_style(styleSize: 15)
|
||||
}
|
||||
.buttonStyle(PressedButtonStyle())
|
||||
.frame(width: 60, height: 60)
|
||||
.background((callViewModel.isPaused || telecomManager.isPausedByRemote) ? .white : (callViewModel.isRecording ? Color.redDanger500 : Color.gray500))
|
||||
.cornerRadius(40)
|
||||
.disabled(callViewModel.isPaused || telecomManager.isPausedByRemote)
|
||||
|
||||
Text("Record")
|
||||
.foregroundStyle(.white)
|
||||
.default_text_style(styleSize: 15)
|
||||
.frame(width: geo.size.width * 0.125, height: geo.size.width * 0.125)
|
||||
} else {
|
||||
VStack {
|
||||
Button {
|
||||
} label: {
|
||||
HStack {
|
||||
Image("record-fill")
|
||||
.renderingMode(.template)
|
||||
.resizable()
|
||||
.foregroundStyle(Color.gray500)
|
||||
.frame(width: 32, height: 32)
|
||||
}
|
||||
}
|
||||
.buttonStyle(PressedButtonStyle())
|
||||
.frame(width: 60, height: 60)
|
||||
.background(.white)
|
||||
.cornerRadius(40)
|
||||
.disabled(true)
|
||||
|
||||
Text("Record")
|
||||
.foregroundStyle(.white)
|
||||
.default_text_style(styleSize: 15)
|
||||
}
|
||||
.frame(width: geo.size.width * 0.125, height: geo.size.width * 0.125)
|
||||
}
|
||||
.frame(width: geo.size.width * 0.125, height: geo.size.width * 0.125)
|
||||
}
|
||||
.frame(height: geo.size.height * 0.15)
|
||||
.padding(.horizontal, 20)
|
||||
|
|
|
|||
|
|
@ -47,9 +47,9 @@ class CallViewModel: ObservableObject {
|
|||
@Published var isTransferInsteadCall: Bool = false
|
||||
@Published var isConference: Bool = false
|
||||
@Published var videoDisplayed: Bool = false
|
||||
@Published var receiveVideo: Bool = false
|
||||
@Published var participantList: [ParticipantModel] = []
|
||||
@Published var activeSpeakerParticipant: ParticipantModel? = nil
|
||||
@Published var activeSpeakerName: String = ""
|
||||
@Published var myParticipantModel: ParticipantModel? = nil
|
||||
|
||||
|
||||
|
|
@ -80,7 +80,7 @@ class CallViewModel: ObservableObject {
|
|||
}
|
||||
}
|
||||
|
||||
func disableAVAudioSession(){
|
||||
func disableAVAudioSession() {
|
||||
do {
|
||||
try AVAudioSession.sharedInstance().setActive(false)
|
||||
} catch _ {
|
||||
|
|
@ -117,6 +117,14 @@ class CallViewModel: ObservableObject {
|
|||
let authToken = self.currentCall!.authenticationToken
|
||||
let isDeviceTrusted = self.currentCall!.authenticationTokenVerified && authToken != nil
|
||||
self.isRemoteDeviceTrusted = self.telecomManager.callInProgress ? isDeviceTrusted : false
|
||||
self.activeSpeakerParticipant = nil
|
||||
|
||||
do {
|
||||
let params = try core.createCallParams(call: self.currentCall)
|
||||
self.videoDisplayed = params.videoDirection == MediaDirection.SendRecv
|
||||
} catch {
|
||||
|
||||
}
|
||||
|
||||
self.getCallsList()
|
||||
self.getConference()
|
||||
|
|
@ -139,28 +147,69 @@ class CallViewModel: ObservableObject {
|
|||
|
||||
func getConference() {
|
||||
coreContext.doOnCoreQueue { core in
|
||||
//conf = self.currentCall?.conference != nil ? self.currentCall!.conference! : core.findConferenceInformationFromUri(uri: (self.currentCall?.remoteContactAddress)!)
|
||||
if self.currentCall?.remoteContactAddress != nil {
|
||||
let conf = core.findConferenceInformationFromUri(uri: (self.currentCall?.remoteContactAddress)!)
|
||||
if self.currentCall?.conference != nil {
|
||||
let conf = self.currentCall!.conference!
|
||||
self.isConference = true
|
||||
DispatchQueue.main.async {
|
||||
self.isConference = conf != nil
|
||||
if self.isConference {
|
||||
self.displayName = conf?.subject ?? ""
|
||||
self.participantList = []
|
||||
conf?.participantInfos.forEach({ participantInfo in
|
||||
if participantInfo.address != nil {
|
||||
if participantInfo.address!.equal(address2: (self.currentCall?.callLog?.localAddress!)!) {
|
||||
self.myParticipantModel = ParticipantModel(address: participantInfo.address!)
|
||||
} else {
|
||||
if self.activeSpeakerParticipant != nil && !participantInfo.address!.equal(address2: self.activeSpeakerParticipant!.address) {
|
||||
self.participantList.append(ParticipantModel(address: participantInfo.address!))
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
self.addConferenceCallBacks()
|
||||
self.displayName = conf.subject ?? ""
|
||||
self.participantList = []
|
||||
|
||||
if self.currentCall?.callLog?.localAddress != nil {
|
||||
self.myParticipantModel = ParticipantModel(address: self.currentCall!.callLog!.localAddress!)
|
||||
}
|
||||
|
||||
if conf.activeSpeakerParticipantDevice?.address != nil {
|
||||
self.activeSpeakerParticipant = ParticipantModel(address: conf.activeSpeakerParticipantDevice!.address!)
|
||||
} else if conf.participantList.first?.address != nil {
|
||||
self.activeSpeakerParticipant = ParticipantModel(address: conf.participantList.first!.address!)
|
||||
} else {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
|
||||
self.getConference()
|
||||
}
|
||||
}
|
||||
|
||||
if self.activeSpeakerParticipant != nil {
|
||||
let friend = ContactsManager.shared.getFriendWithAddress(address: self.activeSpeakerParticipant!.address)
|
||||
if friend != nil && friend!.address != nil && friend!.address!.displayName != nil {
|
||||
self.activeSpeakerName = friend!.address!.displayName!
|
||||
} else {
|
||||
if self.activeSpeakerParticipant!.address.displayName != nil {
|
||||
self.activeSpeakerName = self.activeSpeakerParticipant!.address.displayName!
|
||||
} else if self.activeSpeakerParticipant!.address.username != nil {
|
||||
self.activeSpeakerName = self.activeSpeakerParticipant!.address.username!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
conf.participantList.forEach({ participant in
|
||||
self.participantList.append(ParticipantModel(address: participant.address!))
|
||||
})
|
||||
|
||||
self.addConferenceCallBacks()
|
||||
}
|
||||
} else if self.currentCall?.remoteContactAddress != nil {
|
||||
let conf = core.findConferenceInformationFromUri(uri: (self.currentCall?.remoteContactAddress)!)
|
||||
DispatchQueue.main.async {
|
||||
self.isConference = conf != nil
|
||||
if self.isConference {
|
||||
self.displayName = conf?.subject ?? ""
|
||||
self.participantList = []
|
||||
|
||||
conf?.participantInfos.forEach({ participantInfo in
|
||||
if participantInfo.address != nil {
|
||||
if participantInfo.address!.equal(address2: (self.currentCall?.callLog?.localAddress!)!) {
|
||||
self.myParticipantModel = ParticipantModel(address: participantInfo.address!)
|
||||
} else {
|
||||
if self.activeSpeakerParticipant != nil && !participantInfo.address!.equal(address2: self.activeSpeakerParticipant!.address) {
|
||||
self.participantList.append(ParticipantModel(address: participantInfo.address!))
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
self.addConferenceCallBacks()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -169,14 +218,24 @@ class CallViewModel: ObservableObject {
|
|||
coreContext.doOnCoreQueue { core in
|
||||
self.mConferenceSuscriptions.insert(
|
||||
self.currentCall?.conference?.publisher?.onActiveSpeakerParticipantDevice?.postOnMainQueue {(cbValue: (conference: Conference, participantDevice: ParticipantDevice)) in
|
||||
let direction = cbValue.participantDevice.getStreamCapability(streamType: StreamType.Video)
|
||||
|
||||
self.receiveVideo = direction == MediaDirection.SendRecv || direction == MediaDirection.SendOnly
|
||||
|
||||
if cbValue.participantDevice.address != nil {
|
||||
let activeSpeakerParticipantTmp = self.activeSpeakerParticipant
|
||||
self.activeSpeakerParticipant = ParticipantModel(address: cbValue.participantDevice.address!)
|
||||
|
||||
|
||||
if self.activeSpeakerParticipant != nil {
|
||||
let friend = ContactsManager.shared.getFriendWithAddress(address: self.activeSpeakerParticipant!.address)
|
||||
if friend != nil && friend!.address != nil && friend!.address!.displayName != nil {
|
||||
self.activeSpeakerName = friend!.address!.displayName!
|
||||
} else {
|
||||
if self.activeSpeakerParticipant!.address.displayName != nil {
|
||||
self.activeSpeakerName = self.activeSpeakerParticipant!.address.displayName!
|
||||
} else if self.activeSpeakerParticipant!.address.username != nil {
|
||||
self.activeSpeakerName = self.activeSpeakerParticipant!.address.username!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if self.activeSpeakerParticipant != nil
|
||||
&& ((activeSpeakerParticipantTmp != nil && !activeSpeakerParticipantTmp!.address.equal(address2: self.activeSpeakerParticipant!.address))
|
||||
|| ( activeSpeakerParticipantTmp == nil)) {
|
||||
|
|
@ -184,7 +243,7 @@ class CallViewModel: ObservableObject {
|
|||
self.participantList = []
|
||||
cbValue.conference.participantList.forEach({ participant in
|
||||
if participant.address != nil && !cbValue.conference.isMe(uri: participant.address!) {
|
||||
if !cbValue.conference.isMe(uri: participant.address!) && !participant.address!.equal(address2: self.activeSpeakerParticipant!.address) {
|
||||
if !cbValue.conference.isMe(uri: participant.address!) {
|
||||
self.participantList.append(ParticipantModel(address: participant.address!))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ struct ContactInnerActionsFragment: View {
|
|||
.onTapGesture {
|
||||
withAnimation {
|
||||
telecomManager.doCallWithCore(
|
||||
addr: contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend!.addresses[index], isVideo: false
|
||||
addr: contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend!.addresses[index], isVideo: false, isConference: false
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ struct ContactInnerFragment: View {
|
|||
Spacer()
|
||||
|
||||
Button(action: {
|
||||
telecomManager.doCallWithCore(addr: contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend!.address!, isVideo: false)
|
||||
telecomManager.doCallWithCore(addr: contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend!.address!, isVideo: false, isConference: false)
|
||||
}, label: {
|
||||
VStack {
|
||||
HStack(alignment: .center) {
|
||||
|
|
@ -208,7 +208,7 @@ struct ContactInnerFragment: View {
|
|||
Spacer()
|
||||
|
||||
Button(action: {
|
||||
telecomManager.doCallWithCore(addr: contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend!.address!, isVideo: true)
|
||||
telecomManager.doCallWithCore(addr: contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend!.address!, isVideo: true, isConference: false)
|
||||
}, label: {
|
||||
VStack {
|
||||
HStack(alignment: .center) {
|
||||
|
|
|
|||
|
|
@ -856,7 +856,7 @@ struct ContentView: View {
|
|||
}
|
||||
}
|
||||
|
||||
if telecomManager.callInProgress && telecomManager.callDisplayed {
|
||||
if telecomManager.callDisplayed && ((telecomManager.callInProgress && telecomManager.outgoingCallStarted) || telecomManager.callConnected) {
|
||||
CallView(callViewModel: callViewModel, fullscreenVideo: $fullscreenVideo, isShowCallsListFragment: $isShowCallsListFragment, isShowStartCallFragment: $isShowStartCallFragment)
|
||||
.zIndex(3)
|
||||
.transition(.scale.combined(with: .move(edge: .top)))
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ class ConversationModel: ObservableObject {
|
|||
coreContext.doOnCoreQueue { _ in
|
||||
if self.chatRoom.peerAddress != nil {
|
||||
TelecomManager.shared.doCallWithCore(
|
||||
addr: self.chatRoom.peerAddress!, isVideo: false
|
||||
addr: self.chatRoom.peerAddress!, isVideo: false, isConference: false
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -434,7 +434,7 @@ struct DialerBottomSheet: View {
|
|||
if !startCallViewModel.searchField.isEmpty {
|
||||
do {
|
||||
let address = try Factory.Instance.createAddress(addr: String("sip:" + startCallViewModel.searchField + "@" + startCallViewModel.domain))
|
||||
telecomManager.doCallWithCore(addr: address, isVideo: false)
|
||||
telecomManager.doCallWithCore(addr: address, isVideo: false, isConference: false)
|
||||
} catch {
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -388,11 +388,11 @@ struct HistoryContactFragment: View {
|
|||
Button(action: {
|
||||
if historyViewModel.displayedCall!.dir == .Outgoing && historyViewModel.displayedCall!.toAddress != nil {
|
||||
telecomManager.doCallWithCore(
|
||||
addr: historyViewModel.displayedCall!.toAddress!, isVideo: false
|
||||
addr: historyViewModel.displayedCall!.toAddress!, isVideo: false, isConference: false
|
||||
)
|
||||
} else if historyViewModel.displayedCall!.dir == .Incoming && historyViewModel.displayedCall!.fromAddress != nil {
|
||||
telecomManager.doCallWithCore(
|
||||
addr: historyViewModel.displayedCall!.fromAddress!, isVideo: false
|
||||
addr: historyViewModel.displayedCall!.fromAddress!, isVideo: false, isConference: false
|
||||
)
|
||||
}
|
||||
}, label: {
|
||||
|
|
@ -448,11 +448,11 @@ struct HistoryContactFragment: View {
|
|||
Button(action: {
|
||||
if historyViewModel.displayedCall!.dir == .Outgoing && historyViewModel.displayedCall!.toAddress != nil {
|
||||
telecomManager.doCallWithCore(
|
||||
addr: historyViewModel.displayedCall!.toAddress!, isVideo: true
|
||||
addr: historyViewModel.displayedCall!.toAddress!, isVideo: true, isConference: false
|
||||
)
|
||||
} else if historyViewModel.displayedCall!.dir == .Incoming && historyViewModel.displayedCall!.fromAddress != nil {
|
||||
telecomManager.doCallWithCore(
|
||||
addr: historyViewModel.displayedCall!.fromAddress!, isVideo: true
|
||||
addr: historyViewModel.displayedCall!.fromAddress!, isVideo: true, isConference: false
|
||||
)
|
||||
}
|
||||
}, label: {
|
||||
|
|
|
|||
|
|
@ -165,15 +165,7 @@ struct HistoryListFragment: View {
|
|||
TapGesture()
|
||||
.onEnded { _ in
|
||||
withAnimation {
|
||||
if historyListViewModel.callLogs[index].dir == .Outgoing && historyListViewModel.callLogs[index].toAddress != nil {
|
||||
telecomManager.doCallWithCore(
|
||||
addr: historyListViewModel.callLogs[index].toAddress!, isVideo: false
|
||||
)
|
||||
} else if historyListViewModel.callLogs[index].fromAddress != nil {
|
||||
telecomManager.doCallWithCore(
|
||||
addr: historyListViewModel.callLogs[index].fromAddress!, isVideo: false
|
||||
)
|
||||
}
|
||||
doCall(index: index)
|
||||
historyViewModel.displayedCall = nil
|
||||
}
|
||||
}
|
||||
|
|
@ -217,6 +209,39 @@ struct HistoryListFragment: View {
|
|||
.navigationTitle("")
|
||||
.navigationBarHidden(true)
|
||||
}
|
||||
|
||||
func doCall(index: Int) {
|
||||
if historyListViewModel.callLogs[index].dir == .Outgoing && historyListViewModel.callLogs[index].toAddress != nil {
|
||||
if historyListViewModel.callLogs[index].toAddress!.asStringUriOnly().hasPrefix("sip:conference-focus@sip.linphone.org") {
|
||||
do {
|
||||
//let reudumatin = try Factory.Instance.createAddress(addr: "sip:conference-focus@sip.linphone.org;conf-id=8~YNkpFOv;gr=0ee3f37f-6df2-0071-bb9a-a4e24be30135")
|
||||
let reutest = try Factory.Instance.createAddress(addr: "sip:conference-focus@sip.linphone.org;conf-id=iVs8XshC~;gr=0ee3f37f-6df2-0071-bb9a-a4e24be30135")
|
||||
|
||||
telecomManager.doCallWithCore(
|
||||
addr: reutest, isVideo: false, isConference: true
|
||||
)
|
||||
} catch {}
|
||||
} else {
|
||||
telecomManager.doCallWithCore(
|
||||
addr: historyListViewModel.callLogs[index].toAddress!, isVideo: false, isConference: false
|
||||
)
|
||||
}
|
||||
} else if historyListViewModel.callLogs[index].fromAddress != nil {
|
||||
if historyListViewModel.callLogs[index].fromAddress!.asStringUriOnly().hasPrefix("sip:conference-focus@sip.linphone.org") {
|
||||
do {
|
||||
//let reudumatin = try Factory.Instance.createAddress(addr: "sip:conference-focus@sip.linphone.org;conf-id=8~YNkpFOv;gr=0ee3f37f-6df2-0071-bb9a-a4e24be30135")
|
||||
let reutest = try Factory.Instance.createAddress(addr: "sip:conference-focus@sip.linphone.org;conf-id=iVs8XshC~;gr=0ee3f37f-6df2-0071-bb9a-a4e24be30135")
|
||||
telecomManager.doCallWithCore(
|
||||
addr: reutest, isVideo: false, isConference: true
|
||||
)
|
||||
} catch {}
|
||||
} else {
|
||||
telecomManager.doCallWithCore(
|
||||
addr: historyListViewModel.callLogs[index].fromAddress!, isVideo: false, isConference: false
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#Preview {
|
||||
|
|
|
|||
|
|
@ -219,7 +219,7 @@ struct StartCallFragment: View {
|
|||
|
||||
withAnimation {
|
||||
isShowStartCallFragment.toggle()
|
||||
telecomManager.doCallWithCore(addr: addr, isVideo: false)
|
||||
telecomManager.doCallWithCore(addr: addr, isVideo: false, isConference: false)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
@ -305,7 +305,7 @@ struct StartCallFragment: View {
|
|||
isShowStartCallFragment.toggle()
|
||||
if contactsManager.lastSearchSuggestions[index].address != nil {
|
||||
telecomManager.doCallWithCore(
|
||||
addr: contactsManager.lastSearchSuggestions[index].address!, isVideo: false
|
||||
addr: contactsManager.lastSearchSuggestions[index].address!, isVideo: false, isConference: false
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue