From e8500d75a777389aeac8b11d02a0375ccbb8e054 Mon Sep 17 00:00:00 2001 From: ryanzhao Date: Tue, 21 Sep 2021 15:11:48 +1000 Subject: [PATCH] fix input panel issue & make local video view draggable --- Session/Calls/CallVC.swift | 61 ++++++++++++++---- .../ConversationVC+Interaction.swift | 6 +- Session/Conversations/ConversationVC.swift | 3 +- .../Contents.json | 2 +- .../minimize.pdf} | Bin 4881 -> 4654 bytes 5 files changed, 56 insertions(+), 16 deletions(-) rename Session/Meta/Images.xcassets/Session/{AudioOn.imageset => Minimize.imageset}/Contents.json (77%) rename Session/Meta/Images.xcassets/Session/{AudioOn.imageset/Shape.pdf => Minimize.imageset/minimize.pdf} (65%) diff --git a/Session/Calls/CallVC.swift b/Session/Calls/CallVC.swift index c9a630690..0107642b8 100644 --- a/Session/Calls/CallVC.swift +++ b/Session/Calls/CallVC.swift @@ -8,6 +8,7 @@ final class CallVC : UIViewController, WebRTCSessionDelegate { let mode: Mode let webRTCSession: WebRTCSession var isMuted = false + var conversationVC: ConversationVC? = nil lazy var cameraManager: CameraManager = { let result = CameraManager() @@ -25,6 +26,7 @@ final class CallVC : UIViewController, WebRTCSessionDelegate { result.contentMode = .scaleAspectFill result.set(.width, to: 80) result.set(.height, to: 173) + result.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(handlePanGesture))) return result }() @@ -47,13 +49,13 @@ final class CallVC : UIViewController, WebRTCSessionDelegate { return result }() - private lazy var closeButton: UIButton = { + private lazy var minimizeButton: UIButton = { let result = UIButton(type: .custom) - let image = UIImage(named: "X")!.withTint(.white) + let image = UIImage(named: "Minimize")!.withTint(.white) result.setImage(image, for: UIControl.State.normal) result.set(.width, to: 60) result.set(.height, to: 60) - result.addTarget(self, action: #selector(close), for: UIControl.Event.touchUpInside) + result.addTarget(self, action: #selector(minimize), for: UIControl.Event.touchUpInside) return result }() @@ -83,7 +85,7 @@ final class CallVC : UIViewController, WebRTCSessionDelegate { private lazy var switchAudioButton: UIButton = { let result = UIButton(type: .custom) - let image = UIImage(named: "AudioOn")!.withTint(.white) + let image = UIImage(named: "AudioOff")!.withTint(.white) result.setImage(image, for: UIControl.State.normal) result.set(.width, to: 60) result.set(.height, to: 60) @@ -170,14 +172,14 @@ final class CallVC : UIViewController, WebRTCSessionDelegate { fadeView.translatesAutoresizingMaskIntoConstraints = false fadeView.pin([ UIView.HorizontalEdge.left, UIView.VerticalEdge.top, UIView.HorizontalEdge.right ], to: view) // Close button - view.addSubview(closeButton) - closeButton.translatesAutoresizingMaskIntoConstraints = false - closeButton.pin(.left, to: .left, of: view) - closeButton.pin(.top, to: .top, of: view, withInset: 32) + view.addSubview(minimizeButton) + minimizeButton.translatesAutoresizingMaskIntoConstraints = false + minimizeButton.pin(.left, to: .left, of: view) + minimizeButton.pin(.top, to: .top, of: view, withInset: 32) // Title label view.addSubview(titleLabel) titleLabel.translatesAutoresizingMaskIntoConstraints = false - titleLabel.center(.vertical, in: closeButton) + titleLabel.center(.vertical, in: minimizeButton) titleLabel.center(.horizontal, in: view) // End call button view.addSubview(hangUpButton) @@ -220,6 +222,7 @@ final class CallVC : UIViewController, WebRTCSessionDelegate { self.remoteVideoView.alpha = 0 } Timer.scheduledTimer(withTimeInterval: 2, repeats: false) { _ in + self.conversationVC?.showInputAccessoryView() self.presentingViewController?.dismiss(animated: true, completion: nil) } } @@ -228,9 +231,14 @@ final class CallVC : UIViewController, WebRTCSessionDelegate { Storage.write { transaction in WebRTCSession.current?.endCall(with: self.sessionID, using: transaction) } + self.conversationVC?.showInputAccessoryView() presentingViewController?.dismiss(animated: true, completion: nil) } + @objc private func minimize() { + + } + @objc private func switchCamera() { cameraManager.switchCamera() } @@ -238,16 +246,43 @@ final class CallVC : UIViewController, WebRTCSessionDelegate { @objc private func switchAudio() { if isMuted { switchAudioButton.backgroundColor = UIColor(hex: 0x1F1F1F) - let image = UIImage(named: "AudioOn")!.withTint(.white) - switchAudioButton.setImage(image, for: UIControl.State.normal) isMuted = false webRTCSession.unmute() } else { switchAudioButton.backgroundColor = Colors.destructive - let image = UIImage(named: "AudioOff")!.withTint(.white) - switchAudioButton.setImage(image, for: UIControl.State.normal) isMuted = true webRTCSession.mute() } } + + @objc private func handlePanGesture(gesture: UIPanGestureRecognizer) { + let location = gesture.location(in: self.view) + if let draggedView = gesture.view { + draggedView.center = location + if gesture.state == .ended { + let sideMargin = 40 + Values.verySmallSpacing + if draggedView.frame.midX >= self.view.layer.frame.width / 2 { + UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseIn, animations: { + draggedView.center.x = self.view.layer.frame.width - sideMargin + }, completion: nil) + }else{ + UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseIn, animations: { + draggedView.center.x = sideMargin + }, completion: nil) + } + let topMargin = UIApplication.shared.keyWindow!.safeAreaInsets.top + Values.veryLargeSpacing + if draggedView.frame.minY <= topMargin { + UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseIn, animations: { + draggedView.center.y = topMargin + draggedView.frame.size.height / 2 + }, completion: nil) + } + let bottomMargin = UIApplication.shared.keyWindow!.safeAreaInsets.bottom + if draggedView.frame.maxY >= self.view.layer.frame.height { + UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseIn, animations: { + draggedView.center.y = self.view.layer.frame.height - draggedView.frame.size.height / 2 - bottomMargin + }, completion: nil) + } + } + } + } } diff --git a/Session/Conversations/ConversationVC+Interaction.swift b/Session/Conversations/ConversationVC+Interaction.swift index 1be1fdd84..6aeaa4e64 100644 --- a/Session/Conversations/ConversationVC+Interaction.swift +++ b/Session/Conversations/ConversationVC+Interaction.swift @@ -26,11 +26,15 @@ extension ConversationVC : InputViewDelegate, MessageCellDelegate, ContextMenuAc messagesTableView.scrollToRow(at: indexPath, at: .top, animated: true) } - @objc func startCall() { + // MARK: Call + @objc func startCall(_ sender: Any) { guard let contactSessionID = (thread as? TSContactThread)?.contactSessionID() else { return } let callVC = CallVC(for: contactSessionID, mode: .offer) + callVC.conversationVC = self callVC.modalPresentationStyle = .overFullScreen callVC.modalTransitionStyle = .crossDissolve + self.inputAccessoryView?.isHidden = true + self.inputAccessoryView?.alpha = 0 present(callVC, animated: true, completion: nil) } diff --git a/Session/Conversations/ConversationVC.swift b/Session/Conversations/ConversationVC.swift index 08a895707..73f4a013d 100644 --- a/Session/Conversations/ConversationVC.swift +++ b/Session/Conversations/ConversationVC.swift @@ -253,6 +253,7 @@ final class ConversationVC : BaseVC, ConversationViewModelDelegate, OWSConversat super.viewDidAppear(animated) didFinishInitialLayout = true markAllAsRead() + self.becomeFirstResponder() } override func viewWillDisappear(_ animated: Bool) { @@ -261,7 +262,7 @@ final class ConversationVC : BaseVC, ConversationViewModelDelegate, OWSConversat Storage.write { transaction in self.thread.setDraft(text, transaction: transaction) } - inputAccessoryView?.resignFirstResponder() + self.resignFirstResponder() } override func viewDidDisappear(_ animated: Bool) { diff --git a/Session/Meta/Images.xcassets/Session/AudioOn.imageset/Contents.json b/Session/Meta/Images.xcassets/Session/Minimize.imageset/Contents.json similarity index 77% rename from Session/Meta/Images.xcassets/Session/AudioOn.imageset/Contents.json rename to Session/Meta/Images.xcassets/Session/Minimize.imageset/Contents.json index 516caa513..7ec562a8c 100644 --- a/Session/Meta/Images.xcassets/Session/AudioOn.imageset/Contents.json +++ b/Session/Meta/Images.xcassets/Session/Minimize.imageset/Contents.json @@ -1,7 +1,7 @@ { "images" : [ { - "filename" : "Shape.pdf", + "filename" : "minimize.pdf", "idiom" : "universal" } ], diff --git a/Session/Meta/Images.xcassets/Session/AudioOn.imageset/Shape.pdf b/Session/Meta/Images.xcassets/Session/Minimize.imageset/minimize.pdf similarity index 65% rename from Session/Meta/Images.xcassets/Session/AudioOn.imageset/Shape.pdf rename to Session/Meta/Images.xcassets/Session/Minimize.imageset/minimize.pdf index eb0df35b958edac355af6666deca27144b2af1e5..36cd0d830d3e3347fcc0c7e9b870dcfb32c6cc18 100644 GIT binary patch delta 1317 zcmbQJwoYY&eZ7IPg@TUAr1CbEYuu{Kon36nnX@cH{kGzzUEeL{xldACeQC+WcZ`c>HkUipABsK3dvTfe(+azF z3o>lg-|o#zym;npm}vaOW$hPEOU+Y=y~BRqwL9X=mnEOKSSE>X`;psFQ66a7@&8HSOK2_g)63G3qik_mWfcOEzV^e{*Vf>h(Ld@6N3(QGEYX z>%H`6vD1fV+`Qeg#&OwJ$+^?&6ESeha1 zR-HWg$sxU)8Mkl59oiyT8YaKS<2{pbE06HQ<*S}@&AjuAXG_o--K{syYF@WHGSj&9 z1#?5~cWaKdCBJxFHM#zStGi0v+>J#O*A)MF_wP2xI!Swu zIe%lb+?lUN%FfvQd;NCxC08rtdsfUjG=oDW<&fc7gP^_5Nvhe538$>odCD6t4mnZkum#L;CJ^#m{HnanVw}j9am>lYFd}sbvSgNDmQ0x=G99Ee4jau zdiAF@Wp*v>XO(`ln$7S0ok;bhXWr~ZR*N^x-yRlM{ziAj)gL0)*dJcG^Jvk7Mep8) zsQL2RJt_a2bo}ONoqVDH^985a{;B+P`sweF=Rf|I-~Z&}pVBXXzrU{hV|GC#HSgi85vs|SQ;dnnHwY}Tbid@SR|(yB^p_#q?xB07}{~!5LBWN a3n>8;i%KerQq#ChjExMqR8?L5-M9cSR89E+ delta 1546 zcmah}YdjMO06(O>mMM>HE}P7|%-*Xtt(%e(7fI91bA^*-U1+lMsAgU>;Upye28B{Xd zX)AUX{9==H@jSA)!%?s7F~eVa2p~9`Ra)cgJw8b1)VeA@ygQx#wrj%XxLXaW%C&T; zmj}3-ftZN@)P2fdGyD_BvMH<%VSjT{7iMyueHvybk2~;8PF`Lo@gv%a6CC%?l&Mkyq zp$NFH&(rU%Poi=nL3{2FVUJb`H6b-WSqGVE8e^uwezPTjf`fqe5uLq?NDRkVVYiK4 zzi2xra6ydudz*KKKiQGASYK&`jtC6$mv7)g2c9Q0iU_>EqSEy0179phd?gZ5$#X2K zlAK)BrB&PmqXXiYR6I+%rJ^F$vq;oyd?ozSzM?7~=^H^lB&JWkY^2;9TSa;>^O8sw zDI$NyzXcS&8SQE1vXwxt`Bd5-cD|>&3%jqH=9*({tB|Uh-hN!2Hqns?H(f6LKeRZufqN1aPGW}9{ym8ch zz>J*pf!sOlkzmrn+8y)4a=Cl#T$(i2qQ7zaBBS{uu`{)>07Pu62})!OxR;p<4)Swl z`*;=M$>s;yvha>T94QYjX!g**Utnt7vXL5HDvlbnyzJ^9VLj(wlp=`Or8;3aNT}w8 zrL*h*W#C z#s^!iSO=)X5x^8>E`vj?OVpe1zyHO{PUgK2z_L+V0@Cshrvy%W%q%Ihw@{jS({)>O z#D{qYxpnj8L>7hfQaq{gk=T`SZqyn`m5 z-B{RT_gSlL(ZtCkrpot;OYa?QYxK^@GV-B}+q3gbDAf1fmQliI+pGPyT8IDioEeAd{y&IK?;Z|RIswlwN+E| zzdHkN`Fhm&t>fydBhdUYeW4Z{2X{gtka&J25d5!@0I?=W3>*Ug3y{+goxcejg+QbE zU;~&J3iTfu;w#Sy4aa@8fka}y_HbxE-+(|v;X*