Skip to content

Commit e77402d

Browse files
author
Isaac
committed
[WIP] Chatlist suggestions
1 parent 084bb5b commit e77402d

File tree

18 files changed

+334
-27
lines changed

18 files changed

+334
-27
lines changed

submodules/ChatListUI/Sources/ChatListSearchListPaneNode.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3368,6 +3368,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
33683368
}, openAdInfo: { node, adPeer in
33693369
interaction.openAdInfo(node, adPeer)
33703370
}, openAccountFreezeInfo: {
3371+
}, openUrl: { _ in
33713372
})
33723373
chatListInteraction.isSearchMode = true
33733374

@@ -5363,6 +5364,7 @@ public final class ChatListSearchShimmerNode: ASDisplayNode {
53635364
}, openPhotoSetup: {
53645365
}, openAdInfo: { _, _ in
53655366
}, openAccountFreezeInfo: {
5367+
}, openUrl: { _ in
53665368
})
53675369
var isInlineMode = false
53685370
if case .topics = key {

submodules/ChatListUI/Sources/ChatListShimmerNode.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ public final class ChatListShimmerNode: ASDisplayNode {
163163
}, openPhotoSetup: {
164164
}, openAdInfo: { _, _ in
165165
}, openAccountFreezeInfo: {
166+
}, openUrl: { _ in
166167
})
167168
interaction.isInlineMode = isInlineMode
168169

submodules/ChatListUI/Sources/Node/ChatListNode.swift

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ public final class ChatListNodeInteraction {
116116
let openPhotoSetup: () -> Void
117117
let openAdInfo: (ASDisplayNode, AdPeer) -> Void
118118
let openAccountFreezeInfo: () -> Void
119+
let openUrl: (String) -> Void
119120

120121
public var searchTextHighightState: String?
121122
var highlightedChatLocation: ChatListHighlightedLocation?
@@ -175,7 +176,8 @@ public final class ChatListNodeInteraction {
175176
openWebApp: @escaping (TelegramUser) -> Void,
176177
openPhotoSetup: @escaping () -> Void,
177178
openAdInfo: @escaping (ASDisplayNode, AdPeer) -> Void,
178-
openAccountFreezeInfo: @escaping () -> Void
179+
openAccountFreezeInfo: @escaping () -> Void,
180+
openUrl: @escaping (String) -> Void
179181
) {
180182
self.activateSearch = activateSearch
181183
self.peerSelected = peerSelected
@@ -223,6 +225,7 @@ public final class ChatListNodeInteraction {
223225
self.openPhotoSetup = openPhotoSetup
224226
self.openAdInfo = openAdInfo
225227
self.openAccountFreezeInfo = openAccountFreezeInfo
228+
self.openUrl = openUrl
226229
}
227230
}
228231

@@ -775,6 +778,8 @@ private func mappedInsertEntries(context: AccountContext, nodeInteraction: ChatL
775778
nodeInteraction?.openPhotoSetup()
776779
case .accountFreeze:
777780
nodeInteraction?.openAccountFreezeInfo()
781+
case let .link(url, _, _):
782+
nodeInteraction?.openUrl(url)
778783
}
779784
case .hide:
780785
nodeInteraction?.dismissNotice(notice)
@@ -1123,6 +1128,8 @@ private func mappedUpdateEntries(context: AccountContext, nodeInteraction: ChatL
11231128
nodeInteraction?.openPhotoSetup()
11241129
case .accountFreeze:
11251130
nodeInteraction?.openAccountFreezeInfo()
1131+
case let .link(url, _, _):
1132+
nodeInteraction?.openUrl(url)
11261133
}
11271134
case .hide:
11281135
nodeInteraction?.dismissNotice(notice)
@@ -1906,6 +1913,12 @@ public final class ChatListNode: ListView {
19061913
self?.openAdInfo?(node, adPeer)
19071914
}, openAccountFreezeInfo: { [weak self] in
19081915
self?.openAccountFreezeInfo?()
1916+
}, openUrl: { [weak self] url in
1917+
guard let self else {
1918+
return
1919+
}
1920+
let presentationData = self.context.sharedContext.currentPresentationData.with { $0 }
1921+
context.sharedContext.openExternalUrl(context: self.context, urlContext: .generic, url: url, forceExternal: false, presentationData: presentationData, navigationController: self.context.sharedContext.mainWindow?.viewController as? NavigationController, dismissInput: {})
19091922
})
19101923
nodeInteraction.isInlineMode = isInlineMode
19111924

