mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-23 22:55:00 +00:00
ChatControllerImpl Refactoring
This commit is contained in:
304
submodules/TelegramUI/Sources/Chat/ChatControllerOpenPeer.swift
Normal file
304
submodules/TelegramUI/Sources/Chat/ChatControllerOpenPeer.swift
Normal file
@@ -0,0 +1,304 @@
|
||||
import Foundation
|
||||
import UIKit
|
||||
import Postbox
|
||||
import SwiftSignalKit
|
||||
import Display
|
||||
import AsyncDisplayKit
|
||||
import TelegramCore
|
||||
import SafariServices
|
||||
import MobileCoreServices
|
||||
import Intents
|
||||
import LegacyComponents
|
||||
import TelegramPresentationData
|
||||
import TelegramUIPreferences
|
||||
import DeviceAccess
|
||||
import TextFormat
|
||||
import TelegramBaseController
|
||||
import AccountContext
|
||||
import TelegramStringFormatting
|
||||
import OverlayStatusController
|
||||
import DeviceLocationManager
|
||||
import ShareController
|
||||
import UrlEscaping
|
||||
import ContextUI
|
||||
import ComposePollUI
|
||||
import AlertUI
|
||||
import PresentationDataUtils
|
||||
import UndoUI
|
||||
import TelegramCallsUI
|
||||
import TelegramNotices
|
||||
import GameUI
|
||||
import ScreenCaptureDetection
|
||||
import GalleryUI
|
||||
import OpenInExternalAppUI
|
||||
import LegacyUI
|
||||
import InstantPageUI
|
||||
import LocationUI
|
||||
import BotPaymentsUI
|
||||
import DeleteChatPeerActionSheetItem
|
||||
import HashtagSearchUI
|
||||
import LegacyMediaPickerUI
|
||||
import Emoji
|
||||
import PeerAvatarGalleryUI
|
||||
import PeerInfoUI
|
||||
import RaiseToListen
|
||||
import UrlHandling
|
||||
import AvatarNode
|
||||
import AppBundle
|
||||
import LocalizedPeerData
|
||||
import PhoneNumberFormat
|
||||
import SettingsUI
|
||||
import UrlWhitelist
|
||||
import TelegramIntents
|
||||
import TooltipUI
|
||||
import StatisticsUI
|
||||
import MediaResources
|
||||
import GalleryData
|
||||
import ChatInterfaceState
|
||||
import InviteLinksUI
|
||||
import Markdown
|
||||
import TelegramPermissionsUI
|
||||
import Speak
|
||||
import TranslateUI
|
||||
import UniversalMediaPlayer
|
||||
import WallpaperBackgroundNode
|
||||
import ChatListUI
|
||||
import CalendarMessageScreen
|
||||
import ReactionSelectionNode
|
||||
import ReactionListContextMenuContent
|
||||
import AttachmentUI
|
||||
import AttachmentTextInputPanelNode
|
||||
import MediaPickerUI
|
||||
import ChatPresentationInterfaceState
|
||||
import Pasteboard
|
||||
import ChatSendMessageActionUI
|
||||
import ChatTextLinkEditUI
|
||||
import WebUI
|
||||
import PremiumUI
|
||||
import ImageTransparency
|
||||
import StickerPackPreviewUI
|
||||
import TextNodeWithEntities
|
||||
import EntityKeyboard
|
||||
import ChatTitleView
|
||||
import EmojiStatusComponent
|
||||
import ChatTimerScreen
|
||||
import MediaPasteboardUI
|
||||
import ChatListHeaderComponent
|
||||
import ChatControllerInteraction
|
||||
import FeaturedStickersScreen
|
||||
import ChatEntityKeyboardInputNode
|
||||
import StorageUsageScreen
|
||||
import AvatarEditorScreen
|
||||
import ChatScheduleTimeController
|
||||
import ICloudResources
|
||||
import StoryContainerScreen
|
||||
import MoreHeaderButton
|
||||
import VolumeButtons
|
||||
import ChatAvatarNavigationNode
|
||||
import ChatContextQuery
|
||||
import PeerReportScreen
|
||||
import PeerSelectionController
|
||||
import SaveToCameraRoll
|
||||
import ChatMessageDateAndStatusNode
|
||||
import ReplyAccessoryPanelNode
|
||||
import TextSelectionNode
|
||||
import ChatMessagePollBubbleContentNode
|
||||
import ChatMessageItem
|
||||
import ChatMessageItemImpl
|
||||
import ChatMessageItemView
|
||||
import ChatMessageItemCommon
|
||||
import ChatMessageAnimatedStickerItemNode
|
||||
import ChatMessageBubbleItemNode
|
||||
import ChatNavigationButton
|
||||
import WebsiteType
|
||||
import ChatQrCodeScreen
|
||||
import PeerInfoScreen
|
||||
import MediaEditorScreen
|
||||
import WallpaperGalleryScreen
|
||||
import WallpaperGridScreen
|
||||
import VideoMessageCameraScreen
|
||||
import TopMessageReactions
|
||||
import AudioWaveform
|
||||
import PeerNameColorScreen
|
||||
import ChatEmptyNode
|
||||
import ChatMediaInputStickerGridItem
|
||||
import AdsInfoScreen
|
||||
|
||||
extension ChatControllerImpl {
|
||||
func openPeer(peer: EnginePeer?, navigation: ChatControllerInteractionNavigateToPeer, fromMessage: MessageReference?, fromReactionMessageId: MessageId? = nil, expandAvatar: Bool = false, peerTypes: ReplyMarkupButtonAction.PeerTypes? = nil) {
|
||||
let _ = self.presentVoiceMessageDiscardAlert(action: {
|
||||
if case let .peer(currentPeerId) = self.chatLocation, peer?.id == currentPeerId {
|
||||
switch navigation {
|
||||
case let .info(params):
|
||||
var recommendedChannels = false
|
||||
if let params, params.switchToRecommendedChannels {
|
||||
recommendedChannels = true
|
||||
}
|
||||
self.navigationButtonAction(.openChatInfo(expandAvatar: expandAvatar, recommendedChannels: recommendedChannels))
|
||||
case let .chat(textInputState, _, _):
|
||||
if let textInputState = textInputState {
|
||||
self.updateChatPresentationInterfaceState(animated: true, interactive: true, {
|
||||
return ($0.updatedInterfaceState {
|
||||
return $0.withUpdatedComposeInputState(textInputState)
|
||||
}).updatedInputMode({ _ in
|
||||
return .text
|
||||
})
|
||||
})
|
||||
} else {
|
||||
self.playShakeAnimation()
|
||||
}
|
||||
case let .withBotStartPayload(botStart):
|
||||
self.updateChatPresentationInterfaceState(animated: true, interactive: true, {
|
||||
$0.updatedBotStartPayload(botStart.payload)
|
||||
})
|
||||
case .withAttachBot:
|
||||
self.presentAttachmentMenu(subject: .default)
|
||||
default:
|
||||
break
|
||||
}
|
||||
} else {
|
||||
if let peer = peer {
|
||||
do {
|
||||
var chatPeerId: PeerId?
|
||||
if let peer = self.presentationInterfaceState.renderedPeer?.chatMainPeer as? TelegramGroup {
|
||||
chatPeerId = peer.id
|
||||
} else if let peer = self.presentationInterfaceState.renderedPeer?.chatMainPeer as? TelegramChannel, case .group = peer.info, case .member = peer.participationStatus {
|
||||
chatPeerId = peer.id
|
||||
}
|
||||
|
||||
switch navigation {
|
||||
case .info, .default:
|
||||
let peerSignal: Signal<Peer?, NoError>
|
||||
if let messageId = fromMessage?.id {
|
||||
peerSignal = loadedPeerFromMessage(account: self.context.account, peerId: peer.id, messageId: messageId)
|
||||
} else {
|
||||
peerSignal = self.context.account.postbox.loadedPeerWithId(peer.id) |> map(Optional.init)
|
||||
}
|
||||
self.navigationActionDisposable.set((peerSignal |> take(1) |> deliverOnMainQueue).startStrict(next: { [weak self] peer in
|
||||
if let strongSelf = self, let peer = peer {
|
||||
var mode: PeerInfoControllerMode = .generic
|
||||
if let _ = fromMessage, let chatPeerId = chatPeerId {
|
||||
mode = .group(chatPeerId)
|
||||
}
|
||||
if let fromReactionMessageId = fromReactionMessageId {
|
||||
mode = .reaction(fromReactionMessageId)
|
||||
}
|
||||
if case let .info(params) = navigation, let params, params.switchToRecommendedChannels {
|
||||
mode = .recommendedChannels
|
||||
}
|
||||
var expandAvatar = expandAvatar
|
||||
if peer.smallProfileImage == nil {
|
||||
expandAvatar = false
|
||||
}
|
||||
if let validLayout = strongSelf.validLayout, validLayout.deviceMetrics.type == .tablet {
|
||||
expandAvatar = false
|
||||
}
|
||||
if let infoController = strongSelf.context.sharedContext.makePeerInfoController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, peer: peer, mode: mode, avatarInitiallyExpanded: expandAvatar, fromChat: false, requestsContext: nil) {
|
||||
strongSelf.effectiveNavigationController?.pushViewController(infoController)
|
||||
}
|
||||
}
|
||||
}))
|
||||
case let .chat(textInputState, subject, peekData):
|
||||
if let textInputState = textInputState {
|
||||
let _ = (ChatInterfaceState.update(engine: self.context.engine, peerId: peer.id, threadId: nil, { currentState in
|
||||
return currentState.withUpdatedComposeInputState(textInputState)
|
||||
})
|
||||
|> deliverOnMainQueue).startStandalone(completed: { [weak self] in
|
||||
if let strongSelf = self, let navigationController = strongSelf.effectiveNavigationController {
|
||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(peer), subject: subject, updateTextInputState: textInputState, peekData: peekData))
|
||||
}
|
||||
})
|
||||
} else {
|
||||
if case let .channel(channel) = peer, channel.flags.contains(.isForum) {
|
||||
self.effectiveNavigationController?.pushViewController(ChatListControllerImpl(context: self.context, location: .forum(peerId: channel.id), controlsHistoryPreload: false, enableDebugActions: false))
|
||||
} else {
|
||||
self.effectiveNavigationController?.pushViewController(ChatControllerImpl(context: self.context, chatLocation: .peer(id: peer.id), subject: subject))
|
||||
}
|
||||
}
|
||||
case let .withBotStartPayload(botStart):
|
||||
self.effectiveNavigationController?.pushViewController(ChatControllerImpl(context: self.context, chatLocation: .peer(id: peer.id), botStart: botStart))
|
||||
case let .withAttachBot(attachBotStart):
|
||||
if let navigationController = self.effectiveNavigationController {
|
||||
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(peer), attachBotStart: attachBotStart))
|
||||
}
|
||||
case let .withBotApp(botAppStart):
|
||||
if let navigationController = self.effectiveNavigationController {
|
||||
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(peer), botAppStart: botAppStart))
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
switch navigation {
|
||||
case .info:
|
||||
break
|
||||
case let .chat(textInputState, _, _):
|
||||
if let textInputState = textInputState {
|
||||
let controller = self.context.sharedContext.makePeerSelectionController(PeerSelectionControllerParams(context: self.context, updatedPresentationData: self.updatedPresentationData, requestPeerType: peerTypes.flatMap { $0.requestPeerTypes }, selectForumThreads: true))
|
||||
controller.peerSelected = { [weak self, weak controller] peer, threadId in
|
||||
let peerId = peer.id
|
||||
|
||||
if let strongSelf = self, let strongController = controller {
|
||||
if case let .peer(currentPeerId) = strongSelf.chatLocation, peerId == currentPeerId {
|
||||
strongSelf.updateChatPresentationInterfaceState(animated: true, interactive: true, {
|
||||
return ($0.updatedInterfaceState {
|
||||
return $0.withUpdatedComposeInputState(textInputState)
|
||||
}).updatedInputMode({ _ in
|
||||
return .text
|
||||
})
|
||||
})
|
||||
strongController.dismiss()
|
||||
} else {
|
||||
let _ = (ChatInterfaceState.update(engine: strongSelf.context.engine, peerId: peerId, threadId: threadId, { currentState in
|
||||
return currentState.withUpdatedComposeInputState(textInputState)
|
||||
})
|
||||
|> deliverOnMainQueue).startStandalone(completed: { [weak self] in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
strongSelf.updateChatPresentationInterfaceState(animated: false, interactive: true, { $0.updatedInterfaceState({ $0.withoutSelectionState() }) })
|
||||
|
||||
if let navigationController = strongSelf.effectiveNavigationController {
|
||||
let chatController: Signal<ChatController, NoError>
|
||||
if let threadId {
|
||||
chatController = chatControllerForForumThreadImpl(context: strongSelf.context, peerId: peerId, threadId: threadId)
|
||||
} else {
|
||||
chatController = .single(ChatControllerImpl(context: strongSelf.context, chatLocation: .peer(id: peerId)))
|
||||
}
|
||||
|
||||
let _ = (chatController
|
||||
|> deliverOnMainQueue).start(next: { [weak self, weak navigationController] chatController in
|
||||
guard let strongSelf = self, let navigationController else {
|
||||
return
|
||||
}
|
||||
var viewControllers = navigationController.viewControllers
|
||||
let lastController = viewControllers.last as! ViewController
|
||||
if threadId != nil {
|
||||
viewControllers.remove(at: viewControllers.count - 2)
|
||||
lastController.navigationPresentation = .modal
|
||||
}
|
||||
viewControllers.insert(chatController, at: viewControllers.count - 1)
|
||||
navigationController.setViewControllers(viewControllers, animated: false)
|
||||
|
||||
strongSelf.controllerNavigationDisposable.set((chatController.ready.get()
|
||||
|> filter { $0 }
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak lastController] _ in
|
||||
lastController?.dismiss()
|
||||
}))
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
self.chatDisplayNode.dismissInput()
|
||||
self.effectiveNavigationController?.pushViewController(controller)
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user