Update MessagesViewController to use SignalAttachment.

// FREEBIE
This commit is contained in:
Matthew Chen 2017-03-10 10:59:59 -03:00
parent 7f2810af3f
commit cd928cd9be
8 changed files with 1181 additions and 17 deletions

View File

@ -11,6 +11,10 @@
341BB7491DB727EE001E2975 /* JSQMediaItem+OWS.m in Sources */ = {isa = PBXBuildFile; fileRef = 341BB7481DB727EE001E2975 /* JSQMediaItem+OWS.m */; };
344F2F671E57A932000D9322 /* UIViewController+OWS.m in Sources */ = {isa = PBXBuildFile; fileRef = 344F2F661E57A932000D9322 /* UIViewController+OWS.m */; };
34535D821E256BE9008A4747 /* UIView+OWS.m in Sources */ = {isa = PBXBuildFile; fileRef = 34535D811E256BE9008A4747 /* UIView+OWS.m */; };
348A08421E6A044E0057E290 /* MessagesViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 348A08411E6A044E0057E290 /* MessagesViewController.xib */; };
348A08441E6A1D2C0057E290 /* OWSMessagesToolbarContentView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 348A08431E6A1D2C0057E290 /* OWSMessagesToolbarContentView.xib */; };
348A08511E6C73490057E290 /* AttachmentApprovalViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 348A08501E6C73490057E290 /* AttachmentApprovalViewController.swift */; };
348A08531E6C75590057E290 /* SignalAttachment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 348A08521E6C75590057E290 /* SignalAttachment.swift */; };
348F3A4F1E4A533900750D44 /* CallInterstitialViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 348F3A4E1E4A533900750D44 /* CallInterstitialViewController.swift */; };
34FD93701E3BD43A00109093 /* OWSAnyTouchGestureRecognizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 34FD936F1E3BD43A00109093 /* OWSAnyTouchGestureRecognizer.m */; };
4505C2BF1E648EA300CEBF41 /* ExperienceUpgrade.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4505C2BE1E648EA300CEBF41 /* ExperienceUpgrade.swift */; };
@ -624,6 +628,10 @@
344F2F661E57A932000D9322 /* UIViewController+OWS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UIViewController+OWS.m"; path = "util/UIViewController+OWS.m"; sourceTree = "<group>"; };
34535D801E256BE9008A4747 /* UIView+OWS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+OWS.h"; sourceTree = "<group>"; };
34535D811E256BE9008A4747 /* UIView+OWS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+OWS.m"; sourceTree = "<group>"; };
348A08411E6A044E0057E290 /* MessagesViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MessagesViewController.xib; sourceTree = "<group>"; };
348A08431E6A1D2C0057E290 /* OWSMessagesToolbarContentView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = OWSMessagesToolbarContentView.xib; sourceTree = "<group>"; };
348A08501E6C73490057E290 /* AttachmentApprovalViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AttachmentApprovalViewController.swift; sourceTree = "<group>"; };
348A08521E6C75590057E290 /* SignalAttachment.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SignalAttachment.swift; sourceTree = "<group>"; };
348F3A4E1E4A533900750D44 /* CallInterstitialViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CallInterstitialViewController.swift; sourceTree = "<group>"; };
34FD936E1E3BD43A00109093 /* OWSAnyTouchGestureRecognizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OWSAnyTouchGestureRecognizer.h; path = views/OWSAnyTouchGestureRecognizer.h; sourceTree = "<group>"; };
34FD936F1E3BD43A00109093 /* OWSAnyTouchGestureRecognizer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OWSAnyTouchGestureRecognizer.m; path = views/OWSAnyTouchGestureRecognizer.m; sourceTree = "<group>"; };
@ -2653,6 +2661,7 @@
FC3196321A08142D0094C78E /* Signals */ = {
isa = PBXGroup;
children = (
348A08501E6C73490057E290 /* AttachmentApprovalViewController.swift */,
348F3A4E1E4A533900750D44 /* CallInterstitialViewController.swift */,
4509E79B1DD6545B0025A59F /* CallViewController.swift */,
FC31962B1A06A2190094C78E /* FingerprintViewController.h */,
@ -2663,12 +2672,15 @@
FC3196291A067D8F0094C78E /* MessageComposeTableViewController.m */,
FCAC964F19FF0A6E0046DFC5 /* MessagesViewController.h */,
FCAC965019FF0A6E0046DFC5 /* MessagesViewController.m */,
348A08411E6A044E0057E290 /* MessagesViewController.xib */,
FCFD256D1A151BCB00F4C644 /* NewGroupViewController.h */,
FCFD256E1A151BCB00F4C644 /* NewGroupViewController.m */,
452E3C8C1D935C77002A45B0 /* OWSConversationSettingsTableViewController.h */,
452E3C8D1D935C77002A45B0 /* OWSConversationSettingsTableViewController.m */,
348A08431E6A1D2C0057E290 /* OWSMessagesToolbarContentView.xib */,
A5D0699A1A50E9CB004CB540 /* ShowGroupMembersViewController.h */,
A5D069991A50E9CB004CB540 /* ShowGroupMembersViewController.m */,
348A08521E6C75590057E290 /* SignalAttachment.swift */,
FC4FA0241A1B9DC600DA100A /* SignalsNavigationController.h */,
FC4FA0251A1B9DC600DA100A /* SignalsNavigationController.m */,
FCAC963A19FEF9280046DFC5 /* SignalsViewController.h */,
@ -2897,6 +2909,7 @@
E94066151DFC5B7B00B15392 /* ContactsPicker.xib in Resources */,
AD41D7B61A6F6F0600241130 /* play_button@2x.png in Resources */,
AD83FF3F1A73426500B5C81A /* audio_pause_button_blue.png in Resources */,
348A08421E6A044E0057E290 /* MessagesViewController.xib in Resources */,
45E1F3A31DEF1DF000852CF1 /* NoSignalContactsView.xib in Resources */,
A5509ECA1A69AB8B00ABA4BC /* Main.storyboard in Resources */,
A507A3B11A6C60E300BEED0D /* InboxTableViewCell.xib in Resources */,
@ -2941,6 +2954,7 @@
E1370BE618A0686C00826894 /* sonarping.mp3 in Resources */,
B10C9B5F1A7049EC00ECA2BF /* pause_icon.png in Resources */,
AD83FF471A73428300B5C81A /* audio_play_button_blue.png in Resources */,
348A08441E6A1D2C0057E290 /* OWSMessagesToolbarContentView.xib in Resources */,
AD83FF451A73426500B5C81A /* audio_pause_button@2x.png in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -3137,6 +3151,7 @@
45387B041E36D650005D00B3 /* OWS102MoveLoggingPreferenceToUserDefaults.m in Sources */,
E197B61818BBEC1A00F073E5 /* RemoteIOAudio.m in Sources */,
B67ADDC41989FF8700E1A773 /* RPServerRequestsManager.m in Sources */,
348A08511E6C73490057E290 /* AttachmentApprovalViewController.swift in Sources */,
348F3A4F1E4A533900750D44 /* CallInterstitialViewController.swift in Sources */,
EF764C351DB67CC5000D9A87 /* UIViewController+CameraPermissions.m in Sources */,
453201251E71100C00F20761 /* DisplayableTextFilter.swift in Sources */,
@ -3147,6 +3162,7 @@
76EB05E018170B33006006FC /* NetworkStream.m in Sources */,
45794E861E00620000066731 /* CallUIAdapter.swift in Sources */,
FCFA64B71A24F6730007FB87 /* UIFont+OWS.m in Sources */,
348A08531E6C75590057E290 /* SignalAttachment.swift in Sources */,
B6B9ECFC198B31BA00C620D3 /* PushManager.m in Sources */,
45DF5DF21DDB843F00C936C7 /* CompareSafetyNumbersActivity.swift in Sources */,
76EB05D618170B33006006FC /* ZrtpResponder.m in Sources */,

View File

@ -120,12 +120,33 @@
</barButtonItem>
</navigationItem>
<connections>
<outlet property="inputToolbar" destination="BdJ-vY-dHA" id="EfK-zI-nSM"/>
<segue destination="4oU-Rv-yJi" kind="push" identifier="OWSMessagesViewControllerSeguePushConversationSettings" id="vOd-aS-6Wx"/>
<segue destination="urv-62-RsD" kind="modal" identifier="fingerprintSegue" id="tfr-ZV-qWs"/>
<segue destination="Tyf-mN-gzf" kind="modal" identifier="initiateCallSegue" modalTransitionStyle="crossDissolve" id="I6y-pT-nEd"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="yXZ-iE-5va" userLabel="First Responder" sceneMemberID="firstResponder"/>
<toolbar opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="BdJ-vY-dHA" customClass="OWSMessagesInputToolbar">
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<items>
<barButtonItem title="Item" id="4F3-az-L9s"/>
</items>
</toolbar>
<view contentMode="scaleToFill" id="X6H-b7-xZK" customClass="OWSMessagesToolbarContentView">
<rect key="frame" x="0.0" y="0.0" width="240" height="128"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<connections>
<outlet property="textView" destination="XUl-oy-JS1" id="kzd-TM-IJT"/>
</connections>
</view>
<view contentMode="scaleToFill" id="XUl-oy-JS1" customClass="JSQMessagesComposerTextView">
<rect key="frame" x="0.0" y="0.0" width="240" height="128"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</view>
</objects>
<point key="canvasLocation" x="-2287" y="-1516"/>
</scene>
@ -352,7 +373,7 @@
<!--Conversation Settings-->
<scene sceneID="Flt-X5-Amc">
<objects>
<tableViewController title="Contact Information" id="4oU-Rv-yJi" userLabel="Conversation Settings" customClass="OWSConversationSettingsTableViewController" sceneMemberID="viewController">
<tableViewController storyboardIdentifier="OWSConversationSettingsTableViewController" title="Contact Information" id="4oU-Rv-yJi" userLabel="Conversation Settings" customClass="OWSConversationSettingsTableViewController" sceneMemberID="viewController">
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="static" style="grouped" separatorStyle="default" sectionIndexMinimumDisplayRowCount="1" rowHeight="44" sectionHeaderHeight="18" sectionFooterHeight="18" id="Dgp-fo-Lyr">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
@ -625,7 +646,7 @@
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="Ftx-dN-loa" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-1393" y="-1482"/>
<point key="canvasLocation" x="-1448" y="-1570"/>
</scene>
<!--Show Group Members View Controller-->
<scene sceneID="VBt-Ax-0G9">
@ -1701,7 +1722,7 @@
</simulatedMetricsContainer>
<inferredMetricsTieBreakers>
<segue reference="E8S-Yc-X7E"/>
<segue reference="I6y-pT-nEd"/>
<segue reference="wgA-Oo-kKq"/>
<segue reference="G2B-Fr-Ezs"/>
</inferredMetricsTieBreakers>
</document>

View File

@ -0,0 +1,991 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
import Foundation
//import WebRTC
//import PromiseKit
//// TODO: Add category so that button handlers can be defined where button is created.
//// TODO: Ensure buttons enabled & disabled as necessary.
//@objc(OWSAttachmentApprovalViewController)
class AttachmentApprovalViewController: UIViewController {
let TAG = "[AttachmentApprovalViewController]"
// Dependencies
// let callUIAdapter: CallUIAdapter
// let contactsManager: OWSContactsManager
// MARK: Properties
let attachment : SignalAttachment!
// var thread: TSContactThread!
// var call: SignalCall!
// var hasDismissed = false
// MARK: Views
// var hasConstraints = false
// var blurView: UIVisualEffectView!
// var dateFormatter: DateFormatter?
//
// // MARK: Contact Views
//
// var contactNameLabel: UILabel!
// var contactAvatarView: AvatarImageView!
// var callStatusLabel: UILabel!
// var callDurationTimer: Timer?
//
// // MARK: Ongoing Call Controls
//
// var ongoingCallView: UIView!
//
// var hangUpButton: UIButton!
// var speakerPhoneButton: UIButton!
// var audioModeMuteButton: UIButton!
// var audioModeVideoButton: UIButton!
// var videoModeMuteButton: UIButton!
// var videoModeVideoButton: UIButton!
// // TODO: Later, we'll re-enable the text message button
// // so users can send and read messages during a
// // call.
//// var textMessageButton: UIButton!
//
// // MARK: Incoming Call Controls
//
// var incomingCallView: UIView!
//
// var acceptIncomingButton: UIButton!
// var declineIncomingButton: UIButton!
//
// // MARK: Video Views
//
// var remoteVideoView: RTCEAGLVideoView!
// var localVideoView: RTCCameraPreviewView!
// weak var localVideoTrack: RTCVideoTrack?
// weak var remoteVideoTrack: RTCVideoTrack?
// var remoteVideoSize: CGSize! = CGSize.zero
// var remoteVideoConstraints: [NSLayoutConstraint] = []
// var localVideoConstraints: [NSLayoutConstraint] = []
//
// var shouldRemoteVideoControlsBeHidden = false {
// didSet {
// updateCallUI(callState: call.state)
// }
// }
//
// // MARK: Settings Nag Views
//
// var isShowingSettingsNag = false {
// didSet {
// if oldValue != isShowingSettingsNag {
// updateCallUI(callState: call.state)
// }
// }
// }
// var settingsNagView: UIView!
// var settingsNagDescriptionLabel: UILabel!
// MARK: Initializers
required init?(coder aDecoder: NSCoder) {
self.attachment = SignalAttachment.genericAttachment(withData: nil,
dataUTI: kUTTypeContent as String)
// contactsManager = Environment.getCurrent().contactsManager
// callUIAdapter = Environment.getCurrent().callUIAdapter
super.init(coder: aDecoder)
// TODO: How to deprecate constructor in Swift?
assert(false)
// observeNotifications()
}
required init(attachment : SignalAttachment!) {
// let attachmentData : NSData
// let attachmentType : String
//
// contactsManager = Environment.getCurrent().contactsManager
// callUIAdapter = Environment.getCurrent().callUIAdapter
self.attachment = attachment
super.init(nibName: nil, bundle: nil)
// observeNotifications()
}
// func observeNotifications() {
// NotificationCenter.default.addObserver(self,
// selector:#selector(didBecomeActive),
// name:NSNotification.Name.UIApplicationDidBecomeActive,
// object:nil)
// }
//
// deinit {
// NotificationCenter.default.removeObserver(self)
// }
//
// func didBecomeActive() {
// shouldRemoteVideoControlsBeHidden = false
// }
// MARK: View Lifecycle
// override func viewDidDisappear(_ animated: Bool) {
// super.viewDidDisappear(animated)
//
// callDurationTimer?.invalidate()
// callDurationTimer = nil
// }
//
// override func viewWillAppear(_ animated: Bool) {
// super.viewWillAppear(animated)
//
// updateCallUI(callState: call.state)
// }
//
// override func loadView() {
// self.view =
// }
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.black
//
// guard let thread = self.thread else {
// Logger.error("\(TAG) tried to show call call without specifying thread.")
// showCallFailed(error: OWSErrorMakeAssertionError())
// return
// }
createViews()
// contactNameLabel.text = contactsManager.displayName(forPhoneIdentifier: thread.contactIdentifier())
// contactAvatarView.image = OWSAvatarBuilder.buildImage(for: thread, contactsManager: contactsManager)
//
// assert(call != nil)
// // Subscribe for future call updates
// call.addObserverAndSyncState(observer: self)
//
// Environment.getCurrent().callService.addObserverAndSyncState(observer:self)
}
// MARK: - Create Views
func createViews() {
// self.view.isUserInteractionEnabled = true
// self.view.addGestureRecognizer(OWSAnyTouchGestureRecognizer(target:self,
// action:#selector(didTouchRootView)))
//
// // Dark blurred background.
// let blurEffect = UIBlurEffect(style: .dark)
// blurView = UIVisualEffectView(effect: blurEffect)
// blurView.isUserInteractionEnabled = false
// self.view.addSubview(blurView)
//
// // Create the video views first, as they are under the other views.
// createVideoViews()
//
// createContactViews()
// createOngoingCallControls()
// createIncomingCallControls()
// createSettingsNagViews()
}
// func didTouchRootView(sender: UIGestureRecognizer) {
// if !remoteVideoView.isHidden {
// shouldRemoteVideoControlsBeHidden = !shouldRemoteVideoControlsBeHidden
// }
// }
//
// func createVideoViews() {
// remoteVideoView = RTCEAGLVideoView()
// remoteVideoView.delegate = self
// remoteVideoView.isUserInteractionEnabled = false
// localVideoView = RTCCameraPreviewView()
// remoteVideoView.isHidden = true
// localVideoView.isHidden = true
// self.view.addSubview(remoteVideoView)
// self.view.addSubview(localVideoView)
// }
//
// func createContactViews() {
// contactNameLabel = UILabel()
// contactNameLabel.font = UIFont.ows_lightFont(withSize:ScaleFromIPhone5To7Plus(32, 40))
// contactNameLabel.textColor = UIColor.white
// contactNameLabel.layer.shadowOffset = CGSize.zero
// contactNameLabel.layer.shadowOpacity = 0.35
// contactNameLabel.layer.shadowRadius = 4
// self.view.addSubview(contactNameLabel)
//
// callStatusLabel = UILabel()
// callStatusLabel.font = UIFont.ows_regularFont(withSize:ScaleFromIPhone5To7Plus(19, 25))
// callStatusLabel.textColor = UIColor.white
// callStatusLabel.layer.shadowOffset = CGSize.zero
// callStatusLabel.layer.shadowOpacity = 0.35
// callStatusLabel.layer.shadowRadius = 4
// self.view.addSubview(callStatusLabel)
//
// contactAvatarView = AvatarImageView()
// self.view.addSubview(contactAvatarView)
// }
//
// func createSettingsNagViews() {
// settingsNagView = UIView()
// settingsNagView.isHidden = true
// self.view.addSubview(settingsNagView)
//
// let viewStack = UIView()
// settingsNagView.addSubview(viewStack)
// viewStack.autoPinWidthToSuperview()
// viewStack.autoVCenterInSuperview()
//
// settingsNagDescriptionLabel = UILabel()
// settingsNagDescriptionLabel.text = NSLocalizedString("CALL_VIEW_SETTINGS_NAG_DESCRIPTION_ALL",
// comment: "Reminder to the user of the benefits of enabling CallKit and disabling CallKit privacy.")
// settingsNagDescriptionLabel.font = UIFont.ows_regularFont(withSize:ScaleFromIPhone5To7Plus(16, 18))
// settingsNagDescriptionLabel.textColor = UIColor.white
// settingsNagDescriptionLabel.numberOfLines = 0
// settingsNagDescriptionLabel.lineBreakMode = .byWordWrapping
// viewStack.addSubview(settingsNagDescriptionLabel)
// settingsNagDescriptionLabel.autoPinWidthToSuperview()
// settingsNagDescriptionLabel.autoPinEdge(toSuperviewEdge:.top)
//
// let buttonHeight = ScaleFromIPhone5To7Plus(35, 45)
// let buttonFont = UIFont.ows_regularFont(withSize:ScaleFromIPhone5To7Plus(14, 18))
// let buttonCornerRadius = CGFloat(4)
// let descriptionVSpacingHeight = ScaleFromIPhone5To7Plus(30, 60)
//
// let callSettingsButton = UIButton()
// callSettingsButton.setTitle(NSLocalizedString("CALL_VIEW_SETTINGS_NAG_SHOW_CALL_SETTINGS",
// comment: "Label for button that shows the privacy settings"), for:.normal)
// callSettingsButton.setTitleColor(UIColor.white, for:.normal)
// callSettingsButton.titleLabel!.font = buttonFont
// callSettingsButton.addTarget(self, action:#selector(didPressShowCallSettings), for:.touchUpInside)
// callSettingsButton.backgroundColor = UIColor.ows_signalBrandBlue()
// callSettingsButton.layer.cornerRadius = buttonCornerRadius
// callSettingsButton.clipsToBounds = true
// viewStack.addSubview(callSettingsButton)
// callSettingsButton.autoSetDimension(.height, toSize:buttonHeight)
// callSettingsButton.autoPinWidthToSuperview()
// callSettingsButton.autoPinEdge(.top, to:.bottom, of:settingsNagDescriptionLabel, withOffset:descriptionVSpacingHeight)
//
// let notNowButton = UIButton()
// notNowButton.setTitle(NSLocalizedString("CALL_VIEW_SETTINGS_NAG_NOT_NOW_BUTTON",
// comment: "Label for button that dismiss the call view's settings nag."), for:.normal)
// notNowButton.setTitleColor(UIColor.white, for:.normal)
// notNowButton.titleLabel!.font = buttonFont
// notNowButton.addTarget(self, action:#selector(didPressDismissNag), for:.touchUpInside)
// notNowButton.backgroundColor = UIColor.ows_signalBrandBlue()
// notNowButton.layer.cornerRadius = buttonCornerRadius
// notNowButton.clipsToBounds = true
// viewStack.addSubview(notNowButton)
// notNowButton.autoSetDimension(.height, toSize:buttonHeight)
// notNowButton.autoPinWidthToSuperview()
// notNowButton.autoPinEdge(toSuperviewEdge:.bottom)
// notNowButton.autoPinEdge(.top, to:.bottom, of:callSettingsButton, withOffset:12)
// }
//
// func buttonSize() -> CGFloat {
// return ScaleFromIPhone5To7Plus(84, 108)
// }
//
// func buttonInset() -> CGFloat {
// return ScaleFromIPhone5To7Plus(7, 9)
// }
//
// func createOngoingCallControls() {
//
//// textMessageButton = createButton(imageName:"message-active-wide",
//// action:#selector(didPressTextMessage))
// speakerPhoneButton = createButton(imageName:"speaker-inactive-wide",
// action:#selector(didPressSpeakerphone))
// hangUpButton = createButton(imageName:"hangup-active-wide",
// action:#selector(didPressHangup))
// audioModeMuteButton = createButton(imageName:"mute-unselected-wide",
// action:#selector(didPressMute))
// videoModeMuteButton = createButton(imageName:"video-mute-unselected",
// action:#selector(didPressMute))
// audioModeVideoButton = createButton(imageName:"video-inactive-wide",
// action:#selector(didPressVideo))
// videoModeVideoButton = createButton(imageName:"video-video-unselected",
// action:#selector(didPressVideo))
//
// setButtonSelectedImage(button: audioModeMuteButton, imageName: "mute-selected-wide")
// setButtonSelectedImage(button: videoModeMuteButton, imageName: "video-mute-selected")
// setButtonSelectedImage(button: audioModeVideoButton, imageName: "video-active-wide")
// setButtonSelectedImage(button: videoModeVideoButton, imageName: "video-video-selected")
// setButtonSelectedImage(button: speakerPhoneButton, imageName: "speaker-active-wide")
//
// ongoingCallView = createContainerForCallControls(controlGroups : [
// [audioModeMuteButton, speakerPhoneButton, audioModeVideoButton ],
// [videoModeMuteButton, hangUpButton, videoModeVideoButton ]
// ])
// }
//
// func setButtonSelectedImage(button: UIButton, imageName: String) {
// let image = UIImage(named:imageName)
// assert(image != nil)
// button.setImage(image, for:.selected)
// }
//
// func createIncomingCallControls() {
//
// acceptIncomingButton = createButton(imageName:"call-active-wide",
// action:#selector(didPressAnswerCall))
// declineIncomingButton = createButton(imageName:"hangup-active-wide",
// action:#selector(didPressDeclineCall))
//
// incomingCallView = createContainerForCallControls(controlGroups : [
// [acceptIncomingButton, declineIncomingButton ]
// ])
// }
//
// func createContainerForCallControls(controlGroups: [[UIView]]) -> UIView {
// let containerView = UIView()
// self.view.addSubview(containerView)
// var rows: [UIView] = []
// for controlGroup in controlGroups {
// rows.append(rowWithSubviews(subviews:controlGroup))
// }
// let rowspacing = ScaleFromIPhone5To7Plus(6, 7)
// var prevRow: UIView?
// for row in rows {
// containerView.addSubview(row)
// row.autoHCenterInSuperview()
// if prevRow != nil {
// row.autoPinEdge(.top, to:.bottom, of:prevRow!, withOffset:rowspacing)
// }
// prevRow = row
// }
//
// containerView.setContentHuggingVerticalHigh()
// rows.first!.autoPinEdge(toSuperviewEdge:.top)
// rows.last!.autoPinEdge(toSuperviewEdge:.bottom)
// return containerView
// }
//
// func createButton(imageName: String, action: Selector) -> UIButton {
// let image = UIImage(named:imageName)
// assert(image != nil)
// let button = UIButton()
// button.setImage(image, for:.normal)
// button.imageEdgeInsets = UIEdgeInsets(top: buttonInset(),
// left: buttonInset(),
// bottom: buttonInset(),
// right: buttonInset())
// button.addTarget(self, action:action, for:.touchUpInside)
// button.autoSetDimension(.width, toSize:buttonSize())
// button.autoSetDimension(.height, toSize:buttonSize())
// return button
// }
//
// // Creates a row containing a given set of subviews.
// func rowWithSubviews(subviews: [UIView]) -> UIView {
// let row = UIView()
// row.setContentHuggingVerticalHigh()
// row.autoSetDimension(.height, toSize:buttonSize())
//
// if subviews.count > 1 {
// // If there's more than one subview in the row,
// // space them evenly within the row.
// var lastSubview: UIView?
// for subview in subviews {
// row.addSubview(subview)
// subview.setContentHuggingHorizontalHigh()
// subview.autoVCenterInSuperview()
//
// if lastSubview != nil {
// let spacer = UIView()
// spacer.isHidden = true
// row.addSubview(spacer)
// spacer.autoPinEdge(.left, to:.right, of:lastSubview!)
// spacer.autoPinEdge(.right, to:.left, of:subview)
// spacer.setContentHuggingHorizontalLow()
// spacer.autoVCenterInSuperview()
//
// if subviews.count == 2 {
// // special case to hardcode the spacer's size when there is only 1 spacer.
// spacer.autoSetDimension(.width, toSize: ScaleFromIPhone5To7Plus(46, 60))
// } else {
// spacer.autoSetDimension(.width, toSize: ScaleFromIPhone5To7Plus(3, 5))
// }
// }
//
// lastSubview = subview
// }
// subviews.first!.autoPinEdge(toSuperviewEdge:.left)
// subviews.last!.autoPinEdge(toSuperviewEdge:.right)
// } else if subviews.count == 1 {
// // If there's only one subview in this row, center it.
// let subview = subviews.first!
// row.addSubview(subview)
// subview.autoVCenterInSuperview()
// subview.autoPinWidthToSuperview()
// }
//
// return row
// }
//
// // MARK: - Layout
//
// override func updateViewConstraints() {
// if !hasConstraints {
// // We only want to create our constraints once.
// //
// // Note that constraints are also created elsewhere.
// // This only creates the constraints for the top-level contents of the view.
// hasConstraints = true
//
// let topMargin = CGFloat(40)
// let contactHMargin = CGFloat(30)
// let contactVSpacing = CGFloat(3)
// let ongoingHMargin = ScaleFromIPhone5To7Plus(46, 72)
// let incomingHMargin = ScaleFromIPhone5To7Plus(46, 72)
// let settingsNagHMargin = CGFloat(30)
// let ongoingBottomMargin = ScaleFromIPhone5To7Plus(23, 41)
// let incomingBottomMargin = CGFloat(41)
// let settingsNagBottomMargin = CGFloat(41)
// let avatarTopSpacing = ScaleFromIPhone5To7Plus(25, 50)
// // The buttons have built-in 10% margins, so to appear centered
// // the avatar's bottom spacing should be a bit less.
// let avatarBottomSpacing = ScaleFromIPhone5To7Plus(18, 41)
// // Layout of the local video view is a bit unusual because
// // although the view is square, it will be used
// let videoPreviewHMargin = CGFloat(0)
//
// // Dark blurred background.
// blurView.autoPinEdgesToSuperviewEdges()
//
// localVideoView.autoPinEdge(toSuperviewEdge:.right, withInset:videoPreviewHMargin)
// localVideoView.autoPinEdge(toSuperviewEdge:.top, withInset:topMargin)
// let localVideoSize = ScaleFromIPhone5To7Plus(80, 100)
// localVideoView.autoSetDimension(.width, toSize:localVideoSize)
// localVideoView.autoSetDimension(.height, toSize:localVideoSize)
//
// contactNameLabel.autoPinEdge(toSuperviewEdge:.top, withInset:topMargin)
// contactNameLabel.autoPinEdge(toSuperviewEdge:.left, withInset:contactHMargin)
// contactNameLabel.setContentHuggingVerticalHigh()
//
// callStatusLabel.autoPinEdge(.top, to:.bottom, of:contactNameLabel, withOffset:contactVSpacing)
// callStatusLabel.autoPinEdge(toSuperviewEdge:.left, withInset:contactHMargin)
// callStatusLabel.setContentHuggingVerticalHigh()
//
// contactAvatarView.autoPinEdge(.top, to:.bottom, of:callStatusLabel, withOffset:+avatarTopSpacing)
// contactAvatarView.autoPinEdge(.bottom, to:.top, of:ongoingCallView, withOffset:-avatarBottomSpacing)
// contactAvatarView.autoHCenterInSuperview()
// // Stretch that avatar to fill the available space.
// contactAvatarView.setContentHuggingLow()
// contactAvatarView.setCompressionResistanceLow()
// // Preserve square aspect ratio of contact avatar.
// contactAvatarView.autoMatch(.width, to:.height, of:contactAvatarView)
//
// // Ongoing call controls
// ongoingCallView.autoPinEdge(toSuperviewEdge:.bottom, withInset:ongoingBottomMargin)
// ongoingCallView.autoPinWidthToSuperview(withMargin:ongoingHMargin)
// ongoingCallView.setContentHuggingVerticalHigh()
//
// // Incoming call controls
// incomingCallView.autoPinEdge(toSuperviewEdge:.bottom, withInset:incomingBottomMargin)
// incomingCallView.autoPinWidthToSuperview(withMargin:incomingHMargin)
// incomingCallView.setContentHuggingVerticalHigh()
//
// // Settings nag views
// settingsNagView.autoPinEdge(toSuperviewEdge:.bottom, withInset:settingsNagBottomMargin)
// settingsNagView.autoPinWidthToSuperview(withMargin:settingsNagHMargin)
// settingsNagView.autoPinEdge(.top, to:.bottom, of:callStatusLabel)
// }
//
// updateRemoteVideoLayout()
// updateLocalVideoLayout()
//
// super.updateViewConstraints()
// }
//
// internal func updateRemoteVideoLayout() {
// NSLayoutConstraint.deactivate(self.remoteVideoConstraints)
//
// var constraints: [NSLayoutConstraint] = []
//
// // We fill the screen with the remote video. The remote video's
// // aspect ratio may not (and in fact will very rarely) match the
// // aspect ratio of the current device, so parts of the remote
// // video will be hidden offscreen.
// //
// // It's better to trim the remote video than to adopt a letterboxed
// // layout.
// if remoteVideoSize.width > 0 && remoteVideoSize.height > 0 &&
// self.view.bounds.size.width > 0 && self.view.bounds.size.height > 0 {
//
// var remoteVideoWidth = self.view.bounds.size.width
// var remoteVideoHeight = self.view.bounds.size.height
// if remoteVideoSize.width / self.view.bounds.size.width > remoteVideoSize.height / self.view.bounds.size.height {
// remoteVideoWidth = round(self.view.bounds.size.height * remoteVideoSize.width / remoteVideoSize.height)
// } else {
// remoteVideoHeight = round(self.view.bounds.size.width * remoteVideoSize.height / remoteVideoSize.width)
// }
// constraints.append(remoteVideoView.autoSetDimension(.width, toSize:remoteVideoWidth))
// constraints.append(remoteVideoView.autoSetDimension(.height, toSize:remoteVideoHeight))
// constraints += remoteVideoView.autoCenterInSuperview()
//
// remoteVideoView.frame = CGRect(origin:CGPoint.zero,
// size:CGSize(width:remoteVideoWidth,
// height:remoteVideoHeight))
//
// remoteVideoView.isHidden = false
// } else {
// constraints += remoteVideoView.autoPinEdgesToSuperviewEdges()
// remoteVideoView.isHidden = true
// }
//
// self.remoteVideoConstraints = constraints
//
// // We need to force relayout to occur immediately (and not
// // wait for a UIKit layout/render pass) or the remoteVideoView
// // (which presumably is updating its CALayer directly) will
// // ocassionally appear to have bad frames.
// remoteVideoView.setNeedsLayout()
// remoteVideoView.superview?.setNeedsLayout()
// remoteVideoView.layoutIfNeeded()
// remoteVideoView.superview?.layoutIfNeeded()
//
// updateCallUI(callState: call.state)
// }
//
// internal func updateLocalVideoLayout() {
//
// NSLayoutConstraint.deactivate(self.localVideoConstraints)
//
// var constraints: [NSLayoutConstraint] = []
//
// if localVideoView.isHidden {
// let contactHMargin = CGFloat(30)
// constraints.append(contactNameLabel.autoPinEdge(toSuperviewEdge:.right, withInset:contactHMargin))
// constraints.append(callStatusLabel.autoPinEdge(toSuperviewEdge:.right, withInset:contactHMargin))
// } else {
// let spacing = CGFloat(10)
// constraints.append(contactNameLabel.autoPinEdge(.right, to:.left, of:localVideoView, withOffset:-spacing))
// constraints.append(callStatusLabel.autoPinEdge(.right, to:.left, of:localVideoView, withOffset:-spacing))
// }
//
// self.localVideoConstraints = constraints
// updateCallUI(callState: call.state)
// }
//
// // MARK: - Methods
//
// func showCallFailed(error: Error) {
// // TODO Show something in UI.
// Logger.error("\(TAG) call failed with error: \(error)")
// }
//
// // MARK: - View State
//
// func localizedTextForCallState(_ callState: CallState) -> String {
// assert(Thread.isMainThread)
//
// switch callState {
// case .idle, .remoteHangup, .localHangup:
// return NSLocalizedString("IN_CALL_TERMINATED", comment: "Call setup status label")
// case .dialing:
// return NSLocalizedString("IN_CALL_CONNECTING", comment: "Call setup status label")
// case .remoteRinging, .localRinging:
// return NSLocalizedString("IN_CALL_RINGING", comment: "Call setup status label")
// case .answering:
// return NSLocalizedString("IN_CALL_SECURING", comment: "Call setup status label")
// case .connected:
// if let call = self.call {
// let callDuration = call.connectionDuration()
// let callDurationDate = Date(timeIntervalSinceReferenceDate:callDuration)
// if dateFormatter == nil {
// dateFormatter = DateFormatter()
// dateFormatter!.dateFormat = "HH:mm:ss"
// dateFormatter!.timeZone = TimeZone(identifier:"UTC")!
// }
// var formattedDate = dateFormatter!.string(from: callDurationDate)
// if formattedDate.hasPrefix("00:") {
// // Don't show the "hours" portion of the date format unless the
// // call duration is at least 1 hour.
// formattedDate = formattedDate.substring(from: formattedDate.index(formattedDate.startIndex, offsetBy: 3))
// } else {
// // If showing the "hours" portion of the date format, strip any leading
// // zeroes.
// if formattedDate.hasPrefix("0") {
// formattedDate = formattedDate.substring(from: formattedDate.index(formattedDate.startIndex, offsetBy: 1))
// }
// }
// return formattedDate
// } else {
// return NSLocalizedString("IN_CALL_TALKING", comment: "Call setup status label")
// }
// case .remoteBusy:
// return NSLocalizedString("END_CALL_RESPONDER_IS_BUSY", comment: "Call setup status label")
// case .localFailure:
// if let error = call.error {
// switch error {
// case .timeout(description: _):
// if self.call.direction == .outgoing {
// return NSLocalizedString("CALL_SCREEN_STATUS_NO_ANSWER", comment: "Call setup status label after outgoing call times out")
// }
// default:
// break
// }
// }
//
// return NSLocalizedString("END_CALL_UNCATEGORIZED_FAILURE", comment: "Call setup status label")
// }
// }
//
// func updateCallStatusLabel(callState: CallState) {
// assert(Thread.isMainThread)
//
// let text = String(format: CallStrings.callStatusFormat,
// localizedTextForCallState(callState))
// self.callStatusLabel.text = text
// }
//
// func updateCallUI(callState: CallState) {
// assert(Thread.isMainThread)
// updateCallStatusLabel(callState: callState)
//
// if isShowingSettingsNag {
// settingsNagView.isHidden = false
// contactAvatarView.isHidden = true
// ongoingCallView.isHidden = true
// return
// }
//
// audioModeMuteButton.isSelected = call.isMuted
// videoModeMuteButton.isSelected = call.isMuted
// audioModeVideoButton.isSelected = call.hasLocalVideo
// videoModeVideoButton.isSelected = call.hasLocalVideo
// speakerPhoneButton.isSelected = call.isSpeakerphoneEnabled
//
// // Show Incoming vs. Ongoing call controls
// let isRinging = callState == .localRinging
// incomingCallView.isHidden = !isRinging
// incomingCallView.isUserInteractionEnabled = isRinging
// ongoingCallView.isHidden = isRinging
// ongoingCallView.isUserInteractionEnabled = !isRinging
//
// // Rework control state if remote video is available.
// let hasRemoteVideo = !remoteVideoView.isHidden
// contactAvatarView.isHidden = hasRemoteVideo
//
// // Rework control state if local video is available.
// let hasLocalVideo = !localVideoView.isHidden
// for subview in [speakerPhoneButton, audioModeMuteButton, audioModeVideoButton] {
// subview?.isHidden = hasLocalVideo
// }
// for subview in [videoModeMuteButton, videoModeVideoButton] {
// subview?.isHidden = !hasLocalVideo
// }
//
// // Also hide other controls if user has tapped to hide them.
// if shouldRemoteVideoControlsBeHidden && !remoteVideoView.isHidden {
// contactNameLabel.isHidden = true
// callStatusLabel.isHidden = true
// ongoingCallView.isHidden = true
// } else {
// contactNameLabel.isHidden = false
// callStatusLabel.isHidden = false
// }
//
// // Dismiss Handling
// switch callState {
// case .remoteHangup, .remoteBusy, .localFailure:
// Logger.debug("\(TAG) dismissing after delay because new state is \(callState)")
// dismissIfPossible(shouldDelay:true)
// case .localHangup:
// Logger.debug("\(TAG) dismissing immediately from local hangup")
// dismissIfPossible(shouldDelay:false)
// default: break
// }
//
// if callState == .connected {
// if callDurationTimer == nil {
// let kDurationUpdateFrequencySeconds = 1 / 20.0
// callDurationTimer = Timer.scheduledTimer(timeInterval: kDurationUpdateFrequencySeconds,
// target:self,
// selector:#selector(updateCallDuration),
// userInfo:nil,
// repeats:true)
// }
// } else {
// callDurationTimer?.invalidate()
// callDurationTimer = nil
// }
// }
//
// func updateCallDuration(timer: Timer?) {
// updateCallStatusLabel(callState: call.state)
// }
//
// // MARK: - Actions
//
// /**
// * Ends a connected call. Do not confuse with `didPressDeclineCall`.
// */
// func didPressHangup(sender: UIButton) {
// Logger.info("\(TAG) called \(#function)")
// if let call = self.call {
// callUIAdapter.localHangupCall(call)
// } else {
// Logger.warn("\(TAG) hung up, but call was unexpectedly nil")
// }
//
// dismissIfPossible(shouldDelay:false)
// }
//
// func didPressMute(sender muteButton: UIButton) {
// Logger.info("\(TAG) called \(#function)")
// muteButton.isSelected = !muteButton.isSelected
// if let call = self.call {
// callUIAdapter.setIsMuted(call: call, isMuted: muteButton.isSelected)
// } else {
// Logger.warn("\(TAG) pressed mute, but call was unexpectedly nil")
// }
// }
//
// func didPressSpeakerphone(sender speakerphoneButton: UIButton) {
// Logger.info("\(TAG) called \(#function)")
// speakerphoneButton.isSelected = !speakerphoneButton.isSelected
// if let call = self.call {
// callUIAdapter.setIsSpeakerphoneEnabled(call: call, isEnabled: speakerphoneButton.isSelected)
// } else {
// Logger.warn("\(TAG) pressed mute, but call was unexpectedly nil")
// }
// }
//
// func didPressTextMessage(sender speakerphoneButton: UIButton) {
// Logger.info("\(TAG) called \(#function)")
//
// dismissIfPossible(shouldDelay:false)
// }
//
// func didPressAnswerCall(sender: UIButton) {
// Logger.info("\(TAG) called \(#function)")
//
// guard let call = self.call else {
// Logger.error("\(TAG) call was unexpectedly nil. Terminating call.")
//
// let text = String(format: CallStrings.callStatusFormat,
// NSLocalizedString("END_CALL_UNCATEGORIZED_FAILURE", comment: "Call setup status label"))
// self.callStatusLabel.text = text
//
// dismissIfPossible(shouldDelay:true)
// return
// }
//
// callUIAdapter.answerCall(call)
// }
//
// func didPressVideo(sender: UIButton) {
// Logger.info("\(TAG) called \(#function)")
// let hasLocalVideo = !sender.isSelected
// if let call = self.call {
// callUIAdapter.setHasLocalVideo(call: call, hasLocalVideo: hasLocalVideo)
// } else {
// Logger.warn("\(TAG) pressed video, but call was unexpectedly nil")
// }
// }
//
// /**
// * Denies an incoming not-yet-connected call, Do not confuse with `didPressHangup`.
// */
// func didPressDeclineCall(sender: UIButton) {
// Logger.info("\(TAG) called \(#function)")
//
// if let call = self.call {
// callUIAdapter.declineCall(call)
// } else {
// Logger.warn("\(TAG) denied call, but call was unexpectedly nil")
// }
//
// dismissIfPossible(shouldDelay:false)
// }
//
// func didPressShowCallSettings(sender: UIButton) {
// Logger.info("\(TAG) called \(#function)")
//
// markSettingsNagAsComplete()
//
// dismissIfPossible(shouldDelay: false, ignoreNag: true, completion: {
// // Find the frontmost presented UIViewController from which to present the
// // settings views.
// let fromViewController = UIApplication.shared.frontmostViewController
// assert(fromViewController != nil)
//
// // Construct the "settings" view & push the "privacy settings" view.
// let navigationController = UIStoryboard.main.instantiateViewController(withIdentifier: "SettingsNavigationController") as! UINavigationController
// assert(navigationController.viewControllers.count == 1)
// let privacySettingsViewController = PrivacySettingsTableViewController()
// navigationController.pushViewController(privacySettingsViewController, animated:false)
//
// fromViewController?.present(navigationController, animated: true, completion: nil)
// })
// }
//
// func didPressDismissNag(sender: UIButton) {
// Logger.info("\(TAG) called \(#function)")
//
// markSettingsNagAsComplete()
//
// dismissIfPossible(shouldDelay: false, ignoreNag: true)
// }
//
// // We only show the "blocking" settings nag until the user has chosen
// // to view the privacy settings _or_ dismissed the nag at least once.
// //
// // In either case, we set the "CallKit enabled" and "CallKit privacy enabled"
// // settings to their default values to indicate that the user has reviewed
// // them.
// private func markSettingsNagAsComplete() {
// Logger.info("\(TAG) called \(#function)")
//
// let preferences = Environment.getCurrent().preferences!
//
// preferences.setIsCallKitEnabled(preferences.isCallKitEnabled())
// preferences.setIsCallKitPrivacyEnabled(preferences.isCallKitPrivacyEnabled())
// }
//
// // MARK: - CallObserver
//
// internal func stateDidChange(call: SignalCall, state: CallState) {
// AssertIsOnMainThread()
// Logger.info("\(self.TAG) new call status: \(state)")
// self.updateCallUI(callState: state)
// }
//
// internal func hasLocalVideoDidChange(call: SignalCall, hasLocalVideo: Bool) {
// AssertIsOnMainThread()
// self.updateCallUI(callState: call.state)
// }
//
// internal func muteDidChange(call: SignalCall, isMuted: Bool) {
// AssertIsOnMainThread()
// self.updateCallUI(callState: call.state)
// }
//
// internal func speakerphoneDidChange(call: SignalCall, isEnabled: Bool) {
// AssertIsOnMainThread()
// self.updateCallUI(callState: call.state)
// }
//
// // MARK: - Video
//
// internal func updateLocalVideoTrack(localVideoTrack: RTCVideoTrack?) {
// AssertIsOnMainThread()
// guard self.localVideoTrack != localVideoTrack else {
// return
// }
//
// self.localVideoTrack = localVideoTrack
//
// var source: RTCAVFoundationVideoSource?
// if localVideoTrack?.source is RTCAVFoundationVideoSource {
// source = localVideoTrack?.source as! RTCAVFoundationVideoSource
// }
// localVideoView.captureSession = source?.captureSession
// let isHidden = source == nil
// Logger.info("\(TAG) \(#function) isHidden: \(isHidden)")
// localVideoView.isHidden = isHidden
//
// updateLocalVideoLayout()
// }
//
// internal func updateRemoteVideoTrack(remoteVideoTrack: RTCVideoTrack?) {
// AssertIsOnMainThread()
// guard self.remoteVideoTrack != remoteVideoTrack else {
// return
// }
//
// self.remoteVideoTrack?.remove(remoteVideoView)
// self.remoteVideoTrack = nil
// remoteVideoView.renderFrame(nil)
// self.remoteVideoTrack = remoteVideoTrack
// self.remoteVideoTrack?.add(remoteVideoView)
// shouldRemoteVideoControlsBeHidden = false
//
// if remoteVideoTrack == nil {
// remoteVideoSize = CGSize.zero
// }
//
// updateRemoteVideoLayout()
// }
//
// internal func dismissIfPossible(shouldDelay: Bool, ignoreNag: Bool = false, completion: (() -> Swift.Void)? = nil) {
// if hasDismissed {
// // Don't dismiss twice.
// return
// } else if !ignoreNag &&
// call.direction == .incoming &&
// UIDevice.current.supportsCallKit &&
// (!Environment.getCurrent().preferences.isCallKitEnabled() ||
// Environment.getCurrent().preferences.isCallKitPrivacyEnabled()) {
//
// isShowingSettingsNag = true
//
// // Update the nag view's copy to reflect the settings state.
// if Environment.getCurrent().preferences.isCallKitEnabled() {
// settingsNagDescriptionLabel.text = NSLocalizedString("CALL_VIEW_SETTINGS_NAG_DESCRIPTION_PRIVACY",
// comment: "Reminder to the user of the benefits of disabling CallKit privacy.")
// } else {
// settingsNagDescriptionLabel.text = NSLocalizedString("CALL_VIEW_SETTINGS_NAG_DESCRIPTION_ALL",
// comment: "Reminder to the user of the benefits of enabling CallKit and disabling CallKit privacy.")
// }
// settingsNagDescriptionLabel.superview?.setNeedsLayout()
//
// if Environment.getCurrent().preferences.isCallKitEnabledSet() ||
// Environment.getCurrent().preferences.isCallKitPrivacySet() {
// // User has already touched these preferences, only show
// // the "fleeting" nag, not the "blocking" nag.
//
// // Show nag for N seconds.
// DispatchQueue.main.asyncAfter(deadline: .now() + 5) { [weak self] in
// guard let strongSelf = self else { return }
// strongSelf.dismissIfPossible(shouldDelay: false, ignoreNag: true)
// }
// }
// } else if shouldDelay {
// hasDismissed = true
// DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) { [weak self] in
// guard let strongSelf = self else { return }
// strongSelf.dismiss(animated: true, completion:completion)
// }
// } else {
// hasDismissed = true
// self.dismiss(animated: false, completion:completion)
// }
// }
//
// // MARK: - CallServiceObserver
//
// internal func didUpdateCall(call: SignalCall?) {
// // Do nothing.
// }
//
// internal func didUpdateVideoTracks(localVideoTrack: RTCVideoTrack?,
// remoteVideoTrack: RTCVideoTrack?) {
// AssertIsOnMainThread()
//
// updateLocalVideoTrack(localVideoTrack:localVideoTrack)
// updateRemoteVideoTrack(remoteVideoTrack:remoteVideoTrack)
// }
//
// // MARK: - RTCEAGLVideoViewDelegate
//
// internal func videoView(_ videoView: RTCEAGLVideoView, didChangeVideoSize size: CGSize) {
// AssertIsOnMainThread()
//
// if videoView != remoteVideoView {
// return
// }
//
// Logger.info("\(TAG) \(#function): \(size)")
//
// remoteVideoSize = size
// updateRemoteVideoLayout()
// }
}

View File

@ -7,10 +7,6 @@
//
#import <UIKit/UIKit.h>
#import <JSQMessagesViewController/JSQMessagesComposerTextView.h>
#import <JSQMessagesViewController/JSQMessagesInputToolbar.h>
#import <JSQMessagesViewController/JSQMessagesToolbarContentView.h>
#import <JSQMessagesViewController/JSQMessagesKeyboardController.h>
#import "Contact.h"
#import "LocalizableText.h"

View File

@ -0,0 +1,58 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="11762" systemVersion="15G1217" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="MessagesViewController">
<connections>
<outlet property="collectionView" destination="l9u-2b-4LK" id="bLP-6g-CkO"/>
<outlet property="inputToolbar" destination="BoD-Az-3DM" id="w74-g9-1qA"/>
<outlet property="toolbarBottomLayoutGuide" destination="rHs-6q-NX4" id="d6h-iu-VMX"/>
<outlet property="toolbarHeightConstraint" destination="HIk-02-qcW" id="jE8-xC-1eD"/>
<outlet property="view" destination="mUa-cS-ru4" id="nki-T1-RTI"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="mUa-cS-ru4">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<collectionView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" minimumZoomScale="0.0" maximumZoomScale="0.0" dataMode="prototypes" translatesAutoresizingMaskIntoConstraints="NO" id="l9u-2b-4LK" customClass="JSQMessagesCollectionView">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<collectionViewLayout key="collectionViewLayout" id="dZl-7C-LHR" customClass="JSQMessagesCollectionViewFlowLayout"/>
<cells/>
</collectionView>
<toolbar opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="BoD-Az-3DM" customClass="OWSMessagesInputToolbar">
<rect key="frame" x="0.0" y="623" width="375" height="44"/>
<constraints>
<constraint firstAttribute="height" constant="44" id="HIk-02-qcW"/>
</constraints>
<items/>
</toolbar>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="trailing" secondItem="BoD-Az-3DM" secondAttribute="trailing" id="7xc-Ha-asg"/>
<constraint firstItem="l9u-2b-4LK" firstAttribute="leading" secondItem="mUa-cS-ru4" secondAttribute="leading" id="MmF-oh-Y75"/>
<constraint firstAttribute="trailing" secondItem="l9u-2b-4LK" secondAttribute="trailing" id="O9u-TA-A0e"/>
<constraint firstAttribute="bottom" secondItem="l9u-2b-4LK" secondAttribute="bottom" id="Re7-WW-UmS"/>
<constraint firstItem="l9u-2b-4LK" firstAttribute="top" secondItem="mUa-cS-ru4" secondAttribute="top" id="dCQ-DM-Wdj"/>
<constraint firstAttribute="bottom" secondItem="BoD-Az-3DM" secondAttribute="bottom" id="rHs-6q-NX4"/>
<constraint firstItem="BoD-Az-3DM" firstAttribute="leading" secondItem="mUa-cS-ru4" secondAttribute="leading" id="ts7-8f-0lH"/>
</constraints>
<nil key="simulatedStatusBarMetrics"/>
</view>
</objects>
<simulatedMetricsContainer key="defaultSimulatedMetrics">
<simulatedStatusBarMetrics key="statusBar"/>
<simulatedOrientationMetrics key="orientation"/>
<simulatedScreenMetrics key="destination" type="retina4_7.fullscreen"/>
</simulatedMetricsContainer>
</document>

View File

@ -93,12 +93,7 @@ static NSString *const OWSConversationSettingsTableViewControllerSegueShowGroupM
return self;
}
_storageManager = [TSStorageManager sharedManager];
_contactsManager = [Environment getCurrent].contactsManager;
_messageSender = [[OWSMessageSender alloc] initWithNetworkManager:[Environment getCurrent].networkManager
storageManager:_storageManager
contactsManager:_contactsManager
contactsUpdater:[Environment getCurrent].contactsUpdater];
[self commonInit];
return self;
}
@ -110,14 +105,30 @@ static NSString *const OWSConversationSettingsTableViewControllerSegueShowGroupM
return self;
}
[self commonInit];
return self;
}
- (instancetype)initWithNibName:(nullable NSString *)nibNameOrNil bundle:(nullable NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (!self) {
return self;
}
[self commonInit];
return self;
}
- (void)commonInit
{
_storageManager = [TSStorageManager sharedManager];
_contactsManager = [Environment getCurrent].contactsManager;
_messageSender = [[OWSMessageSender alloc] initWithNetworkManager:[Environment getCurrent].networkManager
storageManager:_storageManager
contactsManager:_contactsManager
contactsUpdater:[Environment getCurrent].contactsUpdater];
return self;
}
- (void)configureWithThread:(TSThread *)thread

