246 lines
7.5 KiB
Swift
246 lines
7.5 KiB
Swift
//
|
|
// Copyright 2021 Signal Messenger, LLC
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
//
|
|
|
|
import AVFoundation
|
|
import SignalServiceKit
|
|
|
|
extension ConversationViewController {
|
|
func addNotificationListeners() {
|
|
AssertIsOnMainThread()
|
|
|
|
NotificationCenter.default.addObserver(
|
|
self,
|
|
selector: #selector(blockListDidChange),
|
|
name: BlockingManager.blockListDidChange,
|
|
object: nil,
|
|
)
|
|
NotificationCenter.default.addObserver(
|
|
self,
|
|
selector: #selector(identityStateDidChange),
|
|
name: .identityStateDidChange,
|
|
object: nil,
|
|
)
|
|
NotificationCenter.default.addObserver(
|
|
self,
|
|
selector: #selector(applicationWillEnterForeground),
|
|
name: .OWSApplicationWillEnterForeground,
|
|
object: nil,
|
|
)
|
|
NotificationCenter.default.addObserver(
|
|
self,
|
|
selector: #selector(applicationDidEnterBackground),
|
|
name: .OWSApplicationDidEnterBackground,
|
|
object: nil,
|
|
)
|
|
NotificationCenter.default.addObserver(
|
|
self,
|
|
selector: #selector(applicationWillResignActive),
|
|
name: .OWSApplicationWillResignActive,
|
|
object: nil,
|
|
)
|
|
NotificationCenter.default.addObserver(
|
|
self,
|
|
selector: #selector(applicationDidBecomeActive),
|
|
name: .OWSApplicationDidBecomeActive,
|
|
object: nil,
|
|
)
|
|
NotificationCenter.default.addObserver(
|
|
self,
|
|
selector: #selector(otherUsersProfileDidChange),
|
|
name: UserProfileNotifications.otherUsersProfileDidChange,
|
|
object: nil,
|
|
)
|
|
NotificationCenter.default.addObserver(
|
|
self,
|
|
selector: #selector(profileWhitelistDidChange),
|
|
name: UserProfileNotifications.profileWhitelistDidChange,
|
|
object: nil,
|
|
)
|
|
NotificationCenter.default.addObserver(
|
|
self,
|
|
selector: #selector(registrationStateDidChange),
|
|
name: .registrationStateDidChange,
|
|
object: nil,
|
|
)
|
|
NotificationCenter.default.addObserver(
|
|
self,
|
|
selector: #selector(appExpiryDidChange),
|
|
name: AppExpiry.AppExpiryDidChange,
|
|
object: nil,
|
|
)
|
|
|
|
NotificationCenter.default.addObserver(
|
|
self,
|
|
selector: #selector(audioSessionInterrupted),
|
|
name: AVAudioSession.interruptionNotification,
|
|
object: AVAudioSession.sharedInstance(),
|
|
)
|
|
|
|
NotificationCenter.default.addObserver(
|
|
self,
|
|
selector: #selector(smsVerificationCodeRequested),
|
|
name: .smsVerificationCodeRequested,
|
|
object: nil,
|
|
)
|
|
SafetyTipsManager.startObservingDarwinNotifications()
|
|
|
|
AppEnvironment.shared.callService.callServiceState.addObserver(self, syncStateImmediately: false)
|
|
}
|
|
|
|
@objc
|
|
private func otherUsersProfileDidChange(_ notification: NSNotification) {
|
|
AssertIsOnMainThread()
|
|
|
|
guard
|
|
let address = notification.userInfo?[UserProfileNotifications.profileAddressKey] as? SignalServiceAddress,
|
|
address.isValid,
|
|
thread.recipientAddressesWithSneakyTransaction.contains(address)
|
|
else {
|
|
return
|
|
}
|
|
|
|
if thread is TSContactThread {
|
|
// update title with profile name
|
|
enqueueReload()
|
|
}
|
|
|
|
// Reload all cells if this is a group conversation,
|
|
// since we may need to update the sender names on the messages.
|
|
// Use a DebounceEvent to de-bounce.
|
|
if isGroupConversation {
|
|
otherUsersProfileDidChangeEvent?.requestNotify()
|
|
}
|
|
}
|
|
|
|
@objc
|
|
private func profileWhitelistDidChange(_ notification: NSNotification) {
|
|
AssertIsOnMainThread()
|
|
|
|
// If profile whitelist just changed, we may want to hide a profile whitelist offer.
|
|
if
|
|
let address = notification.userInfo?[UserProfileNotifications.profileAddressKey] as? SignalServiceAddress,
|
|
address.isValid,
|
|
thread.recipientAddressesWithSneakyTransaction.contains(address)
|
|
{
|
|
ensureBannerState()
|
|
showMessageRequestDialogIfRequired()
|
|
} else if
|
|
let groupId = notification.userInfo?[UserProfileNotifications.profileGroupIdKey] as? Data,
|
|
!groupId.isEmpty,
|
|
let groupThread = thread as? TSGroupThread,
|
|
groupThread.groupModel.groupId == groupId
|
|
{
|
|
ensureBannerState()
|
|
showMessageRequestDialogIfRequired()
|
|
}
|
|
}
|
|
|
|
@objc
|
|
private func blockListDidChange(_ notification: NSNotification) {
|
|
AssertIsOnMainThread()
|
|
|
|
ensureBannerState()
|
|
}
|
|
|
|
@objc
|
|
private func identityStateDidChange(_ notification: NSNotification) {
|
|
AssertIsOnMainThread()
|
|
|
|
enqueueReload()
|
|
ensureBannerState()
|
|
}
|
|
|
|
@objc
|
|
private func applicationWillEnterForeground(_ notification: NSNotification) {
|
|
AssertIsOnMainThread()
|
|
|
|
startReadTimer()
|
|
updateCellsVisible()
|
|
}
|
|
|
|
@objc
|
|
private func applicationDidEnterBackground(_ notification: NSNotification) {
|
|
AssertIsOnMainThread()
|
|
|
|
updateCellsVisible()
|
|
mediaCache.removeAllObjects()
|
|
cancelReadTimer()
|
|
}
|
|
|
|
@objc
|
|
private func applicationWillResignActive(_ notification: NSNotification) {
|
|
AssertIsOnMainThread()
|
|
|
|
finishRecordingVoiceMessage(sendImmediately: false)
|
|
self.isUserScrolling = false
|
|
self.isWaitingForDeceleration = false
|
|
saveDraft()
|
|
markVisibleMessagesAsRead()
|
|
mediaCache.removeAllObjects()
|
|
cancelReadTimer()
|
|
dismissPresentedViewControllerIfNecessary()
|
|
saveLastVisibleSortIdAndOnScreenPercentage()
|
|
|
|
self.dismissKeyBoard()
|
|
}
|
|
|
|
@objc
|
|
private func applicationDidBecomeActive(_ notification: NSNotification) {
|
|
AssertIsOnMainThread()
|
|
|
|
startReadTimer()
|
|
}
|
|
|
|
@objc
|
|
private func audioSessionInterrupted(_ notification: Notification) {
|
|
AssertIsOnMainThread()
|
|
|
|
finishRecordingVoiceMessage(sendImmediately: false)
|
|
}
|
|
|
|
@objc
|
|
private func registrationStateDidChange(_ notification: Notification) {
|
|
AssertIsOnMainThread()
|
|
ensureBottomViewType()
|
|
}
|
|
|
|
@objc
|
|
private func appExpiryDidChange(_ notification: Notification) {
|
|
AssertIsOnMainThread()
|
|
ensureBottomViewType()
|
|
}
|
|
|
|
@objc
|
|
private func smsVerificationCodeRequested(_ notification: NSNotification) {
|
|
AssertIsOnMainThread()
|
|
|
|
let db = DependenciesBridge.shared.db
|
|
let safetyTipsManager = SafetyTipsManager()
|
|
let timestamp: UInt64? = db.read { tx in
|
|
safetyTipsManager.lastVerificationCodeTimestampMsWithinExpiryTime(transaction: tx)
|
|
}
|
|
|
|
guard let timestamp else { return }
|
|
let actionSheetController = SafetyTipsSheet.makeSmsCodeRequestedSheet(
|
|
timestampMs: timestamp,
|
|
fromViewController: self,
|
|
)
|
|
present(actionSheetController, animated: true, completion: {
|
|
db.write { tx in
|
|
safetyTipsManager.removeVerificationCodeRequestedTimestampMs(transaction: tx)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// MARK: -
|
|
|
|
extension ConversationViewController: CallServiceStateObserver {
|
|
func didUpdateCall(from oldValue: SignalCall?, to newValue: SignalCall?) {
|
|
AssertIsOnMainThread()
|
|
updateBarButtonItems()
|
|
}
|
|
}
|