@@ -2134,6 +2147,8 @@ public final class ChatListNode: ListView {
21342147
}
21352148
return .birthdayPremiumGift(peers: todayBirthdayPeers, birthdays: birthdays)
21362149
}
2150+
} else if case let .link(url, title, subtitle) = suggestions.first(where: { if case .link = $0 { return true } else { return false} }) {
2151+
return .single(.link(url: url, title: title, subtitle: subtitle))
21372152
} else {
21382153
return .single(nil)
21392154
}

submodules/ChatListUI/Sources/Node/ChatListNodeEntries.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ public enum ChatListNotice: Equatable {
9393
case starsSubscriptionLowBalance(amount: StarsAmount, peers: [EnginePeer])
9494
case setupPhoto(EnginePeer)
9595
case accountFreeze
96+
case link(url: String, title: String, subtitle: String)
9697
}
9798

9899
enum ChatListNodeEntry: Comparable, Identifiable {

submodules/ChatListUI/Sources/Node/ChatListNoticeItem.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,9 @@ final class ChatListNoticeItemNode: ItemListRevealOptionsItemNode {
291291
case .accountFreeze:
292292
titleString = NSAttributedString(string: item.strings.ChatList_FrozenAccount_Title, font: titleFont, textColor: item.theme.list.itemDestructiveColor)
293293
textString = NSAttributedString(string: item.strings.ChatList_FrozenAccount_Text, font: smallTextFont, textColor: item.theme.rootController.navigationBar.secondaryTextColor)
294+
case let .link(_, title, subtitle):
295+
titleString = NSAttributedString(string: title, font: titleFont, textColor: item.theme.list.itemPrimaryTextColor)
296+
textString = NSAttributedString(string: subtitle, font: smallTextFont, textColor: item.theme.rootController.navigationBar.secondaryTextColor)
294297
}
295298

296299
var leftInset: CGFloat = sideInset
@@ -383,7 +386,7 @@ final class ChatListNoticeItemNode: ItemListRevealOptionsItemNode {
383386

384387
let hasCloseButton: Bool
385388
switch item.notice {
386-
case .xmasPremiumGift, .setupBirthday, .birthdayPremiumGift, .premiumGrace, .starsSubscriptionLowBalance, .setupPhoto:
389+
case .xmasPremiumGift, .setupBirthday, .birthdayPremiumGift, .premiumGrace, .starsSubscriptionLowBalance, .setupPhoto, .link:
387390
hasCloseButton = true
388391
default:
389392
hasCloseButton = false

submodules/SettingsUI/Sources/Text Size/TextSizeSelectionController.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ private final class TextSizeSelectionControllerNode: ASDisplayNode, ASScrollView
234234
}, openPhotoSetup: {
235235
}, openAdInfo: { _, _ in
236236
}, openAccountFreezeInfo: {
237+
}, openUrl: { _ in
237238
})
238239

239240
let chatListPresentationData = ChatListPresentationData(theme: self.presentationData.theme, fontSize: self.presentationData.listsFontSize, strings: self.presentationData.strings, dateTimeFormat: self.presentationData.dateTimeFormat, nameSortOrder: self.presentationData.nameSortOrder, nameDisplayOrder: self.presentationData.nameDisplayOrder, disableAnimations: true)

submodules/SettingsUI/Sources/Themes/ThemePreviewControllerNode.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,7 @@ final class ThemePreviewControllerNode: ASDisplayNode, ASScrollViewDelegate {
383383
}, openPhotoSetup: {
384384
}, openAdInfo: { _, _ in
385385
}, openAccountFreezeInfo: {
386+
}, openUrl: { _ in
386387
})
387388

388389
func makeChatListItem(

submodules/TelegramCore/Sources/State/ManagedProxyInfoUpdates.swift

Lines changed: 127 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,112 @@ public final class PromoChatListItem: AdditionalChatListItem {
7272
}
7373
}
7474

