forked from mirrors/linphone-iphone
Adapt to latest sdk change related to conference + implemented joining spinner + refactored conference miniatures update
This commit is contained in:
parent
5040e6dae9
commit
ec70c161f3
5 changed files with 188 additions and 112 deletions
|
|
@ -26,11 +26,14 @@ class ConferenceParticipantDeviceData {
|
|||
let isMe:Bool
|
||||
|
||||
let videoEnabled = MutableLiveData<Bool>()
|
||||
let activeSpeaker = MutableLiveData<Bool>()
|
||||
let isSpeaking = MutableLiveData<Bool>()
|
||||
let micMuted = MutableLiveData<Bool>()
|
||||
|
||||
let isInConference = MutableLiveData<Bool>()
|
||||
|
||||
let isJoining = MutableLiveData<Bool>()
|
||||
|
||||
|
||||
var core : Core { get { Core.get() } }
|
||||
|
||||
private var participantDeviceDelegate : ParticipantDeviceDelegate?
|
||||
|
|
@ -41,19 +44,22 @@ class ConferenceParticipantDeviceData {
|
|||
participantDeviceDelegate = ParticipantDeviceDelegateStub(
|
||||
onIsSpeakingChanged: { (participantDevice, isSpeaking) in
|
||||
Log.i("[Conference Participant Device] Participant \(participantDevice.address?.asStringUriOnly()) isspeaking = \(isSpeaking)")
|
||||
self.activeSpeaker.value = isSpeaking
|
||||
self.isSpeaking.value = isSpeaking
|
||||
},
|
||||
onIsMuted: { (participantDevice, isMuted) in
|
||||
Log.i("[Conference Participant Device] Participant \(participantDevice.address?.asStringUriOnly()) muted = \(isMuted)")
|
||||
self.micMuted.value = isMuted
|
||||
},
|
||||
onConferenceJoined: { (participantDevice) in
|
||||
Log.i("[Conference Participant Device] Participant \(participantDevice.address?.asStringUriOnly()) has joined the conference")
|
||||
self.isInConference.value = true
|
||||
},
|
||||
onConferenceLeft: { (participantDevice) in
|
||||
Log.i("[Conference Participant Device] Participant \(participantDevice.address?.asStringUriOnly()) has left the conference")
|
||||
self.isInConference.value = false
|
||||
onStateChanged: { (participantDevice, state) in
|
||||
Log.i("[Conference Participant Device] Participant \(participantDevice.address?.asStringUriOnly()) state has changed: \(state)")
|
||||
if ([.Joining,.Alerting].contains(state)) {
|
||||
self.isJoining.value = true
|
||||
} else if (state == .OnHold) {
|
||||
self.isInConference.value = false
|
||||
} else if (state == .Present) {
|
||||
self.isJoining.value = false
|
||||
self.isInConference.value = true
|
||||
}
|
||||
},
|
||||
onStreamCapabilityChanged: { (participantDevice, direction, streamType) in
|
||||
Log.i("[Conference Participant Device] Participant \(participantDevice.address?.asStringUriOnly()) video stream direction changed: \(direction)")
|
||||
|
|
@ -72,7 +78,7 @@ class ConferenceParticipantDeviceData {
|
|||
)
|
||||
|
||||
participantDevice.addDelegate(delegate: participantDeviceDelegate!)
|
||||
activeSpeaker.value = false
|
||||
isSpeaking.value = false
|
||||
micMuted.value = participantDevice.isMuted
|
||||
|
||||
videoEnabled.value = participantDevice.getStreamAvailability(streamType: .Video)
|
||||
|
|
@ -90,7 +96,7 @@ class ConferenceParticipantDeviceData {
|
|||
func clearObservers() {
|
||||
isInConference.clearObservers()
|
||||
videoEnabled.clearObservers()
|
||||
activeSpeaker.clearObservers()
|
||||
isSpeaking.clearObservers()
|
||||
}
|
||||
|
||||
func switchCamera() {
|
||||
|
|
|
|||
|
|
@ -97,16 +97,16 @@ class ConferenceViewModel {
|
|||
Log.w("[Conference] Failed to find participant [\(participant.address!.asStringUriOnly())] in conferenceParticipants list")
|
||||
}
|
||||
},
|
||||
onParticipantDeviceLeft: { (conference: Conference, device: ParticipantDevice) in
|
||||
onParticipantDeviceStateChanged: { (conference: Conference, device: ParticipantDevice, state: ParticipantDeviceState) in
|
||||
if (conference.isMe(uri: device.address!)) {
|
||||
Log.i("[Conference] Left conference")
|
||||
self.isConferenceLocallyPaused.value = true
|
||||
}
|
||||
},
|
||||
onParticipantDeviceJoined: { (conference: Conference, device: ParticipantDevice) in
|
||||
if (conference.isMe(uri: device.address!)) {
|
||||
Log.i("[Conference] Joined conference")
|
||||
self.isConferenceLocallyPaused.value = false
|
||||
if (state == .Present) {
|
||||
Log.i("[Conference] Entered conference")
|
||||
self.isConferenceLocallyPaused.value = false
|
||||
}
|
||||
if (state == .OnHold) {
|
||||
Log.i("[Conference] Left conference")
|
||||
self.isConferenceLocallyPaused.value = true
|
||||
}
|
||||
}
|
||||
},
|
||||
onStateChanged: { (conference: Conference, state: Conference.State) in
|
||||
|
|
|
|||
|
|
@ -32,39 +32,31 @@ class VoipActiveSpeakerParticipantCell: UICollectionViewCell {
|
|||
let switch_camera_button_size = 30
|
||||
static let mute_size = 25
|
||||
let mute_margin = 5
|
||||
|
||||
|
||||
|
||||
|
||||
let videoView = UIView()
|
||||
let avatar = Avatar(diameter:VoipActiveSpeakerParticipantCell.avatar_size,color:VoipTheme.voipBackgroundColor, textStyle: VoipTheme.call_generated_avatar_medium)
|
||||
let pause = UIImageView(image: UIImage(named: "voip_pause")?.tinted(with: .white))
|
||||
let switchCamera = UIImageView(image: UIImage(named:"voip_change_camera")?.tinted(with:.white))
|
||||
let displayName = StyledLabel(VoipTheme.conference_participant_name_font_as)
|
||||
let pauseLabel = StyledLabel(VoipTheme.conference_participant_name_font_as,VoipTexts.conference_participant_paused)
|
||||
let muted = MicMuted(VoipActiveSpeakerParticipantCell.mute_size)
|
||||
|
||||
let joining = RotatingSpinner()
|
||||
|
||||
var participantData: ConferenceParticipantDeviceData? = nil {
|
||||
didSet {
|
||||
if let data = participantData {
|
||||
self.updateElements()
|
||||
data.isJoining.clearObservers()
|
||||
data.isJoining.observe { _ in
|
||||
self.updateElements()
|
||||
}
|
||||
data.isInConference.clearObservers()
|
||||
data.isInConference.readCurrentAndObserve { (isIn) in
|
||||
self.updateBackground()
|
||||
self.pause.isHidden = isIn == true
|
||||
self.pauseLabel.isHidden = self.pause.isHidden
|
||||
self.videoView.isHidden = data.videoEnabled.value != true
|
||||
self.switchCamera.isHidden = data.videoEnabled.value != true || !data.isSwitchCameraAvailable()
|
||||
data.isInConference.observe { _ in
|
||||
self.updateElements()
|
||||
}
|
||||
data.videoEnabled.clearObservers()
|
||||
data.videoEnabled.readCurrentAndObserve { (videoEnabled) in
|
||||
self.updateBackground()
|
||||
if (videoEnabled == true) {
|
||||
self.videoView.isHidden = false
|
||||
data.setVideoView(view: self.videoView)
|
||||
self.avatar.isHidden = true
|
||||
} else {
|
||||
self.videoView.isHidden = true
|
||||
self.avatar.isHidden = false
|
||||
}
|
||||
self.switchCamera.isHidden = videoEnabled != true || !data.isSwitchCameraAvailable()
|
||||
data.videoEnabled.observe { _ in
|
||||
self.updateElements()
|
||||
}
|
||||
data.participantDevice.address.map {
|
||||
avatar.fillFromAddress(address: $0)
|
||||
|
|
@ -72,32 +64,60 @@ class VoipActiveSpeakerParticipantCell: UICollectionViewCell {
|
|||
self.displayName.text = displayName
|
||||
}
|
||||
}
|
||||
data.activeSpeaker.clearObservers()
|
||||
data.activeSpeaker.readCurrentAndObserve { (active) in
|
||||
if (active == true) {
|
||||
self.layer.borderWidth = 2
|
||||
} else {
|
||||
self.layer.borderWidth = 0
|
||||
}
|
||||
data.isSpeaking.clearObservers()
|
||||
data.isSpeaking.observe { _ in
|
||||
self.updateElements(skipVideo: true)
|
||||
}
|
||||
data.micMuted.clearObservers()
|
||||
data.micMuted.readCurrentAndObserve { (muted) in
|
||||
self.muted.isHidden = muted != true
|
||||
data.micMuted.observe { _ in
|
||||
self.updateElements(skipVideo: true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func updateBackground() {
|
||||
func updateElements(skipVideo:Bool = false) {
|
||||
if let data = participantData {
|
||||
if (data.isInConference.value != true) {
|
||||
|
||||
// Background
|
||||
if (data.isInConference.value != true && data.isJoining.value != true) {
|
||||
self.contentView.backgroundColor = VoipTheme.voip_conference_participant_paused_background
|
||||
} else if (data.videoEnabled.value == true) {
|
||||
self.contentView.backgroundColor = .black
|
||||
} else {
|
||||
self.contentView.backgroundColor = VoipTheme.voipParticipantBackgroundColor.get()
|
||||
|
||||
}
|
||||
|
||||
// Avatar
|
||||
self.avatar.isHidden = (data.isInConference.value != true && data.isJoining.value != true) || data.videoEnabled.value == true
|
||||
|
||||
// Video
|
||||
if (!skipVideo) {
|
||||
self.videoView.isHidden = data.isInConference.value != true || data.videoEnabled.value != true
|
||||
if (!self.videoView.isHidden) {
|
||||
data.setVideoView(view: self.videoView)
|
||||
}
|
||||
self.switchCamera.isHidden = self.videoView.isHidden || !data.isSwitchCameraAvailable()
|
||||
}
|
||||
|
||||
// Pause
|
||||
self.pause.isHidden = data.isInConference.value == true || data.isJoining.value == true
|
||||
|
||||
// Border for active speaker
|
||||
self.layer.borderWidth = data.isSpeaking.value == true ? 2 : 0
|
||||
|
||||
// Joining indicator
|
||||
if (data.isJoining.value == true) {
|
||||
self.joining.isHidden = false
|
||||
self.joining.startRotation()
|
||||
} else {
|
||||
self.joining.isHidden = true
|
||||
self.joining.stopRotation()
|
||||
}
|
||||
|
||||
// Muted
|
||||
self.muted.isHidden = data.micMuted.value != true
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -130,14 +150,13 @@ class VoipActiveSpeakerParticipantCell: UICollectionViewCell {
|
|||
|
||||
contentView.addSubview(displayName)
|
||||
displayName.matchParentSideBorders(insetedByDx:ActiveCallView.bottom_displayname_margin_left).alignParentBottom(withMargin:ActiveCallView.bottom_displayname_margin_bottom).done()
|
||||
|
||||
// Paused label commented out as in Android 10.06.2022
|
||||
// contentView.addSubview(pauseLabel)
|
||||
//pauseLabel.toRightOf(displayName).alignParentBottom(withMargin:ActiveCallView.bottom_displayname_margin_bottom).done()
|
||||
|
||||
|
||||
contentView.addSubview(muted)
|
||||
muted.alignParentLeft(withMargin: mute_margin).alignParentTop(withMargin:mute_margin).done()
|
||||
|
||||
contentView.addSubview(joining)
|
||||
joining.square(VoipActiveSpeakerParticipantCell.mute_size).alignParentTop(withMargin: mute_margin).alignParentLeft(withMargin: mute_margin).done()
|
||||
|
||||
contentView.matchParentDimmensions().done()
|
||||
makeHeightMatchWidth().done()
|
||||
|
||||
|
|
|
|||
|
|
@ -36,43 +36,68 @@ class VoipAudioOnlyParticipantCell: UICollectionViewCell {
|
|||
let avatar = Avatar(diameter:VoipCallCell.avatar_size,color:VoipTheme.voipBackgroundColor, textStyle: VoipTheme.call_generated_avatar_small)
|
||||
let paused = UIImageView(image: UIImage(named: "voip_pause")?.tinted(with: .white))
|
||||
let muted = MicMuted(VoipAudioOnlyParticipantCell.mute_size)
|
||||
let joining = RotatingSpinner()
|
||||
|
||||
let displayName = StyledLabel(VoipTheme.conference_participant_name_font_as)
|
||||
|
||||
var participantData: ConferenceParticipantDeviceData? = nil {
|
||||
didSet {
|
||||
if let data = participantData {
|
||||
self.displayName.text = ""
|
||||
self.updateElements()
|
||||
data.isJoining.clearObservers()
|
||||
data.isJoining.observe { _ in
|
||||
self.updateElements()
|
||||
}
|
||||
data.isInConference.clearObservers()
|
||||
data.isInConference.readCurrentAndObserve { (isIn) in
|
||||
self.avatar.isHidden = isIn != true
|
||||
self.paused.isHidden = isIn == true
|
||||
data.participantDevice.address.map {
|
||||
self.avatar.fillFromAddress(address: $0)
|
||||
if let displayName = $0.addressBookEnhancedDisplayName() {
|
||||
self.displayName.text = displayName + (isIn == true ? "" : " \(VoipTexts.conference_participant_paused)")
|
||||
}
|
||||
data.isInConference.observe { _ in
|
||||
self.updateElements()
|
||||
}
|
||||
data.participantDevice.address.map {
|
||||
avatar.fillFromAddress(address: $0)
|
||||
if let displayName = $0.addressBookEnhancedDisplayName() {
|
||||
self.displayName.text = displayName
|
||||
}
|
||||
}
|
||||
if (data.participantDevice.address == nil) {
|
||||
avatar.isHidden = true
|
||||
}
|
||||
data.activeSpeaker.clearObservers()
|
||||
data.activeSpeaker.readCurrentAndObserve { (active) in
|
||||
if (active == true) {
|
||||
self.layer.borderWidth = 2
|
||||
} else {
|
||||
self.layer.borderWidth = 0
|
||||
}
|
||||
data.isSpeaking.clearObservers()
|
||||
data.isSpeaking.observe { _ in
|
||||
self.updateElements(skipVideo: true)
|
||||
}
|
||||
data.micMuted.clearObservers()
|
||||
data.micMuted.readCurrentAndObserve { (muted) in
|
||||
self.muted.isHidden = muted != true
|
||||
data.micMuted.observe { _ in
|
||||
self.updateElements(skipVideo: true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func updateElements(skipVideo:Bool = false) {
|
||||
if let data = participantData {
|
||||
|
||||
// Avatar
|
||||
self.avatar.isHidden = data.isInConference.value != true && data.isJoining.value != true
|
||||
|
||||
|
||||
// Pause
|
||||
self.paused.isHidden = data.isInConference.value == true || data.isJoining.value == true
|
||||
|
||||
// Border for active speaker
|
||||
self.layer.borderWidth = data.isSpeaking.value == true ? 2 : 0
|
||||
|
||||
// Joining indicator
|
||||
if (data.isJoining.value == true) {
|
||||
self.joining.isHidden = false
|
||||
self.joining.startRotation()
|
||||
} else {
|
||||
self.joining.isHidden = true
|
||||
self.joining.stopRotation()
|
||||
}
|
||||
|
||||
// Muted
|
||||
self.muted.isHidden = data.micMuted.value != true
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override init(frame:CGRect) {
|
||||
super.init(frame:.zero)
|
||||
|
|
@ -98,6 +123,10 @@ class VoipAudioOnlyParticipantCell: UICollectionViewCell {
|
|||
|
||||
contentView.addSubview(muted)
|
||||
muted.alignParentRight(withMargin: common_margin).toRightOf(displayName,withLeftMargin: common_margin).centerY().done()
|
||||
|
||||
contentView.addSubview(joining)
|
||||
joining.alignParentRight(withMargin: common_margin).toRightOf(displayName,withLeftMargin: common_margin).centerY().done()
|
||||
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
|
|
|
|||
|
|
@ -42,67 +42,85 @@ class VoipGridParticipantCell: UICollectionViewCell {
|
|||
let displayName = StyledLabel(VoipTheme.conference_participant_name_font_grid)
|
||||
let pauseLabel = StyledLabel(VoipTheme.conference_participant_name_font_grid,VoipTexts.conference_participant_paused)
|
||||
let muted = MicMuted(VoipActiveSpeakerParticipantCell.mute_size)
|
||||
let joining = RotatingSpinner()
|
||||
|
||||
var participantData: ConferenceParticipantDeviceData? = nil {
|
||||
didSet {
|
||||
if let data = participantData {
|
||||
self.updateElements()
|
||||
data.isJoining.clearObservers()
|
||||
data.isJoining.observe { _ in
|
||||
self.updateElements()
|
||||
}
|
||||
data.isInConference.clearObservers()
|
||||
data.isInConference.readCurrentAndObserve { (isIn) in
|
||||
self.updateBackground()
|
||||
self.pause.isHidden = isIn == true
|
||||
self.pauseLabel.isHidden = self.pause.isHidden
|
||||
self.videoView.isHidden = data.videoEnabled.value != true
|
||||
self.switchCamera.isHidden = data.videoEnabled.value != true || !data.isSwitchCameraAvailable()
|
||||
data.isInConference.observe { _ in
|
||||
self.updateElements()
|
||||
}
|
||||
data.videoEnabled.clearObservers()
|
||||
data.videoEnabled.readCurrentAndObserve { (videoEnabled) in
|
||||
self.updateBackground()
|
||||
if (videoEnabled == true) {
|
||||
self.videoView.isHidden = false
|
||||
data.setVideoView(view: self.videoView)
|
||||
self.avatar.isHidden = true
|
||||
} else {
|
||||
self.videoView.isHidden = true
|
||||
self.avatar.isHidden = false
|
||||
}
|
||||
self.switchCamera.isHidden = videoEnabled != true || !data.isSwitchCameraAvailable()
|
||||
data.videoEnabled.observe { _ in
|
||||
self.updateElements()
|
||||
}
|
||||
if (data.participantDevice.address == nil) {
|
||||
avatar.isHidden = true
|
||||
}
|
||||
self.displayName.text = ""
|
||||
data.participantDevice.address.map {
|
||||
avatar.fillFromAddress(address: $0)
|
||||
if let displayName = $0.addressBookEnhancedDisplayName() {
|
||||
self.displayName.text = displayName
|
||||
}
|
||||
}
|
||||
data.activeSpeaker.clearObservers()
|
||||
data.activeSpeaker.readCurrentAndObserve { (active) in
|
||||
if (active == true) {
|
||||
self.layer.borderWidth = 2
|
||||
} else {
|
||||
self.layer.borderWidth = 0
|
||||
}
|
||||
data.isSpeaking.clearObservers()
|
||||
data.isSpeaking.observe { _ in
|
||||
self.updateElements(skipVideo: true)
|
||||
}
|
||||
data.micMuted.clearObservers()
|
||||
data.micMuted.readCurrentAndObserve { (muted) in
|
||||
self.muted.isHidden = muted != true
|
||||
data.micMuted.observe { _ in
|
||||
self.updateElements(skipVideo: true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func updateBackground() {
|
||||
func updateElements(skipVideo:Bool = false) {
|
||||
if let data = participantData {
|
||||
if (data.isInConference.value != true) {
|
||||
|
||||
// Background
|
||||
if (data.isInConference.value != true && data.isJoining.value != true) {
|
||||
self.contentView.backgroundColor = VoipTheme.voip_conference_participant_paused_background
|
||||
} else if (data.videoEnabled.value == true) {
|
||||
self.contentView.backgroundColor = .black
|
||||
} else {
|
||||
self.contentView.backgroundColor = VoipTheme.voipParticipantBackgroundColor.get()
|
||||
|
||||
}
|
||||
|
||||
// Avatar
|
||||
self.avatar.isHidden = (data.isInConference.value != true && data.isJoining.value != true) || data.videoEnabled.value == true
|
||||
|
||||
// Video
|
||||
if (!skipVideo) {
|
||||
self.videoView.isHidden = data.isInConference.value != true || data.videoEnabled.value != true
|
||||
if (!self.videoView.isHidden) {
|
||||
data.setVideoView(view: self.videoView)
|
||||
}
|
||||
self.switchCamera.isHidden = self.videoView.isHidden || !data.isSwitchCameraAvailable()
|
||||
}
|
||||
|
||||
// Pause
|
||||
self.pause.isHidden = data.isInConference.value == true || data.isJoining.value == true
|
||||
self.pauseLabel.isHidden = self.pause.isHidden
|
||||
|
||||
// Border for active speaker
|
||||
self.layer.borderWidth = data.isSpeaking.value == true ? 2 : 0
|
||||
|
||||
// Joining indicator
|
||||
if (data.isJoining.value == true) {
|
||||
self.joining.isHidden = false
|
||||
self.joining.startRotation()
|
||||
} else {
|
||||
self.joining.isHidden = true
|
||||
self.joining.stopRotation()
|
||||
}
|
||||
|
||||
// Muted
|
||||
self.muted.isHidden = data.micMuted.value != true
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -142,6 +160,10 @@ class VoipGridParticipantCell: UICollectionViewCell {
|
|||
contentView.addSubview(muted)
|
||||
muted.alignParentLeft(withMargin: mute_margin).alignParentTop(withMargin:mute_margin).done()
|
||||
|
||||
contentView.addSubview(joining)
|
||||
joining.square(VoipActiveSpeakerParticipantCell.mute_size).alignParentTop(withMargin: mute_margin).alignParentLeft(withMargin: mute_margin).done()
|
||||
|
||||
|
||||
contentView.matchParentDimmensions().done()
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue