diff --git a/Classes/Swift/Conference/Views/ConferenceWaitingRoomView.swift b/Classes/Swift/Conference/Views/ConferenceWaitingRoomView.swift index b48ce8f0e..9d0f3223e 100644 --- a/Classes/Swift/Conference/Views/ConferenceWaitingRoomView.swift +++ b/Classes/Swift/Conference/Views/ConferenceWaitingRoomView.swift @@ -39,7 +39,7 @@ import linphonesw let subject = StyledLabel(VoipTheme.conference_preview_subject_font) let localVideo = UIView() let switchCamera = UIImageView(image: UIImage(named:"voip_change_camera")?.tinted(with:.white)) - let noVideoLabel = StyledLabel(VoipTheme.conference_waiting_room_no_video_font, VoipTexts.conference_waiting_room_video_disabled) + let noVideoLabel = StyledLabel(VoipTheme.conference_waiting_room_no_video_font) let buttonsView = UIStackView() let cancel = FormButton(title: VoipTexts.cancel.uppercased(), backgroundStateColors: VoipTheme.primary_colors_background_gray, bold:false) @@ -48,7 +48,6 @@ import linphonesw var conferenceUrl : String? = nil let conferenceSubject = MutableLiveData() - var conferenceSpeaker : Bool? = false let controlsView = ControlsView(showVideo: true, controlsViewModel: ConferenceWaitingRoomViewModel.sharedModel) var layoutPicker : CallControlButton? = nil @@ -262,8 +261,14 @@ import linphonesw imSpeaker = true } } - - self.conferenceSpeaker = imSpeaker + + if imSpeaker { + self.noVideoLabel.text = VoipTexts.conference_waiting_room_video_disabled + } else { + self.noVideoLabel.text = "You're listener" + } + + ControlsViewModel.shared.imSpeaker = imSpeaker } } diff --git a/Classes/Swift/Voip/ViewModels/ConferenceViewModel.swift b/Classes/Swift/Voip/ViewModels/ConferenceViewModel.swift index 96ae25719..bd4e7777c 100644 --- a/Classes/Swift/Voip/ViewModels/ConferenceViewModel.swift +++ b/Classes/Swift/Voip/ViewModels/ConferenceViewModel.swift @@ -56,6 +56,7 @@ class ConferenceViewModel { let participantAdminStatusChangedEvent = MutableLiveData() let firstToJoinEvent = MutableLiveData(false) + let participantAdded = MutableLiveData(false) let allParticipantsLeftEvent = MutableLiveData(false) @@ -68,6 +69,7 @@ class ConferenceViewModel { conferenceDelegate = ConferenceDelegateStub( onParticipantAdded: { (conference: Conference, participant: Participant) in Log.i("[Conference] \(conference) Participant \(participant) added") + self.participantAdded.value = true self.updateParticipantsList(conference) }, onParticipantRemoved: {(conference: Conference, participant: Participant) in diff --git a/Classes/Swift/Voip/ViewModels/ControlsViewModel.swift b/Classes/Swift/Voip/ViewModels/ControlsViewModel.swift index 87c324514..439b76d00 100644 --- a/Classes/Swift/Voip/ViewModels/ControlsViewModel.swift +++ b/Classes/Swift/Voip/ViewModels/ControlsViewModel.swift @@ -54,7 +54,8 @@ class ControlsViewModel { static let shared = ControlsViewModel() private var coreDelegate : CoreDelegateStub? private var previousCallState = Call.State.Idle - + + var imSpeaker : Bool = true init () { coreDelegate = CoreDelegateStub( diff --git a/Classes/Swift/Voip/Views/CompositeViewControllers/ConferenceCallView.swift b/Classes/Swift/Voip/Views/CompositeViewControllers/ConferenceCallView.swift index a5c2ddb1f..470ad32b9 100644 --- a/Classes/Swift/Voip/Views/CompositeViewControllers/ConferenceCallView.swift +++ b/Classes/Swift/Voip/Views/CompositeViewControllers/ConferenceCallView.swift @@ -30,6 +30,7 @@ import linphonesw var conferenceAudioOnlyView: VoipConferenceAudioOnlyView? = nil let conferenceJoinSpinner = RotatingSpinner(color:VoipTheme.dark_grey_color) @objc var participantsListView : ParticipantsListView? = nil + let noSpeaker = StyledLabel(VoipTheme.conference_waiting_room_no_video_font, "No speaker has joined the meeting yet") static let compositeDescription = UICompositeViewDescription(ConferenceCallView.self, statusBar: StatusBarView.self, tabBar: nil, sideMenu: nil, fullscreen: false, isLeftFragment: false,fragmentWith: nil) static func compositeViewDescription() -> UICompositeViewDescription! { return compositeDescription } @@ -45,6 +46,13 @@ import linphonesw view.addSubview(conferencePausedView!) conferencePausedView?.matchParentSideBorders().matchParentHeight().alignAbove(view:controlsView,withMargin:SharedLayoutConstants.buttons_bottom_margin).done() conferencePausedView?.isHidden = true + + + view.addSubview(noSpeaker) + noSpeaker.matchParentSideBorders(insetedByDx: 30).height(250).centerY().done() + noSpeaker.backgroundColor = VoipTheme.voipParticipantBackgroundColor.get() + noSpeaker.isHidden = true + // Conference grid conferenceGridView = VoipConferenceGridView() @@ -125,8 +133,14 @@ import linphonesw ConferenceViewModel.shared.firstToJoinEvent.observe { (first) in if (first == true) { VoipDialog.toast(message: VoipTexts.conference_first_to_join) - } + if !ControlsViewModel.shared.imSpeaker { + self.noSpeaker.isHidden = false + } + } } + ConferenceViewModel.shared.participantAdded.observe { (participant) in + self.noSpeaker.isHidden = true + } view.onClick { ControlsViewModel.shared.audioRoutesSelected.value = false diff --git a/Classes/Swift/Voip/Views/Fragments/ControlsView.swift b/Classes/Swift/Voip/Views/Fragments/ControlsView.swift index a78814caf..ccc8c545e 100644 --- a/Classes/Swift/Voip/Views/Fragments/ControlsView.swift +++ b/Classes/Swift/Voip/Views/Fragments/ControlsView.swift @@ -39,10 +39,14 @@ class ControlsView: UIStackView { }) addArrangedSubview(mute) controlsViewModel.isMicrophoneMuted.readCurrentAndObserve { (muted) in - mute.isSelected = muted == true + mute.isSelected = muted == true } controlsViewModel.isMuteMicrophoneEnabled.readCurrentAndObserve { (enabled) in - mute.isEnabled = enabled == true + if ControlsViewModel.shared.imSpeaker { + mute.isEnabled = enabled == true + } else { + mute.isEnabled = false + } } mute.accessibilityIdentifier = "call_control_view_mute" mute.accessibilityLabel = "Mute" @@ -95,13 +99,25 @@ class ControlsView: UIStackView { addArrangedSubview(video) video.showActivityIndicatorDataSource = controlsViewModel.isVideoUpdateInProgress controlsViewModel.isVideoEnabled.readCurrentAndObserve { (selected) in - video.isSelected = selected == true + if ControlsViewModel.shared.imSpeaker { + video.isSelected = selected == true + } else { + video.isSelected = false + } } controlsViewModel.isVideoAvailable.readCurrentAndObserve { (available) in - video.isEnabled = available == true && controlsViewModel.isVideoUpdateInProgress.value != true + if ControlsViewModel.shared.imSpeaker { + video.isEnabled = available == true && controlsViewModel.isVideoUpdateInProgress.value != true + } else { + video.isEnabled = false + } } controlsViewModel.isVideoUpdateInProgress.readCurrentAndObserve { (updateInProgress) in - video.isEnabled = updateInProgress != true && controlsViewModel.isVideoAvailable.value == true + if ControlsViewModel.shared.imSpeaker { + video.isEnabled = updateInProgress != true && controlsViewModel.isVideoAvailable.value == true + } else { + video.isEnabled = false + } } video.accessibilityIdentifier = "call_control_view_video" video.accessibilityLabel = "Video"