Show hint when other party enables video

This commit is contained in:
Michael Kirk 2019-03-19 09:23:25 -07:00
parent 6ccd73837c
commit 179dec299f
4 changed files with 125 additions and 3 deletions

View File

@ -506,6 +506,7 @@
4CC1ECFB211A553000CC13BE /* AppUpdateNag.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CC1ECFA211A553000CC13BE /* AppUpdateNag.swift */; };
4CC613362227A00400E21A3A /* ConversationSearch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CC613352227A00400E21A3A /* ConversationSearch.swift */; };
4CEB78C92178EBAB00F315D2 /* OWSSessionResetJobRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CEB78C82178EBAB00F315D2 /* OWSSessionResetJobRecord.m */; };
4CFD151D22415AA400F2450F /* CallVideoHintView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CFD151C22415AA400F2450F /* CallVideoHintView.swift */; };
4CFE6B6C21F92BA700006701 /* LegacyNotificationsAdaptee.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CFE6B6B21F92BA700006701 /* LegacyNotificationsAdaptee.swift */; };
70377AAB1918450100CAF501 /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 70377AAA1918450100CAF501 /* MobileCoreServices.framework */; };
768A1A2B17FC9CD300E00ED8 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 768A1A2A17FC9CD300E00ED8 /* libz.dylib */; };
@ -1256,6 +1257,7 @@
4CEB78C72178EBAB00F315D2 /* OWSSessionResetJobRecord.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OWSSessionResetJobRecord.h; sourceTree = "<group>"; };
4CEB78C82178EBAB00F315D2 /* OWSSessionResetJobRecord.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OWSSessionResetJobRecord.m; sourceTree = "<group>"; };
4CFB4E9B220BC56D00ECB4DE /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = translations/nb.lproj/Localizable.strings; sourceTree = "<group>"; };
4CFD151C22415AA400F2450F /* CallVideoHintView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallVideoHintView.swift; sourceTree = "<group>"; };
4CFE6B6B21F92BA700006701 /* LegacyNotificationsAdaptee.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = LegacyNotificationsAdaptee.swift; path = UserInterface/Notifications/LegacyNotificationsAdaptee.swift; sourceTree = "<group>"; };
4CFF4C0920F55BBA005DA313 /* MenuActionsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuActionsViewController.swift; sourceTree = "<group>"; };
69349DE607F5BA6036C9AC60 /* Pods-SignalShareExtension.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SignalShareExtension.debug.xcconfig"; path = "Pods/Target Support Files/Pods-SignalShareExtension/Pods-SignalShareExtension.debug.xcconfig"; sourceTree = "<group>"; };
@ -1883,11 +1885,11 @@
34B3F8331E8DF1700035BE1A /* ViewControllers */ = {
isa = PBXGroup;
children = (
4CFD151B22415A6C00F2450F /* Call */,
452B998F20A34B6B006F2F9E /* AddContactShareToExistingContactViewController.swift */,
340FC87A204DAC8C007AEB0F /* AppSettings */,
34D5CCA71EAE3D30005515DB /* AvatarViewHelper.h */,
34D5CCA81EAE3D30005515DB /* AvatarViewHelper.m */,
34B3F83B1E8DF1700035BE1A /* CallViewController.swift */,
4C13C9F520E57BA30089A98B /* ColorPickerViewController.swift */,
348BB25C20A0C5530047AEC2 /* ContactShareViewHelper.swift */,
34B3F83E1E8DF1700035BE1A /* ContactsPicker.swift */,
@ -2335,6 +2337,15 @@
path = SSKTests;
sourceTree = "<group>";
};
4CFD151B22415A6C00F2450F /* Call */ = {
isa = PBXGroup;
children = (
34B3F83B1E8DF1700035BE1A /* CallViewController.swift */,
4CFD151C22415AA400F2450F /* CallVideoHintView.swift */,
);
path = Call;
sourceTree = "<group>";
};
76EB03C118170B33006006FC /* src */ = {
isa = PBXGroup;
children = (
@ -3551,6 +3562,7 @@
348570A820F67575004FF32B /* OWSMessageHeaderView.m in Sources */,
450DF2091E0DD2C6003D14BE /* UserNotificationsAdaptee.swift in Sources */,
34B6A907218B5241007C4606 /* TypingIndicatorCell.swift in Sources */,
4CFD151D22415AA400F2450F /* CallVideoHintView.swift in Sources */,
34D1F0AB1F867BFC0066283D /* OWSContactOffersCell.m in Sources */,
343A65981FC4CFE7000477A1 /* ConversationScrollButton.m in Sources */,
34386A51207D0C01009F5D9C /* HomeViewController.m in Sources */,

View File

@ -0,0 +1,83 @@
//
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
//
import Foundation
protocol CallVideoHintViewDelegate: AnyObject {
func didTapCallVideoHintView(_ videoHintView: CallVideoHintView)
}
class CallVideoHintView: UIView {
let label = UILabel()
var tapGesture: UITapGestureRecognizer!
weak var delegate: CallVideoHintViewDelegate?
let kTailHMargin: CGFloat = 12
let kTailWidth: CGFloat = 16
let kTailHeight: CGFloat = 8
init() {
super.init(frame: .zero)
tapGesture = UITapGestureRecognizer(target: self, action: #selector(didTap(tapGesture:)))
addGestureRecognizer(tapGesture)
let layerView = OWSLayerView()
let shapeLayer = CAShapeLayer()
shapeLayer.fillColor = UIColor.ows_signalBlue.cgColor
layerView.layer.addSublayer(shapeLayer)
addSubview(layerView)
layerView.autoPinEdgesToSuperviewEdges()
let container = UIView()
addSubview(container)
container.autoSetDimension(.width, toSize: ScaleFromIPhone5(250), relation: .lessThanOrEqual)
container.layoutMargins = UIEdgeInsets(top: 7, leading: 12, bottom: 7, trailing: 12)
container.autoPinEdgesToSuperviewEdges(with: UIEdgeInsets(top: 0, leading: 0, bottom: kTailHeight, trailing: 0))
container.addSubview(label)
label.autoPinEdgesToSuperviewMargins()
label.setCompressionResistanceHigh()
label.setContentHuggingHigh()
label.font = UIFont.ows_dynamicTypeBody
label.textColor = .ows_white
label.numberOfLines = 0
label.text = NSLocalizedString("CALL_VIEW_ENABLE_VIDEO_HINT", comment: "tooltip label when remote party has enabled their video")
layerView.layoutCallback = { view in
let bezierPath = UIBezierPath()
// Bubble
let bubbleBounds = container.bounds
bezierPath.append(UIBezierPath(roundedRect: bubbleBounds, cornerRadius: 8))
// Tail
var tailBottom = CGPoint(x: self.kTailHMargin + self.kTailWidth * 0.5, y: view.height())
var tailLeft = CGPoint(x: self.kTailHMargin, y: view.height() - self.kTailHeight)
var tailRight = CGPoint(x: self.kTailHMargin + self.kTailWidth, y: view.height() - self.kTailHeight)
if (!CurrentAppContext().isRTL) {
tailBottom.x = view.width() - tailBottom.x
tailLeft.x = view.width() - tailLeft.x
tailRight.x = view.width() - tailRight.x
}
bezierPath.move(to: tailBottom)
bezierPath.addLine(to: tailLeft)
bezierPath.addLine(to: tailRight)
bezierPath.addLine(to: tailBottom)
shapeLayer.path = bezierPath.cgPath
shapeLayer.frame = view.bounds
}
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
// MARK: -
@objc
func didTap(tapGesture: UITapGestureRecognizer) {
self.delegate?.didTapCallVideoHintView(self)
}
}

View File

@ -234,8 +234,10 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver,
func createViews() {
self.view.isUserInteractionEnabled = true
self.view.addGestureRecognizer(OWSAnyTouchGestureRecognizer(target: self,
action: #selector(didTouchRootView)))
self.view.addGestureRecognizer(UITapGestureRecognizer(target: self,
action: #selector(didTouchRootView)))
videoHintView.delegate = self
// Dark blurred background.
let blurEffect = UIBlurEffect(style: .dark)
@ -596,6 +598,8 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver,
updateCallUI(callState: call.state)
}
let videoHintView = CallVideoHintView()
internal func updateLocalVideoLayout() {
if !localVideoView.isHidden {
localVideoView.superview?.bringSubview(toFront: localVideoView)
@ -744,10 +748,20 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver,
contactNameLabel.isHidden = true
callStatusLabel.isHidden = true
ongoingCallControls.isHidden = true
videoHintView.isHidden = true
} else {
leaveCallViewButton.isHidden = false
contactNameLabel.isHidden = false
callStatusLabel.isHidden = false
if hasRemoteVideo && !hasLocalVideo && !hasShownLocalVideo && !hasUserDismissedVideoHint {
view.addSubview(videoHintView)
videoHintView.isHidden = false
videoHintView.autoPinEdge(.bottom, to: .top, of: audioModeVideoButton)
videoHintView.autoPinEdge(.trailing, to: .leading, of: audioModeVideoButton, withOffset: buttonSize() / 2 + videoHintView.kTailHMargin + videoHintView.kTailWidth / 2)
} else {
videoHintView.removeFromSuperview()
}
}
let doLocalVideoLayout = {
@ -1040,6 +1054,8 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver,
return self.remoteVideoTrack != nil
}
var hasUserDismissedVideoHint: Bool = false
internal func updateRemoteVideoTrack(remoteVideoTrack: RTCVideoTrack?) {
AssertIsOnMainThread()
guard self.remoteVideoTrack != remoteVideoTrack else {
@ -1051,6 +1067,7 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver,
remoteVideoView.renderFrame(nil)
self.remoteVideoTrack = remoteVideoTrack
self.remoteVideoTrack?.add(remoteVideoView)
shouldRemoteVideoControlsBeHidden = false
updateRemoteVideoLayout()
@ -1174,3 +1191,10 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver,
}
}
}
extension CallViewController: CallVideoHintViewDelegate {
func didTapCallVideoHintView(_ videoHintView: CallVideoHintView) {
self.hasUserDismissedVideoHint = true
updateRemoteVideoLayout()
}
}

View File

@ -350,6 +350,9 @@
/* Accessibility label for declining incoming calls */
"CALL_VIEW_DECLINE_INCOMING_CALL_LABEL" = "Decline incoming call";
/* tooltip label when remote party has enabled their video */
"CALL_VIEW_ENABLE_VIDEO_HINT" = "Tap here to turn on your video";
/* Accessibility label for hang up call */
"CALL_VIEW_HANGUP_LABEL" = "End call";