Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios

This commit is contained in:
Ilya Laktyushin
2022-10-22 00:28:54 +03:00
52 changed files with 1103 additions and 276 deletions

View File

@@ -265,6 +265,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
private var moreInfoNavigationButton: ChatNavigationButton?
private var peerView: PeerView?
private var threadInfo: EngineMessageHistoryThread.Info?
private var historyStateDisposable: Disposable?
@@ -520,6 +521,18 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
private var inviteRequestsContext: PeerInvitationImportersContext?
private var inviteRequestsDisposable = MetaDisposable()
private var overlayTitle: String? {
var title: String?
if let threadInfo = self.threadInfo {
title = threadInfo.title
} else if let peerView = self.peerView {
if let peer = peerViewMainPeer(peerView) {
title = EnginePeer(peer).displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder)
}
}
return title
}
public init(context: AccountContext, chatLocation: ChatLocation, chatLocationContextHolder: Atomic<ChatLocationContextHolder?> = Atomic<ChatLocationContextHolder?>(value: nil), subject: ChatControllerSubject? = nil, botStart: ChatControllerInitialBotStart? = nil, attachBotStart: ChatControllerInitialAttachBotStart? = nil, mode: ChatControllerPresentationMode = .standard(previewing: false), peekData: ChatPeekTimeout? = nil, peerNearbyData: ChatPeerNearbyData? = nil, chatListFilter: Int32? = nil, chatNavigationStack: [PeerId] = []) {
let _ = ChatControllerCount.modify { value in
return value + 1
@@ -3018,6 +3031,11 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
if case let .replyThread(replyThreadMessage) = strongSelf.chatLocation, replyThreadMessage.messageId == message.id {
return .none
}
if case .peer = strongSelf.chatLocation, let channel = strongSelf.presentationInterfaceState.renderedPeer?.peer as? TelegramChannel, channel.flags.contains(.isForum) {
if message.threadId == nil {
return .none
}
}
if canReplyInChat(strongSelf.presentationInterfaceState) {
return .reply
@@ -3038,7 +3056,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
case let .replyThread(replyThreadMessage):
let peerId = replyThreadMessage.messageId.peerId
strongSelf.navigateToMessage(from: nil, to: .index(MessageIndex(id: MessageId(peerId: peerId, namespace: 0, id: 0), timestamp: timestamp - Int32(NSTimeZone.local.secondsFromGMT()))), scrollPosition: .bottom(0.0), rememberInStack: false, animated: true, completion: nil)
strongSelf.navigateToMessage(from: nil, to: .index(MessageIndex(id: MessageId(peerId: peerId, namespace: 0, id: 0), timestamp: timestamp - Int32(NSTimeZone.local.secondsFromGMT()))), scrollPosition: .bottom(0.0), rememberInStack: false, forceInCurrentChat: true, animated: true, completion: nil)
case .feed:
//TODO:implement
break
@@ -4410,10 +4428,28 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
}))
self.peerDisposable.set((combineLatest(queue: Queue.mainQueue(), peerView.get(), onlineMemberCount, hasScheduledMessages, self.reportIrrelvantGeoNoticePromise.get(), displayedCountSignal)
|> deliverOnMainQueue).start(next: { [weak self] peerView, onlineMemberCount, hasScheduledMessages, peerReportNotice, pinnedCount in
let threadInfo: Signal<EngineMessageHistoryThread.Info?, NoError>
if let threadId = self.chatLocation.threadId {
let viewKey: PostboxViewKey = .messageHistoryThreadInfo(peerId: peerId, threadId: threadId)
threadInfo = context.account.postbox.combinedView(keys: [viewKey])
|> map { views -> EngineMessageHistoryThread.Info? in
guard let view = views.views[viewKey] as? MessageHistoryThreadInfoView else {
return nil
}
guard let data = view.info?.data.get(MessageHistoryThreadData.self) else {
return nil
}
return data.info
}
|> distinctUntilChanged
} else {
threadInfo = .single(nil)
}
self.peerDisposable.set((combineLatest(queue: Queue.mainQueue(), peerView.get(), onlineMemberCount, hasScheduledMessages, self.reportIrrelvantGeoNoticePromise.get(), displayedCountSignal, threadInfo)
|> deliverOnMainQueue).start(next: { [weak self] peerView, onlineMemberCount, hasScheduledMessages, peerReportNotice, pinnedCount, threadInfo in
if let strongSelf = self {
if strongSelf.peerView === peerView && strongSelf.reportIrrelvantGeoNotice == peerReportNotice && strongSelf.hasScheduledMessages == hasScheduledMessages {
if strongSelf.peerView === peerView && strongSelf.reportIrrelvantGeoNotice == peerReportNotice && strongSelf.hasScheduledMessages == hasScheduledMessages && strongSelf.threadInfo == threadInfo {
return
}
@@ -4456,6 +4492,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
let firstTime = strongSelf.peerView == nil
strongSelf.peerView = peerView
strongSelf.threadInfo = threadInfo
if wasGroupChannel != isGroupChannel {
if let isGroupChannel = isGroupChannel, isGroupChannel {
let (recentDisposable, _) = strongSelf.context.peerChannelMemberCategoriesContextsManager.recent(engine: strongSelf.context.engine, postbox: strongSelf.context.account.postbox, network: strongSelf.context.account.network, accountPeerId: context.account.peerId, peerId: peerView.peerId, updated: { _ in })
@@ -4469,7 +4506,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
}
if strongSelf.isNodeLoaded {
strongSelf.chatDisplayNode.peerView = peerView
strongSelf.chatDisplayNode.overlayTitle = strongSelf.overlayTitle
}
var peerIsMuted = false
if let notificationSettings = peerView.notificationSettings as? TelegramPeerNotificationSettings {
@@ -4843,9 +4880,10 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
let firstTime = strongSelf.peerView == nil
strongSelf.peerView = peerView
strongSelf.threadInfo = messageAndTopic.threadData?.info
if strongSelf.isNodeLoaded {
strongSelf.chatDisplayNode.peerView = peerView
strongSelf.chatDisplayNode.overlayTitle = strongSelf.overlayTitle
}
var peerDiscussionId: PeerId?
@@ -5567,9 +5605,23 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
private func topPinnedMessageSignal(latest: Bool) -> Signal<ChatPinnedMessage?, NoError> {
let topPinnedMessage: Signal<ChatPinnedMessage?, NoError>
var pinnedPeerId: EnginePeer.Id?
let threadId = self.chatLocation.threadId
switch self.chatLocation {
case let .peer(peerId):
case let .peer(id):
pinnedPeerId = id
case let .replyThread(message):
if message.isForumPost {
pinnedPeerId = self.chatLocation.peerId
}
default:
break
}
if let peerId = pinnedPeerId {
let topPinnedMessage: Signal<ChatPinnedMessage?, NoError>
struct ReferenceMessage {
var id: MessageId
var isScrolled: Bool
@@ -5613,7 +5665,14 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
location = .Initial(count: count)
}
return (chatHistoryViewForLocation(ChatHistoryLocationInput(content: location, id: 0), ignoreMessagesInTimestampRange: nil, context: context, chatLocation: .peer(id: peerId), chatLocationContextHolder: Atomic<ChatLocationContextHolder?>(value: nil), scheduled: false, fixedCombinedReadStates: nil, tagMask: MessageTags.pinned, appendMessagesFromTheSameGroup: false, additionalData: [], orderStatistics: .combinedLocation)
let chatLocation: ChatLocation
if let threadId {
chatLocation = .replyThread(message: ChatReplyThreadMessage(messageId: MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: Int32(clamping: threadId)), channelMessageId: nil, isChannelPost: false, isForumPost: true, maxMessage: nil, maxReadIncomingMessageId: nil, maxReadOutgoingMessageId: nil, unreadCount: 0, initialFilledHoles: IndexSet(), initialAnchor: .automatic, isNotAvailable: false))
} else {
chatLocation = .peer(id: peerId)
}
return (chatHistoryViewForLocation(ChatHistoryLocationInput(content: location, id: 0), ignoreMessagesInTimestampRange: nil, context: context, chatLocation: chatLocation, chatLocationContextHolder: Atomic<ChatLocationContextHolder?>(value: nil), scheduled: false, fixedCombinedReadStates: nil, tagMask: MessageTags.pinned, appendMessagesFromTheSameGroup: false, additionalData: [], orderStatistics: .combinedLocation)
|> castError(Bool.self)
|> mapToSignal { update -> Signal<ChatHistoryViewUpdate, Bool> in
switch update {
@@ -5833,10 +5892,11 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
return message
}
|> distinctUntilChanged
case .replyThread, .feed:
return topPinnedMessage
} else {
return .single(nil)
}
return topPinnedMessage
}
override public func loadDisplayNode() {
@@ -5902,7 +5962,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
})
}
self.chatDisplayNode.peerView = self.peerView
self.chatDisplayNode.overlayTitle = self.overlayTitle
let currentAccountPeer = self.context.account.postbox.loadedPeerWithId(self.context.account.peerId)
|> map { peer in
@@ -6243,7 +6303,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
switch strongSelf.chatLocation {
case let .replyThread(replyThreadMessage):
if isForum {
pinnedMessageId = nil
pinnedMessageId = topPinnedMessage?.message.id
pinnedMessage = topPinnedMessage
} else {
if isTopReplyThreadMessageShown {
pinnedMessageId = nil
@@ -8327,7 +8388,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}, unblockPeer: { [weak self] in
self?.unblockPeer()
}, pinMessage: { [weak self] messageId, contextController in
if let strongSelf = self, case let .peer(currentPeerId) = strongSelf.chatLocation {
if let strongSelf = self, let currentPeerId = strongSelf.chatLocation.peerId {
if let peer = strongSelf.presentationInterfaceState.renderedPeer?.peer {
if strongSelf.canManagePin() {
let pinAction: (Bool, Bool) -> Void = { notify, forThisPeerOnlyIfPossible in