mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-17 20:00:38 +00:00
Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios
This commit is contained in:
commit
d8a1e46218
@ -1360,6 +1360,7 @@ private final class NotificationServiceHandler {
|
|||||||
Logger.shared.log("NotificationService \(episode)", "Will poll channel \(peerId)")
|
Logger.shared.log("NotificationService \(episode)", "Will poll channel \(peerId)")
|
||||||
|
|
||||||
pollSignal = standalonePollChannelOnce(
|
pollSignal = standalonePollChannelOnce(
|
||||||
|
accountPeerId: stateManager.accountPeerId,
|
||||||
postbox: stateManager.postbox,
|
postbox: stateManager.postbox,
|
||||||
network: stateManager.network,
|
network: stateManager.network,
|
||||||
peerId: peerId,
|
peerId: peerId,
|
||||||
|
|||||||
@ -379,10 +379,42 @@ public enum ChatControllerActivateInput {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final class NavigateToChatControllerParams {
|
public final class NavigateToChatControllerParams {
|
||||||
|
public enum Location {
|
||||||
|
case peer(EnginePeer)
|
||||||
|
case replyThread(ChatReplyThreadMessage)
|
||||||
|
|
||||||
|
public var peerId: EnginePeer.Id {
|
||||||
|
switch self {
|
||||||
|
case let .peer(peer):
|
||||||
|
return peer.id
|
||||||
|
case let .replyThread(message):
|
||||||
|
return message.messageId.peerId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public var threadId: Int64? {
|
||||||
|
switch self {
|
||||||
|
case .peer:
|
||||||
|
return nil
|
||||||
|
case let .replyThread(message):
|
||||||
|
return Int64(message.messageId.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public var asChatLocation: ChatLocation {
|
||||||
|
switch self {
|
||||||
|
case let .peer(peer):
|
||||||
|
return .peer(id: peer.id)
|
||||||
|
case let .replyThread(message):
|
||||||
|
return .replyThread(message: message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public let navigationController: NavigationController
|
public let navigationController: NavigationController
|
||||||
public let chatController: ChatController?
|
public let chatController: ChatController?
|
||||||
public let context: AccountContext
|
public let context: AccountContext
|
||||||
public let chatLocation: ChatLocation
|
public let chatLocation: Location
|
||||||
public let chatLocationContextHolder: Atomic<ChatLocationContextHolder?>
|
public let chatLocationContextHolder: Atomic<ChatLocationContextHolder?>
|
||||||
public let subject: ChatControllerSubject?
|
public let subject: ChatControllerSubject?
|
||||||
public let botStart: ChatControllerInitialBotStart?
|
public let botStart: ChatControllerInitialBotStart?
|
||||||
@ -407,7 +439,7 @@ public final class NavigateToChatControllerParams {
|
|||||||
public let setupController: (ChatController) -> Void
|
public let setupController: (ChatController) -> Void
|
||||||
public let completion: (ChatController) -> Void
|
public let completion: (ChatController) -> Void
|
||||||
|
|
||||||
public init(navigationController: NavigationController, chatController: ChatController? = nil, context: AccountContext, chatLocation: ChatLocation, chatLocationContextHolder: Atomic<ChatLocationContextHolder?> = Atomic<ChatLocationContextHolder?>(value: nil), subject: ChatControllerSubject? = nil, botStart: ChatControllerInitialBotStart? = nil, attachBotStart: ChatControllerInitialAttachBotStart? = nil, updateTextInputState: ChatTextInputState? = nil, activateInput: ChatControllerActivateInput? = nil, keepStack: NavigateToChatKeepStack = .default, useExisting: Bool = true, useBackAnimation: Bool = false, purposefulAction: (() -> Void)? = nil, scrollToEndIfExists: Bool = false, activateMessageSearch: (ChatSearchDomain, String)? = nil, peekData: ChatPeekTimeout? = nil, peerNearbyData: ChatPeerNearbyData? = nil, reportReason: ReportReason? = nil, animated: Bool = true, options: NavigationAnimationOptions = [], parentGroupId: PeerGroupId? = nil, chatListFilter: Int32? = nil, chatNavigationStack: [PeerId] = [], changeColors: Bool = false, setupController: @escaping (ChatController) -> Void = { _ in }, completion: @escaping (ChatController) -> Void = { _ in }) {
|
public init(navigationController: NavigationController, chatController: ChatController? = nil, context: AccountContext, chatLocation: Location, chatLocationContextHolder: Atomic<ChatLocationContextHolder?> = Atomic<ChatLocationContextHolder?>(value: nil), subject: ChatControllerSubject? = nil, botStart: ChatControllerInitialBotStart? = nil, attachBotStart: ChatControllerInitialAttachBotStart? = nil, updateTextInputState: ChatTextInputState? = nil, activateInput: ChatControllerActivateInput? = nil, keepStack: NavigateToChatKeepStack = .default, useExisting: Bool = true, useBackAnimation: Bool = false, purposefulAction: (() -> Void)? = nil, scrollToEndIfExists: Bool = false, activateMessageSearch: (ChatSearchDomain, String)? = nil, peekData: ChatPeekTimeout? = nil, peerNearbyData: ChatPeerNearbyData? = nil, reportReason: ReportReason? = nil, animated: Bool = true, options: NavigationAnimationOptions = [], parentGroupId: PeerGroupId? = nil, chatListFilter: Int32? = nil, chatNavigationStack: [PeerId] = [], changeColors: Bool = false, setupController: @escaping (ChatController) -> Void = { _ in }, completion: @escaping (ChatController) -> Void = { _ in }) {
|
||||||
self.navigationController = navigationController
|
self.navigationController = navigationController
|
||||||
self.chatController = chatController
|
self.chatController = chatController
|
||||||
self.chatLocationContextHolder = chatLocationContextHolder
|
self.chatLocationContextHolder = chatLocationContextHolder
|
||||||
|
|||||||
@ -457,9 +457,15 @@ func chatContextMenuItems(context: AccountContext, peerId: PeerId, promoInfo: Ch
|
|||||||
chatListController.present(textAlertController(context: context, title: nil, text: presentationData.strings.Login_UnknownError, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root))
|
chatListController.present(textAlertController(context: context, title: nil, text: presentationData.strings.Login_UnknownError, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root))
|
||||||
}
|
}
|
||||||
}, completed: {
|
}, completed: {
|
||||||
if let navigationController = (chatListController?.navigationController as? NavigationController) {
|
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peerId)))
|
|> deliverOnMainQueue).start(next: { peer in
|
||||||
|
guard let peer = peer else {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
if let navigationController = (chatListController?.navigationController as? NavigationController) {
|
||||||
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer)))
|
||||||
|
}
|
||||||
|
})
|
||||||
}))
|
}))
|
||||||
f(.default)
|
f(.default)
|
||||||
})))
|
})))
|
||||||
@ -709,22 +715,23 @@ func chatForumTopicMenuItems(context: AccountContext, peerId: PeerId, threadId:
|
|||||||
}
|
}
|
||||||
})))
|
})))
|
||||||
|
|
||||||
var canManage = false
|
var canOpenClose = false
|
||||||
if channel.flags.contains(.isCreator) {
|
if channel.flags.contains(.isCreator) {
|
||||||
canManage = true
|
canOpenClose = true
|
||||||
} else if channel.adminRights != nil {
|
} else if channel.hasPermission(.manageTopics) {
|
||||||
canManage = true
|
canOpenClose = true
|
||||||
} else if threadData.isOwnedByMe {
|
} else if threadData.isOwnedByMe {
|
||||||
canManage = true
|
canOpenClose = true
|
||||||
}
|
}
|
||||||
if canManage {
|
if canOpenClose {
|
||||||
//TODO:localize
|
//TODO:localize
|
||||||
items.append(.action(ContextMenuActionItem(text: threadData.isClosed ? "Restart" : "Close", icon: { theme in generateTintedImage(image: UIImage(bundleImageName: threadData.isClosed ? "Chat/Context Menu/Play": "Chat/Context Menu/Pause"), color: theme.contextMenu.primaryColor) }, action: { _, f in
|
items.append(.action(ContextMenuActionItem(text: threadData.isClosed ? "Restart" : "Close", icon: { theme in generateTintedImage(image: UIImage(bundleImageName: threadData.isClosed ? "Chat/Context Menu/Play": "Chat/Context Menu/Pause"), color: theme.contextMenu.primaryColor) }, action: { _, f in
|
||||||
f(.default)
|
f(.default)
|
||||||
|
|
||||||
let _ = context.engine.peers.setForumChannelTopicClosed(id: peerId, threadId: threadId, isClosed: !threadData.isClosed).start()
|
let _ = context.engine.peers.setForumChannelTopicClosed(id: peerId, threadId: threadId, isClosed: !threadData.isClosed).start()
|
||||||
})))
|
})))
|
||||||
|
}
|
||||||
|
if channel.hasPermission(.deleteAllMessages) {
|
||||||
items.append(.action(ContextMenuActionItem(text: strings.ChatList_Context_Delete, textColor: .destructive, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Delete"), color: theme.contextMenu.destructiveColor) }, action: { [weak chatListController] _, f in
|
items.append(.action(ContextMenuActionItem(text: strings.ChatList_Context_Delete, textColor: .destructive, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Delete"), color: theme.contextMenu.destructiveColor) }, action: { [weak chatListController] _, f in
|
||||||
f(.default)
|
f(.default)
|
||||||
|
|
||||||
|
|||||||
@ -1384,8 +1384,8 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let chatLocation: ChatLocation
|
let chatLocation: NavigateToChatControllerParams.Location
|
||||||
chatLocation = .peer(id: peer.id)
|
chatLocation = .peer(peer)
|
||||||
|
|
||||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: chatLocation, activateInput: (activateInput && !peer.isDeleted) ? .text : nil, scrollToEndIfExists: scrollToEndIfExists, animated: !scrollToEndIfExists, options: navigationAnimationOptions, parentGroupId: groupId._asGroup(), chatListFilter: strongSelf.chatListDisplayNode.containerNode.currentItemNode.chatListFilter?.id, completion: { [weak self] controller in
|
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: chatLocation, activateInput: (activateInput && !peer.isDeleted) ? .text : nil, scrollToEndIfExists: scrollToEndIfExists, animated: !scrollToEndIfExists, options: navigationAnimationOptions, parentGroupId: groupId._asGroup(), chatListFilter: strongSelf.chatListDisplayNode.containerNode.currentItemNode.chatListFilter?.id, completion: { [weak self] controller in
|
||||||
self?.chatListDisplayNode.containerNode.currentItemNode.clearHighlightAnimated(true)
|
self?.chatListDisplayNode.containerNode.currentItemNode.clearHighlightAnimated(true)
|
||||||
@ -1461,7 +1461,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
|||||||
self.chatListDisplayNode.requestOpenMessageFromSearch = { [weak self] peer, threadId, messageId, deactivateOnAction in
|
self.chatListDisplayNode.requestOpenMessageFromSearch = { [weak self] peer, threadId, messageId, deactivateOnAction in
|
||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
strongSelf.openMessageFromSearchDisposable.set((strongSelf.context.engine.peers.ensurePeerIsLocallyAvailable(peer: peer)
|
strongSelf.openMessageFromSearchDisposable.set((strongSelf.context.engine.peers.ensurePeerIsLocallyAvailable(peer: peer)
|
||||||
|> deliverOnMainQueue).start(next: { [weak strongSelf] actualPeerId in
|
|> deliverOnMainQueue).start(next: { [weak strongSelf] actualPeer in
|
||||||
if let strongSelf = strongSelf {
|
if let strongSelf = strongSelf {
|
||||||
if let navigationController = strongSelf.navigationController as? NavigationController {
|
if let navigationController = strongSelf.navigationController as? NavigationController {
|
||||||
var scrollToEndIfExists = false
|
var scrollToEndIfExists = false
|
||||||
@ -1475,7 +1475,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
|||||||
if let threadId = threadId {
|
if let threadId = threadId {
|
||||||
let _ = strongSelf.context.sharedContext.navigateToForumThread(context: strongSelf.context, peerId: peer.id, threadId: threadId, messageId: messageId, navigationController: navigationController, activateInput: nil, keepStack: .never).start()
|
let _ = strongSelf.context.sharedContext.navigateToForumThread(context: strongSelf.context, peerId: peer.id, threadId: threadId, messageId: messageId, navigationController: navigationController, activateInput: nil, keepStack: .never).start()
|
||||||
} else {
|
} else {
|
||||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(id: actualPeerId), subject: .message(id: .id(messageId), highlight: true, timecode: nil), purposefulAction: {
|
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(actualPeer), subject: .message(id: .id(messageId), highlight: true, timecode: nil), purposefulAction: {
|
||||||
if deactivateOnAction {
|
if deactivateOnAction {
|
||||||
self?.deactivateSearch(animated: false)
|
self?.deactivateSearch(animated: false)
|
||||||
}
|
}
|
||||||
@ -1508,7 +1508,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
|||||||
if let threadId = threadId {
|
if let threadId = threadId {
|
||||||
let _ = strongSelf.context.sharedContext.navigateToForumThread(context: strongSelf.context, peerId: peer.id, threadId: threadId, messageId: nil, navigationController: navigationController, activateInput: nil, keepStack: .never).start()
|
let _ = strongSelf.context.sharedContext.navigateToForumThread(context: strongSelf.context, peerId: peer.id, threadId: threadId, messageId: nil, navigationController: navigationController, activateInput: nil, keepStack: .never).start()
|
||||||
} else {
|
} else {
|
||||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(id: peer.id), purposefulAction: { [weak self] in
|
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(peer), purposefulAction: { [weak self] in
|
||||||
self?.deactivateSearch(animated: false)
|
self?.deactivateSearch(animated: false)
|
||||||
}, scrollToEndIfExists: scrollToEndIfExists, options: navigationAnimationOptions))
|
}, scrollToEndIfExists: scrollToEndIfExists, options: navigationAnimationOptions))
|
||||||
}
|
}
|
||||||
@ -2652,7 +2652,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
|||||||
|
|
||||||
sourceController?.beginMessageSearch("")
|
sourceController?.beginMessageSearch("")
|
||||||
})))
|
})))
|
||||||
} else if channel.hasPermission(.manageTopics) {
|
} else if channel.hasPermission(.createTopics) {
|
||||||
items.append(.separator)
|
items.append(.separator)
|
||||||
|
|
||||||
//TODO:localize
|
//TODO:localize
|
||||||
|
|||||||
@ -739,7 +739,7 @@ public enum ChatListSearchEntry: Comparable, Identifiable {
|
|||||||
index = .chatList(EngineChatList.Item.Index.ChatList(pinningIndex: nil, messageIndex: message.index))
|
index = .chatList(EngineChatList.Item.Index.ChatList(pinningIndex: nil, messageIndex: message.index))
|
||||||
case .forum:
|
case .forum:
|
||||||
if let threadId = message.threadId, let threadInfo = threadInfo {
|
if let threadId = message.threadId, let threadInfo = threadInfo {
|
||||||
chatThreadInfo = ChatListItemContent.ThreadInfo(id: threadId, info: threadInfo, isOwner: false, isClosed: false)
|
chatThreadInfo = ChatListItemContent.ThreadInfo(id: threadId, info: threadInfo, isOwnedByMe: false, isClosed: false)
|
||||||
index = .forum(pinnedIndex: .none, timestamp: message.index.timestamp, threadId: threadId, namespace: message.index.id.namespace, id: message.index.id.id)
|
index = .forum(pinnedIndex: .none, timestamp: message.index.timestamp, threadId: threadId, namespace: message.index.id.namespace, id: message.index.id.id)
|
||||||
} else {
|
} else {
|
||||||
index = .chatList( EngineChatList.Item.Index.ChatList(pinningIndex: nil, messageIndex: message.index))
|
index = .chatList( EngineChatList.Item.Index.ChatList(pinningIndex: nil, messageIndex: message.index))
|
||||||
@ -1522,7 +1522,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
|||||||
|
|
||||||
for thread in allAndFoundThreads {
|
for thread in allAndFoundThreads {
|
||||||
if let peer = thread.renderedPeer.peer, let threadData = thread.threadData, case let .forum(_, _, id, _, _) = thread.index {
|
if let peer = thread.renderedPeer.peer, let threadData = thread.threadData, case let .forum(_, _, id, _, _) = thread.index {
|
||||||
entries.append(.topic(peer, ChatListItemContent.ThreadInfo(id: id, info: threadData.info, isOwner: threadData.isOwnedByMe, isClosed: threadData.isClosed), index, presentationData.theme, presentationData.strings, .none))
|
entries.append(.topic(peer, ChatListItemContent.ThreadInfo(id: id, info: threadData.info, isOwnedByMe: threadData.isOwnedByMe, isClosed: threadData.isClosed), index, presentationData.theme, presentationData.strings, .none))
|
||||||
index += 1
|
index += 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -32,13 +32,13 @@ public enum ChatListItemContent {
|
|||||||
public struct ThreadInfo: Equatable {
|
public struct ThreadInfo: Equatable {
|
||||||
public var id: Int64
|
public var id: Int64
|
||||||
public var info: EngineMessageHistoryThread.Info
|
public var info: EngineMessageHistoryThread.Info
|
||||||
public var isOwner: Bool
|
public var isOwnedByMe: Bool
|
||||||
public var isClosed: Bool
|
public var isClosed: Bool
|
||||||
|
|
||||||
public init(id: Int64, info: EngineMessageHistoryThread.Info, isOwner: Bool, isClosed: Bool) {
|
public init(id: Int64, info: EngineMessageHistoryThread.Info, isOwnedByMe: Bool, isClosed: Bool) {
|
||||||
self.id = id
|
self.id = id
|
||||||
self.info = info
|
self.info = info
|
||||||
self.isOwner = isOwner
|
self.isOwnedByMe = isOwnedByMe
|
||||||
self.isClosed = isClosed
|
self.isClosed = isClosed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2010,9 +2010,9 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
|
|||||||
var canOpenClose = false
|
var canOpenClose = false
|
||||||
if channel.flags.contains(.isCreator) {
|
if channel.flags.contains(.isCreator) {
|
||||||
canOpenClose = true
|
canOpenClose = true
|
||||||
} else if channel.hasPermission(.pinMessages) {
|
} else if channel.hasPermission(.manageTopics) {
|
||||||
canOpenClose = true
|
canOpenClose = true
|
||||||
} else if let threadInfo = threadInfo, threadInfo.isOwner {
|
} else if let threadInfo = threadInfo, threadInfo.isOwnedByMe {
|
||||||
canOpenClose = true
|
canOpenClose = true
|
||||||
}
|
}
|
||||||
let canDelete = channel.hasPermission(.deleteAllMessages)
|
let canDelete = channel.hasPermission(.deleteAllMessages)
|
||||||
|
|||||||
@ -394,7 +394,7 @@ func chatListNodeEntriesForView(_ view: EngineChatList, state: ChatListNodeState
|
|||||||
isSelected = state.selectedPeerIds.contains(peerId)
|
isSelected = state.selectedPeerIds.contains(peerId)
|
||||||
}
|
}
|
||||||
|
|
||||||
result.append(.PeerEntry(index: offsetPinnedIndex(entry.index, offset: pinnedIndexOffset), presentationData: state.presentationData, messages: updatedMessages, readState: updatedCombinedReadState, isRemovedFromTotalUnreadCount: entry.isMuted, draftState: draftState, peer: entry.renderedPeer, threadInfo: entry.threadData.flatMap { ChatListItemContent.ThreadInfo(id: threadId, info: $0.info, isOwner: $0.isOwnedByMe, isClosed: $0.isClosed) }, presence: entry.presence, hasUnseenMentions: entry.hasUnseenMentions, hasUnseenReactions: entry.hasUnseenReactions, editing: state.editing, hasActiveRevealControls: hasActiveRevealControls, selected: isSelected, inputActivities: inputActivities, promoInfo: nil, hasFailedMessages: entry.hasFailed, isContact: entry.isContact, forumTopicData: entry.forumTopicData))
|
result.append(.PeerEntry(index: offsetPinnedIndex(entry.index, offset: pinnedIndexOffset), presentationData: state.presentationData, messages: updatedMessages, readState: updatedCombinedReadState, isRemovedFromTotalUnreadCount: entry.isMuted, draftState: draftState, peer: entry.renderedPeer, threadInfo: entry.threadData.flatMap { ChatListItemContent.ThreadInfo(id: threadId, info: $0.info, isOwnedByMe: $0.isOwnedByMe, isClosed: $0.isClosed) }, presence: entry.presence, hasUnseenMentions: entry.hasUnseenMentions, hasUnseenReactions: entry.hasUnseenReactions, editing: state.editing, hasActiveRevealControls: hasActiveRevealControls, selected: isSelected, inputActivities: inputActivities, promoInfo: nil, hasFailedMessages: entry.hasFailed, isContact: entry.isContact, forumTopicData: entry.forumTopicData))
|
||||||
}
|
}
|
||||||
if !view.hasLater {
|
if !view.hasLater {
|
||||||
var pinningIndex: UInt16 = UInt16(pinnedIndexOffset == 0 ? 0 : (pinnedIndexOffset - 1))
|
var pinningIndex: UInt16 = UInt16(pinnedIndexOffset == 0 ? 0 : (pinnedIndexOffset - 1))
|
||||||
@ -472,7 +472,7 @@ func chatListNodeEntriesForView(_ view: EngineChatList, state: ChatListNodeState
|
|||||||
isRemovedFromTotalUnreadCount: item.item.isMuted,
|
isRemovedFromTotalUnreadCount: item.item.isMuted,
|
||||||
draftState: draftState,
|
draftState: draftState,
|
||||||
peer: item.item.renderedPeer,
|
peer: item.item.renderedPeer,
|
||||||
threadInfo: item.item.threadData.flatMap { ChatListItemContent.ThreadInfo(id: threadId, info: $0.info, isOwner: $0.isOwnedByMe, isClosed: $0.isClosed) },
|
threadInfo: item.item.threadData.flatMap { ChatListItemContent.ThreadInfo(id: threadId, info: $0.info, isOwnedByMe: $0.isOwnedByMe, isClosed: $0.isClosed) },
|
||||||
presence: item.item.presence,
|
presence: item.item.presence,
|
||||||
hasUnseenMentions: item.item.hasUnseenMentions,
|
hasUnseenMentions: item.item.hasUnseenMentions,
|
||||||
hasUnseenReactions: item.item.hasUnseenReactions,
|
hasUnseenReactions: item.item.hasUnseenReactions,
|
||||||
|
|||||||
@ -345,14 +345,14 @@ public final class ChatPresentationInterfaceState: Equatable {
|
|||||||
public var title: String
|
public var title: String
|
||||||
public var icon: Int64?
|
public var icon: Int64?
|
||||||
public var iconColor: Int32
|
public var iconColor: Int32
|
||||||
public var isOwn: Bool
|
public var isOwnedByMe: Bool
|
||||||
public var isClosed: Bool
|
public var isClosed: Bool
|
||||||
|
|
||||||
public init(title: String, icon: Int64?, iconColor: Int32, isOwn: Bool, isClosed: Bool) {
|
public init(title: String, icon: Int64?, iconColor: Int32, isOwnedByMe: Bool, isClosed: Bool) {
|
||||||
self.title = title
|
self.title = title
|
||||||
self.icon = icon
|
self.icon = icon
|
||||||
self.iconColor = iconColor
|
self.iconColor = iconColor
|
||||||
self.isOwn = isOwn
|
self.isOwnedByMe = isOwnedByMe
|
||||||
self.isClosed = isClosed
|
self.isClosed = isClosed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,10 +22,18 @@ func contactContextMenuItems(context: AccountContext, peerId: EnginePeer.Id, con
|
|||||||
var items: [ContextMenuItem] = []
|
var items: [ContextMenuItem] = []
|
||||||
|
|
||||||
items.append(.action(ContextMenuActionItem(text: strings.ContactList_Context_SendMessage, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Message"), color: theme.contextMenu.primaryColor) }, action: { _, f in
|
items.append(.action(ContextMenuActionItem(text: strings.ContactList_Context_SendMessage, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Message"), color: theme.contextMenu.primaryColor) }, action: { _, f in
|
||||||
|
let _ = (context.engine.data.get(
|
||||||
|
TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)
|
||||||
|
)
|
||||||
|
|> deliverOnMainQueue).start(next: { peer in
|
||||||
|
guard let peer = peer else {
|
||||||
|
return
|
||||||
|
}
|
||||||
if let contactsController = contactsController, let navigationController = contactsController.navigationController as? NavigationController {
|
if let contactsController = contactsController, let navigationController = contactsController.navigationController as? NavigationController {
|
||||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peerId), peekData: nil))
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer), peekData: nil))
|
||||||
}
|
}
|
||||||
f(.default)
|
f(.default)
|
||||||
|
})
|
||||||
})))
|
})))
|
||||||
|
|
||||||
var canStartSecretChat = true
|
var canStartSecretChat = true
|
||||||
@ -38,9 +46,18 @@ func contactContextMenuItems(context: AccountContext, peerId: EnginePeer.Id, con
|
|||||||
let _ = (context.engine.peers.mostRecentSecretChat(id: peerId)
|
let _ = (context.engine.peers.mostRecentSecretChat(id: peerId)
|
||||||
|> deliverOnMainQueue).start(next: { currentPeerId in
|
|> deliverOnMainQueue).start(next: { currentPeerId in
|
||||||
if let currentPeerId = currentPeerId {
|
if let currentPeerId = currentPeerId {
|
||||||
if let contactsController = contactsController, let navigationController = (contactsController.navigationController as? NavigationController) {
|
let _ = (context.engine.data.get(
|
||||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: currentPeerId), peekData: nil))
|
TelegramEngine.EngineData.Item.Peer.Peer(id: currentPeerId)
|
||||||
|
)
|
||||||
|
|> deliverOnMainQueue).start(next: { peer in
|
||||||
|
guard let peer = peer else {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let contactsController = contactsController, let navigationController = (contactsController.navigationController as? NavigationController) {
|
||||||
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer), peekData: nil))
|
||||||
|
}
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
var createSignal = context.engine.peers.createSecretChat(peerId: peerId)
|
var createSignal = context.engine.peers.createSecretChat(peerId: peerId)
|
||||||
var cancelImpl: (() -> Void)?
|
var cancelImpl: (() -> Void)?
|
||||||
@ -73,9 +90,18 @@ func contactContextMenuItems(context: AccountContext, peerId: EnginePeer.Id, con
|
|||||||
|
|
||||||
createSecretChatDisposable.set((createSignal
|
createSecretChatDisposable.set((createSignal
|
||||||
|> deliverOnMainQueue).start(next: { peerId in
|
|> deliverOnMainQueue).start(next: { peerId in
|
||||||
if let navigationController = (contactsController?.navigationController as? NavigationController) {
|
let _ = (context.engine.data.get(
|
||||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peerId), peekData: nil))
|
TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)
|
||||||
|
)
|
||||||
|
|> deliverOnMainQueue).start(next: { peer in
|
||||||
|
guard let peer = peer else {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let navigationController = (contactsController?.navigationController as? NavigationController) {
|
||||||
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer), peekData: nil))
|
||||||
|
}
|
||||||
|
})
|
||||||
}, error: { error in
|
}, error: { error in
|
||||||
if let contactsController = contactsController {
|
if let contactsController = contactsController {
|
||||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
|
|||||||
@ -323,7 +323,7 @@ public class ContactsController: ViewController {
|
|||||||
scrollToEndIfExists = true
|
scrollToEndIfExists = true
|
||||||
}
|
}
|
||||||
|
|
||||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(id: peer.id), purposefulAction: { [weak self] in
|
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(EnginePeer(peer)), purposefulAction: { [weak self] in
|
||||||
if fromSearch {
|
if fromSearch {
|
||||||
self?.deactivateSearch(animated: false)
|
self?.deactivateSearch(animated: false)
|
||||||
self?.switchToChatsController?()
|
self?.switchToChatsController?()
|
||||||
|
|||||||
@ -64,9 +64,9 @@ public final class HashtagSearchController: TelegramBaseController {
|
|||||||
}, additionalCategorySelected: { _ in
|
}, additionalCategorySelected: { _ in
|
||||||
}, messageSelected: { [weak self] peer, _, message, _ in
|
}, messageSelected: { [weak self] peer, _, message, _ in
|
||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
strongSelf.openMessageFromSearchDisposable.set((strongSelf.context.engine.peers.ensurePeerIsLocallyAvailable(peer: peer) |> deliverOnMainQueue).start(next: { actualPeerId in
|
strongSelf.openMessageFromSearchDisposable.set((strongSelf.context.engine.peers.ensurePeerIsLocallyAvailable(peer: peer) |> deliverOnMainQueue).start(next: { actualPeer in
|
||||||
if let strongSelf = self, let navigationController = strongSelf.navigationController as? NavigationController {
|
if let strongSelf = self, let navigationController = strongSelf.navigationController as? NavigationController {
|
||||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(id: actualPeerId), subject: message.id.peerId == actualPeerId ? .message(id: .id(message.id), highlight: true, timecode: nil) : nil, keepStack: .always))
|
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(actualPeer), subject: message.id.peerId == actualPeer.id ? .message(id: .id(message.id), highlight: true, timecode: nil) : nil, keepStack: .always))
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
strongSelf.controllerNode.listNode.clearHighlightAnimated(true)
|
strongSelf.controllerNode.listNode.clearHighlightAnimated(true)
|
||||||
|
|||||||
@ -153,7 +153,7 @@ public final class InstantPageController: ViewController {
|
|||||||
(self?.navigationController as? NavigationController)?.pushViewController(c)
|
(self?.navigationController as? NavigationController)?.pushViewController(c)
|
||||||
}, openPeer: { [weak self] peer in
|
}, openPeer: { [weak self] peer in
|
||||||
if let strongSelf = self, let navigationController = strongSelf.navigationController as? NavigationController {
|
if let strongSelf = self, let navigationController = strongSelf.navigationController as? NavigationController {
|
||||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(id: peer.id), animated: true))
|
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(peer), animated: true))
|
||||||
}
|
}
|
||||||
}, navigateBack: { [weak self] in
|
}, navigateBack: { [weak self] in
|
||||||
if let strongSelf = self, let controllers = strongSelf.navigationController?.viewControllers.reversed() {
|
if let strongSelf = self, let controllers = strongSelf.navigationController?.viewControllers.reversed() {
|
||||||
|
|||||||
@ -1330,21 +1330,21 @@ final class InstantPageControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
switch navigation {
|
switch navigation {
|
||||||
case let .chat(_, subject, peekData):
|
case let .chat(_, subject, peekData):
|
||||||
if let navigationController = strongSelf.getNavigationController() {
|
if let navigationController = strongSelf.getNavigationController() {
|
||||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(id: peer.id), subject: subject, peekData: peekData))
|
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(peer), subject: subject, peekData: peekData))
|
||||||
}
|
}
|
||||||
case let .withBotStartPayload(botStart):
|
case let .withBotStartPayload(botStart):
|
||||||
if let navigationController = strongSelf.getNavigationController() {
|
if let navigationController = strongSelf.getNavigationController() {
|
||||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(id: peer.id), botStart: botStart, keepStack: .always))
|
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(peer), botStart: botStart, keepStack: .always))
|
||||||
}
|
}
|
||||||
case let .withAttachBot(attachBotStart):
|
case let .withAttachBot(attachBotStart):
|
||||||
if let navigationController = strongSelf.getNavigationController() {
|
if let navigationController = strongSelf.getNavigationController() {
|
||||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(id: peer.id), attachBotStart: attachBotStart))
|
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(peer), attachBotStart: attachBotStart))
|
||||||
}
|
}
|
||||||
case .info:
|
case .info:
|
||||||
let _ = (strongSelf.context.account.postbox.loadedPeerWithId(peer.id)
|
let _ = (strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peer.id))
|
||||||
|> deliverOnMainQueue).start(next: { peer in
|
|> deliverOnMainQueue).start(next: { peer in
|
||||||
if let strongSelf = self {
|
if let strongSelf = self, let peer = peer {
|
||||||
if let controller = strongSelf.context.sharedContext.makePeerInfoController(context: strongSelf.context, updatedPresentationData: nil, peer: peer, mode: .generic, avatarInitiallyExpanded: false, fromChat: false, requestsContext: nil) {
|
if let controller = strongSelf.context.sharedContext.makePeerInfoController(context: strongSelf.context, updatedPresentationData: nil, peer: peer._asPeer(), mode: .generic, avatarInitiallyExpanded: false, fromChat: false, requestsContext: nil) {
|
||||||
strongSelf.getNavigationController()?.pushViewController(controller)
|
strongSelf.getNavigationController()?.pushViewController(controller)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -472,9 +472,16 @@ public final class InviteLinkViewController: ViewController {
|
|||||||
self.isOpaque = false
|
self.isOpaque = false
|
||||||
|
|
||||||
self.interaction = InviteLinkViewInteraction(context: context, openPeer: { [weak self] peerId in
|
self.interaction = InviteLinkViewInteraction(context: context, openPeer: { [weak self] peerId in
|
||||||
if let strongSelf = self, let navigationController = strongSelf.controller?.navigationController as? NavigationController {
|
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peerId), keepStack: .always))
|
|> deliverOnMainQueue).start(next: { peer in
|
||||||
|
guard let peer = peer else {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let strongSelf = self, let navigationController = strongSelf.controller?.navigationController as? NavigationController {
|
||||||
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer), keepStack: .always))
|
||||||
|
}
|
||||||
|
})
|
||||||
}, copyLink: { [weak self] invite in
|
}, copyLink: { [weak self] invite in
|
||||||
UIPasteboard.general.string = invite.link
|
UIPasteboard.general.string = invite.link
|
||||||
|
|
||||||
|
|||||||
@ -383,7 +383,7 @@ public func inviteRequestsController(context: AccountContext, updatedPresentatio
|
|||||||
}
|
}
|
||||||
navigateToChatImpl = { [weak controller] peer in
|
navigateToChatImpl = { [weak controller] peer in
|
||||||
if let navigationController = controller?.navigationController as? NavigationController {
|
if let navigationController = controller?.navigationController as? NavigationController {
|
||||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peer.id), keepStack: .always))
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer), keepStack: .always))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dismissInputImpl = { [weak controller] in
|
dismissInputImpl = { [weak controller] in
|
||||||
|
|||||||
@ -369,7 +369,7 @@ public func channelBlacklistController(context: AccountContext, updatedPresentat
|
|||||||
actionSheet?.dismissAnimated()
|
actionSheet?.dismissAnimated()
|
||||||
if participant.peer is TelegramChannel {
|
if participant.peer is TelegramChannel {
|
||||||
if let navigationController = getNavigationControllerImpl?() {
|
if let navigationController = getNavigationControllerImpl?() {
|
||||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: participant.peer.id)))
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(EnginePeer(participant.peer))))
|
||||||
}
|
}
|
||||||
} else if let infoController = context.sharedContext.makePeerInfoController(context: context, updatedPresentationData: nil, peer: participant.peer, mode: .generic, avatarInitiallyExpanded: false, fromChat: false, requestsContext: nil) {
|
} else if let infoController = context.sharedContext.makePeerInfoController(context: context, updatedPresentationData: nil, peer: participant.peer, mode: .generic, avatarInitiallyExpanded: false, fromChat: false, requestsContext: nil) {
|
||||||
pushControllerImpl?(infoController)
|
pushControllerImpl?(infoController)
|
||||||
|
|||||||
@ -637,10 +637,17 @@ public func channelDiscussionGroupSetupController(context: AccountContext, updat
|
|||||||
controller?.present(c, in: .window(.root), with: a)
|
controller?.present(c, in: .window(.root), with: a)
|
||||||
}
|
}
|
||||||
navigateToGroupImpl = { [weak controller] groupId in
|
navigateToGroupImpl = { [weak controller] groupId in
|
||||||
|
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: groupId))
|
||||||
|
|> deliverOnMainQueue).start(next: { peer in
|
||||||
|
guard let peer = peer else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
guard let navigationController = controller?.navigationController as? NavigationController else {
|
guard let navigationController = controller?.navigationController as? NavigationController else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: groupId), keepStack: .always))
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer), keepStack: .always))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
return controller
|
return controller
|
||||||
}
|
}
|
||||||
|
|||||||
@ -963,9 +963,15 @@ public func channelPermissionsController(context: AccountContext, updatedPresent
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
navigateToChatControllerImpl = { [weak controller] peerId in
|
navigateToChatControllerImpl = { [weak controller] peerId in
|
||||||
if let controller = controller, let navigationController = controller.navigationController as? NavigationController {
|
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peerId), keepStack: .always))
|
|> deliverOnMainQueue).start(next: { peer in
|
||||||
|
guard let peer = peer else {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
if let controller = controller, let navigationController = controller.navigationController as? NavigationController {
|
||||||
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer), keepStack: .always))
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
dismissInputImpl = { [weak controller] in
|
dismissInputImpl = { [weak controller] in
|
||||||
controller?.view.endEditing(true)
|
controller?.view.endEditing(true)
|
||||||
|
|||||||
@ -2251,22 +2251,41 @@ public func channelVisibilityController(context: AccountContext, updatedPresenta
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
if filteredPeerIds.isEmpty {
|
if filteredPeerIds.isEmpty {
|
||||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, chatController: nil, context: context, chatLocation: .peer(id: peerId), keepStack: .never, animated: true))
|
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||||
|
|> deliverOnMainQueue).start(next: { peer in
|
||||||
|
guard let peer = peer else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, chatController: nil, context: context, chatLocation: .peer(peer), keepStack: .never, animated: true))
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
selectionController.displayProgress = true
|
selectionController.displayProgress = true
|
||||||
let _ = (context.engine.peers.addChannelMembers(peerId: peerId, memberIds: filteredPeerIds)
|
let _ = (context.engine.peers.addChannelMembers(peerId: peerId, memberIds: filteredPeerIds)
|
||||||
|> deliverOnMainQueue).start(error: { [weak selectionController] _ in
|
|> deliverOnMainQueue).start(error: { [weak selectionController] _ in
|
||||||
|
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||||
|
|> deliverOnMainQueue).start(next: { peer in
|
||||||
|
guard let peer = peer else {
|
||||||
|
return
|
||||||
|
}
|
||||||
guard let selectionController = selectionController, let navigationController = selectionController.navigationController as? NavigationController else {
|
guard let selectionController = selectionController, let navigationController = selectionController.navigationController as? NavigationController else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, chatController: nil, context: context, chatLocation: .peer(id: peerId), keepStack: .never, animated: true))
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, chatController: nil, context: context, chatLocation: .peer(peer), keepStack: .never, animated: true))
|
||||||
|
})
|
||||||
}, completed: { [weak selectionController] in
|
}, completed: { [weak selectionController] in
|
||||||
|
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||||
|
|> deliverOnMainQueue).start(next: { peer in
|
||||||
|
guard let peer = peer else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
guard let selectionController = selectionController, let navigationController = selectionController.navigationController as? NavigationController else {
|
guard let selectionController = selectionController, let navigationController = selectionController.navigationController as? NavigationController else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, chatController: nil, context: context, chatLocation: .peer(id: peerId), keepStack: .never, animated: true))
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, chatController: nil, context: context, chatLocation: .peer(peer), keepStack: .never, animated: true))
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@ -1249,9 +1249,16 @@ public func deviceContactInfoController(context: AccountContext, updatedPresenta
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
openChatImpl = { [weak controller] peerId in
|
openChatImpl = { [weak controller] peerId in
|
||||||
if let navigationController = (controller?.navigationController as? NavigationController) {
|
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peerId)))
|
|> deliverOnMainQueue).start(next: { peer in
|
||||||
|
guard let peer = peer else {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let navigationController = (controller?.navigationController as? NavigationController) {
|
||||||
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer)))
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
replaceControllerImpl = { [weak controller] value in
|
replaceControllerImpl = { [weak controller] value in
|
||||||
(controller?.navigationController as? NavigationController)?.replaceTopController(value, animated: true)
|
(controller?.navigationController as? NavigationController)?.replaceTopController(value, animated: true)
|
||||||
|
|||||||
@ -486,9 +486,16 @@ public func groupStickerPackSetupController(context: AccountContext, updatedPres
|
|||||||
presentControllerImpl?(StickerPackScreen(context: context, updatedPresentationData: updatedPresentationData, mainStickerPack: packReference, stickerPacks: [packReference], parentNavigationController: controller?.navigationController as? NavigationController), nil)
|
presentControllerImpl?(StickerPackScreen(context: context, updatedPresentationData: updatedPresentationData, mainStickerPack: packReference, stickerPacks: [packReference], parentNavigationController: controller?.navigationController as? NavigationController), nil)
|
||||||
}
|
}
|
||||||
navigateToChatControllerImpl = { [weak controller] peerId in
|
navigateToChatControllerImpl = { [weak controller] peerId in
|
||||||
if let controller = controller, let navigationController = controller.navigationController as? NavigationController {
|
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peerId)))
|
|> deliverOnMainQueue).start(next: { peer in
|
||||||
|
guard let peer = peer else {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let controller = controller, let navigationController = controller.navigationController as? NavigationController {
|
||||||
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer)))
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
dismissImpl = { [weak controller] in
|
dismissImpl = { [weak controller] in
|
||||||
dismissInputImpl?()
|
dismissInputImpl?()
|
||||||
|
|||||||
@ -615,7 +615,7 @@ public func peersNearbyController(context: AccountContext) -> ViewController {
|
|||||||
}
|
}
|
||||||
navigateToChatImpl = { [weak controller] peer in
|
navigateToChatImpl = { [weak controller] peer in
|
||||||
if let navigationController = controller?.navigationController as? NavigationController {
|
if let navigationController = controller?.navigationController as? NavigationController {
|
||||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peer.id), keepStack: .always, purposefulAction: {}, peekData: nil))
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer), keepStack: .always, purposefulAction: {}, peekData: nil))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pushControllerImpl = { [weak controller] c in
|
pushControllerImpl = { [weak controller] c in
|
||||||
|
|||||||
@ -92,6 +92,11 @@ public final class Transaction {
|
|||||||
return self.postbox!.messageHistoryThreadHoleIndexTable.closest(peerId: peerId, threadId: threadId, namespace: namespace, space: .everywhere, range: 1 ... (Int32.max - 1))
|
return self.postbox!.messageHistoryThreadHoleIndexTable.closest(peerId: peerId, threadId: threadId, namespace: namespace, space: .everywhere, range: 1 ... (Int32.max - 1))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func getThreadIndexHole(peerId: PeerId, threadId: Int64, namespace: MessageId.Namespace, containing id: MessageId.Id) -> [MessageHistoryHoleSpace: ClosedRange<MessageId.Id>] {
|
||||||
|
assert(!self.disposed)
|
||||||
|
return self.postbox!.messageHistoryThreadHoleIndexTable.containing(threadId: threadId, id: MessageId(peerId: peerId, namespace: namespace, id: id))
|
||||||
|
}
|
||||||
|
|
||||||
public func getThreadMessageCount(peerId: PeerId, threadId: Int64, namespace: MessageId.Namespace, fromIdExclusive: Int32?, toIndex: MessageIndex) -> Int? {
|
public func getThreadMessageCount(peerId: PeerId, threadId: Int64, namespace: MessageId.Namespace, fromIdExclusive: Int32?, toIndex: MessageIndex) -> Int? {
|
||||||
assert(!self.disposed)
|
assert(!self.disposed)
|
||||||
let fromIndex: MessageIndex?
|
let fromIndex: MessageIndex?
|
||||||
|
|||||||
@ -64,10 +64,18 @@ final class MutableUnreadMessageCountsView: MutablePostboxView {
|
|||||||
case let .totalInGroup(groupId):
|
case let .totalInGroup(groupId):
|
||||||
return .totalInGroup(groupId, postbox.messageHistoryMetadataTable.getTotalUnreadState(groupId: groupId))
|
return .totalInGroup(groupId, postbox.messageHistoryMetadataTable.getTotalUnreadState(groupId: groupId))
|
||||||
case let .peer(peerId):
|
case let .peer(peerId):
|
||||||
|
if let peer = postbox.peerTable.get(peerId), postbox.seedConfiguration.peerSummaryIsThreadBased(peer) {
|
||||||
|
var count: Int32 = 0
|
||||||
|
if let summary = postbox.peerThreadsSummaryTable.get(peerId: peerId) {
|
||||||
|
count = summary.effectiveUnreadCount
|
||||||
|
}
|
||||||
|
return .peer(peerId, CombinedPeerReadState(states: [(0, .idBased(maxIncomingReadId: 1, maxOutgoingReadId: 1, maxKnownId: 1, count: count, markedUnread: false))]))
|
||||||
|
} else {
|
||||||
return .peer(peerId, postbox.readStateTable.getCombinedState(peerId))
|
return .peer(peerId, postbox.readStateTable.getCombinedState(peerId))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func replay(postbox: PostboxImpl, transaction: PostboxTransaction) -> Bool {
|
func replay(postbox: PostboxImpl, transaction: PostboxTransaction) -> Bool {
|
||||||
var updated = false
|
var updated = false
|
||||||
@ -105,6 +113,16 @@ final class MutableUnreadMessageCountsView: MutablePostboxView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
case let .peer(peerId, _):
|
case let .peer(peerId, _):
|
||||||
|
if let peer = postbox.peerTable.get(peerId), postbox.seedConfiguration.peerSummaryIsThreadBased(peer) {
|
||||||
|
if transaction.updatedPeerThreadsSummaries.contains(peerId) {
|
||||||
|
var count: Int32 = 0
|
||||||
|
if let summary = postbox.peerThreadsSummaryTable.get(peerId: peerId) {
|
||||||
|
count = summary.effectiveUnreadCount
|
||||||
|
}
|
||||||
|
self.entries[i] = .peer(peerId, CombinedPeerReadState(states: [(0, .idBased(maxIncomingReadId: 1, maxOutgoingReadId: 1, maxKnownId: 1, count: count, markedUnread: false))]))
|
||||||
|
updated = true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
if transaction.alteredInitialPeerCombinedReadStates[peerId] != nil {
|
if transaction.alteredInitialPeerCombinedReadStates[peerId] != nil {
|
||||||
self.entries[i] = .peer(peerId, postbox.readStateTable.getCombinedState(peerId))
|
self.entries[i] = .peer(peerId, postbox.readStateTable.getCombinedState(peerId))
|
||||||
updated = true
|
updated = true
|
||||||
@ -112,6 +130,7 @@ final class MutableUnreadMessageCountsView: MutablePostboxView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return updated
|
return updated
|
||||||
}
|
}
|
||||||
|
|||||||
@ -696,7 +696,7 @@ private final class QrCodeScanScreenNode: ViewControllerTracingNode, UIScrollVie
|
|||||||
guard let strongSelf = self else {
|
guard let strongSelf = self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(id: peer.id), subject: nil, keepStack: .always, peekData: nil, completion: { [weak navigationController] _ in
|
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(peer), subject: nil, keepStack: .always, peekData: nil, completion: { [weak navigationController] _ in
|
||||||
if let navigationController = navigationController {
|
if let navigationController = navigationController {
|
||||||
var viewControllers = navigationController.viewControllers
|
var viewControllers = navigationController.viewControllers
|
||||||
viewControllers = viewControllers.filter { controller in
|
viewControllers = viewControllers.filter { controller in
|
||||||
|
|||||||
@ -356,10 +356,19 @@ public func deleteAccountOptionsController(context: AccountContext, navigationCo
|
|||||||
supportPeerDisposable.set((supportPeer.get()
|
supportPeerDisposable.set((supportPeer.get()
|
||||||
|> take(1)
|
|> take(1)
|
||||||
|> deliverOnMainQueue).start(next: { peerId in
|
|> deliverOnMainQueue).start(next: { peerId in
|
||||||
if let peerId = peerId, let navigationController = navigationController {
|
guard let peerId = peerId else {
|
||||||
dismissImpl?()
|
return
|
||||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peerId)))
|
|
||||||
}
|
}
|
||||||
|
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||||
|
|> deliverOnMainQueue).start(next: { peer in
|
||||||
|
guard let peer = peer else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if let navigationController = navigationController {
|
||||||
|
dismissImpl?()
|
||||||
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer)))
|
||||||
|
}
|
||||||
|
})
|
||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
])
|
])
|
||||||
|
|||||||
@ -229,10 +229,19 @@ public func logoutOptionsController(context: AccountContext, navigationControlle
|
|||||||
supportPeerDisposable.set((supportPeer.get()
|
supportPeerDisposable.set((supportPeer.get()
|
||||||
|> take(1)
|
|> take(1)
|
||||||
|> deliverOnMainQueue).start(next: { peerId in
|
|> deliverOnMainQueue).start(next: { peerId in
|
||||||
if let peerId = peerId, let navigationController = navigationController {
|
guard let peerId = peerId else {
|
||||||
dismissImpl?()
|
return
|
||||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peerId)))
|
|
||||||
}
|
}
|
||||||
|
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||||
|
|> deliverOnMainQueue).start(next: { peer in
|
||||||
|
guard let peer = peer else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if let navigationController = navigationController {
|
||||||
|
dismissImpl?()
|
||||||
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer)))
|
||||||
|
}
|
||||||
|
})
|
||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
]), nil)
|
]), nil)
|
||||||
|
|||||||
@ -1322,9 +1322,16 @@ public func installedStickerPacksController(context: AccountContext, mode: Insta
|
|||||||
(controller?.navigationController as? NavigationController)?.pushViewController(c)
|
(controller?.navigationController as? NavigationController)?.pushViewController(c)
|
||||||
}
|
}
|
||||||
navigateToChatControllerImpl = { [weak controller] peerId in
|
navigateToChatControllerImpl = { [weak controller] peerId in
|
||||||
if let controller = controller, let navigationController = controller.navigationController as? NavigationController {
|
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peerId)))
|
|> deliverOnMainQueue).start(next: { peer in
|
||||||
|
guard let peer = peer else {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let controller = controller, let navigationController = controller.navigationController as? NavigationController {
|
||||||
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer)))
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
dismissImpl = { [weak controller] in
|
dismissImpl = { [weak controller] in
|
||||||
controller?.dismiss()
|
controller?.dismiss()
|
||||||
|
|||||||
@ -416,9 +416,15 @@ public func themePickerController(context: AccountContext, focusOnItemTag: Theme
|
|||||||
openAccentColorPickerImpl?(themeReference, create)
|
openAccentColorPickerImpl?(themeReference, create)
|
||||||
}, editTheme: { theme in
|
}, editTheme: { theme in
|
||||||
let controller = editThemeController(context: context, mode: .edit(theme), navigateToChat: { peerId in
|
let controller = editThemeController(context: context, mode: .edit(theme), navigateToChat: { peerId in
|
||||||
if let navigationController = getNavigationControllerImpl?() {
|
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peerId)))
|
|> deliverOnMainQueue).start(next: { peer in
|
||||||
|
guard let peer = peer else {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
if let navigationController = getNavigationControllerImpl?() {
|
||||||
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer)))
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
pushControllerImpl?(controller)
|
pushControllerImpl?(controller)
|
||||||
}, editCurrentTheme: {
|
}, editCurrentTheme: {
|
||||||
@ -438,9 +444,15 @@ public func themePickerController(context: AccountContext, focusOnItemTag: Theme
|
|||||||
|> deliverOnMainQueue).start(next: { themeReference in
|
|> deliverOnMainQueue).start(next: { themeReference in
|
||||||
if case let .cloud(cloudTheme) = themeReference, cloudTheme.theme.settings?.isEmpty ?? true {
|
if case let .cloud(cloudTheme) = themeReference, cloudTheme.theme.settings?.isEmpty ?? true {
|
||||||
let controller = editThemeController(context: context, mode: .edit(cloudTheme), navigateToChat: { peerId in
|
let controller = editThemeController(context: context, mode: .edit(cloudTheme), navigateToChat: { peerId in
|
||||||
if let navigationController = getNavigationControllerImpl?() {
|
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peerId)))
|
|> deliverOnMainQueue).start(next: { peer in
|
||||||
|
guard let peer = peer else {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
if let navigationController = getNavigationControllerImpl?() {
|
||||||
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer)))
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
pushControllerImpl?(controller)
|
pushControllerImpl?(controller)
|
||||||
} else {
|
} else {
|
||||||
@ -463,9 +475,15 @@ public func themePickerController(context: AccountContext, focusOnItemTag: Theme
|
|||||||
}
|
}
|
||||||
|> deliverOnMainQueue).start(next: { themeReference in
|
|> deliverOnMainQueue).start(next: { themeReference in
|
||||||
let controller = editThemeController(context: context, mode: .create(nil, nil), navigateToChat: { peerId in
|
let controller = editThemeController(context: context, mode: .create(nil, nil), navigateToChat: { peerId in
|
||||||
if let navigationController = getNavigationControllerImpl?() {
|
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peerId)))
|
|> deliverOnMainQueue).start(next: { peer in
|
||||||
|
guard let peer = peer else {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
if let navigationController = getNavigationControllerImpl?() {
|
||||||
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer)))
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
pushControllerImpl?(controller)
|
pushControllerImpl?(controller)
|
||||||
})
|
})
|
||||||
@ -525,9 +543,15 @@ public func themePickerController(context: AccountContext, focusOnItemTag: Theme
|
|||||||
if theme.theme.isCreator {
|
if theme.theme.isCreator {
|
||||||
items.append(.action(ContextMenuActionItem(text: presentationData.strings.Appearance_EditTheme, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/ApplyTheme"), color: theme.contextMenu.primaryColor) }, action: { c, f in
|
items.append(.action(ContextMenuActionItem(text: presentationData.strings.Appearance_EditTheme, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/ApplyTheme"), color: theme.contextMenu.primaryColor) }, action: { c, f in
|
||||||
let controller = editThemeController(context: context, mode: .edit(theme), navigateToChat: { peerId in
|
let controller = editThemeController(context: context, mode: .edit(theme), navigateToChat: { peerId in
|
||||||
if let navigationController = getNavigationControllerImpl?() {
|
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peerId)))
|
|> deliverOnMainQueue).start(next: { peer in
|
||||||
|
guard let peer = peer else {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
if let navigationController = getNavigationControllerImpl?() {
|
||||||
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer)))
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
c.dismiss(completion: {
|
c.dismiss(completion: {
|
||||||
@ -555,9 +579,15 @@ public func themePickerController(context: AccountContext, focusOnItemTag: Theme
|
|||||||
let controller = ThemeAccentColorController(context: context, mode: .edit(settings: nil, theme: theme, wallpaper: wallpaper, generalThemeReference: reference.generalThemeReference, defaultThemeReference: nil, create: true, completion: { result, settings in
|
let controller = ThemeAccentColorController(context: context, mode: .edit(settings: nil, theme: theme, wallpaper: wallpaper, generalThemeReference: reference.generalThemeReference, defaultThemeReference: nil, create: true, completion: { result, settings in
|
||||||
let controller = editThemeController(context: context, mode: .create(result, settings
|
let controller = editThemeController(context: context, mode: .create(result, settings
|
||||||
), navigateToChat: { peerId in
|
), navigateToChat: { peerId in
|
||||||
if let navigationController = getNavigationControllerImpl?() {
|
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peerId)))
|
|> deliverOnMainQueue).start(next: { peer in
|
||||||
|
guard let peer = peer else {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
if let navigationController = getNavigationControllerImpl?() {
|
||||||
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer)))
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
updateControllersImpl?({ controllers in
|
updateControllersImpl?({ controllers in
|
||||||
var controllers = controllers
|
var controllers = controllers
|
||||||
@ -761,9 +791,15 @@ public func themePickerController(context: AccountContext, focusOnItemTag: Theme
|
|||||||
if cloudTheme.theme.isCreator && cloudThemeExists {
|
if cloudTheme.theme.isCreator && cloudThemeExists {
|
||||||
items.append(.action(ContextMenuActionItem(text: presentationData.strings.Appearance_EditTheme, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/ApplyTheme"), color: theme.contextMenu.primaryColor) }, action: { c, f in
|
items.append(.action(ContextMenuActionItem(text: presentationData.strings.Appearance_EditTheme, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/ApplyTheme"), color: theme.contextMenu.primaryColor) }, action: { c, f in
|
||||||
let controller = editThemeController(context: context, mode: .edit(cloudTheme), navigateToChat: { peerId in
|
let controller = editThemeController(context: context, mode: .edit(cloudTheme), navigateToChat: { peerId in
|
||||||
if let navigationController = getNavigationControllerImpl?() {
|
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peerId)))
|
|> deliverOnMainQueue).start(next: { peer in
|
||||||
|
guard let peer = peer else {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
if let navigationController = getNavigationControllerImpl?() {
|
||||||
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer)))
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
c.dismiss(completion: {
|
c.dismiss(completion: {
|
||||||
@ -796,9 +832,15 @@ public func themePickerController(context: AccountContext, focusOnItemTag: Theme
|
|||||||
}
|
}
|
||||||
let controller = ThemeAccentColorController(context: context, mode: .edit(settings: settings, theme: theme, wallpaper: wallpaper, generalThemeReference: effectiveThemeReference.generalThemeReference, defaultThemeReference: nil, create: true, completion: { result, settings in
|
let controller = ThemeAccentColorController(context: context, mode: .edit(settings: settings, theme: theme, wallpaper: wallpaper, generalThemeReference: effectiveThemeReference.generalThemeReference, defaultThemeReference: nil, create: true, completion: { result, settings in
|
||||||
let controller = editThemeController(context: context, mode: .create(hasSettings ? nil : result, hasSettings ? settings : nil), navigateToChat: { peerId in
|
let controller = editThemeController(context: context, mode: .create(hasSettings ? nil : result, hasSettings ? settings : nil), navigateToChat: { peerId in
|
||||||
if let navigationController = getNavigationControllerImpl?() {
|
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peerId)))
|
|> deliverOnMainQueue).start(next: { peer in
|
||||||
|
guard let peer = peer else {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
if let navigationController = getNavigationControllerImpl?() {
|
||||||
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer)))
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
updateControllersImpl?({ controllers in
|
updateControllersImpl?({ controllers in
|
||||||
var controllers = controllers
|
var controllers = controllers
|
||||||
|
|||||||
@ -522,9 +522,15 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
|
|||||||
})
|
})
|
||||||
}, editTheme: { theme in
|
}, editTheme: { theme in
|
||||||
let controller = editThemeController(context: context, mode: .edit(theme), navigateToChat: { peerId in
|
let controller = editThemeController(context: context, mode: .edit(theme), navigateToChat: { peerId in
|
||||||
if let navigationController = getNavigationControllerImpl?() {
|
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peerId)))
|
|> deliverOnMainQueue).start(next: { peer in
|
||||||
|
guard let peer = peer else {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
if let navigationController = getNavigationControllerImpl?() {
|
||||||
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer)))
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
pushControllerImpl?(controller)
|
pushControllerImpl?(controller)
|
||||||
}, themeContextAction: { isCurrent, reference, node, gesture in
|
}, themeContextAction: { isCurrent, reference, node, gesture in
|
||||||
@ -583,9 +589,15 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
|
|||||||
if theme.theme.isCreator {
|
if theme.theme.isCreator {
|
||||||
items.append(.action(ContextMenuActionItem(text: presentationData.strings.Appearance_EditTheme, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/ApplyTheme"), color: theme.contextMenu.primaryColor) }, action: { c, f in
|
items.append(.action(ContextMenuActionItem(text: presentationData.strings.Appearance_EditTheme, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/ApplyTheme"), color: theme.contextMenu.primaryColor) }, action: { c, f in
|
||||||
let controller = editThemeController(context: context, mode: .edit(theme), navigateToChat: { peerId in
|
let controller = editThemeController(context: context, mode: .edit(theme), navigateToChat: { peerId in
|
||||||
if let navigationController = getNavigationControllerImpl?() {
|
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peerId)))
|
|> deliverOnMainQueue).start(next: { peer in
|
||||||
|
guard let peer = peer else {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
if let navigationController = getNavigationControllerImpl?() {
|
||||||
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer)))
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
c.dismiss(completion: {
|
c.dismiss(completion: {
|
||||||
@ -613,9 +625,15 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
|
|||||||
let controller = ThemeAccentColorController(context: context, mode: .edit(settings: nil, theme: theme, wallpaper: wallpaper, generalThemeReference: reference.generalThemeReference, defaultThemeReference: nil, create: true, completion: { result, settings in
|
let controller = ThemeAccentColorController(context: context, mode: .edit(settings: nil, theme: theme, wallpaper: wallpaper, generalThemeReference: reference.generalThemeReference, defaultThemeReference: nil, create: true, completion: { result, settings in
|
||||||
let controller = editThemeController(context: context, mode: .create(result, settings
|
let controller = editThemeController(context: context, mode: .create(result, settings
|
||||||
), navigateToChat: { peerId in
|
), navigateToChat: { peerId in
|
||||||
if let navigationController = getNavigationControllerImpl?() {
|
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peerId)))
|
|> deliverOnMainQueue).start(next: { peer in
|
||||||
|
guard let peer = peer else {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
if let navigationController = getNavigationControllerImpl?() {
|
||||||
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer)))
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
updateControllersImpl?({ controllers in
|
updateControllersImpl?({ controllers in
|
||||||
var controllers = controllers
|
var controllers = controllers
|
||||||
@ -817,9 +835,15 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
|
|||||||
if cloudTheme.theme.isCreator && cloudThemeExists {
|
if cloudTheme.theme.isCreator && cloudThemeExists {
|
||||||
items.append(.action(ContextMenuActionItem(text: presentationData.strings.Appearance_EditTheme, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/ApplyTheme"), color: theme.contextMenu.primaryColor) }, action: { c, f in
|
items.append(.action(ContextMenuActionItem(text: presentationData.strings.Appearance_EditTheme, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/ApplyTheme"), color: theme.contextMenu.primaryColor) }, action: { c, f in
|
||||||
let controller = editThemeController(context: context, mode: .edit(cloudTheme), navigateToChat: { peerId in
|
let controller = editThemeController(context: context, mode: .edit(cloudTheme), navigateToChat: { peerId in
|
||||||
if let navigationController = getNavigationControllerImpl?() {
|
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peerId)))
|
|> deliverOnMainQueue).start(next: { peer in
|
||||||
|
guard let peer = peer else {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
if let navigationController = getNavigationControllerImpl?() {
|
||||||
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer)))
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
c.dismiss(completion: {
|
c.dismiss(completion: {
|
||||||
@ -852,9 +876,15 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
|
|||||||
}
|
}
|
||||||
let controller = ThemeAccentColorController(context: context, mode: .edit(settings: settings, theme: theme, wallpaper: wallpaper, generalThemeReference: effectiveThemeReference.generalThemeReference, defaultThemeReference: nil, create: true, completion: { result, settings in
|
let controller = ThemeAccentColorController(context: context, mode: .edit(settings: settings, theme: theme, wallpaper: wallpaper, generalThemeReference: effectiveThemeReference.generalThemeReference, defaultThemeReference: nil, create: true, completion: { result, settings in
|
||||||
let controller = editThemeController(context: context, mode: .create(hasSettings ? nil : result, hasSettings ? settings : nil), navigateToChat: { peerId in
|
let controller = editThemeController(context: context, mode: .create(hasSettings ? nil : result, hasSettings ? settings : nil), navigateToChat: { peerId in
|
||||||
if let navigationController = getNavigationControllerImpl?() {
|
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peerId)))
|
|> deliverOnMainQueue).start(next: { peer in
|
||||||
|
guard let peer = peer else {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
if let navigationController = getNavigationControllerImpl?() {
|
||||||
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer)))
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
updateControllersImpl?({ controllers in
|
updateControllersImpl?({ controllers in
|
||||||
var controllers = controllers
|
var controllers = controllers
|
||||||
|
|||||||
@ -514,9 +514,16 @@ public func channelStatsController(context: AccountContext, updatedPresentationD
|
|||||||
var items: [ContextMenuItem] = []
|
var items: [ContextMenuItem] = []
|
||||||
items.append(.action(ContextMenuActionItem(text: presentationData.strings.SharedMedia_ViewInChat, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/GoToMessage"), color: theme.contextMenu.primaryColor) }, action: { [weak controller] c, _ in
|
items.append(.action(ContextMenuActionItem(text: presentationData.strings.SharedMedia_ViewInChat, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/GoToMessage"), color: theme.contextMenu.primaryColor) }, action: { [weak controller] c, _ in
|
||||||
c.dismiss(completion: {
|
c.dismiss(completion: {
|
||||||
if let navigationController = controller?.navigationController as? NavigationController {
|
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peerId), subject: .message(id: .id(messageId), highlight: true, timecode: nil)))
|
|> deliverOnMainQueue).start(next: { peer in
|
||||||
|
guard let peer = peer else {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let navigationController = controller?.navigationController as? NavigationController {
|
||||||
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer), subject: .message(id: .id(messageId), highlight: true, timecode: nil)))
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})))
|
})))
|
||||||
|
|
||||||
|
|||||||
@ -877,10 +877,15 @@ public func groupStatsController(context: AccountContext, updatedPresentationDat
|
|||||||
}
|
}
|
||||||
openPeerHistoryImpl = { [weak controller] participantPeerId in
|
openPeerHistoryImpl = { [weak controller] participantPeerId in
|
||||||
if let navigationController = controller?.navigationController as? NavigationController {
|
if let navigationController = controller?.navigationController as? NavigationController {
|
||||||
let _ = (context.account.postbox.loadedPeerWithId(participantPeerId)
|
let _ = (context.engine.data.get(
|
||||||
|> take(1)
|
TelegramEngine.EngineData.Item.Peer.Peer(id: peerId),
|
||||||
|> deliverOnMainQueue).start(next: { peer in
|
TelegramEngine.EngineData.Item.Peer.Peer(id: participantPeerId)
|
||||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, chatController: nil, context: context, chatLocation: .peer(id: peerId), subject: nil, botStart: nil, updateTextInputState: nil, keepStack: .always, useExisting: false, purposefulAction: nil, scrollToEndIfExists: false, activateMessageSearch: (.member(peer), ""), animated: true))
|
)
|
||||||
|
|> deliverOnMainQueue).start(next: { chatPeer, peer in
|
||||||
|
guard let chatPeer, let peer else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, chatController: nil, context: context, chatLocation: .peer(chatPeer), subject: nil, botStart: nil, updateTextInputState: nil, keepStack: .always, useExisting: false, purposefulAction: nil, scrollToEndIfExists: false, activateMessageSearch: (.member(peer._asPeer()), ""), animated: true))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -259,9 +259,17 @@ public func messageStatsController(context: AccountContext, messageId: MessageId
|
|||||||
controller?.clearItemNodesHighlight(animated: true)
|
controller?.clearItemNodesHighlight(animated: true)
|
||||||
}
|
}
|
||||||
navigateToMessageImpl = { [weak controller] messageId in
|
navigateToMessageImpl = { [weak controller] messageId in
|
||||||
if let navigationController = controller?.navigationController as? NavigationController {
|
let _ = (context.engine.data.get(
|
||||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: messageId.peerId), subject: .message(id: .id(messageId), highlight: true, timecode: nil), keepStack: .always, useExisting: false, purposefulAction: {}, peekData: nil))
|
TelegramEngine.EngineData.Item.Peer.Peer(id: messageId.peerId)
|
||||||
|
)
|
||||||
|
|> deliverOnMainQueue).start(next: { peer in
|
||||||
|
guard let peer = peer else {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
if let navigationController = controller?.navigationController as? NavigationController {
|
||||||
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer), subject: .message(id: .id(messageId), highlight: true, timecode: nil), keepStack: .always, useExisting: false, purposefulAction: {}, peekData: nil))
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
return controller
|
return controller
|
||||||
}
|
}
|
||||||
|
|||||||
@ -149,7 +149,7 @@ public final class StickerPackPreviewController: ViewController, StandalonePrese
|
|||||||
}
|
}
|
||||||
if let peer = peer, let parentNavigationController = strongSelf.parentNavigationController {
|
if let peer = peer, let parentNavigationController = strongSelf.parentNavigationController {
|
||||||
strongSelf.dismiss()
|
strongSelf.dismiss()
|
||||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: parentNavigationController, context: strongSelf.context, chatLocation: .peer(id: peer.id), animated: true))
|
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: parentNavigationController, context: strongSelf.context, chatLocation: .peer(EnginePeer(peer)), animated: true))
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
}, actionPerformed: self.actionPerformed)
|
}, actionPerformed: self.actionPerformed)
|
||||||
|
|||||||
@ -1732,7 +1732,7 @@ public final class StickerPackScreenImpl: ViewController {
|
|||||||
}
|
}
|
||||||
if let peer = peer, let parentNavigationController = strongSelf.parentNavigationController {
|
if let peer = peer, let parentNavigationController = strongSelf.parentNavigationController {
|
||||||
strongSelf.dismiss()
|
strongSelf.dismiss()
|
||||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: parentNavigationController, context: strongSelf.context, chatLocation: .peer(id: peer.id), animated: true))
|
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: parentNavigationController, context: strongSelf.context, chatLocation: .peer(EnginePeer(peer)), animated: true))
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
|
|||||||
@ -1694,7 +1694,7 @@ public final class VoiceChatControllerImpl: ViewController, VoiceChatController
|
|||||||
let context = strongSelf.context
|
let context = strongSelf.context
|
||||||
strongSelf.controller?.dismiss(completion: {
|
strongSelf.controller?.dismiss(completion: {
|
||||||
Queue.mainQueue().after(0.3) {
|
Queue.mainQueue().after(0.3) {
|
||||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peer.id), keepStack: .always, purposefulAction: {}, peekData: nil))
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(EnginePeer(peer)), keepStack: .always, purposefulAction: {}, peekData: nil))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -2671,7 +2671,13 @@ public final class VoiceChatControllerImpl: ViewController, VoiceChatController
|
|||||||
let context = strongSelf.context
|
let context = strongSelf.context
|
||||||
strongSelf.controller?.dismiss(completion: {
|
strongSelf.controller?.dismiss(completion: {
|
||||||
Queue.mainQueue().justDispatch {
|
Queue.mainQueue().justDispatch {
|
||||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: context.account.peerId), keepStack: .always, purposefulAction: {}, peekData: nil))
|
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: context.account.peerId))
|
||||||
|
|> deliverOnMainQueue).start(next: { peer in
|
||||||
|
guard let peer = peer else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer), keepStack: .always, purposefulAction: {}, peekData: nil))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@ -137,6 +137,11 @@ struct HoleFromPreviousState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum StateResetForumTopics {
|
||||||
|
case result(LoadMessageHistoryThreadsResult)
|
||||||
|
case error(PeerId)
|
||||||
|
}
|
||||||
|
|
||||||
struct AccountMutableState {
|
struct AccountMutableState {
|
||||||
let initialState: AccountInitialState
|
let initialState: AccountInitialState
|
||||||
let branchOperationIndex: Int
|
let branchOperationIndex: Int
|
||||||
@ -153,7 +158,7 @@ struct AccountMutableState {
|
|||||||
var namespacesWithHolesFromPreviousState: [PeerId: [MessageId.Namespace: HoleFromPreviousState]]
|
var namespacesWithHolesFromPreviousState: [PeerId: [MessageId.Namespace: HoleFromPreviousState]]
|
||||||
var updatedOutgoingUniqueMessageIds: [Int64: Int32]
|
var updatedOutgoingUniqueMessageIds: [Int64: Int32]
|
||||||
|
|
||||||
var resetForumTopicLists: [PeerId: [MessageHistoryThreadData]] = [:]
|
var resetForumTopicLists: [PeerId: StateResetForumTopics] = [:]
|
||||||
|
|
||||||
var storedMessagesByPeerIdAndTimestamp: [PeerId: Set<MessageIndex>]
|
var storedMessagesByPeerIdAndTimestamp: [PeerId: Set<MessageIndex>]
|
||||||
var displayAlerts: [(text: String, isDropAuth: Bool)] = []
|
var displayAlerts: [(text: String, isDropAuth: Bool)] = []
|
||||||
|
|||||||
@ -6,6 +6,7 @@ public enum TelegramChannelPermission {
|
|||||||
case sendMessages
|
case sendMessages
|
||||||
case pinMessages
|
case pinMessages
|
||||||
case manageTopics
|
case manageTopics
|
||||||
|
case createTopics
|
||||||
case inviteMembers
|
case inviteMembers
|
||||||
case editAllMessages
|
case editAllMessages
|
||||||
case deleteAllMessages
|
case deleteAllMessages
|
||||||
@ -68,6 +69,23 @@ public extension TelegramChannel {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
case .manageTopics:
|
case .manageTopics:
|
||||||
|
if self.flags.contains(.isCreator) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if self.adminRights == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if let adminRights = self.adminRights, adminRights.rights.contains(.canManageTopics) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if let bannedRights = self.bannedRights, bannedRights.flags.contains(.banManageTopics) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if let defaultBannedRights = self.defaultBannedRights, defaultBannedRights.flags.contains(.banManageTopics) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
case .createTopics:
|
||||||
if self.flags.contains(.isCreator) {
|
if self.flags.contains(.isCreator) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|||||||
@ -433,16 +433,69 @@ func _internal_setChannelForumMode(account: Account, peerId: PeerId, isForum: Bo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct LoadMessageHistoryThreadsResult {
|
||||||
|
struct Item {
|
||||||
|
var threadId: Int64
|
||||||
|
var data: MessageHistoryThreadData
|
||||||
|
var topMessage: Int32
|
||||||
|
var unreadMentionsCount: Int32
|
||||||
|
var unreadReactionsCount: Int32
|
||||||
|
var index: StoredPeerThreadCombinedState.Index?
|
||||||
|
|
||||||
|
init(
|
||||||
|
threadId: Int64,
|
||||||
|
data: MessageHistoryThreadData,
|
||||||
|
topMessage: Int32,
|
||||||
|
unreadMentionsCount: Int32,
|
||||||
|
unreadReactionsCount: Int32,
|
||||||
|
index: StoredPeerThreadCombinedState.Index
|
||||||
|
) {
|
||||||
|
self.threadId = threadId
|
||||||
|
self.data = data
|
||||||
|
self.topMessage = topMessage
|
||||||
|
self.unreadMentionsCount = unreadMentionsCount
|
||||||
|
self.unreadReactionsCount = unreadReactionsCount
|
||||||
|
self.index = index
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var peerId: PeerId
|
||||||
|
var items: [Item]
|
||||||
|
var pinnedThreadIds: [Int64]?
|
||||||
|
var combinedState: PeerThreadCombinedState
|
||||||
|
var messages: [StoreMessage]
|
||||||
|
var users: [Api.User]
|
||||||
|
var chats: [Api.Chat]
|
||||||
|
|
||||||
|
init(
|
||||||
|
peerId: PeerId,
|
||||||
|
items: [Item],
|
||||||
|
messages: [StoreMessage],
|
||||||
|
pinnedThreadIds: [Int64]?,
|
||||||
|
combinedState: PeerThreadCombinedState,
|
||||||
|
users: [Api.User],
|
||||||
|
chats: [Api.Chat]
|
||||||
|
) {
|
||||||
|
self.peerId = peerId
|
||||||
|
self.items = items
|
||||||
|
self.messages = messages
|
||||||
|
self.pinnedThreadIds = pinnedThreadIds
|
||||||
|
self.combinedState = combinedState
|
||||||
|
self.users = users
|
||||||
|
self.chats = chats
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
enum LoadMessageHistoryThreadsError {
|
enum LoadMessageHistoryThreadsError {
|
||||||
case generic
|
case generic
|
||||||
}
|
}
|
||||||
|
|
||||||
func _internal_loadMessageHistoryThreads(accountPeerId: PeerId, postbox: Postbox, network: Network, peerId: PeerId, offsetIndex: StoredPeerThreadCombinedState.Index?, limit: Int) -> Signal<Never, LoadMessageHistoryThreadsError> {
|
func _internal_requestMessageHistoryThreads(accountPeerId: PeerId, postbox: Postbox, network: Network, peerId: PeerId, offsetIndex: StoredPeerThreadCombinedState.Index?, limit: Int) -> Signal<LoadMessageHistoryThreadsResult, LoadMessageHistoryThreadsError> {
|
||||||
let signal: Signal<Never, LoadMessageHistoryThreadsError> = postbox.transaction { transaction -> Api.InputChannel? in
|
let signal: Signal<LoadMessageHistoryThreadsResult, LoadMessageHistoryThreadsError> = postbox.transaction { transaction -> Api.InputChannel? in
|
||||||
return transaction.getPeer(peerId).flatMap(apiInputChannel)
|
return transaction.getPeer(peerId).flatMap(apiInputChannel)
|
||||||
}
|
}
|
||||||
|> castError(LoadMessageHistoryThreadsError.self)
|
|> castError(LoadMessageHistoryThreadsError.self)
|
||||||
|> mapToSignal { inputChannel -> Signal<Never, LoadMessageHistoryThreadsError> in
|
|> mapToSignal { inputChannel -> Signal<LoadMessageHistoryThreadsResult, LoadMessageHistoryThreadsError> in
|
||||||
guard let inputChannel = inputChannel else {
|
guard let inputChannel = inputChannel else {
|
||||||
return .fail(.generic)
|
return .fail(.generic)
|
||||||
}
|
}
|
||||||
@ -455,7 +508,7 @@ func _internal_loadMessageHistoryThreads(accountPeerId: PeerId, postbox: Postbox
|
|||||||
offsetId = offsetIndex.messageId
|
offsetId = offsetIndex.messageId
|
||||||
offsetTopic = Int32(clamping: offsetIndex.threadId)
|
offsetTopic = Int32(clamping: offsetIndex.threadId)
|
||||||
}
|
}
|
||||||
let signal: Signal<Never, LoadMessageHistoryThreadsError> = network.request(Api.functions.channels.getForumTopics(
|
let signal: Signal<LoadMessageHistoryThreadsResult, LoadMessageHistoryThreadsError> = network.request(Api.functions.channels.getForumTopics(
|
||||||
flags: flags,
|
flags: flags,
|
||||||
channel: inputChannel,
|
channel: inputChannel,
|
||||||
q: nil,
|
q: nil,
|
||||||
@ -467,35 +520,16 @@ func _internal_loadMessageHistoryThreads(accountPeerId: PeerId, postbox: Postbox
|
|||||||
|> mapError { _ -> LoadMessageHistoryThreadsError in
|
|> mapError { _ -> LoadMessageHistoryThreadsError in
|
||||||
return .generic
|
return .generic
|
||||||
}
|
}
|
||||||
|> mapToSignal { result -> Signal<Never, LoadMessageHistoryThreadsError> in
|
|> mapToSignal { result -> Signal<LoadMessageHistoryThreadsResult, LoadMessageHistoryThreadsError> in
|
||||||
return postbox.transaction { transaction -> Void in
|
|
||||||
var pinnedId: Int64?
|
|
||||||
switch result {
|
switch result {
|
||||||
case let .forumTopics(_, _, topics, messages, chats, users, pts):
|
case let .forumTopics(_, _, topics, messages, chats, users, pts):
|
||||||
var peers: [Peer] = []
|
var items: [LoadMessageHistoryThreadsResult.Item] = []
|
||||||
var peerPresences: [PeerId: Api.User] = [:]
|
var pinnedId: Int64?
|
||||||
for chat in chats {
|
|
||||||
if let groupOrChannel = parseTelegramGroupOrChannel(chat: chat) {
|
|
||||||
peers.append(groupOrChannel)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for user in users {
|
|
||||||
let telegramUser = TelegramUser(user: user)
|
|
||||||
peers.append(telegramUser)
|
|
||||||
peerPresences[telegramUser.id] = user
|
|
||||||
}
|
|
||||||
updatePeers(transaction: transaction, peers: peers, update: { _, updated -> Peer in
|
|
||||||
return updated
|
|
||||||
})
|
|
||||||
|
|
||||||
updatePeerPresences(transaction: transaction, accountPeerId: accountPeerId, peerPresences: peerPresences)
|
|
||||||
|
|
||||||
let addedMessages = messages.compactMap { message -> StoreMessage? in
|
let addedMessages = messages.compactMap { message -> StoreMessage? in
|
||||||
return StoreMessage(apiMessage: message)
|
return StoreMessage(apiMessage: message)
|
||||||
}
|
}
|
||||||
|
|
||||||
let _ = InternalAccountState.addMessages(transaction: transaction, messages: addedMessages, location: .Random)
|
|
||||||
|
|
||||||
let _ = pts
|
let _ = pts
|
||||||
var minIndex: StoredPeerThreadCombinedState.Index?
|
var minIndex: StoredPeerThreadCombinedState.Index?
|
||||||
|
|
||||||
@ -524,32 +558,11 @@ func _internal_loadMessageHistoryThreads(accountPeerId: PeerId, postbox: Postbox
|
|||||||
isClosed: (flags & (1 << 2)) != 0,
|
isClosed: (flags & (1 << 2)) != 0,
|
||||||
notificationSettings: TelegramPeerNotificationSettings(apiSettings: notifySettings)
|
notificationSettings: TelegramPeerNotificationSettings(apiSettings: notifySettings)
|
||||||
)
|
)
|
||||||
guard let info = StoredMessageHistoryThreadInfo(data) else {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
transaction.setMessageHistoryThreadInfo(peerId: peerId, threadId: Int64(id), info: info)
|
|
||||||
|
|
||||||
transaction.replaceMessageTagSummary(peerId: peerId, threadId: Int64(id), tagMask: .unseenPersonalMessage, namespace: Namespaces.Message.Cloud, count: unreadMentionsCount, maxId: topMessage)
|
|
||||||
transaction.replaceMessageTagSummary(peerId: peerId, threadId: Int64(id), tagMask: .unseenReaction, namespace: Namespaces.Message.Cloud, count: unreadReactionsCount, maxId: topMessage)
|
|
||||||
|
|
||||||
if topMessage != 0 {
|
|
||||||
transaction.removeHole(peerId: peerId, threadId: Int64(id), namespace: Namespaces.Message.Cloud, space: .everywhere, range: topMessage ... (Int32.max - 1))
|
|
||||||
}
|
|
||||||
|
|
||||||
var topTimestamp = date
|
var topTimestamp = date
|
||||||
for message in addedMessages {
|
for message in addedMessages {
|
||||||
if message.id.peerId == peerId && message.threadId == Int64(id) {
|
if message.id.peerId == peerId && message.threadId == Int64(id) {
|
||||||
topTimestamp = max(topTimestamp, message.timestamp)
|
topTimestamp = max(topTimestamp, message.timestamp)
|
||||||
|
|
||||||
if case let .Id(messageId) = message.id {
|
|
||||||
for media in message.media {
|
|
||||||
if let action = media as? TelegramMediaAction {
|
|
||||||
if case .topicCreated = action.action {
|
|
||||||
transaction.removeHole(peerId: messageId.peerId, threadId: Int64(id), namespace: Namespaces.Message.Cloud, space: .everywhere, range: 1 ... messageId.id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -561,16 +574,26 @@ func _internal_loadMessageHistoryThreads(accountPeerId: PeerId, postbox: Postbox
|
|||||||
} else {
|
} else {
|
||||||
minIndex = topicIndex
|
minIndex = topicIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
|
items.append(LoadMessageHistoryThreadsResult.Item(
|
||||||
|
threadId: Int64(id),
|
||||||
|
data: data,
|
||||||
|
topMessage: topMessage,
|
||||||
|
unreadMentionsCount: unreadMentionsCount,
|
||||||
|
unreadReactionsCount: unreadReactionsCount,
|
||||||
|
index: topicIndex
|
||||||
|
))
|
||||||
case .forumTopicDeleted:
|
case .forumTopicDeleted:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if offsetIndex != nil {
|
var pinnedThreadIds: [Int64]?
|
||||||
|
if offsetIndex == nil {
|
||||||
if let pinnedId = pinnedId {
|
if let pinnedId = pinnedId {
|
||||||
transaction.setPeerPinnedThreads(peerId: peerId, threadIds: [pinnedId])
|
pinnedThreadIds = [pinnedId]
|
||||||
} else {
|
} else {
|
||||||
transaction.setPeerPinnedThreads(peerId: peerId, threadIds: [])
|
pinnedThreadIds = []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -584,20 +607,85 @@ func _internal_loadMessageHistoryThreads(accountPeerId: PeerId, postbox: Postbox
|
|||||||
nextIndex = StoredPeerThreadCombinedState.Index(timestamp: 0, threadId: 0, messageId: 1)
|
nextIndex = StoredPeerThreadCombinedState.Index(timestamp: 0, threadId: 0, messageId: 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
if let entry = StoredPeerThreadCombinedState(PeerThreadCombinedState(validIndexBoundary: nextIndex)) {
|
let combinedState = PeerThreadCombinedState(validIndexBoundary: nextIndex)
|
||||||
transaction.setPeerThreadCombinedState(peerId: peerId, state: entry)
|
|
||||||
|
return .single(LoadMessageHistoryThreadsResult(
|
||||||
|
peerId: peerId,
|
||||||
|
items: items,
|
||||||
|
messages: addedMessages,
|
||||||
|
pinnedThreadIds: pinnedThreadIds,
|
||||||
|
combinedState: combinedState,
|
||||||
|
users: users,
|
||||||
|
chats: chats
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|> castError(LoadMessageHistoryThreadsError.self)
|
|
||||||
|> ignoreValues
|
|
||||||
}
|
|
||||||
return signal
|
return signal
|
||||||
}
|
}
|
||||||
|
|
||||||
return signal
|
return signal
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func applyLoadMessageHistoryThreadsResults(accountPeerId: PeerId, transaction: Transaction, results: [LoadMessageHistoryThreadsResult]) {
|
||||||
|
for result in results {
|
||||||
|
var peers: [Peer] = []
|
||||||
|
var peerPresences: [PeerId: Api.User] = [:]
|
||||||
|
for chat in result.chats {
|
||||||
|
if let groupOrChannel = parseTelegramGroupOrChannel(chat: chat) {
|
||||||
|
peers.append(groupOrChannel)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for user in result.users {
|
||||||
|
let telegramUser = TelegramUser(user: user)
|
||||||
|
peers.append(telegramUser)
|
||||||
|
peerPresences[telegramUser.id] = user
|
||||||
|
}
|
||||||
|
updatePeers(transaction: transaction, peers: peers, update: { _, updated -> Peer in
|
||||||
|
return updated
|
||||||
|
})
|
||||||
|
|
||||||
|
updatePeerPresences(transaction: transaction, accountPeerId: accountPeerId, peerPresences: peerPresences)
|
||||||
|
|
||||||
|
let _ = InternalAccountState.addMessages(transaction: transaction, messages: result.messages, location: .Random)
|
||||||
|
|
||||||
|
for item in result.items {
|
||||||
|
guard let info = StoredMessageHistoryThreadInfo(item.data) else {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
transaction.setMessageHistoryThreadInfo(peerId: result.peerId, threadId: item.threadId, info: info)
|
||||||
|
|
||||||
|
transaction.replaceMessageTagSummary(peerId: result.peerId, threadId: item.threadId, tagMask: .unseenPersonalMessage, namespace: Namespaces.Message.Cloud, count: item.unreadMentionsCount, maxId: item.topMessage)
|
||||||
|
transaction.replaceMessageTagSummary(peerId: result.peerId, threadId: item.threadId, tagMask: .unseenReaction, namespace: Namespaces.Message.Cloud, count: item.unreadReactionsCount, maxId: item.topMessage)
|
||||||
|
|
||||||
|
if item.topMessage != 0 {
|
||||||
|
transaction.removeHole(peerId: result.peerId, threadId: item.threadId, namespace: Namespaces.Message.Cloud, space: .everywhere, range: item.topMessage ... (Int32.max - 1))
|
||||||
|
}
|
||||||
|
|
||||||
|
for message in result.messages {
|
||||||
|
if message.id.peerId == result.peerId && message.threadId == item.threadId {
|
||||||
|
if case let .Id(messageId) = message.id {
|
||||||
|
for media in message.media {
|
||||||
|
if let action = media as? TelegramMediaAction {
|
||||||
|
if case .topicCreated = action.action {
|
||||||
|
transaction.removeHole(peerId: messageId.peerId, threadId: item.threadId, namespace: Namespaces.Message.Cloud, space: .everywhere, range: 1 ... messageId.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let pinnedThreadIds = result.pinnedThreadIds {
|
||||||
|
transaction.setPeerPinnedThreads(peerId: result.peerId, threadIds: pinnedThreadIds)
|
||||||
|
}
|
||||||
|
|
||||||
|
if let entry = StoredPeerThreadCombinedState(result.combinedState) {
|
||||||
|
transaction.setPeerThreadCombinedState(peerId: result.peerId, state: entry)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public extension EngineMessageHistoryThread {
|
public extension EngineMessageHistoryThread {
|
||||||
struct NotificationException: Equatable {
|
struct NotificationException: Equatable {
|
||||||
public var threadId: Int64
|
public var threadId: Int64
|
||||||
|
|||||||
@ -527,7 +527,7 @@ func initialStateWithDifference(postbox: Postbox, difference: Api.updates.Differ
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func finalStateWithUpdateGroups(postbox: Postbox, network: Network, state: AccountMutableState, groups: [UpdateGroup]) -> Signal<AccountFinalState, NoError> {
|
func finalStateWithUpdateGroups(accountPeerId: PeerId, postbox: Postbox, network: Network, state: AccountMutableState, groups: [UpdateGroup]) -> Signal<AccountFinalState, NoError> {
|
||||||
var updatedState = state
|
var updatedState = state
|
||||||
|
|
||||||
var hadReset = false
|
var hadReset = false
|
||||||
@ -651,10 +651,10 @@ func finalStateWithUpdateGroups(postbox: Postbox, network: Network, state: Accou
|
|||||||
collectedUpdates.append(Api.Update.updateDeleteChannelMessages(channelId: channelId, messages: [], pts: pts, ptsCount: ptsCount))
|
collectedUpdates.append(Api.Update.updateDeleteChannelMessages(channelId: channelId, messages: [], pts: pts, ptsCount: ptsCount))
|
||||||
}
|
}
|
||||||
|
|
||||||
return finalStateWithUpdates(postbox: postbox, network: network, state: updatedState, updates: collectedUpdates, shouldPoll: hadReset, missingUpdates: !ptsUpdatesAfterHole.isEmpty || !qtsUpdatesAfterHole.isEmpty || !seqGroupsAfterHole.isEmpty, shouldResetChannels: false, updatesDate: updatesDate)
|
return finalStateWithUpdates(accountPeerId: accountPeerId, postbox: postbox, network: network, state: updatedState, updates: collectedUpdates, shouldPoll: hadReset, missingUpdates: !ptsUpdatesAfterHole.isEmpty || !qtsUpdatesAfterHole.isEmpty || !seqGroupsAfterHole.isEmpty, shouldResetChannels: false, updatesDate: updatesDate)
|
||||||
}
|
}
|
||||||
|
|
||||||
func finalStateWithDifference(postbox: Postbox, network: Network, state: AccountMutableState, difference: Api.updates.Difference) -> Signal<AccountFinalState, NoError> {
|
func finalStateWithDifference(accountPeerId: PeerId, postbox: Postbox, network: Network, state: AccountMutableState, difference: Api.updates.Difference) -> Signal<AccountFinalState, NoError> {
|
||||||
var updatedState = state
|
var updatedState = state
|
||||||
|
|
||||||
var messages: [Api.Message] = []
|
var messages: [Api.Message] = []
|
||||||
@ -709,7 +709,7 @@ func finalStateWithDifference(postbox: Postbox, network: Network, state: Account
|
|||||||
updatedState.addSecretMessages(encryptedMessages)
|
updatedState.addSecretMessages(encryptedMessages)
|
||||||
}
|
}
|
||||||
|
|
||||||
return finalStateWithUpdates(postbox: postbox, network: network, state: updatedState, updates: updates, shouldPoll: false, missingUpdates: false, shouldResetChannels: true, updatesDate: nil)
|
return finalStateWithUpdates(accountPeerId: accountPeerId, postbox: postbox, network: network, state: updatedState, updates: updates, shouldPoll: false, missingUpdates: false, shouldResetChannels: true, updatesDate: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func sortedUpdates(_ updates: [Api.Update]) -> [Api.Update] {
|
private func sortedUpdates(_ updates: [Api.Update]) -> [Api.Update] {
|
||||||
@ -830,15 +830,15 @@ private func sortedUpdates(_ updates: [Api.Update]) -> [Api.Update] {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
private func finalStateWithUpdates(postbox: Postbox, network: Network, state: AccountMutableState, updates: [Api.Update], shouldPoll: Bool, missingUpdates: Bool, shouldResetChannels: Bool, updatesDate: Int32?) -> Signal<AccountFinalState, NoError> {
|
private func finalStateWithUpdates(accountPeerId: PeerId, postbox: Postbox, network: Network, state: AccountMutableState, updates: [Api.Update], shouldPoll: Bool, missingUpdates: Bool, shouldResetChannels: Bool, updatesDate: Int32?) -> Signal<AccountFinalState, NoError> {
|
||||||
return network.currentGlobalTime
|
return network.currentGlobalTime
|
||||||
|> take(1)
|
|> take(1)
|
||||||
|> mapToSignal { serverTime -> Signal<AccountFinalState, NoError> in
|
|> mapToSignal { serverTime -> Signal<AccountFinalState, NoError> in
|
||||||
return finalStateWithUpdatesAndServerTime(postbox: postbox, network: network, state: state, updates: updates, shouldPoll: shouldPoll, missingUpdates: missingUpdates, shouldResetChannels: shouldResetChannels, updatesDate: updatesDate, serverTime: Int32(serverTime))
|
return finalStateWithUpdatesAndServerTime(accountPeerId: accountPeerId, postbox: postbox, network: network, state: state, updates: updates, shouldPoll: shouldPoll, missingUpdates: missingUpdates, shouldResetChannels: shouldResetChannels, updatesDate: updatesDate, serverTime: Int32(serverTime))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func finalStateWithUpdatesAndServerTime(postbox: Postbox, network: Network, state: AccountMutableState, updates: [Api.Update], shouldPoll: Bool, missingUpdates: Bool, shouldResetChannels: Bool, updatesDate: Int32?, serverTime: Int32) -> Signal<AccountFinalState, NoError> {
|
private func finalStateWithUpdatesAndServerTime(accountPeerId: PeerId, postbox: Postbox, network: Network, state: AccountMutableState, updates: [Api.Update], shouldPoll: Bool, missingUpdates: Bool, shouldResetChannels: Bool, updatesDate: Int32?, serverTime: Int32) -> Signal<AccountFinalState, NoError> {
|
||||||
var updatedState = state
|
var updatedState = state
|
||||||
|
|
||||||
var channelsToPoll = Set<PeerId>()
|
var channelsToPoll = Set<PeerId>()
|
||||||
@ -1585,7 +1585,7 @@ private func finalStateWithUpdatesAndServerTime(postbox: Postbox, network: Netwo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !channelPeers.isEmpty {
|
if !channelPeers.isEmpty {
|
||||||
let resetSignal = resetChannels(postbox: postbox, network: network, peers: channelPeers, state: updatedState)
|
let resetSignal = resetChannels(accountPeerId: accountPeerId, postbox: postbox, network: network, peers: channelPeers, state: updatedState)
|
||||||
|> map { resultState -> (AccountMutableState, Bool, Int32?) in
|
|> map { resultState -> (AccountMutableState, Bool, Int32?) in
|
||||||
return (resultState, true, nil)
|
return (resultState, true, nil)
|
||||||
}
|
}
|
||||||
@ -1596,7 +1596,7 @@ private func finalStateWithUpdatesAndServerTime(postbox: Postbox, network: Netwo
|
|||||||
} else {
|
} else {
|
||||||
for peerId in channelsToPoll.union(missingUpdatesFromChannels) {
|
for peerId in channelsToPoll.union(missingUpdatesFromChannels) {
|
||||||
if let peer = updatedState.peers[peerId] {
|
if let peer = updatedState.peers[peerId] {
|
||||||
pollChannelSignals.append(pollChannel(postbox: postbox, network: network, peer: peer, state: updatedState.branch()))
|
pollChannelSignals.append(pollChannel(accountPeerId: accountPeerId, postbox: postbox, network: network, peer: peer, state: updatedState.branch()))
|
||||||
} else {
|
} else {
|
||||||
Logger.shared.log("State", "can't poll channel \(peerId): no peer found")
|
Logger.shared.log("State", "can't poll channel \(peerId): no peer found")
|
||||||
}
|
}
|
||||||
@ -2220,7 +2220,7 @@ private func resolveMissingPeerChatInfos(network: Network, state: AccountMutable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func pollChannelOnce(postbox: Postbox, network: Network, peerId: PeerId, stateManager: AccountStateManager, delayCompletion: Bool) -> Signal<Int32, NoError> {
|
func pollChannelOnce(accountPeerId: PeerId, postbox: Postbox, network: Network, peerId: PeerId, stateManager: AccountStateManager, delayCompletion: Bool) -> Signal<Int32, NoError> {
|
||||||
return postbox.transaction { transaction -> Signal<Int32, NoError> in
|
return postbox.transaction { transaction -> Signal<Int32, NoError> in
|
||||||
guard let accountState = (transaction.getState() as? AuthorizedAccountState)?.state, let peer = transaction.getPeer(peerId) else {
|
guard let accountState = (transaction.getState() as? AuthorizedAccountState)?.state, let peer = transaction.getPeer(peerId) else {
|
||||||
if delayCompletion {
|
if delayCompletion {
|
||||||
@ -2251,7 +2251,7 @@ func pollChannelOnce(postbox: Postbox, network: Network, peerId: PeerId, stateMa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
let initialState = AccountMutableState(initialState: AccountInitialState(state: accountState, peerIds: Set(), peerIdsRequiringLocalChatState: Set(), channelStates: channelStates, peerChatInfos: peerChatInfos, locallyGeneratedMessageTimestamps: [:], cloudReadStates: [:], channelsToPollExplicitely: Set()), initialPeers: initialPeers, initialReferencedMessageIds: Set(), initialStoredMessages: Set(), initialReadInboxMaxIds: [:], storedMessagesByPeerIdAndTimestamp: [:])
|
let initialState = AccountMutableState(initialState: AccountInitialState(state: accountState, peerIds: Set(), peerIdsRequiringLocalChatState: Set(), channelStates: channelStates, peerChatInfos: peerChatInfos, locallyGeneratedMessageTimestamps: [:], cloudReadStates: [:], channelsToPollExplicitely: Set()), initialPeers: initialPeers, initialReferencedMessageIds: Set(), initialStoredMessages: Set(), initialReadInboxMaxIds: [:], storedMessagesByPeerIdAndTimestamp: [:])
|
||||||
return pollChannel(postbox: postbox, network: network, peer: peer, state: initialState)
|
return pollChannel(accountPeerId: accountPeerId, postbox: postbox, network: network, peer: peer, state: initialState)
|
||||||
|> mapToSignal { (finalState, _, timeout) -> Signal<Int32, NoError> in
|
|> mapToSignal { (finalState, _, timeout) -> Signal<Int32, NoError> in
|
||||||
return resolveAssociatedMessages(postbox: postbox, network: network, state: finalState)
|
return resolveAssociatedMessages(postbox: postbox, network: network, state: finalState)
|
||||||
|> mapToSignal { resultingState -> Signal<AccountFinalState, NoError> in
|
|> mapToSignal { resultingState -> Signal<AccountFinalState, NoError> in
|
||||||
@ -2279,7 +2279,7 @@ func pollChannelOnce(postbox: Postbox, network: Network, peerId: PeerId, stateMa
|
|||||||
|> switchToLatest
|
|> switchToLatest
|
||||||
}
|
}
|
||||||
|
|
||||||
public func standalonePollChannelOnce(postbox: Postbox, network: Network, peerId: PeerId, stateManager: AccountStateManager) -> Signal<Never, NoError> {
|
public func standalonePollChannelOnce(accountPeerId: PeerId, postbox: Postbox, network: Network, peerId: PeerId, stateManager: AccountStateManager) -> Signal<Never, NoError> {
|
||||||
return postbox.transaction { transaction -> Signal<Never, NoError> in
|
return postbox.transaction { transaction -> Signal<Never, NoError> in
|
||||||
guard let accountState = (transaction.getState() as? AuthorizedAccountState)?.state, let peer = transaction.getPeer(peerId) else {
|
guard let accountState = (transaction.getState() as? AuthorizedAccountState)?.state, let peer = transaction.getPeer(peerId) else {
|
||||||
return .complete()
|
return .complete()
|
||||||
@ -2305,7 +2305,7 @@ public func standalonePollChannelOnce(postbox: Postbox, network: Network, peerId
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
let initialState = AccountMutableState(initialState: AccountInitialState(state: accountState, peerIds: Set(), peerIdsRequiringLocalChatState: Set(), channelStates: channelStates, peerChatInfos: peerChatInfos, locallyGeneratedMessageTimestamps: [:], cloudReadStates: [:], channelsToPollExplicitely: Set()), initialPeers: initialPeers, initialReferencedMessageIds: Set(), initialStoredMessages: Set(), initialReadInboxMaxIds: [:], storedMessagesByPeerIdAndTimestamp: [:])
|
let initialState = AccountMutableState(initialState: AccountInitialState(state: accountState, peerIds: Set(), peerIdsRequiringLocalChatState: Set(), channelStates: channelStates, peerChatInfos: peerChatInfos, locallyGeneratedMessageTimestamps: [:], cloudReadStates: [:], channelsToPollExplicitely: Set()), initialPeers: initialPeers, initialReferencedMessageIds: Set(), initialStoredMessages: Set(), initialReadInboxMaxIds: [:], storedMessagesByPeerIdAndTimestamp: [:])
|
||||||
return pollChannel(postbox: postbox, network: network, peer: peer, state: initialState)
|
return pollChannel(accountPeerId: accountPeerId, postbox: postbox, network: network, peer: peer, state: initialState)
|
||||||
|> mapToSignal { (finalState, _, timeout) -> Signal<Never, NoError> in
|
|> mapToSignal { (finalState, _, timeout) -> Signal<Never, NoError> in
|
||||||
return resolveAssociatedMessages(postbox: postbox, network: network, state: finalState)
|
return resolveAssociatedMessages(postbox: postbox, network: network, state: finalState)
|
||||||
|> mapToSignal { resultingState -> Signal<AccountFinalState, NoError> in
|
|> mapToSignal { resultingState -> Signal<AccountFinalState, NoError> in
|
||||||
@ -2322,13 +2322,13 @@ public func standalonePollChannelOnce(postbox: Postbox, network: Network, peerId
|
|||||||
|> switchToLatest
|
|> switchToLatest
|
||||||
}
|
}
|
||||||
|
|
||||||
func keepPollingChannel(postbox: Postbox, network: Network, peerId: PeerId, stateManager: AccountStateManager) -> Signal<Int32, NoError> {
|
func keepPollingChannel(accountPeerId: PeerId, postbox: Postbox, network: Network, peerId: PeerId, stateManager: AccountStateManager) -> Signal<Int32, NoError> {
|
||||||
return pollChannelOnce(postbox: postbox, network: network, peerId: peerId, stateManager: stateManager, delayCompletion: true)
|
return pollChannelOnce(accountPeerId: accountPeerId, postbox: postbox, network: network, peerId: peerId, stateManager: stateManager, delayCompletion: true)
|
||||||
|> restart
|
|> restart
|
||||||
|> delay(1.0, queue: .concurrentDefaultQueue())
|
|> delay(1.0, queue: .concurrentDefaultQueue())
|
||||||
}
|
}
|
||||||
|
|
||||||
private func resetChannels(postbox: Postbox, network: Network, peers: [Peer], state: AccountMutableState) -> Signal<AccountMutableState, NoError> {
|
private func resetChannels(accountPeerId: PeerId, postbox: Postbox, network: Network, peers: [Peer], state: AccountMutableState) -> Signal<AccountMutableState, NoError> {
|
||||||
var inputPeers: [Api.InputDialogPeer] = []
|
var inputPeers: [Api.InputDialogPeer] = []
|
||||||
for peer in peers {
|
for peer in peers {
|
||||||
if let inputPeer = apiInputPeer(peer) {
|
if let inputPeer = apiInputPeer(peer) {
|
||||||
@ -2358,6 +2358,8 @@ private func resetChannels(postbox: Postbox, network: Network, peers: [Peer], st
|
|||||||
var channelSynchronizedUntilMessage: [PeerId: MessageId.Id] = [:]
|
var channelSynchronizedUntilMessage: [PeerId: MessageId.Id] = [:]
|
||||||
var notificationSettings: [PeerId: TelegramPeerNotificationSettings] = [:]
|
var notificationSettings: [PeerId: TelegramPeerNotificationSettings] = [:]
|
||||||
|
|
||||||
|
var resetForumTopics = Set<PeerId>()
|
||||||
|
|
||||||
if let result = result {
|
if let result = result {
|
||||||
switch result {
|
switch result {
|
||||||
case let .peerDialogs(dialogs, messages, chats, users, _):
|
case let .peerDialogs(dialogs, messages, chats, users, _):
|
||||||
@ -2415,7 +2417,7 @@ private func resetChannels(postbox: Postbox, network: Network, peers: [Peer], st
|
|||||||
|
|
||||||
updatedState.updatePeerChatInclusion(peerId: peerId, groupId: groupId, changedGroup: false)
|
updatedState.updatePeerChatInclusion(peerId: peerId, groupId: groupId, changedGroup: false)
|
||||||
|
|
||||||
updatedState.resetForumTopicLists[peerId] = []
|
resetForumTopics.insert(peerId)
|
||||||
}
|
}
|
||||||
|
|
||||||
for message in messages {
|
for message in messages {
|
||||||
@ -2480,16 +2482,39 @@ private func resetChannels(postbox: Postbox, network: Network, peers: [Peer], st
|
|||||||
updatedState.updateNotificationSettings(.peer(peerId: peerId, threadId: nil), notificationSettings: settings)
|
updatedState.updateNotificationSettings(.peer(peerId: peerId, threadId: nil), notificationSettings: settings)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: delete messages later than top
|
var resetTopicsSignals: [Signal<StateResetForumTopics, NoError>] = []
|
||||||
|
for resetForumTopicPeerId in resetForumTopics {
|
||||||
|
resetTopicsSignals.append(_internal_requestMessageHistoryThreads(accountPeerId: accountPeerId, postbox: postbox, network: network, peerId: resetForumTopicPeerId, offsetIndex: nil, limit: 20)
|
||||||
|
|> map(StateResetForumTopics.result)
|
||||||
|
|> `catch` { _ -> Signal<StateResetForumTopics, NoError> in
|
||||||
|
return .single(.error(resetForumTopicPeerId))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return combineLatest(resetTopicsSignals)
|
||||||
|
|> mapToSignal { results -> Signal<AccountMutableState, NoError> in
|
||||||
|
var updatedState = updatedState
|
||||||
|
|
||||||
|
for result in results {
|
||||||
|
let peerId: PeerId
|
||||||
|
switch result {
|
||||||
|
case let .result(item):
|
||||||
|
peerId = item.peerId
|
||||||
|
case let .error(peerIdValue):
|
||||||
|
peerId = peerIdValue
|
||||||
|
}
|
||||||
|
updatedState.resetForumTopicLists[peerId] = result
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: delete messages later than top
|
||||||
return resolveAssociatedMessages(postbox: postbox, network: network, state: updatedState)
|
return resolveAssociatedMessages(postbox: postbox, network: network, state: updatedState)
|
||||||
|> mapToSignal { resultingState -> Signal<AccountMutableState, NoError> in
|
|> mapToSignal { resultingState -> Signal<AccountMutableState, NoError> in
|
||||||
return .single(resultingState)
|
return .single(resultingState)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func pollChannel(postbox: Postbox, network: Network, peer: Peer, state: AccountMutableState) -> Signal<(AccountMutableState, Bool, Int32?), NoError> {
|
private func pollChannel(accountPeerId: PeerId, postbox: Postbox, network: Network, peer: Peer, state: AccountMutableState) -> Signal<(AccountMutableState, Bool, Int32?), NoError> {
|
||||||
if let inputChannel = apiInputChannel(peer) {
|
if let inputChannel = apiInputChannel(peer) {
|
||||||
let limit: Int32
|
let limit: Int32
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
@ -2659,6 +2684,8 @@ private func pollChannel(postbox: Postbox, network: Network, peer: Peer, state:
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var resetForumTopics = Set<PeerId>()
|
||||||
|
|
||||||
if let (peer, pts, topMessage, readInboxMaxId, readOutboxMaxId, unreadCount, unreadMentionsCount, unreadReactionsCount) = parameters {
|
if let (peer, pts, topMessage, readInboxMaxId, readOutboxMaxId, unreadCount, unreadMentionsCount, unreadReactionsCount) = parameters {
|
||||||
updatedState.updateChannelState(peer.peerId, pts: pts)
|
updatedState.updateChannelState(peer.peerId, pts: pts)
|
||||||
updatedState.updateChannelInvalidationPts(peer.peerId, invalidationPts: pts)
|
updatedState.updateChannelInvalidationPts(peer.peerId, invalidationPts: pts)
|
||||||
@ -2667,7 +2694,7 @@ private func pollChannel(postbox: Postbox, network: Network, peer: Peer, state:
|
|||||||
updatedState.mergeUsers(users)
|
updatedState.mergeUsers(users)
|
||||||
|
|
||||||
updatedState.setNeedsHoleFromPreviousState(peerId: peer.peerId, namespace: Namespaces.Message.Cloud, validateChannelPts: pts)
|
updatedState.setNeedsHoleFromPreviousState(peerId: peer.peerId, namespace: Namespaces.Message.Cloud, validateChannelPts: pts)
|
||||||
updatedState.resetForumTopicLists[peer.peerId] = []
|
resetForumTopics.insert(peer.peerId)
|
||||||
|
|
||||||
for apiMessage in messages {
|
for apiMessage in messages {
|
||||||
if var message = StoreMessage(apiMessage: apiMessage) {
|
if var message = StoreMessage(apiMessage: apiMessage) {
|
||||||
@ -2700,9 +2727,33 @@ private func pollChannel(postbox: Postbox, network: Network, peer: Peer, state:
|
|||||||
assertionFailure()
|
assertionFailure()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var resetTopicsSignals: [Signal<StateResetForumTopics, NoError>] = []
|
||||||
|
for resetForumTopicPeerId in resetForumTopics {
|
||||||
|
resetTopicsSignals.append(_internal_requestMessageHistoryThreads(accountPeerId: accountPeerId, postbox: postbox, network: network, peerId: resetForumTopicPeerId, offsetIndex: nil, limit: 20)
|
||||||
|
|> map(StateResetForumTopics.result)
|
||||||
|
|> `catch` { _ -> Signal<StateResetForumTopics, NoError> in
|
||||||
|
return .single(.error(resetForumTopicPeerId))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return combineLatest(resetTopicsSignals)
|
||||||
|
|> mapToSignal { results -> Signal<(AccountMutableState, Bool, Int32?), NoError> in
|
||||||
|
var updatedState = updatedState
|
||||||
|
|
||||||
|
for result in results {
|
||||||
|
let peerId: PeerId
|
||||||
|
switch result {
|
||||||
|
case let .result(item):
|
||||||
|
peerId = item.peerId
|
||||||
|
case let .error(peerIdValue):
|
||||||
|
peerId = peerIdValue
|
||||||
|
}
|
||||||
|
updatedState.resetForumTopicLists[peerId] = result
|
||||||
|
}
|
||||||
|
|
||||||
return .single((updatedState, true, apiTimeout))
|
return .single((updatedState, true, apiTimeout))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Logger.shared.log("State", "can't poll channel \(peer.id): can't create inputChannel")
|
Logger.shared.log("State", "can't poll channel \(peer.id): can't create inputChannel")
|
||||||
return single((state, true, nil), NoError.self)
|
return single((state, true, nil), NoError.self)
|
||||||
@ -4039,7 +4090,8 @@ func replayFinalState(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (peerId, _) in finalState.state.resetForumTopicLists {
|
var resetForumTopicResults: [LoadMessageHistoryThreadsResult] = []
|
||||||
|
for (peerId, result) in finalState.state.resetForumTopicLists {
|
||||||
for item in transaction.getMessageHistoryThreadIndex(peerId: peerId, limit: 10000) {
|
for item in transaction.getMessageHistoryThreadIndex(peerId: peerId, limit: 10000) {
|
||||||
let holeLowerBound = transaction.holeLowerBoundForTopValidRange(peerId: peerId, threadId: item.threadId, namespace: Namespaces.Message.Cloud, space: .everywhere)
|
let holeLowerBound = transaction.holeLowerBoundForTopValidRange(peerId: peerId, threadId: item.threadId, namespace: Namespaces.Message.Cloud, space: .everywhere)
|
||||||
|
|
||||||
@ -4049,8 +4101,16 @@ func replayFinalState(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch result {
|
||||||
|
case let .result(value):
|
||||||
|
resetForumTopicResults.append(value)
|
||||||
|
case .error:
|
||||||
transaction.setPeerThreadCombinedState(peerId: peerId, state: nil)
|
transaction.setPeerThreadCombinedState(peerId: peerId, state: nil)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if !resetForumTopicResults.isEmpty {
|
||||||
|
applyLoadMessageHistoryThreadsResults(accountPeerId: accountPeerId, transaction: transaction, results: resetForumTopicResults)
|
||||||
|
}
|
||||||
|
|
||||||
//TODO Please do not forget fix holes space.
|
//TODO Please do not forget fix holes space.
|
||||||
|
|
||||||
|
|||||||
@ -468,7 +468,7 @@ public final class AccountStateManager {
|
|||||||
Logger.shared.log("State", "pollDifference initial state \(authorizedState) != current state \(state.initialState.state)")
|
Logger.shared.log("State", "pollDifference initial state \(authorizedState) != current state \(state.initialState.state)")
|
||||||
return .single((nil, nil, false))
|
return .single((nil, nil, false))
|
||||||
} else {
|
} else {
|
||||||
return finalStateWithDifference(postbox: postbox, network: network, state: state, difference: difference)
|
return finalStateWithDifference(accountPeerId: accountPeerId, postbox: postbox, network: network, state: state, difference: difference)
|
||||||
|> deliverOn(queue)
|
|> deliverOn(queue)
|
||||||
|> mapToSignal { finalState -> Signal<(difference: Api.updates.Difference?, finalStatte: AccountReplayedFinalState?, skipBecauseOfError: Bool), NoError> in
|
|> mapToSignal { finalState -> Signal<(difference: Api.updates.Difference?, finalStatte: AccountReplayedFinalState?, skipBecauseOfError: Bool), NoError> in
|
||||||
if !finalState.state.preCachedResources.isEmpty {
|
if !finalState.state.preCachedResources.isEmpty {
|
||||||
@ -581,7 +581,7 @@ public final class AccountStateManager {
|
|||||||
let queue = self.queue
|
let queue = self.queue
|
||||||
let signal = initialStateWithUpdateGroups(postbox: postbox, groups: groups)
|
let signal = initialStateWithUpdateGroups(postbox: postbox, groups: groups)
|
||||||
|> mapToSignal { [weak self] state -> Signal<(AccountReplayedFinalState?, AccountFinalState), NoError> in
|
|> mapToSignal { [weak self] state -> Signal<(AccountReplayedFinalState?, AccountFinalState), NoError> in
|
||||||
return finalStateWithUpdateGroups(postbox: postbox, network: network, state: state, groups: groups)
|
return finalStateWithUpdateGroups(accountPeerId: accountPeerId, postbox: postbox, network: network, state: state, groups: groups)
|
||||||
|> deliverOn(queue)
|
|> deliverOn(queue)
|
||||||
|> mapToSignal { finalState in
|
|> mapToSignal { finalState in
|
||||||
if !finalState.discard && !finalState.state.preCachedResources.isEmpty {
|
if !finalState.discard && !finalState.state.preCachedResources.isEmpty {
|
||||||
@ -958,7 +958,7 @@ public final class AccountStateManager {
|
|||||||
Logger.shared.log("State", "pollDifference initial state \(authorizedState) != current state \(state.initialState.state)")
|
Logger.shared.log("State", "pollDifference initial state \(authorizedState) != current state \(state.initialState.state)")
|
||||||
return .single((nil, nil, false))
|
return .single((nil, nil, false))
|
||||||
} else {
|
} else {
|
||||||
return finalStateWithDifference(postbox: postbox, network: network, state: state, difference: difference)
|
return finalStateWithDifference(accountPeerId: accountPeerId, postbox: postbox, network: network, state: state, difference: difference)
|
||||||
|> deliverOn(queue)
|
|> deliverOn(queue)
|
||||||
|> mapToSignal { finalState -> Signal<(difference: Api.updates.Difference?, finalStatte: AccountReplayedFinalState?, skipBecauseOfError: Bool), NoError> in
|
|> mapToSignal { finalState -> Signal<(difference: Api.updates.Difference?, finalStatte: AccountReplayedFinalState?, skipBecauseOfError: Bool), NoError> in
|
||||||
if !finalState.state.preCachedResources.isEmpty {
|
if !finalState.state.preCachedResources.isEmpty {
|
||||||
|
|||||||
@ -1477,7 +1477,7 @@ public final class AccountViewTracker {
|
|||||||
if context.subscribers.isEmpty {
|
if context.subscribers.isEmpty {
|
||||||
if let account = self.account {
|
if let account = self.account {
|
||||||
let queue = self.queue
|
let queue = self.queue
|
||||||
context.disposable.set(keepPollingChannel(postbox: account.postbox, network: account.network, peerId: peerId, stateManager: account.stateManager).start(next: { [weak context] isValidForTimeout in
|
context.disposable.set(keepPollingChannel(accountPeerId: account.peerId, postbox: account.postbox, network: account.network, peerId: peerId, stateManager: account.stateManager).start(next: { [weak context] isValidForTimeout in
|
||||||
queue.async {
|
queue.async {
|
||||||
guard let context = context else {
|
guard let context = context else {
|
||||||
return
|
return
|
||||||
|
|||||||
@ -143,7 +143,14 @@ func managedForumTopicListHoles(network: Network, postbox: Postbox, accountPeerI
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (entry, disposable) in added {
|
for (entry, disposable) in added {
|
||||||
disposable.set(_internal_loadMessageHistoryThreads(accountPeerId: accountPeerId, postbox: postbox, network: network, peerId: entry.peerId, offsetIndex: entry.index, limit: 100).start())
|
disposable.set((_internal_requestMessageHistoryThreads(accountPeerId: accountPeerId, postbox: postbox, network: network, peerId: entry.peerId, offsetIndex: entry.index, limit: 100)
|
||||||
|
|> mapToSignal { result -> Signal<Never, LoadMessageHistoryThreadsError> in
|
||||||
|
return postbox.transaction { transaction in
|
||||||
|
return applyLoadMessageHistoryThreadsResults(accountPeerId: accountPeerId, transaction: transaction, results: [result])
|
||||||
|
}
|
||||||
|
|> castError(LoadMessageHistoryThreadsError.self)
|
||||||
|
|> ignoreValues
|
||||||
|
}).start())
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@ -344,6 +344,16 @@ private class ReplyThreadHistoryContextImpl {
|
|||||||
data.maxIncomingReadId = messageIndex.id.id
|
data.maxIncomingReadId = messageIndex.id.id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let topMessageIndex = transaction.getMessageHistoryThreadTopMessage(peerId: messageId.peerId, threadId: Int64(messageId.id), namespaces: Set([Namespaces.Message.Cloud])) {
|
||||||
|
if messageIndex.id.id >= topMessageIndex.id.id {
|
||||||
|
let containingHole = transaction.getThreadIndexHole(peerId: messageId.peerId, threadId: Int64(messageId.id), namespace: topMessageIndex.id.namespace, containing: topMessageIndex.id.id)
|
||||||
|
if let _ = containingHole[.everywhere] {
|
||||||
|
} else {
|
||||||
|
data.incomingUnreadCount = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
data.maxKnownMessageId = max(data.maxKnownMessageId, messageIndex.id.id)
|
data.maxKnownMessageId = max(data.maxKnownMessageId, messageIndex.id.id)
|
||||||
|
|
||||||
if let entry = StoredMessageHistoryThreadInfo(data) {
|
if let entry = StoredMessageHistoryThreadInfo(data) {
|
||||||
|
|||||||
@ -775,8 +775,11 @@ public extension TelegramEngine {
|
|||||||
return _internal_deleteNotificationSound(account: self.account, fileId: fileId)
|
return _internal_deleteNotificationSound(account: self.account, fileId: fileId)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func ensurePeerIsLocallyAvailable(peer: EnginePeer) -> Signal<EnginePeer.Id, NoError> {
|
public func ensurePeerIsLocallyAvailable(peer: EnginePeer) -> Signal<EnginePeer, NoError> {
|
||||||
return _internal_storedMessageFromSearchPeer(account: self.account, peer: peer._asPeer())
|
return _internal_storedMessageFromSearchPeer(account: self.account, peer: peer._asPeer())
|
||||||
|
|> map { result -> EnginePeer in
|
||||||
|
return EnginePeer(result)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func ensurePeersAreLocallyAvailable(peers: [EnginePeer]) -> Signal<Never, NoError> {
|
public func ensurePeersAreLocallyAvailable(peers: [EnginePeer]) -> Signal<Never, NoError> {
|
||||||
|
|||||||
@ -2,17 +2,21 @@ import Foundation
|
|||||||
import Postbox
|
import Postbox
|
||||||
import SwiftSignalKit
|
import SwiftSignalKit
|
||||||
|
|
||||||
func _internal_storedMessageFromSearchPeer(account: Account, peer: Peer) -> Signal<PeerId, NoError> {
|
func _internal_storedMessageFromSearchPeer(account: Account, peer: Peer) -> Signal<Peer, NoError> {
|
||||||
return account.postbox.transaction { transaction -> PeerId in
|
return account.postbox.transaction { transaction -> Peer in
|
||||||
if transaction.getPeer(peer.id) == nil {
|
if transaction.getPeer(peer.id) == nil {
|
||||||
updatePeers(transaction: transaction, peers: [peer], update: { previousPeer, updatedPeer in
|
updatePeers(transaction: transaction, peers: [peer], update: { previousPeer, updatedPeer in
|
||||||
return updatedPeer
|
return updatedPeer
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if let group = transaction.getPeer(peer.id) as? TelegramGroup, let migrationReference = group.migrationReference {
|
if let group = transaction.getPeer(peer.id) as? TelegramGroup, let migrationReference = group.migrationReference {
|
||||||
return migrationReference.peerId
|
if let migrationPeer = transaction.getPeer(migrationReference.peerId) {
|
||||||
|
return migrationPeer
|
||||||
|
} else {
|
||||||
|
return peer
|
||||||
}
|
}
|
||||||
return peer.id
|
}
|
||||||
|
return peer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -313,13 +313,16 @@ final class AuthorizedApplicationContext {
|
|||||||
|
|
||||||
if let strongSelf = self, let (messages, _, notify, threadData) = messageList.last, let firstMessage = messages.first {
|
if let strongSelf = self, let (messages, _, notify, threadData) = messageList.last, let firstMessage = messages.first {
|
||||||
if UIApplication.shared.applicationState == .active {
|
if UIApplication.shared.applicationState == .active {
|
||||||
let chatLocation: ChatLocation
|
let chatLocation: NavigateToChatControllerParams.Location
|
||||||
if let _ = threadData, let threadId = firstMessage.threadId {
|
if let _ = threadData, let threadId = firstMessage.threadId {
|
||||||
chatLocation = .replyThread(message: ChatReplyThreadMessage(
|
chatLocation = .replyThread(ChatReplyThreadMessage(
|
||||||
messageId: MessageId(peerId: firstMessage.id.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
|
messageId: MessageId(peerId: firstMessage.id.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 {
|
} else {
|
||||||
chatLocation = .peer(id: firstMessage.id.peerId)
|
guard let peer = firstMessage.peers[firstMessage.id.peerId] else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
chatLocation = .peer(EnginePeer(peer))
|
||||||
}
|
}
|
||||||
|
|
||||||
var chatIsVisible = false
|
var chatIsVisible = false
|
||||||
@ -445,7 +448,7 @@ final class AuthorizedApplicationContext {
|
|||||||
return false
|
return false
|
||||||
}, expandAction: { expandData in
|
}, expandAction: { expandData in
|
||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
let chatController = ChatControllerImpl(context: strongSelf.context, chatLocation: chatLocation, mode: .overlay(strongSelf.rootController))
|
let chatController = ChatControllerImpl(context: strongSelf.context, chatLocation: chatLocation.asChatLocation, mode: .overlay(strongSelf.rootController))
|
||||||
chatController.presentationArguments = ChatControllerOverlayPresentationData(expandData: expandData())
|
chatController.presentationArguments = ChatControllerOverlayPresentationData(expandData: expandData())
|
||||||
(strongSelf.rootController.viewControllers.last as? ViewController)?.present(chatController, in: .window(.root), with: ChatControllerOverlayPresentationData(expandData: expandData()))
|
(strongSelf.rootController.viewControllers.last as? ViewController)?.present(chatController, in: .window(.root), with: ChatControllerOverlayPresentationData(expandData: expandData()))
|
||||||
}
|
}
|
||||||
@ -781,7 +784,14 @@ final class AuthorizedApplicationContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let navigateToMessage = {
|
let navigateToMessage = {
|
||||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: strongSelf.rootController, context: strongSelf.context, chatLocation: .peer(id: messageId.peerId), subject: .message(id: .id(messageId), highlight: true, timecode: nil)))
|
let _ = (strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: messageId.peerId))
|
||||||
|
|> deliverOnMainQueue).start(next: { peer in
|
||||||
|
guard let peer = peer else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: strongSelf.rootController, context: strongSelf.context, chatLocation: .peer(peer), subject: .message(id: .id(messageId), highlight: true, timecode: nil)))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if chatIsVisible {
|
if chatIsVisible {
|
||||||
@ -860,16 +870,23 @@ final class AuthorizedApplicationContext {
|
|||||||
|
|
||||||
if visiblePeerId != peerId || messageId != nil {
|
if visiblePeerId != peerId || messageId != nil {
|
||||||
if self.rootController.rootTabController != nil {
|
if self.rootController.rootTabController != nil {
|
||||||
let chatLocation: ChatLocation
|
let _ = (self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||||
|
|> deliverOnMainQueue).start(next: { peer in
|
||||||
|
guard let peer = peer else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let chatLocation: NavigateToChatControllerParams.Location
|
||||||
if let threadId = threadId {
|
if let threadId = threadId {
|
||||||
chatLocation = .replyThread(message: ChatReplyThreadMessage(
|
chatLocation = .replyThread(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
|
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 {
|
} else {
|
||||||
chatLocation = .peer(id: peerId)
|
chatLocation = .peer(peer)
|
||||||
}
|
}
|
||||||
|
|
||||||
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: self.rootController, context: self.context, chatLocation: chatLocation, subject: messageId.flatMap { .message(id: .id($0), highlight: true, timecode: nil) }, activateInput: activateInput ? .text : nil))
|
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: self.rootController, context: self.context, chatLocation: chatLocation, subject: messageId.flatMap { .message(id: .id($0), highlight: true, timecode: nil) }, activateInput: activateInput ? .text : nil))
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
self.scheduledOpenChatWithPeerId = (peerId, messageId, activateInput)
|
self.scheduledOpenChatWithPeerId = (peerId, messageId, activateInput)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6232,7 +6232,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
guard let data = view.info?.data.get(MessageHistoryThreadData.self) else {
|
guard let data = view.info?.data.get(MessageHistoryThreadData.self) else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return ChatPresentationInterfaceState.ThreadData(title: data.info.title, icon: data.info.icon, iconColor: data.info.iconColor, isOwn: data.isOwnedByMe, isClosed: data.isClosed)
|
return ChatPresentationInterfaceState.ThreadData(title: data.info.title, icon: data.info.icon, iconColor: data.info.iconColor, isOwnedByMe: data.isOwnedByMe, isClosed: data.isClosed)
|
||||||
}
|
}
|
||||||
|> distinctUntilChanged
|
|> distinctUntilChanged
|
||||||
} else {
|
} else {
|
||||||
@ -7931,9 +7931,19 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
guard let strongSelf = self else {
|
guard let strongSelf = self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if let navigationController = strongSelf.effectiveNavigationController {
|
let _ = (strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(id: peerId), subject: nil, keepStack: .always))
|
|> deliverOnMainQueue).start(next: { peer in
|
||||||
|
guard let peer = peer else {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
guard let strongSelf = self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if let navigationController = strongSelf.effectiveNavigationController {
|
||||||
|
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(peer), subject: nil, keepStack: .always))
|
||||||
|
}
|
||||||
|
})
|
||||||
}, navigateToProfile: { [weak self] peerId in
|
}, navigateToProfile: { [weak self] peerId in
|
||||||
guard let strongSelf = self else {
|
guard let strongSelf = self else {
|
||||||
return
|
return
|
||||||
@ -9145,7 +9155,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
|
|
||||||
if let navigationController = strongSelf.effectiveNavigationController {
|
if let navigationController = strongSelf.effectiveNavigationController {
|
||||||
let subject: ChatControllerSubject? = sourceMessageId.flatMap { ChatControllerSubject.message(id: .id($0), highlight: true, timecode: nil) }
|
let subject: ChatControllerSubject? = sourceMessageId.flatMap { ChatControllerSubject.message(id: .id($0), highlight: true, timecode: nil) }
|
||||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .replyThread(message: replyThreadResult), subject: subject, keepStack: .always))
|
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .replyThread(replyThreadResult), subject: subject, keepStack: .always))
|
||||||
}
|
}
|
||||||
}, activatePinnedListPreview: { [weak self] node, gesture in
|
}, activatePinnedListPreview: { [weak self] node, gesture in
|
||||||
guard let strongSelf = self else {
|
guard let strongSelf = self else {
|
||||||
@ -9761,7 +9771,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
updatedChatNavigationStack.insert(peerId, at: 0)
|
updatedChatNavigationStack.insert(peerId, at: 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(id: peer.id), animated: false, chatListFilter: nextFolderId, chatNavigationStack: updatedChatNavigationStack, completion: { nextController in
|
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(peer), animated: false, chatListFilter: nextFolderId, chatNavigationStack: updatedChatNavigationStack, completion: { nextController in
|
||||||
(nextController as! ChatControllerImpl).animateFromPreviousController(snapshotState: snapshotState)
|
(nextController as! ChatControllerImpl).animateFromPreviousController(snapshotState: snapshotState)
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
@ -9881,7 +9891,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
updatedChatNavigationStack.removeSubrange(0 ..< (index + 1))
|
updatedChatNavigationStack.removeSubrange(0 ..< (index + 1))
|
||||||
}
|
}
|
||||||
|
|
||||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(id: peer.id), useBackAnimation: true, animated: true, chatListFilter: nextFolderId, chatNavigationStack: updatedChatNavigationStack, completion: { nextController in
|
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(peer), useBackAnimation: true, animated: true, chatListFilter: nextFolderId, chatNavigationStack: updatedChatNavigationStack, completion: { nextController in
|
||||||
let _ = nextController
|
let _ = nextController
|
||||||
}))
|
}))
|
||||||
})))
|
})))
|
||||||
@ -14714,7 +14724,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
statusController?.dismiss()
|
statusController?.dismiss()
|
||||||
}
|
}
|
||||||
|
|
||||||
let chatLocation: ChatLocation = .replyThread(message: result.message)
|
let chatLocation: NavigateToChatControllerParams.Location = .replyThread(result.message)
|
||||||
|
|
||||||
let subject: ChatControllerSubject?
|
let subject: ChatControllerSubject?
|
||||||
if let atMessageId = atMessageId {
|
if let atMessageId = atMessageId {
|
||||||
@ -14781,14 +14791,27 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
}
|
}
|
||||||
|
|
||||||
if isPinnedMessages, let messageId = messageLocation.messageId {
|
if isPinnedMessages, let messageId = messageLocation.messageId {
|
||||||
|
let _ = (self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: messageId.peerId))
|
||||||
|
|> deliverOnMainQueue).start(next: { [weak self] peer in
|
||||||
|
guard let self, let peer = peer else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if let navigationController = self.effectiveNavigationController {
|
if let navigationController = self.effectiveNavigationController {
|
||||||
self.dismiss()
|
self.dismiss()
|
||||||
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(id: messageId.peerId), subject: .message(id: .id(messageId), highlight: true, timecode: nil), keepStack: .always))
|
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(peer), subject: .message(id: .id(messageId), highlight: true, timecode: nil), keepStack: .always))
|
||||||
}
|
}
|
||||||
|
})
|
||||||
} else if case let .peer(peerId) = self.chatLocation, let messageId = messageLocation.messageId, (messageId.peerId != peerId && !forceInCurrentChat) || (isScheduledMessages && messageId.id != 0 && !Namespaces.Message.allScheduled.contains(messageId.namespace)) {
|
} else if case let .peer(peerId) = self.chatLocation, let messageId = messageLocation.messageId, (messageId.peerId != peerId && !forceInCurrentChat) || (isScheduledMessages && messageId.id != 0 && !Namespaces.Message.allScheduled.contains(messageId.namespace)) {
|
||||||
if let navigationController = self.effectiveNavigationController {
|
let _ = (self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: messageId.peerId))
|
||||||
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(id: messageId.peerId), subject: .message(id: .id(messageId), highlight: true, timecode: nil), keepStack: .always))
|
|> deliverOnMainQueue).start(next: { [weak self] peer in
|
||||||
|
guard let self, let peer = peer else {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
if let navigationController = self.effectiveNavigationController {
|
||||||
|
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(peer), subject: .message(id: .id(messageId), highlight: true, timecode: nil), keepStack: .always))
|
||||||
|
}
|
||||||
|
})
|
||||||
} else if forceInCurrentChat {
|
} else if forceInCurrentChat {
|
||||||
if let _ = fromId, let fromIndex = fromIndex, rememberInStack {
|
if let _ = fromId, let fromIndex = fromIndex, rememberInStack {
|
||||||
self.historyNavigationStack.add(fromIndex)
|
self.historyNavigationStack.add(fromIndex)
|
||||||
@ -14967,9 +14990,16 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
strongSelf.chatDisplayNode.historyNode.scrollToMessage(from: fromIndex, to: index, animated: animated, scrollPosition: scrollPosition)
|
strongSelf.chatDisplayNode.historyNode.scrollToMessage(from: fromIndex, to: index, animated: animated, scrollPosition: scrollPosition)
|
||||||
completion?()
|
completion?()
|
||||||
} else {
|
} else {
|
||||||
if let navigationController = strongSelf.effectiveNavigationController {
|
let _ = (strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: messageLocation.peerId))
|
||||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(id: messageLocation.peerId), subject: messageLocation.messageId.flatMap { .message(id: .id($0), highlight: true, timecode: nil) }))
|
|> deliverOnMainQueue).start(next: { peer in
|
||||||
|
guard let strongSelf = self, let peer = peer else {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let navigationController = strongSelf.effectiveNavigationController {
|
||||||
|
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(peer), subject: messageLocation.messageId.flatMap { .message(id: .id($0), highlight: true, timecode: nil) }))
|
||||||
|
}
|
||||||
|
})
|
||||||
completion?()
|
completion?()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -14979,10 +15009,16 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
} else {
|
} else {
|
||||||
|
let _ = (self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: messageLocation.peerId))
|
||||||
|
|> deliverOnMainQueue).start(next: { [weak self] peer in
|
||||||
|
guard let self, let peer = peer else {
|
||||||
|
return
|
||||||
|
}
|
||||||
if let navigationController = self.effectiveNavigationController {
|
if let navigationController = self.effectiveNavigationController {
|
||||||
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(id: messageLocation.peerId), subject: messageLocation.messageId.flatMap { .message(id: .id($0), highlight: true, timecode: nil) }))
|
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(peer), subject: messageLocation.messageId.flatMap { .message(id: .id($0), highlight: true, timecode: nil) }))
|
||||||
}
|
}
|
||||||
completion?()
|
completion?()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -15173,8 +15209,15 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
} else if peerId == strongSelf.context.account.peerId {
|
} else if peerId == strongSelf.context.account.peerId {
|
||||||
let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 }
|
let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 }
|
||||||
strongSelf.present(UndoOverlayController(presentationData: presentationData, content: .forward(savedMessages: true, text: messages.count == 1 ? presentationData.strings.Conversation_ForwardTooltip_SavedMessages_One : presentationData.strings.Conversation_ForwardTooltip_SavedMessages_Many), elevatedLayout: false, animateInAsReplacement: true, action: { [weak self] value in
|
strongSelf.present(UndoOverlayController(presentationData: presentationData, content: .forward(savedMessages: true, text: messages.count == 1 ? presentationData.strings.Conversation_ForwardTooltip_SavedMessages_One : presentationData.strings.Conversation_ForwardTooltip_SavedMessages_Many), elevatedLayout: false, animateInAsReplacement: true, action: { [weak self] value in
|
||||||
if case .info = value, let strongSelf = self, let navigationController = strongSelf.effectiveNavigationController {
|
if case .info = value, let strongSelf = self {
|
||||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(id: context.account.peerId), keepStack: .always, purposefulAction: {}, peekData: nil))
|
let _ = (strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: strongSelf.context.account.peerId))
|
||||||
|
|> deliverOnMainQueue).start(next: { peer in
|
||||||
|
guard let strongSelf = self, let peer = peer, let navigationController = strongSelf.effectiveNavigationController else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(peer), keepStack: .always, purposefulAction: {}, peekData: nil))
|
||||||
|
})
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
@ -15349,7 +15392,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
})
|
})
|
||||||
|> deliverOnMainQueue).start(completed: { [weak self] in
|
|> deliverOnMainQueue).start(completed: { [weak self] in
|
||||||
if let strongSelf = self, let navigationController = strongSelf.effectiveNavigationController {
|
if let strongSelf = self, let navigationController = strongSelf.effectiveNavigationController {
|
||||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(id: peer.id), subject: subject, updateTextInputState: textInputState, peekData: peekData))
|
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(peer), subject: subject, updateTextInputState: textInputState, peekData: peekData))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
@ -15359,7 +15402,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
self.effectiveNavigationController?.pushViewController(ChatControllerImpl(context: self.context, chatLocation: .peer(id: peer.id), botStart: botStart))
|
self.effectiveNavigationController?.pushViewController(ChatControllerImpl(context: self.context, chatLocation: .peer(id: peer.id), botStart: botStart))
|
||||||
case let .withAttachBot(attachBotStart):
|
case let .withAttachBot(attachBotStart):
|
||||||
if let navigationController = self.effectiveNavigationController {
|
if let navigationController = self.effectiveNavigationController {
|
||||||
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(id: peer.id), attachBotStart: attachBotStart))
|
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(peer), attachBotStart: attachBotStart))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -15815,7 +15858,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
if case let .channel(channel) = peerId, channel.flags.contains(.isForum) {
|
if case let .channel(channel) = peerId, channel.flags.contains(.isForum) {
|
||||||
strongSelf.context.sharedContext.navigateToForumChannel(context: strongSelf.context, peerId: peerId.id, navigationController: navigationController)
|
strongSelf.context.sharedContext.navigateToForumChannel(context: strongSelf.context, peerId: peerId.id, navigationController: navigationController)
|
||||||
} else {
|
} else {
|
||||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(id: peerId.id), subject: subject, keepStack: .always, peekData: peekData))
|
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(peerId), subject: subject, keepStack: .always, peekData: peekData))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case .info:
|
case .info:
|
||||||
@ -15834,11 +15877,11 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
$0.updatedBotStartPayload(startPayload.payload)
|
$0.updatedBotStartPayload(startPayload.payload)
|
||||||
})
|
})
|
||||||
} else if let navigationController = strongSelf.effectiveNavigationController {
|
} else if let navigationController = strongSelf.effectiveNavigationController {
|
||||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(id: peerId.id), botStart: startPayload, keepStack: .always))
|
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(peerId), botStart: startPayload, keepStack: .always))
|
||||||
}
|
}
|
||||||
case let .withAttachBot(attachBotStart):
|
case let .withAttachBot(attachBotStart):
|
||||||
if let navigationController = strongSelf.effectiveNavigationController {
|
if let navigationController = strongSelf.effectiveNavigationController {
|
||||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(id: peerId.id), attachBotStart: attachBotStart))
|
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(peerId), attachBotStart: attachBotStart))
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
|
|||||||
@ -992,12 +992,18 @@ final class ChatEntityKeyboardInputNode: ChatInputNode {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if suggestSavedMessages, let navigationController = controllerInteraction.navigationController() {
|
if suggestSavedMessages {
|
||||||
|
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: context.account.peerId))
|
||||||
|
|> deliverOnMainQueue).start(next: { peer in
|
||||||
|
guard let peer = peer, let navigationController = controllerInteraction.navigationController() else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(
|
||||||
navigationController: navigationController,
|
navigationController: navigationController,
|
||||||
chatController: nil,
|
chatController: nil,
|
||||||
context: context,
|
context: context,
|
||||||
chatLocation: .peer(id: context.account.peerId),
|
chatLocation: .peer(peer),
|
||||||
subject: nil,
|
subject: nil,
|
||||||
updateTextInputState: nil,
|
updateTextInputState: nil,
|
||||||
activateInput: .entityInput,
|
activateInput: .entityInput,
|
||||||
@ -1005,6 +1011,7 @@ final class ChatEntityKeyboardInputNode: ChatInputNode {
|
|||||||
completion: { _ in
|
completion: { _ in
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
var replaceImpl: ((ViewController) -> Void)?
|
var replaceImpl: ((ViewController) -> Void)?
|
||||||
let controller = PremiumDemoScreen(context: context, subject: .animatedEmoji, action: {
|
let controller = PremiumDemoScreen(context: context, subject: .animatedEmoji, action: {
|
||||||
|
|||||||
@ -264,9 +264,9 @@ func canReplyInChat(_ chatPresentationInterfaceState: ChatPresentationInterfaceS
|
|||||||
var canManage = false
|
var canManage = false
|
||||||
if channel.flags.contains(.isCreator) {
|
if channel.flags.contains(.isCreator) {
|
||||||
canManage = true
|
canManage = true
|
||||||
} else if channel.adminRights != nil {
|
} else if channel.hasPermission(.manageTopics) {
|
||||||
canManage = true
|
canManage = true
|
||||||
} else if threadData.isOwn {
|
} else if threadData.isOwnedByMe {
|
||||||
canManage = true
|
canManage = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1510,7 +1510,10 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
|
|||||||
guard let navigationController = controllerInteraction.navigationController() else {
|
guard let navigationController = controllerInteraction.navigationController() else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: messages[0].id.peerId), subject: .message(id: .id(messages[0].id), highlight: true, timecode: nil), useExisting: true))
|
guard let peer = messages[0].peers[messages[0].id.peerId] else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(EnginePeer(peer)), subject: .message(id: .id(messages[0].id), highlight: true, timecode: nil), useExisting: true))
|
||||||
})
|
})
|
||||||
})))
|
})))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -164,9 +164,9 @@ func inputPanelForChatPresentationIntefaceState(_ chatPresentationInterfaceState
|
|||||||
var canManage = false
|
var canManage = false
|
||||||
if channel.flags.contains(.isCreator) {
|
if channel.flags.contains(.isCreator) {
|
||||||
canManage = true
|
canManage = true
|
||||||
} else if channel.adminRights != nil {
|
} else if channel.hasPermission(.manageTopics) {
|
||||||
canManage = true
|
canManage = true
|
||||||
} else if threadData.isOwn {
|
} else if threadData.isOwnedByMe {
|
||||||
canManage = true
|
canManage = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -63,9 +63,9 @@ func titlePanelForChatPresentationInterfaceState(_ chatPresentationInterfaceStat
|
|||||||
var canManage = false
|
var canManage = false
|
||||||
if channel.flags.contains(.isCreator) {
|
if channel.flags.contains(.isCreator) {
|
||||||
canManage = true
|
canManage = true
|
||||||
} else if channel.adminRights != nil {
|
} else if channel.hasPermission(.manageTopics) {
|
||||||
canManage = true
|
canManage = true
|
||||||
} else if threadData.isOwn {
|
} else if threadData.isOwnedByMe {
|
||||||
canManage = true
|
canManage = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -773,7 +773,7 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
|
|||||||
self.navigationActionDisposable.set((peerSignal |> take(1) |> deliverOnMainQueue).start(next: { [weak self] peer in
|
self.navigationActionDisposable.set((peerSignal |> take(1) |> deliverOnMainQueue).start(next: { [weak self] peer in
|
||||||
if let strongSelf = self, let peer = peer {
|
if let strongSelf = self, let peer = peer {
|
||||||
if peer is TelegramChannel, let navigationController = strongSelf.getNavigationController() {
|
if peer is TelegramChannel, let navigationController = strongSelf.getNavigationController() {
|
||||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(id: peer.id), peekData: peekData, animated: true))
|
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(EnginePeer(peer)), peekData: peekData, animated: true))
|
||||||
} else {
|
} else {
|
||||||
if let infoController = strongSelf.context.sharedContext.makePeerInfoController(context: strongSelf.context, updatedPresentationData: nil, peer: peer, mode: .generic, avatarInitiallyExpanded: false, fromChat: false, requestsContext: nil) {
|
if let infoController = strongSelf.context.sharedContext.makePeerInfoController(context: strongSelf.context, updatedPresentationData: nil, peer: peer, mode: .generic, avatarInitiallyExpanded: false, fromChat: false, requestsContext: nil) {
|
||||||
strongSelf.pushController(infoController)
|
strongSelf.pushController(infoController)
|
||||||
@ -895,11 +895,11 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
|
|||||||
break
|
break
|
||||||
case let .channelMessage(peer, messageId, timecode):
|
case let .channelMessage(peer, messageId, timecode):
|
||||||
if let navigationController = strongSelf.getNavigationController() {
|
if let navigationController = strongSelf.getNavigationController() {
|
||||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(id: peer.id), subject: .message(id: .id(messageId), highlight: true, timecode: timecode)))
|
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(EnginePeer(peer)), subject: .message(id: .id(messageId), highlight: true, timecode: timecode)))
|
||||||
}
|
}
|
||||||
case let .replyThreadMessage(replyThreadMessage, messageId):
|
case let .replyThreadMessage(replyThreadMessage, messageId):
|
||||||
if let navigationController = strongSelf.getNavigationController() {
|
if let navigationController = strongSelf.getNavigationController() {
|
||||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .replyThread(message: replyThreadMessage), subject: .message(id: .id(messageId), highlight: true, timecode: nil)))
|
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .replyThread(replyThreadMessage), subject: .message(id: .id(messageId), highlight: true, timecode: nil)))
|
||||||
}
|
}
|
||||||
case let .replyThread(messageId):
|
case let .replyThread(messageId):
|
||||||
if let navigationController = strongSelf.getNavigationController() {
|
if let navigationController = strongSelf.getNavigationController() {
|
||||||
|
|||||||
@ -104,9 +104,9 @@ private func peerButtons(_ state: ChatPresentationInterfaceState) -> [ChatReport
|
|||||||
var canManage = false
|
var canManage = false
|
||||||
if channel.flags.contains(.isCreator) {
|
if channel.flags.contains(.isCreator) {
|
||||||
canManage = true
|
canManage = true
|
||||||
} else if channel.adminRights != nil {
|
} else if channel.hasPermission(.manageTopics) {
|
||||||
canManage = true
|
canManage = true
|
||||||
} else if threadData.isOwn {
|
} else if threadData.isOwnedByMe {
|
||||||
canManage = true
|
canManage = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -207,7 +207,7 @@ public class ComposeControllerImpl: ViewController, ComposeController {
|
|||||||
if let peer = peer {
|
if let peer = peer {
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
if let navigationController = strongSelf.navigationController as? NavigationController {
|
if let navigationController = strongSelf.navigationController as? NavigationController {
|
||||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(id: peer.id)))
|
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(EnginePeer(peer))))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -15,11 +15,25 @@ import AttachmentUI
|
|||||||
import ForumCreateTopicScreen
|
import ForumCreateTopicScreen
|
||||||
|
|
||||||
public func navigateToChatControllerImpl(_ params: NavigateToChatControllerParams) {
|
public func navigateToChatControllerImpl(_ params: NavigateToChatControllerParams) {
|
||||||
|
if case let .peer(peer) = params.chatLocation, case let .channel(channel) = peer, channel.flags.contains(.isForum) {
|
||||||
|
for controller in params.navigationController.viewControllers.reversed() {
|
||||||
|
if let controller = controller as? ChatListControllerImpl, case let .forum(peerId) = controller.location, peer.id == peerId {
|
||||||
|
let _ = params.navigationController.popToViewController(controller, animated: params.animated)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let controller = ChatListControllerImpl(context: params.context, location: .forum(peerId: peer.id), controlsHistoryPreload: false, enableDebugActions: false)
|
||||||
|
params.navigationController.pushViewController(controller)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
var found = false
|
var found = false
|
||||||
var isFirst = true
|
var isFirst = true
|
||||||
if params.useExisting {
|
if params.useExisting {
|
||||||
for controller in params.navigationController.viewControllers.reversed() {
|
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 controller = controller as? ChatControllerImpl, controller.chatLocation == params.chatLocation.asChatLocation && (controller.subject != .scheduledMessages || controller.subject == params.subject) {
|
||||||
if let updateTextInputState = params.updateTextInputState {
|
if let updateTextInputState = params.updateTextInputState {
|
||||||
controller.updateTextInputState(updateTextInputState)
|
controller.updateTextInputState(updateTextInputState)
|
||||||
}
|
}
|
||||||
@ -46,7 +60,7 @@ public func navigateToChatControllerImpl(_ params: NavigateToChatControllerParam
|
|||||||
}
|
}
|
||||||
|
|
||||||
if popAndComplete {
|
if popAndComplete {
|
||||||
if let _ = params.navigationController.viewControllers.last as? AttachmentController, let controller = params.navigationController.viewControllers[params.navigationController.viewControllers.count - 2] as? ChatControllerImpl, controller.chatLocation == params.chatLocation {
|
if let _ = params.navigationController.viewControllers.last as? AttachmentController, let controller = params.navigationController.viewControllers[params.navigationController.viewControllers.count - 2] as? ChatControllerImpl, controller.chatLocation == params.chatLocation.asChatLocation {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
let _ = params.navigationController.popToViewController(controller, animated: params.animated)
|
let _ = params.navigationController.popToViewController(controller, animated: params.animated)
|
||||||
@ -89,7 +103,7 @@ public func navigateToChatControllerImpl(_ params: NavigateToChatControllerParam
|
|||||||
controller.presentAttachmentBot(botId: attachBotStart.botId, payload: attachBotStart.payload, justInstalled: attachBotStart.justInstalled)
|
controller.presentAttachmentBot(botId: attachBotStart.botId, payload: attachBotStart.payload, justInstalled: attachBotStart.justInstalled)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
controller = ChatControllerImpl(context: params.context, chatLocation: params.chatLocation, chatLocationContextHolder: params.chatLocationContextHolder, subject: params.subject, botStart: params.botStart, attachBotStart: params.attachBotStart, peekData: params.peekData, peerNearbyData: params.peerNearbyData, chatListFilter: params.chatListFilter, chatNavigationStack: params.chatNavigationStack)
|
controller = ChatControllerImpl(context: params.context, chatLocation: params.chatLocation.asChatLocation, chatLocationContextHolder: params.chatLocationContextHolder, subject: params.subject, botStart: params.botStart, attachBotStart: params.attachBotStart, peekData: params.peekData, peerNearbyData: params.peerNearbyData, chatListFilter: params.chatListFilter, chatNavigationStack: params.chatNavigationStack)
|
||||||
}
|
}
|
||||||
controller.purposefulAction = params.purposefulAction
|
controller.purposefulAction = params.purposefulAction
|
||||||
if let search = params.activateMessageSearch {
|
if let search = params.activateMessageSearch {
|
||||||
@ -158,16 +172,14 @@ public func navigateToChatControllerImpl(_ params: NavigateToChatControllerParam
|
|||||||
if let item = item as? ChatMessageNotificationItem {
|
if let item = item as? ChatMessageNotificationItem {
|
||||||
for message in item.messages {
|
for message in item.messages {
|
||||||
switch params.chatLocation {
|
switch params.chatLocation {
|
||||||
case let .peer(peerId):
|
case let .peer(peer):
|
||||||
if message.id.peerId == peerId {
|
if message.id.peerId == peer.id {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
case let .replyThread(replyThreadMessage):
|
case let .replyThread(replyThreadMessage):
|
||||||
if message.id.peerId == replyThreadMessage.messageId.peerId {
|
if message.id.peerId == replyThreadMessage.messageId.peerId {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
case .feed:
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -244,7 +256,7 @@ public func navigateToForumThreadImpl(context: AccountContext, peerId: EnginePee
|
|||||||
NavigateToChatControllerParams(
|
NavigateToChatControllerParams(
|
||||||
navigationController: navigationController,
|
navigationController: navigationController,
|
||||||
context: context,
|
context: context,
|
||||||
chatLocation: .replyThread(message: result.message),
|
chatLocation: .replyThread(result.message),
|
||||||
chatLocationContextHolder: result.contextHolder,
|
chatLocationContextHolder: result.contextHolder,
|
||||||
subject: messageId.flatMap { .message(id: .id($0), highlight: true, timecode: nil) },
|
subject: messageId.flatMap { .message(id: .id($0), highlight: true, timecode: nil) },
|
||||||
activateInput: actualActivateInput,
|
activateInput: actualActivateInput,
|
||||||
|
|||||||
@ -114,8 +114,13 @@ func openResolvedUrlImpl(_ resolvedUrl: ResolvedUrl, context: AccountContext, ur
|
|||||||
} else {
|
} else {
|
||||||
let _ = (context.engine.messages.requestStartBotInGroup(botPeerId: botPeerId, groupPeerId: peerId, payload: payload)
|
let _ = (context.engine.messages.requestStartBotInGroup(botPeerId: botPeerId, groupPeerId: peerId, payload: payload)
|
||||||
|> deliverOnMainQueue).start(next: { result in
|
|> deliverOnMainQueue).start(next: { result in
|
||||||
|
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||||
|
|> deliverOnMainQueue).start(next: { peer in
|
||||||
|
guard let peer = peer else {
|
||||||
|
return
|
||||||
|
}
|
||||||
if let navigationController = navigationController {
|
if let navigationController = navigationController {
|
||||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peerId)))
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer)))
|
||||||
}
|
}
|
||||||
switch result {
|
switch result {
|
||||||
case let .channelParticipant(participant):
|
case let .channelParticipant(participant):
|
||||||
@ -124,6 +129,7 @@ func openResolvedUrlImpl(_ resolvedUrl: ResolvedUrl, context: AccountContext, ur
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
controller?.dismiss()
|
controller?.dismiss()
|
||||||
|
})
|
||||||
}, error: { _ in
|
}, error: { _ in
|
||||||
|
|
||||||
})
|
})
|
||||||
@ -508,9 +514,14 @@ func openResolvedUrlImpl(_ resolvedUrl: ResolvedUrl, context: AccountContext, ur
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
case let .joinVoiceChat(peerId, invite):
|
case let .joinVoiceChat(peerId, invite):
|
||||||
|
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||||
|
|> deliverOnMainQueue).start(next: { peer in
|
||||||
|
guard let peer = peer else {
|
||||||
|
return
|
||||||
|
}
|
||||||
dismissInput()
|
dismissInput()
|
||||||
if let navigationController = navigationController {
|
if let navigationController = navigationController {
|
||||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peerId), completion: { chatController in
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer), completion: { chatController in
|
||||||
guard let chatController = chatController as? ChatControllerImpl else {
|
guard let chatController = chatController as? ChatControllerImpl else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -519,6 +530,7 @@ func openResolvedUrlImpl(_ resolvedUrl: ResolvedUrl, context: AccountContext, ur
|
|||||||
}), on: .root, blockInteraction: false, completion: {})
|
}), on: .root, blockInteraction: false, completion: {})
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
})
|
||||||
case .importStickers:
|
case .importStickers:
|
||||||
dismissInput()
|
dismissInput()
|
||||||
if let navigationController = navigationController, let data = UIPasteboard.general.data(forPasteboardType: "org.telegram.third-party.stickerset"), let stickerPack = ImportStickerPack(data: data), !stickerPack.stickers.isEmpty {
|
if let navigationController = navigationController, let data = UIPasteboard.general.data(forPasteboardType: "org.telegram.third-party.stickerset"), let stickerPack = ImportStickerPack(data: data), !stickerPack.stickers.isEmpty {
|
||||||
@ -582,14 +594,23 @@ func openResolvedUrlImpl(_ resolvedUrl: ResolvedUrl, context: AccountContext, ur
|
|||||||
|
|
||||||
if let navigationController = navigationController {
|
if let navigationController = navigationController {
|
||||||
let controller = context.sharedContext.makePeerSelectionController(PeerSelectionControllerParams(context: context, updatedPresentationData: updatedPresentationData, filter: filters, hasChatListSelector: true, hasContactSelector: false, title: presentationData.strings.WebApp_SelectChat))
|
let controller = context.sharedContext.makePeerSelectionController(PeerSelectionControllerParams(context: context, updatedPresentationData: updatedPresentationData, filter: filters, hasChatListSelector: true, hasContactSelector: false, title: presentationData.strings.WebApp_SelectChat))
|
||||||
controller.peerSelected = { peer, _ in
|
controller.peerSelected = { [weak navigationController] peer, _ in
|
||||||
let _ = context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peer.id), attachBotStart: ChatControllerInitialAttachBotStart(botId: bot.peer.id, payload: payload, justInstalled: false), keepStack: .never, useExisting: true))
|
guard let navigationController else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let _ = context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(EnginePeer(peer)), attachBotStart: ChatControllerInitialAttachBotStart(botId: bot.peer.id, payload: payload, justInstalled: false), keepStack: .never, useExisting: true))
|
||||||
}
|
}
|
||||||
navigationController.pushViewController(controller)
|
navigationController.pushViewController(controller)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if let navigationController = navigationController, case let .chat(chatPeerId, _) = urlContext {
|
if case let .chat(chatPeerId, _) = urlContext {
|
||||||
let _ = context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: chatPeerId), attachBotStart: ChatControllerInitialAttachBotStart(botId: peerId, payload: payload, justInstalled: false), keepStack: .never, useExisting: true))
|
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: chatPeerId))
|
||||||
|
|> deliverOnMainQueue).start(next: { chatPeer in
|
||||||
|
guard let navigationController = navigationController, let chatPeer else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let _ = context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(chatPeer), attachBotStart: ChatControllerInitialAttachBotStart(botId: peerId, payload: payload, justInstalled: false), keepStack: .never, useExisting: true))
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
presentError(presentationData.strings.WebApp_AddToAttachmentAlreadyAddedError)
|
presentError(presentationData.strings.WebApp_AddToAttachmentAlreadyAddedError)
|
||||||
}
|
}
|
||||||
@ -625,14 +646,24 @@ func openResolvedUrlImpl(_ resolvedUrl: ResolvedUrl, context: AccountContext, ur
|
|||||||
|
|
||||||
if let navigationController = navigationController {
|
if let navigationController = navigationController {
|
||||||
let controller = context.sharedContext.makePeerSelectionController(PeerSelectionControllerParams(context: context, updatedPresentationData: updatedPresentationData, filter: filters, hasChatListSelector: true, hasContactSelector: false, title: presentationData.strings.WebApp_SelectChat))
|
let controller = context.sharedContext.makePeerSelectionController(PeerSelectionControllerParams(context: context, updatedPresentationData: updatedPresentationData, filter: filters, hasChatListSelector: true, hasContactSelector: false, title: presentationData.strings.WebApp_SelectChat))
|
||||||
controller.peerSelected = { peer, _ in
|
controller.peerSelected = { [weak navigationController] peer, _ in
|
||||||
let _ = context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peer.id), attachBotStart: ChatControllerInitialAttachBotStart(botId: botPeer.id, payload: payload, justInstalled: true), useExisting: true))
|
guard let navigationController else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let _ = context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(EnginePeer(peer)), attachBotStart: ChatControllerInitialAttachBotStart(botId: botPeer.id, payload: payload, justInstalled: true), useExisting: true))
|
||||||
}
|
}
|
||||||
navigationController.pushViewController(controller)
|
navigationController.pushViewController(controller)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if let navigationController = navigationController, case let .chat(chatPeerId, _) = urlContext {
|
if case let .chat(chatPeerId, _) = urlContext {
|
||||||
let _ = context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: chatPeerId), attachBotStart: ChatControllerInitialAttachBotStart(botId: botPeer.id, payload: payload, justInstalled: true), useExisting: true))
|
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: chatPeerId))
|
||||||
|
|> deliverOnMainQueue).start(next: { chatPeer in
|
||||||
|
guard let navigationController = navigationController, let chatPeer else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let _ = context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(chatPeer), attachBotStart: ChatControllerInitialAttachBotStart(botId: botPeer.id, payload: payload, justInstalled: true), useExisting: true))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@ -200,17 +200,17 @@ func openExternalUrlImpl(context: AccountContext, urlContext: OpenURLContext, ur
|
|||||||
case let .chat(_, subject, peekData):
|
case let .chat(_, subject, peekData):
|
||||||
context.sharedContext.applicationBindings.dismissNativeController()
|
context.sharedContext.applicationBindings.dismissNativeController()
|
||||||
if let navigationController = navigationController {
|
if let navigationController = navigationController {
|
||||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peer.id), subject: subject, peekData: peekData))
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer), subject: subject, peekData: peekData))
|
||||||
}
|
}
|
||||||
case let .withBotStartPayload(payload):
|
case let .withBotStartPayload(payload):
|
||||||
context.sharedContext.applicationBindings.dismissNativeController()
|
context.sharedContext.applicationBindings.dismissNativeController()
|
||||||
if let navigationController = navigationController {
|
if let navigationController = navigationController {
|
||||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peer.id), botStart: payload))
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer), botStart: payload))
|
||||||
}
|
}
|
||||||
case let .withAttachBot(attachBotStart):
|
case let .withAttachBot(attachBotStart):
|
||||||
context.sharedContext.applicationBindings.dismissNativeController()
|
context.sharedContext.applicationBindings.dismissNativeController()
|
||||||
if let navigationController = navigationController {
|
if let navigationController = navigationController {
|
||||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peer.id), attachBotStart: attachBotStart))
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer), attachBotStart: attachBotStart))
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
|
|||||||
@ -1216,7 +1216,7 @@ func peerInfoCanEdit(peer: Peer?, threadData: MessageHistoryThreadData?, cachedD
|
|||||||
return true
|
return true
|
||||||
} else if let threadData = threadData, threadData.isOwnedByMe {
|
} else if let threadData = threadData, threadData.isOwnedByMe {
|
||||||
return true
|
return true
|
||||||
} else if let _ = peer.adminRights {
|
} else if peer.hasPermission(.manageTopics) {
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
|
|||||||
@ -2147,9 +2147,9 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
|||||||
|
|
||||||
items.append(.action(ContextMenuActionItem(text: strongSelf.presentationData.strings.SharedMedia_ViewInChat, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/GoToMessage"), color: theme.contextMenu.primaryColor) }, action: { c, _ in
|
items.append(.action(ContextMenuActionItem(text: strongSelf.presentationData.strings.SharedMedia_ViewInChat, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/GoToMessage"), color: theme.contextMenu.primaryColor) }, action: { c, _ in
|
||||||
c.dismiss(completion: {
|
c.dismiss(completion: {
|
||||||
if let strongSelf = self, let navigationController = strongSelf.controller?.navigationController as? NavigationController {
|
if let strongSelf = self, let currentPeer = strongSelf.data?.peer, let navigationController = strongSelf.controller?.navigationController as? NavigationController {
|
||||||
let currentPeerId = strongSelf.peerId
|
let currentPeerId = strongSelf.peerId
|
||||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(id: currentPeerId), subject: .message(id: .id(message.id), highlight: true, timecode: nil), keepStack: .always, useExisting: false, purposefulAction: {
|
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(EnginePeer(currentPeer)), subject: .message(id: .id(message.id), highlight: true, timecode: nil), keepStack: .always, useExisting: false, purposefulAction: {
|
||||||
var viewControllers = navigationController.viewControllers
|
var viewControllers = navigationController.viewControllers
|
||||||
var indexesToRemove = Set<Int>()
|
var indexesToRemove = Set<Int>()
|
||||||
var keptCurrentChatController = false
|
var keptCurrentChatController = false
|
||||||
@ -2298,9 +2298,9 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
|||||||
|
|
||||||
items.append(.action(ContextMenuActionItem(text: strings.SharedMedia_ViewInChat, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/GoToMessage"), color: theme.contextMenu.primaryColor) }, action: { c, f in
|
items.append(.action(ContextMenuActionItem(text: strings.SharedMedia_ViewInChat, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/GoToMessage"), color: theme.contextMenu.primaryColor) }, action: { c, f in
|
||||||
c.dismiss(completion: {
|
c.dismiss(completion: {
|
||||||
if let strongSelf = self, let navigationController = strongSelf.controller?.navigationController as? NavigationController {
|
if let strongSelf = self, let currentPeer = strongSelf.data?.peer, let navigationController = strongSelf.controller?.navigationController as? NavigationController {
|
||||||
let currentPeerId = strongSelf.peerId
|
let currentPeerId = strongSelf.peerId
|
||||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(id: currentPeerId), subject: .message(id: .id(message.id), highlight: true, timecode: nil), keepStack: .always, useExisting: false, purposefulAction: {
|
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(EnginePeer(currentPeer)), subject: .message(id: .id(message.id), highlight: true, timecode: nil), keepStack: .always, useExisting: false, purposefulAction: {
|
||||||
var viewControllers = navigationController.viewControllers
|
var viewControllers = navigationController.viewControllers
|
||||||
var indexesToRemove = Set<Int>()
|
var indexesToRemove = Set<Int>()
|
||||||
var keptCurrentChatController = false
|
var keptCurrentChatController = false
|
||||||
@ -3764,7 +3764,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
|||||||
}
|
}
|
||||||
switch navigation {
|
switch navigation {
|
||||||
case let .chat(_, subject, peekData):
|
case let .chat(_, subject, peekData):
|
||||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(id: peer.id), subject: subject, keepStack: .always, peekData: peekData))
|
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(peer), subject: subject, keepStack: .always, peekData: peekData))
|
||||||
case .info:
|
case .info:
|
||||||
if let strongSelf = self, peer.restrictionText(platform: "ios", contentSettings: strongSelf.context.currentContentSettings.with { $0 }) == nil {
|
if let strongSelf = self, peer.restrictionText(platform: "ios", contentSettings: strongSelf.context.currentContentSettings.with { $0 }) == nil {
|
||||||
if let infoController = strongSelf.context.sharedContext.makePeerInfoController(context: strongSelf.context, updatedPresentationData: nil, peer: peer._asPeer(), mode: .generic, avatarInitiallyExpanded: false, fromChat: false, requestsContext: nil) {
|
if let infoController = strongSelf.context.sharedContext.makePeerInfoController(context: strongSelf.context, updatedPresentationData: nil, peer: peer._asPeer(), mode: .generic, avatarInitiallyExpanded: false, fromChat: false, requestsContext: nil) {
|
||||||
@ -3772,9 +3772,9 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
case let .withBotStartPayload(startPayload):
|
case let .withBotStartPayload(startPayload):
|
||||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(id: peer.id), botStart: startPayload))
|
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(peer), botStart: startPayload))
|
||||||
case let .withAttachBot(attachBotStart):
|
case let .withAttachBot(attachBotStart):
|
||||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(id: peer.id), attachBotStart: attachBotStart))
|
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(peer), attachBotStart: attachBotStart))
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -3828,34 +3828,37 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func openPeer(peerId: PeerId, navigation: ChatControllerInteractionNavigateToPeer) {
|
private func openPeer(peerId: PeerId, navigation: ChatControllerInteractionNavigateToPeer) {
|
||||||
|
let _ = (self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||||
|
|> deliverOnMainQueue).start(next: { [weak self] peer in
|
||||||
|
guard let self, let peer = peer else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
switch navigation {
|
switch navigation {
|
||||||
case .default:
|
case .default:
|
||||||
if let navigationController = self.controller?.navigationController as? NavigationController {
|
if let navigationController = self.controller?.navigationController as? NavigationController {
|
||||||
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(id: peerId), keepStack: .always))
|
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(peer), keepStack: .always))
|
||||||
}
|
}
|
||||||
case let .chat(_, subject, peekData):
|
case let .chat(_, subject, peekData):
|
||||||
if let navigationController = self.controller?.navigationController as? NavigationController {
|
if let navigationController = self.controller?.navigationController as? NavigationController {
|
||||||
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(id: peerId), subject: subject, keepStack: .always, peekData: peekData))
|
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(peer), subject: subject, keepStack: .always, peekData: peekData))
|
||||||
}
|
}
|
||||||
case .info:
|
case .info:
|
||||||
self.resolveUrlDisposable.set((self.context.account.postbox.loadedPeerWithId(peerId)
|
if peer.restrictionText(platform: "ios", contentSettings: self.context.currentContentSettings.with { $0 }) == nil {
|
||||||
|> take(1)
|
if let infoController = self.context.sharedContext.makePeerInfoController(context: self.context, updatedPresentationData: nil, peer: peer._asPeer(), mode: .generic, avatarInitiallyExpanded: false, fromChat: false, requestsContext: nil) {
|
||||||
|> deliverOnMainQueue).start(next: { [weak self] peer in
|
(self.controller?.navigationController as? NavigationController)?.pushViewController(infoController)
|
||||||
if let strongSelf = self, peer.restrictionText(platform: "ios", contentSettings: strongSelf.context.currentContentSettings.with { $0 }) == nil {
|
|
||||||
if let infoController = strongSelf.context.sharedContext.makePeerInfoController(context: strongSelf.context, updatedPresentationData: nil, peer: peer, mode: .generic, avatarInitiallyExpanded: false, fromChat: false, requestsContext: nil) {
|
|
||||||
(strongSelf.controller?.navigationController as? NavigationController)?.pushViewController(infoController)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}))
|
|
||||||
case let .withBotStartPayload(startPayload):
|
case let .withBotStartPayload(startPayload):
|
||||||
if let navigationController = self.controller?.navigationController as? NavigationController {
|
if let navigationController = self.controller?.navigationController as? NavigationController {
|
||||||
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(id: peerId), botStart: startPayload))
|
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(peer), botStart: startPayload))
|
||||||
}
|
}
|
||||||
case let .withAttachBot(attachBotStart):
|
case let .withAttachBot(attachBotStart):
|
||||||
if let navigationController = self.controller?.navigationController as? NavigationController {
|
if let navigationController = self.controller?.navigationController as? NavigationController {
|
||||||
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(id: peerId), attachBotStart: attachBotStart))
|
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(peer), attachBotStart: attachBotStart))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private func openPeerMention(_ name: String, navigation: ChatControllerInteractionNavigateToPeer = .default) {
|
private func openPeerMention(_ name: String, navigation: ChatControllerInteractionNavigateToPeer = .default) {
|
||||||
@ -3971,8 +3974,8 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
|||||||
}
|
}
|
||||||
switch key {
|
switch key {
|
||||||
case .message:
|
case .message:
|
||||||
if let navigationController = controller.navigationController as? NavigationController {
|
if let navigationController = controller.navigationController as? NavigationController, let peer = self.data?.peer {
|
||||||
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(id: self.peerId), keepStack: self.nearbyPeerDistance != nil ? .always : .default, peerNearbyData: self.nearbyPeerDistance.flatMap({ ChatPeerNearbyData(distance: $0) }), completion: { [weak self] _ in
|
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(EnginePeer(peer)), keepStack: self.nearbyPeerDistance != nil ? .always : .default, peerNearbyData: self.nearbyPeerDistance.flatMap({ ChatPeerNearbyData(distance: $0) }), completion: { [weak self] _ in
|
||||||
if let strongSelf = self, strongSelf.nearbyPeerDistance != nil {
|
if let strongSelf = self, strongSelf.nearbyPeerDistance != nil {
|
||||||
var viewControllers = navigationController.viewControllers
|
var viewControllers = navigationController.viewControllers
|
||||||
viewControllers = viewControllers.filter { controller in
|
viewControllers = viewControllers.filter { controller in
|
||||||
@ -3987,9 +3990,15 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
|||||||
}
|
}
|
||||||
case .discussion:
|
case .discussion:
|
||||||
if let cachedData = self.data?.cachedData as? CachedChannelData, case let .known(maybeLinkedDiscussionPeerId) = cachedData.linkedDiscussionPeerId, let linkedDiscussionPeerId = maybeLinkedDiscussionPeerId {
|
if let cachedData = self.data?.cachedData as? CachedChannelData, case let .known(maybeLinkedDiscussionPeerId) = cachedData.linkedDiscussionPeerId, let linkedDiscussionPeerId = maybeLinkedDiscussionPeerId {
|
||||||
if let navigationController = controller.navigationController as? NavigationController {
|
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: linkedDiscussionPeerId))
|
||||||
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(id: linkedDiscussionPeerId)))
|
|> deliverOnMainQueue).start(next: { [weak self] linkedDiscussionPeer in
|
||||||
|
guard let self, let linkedDiscussionPeer else {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
if let navigationController = controller.navigationController as? NavigationController {
|
||||||
|
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(linkedDiscussionPeer)))
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
case .call:
|
case .call:
|
||||||
self.requestCall(isVideo: false)
|
self.requestCall(isVideo: false)
|
||||||
@ -4915,8 +4924,8 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
|||||||
}
|
}
|
||||||
navigationController.setViewControllers(viewControllers, animated: true)
|
navigationController.setViewControllers(viewControllers, animated: true)
|
||||||
current.activateSearch()
|
current.activateSearch()
|
||||||
} else {
|
} else if let peer = self.data?.peer {
|
||||||
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(id: self.peerId), keepStack: self.nearbyPeerDistance != nil ? .always : .default, activateMessageSearch: (.everything, ""), peerNearbyData: self.nearbyPeerDistance.flatMap({ ChatPeerNearbyData(distance: $0) }), completion: { [weak self] _ in
|
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(EnginePeer(peer)), keepStack: self.nearbyPeerDistance != nil ? .always : .default, activateMessageSearch: (.everything, ""), peerNearbyData: self.nearbyPeerDistance.flatMap({ ChatPeerNearbyData(distance: $0) }), completion: { [weak self] _ in
|
||||||
if let strongSelf = self, strongSelf.nearbyPeerDistance != nil {
|
if let strongSelf = self, strongSelf.nearbyPeerDistance != nil {
|
||||||
var viewControllers = navigationController.viewControllers
|
var viewControllers = navigationController.viewControllers
|
||||||
viewControllers = viewControllers.filter { controller in
|
viewControllers = viewControllers.filter { controller in
|
||||||
@ -4933,15 +4942,15 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func openChatForReporting(_ reason: ReportReason) {
|
private func openChatForReporting(_ reason: ReportReason) {
|
||||||
if let navigationController = (self.controller?.navigationController as? NavigationController) {
|
if let peer = self.data?.peer, let navigationController = (self.controller?.navigationController as? NavigationController) {
|
||||||
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(id: self.peerId), keepStack: .default, reportReason: reason, completion: { _ in
|
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(EnginePeer(peer)), keepStack: .default, reportReason: reason, completion: { _ in
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func openChatForThemeChange() {
|
private func openChatForThemeChange() {
|
||||||
if let navigationController = (self.controller?.navigationController as? NavigationController) {
|
if let peer = self.data?.peer, let navigationController = (self.controller?.navigationController as? NavigationController) {
|
||||||
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(id: self.peerId), keepStack: .default, changeColors: true, completion: { _ in
|
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(EnginePeer(peer)), keepStack: .default, changeColors: true, completion: { _ in
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5070,9 +5079,15 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
|||||||
guard let strongSelf = self else {
|
guard let strongSelf = self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if let navigationController = (strongSelf.controller?.navigationController as? NavigationController) {
|
let _ = (strongSelf.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(id: peerId)))
|
|> deliverOnMainQueue).start(next: { peer in
|
||||||
|
guard let strongSelf = self, let peer = peer else {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
if let navigationController = (strongSelf.controller?.navigationController as? NavigationController) {
|
||||||
|
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(peer)))
|
||||||
|
}
|
||||||
|
})
|
||||||
}, error: { error in
|
}, error: { error in
|
||||||
guard let strongSelf = self else {
|
guard let strongSelf = self else {
|
||||||
return
|
return
|
||||||
@ -5549,8 +5564,8 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func openChat() {
|
private func openChat() {
|
||||||
if let navigationController = self.controller?.navigationController as? NavigationController {
|
if let peer = self.data?.peer, let navigationController = self.controller?.navigationController as? NavigationController {
|
||||||
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(id: self.peerId), keepStack: self.nearbyPeerDistance != nil ? .always : .default, peerNearbyData: self.nearbyPeerDistance.flatMap({ ChatPeerNearbyData(distance: $0) }), completion: { [weak self] _ in
|
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(EnginePeer(peer)), keepStack: self.nearbyPeerDistance != nil ? .always : .default, peerNearbyData: self.nearbyPeerDistance.flatMap({ ChatPeerNearbyData(distance: $0) }), completion: { [weak self] _ in
|
||||||
if let strongSelf = self, strongSelf.nearbyPeerDistance != nil {
|
if let strongSelf = self, strongSelf.nearbyPeerDistance != nil {
|
||||||
var viewControllers = navigationController.viewControllers
|
var viewControllers = navigationController.viewControllers
|
||||||
viewControllers = viewControllers.filter { controller in
|
viewControllers = viewControllers.filter { controller in
|
||||||
@ -5566,11 +5581,11 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func openChatWithClearedHistory(type: InteractiveHistoryClearingType) {
|
private func openChatWithClearedHistory(type: InteractiveHistoryClearingType) {
|
||||||
guard let navigationController = self.controller?.navigationController as? NavigationController else {
|
guard let peer = self.data?.peer, let navigationController = self.controller?.navigationController as? NavigationController else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(id: self.peerId), keepStack: self.nearbyPeerDistance != nil ? .always : .default, peerNearbyData: self.nearbyPeerDistance.flatMap({ ChatPeerNearbyData(distance: $0) }), setupController: { controller in
|
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(EnginePeer(peer)), keepStack: self.nearbyPeerDistance != nil ? .always : .default, peerNearbyData: self.nearbyPeerDistance.flatMap({ ChatPeerNearbyData(distance: $0) }), setupController: { controller in
|
||||||
(controller as? ChatControllerImpl)?.beginClearHistory(type: type)
|
(controller as? ChatControllerImpl)?.beginClearHistory(type: type)
|
||||||
}, completion: { [weak self] _ in
|
}, completion: { [weak self] _ in
|
||||||
if let strongSelf = self, strongSelf.nearbyPeerDistance != nil {
|
if let strongSelf = self, strongSelf.nearbyPeerDistance != nil {
|
||||||
@ -5615,7 +5630,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
|||||||
if !block {
|
if !block {
|
||||||
let _ = enqueueMessages(account: strongSelf.context.account, peerId: peer.id, messages: [.message(text: "/start", attributes: [], inlineStickers: [:], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])]).start()
|
let _ = enqueueMessages(account: strongSelf.context.account, peerId: peer.id, messages: [.message(text: "/start", attributes: [], inlineStickers: [:], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])]).start()
|
||||||
if let navigationController = strongSelf.controller?.navigationController as? NavigationController {
|
if let navigationController = strongSelf.controller?.navigationController as? NavigationController {
|
||||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(id: peer.id)))
|
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(EnginePeer(peer))))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -6040,8 +6055,8 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
|||||||
}
|
}
|
||||||
let _ = enqueueMessages(account: strongSelf.context.account, peerId: peer.id, messages: [.message(text: text, attributes: [], inlineStickers: [:], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])]).start()
|
let _ = enqueueMessages(account: strongSelf.context.account, peerId: peer.id, messages: [.message(text: text, attributes: [], inlineStickers: [:], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil, bubbleUpEmojiOrStickersets: [])]).start()
|
||||||
|
|
||||||
if let navigationController = strongSelf.controller?.navigationController as? NavigationController {
|
if let peer = strongSelf.data?.peer, let navigationController = strongSelf.controller?.navigationController as? NavigationController {
|
||||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(id: strongSelf.peerId)))
|
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(EnginePeer(peer))))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -6902,9 +6917,15 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
|||||||
case .proxy:
|
case .proxy:
|
||||||
self.controller?.push(proxySettingsController(context: self.context))
|
self.controller?.push(proxySettingsController(context: self.context))
|
||||||
case .savedMessages:
|
case .savedMessages:
|
||||||
if let controller = self.controller, let navigationController = controller.navigationController as? NavigationController {
|
let _ = (self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: self.context.account.peerId))
|
||||||
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(id: self.context.account.peerId)))
|
|> deliverOnMainQueue).start(next: { [weak self] peer in
|
||||||
|
guard let self, let peer = peer else {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
if let controller = self.controller, let navigationController = controller.navigationController as? NavigationController {
|
||||||
|
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(peer)))
|
||||||
|
}
|
||||||
|
})
|
||||||
case .recentCalls:
|
case .recentCalls:
|
||||||
push(CallListController(context: context, mode: .navigation))
|
push(CallListController(context: context, mode: .navigation))
|
||||||
case .devices:
|
case .devices:
|
||||||
@ -7114,7 +7135,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
|||||||
self.tipsPeerDisposable.set((self.context.engine.peers.resolvePeerByName(name: self.presentationData.strings.Settings_TipsUsername) |> deliverOnMainQueue).start(next: { [weak controller] peer in
|
self.tipsPeerDisposable.set((self.context.engine.peers.resolvePeerByName(name: self.presentationData.strings.Settings_TipsUsername) |> deliverOnMainQueue).start(next: { [weak controller] peer in
|
||||||
controller?.dismiss()
|
controller?.dismiss()
|
||||||
if let peer = peer, let navigationController = navigationController {
|
if let peer = peer, let navigationController = navigationController {
|
||||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peer.id)))
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer)))
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
@ -7767,7 +7788,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
|||||||
f(.dismissWithoutContent)
|
f(.dismissWithoutContent)
|
||||||
dismissCalendarScreen?()
|
dismissCalendarScreen?()
|
||||||
|
|
||||||
guard let strongSelf = self, let controller = strongSelf.controller, let navigationController = controller.navigationController as? NavigationController else {
|
guard let strongSelf = self, let peer = strongSelf.data?.peer, let controller = strongSelf.controller, let navigationController = controller.navigationController as? NavigationController else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7775,7 +7796,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
|||||||
navigationController: navigationController,
|
navigationController: navigationController,
|
||||||
chatController: nil,
|
chatController: nil,
|
||||||
context: strongSelf.context,
|
context: strongSelf.context,
|
||||||
chatLocation: .peer(id: strongSelf.peerId),
|
chatLocation: .peer(EnginePeer(peer)),
|
||||||
subject: .message(id: .id(index.id), highlight: false, timecode: nil),
|
subject: .message(id: .id(index.id), highlight: false, timecode: nil),
|
||||||
botStart: nil,
|
botStart: nil,
|
||||||
updateTextInputState: nil,
|
updateTextInputState: nil,
|
||||||
@ -8933,7 +8954,7 @@ public final class PeerInfoScreenImpl: ViewController, PeerInfoScreen, KeyShortc
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(id: peer.id), animated: true, completion: { _ in
|
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(peer), animated: true, completion: { _ in
|
||||||
}))
|
}))
|
||||||
})))
|
})))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -30,7 +30,7 @@ func handleTextLinkActionImpl(context: AccountContext, peerId: PeerId?, navigate
|
|||||||
switch navigation {
|
switch navigation {
|
||||||
case let .chat(_, subject, peekData):
|
case let .chat(_, subject, peekData):
|
||||||
if let navigationController = controller?.navigationController as? NavigationController {
|
if let navigationController = controller?.navigationController as? NavigationController {
|
||||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peer.id), subject: subject, keepStack: .always, peekData: peekData))
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer), subject: subject, keepStack: .always, peekData: peekData))
|
||||||
}
|
}
|
||||||
case .info:
|
case .info:
|
||||||
let peerSignal: Signal<Peer?, NoError>
|
let peerSignal: Signal<Peer?, NoError>
|
||||||
@ -62,7 +62,7 @@ func handleTextLinkActionImpl(context: AccountContext, peerId: PeerId?, navigate
|
|||||||
openResolvedPeerImpl(peer.flatMap(EnginePeer.init), navigation)
|
openResolvedPeerImpl(peer.flatMap(EnginePeer.init), navigation)
|
||||||
case let .channelMessage(peer, messageId, timecode):
|
case let .channelMessage(peer, messageId, timecode):
|
||||||
if let navigationController = controller.navigationController as? NavigationController {
|
if let navigationController = controller.navigationController as? NavigationController {
|
||||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peer.id), subject: .message(id: .id(messageId), highlight: true, timecode: timecode)))
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(EnginePeer(peer)), subject: .message(id: .id(messageId), highlight: true, timecode: timecode)))
|
||||||
}
|
}
|
||||||
case let .replyThreadMessage(replyThreadMessage, messageId):
|
case let .replyThreadMessage(replyThreadMessage, messageId):
|
||||||
if let navigationController = controller.navigationController as? NavigationController {
|
if let navigationController = controller.navigationController as? NavigationController {
|
||||||
|
|||||||
@ -1116,10 +1116,22 @@ public final class WebAppController: ViewController, AttachmentContainable {
|
|||||||
}, action: { [weak self] c, _ in
|
}, action: { [weak self] c, _ in
|
||||||
c.dismiss(completion: nil)
|
c.dismiss(completion: nil)
|
||||||
|
|
||||||
|
guard let strongSelf = self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let _ = (context.engine.data.get(
|
||||||
|
TelegramEngine.EngineData.Item.Peer.Peer(id: strongSelf.botId)
|
||||||
|
)
|
||||||
|
|> deliverOnMainQueue).start(next: { botPeer in
|
||||||
|
guard let botPeer = botPeer else {
|
||||||
|
return
|
||||||
|
}
|
||||||
if let strongSelf = self, let navigationController = strongSelf.getNavigationController() {
|
if let strongSelf = self, let navigationController = strongSelf.getNavigationController() {
|
||||||
strongSelf.dismiss()
|
strongSelf.dismiss()
|
||||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(id: strongSelf.botId)))
|
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(botPeer)))
|
||||||
}
|
}
|
||||||
|
})
|
||||||
})))
|
})))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user