mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-08-08 08:31:13 +00:00
Pinned messages improvements
This commit is contained in:
parent
de7ca018f6
commit
cd96e69361
@ -69,6 +69,11 @@ debug_deps = select({
|
|||||||
"//conditions:default": [],
|
"//conditions:default": [],
|
||||||
})
|
})
|
||||||
|
|
||||||
|
strip_framework = select({
|
||||||
|
":debug": None,
|
||||||
|
"//conditions:default": ":StripFramework",
|
||||||
|
})
|
||||||
|
|
||||||
filegroup(
|
filegroup(
|
||||||
name = "AppResources",
|
name = "AppResources",
|
||||||
srcs = glob([
|
srcs = glob([
|
||||||
@ -542,7 +547,7 @@ ios_framework(
|
|||||||
":MtProtoKitInfoPlist",
|
":MtProtoKitInfoPlist",
|
||||||
],
|
],
|
||||||
minimum_os_version = "9.0",
|
minimum_os_version = "9.0",
|
||||||
ipa_post_processor = ":StripFramework",
|
ipa_post_processor = strip_framework,
|
||||||
deps = [
|
deps = [
|
||||||
"//submodules/MtProtoKit:MtProtoKit",
|
"//submodules/MtProtoKit:MtProtoKit",
|
||||||
],
|
],
|
||||||
@ -583,7 +588,7 @@ ios_framework(
|
|||||||
":SwiftSignalKitInfoPlist",
|
":SwiftSignalKitInfoPlist",
|
||||||
],
|
],
|
||||||
minimum_os_version = "9.0",
|
minimum_os_version = "9.0",
|
||||||
ipa_post_processor = ":StripFramework",
|
ipa_post_processor = strip_framework,
|
||||||
deps = [
|
deps = [
|
||||||
"//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit",
|
"//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit",
|
||||||
],
|
],
|
||||||
@ -627,7 +632,7 @@ ios_framework(
|
|||||||
":SwiftSignalKitFramework",
|
":SwiftSignalKitFramework",
|
||||||
],
|
],
|
||||||
minimum_os_version = "9.0",
|
minimum_os_version = "9.0",
|
||||||
ipa_post_processor = ":StripFramework",
|
ipa_post_processor = strip_framework,
|
||||||
deps = [
|
deps = [
|
||||||
"//submodules/Postbox:Postbox",
|
"//submodules/Postbox:Postbox",
|
||||||
],
|
],
|
||||||
@ -668,7 +673,7 @@ ios_framework(
|
|||||||
":TelegramApiInfoPlist",
|
":TelegramApiInfoPlist",
|
||||||
],
|
],
|
||||||
minimum_os_version = "9.0",
|
minimum_os_version = "9.0",
|
||||||
ipa_post_processor = ":StripFramework",
|
ipa_post_processor = strip_framework,
|
||||||
deps = [
|
deps = [
|
||||||
"//submodules/TelegramApi:TelegramApi",
|
"//submodules/TelegramApi:TelegramApi",
|
||||||
],
|
],
|
||||||
@ -713,7 +718,7 @@ ios_framework(
|
|||||||
":PostboxFramework",
|
":PostboxFramework",
|
||||||
],
|
],
|
||||||
minimum_os_version = "9.0",
|
minimum_os_version = "9.0",
|
||||||
ipa_post_processor = ":StripFramework",
|
ipa_post_processor = strip_framework,
|
||||||
deps = [
|
deps = [
|
||||||
"//submodules/SyncCore:SyncCore",
|
"//submodules/SyncCore:SyncCore",
|
||||||
],
|
],
|
||||||
@ -761,7 +766,7 @@ ios_framework(
|
|||||||
":TelegramApiFramework",
|
":TelegramApiFramework",
|
||||||
],
|
],
|
||||||
minimum_os_version = "9.0",
|
minimum_os_version = "9.0",
|
||||||
ipa_post_processor = ":StripFramework",
|
ipa_post_processor = strip_framework,
|
||||||
deps = [
|
deps = [
|
||||||
"//submodules/TelegramCore:TelegramCore",
|
"//submodules/TelegramCore:TelegramCore",
|
||||||
],
|
],
|
||||||
@ -802,7 +807,7 @@ ios_framework(
|
|||||||
":AsyncDisplayKitInfoPlist",
|
":AsyncDisplayKitInfoPlist",
|
||||||
],
|
],
|
||||||
minimum_os_version = "9.0",
|
minimum_os_version = "9.0",
|
||||||
ipa_post_processor = ":StripFramework",
|
ipa_post_processor = strip_framework,
|
||||||
deps = [
|
deps = [
|
||||||
"//submodules/AsyncDisplayKit:AsyncDisplayKit",
|
"//submodules/AsyncDisplayKit:AsyncDisplayKit",
|
||||||
],
|
],
|
||||||
@ -863,7 +868,7 @@ ios_framework(
|
|||||||
":AsyncDisplayKitFramework",
|
":AsyncDisplayKitFramework",
|
||||||
],
|
],
|
||||||
minimum_os_version = "9.0",
|
minimum_os_version = "9.0",
|
||||||
ipa_post_processor = ":StripFramework",
|
ipa_post_processor = strip_framework,
|
||||||
deps = [
|
deps = [
|
||||||
"//submodules/Display:Display",
|
"//submodules/Display:Display",
|
||||||
],
|
],
|
||||||
@ -914,7 +919,7 @@ ios_framework(
|
|||||||
":DisplayFramework",
|
":DisplayFramework",
|
||||||
],
|
],
|
||||||
minimum_os_version = "9.0",
|
minimum_os_version = "9.0",
|
||||||
ipa_post_processor = ":StripFramework",
|
ipa_post_processor = strip_framework,
|
||||||
deps = [
|
deps = [
|
||||||
"//submodules/TelegramUI:TelegramUI",
|
"//submodules/TelegramUI:TelegramUI",
|
||||||
] + debug_deps,
|
] + debug_deps,
|
||||||
|
@ -5822,3 +5822,8 @@ Any member of this group will be able to see messages in the channel.";
|
|||||||
|
|
||||||
"ChatList.MessageMusic_1" = "1 Music File";
|
"ChatList.MessageMusic_1" = "1 Music File";
|
||||||
"ChatList.MessageMusic_any" = "%@ Music Files";
|
"ChatList.MessageMusic_any" = "%@ Music Files";
|
||||||
|
|
||||||
|
"Conversation.PinOlderMessageAlertTitle" = "Pin Message";
|
||||||
|
"Conversation.PinOlderMessageAlertText" = "Do you want to pin an older message while leaving a more recent one pinned?";
|
||||||
|
"Conversation.PinMessageAlertPin" = "Pin";
|
||||||
|
|
||||||
|
@ -140,7 +140,7 @@ final class HistoryViewStateValidationContexts {
|
|||||||
|
|
||||||
func updateView(id: Int32, view: MessageHistoryView?, location: ChatLocationInput? = nil) {
|
func updateView(id: Int32, view: MessageHistoryView?, location: ChatLocationInput? = nil) {
|
||||||
assert(self.queue.isCurrent())
|
assert(self.queue.isCurrent())
|
||||||
guard let view = view, view.tagMask == nil || view.tagMask == MessageTags.unseenPersonalMessage || view.tagMask == MessageTags.music else {
|
guard let view = view, view.tagMask == nil || view.tagMask == MessageTags.unseenPersonalMessage || view.tagMask == MessageTags.music || view.tagMask == MessageTags.pinned else {
|
||||||
if self.contexts[id] != nil {
|
if self.contexts[id] != nil {
|
||||||
self.contexts.removeValue(forKey: id)
|
self.contexts.removeValue(forKey: id)
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,37 @@ public func requestUpdatePinnedMessage(account: Account, peerId: PeerId, update:
|
|||||||
}
|
}
|
||||||
|> mapToSignal { updates -> Signal<Void, UpdatePinnedMessageError> in
|
|> mapToSignal { updates -> Signal<Void, UpdatePinnedMessageError> in
|
||||||
account.stateManager.addUpdates(updates)
|
account.stateManager.addUpdates(updates)
|
||||||
return account.postbox.transaction { _ in
|
return account.postbox.transaction { transaction in
|
||||||
|
switch updates {
|
||||||
|
case let .updates(updates, _, _, _, _):
|
||||||
|
if updates.isEmpty {
|
||||||
|
if peerId.namespace == Namespaces.Peer.CloudChannel {
|
||||||
|
let messageId: MessageId
|
||||||
|
switch update {
|
||||||
|
case let .pin(id, _):
|
||||||
|
messageId = id
|
||||||
|
case let .clear(id):
|
||||||
|
messageId = id
|
||||||
|
}
|
||||||
|
transaction.updateMessage(messageId, update: { currentMessage in
|
||||||
|
let storeForwardInfo = currentMessage.forwardInfo.flatMap(StoreMessageForwardInfo.init)
|
||||||
|
var updatedTags = currentMessage.tags
|
||||||
|
switch update {
|
||||||
|
case .pin:
|
||||||
|
updatedTags.insert(.pinned)
|
||||||
|
case .clear:
|
||||||
|
updatedTags.remove(.pinned)
|
||||||
|
}
|
||||||
|
if updatedTags == currentMessage.tags {
|
||||||
|
return .skip
|
||||||
|
}
|
||||||
|
return .update(StoreMessage(id: currentMessage.id, globallyUniqueId: currentMessage.globallyUniqueId, groupingKey: currentMessage.groupingKey, threadId: currentMessage.threadId, timestamp: currentMessage.timestamp, flags: StoreMessageFlags(currentMessage.flags), tags: updatedTags, globalTags: currentMessage.globalTags, localTags: currentMessage.localTags, forwardInfo: storeForwardInfo, authorId: currentMessage.author?.id, text: currentMessage.text, attributes: currentMessage.attributes, media: currentMessage.media))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
/*transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, current in
|
/*transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, current in
|
||||||
if let current = current as? CachedChannelData {
|
if let current = current as? CachedChannelData {
|
||||||
let pinnedMessageId: MessageId?
|
let pinnedMessageId: MessageId?
|
||||||
@ -111,6 +141,37 @@ public func requestUpdatePinnedMessage(account: Account, peerId: PeerId, update:
|
|||||||
|> mapToSignal { updates -> Signal<Void, UpdatePinnedMessageError> in
|
|> mapToSignal { updates -> Signal<Void, UpdatePinnedMessageError> in
|
||||||
account.stateManager.addUpdates(updates)
|
account.stateManager.addUpdates(updates)
|
||||||
return account.postbox.transaction { transaction in
|
return account.postbox.transaction { transaction in
|
||||||
|
switch updates {
|
||||||
|
case let .updates(updates, _, _, _, _):
|
||||||
|
if updates.isEmpty {
|
||||||
|
if peerId.namespace == Namespaces.Peer.CloudChannel {
|
||||||
|
let messageId: MessageId
|
||||||
|
switch update {
|
||||||
|
case let .pin(id, _):
|
||||||
|
messageId = id
|
||||||
|
case let .clear(id):
|
||||||
|
messageId = id
|
||||||
|
}
|
||||||
|
transaction.updateMessage(messageId, update: { currentMessage in
|
||||||
|
let storeForwardInfo = currentMessage.forwardInfo.flatMap(StoreMessageForwardInfo.init)
|
||||||
|
var updatedTags = currentMessage.tags
|
||||||
|
switch update {
|
||||||
|
case .pin:
|
||||||
|
updatedTags.insert(.pinned)
|
||||||
|
case .clear:
|
||||||
|
updatedTags.remove(.pinned)
|
||||||
|
}
|
||||||
|
if updatedTags == currentMessage.tags {
|
||||||
|
return .skip
|
||||||
|
}
|
||||||
|
return .update(StoreMessage(id: currentMessage.id, globallyUniqueId: currentMessage.globallyUniqueId, groupingKey: currentMessage.groupingKey, threadId: currentMessage.threadId, timestamp: currentMessage.timestamp, flags: StoreMessageFlags(currentMessage.flags), tags: updatedTags, globalTags: currentMessage.globalTags, localTags: currentMessage.localTags, forwardInfo: storeForwardInfo, authorId: currentMessage.author?.id, text: currentMessage.text, attributes: currentMessage.attributes, media: currentMessage.media))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, current in
|
transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, current in
|
||||||
if let _ = peer as? TelegramGroup {
|
if let _ = peer as? TelegramGroup {
|
||||||
let current = current as? CachedGroupData ?? CachedGroupData()
|
let current = current as? CachedGroupData ?? CachedGroupData()
|
||||||
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -3233,6 +3233,64 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
self.chatTitleView?.updateThemeAndStrings(theme: self.presentationData.theme, strings: self.presentationData.strings, hasEmbeddedTitleContent: self.hasEmbeddedTitleContent)
|
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() {
|
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)
|
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)
|
||||||
|
|
||||||
@ -3402,60 +3460,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
let isTopReplyThreadMessageShown: Signal<Bool, NoError> = self.chatDisplayNode.historyNode.isTopReplyThreadMessageShown.get()
|
let isTopReplyThreadMessageShown: Signal<Bool, NoError> = self.chatDisplayNode.historyNode.isTopReplyThreadMessageShown.get()
|
||||||
|> distinctUntilChanged
|
|> distinctUntilChanged
|
||||||
|
|
||||||
let topPinnedMessage: Signal<ChatPinnedMessage?, NoError>
|
let topPinnedMessage: Signal<ChatPinnedMessage?, NoError> = self.topPinnedMessageSignal(latest: false)
|
||||||
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,
|
|
||||||
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.lowerBound {
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
self.cachedDataDisposable = combineLatest(queue: .mainQueue(), self.chatDisplayNode.historyNode.cachedPeerDataAndMessages, hasPendingMessages, isTopReplyThreadMessageShown, topPinnedMessage).start(next: { [weak self] cachedDataAndMessages, hasPendingMessages, isTopReplyThreadMessageShown, topPinnedMessage in
|
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 {
|
if let strongSelf = self {
|
||||||
@ -3586,7 +3591,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
if case .replyThread = self.chatLocation {
|
if case .replyThread = self.chatLocation {
|
||||||
effectiveCachedDataReady = self.cachedDataReady.get()
|
effectiveCachedDataReady = self.cachedDataReady.get()
|
||||||
} else {
|
} 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
|
self.ready.set(combineLatest(self.chatDisplayNode.historyNode.historyState.get(), self._chatLocationInfoReady.get(), effectiveCachedDataReady, initialData) |> map { _, chatLocationInfoReady, cachedDataReady, _ in
|
||||||
return chatLocationInfoReady && cachedDataReady
|
return chatLocationInfoReady && cachedDataReady
|
||||||
@ -4812,11 +4818,46 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
if pinImmediately {
|
if pinImmediately {
|
||||||
pinAction(true)
|
pinAction(true)
|
||||||
} else {
|
} 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: {
|
let topPinnedMessage: Signal<ChatPinnedMessage?, NoError> = strongSelf.topPinnedMessageSignal(latest: true)
|
||||||
pinAction(false)
|
|> take(1)
|
||||||
}), TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_Yes, action: {
|
|
||||||
pinAction(true)
|
let _ = (topPinnedMessage
|
||||||
})]), in: .window(.root))
|
|> 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 {
|
} else {
|
||||||
if let pinnedMessageId = strongSelf.presentationInterfaceState.pinnedMessage?.message.id {
|
if let pinnedMessageId = strongSelf.presentationInterfaceState.pinnedMessage?.message.id {
|
||||||
@ -4854,7 +4895,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
}
|
}
|
||||||
|
|
||||||
if canManagePin {
|
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 {
|
if let strongSelf = self {
|
||||||
let disposable: MetaDisposable
|
let disposable: MetaDisposable
|
||||||
if let current = strongSelf.unpinMessageDisposable {
|
if let current = strongSelf.unpinMessageDisposable {
|
||||||
@ -4865,7 +4906,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
}
|
}
|
||||||
disposable.set(requestUpdatePinnedMessage(account: strongSelf.context.account, peerId: peer.id, update: .clear(id: id)).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 {
|
} else {
|
||||||
if let pinnedMessage = strongSelf.presentationInterfaceState.pinnedMessage {
|
if let pinnedMessage = strongSelf.presentationInterfaceState.pinnedMessage {
|
||||||
strongSelf.updateChatPresentationInterfaceState(animated: true, interactive: true, {
|
strongSelf.updateChatPresentationInterfaceState(animated: true, interactive: true, {
|
||||||
|
@ -643,27 +643,37 @@ func contextMenuForChatPresentationIntefaceState(chatPresentationInterfaceState:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if data.canPin, case .peer = chatPresentationInterfaceState.chatLocation {
|
if data.canPin, case .peer = chatPresentationInterfaceState.chatLocation {
|
||||||
let isPinned: Bool
|
var pinnedSelectedMessageId: MessageId?
|
||||||
if let _ = chatPresentationInterfaceState.renderedPeer?.peer as? TelegramChannel {
|
if let _ = chatPresentationInterfaceState.renderedPeer?.peer as? TelegramChannel {
|
||||||
isPinned = messages[0].tags.contains(.pinned)
|
for message in messages {
|
||||||
|
if message.tags.contains(.pinned) {
|
||||||
|
pinnedSelectedMessageId = message.id
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
isPinned = chatPresentationInterfaceState.pinnedMessage?.message.id == messages[0].id
|
for message in messages {
|
||||||
|
if chatPresentationInterfaceState.pinnedMessage?.message.id == message.id {
|
||||||
|
pinnedSelectedMessageId = message.id
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !isPinned {
|
if let pinnedSelectedMessageId = pinnedSelectedMessageId {
|
||||||
|
actions.append(.action(ContextMenuActionItem(text: chatPresentationInterfaceState.strings.Conversation_Unpin, icon: { theme in
|
||||||
|
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Unpin"), color: theme.actionSheet.primaryTextColor)
|
||||||
|
}, action: { _, f in
|
||||||
|
interfaceInteraction.unpinMessage(pinnedSelectedMessageId)
|
||||||
|
f(.default)
|
||||||
|
})))
|
||||||
|
} else {
|
||||||
actions.append(.action(ContextMenuActionItem(text: chatPresentationInterfaceState.strings.Conversation_Pin, icon: { theme in
|
actions.append(.action(ContextMenuActionItem(text: chatPresentationInterfaceState.strings.Conversation_Pin, icon: { theme in
|
||||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Pin"), color: theme.actionSheet.primaryTextColor)
|
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Pin"), color: theme.actionSheet.primaryTextColor)
|
||||||
}, action: { _, f in
|
}, action: { _, f in
|
||||||
interfaceInteraction.pinMessage(messages[0].id)
|
interfaceInteraction.pinMessage(messages[0].id)
|
||||||
f(.dismissWithoutContent)
|
f(.dismissWithoutContent)
|
||||||
})))
|
})))
|
||||||
} else {
|
|
||||||
actions.append(.action(ContextMenuActionItem(text: chatPresentationInterfaceState.strings.Conversation_Unpin, icon: { theme in
|
|
||||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Unpin"), color: theme.actionSheet.primaryTextColor)
|
|
||||||
}, action: { _, f in
|
|
||||||
interfaceInteraction.unpinMessage(messages[0].id)
|
|
||||||
f(.default)
|
|
||||||
})))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user