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

This commit is contained in:
Ilya Laktyushin
2020-10-14 01:51:35 +04:00
39 changed files with 4283 additions and 3577 deletions

View File

@@ -3237,6 +3237,64 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
self.chatTitleView?.updateThemeAndStrings(theme: self.presentationData.theme, strings: self.presentationData.strings, hasEmbeddedTitleContent: self.hasEmbeddedTitleContent)
}
private func topPinnedMessageSignal(latest: Bool) -> Signal<ChatPinnedMessage?, NoError> {
let topPinnedMessage: Signal<ChatPinnedMessage?, NoError>
switch self.chatLocation {
case let .peer(peerId) where peerId.namespace == Namespaces.Peer.CloudChannel:
let replyHistory: Signal<ChatHistoryViewUpdate, NoError> = (chatHistoryViewForLocation(ChatHistoryLocationInput(content: .Initial(count: 100), id: 0), context: self.context, chatLocation: .peer(peerId), chatLocationContextHolder: Atomic<ChatLocationContextHolder?>(value: nil), scheduled: false, fixedCombinedReadStates: nil, tagMask: MessageTags.pinned, additionalData: [])
|> castError(Bool.self)
|> mapToSignal { update -> Signal<ChatHistoryViewUpdate, Bool> in
switch update {
case let .Loading(_, type):
if case .Generic(.FillHole) = type {
return .fail(true)
}
case let .HistoryView(_, type, _, _, _, _, _):
if case .Generic(.FillHole) = type {
return .fail(true)
}
}
return .single(update)
})
|> restartIfError
topPinnedMessage = combineLatest(
replyHistory,
latest ? .single(nil) : self.chatDisplayNode.historyNode.topVisibleMessageRange.get()
)
|> map { update, topVisibleMessageRange -> ChatPinnedMessage? in
var message: ChatPinnedMessage?
switch update {
case .Loading:
break
case let .HistoryView(view, _, _, _, _, _, _):
for i in 0 ..< view.entries.count {
let entry = view.entries[i]
var matches = false
if message == nil {
matches = true
} else if let topVisibleMessageRange = topVisibleMessageRange {
if entry.message.id < topVisibleMessageRange.upperBound {
matches = true
}
} else {
matches = true
}
if matches {
message = ChatPinnedMessage(message: entry.message, isLatest: i == view.entries.count - 1)
}
}
break
}
return message
}
|> distinctUntilChanged
default:
topPinnedMessage = .single(nil)
}
return topPinnedMessage
}
override public func loadDisplayNode() {
self.displayNode = ChatControllerNode(context: self.context, chatLocation: self.chatLocation, chatLocationContextHolder: self.chatLocationContextHolder, subject: self.subject, controllerInteraction: self.controllerInteraction!, chatPresentationInterfaceState: self.presentationInterfaceState, automaticMediaDownloadSettings: self.automaticMediaDownloadSettings, navigationBar: self.navigationBar, controller: self)
@@ -3406,60 +3464,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
let isTopReplyThreadMessageShown: Signal<Bool, NoError> = self.chatDisplayNode.historyNode.isTopReplyThreadMessageShown.get()
|> distinctUntilChanged
let topPinnedMessage: Signal<ChatPinnedMessage?, NoError>
switch self.chatLocation {
case let .peer(peerId):
let replyHistory: Signal<ChatHistoryViewUpdate, NoError> = (chatHistoryViewForLocation(ChatHistoryLocationInput(content: .Initial(count: 100), id: 0), context: self.context, chatLocation: .peer(peerId), chatLocationContextHolder: Atomic<ChatLocationContextHolder?>(value: nil), scheduled: false, fixedCombinedReadStates: nil, tagMask: MessageTags.photoOrVideo, additionalData: [])
|> castError(Bool.self)
|> mapToSignal { update -> Signal<ChatHistoryViewUpdate, Bool> in
switch update {
case let .Loading(_, type):
if case .Generic(.FillHole) = type {
return .fail(true)
}
case let .HistoryView(_, type, _, _, _, _, _):
if case .Generic(.FillHole) = type {
return .fail(true)
}
}
return .single(update)
})
|> restartIfError
topPinnedMessage = combineLatest(
replyHistory,
self.chatDisplayNode.historyNode.topVisibleMessage.get()
)
|> map { update, topVisibleMessage -> ChatPinnedMessage? in
var message: ChatPinnedMessage?
switch update {
case .Loading:
break
case let .HistoryView(view, _, _, _, _, _, _):
for i in 0 ..< view.entries.count {
let entry = view.entries[i]
var matches = false
if message == nil {
matches = true
} else if let topVisibleMessage = topVisibleMessage {
if entry.message.id < topVisibleMessage.id {
matches = true
}
} else {
matches = true
}
if matches {
message = ChatPinnedMessage(message: entry.message, isLatest: i == view.entries.count - 1)
}
}
break
}
return message
}
|> distinctUntilChanged
case .replyThread:
topPinnedMessage = .single(nil)
}
let topPinnedMessage: Signal<ChatPinnedMessage?, NoError> = self.topPinnedMessageSignal(latest: false)
self.cachedDataDisposable = combineLatest(queue: .mainQueue(), self.chatDisplayNode.historyNode.cachedPeerDataAndMessages, hasPendingMessages, isTopReplyThreadMessageShown, topPinnedMessage).start(next: { [weak self] cachedDataAndMessages, hasPendingMessages, isTopReplyThreadMessageShown, topPinnedMessage in
if let strongSelf = self {
@@ -3490,7 +3495,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
var pinnedMessage: ChatPinnedMessage?
if case let .replyThread(replyThreadMessage) = strongSelf.chatLocation {
switch strongSelf.chatLocation {
case let .replyThread(replyThreadMessage):
if isTopReplyThreadMessageShown {
pinnedMessageId = nil
} else {
@@ -3501,14 +3507,17 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
pinnedMessage = ChatPinnedMessage(message: message, isLatest: true)
}
}
} else {
if let pinnedMessageId = pinnedMessageId {
if let message = messages?[pinnedMessageId] {
pinnedMessage = ChatPinnedMessage(message: message, isLatest: true)
case let .peer(peerId):
if peerId.namespace == Namespaces.Peer.CloudChannel {
pinnedMessageId = topPinnedMessage?.message.id
pinnedMessage = topPinnedMessage
} else {
if let pinnedMessageId = pinnedMessageId {
if let message = messages?[pinnedMessageId] {
pinnedMessage = ChatPinnedMessage(message: message, isLatest: true)
}
}
}
//pinnedMessageId = topPinnedMessage?.message.id
//pinnedMessage = topPinnedMessage
}
var pinnedMessageUpdated = false
@@ -3586,7 +3595,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
if case .replyThread = self.chatLocation {
effectiveCachedDataReady = self.cachedDataReady.get()
} else {
effectiveCachedDataReady = .single(true)
//effectiveCachedDataReady = .single(true)
effectiveCachedDataReady = self.cachedDataReady.get()
}
self.ready.set(combineLatest(self.chatDisplayNode.historyNode.historyState.get(), self._chatLocationInfoReady.get(), effectiveCachedDataReady, initialData) |> map { _, chatLocationInfoReady, cachedDataReady, _ in
return chatLocationInfoReady && cachedDataReady
@@ -4812,11 +4822,46 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
if pinImmediately {
pinAction(true)
} else {
strongSelf.present(textAlertController(context: strongSelf.context, title: nil, text: strongSelf.presentationData.strings.Conversation_PinMessageAlertGroup, actions: [TextAlertAction(type: .genericAction, title: strongSelf.presentationData.strings.Conversation_PinMessageAlert_OnlyPin, action: {
pinAction(false)
}), TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_Yes, action: {
pinAction(true)
})]), in: .window(.root))
let topPinnedMessage: Signal<ChatPinnedMessage?, NoError> = strongSelf.topPinnedMessageSignal(latest: true)
|> take(1)
let _ = (topPinnedMessage
|> deliverOnMainQueue).start(next: { value in
guard let strongSelf = self else {
return
}
let title: String?
let text: String
let actionLayout: TextAlertContentActionLayout
let actions: [TextAlertAction]
if let value = value, value.message.id > messageId {
title = strongSelf.presentationData.strings.Conversation_PinOlderMessageAlertTitle
text = strongSelf.presentationData.strings.Conversation_PinOlderMessageAlertText
actionLayout = .vertical
actions = [
TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Conversation_PinMessageAlertPin, action: {
pinAction(false)
}),
TextAlertAction(type: .genericAction, title: strongSelf.presentationData.strings.Common_Cancel, action: {
})
]
} else {
title = nil
text = strongSelf.presentationData.strings.Conversation_PinMessageAlertGroup
actionLayout = .horizontal
actions = [
TextAlertAction(type: .genericAction, title: strongSelf.presentationData.strings.Conversation_PinMessageAlert_OnlyPin, action: {
pinAction(false)
}),
TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_Yes, action: {
pinAction(true)
})
]
}
strongSelf.present(textAlertController(context: strongSelf.context, title: title, text: text, actions: actions, actionLayout: actionLayout), in: .window(.root))
})
}
} else {
if let pinnedMessageId = strongSelf.presentationInterfaceState.pinnedMessage?.message.id {
@@ -4832,7 +4877,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
}
}
}, unpinMessage: { [weak self] in
}, unpinMessage: { [weak self] id in
if let strongSelf = self {
if let peer = strongSelf.presentationInterfaceState.renderedPeer?.peer {
var canManagePin = false
@@ -4854,7 +4899,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
if canManagePin {
strongSelf.present(textAlertController(context: strongSelf.context, title: nil, text: strongSelf.presentationData.strings.Conversation_UnpinMessageAlert, actions: [TextAlertAction(type: .genericAction, title: strongSelf.presentationData.strings.Common_Cancel, action: {}), TextAlertAction(type: .genericAction, title: strongSelf.presentationData.strings.Conversation_Unpin, action: {
strongSelf.present(textAlertController(context: strongSelf.context, title: nil, text: strongSelf.presentationData.strings.Conversation_UnpinMessageAlert, actions: [TextAlertAction(type: .genericAction, title: strongSelf.presentationData.strings.Conversation_Unpin, action: {
if let strongSelf = self {
let disposable: MetaDisposable
if let current = strongSelf.unpinMessageDisposable {
@@ -4863,9 +4908,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
disposable = MetaDisposable()
strongSelf.unpinMessageDisposable = disposable
}
disposable.set(requestUpdatePinnedMessage(account: strongSelf.context.account, peerId: peer.id, update: .clear).start())
disposable.set(requestUpdatePinnedMessage(account: strongSelf.context.account, peerId: peer.id, update: .clear(id: id)).start())
}
})]), in: .window(.root))
}), TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_Cancel, action: {})], actionLayout: .vertical), in: .window(.root))
} else {
if let pinnedMessage = strongSelf.presentationInterfaceState.pinnedMessage {
strongSelf.updateChatPresentationInterfaceState(animated: true, interactive: true, {