mirror of
https://github.com/oxen-io/session-ios.git
synced 2023-12-13 21:30:14 +01:00
Merge branch 'charlesmchen/swift4'
This commit is contained in:
commit
295f720f93
80 changed files with 468 additions and 303 deletions
|
@ -2593,12 +2593,12 @@
|
|||
453518911FC63DBF00210559 = {
|
||||
CreatedOnToolsVersion = 9.2;
|
||||
DevelopmentTeam = U68MSDN6DR;
|
||||
LastSwiftMigration = 0910;
|
||||
LastSwiftMigration = 0930;
|
||||
ProvisioningStyle = Automatic;
|
||||
};
|
||||
D221A088169C9E5E00537ABF = {
|
||||
DevelopmentTeam = U68MSDN6DR;
|
||||
LastSwiftMigration = 0800;
|
||||
LastSwiftMigration = 0930;
|
||||
ProvisioningStyle = Automatic;
|
||||
SystemCapabilities = {
|
||||
com.apple.ApplicationGroups.iOS = {
|
||||
|
@ -2629,7 +2629,7 @@
|
|||
};
|
||||
D221A0A9169C9E5F00537ABF = {
|
||||
DevelopmentTeam = U68MSDN6DR;
|
||||
LastSwiftMigration = 0800;
|
||||
LastSwiftMigration = 0930;
|
||||
ProvisioningStyle = Automatic;
|
||||
TestTargetID = D221A088169C9E5E00537ABF;
|
||||
};
|
||||
|
@ -3539,6 +3539,7 @@
|
|||
ONLY_ACTIVE_ARCH = YES;
|
||||
OTHER_CFLAGS = "-fobjc-arc-exceptions";
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_VERSION = 4.0;
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Test;
|
||||
|
@ -3597,7 +3598,8 @@
|
|||
SDKROOT = iphoneos;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Signal/src/Signal-Bridging-Header.h";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 3.0;
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
|
||||
SWIFT_VERSION = 4.0;
|
||||
TEST_AFTER_BUILD = YES;
|
||||
VALID_ARCHS = "arm64 armv7 armv7s";
|
||||
WRAPPER_EXTENSION = app;
|
||||
|
@ -3657,7 +3659,8 @@
|
|||
PROVISIONING_PROFILE = "";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Signal/test/SignalTests-Bridging-Header.h";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 3.0;
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
|
||||
SWIFT_VERSION = 4.0;
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Signal.app/Signal";
|
||||
VALID_ARCHS = "arm64 armv7s armv7 i386 x86_64";
|
||||
};
|
||||
|
@ -3901,7 +3904,8 @@
|
|||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 3.0;
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
|
||||
SWIFT_VERSION = 4.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
VERSION_INFO_PREFIX = "";
|
||||
|
@ -3978,7 +3982,8 @@
|
|||
SKIP_INSTALL = YES;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 3.0;
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
|
||||
SWIFT_VERSION = 4.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VALIDATE_PRODUCT = YES;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
|
@ -4055,7 +4060,8 @@
|
|||
SKIP_INSTALL = YES;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
|
||||
SWIFT_VERSION = 3.0;
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
|
||||
SWIFT_VERSION = 4.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VALIDATE_PRODUCT = YES;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
|
@ -4128,6 +4134,7 @@
|
|||
ONLY_ACTIVE_ARCH = YES;
|
||||
OTHER_CFLAGS = "-fobjc-arc-exceptions";
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_VERSION = 4.0;
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Debug;
|
||||
|
@ -4196,6 +4203,7 @@
|
|||
);
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
|
||||
SWIFT_VERSION = 4.0;
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = "App Store Release";
|
||||
|
@ -4254,7 +4262,8 @@
|
|||
SDKROOT = iphoneos;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Signal/src/Signal-Bridging-Header.h";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 3.0;
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
|
||||
SWIFT_VERSION = 4.0;
|
||||
TEST_AFTER_BUILD = YES;
|
||||
VALID_ARCHS = "arm64 armv7 armv7s";
|
||||
WRAPPER_EXTENSION = app;
|
||||
|
@ -4313,7 +4322,8 @@
|
|||
PROVISIONING_PROFILE = "";
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Signal/src/Signal-Bridging-Header.h";
|
||||
SWIFT_VERSION = 3.0;
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
|
||||
SWIFT_VERSION = 4.0;
|
||||
TEST_AFTER_BUILD = YES;
|
||||
VALID_ARCHS = "arm64 armv7 armv7s";
|
||||
WRAPPER_EXTENSION = app;
|
||||
|
@ -4373,7 +4383,8 @@
|
|||
PROVISIONING_PROFILE = "";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Signal/test/SignalTests-Bridging-Header.h";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 3.0;
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
|
||||
SWIFT_VERSION = 4.0;
|
||||
TEST_HOST = "$(BUNDLE_LOADER)";
|
||||
VALID_ARCHS = "arm64 armv7s armv7 i386 x86_64";
|
||||
};
|
||||
|
@ -4431,7 +4442,8 @@
|
|||
PROVISIONING_PROFILE = "";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Signal/test/SignalTests-Bridging-Header.h";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
|
||||
SWIFT_VERSION = 3.0;
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
|
||||
SWIFT_VERSION = 4.0;
|
||||
TEST_HOST = "$(BUNDLE_LOADER)";
|
||||
VALID_ARCHS = "arm64 armv7s armv7 i386 x86_64";
|
||||
};
|
||||
|
|
|
@ -912,7 +912,7 @@ static NSTimeInterval launchStartedAt;
|
|||
- (void)application:(UIApplication *)application
|
||||
handleActionWithIdentifier:(NSString *)identifier
|
||||
forLocalNotification:(UILocalNotification *)notification
|
||||
completionHandler:(void (^)(void))completionHandler
|
||||
completionHandler:(void (^)())completionHandler
|
||||
{
|
||||
OWSAssertIsOnMainThread();
|
||||
|
||||
|
@ -939,7 +939,7 @@ static NSTimeInterval launchStartedAt;
|
|||
handleActionWithIdentifier:(NSString *)identifier
|
||||
forLocalNotification:(UILocalNotification *)notification
|
||||
withResponseInfo:(NSDictionary *)responseInfo
|
||||
completionHandler:(void (^)(void))completionHandler
|
||||
completionHandler:(void (^)())completionHandler
|
||||
{
|
||||
OWSAssertIsOnMainThread();
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import PromiseKit
|
|||
import SignalServiceKit
|
||||
|
||||
@objc(OWSMessageFetcherJob)
|
||||
class MessageFetcherJob: NSObject {
|
||||
public class MessageFetcherJob: NSObject {
|
||||
|
||||
private var timer: Timer?
|
||||
|
||||
|
@ -16,7 +16,7 @@ class MessageFetcherJob: NSObject {
|
|||
private let messageReceiver: OWSMessageReceiver
|
||||
private let signalService: OWSSignalService
|
||||
|
||||
init(messageReceiver: OWSMessageReceiver, networkManager: TSNetworkManager, signalService: OWSSignalService) {
|
||||
@objc public init(messageReceiver: OWSMessageReceiver, networkManager: TSNetworkManager, signalService: OWSSignalService) {
|
||||
self.messageReceiver = messageReceiver
|
||||
self.networkManager = networkManager
|
||||
self.signalService = signalService
|
||||
|
@ -58,7 +58,7 @@ class MessageFetcherJob: NSObject {
|
|||
return promise
|
||||
}
|
||||
|
||||
@objc func run() -> AnyPromise {
|
||||
@objc public func run() -> AnyPromise {
|
||||
return AnyPromise(run())
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
@ -12,7 +12,7 @@ import SignalMessaging
|
|||
* Syncing is accomplished via the existing contact syncing mechanism, except the only contact synced is ourself. It's incumbent on the linked device
|
||||
* to treat this "self contact" record specially.
|
||||
*/
|
||||
@objc class MultiDeviceProfileKeyUpdateJob: NSObject {
|
||||
@objc public class MultiDeviceProfileKeyUpdateJob: NSObject {
|
||||
|
||||
let TAG = "[MultiDeviceProfileKeyUpdateJob]"
|
||||
|
||||
|
@ -21,7 +21,7 @@ import SignalMessaging
|
|||
let messageSender: MessageSender
|
||||
let profileManager: OWSProfileManager
|
||||
|
||||
required init(profileKey: OWSAES256Key, identityManager: OWSIdentityManager, messageSender: MessageSender, profileManager: OWSProfileManager) {
|
||||
@objc public required init(profileKey: OWSAES256Key, identityManager: OWSIdentityManager, messageSender: MessageSender, profileManager: OWSProfileManager) {
|
||||
self.profileKey = profileKey
|
||||
|
||||
self.identityManager = identityManager
|
||||
|
@ -29,7 +29,7 @@ import SignalMessaging
|
|||
self.profileManager = profileManager
|
||||
}
|
||||
|
||||
class func run(profileKey: OWSAES256Key, identityManager: OWSIdentityManager, messageSender: MessageSender, profileManager: OWSProfileManager) {
|
||||
@objc public class func run(profileKey: OWSAES256Key, identityManager: OWSIdentityManager, messageSender: MessageSender, profileManager: OWSProfileManager) {
|
||||
return self.init(profileKey: profileKey, identityManager: identityManager, messageSender: messageSender, profileManager: profileManager).run()
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import PromiseKit
|
|||
import SignalServiceKit
|
||||
|
||||
@objc(OWSSessionResetJob)
|
||||
class SessionResetJob: NSObject {
|
||||
public class SessionResetJob: NSObject {
|
||||
|
||||
let TAG = "SessionResetJob"
|
||||
|
||||
|
@ -16,7 +16,7 @@ class SessionResetJob: NSObject {
|
|||
let primaryStorage: OWSPrimaryStorage
|
||||
let messageSender: MessageSender
|
||||
|
||||
required init(recipientId: String, thread: TSThread, messageSender: MessageSender, primaryStorage: OWSPrimaryStorage) {
|
||||
@objc public required init(recipientId: String, thread: TSThread, messageSender: MessageSender, primaryStorage: OWSPrimaryStorage) {
|
||||
self.thread = thread
|
||||
self.recipientId = recipientId
|
||||
self.messageSender = messageSender
|
||||
|
@ -64,7 +64,7 @@ class SessionResetJob: NSObject {
|
|||
}
|
||||
}
|
||||
|
||||
class func run(contactThread: TSContactThread, messageSender: MessageSender, primaryStorage: OWSPrimaryStorage) {
|
||||
@objc public class func run(contactThread: TSContactThread, messageSender: MessageSender, primaryStorage: OWSPrimaryStorage) {
|
||||
let job = self.init(recipientId: contactThread.contactIdentifier(),
|
||||
thread: contactThread,
|
||||
messageSender: messageSender,
|
||||
|
|
|
@ -18,8 +18,9 @@ class SyncPushTokensJob: NSObject {
|
|||
return PushRegistrationManager.shared
|
||||
}
|
||||
|
||||
var uploadOnlyIfStale = true
|
||||
@objc var uploadOnlyIfStale = true
|
||||
|
||||
@objc
|
||||
required init(accountManager: AccountManager, preferences: OWSPreferences) {
|
||||
self.accountManager = accountManager
|
||||
self.preferences = preferences
|
||||
|
|
|
@ -10,7 +10,8 @@ import SignalServiceKit
|
|||
* Signal is actually two services - textSecure for messages and red phone (for calls).
|
||||
* AccountManager delegates to both.
|
||||
*/
|
||||
class AccountManager: NSObject {
|
||||
@objc
|
||||
public class AccountManager: NSObject {
|
||||
let TAG = "[AccountManager]"
|
||||
|
||||
let textSecureAccountManager: TSAccountManager
|
||||
|
@ -22,7 +23,8 @@ class AccountManager: NSObject {
|
|||
return PushManager.shared()
|
||||
}
|
||||
|
||||
required init(textSecureAccountManager: TSAccountManager, preferences: OWSPreferences) {
|
||||
@objc
|
||||
public required init(textSecureAccountManager: TSAccountManager, preferences: OWSPreferences) {
|
||||
self.networkManager = textSecureAccountManager.networkManager
|
||||
self.textSecureAccountManager = textSecureAccountManager
|
||||
self.preferences = preferences
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
@ -20,6 +20,7 @@ class CompareSafetyNumbersActivity: UIActivity {
|
|||
var mySafetyNumbers: String?
|
||||
let delegate: CompareSafetyNumbersActivityDelegate
|
||||
|
||||
@objc
|
||||
required init(delegate: CompareSafetyNumbersActivityDelegate) {
|
||||
self.delegate = delegate
|
||||
super.init()
|
||||
|
@ -48,7 +49,7 @@ class CompareSafetyNumbersActivity: UIActivity {
|
|||
}
|
||||
|
||||
override func canPerform(withActivityItems activityItems: [Any]) -> Bool {
|
||||
return stringsFrom(activityItems:activityItems).count > 0
|
||||
return stringsFrom(activityItems: activityItems).count > 0
|
||||
}
|
||||
|
||||
override func prepare(withActivityItems activityItems: [Any]) {
|
||||
|
@ -73,7 +74,7 @@ class CompareSafetyNumbersActivity: UIActivity {
|
|||
|
||||
if pasteboardSafetyNumbers == mySafetyNumbers {
|
||||
Logger.info("\(TAG) successfully matched safety numbers. local numbers: \(String(describing: mySafetyNumbers)) pasteboard:\(pasteboardSafetyNumbers)")
|
||||
delegate.compareSafetyNumbersActivitySucceeded(activity:self)
|
||||
delegate.compareSafetyNumbersActivitySucceeded(activity: self)
|
||||
} else {
|
||||
Logger.warn("\(TAG) local numbers: \(String(describing: mySafetyNumbers)) didn't match pasteboard:\(pasteboardSafetyNumbers)")
|
||||
let error = OWSErrorWithCodeDescription(OWSErrorCode.privacyVerificationFailure,
|
||||
|
@ -91,7 +92,7 @@ class CompareSafetyNumbersActivity: UIActivity {
|
|||
|
||||
var numericOnly: String?
|
||||
if let regex = try? NSRegularExpression(pattern: "\\D", options: .caseInsensitive) {
|
||||
numericOnly = regex.stringByReplacingMatches(in: string!, options: .withTransparentBounds, range: NSMakeRange(0, string!.count), withTemplate: "")
|
||||
numericOnly = regex.stringByReplacingMatches(in: string!, options: .withTransparentBounds, range: NSRange(location: 0, length: string!.count), withTemplate: "")
|
||||
}
|
||||
|
||||
return numericOnly
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
|
||||
import Foundation
|
||||
|
||||
extension UIApplication {
|
||||
@objc public extension UIApplication {
|
||||
|
||||
var frontmostViewControllerIgnoringAlerts: UIViewController? {
|
||||
@objc public var frontmostViewControllerIgnoringAlerts: UIViewController? {
|
||||
return findFrontmostViewController(ignoringAlerts: true)
|
||||
}
|
||||
|
||||
var frontmostViewController: UIViewController? {
|
||||
@objc public var frontmostViewController: UIViewController? {
|
||||
return findFrontmostViewController(ignoringAlerts: false)
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@ extension UIApplication {
|
|||
return viewController.findFrontmostViewController(ignoringAlerts)
|
||||
}
|
||||
|
||||
func openSystemSettings() {
|
||||
@objc public func openSystemSettings() {
|
||||
openURL(URL(string: UIApplicationOpenSettingsURLString)!)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
@ -9,6 +9,7 @@ extension UIStoryboard {
|
|||
case main = "Main"
|
||||
}
|
||||
|
||||
@objc
|
||||
class var main: UIStoryboard {
|
||||
return UIStoryboard(name: StoryboardName.main.rawValue, bundle: Bundle.main)
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
@ -8,7 +8,7 @@ import Foundation
|
|||
* Present call related notifications to the user.
|
||||
*/
|
||||
@objc(OWSCallNotificationsAdapter)
|
||||
class CallNotificationsAdapter: NSObject {
|
||||
public class CallNotificationsAdapter: NSObject {
|
||||
|
||||
let TAG = "[CallNotificationsAdapter]"
|
||||
let adaptee: OWSCallNotificationsAdaptee
|
||||
|
|
|
@ -150,7 +150,7 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver,
|
|||
NotificationCenter.default.removeObserver(self)
|
||||
}
|
||||
|
||||
func didBecomeActive() {
|
||||
@objc func didBecomeActive() {
|
||||
if (self.isViewLoaded) {
|
||||
shouldRemoteVideoControlsBeHidden = false
|
||||
}
|
||||
|
@ -235,7 +235,7 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver,
|
|||
createSettingsNagViews()
|
||||
}
|
||||
|
||||
func didTouchRootView(sender: UIGestureRecognizer) {
|
||||
@objc func didTouchRootView(sender: UIGestureRecognizer) {
|
||||
if !remoteVideoView.isHidden {
|
||||
shouldRemoteVideoControlsBeHidden = !shouldRemoteVideoControlsBeHidden
|
||||
}
|
||||
|
@ -541,7 +541,7 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver,
|
|||
contactAvatarView.autoPinEdge(toSuperviewEdge: .right, withInset: 0, relation: .greaterThanOrEqual)
|
||||
contactAvatarView.autoPinEdge(toSuperviewEdge: .bottom, withInset: 0, relation: .greaterThanOrEqual)
|
||||
contactAvatarView.autoPinEdge(toSuperviewEdge: .left, withInset: 0, relation: .greaterThanOrEqual)
|
||||
NSLayoutConstraint.autoSetPriority(UILayoutPriorityDefaultLow) {
|
||||
NSLayoutConstraint.autoSetPriority(UILayoutPriority.defaultLow) {
|
||||
contactAvatarView.autoPinEdgesToSuperviewMargins()
|
||||
}
|
||||
|
||||
|
@ -825,7 +825,7 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver,
|
|||
/**
|
||||
* Ends a connected call. Do not confuse with `didPressDeclineCall`.
|
||||
*/
|
||||
func didPressHangup(sender: UIButton) {
|
||||
@objc func didPressHangup(sender: UIButton) {
|
||||
Logger.info("\(TAG) called \(#function)")
|
||||
|
||||
callUIAdapter.localHangupCall(call)
|
||||
|
@ -833,14 +833,14 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver,
|
|||
dismissIfPossible(shouldDelay: false)
|
||||
}
|
||||
|
||||
func didPressMute(sender muteButton: UIButton) {
|
||||
@objc func didPressMute(sender muteButton: UIButton) {
|
||||
Logger.info("\(TAG) called \(#function)")
|
||||
muteButton.isSelected = !muteButton.isSelected
|
||||
|
||||
callUIAdapter.setIsMuted(call: call, isMuted: muteButton.isSelected)
|
||||
}
|
||||
|
||||
func didPressAudioSource(sender button: UIButton) {
|
||||
@objc func didPressAudioSource(sender button: UIButton) {
|
||||
Logger.info("\(TAG) called \(#function)")
|
||||
|
||||
if self.hasAlternateAudioSources {
|
||||
|
@ -863,20 +863,20 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver,
|
|||
dismissIfPossible(shouldDelay: false)
|
||||
}
|
||||
|
||||
func didPressAnswerCall(sender: UIButton) {
|
||||
@objc func didPressAnswerCall(sender: UIButton) {
|
||||
Logger.info("\(TAG) called \(#function)")
|
||||
|
||||
callUIAdapter.answerCall(call)
|
||||
}
|
||||
|
||||
func didPressVideo(sender: UIButton) {
|
||||
@objc func didPressVideo(sender: UIButton) {
|
||||
Logger.info("\(TAG) called \(#function)")
|
||||
let hasLocalVideo = !sender.isSelected
|
||||
|
||||
callUIAdapter.setHasLocalVideo(call: call, hasLocalVideo: hasLocalVideo)
|
||||
}
|
||||
|
||||
func didPressFlipCamera(sender: UIButton) {
|
||||
@objc func didPressFlipCamera(sender: UIButton) {
|
||||
// toggle value
|
||||
sender.isSelected = !sender.isSelected
|
||||
|
||||
|
@ -889,7 +889,7 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver,
|
|||
/**
|
||||
* Denies an incoming not-yet-connected call, Do not confuse with `didPressHangup`.
|
||||
*/
|
||||
func didPressDeclineCall(sender: UIButton) {
|
||||
@objc func didPressDeclineCall(sender: UIButton) {
|
||||
Logger.info("\(TAG) called \(#function)")
|
||||
|
||||
callUIAdapter.declineCall(call)
|
||||
|
@ -897,7 +897,7 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver,
|
|||
dismissIfPossible(shouldDelay: false)
|
||||
}
|
||||
|
||||
func didPressShowCallSettings(sender: UIButton) {
|
||||
@objc func didPressShowCallSettings(sender: UIButton) {
|
||||
Logger.info("\(TAG) called \(#function)")
|
||||
|
||||
markSettingsNagAsComplete()
|
||||
|
@ -916,7 +916,7 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver,
|
|||
})
|
||||
}
|
||||
|
||||
func didPressDismissNag(sender: UIButton) {
|
||||
@objc func didPressDismissNag(sender: UIButton) {
|
||||
Logger.info("\(TAG) called \(#function)")
|
||||
|
||||
markSettingsNagAsComplete()
|
||||
|
@ -939,7 +939,7 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver,
|
|||
preferences.setIsCallKitPrivacyEnabled(preferences.isCallKitPrivacyEnabled())
|
||||
}
|
||||
|
||||
func didTapLeaveCall(sender: UIButton) {
|
||||
@objc func didTapLeaveCall(sender: UIButton) {
|
||||
OWSWindowManager.shared().leaveCallView()
|
||||
}
|
||||
|
||||
|
|
|
@ -15,10 +15,12 @@ public protocol ContactShareViewHelperDelegate: class {
|
|||
@objc
|
||||
public class ContactShareViewHelper: NSObject, CNContactViewControllerDelegate {
|
||||
|
||||
@objc
|
||||
weak var delegate: ContactShareViewHelperDelegate?
|
||||
|
||||
let contactsManager: OWSContactsManager
|
||||
|
||||
@objc
|
||||
public required init(contactsManager: OWSContactsManager) {
|
||||
SwiftAssertIsOnMainThread(#function)
|
||||
|
||||
|
@ -89,6 +91,7 @@ public class ContactShareViewHelper: NSObject, CNContactViewControllerDelegate {
|
|||
inviteFlow.sendSMSTo(phoneNumbers: phoneNumbers)
|
||||
}
|
||||
|
||||
@objc
|
||||
func showAddToContacts(contactShare: ContactShareViewModel, fromViewController: UIViewController) {
|
||||
Logger.info("\(logTag) \(#function)")
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@ class ContactViewController: OWSViewController, ContactShareViewHelperDelegate {
|
|||
fatalError("Unimplemented")
|
||||
}
|
||||
|
||||
@objc
|
||||
required init(contactShare: ContactShareViewModel) {
|
||||
contactsManager = Environment.current().contactsManager
|
||||
self.contactShare = contactShare
|
||||
|
@ -214,7 +215,7 @@ class ContactViewController: OWSViewController, ContactShareViewHelperDelegate {
|
|||
|
||||
// Back Button
|
||||
let backButtonSize = CGFloat(50)
|
||||
let backButton = TappableView(actionBlock: { [weak self] _ in
|
||||
let backButton = TappableView(actionBlock: { [weak self] in
|
||||
guard let strongSelf = self else { return }
|
||||
strongSelf.didPressDismiss()
|
||||
})
|
||||
|
@ -280,21 +281,21 @@ class ContactViewController: OWSViewController, ContactShareViewHelperDelegate {
|
|||
stackView.addArrangedSubview(createCircleActionButton(text: NSLocalizedString("ACTION_SEND_MESSAGE",
|
||||
comment: "Label for 'sent message' button in contact view."),
|
||||
imageName: "contact_view_message",
|
||||
actionBlock: { [weak self] _ in
|
||||
actionBlock: { [weak self] in
|
||||
guard let strongSelf = self else { return }
|
||||
strongSelf.didPressSendMessage()
|
||||
}))
|
||||
stackView.addArrangedSubview(createCircleActionButton(text: NSLocalizedString("ACTION_AUDIO_CALL",
|
||||
comment: "Label for 'audio call' button in contact view."),
|
||||
imageName: "contact_view_audio_call",
|
||||
actionBlock: { [weak self] _ in
|
||||
actionBlock: { [weak self] in
|
||||
guard let strongSelf = self else { return }
|
||||
strongSelf.didPressAudioCall()
|
||||
}))
|
||||
stackView.addArrangedSubview(createCircleActionButton(text: NSLocalizedString("ACTION_VIDEO_CALL",
|
||||
comment: "Label for 'video call' button in contact view."),
|
||||
imageName: "contact_view_video_call",
|
||||
actionBlock: { [weak self] _ in
|
||||
actionBlock: { [weak self] in
|
||||
guard let strongSelf = self else { return }
|
||||
strongSelf.didPressVideoCall()
|
||||
}))
|
||||
|
@ -307,7 +308,7 @@ class ContactViewController: OWSViewController, ContactShareViewHelperDelegate {
|
|||
// Show invite button for system contacts without a Signal account.
|
||||
let inviteButton = createLargePillButton(text: NSLocalizedString("ACTION_INVITE",
|
||||
comment: "Label for 'invite' button in contact view."),
|
||||
actionBlock: { [weak self] _ in
|
||||
actionBlock: { [weak self] in
|
||||
guard let strongSelf = self else { return }
|
||||
strongSelf.didPressInvite()
|
||||
})
|
||||
|
@ -334,7 +335,7 @@ class ContactViewController: OWSViewController, ContactShareViewHelperDelegate {
|
|||
// Always show "add to contacts" button.
|
||||
let addToContactsButton = createLargePillButton(text: NSLocalizedString("CONVERSATION_VIEW_ADD_TO_CONTACTS_OFFER",
|
||||
comment: "Message shown in conversation view that offers to add an unknown user to your phone's contacts."),
|
||||
actionBlock: { [weak self] _ in
|
||||
actionBlock: { [weak self] in
|
||||
guard let strongSelf = self else { return }
|
||||
strongSelf.didPressAddToContacts()
|
||||
})
|
||||
|
@ -373,7 +374,7 @@ class ContactViewController: OWSViewController, ContactShareViewHelperDelegate {
|
|||
for phoneNumber in contactShare.phoneNumbers {
|
||||
rows.append(ContactFieldView.contactFieldView(forPhoneNumber: phoneNumber,
|
||||
layoutMargins: UIEdgeInsets(top: 5, left: hMargin, bottom: 5, right: hMargin),
|
||||
actionBlock: { [weak self] _ in
|
||||
actionBlock: { [weak self] in
|
||||
guard let strongSelf = self else { return }
|
||||
strongSelf.didPressPhoneNumber(phoneNumber: phoneNumber)
|
||||
}))
|
||||
|
@ -382,7 +383,7 @@ class ContactViewController: OWSViewController, ContactShareViewHelperDelegate {
|
|||
for email in contactShare.emails {
|
||||
rows.append(ContactFieldView.contactFieldView(forEmail: email,
|
||||
layoutMargins: UIEdgeInsets(top: 5, left: hMargin, bottom: 5, right: hMargin),
|
||||
actionBlock: { [weak self] _ in
|
||||
actionBlock: { [weak self] in
|
||||
guard let strongSelf = self else { return }
|
||||
strongSelf.didPressEmail(email: email)
|
||||
}))
|
||||
|
@ -391,7 +392,7 @@ class ContactViewController: OWSViewController, ContactShareViewHelperDelegate {
|
|||
for address in contactShare.addresses {
|
||||
rows.append(ContactFieldView.contactFieldView(forAddress: address,
|
||||
layoutMargins: UIEdgeInsets(top: 5, left: hMargin, bottom: 5, right: hMargin),
|
||||
actionBlock: { [weak self] _ in
|
||||
actionBlock: { [weak self] in
|
||||
guard let strongSelf = self else { return }
|
||||
strongSelf.didPressAddress(address: address)
|
||||
}))
|
||||
|
|
|
@ -59,6 +59,11 @@ public class ContactsPicker: OWSViewController, UITableViewDelegate, UITableView
|
|||
}
|
||||
|
||||
private let collation = UILocalizedIndexedCollation.current()
|
||||
public var collationForTests: UILocalizedIndexedCollation {
|
||||
get {
|
||||
return collation
|
||||
}
|
||||
}
|
||||
private let contactStore = CNContactStore()
|
||||
|
||||
// Data Source State
|
||||
|
@ -67,6 +72,7 @@ public class ContactsPicker: OWSViewController, UITableViewDelegate, UITableView
|
|||
private lazy var selectedContacts = [Contact]()
|
||||
|
||||
// Configuration
|
||||
@objc
|
||||
public weak var contactsPickerDelegate: ContactsPickerDelegate?
|
||||
private let subtitleCellType: SubtitleCellValue
|
||||
private let allowsMultipleSelection: Bool
|
||||
|
@ -300,11 +306,11 @@ public class ContactsPicker: OWSViewController, UITableViewDelegate, UITableView
|
|||
|
||||
// MARK: - Button Actions
|
||||
|
||||
func onTouchCancelButton() {
|
||||
@objc func onTouchCancelButton() {
|
||||
contactsPickerDelegate?.contactsPickerDidCancel(self)
|
||||
}
|
||||
|
||||
func onTouchDoneButton() {
|
||||
@objc func onTouchDoneButton() {
|
||||
contactsPickerDelegate?.contactsPicker(self, didSelectMultipleContacts: selectedContacts)
|
||||
}
|
||||
|
||||
|
|
|
@ -12,8 +12,10 @@ public protocol ConversationHeaderViewDelegate {
|
|||
@objc
|
||||
public class ConversationHeaderView: UIStackView {
|
||||
|
||||
@objc
|
||||
public weak var delegate: ConversationHeaderViewDelegate?
|
||||
|
||||
@objc
|
||||
public var attributedTitle: NSAttributedString? {
|
||||
get {
|
||||
return self.titleLabel.attributedText
|
||||
|
@ -23,6 +25,7 @@ public class ConversationHeaderView: UIStackView {
|
|||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
public var attributedSubtitle: NSAttributedString? {
|
||||
get {
|
||||
return self.subtitleLabel.attributedText
|
||||
|
@ -41,14 +44,18 @@ public class ConversationHeaderView: UIStackView {
|
|||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
public let titlePrimaryFont: UIFont = UIFont.ows_boldFont(withSize: 17)
|
||||
@objc
|
||||
public let titleSecondaryFont: UIFont = UIFont.ows_regularFont(withSize: 9)
|
||||
|
||||
@objc
|
||||
public let subtitleFont: UIFont = UIFont.ows_regularFont(withSize: 12)
|
||||
|
||||
private let titleLabel: UILabel
|
||||
private let subtitleLabel: UILabel
|
||||
private let avatarView: AvatarImageView
|
||||
|
||||
@objc
|
||||
public required init(thread: TSThread, contactsManager: OWSContactsManager) {
|
||||
|
||||
let avatarView = ConversationAvatarImageView(thread: thread, diameter: 36, contactsManager: contactsManager)
|
||||
|
@ -110,7 +117,7 @@ public class ConversationHeaderView: UIStackView {
|
|||
|
||||
// MARK: Delegate Methods
|
||||
|
||||
func didTapView(tapGesture: UITapGestureRecognizer) {
|
||||
@objc func didTapView(tapGesture: UITapGestureRecognizer) {
|
||||
guard tapGesture.state == .recognized else {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
@ -52,7 +52,7 @@ class OWSLayerView: UIView {
|
|||
// region b) the rectangle at which the src image should be rendered
|
||||
// given a dst view or output context that will yield the
|
||||
// appropriate cropping.
|
||||
class CropScaleImageViewController: OWSViewController {
|
||||
@objc class CropScaleImageViewController: OWSViewController {
|
||||
|
||||
let TAG = "[CropScaleImageViewController]"
|
||||
|
||||
|
@ -71,7 +71,7 @@ class CropScaleImageViewController: OWSViewController {
|
|||
//
|
||||
// TODO: We could make this a parameter.
|
||||
var dstSizePixels: CGSize {
|
||||
return CGSize(width:210, height:210)
|
||||
return CGSize(width: 210, height: 210)
|
||||
}
|
||||
var dstAspectRatio: CGFloat {
|
||||
return dstSizePixels.width / dstSizePixels.height
|
||||
|
@ -107,7 +107,7 @@ class CropScaleImageViewController: OWSViewController {
|
|||
fatalError("\(#function) is unimplemented.")
|
||||
}
|
||||
|
||||
required init(srcImage: UIImage, successCompletion : @escaping (UIImage) -> Void) {
|
||||
@objc required init(srcImage: UIImage, successCompletion : @escaping (UIImage) -> Void) {
|
||||
// normalized() can be slightly expensive but in practice this is fine.
|
||||
self.srcImage = srcImage.normalized()
|
||||
self.successCompletion = successCompletion
|
||||
|
@ -136,13 +136,13 @@ class CropScaleImageViewController: OWSViewController {
|
|||
|
||||
// The "default" (no scaling, no translation) crop frame, expressed in
|
||||
// srcImage's coordinate system.
|
||||
srcDefaultCropSizePoints = defaultCropSizePoints(dstSizePoints:unitSquareSize)
|
||||
srcDefaultCropSizePoints = defaultCropSizePoints(dstSizePoints: unitSquareSize)
|
||||
assert(srcImageSizePoints.width >= srcDefaultCropSizePoints.width)
|
||||
assert(srcImageSizePoints.height >= srcDefaultCropSizePoints.height)
|
||||
|
||||
// By default, center the crop region in the src image.
|
||||
srcTranslation = CGPoint(x:(srcImageSizePoints.width - srcDefaultCropSizePoints.width) * 0.5,
|
||||
y:(srcImageSizePoints.height - srcDefaultCropSizePoints.height) * 0.5)
|
||||
srcTranslation = CGPoint(x: (srcImageSizePoints.width - srcDefaultCropSizePoints.width) * 0.5,
|
||||
y: (srcImageSizePoints.height - srcDefaultCropSizePoints.height) * 0.5)
|
||||
}
|
||||
|
||||
// Given a dst size, find the size of the largest crop region
|
||||
|
@ -182,7 +182,7 @@ class CropScaleImageViewController: OWSViewController {
|
|||
self.view.addSubview(contentView)
|
||||
contentView.autoPinEdgesToSuperviewEdges()
|
||||
|
||||
let imageView = OWSLayerView(frame:CGRect.zero, layoutCallback: {[weak self] _ in
|
||||
let imageView = OWSLayerView(frame: CGRect.zero, layoutCallback: { [weak self] in
|
||||
guard let strongSelf = self else { return }
|
||||
strongSelf.updateImageLayout()
|
||||
})
|
||||
|
@ -205,7 +205,7 @@ class CropScaleImageViewController: OWSViewController {
|
|||
}
|
||||
let path = UIBezierPath(rect: bounds)
|
||||
|
||||
let circleRect = strongSelf.cropFrame(forBounds:bounds)
|
||||
let circleRect = strongSelf.cropFrame(forBounds: bounds)
|
||||
let radius = circleRect.size.width * 0.5
|
||||
let circlePath = UIBezierPath(roundedRect: circleRect, cornerRadius: radius)
|
||||
|
||||
|
@ -222,13 +222,13 @@ class CropScaleImageViewController: OWSViewController {
|
|||
let titleLabel = UILabel()
|
||||
titleLabel.textColor = UIColor.white
|
||||
titleLabel.textAlignment = .center
|
||||
titleLabel.font = UIFont.ows_mediumFont(withSize:ScaleFromIPhone5(16))
|
||||
titleLabel.font = UIFont.ows_mediumFont(withSize: ScaleFromIPhone5(16))
|
||||
titleLabel.text = NSLocalizedString("CROP_SCALE_IMAGE_VIEW_TITLE",
|
||||
comment: "Title for the 'crop/scale image' dialog.")
|
||||
contentView.addSubview(titleLabel)
|
||||
titleLabel.autoPinWidthToSuperview()
|
||||
let titleLabelMargin = ScaleFromIPhone5(16)
|
||||
titleLabel.autoPin(toTopLayoutGuideOf:self, withInset:titleLabelMargin)
|
||||
titleLabel.autoPin(toTopLayoutGuideOf: self, withInset: titleLabelMargin)
|
||||
|
||||
createButtonRow(contentView: contentView)
|
||||
|
||||
|
@ -286,7 +286,7 @@ class CropScaleImageViewController: OWSViewController {
|
|||
assert(defaultCropOriginPoints.y >= 0)
|
||||
assert(defaultCropOriginPoints.x <= imageSizePoints.width - defaultCropSizePoints.width)
|
||||
assert(defaultCropOriginPoints.y <= imageSizePoints.height - defaultCropSizePoints.height)
|
||||
return CGRect(origin:defaultCropOriginPoints, size:defaultCropSizePoints)
|
||||
return CGRect(origin: defaultCropOriginPoints, size: defaultCropSizePoints)
|
||||
}
|
||||
|
||||
// Updates the image view _AND_ normalizes the current scale/translate state.
|
||||
|
@ -308,19 +308,19 @@ class CropScaleImageViewController: OWSViewController {
|
|||
return
|
||||
}
|
||||
// The frame of the crop circle within the image view.
|
||||
let cropFrame = self.cropFrame(forBounds:CGRect(origin:CGPoint.zero, size: imageViewSizePoints))
|
||||
let cropFrame = self.cropFrame(forBounds: CGRect(origin: CGPoint.zero, size: imageViewSizePoints))
|
||||
|
||||
// Normalize the scaling property.
|
||||
imageScale = max(kMinImageScale, min(kMaxImageScale, imageScale))
|
||||
|
||||
let srcCropSizePoints = CGSize(width:srcDefaultCropSizePoints.width / imageScale,
|
||||
height:srcDefaultCropSizePoints.height / imageScale)
|
||||
let srcCropSizePoints = CGSize(width: srcDefaultCropSizePoints.width / imageScale,
|
||||
height: srcDefaultCropSizePoints.height / imageScale)
|
||||
|
||||
let minSrcTranslationPoints = CGPoint.zero
|
||||
|
||||
// Prevent panning outside of image area.
|
||||
let maxSrcTranslationPoints = CGPoint(x:srcImageSizePoints.width - srcCropSizePoints.width,
|
||||
y:srcImageSizePoints.height - srcCropSizePoints.height
|
||||
let maxSrcTranslationPoints = CGPoint(x: srcImageSizePoints.width - srcCropSizePoints.width,
|
||||
y: srcImageSizePoints.height - srcCropSizePoints.height
|
||||
)
|
||||
|
||||
// Normalize the translation property
|
||||
|
@ -352,15 +352,15 @@ class CropScaleImageViewController: OWSViewController {
|
|||
// output will be WYSIWYG with the view state.
|
||||
private func imageRenderRect(forDstSize dstSize: CGSize) -> CGRect {
|
||||
|
||||
let srcCropSizePoints = CGSize(width:srcDefaultCropSizePoints.width / imageScale,
|
||||
height:srcDefaultCropSizePoints.height / imageScale)
|
||||
let srcCropSizePoints = CGSize(width: srcDefaultCropSizePoints.width / imageScale,
|
||||
height: srcDefaultCropSizePoints.height / imageScale)
|
||||
|
||||
let srcToViewRatio = dstSize.width / srcCropSizePoints.width
|
||||
|
||||
return CGRect(origin: CGPoint(x:srcTranslation.x * -srcToViewRatio,
|
||||
y:srcTranslation.y * -srcToViewRatio),
|
||||
size: CGSize(width:srcImageSizePoints.width * +srcToViewRatio,
|
||||
height:srcImageSizePoints.height * +srcToViewRatio
|
||||
return CGRect(origin: CGPoint(x: srcTranslation.x * -srcToViewRatio,
|
||||
y: srcTranslation.y * -srcToViewRatio),
|
||||
size: CGSize(width: srcImageSizePoints.width * +srcToViewRatio,
|
||||
height: srcImageSizePoints.height * +srcToViewRatio
|
||||
))
|
||||
}
|
||||
|
||||
|
@ -369,7 +369,7 @@ class CropScaleImageViewController: OWSViewController {
|
|||
var lastPinchLocation: CGPoint = CGPoint.zero
|
||||
var lastPinchScale: CGFloat = 1.0
|
||||
|
||||
func handlePinch(sender: UIPinchGestureRecognizer) {
|
||||
@objc func handlePinch(sender: UIPinchGestureRecognizer) {
|
||||
switch (sender.state) {
|
||||
case .possible:
|
||||
break
|
||||
|
@ -388,11 +388,11 @@ class CropScaleImageViewController: OWSViewController {
|
|||
let scaleDiff = sender.scale / lastPinchScale
|
||||
|
||||
// Update scaling.
|
||||
let srcCropSizeBeforeScalePoints = CGSize(width:srcDefaultCropSizePoints.width / imageScale,
|
||||
height:srcDefaultCropSizePoints.height / imageScale)
|
||||
let srcCropSizeBeforeScalePoints = CGSize(width: srcDefaultCropSizePoints.width / imageScale,
|
||||
height: srcDefaultCropSizePoints.height / imageScale)
|
||||
imageScale = max(kMinImageScale, min(kMaxImageScale, imageScale * scaleDiff))
|
||||
let srcCropSizeAfterScalePoints = CGSize(width:srcDefaultCropSizePoints.width / imageScale,
|
||||
height:srcDefaultCropSizePoints.height / imageScale)
|
||||
let srcCropSizeAfterScalePoints = CGSize(width: srcDefaultCropSizePoints.width / imageScale,
|
||||
height: srcDefaultCropSizePoints.height / imageScale)
|
||||
// Since the translation state reflects the "upper left" corner of the crop region, we need to
|
||||
// adjust the translation when scaling to preserve the "center" of the crop region.
|
||||
srcTranslation.x += (srcCropSizeBeforeScalePoints.width - srcCropSizeAfterScalePoints.width) * 0.5
|
||||
|
@ -400,16 +400,16 @@ class CropScaleImageViewController: OWSViewController {
|
|||
|
||||
// Update translation.
|
||||
let viewSizePoints = imageView.frame.size
|
||||
let srcCropSizePoints = CGSize(width:srcDefaultCropSizePoints.width / imageScale,
|
||||
height:srcDefaultCropSizePoints.height / imageScale)
|
||||
let srcCropSizePoints = CGSize(width: srcDefaultCropSizePoints.width / imageScale,
|
||||
height: srcDefaultCropSizePoints.height / imageScale)
|
||||
|
||||
let viewToSrcRatio = srcCropSizePoints.width / viewSizePoints.width
|
||||
|
||||
let gestureTranslation = CGPoint(x:location.x - lastPinchLocation.x,
|
||||
y:location.y - lastPinchLocation.y)
|
||||
let gestureTranslation = CGPoint(x: location.x - lastPinchLocation.x,
|
||||
y: location.y - lastPinchLocation.y)
|
||||
|
||||
srcTranslation = CGPoint(x:srcTranslation.x + gestureTranslation.x * -viewToSrcRatio,
|
||||
y:srcTranslation.y + gestureTranslation.y * -viewToSrcRatio)
|
||||
srcTranslation = CGPoint(x: srcTranslation.x + gestureTranslation.x * -viewToSrcRatio,
|
||||
y: srcTranslation.y + gestureTranslation.y * -viewToSrcRatio)
|
||||
|
||||
lastPinchLocation = location
|
||||
lastPinchScale = sender.scale
|
||||
|
@ -426,7 +426,7 @@ class CropScaleImageViewController: OWSViewController {
|
|||
|
||||
var srcTranslationAtPanStart: CGPoint = CGPoint.zero
|
||||
|
||||
func handlePan(sender: UIPanGestureRecognizer) {
|
||||
@objc func handlePan(sender: UIPanGestureRecognizer) {
|
||||
switch (sender.state) {
|
||||
case .possible:
|
||||
break
|
||||
|
@ -435,8 +435,8 @@ class CropScaleImageViewController: OWSViewController {
|
|||
break
|
||||
case .changed, .ended:
|
||||
let viewSizePoints = imageView.frame.size
|
||||
let srcCropSizePoints = CGSize(width:srcDefaultCropSizePoints.width / imageScale,
|
||||
height:srcDefaultCropSizePoints.height / imageScale)
|
||||
let srcCropSizePoints = CGSize(width: srcDefaultCropSizePoints.width / imageScale,
|
||||
height: srcDefaultCropSizePoints.height / imageScale)
|
||||
|
||||
let viewToSrcRatio = srcCropSizePoints.width / viewSizePoints.width
|
||||
|
||||
|
@ -444,8 +444,8 @@ class CropScaleImageViewController: OWSViewController {
|
|||
sender.translation(in: sender.view)
|
||||
|
||||
// Update translation.
|
||||
srcTranslation = CGPoint(x:srcTranslationAtPanStart.x + gestureTranslation.x * -viewToSrcRatio,
|
||||
y:srcTranslationAtPanStart.y + gestureTranslation.y * -viewToSrcRatio)
|
||||
srcTranslation = CGPoint(x: srcTranslationAtPanStart.x + gestureTranslation.x * -viewToSrcRatio,
|
||||
y: srcTranslationAtPanStart.y + gestureTranslation.y * -viewToSrcRatio)
|
||||
break
|
||||
case .cancelled, .failed:
|
||||
srcTranslation
|
||||
|
@ -463,47 +463,47 @@ class CropScaleImageViewController: OWSViewController {
|
|||
let buttonRow = UIView()
|
||||
self.view.addSubview(buttonRow)
|
||||
buttonRow.autoPinWidthToSuperview()
|
||||
buttonRow.autoPinEdge(toSuperviewEdge:.bottom, withInset:buttonBottomMargin)
|
||||
buttonRow.autoPinEdge(.top, to:.bottom, of:contentView, withOffset:buttonTopMargin)
|
||||
buttonRow.autoPinEdge(toSuperviewEdge: .bottom, withInset: buttonBottomMargin)
|
||||
buttonRow.autoPinEdge(.top, to: .bottom, of: contentView, withOffset: buttonTopMargin)
|
||||
|
||||
let cancelButton = createButton(title: CommonStrings.cancelButton,
|
||||
action: #selector(cancelPressed))
|
||||
buttonRow.addSubview(cancelButton)
|
||||
cancelButton.autoPinEdge(toSuperviewEdge:.top)
|
||||
cancelButton.autoPinEdge(toSuperviewEdge:.bottom)
|
||||
cancelButton.autoPinEdge(toSuperviewEdge: .top)
|
||||
cancelButton.autoPinEdge(toSuperviewEdge: .bottom)
|
||||
cancelButton.autoPinEdge(toSuperviewEdge: .left)
|
||||
|
||||
let doneButton = createButton(title: NSLocalizedString("BUTTON_DONE",
|
||||
comment: "Label for generic done button."),
|
||||
action: #selector(donePressed))
|
||||
buttonRow.addSubview(doneButton)
|
||||
doneButton.autoPinEdge(toSuperviewEdge:.top)
|
||||
doneButton.autoPinEdge(toSuperviewEdge:.bottom)
|
||||
doneButton.autoPinEdge(toSuperviewEdge: .top)
|
||||
doneButton.autoPinEdge(toSuperviewEdge: .bottom)
|
||||
doneButton.autoPinEdge(toSuperviewEdge: .right)
|
||||
}
|
||||
|
||||
private func createButton(title: String, action: Selector) -> UIButton {
|
||||
let buttonFont = UIFont.ows_mediumFont(withSize:ScaleFromIPhone5To7Plus(18, 22))
|
||||
let buttonFont = UIFont.ows_mediumFont(withSize: ScaleFromIPhone5To7Plus(18, 22))
|
||||
let buttonWidth = ScaleFromIPhone5To7Plus(110, 140)
|
||||
let buttonHeight = ScaleFromIPhone5To7Plus(35, 45)
|
||||
|
||||
let button = UIButton()
|
||||
button.setTitle(title, for:.normal)
|
||||
button.setTitleColor(UIColor.white, for:.normal)
|
||||
button.setTitle(title, for: .normal)
|
||||
button.setTitleColor(UIColor.white, for: .normal)
|
||||
button.titleLabel!.font = buttonFont
|
||||
button.addTarget(self, action:action, for:.touchUpInside)
|
||||
button.autoSetDimension(.width, toSize:buttonWidth)
|
||||
button.autoSetDimension(.height, toSize:buttonHeight)
|
||||
button.addTarget(self, action: action, for: .touchUpInside)
|
||||
button.autoSetDimension(.width, toSize: buttonWidth)
|
||||
button.autoSetDimension(.height, toSize: buttonHeight)
|
||||
return button
|
||||
}
|
||||
|
||||
// MARK: - Event Handlers
|
||||
|
||||
func cancelPressed(sender: UIButton) {
|
||||
dismiss(animated: true, completion:nil)
|
||||
@objc func cancelPressed(sender: UIButton) {
|
||||
dismiss(animated: true, completion: nil)
|
||||
}
|
||||
|
||||
func donePressed(sender: UIButton) {
|
||||
@objc func donePressed(sender: UIButton) {
|
||||
let successCompletion = self.successCompletion
|
||||
dismiss(animated: true, completion: {
|
||||
guard let dstImage = self.generateDstImage() else {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
class DebugUIFileBrowser: OWSTableViewController {
|
||||
@objc class DebugUIFileBrowser: OWSTableViewController {
|
||||
|
||||
// MARK: Dependencies
|
||||
var fileManager: FileManager {
|
||||
|
@ -12,7 +12,7 @@ class DebugUIFileBrowser: OWSTableViewController {
|
|||
// MARK: Overrides
|
||||
let fileURL: URL
|
||||
|
||||
init(fileURL: URL) {
|
||||
@objc init(fileURL: URL) {
|
||||
self.fileURL = fileURL
|
||||
|
||||
super.init(nibName: nil, bundle: nil)
|
||||
|
@ -125,7 +125,7 @@ class DebugUIFileBrowser: OWSTableViewController {
|
|||
preferredStyle: .alert)
|
||||
|
||||
alert.addAction(OWSAlerts.cancelAction)
|
||||
alert.addAction(UIAlertAction(title:"Rename \(strongSelf.fileURL.lastPathComponent)", style:.default) { _ in
|
||||
alert.addAction(UIAlertAction(title: "Rename \(strongSelf.fileURL.lastPathComponent)", style: .default) { _ in
|
||||
guard let textField = alert.textFields?.first else {
|
||||
owsFail("missing text field")
|
||||
return
|
||||
|
@ -170,7 +170,7 @@ class DebugUIFileBrowser: OWSTableViewController {
|
|||
preferredStyle: .alert)
|
||||
|
||||
alert.addAction(OWSAlerts.cancelAction)
|
||||
alert.addAction(UIAlertAction(title:"Moving \(filename)", style:.default) { _ in
|
||||
alert.addAction(UIAlertAction(title: "Moving \(filename)", style: .default) { _ in
|
||||
guard let textField = alert.textFields?.first else {
|
||||
owsFail("missing text field")
|
||||
return
|
||||
|
@ -259,7 +259,7 @@ class DebugUIFileBrowser: OWSTableViewController {
|
|||
|
||||
let protections: [FileProtectionType] = [.none, .complete, .completeUnlessOpen, .completeUntilFirstUserAuthentication]
|
||||
protections.forEach { (protection: FileProtectionType) in
|
||||
actionSheet.addAction(UIAlertAction(title: "\(protection.rawValue.replacingOccurrences(of:"NSFile", with: ""))", style: .default) { (_: UIAlertAction) in
|
||||
actionSheet.addAction(UIAlertAction(title: "\(protection.rawValue.replacingOccurrences(of: "NSFile", with: ""))", style: .default) { (_: UIAlertAction) in
|
||||
Logger.debug("\(strongSelf.logTag) chose protection: \(protection) for file: \(fileURL)")
|
||||
let fileAttributes: [FileAttributeKey: Any] = [.protectionKey: protection]
|
||||
do {
|
||||
|
@ -288,7 +288,7 @@ class DebugUIFileBrowser: OWSTableViewController {
|
|||
preferredStyle: .alert)
|
||||
|
||||
alert.addAction(OWSAlerts.cancelAction)
|
||||
alert.addAction(UIAlertAction(title:"Create", style:.default) { _ in
|
||||
alert.addAction(UIAlertAction(title: "Create", style: .default) { _ in
|
||||
guard let textField = alert.textFields?.first else {
|
||||
owsFail("missing text field")
|
||||
return
|
||||
|
@ -326,7 +326,7 @@ class DebugUIFileBrowser: OWSTableViewController {
|
|||
preferredStyle: .alert)
|
||||
|
||||
alert.addAction(OWSAlerts.cancelAction)
|
||||
alert.addAction(UIAlertAction(title:"Create", style:.default) { _ in
|
||||
alert.addAction(UIAlertAction(title: "Create", style: .default) { _ in
|
||||
guard let textField = alert.textFields?.first else {
|
||||
owsFail("missing text field")
|
||||
return
|
||||
|
|
|
@ -103,7 +103,7 @@ private class IntroducingCustomNotificationAudioExperienceUpgradeViewController:
|
|||
return button
|
||||
}
|
||||
|
||||
func didTapButton(sender: UIButton) {
|
||||
@objc func didTapButton(sender: UIButton) {
|
||||
Logger.debug("\(TAG) in \(#function)")
|
||||
|
||||
guard let buttonAction = self.buttonAction else {
|
||||
|
@ -213,7 +213,7 @@ private class IntroductingReadReceiptsExperienceUpgradeViewController: Experienc
|
|||
return button
|
||||
}
|
||||
|
||||
func didTapButton(sender: UIButton) {
|
||||
@objc func didTapButton(sender: UIButton) {
|
||||
Logger.debug("\(TAG) in \(#function)")
|
||||
|
||||
guard let buttonAction = self.buttonAction else {
|
||||
|
@ -343,7 +343,7 @@ private class IntroductingProfilesExperienceUpgradeViewController: ExperienceUpg
|
|||
|
||||
// MARK: - Actions
|
||||
|
||||
func didTapButton(sender: UIButton) {
|
||||
@objc func didTapButton(sender: UIButton) {
|
||||
Logger.debug("\(TAG) in \(#function)")
|
||||
|
||||
// dismiss the modally presented view controller, then proceed.
|
||||
|
@ -382,7 +382,7 @@ private class CallKitExperienceUpgradeViewController: ExperienceUpgradeViewContr
|
|||
|
||||
// MARK: - Actions
|
||||
|
||||
func didTapPrivacySettingsButton(sender: UIButton) {
|
||||
@objc func didTapPrivacySettingsButton(sender: UIButton) {
|
||||
Logger.debug("\(TAG) in \(#function)")
|
||||
|
||||
// dismiss the modally presented view controller, then proceed.
|
||||
|
@ -480,7 +480,8 @@ func setPageControlAppearance() {
|
|||
pageControl.currentPageIndicatorTintColor = UIColor.ows_materialBlue
|
||||
}
|
||||
|
||||
class ExperienceUpgradesPageViewController: OWSViewController, UIPageViewControllerDataSource {
|
||||
@objc
|
||||
public class ExperienceUpgradesPageViewController: OWSViewController, UIPageViewControllerDataSource {
|
||||
|
||||
let TAG = "[ExperienceUpgradeViewController]"
|
||||
|
||||
|
@ -494,7 +495,8 @@ class ExperienceUpgradesPageViewController: OWSViewController, UIPageViewControl
|
|||
|
||||
// MARK: - Initializers
|
||||
|
||||
required init(experienceUpgrades: [ExperienceUpgrade]) {
|
||||
@objc
|
||||
public required init(experienceUpgrades: [ExperienceUpgrade]) {
|
||||
self.experienceUpgrades = experienceUpgrades
|
||||
|
||||
setPageControlAppearance()
|
||||
|
@ -507,13 +509,14 @@ class ExperienceUpgradesPageViewController: OWSViewController, UIPageViewControl
|
|||
}
|
||||
|
||||
@available(*, unavailable, message:"unavailable, use initWithExperienceUpgrade instead")
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
@objc
|
||||
public required init?(coder aDecoder: NSCoder) {
|
||||
fatalError("unimplemented")
|
||||
}
|
||||
|
||||
// MARK: - View lifecycle
|
||||
|
||||
override func viewDidLoad() {
|
||||
@objc public override func viewDidLoad() {
|
||||
guard let firstViewController = allViewControllers.first else {
|
||||
owsFail("\(TAG) no pages to show.")
|
||||
dismiss(animated: true)
|
||||
|
@ -524,7 +527,7 @@ class ExperienceUpgradesPageViewController: OWSViewController, UIPageViewControl
|
|||
self.pageViewController.setViewControllers([ firstViewController ], direction: .forward, animated: false, completion: nil)
|
||||
}
|
||||
|
||||
override func loadView() {
|
||||
@objc public override func loadView() {
|
||||
self.view = UIView.container()
|
||||
view.backgroundColor = UIColor.white
|
||||
|
||||
|
@ -677,7 +680,7 @@ class ExperienceUpgradesPageViewController: OWSViewController, UIPageViewControl
|
|||
allViewControllers.append(viewController)
|
||||
}
|
||||
|
||||
override func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) {
|
||||
@objc public override func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) {
|
||||
// Blocking write before dismiss, to be sure they're marked as complete
|
||||
// before HomeView.didAppear is re-fired.
|
||||
self.editingDBConnection.readWrite { transaction in
|
||||
|
@ -687,12 +690,12 @@ class ExperienceUpgradesPageViewController: OWSViewController, UIPageViewControl
|
|||
super.dismiss(animated: flag, completion: completion)
|
||||
}
|
||||
|
||||
func didTapDismissButton(sender: UIButton) {
|
||||
@objc func didTapDismissButton(sender: UIButton) {
|
||||
Logger.debug("\(TAG) in \(#function)")
|
||||
self.dismiss(animated: true)
|
||||
}
|
||||
|
||||
func handleDismissGesture(sender: AnyObject) {
|
||||
@objc func handleDismissGesture(sender: AnyObject) {
|
||||
Logger.debug("\(TAG) in \(#function)")
|
||||
self.dismiss(animated: true)
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ class GifPickerViewController: OWSViewController, UISearchBarDelegate, UICollect
|
|||
|
||||
var lastQuery: String = ""
|
||||
|
||||
@objc
|
||||
public weak var delegate: GifPickerViewControllerDelegate?
|
||||
|
||||
let thread: TSThread
|
||||
|
@ -60,6 +61,7 @@ class GifPickerViewController: OWSViewController, UISearchBarDelegate, UICollect
|
|||
fatalError("\(#function) is unimplemented.")
|
||||
}
|
||||
|
||||
@objc
|
||||
required init(thread: TSThread, messageSender: MessageSender) {
|
||||
self.thread = thread
|
||||
self.messageSender = messageSender
|
||||
|
@ -79,7 +81,7 @@ class GifPickerViewController: OWSViewController, UISearchBarDelegate, UICollect
|
|||
progressiveSearchTimer?.invalidate()
|
||||
}
|
||||
|
||||
func didBecomeActive() {
|
||||
@objc func didBecomeActive() {
|
||||
SwiftAssertIsOnMainThread(#function)
|
||||
|
||||
Logger.info("\(self.TAG) \(#function)")
|
||||
|
@ -88,7 +90,7 @@ class GifPickerViewController: OWSViewController, UISearchBarDelegate, UICollect
|
|||
ensureCellState()
|
||||
}
|
||||
|
||||
func reachabilityChanged() {
|
||||
@objc func reachabilityChanged() {
|
||||
SwiftAssertIsOnMainThread(#function)
|
||||
|
||||
Logger.info("\(self.TAG) \(#function)")
|
||||
|
@ -418,7 +420,7 @@ class GifPickerViewController: OWSViewController, UISearchBarDelegate, UICollect
|
|||
|
||||
// MARK: - Event Handlers
|
||||
|
||||
func donePressed(sender: UIButton) {
|
||||
@objc func donePressed(sender: UIButton) {
|
||||
dismiss(animated: true, completion: nil)
|
||||
}
|
||||
|
||||
|
@ -505,7 +507,7 @@ class GifPickerViewController: OWSViewController, UISearchBarDelegate, UICollect
|
|||
|
||||
// MARK: - Event Handlers
|
||||
|
||||
func retryTapped(sender: UIGestureRecognizer) {
|
||||
@objc func retryTapped(sender: UIGestureRecognizer) {
|
||||
guard sender.state == .recognized else {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -19,12 +19,15 @@ class InviteFlow: NSObject, MFMessageComposeViewControllerDelegate, MFMailCompos
|
|||
let installUrl = "https://signal.org/install/"
|
||||
let homepageUrl = "https://signal.org"
|
||||
|
||||
@objc
|
||||
let actionSheetController: UIAlertController
|
||||
@objc
|
||||
let presentingViewController: UIViewController
|
||||
let contactsManager: OWSContactsManager
|
||||
|
||||
var channel: Channel?
|
||||
|
||||
@objc
|
||||
required init(presentingViewController: UIViewController, contactsManager: OWSContactsManager) {
|
||||
self.presentingViewController = presentingViewController
|
||||
self.contactsManager = contactsManager
|
||||
|
@ -165,6 +168,7 @@ class InviteFlow: NSObject, MFMessageComposeViewControllerDelegate, MFMailCompos
|
|||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
public func sendSMSTo(phoneNumbers: [String]) {
|
||||
if #available(iOS 10.0, *) {
|
||||
// iOS10 message compose view doesn't respect some system appearence attributes.
|
||||
|
|
|
@ -24,6 +24,7 @@ public class LongTextViewController: OWSViewController {
|
|||
fatalError("\(#function) is unimplemented.")
|
||||
}
|
||||
|
||||
@objc
|
||||
public required init(viewItem: ConversationViewItem) {
|
||||
self.viewItem = viewItem
|
||||
|
||||
|
@ -76,7 +77,7 @@ public class LongTextViewController: OWSViewController {
|
|||
view.addSubview(messageTextView)
|
||||
messageTextView.autoPinEdge(toSuperviewEdge: .leading)
|
||||
messageTextView.autoPinEdge(toSuperviewEdge: .trailing)
|
||||
messageTextView.textContainerInset = UIEdgeInsetsMake(0, view.layoutMargins.left, 0, view.layoutMargins.right)
|
||||
messageTextView.textContainerInset = UIEdgeInsets(top: 0, left: view.layoutMargins.left, bottom: 0, right: view.layoutMargins.right)
|
||||
messageTextView.autoPin(toTopLayoutGuideOf: self, withInset: 0)
|
||||
|
||||
let footer = UIToolbar()
|
||||
|
@ -95,7 +96,7 @@ public class LongTextViewController: OWSViewController {
|
|||
|
||||
// MARK: - Actions
|
||||
|
||||
func shareButtonPressed() {
|
||||
@objc func shareButtonPressed() {
|
||||
AttachmentSharing.showShareUI(forText: messageBody)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -203,6 +203,7 @@ class MediaGalleryViewController: OWSNavigationController, MediaGalleryDataSourc
|
|||
Logger.debug("\(logTag) deinit")
|
||||
}
|
||||
|
||||
@objc
|
||||
init(thread: TSThread, uiDatabaseConnection: YapDatabaseConnection, options: MediaGalleryOption = []) {
|
||||
self.thread = thread
|
||||
assert(uiDatabaseConnection.isInLongLivedReadTransaction())
|
||||
|
@ -277,6 +278,7 @@ class MediaGalleryViewController: OWSNavigationController, MediaGalleryDataSourc
|
|||
// TODO rename to replacingOriginRect
|
||||
private var originRect: CGRect?
|
||||
|
||||
@objc
|
||||
public func presentDetailView(fromViewController: UIViewController, mediaMessage: TSMessage, replacingView: UIView) {
|
||||
var galleryItem: MediaGalleryItem?
|
||||
uiDatabaseConnection.read { transaction in
|
||||
|
@ -397,6 +399,7 @@ class MediaGalleryViewController: OWSNavigationController, MediaGalleryDataSourc
|
|||
// e.g. the conversation settings view controller
|
||||
var fromNavController: OWSNavigationController?
|
||||
|
||||
@objc
|
||||
func pushTileView(fromNavController: OWSNavigationController) {
|
||||
var mostRecentItem: MediaGalleryItem?
|
||||
self.uiDatabaseConnection.read { transaction in
|
||||
|
|
|
@ -13,6 +13,7 @@ public class GalleryItemBox: NSObject {
|
|||
self.value = value
|
||||
}
|
||||
|
||||
@objc
|
||||
public var attachmentStream: TSAttachmentStream {
|
||||
return value.attachmentStream
|
||||
}
|
||||
|
|
|
@ -49,6 +49,7 @@ class MessageDetailViewController: OWSViewController, MediaGalleryDataSourceDele
|
|||
fatalError("\(#function) is unimplemented.")
|
||||
}
|
||||
|
||||
@objc
|
||||
required init(viewItem: ConversationViewItem, message: TSMessage, mode: MessageMetadataViewMode) {
|
||||
self.contactsManager = Environment.current().contactsManager
|
||||
self.viewItem = viewItem
|
||||
|
@ -496,7 +497,7 @@ class MessageDetailViewController: OWSViewController, MediaGalleryDataSourceDele
|
|||
|
||||
// MARK: - Actions
|
||||
|
||||
func shareButtonPressed() {
|
||||
@objc func shareButtonPressed() {
|
||||
guard let attachmentStream = attachmentStream else {
|
||||
Logger.error("\(logTag) Share button should only be shown with attachment, but no attachment found.")
|
||||
return
|
||||
|
@ -525,7 +526,7 @@ class MessageDetailViewController: OWSViewController, MediaGalleryDataSourceDele
|
|||
}
|
||||
}
|
||||
|
||||
internal func yapDatabaseModified(notification: NSNotification) {
|
||||
@objc internal func yapDatabaseModified(notification: NSNotification) {
|
||||
SwiftAssertIsOnMainThread(#function)
|
||||
|
||||
guard !wasDeleted else {
|
||||
|
|
|
@ -44,7 +44,7 @@ public class OWS2FAReminderViewController: UIViewController, PinEntryViewDelegat
|
|||
let instructionsTextHeader = NSLocalizedString("REMINDER_2FA_BODY_HEADER", comment: "Body header for when user is periodically prompted to enter their registration lock PIN")
|
||||
let instructionsTextBody = NSLocalizedString("REMINDER_2FA_BODY", comment: "Body text for when user is periodically prompted to enter their registration lock PIN")
|
||||
|
||||
let attributes = [NSFontAttributeName: pinEntryView.boldLabelFont]
|
||||
let attributes = [NSAttributedStringKey.font: pinEntryView.boldLabelFont]
|
||||
|
||||
let attributedInstructionsText = NSAttributedString(string: instructionsTextHeader, attributes: attributes).rtlSafeAppend(" ", referenceView: pinEntryView).rtlSafeAppend(instructionsTextBody, referenceView: pinEntryView)
|
||||
|
||||
|
|
|
@ -5,7 +5,8 @@
|
|||
import Foundation
|
||||
import SignalServiceKit
|
||||
|
||||
class SafetyNumberConfirmationAlert: NSObject {
|
||||
@objc
|
||||
public class SafetyNumberConfirmationAlert: NSObject {
|
||||
|
||||
let TAG = "[SafetyNumberConfirmationAlert]"
|
||||
|
||||
|
@ -17,18 +18,22 @@ class SafetyNumberConfirmationAlert: NSObject {
|
|||
self.primaryStorage = OWSPrimaryStorage.shared()
|
||||
}
|
||||
|
||||
@objc
|
||||
public class func presentAlertIfNecessary(recipientId: String, confirmationText: String, contactsManager: OWSContactsManager, completion: @escaping (Bool) -> Void) -> Bool {
|
||||
return self.presentAlertIfNecessary(recipientIds: [recipientId], confirmationText: confirmationText, contactsManager: contactsManager, completion: completion, beforePresentationHandler: nil)
|
||||
}
|
||||
|
||||
@objc
|
||||
public class func presentAlertIfNecessary(recipientId: String, confirmationText: String, contactsManager: OWSContactsManager, completion: @escaping (Bool) -> Void, beforePresentationHandler: (() -> Void)? = nil) -> Bool {
|
||||
return self.presentAlertIfNecessary(recipientIds: [recipientId], confirmationText: confirmationText, contactsManager: contactsManager, completion: completion, beforePresentationHandler: beforePresentationHandler)
|
||||
}
|
||||
|
||||
@objc
|
||||
public class func presentAlertIfNecessary(recipientIds: [String], confirmationText: String, contactsManager: OWSContactsManager, completion: @escaping (Bool) -> Void) -> Bool {
|
||||
return self.presentAlertIfNecessary(recipientIds: recipientIds, confirmationText: confirmationText, contactsManager: contactsManager, completion: completion, beforePresentationHandler: nil)
|
||||
}
|
||||
|
||||
@objc
|
||||
public class func presentAlertIfNecessary(recipientIds: [String], confirmationText: String, contactsManager: OWSContactsManager, completion: @escaping (Bool) -> Void, beforePresentationHandler: (() -> Void)? = nil) -> Bool {
|
||||
return SafetyNumberConfirmationAlert(contactsManager: contactsManager).presentIfNecessary(recipientIds: recipientIds,
|
||||
confirmationText: confirmationText,
|
||||
|
|
|
@ -6,7 +6,7 @@ import Foundation
|
|||
import SignalServiceKit
|
||||
import SignalMessaging
|
||||
|
||||
@objc enum MessageReceiptStatus: Int {
|
||||
@objc public enum MessageReceiptStatus: Int {
|
||||
case uploading
|
||||
case sending
|
||||
case sent
|
||||
|
@ -25,7 +25,8 @@ public class MessageRecipientStatusUtils: NSObject {
|
|||
}
|
||||
|
||||
// This method is per-recipient.
|
||||
class func recipientStatus(outgoingMessage: TSOutgoingMessage,
|
||||
@objc
|
||||
public class func recipientStatus(outgoingMessage: TSOutgoingMessage,
|
||||
recipientState: TSOutgoingMessageRecipientState,
|
||||
referenceView: UIView) -> MessageReceiptStatus {
|
||||
let (messageReceiptStatus, _, _) = recipientStatusAndStatusMessage(outgoingMessage: outgoingMessage,
|
||||
|
@ -143,6 +144,7 @@ public class MessageRecipientStatusUtils: NSObject {
|
|||
}
|
||||
|
||||
// This method is per-message.
|
||||
@objc
|
||||
public class func receiptMessage(outgoingMessage: TSOutgoingMessage,
|
||||
referenceView: UIView) -> String {
|
||||
let (_, message ) = receiptStatusAndMessage(outgoingMessage: outgoingMessage,
|
||||
|
@ -151,7 +153,8 @@ public class MessageRecipientStatusUtils: NSObject {
|
|||
}
|
||||
|
||||
// This method is per-message.
|
||||
class func recipientStatus(outgoingMessage: TSOutgoingMessage, referenceView: UIView) -> MessageReceiptStatus {
|
||||
@objc
|
||||
public class func recipientStatus(outgoingMessage: TSOutgoingMessage, referenceView: UIView) -> MessageReceiptStatus {
|
||||
let (status, _ ) = receiptStatusAndMessage(outgoingMessage: outgoingMessage,
|
||||
referenceView: referenceView)
|
||||
return status
|
||||
|
|
|
@ -6,21 +6,22 @@ import Foundation
|
|||
|
||||
@objc
|
||||
public class ThreadViewModel: NSObject {
|
||||
let hasUnreadMessages: Bool
|
||||
let lastMessageDate: Date
|
||||
let isGroupThread: Bool
|
||||
let threadRecord: TSThread
|
||||
let unreadCount: UInt
|
||||
let contactIdentifier: String?
|
||||
let name: String
|
||||
let isMuted: Bool
|
||||
@objc public let hasUnreadMessages: Bool
|
||||
@objc public let lastMessageDate: Date
|
||||
@objc public let isGroupThread: Bool
|
||||
@objc public let threadRecord: TSThread
|
||||
@objc public let unreadCount: UInt
|
||||
@objc public let contactIdentifier: String?
|
||||
@objc public let name: String
|
||||
@objc public let isMuted: Bool
|
||||
var isContactThread: Bool {
|
||||
return !isGroupThread
|
||||
}
|
||||
|
||||
let lastMessageText: String?
|
||||
@objc public let lastMessageText: String?
|
||||
|
||||
init(thread: TSThread, transaction: YapDatabaseReadTransaction) {
|
||||
@objc
|
||||
public init(thread: TSThread, transaction: YapDatabaseReadTransaction) {
|
||||
self.threadRecord = thread
|
||||
self.lastMessageDate = thread.lastMessageDate()
|
||||
self.isGroupThread = thread.isGroupThread()
|
||||
|
|
|
@ -71,7 +71,7 @@ import SignalMessaging
|
|||
* --[SS.Hangup]-->
|
||||
*/
|
||||
|
||||
enum CallError: Error {
|
||||
public enum CallError: Error {
|
||||
case providerReset
|
||||
case assertionError(description: String)
|
||||
case disconnected
|
||||
|
@ -154,17 +154,23 @@ private class SignalCallData: NSObject {
|
|||
|
||||
let (callConnectedPromise, fulfillCallConnectedPromise, rejectCallConnectedPromise) = Promise<Void>.pending()
|
||||
self.callConnectedPromise = callConnectedPromise
|
||||
self.fulfillCallConnectedPromise = fulfillCallConnectedPromise
|
||||
self.fulfillCallConnectedPromise = {
|
||||
fulfillCallConnectedPromise(())
|
||||
}
|
||||
self.rejectCallConnectedPromise = rejectCallConnectedPromise
|
||||
|
||||
let (peerConnectionClientPromise, fulfillPeerConnectionClientPromise, rejectPeerConnectionClientPromise) = Promise<Void>.pending()
|
||||
self.peerConnectionClientPromise = peerConnectionClientPromise
|
||||
self.fulfillPeerConnectionClientPromise = fulfillPeerConnectionClientPromise
|
||||
self.fulfillPeerConnectionClientPromise = {
|
||||
fulfillPeerConnectionClientPromise(())
|
||||
}
|
||||
self.rejectPeerConnectionClientPromise = rejectPeerConnectionClientPromise
|
||||
|
||||
let (readyToSendIceUpdatesPromise, fulfillReadyToSendIceUpdatesPromise, rejectReadyToSendIceUpdatesPromise) = Promise<Void>.pending()
|
||||
self.readyToSendIceUpdatesPromise = readyToSendIceUpdatesPromise
|
||||
self.fulfillReadyToSendIceUpdatesPromise = fulfillReadyToSendIceUpdatesPromise
|
||||
self.fulfillReadyToSendIceUpdatesPromise = {
|
||||
fulfillReadyToSendIceUpdatesPromise(())
|
||||
}
|
||||
self.rejectReadyToSendIceUpdatesPromise = rejectReadyToSendIceUpdatesPromise
|
||||
|
||||
super.init()
|
||||
|
@ -201,7 +207,7 @@ private class SignalCallData: NSObject {
|
|||
}
|
||||
|
||||
// This class' state should only be accessed on the main queue.
|
||||
@objc class CallService: NSObject, CallObserver, PeerConnectionClientDelegate {
|
||||
@objc public class CallService: NSObject, CallObserver, PeerConnectionClientDelegate {
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
|
@ -216,7 +222,7 @@ private class SignalCallData: NSObject {
|
|||
|
||||
// Exposed by environment.m
|
||||
internal let notificationsAdapter: CallNotificationsAdapter
|
||||
internal var callUIAdapter: CallUIAdapter!
|
||||
@objc public var callUIAdapter: CallUIAdapter!
|
||||
|
||||
// MARK: Class
|
||||
|
||||
|
@ -253,6 +259,7 @@ private class SignalCallData: NSObject {
|
|||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
var call: SignalCall? {
|
||||
get {
|
||||
SwiftAssertIsOnMainThread(#function)
|
||||
|
@ -292,7 +299,7 @@ private class SignalCallData: NSObject {
|
|||
}
|
||||
}
|
||||
|
||||
required init(accountManager: AccountManager, contactsManager: OWSContactsManager, messageSender: MessageSender, notificationsAdapter: CallNotificationsAdapter) {
|
||||
@objc public required init(accountManager: AccountManager, contactsManager: OWSContactsManager, messageSender: MessageSender, notificationsAdapter: CallNotificationsAdapter) {
|
||||
self.accountManager = accountManager
|
||||
self.contactsManager = contactsManager
|
||||
self.messageSender = messageSender
|
||||
|
@ -319,12 +326,12 @@ private class SignalCallData: NSObject {
|
|||
NotificationCenter.default.removeObserver(self)
|
||||
}
|
||||
|
||||
func didEnterBackground() {
|
||||
@objc func didEnterBackground() {
|
||||
SwiftAssertIsOnMainThread(#function)
|
||||
self.updateIsVideoEnabled()
|
||||
}
|
||||
|
||||
func didBecomeActive() {
|
||||
@objc func didBecomeActive() {
|
||||
SwiftAssertIsOnMainThread(#function)
|
||||
self.updateIsVideoEnabled()
|
||||
}
|
||||
|
@ -332,7 +339,7 @@ private class SignalCallData: NSObject {
|
|||
/**
|
||||
* Choose whether to use CallKit or a Notification backed interface for calling.
|
||||
*/
|
||||
public func createCallUIAdapter() {
|
||||
@objc public func createCallUIAdapter() {
|
||||
SwiftAssertIsOnMainThread(#function)
|
||||
|
||||
if self.call != nil {
|
||||
|
@ -347,7 +354,7 @@ private class SignalCallData: NSObject {
|
|||
/**
|
||||
* Initiate an outgoing call.
|
||||
*/
|
||||
public func handleOutgoingCall(_ call: SignalCall) -> Promise<Void> {
|
||||
func handleOutgoingCall(_ call: SignalCall) -> Promise<Void> {
|
||||
SwiftAssertIsOnMainThread(#function)
|
||||
|
||||
guard self.call == nil else {
|
||||
|
@ -932,7 +939,7 @@ private class SignalCallData: NSObject {
|
|||
*
|
||||
* Used by notification actions which can't serialize a call object.
|
||||
*/
|
||||
public func handleAnswerCall(localId: UUID) {
|
||||
@objc public func handleAnswerCall(localId: UUID) {
|
||||
SwiftAssertIsOnMainThread(#function)
|
||||
|
||||
guard let call = self.call else {
|
||||
|
@ -1245,6 +1252,7 @@ private class SignalCallData: NSObject {
|
|||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
func handleCallKitStartVideo() {
|
||||
SwiftAssertIsOnMainThread(#function)
|
||||
|
||||
|
@ -1498,7 +1506,6 @@ private class SignalCallData: NSObject {
|
|||
default:
|
||||
assert(failedCall.callRecord != nil)
|
||||
}
|
||||
|
||||
|
||||
// It's essential to set call.state before terminateCall, because terminateCall nils self.call
|
||||
failedCall.error = error
|
||||
|
|
|
@ -9,13 +9,13 @@ import SignalMessaging
|
|||
/**
|
||||
* Creates an outbound call via WebRTC.
|
||||
*/
|
||||
@objc class OutboundCallInitiator: NSObject {
|
||||
@objc public class OutboundCallInitiator: NSObject {
|
||||
let TAG = "[OutboundCallInitiator]"
|
||||
|
||||
let contactsManager: OWSContactsManager
|
||||
let contactsUpdater: ContactsUpdater
|
||||
|
||||
init(contactsManager: OWSContactsManager, contactsUpdater: ContactsUpdater) {
|
||||
@objc public init(contactsManager: OWSContactsManager, contactsUpdater: ContactsUpdater) {
|
||||
self.contactsManager = contactsManager
|
||||
self.contactsUpdater = contactsUpdater
|
||||
|
||||
|
@ -27,7 +27,7 @@ import SignalMessaging
|
|||
/**
|
||||
* |handle| is a user formatted phone number, e.g. from a system contacts entry
|
||||
*/
|
||||
public func initiateCall(handle: String) -> Bool {
|
||||
@objc public func initiateCall(handle: String) -> Bool {
|
||||
Logger.info("\(TAG) in \(#function) with handle: \(handle)")
|
||||
|
||||
guard let recipientId = PhoneNumber(fromE164: handle)?.toE164() else {
|
||||
|
@ -41,7 +41,7 @@ import SignalMessaging
|
|||
/**
|
||||
* |recipientId| is a e164 formatted phone number.
|
||||
*/
|
||||
public func initiateCall(recipientId: String,
|
||||
@objc public func initiateCall(recipientId: String,
|
||||
isVideo: Bool) -> Bool {
|
||||
// Rather than an init-assigned dependency property, we access `callUIAdapter` via Environment
|
||||
// because it can change after app launch due to user settings
|
||||
|
|
|
@ -545,7 +545,7 @@ class PeerConnectionClient: NSObject, RTCPeerConnectionDelegate, RTCDataChannelD
|
|||
if let error = error {
|
||||
reject(error)
|
||||
} else {
|
||||
fulfill()
|
||||
fulfill(())
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -575,7 +575,7 @@ class PeerConnectionClient: NSObject, RTCPeerConnectionDelegate, RTCDataChannelD
|
|||
reject(error)
|
||||
return
|
||||
}
|
||||
fulfill()
|
||||
fulfill(())
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -616,7 +616,7 @@ class PeerConnectionClient: NSObject, RTCPeerConnectionDelegate, RTCDataChannelD
|
|||
reject(error)
|
||||
return
|
||||
}
|
||||
fulfill()
|
||||
fulfill(())
|
||||
})
|
||||
}
|
||||
return promise
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
import Foundation
|
||||
import SignalServiceKit
|
||||
|
||||
enum CallState: String {
|
||||
public enum CallState: String {
|
||||
case idle
|
||||
case dialing
|
||||
case answering
|
||||
|
@ -37,11 +37,13 @@ protocol CallObserver: class {
|
|||
*
|
||||
* This class' state should only be accessed on the main queue.
|
||||
*/
|
||||
@objc class SignalCall: NSObject {
|
||||
@objc public class SignalCall: NSObject {
|
||||
|
||||
let TAG = "[SignalCall]"
|
||||
|
||||
var observers = [Weak<CallObserver>]()
|
||||
|
||||
@objc
|
||||
let remotePhoneNumber: String
|
||||
|
||||
var isTerminated: Bool {
|
||||
|
@ -59,6 +61,7 @@ protocol CallObserver: class {
|
|||
let direction: CallDirection
|
||||
|
||||
// Distinguishes between calls locally, e.g. in CallKit
|
||||
@objc
|
||||
let localId: UUID
|
||||
|
||||
let thread: TSContactThread
|
||||
|
|
|
@ -19,6 +19,8 @@ final class CallKitCallManager: NSObject {
|
|||
|
||||
let callController = CXCallController()
|
||||
let showNamesOnCallScreen: Bool
|
||||
|
||||
@objc
|
||||
static let kAnonymousCallHandlePrefix = "Signal:"
|
||||
|
||||
required init(showNamesOnCallScreen: Bool) {
|
||||
|
|
|
@ -82,7 +82,7 @@ extension CallUIAdaptee {
|
|||
* Notify the user of call related activities.
|
||||
* Driven by either a CallKit or System notifications adaptee
|
||||
*/
|
||||
@objc class CallUIAdapter: NSObject, CallServiceObserver {
|
||||
@objc public class CallUIAdapter: NSObject, CallServiceObserver {
|
||||
|
||||
let TAG = "[CallUIAdapter]"
|
||||
private let adaptee: CallUIAdaptee
|
||||
|
@ -90,7 +90,7 @@ extension CallUIAdaptee {
|
|||
internal let audioService: CallAudioService
|
||||
internal let callService: CallService
|
||||
|
||||
required init(callService: CallService, contactsManager: OWSContactsManager, notificationsAdapter: CallNotificationsAdapter) {
|
||||
public required init(callService: CallService, contactsManager: OWSContactsManager, notificationsAdapter: CallNotificationsAdapter) {
|
||||
SwiftAssertIsOnMainThread(#function)
|
||||
|
||||
self.contactsManager = contactsManager
|
||||
|
@ -155,7 +155,7 @@ extension CallUIAdaptee {
|
|||
return call
|
||||
}
|
||||
|
||||
internal func answerCall(localId: UUID) {
|
||||
@objc public func answerCall(localId: UUID) {
|
||||
SwiftAssertIsOnMainThread(#function)
|
||||
|
||||
adaptee.answerCall(localId: localId)
|
||||
|
@ -167,7 +167,7 @@ extension CallUIAdaptee {
|
|||
adaptee.answerCall(call)
|
||||
}
|
||||
|
||||
internal func declineCall(localId: UUID) {
|
||||
@objc public func declineCall(localId: UUID) {
|
||||
SwiftAssertIsOnMainThread(#function)
|
||||
|
||||
adaptee.declineCall(localId: localId)
|
||||
|
@ -187,7 +187,7 @@ extension CallUIAdaptee {
|
|||
}
|
||||
}
|
||||
|
||||
internal func startAndShowOutgoingCall(recipientId: String, hasLocalVideo: Bool) {
|
||||
@objc public func startAndShowOutgoingCall(recipientId: String, hasLocalVideo: Bool) {
|
||||
SwiftAssertIsOnMainThread(#function)
|
||||
|
||||
adaptee.startAndShowOutgoingCall(recipientId: recipientId, hasLocalVideo: hasLocalVideo)
|
||||
|
|
|
@ -7,7 +7,7 @@ import SignalServiceKit
|
|||
import SignalMessaging
|
||||
|
||||
@objc(OWSWebRTCCallMessageHandler)
|
||||
class WebRTCCallMessageHandler: NSObject, OWSCallMessageHandler {
|
||||
public class WebRTCCallMessageHandler: NSObject, OWSCallMessageHandler {
|
||||
|
||||
// MARK - Properties
|
||||
|
||||
|
@ -21,7 +21,7 @@ class WebRTCCallMessageHandler: NSObject, OWSCallMessageHandler {
|
|||
|
||||
// MARK: Initializers
|
||||
|
||||
required init(accountManager: AccountManager, callService: CallService, messageSender: MessageSender) {
|
||||
@objc public required init(accountManager: AccountManager, callService: CallService, messageSender: MessageSender) {
|
||||
self.accountManager = accountManager
|
||||
self.callService = callService
|
||||
self.messageSender = messageSender
|
||||
|
|
|
@ -1,24 +1,24 @@
|
|||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import SignalServiceKit
|
||||
import SignalMessaging
|
||||
|
||||
class ExperienceUpgrade: TSYapDatabaseObject {
|
||||
@objc public class ExperienceUpgrade: TSYapDatabaseObject {
|
||||
let title: String
|
||||
let body: String
|
||||
let image: UIImage?
|
||||
|
||||
required init(uniqueId: String, title: String, body: String, image: UIImage) {
|
||||
@objc public required init(uniqueId: String, title: String, body: String, image: UIImage) {
|
||||
self.title = title
|
||||
self.body = body
|
||||
self.image = image
|
||||
super.init(uniqueId: uniqueId)
|
||||
}
|
||||
|
||||
override required init(uniqueId: String?) {
|
||||
@objc public override required init(uniqueId: String?) {
|
||||
// This is the unfortunate seam between strict swift and fast-and-loose objc
|
||||
// we can't leave these properties nil, since we really "don't know" that the superclass
|
||||
// will assign them.
|
||||
|
@ -28,7 +28,7 @@ class ExperienceUpgrade: TSYapDatabaseObject {
|
|||
super.init(uniqueId: uniqueId)
|
||||
}
|
||||
|
||||
required init!(coder: NSCoder) {
|
||||
@objc public required init!(coder: NSCoder) {
|
||||
// This is the unfortunate seam between strict swift and fast-and-loose objc
|
||||
// we can't leave these properties nil, since we really "don't know" that the superclass
|
||||
// will assign them.
|
||||
|
@ -38,7 +38,7 @@ class ExperienceUpgrade: TSYapDatabaseObject {
|
|||
super.init(coder: coder)
|
||||
}
|
||||
|
||||
required init(dictionary dictionaryValue: [AnyHashable : Any]!) throws {
|
||||
@objc public required init(dictionary dictionaryValue: [AnyHashable: Any]!) throws {
|
||||
// This is the unfortunate seam between strict swift and fast-and-loose objc
|
||||
// we can't leave these properties nil, since we really "don't know" that the superclass
|
||||
// will assign them.
|
||||
|
@ -48,7 +48,7 @@ class ExperienceUpgrade: TSYapDatabaseObject {
|
|||
try super.init(dictionary: dictionaryValue)
|
||||
}
|
||||
|
||||
override class func storageBehaviorForProperty(withKey propertyKey: String) -> MTLPropertyStorage {
|
||||
@objc public override class func storageBehaviorForProperty(withKey propertyKey: String) -> MTLPropertyStorage {
|
||||
// These exist in a hardcoded set - no need to save them, plus it allows us to
|
||||
// update copy/image down the line if there was a typo and we want to re-expose
|
||||
// these models in a "change log" archive.
|
||||
|
|
|
@ -13,7 +13,7 @@ enum ExperienceUpgradeId: String {
|
|||
introducingCustomNotificationAudio = "005"
|
||||
}
|
||||
|
||||
class ExperienceUpgradeFinder: NSObject {
|
||||
@objc public class ExperienceUpgradeFinder: NSObject {
|
||||
|
||||
// MARK - Singleton class
|
||||
|
||||
|
@ -44,25 +44,26 @@ class ExperienceUpgradeFinder: NSObject {
|
|||
return ExperienceUpgrade(uniqueId: ExperienceUpgradeId.introducingProfiles.rawValue,
|
||||
title: NSLocalizedString("UPGRADE_EXPERIENCE_INTRODUCING_PROFILES_TITLE", comment: "Header for upgrade experience"),
|
||||
body: NSLocalizedString("UPGRADE_EXPERIENCE_INTRODUCING_PROFILES_DESCRIPTION", comment: "Description of new profile feature for upgrading (existing) users"),
|
||||
image:#imageLiteral(resourceName: "introductory_splash_profile"))
|
||||
image: #imageLiteral(resourceName: "introductory_splash_profile"))
|
||||
}
|
||||
|
||||
var introducingReadReceipts: ExperienceUpgrade {
|
||||
return ExperienceUpgrade(uniqueId: ExperienceUpgradeId.introducingReadReceipts.rawValue,
|
||||
title: NSLocalizedString("UPGRADE_EXPERIENCE_INTRODUCING_READ_RECEIPTS_TITLE", comment: "Header for upgrade experience"),
|
||||
body: NSLocalizedString("UPGRADE_EXPERIENCE_INTRODUCING_READ_RECEIPTS_DESCRIPTION", comment: "Description of new profile feature for upgrading (existing) users"),
|
||||
image:#imageLiteral(resourceName: "introductory_splash_read_receipts"))
|
||||
image: #imageLiteral(resourceName: "introductory_splash_read_receipts"))
|
||||
}
|
||||
|
||||
var configurableNotificationAudio: ExperienceUpgrade {
|
||||
return ExperienceUpgrade(uniqueId: ExperienceUpgradeId.introducingCustomNotificationAudio.rawValue,
|
||||
title: NSLocalizedString("UPGRADE_EXPERIENCE_INTRODUCING_NOTIFICATION_AUDIO_TITLE", comment: "Header for upgrade experience"),
|
||||
body: NSLocalizedString("UPGRADE_EXPERIENCE_INTRODUCING_NOTIFICATION_AUDIO_DESCRIPTION", comment: "Description for notification audio customization"),
|
||||
image:#imageLiteral(resourceName: "introductory_splash_custom_audio"))
|
||||
image: #imageLiteral(resourceName: "introductory_splash_custom_audio"))
|
||||
}
|
||||
|
||||
// Keep these ordered by increasing uniqueId.
|
||||
private var allExperienceUpgrades: [ExperienceUpgrade] {
|
||||
@objc
|
||||
public var allExperienceUpgrades: [ExperienceUpgrade] {
|
||||
return [
|
||||
// Disable old experience upgrades. Most people have seen them by now, and accomodating multiple makes layout harder.
|
||||
// Note if we ever want to show multiple experience upgrades again
|
||||
|
@ -78,11 +79,11 @@ class ExperienceUpgradeFinder: NSObject {
|
|||
|
||||
// MARK: - Instance Methods
|
||||
|
||||
public func allUnseen(transaction: YapDatabaseReadTransaction) -> [ExperienceUpgrade] {
|
||||
@objc public func allUnseen(transaction: YapDatabaseReadTransaction) -> [ExperienceUpgrade] {
|
||||
return allExperienceUpgrades.filter { ExperienceUpgrade.fetch(uniqueId: $0.uniqueId!, transaction: transaction) == nil }
|
||||
}
|
||||
|
||||
public func markAllAsSeen(transaction: YapDatabaseReadWriteTransaction) {
|
||||
@objc public func markAllAsSeen(transaction: YapDatabaseReadWriteTransaction) {
|
||||
Logger.info("\(logTag) marking experience upgrades as seen")
|
||||
allExperienceUpgrades.forEach { $0.save(with: transaction) }
|
||||
}
|
||||
|
|
|
@ -105,13 +105,13 @@ public enum PushRegistrationError: Error {
|
|||
|
||||
// MARK: PKPushRegistryDelegate - voIP Push Token
|
||||
|
||||
public func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, forType type: PKPushType) {
|
||||
public func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType) {
|
||||
Logger.info("\(self.logTag) in \(#function)")
|
||||
assert(type == .voIP)
|
||||
self.pushManager.application(UIApplication.shared, didReceiveRemoteNotification: payload.dictionaryPayload)
|
||||
}
|
||||
|
||||
public func pushRegistry(_ registry: PKPushRegistry, didUpdate credentials: PKPushCredentials, forType type: PKPushType) {
|
||||
public func pushRegistry(_ registry: PKPushRegistry, didUpdate credentials: PKPushCredentials, for type: PKPushType) {
|
||||
Logger.info("\(self.logTag) in \(#function)")
|
||||
assert(type == .voIP)
|
||||
assert(credentials.type == .voIP)
|
||||
|
@ -123,7 +123,7 @@ public enum PushRegistrationError: Error {
|
|||
fulfillVoipTokenPromise(credentials.token)
|
||||
}
|
||||
|
||||
public func pushRegistry(_ registry: PKPushRegistry, didInvalidatePushTokenForType type: PKPushType) {
|
||||
public func pushRegistry(_ registry: PKPushRegistry, didInvalidatePushTokenFor type: PKPushType) {
|
||||
// It's not clear when this would happen. We've never previously handled it, but we should at
|
||||
// least start learning if it happens.
|
||||
owsFail("\(self.logTag) in \(#function)")
|
||||
|
@ -145,7 +145,9 @@ public enum PushRegistrationError: Error {
|
|||
|
||||
let (promise, fulfill, _) = Promise<Void>.pending()
|
||||
self.userNotificationSettingsPromise = promise
|
||||
self.fulfillUserNotificationSettingsPromise = fulfill
|
||||
self.fulfillUserNotificationSettingsPromise = {
|
||||
fulfill(())
|
||||
}
|
||||
|
||||
Logger.info("\(self.logTag) registering user notification settings")
|
||||
|
||||
|
@ -266,7 +268,7 @@ public enum PushRegistrationError: Error {
|
|||
|
||||
// If we've already completed registering for a voip token, resolve it immediately,
|
||||
// rather than waiting for the delegate method to be called.
|
||||
if let voipTokenData = voipRegistry.pushToken(forType: .voIP) {
|
||||
if let voipTokenData = voipRegistry.pushToken(for: .voIP) {
|
||||
Logger.info("\(self.logTag) using pre-registered voIP token")
|
||||
fulfill(voipTokenData)
|
||||
}
|
||||
|
|
|
@ -58,6 +58,10 @@ NSString *const OWSPrimaryStorageAppUpgradeNagDate = @"TSStorageManagerAppUpgrad
|
|||
|
||||
- (void)showAppUpgradeNagIfNecessary
|
||||
{
|
||||
if (CurrentAppContext().isRunningTests) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Only show nag if we are "at rest" in the home view or registration view without any
|
||||
// alerts or dialogs showing.
|
||||
UIViewController *frontmostViewController =
|
||||
|
|
|
@ -80,7 +80,7 @@ import CloudKit
|
|||
// backups can reuse the same record.
|
||||
@objc
|
||||
public class func savePersistentFileOnceToCloud(fileId: String,
|
||||
fileUrlBlock: @escaping (()) -> URL?,
|
||||
fileUrlBlock: @escaping () -> URL?,
|
||||
success: @escaping (String) -> Void,
|
||||
failure: @escaping (Error) -> Void) {
|
||||
saveFileOnceToCloud(recordName: recordNameForPersistentFile(fileId: fileId),
|
||||
|
@ -208,7 +208,7 @@ import CloudKit
|
|||
@objc
|
||||
public class func saveFileOnceToCloud(recordName: String,
|
||||
recordType: String,
|
||||
fileUrlBlock: @escaping (()) -> URL?,
|
||||
fileUrlBlock: @escaping () -> URL?,
|
||||
success: @escaping (String) -> Void,
|
||||
failure: @escaping (Error) -> Void) {
|
||||
|
||||
|
@ -242,7 +242,7 @@ import CloudKit
|
|||
|
||||
@objc
|
||||
public class func deleteRecordsFromCloud(recordNames: [String],
|
||||
success: @escaping (()) -> Void,
|
||||
success: @escaping () -> Void,
|
||||
failure: @escaping (Error) -> Void) {
|
||||
deleteRecordsFromCloud(recordNames: recordNames,
|
||||
remainingRetries: maxRetries,
|
||||
|
@ -252,7 +252,7 @@ import CloudKit
|
|||
|
||||
private class func deleteRecordsFromCloud(recordNames: [String],
|
||||
remainingRetries: Int,
|
||||
success: @escaping (()) -> Void,
|
||||
success: @escaping () -> Void,
|
||||
failure: @escaping (Error) -> Void) {
|
||||
|
||||
let recordIDs = recordNames.map { CKRecordID(recordName: $0) }
|
||||
|
@ -466,7 +466,7 @@ import CloudKit
|
|||
@objc
|
||||
public class func downloadFileFromCloud(recordName: String,
|
||||
toFileUrl: URL,
|
||||
success: @escaping (()) -> Void,
|
||||
success: @escaping () -> Void,
|
||||
failure: @escaping (Error) -> Void) {
|
||||
|
||||
downloadFromCloud(recordName: recordName,
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
|
||||
@objc class TextFieldHelper: NSObject {
|
||||
@objc public class TextFieldHelper: NSObject {
|
||||
|
||||
// Used to implement the UITextFieldDelegate method: `textField:shouldChangeCharactersInRange:replacementString`
|
||||
// Takes advantage of Swift's superior unicode handling to append partial pasted text without splitting multi-byte characters.
|
||||
class func textField(_ textField: UITextField, shouldChangeCharactersInRange editingRange: NSRange, replacementString: String, byteLimit: UInt) -> Bool {
|
||||
@objc public class func textField(_ textField: UITextField, shouldChangeCharactersInRange editingRange: NSRange, replacementString: String, byteLimit: UInt) -> Bool {
|
||||
|
||||
let byteLength = { (string: String) -> UInt in
|
||||
return UInt(string.utf8.count)
|
||||
|
@ -38,7 +38,7 @@ import UIKit
|
|||
|
||||
var acceptableSubstring = ""
|
||||
|
||||
for (_, char) in replacementString.characters.enumerated() {
|
||||
for (_, char) in replacementString.enumerated() {
|
||||
var maybeAcceptableSubstring = acceptableSubstring
|
||||
maybeAcceptableSubstring.append(char)
|
||||
if (byteLength(maybeAcceptableSubstring) <= availableSpace) {
|
||||
|
@ -48,7 +48,7 @@ import UIKit
|
|||
}
|
||||
}
|
||||
|
||||
textField.text = (existingString as NSString).replacingCharacters(in: editingRange, with:acceptableSubstring)
|
||||
textField.text = (existingString as NSString).replacingCharacters(in: editingRange, with: acceptableSubstring)
|
||||
|
||||
// We've already handled any valid editing manually, so prevent further changes.
|
||||
return false
|
||||
|
|
|
@ -24,6 +24,7 @@ class AttachmentPointerView: UIView {
|
|||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
required init(attachmentPointer: TSAttachmentPointer, isIncoming: Bool) {
|
||||
self.isIncoming = isIncoming
|
||||
self.attachmentPointer = attachmentPointer
|
||||
|
@ -52,7 +53,7 @@ class AttachmentPointerView: UIView {
|
|||
NotificationCenter.default.removeObserver(self)
|
||||
}
|
||||
|
||||
internal func attachmentDownloadProgress(_ notification: Notification) {
|
||||
@objc internal func attachmentDownloadProgress(_ notification: Notification) {
|
||||
guard let attachmentId = attachmentPointer.uniqueId else {
|
||||
owsFail("Missing attachment id.")
|
||||
return
|
||||
|
|
|
@ -5,9 +5,9 @@
|
|||
import UIKit
|
||||
import SignalServiceKit
|
||||
|
||||
@objc class AudioProgressView: UIView {
|
||||
@objc public class AudioProgressView: UIView {
|
||||
|
||||
override var bounds: CGRect {
|
||||
@objc public override var bounds: CGRect {
|
||||
didSet {
|
||||
if oldValue != bounds {
|
||||
updateSubviews()
|
||||
|
@ -15,7 +15,7 @@ import SignalServiceKit
|
|||
}
|
||||
}
|
||||
|
||||
override var frame: CGRect {
|
||||
@objc public override var frame: CGRect {
|
||||
didSet {
|
||||
if oldValue != frame {
|
||||
updateSubviews()
|
||||
|
@ -23,13 +23,13 @@ import SignalServiceKit
|
|||
}
|
||||
}
|
||||
|
||||
var horizontalBarColor = UIColor.black {
|
||||
@objc public var horizontalBarColor = UIColor.black {
|
||||
didSet {
|
||||
updateContent()
|
||||
}
|
||||
}
|
||||
|
||||
var progressColor = UIColor.blue {
|
||||
@objc public var progressColor = UIColor.blue {
|
||||
didSet {
|
||||
updateContent()
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ import SignalServiceKit
|
|||
private let horizontalBarLayer: CAShapeLayer
|
||||
private let progressLayer: CAShapeLayer
|
||||
|
||||
var progress: CGFloat = 0 {
|
||||
@objc public var progress: CGFloat = 0 {
|
||||
didSet {
|
||||
if oldValue != progress {
|
||||
updateContent()
|
||||
|
@ -47,7 +47,7 @@ import SignalServiceKit
|
|||
}
|
||||
|
||||
@available(*, unavailable, message:"use other constructor instead.")
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
@objc public required init?(coder aDecoder: NSCoder) {
|
||||
fatalError("\(#function) is unimplemented.")
|
||||
}
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@ class ContactCell: UITableViewCell {
|
|||
}
|
||||
}
|
||||
|
||||
func didChangePreferredContentSize() {
|
||||
@objc func didChangePreferredContentSize() {
|
||||
self.titleLabel.font = UIFont.ows_dynamicTypeBody
|
||||
self.subtitleLabel.font = UIFont.ows_dynamicTypeSubheadline
|
||||
}
|
||||
|
@ -130,13 +130,13 @@ fileprivate extension CNContact {
|
|||
|
||||
let boldDescriptor = font.fontDescriptor.withSymbolicTraits(.traitBold)
|
||||
let boldAttributes = [
|
||||
NSFontAttributeName: UIFont(descriptor: boldDescriptor!, size: 0)
|
||||
NSAttributedStringKey.font: UIFont(descriptor: boldDescriptor!, size: 0)
|
||||
]
|
||||
|
||||
if let attributedName = CNContactFormatter.attributedString(from: self, style: .fullName, defaultAttributes: nil) {
|
||||
let highlightedName = attributedName.mutableCopy() as! NSMutableAttributedString
|
||||
highlightedName.enumerateAttributes(in: NSRange(location: 0, length: highlightedName.length), options: [], using: { (attrs, range, _) in
|
||||
if let property = attrs[CNContactPropertyAttribute] as? String, property == keyToHighlight {
|
||||
if let property = attrs[NSAttributedStringKey(rawValue: CNContactPropertyAttribute)] as? String, property == keyToHighlight {
|
||||
highlightedName.addAttributes(boldAttributes, range: range)
|
||||
}
|
||||
})
|
||||
|
|
|
@ -14,7 +14,7 @@ class PanDirectionGestureRecognizer: UIPanGestureRecognizer {
|
|||
|
||||
let direction: PanDirection
|
||||
|
||||
init(direction: PanDirection, target: AnyObject, action: Selector) {
|
||||
@objc init(direction: PanDirection, target: AnyObject, action: Selector) {
|
||||
self.direction = direction
|
||||
|
||||
super.init(target: target, action: action)
|
||||
|
|
|
@ -51,6 +51,7 @@ import SignalServiceKit
|
|||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
@objc
|
||||
public func configure(thread: TSGroupThread, contactsManager: OWSContactsManager) {
|
||||
if let groupName = thread.groupModel.groupName, !groupName.isEmpty {
|
||||
self.nameLabel.text = groupName
|
||||
|
|
|
@ -11,16 +11,19 @@ protocol QuotedReplyPreviewDelegate: class {
|
|||
|
||||
@objc
|
||||
class QuotedReplyPreview: UIView {
|
||||
@objc
|
||||
public weak var delegate: QuotedReplyPreviewDelegate?
|
||||
|
||||
private let quotedReply: OWSQuotedReplyModel
|
||||
private var quotedMessageView: OWSQuotedMessageView?
|
||||
private var heightConstraint: NSLayoutConstraint!
|
||||
|
||||
@objc
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
@objc
|
||||
init(quotedReply: OWSQuotedReplyModel) {
|
||||
self.quotedReply = quotedReply
|
||||
|
||||
|
@ -83,7 +86,7 @@ class QuotedReplyPreview: UIView {
|
|||
self.heightConstraint.constant = size.height
|
||||
}
|
||||
|
||||
func contentSizeCategoryDidChange(_ notification: Notification) {
|
||||
@objc func contentSizeCategoryDidChange(_ notification: Notification) {
|
||||
Logger.debug("\(self.logTag) in \(#function)")
|
||||
|
||||
updateContents()
|
||||
|
|
|
@ -125,7 +125,7 @@ class ReminderView: UIView {
|
|||
iconView.autoSetDimension(.width, toSize: 13)
|
||||
}
|
||||
|
||||
func handleTap(gestureRecognizer: UIGestureRecognizer) {
|
||||
@objc func handleTap(gestureRecognizer: UIGestureRecognizer) {
|
||||
tapAction()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,13 @@ enum PushNotificationRequestResult: String {
|
|||
}
|
||||
|
||||
class FailingTSAccountManager: TSAccountManager {
|
||||
let phoneNumberAwaitingVerification = "+13235555555"
|
||||
override public init(networkManager: TSNetworkManager, primaryStorage: OWSPrimaryStorage) {
|
||||
SwiftAssertIsOnMainThread(#function)
|
||||
|
||||
super.init(networkManager: networkManager, primaryStorage: primaryStorage)
|
||||
|
||||
self.phoneNumberAwaitingVerification = "+13235555555"
|
||||
}
|
||||
|
||||
override func verifyAccount(withCode: String,
|
||||
pin: String?,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
import XCTest
|
||||
|
@ -12,35 +12,37 @@ import WebRTC
|
|||
class FakePeerConnectionClientDelegate: PeerConnectionClientDelegate {
|
||||
|
||||
enum ConnectionState {
|
||||
case connected, failed
|
||||
case connected, disconnected, failed
|
||||
}
|
||||
|
||||
var connectionState: ConnectionState?
|
||||
var localIceCandidates = [RTCIceCandidate]()
|
||||
var dataChannelMessages = [OWSWebRTCProtosData]()
|
||||
|
||||
internal func peerConnectionClientIceConnected(_ peerconnectionClient: PeerConnectionClient) {
|
||||
func peerConnectionClientIceConnected(_ peerconnectionClient: PeerConnectionClient) {
|
||||
connectionState = .connected
|
||||
}
|
||||
|
||||
internal func peerConnectionClientIceFailed(_ peerconnectionClient: PeerConnectionClient) {
|
||||
func peerConnectionClientIceDisconnected(_ peerconnectionClient: PeerConnectionClient) {
|
||||
connectionState = .disconnected
|
||||
}
|
||||
|
||||
func peerConnectionClientIceFailed(_ peerconnectionClient: PeerConnectionClient) {
|
||||
connectionState = .failed
|
||||
}
|
||||
|
||||
internal func peerConnectionClient(_ peerconnectionClient: PeerConnectionClient, addedLocalIceCandidate iceCandidate: RTCIceCandidate) {
|
||||
func peerConnectionClient(_ peerconnectionClient: PeerConnectionClient, addedLocalIceCandidate iceCandidate: RTCIceCandidate) {
|
||||
localIceCandidates.append(iceCandidate)
|
||||
}
|
||||
|
||||
internal func peerConnectionClient(_ peerconnectionClient: PeerConnectionClient, received dataChannelMessage: OWSWebRTCProtosData) {
|
||||
func peerConnectionClient(_ peerconnectionClient: PeerConnectionClient, received dataChannelMessage: OWSWebRTCProtosData) {
|
||||
dataChannelMessages.append(dataChannelMessage)
|
||||
}
|
||||
|
||||
internal func peerConnectionClient(_ peerconnectionClient: PeerConnectionClient, didUpdateLocal videoTrack: RTCVideoTrack?) {
|
||||
|
||||
func peerConnectionClient(_ peerconnectionClient: PeerConnectionClient, didUpdateLocal videoTrack: RTCVideoTrack?) {
|
||||
}
|
||||
|
||||
internal func peerConnectionClient(_ peerconnectionClient: PeerConnectionClient, didUpdateRemote videoTrack: RTCVideoTrack?) {
|
||||
|
||||
func peerConnectionClient(_ peerconnectionClient: PeerConnectionClient, didUpdateRemote videoTrack: RTCVideoTrack?) {
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -32,10 +32,10 @@ final class ContactsPickerTest: XCTestCase {
|
|||
let emailOnlyContactD = CNMutableContact()
|
||||
emailOnlyContactD.emailAddresses.append(CNLabeledValue(label: nil, value: "dude@bla.com"))
|
||||
|
||||
let contactsPicker = ContactsPicker(delegate: nil)
|
||||
let contactsPicker = ContactsPicker(allowsMultipleSelection: false, subtitleCellType: .phoneNumber)
|
||||
let collatedContacts = contactsPicker.collatedContacts([emailOnlyContactB, emailOnlyContactD])
|
||||
|
||||
let sectionTitles = contactsPicker.collation.sectionTitles
|
||||
let sectionTitles = contactsPicker.collationForTests.sectionTitles
|
||||
if let bIndex = sectionTitles.index(of: "B") {
|
||||
let bSectionContacts = collatedContacts[bIndex]
|
||||
XCTAssertEqual(bSectionContacts.first, emailOnlyContactB)
|
||||
|
@ -54,10 +54,10 @@ final class ContactsPickerTest: XCTestCase {
|
|||
nameAndEmailContact.givenName = "Alice"
|
||||
nameAndEmailContact.emailAddresses.append(CNLabeledValue(label: nil, value: "nameAndEmail@bla.com"))
|
||||
|
||||
let contactsPicker = ContactsPicker(delegate: nil)
|
||||
let contactsPicker = ContactsPicker(allowsMultipleSelection: false, subtitleCellType: .phoneNumber)
|
||||
let collatedContacts = contactsPicker.collatedContacts([nameAndEmailContact])
|
||||
|
||||
let sectionTitles = contactsPicker.collation.sectionTitles
|
||||
let sectionTitles = contactsPicker.collationForTests.sectionTitles
|
||||
if let aIndex = sectionTitles.index(of: "A") {
|
||||
let aSectionContacts = collatedContacts[aIndex]
|
||||
XCTAssertEqual(aSectionContacts.first, nameAndEmailContact)
|
||||
|
|
|
@ -27,6 +27,7 @@ FOUNDATION_EXPORT const unsigned char SignalMessagingVersionString[];
|
|||
#import <SignalMessaging/OWSContactsSyncing.h>
|
||||
#import <SignalMessaging/OWSDatabaseMigration.h>
|
||||
#import <SignalMessaging/OWSFormat.h>
|
||||
#import <SignalMessaging/OWSGroupAvatarBuilder.h>
|
||||
#import <SignalMessaging/OWSLogger.h>
|
||||
#import <SignalMessaging/OWSMath.h>
|
||||
#import <SignalMessaging/OWSNavigationController.h>
|
||||
|
@ -37,10 +38,12 @@ FOUNDATION_EXPORT const unsigned char SignalMessagingVersionString[];
|
|||
#import <SignalMessaging/OWSUserProfile.h>
|
||||
#import <SignalMessaging/OWSWindowManager.h>
|
||||
#import <SignalMessaging/Release.h>
|
||||
#import <SignalMessaging/ScreenLockViewController.h>
|
||||
#import <SignalMessaging/SharingThreadPickerViewController.h>
|
||||
#import <SignalMessaging/SignalKeyingStorage.h>
|
||||
#import <SignalMessaging/TSUnreadIndicatorInteraction.h>
|
||||
#import <SignalMessaging/ThreadUtil.h>
|
||||
#import <SignalMessaging/ThreadViewHelper.h>
|
||||
#import <SignalMessaging/UIColor+OWS.h>
|
||||
#import <SignalMessaging/UIFont+OWS.h>
|
||||
#import <SignalMessaging/UIUtil.h>
|
||||
|
|
|
@ -12,10 +12,12 @@ public protocol ReturnToCallViewControllerDelegate: class {
|
|||
@objc
|
||||
public class ReturnToCallViewController: UIViewController {
|
||||
|
||||
@objc
|
||||
public weak var delegate: ReturnToCallViewControllerDelegate?
|
||||
|
||||
let returnToCallLabel = UILabel()
|
||||
|
||||
@objc
|
||||
public func startAnimating() {
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(didTapStatusBar(notification:)), name: .TappedStatusBar, object: nil)
|
||||
self.returnToCallLabel.layer.removeAllAnimations()
|
||||
|
@ -27,6 +29,7 @@ public class ReturnToCallViewController: UIViewController {
|
|||
completion: { _ in self.returnToCallLabel.alpha = 1 })
|
||||
}
|
||||
|
||||
@objc
|
||||
public func stopAnimating() {
|
||||
NotificationCenter.default.removeObserver(self, name: .TappedStatusBar, object: nil)
|
||||
self.returnToCallLabel.layer.removeAllAnimations()
|
||||
|
|
|
@ -7,16 +7,20 @@ import Foundation
|
|||
@objc
|
||||
public class ContactShareViewModel: NSObject {
|
||||
|
||||
@objc
|
||||
public let dbRecord: OWSContact
|
||||
|
||||
@objc
|
||||
public var avatarImageData: Data? {
|
||||
didSet {
|
||||
self.cachedAvatarImage = nil
|
||||
}
|
||||
}
|
||||
|
||||
var cachedAvatarImage: UIImage?
|
||||
var avatarImage: UIImage? {
|
||||
private var cachedAvatarImage: UIImage?
|
||||
|
||||
@objc
|
||||
public var avatarImage: UIImage? {
|
||||
if self.cachedAvatarImage != nil {
|
||||
return self.cachedAvatarImage
|
||||
}
|
||||
|
@ -29,11 +33,13 @@ public class ContactShareViewModel: NSObject {
|
|||
return cachedAvatarImage
|
||||
}
|
||||
|
||||
@objc
|
||||
public required init(contactShareRecord: OWSContact, avatarImageData: Data?) {
|
||||
self.dbRecord = contactShareRecord
|
||||
self.avatarImageData = avatarImageData
|
||||
}
|
||||
|
||||
@objc
|
||||
public convenience init(contactShareRecord: OWSContact, transaction: YapDatabaseReadTransaction) {
|
||||
if let avatarAttachment = contactShareRecord.avatarAttachment(with: transaction) as? TSAttachmentStream {
|
||||
self.init(contactShareRecord: contactShareRecord, avatarImageData: avatarAttachment.validStillImageData())
|
||||
|
@ -42,6 +48,7 @@ public class ContactShareViewModel: NSObject {
|
|||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
public func getAvatarImage(diameter: CGFloat, contactsManager: OWSContactsManager) -> UIImage {
|
||||
if let avatarImage = avatarImage {
|
||||
return avatarImage
|
||||
|
@ -71,6 +78,7 @@ public class ContactShareViewModel: NSObject {
|
|||
|
||||
// MARK: Delegated -> dbRecord
|
||||
|
||||
@objc
|
||||
public var name: OWSContactName {
|
||||
get {
|
||||
return dbRecord.name
|
||||
|
@ -80,6 +88,7 @@ public class ContactShareViewModel: NSObject {
|
|||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
public var addresses: [OWSContactAddress] {
|
||||
get {
|
||||
return dbRecord.addresses
|
||||
|
@ -89,6 +98,7 @@ public class ContactShareViewModel: NSObject {
|
|||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
public var emails: [OWSContactEmail] {
|
||||
get {
|
||||
return dbRecord.emails
|
||||
|
@ -98,6 +108,7 @@ public class ContactShareViewModel: NSObject {
|
|||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
public var phoneNumbers: [OWSContactPhoneNumber] {
|
||||
get {
|
||||
return dbRecord.phoneNumbers
|
||||
|
@ -107,30 +118,37 @@ public class ContactShareViewModel: NSObject {
|
|||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
public func systemContactsWithSignalAccountPhoneNumbers(_ contactsManager: ContactsManagerProtocol) -> [String] {
|
||||
return dbRecord.systemContactsWithSignalAccountPhoneNumbers(contactsManager)
|
||||
}
|
||||
|
||||
@objc
|
||||
public func systemContactPhoneNumbers(_ contactsManager: ContactsManagerProtocol) -> [String] {
|
||||
return dbRecord.systemContactPhoneNumbers(contactsManager)
|
||||
}
|
||||
|
||||
@objc
|
||||
public func e164PhoneNumbers() -> [String] {
|
||||
return dbRecord.e164PhoneNumbers()
|
||||
}
|
||||
|
||||
@objc
|
||||
public var displayName: String {
|
||||
return dbRecord.name.displayName
|
||||
}
|
||||
|
||||
@objc
|
||||
public var ows_isValid: Bool {
|
||||
return dbRecord.ows_isValid()
|
||||
}
|
||||
|
||||
@objc
|
||||
public var isProfileAvatar: Bool {
|
||||
return dbRecord.isProfileAvatar
|
||||
}
|
||||
|
||||
@objc
|
||||
public func cnContact(mergedWithExistingContact existingContact: Contact) -> CNContact? {
|
||||
|
||||
guard let newCNContact = OWSContacts.systemContact(for: self.dbRecord, imageData: self.avatarImageData) else {
|
||||
|
@ -141,6 +159,7 @@ public class ContactShareViewModel: NSObject {
|
|||
return existingContact.buildCNContact(mergedWithNewContact: newCNContact)
|
||||
}
|
||||
|
||||
@objc
|
||||
public func copy(withName name: OWSContactName) -> ContactShareViewModel {
|
||||
|
||||
// TODO move the `copy` logic into the view model?
|
||||
|
@ -149,6 +168,7 @@ public class ContactShareViewModel: NSObject {
|
|||
return ContactShareViewModel(contactShareRecord: newDbRecord, avatarImageData: self.avatarImageData)
|
||||
}
|
||||
|
||||
@objc
|
||||
public func newContact(withName name: OWSContactName) -> ContactShareViewModel {
|
||||
|
||||
// TODO move the `newContact` logic into the view model?
|
||||
|
|
|
@ -95,7 +95,7 @@ public class ConversationAvatarImageView: AvatarImageView {
|
|||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
func handleSignalAccountsChanged(notification: Notification) {
|
||||
@objc func handleSignalAccountsChanged(notification: Notification) {
|
||||
Logger.debug("\(self.logTag) in \(#function)")
|
||||
|
||||
// PERF: It would be nice if we could do this only if *this* user's SignalAccount changed,
|
||||
|
@ -104,7 +104,7 @@ public class ConversationAvatarImageView: AvatarImageView {
|
|||
self.updateImage()
|
||||
}
|
||||
|
||||
func handleOtherUsersProfileChanged(notification: Notification) {
|
||||
@objc func handleOtherUsersProfileChanged(notification: Notification) {
|
||||
Logger.debug("\(self.logTag) in \(#function)")
|
||||
|
||||
guard let changedRecipientId = notification.userInfo?[kNSNotificationKey_ProfileRecipientId] as? String else {
|
||||
|
@ -126,7 +126,7 @@ public class ConversationAvatarImageView: AvatarImageView {
|
|||
self.updateImage()
|
||||
}
|
||||
|
||||
func handleGroupAvatarChanged(notification: Notification) {
|
||||
@objc func handleGroupAvatarChanged(notification: Notification) {
|
||||
Logger.debug("\(self.logTag) in \(#function)")
|
||||
|
||||
guard let changedGroupThreadId = notification.userInfo?[TSGroupThread_NotificationKey_UniqueId] as? String else {
|
||||
|
|
|
@ -16,6 +16,7 @@ public protocol DisappearingTimerConfigurationViewDelegate: class {
|
|||
@objc
|
||||
public class DisappearingTimerConfigurationView: UIView {
|
||||
|
||||
@objc
|
||||
public weak var delegate: DisappearingTimerConfigurationViewDelegate? {
|
||||
didSet {
|
||||
// gesture recognizer is only enabled when a delegate is assigned.
|
||||
|
|
|
@ -6,30 +6,35 @@ import Foundation
|
|||
import UIKit
|
||||
|
||||
@objc
|
||||
protocol NavBarLayoutDelegate: class {
|
||||
public protocol NavBarLayoutDelegate: class {
|
||||
func navBarCallLayoutDidChange(navbar: OWSNavigationBar)
|
||||
}
|
||||
|
||||
@objc
|
||||
class OWSNavigationBar: UINavigationBar {
|
||||
public class OWSNavigationBar: UINavigationBar {
|
||||
|
||||
weak var navBarLayoutDelegate: NavBarLayoutDelegate?
|
||||
@objc
|
||||
public weak var navBarLayoutDelegate: NavBarLayoutDelegate?
|
||||
|
||||
let navbarWithoutStatusHeight: CGFloat = 44
|
||||
@objc
|
||||
public let navbarWithoutStatusHeight: CGFloat = 44
|
||||
|
||||
var callBannerHeight: CGFloat {
|
||||
@objc
|
||||
public var callBannerHeight: CGFloat {
|
||||
return OWSWindowManagerCallScreenHeight()
|
||||
}
|
||||
|
||||
var statusBarHeight: CGFloat {
|
||||
@objc
|
||||
public var statusBarHeight: CGFloat {
|
||||
return CurrentAppContext().statusBarHeight
|
||||
}
|
||||
|
||||
var fullWidth: CGFloat {
|
||||
@objc
|
||||
public var fullWidth: CGFloat {
|
||||
return UIScreen.main.bounds.size.width
|
||||
}
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
public required init?(coder aDecoder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
|
@ -54,7 +59,7 @@ class OWSNavigationBar: UINavigationBar {
|
|||
self.navBarLayoutDelegate?.navBarCallLayoutDidChange(navbar: self)
|
||||
}
|
||||
|
||||
override func sizeThatFits(_ size: CGSize) -> CGSize {
|
||||
public override func sizeThatFits(_ size: CGSize) -> CGSize {
|
||||
guard OWSWindowManager.shared().hasCall() else {
|
||||
return super.sizeThatFits(size)
|
||||
}
|
||||
|
@ -69,7 +74,7 @@ class OWSNavigationBar: UINavigationBar {
|
|||
}
|
||||
}
|
||||
|
||||
override func layoutSubviews() {
|
||||
public override func layoutSubviews() {
|
||||
guard OWSWindowManager.shared().hasCall() else {
|
||||
super.layoutSubviews()
|
||||
return
|
||||
|
|
|
@ -23,7 +23,7 @@ public class TappableStackView: UIStackView {
|
|||
self.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(wasTapped)))
|
||||
}
|
||||
|
||||
func wasTapped(sender: UIGestureRecognizer) {
|
||||
@objc func wasTapped(sender: UIGestureRecognizer) {
|
||||
Logger.info("\(logTag) \(#function)")
|
||||
|
||||
guard sender.state == .recognized else {
|
||||
|
|
|
@ -22,7 +22,7 @@ public class TappableView: UIView {
|
|||
self.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(wasTapped)))
|
||||
}
|
||||
|
||||
func wasTapped(sender: UIGestureRecognizer) {
|
||||
@objc func wasTapped(sender: UIGestureRecognizer) {
|
||||
Logger.info("\(logTag) \(#function)")
|
||||
|
||||
guard sender.state == .recognized else {
|
||||
|
|
|
@ -216,7 +216,7 @@ public class AttachmentApprovalViewController: OWSViewController, CaptioningTool
|
|||
}
|
||||
}
|
||||
|
||||
public func didTapPlayerView(_ gestureRecognizer: UIGestureRecognizer) {
|
||||
@objc public func didTapPlayerView(_ gestureRecognizer: UIGestureRecognizer) {
|
||||
assert(self.videoPlayer != nil)
|
||||
self.pauseVideo()
|
||||
}
|
||||
|
@ -251,7 +251,7 @@ public class AttachmentApprovalViewController: OWSViewController, CaptioningTool
|
|||
self.playVideo()
|
||||
}
|
||||
|
||||
func cancelPressed(sender: UIButton) {
|
||||
@objc func cancelPressed(sender: UIButton) {
|
||||
self.delegate?.attachmentApproval(self, didCancelAttachment: attachment)
|
||||
}
|
||||
|
||||
|
@ -619,7 +619,7 @@ class CaptioningToolbar: UIView, UITextViewDelegate {
|
|||
bottomGradient.autoPinEdgesToSuperviewEdges(with: .zero, excludingEdge: .top)
|
||||
}
|
||||
|
||||
func didTapSend() {
|
||||
@objc func didTapSend() {
|
||||
self.captioningToolbarDelegate?.captioningToolbarDidTapSend(self, captionText: self.textView.text)
|
||||
}
|
||||
|
||||
|
|
|
@ -203,7 +203,7 @@ class ContactShareFieldView: UIStackView {
|
|||
self.addArrangedSubview(previewView)
|
||||
}
|
||||
|
||||
func wasTapped(sender: UIGestureRecognizer) {
|
||||
@objc func wasTapped(sender: UIGestureRecognizer) {
|
||||
Logger.info("\(self.logTag) \(#function)")
|
||||
|
||||
guard sender.state == .recognized else {
|
||||
|
@ -401,7 +401,7 @@ public class ContactShareApprovalViewController: OWSViewController, EditContactS
|
|||
func createNameRow() -> UIView {
|
||||
let nameVMargin = CGFloat(16)
|
||||
|
||||
let stackView = TappableStackView(actionBlock: { [weak self] _ in
|
||||
let stackView = TappableStackView(actionBlock: { [weak self] in
|
||||
guard let strongSelf = self else { return }
|
||||
strongSelf.didPressEditName()
|
||||
})
|
||||
|
@ -447,7 +447,7 @@ public class ContactShareApprovalViewController: OWSViewController, EditContactS
|
|||
|
||||
// MARK: -
|
||||
|
||||
func didPressSendButton() {
|
||||
@objc func didPressSendButton() {
|
||||
SwiftAssertIsOnMainThread(#function)
|
||||
|
||||
guard isAtLeastOneFieldSelected() else {
|
||||
|
@ -475,7 +475,7 @@ public class ContactShareApprovalViewController: OWSViewController, EditContactS
|
|||
delegate.approveContactShare(self, didApproveContactShare: filteredContactShare)
|
||||
}
|
||||
|
||||
func didPressCancel() {
|
||||
@objc func didPressCancel() {
|
||||
Logger.info("\(logTag) \(#function)")
|
||||
|
||||
guard let delegate = self.delegate else {
|
||||
|
|
|
@ -76,7 +76,7 @@ class ContactNameFieldView: UIView {
|
|||
valueView.addTarget(self, action: #selector(textFieldDidChange), for: .editingChanged)
|
||||
}
|
||||
|
||||
func wasTapped(sender: UIGestureRecognizer) {
|
||||
@objc func wasTapped(sender: UIGestureRecognizer) {
|
||||
Logger.info("\(self.logTag) \(#function)")
|
||||
|
||||
guard sender.state == .recognized else {
|
||||
|
@ -86,7 +86,7 @@ class ContactNameFieldView: UIView {
|
|||
valueView.becomeFirstResponder()
|
||||
}
|
||||
|
||||
func textFieldDidChange(sender: UITextField) {
|
||||
@objc func textFieldDidChange(sender: UITextField) {
|
||||
Logger.info("\(self.logTag) \(#function)")
|
||||
|
||||
hasUnsavedChanges = true
|
||||
|
@ -285,7 +285,7 @@ public class EditContactShareNameViewController: OWSViewController, ContactNameF
|
|||
|
||||
// MARK: -
|
||||
|
||||
func didPressSave() {
|
||||
@objc func didPressSave() {
|
||||
Logger.info("\(logTag) \(#function)")
|
||||
|
||||
guard let newName = OWSContactName() else {
|
||||
|
@ -315,7 +315,7 @@ public class EditContactShareNameViewController: OWSViewController, ContactNameF
|
|||
navigationController.popViewController(animated: true)
|
||||
}
|
||||
|
||||
func didPressCancel() {
|
||||
@objc func didPressCancel() {
|
||||
Logger.info("\(logTag) \(#function)")
|
||||
|
||||
guard let navigationController = self.navigationController else {
|
||||
|
|
|
@ -164,7 +164,7 @@ public class MediaMessageView: UIView, OWSAudioPlayerDelegate {
|
|||
// it's superview is big enough to contain it.
|
||||
stackView.autoPinWidthToSuperview()
|
||||
stackView.autoVCenterInSuperview()
|
||||
NSLayoutConstraint.autoSetPriority(UILayoutPriorityDefaultLow) {
|
||||
NSLayoutConstraint.autoSetPriority(UILayoutPriority.defaultLow) {
|
||||
stackView.autoPinHeightToSuperview()
|
||||
}
|
||||
stackView.autoPinEdge(toSuperviewEdge: .top, withInset: 0, relation: .greaterThanOrEqual)
|
||||
|
@ -277,7 +277,7 @@ public class MediaMessageView: UIView, OWSAudioPlayerDelegate {
|
|||
// it's superview is big enough to contain it.
|
||||
stackView.autoPinWidthToSuperview()
|
||||
stackView.autoVCenterInSuperview()
|
||||
NSLayoutConstraint.autoSetPriority(UILayoutPriorityDefaultLow) {
|
||||
NSLayoutConstraint.autoSetPriority(UILayoutPriority.defaultLow) {
|
||||
stackView.autoPinHeightToSuperview()
|
||||
}
|
||||
stackView.autoPinEdge(toSuperviewEdge: .top, withInset: 0, relation: .greaterThanOrEqual)
|
||||
|
|
|
@ -200,11 +200,11 @@ public class MessageApprovalViewController: OWSViewController, UITextViewDelegat
|
|||
|
||||
// MARK: - Event Handlers
|
||||
|
||||
func cancelPressed(sender: UIButton) {
|
||||
@objc func cancelPressed(sender: UIButton) {
|
||||
delegate?.messageApprovalDidCancel(self)
|
||||
}
|
||||
|
||||
func sendPressed(sender: UIButton) {
|
||||
@objc func sendPressed(sender: UIButton) {
|
||||
delegate?.messageApproval(self, didApproveMessage: self.textView.text)
|
||||
}
|
||||
|
||||
|
|
|
@ -13,12 +13,14 @@ protocol OWSVideoPlayerDelegate: class {
|
|||
@objc
|
||||
public class OWSVideoPlayer: NSObject {
|
||||
|
||||
@objc
|
||||
let avPlayer: AVPlayer
|
||||
let audioActivity: AudioActivity
|
||||
|
||||
@objc
|
||||
weak var delegate: OWSVideoPlayerDelegate?
|
||||
|
||||
init(url: URL) {
|
||||
@objc init(url: URL) {
|
||||
self.avPlayer = AVPlayer(url: url)
|
||||
self.audioActivity = AudioActivity(audioDescription: "[OWSVideoPlayer] url:\(url)")
|
||||
|
||||
|
@ -32,11 +34,13 @@ public class OWSVideoPlayer: NSObject {
|
|||
|
||||
// MARK: Playback Controls
|
||||
|
||||
@objc
|
||||
public func pause() {
|
||||
avPlayer.pause()
|
||||
OWSAudioSession.shared.endAudioActivity(self.audioActivity)
|
||||
}
|
||||
|
||||
@objc
|
||||
public func play() {
|
||||
OWSAudioSession.shared.startPlaybackAudioActivity(self.audioActivity)
|
||||
|
||||
|
@ -53,6 +57,7 @@ public class OWSVideoPlayer: NSObject {
|
|||
avPlayer.play()
|
||||
}
|
||||
|
||||
@objc
|
||||
public func stop() {
|
||||
avPlayer.pause()
|
||||
avPlayer.seek(to: kCMTimeZero)
|
||||
|
|
|
@ -958,7 +958,7 @@ public class SignalAttachment: NSObject {
|
|||
}
|
||||
|
||||
exportSession.shouldOptimizeForNetworkUse = true
|
||||
exportSession.outputFileType = AVFileTypeMPEG4
|
||||
exportSession.outputFileType = AVFileType.mp4
|
||||
exportSession.metadataItemFilter = AVMetadataItemFilter.forSharing()
|
||||
|
||||
let exportURL = videoTempPath.appendingPathComponent(UUID().uuidString).appendingPathExtension("mp4")
|
||||
|
@ -1011,6 +1011,7 @@ public class SignalAttachment: NSObject {
|
|||
return VideoCompressionResult(attachmentPromise: attachmentPromise, exportSession: exportSession)
|
||||
}
|
||||
|
||||
@objc
|
||||
public class func isInvalidVideo(dataSource: DataSource, dataUTI: String) -> Bool {
|
||||
guard videoUTISet.contains(dataUTI) else {
|
||||
// not a video
|
||||
|
|
|
@ -7,6 +7,7 @@ import AVFoundation
|
|||
|
||||
@objc
|
||||
public class VideoPlayerView: UIView {
|
||||
@objc
|
||||
var player: AVPlayer? {
|
||||
get {
|
||||
return playerLayer.player
|
||||
|
@ -75,6 +76,7 @@ public class PlayerProgressBar: UIView {
|
|||
|
||||
private let kPreferredTimeScale: CMTimeScale = 100
|
||||
|
||||
@objc
|
||||
public var player: AVPlayer? {
|
||||
didSet {
|
||||
guard let item = player?.currentItem else {
|
||||
|
@ -112,7 +114,7 @@ public class PlayerProgressBar: UIView {
|
|||
|
||||
// Configure controls
|
||||
|
||||
let kLabelFont = UIFont.monospacedDigitSystemFont(ofSize: 12, weight: UIFontWeightRegular)
|
||||
let kLabelFont = UIFont.monospacedDigitSystemFont(ofSize: 12, weight: UIFont.Weight.regular)
|
||||
positionLabel.font = kLabelFont
|
||||
remainingLabel.font = kLabelFont
|
||||
|
||||
|
|
|
@ -1,19 +1,22 @@
|
|||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
import PromiseKit
|
||||
|
||||
@objc
|
||||
public extension AnyPromise {
|
||||
/**
|
||||
* Sometimes there isn't a straight forward candidate to retain a promise, in that case we tell the
|
||||
* promise to self retain, until it completes to avoid the risk it's GC'd before completion.
|
||||
*/
|
||||
@objc
|
||||
func retainUntilComplete() {
|
||||
// Unfortunately, there is (currently) no way to surpress the
|
||||
// compiler warning: "Variable 'retainCycle' was written to, but never read"
|
||||
var retainCycle: AnyPromise? = self
|
||||
self.always {
|
||||
assert(retainCycle != nil)
|
||||
retainCycle = nil
|
||||
}
|
||||
}
|
||||
|
@ -29,6 +32,7 @@ public extension Promise {
|
|||
// compiler warning: "Variable 'retainCycle' was written to, but never read"
|
||||
var retainCycle: Promise<T>? = self
|
||||
self.always {
|
||||
assert(retainCycle != nil)
|
||||
retainCycle = nil
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,12 +4,14 @@
|
|||
|
||||
import Foundation
|
||||
|
||||
@objc
|
||||
public extension UIDevice {
|
||||
var supportsCallKit: Bool {
|
||||
return ProcessInfo().isOperatingSystemAtLeast(OperatingSystemVersion(majorVersion: 10, minorVersion: 0, patchVersion: 0))
|
||||
}
|
||||
|
||||
var isIPhoneX: Bool {
|
||||
@objc
|
||||
public var isIPhoneX: Bool {
|
||||
switch UIScreen.main.nativeBounds.height {
|
||||
case 1136:
|
||||
// iPhone 5 or 5S or 5C
|
||||
|
|
|
@ -15,6 +15,7 @@ public class ModalActivityIndicatorViewController: OWSViewController {
|
|||
|
||||
let canCancel: Bool
|
||||
|
||||
@objc
|
||||
public var wasCancelled: Bool = false
|
||||
|
||||
var activityIndicator: UIActivityIndicatorView?
|
||||
|
@ -35,6 +36,7 @@ public class ModalActivityIndicatorViewController: OWSViewController {
|
|||
super.init(nibName: nil, bundle: nil)
|
||||
}
|
||||
|
||||
@objc
|
||||
public class func present(fromViewController: UIViewController,
|
||||
canCancel: Bool, backgroundBlock : @escaping (ModalActivityIndicatorViewController) -> Void) {
|
||||
SwiftAssertIsOnMainThread(#function)
|
||||
|
@ -50,6 +52,7 @@ public class ModalActivityIndicatorViewController: OWSViewController {
|
|||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
public func dismiss(completion : @escaping () -> Void) {
|
||||
SwiftAssertIsOnMainThread(#function)
|
||||
|
||||
|
@ -132,7 +135,7 @@ public class ModalActivityIndicatorViewController: OWSViewController {
|
|||
self.presentTimer = nil
|
||||
}
|
||||
|
||||
func presentTimerFired() {
|
||||
@objc func presentTimerFired() {
|
||||
SwiftAssertIsOnMainThread(#function)
|
||||
|
||||
clearTimer()
|
||||
|
@ -143,7 +146,7 @@ public class ModalActivityIndicatorViewController: OWSViewController {
|
|||
}
|
||||
}
|
||||
|
||||
func cancelPressed() {
|
||||
@objc func cancelPressed() {
|
||||
SwiftAssertIsOnMainThread(#function)
|
||||
|
||||
wasCancelled = true
|
||||
|
|
|
@ -13,8 +13,8 @@ public class AudioActivity: NSObject {
|
|||
return "<\(self.logTag) audioDescription: \"\(audioDescription)\">"
|
||||
}
|
||||
|
||||
public
|
||||
init(audioDescription: String) {
|
||||
@objc
|
||||
public init(audioDescription: String) {
|
||||
self.audioDescription = audioDescription
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,7 @@ public class AudioActivity: NSObject {
|
|||
public class OWSAudioSession: NSObject {
|
||||
|
||||
// Force singleton access
|
||||
public static let shared = OWSAudioSession()
|
||||
@objc public static let shared = OWSAudioSession()
|
||||
private override init() {}
|
||||
private let avAudioSession = AVAudioSession.sharedInstance()
|
||||
|
||||
|
@ -35,6 +35,7 @@ public class OWSAudioSession: NSObject {
|
|||
|
||||
// Respects hardware mute switch, plays through external speaker, mixes with backround audio
|
||||
// appropriate for foreground sound effects.
|
||||
@objc
|
||||
public func startAmbientAudioActivity(_ audioActivity: AudioActivity) {
|
||||
Logger.debug("\(logTag) in \(#function)")
|
||||
|
||||
|
@ -56,6 +57,7 @@ public class OWSAudioSession: NSObject {
|
|||
}
|
||||
|
||||
// Ignores hardware mute switch, plays through external speaker
|
||||
@objc
|
||||
public func startPlaybackAudioActivity(_ audioActivity: AudioActivity) {
|
||||
Logger.debug("\(logTag) in \(#function)")
|
||||
|
||||
|
@ -71,6 +73,7 @@ public class OWSAudioSession: NSObject {
|
|||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
public func startRecordingAudioActivity(_ audioActivity: AudioActivity) -> Bool {
|
||||
Logger.debug("\(logTag) in \(#function)")
|
||||
|
||||
|
@ -90,6 +93,7 @@ public class OWSAudioSession: NSObject {
|
|||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
public func startAudioActivity(_ audioActivity: AudioActivity) {
|
||||
Logger.debug("\(logTag) in \(#function) with \(audioActivity)")
|
||||
|
||||
|
@ -99,6 +103,7 @@ public class OWSAudioSession: NSObject {
|
|||
self.currentActivities.append(Weak(value: audioActivity))
|
||||
}
|
||||
|
||||
@objc
|
||||
public func endAudioActivity(_ audioActivity: AudioActivity) {
|
||||
Logger.debug("\(logTag) in \(#function) with audioActivity: \(audioActivity)")
|
||||
|
||||
|
@ -171,6 +176,7 @@ public class OWSAudioSession: NSObject {
|
|||
* This must be called before any audio tracks are added to the peerConnection, else we'll start recording before all
|
||||
* our signaling is set up.
|
||||
*/
|
||||
@objc
|
||||
public func configureRTCAudio() {
|
||||
Logger.info("\(logTag) in \(#function)")
|
||||
rtcAudioSession.useManualAudio = true
|
||||
|
@ -180,6 +186,7 @@ public class OWSAudioSession: NSObject {
|
|||
* Because we useManualAudio with our RTCAudioSession, we have to start/stop the recording audio session ourselves.
|
||||
* See header for details on manual audio.
|
||||
*/
|
||||
@objc
|
||||
public var isRTCAudioEnabled: Bool {
|
||||
get {
|
||||
return rtcAudioSession.isAudioEnabled
|
||||
|
|
|
@ -14,13 +14,14 @@ public class OWS106EnsureProfileComplete: OWSDatabaseMigration {
|
|||
private static var sharedCompleteRegistrationFixerJob: CompleteRegistrationFixerJob?
|
||||
|
||||
// increment a similar constant for each migration.
|
||||
@objc
|
||||
class func migrationId() -> String {
|
||||
return "106"
|
||||
}
|
||||
|
||||
// Overriding runUp since we have some specific completion criteria which
|
||||
// is more likely to fail since it involves network requests.
|
||||
override public func runUp(completion:@escaping ((Void)) -> Void) {
|
||||
override public func runUp(completion:@escaping () -> Void) {
|
||||
let job = CompleteRegistrationFixerJob(completionHandler: { (didSucceed) in
|
||||
|
||||
if (didSucceed) {
|
||||
|
@ -98,7 +99,7 @@ public class OWS106EnsureProfileComplete: OWSDatabaseMigration {
|
|||
ProfileFetcherJob(networkManager: networkManager).getProfile(recipientId: localRecipientId).then { _ -> Void in
|
||||
Logger.info("\(self.TAG) verified recipient profile is in good shape: \(localRecipientId)")
|
||||
|
||||
fulfill()
|
||||
fulfill(())
|
||||
}.catch { error in
|
||||
switch error {
|
||||
case SignalServiceProfile.ValidationError.invalidIdentityKey(let description):
|
||||
|
@ -107,7 +108,7 @@ public class OWS106EnsureProfileComplete: OWSDatabaseMigration {
|
|||
TSPreKeyManager.registerPreKeys(with: .signedAndOneTime,
|
||||
success: {
|
||||
Logger.info("\(self.TAG) successfully uploaded pre-keys. Profile should be fixed.")
|
||||
fulfill()
|
||||
fulfill(())
|
||||
},
|
||||
failure: { _ in
|
||||
reject(OWSErrorWithCodeDescription(.signalServiceFailure, "\(self.TAG) Unknown error in \(#function)"))
|
||||
|
|
|
@ -20,6 +20,7 @@ public class DeviceSleepManager: NSObject {
|
|||
|
||||
let TAG = "[DeviceSleepManager]"
|
||||
|
||||
@objc
|
||||
public static let sharedInstance = DeviceSleepManager()
|
||||
|
||||
private class SleepBlock: CustomDebugStringConvertible {
|
||||
|
@ -57,6 +58,7 @@ public class DeviceSleepManager: NSObject {
|
|||
ensureSleepBlocking()
|
||||
}
|
||||
|
||||
@objc
|
||||
public func addBlock(blockObject: NSObject) {
|
||||
SwiftAssertIsOnMainThread(#function)
|
||||
|
||||
|
@ -65,6 +67,7 @@ public class DeviceSleepManager: NSObject {
|
|||
ensureSleepBlocking()
|
||||
}
|
||||
|
||||
@objc
|
||||
public func removeBlock(blockObject: NSObject) {
|
||||
SwiftAssertIsOnMainThread(#function)
|
||||
|
||||
|
|
|
@ -152,20 +152,22 @@ extension String {
|
|||
|
||||
static let TAG = "[DisplayableText]"
|
||||
|
||||
public let fullText: String
|
||||
public let displayText: String
|
||||
public let isTextTruncated: Bool
|
||||
public let jumbomojiCount: UInt
|
||||
@objc public let fullText: String
|
||||
@objc public let displayText: String
|
||||
@objc public let isTextTruncated: Bool
|
||||
@objc public let jumbomojiCount: UInt
|
||||
|
||||
@objc
|
||||
static let kMaxJumbomojiCount: UInt = 5
|
||||
// This value is a bit arbitrary since we don't need to be 100% correct about
|
||||
// rendering "Jumbomoji". It allows us to place an upper bound on worst-case
|
||||
// performacne.
|
||||
@objc
|
||||
static let kMaxCharactersPerEmojiCount: UInt = 10
|
||||
|
||||
// MARK: Initializers
|
||||
|
||||
init(fullText: String, displayText: String, isTextTruncated: Bool) {
|
||||
@objc public init(fullText: String, displayText: String, isTextTruncated: Bool) {
|
||||
self.fullText = fullText
|
||||
self.displayText = displayText
|
||||
self.isTextTruncated = isTextTruncated
|
||||
|
|
|
@ -7,14 +7,17 @@ public class AnyLRUCache: NSObject {
|
|||
|
||||
let backingCache: LRUCache<NSObject, NSObject>
|
||||
|
||||
@objc
|
||||
public init(maxSize: Int) {
|
||||
backingCache = LRUCache(maxSize: maxSize)
|
||||
}
|
||||
|
||||
@objc
|
||||
public func get(key: NSObject) -> NSObject? {
|
||||
return self.backingCache.get(key: key)
|
||||
}
|
||||
|
||||
@objc
|
||||
public func set(key: NSObject, value: NSObject) {
|
||||
self.backingCache.set(key: key, value: value)
|
||||
}
|
||||
|
|
|
@ -20,26 +20,31 @@ public class OWSMessagesBubbleImageFactory: NSObject {
|
|||
return UIView().isRTL()
|
||||
}()
|
||||
|
||||
@objc
|
||||
public lazy var incoming: JSQMessagesBubbleImage = {
|
||||
let color = bubbleColorIncoming
|
||||
let color = OWSMessagesBubbleImageFactory.bubbleColorIncoming
|
||||
return self.incoming(color: color)
|
||||
}()
|
||||
|
||||
@objc
|
||||
public lazy var outgoing: JSQMessagesBubbleImage = {
|
||||
let color = bubbleColorOutgoingSent
|
||||
let color = OWSMessagesBubbleImageFactory.bubbleColorOutgoingSent
|
||||
return self.outgoing(color: color)
|
||||
}()
|
||||
|
||||
@objc
|
||||
public lazy var currentlyOutgoing: JSQMessagesBubbleImage = {
|
||||
let color = bubbleColorOutgoingSending
|
||||
let color = OWSMessagesBubbleImageFactory.bubbleColorOutgoingSending
|
||||
return self.outgoing(color: color)
|
||||
}()
|
||||
|
||||
@objc
|
||||
public lazy var outgoingFailed: JSQMessagesBubbleImage = {
|
||||
let color = bubbleColorOutgoingUnsent
|
||||
let color = OWSMessagesBubbleImageFactory.bubbleColorOutgoingUnsent
|
||||
return self.outgoing(color: color)
|
||||
}()
|
||||
|
||||
@objc
|
||||
public func bubble(message: TSMessage) -> JSQMessagesBubbleImage {
|
||||
if message is TSIncomingMessage {
|
||||
return self.incoming
|
||||
|
@ -70,6 +75,7 @@ public class OWSMessagesBubbleImageFactory: NSObject {
|
|||
@objc
|
||||
public static let bubbleColorOutgoingSent = UIColor.ows_materialBlue
|
||||
|
||||
@objc
|
||||
public func bubbleColor(message: TSMessage) -> UIColor {
|
||||
if message is TSIncomingMessage {
|
||||
return OWSMessagesBubbleImageFactory.bubbleColorIncoming
|
||||
|
|
|
@ -60,6 +60,7 @@ import Foundation
|
|||
}
|
||||
|
||||
@objc public class MediaStrings: NSObject {
|
||||
@objc
|
||||
static public let allMedia = NSLocalizedString("MEDIA_DETAIL_VIEW_ALL_MEDIA_BUTTON", comment: "nav bar button item")
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,11 @@ extern NSString *const kNSNotificationName_LocalNumberDidChange;
|
|||
|
||||
@interface TSAccountManager : NSObject
|
||||
|
||||
// This property is exposed for testing purposes only.
|
||||
#ifdef DEBUG
|
||||
@property (nonatomic, nullable) NSString *phoneNumberAwaitingVerification;
|
||||
#endif
|
||||
|
||||
#pragma mark - Initializers
|
||||
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
|
|
@ -25,8 +25,6 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
@property (nonatomic, copy) NSString *messageDraft;
|
||||
@property (atomic, nullable) NSDate *mutedUntilDate;
|
||||
|
||||
- (TSInteraction *)lastInteractionWithTranscation:(YapDatabaseReadTransaction *)transaction;
|
||||
|
||||
@end
|
||||
|
||||
@implementation TSThread
|
||||
|
|
Loading…
Reference in a new issue