mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-23 22:55:00 +00:00
Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios
This commit is contained in:
@@ -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, {
|
||||
|
||||
Reference in New Issue
Block a user