Replace outgoing call view for conference joining by spinner

This commit is contained in:
Christophe Deschamps 2022-03-22 12:20:54 +01:00
parent f452f010bb
commit e4da04b464
14 changed files with 46 additions and 15 deletions

View file

@ -151,7 +151,7 @@ static UICompositeViewDescription *compositeDescription = nil;
[_tableView reloadData];
} else {
const LinphoneAddress *addr = linphone_participant_device_get_address(entry->device);
[CallManager.instance startCallWithAddr:(LinphoneAddress *)addr isSas:TRUE];
[CallManager.instance startCallWithAddr:(LinphoneAddress *)addr isSas:TRUE isVideo:false isConference:false];
}
} else {
bctbx_list_t *devices = linphone_participant_get_devices(entry->participant);

View file

@ -1862,7 +1862,7 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) {
}
[self checkLocalNetworkPermission];
// For OutgoingCall, show CallOutgoingView
[CallManager.instance startCallWithAddr:iaddr isSas:FALSE];
[CallManager.instance startCallWithAddr:iaddr isSas:FALSE isVideo:false isConference:false];
}
#pragma mark - Misc Functions

View file

@ -378,9 +378,12 @@ static RootViewManager *rootViewManagerInstance = nil;
case LinphoneCallOutgoingEarlyMedia:
case LinphoneCallOutgoingProgress:
case LinphoneCallOutgoingRinging: {
OutgoingCallView *v = VIEW(OutgoingCallView);
[self changeCurrentView:OutgoingCallView.compositeViewDescription];
[v setCallWithCall:call];
CallAppData *data = [CallManager getAppDataWithCall:call];
if (!data.isConference) {
OutgoingCallView *v = VIEW(OutgoingCallView);
[self changeCurrentView:OutgoingCallView.compositeViewDescription];
[v setCallWithCall:call];
}
break;
}
case LinphoneCallPausedByRemote:

View file

@ -27,6 +27,8 @@ import AVFoundation
@objc class CallAppData: NSObject {
@objc var batteryWarningShown = false
@objc var videoRequested = false /*set when user has requested for video*/
@objc var isConference = true
}
/*
@ -207,7 +209,7 @@ import AVFoundation
}
// for outgoing call. There is not yet callId
@objc func startCall(addr: OpaquePointer?, isSas: Bool) {
@objc func startCall(addr: OpaquePointer?, isSas: Bool, isVideo: Bool, isConference: Bool = false) {
if (addr == nil) {
print("Can not start a call with null address!")
return
@ -221,27 +223,27 @@ import AVFoundation
let startCallAction = CXStartCallAction(call: uuid, handle: handle)
let transaction = CXTransaction(action: startCallAction)
let callInfo = CallInfo.newOutgoingCallInfo(addr: sAddr, isSas: isSas, displayName: name)
let callInfo = CallInfo.newOutgoingCallInfo(addr: sAddr, isSas: isSas, displayName: name, isVideo: isVideo, isConference:isConference)
providerDelegate.callInfos.updateValue(callInfo, forKey: uuid)
providerDelegate.uuids.updateValue(uuid, forKey: "")
setHeldOtherCalls(exceptCallid: "")
requestTransaction(transaction, action: "startCall")
}else {
try? doCall(addr: sAddr, isSas: isSas)
try? doCall(addr: sAddr, isSas: isSas, isVideo:isVideo, isConference:isConference)
}
}
func startCall(addr:String, isSas: Bool = false) {
func startCall(addr:String, isSas: Bool = false, isVideo: Bool, isConference: Bool = false) {
do {
let address = try Factory.Instance.createAddress(addr: addr)
startCall(addr: address.getCobject,isSas: isSas)
startCall(addr: address.getCobject,isSas: isSas, isVideo: isVideo, isConference:isConference)
} catch {
Log.e("[CallManager] unable to create address for a new outgoing call : \(addr) \(error) ")
}
}
func doCall(addr: Address, isSas: Bool) throws {
func doCall(addr: Address, isSas: Bool, isVideo: Bool, isConference:Bool = false) throws {
let displayName = FastAddressBook.displayName(for: addr.getCobject)
let lcallParams = try CallManager.instance().core!.createCallParams(call: nil)
@ -270,6 +272,13 @@ import AVFoundation
if (isSas) {
lcallParams.mediaEncryption = .ZRTP
}
if (isConference) {
lcallParams.videoEnabled = true
lcallParams.videoDirection = isVideo ? .SendRecv : .RecvOnly
} else {
lcallParams.videoEnabled = isVideo
}
let call = CallManager.instance().core!.inviteAddressWithParams(addr: addr, params: lcallParams)
if (call != nil) {
// The LinphoneCallAppData object should be set on call creation with callback
@ -280,6 +289,7 @@ import AVFoundation
Log.directLog(BCTBX_LOG_ERROR, text: "New call instanciated but app data was not set. Expect it to crash.")
/* will be used later to notify user if video was not activated because of the linphone core*/
} else {
data!.isConference = isConference
data!.videoRequested = lcallParams.videoEnabled
CallManager.setAppData(sCall: call!, appData: data)
}

