mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-11-06 17:00:13 +00:00
Another feed experiment
This commit is contained in:
parent
fe0311b1e9
commit
a9c595a640
3
.bazelrc
3
.bazelrc
@ -8,7 +8,8 @@ build --per_file_copt="third-party/webrtc/.*\.cc$","@-std=c++14"
|
||||
build --per_file_copt="third-party/webrtc/.*\.mm$","@-std=c++14"
|
||||
build --per_file_copt="submodules/LottieMeshSwift/LottieMeshBinding/Sources/.*\.mm$","@-std=c++14"
|
||||
|
||||
build --swiftcopt=-disallow-use-new-driver
|
||||
#build --swiftcopt=-disallow-use-new-driver
|
||||
build --swiftcopt=-whole-module-optimization
|
||||
|
||||
#build --swiftcopt=-sanitize=address
|
||||
#build --copt=-fsanitize=address
|
||||
|
||||
@ -49,7 +49,7 @@ func unreadMessages(account: Account) -> Signal<[INMessage], NoError> {
|
||||
}
|
||||
|
||||
if !isMuted && hasUnread {
|
||||
signals.append(account.postbox.aroundMessageHistoryViewForLocation(.peer(index.messageIndex.id.peerId), anchor: .upperBound, ignoreMessagesInTimestampRange: nil, count: 10, fixedCombinedReadStates: fixedCombinedReadStates, topTaggedMessageIdNamespaces: Set(), tagMask: nil, appendMessagesFromTheSameGroup: false, namespaces: .not(Namespaces.Message.allScheduled), orderStatistics: .combinedLocation)
|
||||
signals.append(account.postbox.aroundMessageHistoryViewForLocation(.peer(peerId: index.messageIndex.id.peerId), anchor: .upperBound, ignoreMessagesInTimestampRange: nil, count: 10, fixedCombinedReadStates: fixedCombinedReadStates, topTaggedMessageIdNamespaces: Set(), tagMask: nil, appendMessagesFromTheSameGroup: false, namespaces: .not(Namespaces.Message.allScheduled), orderStatistics: .combinedLocation)
|
||||
|> take(1)
|
||||
|> map { view -> [INMessage] in
|
||||
var messages: [INMessage] = []
|
||||
|
||||
@ -41,6 +41,7 @@ def generate(build_environment: BuildEnvironment, disable_extensions, disable_pr
|
||||
tulsi_build_command += ['--xcode_version={}'.format(build_environment.xcode_version)]
|
||||
tulsi_build_command += ['--use_top_level_targets_for_symlinks']
|
||||
tulsi_build_command += ['--verbose_failures']
|
||||
tulsi_build_command += ['--swiftcopt=-whole-module-optimization']
|
||||
|
||||
call_executable(tulsi_build_command)
|
||||
|
||||
|
||||
@ -1 +1 @@
|
||||
Subproject commit ec7dd9ddf4b73dedb02df827b7ab3b2cbb1f2ac0
|
||||
Subproject commit 2b8fbf5a95d43dd43ba20b5a690c2bf8e1146063
|
||||
@ -267,8 +267,9 @@ public enum ChatSearchDomain: Equatable {
|
||||
}
|
||||
|
||||
public enum ChatLocation: Equatable {
|
||||
case peer(PeerId)
|
||||
case replyThread(ChatReplyThreadMessage)
|
||||
case peer(id: PeerId)
|
||||
case replyThread(message: ChatReplyThreadMessage)
|
||||
case feed(id: Int32)
|
||||
}
|
||||
|
||||
public final class NavigateToChatControllerParams {
|
||||
|
||||
@ -10,6 +10,7 @@ import UniversalMediaPlayer
|
||||
public enum PeerMessagesMediaPlaylistId: Equatable, SharedMediaPlaylistId {
|
||||
case peer(PeerId)
|
||||
case recentActions(PeerId)
|
||||
case feed(Int32)
|
||||
case custom
|
||||
|
||||
public func isEqual(to: SharedMediaPlaylistId) -> Bool {
|
||||
@ -34,6 +35,8 @@ public enum PeerMessagesPlaylistLocation: Equatable, SharedMediaPlaylistLocation
|
||||
return .peer(peerId)
|
||||
case let .replyThread(replyThreaMessage):
|
||||
return .peer(replyThreaMessage.messageId.peerId)
|
||||
case let .feed(id):
|
||||
return .feed(id)
|
||||
}
|
||||
case let .singleMessage(id):
|
||||
return .peer(id.peerId)
|
||||
|
||||
@ -248,7 +248,7 @@ public class AttachmentTextInputPanelNode: ASDisplayNode, TGCaptionPanelView, AS
|
||||
self.isAttachment = isAttachment
|
||||
|
||||
var hasSpoilers = true
|
||||
if presentationInterfaceState.chatLocation.peerId.namespace == Namespaces.Peer.SecretChat {
|
||||
if presentationInterfaceState.chatLocation.peerId?.namespace == Namespaces.Peer.SecretChat {
|
||||
hasSpoilers = false
|
||||
}
|
||||
self.inputMenu = TextInputMenu(hasSpoilers: hasSpoilers)
|
||||
|
||||
@ -374,7 +374,7 @@ func chatContextMenuItems(context: AccountContext, peerId: PeerId, promoInfo: Ch
|
||||
}
|
||||
}, completed: {
|
||||
if let navigationController = (chatListController?.navigationController as? NavigationController) {
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peerId)))
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peerId)))
|
||||
}
|
||||
}))
|
||||
f(.default)
|
||||
|
||||
@ -895,7 +895,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
scrollToEndIfExists = true
|
||||
}
|
||||
|
||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(peer.id), activateInput: activateInput && !peer.isDeleted, scrollToEndIfExists: scrollToEndIfExists, animated: !scrollToEndIfExists, options: strongSelf.groupId == PeerGroupId.root ? [.removeOnMasterDetails] : [], parentGroupId: strongSelf.groupId, chatListFilter: strongSelf.chatListDisplayNode.containerNode.currentItemNode.chatListFilter?.id, completion: { [weak self] controller in
|
||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(id: peer.id), activateInput: activateInput && !peer.isDeleted, scrollToEndIfExists: scrollToEndIfExists, animated: !scrollToEndIfExists, options: strongSelf.groupId == PeerGroupId.root ? [.removeOnMasterDetails] : [], parentGroupId: strongSelf.groupId, chatListFilter: strongSelf.chatListDisplayNode.containerNode.currentItemNode.chatListFilter?.id, completion: { [weak self] controller in
|
||||
self?.chatListDisplayNode.containerNode.currentItemNode.clearHighlightAnimated(true)
|
||||
if let promoInfo = promoInfo {
|
||||
switch promoInfo {
|
||||
@ -974,7 +974,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
if let layout = strongSelf.validLayout, case .regular = layout.metrics.widthClass {
|
||||
scrollToEndIfExists = true
|
||||
}
|
||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(actualPeerId), subject: .message(id: .id(messageId), highlight: true, timecode: nil), purposefulAction: {
|
||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(id: actualPeerId), subject: .message(id: .id(messageId), highlight: true, timecode: nil), purposefulAction: {
|
||||
if deactivateOnAction {
|
||||
self?.deactivateSearch(animated: false)
|
||||
}
|
||||
@ -1005,7 +1005,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
scrollToEndIfExists = true
|
||||
}
|
||||
if let navigationController = strongSelf.navigationController as? NavigationController {
|
||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(peer.id), purposefulAction: { [weak self] in
|
||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(id: peer.id), purposefulAction: { [weak self] in
|
||||
self?.deactivateSearch(animated: false)
|
||||
}, scrollToEndIfExists: scrollToEndIfExists, options: strongSelf.groupId == PeerGroupId.root ? [.removeOnMasterDetails] : []))
|
||||
strongSelf.chatListDisplayNode.containerNode.currentItemNode.clearHighlightAnimated(true)
|
||||
@ -1125,7 +1125,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
let contextController = ContextController(account: strongSelf.context.account, presentationData: strongSelf.presentationData, source: .controller(ContextControllerContentSourceImpl(controller: chatListController, sourceNode: node, navigationController: strongSelf.navigationController as? NavigationController)), items: archiveContextMenuItems(context: strongSelf.context, groupId: groupId._asGroup(), chatListController: strongSelf) |> map { ContextController.Items(content: .list($0)) }, gesture: gesture)
|
||||
strongSelf.presentInGlobalOverlay(contextController)
|
||||
case let .peer(_, peer, _, _, _, _, _, _, _, promoInfo, _, _, _):
|
||||
let chatController = strongSelf.context.sharedContext.makeChatController(context: strongSelf.context, chatLocation: .peer(peer.peerId), subject: nil, botStart: nil, mode: .standard(previewing: true))
|
||||
let chatController = strongSelf.context.sharedContext.makeChatController(context: strongSelf.context, chatLocation: .peer(id: peer.peerId), subject: nil, botStart: nil, mode: .standard(previewing: true))
|
||||
chatController.canReadHistory.set(false)
|
||||
let contextController = ContextController(account: strongSelf.context.account, presentationData: strongSelf.presentationData, source: .controller(ContextControllerContentSourceImpl(controller: chatController, sourceNode: node, navigationController: strongSelf.navigationController as? NavigationController)), items: chatContextMenuItems(context: strongSelf.context, peerId: peer.peerId, promoInfo: promoInfo, source: .chatList(filter: strongSelf.chatListDisplayNode.containerNode.currentItemNode.chatListFilter), chatListController: strongSelf, joined: joined) |> map { ContextController.Items(content: .list($0)) }, gesture: gesture)
|
||||
strongSelf.presentInGlobalOverlay(contextController)
|
||||
@ -1146,7 +1146,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
if case let .search(messageId) = source, let id = messageId {
|
||||
subject = .message(id: .id(id), highlight: false, timecode: nil)
|
||||
}
|
||||
let chatController = strongSelf.context.sharedContext.makeChatController(context: strongSelf.context, chatLocation: .peer(peer.id), subject: subject, botStart: nil, mode: .standard(previewing: true))
|
||||
let chatController = strongSelf.context.sharedContext.makeChatController(context: strongSelf.context, chatLocation: .peer(id: peer.id), subject: subject, botStart: nil, mode: .standard(previewing: true))
|
||||
chatController.canReadHistory.set(false)
|
||||
contextContentSource = .controller(ContextControllerContentSourceImpl(controller: chatController, sourceNode: node, navigationController: strongSelf.navigationController as? NavigationController))
|
||||
}
|
||||
@ -1378,6 +1378,22 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
})))
|
||||
}
|
||||
|
||||
if let id = id {
|
||||
//TODO:localize
|
||||
items.append(.action(ContextMenuActionItem(text: "View as Feed", icon: { _ in
|
||||
return nil
|
||||
}, action: { c, f in
|
||||
c.dismiss(completion: {
|
||||
guard let strongSelf = self, let navigationController = strongSelf.navigationController as? NavigationController else {
|
||||
return
|
||||
}
|
||||
|
||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .feed(id: id), subject: nil, purposefulAction: {
|
||||
}, scrollToEndIfExists: false, options: []))
|
||||
})
|
||||
})))
|
||||
}
|
||||
|
||||
let controller = ContextController(account: strongSelf.context.account, presentationData: strongSelf.presentationData, source: .extracted(ChatListHeaderBarContextExtractedContentSource(controller: strongSelf, sourceNode: sourceNode, keepInPlace: keepInPlace)), items: .single(ContextController.Items(content: .list(items))), recognizer: nil, gesture: gesture)
|
||||
strongSelf.context.sharedContext.mainWindow?.presentInGlobalOverlay(controller)
|
||||
})
|
||||
|
||||
@ -1009,7 +1009,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
|
||||
|
||||
private func mediaMessageContextAction(_ message: EngineMessage, node: ASDisplayNode?, rect: CGRect?, gesture anyRecognizer: UIGestureRecognizer?) {
|
||||
let gesture: ContextGesture? = anyRecognizer as? ContextGesture
|
||||
let _ = (chatMediaListPreviewControllerData(context: self.context, chatLocation: .peer(message.id.peerId), chatLocationContextHolder: Atomic<ChatLocationContextHolder?>(value: nil), message: message._asMessage(), standalone: true, reverseMessageGalleryOrder: false, navigationController: self.navigationController)
|
||||
let _ = (chatMediaListPreviewControllerData(context: self.context, chatLocation: .peer(id: message.id.peerId), chatLocationContextHolder: Atomic<ChatLocationContextHolder?>(value: nil), message: message._asMessage(), standalone: true, reverseMessageGalleryOrder: false, navigationController: self.navigationController)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] previewData in
|
||||
guard let strongSelf = self else {
|
||||
gesture?.cancel()
|
||||
@ -1351,7 +1351,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
|
||||
})
|
||||
|> deliverOnMainQueue).start(completed: {
|
||||
if let strongSelf = self {
|
||||
let controller = strongSelf.context.sharedContext.makeChatController(context: strongSelf.context, chatLocation: .peer(peerId), subject: nil, botStart: nil, mode: .standard(previewing: false))
|
||||
let controller = strongSelf.context.sharedContext.makeChatController(context: strongSelf.context, chatLocation: .peer(id: peerId), subject: nil, botStart: nil, mode: .standard(previewing: false))
|
||||
controller.purposefulAction = { [weak self] in
|
||||
self?.cancel?()
|
||||
}
|
||||
|
||||
@ -576,7 +576,7 @@ public enum ChatListSearchEntry: Comparable, Identifiable {
|
||||
isMedia = true
|
||||
}
|
||||
if isMedia {
|
||||
return ListMessageItem(presentationData: ChatPresentationData(theme: ChatPresentationThemeData(theme: presentationData.theme, wallpaper: .builtin(WallpaperSettings())), fontSize: presentationData.fontSize, strings: presentationData.strings, dateTimeFormat: presentationData.dateTimeFormat, nameDisplayOrder: presentationData.nameDisplayOrder, disableAnimations: true, largeEmoji: false, chatBubbleCorners: PresentationChatBubbleCorners(mainRadius: 0.0, auxiliaryRadius: 0.0, mergeBubbleCorners: false)), context: context, chatLocation: .peer(peer.peerId), interaction: listInteraction, message: message._asMessage(), selection: selection, displayHeader: enableHeaders && !displayCustomHeader, customHeader: key == .downloads ? header : nil, hintIsLink: tagMask == .webPage, isGlobalSearchResult: key != .downloads, isDownloadList: key == .downloads)
|
||||
return ListMessageItem(presentationData: ChatPresentationData(theme: ChatPresentationThemeData(theme: presentationData.theme, wallpaper: .builtin(WallpaperSettings())), fontSize: presentationData.fontSize, strings: presentationData.strings, dateTimeFormat: presentationData.dateTimeFormat, nameDisplayOrder: presentationData.nameDisplayOrder, disableAnimations: true, largeEmoji: false, chatBubbleCorners: PresentationChatBubbleCorners(mainRadius: 0.0, auxiliaryRadius: 0.0, mergeBubbleCorners: false)), context: context, chatLocation: .peer(id: peer.peerId), interaction: listInteraction, message: message._asMessage(), selection: selection, displayHeader: enableHeaders && !displayCustomHeader, customHeader: key == .downloads ? header : nil, hintIsLink: tagMask == .webPage, isGlobalSearchResult: key != .downloads, isDownloadList: key == .downloads)
|
||||
} else {
|
||||
return ChatListItem(presentationData: presentationData, context: context, peerGroupId: .root, filterData: nil, index: EngineChatList.Item.Index(pinningIndex: nil, messageIndex: message.index), content: .peer(messages: [message], peer: peer, combinedReadState: readState, isRemovedFromTotalUnreadCount: false, presence: nil, hasUnseenMentions: false, hasUnseenReactions: false, draftState: nil, inputActivities: nil, promoInfo: nil, ignoreUnreadBadge: true, displayAsMessage: false, hasFailedMessages: false), editing: false, hasActiveRevealControls: false, selected: false, header: tagMask == nil ? header : nil, enableContextActions: false, hiddenOffset: false, interaction: interaction)
|
||||
}
|
||||
@ -1500,7 +1500,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
||||
let gallerySource: GalleryControllerItemSource
|
||||
|
||||
if strongSelf.key == .downloads {
|
||||
gallerySource = .peerMessagesAtId(messageId: message.id, chatLocation: .peer(message.id.peerId), chatLocationContextHolder: Atomic<ChatLocationContextHolder?>(value: nil))
|
||||
gallerySource = .peerMessagesAtId(messageId: message.id, chatLocation: .peer(id: message.id.peerId), chatLocationContextHolder: Atomic<ChatLocationContextHolder?>(value: nil))
|
||||
} else {
|
||||
gallerySource = .custom(messages: foundMessages |> map { message, a, b in
|
||||
return (message.map { $0._asMessage() }, a, b)
|
||||
@ -1520,7 +1520,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
||||
})
|
||||
}
|
||||
|
||||
return context.sharedContext.openChatMessage(OpenChatMessageParams(context: context, chatLocation: .peer(message.id.peerId), chatLocationContextHolder: nil, message: message, standalone: false, reverseMessageGalleryOrder: true, mode: mode, navigationController: navigationController, dismissInput: {
|
||||
return context.sharedContext.openChatMessage(OpenChatMessageParams(context: context, chatLocation: .peer(id: message.id.peerId), chatLocationContextHolder: nil, message: message, standalone: false, reverseMessageGalleryOrder: true, mode: mode, navigationController: navigationController, dismissInput: {
|
||||
interaction.dismissInput()
|
||||
}, present: { c, a in
|
||||
interaction.present(c, a)
|
||||
@ -2183,7 +2183,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
||||
strongSelf.interaction.dismissInput()
|
||||
strongSelf.interaction.present(controller, nil)
|
||||
} else {
|
||||
let signal = strongSelf.context.sharedContext.messageFromPreloadedChatHistoryViewForLocation(id: id.messageId, location: ChatHistoryLocationInput(content: .InitialSearch(location: .id(id.messageId), count: 60, highlight: true), id: 0), context: strongSelf.context, chatLocation: .peer(id.messageId.peerId), subject: nil, chatLocationContextHolder: Atomic<ChatLocationContextHolder?>(value: nil), tagMask: EngineMessage.Tags.music)
|
||||
let signal = strongSelf.context.sharedContext.messageFromPreloadedChatHistoryViewForLocation(id: id.messageId, location: ChatHistoryLocationInput(content: .InitialSearch(location: .id(id.messageId), count: 60, highlight: true), id: 0), context: strongSelf.context, chatLocation: .peer(id: id.messageId.peerId), subject: nil, chatLocationContextHolder: Atomic<ChatLocationContextHolder?>(value: nil), tagMask: EngineMessage.Tags.music)
|
||||
|
||||
var cancelImpl: (() -> Void)?
|
||||
let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 }
|
||||
@ -2764,7 +2764,7 @@ private final class ChatListSearchShimmerNode: ASDisplayNode {
|
||||
associatedMessageIds: []
|
||||
)
|
||||
|
||||
return ListMessageItem(presentationData: ChatPresentationData(presentationData: presentationData), context: context, chatLocation: .peer(peer1.id), interaction: ListMessageItemInteraction.default, message: message._asMessage(), selection: hasSelection ? .selectable(selected: false) : .none, displayHeader: false, customHeader: nil, hintIsLink: true, isGlobalSearchResult: true)
|
||||
return ListMessageItem(presentationData: ChatPresentationData(presentationData: presentationData), context: context, chatLocation: .peer(id: peer1.id), interaction: ListMessageItemInteraction.default, message: message._asMessage(), selection: hasSelection ? .selectable(selected: false) : .none, displayHeader: false, customHeader: nil, hintIsLink: true, isGlobalSearchResult: true)
|
||||
case .files:
|
||||
var media: [EngineMedia] = []
|
||||
media.append(.file(TelegramMediaFile(fileId: EngineMedia.Id(namespace: 0, id: 0), partialReference: nil, resource: LocalFileMediaResource(fileId: 0), previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "application/text", size: 0, attributes: [.FileName(fileName: "Text.txt")])))
|
||||
@ -2791,7 +2791,7 @@ private final class ChatListSearchShimmerNode: ASDisplayNode {
|
||||
associatedMessageIds: []
|
||||
)
|
||||
|
||||
return ListMessageItem(presentationData: ChatPresentationData(presentationData: presentationData), context: context, chatLocation: .peer(peer1.id), interaction: ListMessageItemInteraction.default, message: message._asMessage(), selection: hasSelection ? .selectable(selected: false) : .none, displayHeader: false, customHeader: nil, hintIsLink: false, isGlobalSearchResult: true)
|
||||
return ListMessageItem(presentationData: ChatPresentationData(presentationData: presentationData), context: context, chatLocation: .peer(id: peer1.id), interaction: ListMessageItemInteraction.default, message: message._asMessage(), selection: hasSelection ? .selectable(selected: false) : .none, displayHeader: false, customHeader: nil, hintIsLink: false, isGlobalSearchResult: true)
|
||||
case .music:
|
||||
var media: [EngineMedia] = []
|
||||
media.append(.file(TelegramMediaFile(fileId: EngineMedia.Id(namespace: 0, id: 0), partialReference: nil, resource: LocalFileMediaResource(fileId: 0), previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "audio/ogg", size: 0, attributes: [.Audio(isVoice: false, duration: 0, title: nil, performer: nil, waveform: Data())])))
|
||||
@ -2818,7 +2818,7 @@ private final class ChatListSearchShimmerNode: ASDisplayNode {
|
||||
associatedMessageIds: []
|
||||
)
|
||||
|
||||
return ListMessageItem(presentationData: ChatPresentationData(presentationData: presentationData), context: context, chatLocation: .peer(peer1.id), interaction: ListMessageItemInteraction.default, message: message._asMessage(), selection: hasSelection ? .selectable(selected: false) : .none, displayHeader: false, customHeader: nil, hintIsLink: false, isGlobalSearchResult: true)
|
||||
return ListMessageItem(presentationData: ChatPresentationData(presentationData: presentationData), context: context, chatLocation: .peer(id: peer1.id), interaction: ListMessageItemInteraction.default, message: message._asMessage(), selection: hasSelection ? .selectable(selected: false) : .none, displayHeader: false, customHeader: nil, hintIsLink: false, isGlobalSearchResult: true)
|
||||
case .voice:
|
||||
var media: [EngineMedia] = []
|
||||
media.append(.file(TelegramMediaFile(fileId: EngineMedia.Id(namespace: 0, id: 0), partialReference: nil, resource: LocalFileMediaResource(fileId: 0), previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "audio/ogg", size: 0, attributes: [.Audio(isVoice: true, duration: 0, title: nil, performer: nil, waveform: Data())])))
|
||||
@ -2845,7 +2845,7 @@ private final class ChatListSearchShimmerNode: ASDisplayNode {
|
||||
associatedMessageIds: []
|
||||
)
|
||||
|
||||
return ListMessageItem(presentationData: ChatPresentationData(presentationData: presentationData), context: context, chatLocation: .peer(peer1.id), interaction: ListMessageItemInteraction.default, message: message._asMessage(), selection: hasSelection ? .selectable(selected: false) : .none, displayHeader: false, customHeader: nil, hintIsLink: false, isGlobalSearchResult: true)
|
||||
return ListMessageItem(presentationData: ChatPresentationData(presentationData: presentationData), context: context, chatLocation: .peer(id: peer1.id), interaction: ListMessageItemInteraction.default, message: message._asMessage(), selection: hasSelection ? .selectable(selected: false) : .none, displayHeader: false, customHeader: nil, hintIsLink: false, isGlobalSearchResult: true)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -42,7 +42,7 @@ public enum ChatListItemContent {
|
||||
public var chatLocation: ChatLocation? {
|
||||
switch self {
|
||||
case let .peer(_, peer, _, _, _, _, _, _, _, _, _, _, _):
|
||||
return .peer(peer.peerId)
|
||||
return .peer(id: peer.peerId)
|
||||
case .groupReference:
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -1938,7 +1938,7 @@ public final class ChatListNode: ListView {
|
||||
}
|
||||
switch chatListView.filteredEntries[entryCount - i - 1] {
|
||||
case let .PeerEntry(index, _, _, _, _, _, peer, _, _, _, _, _, _, _, _, _, _):
|
||||
if interaction.highlightedChatLocation?.location == ChatLocation.peer(peer.peerId) {
|
||||
if interaction.highlightedChatLocation?.location == ChatLocation.peer(id: peer.peerId) {
|
||||
current = (index, peer.peer!, entryCount - i - 1)
|
||||
break outer
|
||||
}
|
||||
|
||||
@ -8,12 +8,14 @@ import AccountContext
|
||||
import ChatInterfaceState
|
||||
|
||||
public extension ChatLocation {
|
||||
var peerId: PeerId {
|
||||
var peerId: PeerId? {
|
||||
switch self {
|
||||
case let .peer(peerId):
|
||||
return peerId
|
||||
case let .replyThread(replyThreadMessage):
|
||||
return replyThreadMessage.messageId.peerId
|
||||
case .feed:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -19,7 +19,7 @@ func contactContextMenuItems(context: AccountContext, peerId: EnginePeer.Id, con
|
||||
|
||||
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
|
||||
if let contactsController = contactsController, let navigationController = contactsController.navigationController as? NavigationController {
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peerId), peekData: nil))
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peerId), peekData: nil))
|
||||
}
|
||||
f(.default)
|
||||
})))
|
||||
@ -56,7 +56,7 @@ func contactContextMenuItems(context: AccountContext, peerId: EnginePeer.Id, con
|
||||
|> deliverOnMainQueue).start(next: { currentPeerId in
|
||||
if let currentPeerId = currentPeerId {
|
||||
if let contactsController = contactsController, let navigationController = (contactsController.navigationController as? NavigationController) {
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(currentPeerId), peekData: nil))
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: currentPeerId), peekData: nil))
|
||||
}
|
||||
} else {
|
||||
var createSignal = context.engine.peers.createSecretChat(peerId: peerId)
|
||||
@ -91,7 +91,7 @@ func contactContextMenuItems(context: AccountContext, peerId: EnginePeer.Id, con
|
||||
createSecretChatDisposable.set((createSignal
|
||||
|> deliverOnMainQueue).start(next: { peerId in
|
||||
if let navigationController = (contactsController?.navigationController as? NavigationController) {
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peerId), peekData: nil))
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peerId), peekData: nil))
|
||||
}
|
||||
}, error: { error in
|
||||
if let contactsController = contactsController {
|
||||
|
||||
@ -323,7 +323,7 @@ public class ContactsController: ViewController {
|
||||
scrollToEndIfExists = true
|
||||
}
|
||||
|
||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(peer.id), purposefulAction: { [weak self] in
|
||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(id: peer.id), purposefulAction: { [weak self] in
|
||||
if fromSearch {
|
||||
self?.deactivateSearch(animated: false)
|
||||
self?.switchToChatsController?()
|
||||
|
||||
@ -174,7 +174,7 @@ final class ContactsControllerNode: ASDisplayNode {
|
||||
guard let contactsController = self.controller else {
|
||||
return
|
||||
}
|
||||
let chatController = self.context.sharedContext.makeChatController(context: self.context, chatLocation: .peer(peer.id), subject: nil, botStart: nil, mode: .standard(previewing: true))
|
||||
let chatController = self.context.sharedContext.makeChatController(context: self.context, chatLocation: .peer(id: peer.id), subject: nil, botStart: nil, mode: .standard(previewing: true))
|
||||
chatController.canReadHistory.set(false)
|
||||
let contextController = ContextController(account: self.context.account, presentationData: self.presentationData, source: .controller(ContextControllerContentSourceImpl(controller: chatController, sourceNode: node)), items: contactContextMenuItems(context: self.context, peerId: peer.id, contactsController: contactsController) |> map { ContextController.Items(content: .list($0)) }, gesture: gesture)
|
||||
contactsController.presentInGlobalOverlay(contextController)
|
||||
|
||||
@ -478,7 +478,7 @@ public class ContactsPeerItemNode: ItemListRevealOptionsItemNode {
|
||||
switch item.peer {
|
||||
case let .peer(_, chatPeer):
|
||||
if let peer = chatPeer {
|
||||
if ChatLocation.peer(peer.id) == item.itemHighlighting?.chatLocation {
|
||||
if ChatLocation.peer(id: peer.id) == item.itemHighlighting?.chatLocation {
|
||||
reallyHighlighted = true
|
||||
}
|
||||
}
|
||||
|
||||
@ -211,7 +211,7 @@ public func chatMessageGalleryControllerData(context: AccountContext, chatLocati
|
||||
}
|
||||
|
||||
if internalDocumentItemSupportsMimeType(file.mimeType, fileName: file.fileName ?? "file") {
|
||||
let gallery = GalleryController(context: context, source: source ?? .peerMessagesAtId(messageId: message.id, chatLocation: chatLocation ?? .peer(message.id.peerId), chatLocationContextHolder: chatLocationContextHolder ?? Atomic<ChatLocationContextHolder?>(value: nil)), invertItemOrder: reverseMessageGalleryOrder, streamSingleVideo: stream, fromPlayingVideo: autoplayingVideo, landscape: landscape, timecode: timecode, synchronousLoad: synchronousLoad, replaceRootController: { [weak navigationController] controller, ready in
|
||||
let gallery = GalleryController(context: context, source: source ?? .peerMessagesAtId(messageId: message.id, chatLocation: chatLocation ?? .peer(id: message.id.peerId), chatLocationContextHolder: chatLocationContextHolder ?? Atomic<ChatLocationContextHolder?>(value: nil)), invertItemOrder: reverseMessageGalleryOrder, streamSingleVideo: stream, fromPlayingVideo: autoplayingVideo, landscape: landscape, timecode: timecode, synchronousLoad: synchronousLoad, replaceRootController: { [weak navigationController] controller, ready in
|
||||
navigationController?.replaceTopController(controller, animated: false, ready: ready)
|
||||
}, baseNavigationController: navigationController, actionInteraction: actionInteraction)
|
||||
return .gallery(.single(gallery))
|
||||
@ -239,7 +239,7 @@ public func chatMessageGalleryControllerData(context: AccountContext, chatLocati
|
||||
return .gallery(startState
|
||||
|> deliverOnMainQueue
|
||||
|> map { startState in
|
||||
let gallery = GalleryController(context: context, source: source ?? (standalone ? .standaloneMessage(message) : .peerMessagesAtId(messageId: message.id, chatLocation: chatLocation ?? .peer(message.id.peerId), chatLocationContextHolder: chatLocationContextHolder ?? Atomic<ChatLocationContextHolder?>(value: nil))), invertItemOrder: reverseMessageGalleryOrder, streamSingleVideo: stream, fromPlayingVideo: autoplayingVideo, landscape: landscape, timecode: startState.timecode, playbackRate: startState.rate, synchronousLoad: synchronousLoad, replaceRootController: { [weak navigationController] controller, ready in
|
||||
let gallery = GalleryController(context: context, source: source ?? (standalone ? .standaloneMessage(message) : .peerMessagesAtId(messageId: message.id, chatLocation: chatLocation ?? .peer(id: message.id.peerId), chatLocationContextHolder: chatLocationContextHolder ?? Atomic<ChatLocationContextHolder?>(value: nil))), invertItemOrder: reverseMessageGalleryOrder, streamSingleVideo: stream, fromPlayingVideo: autoplayingVideo, landscape: landscape, timecode: startState.timecode, playbackRate: startState.rate, synchronousLoad: synchronousLoad, replaceRootController: { [weak navigationController] controller, ready in
|
||||
navigationController?.replaceTopController(controller, animated: false, ready: ready)
|
||||
}, baseNavigationController: navigationController, actionInteraction: actionInteraction)
|
||||
gallery.temporaryDoNotWaitForReady = autoplayingVideo
|
||||
|
||||
@ -2083,7 +2083,7 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode {
|
||||
|
||||
switch contentInfo {
|
||||
case let .message(message):
|
||||
let gallery = GalleryController(context: context, source: .peerMessagesAtId(messageId: message.id, chatLocation: .peer(message.id.peerId), chatLocationContextHolder: Atomic<ChatLocationContextHolder?>(value: nil)), playbackRate: playbackRate, replaceRootController: { controller, ready in
|
||||
let gallery = GalleryController(context: context, source: .peerMessagesAtId(messageId: message.id, chatLocation: .peer(id: message.id.peerId), chatLocationContextHolder: Atomic<ChatLocationContextHolder?>(value: nil)), playbackRate: playbackRate, replaceRootController: { controller, ready in
|
||||
if let baseNavigationController = baseNavigationController {
|
||||
baseNavigationController.replaceTopController(controller, animated: false, ready: ready)
|
||||
}
|
||||
@ -2207,7 +2207,7 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode {
|
||||
|
||||
switch contentInfo {
|
||||
case let .message(message):
|
||||
let gallery = GalleryController(context: context, source: .peerMessagesAtId(messageId: message.id, chatLocation: .peer(message.id.peerId), chatLocationContextHolder: Atomic<ChatLocationContextHolder?>(value: nil)), playbackRate: playbackRate, replaceRootController: { [weak baseNavigationController] controller, ready in
|
||||
let gallery = GalleryController(context: context, source: .peerMessagesAtId(messageId: message.id, chatLocation: .peer(id: message.id.peerId), chatLocationContextHolder: Atomic<ChatLocationContextHolder?>(value: nil)), playbackRate: playbackRate, replaceRootController: { [weak baseNavigationController] controller, ready in
|
||||
if let baseNavigationController = baseNavigationController {
|
||||
baseNavigationController.replaceTopController(controller, animated: false, ready: ready)
|
||||
}
|
||||
@ -2272,7 +2272,7 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode {
|
||||
|
||||
switch contentInfo {
|
||||
case let .message(message):
|
||||
let gallery = GalleryController(context: context, source: .peerMessagesAtId(messageId: message.id, chatLocation: .peer(message.id.peerId), chatLocationContextHolder: Atomic<ChatLocationContextHolder?>(value: nil)), playbackRate: playbackRate, replaceRootController: { controller, ready in
|
||||
let gallery = GalleryController(context: context, source: .peerMessagesAtId(messageId: message.id, chatLocation: .peer(id: message.id.peerId), chatLocationContextHolder: Atomic<ChatLocationContextHolder?>(value: nil)), playbackRate: playbackRate, replaceRootController: { controller, ready in
|
||||
if let baseNavigationController = baseNavigationController {
|
||||
baseNavigationController.replaceTopController(controller, animated: false, ready: ready)
|
||||
}
|
||||
|
||||
@ -71,7 +71,12 @@ public func reverseGeocodeLocation(latitude: Double, longitude: Double) -> Signa
|
||||
let geocoder = CLGeocoder()
|
||||
geocoder.reverseGeocodeLocation(CLLocation(latitude: latitude, longitude: longitude), completionHandler: { placemarks, _ in
|
||||
if let placemarks = placemarks, let placemark = placemarks.first {
|
||||
let result = ReverseGeocodedPlacemark(street: placemark.thoroughfare, city: placemark.locality, country: placemark.country)
|
||||
let result: ReverseGeocodedPlacemark
|
||||
if placemark.thoroughfare == nil && placemark.locality == nil && placemark.country == nil {
|
||||
result = ReverseGeocodedPlacemark(street: placemark.name, city: nil, country: nil)
|
||||
} else {
|
||||
result = ReverseGeocodedPlacemark(street: placemark.thoroughfare, city: placemark.locality, country: placemark.country)
|
||||
}
|
||||
subscriber.putNext(result)
|
||||
subscriber.putCompletion()
|
||||
} else {
|
||||
|
||||
@ -57,7 +57,7 @@ public final class HashtagSearchController: TelegramBaseController {
|
||||
if let strongSelf = self {
|
||||
strongSelf.openMessageFromSearchDisposable.set((storedMessageFromSearchPeer(account: strongSelf.context.account, peer: peer._asPeer()) |> deliverOnMainQueue).start(next: { actualPeerId in
|
||||
if let strongSelf = self, let navigationController = strongSelf.navigationController as? NavigationController {
|
||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(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(id: actualPeerId), subject: message.id.peerId == actualPeerId ? .message(id: .id(message.id), highlight: true, timecode: nil) : nil, keepStack: .always))
|
||||
}
|
||||
}))
|
||||
strongSelf.controllerNode.listNode.clearHighlightAnimated(true)
|
||||
|
||||
@ -47,7 +47,7 @@ final class HashtagSearchControllerNode: ASDisplayNode {
|
||||
self.segmentedControlNode = SegmentedControlNode(theme: SegmentedControlTheme(theme: presentationData.theme), items: items.map { SegmentedControlItem(title: $0) }, selectedIndex: 0)
|
||||
|
||||
if let peer = peer {
|
||||
self.chatController = context.sharedContext.makeChatController(context: context, chatLocation: .peer(peer.id), subject: nil, botStart: nil, mode: .inline(navigationController))
|
||||
self.chatController = context.sharedContext.makeChatController(context: context, chatLocation: .peer(id: peer.id), subject: nil, botStart: nil, mode: .inline(navigationController))
|
||||
} else {
|
||||
self.chatController = nil
|
||||
}
|
||||
|
||||
@ -153,7 +153,7 @@ public final class InstantPageController: ViewController {
|
||||
(self?.navigationController as? NavigationController)?.pushViewController(c)
|
||||
}, openPeer: { [weak self] peerId in
|
||||
if let strongSelf = self, let navigationController = strongSelf.navigationController as? NavigationController {
|
||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(peerId), animated: true))
|
||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(id: peerId), animated: true))
|
||||
}
|
||||
}, navigateBack: { [weak self] in
|
||||
if let strongSelf = self, let controllers = strongSelf.navigationController?.viewControllers.reversed() {
|
||||
|
||||
@ -1241,11 +1241,11 @@ final class InstantPageControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
switch navigation {
|
||||
case let .chat(_, subject, peekData):
|
||||
if let navigationController = strongSelf.getNavigationController() {
|
||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(peerId), subject: subject, peekData: peekData))
|
||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(id: peerId), subject: subject, peekData: peekData))
|
||||
}
|
||||
case let .withBotStartPayload(botStart):
|
||||
if let navigationController = strongSelf.getNavigationController() {
|
||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(peerId), botStart: botStart, keepStack: .always))
|
||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(id: peerId), botStart: botStart, keepStack: .always))
|
||||
}
|
||||
case .info:
|
||||
let _ = (strongSelf.context.account.postbox.loadedPeerWithId(peerId)
|
||||
|
||||
@ -473,7 +473,7 @@ public final class InviteLinkViewController: ViewController {
|
||||
|
||||
self.interaction = InviteLinkViewInteraction(context: context, openPeer: { [weak self] peerId in
|
||||
if let strongSelf = self, let navigationController = strongSelf.controller?.navigationController as? NavigationController {
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peerId), keepStack: .always))
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peerId), keepStack: .always))
|
||||
}
|
||||
}, copyLink: { [weak self] invite in
|
||||
UIPasteboard.general.string = invite.link
|
||||
|
||||
@ -383,7 +383,7 @@ public func inviteRequestsController(context: AccountContext, updatedPresentatio
|
||||
}
|
||||
navigateToChatImpl = { [weak controller] peer in
|
||||
if let navigationController = controller?.navigationController as? NavigationController {
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer.id), keepStack: .always))
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peer.id), keepStack: .always))
|
||||
}
|
||||
}
|
||||
dismissInputImpl = { [weak controller] in
|
||||
|
||||
@ -476,7 +476,7 @@ ActionStage *ActionStageInstance()
|
||||
{
|
||||
TGLegacyLog(@"%s should be called from graph queue", __PRETTY_FUNCTION__);
|
||||
|
||||
return nil;
|
||||
return false;
|
||||
}
|
||||
|
||||
__block bool result = false;
|
||||
@ -517,7 +517,7 @@ ActionStage *ActionStageInstance()
|
||||
{
|
||||
TGLegacyLog(@"%s should be called from graph queue", __PRETTY_FUNCTION__);
|
||||
|
||||
return nil;
|
||||
return false;
|
||||
}
|
||||
|
||||
__block bool result = false;
|
||||
|
||||
@ -604,7 +604,7 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable {
|
||||
}
|
||||
|
||||
var hasTimer = false
|
||||
if controller.chatLocation?.peerId != controller.context.account.peerId && controller.chatLocation?.peerId.namespace == Namespaces.Peer.CloudUser {
|
||||
if controller.chatLocation?.peerId != controller.context.account.peerId && controller.chatLocation?.peerId?.namespace == Namespaces.Peer.CloudUser {
|
||||
hasTimer = true
|
||||
}
|
||||
|
||||
@ -643,7 +643,7 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable {
|
||||
}
|
||||
|
||||
var hasTimer = false
|
||||
if controller.chatLocation?.peerId != controller.context.account.peerId && controller.chatLocation?.peerId.namespace == Namespaces.Peer.CloudUser {
|
||||
if controller.chatLocation?.peerId != controller.context.account.peerId && controller.chatLocation?.peerId?.namespace == Namespaces.Peer.CloudUser {
|
||||
hasTimer = true
|
||||
}
|
||||
|
||||
|
||||
@ -31,7 +31,7 @@
|
||||
{
|
||||
if (block != nil)
|
||||
{
|
||||
__strong id strongBlock = (__bridge_transfer id)block;
|
||||
__unused __strong id strongBlock = (__bridge_transfer id)block;
|
||||
strongBlock = nil;
|
||||
}
|
||||
}
|
||||
|
||||
@ -136,7 +136,7 @@ static NSMutableDictionary *keychains()
|
||||
{
|
||||
uint8_t buf[32];
|
||||
|
||||
int result = 0;
|
||||
__unused int result = 0;
|
||||
result = SecRandomCopyBytes(kSecRandomDefault, 32, buf);
|
||||
_aesKey = [[NSData alloc] initWithBytes:buf length:32];
|
||||
|
||||
|
||||
@ -32,7 +32,7 @@ static const void *MTNetworkAvailabilityContextRetain(const void *info)
|
||||
static void MTNetworkAvailabilityContextRelease(const void *info)
|
||||
{
|
||||
void *retainedThing = (__bridge void *)((__bridge id)info);
|
||||
id unretainedThing = (__bridge_transfer id)retainedThing;
|
||||
__unused id unretainedThing = (__bridge_transfer id)retainedThing;
|
||||
unretainedThing = nil;
|
||||
}
|
||||
|
||||
|
||||
@ -369,7 +369,7 @@ public func channelBlacklistController(context: AccountContext, updatedPresentat
|
||||
actionSheet?.dismissAnimated()
|
||||
if participant.peer is TelegramChannel {
|
||||
if let navigationController = getNavigationControllerImpl?() {
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(participant.peer.id)))
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: participant.peer.id)))
|
||||
}
|
||||
} else if let infoController = context.sharedContext.makePeerInfoController(context: context, updatedPresentationData: nil, peer: participant.peer, mode: .generic, avatarInitiallyExpanded: false, fromChat: false, requestsContext: nil) {
|
||||
pushControllerImpl?(infoController)
|
||||
|
||||
@ -642,7 +642,7 @@ public func channelDiscussionGroupSetupController(context: AccountContext, updat
|
||||
guard let navigationController = controller?.navigationController as? NavigationController else {
|
||||
return
|
||||
}
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(groupId), keepStack: .always))
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: groupId), keepStack: .always))
|
||||
}
|
||||
return controller
|
||||
}
|
||||
|
||||
@ -930,7 +930,7 @@ public func channelPermissionsController(context: AccountContext, updatedPresent
|
||||
}
|
||||
navigateToChatControllerImpl = { [weak controller] peerId in
|
||||
if let controller = controller, let navigationController = controller.navigationController as? NavigationController {
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peerId), keepStack: .always))
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peerId), keepStack: .always))
|
||||
}
|
||||
}
|
||||
dismissInputImpl = { [weak controller] in
|
||||
|
||||
@ -1490,7 +1490,7 @@ public func channelVisibilityController(context: AccountContext, updatedPresenta
|
||||
}
|
||||
})
|
||||
if filteredPeerIds.isEmpty {
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, chatController: nil, context: context, chatLocation: .peer(peerId), keepStack: .never, animated: true))
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, chatController: nil, context: context, chatLocation: .peer(id: peerId), keepStack: .never, animated: true))
|
||||
} else {
|
||||
selectionController.displayProgress = true
|
||||
let _ = (context.engine.peers.addChannelMembers(peerId: peerId, memberIds: filteredPeerIds)
|
||||
@ -1499,19 +1499,19 @@ public func channelVisibilityController(context: AccountContext, updatedPresenta
|
||||
return
|
||||
}
|
||||
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, chatController: nil, context: context, chatLocation: .peer(peerId), keepStack: .never, animated: true))
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, chatController: nil, context: context, chatLocation: .peer(id: peerId), keepStack: .never, animated: true))
|
||||
}, completed: { [weak selectionController] in
|
||||
guard let selectionController = selectionController, let navigationController = selectionController.navigationController as? NavigationController else {
|
||||
return
|
||||
}
|
||||
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, chatController: nil, context: context, chatLocation: .peer(peerId), keepStack: .never, animated: true))
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, chatController: nil, context: context, chatLocation: .peer(id: peerId), keepStack: .never, animated: true))
|
||||
})
|
||||
}
|
||||
})
|
||||
} else {
|
||||
if let navigationController = controller.navigationController as? NavigationController {
|
||||
navigationController.replaceAllButRootController(context.sharedContext.makeChatController(context: context, chatLocation: .peer(peerId), subject: nil, botStart: nil, mode: .standard(previewing: false)), animated: true)
|
||||
navigationController.replaceAllButRootController(context.sharedContext.makeChatController(context: context, chatLocation: .peer(id: peerId), subject: nil, botStart: nil, mode: .standard(previewing: false)), animated: true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -150,7 +150,7 @@ public func convertToSupergroupController(context: AccountContext, peerId: PeerI
|
||||
if !alreadyConverting {
|
||||
convertDisposable.set((context.engine.peers.convertGroupToSupergroup(peerId: peerId)
|
||||
|> deliverOnMainQueue).start(next: { createdPeerId in
|
||||
replaceControllerImpl?(context.sharedContext.makeChatController(context: context, chatLocation: .peer(createdPeerId), subject: nil, botStart: nil, mode: .standard(previewing: false)))
|
||||
replaceControllerImpl?(context.sharedContext.makeChatController(context: context, chatLocation: .peer(id: createdPeerId), subject: nil, botStart: nil, mode: .standard(previewing: false)))
|
||||
}))
|
||||
}
|
||||
})]), nil)
|
||||
|
||||
@ -1240,7 +1240,7 @@ public func deviceContactInfoController(context: AccountContext, updatedPresenta
|
||||
}
|
||||
openChatImpl = { [weak controller] peerId in
|
||||
if let navigationController = (controller?.navigationController as? NavigationController) {
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peerId)))
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peerId)))
|
||||
}
|
||||
}
|
||||
replaceControllerImpl = { [weak controller] value in
|
||||
|
||||
@ -487,7 +487,7 @@ public func groupStickerPackSetupController(context: AccountContext, updatedPres
|
||||
}
|
||||
navigateToChatControllerImpl = { [weak controller] peerId in
|
||||
if let controller = controller, let navigationController = controller.navigationController as? NavigationController {
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peerId)))
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peerId)))
|
||||
}
|
||||
}
|
||||
dismissImpl = { [weak controller] in
|
||||
|
||||
@ -490,7 +490,7 @@ public func peersNearbyController(context: AccountContext) -> ViewController {
|
||||
}))
|
||||
}, contextAction: { peer, node, gesture in
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
let chatController = context.sharedContext.makeChatController(context: context, chatLocation: .peer(peer.id), subject: nil, botStart: nil, mode: .standard(previewing: true))
|
||||
let chatController = context.sharedContext.makeChatController(context: context, chatLocation: .peer(id: peer.id), subject: nil, botStart: nil, mode: .standard(previewing: true))
|
||||
chatController.canReadHistory.set(false)
|
||||
let contextController = ContextController(account: context.account, presentationData: presentationData, source: .controller(ContextControllerContentSourceImpl(controller: chatController, sourceNode: node)), items: peerNearbyContextMenuItems(context: context, peerId: peer.id, present: { c in
|
||||
presentControllerImpl?(c, nil)
|
||||
@ -604,7 +604,7 @@ public func peersNearbyController(context: AccountContext) -> ViewController {
|
||||
}
|
||||
navigateToChatImpl = { [weak controller] peer in
|
||||
if let navigationController = controller?.navigationController as? NavigationController {
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer.id), keepStack: .always, purposefulAction: {}, peekData: nil))
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peer.id), keepStack: .always, purposefulAction: {}, peekData: nil))
|
||||
}
|
||||
}
|
||||
pushControllerImpl = { [weak controller] c in
|
||||
|
||||
@ -16,6 +16,7 @@ swift_library(
|
||||
"//submodules/MurMurHash32:MurMurHash32",
|
||||
"//submodules/StringTransliteration:StringTransliteration",
|
||||
"//submodules/ManagedFile:ManagedFile",
|
||||
"//submodules/Utils/RangeSet:RangeSet",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
||||
@ -2,8 +2,9 @@ import Foundation
|
||||
import SwiftSignalKit
|
||||
|
||||
public enum ChatLocationInput {
|
||||
case peer(PeerId)
|
||||
case external(PeerId, Int64, Signal<MessageHistoryViewExternalInput, NoError>)
|
||||
case peer(peerId: PeerId)
|
||||
case thread(peerId: PeerId, threadId: Int64, data: Signal<MessageHistoryViewExternalInput, NoError>)
|
||||
case feed(id: Int32, data: Signal<MessageHistoryViewExternalInput, NoError>)
|
||||
}
|
||||
|
||||
public enum ResolvedChatLocationInput {
|
||||
|
||||
@ -5,12 +5,14 @@ public struct MessageHistoryHolesViewEntry: Equatable, Hashable {
|
||||
public let direction: MessageHistoryViewRelativeHoleDirection
|
||||
public let space: MessageHistoryHoleSpace
|
||||
public let count: Int
|
||||
public let userId: Int64?
|
||||
|
||||
public init(hole: MessageHistoryViewHole, direction: MessageHistoryViewRelativeHoleDirection, space: MessageHistoryHoleSpace, count: Int) {
|
||||
public init(hole: MessageHistoryViewHole, direction: MessageHistoryViewRelativeHoleDirection, space: MessageHistoryHoleSpace, count: Int, userId: Int64?) {
|
||||
self.hole = hole
|
||||
self.direction = direction
|
||||
self.space = space
|
||||
self.count = count
|
||||
self.userId = userId
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -248,37 +248,30 @@ public struct MessageHistoryViewOrderStatistics: OptionSet {
|
||||
}
|
||||
|
||||
public final class MessageHistoryViewExternalInput: Equatable {
|
||||
public let peerId: PeerId
|
||||
public let threadId: Int64
|
||||
public enum Content: Equatable {
|
||||
case messages(indices: [MessageIndex], holes: [MessageId.Namespace: IndexSet], userId: Int64?)
|
||||
case thread(peerId: PeerId, id: Int64, holes: [MessageId.Namespace: IndexSet])
|
||||
}
|
||||
|
||||
public let content: Content
|
||||
public let maxReadIncomingMessageId: MessageId?
|
||||
public let maxReadOutgoingMessageId: MessageId?
|
||||
public let holes: [MessageId.Namespace: IndexSet]
|
||||
|
||||
public init(
|
||||
peerId: PeerId,
|
||||
threadId: Int64,
|
||||
content: Content,
|
||||
maxReadIncomingMessageId: MessageId?,
|
||||
maxReadOutgoingMessageId: MessageId?,
|
||||
holes: [MessageId.Namespace: IndexSet]
|
||||
maxReadOutgoingMessageId: MessageId?
|
||||
) {
|
||||
self.peerId = peerId
|
||||
self.threadId = threadId
|
||||
self.content = content
|
||||
self.maxReadIncomingMessageId = maxReadIncomingMessageId
|
||||
self.maxReadOutgoingMessageId = maxReadOutgoingMessageId
|
||||
self.holes = holes
|
||||
}
|
||||
|
||||
public static func ==(lhs: MessageHistoryViewExternalInput, rhs: MessageHistoryViewExternalInput) -> Bool {
|
||||
if lhs === rhs {
|
||||
return true
|
||||
}
|
||||
if lhs.peerId != rhs.peerId {
|
||||
return false
|
||||
}
|
||||
if lhs.threadId != rhs.threadId {
|
||||
return false
|
||||
}
|
||||
if lhs.holes != rhs.holes {
|
||||
if lhs.content != rhs.content {
|
||||
return false
|
||||
}
|
||||
if lhs.maxReadIncomingMessageId != rhs.maxReadIncomingMessageId {
|
||||
@ -332,6 +325,8 @@ final class MutableMessageHistoryView {
|
||||
|
||||
fileprivate var isAddedToChatList: Bool
|
||||
|
||||
private var userId: Int64?
|
||||
|
||||
init(
|
||||
postbox: PostboxImpl,
|
||||
orderStatistics: MessageHistoryViewOrderStatistics,
|
||||
@ -370,7 +365,13 @@ final class MutableMessageHistoryView {
|
||||
case let .single(peerId):
|
||||
self.isAddedToChatList = postbox.chatListTable.getPeerChatListIndex(peerId: peerId) != nil
|
||||
case let .external(input):
|
||||
self.isAddedToChatList = postbox.chatListTable.getPeerChatListIndex(peerId: input.peerId) != nil
|
||||
switch input.content {
|
||||
case let .thread(peerId, _, _):
|
||||
self.isAddedToChatList = postbox.chatListTable.getPeerChatListIndex(peerId: peerId) != nil
|
||||
case let .messages(_, _, userId):
|
||||
self.isAddedToChatList = false
|
||||
self.userId = userId
|
||||
}
|
||||
}
|
||||
|
||||
self.state = HistoryViewState(postbox: postbox, inputAnchor: inputAnchor, tag: tag, appendMessagesFromTheSameGroup: appendMessagesFromTheSameGroup, namespaces: namespaces, statistics: self.orderStatistics, ignoreMessagesInTimestampRange: self.ignoreMessagesInTimestampRange, halfLimit: count + 1, locations: peerIds)
|
||||
@ -441,16 +442,19 @@ final class MutableMessageHistoryView {
|
||||
var holePeerIdsSet = Set<PeerId>()
|
||||
|
||||
if !transaction.chatListOperations.isEmpty {
|
||||
let mainPeerId: PeerId
|
||||
switch peerIds {
|
||||
case let .associated(peerId, _):
|
||||
mainPeerId = peerId
|
||||
self.isAddedToChatList = postbox.chatListTable.getPeerChatListIndex(peerId: peerId) != nil
|
||||
case let .single(peerId):
|
||||
mainPeerId = peerId
|
||||
self.isAddedToChatList = postbox.chatListTable.getPeerChatListIndex(peerId: peerId) != nil
|
||||
case let .external(input):
|
||||
mainPeerId = input.peerId
|
||||
switch input.content {
|
||||
case let .thread(peerId, _, _):
|
||||
self.isAddedToChatList = postbox.chatListTable.getPeerChatListIndex(peerId: peerId) != nil
|
||||
case .messages:
|
||||
self.isAddedToChatList = false
|
||||
}
|
||||
}
|
||||
self.isAddedToChatList = postbox.chatListTable.getPeerChatListIndex(peerId: mainPeerId) != nil
|
||||
}
|
||||
|
||||
switch self.peerIds {
|
||||
@ -476,27 +480,43 @@ final class MutableMessageHistoryView {
|
||||
}
|
||||
}
|
||||
case let .external(input):
|
||||
if let value = transaction.currentOperationsByPeerId[input.peerId] {
|
||||
operations.append(value)
|
||||
switch input.content {
|
||||
case let .thread(peerId, _, _):
|
||||
if let value = transaction.currentOperationsByPeerId[peerId] {
|
||||
operations.append(value)
|
||||
}
|
||||
case .messages:
|
||||
//TODO:implement
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
var hasChanges = false
|
||||
|
||||
let unwrappedTag: MessageTags = self.tag ?? []
|
||||
let threadId: Int64?
|
||||
let externalThreadId: Int64?
|
||||
let isExternal: Bool
|
||||
switch self.peerIds {
|
||||
case .single, .associated:
|
||||
threadId = nil
|
||||
externalThreadId = nil
|
||||
isExternal = false
|
||||
case let .external(input):
|
||||
threadId = input.threadId
|
||||
isExternal = true
|
||||
switch input.content {
|
||||
case let .thread(_, id, _):
|
||||
externalThreadId = id
|
||||
case .messages:
|
||||
externalThreadId = nil
|
||||
//TODO:implement
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
switch self.state {
|
||||
case let .loading(loadingState):
|
||||
for (key, holeOperations) in transaction.currentPeerHoleOperations {
|
||||
var matchesSpace = false
|
||||
if threadId == nil {
|
||||
if !isExternal {
|
||||
switch key.space {
|
||||
case .everywhere:
|
||||
matchesSpace = unwrappedTag.isEmpty
|
||||
@ -557,7 +577,7 @@ final class MutableMessageHistoryView {
|
||||
|
||||
var matches = false
|
||||
if matchesTag {
|
||||
if threadId == nil || message.threadId == threadId {
|
||||
if !isExternal || message.threadId == externalThreadId {
|
||||
if self.namespaces.contains(message.id.namespace) {
|
||||
matches = true
|
||||
if loadedState.add(entry: .IntermediateMessageEntry(message, nil, nil)) {
|
||||
@ -608,7 +628,7 @@ final class MutableMessageHistoryView {
|
||||
}
|
||||
for (key, holeOperations) in transaction.currentPeerHoleOperations {
|
||||
var matchesSpace = false
|
||||
if threadId == nil {
|
||||
if !isExternal {
|
||||
switch key.space {
|
||||
case .everywhere:
|
||||
matchesSpace = unwrappedTag.isEmpty
|
||||
@ -880,14 +900,14 @@ final class MutableMessageHistoryView {
|
||||
}
|
||||
}
|
||||
|
||||
func firstHole() -> (MessageHistoryViewHole, MessageHistoryViewRelativeHoleDirection, Int)? {
|
||||
func firstHole() -> (MessageHistoryViewHole, MessageHistoryViewRelativeHoleDirection, Int, Int64?)? {
|
||||
switch self.sampledState {
|
||||
case let .loading(loadingSample):
|
||||
switch loadingSample {
|
||||
case .ready:
|
||||
return nil
|
||||
case let .loadHole(peerId, namespace, _, threadId, id):
|
||||
return (.peer(MessageHistoryViewPeerHole(peerId: peerId, namespace: namespace, threadId: threadId)), .aroundId(MessageId(peerId: peerId, namespace: namespace, id: id)), self.fillCount * 2)
|
||||
return (.peer(MessageHistoryViewPeerHole(peerId: peerId, namespace: namespace, threadId: threadId)), .aroundId(MessageId(peerId: peerId, namespace: namespace, id: id)), self.fillCount * 2, self.userId)
|
||||
}
|
||||
case let .loaded(loadedSample):
|
||||
if let hole = loadedSample.hole {
|
||||
@ -897,7 +917,7 @@ final class MutableMessageHistoryView {
|
||||
} else {
|
||||
direction = .aroundId(MessageId(peerId: hole.peerId, namespace: hole.namespace, id: hole.startId))
|
||||
}
|
||||
return (.peer(MessageHistoryViewPeerHole(peerId: hole.peerId, namespace: hole.namespace, threadId: hole.threadId)), direction, self.fillCount * 2)
|
||||
return (.peer(MessageHistoryViewPeerHole(peerId: hole.peerId, namespace: hole.namespace, threadId: hole.threadId)), direction, self.fillCount * 2, self.userId)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -70,7 +70,102 @@ private extension MessageHistoryInput {
|
||||
}
|
||||
return items
|
||||
case let .external(input, tag):
|
||||
return postbox.messageHistoryTable.fetch(peerId: peerId, namespace: namespace, tag: tag, threadId: input.threadId, from: fromIndex, includeFrom: includeFrom, to: toIndex, ignoreMessagesInTimestampRange: ignoreMessagesInTimestampRange, limit: limit)
|
||||
switch input.content {
|
||||
case let .thread(peerId, id, _):
|
||||
return postbox.messageHistoryTable.fetch(peerId: peerId, namespace: namespace, tag: tag, threadId: id, from: fromIndex, includeFrom: includeFrom, to: toIndex, ignoreMessagesInTimestampRange: ignoreMessagesInTimestampRange, limit: limit)
|
||||
case let .messages(allIndices, _, _):
|
||||
if allIndices.isEmpty {
|
||||
return []
|
||||
}
|
||||
var indices: [MessageIndex] = []
|
||||
var startIndex = fromIndex
|
||||
var localIncludeFrom = includeFrom
|
||||
while true {
|
||||
var sliceIndices: [MessageIndex] = []
|
||||
if fromIndex < toIndex {
|
||||
for i in 0 ..< allIndices.count {
|
||||
var matches = false
|
||||
if localIncludeFrom {
|
||||
if allIndices[i] >= startIndex {
|
||||
matches = true
|
||||
}
|
||||
} else {
|
||||
if allIndices[i] > startIndex {
|
||||
matches = true
|
||||
}
|
||||
}
|
||||
if matches {
|
||||
for j in i ..< min(i + limit, allIndices.count) {
|
||||
sliceIndices.append(allIndices[j])
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
//sliceIndices = self.threadsTable.laterIndices(threadId: threadId, peerId: peerId, namespace: namespace, index: startIndex, includeFrom: localIncludeFrom, count: limit)
|
||||
} else {
|
||||
for i in (0 ..< allIndices.count).reversed() {
|
||||
var matches = false
|
||||
if localIncludeFrom {
|
||||
if allIndices[i] <= startIndex {
|
||||
matches = true
|
||||
}
|
||||
} else {
|
||||
if allIndices[i] < startIndex {
|
||||
matches = true
|
||||
}
|
||||
}
|
||||
if matches {
|
||||
for j in (max(i - limit + 1, 0) ... i).reversed() {
|
||||
sliceIndices.append(allIndices[j])
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
//sliceIndices = self.threadsTable.earlierIndices(threadId: threadId, peerId: peerId, namespace: namespace, index: startIndex, includeFrom: localIncludeFrom, count: limit)
|
||||
}
|
||||
if sliceIndices.isEmpty {
|
||||
break
|
||||
}
|
||||
startIndex = sliceIndices[sliceIndices.count - 1]
|
||||
localIncludeFrom = false
|
||||
|
||||
for index in sliceIndices {
|
||||
if let ignoreMessagesInTimestampRange = ignoreMessagesInTimestampRange {
|
||||
if ignoreMessagesInTimestampRange.contains(index.timestamp) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
indices.append(index)
|
||||
}
|
||||
if indices.count >= limit {
|
||||
break
|
||||
}
|
||||
}
|
||||
var result: [IntermediateMessage] = []
|
||||
if fromIndex < toIndex {
|
||||
assert(indices.sorted() == indices)
|
||||
} else {
|
||||
assert(indices.sorted().reversed() == indices)
|
||||
}
|
||||
for index in indices {
|
||||
if fromIndex < toIndex {
|
||||
if index < fromIndex || index > toIndex {
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
if index < toIndex || index > fromIndex {
|
||||
continue
|
||||
}
|
||||
}
|
||||
if let message = postbox.messageHistoryTable.getMessage(index) {
|
||||
result.append(message)
|
||||
} else {
|
||||
assertionFailure()
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -105,8 +200,13 @@ private func canContainHoles(_ peerIdAndNamespace: PeerIdAndNamespace, input: Me
|
||||
return false
|
||||
}
|
||||
return messageNamespaces[peerIdAndNamespace.namespace] != nil
|
||||
case .external:
|
||||
return true
|
||||
case let .external(data, _):
|
||||
switch data.content {
|
||||
case .thread:
|
||||
return true
|
||||
case .messages:
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -395,14 +495,29 @@ private func sampleHoleRanges(input: MessageHistoryInput, orderedEntriesBySpace:
|
||||
case let .automatic(automatic):
|
||||
tag = automatic?.tag
|
||||
case let .external(value, _):
|
||||
threadId = value.threadId
|
||||
switch value.content {
|
||||
case let .thread(_, id, _):
|
||||
threadId = id
|
||||
case .messages:
|
||||
threadId = nil
|
||||
}
|
||||
}
|
||||
|
||||
for (space, indices) in holes.holesBySpace {
|
||||
if indices.isEmpty {
|
||||
continue
|
||||
}
|
||||
assert(canContainHoles(space, input: input, seedConfiguration: seedConfiguration))
|
||||
switch input {
|
||||
case .automatic:
|
||||
assert(canContainHoles(space, input: input, seedConfiguration: seedConfiguration))
|
||||
case let .external(data, _):
|
||||
switch data.content {
|
||||
case .thread:
|
||||
assert(canContainHoles(space, input: input, seedConfiguration: seedConfiguration))
|
||||
case .messages:
|
||||
break
|
||||
}
|
||||
}
|
||||
switch anchor {
|
||||
case .lowerBound, .upperBound:
|
||||
break
|
||||
@ -764,7 +879,7 @@ struct OrderedHistoryViewEntries {
|
||||
if self.lowerOrAtAnchor.count > 1 {
|
||||
for i in 1 ..< self.lowerOrAtAnchor.count {
|
||||
if self.lowerOrAtAnchor[i].index < self.lowerOrAtAnchor[i - 1].index {
|
||||
//assertionFailure()
|
||||
assertionFailure()
|
||||
break
|
||||
}
|
||||
}
|
||||
@ -772,7 +887,7 @@ struct OrderedHistoryViewEntries {
|
||||
if self.higherThanAnchor.count > 1 {
|
||||
for i in 1 ..< self.higherThanAnchor.count {
|
||||
if self.higherThanAnchor[i].index < self.higherThanAnchor[i - 1].index {
|
||||
//assertionFailure()
|
||||
assertionFailure()
|
||||
break
|
||||
}
|
||||
}
|
||||
@ -897,28 +1012,35 @@ final class HistoryViewLoadedState {
|
||||
self.holes = holes
|
||||
|
||||
var peerIds: [PeerId] = []
|
||||
var spaces: [PeerIdAndNamespace] = []
|
||||
|
||||
let input: MessageHistoryInput
|
||||
switch locations {
|
||||
case let .single(peerId):
|
||||
case let .single(peerId):
|
||||
peerIds.append(peerId)
|
||||
input = .automatic(tag.flatMap { tag in
|
||||
MessageHistoryInput.Automatic(tag: tag, appendMessagesFromTheSameGroup: appendMessagesFromTheSameGroup)
|
||||
})
|
||||
case let .associated(peerId, associatedId):
|
||||
peerIds.append(peerId)
|
||||
if let associatedId = associatedId {
|
||||
peerIds.append(associatedId.peerId)
|
||||
}
|
||||
input = .automatic(tag.flatMap { tag in
|
||||
MessageHistoryInput.Automatic(tag: tag, appendMessagesFromTheSameGroup: appendMessagesFromTheSameGroup)
|
||||
})
|
||||
case let .external(external):
|
||||
switch external.content {
|
||||
case let .thread(peerId, _, _):
|
||||
peerIds.append(peerId)
|
||||
input = .automatic(tag.flatMap { tag in
|
||||
MessageHistoryInput.Automatic(tag: tag, appendMessagesFromTheSameGroup: appendMessagesFromTheSameGroup)
|
||||
})
|
||||
case let .associated(peerId, associatedId):
|
||||
peerIds.append(peerId)
|
||||
if let associatedId = associatedId {
|
||||
peerIds.append(associatedId.peerId)
|
||||
}
|
||||
input = .automatic(tag.flatMap { tag in
|
||||
MessageHistoryInput.Automatic(tag: tag, appendMessagesFromTheSameGroup: appendMessagesFromTheSameGroup)
|
||||
})
|
||||
case let .external(external):
|
||||
peerIds.append(external.peerId)
|
||||
input = .external(external, tag)
|
||||
case .messages:
|
||||
input = .external(external, tag)
|
||||
spaces.append(PeerIdAndNamespace(peerId: PeerId(namespace: PeerId.Namespace.max, id: PeerId.Id.max), namespace: 0))
|
||||
}
|
||||
}
|
||||
self.input = input
|
||||
|
||||
var spaces: [PeerIdAndNamespace] = []
|
||||
for peerId in peerIds {
|
||||
for namespace in postbox.messageHistoryIndexTable.existingNamespaces(peerId: peerId) {
|
||||
if namespaces.contains(namespace) {
|
||||
@ -1269,6 +1391,15 @@ final class HistoryViewLoadedState {
|
||||
let combinedSpacesAndIndicesByDirection = sampleEntries(orderedEntriesBySpace: self.orderedEntriesBySpace, anchor: self.anchor, halfLimit: self.halfLimit)
|
||||
let (clipRanges, sampledHole) = sampleHoleRanges(input: self.input, orderedEntriesBySpace: self.orderedEntriesBySpace, holes: self.holes, anchor: self.anchor, halfLimit: self.halfLimit, seedConfiguration: self.seedConfiguration)
|
||||
|
||||
/*switch self.input {
|
||||
case .external:
|
||||
if sampledHole == nil {
|
||||
assert(true)
|
||||
}
|
||||
default:
|
||||
break
|
||||
}*/
|
||||
|
||||
var holesToLower = false
|
||||
var holesToHigher = false
|
||||
var result: [MessageHistoryMessageEntry] = []
|
||||
@ -1360,7 +1491,17 @@ private func fetchHoles(postbox: PostboxImpl, locations: MessageHistoryViewInput
|
||||
peerIds.append(associatedId.peerId)
|
||||
}
|
||||
case let .external(input):
|
||||
peerIds.append(input.peerId)
|
||||
switch input.content {
|
||||
case let .thread(peerId, _, _):
|
||||
peerIds.append(peerId)
|
||||
case let .messages(_, holes, _):
|
||||
let key = PeerIdAndNamespace(peerId: PeerId(namespace: PeerId.Namespace.max, id: PeerId.Id.max), namespace: 0)
|
||||
if let namespaceHoles = holes[0] {
|
||||
return [key: namespaceHoles]
|
||||
} else {
|
||||
return [:]
|
||||
}
|
||||
}
|
||||
}
|
||||
switch locations {
|
||||
case .single, .associated:
|
||||
@ -1382,19 +1523,24 @@ private func fetchHoles(postbox: PostboxImpl, locations: MessageHistoryViewInput
|
||||
}
|
||||
return holesBySpace
|
||||
case let .external(input):
|
||||
var holesBySpace: [PeerIdAndNamespace: IndexSet] = [:]
|
||||
for peerId in peerIds {
|
||||
for (namespace, indices) in input.holes {
|
||||
if namespaces.contains(namespace) {
|
||||
if !indices.isEmpty {
|
||||
let peerIdAndNamespace = PeerIdAndNamespace(peerId: peerId, namespace: namespace)
|
||||
assert(canContainHoles(peerIdAndNamespace, input: .external(input, tag), seedConfiguration: postbox.seedConfiguration))
|
||||
holesBySpace[peerIdAndNamespace] = indices
|
||||
switch input.content {
|
||||
case let .thread(_, _, holes):
|
||||
var holesBySpace: [PeerIdAndNamespace: IndexSet] = [:]
|
||||
for peerId in peerIds {
|
||||
for (namespace, indices) in holes {
|
||||
if namespaces.contains(namespace) {
|
||||
if !indices.isEmpty {
|
||||
let peerIdAndNamespace = PeerIdAndNamespace(peerId: peerId, namespace: namespace)
|
||||
assert(canContainHoles(peerIdAndNamespace, input: .external(input, tag), seedConfiguration: postbox.seedConfiguration))
|
||||
holesBySpace[peerIdAndNamespace] = indices
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return holesBySpace
|
||||
case .messages:
|
||||
return [:]
|
||||
}
|
||||
return holesBySpace
|
||||
}
|
||||
}
|
||||
|
||||
@ -1516,7 +1662,12 @@ enum HistoryViewState {
|
||||
var threadId: Int64?
|
||||
switch locations {
|
||||
case let .external(input):
|
||||
threadId = input.threadId
|
||||
switch input.content {
|
||||
case let .thread(_, id, _):
|
||||
threadId = id
|
||||
case .messages:
|
||||
break
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
@ -66,7 +66,7 @@ final class MutableMessageOfInterestHolesView: MutablePostboxView {
|
||||
|
||||
private func updateFromView() -> Bool {
|
||||
let closestHole: MessageOfInterestHole?
|
||||
if let (hole, direction, _) = self.wrappedView.firstHole() {
|
||||
if let (hole, direction, _, _) = self.wrappedView.firstHole() {
|
||||
closestHole = MessageOfInterestHole(hole: hole, direction: direction)
|
||||
} else {
|
||||
closestHole = nil
|
||||
|
||||
@ -2549,10 +2549,10 @@ final class PostboxImpl {
|
||||
switch chatLocation {
|
||||
case let .peer(peerId):
|
||||
return .single((.peer(peerId), false))
|
||||
case let .external(_, _, input):
|
||||
case .thread(_, _, let data), .feed(_, let data):
|
||||
return Signal { subscriber in
|
||||
var isHoleFill = false
|
||||
return (input
|
||||
return (data
|
||||
|> map { value -> (ResolvedChatLocationInput, Bool) in
|
||||
let wasHoleFill = isHoleFill
|
||||
isHoleFill = true
|
||||
@ -2812,12 +2812,21 @@ final class PostboxImpl {
|
||||
|
||||
let initialData: InitialMessageHistoryData
|
||||
switch peerIds {
|
||||
case let .single(peerId):
|
||||
initialData = self.initialMessageHistoryData(peerId: peerId, threadId: nil)
|
||||
case let .associated(peerId, _):
|
||||
initialData = self.initialMessageHistoryData(peerId: peerId, threadId: nil)
|
||||
case let .external(input):
|
||||
initialData = self.initialMessageHistoryData(peerId: input.peerId, threadId: input.threadId)
|
||||
case let .single(peerId):
|
||||
initialData = self.initialMessageHistoryData(peerId: peerId, threadId: nil)
|
||||
case let .associated(peerId, _):
|
||||
initialData = self.initialMessageHistoryData(peerId: peerId, threadId: nil)
|
||||
case let .external(input):
|
||||
switch input.content {
|
||||
case let .thread(peerId, id, _):
|
||||
initialData = self.initialMessageHistoryData(peerId: peerId, threadId: id)
|
||||
case .messages:
|
||||
initialData = InitialMessageHistoryData(
|
||||
peer: nil,
|
||||
storedInterfaceState: nil,
|
||||
associatedMessages: [:]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
subscriber.putNext((MessageHistoryView(mutableView), initialUpdateType, initialData))
|
||||
|
||||
@ -428,14 +428,14 @@ final class ViewTracker {
|
||||
private func updateTrackedHoles() {
|
||||
var firstHolesAndTags = Set<MessageHistoryHolesViewEntry>()
|
||||
for (view, _) in self.messageHistoryViews.copyItems() {
|
||||
if let (hole, direction, count) = view.firstHole() {
|
||||
if let (hole, direction, count, userId) = view.firstHole() {
|
||||
let space: MessageHistoryHoleSpace
|
||||
if let tag = view.tag {
|
||||
space = .tag(tag)
|
||||
} else {
|
||||
space = .everywhere
|
||||
}
|
||||
firstHolesAndTags.insert(MessageHistoryHolesViewEntry(hole: hole, direction: direction, space: space, count: count))
|
||||
firstHolesAndTags.insert(MessageHistoryHolesViewEntry(hole: hole, direction: direction, space: space, count: count, userId: userId))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -696,7 +696,7 @@ private final class QrCodeScanScreenNode: ViewControllerTracingNode, UIScrollVie
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(peerId), subject: nil, keepStack: .always, peekData: nil, completion: { [weak navigationController] _ in
|
||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(id: peerId), subject: nil, keepStack: .always, peekData: nil, completion: { [weak navigationController] _ in
|
||||
if let navigationController = navigationController {
|
||||
var viewControllers = navigationController.viewControllers
|
||||
viewControllers = viewControllers.filter { controller in
|
||||
|
||||
@ -31,7 +31,7 @@
|
||||
{
|
||||
if (block != nil)
|
||||
{
|
||||
__strong id strongBlock = (__bridge_transfer id)block;
|
||||
__unused __strong id strongBlock = (__bridge_transfer id)block;
|
||||
strongBlock = nil;
|
||||
}
|
||||
}
|
||||
|
||||
@ -29,7 +29,7 @@
|
||||
}
|
||||
|
||||
-(void)dealloc {
|
||||
__block id value = self->valueRef;
|
||||
__unused __block id value = self->valueRef;
|
||||
self->valueRef = nil;
|
||||
[_queue dispatch:^{
|
||||
value = nil;
|
||||
|
||||
@ -81,6 +81,11 @@ public func searchPeerMembers(context: AccountContext, peerId: EnginePeer.Id, ch
|
||||
return ActionDisposable {
|
||||
disposable.dispose()
|
||||
}
|
||||
case .feed:
|
||||
subscriber.putNext(([], true))
|
||||
|
||||
return ActionDisposable {
|
||||
}
|
||||
}
|
||||
} |> runOn(Queue.mainQueue())
|
||||
}
|
||||
|
||||
@ -196,7 +196,7 @@ public func logoutOptionsController(context: AccountContext, navigationControlle
|
||||
|> deliverOnMainQueue).start(next: { peerId in
|
||||
if let peerId = peerId, let navigationController = navigationController {
|
||||
dismissImpl?()
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peerId)))
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peerId)))
|
||||
}
|
||||
}))
|
||||
})
|
||||
|
||||
@ -834,7 +834,7 @@ func settingsSearchableItems(context: AccountContext, notificationExceptionsList
|
||||
allItems.append(contentsOf: profileItems)
|
||||
|
||||
let savedMessages = SettingsSearchableItem(id: .savedMessages(0), title: strings.Settings_SavedMessages, alternate: synonyms(strings.SettingsSearch_Synonyms_SavedMessages), icon: .savedMessages, breadcrumbs: [], present: { context, _, present in
|
||||
present(.push, context.sharedContext.makeChatController(context: context, chatLocation: .peer(context.account.peerId), subject: nil, botStart: nil, mode: .standard(previewing: false)))
|
||||
present(.push, context.sharedContext.makeChatController(context: context, chatLocation: .peer(id: context.account.peerId), subject: nil, botStart: nil, mode: .standard(previewing: false)))
|
||||
})
|
||||
allItems.append(savedMessages)
|
||||
|
||||
@ -885,7 +885,7 @@ func settingsSearchableItems(context: AccountContext, notificationExceptionsList
|
||||
let _ = (context.engine.peers.supportPeerId()
|
||||
|> deliverOnMainQueue).start(next: { peerId in
|
||||
if let peerId = peerId {
|
||||
present(.push, context.sharedContext.makeChatController(context: context, chatLocation: .peer(peerId), subject: nil, botStart: nil, mode: .standard(previewing: false)))
|
||||
present(.push, context.sharedContext.makeChatController(context: context, chatLocation: .peer(id: peerId), subject: nil, botStart: nil, mode: .standard(previewing: false)))
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
@ -1238,7 +1238,7 @@ public func installedStickerPacksController(context: AccountContext, mode: Insta
|
||||
}
|
||||
navigateToChatControllerImpl = { [weak controller] peerId in
|
||||
if let controller = controller, let navigationController = controller.navigationController as? NavigationController {
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peerId)))
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peerId)))
|
||||
}
|
||||
}
|
||||
dismissImpl = { [weak controller] in
|
||||
|
||||
@ -417,7 +417,7 @@ public func themePickerController(context: AccountContext, focusOnItemTag: Theme
|
||||
}, editTheme: { theme in
|
||||
let controller = editThemeController(context: context, mode: .edit(theme), navigateToChat: { peerId in
|
||||
if let navigationController = getNavigationControllerImpl?() {
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peerId)))
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peerId)))
|
||||
}
|
||||
})
|
||||
pushControllerImpl?(controller)
|
||||
@ -439,7 +439,7 @@ public func themePickerController(context: AccountContext, focusOnItemTag: Theme
|
||||
if case let .cloud(cloudTheme) = themeReference, cloudTheme.theme.settings?.isEmpty ?? true {
|
||||
let controller = editThemeController(context: context, mode: .edit(cloudTheme), navigateToChat: { peerId in
|
||||
if let navigationController = getNavigationControllerImpl?() {
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peerId)))
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peerId)))
|
||||
}
|
||||
})
|
||||
pushControllerImpl?(controller)
|
||||
@ -464,7 +464,7 @@ public func themePickerController(context: AccountContext, focusOnItemTag: Theme
|
||||
|> deliverOnMainQueue).start(next: { themeReference in
|
||||
let controller = editThemeController(context: context, mode: .create(nil, nil), navigateToChat: { peerId in
|
||||
if let navigationController = getNavigationControllerImpl?() {
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peerId)))
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peerId)))
|
||||
}
|
||||
})
|
||||
pushControllerImpl?(controller)
|
||||
@ -526,7 +526,7 @@ public func themePickerController(context: AccountContext, focusOnItemTag: Theme
|
||||
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
|
||||
if let navigationController = getNavigationControllerImpl?() {
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peerId)))
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peerId)))
|
||||
}
|
||||
})
|
||||
|
||||
@ -556,7 +556,7 @@ public func themePickerController(context: AccountContext, focusOnItemTag: Theme
|
||||
let controller = editThemeController(context: context, mode: .create(result, settings
|
||||
), navigateToChat: { peerId in
|
||||
if let navigationController = getNavigationControllerImpl?() {
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peerId)))
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peerId)))
|
||||
}
|
||||
})
|
||||
updateControllersImpl?({ controllers in
|
||||
@ -762,7 +762,7 @@ public func themePickerController(context: AccountContext, focusOnItemTag: Theme
|
||||
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
|
||||
if let navigationController = getNavigationControllerImpl?() {
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peerId)))
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peerId)))
|
||||
}
|
||||
})
|
||||
|
||||
@ -797,7 +797,7 @@ 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 = editThemeController(context: context, mode: .create(hasSettings ? nil : result, hasSettings ? settings : nil), navigateToChat: { peerId in
|
||||
if let navigationController = getNavigationControllerImpl?() {
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peerId)))
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peerId)))
|
||||
}
|
||||
})
|
||||
updateControllersImpl?({ controllers in
|
||||
|
||||
@ -501,7 +501,7 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
|
||||
}, editTheme: { theme in
|
||||
let controller = editThemeController(context: context, mode: .edit(theme), navigateToChat: { peerId in
|
||||
if let navigationController = getNavigationControllerImpl?() {
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peerId)))
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peerId)))
|
||||
}
|
||||
})
|
||||
pushControllerImpl?(controller)
|
||||
@ -562,7 +562,7 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
|
||||
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
|
||||
if let navigationController = getNavigationControllerImpl?() {
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peerId)))
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peerId)))
|
||||
}
|
||||
})
|
||||
|
||||
@ -592,7 +592,7 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
|
||||
let controller = editThemeController(context: context, mode: .create(result, settings
|
||||
), navigateToChat: { peerId in
|
||||
if let navigationController = getNavigationControllerImpl?() {
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peerId)))
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peerId)))
|
||||
}
|
||||
})
|
||||
updateControllersImpl?({ controllers in
|
||||
@ -796,7 +796,7 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
|
||||
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
|
||||
if let navigationController = getNavigationControllerImpl?() {
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peerId)))
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peerId)))
|
||||
}
|
||||
})
|
||||
|
||||
@ -831,7 +831,7 @@ 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 = editThemeController(context: context, mode: .create(hasSettings ? nil : result, hasSettings ? settings : nil), navigateToChat: { peerId in
|
||||
if let navigationController = getNavigationControllerImpl?() {
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peerId)))
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peerId)))
|
||||
}
|
||||
})
|
||||
updateControllersImpl?({ controllers in
|
||||
|
||||
@ -450,7 +450,7 @@ public func channelStatsController(context: AccountContext, updatedPresentationD
|
||||
contextActionImpl?(messageId, node, gesture)
|
||||
})
|
||||
|
||||
let messageView = context.account.viewTracker.aroundMessageHistoryViewForLocation(.peer(peerId), index: .upperBound, anchorIndex: .upperBound, count: 100, fixedCombinedReadStates: nil)
|
||||
let messageView = context.account.viewTracker.aroundMessageHistoryViewForLocation(.peer(peerId: peerId), index: .upperBound, anchorIndex: .upperBound, count: 100, fixedCombinedReadStates: nil)
|
||||
|> map { messageHistoryView, _, _ -> MessageHistoryView? in
|
||||
return messageHistoryView
|
||||
}
|
||||
@ -518,7 +518,7 @@ public func channelStatsController(context: AccountContext, updatedPresentationD
|
||||
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: {
|
||||
if let navigationController = controller?.navigationController as? NavigationController {
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peerId), subject: .message(id: .id(messageId), highlight: true, timecode: nil)))
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peerId), subject: .message(id: .id(messageId), highlight: true, timecode: nil)))
|
||||
}
|
||||
})
|
||||
})))
|
||||
|
||||
@ -884,7 +884,7 @@ public func groupStatsController(context: AccountContext, updatedPresentationDat
|
||||
let _ = (context.account.postbox.loadedPeerWithId(participantPeerId)
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { peer in
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, chatController: nil, context: context, chatLocation: .peer(peerId), subject: nil, botStart: nil, updateTextInputState: nil, activateInput: false, keepStack: .always, useExisting: false, purposefulAction: nil, scrollToEndIfExists: false, activateMessageSearch: (.member(peer), ""), animated: true))
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, chatController: nil, context: context, chatLocation: .peer(id: peerId), subject: nil, botStart: nil, updateTextInputState: nil, activateInput: false, keepStack: .always, useExisting: false, purposefulAction: nil, scrollToEndIfExists: false, activateMessageSearch: (.member(peer), ""), animated: true))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -263,7 +263,7 @@ public func messageStatsController(context: AccountContext, messageId: MessageId
|
||||
}
|
||||
navigateToMessageImpl = { [weak controller] messageId in
|
||||
if let navigationController = controller?.navigationController as? NavigationController {
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(messageId.peerId), subject: .message(id: .id(messageId), highlight: true, timecode: nil), keepStack: .always, useExisting: false, purposefulAction: {}, peekData: nil))
|
||||
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))
|
||||
}
|
||||
}
|
||||
return controller
|
||||
|
||||
@ -149,7 +149,7 @@ public final class StickerPackPreviewController: ViewController, StandalonePrese
|
||||
}
|
||||
if let peer = peer, let parentNavigationController = strongSelf.parentNavigationController {
|
||||
strongSelf.dismiss()
|
||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: parentNavigationController, context: strongSelf.context, chatLocation: .peer(peer.id), animated: true))
|
||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: parentNavigationController, context: strongSelf.context, chatLocation: .peer(id: peer.id), animated: true))
|
||||
}
|
||||
}))
|
||||
}, actionPerformed: self.actionPerformed)
|
||||
|
||||
@ -107,7 +107,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
||||
dict[483104362] = { return Api.RichText.parse_textPhone($0) }
|
||||
dict[136105807] = { return Api.RichText.parse_textImage($0) }
|
||||
dict[894777186] = { return Api.RichText.parse_textAnchor($0) }
|
||||
dict[-818518751] = { return Api.UserFull.parse_userFull($0) }
|
||||
dict[-1938625919] = { return Api.UserFull.parse_userFull($0) }
|
||||
dict[-292807034] = { return Api.InputChannel.parse_inputChannelEmpty($0) }
|
||||
dict[-212145112] = { return Api.InputChannel.parse_inputChannel($0) }
|
||||
dict[1536380829] = { return Api.InputChannel.parse_inputChannelFromMessage($0) }
|
||||
@ -292,6 +292,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
||||
dict[1885586395] = { return Api.Update.parse_updatePendingJoinRequests($0) }
|
||||
dict[299870598] = { return Api.Update.parse_updateBotChatInviteRequester($0) }
|
||||
dict[357013699] = { return Api.Update.parse_updateMessageReactions($0) }
|
||||
dict[1951948721] = { return Api.Update.parse_updateReadFeed($0) }
|
||||
dict[136574537] = { return Api.messages.VotesList.parse_votesList($0) }
|
||||
dict[1558266229] = { return Api.PopularContact.parse_popularContact($0) }
|
||||
dict[-592373577] = { return Api.GroupCallParticipantVideoSourceGroup.parse_groupCallParticipantVideoSourceGroup($0) }
|
||||
@ -433,6 +434,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
||||
dict[1694474197] = { return Api.messages.Chats.parse_chats($0) }
|
||||
dict[-1663561404] = { return Api.messages.Chats.parse_chatsSlice($0) }
|
||||
dict[-2118733814] = { return Api.messages.ChatInviteImporters.parse_chatInviteImporters($0) }
|
||||
dict[1348066419] = { return Api.FeedPosition.parse_feedPosition($0) }
|
||||
dict[-659913713] = { return Api.InputGroupCall.parse_inputGroupCall($0) }
|
||||
dict[-2091463255] = { return Api.channels.SendAsPeers.parse_sendAsPeers($0) }
|
||||
dict[482797855] = { return Api.InputSingleMedia.parse_inputSingleMedia($0) }
|
||||
@ -851,6 +853,8 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
||||
dict[-463335103] = { return Api.PrivacyRule.parse_privacyValueDisallowUsers($0) }
|
||||
dict[1796427406] = { return Api.PrivacyRule.parse_privacyValueAllowChatParticipants($0) }
|
||||
dict[1103656293] = { return Api.PrivacyRule.parse_privacyValueDisallowChatParticipants($0) }
|
||||
dict[-619039485] = { return Api.feed.FeedMessages.parse_feedMessagesNotModified($0) }
|
||||
dict[-587770695] = { return Api.feed.FeedMessages.parse_feedMessages($0) }
|
||||
dict[-1230047312] = { return Api.MessageAction.parse_messageActionEmpty($0) }
|
||||
dict[-1119368275] = { return Api.MessageAction.parse_messageActionChatCreate($0) }
|
||||
dict[-1247687078] = { return Api.MessageAction.parse_messageActionChatEditTitle($0) }
|
||||
@ -1255,6 +1259,8 @@ public struct Api {
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.messages.ChatInviteImporters:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.FeedPosition:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.InputGroupCall:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.channels.SendAsPeers:
|
||||
@ -1627,6 +1633,8 @@ public struct Api {
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.PrivacyRule:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.feed.FeedMessages:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.MessageAction:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.PhoneCall:
|
||||
|
||||
@ -2944,13 +2944,13 @@ public extension Api {
|
||||
|
||||
}
|
||||
public enum UserFull: TypeConstructorDescription {
|
||||
case userFull(flags: Int32, id: Int64, about: String?, settings: Api.PeerSettings, profilePhoto: Api.Photo?, notifySettings: Api.PeerNotifySettings, botInfo: Api.BotInfo?, pinnedMsgId: Int32?, commonChatsCount: Int32, folderId: Int32?, ttlPeriod: Int32?, themeEmoticon: String?, privateForwardName: String?)
|
||||
case userFull(flags: Int32, id: Int64, about: String?, settings: Api.PeerSettings, profilePhoto: Api.Photo?, notifySettings: Api.PeerNotifySettings, botInfo: Api.BotInfo?, pinnedMsgId: Int32?, commonChatsCount: Int32, folderId: Int32?, ttlPeriod: Int32?, themeEmoticon: String?, privateForwardName: String?, botGroupAdminRights: Api.ChatAdminRights?, botBroadcastAdminRights: Api.ChatAdminRights?)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .userFull(let flags, let id, let about, let settings, let profilePhoto, let notifySettings, let botInfo, let pinnedMsgId, let commonChatsCount, let folderId, let ttlPeriod, let themeEmoticon, let privateForwardName):
|
||||
case .userFull(let flags, let id, let about, let settings, let profilePhoto, let notifySettings, let botInfo, let pinnedMsgId, let commonChatsCount, let folderId, let ttlPeriod, let themeEmoticon, let privateForwardName, let botGroupAdminRights, let botBroadcastAdminRights):
|
||||
if boxed {
|
||||
buffer.appendInt32(-818518751)
|
||||
buffer.appendInt32(-1938625919)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt64(id, buffer: buffer, boxed: false)
|
||||
@ -2965,14 +2965,16 @@ public extension Api {
|
||||
if Int(flags) & Int(1 << 14) != 0 {serializeInt32(ttlPeriod!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 15) != 0 {serializeString(themeEmoticon!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 16) != 0 {serializeString(privateForwardName!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 17) != 0 {botGroupAdminRights!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 18) != 0 {botBroadcastAdminRights!.serialize(buffer, true)}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .userFull(let flags, let id, let about, let settings, let profilePhoto, let notifySettings, let botInfo, let pinnedMsgId, let commonChatsCount, let folderId, let ttlPeriod, let themeEmoticon, let privateForwardName):
|
||||
return ("userFull", [("flags", flags), ("id", id), ("about", about), ("settings", settings), ("profilePhoto", profilePhoto), ("notifySettings", notifySettings), ("botInfo", botInfo), ("pinnedMsgId", pinnedMsgId), ("commonChatsCount", commonChatsCount), ("folderId", folderId), ("ttlPeriod", ttlPeriod), ("themeEmoticon", themeEmoticon), ("privateForwardName", privateForwardName)])
|
||||
case .userFull(let flags, let id, let about, let settings, let profilePhoto, let notifySettings, let botInfo, let pinnedMsgId, let commonChatsCount, let folderId, let ttlPeriod, let themeEmoticon, let privateForwardName, let botGroupAdminRights, let botBroadcastAdminRights):
|
||||
return ("userFull", [("flags", flags), ("id", id), ("about", about), ("settings", settings), ("profilePhoto", profilePhoto), ("notifySettings", notifySettings), ("botInfo", botInfo), ("pinnedMsgId", pinnedMsgId), ("commonChatsCount", commonChatsCount), ("folderId", folderId), ("ttlPeriod", ttlPeriod), ("themeEmoticon", themeEmoticon), ("privateForwardName", privateForwardName), ("botGroupAdminRights", botGroupAdminRights), ("botBroadcastAdminRights", botBroadcastAdminRights)])
|
||||
}
|
||||
}
|
||||
|
||||
@ -3011,6 +3013,14 @@ public extension Api {
|
||||
if Int(_1!) & Int(1 << 15) != 0 {_12 = parseString(reader) }
|
||||
var _13: String?
|
||||
if Int(_1!) & Int(1 << 16) != 0 {_13 = parseString(reader) }
|
||||
var _14: Api.ChatAdminRights?
|
||||
if Int(_1!) & Int(1 << 17) != 0 {if let signature = reader.readInt32() {
|
||||
_14 = Api.parse(reader, signature: signature) as? Api.ChatAdminRights
|
||||
} }
|
||||
var _15: Api.ChatAdminRights?
|
||||
if Int(_1!) & Int(1 << 18) != 0 {if let signature = reader.readInt32() {
|
||||
_15 = Api.parse(reader, signature: signature) as? Api.ChatAdminRights
|
||||
} }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = (Int(_1!) & Int(1 << 1) == 0) || _3 != nil
|
||||
@ -3024,8 +3034,10 @@ public extension Api {
|
||||
let _c11 = (Int(_1!) & Int(1 << 14) == 0) || _11 != nil
|
||||
let _c12 = (Int(_1!) & Int(1 << 15) == 0) || _12 != nil
|
||||
let _c13 = (Int(_1!) & Int(1 << 16) == 0) || _13 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 {
|
||||
return Api.UserFull.userFull(flags: _1!, id: _2!, about: _3, settings: _4!, profilePhoto: _5, notifySettings: _6!, botInfo: _7, pinnedMsgId: _8, commonChatsCount: _9!, folderId: _10, ttlPeriod: _11, themeEmoticon: _12, privateForwardName: _13)
|
||||
let _c14 = (Int(_1!) & Int(1 << 17) == 0) || _14 != nil
|
||||
let _c15 = (Int(_1!) & Int(1 << 18) == 0) || _15 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 {
|
||||
return Api.UserFull.userFull(flags: _1!, id: _2!, about: _3, settings: _4!, profilePhoto: _5, notifySettings: _6!, botInfo: _7, pinnedMsgId: _8, commonChatsCount: _9!, folderId: _10, ttlPeriod: _11, themeEmoticon: _12, privateForwardName: _13, botGroupAdminRights: _14, botBroadcastAdminRights: _15)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
@ -4924,6 +4936,7 @@ public extension Api {
|
||||
case updatePendingJoinRequests(peer: Api.Peer, requestsPending: Int32, recentRequesters: [Int64])
|
||||
case updateBotChatInviteRequester(peer: Api.Peer, date: Int32, userId: Int64, about: String, invite: Api.ExportedChatInvite, qts: Int32)
|
||||
case updateMessageReactions(peer: Api.Peer, msgId: Int32, reactions: Api.MessageReactions)
|
||||
case updateReadFeed(flags: Int32, filterId: Int32, maxPosition: Api.FeedPosition, unreadCount: Int32?, unreadMutedCount: Int32?)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
@ -5769,6 +5782,16 @@ public extension Api {
|
||||
serializeInt32(msgId, buffer: buffer, boxed: false)
|
||||
reactions.serialize(buffer, true)
|
||||
break
|
||||
case .updateReadFeed(let flags, let filterId, let maxPosition, let unreadCount, let unreadMutedCount):
|
||||
if boxed {
|
||||
buffer.appendInt32(1951948721)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt32(filterId, buffer: buffer, boxed: false)
|
||||
maxPosition.serialize(buffer, true)
|
||||
if Int(flags) & Int(1 << 0) != 0 {serializeInt32(unreadCount!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 0) != 0 {serializeInt32(unreadMutedCount!, buffer: buffer, boxed: false)}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
@ -5966,6 +5989,8 @@ public extension Api {
|
||||
return ("updateBotChatInviteRequester", [("peer", peer), ("date", date), ("userId", userId), ("about", about), ("invite", invite), ("qts", qts)])
|
||||
case .updateMessageReactions(let peer, let msgId, let reactions):
|
||||
return ("updateMessageReactions", [("peer", peer), ("msgId", msgId), ("reactions", reactions)])
|
||||
case .updateReadFeed(let flags, let filterId, let maxPosition, let unreadCount, let unreadMutedCount):
|
||||
return ("updateReadFeed", [("flags", flags), ("filterId", filterId), ("maxPosition", maxPosition), ("unreadCount", unreadCount), ("unreadMutedCount", unreadMutedCount)])
|
||||
}
|
||||
}
|
||||
|
||||
@ -7697,6 +7722,31 @@ public extension Api {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_updateReadFeed(_ reader: BufferReader) -> Update? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int32?
|
||||
_2 = reader.readInt32()
|
||||
var _3: Api.FeedPosition?
|
||||
if let signature = reader.readInt32() {
|
||||
_3 = Api.parse(reader, signature: signature) as? Api.FeedPosition
|
||||
}
|
||||
var _4: Int32?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {_4 = reader.readInt32() }
|
||||
var _5: Int32?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {_5 = reader.readInt32() }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = (Int(_1!) & Int(1 << 0) == 0) || _4 != nil
|
||||
let _c5 = (Int(_1!) & Int(1 << 0) == 0) || _5 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 {
|
||||
return Api.Update.updateReadFeed(flags: _1!, filterId: _2!, maxPosition: _3!, unreadCount: _4, unreadMutedCount: _5)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public enum PopularContact: TypeConstructorDescription {
|
||||
@ -11394,6 +11444,50 @@ public extension Api {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public enum FeedPosition: TypeConstructorDescription {
|
||||
case feedPosition(date: Int32, peer: Api.Peer, id: Int32)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .feedPosition(let date, let peer, let id):
|
||||
if boxed {
|
||||
buffer.appendInt32(1348066419)
|
||||
}
|
||||
serializeInt32(date, buffer: buffer, boxed: false)
|
||||
peer.serialize(buffer, true)
|
||||
serializeInt32(id, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .feedPosition(let date, let peer, let id):
|
||||
return ("feedPosition", [("date", date), ("peer", peer), ("id", id)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_feedPosition(_ reader: BufferReader) -> FeedPosition? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Api.Peer?
|
||||
if let signature = reader.readInt32() {
|
||||
_2 = Api.parse(reader, signature: signature) as? Api.Peer
|
||||
}
|
||||
var _3: Int32?
|
||||
_3 = reader.readInt32()
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
if _c1 && _c2 && _c3 {
|
||||
return Api.FeedPosition.feedPosition(date: _1!, peer: _2!, id: _3!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public enum InputGroupCall: TypeConstructorDescription {
|
||||
case inputGroupCall(id: Int64, accessHash: Int64)
|
||||
|
||||
@ -621,6 +621,104 @@ public struct upload {
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
public struct feed {
|
||||
public enum FeedMessages: TypeConstructorDescription {
|
||||
case feedMessagesNotModified
|
||||
case feedMessages(flags: Int32, maxPosition: Api.FeedPosition?, minPosition: Api.FeedPosition?, readMaxPosition: Api.FeedPosition?, messages: [Api.Message], chats: [Api.Chat], users: [Api.User])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .feedMessagesNotModified:
|
||||
if boxed {
|
||||
buffer.appendInt32(-619039485)
|
||||
}
|
||||
|
||||
break
|
||||
case .feedMessages(let flags, let maxPosition, let minPosition, let readMaxPosition, let messages, let chats, let users):
|
||||
if boxed {
|
||||
buffer.appendInt32(-587770695)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 0) != 0 {maxPosition!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 1) != 0 {minPosition!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 2) != 0 {readMaxPosition!.serialize(buffer, true)}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(messages.count))
|
||||
for item in messages {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(chats.count))
|
||||
for item in chats {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(users.count))
|
||||
for item in users {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .feedMessagesNotModified:
|
||||
return ("feedMessagesNotModified", [])
|
||||
case .feedMessages(let flags, let maxPosition, let minPosition, let readMaxPosition, let messages, let chats, let users):
|
||||
return ("feedMessages", [("flags", flags), ("maxPosition", maxPosition), ("minPosition", minPosition), ("readMaxPosition", readMaxPosition), ("messages", messages), ("chats", chats), ("users", users)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_feedMessagesNotModified(_ reader: BufferReader) -> FeedMessages? {
|
||||
return Api.feed.FeedMessages.feedMessagesNotModified
|
||||
}
|
||||
public static func parse_feedMessages(_ reader: BufferReader) -> FeedMessages? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Api.FeedPosition?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {if let signature = reader.readInt32() {
|
||||
_2 = Api.parse(reader, signature: signature) as? Api.FeedPosition
|
||||
} }
|
||||
var _3: Api.FeedPosition?
|
||||
if Int(_1!) & Int(1 << 1) != 0 {if let signature = reader.readInt32() {
|
||||
_3 = Api.parse(reader, signature: signature) as? Api.FeedPosition
|
||||
} }
|
||||
var _4: Api.FeedPosition?
|
||||
if Int(_1!) & Int(1 << 2) != 0 {if let signature = reader.readInt32() {
|
||||
_4 = Api.parse(reader, signature: signature) as? Api.FeedPosition
|
||||
} }
|
||||
var _5: [Api.Message]?
|
||||
if let _ = reader.readInt32() {
|
||||
_5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Message.self)
|
||||
}
|
||||
var _6: [Api.Chat]?
|
||||
if let _ = reader.readInt32() {
|
||||
_6 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
|
||||
}
|
||||
var _7: [Api.User]?
|
||||
if let _ = reader.readInt32() {
|
||||
_7 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = (Int(_1!) & Int(1 << 0) == 0) || _2 != nil
|
||||
let _c3 = (Int(_1!) & Int(1 << 1) == 0) || _3 != nil
|
||||
let _c4 = (Int(_1!) & Int(1 << 2) == 0) || _4 != nil
|
||||
let _c5 = _5 != nil
|
||||
let _c6 = _6 != nil
|
||||
let _c7 = _7 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 {
|
||||
return Api.feed.FeedMessages.feedMessages(flags: _1!, maxPosition: _2, minPosition: _3, readMaxPosition: _4, messages: _5!, chats: _6!, users: _7!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
public struct stickers {
|
||||
public enum SuggestedShortName: TypeConstructorDescription {
|
||||
case suggestedShortName(shortName: String)
|
||||
@ -6865,6 +6963,43 @@ public extension Api {
|
||||
})
|
||||
}
|
||||
}
|
||||
public struct feed {
|
||||
public static func getFeed(flags: Int32, filterId: Int32, offsetPosition: Api.FeedPosition?, addOffset: Int32, limit: Int32, maxPosition: Api.FeedPosition?, minPosition: Api.FeedPosition?, hash: Int64) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.feed.FeedMessages>) {
|
||||
let buffer = Buffer()
|
||||
buffer.appendInt32(2121717715)
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt32(filterId, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 0) != 0 {offsetPosition!.serialize(buffer, true)}
|
||||
serializeInt32(addOffset, buffer: buffer, boxed: false)
|
||||
serializeInt32(limit, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 1) != 0 {maxPosition!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 2) != 0 {minPosition!.serialize(buffer, true)}
|
||||
serializeInt64(hash, buffer: buffer, boxed: false)
|
||||
return (FunctionDescription(name: "feed.getFeed", parameters: [("flags", flags), ("filterId", filterId), ("offsetPosition", offsetPosition), ("addOffset", addOffset), ("limit", limit), ("maxPosition", maxPosition), ("minPosition", minPosition), ("hash", hash)]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.feed.FeedMessages? in
|
||||
let reader = BufferReader(buffer)
|
||||
var result: Api.feed.FeedMessages?
|
||||
if let signature = reader.readInt32() {
|
||||
result = Api.parse(reader, signature: signature) as? Api.feed.FeedMessages
|
||||
}
|
||||
return result
|
||||
})
|
||||
}
|
||||
|
||||
public static func readFeed(filterId: Int32, maxPosition: Api.FeedPosition) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
|
||||
let buffer = Buffer()
|
||||
buffer.appendInt32(-1271479809)
|
||||
serializeInt32(filterId, buffer: buffer, boxed: false)
|
||||
maxPosition.serialize(buffer, true)
|
||||
return (FunctionDescription(name: "feed.readFeed", parameters: [("filterId", filterId), ("maxPosition", maxPosition)]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in
|
||||
let reader = BufferReader(buffer)
|
||||
var result: Api.Updates?
|
||||
if let signature = reader.readInt32() {
|
||||
result = Api.parse(reader, signature: signature) as? Api.Updates
|
||||
}
|
||||
return result
|
||||
})
|
||||
}
|
||||
}
|
||||
public struct stickers {
|
||||
public static func createStickerSet(flags: Int32, userId: Api.InputUser, title: String, shortName: String, thumb: Api.InputDocument?, stickers: [Api.InputStickerSetItem], software: String?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.messages.StickerSet>) {
|
||||
let buffer = Buffer()
|
||||
|
||||
@ -758,7 +758,7 @@ open class TelegramBaseController: ViewController, KeyShortcutResponder {
|
||||
strongSelf.displayNode.view.window?.endEditing(true)
|
||||
strongSelf.present(controller, in: .window(.root))
|
||||
} else {
|
||||
let signal = strongSelf.context.sharedContext.messageFromPreloadedChatHistoryViewForLocation(id: id.messageId, location: ChatHistoryLocationInput(content: .InitialSearch(location: .id(id.messageId), count: 60, highlight: true), id: 0), context: strongSelf.context, chatLocation: .peer(id.messageId.peerId), subject: nil, chatLocationContextHolder: Atomic<ChatLocationContextHolder?>(value: nil), tagMask: MessageTags.music)
|
||||
let signal = strongSelf.context.sharedContext.messageFromPreloadedChatHistoryViewForLocation(id: id.messageId, location: ChatHistoryLocationInput(content: .InitialSearch(location: .id(id.messageId), count: 60, highlight: true), id: 0), context: strongSelf.context, chatLocation: .peer(id: id.messageId.peerId), subject: nil, chatLocationContextHolder: Atomic<ChatLocationContextHolder?>(value: nil), tagMask: MessageTags.music)
|
||||
|
||||
var cancelImpl: (() -> Void)?
|
||||
let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 }
|
||||
|
||||
@ -1693,7 +1693,7 @@ public final class VoiceChatControllerImpl: ViewController, VoiceChatController
|
||||
let context = strongSelf.context
|
||||
strongSelf.controller?.dismiss(completion: {
|
||||
Queue.mainQueue().after(0.3) {
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer.id), keepStack: .always, purposefulAction: {}, peekData: nil))
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peer.id), keepStack: .always, purposefulAction: {}, peekData: nil))
|
||||
}
|
||||
})
|
||||
|
||||
@ -2653,7 +2653,7 @@ public final class VoiceChatControllerImpl: ViewController, VoiceChatController
|
||||
let context = strongSelf.context
|
||||
strongSelf.controller?.dismiss(completion: {
|
||||
Queue.mainQueue().justDispatch {
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(context.account.peerId), keepStack: .always, purposefulAction: {}, peekData: nil))
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: context.account.peerId), keepStack: .always, purposefulAction: {}, peekData: nil))
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@ -20,6 +20,7 @@ swift_library(
|
||||
"//submodules/NetworkLogging:NetworkLogging",
|
||||
"//submodules/Reachability:Reachability",
|
||||
"//submodules/ManagedFile:ManagedFile",
|
||||
"//submodules/Utils/RangeSet:RangeSet",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
||||
@ -183,18 +183,20 @@ private func fetchPoll(account: Account, messageId: MessageId) -> Signal<Void, N
|
||||
private func wrappedHistoryViewAdditionalData(chatLocation: ChatLocationInput, additionalData: [AdditionalMessageHistoryViewData]) -> [AdditionalMessageHistoryViewData] {
|
||||
var result = additionalData
|
||||
switch chatLocation {
|
||||
case let .peer(peerId):
|
||||
if peerId.namespace == Namespaces.Peer.CloudChannel {
|
||||
if result.firstIndex(where: { if case .peerChatState = $0 { return true } else { return false } }) == nil {
|
||||
result.append(.peerChatState(peerId))
|
||||
}
|
||||
case let .peer(peerId):
|
||||
if peerId.namespace == Namespaces.Peer.CloudChannel {
|
||||
if result.firstIndex(where: { if case .peerChatState = $0 { return true } else { return false } }) == nil {
|
||||
result.append(.peerChatState(peerId))
|
||||
}
|
||||
case let .external(peerId, _, _):
|
||||
if peerId.namespace == Namespaces.Peer.CloudChannel {
|
||||
if result.firstIndex(where: { if case .peerChatState = $0 { return true } else { return false } }) == nil {
|
||||
result.append(.peerChatState(peerId))
|
||||
}
|
||||
}
|
||||
case let .thread(peerId, _, _):
|
||||
if peerId.namespace == Namespaces.Peer.CloudChannel {
|
||||
if result.firstIndex(where: { if case .peerChatState = $0 { return true } else { return false } }) == nil {
|
||||
result.append(.peerChatState(peerId))
|
||||
}
|
||||
}
|
||||
case .feed:
|
||||
break
|
||||
}
|
||||
return result
|
||||
}
|
||||
@ -1474,7 +1476,7 @@ public final class AccountViewTracker {
|
||||
strongSelf.updatePolls(viewId: viewId, messageIds: pollMessageIds, messages: pollMessageDict)
|
||||
if case let .peer(peerId) = chatLocation, peerId.namespace == Namespaces.Peer.CloudChannel {
|
||||
strongSelf.historyViewStateValidationContexts.updateView(id: viewId, view: next.0)
|
||||
} else if case let .external(peerId, _, _) = chatLocation, peerId.namespace == Namespaces.Peer.CloudChannel {
|
||||
} else if case let .thread(peerId, _, _) = chatLocation, peerId.namespace == Namespaces.Peer.CloudChannel {
|
||||
strongSelf.historyViewStateValidationContexts.updateView(id: viewId, view: next.0, location: chatLocation)
|
||||
}
|
||||
}
|
||||
@ -1485,27 +1487,31 @@ public final class AccountViewTracker {
|
||||
strongSelf.updatePendingWebpages(viewId: viewId, messageIds: [], localWebpages: [:])
|
||||
strongSelf.updatePolls(viewId: viewId, messageIds: [], messages: [:])
|
||||
switch chatLocation {
|
||||
case let .peer(peerId):
|
||||
if peerId.namespace == Namespaces.Peer.CloudChannel {
|
||||
strongSelf.historyViewStateValidationContexts.updateView(id: viewId, view: nil)
|
||||
}
|
||||
case let .external(peerId, _, _):
|
||||
if peerId.namespace == Namespaces.Peer.CloudChannel {
|
||||
strongSelf.historyViewStateValidationContexts.updateView(id: viewId, view: nil, location: chatLocation)
|
||||
}
|
||||
case let .peer(peerId):
|
||||
if peerId.namespace == Namespaces.Peer.CloudChannel {
|
||||
strongSelf.historyViewStateValidationContexts.updateView(id: viewId, view: nil)
|
||||
}
|
||||
case let .thread(peerId, _, _):
|
||||
if peerId.namespace == Namespaces.Peer.CloudChannel {
|
||||
strongSelf.historyViewStateValidationContexts.updateView(id: viewId, view: nil, location: chatLocation)
|
||||
}
|
||||
case .feed:
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
let peerId: PeerId
|
||||
let peerId: PeerId?
|
||||
switch chatLocation {
|
||||
case let .peer(peerIdValue):
|
||||
peerId = peerIdValue
|
||||
case let .external(peerIdValue, _, _):
|
||||
case let .thread(peerIdValue, _, _):
|
||||
peerId = peerIdValue
|
||||
case .feed:
|
||||
peerId = nil
|
||||
}
|
||||
if peerId.namespace == Namespaces.Peer.CloudChannel {
|
||||
if let peerId = peerId, peerId.namespace == Namespaces.Peer.CloudChannel {
|
||||
return Signal<(MessageHistoryView, ViewUpdateType, InitialMessageHistoryData?), NoError> { subscriber in
|
||||
let combinedDisposable = MetaDisposable()
|
||||
self.queue.async {
|
||||
|
||||
@ -156,7 +156,7 @@ final class HistoryViewStateValidationContexts {
|
||||
}
|
||||
}
|
||||
|
||||
if let location = location, case let .external(peerId, threadId, _) = location {
|
||||
if let location = location, case let .thread(peerId, threadId, _) = location {
|
||||
var rangesToInvalidate: [[MessageId]] = []
|
||||
let addToRange: (MessageId, inout [[MessageId]]) -> Void = { id, ranges in
|
||||
if ranges.isEmpty {
|
||||
|
||||
@ -210,7 +210,7 @@ public class BoxedMessage: NSObject {
|
||||
|
||||
public class Serialization: NSObject, MTSerialization {
|
||||
public func currentLayer() -> UInt {
|
||||
return 139
|
||||
return 141
|
||||
}
|
||||
|
||||
public func parseMessage(_ data: Data!) -> Any! {
|
||||
|
||||
@ -10,7 +10,7 @@ public enum EarliestUnseenPersonalMentionMessageResult: Equatable {
|
||||
}
|
||||
|
||||
func _internal_earliestUnseenPersonalMentionMessage(account: Account, peerId: PeerId) -> Signal<EarliestUnseenPersonalMentionMessageResult, NoError> {
|
||||
return account.viewTracker.aroundMessageHistoryViewForLocation(.peer(peerId), index: .lowerBound, anchorIndex: .lowerBound, count: 4, fixedCombinedReadStates: nil, tagMask: .unseenPersonalMessage, additionalData: [.peerChatState(peerId)])
|
||||
return account.viewTracker.aroundMessageHistoryViewForLocation(.peer(peerId: peerId), index: .lowerBound, anchorIndex: .lowerBound, count: 4, fixedCombinedReadStates: nil, tagMask: .unseenPersonalMessage, additionalData: [.peerChatState(peerId)])
|
||||
|> mapToSignal { view -> Signal<EarliestUnseenPersonalMentionMessageResult, NoError> in
|
||||
if view.0.isLoading {
|
||||
return .single(.loading)
|
||||
@ -77,7 +77,7 @@ func _internal_earliestUnseenPersonalMentionMessage(account: Account, peerId: Pe
|
||||
}
|
||||
|
||||
func _internal_earliestUnseenPersonalReactionMessage(account: Account, peerId: PeerId) -> Signal<EarliestUnseenPersonalMentionMessageResult, NoError> {
|
||||
return account.viewTracker.aroundMessageHistoryViewForLocation(.peer(peerId), index: .lowerBound, anchorIndex: .lowerBound, count: 4, fixedCombinedReadStates: nil, tagMask: .unseenReaction, additionalData: [.peerChatState(peerId)])
|
||||
return account.viewTracker.aroundMessageHistoryViewForLocation(.peer(peerId: peerId), index: .lowerBound, anchorIndex: .lowerBound, count: 4, fixedCombinedReadStates: nil, tagMask: .unseenReaction, additionalData: [.peerChatState(peerId)])
|
||||
|> mapToSignal { view -> Signal<EarliestUnseenPersonalMentionMessageResult, NoError> in
|
||||
if view.0.isLoading {
|
||||
return .single(.loading)
|
||||
|
||||
@ -0,0 +1,538 @@
|
||||
import Foundation
|
||||
import Postbox
|
||||
import SwiftSignalKit
|
||||
import TelegramApi
|
||||
|
||||
private class FeedHistoryContextImpl {
|
||||
private let queue: Queue
|
||||
private let account: Account
|
||||
private let feedId: Int32
|
||||
private let userId: Int64
|
||||
|
||||
private var currentHole: (MessageHistoryHolesViewEntry, Disposable)?
|
||||
|
||||
struct State: Equatable {
|
||||
var messageIndices: [MessageIndex]
|
||||
var holeIndices: [MessageId.Namespace: IndexSet]
|
||||
}
|
||||
|
||||
let state = Promise<State>()
|
||||
private var stateValue: State? {
|
||||
didSet {
|
||||
if let stateValue = self.stateValue {
|
||||
if stateValue != oldValue {
|
||||
self.state.set(.single(stateValue))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let maxReadOutgoingMessageId = Promise<MessageId?>()
|
||||
private var maxReadOutgoingMessageIdValue: MessageId? {
|
||||
didSet {
|
||||
if self.maxReadOutgoingMessageIdValue != oldValue {
|
||||
self.maxReadOutgoingMessageId.set(.single(self.maxReadOutgoingMessageIdValue))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var maxReadIncomingMessageIdValue: MessageId?
|
||||
|
||||
let unreadCount = Promise<Int>()
|
||||
private var unreadCountValue: Int = 0 {
|
||||
didSet {
|
||||
if self.unreadCountValue != oldValue {
|
||||
self.unreadCount.set(.single(self.unreadCountValue))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var initialStateDisposable: Disposable?
|
||||
private var holesDisposable: Disposable?
|
||||
private var readStateDisposable: Disposable?
|
||||
private var updateInitialStateDisposable: Disposable?
|
||||
private let readDisposable = MetaDisposable()
|
||||
|
||||
init(queue: Queue, account: Account, feedId: Int32, userId: Int64) {
|
||||
self.queue = queue
|
||||
self.account = account
|
||||
self.feedId = feedId
|
||||
self.userId = userId
|
||||
|
||||
self.maxReadOutgoingMessageIdValue = nil
|
||||
self.maxReadOutgoingMessageId.set(.single(self.maxReadOutgoingMessageIdValue))
|
||||
|
||||
self.maxReadIncomingMessageIdValue = nil
|
||||
|
||||
self.unreadCountValue = 0
|
||||
self.unreadCount.set(.single(self.unreadCountValue))
|
||||
|
||||
self.initialStateDisposable = (account.postbox.transaction { transaction -> State in
|
||||
return State(messageIndices: [], holeIndices: [Namespaces.Message.Cloud: IndexSet(integersIn: 2 ... 2)])
|
||||
}
|
||||
|> deliverOn(self.queue)).start(next: { [weak self] state in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
strongSelf.stateValue = state
|
||||
strongSelf.state.set(.single(state))
|
||||
})
|
||||
|
||||
/*self.updateInitialStateDisposable = (account.network.request(Api.functions.feed.getFeed(flags: 0, filterId: self.feedId, offsetPosition: nil, addOffset: 0, limit: 100, maxPosition: nil, minPosition: nil, hash: 0))
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<Api.feed.FeedMessages?, NoError> in
|
||||
return .single(nil)
|
||||
}
|
||||
|> mapToSignal { result -> Signal<[MessageIndex], NoError> in
|
||||
return account.postbox.transaction { transaction -> [MessageIndex] in
|
||||
guard let result = result else {
|
||||
return []
|
||||
}
|
||||
|
||||
let messages: [Api.Message]
|
||||
let chats: [Api.Chat]
|
||||
let users: [Api.User]
|
||||
|
||||
switch result {
|
||||
case let .feedMessages(_, _, _, _, apiMessages, apiChats, apiUsers):
|
||||
messages = apiMessages
|
||||
chats = apiChats
|
||||
users = apiUsers
|
||||
case .feedMessagesNotModified:
|
||||
messages = []
|
||||
users = []
|
||||
chats = []
|
||||
}
|
||||
|
||||
var peers: [Peer] = []
|
||||
var peerPresences: [PeerId: PeerPresence] = [:]
|
||||
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)
|
||||
if let presence = TelegramUserPresence(apiUser: user) {
|
||||
peerPresences[telegramUser.id] = presence
|
||||
}
|
||||
}
|
||||
|
||||
var storeMessages: [StoreMessage] = []
|
||||
|
||||
for message in messages {
|
||||
if let storeMessage = StoreMessage(apiMessage: message, namespace: Namespaces.Message.Cloud) {
|
||||
storeMessages.append(storeMessage)
|
||||
}
|
||||
}
|
||||
|
||||
updatePeers(transaction: transaction, peers: peers, update: { _, updated -> Peer in
|
||||
return updated
|
||||
})
|
||||
updatePeerPresences(transaction: transaction, accountPeerId: account.peerId, peerPresences: peerPresences)
|
||||
|
||||
let _ = transaction.addMessages(storeMessages, location: .Random)
|
||||
|
||||
return storeMessages.compactMap({ message in
|
||||
return message.index
|
||||
}).sorted()
|
||||
}
|
||||
}
|
||||
|> deliverOn(self.queue)).start(next: { [weak self] indices in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
assert(indices.sorted() == indices)
|
||||
strongSelf.stateValue = State(messageIndices: indices, holeIndices: [:])
|
||||
})*/
|
||||
|
||||
let userId = self.userId
|
||||
self.holesDisposable = (account.postbox.messageHistoryHolesView()
|
||||
|> map { view -> MessageHistoryHolesViewEntry? in
|
||||
for entry in view.entries {
|
||||
if entry.userId == userId {
|
||||
return entry
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|> distinctUntilChanged
|
||||
|> deliverOn(self.queue)).start(next: { [weak self] entry in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
strongSelf.setCurrentHole(entry: entry)
|
||||
})
|
||||
|
||||
/*self.readStateDisposable = (account.stateManager.threadReadStateUpdates
|
||||
|> deliverOn(self.queue)).start(next: { [weak self] (_, outgoing) in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
if let value = outgoing[data.messageId] {
|
||||
strongSelf.maxReadOutgoingMessageIdValue = MessageId(peerId: data.messageId.peerId, namespace: Namespaces.Message.Cloud, id: value)
|
||||
}
|
||||
})
|
||||
|
||||
let updateInitialState: Signal<DiscussionMessage, FetchChannelReplyThreadMessageError> = account.postbox.transaction { transaction -> Api.InputPeer? in
|
||||
return transaction.getPeer(data.messageId.peerId).flatMap(apiInputPeer)
|
||||
}
|
||||
|> castError(FetchChannelReplyThreadMessageError.self)
|
||||
|> mapToSignal { inputPeer -> Signal<DiscussionMessage, FetchChannelReplyThreadMessageError> in
|
||||
guard let inputPeer = inputPeer else {
|
||||
return .fail(.generic)
|
||||
}
|
||||
|
||||
return account.network.request(Api.functions.messages.getDiscussionMessage(peer: inputPeer, msgId: data.messageId.id))
|
||||
|> mapError { _ -> FetchChannelReplyThreadMessageError in
|
||||
return .generic
|
||||
}
|
||||
|> mapToSignal { discussionMessage -> Signal<DiscussionMessage, FetchChannelReplyThreadMessageError> in
|
||||
return account.postbox.transaction { transaction -> Signal<DiscussionMessage, FetchChannelReplyThreadMessageError> in
|
||||
switch discussionMessage {
|
||||
case let .discussionMessage(_, messages, maxId, readInboxMaxId, readOutboxMaxId, unreadCount, chats, users):
|
||||
let parsedMessages = messages.compactMap { message -> StoreMessage? in
|
||||
StoreMessage(apiMessage: message)
|
||||
}
|
||||
|
||||
guard let topMessage = parsedMessages.last, let parsedIndex = topMessage.index else {
|
||||
return .fail(.generic)
|
||||
}
|
||||
|
||||
var channelMessageId: MessageId?
|
||||
var replyThreadAttribute: ReplyThreadMessageAttribute?
|
||||
for attribute in topMessage.attributes {
|
||||
if let attribute = attribute as? SourceReferenceMessageAttribute {
|
||||
channelMessageId = attribute.messageId
|
||||
} else if let attribute = attribute as? ReplyThreadMessageAttribute {
|
||||
replyThreadAttribute = attribute
|
||||
}
|
||||
}
|
||||
|
||||
var peers: [Peer] = []
|
||||
var peerPresences: [PeerId: PeerPresence] = [:]
|
||||
|
||||
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)
|
||||
if let presence = TelegramUserPresence(apiUser: user) {
|
||||
peerPresences[telegramUser.id] = presence
|
||||
}
|
||||
}
|
||||
|
||||
let _ = transaction.addMessages(parsedMessages, location: .Random)
|
||||
|
||||
updatePeers(transaction: transaction, peers: peers, update: { _, updated -> Peer in
|
||||
return updated
|
||||
})
|
||||
|
||||
updatePeerPresences(transaction: transaction, accountPeerId: account.peerId, peerPresences: peerPresences)
|
||||
|
||||
let resolvedMaxMessage: MessageId?
|
||||
if let maxId = maxId {
|
||||
resolvedMaxMessage = MessageId(
|
||||
peerId: parsedIndex.id.peerId,
|
||||
namespace: Namespaces.Message.Cloud,
|
||||
id: maxId
|
||||
)
|
||||
} else {
|
||||
resolvedMaxMessage = nil
|
||||
}
|
||||
|
||||
var isChannelPost = false
|
||||
for attribute in topMessage.attributes {
|
||||
if let _ = attribute as? SourceReferenceMessageAttribute {
|
||||
isChannelPost = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
let maxReadIncomingMessageId = readInboxMaxId.flatMap { readMaxId in
|
||||
MessageId(peerId: parsedIndex.id.peerId, namespace: Namespaces.Message.Cloud, id: readMaxId)
|
||||
}
|
||||
|
||||
if let channelMessageId = channelMessageId, let replyThreadAttribute = replyThreadAttribute {
|
||||
account.viewTracker.updateReplyInfoForMessageId(channelMessageId, info: AccountViewTracker.UpdatedMessageReplyInfo(
|
||||
timestamp: Int32(CFAbsoluteTimeGetCurrent()),
|
||||
commentsPeerId: parsedIndex.id.peerId,
|
||||
maxReadIncomingMessageId: maxReadIncomingMessageId,
|
||||
maxMessageId: resolvedMaxMessage
|
||||
))
|
||||
|
||||
transaction.updateMessage(channelMessageId, update: { currentMessage in
|
||||
var attributes = currentMessage.attributes
|
||||
loop: for j in 0 ..< attributes.count {
|
||||
if let attribute = attributes[j] as? ReplyThreadMessageAttribute {
|
||||
attributes[j] = ReplyThreadMessageAttribute(
|
||||
count: replyThreadAttribute.count,
|
||||
latestUsers: attribute.latestUsers,
|
||||
commentsPeerId: attribute.commentsPeerId,
|
||||
maxMessageId: replyThreadAttribute.maxMessageId,
|
||||
maxReadMessageId: replyThreadAttribute.maxReadMessageId
|
||||
)
|
||||
}
|
||||
}
|
||||
return .update(StoreMessage(id: currentMessage.id, globallyUniqueId: currentMessage.globallyUniqueId, groupingKey: currentMessage.groupingKey, threadId: currentMessage.threadId, timestamp: currentMessage.timestamp, flags: StoreMessageFlags(currentMessage.flags), tags: currentMessage.tags, globalTags: currentMessage.globalTags, localTags: currentMessage.localTags, forwardInfo: currentMessage.forwardInfo.flatMap(StoreMessageForwardInfo.init), authorId: currentMessage.author?.id, text: currentMessage.text, attributes: attributes, media: currentMessage.media))
|
||||
})
|
||||
}
|
||||
|
||||
return .single(DiscussionMessage(
|
||||
messageId: parsedIndex.id,
|
||||
channelMessageId: channelMessageId,
|
||||
isChannelPost: isChannelPost,
|
||||
maxMessage: resolvedMaxMessage,
|
||||
maxReadIncomingMessageId: maxReadIncomingMessageId,
|
||||
maxReadOutgoingMessageId: readOutboxMaxId.flatMap { readMaxId in
|
||||
MessageId(peerId: parsedIndex.id.peerId, namespace: Namespaces.Message.Cloud, id: readMaxId)
|
||||
},
|
||||
unreadCount: Int(unreadCount)
|
||||
))
|
||||
}
|
||||
}
|
||||
|> castError(FetchChannelReplyThreadMessageError.self)
|
||||
|> switchToLatest
|
||||
}
|
||||
}
|
||||
|
||||
self.updateInitialStateDisposable = (updateInitialState
|
||||
|> deliverOnMainQueue).start(next: { [weak self] updatedData in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
if let maxReadOutgoingMessageId = updatedData.maxReadOutgoingMessageId {
|
||||
if let current = strongSelf.maxReadOutgoingMessageIdValue {
|
||||
if maxReadOutgoingMessageId > current {
|
||||
strongSelf.maxReadOutgoingMessageIdValue = maxReadOutgoingMessageId
|
||||
}
|
||||
} else {
|
||||
strongSelf.maxReadOutgoingMessageIdValue = maxReadOutgoingMessageId
|
||||
}
|
||||
}
|
||||
})*/
|
||||
}
|
||||
|
||||
deinit {
|
||||
self.initialStateDisposable?.dispose()
|
||||
self.holesDisposable?.dispose()
|
||||
self.readDisposable.dispose()
|
||||
self.updateInitialStateDisposable?.dispose()
|
||||
}
|
||||
|
||||
func setCurrentHole(entry: MessageHistoryHolesViewEntry?) {
|
||||
if self.currentHole?.0 != entry {
|
||||
self.currentHole?.1.dispose()
|
||||
if let entry = entry {
|
||||
self.currentHole = (entry, self.fetchHole(entry: entry).start(next: { [weak self] updatedState in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
strongSelf.currentHole = nil
|
||||
strongSelf.stateValue = updatedState
|
||||
}))
|
||||
} else {
|
||||
self.currentHole = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func fetchHole(entry: MessageHistoryHolesViewEntry) -> Signal<State, NoError> {
|
||||
//feed.getFeed flags:# filter_id:int offset_to_max_read:flags.3?true offset_position:flags.0?FeedPosition add_offset:int limit:int max_position:flags.1?FeedPosition min_position:flags.2?FeedPosition hash:long = messages.FeedMessages;
|
||||
|
||||
let offsetPosition: Api.FeedPosition?
|
||||
let addOffset: Int32 = 0
|
||||
|
||||
switch entry.direction {
|
||||
case let .range(start, end):
|
||||
if min(start.id, end.id) == 1 && max(start.id, end.id) == Int32.max - 1 {
|
||||
offsetPosition = nil
|
||||
} else {
|
||||
return .never()
|
||||
}
|
||||
case let .aroundId(id):
|
||||
let _ = id
|
||||
return .never()
|
||||
}
|
||||
|
||||
var flags: Int32 = 0
|
||||
if let _ = offsetPosition {
|
||||
flags |= 1 << 0
|
||||
}
|
||||
|
||||
let account = self.account
|
||||
let state = self.stateValue
|
||||
return self.account.network.request(Api.functions.feed.getFeed(
|
||||
flags: flags,
|
||||
filterId: self.feedId,
|
||||
offsetPosition: offsetPosition,
|
||||
addOffset: addOffset,
|
||||
limit: 100,
|
||||
maxPosition: nil,
|
||||
minPosition: nil,
|
||||
hash: 0
|
||||
))
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<Api.feed.FeedMessages?, NoError> in
|
||||
return .single(nil)
|
||||
}
|
||||
|> mapToSignal { result -> Signal<State, NoError> in
|
||||
return account.postbox.transaction { transaction -> State in
|
||||
guard let result = result else {
|
||||
var updatedState = state ?? State(messageIndices: [], holeIndices: [:])
|
||||
updatedState.holeIndices = [:]
|
||||
return updatedState
|
||||
}
|
||||
|
||||
let messages: [Api.Message]
|
||||
let chats: [Api.Chat]
|
||||
let users: [Api.User]
|
||||
|
||||
switch result {
|
||||
case let .feedMessages(_, _, _, _, apiMessages, apiChats, apiUsers):
|
||||
messages = apiMessages
|
||||
chats = apiChats
|
||||
users = apiUsers
|
||||
case .feedMessagesNotModified:
|
||||
messages = []
|
||||
users = []
|
||||
chats = []
|
||||
}
|
||||
|
||||
var peers: [Peer] = []
|
||||
var peerPresences: [PeerId: PeerPresence] = [:]
|
||||
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)
|
||||
if let presence = TelegramUserPresence(apiUser: user) {
|
||||
peerPresences[telegramUser.id] = presence
|
||||
}
|
||||
}
|
||||
|
||||
var storeMessages: [StoreMessage] = []
|
||||
|
||||
for message in messages {
|
||||
if let storeMessage = StoreMessage(apiMessage: message, namespace: Namespaces.Message.Cloud) {
|
||||
storeMessages.append(storeMessage)
|
||||
}
|
||||
}
|
||||
|
||||
updatePeers(transaction: transaction, peers: peers, update: { _, updated -> Peer in
|
||||
return updated
|
||||
})
|
||||
updatePeerPresences(transaction: transaction, accountPeerId: account.peerId, peerPresences: peerPresences)
|
||||
|
||||
let _ = transaction.addMessages(storeMessages, location: .Random)
|
||||
|
||||
var updatedState = state ?? State(messageIndices: [], holeIndices: [:])
|
||||
var currentSet = Set<MessageIndex>(updatedState.messageIndices)
|
||||
|
||||
for index in storeMessages.compactMap(\.index) {
|
||||
if !currentSet.contains(index) {
|
||||
currentSet.insert(index)
|
||||
}
|
||||
updatedState.messageIndices.append(index)
|
||||
}
|
||||
|
||||
updatedState.messageIndices.sort()
|
||||
|
||||
updatedState.holeIndices = [:]
|
||||
return updatedState
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func applyMaxReadIndex(messageIndex: MessageIndex) {
|
||||
}
|
||||
}
|
||||
|
||||
public class FeedHistoryContext {
|
||||
fileprivate final class GuardReference {
|
||||
private let deallocated: () -> Void
|
||||
|
||||
init(deallocated: @escaping () -> Void) {
|
||||
self.deallocated = deallocated
|
||||
}
|
||||
|
||||
deinit {
|
||||
self.deallocated()
|
||||
}
|
||||
}
|
||||
|
||||
private let queue = Queue()
|
||||
private let impl: QueueLocalObject<FeedHistoryContextImpl>
|
||||
|
||||
private let userId: Int64 = Int64.random(in: 0 ..< Int64.max)
|
||||
|
||||
public var state: Signal<MessageHistoryViewExternalInput, NoError> {
|
||||
let userId = self.userId
|
||||
|
||||
return Signal { subscriber in
|
||||
let disposable = MetaDisposable()
|
||||
|
||||
self.impl.with { impl in
|
||||
let stateDisposable = impl.state.get().start(next: { state in
|
||||
subscriber.putNext(MessageHistoryViewExternalInput(
|
||||
content: .messages(indices: state.messageIndices, holes: state.holeIndices, userId: userId),
|
||||
maxReadIncomingMessageId: nil,
|
||||
maxReadOutgoingMessageId: nil
|
||||
))
|
||||
})
|
||||
disposable.set(stateDisposable)
|
||||
}
|
||||
|
||||
return disposable
|
||||
}
|
||||
}
|
||||
|
||||
public var maxReadOutgoingMessageId: Signal<MessageId?, NoError> {
|
||||
return Signal { subscriber in
|
||||
let disposable = MetaDisposable()
|
||||
|
||||
self.impl.with { impl in
|
||||
disposable.set(impl.maxReadOutgoingMessageId.get().start(next: { value in
|
||||
subscriber.putNext(value)
|
||||
}))
|
||||
}
|
||||
|
||||
return disposable
|
||||
}
|
||||
}
|
||||
|
||||
public var unreadCount: Signal<Int, NoError> {
|
||||
return Signal { subscriber in
|
||||
let disposable = MetaDisposable()
|
||||
|
||||
self.impl.with { impl in
|
||||
disposable.set(impl.unreadCount.get().start(next: { value in
|
||||
subscriber.putNext(value)
|
||||
}))
|
||||
}
|
||||
|
||||
return disposable
|
||||
}
|
||||
}
|
||||
|
||||
public init(account: Account, feedId: Int32) {
|
||||
let queue = self.queue
|
||||
let userId = self.userId
|
||||
self.impl = QueueLocalObject(queue: queue, generate: {
|
||||
return FeedHistoryContextImpl(queue: queue, account: account, feedId: feedId, userId: userId)
|
||||
})
|
||||
}
|
||||
|
||||
public func applyMaxReadIndex(messageIndex: MessageIndex) {
|
||||
self.impl.with { impl in
|
||||
impl.applyMaxReadIndex(messageIndex: messageIndex)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4,7 +4,7 @@ import SwiftSignalKit
|
||||
import TelegramApi
|
||||
|
||||
func _internal_topPeerActiveLiveLocationMessages(viewTracker: AccountViewTracker, accountPeerId: PeerId, peerId: PeerId) -> Signal<(Peer?, [Message]), NoError> {
|
||||
return viewTracker.aroundMessageHistoryViewForLocation(.peer(peerId), index: .upperBound, anchorIndex: .upperBound, count: 50, fixedCombinedReadStates: nil, tagMask: .liveLocation, orderStatistics: [], additionalData: [.peer(accountPeerId)])
|
||||
return viewTracker.aroundMessageHistoryViewForLocation(.peer(peerId: peerId), index: .upperBound, anchorIndex: .upperBound, count: 50, fixedCombinedReadStates: nil, tagMask: .liveLocation, orderStatistics: [], additionalData: [.peer(accountPeerId)])
|
||||
|> map { (view, _, _) -> (Peer?, [Message]) in
|
||||
var accountPeer: Peer?
|
||||
for entry in view.additionalData {
|
||||
|
||||
@ -477,11 +477,9 @@ public class ReplyThreadHistoryContext {
|
||||
self.impl.with { impl in
|
||||
let stateDisposable = impl.state.get().start(next: { state in
|
||||
subscriber.putNext(MessageHistoryViewExternalInput(
|
||||
peerId: state.messageId.peerId,
|
||||
threadId: makeMessageThreadId(state.messageId),
|
||||
content: .thread(peerId: state.messageId.peerId, id: makeMessageThreadId(state.messageId), holes: state.holeIndices),
|
||||
maxReadIncomingMessageId: state.maxReadIncomingMessageId,
|
||||
maxReadOutgoingMessageId: state.maxReadOutgoingMessageId,
|
||||
holes: state.holeIndices
|
||||
maxReadOutgoingMessageId: state.maxReadOutgoingMessageId
|
||||
))
|
||||
})
|
||||
disposable.set(stateDisposable)
|
||||
@ -804,13 +802,15 @@ func _internal_fetchChannelReplyThreadMessage(account: Account, messageId: Messa
|
||||
|
||||
let testView = transaction.getMessagesHistoryViewState(
|
||||
input: .external(MessageHistoryViewExternalInput(
|
||||
peerId: commentsPeerId,
|
||||
threadId: makeMessageThreadId(threadMessageId),
|
||||
content: .thread(
|
||||
peerId: commentsPeerId,
|
||||
id: makeMessageThreadId(threadMessageId),
|
||||
holes: [
|
||||
Namespaces.Message.Cloud: holes
|
||||
]
|
||||
),
|
||||
maxReadIncomingMessageId: nil,
|
||||
maxReadOutgoingMessageId: nil,
|
||||
holes: [
|
||||
Namespaces.Message.Cloud: holes
|
||||
]
|
||||
maxReadOutgoingMessageId: nil
|
||||
)),
|
||||
ignoreMessagesInTimestampRange: nil,
|
||||
count: 40,
|
||||
|
||||
@ -188,7 +188,7 @@ public final class SparseMessageList {
|
||||
#else*/
|
||||
count = 200
|
||||
//#endif
|
||||
self.topItemsDisposable.set((self.account.postbox.aroundMessageHistoryViewForLocation(.peer(peerId), anchor: .upperBound, ignoreMessagesInTimestampRange: nil, count: count, fixedCombinedReadStates: nil, topTaggedMessageIdNamespaces: Set(), tagMask: self.messageTag, appendMessagesFromTheSameGroup: false, namespaces: .not(Set(Namespaces.Message.allScheduled)), orderStatistics: [])
|
||||
self.topItemsDisposable.set((self.account.postbox.aroundMessageHistoryViewForLocation(.peer(peerId: peerId), anchor: .upperBound, ignoreMessagesInTimestampRange: nil, count: count, fixedCombinedReadStates: nil, topTaggedMessageIdNamespaces: Set(), tagMask: self.messageTag, appendMessagesFromTheSameGroup: false, namespaces: .not(Set(Namespaces.Message.allScheduled)), orderStatistics: [])
|
||||
|> deliverOn(self.queue)).start(next: { [weak self] view, updateType, _ in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
|
||||
@ -216,7 +216,7 @@ func _internal_fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPee
|
||||
}
|
||||
|
||||
switch fullUser {
|
||||
case let .userFull(_, _, _, _, _, userFullNotifySettings, _, _, _, _, _, _, _):
|
||||
case let .userFull(_, _, _, _, _, userFullNotifySettings, _, _, _, _, _, _, _, _, _):
|
||||
updatePeers(transaction: transaction, peers: peers, update: { previous, updated -> Peer in
|
||||
if previous?.id == accountPeerId, let accountUser = accountUser, let user = TelegramUser.merge(previous as? TelegramUser, rhs: accountUser) {
|
||||
return user
|
||||
@ -234,7 +234,7 @@ func _internal_fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPee
|
||||
previous = CachedUserData()
|
||||
}
|
||||
switch fullUser {
|
||||
case let .userFull(userFullFlags, _, userFullAbout, userFullSettings, _, _, userFullBotInfo, userFullPinnedMsgId, userFullCommonChatsCount, _, userFullTtlPeriod, userFullThemeEmoticon, _):
|
||||
case let .userFull(userFullFlags, _, userFullAbout, userFullSettings, _, _, userFullBotInfo, userFullPinnedMsgId, userFullCommonChatsCount, _, userFullTtlPeriod, userFullThemeEmoticon, _, _, _):
|
||||
let botInfo = userFullBotInfo.flatMap(BotInfo.init(apiBotInfo:))
|
||||
let isBlocked = (userFullFlags & (1 << 0)) != 0
|
||||
let voiceCallsAvailable = (userFullFlags & (1 << 4)) != 0
|
||||
|
||||
@ -278,10 +278,13 @@ public final class AccountContextImpl: AccountContext {
|
||||
public func chatLocationInput(for location: ChatLocation, contextHolder: Atomic<ChatLocationContextHolder?>) -> ChatLocationInput {
|
||||
switch location {
|
||||
case let .peer(peerId):
|
||||
return .peer(peerId)
|
||||
return .peer(peerId: peerId)
|
||||
case let .replyThread(data):
|
||||
let context = chatLocationContext(holder: contextHolder, account: self.account, data: data)
|
||||
return .external(data.messageId.peerId, makeMessageThreadId(data.messageId), context.state)
|
||||
return .thread(peerId: data.messageId.peerId, threadId: makeMessageThreadId(data.messageId), data: context.state)
|
||||
case let .feed(id):
|
||||
let context = chatLocationContext(holder: contextHolder, account: self.account, feedId: id)
|
||||
return .feed(id: id, data: context.state)
|
||||
}
|
||||
}
|
||||
|
||||
@ -292,6 +295,9 @@ public final class AccountContextImpl: AccountContext {
|
||||
case let .replyThread(data):
|
||||
let context = chatLocationContext(holder: contextHolder, account: self.account, data: data)
|
||||
return context.maxReadOutgoingMessageId
|
||||
case let .feed(id):
|
||||
let context = chatLocationContext(holder: contextHolder, account: self.account, feedId: id)
|
||||
return context.maxReadOutgoingMessageId
|
||||
}
|
||||
}
|
||||
|
||||
@ -314,6 +320,9 @@ public final class AccountContextImpl: AccountContext {
|
||||
case let .replyThread(data):
|
||||
let context = chatLocationContext(holder: contextHolder, account: self.account, data: data)
|
||||
return context.unreadCount
|
||||
case let .feed(id):
|
||||
let context = chatLocationContext(holder: contextHolder, account: self.account, feedId: id)
|
||||
return context.unreadCount
|
||||
}
|
||||
}
|
||||
|
||||
@ -324,6 +333,9 @@ public final class AccountContextImpl: AccountContext {
|
||||
case let .replyThread(data):
|
||||
let context = chatLocationContext(holder: contextHolder, account: self.account, data: data)
|
||||
context.applyMaxReadIndex(messageIndex: messageIndex)
|
||||
case let .feed(id):
|
||||
let context = chatLocationContext(holder: contextHolder, account: self.account, feedId: id)
|
||||
context.applyMaxReadIndex(messageIndex: messageIndex)
|
||||
}
|
||||
}
|
||||
|
||||
@ -448,16 +460,27 @@ public final class AccountContextImpl: AccountContext {
|
||||
|
||||
private func chatLocationContext(holder: Atomic<ChatLocationContextHolder?>, account: Account, data: ChatReplyThreadMessage) -> ReplyThreadHistoryContext {
|
||||
let holder = holder.modify { current in
|
||||
if let current = current as? ChatLocationContextHolderImpl {
|
||||
if let current = current as? ChatLocationReplyContextHolderImpl {
|
||||
return current
|
||||
} else {
|
||||
return ChatLocationContextHolderImpl(account: account, data: data)
|
||||
return ChatLocationReplyContextHolderImpl(account: account, data: data)
|
||||
}
|
||||
} as! ChatLocationContextHolderImpl
|
||||
} as! ChatLocationReplyContextHolderImpl
|
||||
return holder.context
|
||||
}
|
||||
|
||||
private final class ChatLocationContextHolderImpl: ChatLocationContextHolder {
|
||||
private func chatLocationContext(holder: Atomic<ChatLocationContextHolder?>, account: Account, feedId: Int32) -> FeedHistoryContext {
|
||||
let holder = holder.modify { current in
|
||||
if let current = current as? ChatLocationFeedContextHolderImpl {
|
||||
return current
|
||||
} else {
|
||||
return ChatLocationFeedContextHolderImpl(account: account, feedId: feedId)
|
||||
}
|
||||
} as! ChatLocationFeedContextHolderImpl
|
||||
return holder.context
|
||||
}
|
||||
|
||||
private final class ChatLocationReplyContextHolderImpl: ChatLocationContextHolder {
|
||||
let context: ReplyThreadHistoryContext
|
||||
|
||||
init(account: Account, data: ChatReplyThreadMessage) {
|
||||
@ -465,6 +488,14 @@ private final class ChatLocationContextHolderImpl: ChatLocationContextHolder {
|
||||
}
|
||||
}
|
||||
|
||||
private final class ChatLocationFeedContextHolderImpl: ChatLocationContextHolder {
|
||||
let context: FeedHistoryContext
|
||||
|
||||
init(account: Account, feedId: Int32) {
|
||||
self.context = FeedHistoryContext(account: account, feedId: feedId)
|
||||
}
|
||||
}
|
||||
|
||||
func getAppConfiguration(transaction: Transaction) -> AppConfiguration {
|
||||
let appConfiguration: AppConfiguration = transaction.getPreferencesEntry(key: PreferencesKeys.appConfiguration)?.get(AppConfiguration.self) ?? AppConfiguration.defaultValue
|
||||
return appConfiguration
|
||||
|
||||
@ -414,16 +414,14 @@ final class AuthorizedApplicationContext {
|
||||
}
|
||||
|
||||
if !processed {
|
||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: strongSelf.rootController, context: strongSelf.context, chatLocation: .peer(firstMessage.id.peerId)))
|
||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: strongSelf.rootController, context: strongSelf.context, chatLocation: .peer(id: firstMessage.id.peerId)))
|
||||
}
|
||||
}
|
||||
return false
|
||||
}, expandAction: { expandData in
|
||||
if let strongSelf = self {
|
||||
let chatController = ChatControllerImpl(context: strongSelf.context, chatLocation: .peer(firstMessage.id.peerId), mode: .overlay(strongSelf.rootController))
|
||||
//chatController.navigation_setNavigationController(strongSelf.rootController)
|
||||
let chatController = ChatControllerImpl(context: strongSelf.context, chatLocation: .peer(id: firstMessage.id.peerId), mode: .overlay(strongSelf.rootController))
|
||||
chatController.presentationArguments = ChatControllerOverlayPresentationData(expandData: expandData())
|
||||
//strongSelf.rootController.pushViewController(chatController)
|
||||
(strongSelf.rootController.viewControllers.last as? ViewController)?.present(chatController, in: .window(.root), with: ChatControllerOverlayPresentationData(expandData: expandData()))
|
||||
}
|
||||
}))
|
||||
@ -466,7 +464,7 @@ final class AuthorizedApplicationContext {
|
||||
if let strongSelf = self, let botName = botName {
|
||||
strongSelf.termsOfServiceProceedToBotDisposable.set((strongSelf.context.engine.peers.resolvePeerByName(name: botName, ageLimit: 10) |> take(1) |> deliverOnMainQueue).start(next: { peer in
|
||||
if let strongSelf = self, let peer = peer {
|
||||
self?.rootController.pushViewController(ChatControllerImpl(context: strongSelf.context, chatLocation: .peer(peer.id)))
|
||||
self?.rootController.pushViewController(ChatControllerImpl(context: strongSelf.context, chatLocation: .peer(id: peer.id)))
|
||||
}
|
||||
}))
|
||||
}
|
||||
@ -758,7 +756,7 @@ final class AuthorizedApplicationContext {
|
||||
}
|
||||
|
||||
let navigateToMessage = {
|
||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: strongSelf.rootController, context: strongSelf.context, chatLocation: .peer(messageId.peerId), subject: .message(id: .id(messageId), highlight: true, timecode: nil)))
|
||||
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)))
|
||||
}
|
||||
|
||||
if chatIsVisible {
|
||||
@ -837,7 +835,7 @@ final class AuthorizedApplicationContext {
|
||||
|
||||
if visiblePeerId != peerId || messageId != nil {
|
||||
if self.rootController.rootTabController != nil {
|
||||
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: self.rootController, context: self.context, chatLocation: .peer(peerId), subject: messageId.flatMap { .message(id: .id($0), highlight: true, timecode: nil) }, activateInput: activateInput))
|
||||
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: self.rootController, context: self.context, chatLocation: .peer(id: peerId), subject: messageId.flatMap { .message(id: .id($0), highlight: true, timecode: nil) }, activateInput: activateInput))
|
||||
} else {
|
||||
self.scheduledOpenChatWithPeerId = (peerId, messageId, activateInput)
|
||||
}
|
||||
|
||||
@ -131,7 +131,7 @@ private enum AttachmentFileEntry: ItemListNodeEntry {
|
||||
let dateTimeFormat = arguments.context.sharedContext.currentPresentationData.with({$0}).dateTimeFormat
|
||||
let chatPresentationData = ChatPresentationData(theme: ChatPresentationThemeData(theme: presentationData.theme, wallpaper: .color(0)), fontSize: presentationData.fontSize, strings: presentationData.strings, dateTimeFormat: dateTimeFormat, nameDisplayOrder: .firstLast, disableAnimations: false, largeEmoji: false, chatBubbleCorners: PresentationChatBubbleCorners(mainRadius: 0, auxiliaryRadius: 0, mergeBubbleCorners: false))
|
||||
|
||||
return ListMessageItem(presentationData: chatPresentationData, context: arguments.context, chatLocation: .peer(PeerId(0)), interaction: interaction, message: message, selection: .none, displayHeader: false, displayFileInfo: false, displayBackground: true, style: .blocks)
|
||||
return ListMessageItem(presentationData: chatPresentationData, context: arguments.context, chatLocation: .peer(id: PeerId(0)), interaction: interaction, message: message, selection: .none, displayHeader: false, displayFileInfo: false, displayBackground: true, style: .blocks)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -269,7 +269,7 @@ private final class AttachmentFileSearchEntry: Comparable, Identifiable {
|
||||
interaction.send(message)
|
||||
return false
|
||||
}, openMessageContextMenu: { _, _, _, _, _ in }, toggleMessagesSelection: { _, _ in }, openUrl: { _, _, _, _ in }, openInstantPage: { _, _ in }, longTap: { _, _ in }, getHiddenMedia: { return [:] })
|
||||
return ListMessageItem(presentationData: ChatPresentationData(presentationData: interaction.context.sharedContext.currentPresentationData.with({$0})), context: interaction.context, chatLocation: .peer(PeerId(0)), interaction: itemInteraction, message: message, selection: .none, displayHeader: true, displayFileInfo: false, displayBackground: true, style: .plain)
|
||||
return ListMessageItem(presentationData: ChatPresentationData(presentationData: interaction.context.sharedContext.currentPresentationData.with({$0})), context: interaction.context, chatLocation: .peer(id: PeerId(0)), interaction: itemInteraction, message: message, selection: .none, displayHeader: true, displayFileInfo: false, displayBackground: true, style: .plain)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -2414,7 +2414,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
let effectiveInputText = effectivePresentationInterfaceState.interfaceState.composeInputState.inputText
|
||||
let trimmedInputText = effectiveInputText.string.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
let peerId = effectivePresentationInterfaceState.chatLocation.peerId
|
||||
if peerId.namespace != Namespaces.Peer.SecretChat, let interactiveEmojis = self.interactiveEmojis, interactiveEmojis.emojis.contains(trimmedInputText) {
|
||||
if peerId?.namespace != Namespaces.Peer.SecretChat, let interactiveEmojis = self.interactiveEmojis, interactiveEmojis.emojis.contains(trimmedInputText) {
|
||||
messages.append(.message(text: "", attributes: [], mediaReference: AnyMediaReference.standalone(media: TelegramMediaDice(emoji: trimmedInputText)), replyToMessageId: self.chatPresentationInterfaceState.interfaceState.replyMessageId, localGroupingKey: nil, correlationId: nil))
|
||||
} else {
|
||||
let inputText = convertMarkdownToAttributes(effectiveInputText)
|
||||
|
||||
@ -42,7 +42,7 @@ private final class ChatEmptyNodeRegularChatContent: ASDisplayNode, ChatEmptyNod
|
||||
|
||||
let text: String
|
||||
switch interfaceState.chatLocation {
|
||||
case .peer, .replyThread:
|
||||
case .peer, .replyThread, .feed:
|
||||
if case .scheduledMessages = interfaceState.subject {
|
||||
text = interfaceState.strings.ScheduledMessages_EmptyPlaceholder
|
||||
} else {
|
||||
|
||||
@ -928,7 +928,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
|
||||
let customChannelDiscussionReadState: Signal<MessageId?, NoError>
|
||||
if case let .peer(peerId) = chatLocation, peerId.namespace == Namespaces.Peer.CloudChannel {
|
||||
let cachedDataKey = PostboxViewKey.cachedPeerData(peerId: chatLocation.peerId)
|
||||
let cachedDataKey = PostboxViewKey.cachedPeerData(peerId: peerId)
|
||||
let peerKey = PostboxViewKey.basicPeer(peerId)
|
||||
customChannelDiscussionReadState = context.account.postbox.combinedView(keys: [cachedDataKey, peerKey])
|
||||
|> mapToSignal { views -> Signal<PeerId?, NoError> in
|
||||
@ -1062,7 +1062,12 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
case let .id(id):
|
||||
initialSearchLocation = .id(id)
|
||||
case let .timestamp(timestamp):
|
||||
initialSearchLocation = .index(MessageIndex(id: MessageId(peerId: strongSelf.chatLocation.peerId, namespace: Namespaces.Message.Cloud, id: 1), timestamp: timestamp))
|
||||
if let peerId = strongSelf.chatLocation.peerId {
|
||||
initialSearchLocation = .index(MessageIndex(id: MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: 1), timestamp: timestamp))
|
||||
} else {
|
||||
//TODO:implement
|
||||
initialSearchLocation = .index(.absoluteUpperBound())
|
||||
}
|
||||
}
|
||||
strongSelf.chatHistoryLocationValue = ChatHistoryLocationInput(content: .InitialSearch(location: initialSearchLocation, count: 60, highlight: highlight), id: (strongSelf.chatHistoryLocationValue?.id).flatMap({ $0 + 1 }) ?? 0)
|
||||
} else if let subject = subject, case let .pinnedMessages(maybeMessageId) = subject, let messageId = maybeMessageId {
|
||||
@ -1307,7 +1312,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
}
|
||||
if apply {
|
||||
switch chatLocation {
|
||||
case .peer, .replyThread:
|
||||
case .peer, .replyThread, .feed:
|
||||
if !context.sharedContext.immediateExperimentalUISettings.skipReadHistory {
|
||||
context.applyMaxReadIndex(for: chatLocation, contextHolder: chatLocationContextHolder, messageIndex: messageIndex)
|
||||
}
|
||||
@ -1348,7 +1353,12 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
case let .id(id):
|
||||
initialSearchLocation = .id(id)
|
||||
case let .timestamp(timestamp):
|
||||
initialSearchLocation = .index(MessageIndex(id: MessageId(peerId: self.chatLocation.peerId, namespace: Namespaces.Message.Cloud, id: 1), timestamp: timestamp))
|
||||
if let peerId = self.chatLocation.peerId {
|
||||
initialSearchLocation = .index(MessageIndex(id: MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: 1), timestamp: timestamp))
|
||||
} else {
|
||||
//TODO:implement
|
||||
initialSearchLocation = .index(MessageIndex.absoluteUpperBound())
|
||||
}
|
||||
}
|
||||
self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .InitialSearch(location: initialSearchLocation, count: 60, highlight: highlight), id: 0)
|
||||
} else if let subject = subject, case let .pinnedMessages(maybeMessageId) = subject, let messageId = maybeMessageId {
|
||||
@ -2108,7 +2118,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
switch self.chatLocation {
|
||||
case .peer:
|
||||
messageIndex = maxIncomingIndex
|
||||
case .replyThread:
|
||||
case .replyThread, .feed:
|
||||
messageIndex = maxOverallIndex
|
||||
}
|
||||
|
||||
@ -2520,7 +2530,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
switch strongSelf.chatLocation {
|
||||
case .peer:
|
||||
messageIndex = incomingIndex
|
||||
case .replyThread:
|
||||
case .replyThread, .feed:
|
||||
messageIndex = overallIndex
|
||||
}
|
||||
|
||||
|
||||
@ -69,7 +69,7 @@ private enum ChatHistorySearchEntry: Comparable, Identifiable {
|
||||
func item(context: AccountContext, peerId: PeerId, interaction: ChatControllerInteraction) -> ListViewItem {
|
||||
switch self {
|
||||
case let .message(message, theme, strings, dateTimeFormat, fontSize):
|
||||
return ListMessageItem(presentationData: ChatPresentationData(theme: ChatPresentationThemeData(theme: theme, wallpaper: .builtin(WallpaperSettings())), fontSize: fontSize, strings: strings, dateTimeFormat: dateTimeFormat, nameDisplayOrder: .firstLast, disableAnimations: false, largeEmoji: false, chatBubbleCorners: PresentationChatBubbleCorners(mainRadius: 0.0, auxiliaryRadius: 0.0, mergeBubbleCorners: false)), context: context, chatLocation: .peer(peerId), interaction: ListMessageItemInteraction(controllerInteraction: interaction), message: message, selection: .none, displayHeader: true)
|
||||
return ListMessageItem(presentationData: ChatPresentationData(theme: ChatPresentationThemeData(theme: theme, wallpaper: .builtin(WallpaperSettings())), fontSize: fontSize, strings: strings, dateTimeFormat: dateTimeFormat, nameDisplayOrder: .firstLast, disableAnimations: false, largeEmoji: false, chatBubbleCorners: PresentationChatBubbleCorners(mainRadius: 0.0, auxiliaryRadius: 0.0, mergeBubbleCorners: false)), context: context, chatLocation: .peer(id: peerId), interaction: ListMessageItemInteraction(controllerInteraction: interaction), message: message, selection: .none, displayHeader: true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -305,15 +305,15 @@ private func extractAdditionalData(view: MessageHistoryView, chatLocation: ChatL
|
||||
cachedDataMessages[message.id] = message
|
||||
}
|
||||
case let .totalUnreadState(totalUnreadState):
|
||||
switch chatLocation {
|
||||
case let .peer(peerId):
|
||||
if let combinedReadStates = view.fixedReadStates {
|
||||
if case let .peer(readStates) = combinedReadStates, let readState = readStates[peerId] {
|
||||
readStateData[peerId] = ChatHistoryCombinedInitialReadStateData(unreadCount: readState.count, totalState: totalUnreadState, notificationSettings: notificationSettings)
|
||||
}
|
||||
}
|
||||
case .replyThread:
|
||||
break
|
||||
switch chatLocation {
|
||||
case let .peer(peerId):
|
||||
if let combinedReadStates = view.fixedReadStates {
|
||||
if case let .peer(readStates) = combinedReadStates, let readState = readStates[peerId] {
|
||||
readStateData[peerId] = ChatHistoryCombinedInitialReadStateData(unreadCount: readState.count, totalState: totalUnreadState, notificationSettings: notificationSettings)
|
||||
}
|
||||
}
|
||||
case .replyThread, .feed:
|
||||
break
|
||||
}
|
||||
default:
|
||||
break
|
||||
@ -383,7 +383,7 @@ func fetchAndPreloadReplyThreadInfo(context: AccountContext, subject: ReplyThrea
|
||||
let preloadSignal = preloadedChatHistoryViewForLocation(
|
||||
input,
|
||||
context: context,
|
||||
chatLocation: .replyThread(replyThreadMessage),
|
||||
chatLocation: .replyThread(message: replyThreadMessage),
|
||||
subject: nil,
|
||||
chatLocationContextHolder: chatLocationContextHolder,
|
||||
fixedCombinedReadStates: nil,
|
||||
|
||||
@ -151,14 +151,14 @@ final class ChatInfoTitlePanelNode: ChatTitleAccessoryPanelNode {
|
||||
|
||||
let updatedButtons: [ChatInfoTitleButton]
|
||||
switch interfaceState.chatLocation {
|
||||
case .peer:
|
||||
if let peer = interfaceState.renderedPeer?.peer {
|
||||
updatedButtons = peerButtons(peer, interfaceState: interfaceState)
|
||||
} else {
|
||||
updatedButtons = []
|
||||
}
|
||||
case .replyThread:
|
||||
case .peer:
|
||||
if let peer = interfaceState.renderedPeer?.peer {
|
||||
updatedButtons = peerButtons(peer, interfaceState: interfaceState)
|
||||
} else {
|
||||
updatedButtons = []
|
||||
}
|
||||
case .replyThread, .feed:
|
||||
updatedButtons = []
|
||||
}
|
||||
|
||||
var buttonsUpdated = false
|
||||
|
||||
@ -259,20 +259,22 @@ func canReplyInChat(_ chatPresentationInterfaceState: ChatPresentationInterfaceS
|
||||
|
||||
var canReply = false
|
||||
switch chatPresentationInterfaceState.chatLocation {
|
||||
case .peer:
|
||||
if let channel = peer as? TelegramChannel {
|
||||
if case .member = channel.participationStatus {
|
||||
canReply = channel.hasPermission(.sendMessages)
|
||||
}
|
||||
} else if let group = peer as? TelegramGroup {
|
||||
if case .Member = group.membership {
|
||||
canReply = true
|
||||
}
|
||||
} else {
|
||||
case .peer:
|
||||
if let channel = peer as? TelegramChannel {
|
||||
if case .member = channel.participationStatus {
|
||||
canReply = channel.hasPermission(.sendMessages)
|
||||
}
|
||||
} else if let group = peer as? TelegramGroup {
|
||||
if case .Member = group.membership {
|
||||
canReply = true
|
||||
}
|
||||
case .replyThread:
|
||||
} else {
|
||||
canReply = true
|
||||
}
|
||||
case .replyThread:
|
||||
canReply = true
|
||||
case .feed:
|
||||
canReply = false
|
||||
}
|
||||
return canReply
|
||||
}
|
||||
@ -481,29 +483,29 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
|
||||
canPin = false
|
||||
} else if messages[0].flags.intersection([.Failed, .Unsent]).isEmpty {
|
||||
switch chatPresentationInterfaceState.chatLocation {
|
||||
case .peer, .replyThread:
|
||||
if let channel = messages[0].peers[messages[0].id.peerId] as? TelegramChannel {
|
||||
if !isAction {
|
||||
canPin = channel.hasPermission(.pinMessages)
|
||||
}
|
||||
} else if let group = messages[0].peers[messages[0].id.peerId] as? TelegramGroup {
|
||||
if !isAction {
|
||||
switch group.role {
|
||||
case .creator, .admin:
|
||||
canPin = true
|
||||
default:
|
||||
if let defaultBannedRights = group.defaultBannedRights {
|
||||
canPin = !defaultBannedRights.flags.contains(.banPinMessages)
|
||||
} else {
|
||||
canPin = true
|
||||
}
|
||||
case .peer, .replyThread, .feed:
|
||||
if let channel = messages[0].peers[messages[0].id.peerId] as? TelegramChannel {
|
||||
if !isAction {
|
||||
canPin = channel.hasPermission(.pinMessages)
|
||||
}
|
||||
} else if let group = messages[0].peers[messages[0].id.peerId] as? TelegramGroup {
|
||||
if !isAction {
|
||||
switch group.role {
|
||||
case .creator, .admin:
|
||||
canPin = true
|
||||
default:
|
||||
if let defaultBannedRights = group.defaultBannedRights {
|
||||
canPin = !defaultBannedRights.flags.contains(.banPinMessages)
|
||||
} else {
|
||||
canPin = true
|
||||
}
|
||||
}
|
||||
} else if let _ = messages[0].peers[messages[0].id.peerId] as? TelegramUser, chatPresentationInterfaceState.explicitelyCanPinMessages {
|
||||
if !isAction {
|
||||
canPin = true
|
||||
}
|
||||
}
|
||||
} else if let _ = messages[0].peers[messages[0].id.peerId] as? TelegramUser, chatPresentationInterfaceState.explicitelyCanPinMessages {
|
||||
if !isAction {
|
||||
canPin = true
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
canReply = false
|
||||
|
||||
@ -766,6 +766,8 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
|
||||
if !isBroadcastChannel {
|
||||
hasAvatar = true
|
||||
} else if case .feed = item.chatLocation {
|
||||
hasAvatar = true
|
||||
}
|
||||
}
|
||||
} else if incoming {
|
||||
@ -790,6 +792,8 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
} else if incoming {
|
||||
hasAvatar = true
|
||||
}
|
||||
case .feed:
|
||||
hasAvatar = true
|
||||
}
|
||||
|
||||
if hasAvatar {
|
||||
|
||||
@ -1043,7 +1043,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
||||
var hasAvatar = false
|
||||
|
||||
var allowFullWidth = false
|
||||
let chatLocationPeerId: PeerId = item.chatLocation.peerId
|
||||
let chatLocationPeerId: PeerId = item.chatLocation.peerId ?? item.content.firstMessage.id.peerId
|
||||
|
||||
do {
|
||||
let peerId = chatLocationPeerId
|
||||
@ -1107,6 +1107,8 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
||||
|
||||
if !isBroadcastChannel {
|
||||
hasAvatar = item.content.firstMessage.effectivelyIncoming(item.context.account.peerId)
|
||||
} else if case .feed = item.chatLocation {
|
||||
hasAvatar = true
|
||||
}
|
||||
}
|
||||
} else if incoming {
|
||||
|
||||
@ -43,7 +43,7 @@ final class ChatMessageEventLogPreviousDescriptionContentNode: ChatMessageBubble
|
||||
}
|
||||
let mediaAndFlags: (Media, ChatMessageAttachedContentNodeMediaFlags)? = nil
|
||||
|
||||
let (initialWidth, continueLayout) = contentNodeLayout(item.presentationData, item.controllerInteraction.automaticMediaDownloadSettings, item.associatedData, item.attributes, item.context, item.controllerInteraction, item.message, true, .peer(item.message.id.peerId), title, nil, text, messageEntities, mediaAndFlags, nil, nil, nil, true, layoutConstants, preparePosition, constrainedSize)
|
||||
let (initialWidth, continueLayout) = contentNodeLayout(item.presentationData, item.controllerInteraction.automaticMediaDownloadSettings, item.associatedData, item.attributes, item.context, item.controllerInteraction, item.message, true, .peer(id: item.message.id.peerId), title, nil, text, messageEntities, mediaAndFlags, nil, nil, nil, true, layoutConstants, preparePosition, constrainedSize)
|
||||
|
||||
let contentProperties = ChatMessageBubbleContentProperties(hidesSimpleAuthorHeader: false, headerSpacing: 8.0, hidesBackground: .never, forceFullCorners: false, forceAlignment: .none)
|
||||
|
||||
|
||||
@ -38,7 +38,7 @@ final class ChatMessageEventLogPreviousLinkContentNode: ChatMessageBubbleContent
|
||||
let text: String = item.message.text
|
||||
let mediaAndFlags: (Media, ChatMessageAttachedContentNodeMediaFlags)? = nil
|
||||
|
||||
let (initialWidth, continueLayout) = contentNodeLayout(item.presentationData, item.controllerInteraction.automaticMediaDownloadSettings, item.associatedData, item.attributes, item.context, item.controllerInteraction, item.message, true, .peer(item.message.id.peerId), title, nil, text, messageEntities, mediaAndFlags, nil, nil, nil, true, layoutConstants, preparePosition, constrainedSize)
|
||||
let (initialWidth, continueLayout) = contentNodeLayout(item.presentationData, item.controllerInteraction.automaticMediaDownloadSettings, item.associatedData, item.attributes, item.context, item.controllerInteraction, item.message, true, .peer(id: item.message.id.peerId), title, nil, text, messageEntities, mediaAndFlags, nil, nil, nil, true, layoutConstants, preparePosition, constrainedSize)
|
||||
|
||||
let contentProperties = ChatMessageBubbleContentProperties(hidesSimpleAuthorHeader: false, headerSpacing: 8.0, hidesBackground: .never, forceFullCorners: false, forceAlignment: .none)
|
||||
|
||||
|
||||
@ -43,7 +43,7 @@ final class ChatMessageEventLogPreviousMessageContentNode: ChatMessageBubbleCont
|
||||
}
|
||||
let mediaAndFlags: (Media, ChatMessageAttachedContentNodeMediaFlags)? = nil
|
||||
|
||||
let (initialWidth, continueLayout) = contentNodeLayout(item.presentationData, item.controllerInteraction.automaticMediaDownloadSettings, item.associatedData, item.attributes, item.context, item.controllerInteraction, item.message, true, .peer(item.message.id.peerId), title, nil, text, messageEntities, mediaAndFlags, nil, nil, nil, true, layoutConstants, preparePosition, constrainedSize)
|
||||
let (initialWidth, continueLayout) = contentNodeLayout(item.presentationData, item.controllerInteraction.automaticMediaDownloadSettings, item.associatedData, item.attributes, item.context, item.controllerInteraction, item.message, true, .peer(id: item.message.id.peerId), title, nil, text, messageEntities, mediaAndFlags, nil, nil, nil, true, layoutConstants, preparePosition, constrainedSize)
|
||||
|
||||
let contentProperties = ChatMessageBubbleContentProperties(hidesSimpleAuthorHeader: false, headerSpacing: 8.0, hidesBackground: .never, forceFullCorners: false, forceAlignment: .none)
|
||||
|
||||
|
||||
@ -77,7 +77,7 @@ final class ChatMessageGameBubbleContentNode: ChatMessageBubbleContentNode {
|
||||
}
|
||||
}
|
||||
|
||||
let (initialWidth, continueLayout) = contentNodeLayout(item.presentationData, item.controllerInteraction.automaticMediaDownloadSettings, item.associatedData, item.attributes, item.context, item.controllerInteraction, item.message, item.read, .peer(item.message.id.peerId), title, nil, item.message.text.isEmpty ? text : item.message.text, item.message.text.isEmpty ? nil : messageEntities, mediaAndFlags, nil, nil, nil, true, layoutConstants, preparePosition, constrainedSize)
|
||||
let (initialWidth, continueLayout) = contentNodeLayout(item.presentationData, item.controllerInteraction.automaticMediaDownloadSettings, item.associatedData, item.attributes, item.context, item.controllerInteraction, item.message, item.read, .peer(id: item.message.id.peerId), title, nil, item.message.text.isEmpty ? text : item.message.text, item.message.text.isEmpty ? nil : messageEntities, mediaAndFlags, nil, nil, nil, true, layoutConstants, preparePosition, constrainedSize)
|
||||
|
||||
let contentProperties = ChatMessageBubbleContentProperties(hidesSimpleAuthorHeader: false, headerSpacing: 8.0, hidesBackground: .never, forceFullCorners: false, forceAlignment: .none)
|
||||
|
||||
|
||||
@ -274,13 +274,7 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView, UIGestureRecognizerD
|
||||
let avatarInset: CGFloat
|
||||
var hasAvatar = false
|
||||
|
||||
let messagePeerId: PeerId
|
||||
switch item.chatLocation {
|
||||
case let .peer(peerId):
|
||||
messagePeerId = peerId
|
||||
case let .replyThread(replyThreadMessage):
|
||||
messagePeerId = replyThreadMessage.messageId.peerId
|
||||
}
|
||||
let messagePeerId = item.chatLocation.peerId ?? item.content.firstMessage.id.peerId
|
||||
|
||||
do {
|
||||
if messagePeerId != item.context.account.peerId {
|
||||
@ -296,6 +290,8 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView, UIGestureRecognizerD
|
||||
|
||||
if !isBroadcastChannel {
|
||||
hasAvatar = true
|
||||
} else if case .feed = item.chatLocation {
|
||||
hasAvatar = true
|
||||
}
|
||||
}
|
||||
} else if incoming {
|
||||
|
||||
@ -297,7 +297,7 @@ public final class ChatMessageItem: ListViewItem, CustomStringConvertible {
|
||||
var effectiveAuthor: Peer?
|
||||
let displayAuthorInfo: Bool
|
||||
|
||||
let messagePeerId: PeerId = chatLocation.peerId
|
||||
let messagePeerId: PeerId = chatLocation.peerId ?? content.firstMessage.id.peerId
|
||||
|
||||
do {
|
||||
let peerId = messagePeerId
|
||||
|
||||
@ -354,40 +354,44 @@ class ChatMessageStickerItemNode: ChatMessageItemView {
|
||||
var hasAvatar = false
|
||||
|
||||
switch item.chatLocation {
|
||||
case let .peer(peerId):
|
||||
if !peerId.isRepliesOrSavedMessages(accountPeerId: item.context.account.peerId) {
|
||||
if peerId.isGroupOrChannel && item.message.author != nil {
|
||||
var isBroadcastChannel = false
|
||||
if let peer = item.message.peers[item.message.id.peerId] as? TelegramChannel, case .broadcast = peer.info {
|
||||
isBroadcastChannel = true
|
||||
}
|
||||
|
||||
if !isBroadcastChannel {
|
||||
hasAvatar = true
|
||||
}
|
||||
case let .peer(peerId):
|
||||
if !peerId.isRepliesOrSavedMessages(accountPeerId: item.context.account.peerId) {
|
||||
if peerId.isGroupOrChannel && item.message.author != nil {
|
||||
var isBroadcastChannel = false
|
||||
if let peer = item.message.peers[item.message.id.peerId] as? TelegramChannel, case .broadcast = peer.info {
|
||||
isBroadcastChannel = true
|
||||
}
|
||||
} else if incoming {
|
||||
hasAvatar = true
|
||||
}
|
||||
case let .replyThread(replyThreadMessage):
|
||||
if replyThreadMessage.messageId.peerId != item.context.account.peerId {
|
||||
if replyThreadMessage.messageId.peerId.isGroupOrChannel && item.message.author != nil {
|
||||
var isBroadcastChannel = false
|
||||
if let peer = item.message.peers[item.message.id.peerId] as? TelegramChannel, case .broadcast = peer.info {
|
||||
isBroadcastChannel = true
|
||||
}
|
||||
|
||||
if replyThreadMessage.isChannelPost, replyThreadMessage.effectiveTopId == item.message.id {
|
||||
isBroadcastChannel = true
|
||||
}
|
||||
|
||||
if !isBroadcastChannel {
|
||||
hasAvatar = true
|
||||
}
|
||||
|
||||
if !isBroadcastChannel {
|
||||
hasAvatar = true
|
||||
} else if case .feed = item.chatLocation {
|
||||
hasAvatar = true
|
||||
}
|
||||
} else if incoming {
|
||||
hasAvatar = true
|
||||
}
|
||||
} else if incoming {
|
||||
hasAvatar = true
|
||||
}
|
||||
case let .replyThread(replyThreadMessage):
|
||||
if replyThreadMessage.messageId.peerId != item.context.account.peerId {
|
||||
if replyThreadMessage.messageId.peerId.isGroupOrChannel && item.message.author != nil {
|
||||
var isBroadcastChannel = false
|
||||
if let peer = item.message.peers[item.message.id.peerId] as? TelegramChannel, case .broadcast = peer.info {
|
||||
isBroadcastChannel = true
|
||||
}
|
||||
|
||||
if replyThreadMessage.isChannelPost, replyThreadMessage.effectiveTopId == item.message.id {
|
||||
isBroadcastChannel = true
|
||||
}
|
||||
|
||||
if !isBroadcastChannel {
|
||||
hasAvatar = true
|
||||
}
|
||||
}
|
||||
} else if incoming {
|
||||
hasAvatar = true
|
||||
}
|
||||
case .feed:
|
||||
hasAvatar = true
|
||||
}
|
||||
|
||||
if hasAvatar {
|
||||
|
||||
@ -767,7 +767,7 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
|
||||
self.navigationActionDisposable.set((peerSignal |> take(1) |> deliverOnMainQueue).start(next: { [weak self] peer in
|
||||
if let strongSelf = self, let peer = peer {
|
||||
if peer is TelegramChannel, let navigationController = strongSelf.getNavigationController() {
|
||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(peer.id), peekData: peekData, animated: true))
|
||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(id: peer.id), peekData: peekData, animated: true))
|
||||
} else {
|
||||
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)
|
||||
@ -889,11 +889,11 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
|
||||
break
|
||||
case let .channelMessage(peerId, messageId, timecode):
|
||||
if let navigationController = strongSelf.getNavigationController() {
|
||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(peerId), subject: .message(id: .id(messageId), highlight: true, timecode: timecode)))
|
||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(id: peerId), subject: .message(id: .id(messageId), highlight: true, timecode: timecode)))
|
||||
}
|
||||
case let .replyThreadMessage(replyThreadMessage, messageId):
|
||||
if let navigationController = strongSelf.getNavigationController() {
|
||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .replyThread(replyThreadMessage), subject: .message(id: .id(messageId), highlight: true, timecode: nil)))
|
||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .replyThread(message: replyThreadMessage), subject: .message(id: .id(messageId), highlight: true, timecode: nil)))
|
||||
}
|
||||
case let .stickerPack(name):
|
||||
let packReference: StickerPackReference = .name(name)
|
||||
|
||||
@ -114,7 +114,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
|
||||
let action = TelegramMediaActionType.titleUpdated(title: new)
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case let .changeAbout(prev, new):
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var author: Peer?
|
||||
@ -145,14 +145,14 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
}
|
||||
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||
let message = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: 1), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case .content:
|
||||
let peers = SimpleDictionary<PeerId, Peer>()
|
||||
let attributes: [MessageAttribute] = []
|
||||
let prevMessage = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: prev, attributes: [], media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: new, attributes: attributes, media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil), additionalContent: !prev.isEmpty ? .eventLogPreviousDescription(prevMessage) : nil)
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil), additionalContent: !prev.isEmpty ? .eventLogPreviousDescription(prevMessage) : nil)
|
||||
}
|
||||
case let .changeUsername(prev, new):
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
@ -183,7 +183,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
}
|
||||
let action: TelegramMediaActionType = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||
let message = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: 1), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case .content:
|
||||
var previousAttributes: [MessageAttribute] = []
|
||||
var attributes: [MessageAttribute] = []
|
||||
@ -202,7 +202,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
|
||||
let prevMessage = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: 1), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: prevText, attributes: previousAttributes, media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: text, attributes: attributes, media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil), additionalContent: !prev.isEmpty ? .eventLogPreviousLink(prevMessage) : nil)
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil), additionalContent: !prev.isEmpty ? .eventLogPreviousLink(prevMessage) : nil)
|
||||
}
|
||||
case let .changePhoto(_, new):
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
@ -221,7 +221,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
|
||||
let action = TelegramMediaActionType.photoUpdated(image: photo)
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case let .toggleInvites(value):
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var author: Peer?
|
||||
@ -248,7 +248,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
}
|
||||
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case let .toggleSignatures(value):
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var author: Peer?
|
||||
@ -275,7 +275,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
}
|
||||
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case let .updatePinned(message):
|
||||
switch self.id.contentIndex {
|
||||
case .header:
|
||||
@ -306,7 +306,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
|
||||
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||
let message = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: 1), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case .content:
|
||||
if let message = message {
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
@ -324,7 +324,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
}
|
||||
}
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: message.effectiveAuthor, text: message.text, attributes: attributes, media: message.media, peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
} else {
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var author: Peer?
|
||||
@ -346,7 +346,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: 0), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
}
|
||||
}
|
||||
case let .editMessage(prev, message):
|
||||
@ -391,7 +391,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||
|
||||
let message = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: 1), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case .content:
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var attributes: [MessageAttribute] = []
|
||||
@ -408,7 +408,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
}
|
||||
}
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: message.effectiveAuthor, text: message.text, attributes: attributes, media: message.media, peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: filterOriginalMessageFlags(message), read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil), additionalContent: !prev.text.isEmpty || !message.text.isEmpty ? .eventLogPreviousMessage(filterOriginalMessageFlags(prev)) : nil)
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: filterOriginalMessageFlags(message), read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil), additionalContent: !prev.text.isEmpty || !message.text.isEmpty ? .eventLogPreviousMessage(filterOriginalMessageFlags(prev)) : nil)
|
||||
}
|
||||
case let .deleteMessage(message):
|
||||
switch self.id.contentIndex {
|
||||
@ -434,7 +434,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||
|
||||
let message = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: 1), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case .content:
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var attributes: [MessageAttribute] = []
|
||||
@ -458,7 +458,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
}
|
||||
}
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: message.effectiveAuthor, text: message.text, attributes: attributes, media: message.media, peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
}
|
||||
case .participantJoin, .participantLeave:
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
@ -476,7 +476,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
action = TelegramMediaActionType.removedMembers(peerIds: [self.entry.event.peerId])
|
||||
}
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case let .participantInvite(participant):
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var author: Peer?
|
||||
@ -493,7 +493,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
let action: TelegramMediaActionType
|
||||
action = TelegramMediaActionType.addedMembers(peerIds: [participant.peer.id])
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case let .participantToggleBan(prev, new):
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var attributes: [MessageAttribute] = []
|
||||
@ -623,7 +623,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
}
|
||||
}
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: text, attributes: attributes, media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case let .participantToggleAdmin(prev, new):
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var attributes: [MessageAttribute] = []
|
||||
@ -856,7 +856,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
}
|
||||
}
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: text, attributes: attributes, media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case let .changeStickerPack(_, new):
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var author: Peer?
|
||||
@ -885,7 +885,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case let .togglePreHistoryHidden(value):
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var author: Peer?
|
||||
@ -915,7 +915,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case let .updateDefaultBannedRights(prev, new):
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var attributes: [MessageAttribute] = []
|
||||
@ -973,7 +973,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
}
|
||||
}
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: text, attributes: attributes, media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case let .pollStopped(message):
|
||||
switch self.id.contentIndex {
|
||||
case .header:
|
||||
@ -1001,7 +1001,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||
|
||||
let message = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: 1), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case .content:
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var attributes: [MessageAttribute] = []
|
||||
@ -1018,7 +1018,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
}
|
||||
}
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: message.author, text: message.text, attributes: attributes, media: message.media, peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: filterOriginalMessageFlags(message), read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil), additionalContent: nil)
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: filterOriginalMessageFlags(message), read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil), additionalContent: nil)
|
||||
}
|
||||
case let .linkedPeerUpdated(previous, updated):
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
@ -1074,7 +1074,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case let .changeGeoLocation(_, updated):
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var author: Peer?
|
||||
@ -1096,12 +1096,12 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
let mediaMap = TelegramMediaMap(latitude: updated.latitude, longitude: updated.longitude, heading: nil, accuracyRadius: nil, geoPlace: nil, venue: nil, liveBroadcastingTimeout: nil, liveProximityNotificationRadius: nil)
|
||||
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: text, attributes: [], media: [mediaMap], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
} else {
|
||||
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
}
|
||||
case let .updateSlowmode(_, newValue):
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
@ -1132,7 +1132,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case .startGroupCall, .endGroupCall:
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var author: Peer?
|
||||
@ -1169,7 +1169,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case let .groupCallUpdateParticipantMuteStatus(participantId, isMuted):
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var author: Peer?
|
||||
@ -1203,7 +1203,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case let .updateGroupCallSettings(joinMuted):
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var author: Peer?
|
||||
@ -1232,7 +1232,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case let .groupCallUpdateParticipantVolume(participantId, volume):
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var author: Peer?
|
||||
@ -1263,7 +1263,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case let .deleteExportedInvitation(invite):
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var author: Peer?
|
||||
@ -1289,7 +1289,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case let .revokeExportedInvitation(invite):
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var author: Peer?
|
||||
@ -1315,7 +1315,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case let .editExportedInvitation(_, updatedInvite):
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var author: Peer?
|
||||
@ -1341,7 +1341,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case let .participantJoinedViaInvite(invite):
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var author: Peer?
|
||||
@ -1367,7 +1367,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case let .changeHistoryTTL(_, updatedValue):
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var author: Peer?
|
||||
@ -1398,7 +1398,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case let .changeAvailableReactions(_, updatedValue):
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var author: Peer?
|
||||
@ -1430,7 +1430,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case let .changeTheme(_, updatedValue):
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var author: Peer?
|
||||
@ -1461,7 +1461,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case let .participantJoinByRequest(invite, approvedBy):
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var author: Peer?
|
||||
@ -1494,7 +1494,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case let .toggleCopyProtection(value):
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var author: Peer?
|
||||
@ -1521,7 +1521,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
}
|
||||
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case let .sendMessage(message):
|
||||
switch self.id.contentIndex {
|
||||
case .header:
|
||||
@ -1546,7 +1546,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
|
||||
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||
let message = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: 1), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
case .content:
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
var attributes: [MessageAttribute] = []
|
||||
@ -1563,7 +1563,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
||||
}
|
||||
}
|
||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: message.effectiveAuthor, text: message.text, attributes: attributes, media: message.media, peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,8 +32,8 @@ final class ChatSearchNavigationContentNode: NavigationBarContentNode {
|
||||
self.searchBar = SearchBarNode(theme: SearchBarNodeTheme(theme: theme, hasBackground: false, hasSeparator: false), strings: strings, fieldStyle: .modern)
|
||||
let placeholderText: String
|
||||
switch chatLocation {
|
||||
case .peer, .replyThread:
|
||||
placeholderText = strings.Conversation_SearchPlaceholder
|
||||
case .peer, .replyThread, .feed:
|
||||
placeholderText = strings.Conversation_SearchPlaceholder
|
||||
}
|
||||
self.searchBar.placeholderString = NSAttributedString(string: placeholderText, font: searchBarFont, textColor: theme.rootController.navigationSearchBar.inputPlaceholderTextColor)
|
||||
|
||||
@ -104,8 +104,8 @@ final class ChatSearchNavigationContentNode: NavigationBarContentNode {
|
||||
self.searchBar.prefixString = nil
|
||||
let placeholderText: String
|
||||
switch self.chatLocation {
|
||||
case .peer, .replyThread:
|
||||
placeholderText = self.strings.Conversation_SearchPlaceholder
|
||||
case .peer, .replyThread, .feed:
|
||||
placeholderText = self.strings.Conversation_SearchPlaceholder
|
||||
}
|
||||
self.searchBar.placeholderString = NSAttributedString(string: placeholderText, font: searchBarFont, textColor: theme.rootController.navigationSearchBar.inputPlaceholderTextColor)
|
||||
case .members:
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user