Skip to content

Commit 603d575

Browse files
author
Isaac
committed
[WIP] Post suggestions
1 parent 96a5df0 commit 603d575

File tree

57 files changed

+2472
-714
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+2472
-714
lines changed

submodules/AccountContext/Sources/AccountContext.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1212,9 +1212,10 @@ public protocol SharedAccountContext: AnyObject {
12121212
func makeGalleryController(context: AccountContext, source: GalleryControllerItemSource, streamSingleVideo: Bool, isPreview: Bool) -> ViewController
12131213

12141214
func makeAccountFreezeInfoScreen(context: AccountContext) -> ViewController
1215-
12161215
func makeSendInviteLinkScreen(context: AccountContext, subject: SendInviteLinkScreenSubject, peers: [TelegramForbiddenInvitePeer], theme: PresentationTheme?) -> ViewController
12171216

1217+
func makePostSuggestionsSettingsScreen(context: AccountContext) -> ViewController
1218+
12181219
func makeDebugSettingsController(context: AccountContext?) -> ViewController?
12191220

12201221
func openCreateGroupCallUI(context: AccountContext, peerIds: [EnginePeer.Id], parentController: ViewController)

submodules/AccountContext/Sources/ChatController.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1166,6 +1166,7 @@ public enum ChatCustomContentsKind: Equatable {
11661166
case quickReplyMessageInput(shortcut: String, shortcutType: ChatQuickReplyShortcutType)
11671167
case businessLinkSetup(link: TelegramBusinessChatLinks.Link)
11681168
case hashTagSearch(publicPosts: Bool)
1169+
case postSuggestions(price: StarsAmount)
11691170
}
11701171

11711172
public protocol ChatCustomContentsProtocol: AnyObject {

submodules/AttachmentUI/Sources/AttachmentPanel.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1243,6 +1243,7 @@ final class AttachmentPanel: ASDisplayNode, ASScrollViewDelegate {
12431243
}, joinGroupCall: { _ in
12441244
}, presentInviteMembers: {
12451245
}, presentGigagroupHelp: {
1246+
}, openSuggestPost: {
12461247
}, editMessageMedia: { _, _ in
12471248
}, updateShowCommands: { _ in
12481249
}, updateShowSendAsPeers: { _ in

submodules/ChatPresentationInterfaceState/Sources/ChatPanelInterfaceInteraction.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ public final class ChatPanelInterfaceInteraction {
151151
public let joinGroupCall: (CachedChannelData.ActiveCall) -> Void
152152
public let presentInviteMembers: () -> Void
153153
public let presentGigagroupHelp: () -> Void
154+
public let openSuggestPost: () -> Void
154155
public let updateShowCommands: ((Bool) -> Bool) -> Void
155156
public let updateShowSendAsPeers: ((Bool) -> Bool) -> Void
156157
public let openInviteRequests: () -> Void
@@ -267,6 +268,7 @@ public final class ChatPanelInterfaceInteraction {
267268
joinGroupCall: @escaping (CachedChannelData.ActiveCall) -> Void,
268269
presentInviteMembers: @escaping () -> Void,
269270
presentGigagroupHelp: @escaping () -> Void,
271+
openSuggestPost: @escaping () -> Void,
270272
editMessageMedia: @escaping (MessageId, Bool) -> Void,
271273
updateShowCommands: @escaping ((Bool) -> Bool) -> Void,
272274
updateShowSendAsPeers: @escaping ((Bool) -> Bool) -> Void,
@@ -384,6 +386,7 @@ public final class ChatPanelInterfaceInteraction {
384386
self.joinGroupCall = joinGroupCall
385387
self.presentInviteMembers = presentInviteMembers
386388
self.presentGigagroupHelp = presentGigagroupHelp
389+
self.openSuggestPost = openSuggestPost
387390
self.updateShowCommands = updateShowCommands
388391
self.updateShowSendAsPeers = updateShowSendAsPeers
389392
self.openInviteRequests = openInviteRequests
@@ -507,6 +510,7 @@ public final class ChatPanelInterfaceInteraction {
507510
}, joinGroupCall: { _ in
508511
}, presentInviteMembers: {
509512
}, presentGigagroupHelp: {
513+
}, openSuggestPost: {
510514
}, editMessageMedia: { _, _ in
511515
}, updateShowCommands: { _ in
512516
}, updateShowSendAsPeers: { _ in

submodules/TelegramCore/Sources/Account/AccountManager.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,7 @@ private var declaredEncodables: Void = {
228228
declareEncodable(DerivedDataMessageAttribute.self, f: { DerivedDataMessageAttribute(decoder: $0) })
229229
declareEncodable(TelegramApplicationIcons.self, f: { TelegramApplicationIcons(decoder: $0) })
230230
declareEncodable(OutgoingQuickReplyMessageAttribute.self, f: { OutgoingQuickReplyMessageAttribute(decoder: $0) })
231+
declareEncodable(OutgoingSuggestedPostMessageAttribute.self, f: { OutgoingSuggestedPostMessageAttribute(decoder: $0) })
231232
declareEncodable(EffectMessageAttribute.self, f: { EffectMessageAttribute(decoder: $0) })
232233
declareEncodable(FactCheckMessageAttribute.self, f: { FactCheckMessageAttribute(decoder: $0) })
233234
declareEncodable(TelegramMediaPaidContent.self, f: { TelegramMediaPaidContent(decoder: $0) })

submodules/TelegramCore/Sources/PendingMessages/EnqueueMessage.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,8 @@ private func filterMessageAttributesForOutgoingMessage(_ attributes: [MessageAtt
236236
return true
237237
case _ as OutgoingQuickReplyMessageAttribute:
238238
return true
239+
case _ as OutgoingSuggestedPostMessageAttribute:
240+
return true
239241
case _ as EmbeddedMediaStickersMessageAttribute:
240242
return true
241243
case _ as EmojiSearchQueryMessageAttribute:
@@ -275,6 +277,8 @@ private func filterMessageAttributesForForwardedMessage(_ attributes: [MessageAt
275277
return true
276278
case _ as OutgoingQuickReplyMessageAttribute:
277279
return true
280+
case _ as OutgoingSuggestedPostMessageAttribute:
281+
return true
278282
case _ as ForwardOptionsMessageAttribute:
279283
return true
280284
case _ as SendAsMessageAttribute:
@@ -733,6 +737,9 @@ func enqueueMessages(transaction: Transaction, account: Account, peerId: PeerId,
733737
} else if attribute is OutgoingQuickReplyMessageAttribute {
734738
messageNamespace = Namespaces.Message.QuickReplyLocal
735739
effectiveTimestamp = 0
740+
} else if attribute is OutgoingSuggestedPostMessageAttribute {
741+
messageNamespace = Namespaces.Message.SuggestedPostLocal
742+
effectiveTimestamp = 0
736743
} else if let attribute = attribute as? SendAsMessageAttribute {
737744
if let peer = transaction.getPeer(attribute.peerId) {
738745
sendAsPeer = peer
@@ -769,6 +776,9 @@ func enqueueMessages(transaction: Transaction, account: Account, peerId: PeerId,
769776
if messageNamespace != Namespaces.Message.QuickReplyLocal {
770777
attributes.removeAll(where: { $0 is OutgoingQuickReplyMessageAttribute })
771778
}
779+
if messageNamespace != Namespaces.Message.SuggestedPostLocal {
780+
attributes.removeAll(where: { $0 is OutgoingSuggestedPostMessageAttribute })
781+
}
772782

773783
if let peer = peer as? TelegramChannel {
774784
switch peer.info {
@@ -1003,6 +1013,9 @@ func enqueueMessages(transaction: Transaction, account: Account, peerId: PeerId,
10031013
} else if attribute is OutgoingQuickReplyMessageAttribute {
10041014
messageNamespace = Namespaces.Message.QuickReplyLocal
10051015
effectiveTimestamp = 0
1016+
} else if attribute is OutgoingSuggestedPostMessageAttribute {
1017+
messageNamespace = Namespaces.Message.SuggestedPostLocal
1018+
effectiveTimestamp = 0
10061019
} else if let attribute = attribute as? ReplyMessageAttribute {
10071020
if let threadMessageId = attribute.threadMessageId {
10081021
threadId = Int64(threadMessageId.id)
@@ -1035,6 +1048,9 @@ func enqueueMessages(transaction: Transaction, account: Account, peerId: PeerId,
10351048
if messageNamespace != Namespaces.Message.QuickReplyLocal {
10361049
attributes.removeAll(where: { $0 is OutgoingQuickReplyMessageAttribute })
10371050
}
1051+
if messageNamespace != Namespaces.Message.SuggestedPostLocal {
1052+
attributes.removeAll(where: { $0 is OutgoingSuggestedPostMessageAttribute })
1053+
}
10381054

10391055
let (tags, globalTags) = tagsForStoreMessage(incoming: false, attributes: attributes, media: sourceMessage.media, textEntities: entitiesAttribute?.entities, isPinned: false)
10401056

submodules/TelegramCore/Sources/PendingMessages/RequestEditMessage.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,9 @@ private func requestEditMessageInternal(accountPeerId: PeerId, postbox: Postbox,
179179
if messageId.namespace == Namespaces.Message.QuickReplyCloud {
180180
quickReplyShortcutId = Int32(clamping: message.threadId ?? 0)
181181
flags |= Int32(1 << 17)
182+
} else if messageId.namespace == Namespaces.Message.SuggestedPostLocal {
183+
//TODO:release
184+
preconditionFailure()
182185
}
183186

184187
return network.request(Api.functions.messages.editMessage(flags: flags, peer: inputPeer, id: messageId.id, message: text, media: inputMedia, replyMarkup: nil, entities: apiEntities, scheduleDate: effectiveScheduleTime, quickReplyShortcutId: quickReplyShortcutId))

submodules/TelegramCore/Sources/State/AccountViewTracker.swift

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ private func fetchWebpage(account: Account, messageId: MessageId, threadId: Int6
7272
targetMessageNamespace = Namespaces.Message.ScheduledCloud
7373
} else if Namespaces.Message.allQuickReply.contains(messageId.namespace) {
7474
targetMessageNamespace = Namespaces.Message.QuickReplyCloud
75+
} else if Namespaces.Message.allSuggestedPost.contains(messageId.namespace) {
76+
targetMessageNamespace = Namespaces.Message.SuggestedPostCloud
7577
} else {
7678
targetMessageNamespace = Namespaces.Message.Cloud
7779
}
@@ -1071,6 +1073,10 @@ public final class AccountViewTracker {
10711073
} else {
10721074
fetchSignal = .never()
10731075
}
1076+
} else if let messageId = messageIds.first, messageId.namespace == Namespaces.Message.SuggestedPostCloud {
1077+
//TODO:release
1078+
assertionFailure()
1079+
fetchSignal = .never()
10741080
} else if peerIdAndThreadId.peerId.namespace == Namespaces.Peer.CloudUser || peerIdAndThreadId.peerId.namespace == Namespaces.Peer.CloudGroup {
10751081
fetchSignal = account.network.request(Api.functions.messages.getMessages(id: messageIds.map { Api.InputMessage.inputMessageID(id: $0.id) }))
10761082
} else if peerIdAndThreadId.peerId.namespace == Namespaces.Peer.CloudChannel {
@@ -2120,6 +2126,36 @@ public final class AccountViewTracker {
21202126
}
21212127
return signal
21222128
}
2129+
2130+
public func postSuggestionsViewForLocation(peerId: EnginePeer.Id, additionalData: [AdditionalMessageHistoryViewData] = []) -> Signal<(MessageHistoryView, ViewUpdateType, InitialMessageHistoryData?), NoError> {
2131+
guard let account = self.account else {
2132+
return .never()
2133+
}
2134+
let chatLocation: ChatLocationInput = .peer(peerId: peerId, threadId: nil)
2135+
let signal = account.postbox.aroundMessageHistoryViewForLocation(chatLocation, anchor: .upperBound, ignoreMessagesInTimestampRange: nil, ignoreMessageIds: Set(), count: 200, fixedCombinedReadStates: nil, topTaggedMessageIdNamespaces: [], tag: nil, appendMessagesFromTheSameGroup: false, namespaces: .just(Namespaces.Message.allSuggestedPost), orderStatistics: [], additionalData: additionalData)
2136+
return withState(signal, { [weak self] () -> Int32 in
2137+
if let strongSelf = self {
2138+
return OSAtomicIncrement32(&strongSelf.nextViewId)
2139+
} else {
2140+
return -1
2141+
}
2142+
}, next: { [weak self] next, viewId in
2143+
if let strongSelf = self {
2144+
strongSelf.queue.async {
2145+
let (messageIds, localWebpages) = pendingWebpages(entries: next.0.entries)
2146+
strongSelf.updatePendingWebpages(viewId: viewId, threadId: nil, messageIds: messageIds, localWebpages: localWebpages)
2147+
strongSelf.historyViewStateValidationContexts.updateView(id: viewId, view: next.0, location: chatLocation)
2148+
}
2149+
}
2150+
}, disposed: { [weak self] viewId in
2151+
if let strongSelf = self {
2152+
strongSelf.queue.async {
2153+
strongSelf.updatePendingWebpages(viewId: viewId, threadId: nil, messageIds: [], localWebpages: [:])
2154+
strongSelf.historyViewStateValidationContexts.updateView(id: viewId, view: nil, location: nil)
2155+
}
2156+
}
2157+
})
2158+
}
21232159

21242160
public func aroundMessageOfInterestHistoryViewForLocation(_ chatLocation: ChatLocationInput, ignoreMessagesInTimestampRange: ClosedRange<Int32>? = nil, ignoreMessageIds: Set<MessageId> = Set(), count: Int, tag: HistoryViewInputTag? = nil, appendMessagesFromTheSameGroup: Bool = false, orderStatistics: MessageHistoryViewOrderStatistics = [], additionalData: [AdditionalMessageHistoryViewData] = [], useRootInterfaceStateForThread: Bool = false) -> Signal<(MessageHistoryView, ViewUpdateType, InitialMessageHistoryData?), NoError> {
21252161
if let account = self.account {

submodules/TelegramCore/Sources/State/ApplyUpdateMessage.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,14 @@ func applyUpdateMessage(postbox: Postbox, stateManager: AccountStateManager, mes
198198
}
199199
}
200200
}
201+
if Namespaces.Message.allSuggestedPost.contains(message.id.namespace) {
202+
for i in 0 ..< updatedAttributes.count {
203+
if updatedAttributes[i] is OutgoingSuggestedPostMessageAttribute {
204+
updatedAttributes.remove(at: i)
205+
break
206+
}
207+
}
208+
}
201209

202210
attributes = updatedAttributes
203211
text = currentMessage.text
@@ -220,6 +228,8 @@ func applyUpdateMessage(postbox: Postbox, stateManager: AccountStateManager, mes
220228
}
221229
if Namespaces.Message.allQuickReply.contains(message.id.namespace) {
222230
namespace = Namespaces.Message.QuickReplyCloud
231+
} else if Namespaces.Message.allSuggestedPost.contains(message.id.namespace) {
232+
namespace = Namespaces.Message.SuggestedPostCloud
223233
} else if let updatedTimestamp = updatedTimestamp {
224234
if attributes.contains(where: { $0 is PendingProcessingMessageAttribute }) {
225235
namespace = Namespaces.Message.ScheduledCloud
@@ -243,6 +253,8 @@ func applyUpdateMessage(postbox: Postbox, stateManager: AccountStateManager, mes
243253
if let threadId {
244254
_internal_applySentQuickReplyMessage(transaction: transaction, shortcut: attribute.shortcut, quickReplyId: Int32(clamping: threadId))
245255
}
256+
} else if attribute is OutgoingSuggestedPostMessageAttribute {
257+
//TODO:release
246258
}
247259
}
248260

@@ -397,6 +409,8 @@ func applyUpdateGroupMessages(postbox: Postbox, stateManager: AccountStateManage
397409
var namespace = Namespaces.Message.Cloud
398410
if Namespaces.Message.allQuickReply.contains(messages[0].id.namespace) {
399411
namespace = Namespaces.Message.QuickReplyCloud
412+
} else if Namespaces.Message.allSuggestedPost.contains(messages[0].id.namespace) {
413+
namespace = Namespaces.Message.SuggestedPostCloud
400414
} else if let message = messages.first, let apiMessage = result.messages.first {
401415
if message.scheduleTime != nil && message.scheduleTime == apiMessage.timestamp {
402416
namespace = Namespaces.Message.ScheduledCloud
@@ -474,6 +488,8 @@ func applyUpdateGroupMessages(postbox: Postbox, stateManager: AccountStateManage
474488
if let threadId = updatedMessage.threadId {
475489
_internal_applySentQuickReplyMessage(transaction: transaction, shortcut: attribute.shortcut, quickReplyId: Int32(clamping: threadId))
476490
}
491+
} else if attribute is OutgoingSuggestedPostMessageAttribute {
492+
//TODO:release
477493
}
478494
}
479495
}

submodules/TelegramCore/Sources/State/CloudChatRemoveMessagesOperation.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,25 @@ func cloudChatAddClearHistoryOperation(transaction: Transaction, peerId: PeerId,
3535
} else if case .forEveryone = type {
3636
transaction.operationLogAddEntry(peerId: peerId, tag: OperationLogTags.CloudChatRemoveMessages, tagLocalIndex: .automatic, tagMergedIndex: .automatic, contents: CloudChatClearHistoryOperation(peerId: peerId, topMessageId: MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: .max), threadId: threadId, minTimestamp: minTimestamp, maxTimestamp: maxTimestamp, type: type))
3737
}
38+
} else if type == .suggestedPostMessages {
39+
var messageIds: [MessageId] = []
40+
transaction.withAllMessages(peerId: peerId, namespace: Namespaces.Message.SuggestedPostCloud) { message -> Bool in
41+
messageIds.append(message.id)
42+
return true
43+
}
44+
cloudChatAddRemoveMessagesOperation(transaction: transaction, peerId: peerId, threadId: threadId, messageIds: messageIds, type: .forLocalPeer)
45+
46+
let topMessageId: MessageId?
47+
if let explicitTopMessageId = explicitTopMessageId {
48+
topMessageId = explicitTopMessageId
49+
} else {
50+
topMessageId = transaction.getTopPeerMessageId(peerId: peerId, namespace: Namespaces.Message.SuggestedPostCloud)
51+
}
52+
if let topMessageId = topMessageId {
53+
transaction.operationLogAddEntry(peerId: peerId, tag: OperationLogTags.CloudChatRemoveMessages, tagLocalIndex: .automatic, tagMergedIndex: .automatic, contents: CloudChatClearHistoryOperation(peerId: peerId, topMessageId: topMessageId, threadId: threadId, minTimestamp: minTimestamp, maxTimestamp: maxTimestamp, type: type))
54+
} else if case .forEveryone = type {
55+
transaction.operationLogAddEntry(peerId: peerId, tag: OperationLogTags.CloudChatRemoveMessages, tagLocalIndex: .automatic, tagMergedIndex: .automatic, contents: CloudChatClearHistoryOperation(peerId: peerId, topMessageId: MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: .max), threadId: threadId, minTimestamp: minTimestamp, maxTimestamp: maxTimestamp, type: type))
56+
}
3857
} else {
3958
let topMessageId: MessageId?
4059
if let explicitTopMessageId = explicitTopMessageId {

0 commit comments

Comments
 (0)