View File

@ -0,0 +1,71 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="11762" systemVersion="15G1217" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="1" customClass="OWSMessagesToolbarContentView">
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="LEq-G7-jGt" userLabel="Left button container">
<rect key="frame" x="8" y="6" width="34" height="32"/>
<color key="backgroundColor" red="0.66666666666666663" green="0.66666666666666663" blue="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="height" constant="32" id="0sE-GV-joM"/>
<constraint firstAttribute="width" constant="34" id="eMy-Af-wwH"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Myo-1S-Vg1" userLabel="Right button container">
<rect key="frame" x="262" y="6" width="50" height="32"/>
<color key="backgroundColor" red="0.66666666666666663" green="0.66666666666666663" blue="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="height" constant="32" id="NaR-re-dJ4"/>
<constraint firstAttribute="width" constant="50" id="yde-S9-dHe"/>
</constraints>
</view>
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="dm4-NT-mvr" customClass="OWSMessagesComposerTextView">
<rect key="frame" x="50" y="7" width="204" height="30"/>
<color key="backgroundColor" red="0.66666666666666663" green="0.66666666666666663" blue="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
</textView>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="Myo-1S-Vg1" firstAttribute="leading" secondItem="dm4-NT-mvr" secondAttribute="trailing" constant="8" id="7Ld-5r-Hp3"/>
<constraint firstItem="dm4-NT-mvr" firstAttribute="top" secondItem="1" secondAttribute="top" constant="7" id="9Tz-Wq-xIf"/>
<constraint firstAttribute="bottom" secondItem="dm4-NT-mvr" secondAttribute="bottom" constant="7" id="CCb-V7-yek"/>
<constraint firstAttribute="bottom" secondItem="Myo-1S-Vg1" secondAttribute="bottom" constant="6" id="EaS-Oq-Qp5"/>
<constraint firstItem="LEq-G7-jGt" firstAttribute="leading" secondItem="1" secondAttribute="leading" constant="8" id="LAU-fo-GJJ"/>
<constraint firstAttribute="trailing" secondItem="Myo-1S-Vg1" secondAttribute="trailing" constant="8" id="ds6-61-GNv"/>
<constraint firstAttribute="bottom" secondItem="LEq-G7-jGt" secondAttribute="bottom" constant="6" id="oG2-YD-ZZI"/>
<constraint firstItem="dm4-NT-mvr" firstAttribute="leading" secondItem="LEq-G7-jGt" secondAttribute="trailing" constant="8" id="owo-gB-gyR"/>
</constraints>
<nil key="simulatedStatusBarMetrics"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<connections>
<outlet property="leftBarButtonContainerView" destination="LEq-G7-jGt" id="F0V-4N-1Mo"/>
<outlet property="leftBarButtonContainerViewWidthConstraint" destination="eMy-Af-wwH" id="FI9-F2-2bN"/>
<outlet property="leftHorizontalSpacingConstraint" destination="LAU-fo-GJJ" id="X2c-BI-0Q4"/>
<outlet property="rightBarButtonContainerView" destination="Myo-1S-Vg1" id="0SR-cw-EkD"/>
<outlet property="rightBarButtonContainerViewWidthConstraint" destination="yde-S9-dHe" id="WGu-df-M3L"/>
<outlet property="rightHorizontalSpacingConstraint" destination="ds6-61-GNv" id="ZQh-8M-QFs"/>
<outlet property="textView" destination="dm4-NT-mvr" id="PFw-HO-oT8"/>
</connections>
<point key="canvasLocation" x="268" y="548"/>
</view>
</objects>
<simulatedMetricsContainer key="defaultSimulatedMetrics">
<simulatedStatusBarMetrics key="statusBar"/>
<simulatedOrientationMetrics key="orientation"/>
<simulatedScreenMetrics key="destination" type="retina4_7.fullscreen"/>
</simulatedMetricsContainer>
</document>

View File

@ -564,8 +564,8 @@ NSString *const SignalsViewControllerSegueShowIncomingCall = @"ShowIncomingCallS
- (void)presentThread:(TSThread *)thread keyboardOnViewAppearing:(BOOL)keyboardOnViewAppearing {
dispatch_async(dispatch_get_main_queue(), ^{
MessagesViewController *mvc = [[UIStoryboard storyboardWithName:AppDelegateStoryboardMain bundle:NULL]
instantiateViewControllerWithIdentifier:@"MessagesViewController"];
MessagesViewController *mvc = [[MessagesViewController alloc] initWithNibName:@"MessagesViewController"
bundle:nil];
if (self.presentedViewController) {
[self.presentedViewController dismissViewControllerAnimated:YES completion:nil];