From 2bb1f6c22a8bcbbae488c3aff9fea057384654b9 Mon Sep 17 00:00:00 2001 From: Jordan Rose Date: Fri, 19 Aug 2022 12:15:27 -0700 Subject: [PATCH] Move the "Your camera is off" indicator up to GroupCallViewController ...so it can be constrained to not overlap the call header or call controls when in larger font sizes. Additionally, the new view uses a smaller font, and a horizontal layout for the icon + label when on small screens. --- .../Calls/UserInterface/CallControls.swift | 3 +- .../Group/GroupCallMemberView.swift | 14 +----- .../Group/GroupCallViewController.swift | 45 +++++++++++++++++++ 3 files changed, 49 insertions(+), 13 deletions(-) diff --git a/Signal/src/Calls/UserInterface/CallControls.swift b/Signal/src/Calls/UserInterface/CallControls.swift index f3db7d7430..d1ad69eece 100644 --- a/Signal/src/Calls/UserInterface/CallControls.swift +++ b/Signal/src/Calls/UserInterface/CallControls.swift @@ -119,7 +119,8 @@ class CallControls: UIView { addSubview(controlsStack) controlsStack.autoPinWidthToSuperview() - controlsStack.autoPinEdge(toSuperviewSafeArea: .bottom, withInset: 56) + controlsStack.autoPinEdge(toSuperviewSafeArea: .bottom, withInset: 40, relation: .lessThanOrEqual) + controlsStack.autoPinEdge(toSuperviewSafeArea: .bottom, withInset: 56).priority = .defaultHigh - 1 controlsStack.autoPinEdge(toSuperviewEdge: .top) updateControls() diff --git a/Signal/src/Calls/UserInterface/Group/GroupCallMemberView.swift b/Signal/src/Calls/UserInterface/Group/GroupCallMemberView.swift index b4f126104b..6aa9d791cc 100644 --- a/Signal/src/Calls/UserInterface/Group/GroupCallMemberView.swift +++ b/Signal/src/Calls/UserInterface/Group/GroupCallMemberView.swift @@ -124,7 +124,6 @@ class GroupCallLocalMemberView: GroupCallMemberView { let videoView = LocalVideoView() let videoOffIndicatorImage = UIImageView() - let videoOffLabel = UILabel() var videoOffIndicatorWidth: CGFloat { if width > 102 { @@ -163,15 +162,6 @@ class GroupCallLocalMemberView: GroupCallMemberView { videoOffIndicatorImage.autoMatch(.height, to: .width, of: videoOffIndicatorImage) videoOffIndicatorImage.autoCenterInSuperview() - videoOffLabel.font = .ows_dynamicTypeSubheadline - videoOffLabel.text = NSLocalizedString("CALLING_MEMBER_VIEW_YOUR_CAMERA_IS_OFF", - comment: "Indicates to the user that their camera is currently off.") - videoOffLabel.textAlignment = .center - videoOffLabel.textColor = Theme.darkThemePrimaryColor - noVideoView.addSubview(videoOffLabel) - videoOffLabel.autoPinWidthToSuperview() - videoOffLabel.autoPinEdge(.top, to: .bottom, of: videoOffIndicatorImage, withOffset: 10) - videoView.contentMode = .scaleAspectFill insertSubview(videoView, belowSubview: muteIndicatorImage) videoView.frame = bounds @@ -193,8 +183,8 @@ class GroupCallLocalMemberView: GroupCallMemberView { videoView.captureSession = call.videoCaptureController.captureSession noVideoView.isHidden = !videoView.isHidden - videoOffLabel.isHidden = !videoView.isHidden || !isFullScreen - videoOffIndicatorImage.isHidden = !videoView.isHidden + // In full-screen mode the image is shown as part of the "Your camera is off" message. + videoOffIndicatorImage.isHidden = noVideoView.isHidden || isFullScreen guard let localAddress = tsAccountManager.localAddress else { return owsFailDebug("missing local address") diff --git a/Signal/src/Calls/UserInterface/Group/GroupCallViewController.swift b/Signal/src/Calls/UserInterface/Group/GroupCallViewController.swift index 21496617a8..9438d7978d 100644 --- a/Signal/src/Calls/UserInterface/Group/GroupCallViewController.swift +++ b/Signal/src/Calls/UserInterface/Group/GroupCallViewController.swift @@ -13,6 +13,7 @@ class GroupCallViewController: UIViewController { private let call: SignalCall private var groupCall: GroupCall { call.groupCall } private lazy var callControls = CallControls(call: call, delegate: self) + private lazy var noVideoIndicatorView: UIStackView = createNoVideoIndicatorView() private lazy var callHeader = CallHeader(call: call, delegate: self) private lazy var notificationView = GroupCallNotificationView(call: call) @@ -164,12 +165,19 @@ class GroupCallViewController: UIViewController { callHeader.autoPinWidthToSuperview() callHeader.autoPinEdge(toSuperviewEdge: .top) + view.addSubview(noVideoIndicatorView) + noVideoIndicatorView.autoHCenterInSuperview() + // Be flexible on the vertical centering on a cramped screen. + noVideoIndicatorView.autoVCenterInSuperview().priority = .defaultLow + noVideoIndicatorView.autoPinEdge(.top, to: .bottom, of: callHeader, withOffset: 8, relation: .greaterThanOrEqual) + view.addSubview(notificationView) notificationView.autoPinEdgesToSuperviewEdges() view.addSubview(callControls) callControls.autoPinWidthToSuperview() callControls.autoPinEdge(toSuperviewEdge: .bottom) + callControls.autoPinEdge(.top, to: .bottom, of: noVideoIndicatorView, withOffset: 8, relation: .greaterThanOrEqual) view.addSubview(videoOverflow) videoOverflow.autoPinEdge(toSuperviewEdge: .leading) @@ -188,6 +196,39 @@ class GroupCallViewController: UIViewController { updateCallUI() } + private func createNoVideoIndicatorView() -> UIStackView { + let icon = UIImageView() + icon.contentMode = .scaleAspectFit + icon.setTemplateImage(#imageLiteral(resourceName: "video-off-solid-28"), tintColor: .ows_white) + + let label = UILabel() + label.font = .ows_dynamicTypeCaption1 + label.text = NSLocalizedString("CALLING_MEMBER_VIEW_YOUR_CAMERA_IS_OFF", + comment: "Indicates to the user that their camera is currently off.") + label.textAlignment = .center + label.textColor = Theme.darkThemePrimaryColor + + let container = UIStackView(arrangedSubviews: [icon, label]) + if UIDevice.current.isIPhone5OrShorter { + // Use a horizontal layout to save on vertical space. + // Allow the icon to shrink below its natural size of 28pt... + icon.setContentCompressionResistancePriority(.defaultLow, for: .vertical) + container.axis = .horizontal + container.spacing = 4 + // ...by always matching the label's height. + container.alignment = .fill + } else { + // Use a simple vertical layout. + icon.autoSetDimensions(to: CGSize(square: 28)) + container.axis = .vertical + container.spacing = 10 + container.alignment = .center + label.autoPinWidthToSuperview() + } + + return container + } + override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { super.viewWillTransition(to: size, with: coordinator) @@ -411,6 +452,10 @@ class GroupCallViewController: UIViewController { guard !isCallMinimized else { return } + let showNoVideoIndicator = groupCall.remoteDeviceStates.isEmpty && groupCall.isOutgoingVideoMuted + // Hide the subviews of this view to collapse the stack. + noVideoIndicatorView.subviews.forEach { $0.isHidden = !showNoVideoIndicator } + let hideRemoteControls = shouldRemoteVideoControlsBeHidden && !groupCall.remoteDeviceStates.isEmpty let remoteControlsAreHidden = callControls.isHidden && callHeader.isHidden if hideRemoteControls != remoteControlsAreHidden {