75+
76+
public final class ServerSuggestionInfo: Codable, Equatable {
77+
public final class Item: Codable, Equatable {
78+
public final class Text: Codable, Equatable {
79+
public let string: String
80+
public let entities: [MessageTextEntity]
81+
82+
public init(string: String, entities: [MessageTextEntity]) {
83+
self.string = string
84+
self.entities = entities
85+
}
86+
87+
public static func ==(lhs: Text, rhs: Text) -> Bool {
88+
if lhs.string != rhs.string {
89+
return false
90+
}
91+
if lhs.entities != rhs.entities {
92+
return false
93+
}
94+
return true
95+
}
96+
}
97+
98+
public enum Action: Codable, Equatable {
99+
private enum CodingKeys: String, CodingKey {
100+
case link
101+
}
102+
103+
case link(url: String)
104+
105+
public init(from decoder: any Decoder) throws {
106+
let container = try decoder.container(keyedBy: CodingKeys.self)
107+
self = .link(url: try container.decode(String.self, forKey: .link))
108+
}
109+
}
110+
111+
public let id: String
112+
public let title: Text
113+
public let text: Text
114+
public let action: Action
115+
116+
public init(id: String, title: Text, text: Text, action: Action) {
117+
self.id = id
118+
self.title = title
119+
self.text = text
120+
self.action = action
121+
}
122+
123+
public static func ==(lhs: Item, rhs: Item) -> Bool {
124+
if lhs.id != rhs.id {
125+
return false
126+
}
127+
if lhs.title != rhs.title {
128+
return false
129+
}
130+
if lhs.text != rhs.text {
131+
return false
132+
}
133+
if lhs.action != rhs.action {
134+
return false
135+
}
136+
return true
137+
}
138+
}
139+
140+
public let legacyItems: [String]
141+
public let items: [Item]
142+
public let dismissedIds: [String]
143+
144+
public init(legacyItems: [String], items: [Item], dismissedIds: [String]) {
145+
self.legacyItems = legacyItems
146+
self.items = items
147+
self.dismissedIds = dismissedIds
148+
}
149+
150+
public static func ==(lhs: ServerSuggestionInfo, rhs: ServerSuggestionInfo) -> Bool {
151+
if lhs.items != rhs.items {
152+
return false
153+
}
154+
return true
155+
}
156+
}
157+
158+
extension ServerSuggestionInfo.Item.Text {
159+
convenience init(_ apiText: Api.TextWithEntities) {
160+
switch apiText {
161+
case let .textWithEntities(text, entities):
162+
self.init(string: text, entities: messageTextEntitiesFromApiEntities(entities))
163+
}
164+
}
165+
}
166+
167+
extension ServerSuggestionInfo.Item {
168+
convenience init(_ apiItem: Api.PendingSuggestion) {
169+
switch apiItem {
170+
case let .pendingSuggestion(suggestion, title, description, url):
171+
self.init(
172+
id: suggestion,
173+
title: ServerSuggestionInfo.Item.Text(title),
174+
text: ServerSuggestionInfo.Item.Text(description),
175+
action: .link(url: url)
176+
)
177+
}
178+
}
179+
}
180+
75181
func managedPromoInfoUpdates(accountPeerId: PeerId, postbox: Postbox, network: Network, viewTracker: AccountViewTracker) -> Signal<Void, NoError> {
76182
return Signal { subscriber in
77183
let queue = Queue()
@@ -88,24 +194,38 @@ func managedPromoInfoUpdates(accountPeerId: PeerId, postbox: Postbox, network: N
88194
switch data {
89195
case .promoDataEmpty:
90196
transaction.replaceAdditionalChatListItems([])
91-
case let .promoData(_, _, peer, chats, users, psaType, psaMessage):
92-
let parsedPeers = AccumulatedPeers(transaction: transaction, chats: chats, users: users)
197+
case let .promoData(flags, expires, peer, psaType, psaMessage, pendingSuggestions, dismissedSuggestions, customPendingSuggestion, chats, users):
198+
let _ = expires
93199

200+
let parsedPeers = AccumulatedPeers(transaction: transaction, chats: chats, users: users)
94201
updatePeers(transaction: transaction, accountPeerId: accountPeerId, peers: parsedPeers)
95202

96-
let kind: PromoChatListItem.Kind
97-
if let psaType = psaType {
203+
var kind: PromoChatListItem.Kind?
204+
if let psaType {
98205
kind = .psa(type: psaType, message: psaMessage)
99-
} else {
206+
} else if ((flags & 1) << 0) != 0 {
100207
kind = .proxy
101208
}
102209

103210
var additionalChatListItems: [AdditionalChatListItem] = []
104-
if let parsedPeer = transaction.getPeer(peer.peerId) {
211+
if let kind, let peer, let parsedPeer = transaction.getPeer(peer.peerId) {
105212
additionalChatListItems.append(PromoChatListItem(peerId: parsedPeer.id, kind: kind))
106213
}
107-
108214
transaction.replaceAdditionalChatListItems(additionalChatListItems)
215+
216+
var customItems: [ServerSuggestionInfo.Item] = []
217+
if let customPendingSuggestion {
218+
customItems.append(ServerSuggestionInfo.Item(customPendingSuggestion))
219+
}
220+
let suggestionInfo = ServerSuggestionInfo(
221+
legacyItems: pendingSuggestions,
222+
items: customItems,
223+
dismissedIds: dismissedSuggestions
224+
)
225+
226+
transaction.updatePreferencesEntry(key: PreferencesKeys.serverSuggestionInfo(), { _ in
227+
return PreferencesEntry(suggestionInfo)
228+
})
109229
}
110230
}
111231
}

0 commit comments

Comments
 (0)