View file

@ -84,7 +84,7 @@ import linphonesw
}
start.onClick {
self.conferenceUrl.map{ CallManager.instance().startCall(addr: $0, isSas: false) }
self.conferenceUrl.map{ CallManager.instance().startCall(addr: $0, isSas: false, isVideo: true, isConference: true) }
}

View file

@ -32,6 +32,8 @@ import os
var connected = false
var reason: Reason = Reason.None
var displayName: String?
var videoEnabled = false
var isConference = false
static func newIncomingCallInfo(callId: String) -> CallInfo {
let callInfo = CallInfo()
@ -39,12 +41,14 @@ import os
return callInfo
}
static func newOutgoingCallInfo(addr: Address, isSas: Bool, displayName: String) -> CallInfo {
static func newOutgoingCallInfo(addr: Address, isSas: Bool, displayName: String, isVideo: Bool, isConference:Bool) -> CallInfo {
let callInfo = CallInfo()
callInfo.isOutgoing = true
callInfo.sasEnabled = isSas
callInfo.toAddr = addr
callInfo.displayName = displayName
callInfo.videoEnabled = isVideo
callInfo.isConference = isConference
return callInfo
}
}
@ -252,7 +256,7 @@ extension ProviderDelegate: CXProviderDelegate {
}
CallManager.instance().core?.configureAudioSession()
try CallManager.instance().doCall(addr: addr!, isSas: callInfo?.sasEnabled ?? false)
try CallManager.instance().doCall(addr: addr!, isSas: callInfo?.sasEnabled ?? false, isVideo: callInfo?.videoEnabled ?? false, isConference: callInfo?.isConference ?? false)
} catch {
Log.directLog(BCTBX_LOG_ERROR, text: "CallKit: Call started failed because \(error)")
action.fail()

View file

@ -88,7 +88,7 @@ class CallData {
isRemotelyPaused.value = isCallRemotelyPaused()
canBePaused.value = canCallBePaused()
let conference = call.conference
isInRemoteConference.value = conference != nil
isInRemoteConference.value = conference != nil || CallManager.getAppData(call: call.getCobject!)?.isConference == true
if (conference != nil) {
remoteConferenceSubject.value = conference?.subject != nil && (conference?.subject.count)! > 0 ? conference!.subject : VoipTexts.conference_default_title
}

View file

@ -33,6 +33,7 @@ class CallsViewModel {
let callConnectedEvent = MutableLiveData<Call>()
let callUpdateEvent = MutableLiveData<Call>()
let noMoreCallEvent = MutableLiveData(false)
var core : Core { get { Core.get() } }
static let shared = CallsViewModel()

View file

@ -33,6 +33,8 @@ import linphonesw
var currentCallView : ActiveCallView? = nil
var conferenceGridView: VoipConferenceGridView? = nil
var conferenceActiveSpeakerView: VoipConferenceActiveSpeakerView? = nil
let conferenceJoinSpinner = RotatingSpinner()
let extraButtonsView = VoipExtraButtonsView()
var numpadView : NumpadView? = nil
@ -128,6 +130,17 @@ import linphonesw
}
}
ConferenceViewModel.shared.conferenceCreationPending.readCurrentAndObserve { isCreationPending in
if (ConferenceViewModel.shared.conferenceExists.value == true && isCreationPending == true) {
fullScreenMutableContainerView.addSubview(self.conferenceJoinSpinner)
self.conferenceJoinSpinner.square(IncomingOutgoingCommonView.spinner_size).center().done()
self.conferenceJoinSpinner.startRotation()
} else {
self.conferenceJoinSpinner.removeFromSuperview()
self.conferenceJoinSpinner.stopRotation()
}
}
// Conference active speaker
conferenceActiveSpeakerView = VoipConferenceActiveSpeakerView()
fullScreenMutableContainerView.addSubview(conferenceActiveSpeakerView!)