From 7e308427d0e09589817040ea672dfd8738acdb7b Mon Sep 17 00:00:00 2001 From: Christophe Deschamps Date: Wed, 17 Aug 2022 19:36:18 +0200 Subject: [PATCH] - Ability to mute/unmute when outside a conference - Call stats & Numpad views above controls - Group call icon in call list cosmetic - Calls List : fix icon size & layout issue on some iOS Devices - Black background on video full screen conference --- .../Voip/ViewModels/ControlsViewModel.swift | 2 +- .../ActiveCallOrConferenceView.swift | 65 +++++++++---------- .../OutgoingCallView.swift | 2 +- .../Voip/Views/Fragments/CallStatsView.swift | 4 +- .../Fragments/CallsList/VoipCallCell.swift | 9 ++- .../VoipConferenceActiveSpeakerView.swift | 5 +- .../Conference/VoipConferenceGridView.swift | 4 +- .../Voip/Views/Fragments/NumpadView.swift | 4 +- Classes/Swift/Voip/Widgets/Avatar.swift | 2 +- 9 files changed, 50 insertions(+), 47 deletions(-) diff --git a/Classes/Swift/Voip/ViewModels/ControlsViewModel.swift b/Classes/Swift/Voip/ViewModels/ControlsViewModel.swift index 224843936..c7ee93807 100644 --- a/Classes/Swift/Voip/ViewModels/ControlsViewModel.swift +++ b/Classes/Swift/Voip/ViewModels/ControlsViewModel.swift @@ -207,7 +207,7 @@ class ControlsViewModel { func updateMicState() { isMicrophoneMuted.value = !micAuthorized() || !core.micEnabled - isMuteMicrophoneEnabled.value = core.currentCall != nil || core.conference?.isIn == true + isMuteMicrophoneEnabled.value = CallsViewModel.shared.currentCallData.value??.call != nil } func micAuthorized() -> Bool { diff --git a/Classes/Swift/Voip/Views/CompositeViewControllers/ActiveCallOrConferenceView.swift b/Classes/Swift/Voip/Views/CompositeViewControllers/ActiveCallOrConferenceView.swift index 84cbe4961..8d97a4eaf 100644 --- a/Classes/Swift/Voip/Views/CompositeViewControllers/ActiveCallOrConferenceView.swift +++ b/Classes/Swift/Voip/Views/CompositeViewControllers/ActiveCallOrConferenceView.swift @@ -29,17 +29,17 @@ import linphonesw var callPausedByRemoteView : PausedCallOrConferenceView? = nil var callPausedByLocalView : PausedCallOrConferenceView? = nil - + var conferencePausedView : PausedCallOrConferenceView? = nil - + var currentCallView : ActiveCallView? = nil var conferenceGridView: VoipConferenceGridView? = nil var conferenceActiveSpeakerView: VoipConferenceActiveSpeakerView? = nil var conferenceAudioOnlyView: VoipConferenceAudioOnlyView? = nil - + let conferenceJoinSpinner = RotatingSpinner() - - + + let extraButtonsView = VoipExtraButtonsView() var numpadView : NumpadView? = nil var currentCallStatsVew : CallStatsView? = nil @@ -72,12 +72,12 @@ import linphonesw // Controls view.addSubview(controlsView) controlsView.alignParentBottom(withMargin:SharedLayoutConstants.buttons_bottom_margin).centerX().done() - + // Container view fullScreenMutableContainerView.backgroundColor = .clear self.view.addSubview(fullScreenMutableContainerView) fullScreenMutableContainerView.alignParentLeft(withMargin: ActiveCallOrConferenceView.content_inset).alignParentRight(withMargin: ActiveCallOrConferenceView.content_inset).matchParentHeight().alignAbove(view:controlsView,withMargin:SharedLayoutConstants.buttons_bottom_margin).done() - + // Current (Single) Call (VoipCallView) currentCallView = ActiveCallView() currentCallView!.isHidden = true @@ -95,7 +95,7 @@ import linphonesw if (currentCallData == nil) { self.callPausedByRemoteView?.isHidden = true self.callPausedByLocalView?.isHidden = true - + } else { currentCallData??.isIncoming.readCurrentAndObserve { _ in self.updateNavigation() } currentCallData??.isOutgoing.readCurrentAndObserve { _ in self.updateNavigation() } @@ -109,7 +109,7 @@ import linphonesw } } - + currentCallView!.matchParentDimmensions().done() // Paused by remote (Call) @@ -120,12 +120,12 @@ import linphonesw // Paused by local (Call) callPausedByLocalView = PausedCallOrConferenceView(iconName: "voip_conference_play_big",titleText: VoipTexts.call_locally_paused_title,subTitleText: VoipTexts.call_locally_paused_subtitle, onClickAction: { - CallsViewModel.shared.currentCallData.value??.togglePause() + CallsViewModel.shared.currentCallData.value??.togglePause() }) view.addSubview(callPausedByLocalView!) callPausedByLocalView?.matchParentSideBorders().matchParentHeight().alignAbove(view:controlsView,withMargin:SharedLayoutConstants.buttons_bottom_margin).done() callPausedByLocalView?.isHidden = true - + // Conference paused conferencePausedView = PausedCallOrConferenceView(iconName: "voip_conference_play_big",titleText: VoipTexts.conference_paused_title,subTitleText: VoipTexts.conference_paused_subtitle, onClickAction: { @@ -134,7 +134,7 @@ import linphonesw view.addSubview(conferencePausedView!) conferencePausedView?.matchParentSideBorders().matchParentHeight().alignAbove(view:controlsView,withMargin:SharedLayoutConstants.buttons_bottom_margin).done() conferencePausedView?.isHidden = true - + // Conference grid conferenceGridView = VoipConferenceGridView() fullScreenMutableContainerView.addSubview(conferenceGridView!) @@ -177,7 +177,7 @@ import linphonesw fullScreenMutableContainerView.addSubview(conferenceAudioOnlyView!) conferenceAudioOnlyView?.matchParentDimmensions().done() conferenceAudioOnlyView?.isHidden = true - + ConferenceViewModel.shared.conferenceDisplayMode.readCurrentAndObserve { (conferenceMode) in if (ConferenceViewModel.shared.conferenceExists.value == true) { self.displaySelectedConferenceLayout() @@ -230,7 +230,7 @@ import linphonesw }) view.addSubview(showextraButtons) showextraButtons.alignParentRight(withMargin:SharedLayoutConstants.margin_call_view_side_controls_buttons).alignParentBottom(withMargin:SharedLayoutConstants.buttons_bottom_margin).done() - + let boucingCounter = BouncingCounter(inButton:showextraButtons) view.addSubview(boucingCounter) boucingCounter.dataSource = CallsViewModel.shared.chatAndCallsCount @@ -252,14 +252,14 @@ import linphonesw if (visible == true && CallsViewModel.shared.currentCallData.value != nil ) { self.numpadView?.removeFromSuperview() self.shadingMask.isHidden = false - self.numpadView = NumpadView(superView: self.view,callData: CallsViewModel.shared.currentCallData.value!!,marginTop:self.currentCallView?.centerSection.frame.origin.y ?? 0.0, onDismissAction: { - ControlsViewModel.shared.numpadVisible.value = false + self.numpadView = NumpadView(superView: self.view,callData: CallsViewModel.shared.currentCallData.value!!,marginTop:self.currentCallView?.centerSection.frame.origin.y ?? 0.0, above:self.controlsView, onDismissAction: { + ControlsViewModel.shared.numpadVisible.value = false }) - } else { - self.numpadView?.removeFromSuperview() - self.shadingMask.isHidden = true - } - + } else { + self.numpadView?.removeFromSuperview() + self.shadingMask.isHidden = true + } + } // Call stats @@ -267,14 +267,13 @@ import linphonesw if (visible == true && CallsViewModel.shared.currentCallData.value != nil ) { self.currentCallStatsVew?.removeFromSuperview() self.shadingMask.isHidden = false - self.currentCallStatsVew = CallStatsView(superView: self.view,callData: CallsViewModel.shared.currentCallData.value!!,marginTop:self.currentCallView?.centerSection.frame.origin.y ?? 0.0, onDismissAction: { - ControlsViewModel.shared.callStatsVisible.value = false + self.currentCallStatsVew = CallStatsView(superView: self.view,callData: CallsViewModel.shared.currentCallData.value!!,marginTop:self.currentCallView?.centerSection.frame.origin.y ?? 0.0, above:self.controlsView, onDismissAction: { + ControlsViewModel.shared.callStatsVisible.value = false }) } else { - self.currentCallStatsVew?.removeFromSuperview() - self.shadingMask.isHidden = true - } - + self.currentCallStatsVew?.removeFromSuperview() + self.shadingMask.isHidden = true + } } // Video activation dialog request @@ -382,18 +381,18 @@ import linphonesw } } } else { - PhoneMainView.instance().changeCurrentView(self.compositeViewDescription()) + PhoneMainView.instance().changeCurrentView(self.compositeViewDescription()) } } } func goToChat() { /*guard - let chatRoom = CallsViewModel.shared.currentCallData.value??.chatRoom - else { - Log.w("[Call] Failed to find existing chat room associated to call") - return - }*/ + let chatRoom = CallsViewModel.shared.currentCallData.value??.chatRoom + else { + Log.w("[Call] Failed to find existing chat room associated to call") + return + }*/ PhoneMainView.instance().changeCurrentView(ChatsListView.compositeViewDescription()) } diff --git a/Classes/Swift/Voip/Views/CompositeViewControllers/OutgoingCallView.swift b/Classes/Swift/Voip/Views/CompositeViewControllers/OutgoingCallView.swift index 3c8f4c11f..9692d692a 100644 --- a/Classes/Swift/Voip/Views/CompositeViewControllers/OutgoingCallView.swift +++ b/Classes/Swift/Voip/Views/CompositeViewControllers/OutgoingCallView.swift @@ -61,7 +61,7 @@ import linphonesw showNumPad = CallControlButton(imageInset:UIEdgeInsets(top: numpad_icon_padding, left: numpad_icon_padding, bottom: numpad_icon_padding, right: numpad_icon_padding), buttonTheme: VoipTheme.call_numpad, onClickAction: { self.numpadView?.removeFromSuperview() self.shadingMask.isHidden = false - self.numpadView = NumpadView(superView: self.view,callData: self.callData!, marginTop: 0.0, onDismissAction: { + self.numpadView = NumpadView(superView: self.view,callData: self.callData!, marginTop: 0.0,above:controlsView, onDismissAction: { self.numpadView?.removeFromSuperview() self.shadingMask.isHidden = true }) diff --git a/Classes/Swift/Voip/Views/Fragments/CallStatsView.swift b/Classes/Swift/Voip/Views/Fragments/CallStatsView.swift index 27214817d..0c10ae3e1 100644 --- a/Classes/Swift/Voip/Views/Fragments/CallStatsView.swift +++ b/Classes/Swift/Voip/Views/Fragments/CallStatsView.swift @@ -28,13 +28,13 @@ import linphonesw let corner_radius = 20.0 let audio_video_margin = 20 - init(superView:UIView, callData:CallData, marginTop:CGFloat, onDismissAction : @escaping ()->Void) { + init(superView:UIView, callData:CallData, marginTop:CGFloat, above:UIView, onDismissAction : @escaping ()->Void) { super.init(frame:.zero) backgroundColor = VoipTheme.voip_translucent_popup_background layer.cornerRadius = corner_radius clipsToBounds = true superView.addSubview(self) - matchParentSideBorders(insetedByDx: side_margins).alignParentTop(withMargin: marginTop).alignParentBottom().done() + matchParentSideBorders(insetedByDx: side_margins).alignParentTop(withMargin: marginTop).alignAbove(view: above,withMargin: SharedLayoutConstants.buttons_bottom_margin).done() callData.callState.observe { state in if (state == Call.State.End) { diff --git a/Classes/Swift/Voip/Views/Fragments/CallsList/VoipCallCell.swift b/Classes/Swift/Voip/Views/Fragments/CallsList/VoipCallCell.swift index 3c651c562..9fc3e1d2a 100644 --- a/Classes/Swift/Voip/Views/Fragments/CallsList/VoipCallCell.swift +++ b/Classes/Swift/Voip/Views/Fragments/CallsList/VoipCallCell.swift @@ -31,8 +31,7 @@ class VoipCallCell: UITableViewCell { static let avatar_size = 45.0 let avatar_left_margin = 40.0 let texts_left_margin = 20.0 - let side_menu_icon_size = 80.0 - + let side_menu_icon_size = 70.0 var onMenuClickAction : (()->Void) = {} let callStatusIcon = UIImageView() @@ -86,11 +85,11 @@ class VoipCallCell: UITableViewCell { contentView.addSubview(nameAddress) nameAddress.toRightOf(avatar,withLeftMargin:texts_left_margin).wrapContentY().centerY().done() - menuButton = CallControlButton(buttonTheme: VoipTheme.voip_call_list_active_menu, onClickAction: { + menuButton = CallControlButton(width:Int(side_menu_icon_size), height:Int(side_menu_icon_size), buttonTheme: VoipTheme.voip_call_list_active_menu, onClickAction: { self.owningCallsListView?.toggleMenu(forCell: self) }) - contentView.addSubview(menuButton!) - menuButton!.size(w: side_menu_icon_size, h: side_menu_icon_size).alignParentRight().centerY().done() + addSubview(menuButton!) + menuButton!.alignParentRight().centerY().done() } diff --git a/Classes/Swift/Voip/Views/Fragments/Conference/VoipConferenceActiveSpeakerView.swift b/Classes/Swift/Voip/Views/Fragments/Conference/VoipConferenceActiveSpeakerView.swift index 5a718ff3d..b4a8572ac 100644 --- a/Classes/Swift/Voip/Views/Fragments/Conference/VoipConferenceActiveSpeakerView.swift +++ b/Classes/Swift/Voip/Views/Fragments/Conference/VoipConferenceActiveSpeakerView.swift @@ -163,7 +163,7 @@ class VoipConferenceActiveSpeakerView: UIView, UICollectionViewDataSource, UICol // Container view that can toggle full screen by single tap let fullScreenMutableView = UIView() addSubview(fullScreenMutableView) - fullScreenMutableView.backgroundColor = VoipTheme.voipBackgroundColor.get() + fullScreenMutableView.backgroundColor = ControlsViewModel.shared.fullScreenMode.value == true ? .black : VoipTheme.voipBackgroundColor.get() fullScreenMutableView.matchParentSideBorders().alignUnder(view:headerView,withMargin: ActiveCallView.center_view_margin_top).alignParentBottom().done() fullScreenOpaqueMasqForNotchedDevices.backgroundColor = fullScreenMutableView.backgroundColor @@ -202,6 +202,8 @@ class VoipConferenceActiveSpeakerView: UIView, UICollectionViewDataSource, UICol fullScreenMutableView.removeFromSuperview() self.fullScreenOpaqueMasqForNotchedDevices.removeFromSuperview() if (fullScreen == true) { + fullScreenMutableView.backgroundColor = .black + self.fullScreenOpaqueMasqForNotchedDevices.backgroundColor = .black self.fullScreenOpaqueMasqForNotchedDevices.addSubview(fullScreenMutableView) PhoneMainView.instance().mainViewController.view?.addSubview(self.fullScreenOpaqueMasqForNotchedDevices) self.fullScreenOpaqueMasqForNotchedDevices.matchParentDimmensions().done() @@ -211,6 +213,7 @@ class VoipConferenceActiveSpeakerView: UIView, UICollectionViewDataSource, UICol fullScreenMutableView.matchParentDimmensions().done() } } else { + fullScreenMutableView.backgroundColor = VoipTheme.voipBackgroundColor.get() self.addSubview(fullScreenMutableView) fullScreenMutableView.matchParentSideBorders().alignUnder(view:headerView,withMargin: ActiveCallView.center_view_margin_top).alignParentBottom().done() } diff --git a/Classes/Swift/Voip/Views/Fragments/Conference/VoipConferenceGridView.swift b/Classes/Swift/Voip/Views/Fragments/Conference/VoipConferenceGridView.swift index dcccdf8c7..b5d1598a4 100644 --- a/Classes/Swift/Voip/Views/Fragments/Conference/VoipConferenceGridView.swift +++ b/Classes/Swift/Voip/Views/Fragments/Conference/VoipConferenceGridView.swift @@ -142,7 +142,7 @@ class VoipConferenceGridView: UIView, UICollectionViewDataSource, UICollectionVi grid.isScrollEnabled = false addSubview(gridContainer) gridContainer.addSubview(grid) - gridContainer.backgroundColor = VoipTheme.voipBackgroundColor.get() + gridContainer.backgroundColor = ControlsViewModel.shared.fullScreenMode.value == true ? .black : VoipTheme.voipBackgroundColor.get() gridContainer.matchParentSideBorders(insetedByDx: inter_cell).alignUnder(view:headerView,withMargin: ActiveCallView.center_view_margin_top).alignParentBottom(withMargin: inter_cell).done() grid.matchParentDimmensions().done() @@ -164,10 +164,12 @@ class VoipConferenceGridView: UIView, UICollectionViewDataSource, UICollectionVi self.gridContainer.removeFromSuperview() PhoneMainView.instance().mainViewController.view?.addSubview(self.gridContainer) self.gridContainer.matchParentDimmensions().center().done() + self.gridContainer.backgroundColor = .black } else { self.gridContainer.removeFromSuperview() self.addSubview(self.gridContainer) self.gridContainer.matchParentSideBorders().alignUnder(view:headerView,withMargin: ActiveCallView.center_view_margin_top).alignParentBottom().done() + self.gridContainer.backgroundColor = VoipTheme.voipBackgroundColor.get() } DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { self.reloadData() diff --git a/Classes/Swift/Voip/Views/Fragments/NumpadView.swift b/Classes/Swift/Voip/Views/Fragments/NumpadView.swift index 148cbd38d..f69b5d3da 100644 --- a/Classes/Swift/Voip/Views/Fragments/NumpadView.swift +++ b/Classes/Swift/Voip/Views/Fragments/NumpadView.swift @@ -35,13 +35,13 @@ import linphonesw let side_padding = 50.0 - init(superView:UIView, callData:CallData, marginTop:CGFloat, onDismissAction : @escaping ()->Void) { + init(superView:UIView, callData:CallData, marginTop:CGFloat, above:UIView, onDismissAction : @escaping ()->Void) { super.init(frame:.zero) backgroundColor = VoipTheme.voip_translucent_popup_background layer.cornerRadius = corner_radius clipsToBounds = true superView.addSubview(self) - matchParentSideBorders(insetedByDx: side_margins).alignParentTop(withMargin: marginTop).alignParentBottom().done() + matchParentSideBorders(insetedByDx: side_margins).alignParentTop(withMargin: marginTop).alignAbove(view: above,withMargin: SharedLayoutConstants.buttons_bottom_margin).done() callData.callState.observe { state in if (state == Call.State.End) { diff --git a/Classes/Swift/Voip/Widgets/Avatar.swift b/Classes/Swift/Voip/Widgets/Avatar.swift index 3e54477f2..71fc032a2 100644 --- a/Classes/Swift/Voip/Widgets/Avatar.swift +++ b/Classes/Swift/Voip/Widgets/Avatar.swift @@ -46,7 +46,7 @@ class Avatar : UIImageView { func fillFromAddress(address:Address, isGroup:Bool = false) { if (isGroup) { - self.image = UIImage(named:"voip_multiple_contacts_avatar")?.withPadding(padding: 50) + self.image = UIImage(named:"voip_multiple_contacts_avatar") initialsLabel.isHidden = true } else if let image = address.contact()?.avatar() { self.image = image