Add 'call is full' UI

This commit is contained in:
Nora Trapp 2020-11-20 10:39:41 -08:00
parent c4432f804c
commit 31ca0f4af9
7 changed files with 118 additions and 10 deletions

View File

@ -4,6 +4,7 @@
import Foundation
import SignalServiceKit
import SignalRingRTC
class GroupCallUpdateMessageHandler: CallServiceObserver, CallObserver {

View File

@ -286,3 +286,14 @@ extension SignalCall: IndividualCallDelegate {
observers.elements.forEach { $0.individualCallRemoteVideoMuteDidChange(self, isVideoMuted: isVideoMuted) }
}
}
extension GroupCall {
public var isFull: Bool {
guard let peekInfo = peekInfo, let maxDevices = peekInfo.maxDevices else { return false }
return peekInfo.deviceCount >= maxDevices
}
public var maxDevices: UInt32? {
guard let peekInfo = peekInfo, let maxDevices = peekInfo.maxDevices else { return nil }
return maxDevices
}
}

View File

@ -76,6 +76,14 @@ class CallControls: UIView {
}
button.contentEdgeInsets = UIEdgeInsets(top: 11, leading: 11, bottom: 11, trailing: 11)
button.addSubview(joinButtonActivityIndicator)
button.setTitle(
NSLocalizedString(
"GROUP_CALL_IS_FULL",
comment: "Text explaining the group call is full"
),
for: .disabled
)
button.setTitleColor(.ows_whiteAlpha40, for: .disabled)
joinButtonActivityIndicator.autoCenterInSuperview()
return button
}()
@ -221,12 +229,16 @@ class CallControls: UIView {
let startCallText = NSLocalizedString("GROUP_CALL_START_BUTTON", comment: "Button to start a group call")
let joinCallText = NSLocalizedString("GROUP_CALL_JOIN_BUTTON", comment: "Button to join an ongoing group call")
if call.groupCall.localDeviceState.joinState == .joining {
if call.groupCall.isFull {
joinButton.isEnabled = false
} else if call.groupCall.localDeviceState.joinState == .joining {
joinButton.isEnabled = true
joinButton.isUserInteractionEnabled = false
joinButtonActivityIndicator.startAnimating()
joinButton.setTitle("", for: .normal)
} else {
joinButton.isEnabled = true
joinButton.isUserInteractionEnabled = true
joinButtonActivityIndicator.stopAnimating()

View File

@ -92,6 +92,41 @@ class GroupCallLocalMemberView: GroupCallMemberView {
lazy var videoOffIndicatorWidthConstraint = videoOffIndicatorImage.autoSetDimension(.width, toSize: videoOffIndicatorWidth)
lazy var callFullLabel: UILabel = {
let label = UILabel()
label.numberOfLines = 0
label.lineBreakMode = .byWordWrapping
label.font = .ows_dynamicTypeSubheadline
label.textAlignment = .center
label.textColor = Theme.darkThemePrimaryColor
return label
}()
lazy var callFullStack: UIStackView = {
let callFullStack = UIStackView()
callFullStack.axis = .vertical
callFullStack.spacing = 8
let imageView = UIImageView(image: #imageLiteral(resourceName: "sad-cat"))
imageView.contentMode = .scaleAspectFit
imageView.autoSetDimensions(to: CGSize(square: 200))
callFullStack.addArrangedSubview(imageView)
let titleLabel = UILabel()
titleLabel.text = NSLocalizedString(
"GROUP_CALL_IS_FULL",
comment: "Text explaining the group call is full"
)
titleLabel.font = UIFont.ows_dynamicTypeSubheadline.ows_semibold
titleLabel.textAlignment = .center
titleLabel.textColor = Theme.darkThemePrimaryColor
callFullStack.addArrangedSubview(titleLabel)
callFullStack.addArrangedSubview(callFullLabel)
return callFullStack
}()
override init() {
super.init()
@ -114,6 +149,10 @@ class GroupCallLocalMemberView: GroupCallMemberView {
insertSubview(videoView, belowSubview: muteIndicatorImage)
videoView.frame = bounds
addSubview(callFullStack)
callFullStack.autoAlignAxis(.horizontal, toSameAxisOf: self, withOffset: -30)
callFullStack.autoPinWidthToSuperview(withMargin: 16)
layer.shadowOffset = .zero
layer.shadowOpacity = 0.25
layer.shadowRadius = 4
@ -130,7 +169,34 @@ class GroupCallLocalMemberView: GroupCallMemberView {
videoView.isHidden = call.groupCall.isOutgoingVideoMuted
videoView.captureSession = call.videoCaptureController.captureSession
noVideoView.isHidden = !videoView.isHidden
videoOffLabel.isHidden = !videoView.isHidden || !isFullScreen
if isFullScreen,
call.groupCall.isFull,
case .notJoined = call.groupCall.localDeviceState.joinState {
let text: String
if let maxDevices = call.groupCall.maxDevices {
let formatString = NSLocalizedString(
"GROUP_CALL_HAS_MAX_DEVICES_FORMAT",
comment: "An error displayed to the user when the group call ends because it has exceeded the max devices. Embeds {{max device count}}."
)
text = String(format: formatString, maxDevices)
} else {
text = NSLocalizedString(
"GROUP_CALL_HAS_MAX_DEVICES_UNKNOWN_COUNT",
comment: "An error displayed to the user when the group call ends because it has exceeded the max devices."
)
}
callFullLabel.text = text
callFullStack.isHidden = false
videoOffLabel.isHidden = true
videoOffIndicatorImage.isHidden = true
} else {
callFullStack.isHidden = true
videoOffLabel.isHidden = !videoView.isHidden || !isFullScreen
videoOffIndicatorImage.isHidden = !videoView.isHidden
}
guard let localAddress = tsAccountManager.localAddress else {
return owsFailDebug("missing local address")

View File

@ -142,6 +142,11 @@ extension GroupCallNotificationView: CallObserver {
AssertIsOnMainThread()
owsAssertDebug(call.isGroupCall)
hasJoined = false
activeMembers.removeAll()
membersPendingJoinNotification.removeAll()
membersPendingLeaveNotification.removeAll()
updateActiveMembers()
}
}

View File

@ -471,14 +471,21 @@ extension GroupCallViewController: CallObserver {
guard reason != .deviceExplicitlyDisconnected else { return }
let title: String
switch reason {
case .hasMaxDevices:
let formatString = NSLocalizedString(
"GROUP_CALL_HAS_MAX_DEVICES_FORMAT",
comment: "An error displayed to the user when the group call ends because it has exceeded the max devices. Embeds {{max device count}}."
)
title = String(format: formatString, groupCall.peekInfo?.maxDevices ?? 5)
default:
if reason == .hasMaxDevices {
if let maxDevices = groupCall.maxDevices {
let formatString = NSLocalizedString(
"GROUP_CALL_HAS_MAX_DEVICES_FORMAT",
comment: "An error displayed to the user when the group call ends because it has exceeded the max devices. Embeds {{max device count}}."
)
title = String(format: formatString, maxDevices)
} else {
title = NSLocalizedString(
"GROUP_CALL_HAS_MAX_DEVICES_UNKNOWN_COUNT",
comment: "An error displayed to the user when the group call ends because it has exceeded the max devices."
)
}
} else {
owsFailDebug("Group call ended with reason \(reason)")
title = NSLocalizedString(
"GROUP_CALL_UNEXPECTEDLY_ENDED",

View File

@ -1528,6 +1528,12 @@
/* An error displayed to the user when the group call ends because it has exceeded the max devices. Embeds {{max device count}}. */
"GROUP_CALL_HAS_MAX_DEVICES_FORMAT" = "The maximum number of %ld participants has been reached for this call. Try again later.";
/* An error displayed to the user when the group call ends because it has exceeded the max devices. */
"GROUP_CALL_HAS_MAX_DEVICES_UNKNOWN_COUNT" = "The maximum number of participants has been reached for this call. Try again later.";
/* Text explaining the group call is full */
"GROUP_CALL_IS_FULL" = "Call is Full";
/* Button to join an ongoing group call */
"GROUP_CALL_JOIN_BUTTON" = "Join Call";