Swiftgram/submodules/TelegramUI/Sources/NavigateToChatController.swift
2021-08-22 18:30:49 +03:00

199 lines
9.0 KiB
Swift

import Foundation
import UIKit
import Display
import TelegramCore
import Postbox
import AccountContext
import GalleryUI
import InstantPageUI
import ChatListUI
import PeerAvatarGalleryUI
import SettingsUI
public func navigateToChatControllerImpl(_ params: NavigateToChatControllerParams) {
var found = false
var isFirst = true
if params.useExisting {
for controller in params.navigationController.viewControllers.reversed() {
if let controller = controller as? ChatControllerImpl, controller.chatLocation == params.chatLocation && (controller.subject != .scheduledMessages || controller.subject == params.subject) {
if let updateTextInputState = params.updateTextInputState {
controller.updateTextInputState(updateTextInputState)
}
if let subject = params.subject, case let .message(messageId, _, timecode) = subject {
let navigationController = params.navigationController
let animated = params.animated
controller.navigateToMessage(messageLocation: .id(messageId, timecode), animated: isFirst, completion: { [weak navigationController, weak controller] in
if let navigationController = navigationController, let controller = controller {
let _ = navigationController.popToViewController(controller, animated: animated)
}
}, customPresentProgress: { [weak navigationController] c, a in
(navigationController?.viewControllers.last as? ViewController)?.present(c, in: .window(.root), with: a)
})
} else if params.scrollToEndIfExists && isFirst {
controller.scrollToEndOfHistory()
let _ = params.navigationController.popToViewController(controller, animated: params.animated)
params.completion(controller)
} else if let search = params.activateMessageSearch {
controller.activateSearch(domain: search.0, query: search.1)
let _ = params.navigationController.popToViewController(controller, animated: params.animated)
params.completion(controller)
} else if let reportReason = params.reportReason {
controller.beginReportSelection(reason: reportReason)
let _ = params.navigationController.popToViewController(controller, animated: params.animated)
params.completion(controller)
} else {
let _ = params.navigationController.popToViewController(controller, animated: params.animated)
params.completion(controller)
}
controller.purposefulAction = params.purposefulAction
if params.activateInput {
controller.activateInput()
}
if params.changeColors {
controller.presentThemeSelection()
}
if let botStart = params.botStart {
controller.updateChatPresentationInterfaceState(interactive: false, { state -> ChatPresentationInterfaceState in
return state.updatedBotStartPayload(botStart.payload)
})
}
found = true
break
}
isFirst = false
}
}
if !found {
let controller: ChatControllerImpl
if let chatController = params.chatController as? ChatControllerImpl {
controller = chatController
if let botStart = params.botStart {
controller.updateChatPresentationInterfaceState(interactive: false, { state -> ChatPresentationInterfaceState in
return state.updatedBotStartPayload(botStart.payload)
})
}
} else {
controller = ChatControllerImpl(context: params.context, chatLocation: params.chatLocation, chatLocationContextHolder: params.chatLocationContextHolder, subject: params.subject, botStart: params.botStart, peekData: params.peekData, peerNearbyData: params.peerNearbyData, chatListFilter: params.chatListFilter)
}
controller.purposefulAction = params.purposefulAction
if let search = params.activateMessageSearch {
controller.activateSearch(domain: search.0, query: search.1)
}
let resolvedKeepStack: Bool
switch params.keepStack {
case .default:
resolvedKeepStack = params.context.sharedContext.immediateExperimentalUISettings.keepChatNavigationStack
case .always:
resolvedKeepStack = true
case .never:
resolvedKeepStack = false
}
if resolvedKeepStack {
params.navigationController.pushViewController(controller, animated: params.animated, completion: {
params.completion(controller)
})
} else {
let viewControllers = params.navigationController.viewControllers.filter({ controller in
if controller is ChatListController {
if let parentGroupId = params.parentGroupId {
return parentGroupId != .root
} else {
return true
}
} else if controller is TabBarController {
return true
} else {
return false
}
})
if viewControllers.isEmpty {
params.navigationController.replaceAllButRootController(controller, animated: params.animated, animationOptions: params.options, completion: {
params.completion(controller)
})
} else {
params.navigationController.replaceControllersAndPush(controllers: viewControllers, controller: controller, animated: params.animated, options: params.options, completion: {
params.completion(controller)
})
}
}
if params.activateInput {
controller.activateInput()
}
if params.changeColors {
controller.presentThemeSelection()
}
}
params.navigationController.currentWindow?.forEachController { controller in
if let controller = controller as? NotificationContainerController {
controller.removeItems { item in
if let item = item as? ChatMessageNotificationItem {
for message in item.messages {
switch params.chatLocation {
case let .peer(peerId):
if message.id.peerId == peerId {
return true
}
case let .replyThread(replyThreadMessage):
if message.id.peerId == replyThreadMessage.messageId.peerId {
return true
}
}
}
}
return false
}
}
}
}
private func findOpaqueLayer(rootLayer: CALayer, layer: CALayer) -> Bool {
if layer.isHidden || layer.opacity < 0.8 {
return false
}
if !layer.isHidden, let backgroundColor = layer.backgroundColor, backgroundColor.alpha > 0.8 {
let coveringRect = layer.convert(layer.bounds, to: rootLayer)
let intersection = coveringRect.intersection(rootLayer.bounds)
let intersectionArea = intersection.width * intersection.height
let rootArea = rootLayer.bounds.width * rootLayer.bounds.height
if !rootArea.isZero && intersectionArea / rootArea > 0.8 {
return true
}
}
if let sublayers = layer.sublayers {
for sublayer in sublayers {
if findOpaqueLayer(rootLayer: rootLayer, layer: sublayer) {
return true
}
}
}
return false
}
public func isInlineControllerForChatNotificationOverlayPresentation(_ controller: ViewController) -> Bool {
if controller is InstantPageController {
return true
}
return false
}
public func isOverlayControllerForChatNotificationOverlayPresentation(_ controller: ContainableController) -> Bool {
if controller is GalleryController || controller is AvatarGalleryController || controller is WallpaperGalleryController || controller is InstantPageGalleryController || controller is InstantVideoController || controller is NavigationController {
return true
}
if controller.isViewLoaded {
if let backgroundColor = controller.view.backgroundColor, !backgroundColor.isEqual(UIColor.clear) {
return true
}
if findOpaqueLayer(rootLayer: controller.view.layer, layer: controller.view.layer) {
return true
}
}
return false
}