Various improvements

This commit is contained in:
Ilya Laktyushin 2022-10-15 21:08:11 +03:00
parent da4934dc97
commit 59b593696e
54 changed files with 379 additions and 236 deletions

View File

@ -135,7 +135,7 @@ func personWithUser(stableId: String, user: TelegramUser) -> INPerson {
let personHandle: INPersonHandle
if let phone = user.phone {
personHandle = INPersonHandle(value: formatPhoneNumber(phone), type: .phoneNumber)
} else if let username = user.username {
} else if let username = user.addressName {
personHandle = INPersonHandle(value: "@\(username)", type: .unknown)
} else {
personHandle = INPersonHandle(value: user.nameOrPhone, type: .unknown)

View File

@ -790,7 +790,7 @@ class DefaultIntentHandler: INExtension, INSendMessageIntentHandling, INSearchFo
accountResults.append(accountTransaction(rootPath: rootPath, id: accountId, encryptionParameters: encryptionParameters, isReadOnly: true, useCopy: false, transaction: { postbox, transaction -> INObjectSection<Friend> in
var accountTitle: String = ""
if let peer = transaction.getPeer(accountPeerId) as? TelegramUser {
if let username = peer.username, !username.isEmpty {
if let username = peer.addressName, !username.isEmpty {
accountTitle = "@\(username)"
} else {
accountTitle = peer.debugDisplayTitle
@ -963,7 +963,7 @@ private final class WidgetIntentHandler {
accountResults.append(accountTransaction(rootPath: rootPath, id: accountId, encryptionParameters: encryptionParameters, isReadOnly: true, useCopy: false, transaction: { postbox, transaction -> INObjectSection<Friend> in
var accountTitle: String = ""
if let peer = transaction.getPeer(accountPeerId) as? TelegramUser {
if let username = peer.username, !username.isEmpty {
if let username = peer.addressName, !username.isEmpty {
accountTitle = "@\(username)"
} else {
accountTitle = peer.debugDisplayTitle

View File

@ -129,7 +129,7 @@ private func callWithTelegramMessage(_ telegramMessage: Message, account: Accoun
if #available(iOSApplicationExtension 10.2, iOS 10.2, *) {
var type: INPersonHandleType
var label: INPersonHandleLabel?
if let username = user.username {
if let username = user.addressName {
label = INPersonHandleLabel(rawValue: "@\(username)")
type = .unknown
} else if let phone = user.phone {
@ -168,7 +168,7 @@ private func messageWithTelegramMessage(_ telegramMessage: Message) -> INMessage
if #available(iOSApplicationExtension 10.2, iOS 10.2, *) {
var type: INPersonHandleType
var label: INPersonHandleLabel?
if let username = user.username {
if let username = user.addressName {
label = INPersonHandleLabel(rawValue: "@\(username)")
type = .unknown
} else if let phone = user.phone {

View File

@ -737,7 +737,7 @@ public protocol SharedAccountContext: AnyObject {
func makePrivacyAndSecurityController(context: AccountContext) -> ViewController
func navigateToChatController(_ params: NavigateToChatControllerParams)
func navigateToForumChannel(context: AccountContext, peerId: EnginePeer.Id, navigationController: NavigationController)
func navigateToForumThread(context: AccountContext, peerId: EnginePeer.Id, threadId: Int64, navigationController: NavigationController, activateInput: ChatControllerActivateInput?) -> Signal<Never, NoError>
func navigateToForumThread(context: AccountContext, peerId: EnginePeer.Id, threadId: Int64, messageId: EngineMessage.Id?, navigationController: NavigationController, activateInput: ChatControllerActivateInput?) -> Signal<Never, NoError>
func openStorageUsage(context: AccountContext)
func openLocationScreen(context: AccountContext, messageId: MessageId, navigationController: NavigationController)
func openExternalUrl(context: AccountContext, urlContext: OpenURLContext, url: String, forceExternal: Bool, presentationData: PresentationData, navigationController: NavigationController?, dismissInput: @escaping () -> Void)

View File

@ -1362,7 +1362,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
strongSelf.context.sharedContext.navigateToForumChannel(context: strongSelf.context, peerId: channel.id, navigationController: navigationController)
} else {
if let threadId = threadId {
let _ = strongSelf.context.sharedContext.navigateToForumThread(context: strongSelf.context, peerId: peer.id, threadId: threadId, navigationController: navigationController, activateInput: nil).start()
let _ = strongSelf.context.sharedContext.navigateToForumThread(context: strongSelf.context, peerId: peer.id, threadId: threadId, messageId: nil, navigationController: navigationController, activateInput: nil).start()
strongSelf.chatListDisplayNode.containerNode.currentItemNode.clearHighlightAnimated(true)
} else {
var navigationAnimationOptions: NavigationAnimationOptions = []
@ -1462,11 +1462,15 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
if case .chatList(.root) = strongSelf.location {
navigationAnimationOptions = .removeOnMasterDetails
}
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(id: actualPeerId), subject: .message(id: .id(messageId), highlight: true, timecode: nil), purposefulAction: {
if deactivateOnAction {
self?.deactivateSearch(animated: false)
}
}, scrollToEndIfExists: scrollToEndIfExists, options: navigationAnimationOptions))
if let threadId = threadId {
let _ = strongSelf.context.sharedContext.navigateToForumThread(context: strongSelf.context, peerId: peer.id, threadId: threadId, messageId: messageId, navigationController: navigationController, activateInput: nil).start()
} else {
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(id: actualPeerId), subject: .message(id: .id(messageId), highlight: true, timecode: nil), purposefulAction: {
if deactivateOnAction {
self?.deactivateSearch(animated: false)
}
}, scrollToEndIfExists: scrollToEndIfExists, options: navigationAnimationOptions))
}
strongSelf.chatListDisplayNode.containerNode.currentItemNode.clearHighlightAnimated(true)
}
}
@ -1474,7 +1478,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
}
}
self.chatListDisplayNode.requestOpenPeerFromSearch = { [weak self] peer, dismissSearch in
self.chatListDisplayNode.requestOpenPeerFromSearch = { [weak self] peer, threadId, dismissSearch in
if let strongSelf = self {
let storedPeer = strongSelf.context.engine.peers.ensurePeerIsLocallyAvailable(peer: peer) |> map { _ -> Void in return Void() }
strongSelf.openMessageFromSearchDisposable.set((storedPeer |> deliverOnMainQueue).start(completed: { [weak strongSelf] in
@ -1491,9 +1495,13 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
if case .chatList(.root) = strongSelf.location {
navigationAnimationOptions = .removeOnMasterDetails
}
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(id: peer.id), purposefulAction: { [weak self] in
self?.deactivateSearch(animated: false)
}, scrollToEndIfExists: scrollToEndIfExists, options: navigationAnimationOptions))
if let threadId = threadId {
let _ = strongSelf.context.sharedContext.navigateToForumThread(context: strongSelf.context, peerId: peer.id, threadId: threadId, messageId: nil, navigationController: navigationController, activateInput: nil).start()
} else {
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(id: peer.id), purposefulAction: { [weak self] in
self?.deactivateSearch(animated: false)
}, scrollToEndIfExists: scrollToEndIfExists, options: navigationAnimationOptions))
}
strongSelf.chatListDisplayNode.containerNode.currentItemNode.clearHighlightAnimated(true)
}
}
@ -1584,7 +1592,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
let _ = (context.engine.peers.createForumChannelTopic(id: peerId, title: title, iconColor: availableColors.randomElement()!, iconFileId: fileId)
|> deliverOnMainQueue).start(next: { topicId in
let _ = context.sharedContext.navigateToForumThread(context: context, peerId: peerId, threadId: topicId, navigationController: navigationController, activateInput: .text).start()
let _ = context.sharedContext.navigateToForumThread(context: context, peerId: peerId, threadId: topicId, messageId: nil, navigationController: navigationController, activateInput: .text).start()
})
}
strongSelf.push(controller)
@ -2591,7 +2599,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
let _ = (context.engine.peers.createForumChannelTopic(id: peerId, title: title, iconColor: availableColors.randomElement()!, iconFileId: fileId)
|> deliverOnMainQueue).start(next: { topicId in
if let navigationController = (sourceController.navigationController as? NavigationController) {
let _ = context.sharedContext.navigateToForumThread(context: context, peerId: peerId, threadId: topicId, navigationController: navigationController, activateInput: .text).start()
let _ = context.sharedContext.navigateToForumThread(context: context, peerId: peerId, threadId: topicId, messageId: nil, navigationController: navigationController, activateInput: .text).start()
}
})
}

View File

@ -1135,7 +1135,7 @@ final class ChatListControllerNode: ASDisplayNode {
private var containerLayout: (ContainerViewLayout, CGFloat, CGFloat, CGFloat)?
var requestDeactivateSearch: (() -> Void)?
var requestOpenPeerFromSearch: ((EnginePeer, Bool) -> Void)?
var requestOpenPeerFromSearch: ((EnginePeer, Int64?, Bool) -> Void)?
var requestOpenRecentPeerOptions: ((EnginePeer) -> Void)?
var requestOpenMessageFromSearch: ((EnginePeer, Int64?, EngineMessage.Id, Bool) -> Void)?
var requestAddContact: ((String) -> Void)?
@ -1311,8 +1311,8 @@ final class ChatListControllerNode: ASDisplayNode {
let filter: ChatListNodePeersFilter = []
let contentNode = ChatListSearchContainerNode(context: self.context, animationCache: self.animationCache, animationRenderer: self.animationRenderer, filter: filter, location: location, displaySearchFilters: displaySearchFilters, hasDownloads: hasDownloads, initialFilter: initialFilter, openPeer: { [weak self] peer, _, dismissSearch in
self?.requestOpenPeerFromSearch?(peer, dismissSearch)
let contentNode = ChatListSearchContainerNode(context: self.context, animationCache: self.animationCache, animationRenderer: self.animationRenderer, filter: filter, location: location, displaySearchFilters: displaySearchFilters, hasDownloads: hasDownloads, initialFilter: initialFilter, openPeer: { [weak self] peer, _, threadId, dismissSearch in
self?.requestOpenPeerFromSearch?(peer, threadId, dismissSearch)
}, openDisabledPeer: { _ in
}, openRecentPeerOptions: { [weak self] peer in
self?.requestOpenRecentPeerOptions?(peer)

View File

@ -43,7 +43,7 @@ private enum ChatListTokenId: Int32 {
}
final class ChatListSearchInteraction {
let openPeer: (EnginePeer, EnginePeer?, Bool) -> Void
let openPeer: (EnginePeer, EnginePeer?, Int64?, Bool) -> Void
let openDisabledPeer: (EnginePeer) -> Void
let openMessage: (EnginePeer, Int64?, EngineMessage.Id, Bool) -> Void
let openUrl: (String) -> Void
@ -57,7 +57,7 @@ final class ChatListSearchInteraction {
let dismissInput: () -> Void
let getSelectedMessageIds: () -> Set<EngineMessage.Id>?
init(openPeer: @escaping (EnginePeer, EnginePeer?, Bool) -> Void, openDisabledPeer: @escaping (EnginePeer) -> Void, openMessage: @escaping (EnginePeer, Int64?, EngineMessage.Id, Bool) -> Void, openUrl: @escaping (String) -> Void, clearRecentSearch: @escaping () -> Void, addContact: @escaping (String) -> Void, toggleMessageSelection: @escaping (EngineMessage.Id, Bool) -> Void, messageContextAction: @escaping ((EngineMessage, ASDisplayNode?, CGRect?, UIGestureRecognizer?, ChatListSearchPaneKey, (id: String, size: Int64, isFirstInList: Bool)?) -> Void), mediaMessageContextAction: @escaping ((EngineMessage, ASDisplayNode?, CGRect?, UIGestureRecognizer?) -> Void), peerContextAction: ((EnginePeer, ChatListSearchContextActionSource, ASDisplayNode, ContextGesture?, CGPoint?) -> Void)?, present: @escaping (ViewController, Any?) -> Void, dismissInput: @escaping () -> Void, getSelectedMessageIds: @escaping () -> Set<EngineMessage.Id>?) {
init(openPeer: @escaping (EnginePeer, EnginePeer?, Int64?, Bool) -> Void, openDisabledPeer: @escaping (EnginePeer) -> Void, openMessage: @escaping (EnginePeer, Int64?, EngineMessage.Id, Bool) -> Void, openUrl: @escaping (String) -> Void, clearRecentSearch: @escaping () -> Void, addContact: @escaping (String) -> Void, toggleMessageSelection: @escaping (EngineMessage.Id, Bool) -> Void, messageContextAction: @escaping ((EngineMessage, ASDisplayNode?, CGRect?, UIGestureRecognizer?, ChatListSearchPaneKey, (id: String, size: Int64, isFirstInList: Bool)?) -> Void), mediaMessageContextAction: @escaping ((EngineMessage, ASDisplayNode?, CGRect?, UIGestureRecognizer?) -> Void), peerContextAction: ((EnginePeer, ChatListSearchContextActionSource, ASDisplayNode, ContextGesture?, CGPoint?) -> Void)?, present: @escaping (ViewController, Any?) -> Void, dismissInput: @escaping () -> Void, getSelectedMessageIds: @escaping () -> Set<EngineMessage.Id>?) {
self.openPeer = openPeer
self.openDisabledPeer = openDisabledPeer
self.openMessage = openMessage
@ -133,7 +133,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
private var validLayout: (ContainerViewLayout, CGFloat)?
public init(context: AccountContext, animationCache: AnimationCache, animationRenderer: MultiAnimationRenderer, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, filter: ChatListNodePeersFilter, location: ChatListControllerLocation, displaySearchFilters: Bool, hasDownloads: Bool, initialFilter: ChatListSearchFilter = .chats, openPeer originalOpenPeer: @escaping (EnginePeer, EnginePeer?, Bool) -> Void, openDisabledPeer: @escaping (EnginePeer) -> Void, openRecentPeerOptions: @escaping (EnginePeer) -> Void, openMessage originalOpenMessage: @escaping (EnginePeer, Int64?, EngineMessage.Id, Bool) -> Void, addContact: ((String) -> Void)?, peerContextAction: ((EnginePeer, ChatListSearchContextActionSource, ASDisplayNode, ContextGesture?, CGPoint?) -> Void)?, present: @escaping (ViewController, Any?) -> Void, presentInGlobalOverlay: @escaping (ViewController, Any?) -> Void, navigationController: NavigationController?) {
public init(context: AccountContext, animationCache: AnimationCache, animationRenderer: MultiAnimationRenderer, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, filter: ChatListNodePeersFilter, location: ChatListControllerLocation, displaySearchFilters: Bool, hasDownloads: Bool, initialFilter: ChatListSearchFilter = .chats, openPeer originalOpenPeer: @escaping (EnginePeer, EnginePeer?, Int64?, Bool) -> Void, openDisabledPeer: @escaping (EnginePeer) -> Void, openRecentPeerOptions: @escaping (EnginePeer) -> Void, openMessage originalOpenMessage: @escaping (EnginePeer, Int64?, EngineMessage.Id, Bool) -> Void, addContact: ((String) -> Void)?, peerContextAction: ((EnginePeer, ChatListSearchContextActionSource, ASDisplayNode, ContextGesture?, CGPoint?) -> Void)?, present: @escaping (ViewController, Any?) -> Void, presentInGlobalOverlay: @escaping (ViewController, Any?) -> Void, navigationController: NavigationController?) {
self.context = context
self.peersFilter = filter
self.location = location
@ -159,8 +159,8 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
self.addSubnode(self.paneContainerNode)
let interaction = ChatListSearchInteraction(openPeer: { peer, chatPeer, value in
originalOpenPeer(peer, chatPeer, value)
let interaction = ChatListSearchInteraction(openPeer: { peer, chatPeer, threadId, value in
originalOpenPeer(peer, chatPeer, threadId, value)
if peer.id.namespace != Namespaces.Peer.SecretChat {
addAppLogEvent(postbox: context.account.postbox, type: "search_global_open_peer", peerId: peer.id)
}

View File

@ -463,23 +463,23 @@ public enum ChatListSearchEntry: Comparable, Identifiable {
public func item(context: AccountContext, presentationData: PresentationData, enableHeaders: Bool, filter: ChatListNodePeersFilter, location: ChatListControllerLocation, key: ChatListSearchPaneKey, tagMask: EngineMessage.Tags?, interaction: ChatListNodeInteraction, listInteraction: ListMessageItemInteraction, peerContextAction: ((EnginePeer, ChatListSearchContextActionSource, ASDisplayNode, ContextGesture?, CGPoint?) -> Void)?, toggleExpandLocalResults: @escaping () -> Void, toggleExpandGlobalResults: @escaping () -> Void, searchPeer: @escaping (EnginePeer) -> Void, searchQuery: String?, searchOptions: ChatListSearchOptions?, messageContextAction: ((EngineMessage, ASDisplayNode?, CGRect?, UIGestureRecognizer?, ChatListSearchPaneKey, (id: String, size: Int64, isFirstInList: Bool)?) -> Void)?, openClearRecentlyDownloaded: @escaping () -> Void, toggleAllPaused: @escaping () -> Void) -> ListViewItem {
switch self {
case let .topic(peer, threadInfo, _, theme, strings, expandType):
let actionTitle: String?
switch expandType {
case .none:
actionTitle = nil
case .expand:
actionTitle = strings.ChatList_Search_ShowMore
case .collapse:
actionTitle = strings.ChatList_Search_ShowLess
}
let header = ChatListSearchItemHeader(type: .topics, theme: theme, strings: strings, actionTitle: actionTitle, action: actionTitle == nil ? nil : {
toggleExpandGlobalResults()
})
return ContactsPeerItem(presentationData: ItemListPresentationData(presentationData), sortOrder: .firstLast, displayOrder: .firstLast, context: context, peerMode: .generalSearch, peer: .thread(peer: peer, title: threadInfo.info.title, icon: threadInfo.info.icon, color: 0), status: .none, badge: nil, enabled: true, selection: .none, editing: ContactsPeerItemEditing(editable: false, editing: false, revealed: false), index: nil, header: header, action: { _ in
interaction.peerSelected(peer, threadInfo.id, nil, nil)
}, contextAction: nil, animationCache: interaction.animationCache, animationRenderer: interaction.animationRenderer)
case let .topic(peer, threadInfo, _, theme, strings, expandType):
let actionTitle: String?
switch expandType {
case .none:
actionTitle = nil
case .expand:
actionTitle = strings.ChatList_Search_ShowMore
case .collapse:
actionTitle = strings.ChatList_Search_ShowLess
}
let header = ChatListSearchItemHeader(type: .topics, theme: theme, strings: strings, actionTitle: actionTitle, action: actionTitle == nil ? nil : {
toggleExpandGlobalResults()
})
return ContactsPeerItem(presentationData: ItemListPresentationData(presentationData), sortOrder: .firstLast, displayOrder: .firstLast, context: context, peerMode: .generalSearch, peer: .thread(peer: peer, title: threadInfo.info.title, icon: threadInfo.info.icon, color: 0), status: .none, badge: nil, enabled: true, selection: .none, editing: ContactsPeerItemEditing(editable: false, editing: false, revealed: false), index: nil, header: header, action: { _ in
interaction.peerSelected(peer, nil, threadInfo.id, nil)
}, contextAction: nil, animationCache: interaction.animationCache, animationRenderer: interaction.animationRenderer)
case let .recentlySearchedPeer(peer, associatedPeer, unreadBadge, _, theme, strings, nameSortOrder, nameDisplayOrder):
let primaryPeer: EnginePeer
var chatPeer: EnginePeer?
@ -543,7 +543,7 @@ public enum ChatListSearchEntry: Comparable, Identifiable {
return ContactsPeerItem(presentationData: ItemListPresentationData(presentationData), sortOrder: nameSortOrder, displayOrder: nameDisplayOrder, context: context, peerMode: .generalSearch, peer: .peer(peer: primaryPeer, chatPeer: chatPeer), status: .none, badge: badge, enabled: enabled, selection: .none, editing: ContactsPeerItemEditing(editable: false, editing: false, revealed: false), index: nil, header: header, action: { contactPeer in
if case let .peer(maybePeer, maybeChatPeer) = contactPeer, let peer = maybePeer, let chatPeer = maybeChatPeer {
interaction.peerSelected(chatPeer, nil, peer, nil)
interaction.peerSelected(chatPeer, peer, nil, nil)
} else {
interaction.peerSelected(peer, nil, nil, nil)
}
@ -630,7 +630,7 @@ public enum ChatListSearchEntry: Comparable, Identifiable {
return ContactsPeerItem(presentationData: ItemListPresentationData(presentationData), sortOrder: nameSortOrder, displayOrder: nameDisplayOrder, context: context, peerMode: .generalSearch, peer: .peer(peer: primaryPeer, chatPeer: chatPeer), status: .none, badge: badge, enabled: enabled, selection: .none, editing: ContactsPeerItemEditing(editable: false, editing: false, revealed: false), index: nil, header: header, action: { contactPeer in
if case let .peer(maybePeer, maybeChatPeer) = contactPeer, let peer = maybePeer, let chatPeer = maybeChatPeer {
interaction.peerSelected(chatPeer, nil, peer, nil)
interaction.peerSelected(chatPeer, peer, nil, nil)
} else {
interaction.peerSelected(peer, nil, nil, nil)
}
@ -739,10 +739,10 @@ public enum ChatListSearchEntry: Comparable, Identifiable {
index = .chatList(EngineChatList.Item.Index.ChatList(pinningIndex: nil, messageIndex: message.index))
case .forum:
if let threadId = message.threadId, let threadInfo = threadInfo {
chatThreadInfo = ChatListItemContent.ThreadInfo(id: threadId, info: threadInfo)
index = .forum(timestamp: message.index.timestamp, threadId: threadId, namespace: message.index.id.namespace, id: message.index.id.id)
chatThreadInfo = ChatListItemContent.ThreadInfo(id: threadId, info: threadInfo, isOwner: false, isClosed: false)
index = .forum(pinnedIndex: .none, timestamp: message.index.timestamp, threadId: threadId, namespace: message.index.id.namespace, id: message.index.id.id)
} else {
index = .chatList(EngineChatList.Item.Index.ChatList(pinningIndex: nil, messageIndex: message.index))
index = .chatList( EngineChatList.Item.Index.ChatList(pinningIndex: nil, messageIndex: message.index))
}
}
return ChatListItem(presentationData: presentationData, context: context, chatListLocation: .chatList(groupId: .root), filterData: nil, index: index, content: .peer(messages: [message], peer: peer, threadInfo: chatThreadInfo, combinedReadState: readState, isRemovedFromTotalUnreadCount: false, presence: nil, hasUnseenMentions: false, hasUnseenReactions: false, draftState: nil, inputActivities: nil, promoInfo: nil, ignoreUnreadBadge: true, displayAsMessage: false, hasFailedMessages: false, forumTopicData: nil), editing: false, hasActiveRevealControls: false, selected: false, header: tagMask == nil ? header : nil, enableContextActions: false, hiddenOffset: false, interaction: interaction)
@ -1245,7 +1245,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
if let resourceValue = findMediaResourceById(message: item.message, resourceId: item.resourceId), let size = resourceValue.size {
resource = (resourceValue.id.stringRepresentation, size, entries.isEmpty)
}
entries.append(.message(message, peer, nil, nil, presentationData, 1, nil, false, .downloading(item.priority), resource, .downloading, allPaused))
}
for item in downloadItems.doneItems.sorted(by: { ChatListSearchEntry.MessageOrderingKey.downloaded(timestamp: $0.timestamp, index: $0.message.index) < ChatListSearchEntry.MessageOrderingKey.downloaded(timestamp: $1.timestamp, index: $1.message.index) }) {
@ -1490,17 +1490,17 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
}
})
let foundThreads: Signal<([Int64: EngineMessageHistoryThread.Info], [EngineChatList.Item]), NoError> = chatListViewForLocation(chatListLocation: location, location: .initial(count: 1000, filter: nil), account: context.account)
|> map { view -> ([Int64: EngineMessageHistoryThread.Info], [EngineChatList.Item]) in
var itemsMap: [Int64: EngineMessageHistoryThread.Info] = [:]
let foundThreads: Signal<([Int64: MessageHistoryThreadData], [EngineChatList.Item]), NoError> = chatListViewForLocation(chatListLocation: location, location: .initial(count: 1000, filter: nil), account: context.account)
|> map { view -> ([Int64: MessageHistoryThreadData], [EngineChatList.Item]) in
var itemsMap: [Int64: MessageHistoryThreadData] = [:]
var filteredItems: [EngineChatList.Item] = []
let queryTokens = stringIndexTokens(finalQuery, transliteration: .combined)
for item in view.list.items {
if case let .forum(_, index, _, _) = item.index, let threadInfo = item.threadInfo {
itemsMap[index] = threadInfo
if case let .forum(_, _, index, _, _) = item.index, let threadData = item.threadData {
itemsMap[index] = threadData
}
if !finalQuery.isEmpty {
if let title = item.threadInfo?.title {
if let title = item.threadData?.info.title {
let tokens = stringIndexTokens(title, transliteration: .combined)
if matchStringIndexTokens(tokens, with: queryTokens) {
filteredItems.append(item)
@ -1508,6 +1508,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
}
}
}
return (itemsMap, filteredItems)
}
@ -1518,8 +1519,8 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
var index = 0
for thread in allAndFoundThreads.1 {
if let peer = thread.renderedPeer.peer, let threadInfo = thread.threadInfo, case let .forum(_, id, _, _) = thread.index {
entries.append(.topic(peer, ChatListItemContent.ThreadInfo(id: id, info: threadInfo), index, presentationData.theme, presentationData.strings, .none))
if let peer = thread.renderedPeer.peer, let threadData = thread.threadData, case let .forum(_, _, id, _, _) = thread.index {
entries.append(.topic(peer, ChatListItemContent.ThreadInfo(id: id, info: threadData.info, isOwner: threadData.isOwnedByMe, isClosed: threadData.isClosed), index, presentationData.theme, presentationData.strings, .none))
index += 1
}
}
@ -1715,7 +1716,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
peer = EngineRenderedPeer(peer: EnginePeer(channelPeer))
}
}
entries.append(.message(message, peer, nil, message.threadId.flatMap { allAndFoundThreads.0[$0] }, presentationData, 1, nil, true, .index(message.index), nil, .generic, false))
entries.append(.message(message, peer, nil, message.threadId.flatMap { allAndFoundThreads.0[$0]?.info }, presentationData, 1, nil, true, .index(message.index), nil, .generic, false))
index += 1
}
@ -1738,7 +1739,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
peer = EngineRenderedPeer(peer: EnginePeer(channelPeer))
}
}
entries.append(.message(message, peer, foundRemoteMessages.0.1[message.id.peerId], message.threadId.flatMap { allAndFoundThreads.0[$0] }, presentationData, foundRemoteMessages.0.2, selectionState?.contains(message.id), headerId == firstHeaderId, .index(message.index), nil, .generic, false))
entries.append(.message(message, peer, foundRemoteMessages.0.1[message.id.peerId], message.threadId.flatMap { allAndFoundThreads.0[$0]?.info }, presentationData, foundRemoteMessages.0.2, selectionState?.contains(message.id), headerId == firstHeaderId, .index(message.index), nil, .generic, false))
index += 1
}
}
@ -1810,9 +1811,9 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
}
let chatListInteraction = ChatListNodeInteraction(context: context, animationCache: self.animationCache, animationRenderer: self.animationRenderer, activateSearch: {
}, peerSelected: { [weak self] peer, _, chatPeer, _ in
}, peerSelected: { [weak self] peer, chatPeer, threadId, _ in
interaction.dismissInput()
interaction.openPeer(peer, chatPeer, false)
interaction.openPeer(peer, chatPeer, threadId, false)
let _ = context.engine.peers.addRecentlySearchedPeer(peerId: peer.id).start()
self?.listNode.clearHighlightAnimated(true)
}, disabledPeerSelected: { _ in
@ -2159,7 +2160,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
let firstTime = previousEntries == nil
let transition = chatListSearchContainerPreparedRecentTransition(from: previousEntries ?? [], to: entries, context: context, presentationData: presentationData, filter: peersFilter, peerSelected: { peer in
interaction.openPeer(peer, nil, true)
interaction.openPeer(peer, nil, nil, true)
let _ = context.engine.peers.addRecentlySearchedPeer(peerId: peer.id).start()
self?.recentListNode.clearHighlightAnimated(true)
}, disabledPeerSelected: { peer in

View File

@ -56,7 +56,7 @@ public final class ChatListNodeInteraction {
}
let activateSearch: () -> Void
let peerSelected: (EnginePeer, Int64?, EnginePeer?, ChatListNodeEntryPromoInfo?) -> Void
let peerSelected: (EnginePeer, EnginePeer?, Int64?, ChatListNodeEntryPromoInfo?) -> Void
let disabledPeerSelected: (EnginePeer) -> Void
let togglePeerSelected: (EnginePeer) -> Void
let togglePeersSelection: ([PeerEntry], Bool) -> Void
@ -90,7 +90,7 @@ public final class ChatListNodeInteraction {
animationCache: AnimationCache,
animationRenderer: MultiAnimationRenderer,
activateSearch: @escaping () -> Void,
peerSelected: @escaping (EnginePeer, Int64?, EnginePeer?, ChatListNodeEntryPromoInfo?) -> Void,
peerSelected: @escaping (EnginePeer, EnginePeer?, Int64?, ChatListNodeEntryPromoInfo?) -> Void,
disabledPeerSelected: @escaping (EnginePeer) -> Void,
togglePeerSelected: @escaping (EnginePeer) -> Void,
togglePeersSelection: @escaping ([PeerEntry], Bool) -> Void,
@ -795,7 +795,7 @@ public final class ChatListNode: ListView {
if let strongSelf = self, let activateSearch = strongSelf.activateSearch {
activateSearch()
}
}, peerSelected: { [weak self] peer, threadId, _, promoInfo in
}, peerSelected: { [weak self] peer, _, threadId, promoInfo in
if let strongSelf = self, let peerSelected = strongSelf.peerSelected {
peerSelected(peer, threadId, true, true, promoInfo)
}

View File

@ -149,7 +149,7 @@ final class InstantPagePeerReferenceNode: ASDisplayNode, InstantPageNode {
let context = self.context
let signal = actualizedPeer(postbox: account.postbox, network: account.network, peer: initialPeer)
|> mapToSignal({ peer -> Signal<Peer, NoError> in
if let peer = peer as? TelegramChannel, let username = peer.username, peer.accessHash == nil {
if let peer = peer as? TelegramChannel, let username = peer.addressName, peer.accessHash == nil {
return .single(peer) |> then(context.engine.peers.resolvePeerByName(name: username)
|> mapToSignal({ updatedPeer -> Signal<Peer, NoError> in
if let updatedPeer = updatedPeer {

View File

@ -203,7 +203,7 @@ public class AdditionalLinkItemNode: ListViewItemNode, ItemListItemNode {
let iconColor: UIColor
if let username = item.username {
if username.flags.contains(.isEditable) || username.flags.contains(.isActive) {
if username.isActive {
iconColor = item.presentationData.theme.list.itemAccentColor
} else {
iconColor = UIColor(rgb: 0xa8b2bb)
@ -218,7 +218,7 @@ public class AdditionalLinkItemNode: ListViewItemNode, ItemListItemNode {
if let username = item.username {
titleText = "@\(username.username)"
if username.flags.contains(.isEditable) || username.flags.contains(.isActive) {
if username.isActive {
subtitleText = item.presentationData.strings.Group_Setup_LinkActive
subtitleColor = item.presentationData.theme.list.itemAccentColor
} else {
@ -388,13 +388,14 @@ public class AdditionalLinkItemNode: ListViewItemNode, ItemListItemNode {
strongSelf.highlightedBackgroundNode.frame = CGRect(origin: CGPoint(x: 0.0, y: -UIScreenPixel), size: CGSize(width: params.width, height: contentSize.height + UIScreenPixel + UIScreenPixel))
if strongSelf.reorderControlNode == nil && item.username?.flags.contains(.isActive) == true {
let isReorderable = item.username?.isActive == true
if isReorderable {
let reorderControlNode = reorderControlSizeAndApply.1(layout.contentSize.height, false, .immediate)
strongSelf.reorderControlNode = reorderControlNode
strongSelf.addSubnode(reorderControlNode)
reorderControlNode.alpha = 0.0
transition.updateAlpha(node: reorderControlNode, alpha: 1.0)
} else if let reorderControlNode = strongSelf.reorderControlNode, item.username?.flags.contains(.isActive) == false {
} else if let reorderControlNode = strongSelf.reorderControlNode, item.username?.isActive == false {
strongSelf.reorderControlNode = nil
reorderControlNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false, completion: { [weak reorderControlNode] _ in
reorderControlNode?.removeFromSupernode()

View File

@ -406,7 +406,7 @@ public class ItemListAvatarAndNameInfoItemNode: ListViewItemNode, ItemListItemNo
if let phone = peer.phone, !phone.isEmpty {
statusText += formatPhoneNumber(phone)
}
if let username = peer.username, !username.isEmpty {
if let username = peer.addressName, !username.isEmpty {
if !statusText.isEmpty {
statusText += "\n"
}

View File

@ -943,14 +943,14 @@ private func channelVisibilityControllerEntries(presentationData: PresentationDa
}
}
let currentAddressName: String
let currentUsername: String
if let current = state.editingPublicLinkText {
currentAddressName = current
currentUsername = current
} else {
if let addressName = peer.addressName {
currentAddressName = addressName
if let username = peer.editableUsername {
currentUsername = username
} else {
currentAddressName = ""
currentUsername = ""
}
}
@ -1019,7 +1019,7 @@ private func channelVisibilityControllerEntries(presentationData: PresentationDa
} else {
switch selectedType {
case .publicChannel:
entries.append(.editablePublicLink(presentationData.theme, presentationData.strings, presentationData.strings.Group_PublicLink_Placeholder, currentAddressName))
entries.append(.editablePublicLink(presentationData.theme, presentationData.strings, presentationData.strings.Group_PublicLink_Placeholder, currentUsername))
if let status = state.addressNameValidationStatus {
let text: String
switch status {
@ -1055,7 +1055,7 @@ private func channelVisibilityControllerEntries(presentationData: PresentationDa
case let .availability(availability):
switch availability {
case .available:
text = presentationData.strings.Channel_Username_UsernameIsAvailable(currentAddressName).string
text = presentationData.strings.Channel_Username_UsernameIsAvailable(currentUsername).string
case .invalid:
text = presentationData.strings.Channel_Username_InvalidCharacters
case .taken:
@ -1208,11 +1208,11 @@ private func channelVisibilityControllerEntries(presentationData: PresentationDa
selectedType = .privateChannel
}
let currentAddressName: String
let currentUsername: String
if let current = state.editingPublicLinkText {
currentAddressName = current
currentUsername = current
} else {
currentAddressName = ""
currentUsername = ""
}
entries.append(.typeHeader(presentationData.theme, presentationData.strings.Group_Setup_TypeHeader.uppercased()))
@ -1228,7 +1228,7 @@ private func channelVisibilityControllerEntries(presentationData: PresentationDa
switch selectedType {
case .publicChannel:
entries.append(.editablePublicLink(presentationData.theme, presentationData.strings, "", currentAddressName))
entries.append(.editablePublicLink(presentationData.theme, presentationData.strings, "", currentUsername))
if let status = state.addressNameValidationStatus {
let text: String
switch status {
@ -1248,7 +1248,7 @@ private func channelVisibilityControllerEntries(presentationData: PresentationDa
case let .availability(availability):
switch availability {
case .available:
text = presentationData.strings.Channel_Username_UsernameIsAvailable(currentAddressName).string
text = presentationData.strings.Channel_Username_UsernameIsAvailable(currentUsername).string
case .invalid:
text = presentationData.strings.Channel_Username_InvalidCharacters
case .taken:
@ -1319,38 +1319,38 @@ private func updatedAddressName(mode: ChannelVisibilityControllerMode, state: Ch
if let peer = peer as? TelegramChannel {
let selectedType = effectiveChannelType(mode: mode, state: state, peer: peer, cachedData: cachedData)
let currentAddressName: String
let currentUsername: String
switch selectedType {
case .privateChannel:
currentAddressName = ""
currentUsername = ""
case .publicChannel:
if let current = state.editingPublicLinkText {
currentAddressName = current
currentUsername = current
} else {
if let addressName = peer.addressName {
currentAddressName = addressName
if let username = peer.editableUsername {
currentUsername = username
} else {
currentAddressName = ""
currentUsername = ""
}
}
}
if !currentAddressName.isEmpty {
if currentAddressName != peer.addressName {
return currentAddressName
if !currentUsername.isEmpty {
if currentUsername != peer.editableUsername {
return currentUsername
} else {
return nil
}
} else if peer.addressName != nil {
} else if peer.editableUsername != nil {
return ""
} else {
return nil
}
} else if let _ = peer as? TelegramGroup {
let currentAddressName = state.editingPublicLinkText ?? ""
if !currentAddressName.isEmpty {
return currentAddressName
let currentUsername = state.editingPublicLinkText ?? ""
if !currentUsername.isEmpty {
return currentUsername
} else {
return nil
}
@ -2082,7 +2082,7 @@ public func channelVisibilityController(context: AccountContext, updatedPresenta
switch entry {
case let .additionalLink(_, link, _):
currentUsernames.append(link.username)
if !link.flags.contains(.isActive) && maxIndex == nil {
if !link.isActive && maxIndex == nil {
maxIndex = max(0, i - 1)
}
i += 1
@ -2094,7 +2094,7 @@ public func channelVisibilityController(context: AccountContext, updatedPresenta
if toIndex < entries.count {
switch entries[toIndex] {
case let .additionalLink(_, toUsername, _):
if toUsername.flags.contains(.isActive) {
if toUsername.isActive {
referenceId = toUsername.username
} else {
afterAll = true

View File

@ -230,7 +230,7 @@ private enum UsernameSetupEntry: ItemListNodeEntry {
case let .additionalLink(_, link, _):
return AdditionalLinkItem(presentationData: presentationData, username: link, sectionId: self.section, style: .blocks, tapAction: {
if !link.flags.contains(.isEditable) {
if link.flags.contains(.isActive) {
if link.isActive {
arguments.deactivateLink(link.username)
} else {
arguments.activateLink(link.username)
@ -291,19 +291,19 @@ private func usernameSetupControllerEntries(presentationData: PresentationData,
var entries: [UsernameSetupEntry] = []
if let peer = view.peers[view.peerId] as? TelegramUser {
let currentAddressName: String
let currentUsername: String
if let current = state.editingPublicLinkText {
currentAddressName = current
currentUsername = current
} else {
if let addressName = peer.addressName {
currentAddressName = addressName
if let username = peer.editableUsername {
currentUsername = username
} else {
currentAddressName = ""
currentUsername = ""
}
}
entries.append(.publicLinkHeader(presentationData.theme, presentationData.strings.Username_Username))
entries.append(.editablePublicLink(presentationData.theme, presentationData.strings, presentationData.strings.Username_Title, peer.addressName, currentAddressName))
entries.append(.editablePublicLink(presentationData.theme, presentationData.strings, presentationData.strings.Username_Title, peer.editableUsername, currentUsername))
if let status = state.addressNameValidationStatus {
let statusText: String
switch status {
@ -323,7 +323,7 @@ private func usernameSetupControllerEntries(presentationData: PresentationData,
case let .availability(availability):
switch availability {
case .available:
statusText = presentationData.strings.Username_UsernameIsAvailable(currentAddressName).string
statusText = presentationData.strings.Username_UsernameIsAvailable(currentUsername).string
case .invalid:
statusText = presentationData.strings.Username_InvalidCharacters
case .taken:
@ -332,7 +332,7 @@ private func usernameSetupControllerEntries(presentationData: PresentationData,
case .checking:
statusText = presentationData.strings.Username_CheckingUsername
}
entries.append(.publicLinkStatus(presentationData.theme, currentAddressName, status, statusText))
entries.append(.publicLinkStatus(presentationData.theme, currentUsername, status, statusText))
}
var infoText = presentationData.strings.Username_Help
@ -341,7 +341,7 @@ private func usernameSetupControllerEntries(presentationData: PresentationData,
if otherUsernames.isEmpty {
infoText += "\n\n"
let hintText = presentationData.strings.Username_LinkHint(currentAddressName.replacingOccurrences(of: "[", with: "").replacingOccurrences(of: "]", with: "")).string.replacingOccurrences(of: "]", with: "]()")
let hintText = presentationData.strings.Username_LinkHint(currentUsername.replacingOccurrences(of: "[", with: "").replacingOccurrences(of: "]", with: "")).string.replacingOccurrences(of: "]", with: "]()")
infoText += hintText
}
entries.append(.publicLinkInfo(presentationData.theme, infoText))
@ -546,7 +546,7 @@ public func usernameSetupController(context: AccountContext) -> ViewController {
switch entry {
case let .additionalLink(_, link, _):
currentUsernames.append(link.username)
if !link.flags.contains(.isActive) && maxIndex == nil {
if !link.isActive && maxIndex == nil {
maxIndex = max(0, i - 1)
}
i += 1
@ -558,7 +558,7 @@ public func usernameSetupController(context: AccountContext) -> ViewController {
if toIndex < entries.count {
switch entries[toIndex] {
case let .additionalLink(_, toUsername, _):
if toUsername.flags.contains(.isActive) {
if toUsername.isActive {
referenceId = toUsername.username
} else {
afterAll = true

View File

@ -97,6 +97,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-1312568665] = { return Api.ChannelAdminLogEventAction.parse_channelAdminLogEventActionChangeStickerSet($0) }
dict[-421545947] = { return Api.ChannelAdminLogEventAction.parse_channelAdminLogEventActionChangeTitle($0) }
dict[1783299128] = { return Api.ChannelAdminLogEventAction.parse_channelAdminLogEventActionChangeUsername($0) }
dict[-263212119] = { return Api.ChannelAdminLogEventAction.parse_channelAdminLogEventActionChangeUsernames($0) }
dict[771095562] = { return Api.ChannelAdminLogEventAction.parse_channelAdminLogEventActionDefaultBannedRights($0) }
dict[1121994683] = { return Api.ChannelAdminLogEventAction.parse_channelAdminLogEventActionDeleteMessage($0) }
dict[-610299584] = { return Api.ChannelAdminLogEventAction.parse_channelAdminLogEventActionDiscardGroupCall($0) }
@ -795,7 +796,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[889491791] = { return Api.Update.parse_updateDialogFilters($0) }
dict[1852826908] = { return Api.Update.parse_updateDialogPinned($0) }
dict[-513517117] = { return Api.Update.parse_updateDialogUnreadMark($0) }
dict[-299124375] = { return Api.Update.parse_updateDraftMessage($0) }
dict[457829485] = { return Api.Update.parse_updateDraftMessage($0) }
dict[457133559] = { return Api.Update.parse_updateEditChannelMessage($0) }
dict[-469536605] = { return Api.Update.parse_updateEditMessage($0) }
dict[386986326] = { return Api.Update.parse_updateEncryptedChatTyping($0) }
@ -815,7 +816,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[1318109142] = { return Api.Update.parse_updateMessageID($0) }
dict[-1398708869] = { return Api.Update.parse_updateMessagePoll($0) }
dict[274961865] = { return Api.Update.parse_updateMessagePollVote($0) }
dict[357013699] = { return Api.Update.parse_updateMessageReactions($0) }
dict[1578843320] = { return Api.Update.parse_updateMessageReactions($0) }
dict[-2030252155] = { return Api.Update.parse_updateMoveStickerSetToTop($0) }
dict[1656358105] = { return Api.Update.parse_updateNewChannelMessage($0) }
dict[314359194] = { return Api.Update.parse_updateNewEncryptedMessage($0) }
@ -855,7 +856,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-2112423005] = { return Api.Update.parse_updateTheme($0) }
dict[8703322] = { return Api.Update.parse_updateTranscribedAudio($0) }
dict[674706841] = { return Api.Update.parse_updateUserEmojiStatus($0) }
dict[-1007549728] = { return Api.Update.parse_updateUserName($0) }
dict[-1484486364] = { return Api.Update.parse_updateUserName($0) }
dict[88680979] = { return Api.Update.parse_updateUserPhone($0) }
dict[-232290676] = { return Api.Update.parse_updateUserPhoto($0) }
dict[-440534818] = { return Api.Update.parse_updateUserStatus($0) }

View File

@ -805,7 +805,7 @@ public extension Api {
}
}
public extension Api {
indirect enum BotCommandScope: TypeConstructorDescription {
enum BotCommandScope: TypeConstructorDescription {
case botCommandScopeChatAdmins
case botCommandScopeChats
case botCommandScopeDefault

View File

@ -263,7 +263,7 @@ public extension Api {
}
}
public extension Api {
indirect enum InputStorePaymentPurpose: TypeConstructorDescription {
enum InputStorePaymentPurpose: TypeConstructorDescription {
case inputStorePaymentGiftPremium(userId: Api.InputUser, currency: String, amount: Int64)
case inputStorePaymentPremiumSubscription(flags: Int32)
@ -461,7 +461,7 @@ public extension Api {
}
}
public extension Api {
indirect enum InputUser: TypeConstructorDescription {
enum InputUser: TypeConstructorDescription {
case inputUser(userId: Int64, accessHash: Int64)
case inputUserEmpty
case inputUserFromMessage(peer: Api.InputPeer, msgId: Int32, userId: Int64)

View File

@ -1,5 +1,5 @@
public extension Api {
indirect enum KeyboardButton: TypeConstructorDescription {
enum KeyboardButton: TypeConstructorDescription {
case inputKeyboardButtonUrlAuth(flags: Int32, text: String, fwdText: String?, url: String, bot: Api.InputUser)
case inputKeyboardButtonUserProfile(text: String, userId: Api.InputUser)
case keyboardButton(text: String)
@ -757,7 +757,7 @@ public extension Api {
}
}
public extension Api {
indirect enum Message: TypeConstructorDescription {
enum Message: TypeConstructorDescription {
case message(flags: Int32, id: Int32, fromId: Api.Peer?, peerId: Api.Peer, fwdFrom: Api.MessageFwdHeader?, viaBotId: Int64?, replyTo: Api.MessageReplyHeader?, date: Int32, message: String, media: Api.MessageMedia?, replyMarkup: Api.ReplyMarkup?, entities: [Api.MessageEntity]?, views: Int32?, forwards: Int32?, replies: Api.MessageReplies?, editDate: Int32?, postAuthor: String?, groupedId: Int64?, reactions: Api.MessageReactions?, restrictionReason: [Api.RestrictionReason]?, ttlPeriod: Int32?)
case messageEmpty(flags: Int32, id: Int32, peerId: Api.Peer?)
case messageService(flags: Int32, id: Int32, fromId: Api.Peer?, peerId: Api.Peer, replyTo: Api.MessageReplyHeader?, date: Int32, action: Api.MessageAction, ttlPeriod: Int32?)

View File

@ -1,5 +1,5 @@
public extension Api {
indirect enum MessageEntity: TypeConstructorDescription {
enum MessageEntity: TypeConstructorDescription {
case inputMessageEntityMentionName(offset: Int32, length: Int32, userId: Api.InputUser)
case messageEntityBankCard(offset: Int32, length: Int32)
case messageEntityBlockquote(offset: Int32, length: Int32)

View File

@ -891,7 +891,7 @@ public extension Api {
}
}
public extension Api {
indirect enum PageCaption: TypeConstructorDescription {
enum PageCaption: TypeConstructorDescription {
case pageCaption(text: Api.RichText, credit: Api.RichText)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
@ -935,7 +935,7 @@ public extension Api {
}
}
public extension Api {
indirect enum PageListItem: TypeConstructorDescription {
enum PageListItem: TypeConstructorDescription {
case pageListItemBlocks(blocks: [Api.PageBlock])
case pageListItemText(text: Api.RichText)

View File

@ -1,5 +1,5 @@
public extension Api {
indirect enum PageListOrderedItem: TypeConstructorDescription {
enum PageListOrderedItem: TypeConstructorDescription {
case pageListOrderedItemBlocks(num: String, blocks: [Api.PageBlock])
case pageListOrderedItemText(num: String, text: Api.RichText)
@ -135,7 +135,7 @@ public extension Api {
}
}
public extension Api {
indirect enum PageTableCell: TypeConstructorDescription {
enum PageTableCell: TypeConstructorDescription {
case pageTableCell(flags: Int32, text: Api.RichText?, colspan: Int32?, rowspan: Int32?)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {

View File

@ -157,7 +157,7 @@ public extension Api {
}
}
public extension Api {
indirect enum RecentMeUrl: TypeConstructorDescription {
enum RecentMeUrl: TypeConstructorDescription {
case recentMeUrlChat(url: String, chatId: Int64)
case recentMeUrlChatInvite(url: String, chatInvite: Api.ChatInvite)
case recentMeUrlStickerSet(url: String, set: Api.StickerSetCovered)

View File

@ -433,7 +433,7 @@ public extension Api {
}
}
public extension Api {
indirect enum SponsoredMessage: TypeConstructorDescription {
enum SponsoredMessage: TypeConstructorDescription {
case sponsoredMessage(flags: Int32, randomId: Buffer, fromId: Api.Peer?, chatInvite: Api.ChatInvite?, chatInviteHash: String?, channelPost: Int32?, startParam: String?, message: String, entities: [Api.MessageEntity]?)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {

View File

@ -555,7 +555,7 @@ public extension Api {
}
}
public extension Api {
indirect enum ChannelAdminLogEvent: TypeConstructorDescription {
enum ChannelAdminLogEvent: TypeConstructorDescription {
case channelAdminLogEvent(id: Int64, date: Int32, userId: Int64, action: Api.ChannelAdminLogEventAction)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
@ -605,7 +605,7 @@ public extension Api {
}
}
public extension Api {
indirect enum ChannelAdminLogEventAction: TypeConstructorDescription {
enum ChannelAdminLogEventAction: TypeConstructorDescription {
case channelAdminLogEventActionChangeAbout(prevValue: String, newValue: String)
case channelAdminLogEventActionChangeAvailableReactions(prevValue: Api.ChatReactions, newValue: Api.ChatReactions)
case channelAdminLogEventActionChangeHistoryTTL(prevValue: Int32, newValue: Int32)
@ -615,6 +615,7 @@ public extension Api {
case channelAdminLogEventActionChangeStickerSet(prevStickerset: Api.InputStickerSet, newStickerset: Api.InputStickerSet)
case channelAdminLogEventActionChangeTitle(prevValue: String, newValue: String)
case channelAdminLogEventActionChangeUsername(prevValue: String, newValue: String)
case channelAdminLogEventActionChangeUsernames(prevValue: [String], newValue: [String])
case channelAdminLogEventActionDefaultBannedRights(prevBannedRights: Api.ChatBannedRights, newBannedRights: Api.ChatBannedRights)
case channelAdminLogEventActionDeleteMessage(message: Api.Message)
case channelAdminLogEventActionDiscardGroupCall(call: Api.InputGroupCall)
@ -708,6 +709,21 @@ public extension Api {
serializeString(prevValue, buffer: buffer, boxed: false)
serializeString(newValue, buffer: buffer, boxed: false)
break
case .channelAdminLogEventActionChangeUsernames(let prevValue, let newValue):
if boxed {
buffer.appendInt32(-263212119)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(prevValue.count))
for item in prevValue {
serializeString(item, buffer: buffer, boxed: false)
}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(newValue.count))
for item in newValue {
serializeString(item, buffer: buffer, boxed: false)
}
break
case .channelAdminLogEventActionDefaultBannedRights(let prevBannedRights, let newBannedRights):
if boxed {
buffer.appendInt32(771095562)
@ -900,6 +916,8 @@ public extension Api {
return ("channelAdminLogEventActionChangeTitle", [("prevValue", String(describing: prevValue)), ("newValue", String(describing: newValue))])
case .channelAdminLogEventActionChangeUsername(let prevValue, let newValue):
return ("channelAdminLogEventActionChangeUsername", [("prevValue", String(describing: prevValue)), ("newValue", String(describing: newValue))])
case .channelAdminLogEventActionChangeUsernames(let prevValue, let newValue):
return ("channelAdminLogEventActionChangeUsernames", [("prevValue", String(describing: prevValue)), ("newValue", String(describing: newValue))])
case .channelAdminLogEventActionDefaultBannedRights(let prevBannedRights, let newBannedRights):
return ("channelAdminLogEventActionDefaultBannedRights", [("prevBannedRights", String(describing: prevBannedRights)), ("newBannedRights", String(describing: newBannedRights))])
case .channelAdminLogEventActionDeleteMessage(let message):
@ -1099,6 +1117,24 @@ public extension Api {
return nil
}
}
public static func parse_channelAdminLogEventActionChangeUsernames(_ reader: BufferReader) -> ChannelAdminLogEventAction? {
var _1: [String]?
if let _ = reader.readInt32() {
_1 = Api.parseVector(reader, elementSignature: -1255641564, elementType: String.self)
}
var _2: [String]?
if let _ = reader.readInt32() {
_2 = Api.parseVector(reader, elementSignature: -1255641564, elementType: String.self)
}
let _c1 = _1 != nil
let _c2 = _2 != nil
if _c1 && _c2 {
return Api.ChannelAdminLogEventAction.channelAdminLogEventActionChangeUsernames(prevValue: _1!, newValue: _2!)
}
else {
return nil
}
}
public static func parse_channelAdminLogEventActionDefaultBannedRights(_ reader: BufferReader) -> ChannelAdminLogEventAction? {
var _1: Api.ChatBannedRights?
if let signature = reader.readInt32() {

View File

@ -653,7 +653,7 @@ public extension Api {
}
}
public extension Api {
indirect enum Update: TypeConstructorDescription {
enum Update: TypeConstructorDescription {
case updateAttachMenuBots
case updateBotCallbackQuery(flags: Int32, queryId: Int64, userId: Int64, peer: Api.Peer, msgId: Int32, chatInstance: Int64, data: Buffer?, gameShortName: String?)
case updateBotChatInviteRequester(peer: Api.Peer, date: Int32, userId: Int64, about: String, invite: Api.ExportedChatInvite, qts: Int32)
@ -695,7 +695,7 @@ public extension Api {
case updateDialogFilters
case updateDialogPinned(flags: Int32, folderId: Int32?, peer: Api.DialogPeer)
case updateDialogUnreadMark(flags: Int32, peer: Api.DialogPeer)
case updateDraftMessage(peer: Api.Peer, draft: Api.DraftMessage)
case updateDraftMessage(flags: Int32, peer: Api.Peer, topMsgId: Int32?, draft: Api.DraftMessage)
case updateEditChannelMessage(message: Api.Message, pts: Int32, ptsCount: Int32)
case updateEditMessage(message: Api.Message, pts: Int32, ptsCount: Int32)
case updateEncryptedChatTyping(chatId: Int32)
@ -715,7 +715,7 @@ public extension Api {
case updateMessageID(id: Int32, randomId: Int64)
case updateMessagePoll(flags: Int32, pollId: Int64, poll: Api.Poll?, results: Api.PollResults)
case updateMessagePollVote(pollId: Int64, userId: Int64, options: [Buffer], qts: Int32)
case updateMessageReactions(peer: Api.Peer, msgId: Int32, reactions: Api.MessageReactions)
case updateMessageReactions(flags: Int32, peer: Api.Peer, msgId: Int32, topMsgId: Int32?, reactions: Api.MessageReactions)
case updateMoveStickerSetToTop(flags: Int32, stickerset: Int64)
case updateNewChannelMessage(message: Api.Message, pts: Int32, ptsCount: Int32)
case updateNewEncryptedMessage(message: Api.EncryptedMessage, qts: Int32)
@ -755,7 +755,7 @@ public extension Api {
case updateTheme(theme: Api.Theme)
case updateTranscribedAudio(flags: Int32, peer: Api.Peer, msgId: Int32, transcriptionId: Int64, text: String)
case updateUserEmojiStatus(userId: Int64, emojiStatus: Api.EmojiStatus)
case updateUserName(userId: Int64, firstName: String, lastName: String, username: String)
case updateUserName(userId: Int64, firstName: String, lastName: String, usernames: [Api.Username])
case updateUserPhone(userId: Int64, phone: String)
case updateUserPhoto(userId: Int64, date: Int32, photo: Api.UserProfilePhoto, previous: Api.Bool)
case updateUserStatus(userId: Int64, status: Api.UserStatus)
@ -1139,11 +1139,13 @@ public extension Api {
serializeInt32(flags, buffer: buffer, boxed: false)
peer.serialize(buffer, true)
break
case .updateDraftMessage(let peer, let draft):
case .updateDraftMessage(let flags, let peer, let topMsgId, let draft):
if boxed {
buffer.appendInt32(-299124375)
buffer.appendInt32(457829485)
}
serializeInt32(flags, buffer: buffer, boxed: false)
peer.serialize(buffer, true)
if Int(flags) & Int(1 << 0) != 0 {serializeInt32(topMsgId!, buffer: buffer, boxed: false)}
draft.serialize(buffer, true)
break
case .updateEditChannelMessage(let message, let pts, let ptsCount):
@ -1301,12 +1303,14 @@ public extension Api {
}
serializeInt32(qts, buffer: buffer, boxed: false)
break
case .updateMessageReactions(let peer, let msgId, let reactions):
case .updateMessageReactions(let flags, let peer, let msgId, let topMsgId, let reactions):
if boxed {
buffer.appendInt32(357013699)
buffer.appendInt32(1578843320)
}
serializeInt32(flags, buffer: buffer, boxed: false)
peer.serialize(buffer, true)
serializeInt32(msgId, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 0) != 0 {serializeInt32(topMsgId!, buffer: buffer, boxed: false)}
reactions.serialize(buffer, true)
break
case .updateMoveStickerSetToTop(let flags, let stickerset):
@ -1639,14 +1643,18 @@ public extension Api {
serializeInt64(userId, buffer: buffer, boxed: false)
emojiStatus.serialize(buffer, true)
break
case .updateUserName(let userId, let firstName, let lastName, let username):
case .updateUserName(let userId, let firstName, let lastName, let usernames):
if boxed {
buffer.appendInt32(-1007549728)
buffer.appendInt32(-1484486364)
}
serializeInt64(userId, buffer: buffer, boxed: false)
serializeString(firstName, buffer: buffer, boxed: false)
serializeString(lastName, buffer: buffer, boxed: false)
serializeString(username, buffer: buffer, boxed: false)
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(usernames.count))
for item in usernames {
item.serialize(buffer, true)
}
break
case .updateUserPhone(let userId, let phone):
if boxed {
@ -1779,8 +1787,8 @@ public extension Api {
return ("updateDialogPinned", [("flags", String(describing: flags)), ("folderId", String(describing: folderId)), ("peer", String(describing: peer))])
case .updateDialogUnreadMark(let flags, let peer):
return ("updateDialogUnreadMark", [("flags", String(describing: flags)), ("peer", String(describing: peer))])
case .updateDraftMessage(let peer, let draft):
return ("updateDraftMessage", [("peer", String(describing: peer)), ("draft", String(describing: draft))])
case .updateDraftMessage(let flags, let peer, let topMsgId, let draft):
return ("updateDraftMessage", [("flags", String(describing: flags)), ("peer", String(describing: peer)), ("topMsgId", String(describing: topMsgId)), ("draft", String(describing: draft))])
case .updateEditChannelMessage(let message, let pts, let ptsCount):
return ("updateEditChannelMessage", [("message", String(describing: message)), ("pts", String(describing: pts)), ("ptsCount", String(describing: ptsCount))])
case .updateEditMessage(let message, let pts, let ptsCount):
@ -1819,8 +1827,8 @@ public extension Api {
return ("updateMessagePoll", [("flags", String(describing: flags)), ("pollId", String(describing: pollId)), ("poll", String(describing: poll)), ("results", String(describing: results))])
case .updateMessagePollVote(let pollId, let userId, let options, let qts):
return ("updateMessagePollVote", [("pollId", String(describing: pollId)), ("userId", String(describing: userId)), ("options", String(describing: options)), ("qts", String(describing: qts))])
case .updateMessageReactions(let peer, let msgId, let reactions):
return ("updateMessageReactions", [("peer", String(describing: peer)), ("msgId", String(describing: msgId)), ("reactions", String(describing: reactions))])
case .updateMessageReactions(let flags, let peer, let msgId, let topMsgId, let reactions):
return ("updateMessageReactions", [("flags", String(describing: flags)), ("peer", String(describing: peer)), ("msgId", String(describing: msgId)), ("topMsgId", String(describing: topMsgId)), ("reactions", String(describing: reactions))])
case .updateMoveStickerSetToTop(let flags, let stickerset):
return ("updateMoveStickerSetToTop", [("flags", String(describing: flags)), ("stickerset", String(describing: stickerset))])
case .updateNewChannelMessage(let message, let pts, let ptsCount):
@ -1899,8 +1907,8 @@ public extension Api {
return ("updateTranscribedAudio", [("flags", String(describing: flags)), ("peer", String(describing: peer)), ("msgId", String(describing: msgId)), ("transcriptionId", String(describing: transcriptionId)), ("text", String(describing: text))])
case .updateUserEmojiStatus(let userId, let emojiStatus):
return ("updateUserEmojiStatus", [("userId", String(describing: userId)), ("emojiStatus", String(describing: emojiStatus))])
case .updateUserName(let userId, let firstName, let lastName, let username):
return ("updateUserName", [("userId", String(describing: userId)), ("firstName", String(describing: firstName)), ("lastName", String(describing: lastName)), ("username", String(describing: username))])
case .updateUserName(let userId, let firstName, let lastName, let usernames):
return ("updateUserName", [("userId", String(describing: userId)), ("firstName", String(describing: firstName)), ("lastName", String(describing: lastName)), ("usernames", String(describing: usernames))])
case .updateUserPhone(let userId, let phone):
return ("updateUserPhone", [("userId", String(describing: userId)), ("phone", String(describing: phone))])
case .updateUserPhoto(let userId, let date, let photo, let previous):
@ -2716,18 +2724,24 @@ public extension Api {
}
}
public static func parse_updateDraftMessage(_ reader: BufferReader) -> Update? {
var _1: Api.Peer?
var _1: Int32?
_1 = reader.readInt32()
var _2: Api.Peer?
if let signature = reader.readInt32() {
_1 = Api.parse(reader, signature: signature) as? Api.Peer
_2 = Api.parse(reader, signature: signature) as? Api.Peer
}
var _2: Api.DraftMessage?
var _3: Int32?
if Int(_1!) & Int(1 << 0) != 0 {_3 = reader.readInt32() }
var _4: Api.DraftMessage?
if let signature = reader.readInt32() {
_2 = Api.parse(reader, signature: signature) as? Api.DraftMessage
_4 = Api.parse(reader, signature: signature) as? Api.DraftMessage
}
let _c1 = _1 != nil
let _c2 = _2 != nil
if _c1 && _c2 {
return Api.Update.updateDraftMessage(peer: _1!, draft: _2!)
let _c3 = (Int(_1!) & Int(1 << 0) == 0) || _3 != nil
let _c4 = _4 != nil
if _c1 && _c2 && _c3 && _c4 {
return Api.Update.updateDraftMessage(flags: _1!, peer: _2!, topMsgId: _3, draft: _4!)
}
else {
return nil
@ -3046,21 +3060,27 @@ public extension Api {
}
}
public static func parse_updateMessageReactions(_ reader: BufferReader) -> Update? {
var _1: Api.Peer?
var _1: Int32?
_1 = reader.readInt32()
var _2: Api.Peer?
if let signature = reader.readInt32() {
_1 = Api.parse(reader, signature: signature) as? Api.Peer
_2 = Api.parse(reader, signature: signature) as? Api.Peer
}
var _2: Int32?
_2 = reader.readInt32()
var _3: Api.MessageReactions?
var _3: Int32?
_3 = reader.readInt32()
var _4: Int32?
if Int(_1!) & Int(1 << 0) != 0 {_4 = reader.readInt32() }
var _5: Api.MessageReactions?
if let signature = reader.readInt32() {
_3 = Api.parse(reader, signature: signature) as? Api.MessageReactions
_5 = Api.parse(reader, signature: signature) as? Api.MessageReactions
}
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
if _c1 && _c2 && _c3 {
return Api.Update.updateMessageReactions(peer: _1!, msgId: _2!, reactions: _3!)
let _c4 = (Int(_1!) & Int(1 << 0) == 0) || _4 != nil
let _c5 = _5 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 {
return Api.Update.updateMessageReactions(flags: _1!, peer: _2!, msgId: _3!, topMsgId: _4, reactions: _5!)
}
else {
return nil
@ -3680,14 +3700,16 @@ public extension Api {
_2 = parseString(reader)
var _3: String?
_3 = parseString(reader)
var _4: String?
_4 = parseString(reader)
var _4: [Api.Username]?
if let _ = reader.readInt32() {
_4 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Username.self)
}
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
let _c4 = _4 != nil
if _c1 && _c2 && _c3 && _c4 {
return Api.Update.updateUserName(userId: _1!, firstName: _2!, lastName: _3!, username: _4!)
return Api.Update.updateUserName(userId: _1!, firstName: _2!, lastName: _3!, usernames: _4!)
}
else {
return nil

View File

@ -1,5 +1,5 @@
public extension Api {
indirect enum Updates: TypeConstructorDescription {
enum Updates: TypeConstructorDescription {
case updateShort(update: Api.Update, date: Int32)
case updateShortChatMessage(flags: Int32, id: Int32, fromId: Int64, chatId: Int64, message: String, pts: Int32, ptsCount: Int32, date: Int32, fwdFrom: Api.MessageFwdHeader?, viaBotId: Int64?, replyTo: Api.MessageReplyHeader?, entities: [Api.MessageEntity]?, ttlPeriod: Int32?)
case updateShortMessage(flags: Int32, id: Int32, userId: Int64, message: String, pts: Int32, ptsCount: Int32, date: Int32, fwdFrom: Api.MessageFwdHeader?, viaBotId: Int64?, replyTo: Api.MessageReplyHeader?, entities: [Api.MessageEntity]?, ttlPeriod: Int32?)

View File

@ -1291,7 +1291,7 @@ public extension Api.payments {
}
}
public extension Api.payments {
indirect enum PaymentResult: TypeConstructorDescription {
enum PaymentResult: TypeConstructorDescription {
case paymentResult(updates: Api.Updates)
case paymentVerificationNeeded(url: String)

View File

@ -5741,11 +5741,12 @@ public extension Api.functions.messages {
}
}
public extension Api.functions.messages {
static func saveDraft(flags: Int32, replyToMsgId: Int32?, peer: Api.InputPeer, message: String, entities: [Api.MessageEntity]?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
static func saveDraft(flags: Int32, replyToMsgId: Int32?, topMsgId: Int32?, peer: Api.InputPeer, message: String, entities: [Api.MessageEntity]?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
let buffer = Buffer()
buffer.appendInt32(-1137057461)
buffer.appendInt32(-1271718337)
serializeInt32(flags, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 0) != 0 {serializeInt32(replyToMsgId!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 2) != 0 {serializeInt32(topMsgId!, buffer: buffer, boxed: false)}
peer.serialize(buffer, true)
serializeString(message, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 3) != 0 {buffer.appendInt32(481674261)
@ -5753,7 +5754,7 @@ public extension Api.functions.messages {
for item in entities! {
item.serialize(buffer, true)
}}
return (FunctionDescription(name: "messages.saveDraft", parameters: [("flags", String(describing: flags)), ("replyToMsgId", String(describing: replyToMsgId)), ("peer", String(describing: peer)), ("message", String(describing: message)), ("entities", String(describing: entities))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Bool? in
return (FunctionDescription(name: "messages.saveDraft", parameters: [("flags", String(describing: flags)), ("replyToMsgId", String(describing: replyToMsgId)), ("topMsgId", String(describing: topMsgId)), ("peer", String(describing: peer)), ("message", String(describing: message)), ("entities", String(describing: entities))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Bool? in
let reader = BufferReader(buffer)
var result: Api.Bool?
if let signature = reader.readInt32() {

View File

@ -521,7 +521,7 @@ public extension Api {
}
}
public extension Api {
indirect enum Chat: TypeConstructorDescription {
enum Chat: TypeConstructorDescription {
case channel(flags: Int32, flags2: Int32, id: Int64, accessHash: Int64?, title: String, username: String?, photo: Api.ChatPhoto, date: Int32, restrictionReason: [Api.RestrictionReason]?, adminRights: Api.ChatAdminRights?, bannedRights: Api.ChatBannedRights?, defaultBannedRights: Api.ChatBannedRights?, participantsCount: Int32?, usernames: [Api.Username]?)
case channelForbidden(flags: Int32, id: Int64, accessHash: Int64, title: String, untilDate: Int32?)
case chat(flags: Int32, id: Int64, title: String, photo: Api.ChatPhoto, participantsCount: Int32, date: Int32, version: Int32, migratedTo: Api.InputChannel?, adminRights: Api.ChatAdminRights?, defaultBannedRights: Api.ChatBannedRights?)
@ -1219,7 +1219,7 @@ public extension Api {
}
}
public extension Api {
indirect enum ChatInvite: TypeConstructorDescription {
enum ChatInvite: TypeConstructorDescription {
case chatInvite(flags: Int32, title: String, about: String?, photo: Api.Photo, participantsCount: Int32, participants: [Api.User]?)
case chatInviteAlready(chat: Api.Chat)
case chatInvitePeek(chat: Api.Chat, expires: Int32)

View File

@ -1,5 +1,5 @@
public extension Api {
indirect enum InputChannel: TypeConstructorDescription {
enum InputChannel: TypeConstructorDescription {
case inputChannel(channelId: Int64, accessHash: Int64)
case inputChannelEmpty
case inputChannelFromMessage(peer: Api.InputPeer, msgId: Int32, channelId: Int64)
@ -311,7 +311,7 @@ public extension Api {
}
}
public extension Api {
indirect enum InputDialogPeer: TypeConstructorDescription {
enum InputDialogPeer: TypeConstructorDescription {
case inputDialogPeer(peer: Api.InputPeer)
case inputDialogPeerFolder(folderId: Int32)
@ -653,7 +653,7 @@ public extension Api {
}
}
public extension Api {
indirect enum InputFileLocation: TypeConstructorDescription {
enum InputFileLocation: TypeConstructorDescription {
case inputDocumentFileLocation(id: Int64, accessHash: Int64, fileReference: Buffer, thumbSize: String)
case inputEncryptedFileLocation(id: Int64, accessHash: Int64)
case inputFileLocation(volumeId: Int64, localId: Int32, secret: Int64, fileReference: Buffer)
@ -963,7 +963,7 @@ public extension Api {
}
}
public extension Api {
indirect enum InputFolderPeer: TypeConstructorDescription {
enum InputFolderPeer: TypeConstructorDescription {
case inputFolderPeer(peer: Api.InputPeer, folderId: Int32)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {

View File

@ -1,5 +1,5 @@
public extension Api {
indirect enum InputGame: TypeConstructorDescription {
enum InputGame: TypeConstructorDescription {
case inputGameID(id: Int64, accessHash: Int64)
case inputGameShortName(botId: Api.InputUser, shortName: String)
@ -165,7 +165,7 @@ public extension Api {
}
}
public extension Api {
indirect enum InputInvoice: TypeConstructorDescription {
enum InputInvoice: TypeConstructorDescription {
case inputInvoiceMessage(peer: Api.InputPeer, msgId: Int32)
case inputInvoiceSlug(slug: String)
@ -857,7 +857,7 @@ public extension Api {
}
}
public extension Api {
indirect enum InputNotifyPeer: TypeConstructorDescription {
enum InputNotifyPeer: TypeConstructorDescription {
case inputNotifyBroadcasts
case inputNotifyChats
case inputNotifyForumTopic(peer: Api.InputPeer, topMsgId: Int32)

View File

@ -781,7 +781,7 @@ public extension Api {
}
}
public extension Api {
indirect enum InputSingleMedia: TypeConstructorDescription {
enum InputSingleMedia: TypeConstructorDescription {
case inputSingleMedia(flags: Int32, media: Api.InputMedia, randomId: Int64, message: String, entities: [Api.MessageEntity]?)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {

View File

@ -125,7 +125,7 @@ private func peerIdsRequiringLocalChatStateFromUpdates(_ updates: [Api.Update])
peerIds.insert(PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(channelId)))
case let .updateReadHistoryInbox(_, _, peer, _, _, _, _):
peerIds.insert(peer.peerId)
case let .updateDraftMessage(peer, draft):
case let .updateDraftMessage(_, peer, _, draft):
switch draft {
case .draftMessage:
peerIds.insert(peer.peerId)
@ -1236,11 +1236,11 @@ private func finalStateWithUpdatesAndServerTime(postbox: Postbox, network: Netwo
})
case let .updateUserStatus(userId, status):
updatedState.mergePeerPresences([PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId)): status], explicit: true)
case let .updateUserName(userId, _, _, username):
case let .updateUserName(userId, _, _, usernames):
//TODO add contact checking for apply first and last name
updatedState.updatePeer(PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId)), { peer in
if let user = peer as? TelegramUser {
return user.withUpdatedUsername(username)
return user.withUpdatedUsernames(usernames.map { TelegramPeerUsername(apiUsername: $0) })
} else {
return peer
}
@ -1410,7 +1410,7 @@ private func finalStateWithUpdatesAndServerTime(postbox: Postbox, network: Netwo
updatedState.addUpdateInstalledStickerPacks(.sync)
case .updateSavedGifs:
updatedState.addUpdateRecentGifs()
case let .updateDraftMessage(peer, draft):
case let .updateDraftMessage(_, peer, _, draft):
let inputState: SynchronizeableChatInputState?
switch draft {
case .draftMessageEmpty:
@ -1551,7 +1551,7 @@ private func finalStateWithUpdatesAndServerTime(postbox: Postbox, network: Netwo
return current
}
})
case let .updateMessageReactions(peer, msgId, reactions):
case let .updateMessageReactions(_, peer, msgId, _, reactions):
updatedState.updateMessageReactions(MessageId(peerId: peer.peerId, namespace: Namespaces.Message.Cloud, id: msgId), reactions: reactions, eventTimestamp: updatesDate)
case .updateAttachMenuBots:
updatedState.addUpdateAttachMenuBots()

View File

@ -858,7 +858,7 @@ public final class AccountViewTracker {
}
for update in updateList {
switch update {
case let .updateMessageReactions(peer, msgId, reactions):
case let .updateMessageReactions(_, peer, msgId, _, reactions):
transaction.updateMessage(MessageId(peerId: peer.peerId, namespace: Namespaces.Message.Cloud, id: msgId), update: { currentMessage in
var updatedReactions = ReactionsMessageAttribute(apiReactions: reactions)

View File

@ -141,14 +141,14 @@ private func synchronizeChatInputState(transaction: Transaction, postbox: Postbo
flags |= (1 << 3)
}
}
return network.request(Api.functions.messages.saveDraft(flags: flags, replyToMsgId: inputState?.replyToMessageId?.id, peer: inputPeer, message: inputState?.text ?? "", entities: apiEntitiesFromMessageTextEntities(inputState?.entities ?? [], associatedPeers: SimpleDictionary())))
|> delay(2.0, queue: Queue.concurrentDefaultQueue())
|> `catch` { _ -> Signal<Api.Bool, NoError> in
return .single(.boolFalse)
}
|> mapToSignal { _ -> Signal<Void, NoError> in
return .complete()
}
return network.request(Api.functions.messages.saveDraft(flags: flags, replyToMsgId: inputState?.replyToMessageId?.id, topMsgId: nil, peer: inputPeer, message: inputState?.text ?? "", entities: apiEntitiesFromMessageTextEntities(inputState?.entities ?? [], associatedPeers: SimpleDictionary())))
|> delay(2.0, queue: Queue.concurrentDefaultQueue())
|> `catch` { _ -> Signal<Api.Bool, NoError> in
return .single(.boolFalse)
}
|> mapToSignal { _ -> Signal<Void, NoError> in
return .complete()
}
} else {
return .complete()
}

View File

@ -296,7 +296,7 @@ extension Api.Update {
} else {
return []
}
case let .updateDraftMessage(peer: peer, draft: _):
case let .updateDraftMessage(_, peer, _, _):
return [peer.peerId]
case let .updateNewScheduledMessage(message):
return apiMessagePeerIds(message)

View File

@ -26,7 +26,7 @@ func _internal_clearCloudDraftsInteractively(postbox: Postbox, network: Network,
}
for update in updates {
switch update {
case let .updateDraftMessage(peer, _):
case let .updateDraftMessage(_, peer, _, _):
peerIds.insert(peer.peerId)
default:
break
@ -42,7 +42,7 @@ func _internal_clearCloudDraftsInteractively(postbox: Postbox, network: Network,
_internal_updateChatInputState(transaction: transaction, peerId: peerId, inputState: nil)
if let peer = transaction.getPeer(peerId), let inputPeer = apiInputPeer(peer) {
signals.append(network.request(Api.functions.messages.saveDraft(flags: 0, replyToMsgId: nil, peer: inputPeer, message: "", entities: nil))
signals.append(network.request(Api.functions.messages.saveDraft(flags: 0, replyToMsgId: nil, topMsgId: nil, peer: inputPeer, message: "", entities: nil))
|> `catch` { _ -> Signal<Api.Bool, NoError> in
return .single(.boolFalse)
}

View File

@ -303,7 +303,7 @@ func _internal_reorderAddressNames(account: Account, domain: AddressNameDomain,
return account.postbox.transaction { transaction -> Signal<Void, ReorderAddressNamesError> in
switch domain {
case .account:
return account.network.request(Api.functions.account.reorderUsernames(order: names.filter { $0.flags.contains(.isActive) }.map { $0.username }), automaticFloodWait: false)
return account.network.request(Api.functions.account.reorderUsernames(order: names.filter { $0.isActive }.map { $0.username }), automaticFloodWait: false)
|> mapError { _ -> ReorderAddressNamesError in
return .generic
}
@ -319,7 +319,7 @@ func _internal_reorderAddressNames(account: Account, domain: AddressNameDomain,
}
case let .peer(peerId):
if let peer = transaction.getPeer(peerId), let inputChannel = apiInputChannel(peer) {
return account.network.request(Api.functions.channels.reorderUsernames(channel: inputChannel, order: names.filter { $0.flags.contains(.isActive) }.map { $0.username }), automaticFloodWait: false)
return account.network.request(Api.functions.channels.reorderUsernames(channel: inputChannel, order: names.filter { $0.isActive }.map { $0.username }), automaticFloodWait: false)
|> mapError { _ -> ReorderAddressNamesError in
return .generic
}

View File

@ -68,6 +68,7 @@ public enum AdminLogEventAction {
case toggleCopyProtection(Bool)
case sendMessage(Message)
case changeAvailableReactions(previousValue: PeerAllowedReactions, updatedValue: PeerAllowedReactions)
case changeUsernames(prev: [String], new: [String])
}
public enum ChannelAdminLogEventError {
@ -265,6 +266,8 @@ func channelAdminLogEvents(postbox: Postbox, network: Network, peerId: PeerId, m
}
case let .channelAdminLogEventActionChangeAvailableReactions(prevValue, newValue):
action = .changeAvailableReactions(previousValue: PeerAllowedReactions(apiReactions: prevValue), updatedValue: PeerAllowedReactions(apiReactions: newValue))
case let .channelAdminLogEventActionChangeUsernames(prevValue, newValue):
action = .changeUsernames(prev: prevValue, new: newValue)
}
let peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId))
if let action = action {

View File

@ -7,7 +7,7 @@ private final class LinkHelperClass: NSObject {
}
public func canSendMessagesToPeer(_ peer: Peer) -> Bool {
if let peer = peer as? TelegramUser, peer.username == "replies" {
if let peer = peer as? TelegramUser, peer.addressName == "replies" {
return false
} else if peer is TelegramUser || peer is TelegramGroup {
return !peer.isDeleted

View File

@ -41,19 +41,20 @@ public extension Peer {
return nil
}
}
var addressName: String? {
switch self {
case let user as TelegramUser:
return user.username
return user.usernames.first(where: { $0.isActive }).map { $0.username } ?? user.username
case _ as TelegramGroup:
return nil
case let channel as TelegramChannel:
return channel.username
return channel.usernames.first(where: { $0.isActive }).map { $0.username } ?? channel.username
default:
return nil
}
}
var usernames: [TelegramPeerUsername] {
switch self {
case let user as TelegramUser:
@ -67,6 +68,19 @@ public extension Peer {
}
}
var editableUsername: String? {
switch self {
case let user as TelegramUser:
return user.usernames.first(where: { $0.flags.contains(.isEditable) }).map { $0.username } ?? user.username
case _ as TelegramGroup:
return nil
case let channel as TelegramChannel:
return channel.usernames.first(where: { $0.flags.contains(.isEditable) }).map { $0.username } ?? channel.username
default:
return nil
}
}
var displayLetters: [String] {
switch self {
case let user as TelegramUser:
@ -189,6 +203,12 @@ public extension Peer {
}
}
public extension TelegramPeerUsername {
var isActive: Bool {
return self.flags.contains(.isActive) || self.flags.contains(.isEditable)
}
}
public extension PeerId {
var isGroupOrChannel: Bool {
switch self.namespace {

View File

@ -10980,7 +10980,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
canClearForEveryone = nil
}
} else if let channel = chatPeer as? TelegramChannel {
if let username = channel.username, !username.isEmpty {
if let username = channel.addressName, !username.isEmpty {
if isLargeGroupOrChannel {
canClearCache = true
canClearForMyself = nil
@ -15486,7 +15486,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
self.chatDisplayNode.dismissInput()
if let peer = peer as? TelegramChannel, let username = peer.username, !username.isEmpty {
if let peer = peer as? TelegramChannel, let username = peer.addressName, !username.isEmpty {
let actionSheet = ActionSheetController(presentationData: self.presentationData)
var items: [ActionSheetItem] = []

View File

@ -84,7 +84,7 @@ private func peerButtons(_ peer: Peer, interfaceState: ChatPresentationInterface
buttons.append(.info)
return buttons
} else if let channel = peer as? TelegramChannel {
if channel.flags.contains(.isCreator) || channel.username == nil {
if channel.flags.contains(.isCreator) || channel.addressName == nil {
return [.search, muteAction, infoButton]
} else {
return [.search, .report, muteAction, infoButton]

View File

@ -1145,7 +1145,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
if let attribute = attribute as? InlineBotMessageAttribute {
var inlineBotNameString: String?
if let peerId = attribute.peerId, let bot = item.message.peers[peerId] as? TelegramUser {
inlineBotNameString = bot.username
inlineBotNameString = bot.addressName
} else {
inlineBotNameString = attribute.title
}
@ -1983,7 +1983,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
if let item = self.item, let forwardInfo = item.message.forwardInfo {
let performAction: () -> Void = {
if let sourceMessageId = forwardInfo.sourceMessageId {
if !item.message.id.peerId.isReplies, let channel = forwardInfo.author as? TelegramChannel, channel.username == nil {
if !item.message.id.peerId.isReplies, let channel = forwardInfo.author as? TelegramChannel, channel.addressName == nil {
if case let .broadcast(info) = channel.info, info.flags.contains(.hasDiscussionGroup) {
} else if case .member = channel.participationStatus {
} else {

View File

@ -1412,7 +1412,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
for attribute in firstMessage.attributes {
if let attribute = attribute as? InlineBotMessageAttribute {
if let peerId = attribute.peerId, let bot = firstMessage.peers[peerId] as? TelegramUser {
inlineBotNameString = bot.username
inlineBotNameString = bot.addressName
} else {
inlineBotNameString = attribute.title
}
@ -3363,7 +3363,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
if let item = self.item, let forwardInfo = item.message.forwardInfo {
let performAction: () -> Void = {
if let sourceMessageId = forwardInfo.sourceMessageId {
if let channel = forwardInfo.author as? TelegramChannel, channel.username == nil {
if let channel = forwardInfo.author as? TelegramChannel, channel.addressName == nil {
if case let .broadcast(info) = channel.info, info.flags.contains(.hasDiscussionGroup) {
} else if case .member = channel.participationStatus {
} else if !item.message.id.peerId.isReplies {

View File

@ -184,7 +184,7 @@ class ChatMessageForwardInfoNode: ASDisplayNode {
var currentCredibilityIconImage: UIImage?
var highlight = true
if let peer = peer {
if let channel = peer as? TelegramChannel, channel.username == nil {
if let channel = peer as? TelegramChannel, channel.addressName == nil {
if case let .broadcast(info) = channel.info, info.flags.contains(.hasDiscussionGroup) {
} else if case .member = channel.participationStatus {
} else {

View File

@ -424,7 +424,7 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView, UIGestureRecognizerD
if let attribute = attribute as? InlineBotMessageAttribute {
var inlineBotNameString: String?
if let peerId = attribute.peerId, let bot = item.message.peers[peerId] as? TelegramUser {
inlineBotNameString = bot.username
inlineBotNameString = bot.addressName
} else {
inlineBotNameString = attribute.title
}
@ -918,7 +918,7 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView, UIGestureRecognizerD
if let item = self.item, let forwardInfo = item.message.forwardInfo {
let performAction: () -> Void = {
if let sourceMessageId = forwardInfo.sourceMessageId {
if !item.message.id.peerId.isReplies, let channel = forwardInfo.author as? TelegramChannel, channel.username == nil {
if !item.message.id.peerId.isReplies, let channel = forwardInfo.author as? TelegramChannel, channel.addressName == nil {
if case let .broadcast(info) = channel.info, info.flags.contains(.hasDiscussionGroup) {
} else if case .member = channel.participationStatus {
} else {

View File

@ -590,7 +590,7 @@ class ChatMessageStickerItemNode: ChatMessageItemView {
if let attribute = attribute as? InlineBotMessageAttribute {
var inlineBotNameString: String?
if let peerId = attribute.peerId, let bot = item.message.peers[peerId] as? TelegramUser {
inlineBotNameString = bot.username
inlineBotNameString = bot.addressName
} else {
inlineBotNameString = attribute.title
}

View File

@ -200,6 +200,56 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
attributes.append(TextEntitiesMessageAttribute(entities: [MessageTextEntity(range: 0 ..< text.count, type: .Italic)]))
}
let prevMessage = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: 1), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: prevText, attributes: previousAttributes, media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:])
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: text, attributes: attributes, media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:])
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil), additionalContent: !prev.isEmpty ? .eventLogPreviousLink(prevMessage) : nil)
}
case let .changeUsernames(prev, new):
var peers = SimpleDictionary<PeerId, Peer>()
var author: Peer?
if let peer = self.entry.peers[self.entry.event.peerId] {
author = peer
peers[peer.id] = peer
}
switch self.id.contentIndex {
case .header:
var text: String = ""
var entities: [MessageTextEntity] = []
if let peer = peer as? TelegramChannel, case .broadcast = peer.info {
appendAttributedText(text: self.presentationData.strings.Channel_AdminLog_MessageChangedChannelUsername(author.flatMap(EnginePeer.init)?.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder) ?? ""), generateEntities: { index in
if index == 0, let author = author {
return [.TextMention(peerId: author.id)]
}
return []
}, to: &text, entities: &entities)
} else {
appendAttributedText(text: self.presentationData.strings.Channel_AdminLog_MessageChangedGroupUsername(author.flatMap(EnginePeer.init)?.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder) ?? ""), generateEntities: { index in
if index == 0, let author = author {
return [.TextMention(peerId: author.id)]
}
return []
}, to: &text, entities: &entities)
}
let action: TelegramMediaActionType = TelegramMediaActionType.customText(text: text, entities: entities)
let message = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: 1), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:])
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil))
case .content:
var previousAttributes: [MessageAttribute] = []
var attributes: [MessageAttribute] = []
let prevText = "https://t.me/\(prev.first ?? "")"
previousAttributes.append(TextEntitiesMessageAttribute(entities: [MessageTextEntity(range: 0 ..< prevText.count, type: .Url)]))
let text: String
if !new.isEmpty {
text = "https://t.me/\(new.first ?? "")"
attributes.append(TextEntitiesMessageAttribute(entities: [MessageTextEntity(range: 0 ..< text.count, type: .Url)]))
} else {
text = self.presentationData.strings.Channel_AdminLog_EmptyMessageText
attributes.append(TextEntitiesMessageAttribute(entities: [MessageTextEntity(range: 0 ..< text.count, type: .Italic)]))
}
let prevMessage = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: 1), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: prevText, attributes: previousAttributes, media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:])
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: text, attributes: attributes, media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:])
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(id: peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true, availableReactions: nil, defaultReaction: nil, isPremium: false, accountPeer: nil), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(), location: nil), additionalContent: !prev.isEmpty ? .eventLogPreviousLink(prevMessage) : nil)

View File

@ -228,8 +228,8 @@ public func isOverlayControllerForChatNotificationOverlayPresentation(_ controll
return false
}
public func navigateToForumThreadImpl(context: AccountContext, peerId: EnginePeer.Id, threadId: Int64, navigationController: NavigationController, activateInput: ChatControllerActivateInput?) -> Signal<Never, NoError> {
return fetchAndPreloadReplyThreadInfo(context: context, subject: .groupMessage(MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: Int32(clamping: threadId))), atMessageId: nil, preload: false)
public func navigateToForumThreadImpl(context: AccountContext, peerId: EnginePeer.Id, threadId: Int64, messageId: EngineMessage.Id?, navigationController: NavigationController, activateInput: ChatControllerActivateInput?) -> Signal<Never, NoError> {
return fetchAndPreloadReplyThreadInfo(context: context, subject: .groupMessage(MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: Int32(clamping: threadId))), atMessageId: messageId, preload: false)
|> deliverOnMainQueue
|> beforeNext { [weak context, weak navigationController] result in
guard let context = context, let navigationController = navigationController else {
@ -239,7 +239,11 @@ public func navigateToForumThreadImpl(context: AccountContext, peerId: EnginePee
let chatLocation: ChatLocation = .replyThread(message: result.message)
let subject: ChatControllerSubject?
subject = nil
if let messageId = messageId {
subject = .message(id: .id(messageId), highlight: true, timecode: nil)
} else {
subject = nil
}
var actualActivateInput: ChatControllerActivateInput? = result.isEmpty ? .text : nil
if let activateInput = activateInput {

View File

@ -2614,8 +2614,7 @@ final class PeerInfoHeaderNode: ASDisplayNode {
if self.isSettings, let user = peer as? TelegramUser {
var subtitle = formatPhoneNumber(user.phone ?? "")
let mainUsername = user.usernames.first(where: { $0.flags.contains(.isActive) })?.username ?? user.username
if let mainUsername = mainUsername, !mainUsername.isEmpty {
if let mainUsername = user.addressName, !mainUsername.isEmpty {
subtitle = "\(subtitle) • @\(mainUsername)"
}
smallSubtitleString = NSAttributedString(string: subtitle, font: Font.regular(15.0), textColor: UIColor(rgb: 0xffffff, alpha: 0.7))

View File

@ -956,10 +956,9 @@ private func infoItems(data: PeerInfoScreenData?, context: AccountContext, prese
interaction.requestLayout(false)
}))
}
if let username = user.username {
let mainUsername = user.usernames.first(where: { $0.flags.contains(.isActive) })?.username ?? username
if let mainUsername = user.addressName {
var additionalUsernames: String?
let usernames = user.usernames.filter { $0.flags.contains(.isActive) && $0.username != mainUsername }
let usernames = user.usernames.filter { $0.isActive && $0.username != mainUsername }
if !usernames.isEmpty {
additionalUsernames = presentationData.strings.Profile_AdditionalUsernames(String(usernames.map { "@\($0.username)" }.joined(separator: ", "))).string
}
@ -973,7 +972,7 @@ private func infoItems(data: PeerInfoScreenData?, context: AccountContext, prese
textColor: .accent,
icon: .qrCode,
action: { _ in
interaction.openUsername(username)
interaction.openUsername(mainUsername)
}, longTapAction: { sourceNode in
interaction.openPeerInfoContextMenu(.link(customLink: nil), sourceNode, nil)
}, linkItemAction: { type, item, _, _ in
@ -1134,11 +1133,9 @@ private func infoItems(data: PeerInfoScreenData?, context: AccountContext, prese
))
}
if let username = channel.username {
if let mainUsername = channel.addressName {
var additionalUsernames: String?
let mainUsername = channel.usernames.first(where: { $0.flags.contains(.isActive) })?.username ?? username
let usernames = channel.usernames.filter { $0.flags.contains(.isActive) && $0.username != mainUsername }
let usernames = channel.usernames.filter { $0.isActive && $0.username != mainUsername }
if !usernames.isEmpty {
additionalUsernames = presentationData.strings.Profile_AdditionalUsernames(String(usernames.map { "@\($0.username)" }.joined(separator: ", "))).string
}
@ -1152,7 +1149,7 @@ private func infoItems(data: PeerInfoScreenData?, context: AccountContext, prese
textColor: .accent,
icon: .qrCode,
action: { _ in
interaction.openUsername(username)
interaction.openUsername(mainUsername)
}, longTapAction: { sourceNode in
interaction.openPeerInfoContextMenu(.link(customLink: nil), sourceNode, nil)
}, linkItemAction: { type, item, sourceNode, sourceRect in
@ -1350,7 +1347,7 @@ private func editingItems(data: PeerInfoScreenData?, context: AccountContext, pr
if isCreator {
let linkText: String
if let _ = channel.username {
if let _ = channel.addressName {
linkText = presentationData.strings.Channel_Setup_TypePublic
} else {
linkText = presentationData.strings.Channel_Setup_TypePrivate
@ -1360,7 +1357,7 @@ private func editingItems(data: PeerInfoScreenData?, context: AccountContext, pr
}))
}
if (isCreator && (channel.username?.isEmpty ?? true)) || (!channel.flags.contains(.isCreator) && channel.adminRights?.rights.contains(.canInviteUsers) == true) {
if (isCreator && (channel.addressName?.isEmpty ?? true)) || (!channel.flags.contains(.isCreator) && channel.adminRights?.rights.contains(.canInviteUsers) == true) {
let invitesText: String
if let count = data.invitations?.count, count > 0 {
invitesText = "\(count)"
@ -1488,7 +1485,7 @@ private func editingItems(data: PeerInfoScreenData?, context: AccountContext, pr
let ItemTopics = 116
let isCreator = channel.flags.contains(.isCreator)
let isPublic = channel.username != nil
let isPublic = channel.addressName != nil
if let cachedData = data.cachedData as? CachedChannelData {
if isCreator, let location = cachedData.peerGeoLocation {
@ -1515,7 +1512,7 @@ private func editingItems(data: PeerInfoScreenData?, context: AccountContext, pr
if cachedData.peerGeoLocation != nil {
if isCreator {
let linkText: String
if let username = channel.username {
if let username = channel.addressName {
linkText = "@\(username)"
} else {
linkText = presentationData.strings.GroupInfo_PublicLinkAdd
@ -1533,7 +1530,7 @@ private func editingItems(data: PeerInfoScreenData?, context: AccountContext, pr
}
}
if (isCreator && (channel.username?.isEmpty ?? true) && cachedData.peerGeoLocation == nil) || (!isCreator && channel.adminRights?.rights.contains(.canInviteUsers) == true) {
if (isCreator && (channel.addressName?.isEmpty ?? true) && cachedData.peerGeoLocation == nil) || (!isCreator && channel.adminRights?.rights.contains(.canInviteUsers) == true) {
let invitesText: String
if let count = data.invitations?.count, count > 0 {
invitesText = "\(count)"
@ -3210,7 +3207,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
}))
}
if copyUsername, let username = user.username, !username.isEmpty {
if copyUsername, let username = user.addressName, !username.isEmpty {
actions.append(ContextMenuAction(content: .text(title: strongSelf.presentationData.strings.Settings_CopyUsername, accessibilityLabel: strongSelf.presentationData.strings.Settings_CopyUsername), action: { [weak self] in
UIPasteboard.general.string = "@\(username)"
@ -4268,7 +4265,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
}
if let _ = user.botInfo {
if user.username != nil {
if user.addressName != nil {
items.append(.action(ContextMenuActionItem(text: presentationData.strings.UserInfo_ShareBot, icon: { theme in
generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Forward"), color: theme.contextMenu.primaryColor)
}, action: { [weak self] _, f in
@ -5827,7 +5824,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
guard let strongSelf = self else {
return
}
if case let .user(peer) = peer, let username = peer.username {
if case let .user(peer) = peer, let username = peer.addressName {
let shareController = ShareController(context: strongSelf.context, subject: .url("https://t.me/\(username)"), updatedPresentationData: strongSelf.controller?.updatedPresentationData)
shareController.completed = { [weak self] peerIds in
guard let strongSelf = self else {
@ -9585,7 +9582,7 @@ struct ClearPeerHistory {
var canDeleteLocally = true
if case .broadcast = channel.info {
canDeleteLocally = false
} else if channel.username != nil {
} else if channel.addressName != nil {
canDeleteLocally = false
}

View File

@ -600,7 +600,7 @@ final class PeerSelectionControllerNode: ASDisplayNode {
location: .chatList(groupId: EngineChatList.Group(.root)),
displaySearchFilters: false,
hasDownloads: false,
openPeer: { [weak self] peer, chatPeer, _ in
openPeer: { [weak self] peer, chatPeer, _, _ in
guard let strongSelf = self else {
return
}

View File

@ -1159,8 +1159,8 @@ public final class SharedAccountContextImpl: SharedAccountContext {
navigateToForumChannelImpl(context: context, peerId: peerId, navigationController: navigationController)
}
public func navigateToForumThread(context: AccountContext, peerId: EnginePeer.Id, threadId: Int64, navigationController: NavigationController, activateInput: ChatControllerActivateInput?) -> Signal<Never, NoError> {
return navigateToForumThreadImpl(context: context, peerId: peerId, threadId: threadId, navigationController: navigationController, activateInput: activateInput)
public func navigateToForumThread(context: AccountContext, peerId: EnginePeer.Id, threadId: Int64, messageId: EngineMessage.Id?, navigationController: NavigationController, activateInput: ChatControllerActivateInput?) -> Signal<Never, NoError> {
return navigateToForumThreadImpl(context: context, peerId: peerId, threadId: threadId, messageId: messageId, navigationController: navigationController, activateInput: activateInput)
}
public func openStorageUsage(context: AccountContext) {