diff --git a/submodules/ChatListUI/BUILD b/submodules/ChatListUI/BUILD index 407a87ff4c..49af1bbc83 100644 --- a/submodules/ChatListUI/BUILD +++ b/submodules/ChatListUI/BUILD @@ -78,6 +78,7 @@ swift_library( "//submodules/TelegramUI/Components/EmojiStatusComponent", "//submodules/TelegramUI/Components/EmojiStatusSelectionComponent", "//submodules/TelegramUI/Components/EntityKeyboard", + "//submodules/TelegramUI/Components/ForumCreateTopicScreen:ForumCreateTopicScreen", "//submodules/AnimationUI:AnimationUI", ], visibility = [ diff --git a/submodules/ChatListUI/Sources/ChatListController.swift b/submodules/ChatListUI/Sources/ChatListController.swift index bdc9556c17..5d017b3aee 100644 --- a/submodules/ChatListUI/Sources/ChatListController.swift +++ b/submodules/ChatListUI/Sources/ChatListController.swift @@ -36,6 +36,7 @@ import MultiAnimationRenderer import EmojiStatusSelectionComponent import EntityKeyboard import TelegramStringFormatting +import ForumCreateTopicScreen import AnimationUI private func fixListNodeScrolling(_ listNode: ListView, searchNode: NavigationBarSearchContentNode) -> Bool { diff --git a/submodules/ChatListUI/Sources/ChatListControllerNode.swift b/submodules/ChatListUI/Sources/ChatListControllerNode.swift index b76c283be6..2e225b345c 100644 --- a/submodules/ChatListUI/Sources/ChatListControllerNode.swift +++ b/submodules/ChatListUI/Sources/ChatListControllerNode.swift @@ -179,7 +179,7 @@ private final class ChatListShimmerNode: ASDisplayNode { let chatListPresentationData = ChatListPresentationData(theme: presentationData.theme, fontSize: presentationData.chatFontSize, strings: presentationData.strings, dateTimeFormat: presentationData.dateTimeFormat, nameSortOrder: presentationData.nameSortOrder, nameDisplayOrder: presentationData.nameDisplayOrder, disableAnimations: true) - let peer1: EnginePeer = .user(TelegramUser(id: EnginePeer.Id(namespace: Namespaces.Peer.CloudUser, id: EnginePeer.Id.Id._internalFromInt64Value(0)), accessHash: nil, firstName: "FirstName", lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: nil)) + let peer1: EnginePeer = .user(TelegramUser(id: EnginePeer.Id(namespace: Namespaces.Peer.CloudUser, id: EnginePeer.Id.Id._internalFromInt64Value(0)), accessHash: nil, firstName: "FirstName", lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [])) let timestamp1: Int32 = 100000 let peers: [EnginePeer.Id: EnginePeer] = [:] let interaction = ChatListNodeInteraction(context: context, animationCache: animationCache, animationRenderer: animationRenderer, activateSearch: {}, peerSelected: { _, _, _, _ in }, disabledPeerSelected: { _ in }, togglePeerSelected: { _ in }, togglePeersSelection: { _, _ in }, additionalCategorySelected: { _ in diff --git a/submodules/ChatListUI/Sources/ChatListSearchListPaneNode.swift b/submodules/ChatListUI/Sources/ChatListSearchListPaneNode.swift index 6b9b531187..35d5320074 100644 --- a/submodules/ChatListUI/Sources/ChatListSearchListPaneNode.swift +++ b/submodules/ChatListUI/Sources/ChatListSearchListPaneNode.swift @@ -2946,7 +2946,7 @@ private final class ChatListSearchShimmerNode: ASDisplayNode { let chatListPresentationData = ChatListPresentationData(theme: presentationData.theme, fontSize: presentationData.chatFontSize, strings: presentationData.strings, dateTimeFormat: presentationData.dateTimeFormat, nameSortOrder: presentationData.nameSortOrder, nameDisplayOrder: presentationData.nameDisplayOrder, disableAnimations: true) - let peer1: EnginePeer = .user(TelegramUser(id: EnginePeer.Id(namespace: Namespaces.Peer.CloudUser, id: EnginePeer.Id.Id._internalFromInt64Value(0)), accessHash: nil, firstName: "FirstName", lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: nil)) + let peer1: EnginePeer = .user(TelegramUser(id: EnginePeer.Id(namespace: Namespaces.Peer.CloudUser, id: EnginePeer.Id.Id._internalFromInt64Value(0)), accessHash: nil, firstName: "FirstName", lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [])) let timestamp1: Int32 = 100000 var peers: [EnginePeer.Id: EnginePeer] = [:] peers[peer1.id] = peer1 diff --git a/submodules/Components/ViewControllerComponent/Sources/ViewControllerComponent.swift b/submodules/Components/ViewControllerComponent/Sources/ViewControllerComponent.swift index b635d9e54f..156f4aab63 100644 --- a/submodules/Components/ViewControllerComponent/Sources/ViewControllerComponent.swift +++ b/submodules/Components/ViewControllerComponent/Sources/ViewControllerComponent.swift @@ -24,7 +24,9 @@ open class ViewControllerComponentContainer: ViewController { public let statusBarHeight: CGFloat public let navigationHeight: CGFloat public let safeInsets: UIEdgeInsets + public let inputHeight: CGFloat public let metrics: LayoutMetrics + public let deviceMetrics: DeviceMetrics public let isVisible: Bool public let theme: PresentationTheme public let strings: PresentationStrings @@ -35,7 +37,9 @@ open class ViewControllerComponentContainer: ViewController { statusBarHeight: CGFloat, navigationHeight: CGFloat, safeInsets: UIEdgeInsets, + inputHeight: CGFloat, metrics: LayoutMetrics, + deviceMetrics: DeviceMetrics, isVisible: Bool, theme: PresentationTheme, strings: PresentationStrings, @@ -45,7 +49,9 @@ open class ViewControllerComponentContainer: ViewController { self.statusBarHeight = statusBarHeight self.navigationHeight = navigationHeight self.safeInsets = safeInsets + self.inputHeight = inputHeight self.metrics = metrics + self.deviceMetrics = deviceMetrics self.isVisible = isVisible self.theme = theme self.strings = strings @@ -67,9 +73,15 @@ open class ViewControllerComponentContainer: ViewController { if lhs.safeInsets != rhs.safeInsets { return false } + if lhs.inputHeight != rhs.inputHeight { + return false + } if lhs.metrics != rhs.metrics { return false } + if lhs.deviceMetrics != rhs.deviceMetrics { + return false + } if lhs.isVisible != rhs.isVisible { return false } @@ -125,7 +137,9 @@ open class ViewControllerComponentContainer: ViewController { statusBarHeight: layout.statusBarHeight ?? 0.0, navigationHeight: navigationHeight, safeInsets: UIEdgeInsets(top: layout.intrinsicInsets.top + layout.safeInsets.top, left: layout.safeInsets.left, bottom: layout.intrinsicInsets.bottom + layout.safeInsets.bottom, right: layout.safeInsets.right), + inputHeight: layout.inputHeight ?? 0.0, metrics: layout.metrics, + deviceMetrics: layout.deviceMetrics, isVisible: self.currentIsVisible, theme: self.theme ?? self.presentationData.theme, strings: self.presentationData.strings, diff --git a/submodules/ContactListUI/Sources/InviteContactsControllerNode.swift b/submodules/ContactListUI/Sources/InviteContactsControllerNode.swift index 9666179b78..faba0442e6 100644 --- a/submodules/ContactListUI/Sources/InviteContactsControllerNode.swift +++ b/submodules/ContactListUI/Sources/InviteContactsControllerNode.swift @@ -56,7 +56,7 @@ private enum InviteContactsEntry: Comparable, Identifiable { } else { status = .none } - let peer: EnginePeer = .user(TelegramUser(id: EnginePeer.Id(namespace: .max, id: EnginePeer.Id.Id._internalFromInt64Value(0)), accessHash: nil, firstName: contact.firstName, lastName: contact.lastName, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: nil)) + let peer: EnginePeer = .user(TelegramUser(id: EnginePeer.Id(namespace: .max, id: EnginePeer.Id.Id._internalFromInt64Value(0)), accessHash: nil, firstName: contact.firstName, lastName: contact.lastName, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [])) return ContactsPeerItem(presentationData: ItemListPresentationData(presentationData), sortOrder: nameSortOrder, displayOrder: nameDisplayOrder, context: context, peerMode: .peer, peer: .peer(peer: peer, chatPeer: peer), status: status, enabled: true, selection: selection, editing: ContactsPeerItemEditing(editable: false, editing: false, revealed: false), index: nil, header: ChatListSearchItemHeader(type: .contacts, theme: theme, strings: strings, actionTitle: nil, action: nil), action: { _ in interaction.toggleContact(id) }) diff --git a/submodules/InstantPageUI/Sources/InstantPageControllerNode.swift b/submodules/InstantPageUI/Sources/InstantPageControllerNode.swift index 604a8aa477..d3e37e1c43 100644 --- a/submodules/InstantPageUI/Sources/InstantPageControllerNode.swift +++ b/submodules/InstantPageUI/Sources/InstantPageControllerNode.swift @@ -1403,7 +1403,7 @@ final class InstantPageControllerNode: ASDisplayNode, UIScrollViewDelegate { }, openUrl: { _ in }, openPeer: { _ in }, showAll: false) - let peer = TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(0)), accessHash: nil, firstName: "", lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: nil) + let peer = TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(0)), accessHash: nil, firstName: "", lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: []) let message = Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: 0, id: 0), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 0, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peer, text: "", attributes: [], media: [map], peers: SimpleDictionary(), associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) let controller = LocationViewController(context: self.context, subject: message, params: controllerParams) diff --git a/submodules/InviteLinksUI/Sources/InviteLinkViewController.swift b/submodules/InviteLinksUI/Sources/InviteLinkViewController.swift index 20797e6516..c0ef30c836 100644 --- a/submodules/InviteLinksUI/Sources/InviteLinkViewController.swift +++ b/submodules/InviteLinksUI/Sources/InviteLinkViewController.swift @@ -690,7 +690,7 @@ public final class InviteLinkViewController: ViewController { if requestsState.importers.isEmpty && requestsState.isLoadingMore { count = min(4, state.count) loading = true - let fakeUser = TelegramUser(id: EnginePeer.Id(namespace: .max, id: EnginePeer.Id.Id._internalFromInt64Value(0)), accessHash: nil, firstName: "", lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: nil) + let fakeUser = TelegramUser(id: EnginePeer.Id(namespace: .max, id: EnginePeer.Id.Id._internalFromInt64Value(0)), accessHash: nil, firstName: "", lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: []) for i in 0 ..< count { entries.append(.request(Int32(i), presentationData.theme, presentationData.dateTimeFormat, EnginePeer.user(fakeUser), 0, true)) } @@ -724,7 +724,7 @@ public final class InviteLinkViewController: ViewController { if state.importers.isEmpty && state.isLoadingMore { count = min(4, state.count) loading = true - let fakeUser = TelegramUser(id: EnginePeer.Id(namespace: .max, id: EnginePeer.Id.Id._internalFromInt64Value(0)), accessHash: nil, firstName: "", lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: nil) + let fakeUser = TelegramUser(id: EnginePeer.Id(namespace: .max, id: EnginePeer.Id.Id._internalFromInt64Value(0)), accessHash: nil, firstName: "", lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: []) for i in 0 ..< count { entries.append(.importer(Int32(i), presentationData.theme, presentationData.dateTimeFormat, EnginePeer.user(fakeUser), 0, true)) } diff --git a/submodules/MediaPickerUI/Sources/MediaPickerSelectedListNode.swift b/submodules/MediaPickerUI/Sources/MediaPickerSelectedListNode.swift index ef9e4100f6..36e33fc96e 100644 --- a/submodules/MediaPickerUI/Sources/MediaPickerSelectedListNode.swift +++ b/submodules/MediaPickerUI/Sources/MediaPickerSelectedListNode.swift @@ -728,7 +728,7 @@ final class MediaPickerSelectedListNode: ASDisplayNode, UIScrollViewDelegate, UI let peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(1)) var peers = SimpleDictionary() - peers[peerId] = TelegramUser(id: peerId, accessHash: nil, firstName: "", lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: nil) + peers[peerId] = TelegramUser(id: peerId, accessHash: nil, firstName: "", lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: []) let previewText = groupLayouts.count > 1 ? presentationData.strings.Attachment_MessagesPreview : presentationData.strings.Attachment_MessagePreview diff --git a/submodules/PeerInfoUI/Sources/DeviceContactInfoController.swift b/submodules/PeerInfoUI/Sources/DeviceContactInfoController.swift index aab00da39e..f38b84554a 100644 --- a/submodules/PeerInfoUI/Sources/DeviceContactInfoController.swift +++ b/submodules/PeerInfoUI/Sources/DeviceContactInfoController.swift @@ -652,7 +652,7 @@ private func deviceContactInfoEntries(account: Account, engine: TelegramEngine, firstName = presentationData.strings.Message_Contact } - entries.append(.info(entries.count, presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, peer: peer ?? TelegramUser(id: PeerId(namespace: .max, id: PeerId.Id._internalFromInt64Value(0)), accessHash: nil, firstName: firstName, lastName: isOrganization ? nil : personName.1, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: nil), state: ItemListAvatarAndNameInfoItemState(editingName: editingName, updatingName: nil), job: isOrganization ? nil : jobSummary, isPlain: !isShare)) + entries.append(.info(entries.count, presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, peer: peer ?? TelegramUser(id: PeerId(namespace: .max, id: PeerId.Id._internalFromInt64Value(0)), accessHash: nil, firstName: firstName, lastName: isOrganization ? nil : personName.1, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: []), state: ItemListAvatarAndNameInfoItemState(editingName: editingName, updatingName: nil), job: isOrganization ? nil : jobSummary, isPlain: !isShare)) if !selecting { if let _ = peer { diff --git a/submodules/PremiumUI/Sources/PremiumLimitsListScreen.swift b/submodules/PremiumUI/Sources/PremiumLimitsListScreen.swift index 9c083cf901..7eef3f2c21 100644 --- a/submodules/PremiumUI/Sources/PremiumLimitsListScreen.swift +++ b/submodules/PremiumUI/Sources/PremiumLimitsListScreen.swift @@ -630,7 +630,9 @@ public class PremimLimitsListScreen: ViewController { statusBarHeight: 0.0, navigationHeight: navigationHeight, safeInsets: UIEdgeInsets(top: layout.intrinsicInsets.top + layout.safeInsets.top, left: layout.safeInsets.left, bottom: footerHeight, right: layout.safeInsets.right), + inputHeight: layout.inputHeight ?? 0.0, metrics: layout.metrics, + deviceMetrics: layout.deviceMetrics, isVisible: self.currentIsVisible, theme: self.theme ?? self.presentationData.theme, strings: self.presentationData.strings, diff --git a/submodules/SettingsUI/Sources/BubbleSettings/BubbleSettingsController.swift b/submodules/SettingsUI/Sources/BubbleSettings/BubbleSettingsController.swift index 5157b8ddf3..c94c8c1b81 100644 --- a/submodules/SettingsUI/Sources/BubbleSettings/BubbleSettingsController.swift +++ b/submodules/SettingsUI/Sources/BubbleSettings/BubbleSettingsController.swift @@ -163,8 +163,8 @@ private final class BubbleSettingsControllerNode: ASDisplayNode, UIScrollViewDel let otherPeerId = self.context.account.peerId var peers = SimpleDictionary() var messages = SimpleDictionary() - peers[peerId] = TelegramUser(id: peerId, accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_Chat_2_ReplyName, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: nil) - peers[otherPeerId] = TelegramUser(id: otherPeerId, accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_Chat_2_ReplyName, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: nil) + peers[peerId] = TelegramUser(id: peerId, accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_Chat_2_ReplyName, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: []) + peers[otherPeerId] = TelegramUser(id: otherPeerId, accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_Chat_2_ReplyName, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: []) let replyMessageId = MessageId(peerId: peerId, namespace: 0, id: 3) messages[replyMessageId] = Message(stableId: 3, stableVersion: 0, id: replyMessageId, globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66000, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_1_Text, attributes: [], media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) diff --git a/submodules/SettingsUI/Sources/Privacy and Security/ForwardPrivacyChatPreviewItem.swift b/submodules/SettingsUI/Sources/Privacy and Security/ForwardPrivacyChatPreviewItem.swift index cb86101b46..bc6b2838c6 100644 --- a/submodules/SettingsUI/Sources/Privacy and Security/ForwardPrivacyChatPreviewItem.swift +++ b/submodules/SettingsUI/Sources/Privacy and Security/ForwardPrivacyChatPreviewItem.swift @@ -145,7 +145,7 @@ class ForwardPrivacyChatPreviewItemNode: ListViewItemNode { var peers = SimpleDictionary() let messages = SimpleDictionary() - peers[peerId] = TelegramUser(id: peerId, accessHash: nil, firstName: item.peerName, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: nil) + peers[peerId] = TelegramUser(id: peerId, accessHash: nil, firstName: item.peerName, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: []) let forwardInfo = MessageForwardInfo(author: item.linkEnabled ? peers[peerId] : nil, source: nil, sourceMessageId: nil, date: 0, authorSignature: item.linkEnabled ? nil : item.peerName, psaType: nil, flags: []) diff --git a/submodules/SettingsUI/Sources/Reactions/ReactionChatPreviewItem.swift b/submodules/SettingsUI/Sources/Reactions/ReactionChatPreviewItem.swift index 5086e1e7e3..eb238e4687 100644 --- a/submodules/SettingsUI/Sources/Reactions/ReactionChatPreviewItem.swift +++ b/submodules/SettingsUI/Sources/Reactions/ReactionChatPreviewItem.swift @@ -274,7 +274,7 @@ class ReactionChatPreviewItemNode: ListViewItemNode { var peers = SimpleDictionary() let messages = SimpleDictionary() - peers[userPeerId] = TelegramUser(id: userPeerId, accessHash: nil, firstName: item.strings.Settings_QuickReactionSetup_DemoMessageAuthor, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: nil) + peers[userPeerId] = TelegramUser(id: userPeerId, accessHash: nil, firstName: item.strings.Settings_QuickReactionSetup_DemoMessageAuthor, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: []) let messageText = item.strings.Settings_QuickReactionSetup_DemoMessageText diff --git a/submodules/SettingsUI/Sources/Text Size/TextSizeSelectionController.swift b/submodules/SettingsUI/Sources/Text Size/TextSizeSelectionController.swift index 0f887b5f7b..b2836c5c3a 100644 --- a/submodules/SettingsUI/Sources/Text Size/TextSizeSelectionController.swift +++ b/submodules/SettingsUI/Sources/Text Size/TextSizeSelectionController.swift @@ -295,14 +295,14 @@ private final class TextSizeSelectionControllerNode: ASDisplayNode, UIScrollView ) } - let selfPeer: EnginePeer = .user(TelegramUser(id: self.context.account.peerId, accessHash: nil, firstName: nil, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: nil)) - let peer1: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(1)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_1_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: nil)) - let peer2: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(2)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_2_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: nil)) - let peer3: EnginePeer = .channel(TelegramChannel(id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(3)), accessHash: nil, title: self.presentationData.strings.Appearance_ThemePreview_ChatList_3_Name, username: nil, photo: [], creationDate: 0, version: 0, participationStatus: .member, info: .group(.init(flags: [])), flags: [], restrictionInfo: nil, adminRights: nil, bannedRights: nil, defaultBannedRights: nil, usernames: nil)) - let peer3Author: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(4)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_3_AuthorName, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: nil)) - let peer4: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(4)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_4_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: nil)) - let peer5: EnginePeer = .channel(TelegramChannel(id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(5)), accessHash: nil, title: self.presentationData.strings.Appearance_ThemePreview_ChatList_5_Name, username: nil, photo: [], creationDate: 0, version: 0, participationStatus: .member, info: .broadcast(.init(flags: [])), flags: [], restrictionInfo: nil, adminRights: nil, bannedRights: nil, defaultBannedRights: nil, usernames: nil)) - let peer6: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.SecretChat, id: PeerId.Id._internalFromInt64Value(5)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_6_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: nil)) + let selfPeer: EnginePeer = .user(TelegramUser(id: self.context.account.peerId, accessHash: nil, firstName: nil, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [])) + let peer1: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(1)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_1_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [])) + let peer2: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(2)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_2_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [])) + let peer3: EnginePeer = .channel(TelegramChannel(id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(3)), accessHash: nil, title: self.presentationData.strings.Appearance_ThemePreview_ChatList_3_Name, username: nil, photo: [], creationDate: 0, version: 0, participationStatus: .member, info: .group(.init(flags: [])), flags: [], restrictionInfo: nil, adminRights: nil, bannedRights: nil, defaultBannedRights: nil, usernames: [])) + let peer3Author: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(4)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_3_AuthorName, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [])) + let peer4: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(4)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_4_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [])) + let peer5: EnginePeer = .channel(TelegramChannel(id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(5)), accessHash: nil, title: self.presentationData.strings.Appearance_ThemePreview_ChatList_5_Name, username: nil, photo: [], creationDate: 0, version: 0, participationStatus: .member, info: .broadcast(.init(flags: [])), flags: [], restrictionInfo: nil, adminRights: nil, bannedRights: nil, defaultBannedRights: nil, usernames: [])) + let peer6: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.SecretChat, id: PeerId.Id._internalFromInt64Value(5)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_6_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [])) let timestamp = self.referenceTimestamp @@ -418,8 +418,8 @@ private final class TextSizeSelectionControllerNode: ASDisplayNode, UIScrollView let otherPeerId = self.context.account.peerId var peers = SimpleDictionary() var messages = SimpleDictionary() - peers[peerId] = TelegramUser(id: peerId, accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_Chat_2_ReplyName, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: nil) - peers[otherPeerId] = TelegramUser(id: otherPeerId, accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_Chat_2_ReplyName, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: nil) + peers[peerId] = TelegramUser(id: peerId, accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_Chat_2_ReplyName, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: []) + peers[otherPeerId] = TelegramUser(id: otherPeerId, accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_Chat_2_ReplyName, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: []) let replyMessageId = MessageId(peerId: peerId, namespace: 0, id: 3) messages[replyMessageId] = Message(stableId: 3, stableVersion: 0, id: replyMessageId, globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66000, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: self.presentationData.strings.Appearance_ThemePreview_Chat_1_Text, attributes: [], media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) diff --git a/submodules/SettingsUI/Sources/Themes/ThemeAccentColorControllerNode.swift b/submodules/SettingsUI/Sources/Themes/ThemeAccentColorControllerNode.swift index a17f3d7931..833a41e9f2 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeAccentColorControllerNode.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeAccentColorControllerNode.swift @@ -915,12 +915,12 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate ) } - let selfPeer: EnginePeer = .user(TelegramUser(id: self.context.account.peerId, accessHash: nil, firstName: nil, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: nil)) - let peer1: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(1)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_1_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: nil)) - let peer2: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(2)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_2_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: nil)) - let peer3: EnginePeer = .channel(TelegramChannel(id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(3)), accessHash: nil, title: self.presentationData.strings.Appearance_ThemePreview_ChatList_3_Name, username: nil, photo: [], creationDate: 0, version: 0, participationStatus: .member, info: .group(.init(flags: [])), flags: [], restrictionInfo: nil, adminRights: nil, bannedRights: nil, defaultBannedRights: nil, usernames: nil)) - let peer3Author: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(4)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_3_AuthorName, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: nil)) - let peer4: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(4)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_4_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: nil)) + let selfPeer: EnginePeer = .user(TelegramUser(id: self.context.account.peerId, accessHash: nil, firstName: nil, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [])) + let peer1: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(1)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_1_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [])) + let peer2: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(2)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_2_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [])) + let peer3: EnginePeer = .channel(TelegramChannel(id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(3)), accessHash: nil, title: self.presentationData.strings.Appearance_ThemePreview_ChatList_3_Name, username: nil, photo: [], creationDate: 0, version: 0, participationStatus: .member, info: .group(.init(flags: [])), flags: [], restrictionInfo: nil, adminRights: nil, bannedRights: nil, defaultBannedRights: nil, usernames: [])) + let peer3Author: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(4)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_3_AuthorName, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [])) + let peer4: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(4)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_4_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [])) let timestamp = self.referenceTimestamp @@ -1008,8 +1008,8 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate let otherPeerId = self.context.account.peerId var peers = SimpleDictionary() var messages = SimpleDictionary() - peers[peerId] = TelegramUser(id: peerId, accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_Chat_2_ReplyName, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: nil) - peers[otherPeerId] = TelegramUser(id: otherPeerId, accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_Chat_2_ReplyName, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: nil) + peers[peerId] = TelegramUser(id: peerId, accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_Chat_2_ReplyName, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: []) + peers[otherPeerId] = TelegramUser(id: otherPeerId, accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_Chat_2_ReplyName, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: []) var sampleMessages: [Message] = [] diff --git a/submodules/SettingsUI/Sources/Themes/ThemePreviewControllerNode.swift b/submodules/SettingsUI/Sources/Themes/ThemePreviewControllerNode.swift index 22bfb2112b..f28f26218a 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemePreviewControllerNode.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemePreviewControllerNode.swift @@ -440,15 +440,15 @@ final class ThemePreviewControllerNode: ASDisplayNode, UIScrollViewDelegate { let chatListPresentationData = ChatListPresentationData(theme: self.previewTheme, fontSize: self.presentationData.listsFontSize, strings: self.presentationData.strings, dateTimeFormat: self.presentationData.dateTimeFormat, nameSortOrder: self.presentationData.nameSortOrder, nameDisplayOrder: self.presentationData.nameDisplayOrder, disableAnimations: true) - let selfPeer: EnginePeer = .user(TelegramUser(id: self.context.account.peerId, accessHash: nil, firstName: nil, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: nil)) - let peer1: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(1)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_1_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: nil)) - let peer2: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(2)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_2_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: nil)) - let peer3: EnginePeer = .channel(TelegramChannel(id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(3)), accessHash: nil, title: self.presentationData.strings.Appearance_ThemePreview_ChatList_3_Name, username: nil, photo: [], creationDate: 0, version: 0, participationStatus: .member, info: .group(.init(flags: [])), flags: [], restrictionInfo: nil, adminRights: nil, bannedRights: nil, defaultBannedRights: nil, usernames: nil)) - let peer3Author: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(4)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_3_AuthorName, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: nil)) - let peer4: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(4)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_4_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: nil)) - let peer5: EnginePeer = .channel(TelegramChannel(id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(5)), accessHash: nil, title: self.presentationData.strings.Appearance_ThemePreview_ChatList_5_Name, username: nil, photo: [], creationDate: 0, version: 0, participationStatus: .member, info: .broadcast(.init(flags: [])), flags: [], restrictionInfo: nil, adminRights: nil, bannedRights: nil, defaultBannedRights: nil, usernames: nil)) - let peer6: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.SecretChat, id: PeerId.Id._internalFromInt64Value(5)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_6_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: nil)) - let peer7: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(6)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_7_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: nil)) + let selfPeer: EnginePeer = .user(TelegramUser(id: self.context.account.peerId, accessHash: nil, firstName: nil, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [])) + let peer1: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(1)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_1_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [])) + let peer2: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(2)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_2_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [])) + let peer3: EnginePeer = .channel(TelegramChannel(id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(3)), accessHash: nil, title: self.presentationData.strings.Appearance_ThemePreview_ChatList_3_Name, username: nil, photo: [], creationDate: 0, version: 0, participationStatus: .member, info: .group(.init(flags: [])), flags: [], restrictionInfo: nil, adminRights: nil, bannedRights: nil, defaultBannedRights: nil, usernames: [])) + let peer3Author: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(4)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_3_AuthorName, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [])) + let peer4: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(4)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_4_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [])) + let peer5: EnginePeer = .channel(TelegramChannel(id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(5)), accessHash: nil, title: self.presentationData.strings.Appearance_ThemePreview_ChatList_5_Name, username: nil, photo: [], creationDate: 0, version: 0, participationStatus: .member, info: .broadcast(.init(flags: [])), flags: [], restrictionInfo: nil, adminRights: nil, bannedRights: nil, defaultBannedRights: nil, usernames: [])) + let peer6: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.SecretChat, id: PeerId.Id._internalFromInt64Value(5)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_6_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [])) + let peer7: EnginePeer = .user(TelegramUser(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(6)), accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_ChatList_7_Name, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [])) let timestamp = self.referenceTimestamp @@ -569,8 +569,8 @@ final class ThemePreviewControllerNode: ASDisplayNode, UIScrollViewDelegate { let otherPeerId = self.context.account.peerId var peers = SimpleDictionary() var messages = SimpleDictionary() - peers[peerId] = TelegramUser(id: peerId, accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_Chat_2_ReplyName, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: nil) - peers[otherPeerId] = TelegramUser(id: otherPeerId, accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_Chat_2_ReplyName, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: nil) + peers[peerId] = TelegramUser(id: peerId, accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_Chat_2_ReplyName, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: []) + peers[otherPeerId] = TelegramUser(id: otherPeerId, accessHash: nil, firstName: self.presentationData.strings.Appearance_ThemePreview_Chat_2_ReplyName, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: []) var sampleMessages: [Message] = [] diff --git a/submodules/SettingsUI/Sources/Themes/ThemeSettingsChatPreviewItem.swift b/submodules/SettingsUI/Sources/Themes/ThemeSettingsChatPreviewItem.swift index a661003a59..92e653ab25 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeSettingsChatPreviewItem.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeSettingsChatPreviewItem.swift @@ -155,11 +155,19 @@ class ThemeSettingsChatPreviewItemNode: ListViewItemNode { let replyMessageId = MessageId(peerId: peerId, namespace: 0, id: 3) if let (author, text) = messageItem.reply { +<<<<<<< HEAD peers[peerId] = TelegramUser(id: peerId, accessHash: nil, firstName: author, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: nil) messages[replyMessageId] = Message(stableId: 3, stableVersion: 0, id: replyMessageId, globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66000, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: text, attributes: [], media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) } let message = Message(stableId: 1, stableVersion: 0, id: MessageId(peerId: messageItem.outgoing ? otherPeerId : peerId, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66000, flags: messageItem.outgoing ? [] : [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: messageItem.outgoing ? TelegramUser(id: otherPeerId, accessHash: nil, firstName: "", lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: nil) : nil, text: messageItem.text, attributes: messageItem.reply != nil ? [ReplyMessageAttribute(messageId: replyMessageId, threadMessageId: nil)] : [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:]) +======= + peers[peerId] = TelegramUser(id: peerId, accessHash: nil, firstName: author, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: []) + messages[replyMessageId] = Message(stableId: 3, stableVersion: 0, id: replyMessageId, globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66000, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[peerId], text: text, attributes: [], media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:]) + } + + let message = Message(stableId: 1, stableVersion: 0, id: MessageId(peerId: messageItem.outgoing ? otherPeerId : peerId, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66000, flags: messageItem.outgoing ? [] : [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: messageItem.outgoing ? TelegramUser(id: otherPeerId, accessHash: nil, firstName: "", lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: []) : nil, text: messageItem.text, attributes: messageItem.reply != nil ? [ReplyMessageAttribute(messageId: replyMessageId, threadMessageId: nil)] : [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:]) +>>>>>>> 295bfcaab3a868c87880c978170ccb6ab87caaf8 items.append(item.context.sharedContext.makeChatMessagePreviewItem(context: item.context, messages: [message], theme: item.componentTheme, strings: item.strings, wallpaper: item.wallpaper, fontSize: item.fontSize, chatBubbleCorners: item.chatBubbleCorners, dateTimeFormat: item.dateTimeFormat, nameOrder: item.nameDisplayOrder, forcedResourceStatus: nil, tapMessage: nil, clickThroughMessage: nil, backgroundNode: currentBackgroundNode, availableReactions: nil, isCentered: false)) } diff --git a/submodules/SettingsUI/Sources/Themes/WallpaperGalleryItem.swift b/submodules/SettingsUI/Sources/Themes/WallpaperGalleryItem.swift index 43d3cf5419..5625a33427 100644 --- a/submodules/SettingsUI/Sources/Themes/WallpaperGalleryItem.swift +++ b/submodules/SettingsUI/Sources/Themes/WallpaperGalleryItem.swift @@ -1033,8 +1033,8 @@ final class WallpaperGalleryItemNode: GalleryItemNode { let otherPeerId = self.context.account.peerId var peers = SimpleDictionary() let messages = SimpleDictionary() - peers[peerId] = TelegramUser(id: peerId, accessHash: nil, firstName: self.presentationData.strings.Appearance_PreviewReplyAuthor, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: nil) - peers[otherPeerId] = TelegramUser(id: otherPeerId, accessHash: nil, firstName: self.presentationData.strings.Appearance_PreviewReplyAuthor, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: nil) + peers[peerId] = TelegramUser(id: peerId, accessHash: nil, firstName: self.presentationData.strings.Appearance_PreviewReplyAuthor, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: []) + peers[otherPeerId] = TelegramUser(id: otherPeerId, accessHash: nil, firstName: self.presentationData.strings.Appearance_PreviewReplyAuthor, lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: []) var topMessageText = "" var bottomMessageText = "" diff --git a/submodules/SettingsUI/Sources/UsernameSetupController.swift b/submodules/SettingsUI/Sources/UsernameSetupController.swift index ab13d69db1..b2d5c3341a 100644 --- a/submodules/SettingsUI/Sources/UsernameSetupController.swift +++ b/submodules/SettingsUI/Sources/UsernameSetupController.swift @@ -268,10 +268,20 @@ private func usernameSetupControllerEntries(presentationData: PresentationData, } var infoText = presentationData.strings.Username_Help - infoText += "\n\n" - let hintText = presentationData.strings.Username_LinkHint(currentAddressName.replacingOccurrences(of: "[", with: "").replacingOccurrences(of: "]", with: "")).string.replacingOccurrences(of: "]", with: "]()") - infoText += hintText + + let otherUsernames = peer.usernames.filter { !$0.flags.contains(.isEditable) } + + if otherUsernames.isEmpty { + infoText += "\n\n" + let hintText = presentationData.strings.Username_LinkHint(currentAddressName.replacingOccurrences(of: "[", with: "").replacingOccurrences(of: "]", with: "")).string.replacingOccurrences(of: "]", with: "]()") + infoText += hintText + } entries.append(.publicLinkInfo(presentationData.theme, infoText)) + + if !otherUsernames.isEmpty { + entries.append(.additionalLinkHeader(presentationData.theme, presentationData.strings.Username_LinksOrder)) + entries.append(.additionalLinkInfo(presentationData.theme, presentationData.strings.Username_LinksOrderInfo)) + } } return entries diff --git a/submodules/TelegramCore/Sources/Account/AccountManager.swift b/submodules/TelegramCore/Sources/Account/AccountManager.swift index af52500d12..a90d00bcfd 100644 --- a/submodules/TelegramCore/Sources/Account/AccountManager.swift +++ b/submodules/TelegramCore/Sources/Account/AccountManager.swift @@ -190,6 +190,7 @@ private var declaredEncodables: Void = { declareEncodable(AudioTranscriptionMessageAttribute.self, f: { AudioTranscriptionMessageAttribute(decoder: $0) }) declareEncodable(NonPremiumMessageAttribute.self, f: { NonPremiumMessageAttribute(decoder: $0) }) declareEncodable(TelegramExtendedMedia.self, f: { TelegramExtendedMedia(decoder: $0) }) + declareEncodable(TelegramPeerUsername.self, f: { TelegramPeerUsername(decoder: $0) }) return }() diff --git a/submodules/TelegramCore/Sources/ApiUtils/ApiGroupOrChannel.swift b/submodules/TelegramCore/Sources/ApiUtils/ApiGroupOrChannel.swift index 2162898dfd..fd6363820e 100644 --- a/submodules/TelegramCore/Sources/ApiUtils/ApiGroupOrChannel.swift +++ b/submodules/TelegramCore/Sources/ApiUtils/ApiGroupOrChannel.swift @@ -143,7 +143,7 @@ func parseTelegramGroupOrChannel(chat: Api.Chat) -> Peer? { } } - return TelegramChannel(id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(id)), accessHash: accessHashValue, title: title, username: username, photo: imageRepresentationsForApiChatPhoto(photo), creationDate: date, version: 0, participationStatus: participationStatus, info: info, flags: channelFlags, restrictionInfo: restrictionInfo, adminRights: adminRights.flatMap(TelegramChatAdminRights.init), bannedRights: bannedRights.flatMap(TelegramChatBannedRights.init), defaultBannedRights: defaultBannedRights.flatMap(TelegramChatBannedRights.init), usernames: usernames?.compactMap(TelegramPeerUsername.init)) + return TelegramChannel(id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(id)), accessHash: accessHashValue, title: title, username: username, photo: imageRepresentationsForApiChatPhoto(photo), creationDate: date, version: 0, participationStatus: participationStatus, info: info, flags: channelFlags, restrictionInfo: restrictionInfo, adminRights: adminRights.flatMap(TelegramChatAdminRights.init), bannedRights: bannedRights.flatMap(TelegramChatBannedRights.init), defaultBannedRights: defaultBannedRights.flatMap(TelegramChatBannedRights.init), usernames: usernames?.map(TelegramPeerUsername.init(apiUsername:)) ?? []) case let .channelForbidden(flags, id, accessHash, title, untilDate): let info: TelegramChannelInfo if (flags & Int32(1 << 8)) != 0 { @@ -152,7 +152,7 @@ func parseTelegramGroupOrChannel(chat: Api.Chat) -> Peer? { info = .broadcast(TelegramChannelBroadcastInfo(flags: [])) } - return TelegramChannel(id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(id)), accessHash: .personal(accessHash), title: title, username: nil, photo: [], creationDate: 0, version: 0, participationStatus: .kicked, info: info, flags: TelegramChannelFlags(), restrictionInfo: nil, adminRights: nil, bannedRights: TelegramChatBannedRights(flags: [.banReadMessages], untilDate: untilDate ?? Int32.max), defaultBannedRights: nil, usernames: nil) + return TelegramChannel(id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(id)), accessHash: .personal(accessHash), title: title, username: nil, photo: [], creationDate: 0, version: 0, participationStatus: .kicked, info: info, flags: TelegramChannelFlags(), restrictionInfo: nil, adminRights: nil, bannedRights: TelegramChatBannedRights(flags: [.banReadMessages], untilDate: untilDate ?? Int32.max), defaultBannedRights: nil, usernames: []) } } @@ -193,8 +193,7 @@ func mergeGroupOrChannel(lhs: Peer?, rhs: Api.Chat) -> Peer? { info = .group(TelegramChannelGroupInfo(flags: infoFlags)) } - - return TelegramChannel(id: lhs.id, accessHash: lhs.accessHash, title: title, username: username, photo: imageRepresentationsForApiChatPhoto(photo), creationDate: lhs.creationDate, version: lhs.version, participationStatus: lhs.participationStatus, info: info, flags: channelFlags, restrictionInfo: lhs.restrictionInfo, adminRights: lhs.adminRights, bannedRights: lhs.bannedRights, defaultBannedRights: defaultBannedRights.flatMap(TelegramChatBannedRights.init), usernames: usernames?.compactMap(TelegramPeerUsername.init)) + return TelegramChannel(id: lhs.id, accessHash: lhs.accessHash, title: title, username: username, photo: imageRepresentationsForApiChatPhoto(photo), creationDate: lhs.creationDate, version: lhs.version, participationStatus: lhs.participationStatus, info: info, flags: channelFlags, restrictionInfo: lhs.restrictionInfo, adminRights: lhs.adminRights, bannedRights: lhs.bannedRights, defaultBannedRights: defaultBannedRights.flatMap(TelegramChatBannedRights.init), usernames: usernames?.map(TelegramPeerUsername.init(apiUsername:)) ?? []) } else { return parseTelegramGroupOrChannel(chat: rhs) } diff --git a/submodules/TelegramCore/Sources/ApiUtils/TelegramUser.swift b/submodules/TelegramCore/Sources/ApiUtils/TelegramUser.swift index 8341fa08f5..156b2c3610 100644 --- a/submodules/TelegramCore/Sources/ApiUtils/TelegramUser.swift +++ b/submodules/TelegramCore/Sources/ApiUtils/TelegramUser.swift @@ -23,6 +23,15 @@ func parsedTelegramProfilePhoto(_ photo: Api.UserProfilePhoto) -> [TelegramMedia return representations } +extension TelegramPeerUsername { + init(apiUsername: Api.Username) { + switch apiUsername { + case let .username(flags, username): + self.init(flags: Flags(rawValue: flags), username: username) + } + } +} + extension TelegramUser { convenience init(user: Api.User) { switch user { @@ -75,9 +84,9 @@ extension TelegramUser { let restrictionInfo: PeerAccessRestrictionInfo? = restrictionReason.flatMap(PeerAccessRestrictionInfo.init(apiReasons:)) - self.init(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(id)), accessHash: accessHashValue, firstName: firstName, lastName: lastName, username: username, phone: phone, photo: representations, botInfo: botInfo, restrictionInfo: restrictionInfo, flags: userFlags, emojiStatus: emojiStatus.flatMap(PeerEmojiStatus.init(apiStatus:)), usernames: usernames?.compactMap(TelegramPeerUsername.init)) + self.init(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(id)), accessHash: accessHashValue, firstName: firstName, lastName: lastName, username: username, phone: phone, photo: representations, botInfo: botInfo, restrictionInfo: restrictionInfo, flags: userFlags, emojiStatus: emojiStatus.flatMap(PeerEmojiStatus.init(apiStatus:)), usernames: usernames?.map(TelegramPeerUsername.init(apiUsername:)) ?? []) case let .userEmpty(id): - self.init(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(id)), accessHash: nil, firstName: nil, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: nil) + self.init(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(id)), accessHash: nil, firstName: nil, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: []) } } @@ -150,7 +159,7 @@ extension TelegramUser { accessHash = lhs.accessHash ?? rhsAccessHashValue } - return TelegramUser(id: lhs.id, accessHash: accessHash, firstName: lhs.firstName, lastName: lhs.lastName, username: username, phone: lhs.phone, photo: telegramPhoto, botInfo: botInfo, restrictionInfo: restrictionInfo, flags: userFlags, emojiStatus: emojiStatus.flatMap(PeerEmojiStatus.init(apiStatus:)), usernames: usernames?.compactMap(TelegramPeerUsername.init)) + return TelegramUser(id: lhs.id, accessHash: accessHash, firstName: lhs.firstName, lastName: lhs.lastName, username: username, phone: lhs.phone, photo: telegramPhoto, botInfo: botInfo, restrictionInfo: restrictionInfo, flags: userFlags, emojiStatus: emojiStatus.flatMap(PeerEmojiStatus.init(apiStatus:)), usernames: usernames?.map(TelegramPeerUsername.init(apiUsername:)) ?? []) } else { return TelegramUser(user: rhs) } diff --git a/submodules/TelegramCore/Sources/State/AccountStateManagementUtils.swift b/submodules/TelegramCore/Sources/State/AccountStateManagementUtils.swift index b8da3557d1..ce5047a018 100644 --- a/submodules/TelegramCore/Sources/State/AccountStateManagementUtils.swift +++ b/submodules/TelegramCore/Sources/State/AccountStateManagementUtils.swift @@ -1020,7 +1020,7 @@ private func finalStateWithUpdatesAndServerTime(postbox: Postbox, network: Netwo if updatedState.peers[peerId] == nil { updatedState.updatePeer(peerId, { peer in if peer == nil { - return TelegramUser(id: peerId, accessHash: nil, firstName: "Telegram Notifications", lastName: nil, username: nil, phone: nil, photo: [], botInfo: BotUserInfo(flags: [], inlinePlaceholder: nil), restrictionInfo: nil, flags: [.isVerified], emojiStatus: nil, usernames: nil) + return TelegramUser(id: peerId, accessHash: nil, firstName: "Telegram Notifications", lastName: nil, username: nil, phone: nil, photo: [], botInfo: BotUserInfo(flags: [], inlinePlaceholder: nil), restrictionInfo: nil, flags: [.isVerified], emojiStatus: nil, usernames: []) } else { return peer } diff --git a/submodules/TelegramCore/Sources/State/UpdatesApiUtils.swift b/submodules/TelegramCore/Sources/State/UpdatesApiUtils.swift index 765c519afa..8217124be9 100644 --- a/submodules/TelegramCore/Sources/State/UpdatesApiUtils.swift +++ b/submodules/TelegramCore/Sources/State/UpdatesApiUtils.swift @@ -157,7 +157,7 @@ extension Api.Chat { extension Api.User { var peerId: PeerId { switch self { - case .user(_, _, let id, _, _, _, _, _, _, _, _, _, _, _, _, _): + case let .user(_, _, id, _, _, _, _, _, _, _, _, _, _, _, _, _): return PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(id)) case let .userEmpty(id): return PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(id)) diff --git a/submodules/TelegramCore/Sources/SyncCore/SyncCore_CachedUserData.swift b/submodules/TelegramCore/Sources/SyncCore/SyncCore_CachedUserData.swift index 74103f9a0e..8e7087c4f8 100644 --- a/submodules/TelegramCore/Sources/SyncCore/SyncCore_CachedUserData.swift +++ b/submodules/TelegramCore/Sources/SyncCore/SyncCore_CachedUserData.swift @@ -109,47 +109,6 @@ extension PeerEmojiStatus { } } - -public struct TelegramPeerUsername : PostboxCoding,Equatable { - public struct Flags: OptionSet { - public var rawValue: Int32 - public init() { - self.rawValue = 0 - } - public init(rawValue: Int32) { - self.rawValue = rawValue - } - public static let isEditable = Flags(rawValue: 1 << 0) - } - - public let flags: Flags - public let value: String - - init(flags: Flags, value: String) { - self.flags = flags - self.value = value - } - - public init(decoder: PostboxDecoder) { - self.flags = Flags(rawValue: decoder.decodeInt32ForKey("fl", orElse: 0)) - self.value = decoder.decodeStringForKey("v", orElse: "") - } - - public func encode(_ encoder: PostboxEncoder) { - encoder.encodeInt32(self.flags.rawValue, forKey: "fl") - encoder.encodeString(self.value, forKey: "v") - } -} - -extension TelegramPeerUsername { - init(api apiValue: Api.Username) { - switch apiValue { - case let .username(flags, username): - self.init(flags: .init(rawValue: flags), value: username) - } - } -} - public final class CachedUserData: CachedPeerData { public let about: String? public let botInfo: BotInfo? diff --git a/submodules/TelegramCore/Sources/SyncCore/SyncCore_TelegramChannel.swift b/submodules/TelegramCore/Sources/SyncCore/SyncCore_TelegramChannel.swift index df2a2f37d3..a6f9a3f9ea 100644 --- a/submodules/TelegramCore/Sources/SyncCore/SyncCore_TelegramChannel.swift +++ b/submodules/TelegramCore/Sources/SyncCore/SyncCore_TelegramChannel.swift @@ -165,8 +165,8 @@ public final class TelegramChannel: Peer, Equatable { public let adminRights: TelegramChatAdminRights? public let bannedRights: TelegramChatBannedRights? public let defaultBannedRights: TelegramChatBannedRights? - public let usernames: [TelegramPeerUsername]? - + public let usernames: [TelegramPeerUsername] + public var indexName: PeerIndexNameRepresentation { return .title(title: self.title, addressName: self.username) } @@ -177,7 +177,8 @@ public final class TelegramChannel: Peer, Equatable { public let notificationSettingsPeerId: PeerId? = nil public var timeoutAttribute: UInt32? { return nil } - public init(id: PeerId, accessHash: TelegramPeerAccessHash?, title: String, username: String?, photo: [TelegramMediaImageRepresentation], creationDate: Int32, version: Int32, participationStatus: TelegramChannelParticipationStatus, info: TelegramChannelInfo, flags: TelegramChannelFlags, restrictionInfo: PeerAccessRestrictionInfo?, adminRights: TelegramChatAdminRights?, bannedRights: TelegramChatBannedRights?, defaultBannedRights: TelegramChatBannedRights?, usernames: [TelegramPeerUsername]?) { + + public init(id: PeerId, accessHash: TelegramPeerAccessHash?, title: String, username: String?, photo: [TelegramMediaImageRepresentation], creationDate: Int32, version: Int32, participationStatus: TelegramChannelParticipationStatus, info: TelegramChannelInfo, flags: TelegramChannelFlags, restrictionInfo: PeerAccessRestrictionInfo?, adminRights: TelegramChatAdminRights?, bannedRights: TelegramChatBannedRights?, defaultBannedRights: TelegramChatBannedRights?, usernames: [TelegramPeerUsername]) { self.id = id self.accessHash = accessHash self.title = title @@ -220,10 +221,7 @@ public final class TelegramChannel: Peer, Equatable { self.adminRights = decoder.decodeObjectForKey("ar", decoder: { TelegramChatAdminRights(decoder: $0) }) as? TelegramChatAdminRights self.bannedRights = decoder.decodeObjectForKey("br", decoder: { TelegramChatBannedRights(decoder: $0) }) as? TelegramChatBannedRights self.defaultBannedRights = decoder.decodeObjectForKey("dbr", decoder: { TelegramChatBannedRights(decoder: $0) }) as? TelegramChatBannedRights - - self.usernames = try? decoder.decodeObjectArrayWithCustomDecoderForKey("un", decoder: { - TelegramPeerUsername(decoder: $0) - }) + self.usernames = decoder.decodeObjectArrayForKey("uns") } public func encode(_ encoder: PostboxEncoder) { @@ -272,12 +270,7 @@ public final class TelegramChannel: Peer, Equatable { } else { encoder.encodeNil(forKey: "dbr") } - - if let usernames = self.usernames { - encoder.encodeObjectArray(usernames, forKey: "un") - } else { - encoder.encodeNil(forKey: "un") - } + encoder.encodeObjectArray(self.usernames, forKey: "uns") } public func isEqual(_ other: Peer) -> Bool { @@ -323,6 +316,10 @@ public final class TelegramChannel: Peer, Equatable { return TelegramChannel(id: self.id, accessHash: self.accessHash, title: self.title, username: addressName, photo: self.photo, creationDate: self.creationDate, version: self.version, participationStatus: self.participationStatus, info: self.info, flags: self.flags, restrictionInfo: self.restrictionInfo, adminRights: self.adminRights, bannedRights: self.bannedRights, defaultBannedRights: self.defaultBannedRights, usernames: self.usernames) } + public func withUpdatedAddressNames(_ addressNames: [TelegramPeerUsername]) -> TelegramChannel { + return TelegramChannel(id: self.id, accessHash: self.accessHash, title: self.title, username: self.username, photo: self.photo, creationDate: self.creationDate, version: self.version, participationStatus: self.participationStatus, info: self.info, flags: self.flags, restrictionInfo: self.restrictionInfo, adminRights: self.adminRights, bannedRights: self.bannedRights, defaultBannedRights: self.defaultBannedRights, usernames: addressNames) + } + public func withUpdatedDefaultBannedRights(_ defaultBannedRights: TelegramChatBannedRights?) -> TelegramChannel { return TelegramChannel(id: self.id, accessHash: self.accessHash, title: self.title, username: self.username, photo: self.photo, creationDate: self.creationDate, version: self.version, participationStatus: self.participationStatus, info: self.info, flags: self.flags, restrictionInfo: self.restrictionInfo, adminRights: self.adminRights, bannedRights: self.bannedRights, defaultBannedRights: defaultBannedRights, usernames: self.usernames) } diff --git a/submodules/TelegramCore/Sources/SyncCore/SyncCore_TelegramUser.swift b/submodules/TelegramCore/Sources/SyncCore/SyncCore_TelegramUser.swift index 67a70220d9..3ec0a6f8d5 100644 --- a/submodules/TelegramCore/Sources/SyncCore/SyncCore_TelegramUser.swift +++ b/submodules/TelegramCore/Sources/SyncCore/SyncCore_TelegramUser.swift @@ -59,6 +59,41 @@ public struct BotUserInfo: PostboxCoding, Equatable { } } +public struct TelegramPeerUsername: PostboxCoding, Equatable { + public struct Flags: OptionSet { + public var rawValue: Int32 + + public init() { + self.rawValue = 0 + } + + public init(rawValue: Int32) { + self.rawValue = rawValue + } + + public static let isEditable = Flags(rawValue: (1 << 0)) + public static let isActive = Flags(rawValue: (1 << 1)) + } + + public let flags: Flags + public let username: String + + public init(flags: Flags, username: String) { + self.flags = flags + self.username = username + } + + public init(decoder: PostboxDecoder) { + self.flags = Flags(rawValue: decoder.decodeInt32ForKey("f", orElse: 0)) + self.username = decoder.decodeStringForKey("un", orElse: "") + } + + public func encode(_ encoder: PostboxEncoder) { + encoder.encodeInt32(self.flags.rawValue, forKey: "f") + encoder.encodeString(self.username, forKey: "un") + } +} + public final class TelegramUser: Peer, Equatable { public let id: PeerId public let accessHash: TelegramPeerAccessHash? @@ -71,7 +106,7 @@ public final class TelegramUser: Peer, Equatable { public let restrictionInfo: PeerAccessRestrictionInfo? public let flags: UserInfoFlags public let emojiStatus: PeerEmojiStatus? - public let usernames: [TelegramPeerUsername]? + public let usernames: [TelegramPeerUsername] public var nameOrPhone: String { if let firstName = self.firstName { @@ -128,7 +163,7 @@ public final class TelegramUser: Peer, Equatable { } } - public init(id: PeerId, accessHash: TelegramPeerAccessHash?, firstName: String?, lastName: String?, username: String?, phone: String?, photo: [TelegramMediaImageRepresentation], botInfo: BotUserInfo?, restrictionInfo: PeerAccessRestrictionInfo?, flags: UserInfoFlags, emojiStatus: PeerEmojiStatus?, usernames: [TelegramPeerUsername]?) { + public init(id: PeerId, accessHash: TelegramPeerAccessHash?, firstName: String?, lastName: String?, username: String?, phone: String?, photo: [TelegramMediaImageRepresentation], botInfo: BotUserInfo?, restrictionInfo: PeerAccessRestrictionInfo?, flags: UserInfoFlags, emojiStatus: PeerEmojiStatus?, usernames: [TelegramPeerUsername]) { self.id = id self.accessHash = accessHash self.firstName = firstName @@ -178,9 +213,7 @@ public final class TelegramUser: Peer, Equatable { self.emojiStatus = decoder.decode(PeerEmojiStatus.self, forKey: "emjs") - self.usernames = try? decoder.decodeObjectArrayWithCustomDecoderForKey("un", decoder: { - TelegramPeerUsername(decoder: $0) - }) + self.usernames = decoder.decodeObjectArrayForKey("uns") } public func encode(_ encoder: PostboxEncoder) { @@ -233,11 +266,7 @@ public final class TelegramUser: Peer, Equatable { encoder.encodeNil(forKey: "emjs") } - if let usernames = self.usernames { - encoder.encodeObjectArray(usernames, forKey: "un") - } else { - encoder.encodeNil(forKey: "un") - } + encoder.encodeObjectArray(self.usernames, forKey: "uns") } public func isEqual(_ other: Peer) -> Bool { @@ -290,14 +319,18 @@ public final class TelegramUser: Peer, Equatable { if lhs.usernames != rhs.usernames { return false } - + return true } - public func withUpdatedUsername(_ username:String?) -> TelegramUser { + public func withUpdatedUsername(_ username: String?) -> TelegramUser { return TelegramUser(id: self.id, accessHash: self.accessHash, firstName: self.firstName, lastName: self.lastName, username: username, phone: self.phone, photo: self.photo, botInfo: self.botInfo, restrictionInfo: self.restrictionInfo, flags: self.flags, emojiStatus: self.emojiStatus, usernames: self.usernames) } + public func withUpdatedUsernames(_ usernames: [TelegramPeerUsername]) -> TelegramUser { + return TelegramUser(id: self.id, accessHash: self.accessHash, firstName: self.firstName, lastName: self.lastName, username: self.username, phone: self.phone, photo: self.photo, botInfo: self.botInfo, restrictionInfo: self.restrictionInfo, flags: self.flags, emojiStatus: self.emojiStatus, usernames: usernames) + } + public func withUpdatedNames(firstName: String?, lastName: String?) -> TelegramUser { return TelegramUser(id: self.id, accessHash: self.accessHash, firstName: firstName, lastName: lastName, username: self.username, phone: self.phone, photo: self.photo, botInfo: self.botInfo, restrictionInfo: self.restrictionInfo, flags: self.flags, emojiStatus: self.emojiStatus, usernames: self.usernames) } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Messages/AdMessages.swift b/submodules/TelegramCore/Sources/TelegramEngine/Messages/AdMessages.swift index 961308a741..363008598d 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Messages/AdMessages.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Messages/AdMessages.swift @@ -222,7 +222,7 @@ private class AdMessagesHistoryContextImpl { adminRights: nil, bannedRights: nil, defaultBannedRights: nil, - usernames: nil + usernames: [] ) } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Peers/AddressNames.swift b/submodules/TelegramCore/Sources/TelegramEngine/Peers/AddressNames.swift index 49bcd36685..5ac2645ec5 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Peers/AddressNames.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Peers/AddressNames.swift @@ -172,6 +172,124 @@ func _internal_updateAddressName(account: Account, domain: AddressNameDomain, na } |> mapError { _ -> UpdateAddressNameError in } |> switchToLatest } +public enum ToggleAddressNameActiveError { + case generic +} + +func _internal_toggleAddressNameActive(account: Account, domain: AddressNameDomain, name: String, active: Bool) -> Signal { + return account.postbox.transaction { transaction -> Signal in + switch domain { + case .account: + return account.network.request(Api.functions.account.toggleUsername(username: name, active: active ? .boolTrue : .boolFalse), automaticFloodWait: false) + |> mapError { _ -> ToggleAddressNameActiveError in + return .generic + } + |> mapToSignal { result -> Signal in + return account.postbox.transaction { transaction -> Void in + if case .boolTrue = result, let peer = transaction.getPeer(account.peerId) as? TelegramUser { + var updatedNames = peer.usernames + if let index = updatedNames.firstIndex(where: { $0.username == name }) { + var updatedFlags = updatedNames[index].flags + if active { + updatedFlags.insert(.isActive) + } else { + updatedFlags.remove(.isActive) + } + let updatedName = TelegramPeerUsername(flags: updatedFlags, username: name) + updatedNames.remove(at: index) + updatedNames.insert(updatedName, at: index) + } + let updatedUser = peer.withUpdatedUsernames(updatedNames) + updatePeers(transaction: transaction, peers: [updatedUser], update: { _, updated in + return updated + }) + } + } |> mapError { _ -> ToggleAddressNameActiveError in } + } + case let .peer(peerId): + if let peer = transaction.getPeer(peerId), let inputChannel = apiInputChannel(peer) { + return account.network.request(Api.functions.channels.toggleUsername(channel: inputChannel, username: name, active: active ? .boolTrue : .boolFalse), automaticFloodWait: false) + |> mapError { _ -> ToggleAddressNameActiveError in + return .generic + } + |> mapToSignal { result -> Signal in + return account.postbox.transaction { transaction -> Void in + if case .boolTrue = result, let peer = transaction.getPeer(peerId) as? TelegramChannel { + var updatedNames = peer.usernames + if let index = updatedNames.firstIndex(where: { $0.username == name }) { + var updatedFlags = updatedNames[index].flags + if active { + updatedFlags.insert(.isActive) + } else { + updatedFlags.remove(.isActive) + } + let updatedName = TelegramPeerUsername(flags: updatedFlags, username: name) + updatedNames.remove(at: index) + updatedNames.insert(updatedName, at: index) + } + let updatedPeer = peer.withUpdatedAddressNames(updatedNames) + updatePeers(transaction: transaction, peers: [updatedPeer], update: { _, updated in + return updated + }) + } + } |> mapError { _ -> ToggleAddressNameActiveError in } + } + } else { + return .fail(.generic) + } + case .theme: + return .complete() + } + } |> mapError { _ -> ToggleAddressNameActiveError in } |> switchToLatest +} + +public enum ReorderAddressNamesError { + case generic +} + +func _internal_reorderAddressNames(account: Account, domain: AddressNameDomain, names: [TelegramPeerUsername]) -> Signal { + return account.postbox.transaction { transaction -> Signal in + switch domain { + case .account: + return account.network.request(Api.functions.account.reorderUsernames(order: names.map { $0.username }), automaticFloodWait: false) + |> mapError { _ -> ReorderAddressNamesError in + return .generic + } + |> mapToSignal { result -> Signal in + return account.postbox.transaction { transaction -> Void in + if case .boolTrue = result, let peer = transaction.getPeer(account.peerId) as? TelegramUser { + let updatedUser = peer.withUpdatedUsernames(names) + updatePeers(transaction: transaction, peers: [updatedUser], update: { _, updated in + return updated + }) + } + } |> mapError { _ -> ReorderAddressNamesError in } + } + 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.map { $0.username }), automaticFloodWait: false) + |> mapError { _ -> ReorderAddressNamesError in + return .generic + } + |> mapToSignal { result -> Signal in + return account.postbox.transaction { transaction -> Void in + if case .boolTrue = result, let peer = transaction.getPeer(peerId) as? TelegramChannel { + let updatedPeer = peer.withUpdatedAddressNames(names) + updatePeers(transaction: transaction, peers: [updatedPeer], update: { _, updated in + return updated + }) + } + } |> mapError { _ -> ReorderAddressNamesError in } + } + } else { + return .fail(.generic) + } + case .theme: + return .complete() + } + } |> mapError { _ -> ReorderAddressNamesError in } |> switchToLatest +} + func _internal_checkPublicChannelCreationAvailability(account: Account, location: Bool = false) -> Signal { var flags: Int32 = (1 << 1) if location { diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Peers/TelegramEnginePeers.swift b/submodules/TelegramCore/Sources/TelegramEngine/Peers/TelegramEnginePeers.swift index d57cb899f7..88a0fac4d2 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Peers/TelegramEnginePeers.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Peers/TelegramEnginePeers.swift @@ -46,7 +46,15 @@ public extension TelegramEngine { public func updateAddressName(domain: AddressNameDomain, name: String?) -> Signal { return _internal_updateAddressName(account: self.account, domain: domain, name: name) } - + + public func toggleAddressNameActive(domain: AddressNameDomain, name: String, active: Bool) -> Signal { + return _internal_toggleAddressNameActive(account: self.account, domain: domain, name: name, active: active) + } + + public func reorderAddressNames(domain: AddressNameDomain, names: [TelegramPeerUsername]) -> Signal { + return _internal_reorderAddressNames(account: self.account, domain: domain, names: names) + } + public func checkPublicChannelCreationAvailability(location: Bool = false) -> Signal { return _internal_checkPublicChannelCreationAvailability(account: self.account, location: location) } diff --git a/submodules/TelegramUI/BUILD b/submodules/TelegramUI/BUILD index fbf8af2f5a..43ac6f9139 100644 --- a/submodules/TelegramUI/BUILD +++ b/submodules/TelegramUI/BUILD @@ -298,6 +298,7 @@ swift_library( "//submodules/Components/PagerComponent:PagerComponent", "//submodules/Components/LottieAnimationComponent:LottieAnimationComponent", "//submodules/TelegramUI/Components/ForumTopicListScreen:ForumTopicListScreen", + "//submodules/TelegramUI/Components/ForumCreateTopicScreen:ForumCreateTopicScreen", ] + select({ "@build_bazel_rules_apple//apple:ios_armv7": [], "@build_bazel_rules_apple//apple:ios_arm64": appcenter_targets, diff --git a/submodules/TelegramUI/Components/EmojiStatusComponent/Sources/EmojiStatusComponent.swift b/submodules/TelegramUI/Components/EmojiStatusComponent/Sources/EmojiStatusComponent.swift index 1716525d34..18b9dbb76f 100644 --- a/submodules/TelegramUI/Components/EmojiStatusComponent/Sources/EmojiStatusComponent.swift +++ b/submodules/TelegramUI/Components/EmojiStatusComponent/Sources/EmojiStatusComponent.swift @@ -48,6 +48,7 @@ public final class EmojiStatusComponent: Component { case verified(fillColor: UIColor, foregroundColor: UIColor, sizeType: SizeType) case text(color: UIColor, string: String) case animation(content: AnimationContent, size: CGSize, placeholderColor: UIColor, themeColor: UIColor?, loopMode: LoopMode) + case topic(title: String) } public let context: AccountContext @@ -222,6 +223,67 @@ public final class EmojiStatusComponent: Component { } else { iconImage = nil } + case let .topic(title): + func generateTopicIcon(backgroundColors: [UIColor], strokeColors: [UIColor]) -> UIImage? { + return generateImage(CGSize(width: 44.0, height: 44.0), rotatedContext: { size, context in + context.clear(CGRect(origin: .zero, size: size)) + + context.saveGState() + + context.translateBy(x: size.width / 2.0, y: size.height / 2.0) + context.scaleBy(x: 1.333, y: 1.333) + context.translateBy(x: -14.0 - UIScreenPixel, y: -14.0 - UIScreenPixel) + + let _ = try? drawSvgPath(context, path: "M24.1835,4.71703 C21.7304,2.42169 18.2984,0.995605 14.5,0.995605 C7.04416,0.995605 1.0,6.49029 1.0,13.2683 C1.0,17.1341 2.80572,20.3028 5.87839,22.5523 C6.27132,22.84 6.63324,24.4385 5.75738,25.7811 C5.39922,26.3301 5.00492,26.7573 4.70138,27.0861 C4.26262,27.5614 4.01347,27.8313 4.33716,27.967 C4.67478,28.1086 6.66968,28.1787 8.10952,27.3712 C9.23649,26.7392 9.91903,26.1087 10.3787,25.6842 C10.7588,25.3331 10.9864,25.1228 11.187,25.1688 C11.9059,25.3337 12.6478,25.4461 13.4075,25.5015 C13.4178,25.5022 13.4282,25.503 13.4386,25.5037 C13.7888,25.5284 14.1428,25.5411 14.5,25.5411 C21.9558,25.5411 28.0,20.0464 28.0,13.2683 C28.0,9.94336 26.5455,6.92722 24.1835,4.71703 ") + context.closePath() + context.clip() + + let colorsArray = backgroundColors.map { $0.cgColor } as NSArray + var locations: [CGFloat] = [0.0, 1.0] + let gradient = CGGradient(colorsSpace: deviceColorSpace, colors: colorsArray, locations: &locations)! + context.drawLinearGradient(gradient, start: CGPoint(), end: CGPoint(x: 0.0, y: size.height), options: CGGradientDrawingOptions()) + + context.resetClip() + + let _ = try? drawSvgPath(context, path: "M24.1835,4.71703 C21.7304,2.42169 18.2984,0.995605 14.5,0.995605 C7.04416,0.995605 1.0,6.49029 1.0,13.2683 C1.0,17.1341 2.80572,20.3028 5.87839,22.5523 C6.27132,22.84 6.63324,24.4385 5.75738,25.7811 C5.39922,26.3301 5.00492,26.7573 4.70138,27.0861 C4.26262,27.5614 4.01347,27.8313 4.33716,27.967 C4.67478,28.1086 6.66968,28.1787 8.10952,27.3712 C9.23649,26.7392 9.91903,26.1087 10.3787,25.6842 C10.7588,25.3331 10.9864,25.1228 11.187,25.1688 C11.9059,25.3337 12.6478,25.4461 13.4075,25.5015 C13.4178,25.5022 13.4282,25.503 13.4386,25.5037 C13.7888,25.5284 14.1428,25.5411 14.5,25.5411 C21.9558,25.5411 28.0,20.0464 28.0,13.2683 C28.0,9.94336 26.5455,6.92722 24.1835,4.71703 ") + context.closePath() + if let path = context.path { + let strokePath = path.copy(strokingWithWidth: 1.0, lineCap: .round, lineJoin: .round, miterLimit: 0.0) + context.beginPath() + context.addPath(strokePath) + context.clip() + + let colorsArray = strokeColors.map { $0.cgColor } as NSArray + var locations: [CGFloat] = [0.0, 1.0] + let gradient = CGGradient(colorsSpace: deviceColorSpace, colors: colorsArray, locations: &locations)! + context.drawLinearGradient(gradient, start: CGPoint(), end: CGPoint(x: 0.0, y: size.height), options: CGGradientDrawingOptions()) + } + + context.restoreGState() + + let attributedString = NSAttributedString(string: title, attributes: [NSAttributedString.Key.font: Font.with(size: 19.0, design: .round, weight: .bold), NSAttributedString.Key.foregroundColor: UIColor.white]) + + let line = CTLineCreateWithAttributedString(attributedString) + let lineBounds = CTLineGetBoundsWithOptions(line, .useGlyphPathBounds) + + let lineOffset = CGPoint(x: title == "B" ? 1.0 : 0.0, y: 0.0) + let lineOrigin = CGPoint(x: floorToScreenPixels(-lineBounds.origin.x + (size.width - lineBounds.size.width) / 2.0) + lineOffset.x, y: floorToScreenPixels(-lineBounds.origin.y + (size.height - lineBounds.size.height) / 2.0) + 2.0) + + context.translateBy(x: size.width / 2.0, y: size.height / 2.0) + context.scaleBy(x: 1.0, y: -1.0) + context.translateBy(x: -size.width / 2.0, y: -size.height / 2.0) + + context.translateBy(x: lineOrigin.x, y: lineOrigin.y) + CTLineDraw(line, context) + context.translateBy(x: -lineOrigin.x, y: -lineOrigin.y) + }) + } + + if let image = generateTopicIcon(backgroundColors: [UIColor(rgb: 0x6FB9F0), UIColor(rgb: 0x0261E4)], strokeColors: [UIColor(rgb: 0x026CB5), UIColor(rgb: 0x064BB7)]) { + iconImage = image + } else { + iconImage = nil + } case let .verified(fillColor, foregroundColor, sizeType): let imageNamePrefix: String switch sizeType { diff --git a/submodules/TelegramUI/Components/EntityKeyboard/Sources/EmojiPagerContentComponent.swift b/submodules/TelegramUI/Components/EntityKeyboard/Sources/EmojiPagerContentComponent.swift index f547374e75..13253c81d5 100644 --- a/submodules/TelegramUI/Components/EntityKeyboard/Sources/EmojiPagerContentComponent.swift +++ b/submodules/TelegramUI/Components/EntityKeyboard/Sources/EmojiPagerContentComponent.swift @@ -2143,8 +2143,9 @@ public final class EmojiPagerContentComponent: Component { case icon(Icon) } - public enum Icon: Equatable { + public enum Icon: Equatable, Hashable { case premiumStar + case topic(String) } case animation(EntityKeyboardAnimationData) @@ -2942,6 +2943,11 @@ public final class EmojiPagerContentComponent: Component { let imageSize = image.size.aspectFitted(CGSize(width: size.width - 6.0, height: size.height - 6.0)) image.draw(in: CGRect(origin: CGPoint(x: floor((size.width - imageSize.width) / 2.0), y: floor((size.height - imageSize.height) / 2.0)), size: imageSize)) } + case let .topic(title): + if let image = generateTopicIcon(backgroundColors: [UIColor(rgb: 0x6FB9F0), UIColor(rgb: 0x0261E4)], strokeColors: [UIColor(rgb: 0x026CB5), UIColor(rgb: 0x064BB7)], title: title) { + let imageSize = image.size//.aspectFitted(CGSize(width: size.width - 6.0, height: size.height - 6.0)) + image.draw(in: CGRect(origin: CGPoint(x: floor((size.width - imageSize.width) / 2.0), y: floor((size.height - imageSize.height) / 2.0)), size: imageSize)) + } } UIGraphicsPopContext() @@ -2986,6 +2992,26 @@ public final class EmojiPagerContentComponent: Component { return nullAction } + func update(content: ItemContent) { + if self.content != content { + if case let .icon(icon) = content, case let .topic(title) = icon { + let image = generateImage(self.size, opaque: false, scale: min(UIScreenScale, 3.0), rotatedContext: { size, context in + context.clear(CGRect(origin: CGPoint(), size: size)) + + UIGraphicsPushContext(context) + + if let image = generateTopicIcon(backgroundColors: [UIColor(rgb: 0x6FB9F0), UIColor(rgb: 0x0261E4)], strokeColors: [UIColor(rgb: 0x026CB5), UIColor(rgb: 0x064BB7)], title: title) { + let imageSize = image.size//.aspectFitted(CGSize(width: size.width - 6.0, height: size.height - 6.0)) + image.draw(in: CGRect(origin: CGPoint(x: floor((size.width - imageSize.width) / 2.0), y: floor((size.height - imageSize.height) / 2.0)), size: imageSize)) + } + + UIGraphicsPopContext() + }) + self.contents = image?.cgImage + } + } + } + func update(transition: Transition, size: CGSize, badge: Badge?, blurredBadgeColor: UIColor, blurredBadgeBackgroundColor: UIColor) { if self.badge != badge || self.validSize != size { self.badge = badge @@ -5244,6 +5270,11 @@ public final class EmojiPagerContentComponent: Component { badge = .premium } } + + if case .icon = item.content { + itemLayer.update(content: item.content) + } + itemLayer.update(transition: transition, size: itemFrame.size, badge: badge, blurredBadgeColor: UIColor(white: 0.0, alpha: 0.1), blurredBadgeBackgroundColor: keyboardChildEnvironment.theme.list.plainBackgroundColor) if item.accentTint { @@ -5263,7 +5294,13 @@ public final class EmojiPagerContentComponent: Component { } } + var isSelected = false if let itemFile = item.itemFile, component.selectedItems.contains(itemFile.fileId) { + isSelected = true + } else if case let .icon(icon) = item.content.id, case .topic = icon, component.selectedItems.isEmpty { + } + + if isSelected { let itemSelectionLayer: ItemSelectionLayer if let current = self.visibleItemSelectionLayers[itemId] { itemSelectionLayer = current @@ -5406,7 +5443,8 @@ public final class EmojiPagerContentComponent: Component { default: break } - if let fileId = fileId, component.selectedItems.contains(fileId) { + if case let .icon(icon) = id.itemId, case .topic = icon, component.selectedItems.isEmpty { + } else if let fileId = fileId, component.selectedItems.contains(fileId) { } else { itemSelectionLayer.removeFromSuperlayer() removedItemSelectionLayerIds.append(id) @@ -6149,13 +6187,15 @@ public final class EmojiPagerContentComponent: Component { isStandalone: Bool, isStatusSelection: Bool, isReactionSelection: Bool, + isTopicIconSelection: Bool = false, isQuickReactionSelection: Bool = false, topReactionItems: [EmojiComponentReactionItem], areUnicodeEmojiEnabled: Bool, areCustomEmojiEnabled: Bool, chatPeerId: EnginePeer.Id?, selectedItems: Set = Set(), - topStatusTitle: String? = nil + topStatusTitle: String? = nil, + topicTitle: String? = nil ) -> Signal { let premiumConfiguration = PremiumConfiguration.with(appConfiguration: context.currentAppConfiguration.with { $0 }) let isPremiumDisabled = premiumConfiguration.isPremiumDisabled @@ -6236,7 +6276,24 @@ public final class EmojiPagerContentComponent: Component { } } - if isStatusSelection { + if isTopicIconSelection { + let resultItem = EmojiPagerContentComponent.Item( + animationData: nil, + content: .icon(.topic(String((topicTitle ?? "").prefix(1)))), + itemFile: nil, + subgroupId: nil, + icon: .none, + accentTint: false + ) + + let groupId = "recent" + if let groupIndex = itemGroupIndexById[groupId] { + itemGroups[groupIndex].items.append(resultItem) + } else { + itemGroupIndexById[groupId] = itemGroups.count + itemGroups.append(ItemGroup(supergroupId: groupId, id: groupId, title: nil, subtitle: nil, isPremiumLocked: false, isFeatured: false, collapsedLineCount: 5, isClearable: false, headerItem: nil, items: [resultItem])) + } + } else if isStatusSelection { let resultItem = EmojiPagerContentComponent.Item( animationData: nil, content: .icon(.premiumStar), @@ -6848,3 +6905,58 @@ public final class EmojiPagerContentComponent: Component { return emojiItems } } + +func generateTopicIcon(backgroundColors: [UIColor], strokeColors: [UIColor], title: String) -> UIImage? { + return generateImage(CGSize(width: 44.0, height: 44.0), rotatedContext: { size, context in + context.clear(CGRect(origin: .zero, size: size)) + + context.saveGState() + + context.translateBy(x: size.width / 2.0, y: size.height / 2.0) + context.scaleBy(x: 1.2, y: 1.2) + context.translateBy(x: -14.0 - UIScreenPixel, y: -14.0 - UIScreenPixel) + + let _ = try? drawSvgPath(context, path: "M24.1835,4.71703 C21.7304,2.42169 18.2984,0.995605 14.5,0.995605 C7.04416,0.995605 1.0,6.49029 1.0,13.2683 C1.0,17.1341 2.80572,20.3028 5.87839,22.5523 C6.27132,22.84 6.63324,24.4385 5.75738,25.7811 C5.39922,26.3301 5.00492,26.7573 4.70138,27.0861 C4.26262,27.5614 4.01347,27.8313 4.33716,27.967 C4.67478,28.1086 6.66968,28.1787 8.10952,27.3712 C9.23649,26.7392 9.91903,26.1087 10.3787,25.6842 C10.7588,25.3331 10.9864,25.1228 11.187,25.1688 C11.9059,25.3337 12.6478,25.4461 13.4075,25.5015 C13.4178,25.5022 13.4282,25.503 13.4386,25.5037 C13.7888,25.5284 14.1428,25.5411 14.5,25.5411 C21.9558,25.5411 28.0,20.0464 28.0,13.2683 C28.0,9.94336 26.5455,6.92722 24.1835,4.71703 ") + context.closePath() + context.clip() + + let colorsArray = backgroundColors.map { $0.cgColor } as NSArray + var locations: [CGFloat] = [0.0, 1.0] + let gradient = CGGradient(colorsSpace: deviceColorSpace, colors: colorsArray, locations: &locations)! + context.drawLinearGradient(gradient, start: CGPoint(), end: CGPoint(x: 0.0, y: size.height), options: CGGradientDrawingOptions()) + + context.resetClip() + + let _ = try? drawSvgPath(context, path: "M24.1835,4.71703 C21.7304,2.42169 18.2984,0.995605 14.5,0.995605 C7.04416,0.995605 1.0,6.49029 1.0,13.2683 C1.0,17.1341 2.80572,20.3028 5.87839,22.5523 C6.27132,22.84 6.63324,24.4385 5.75738,25.7811 C5.39922,26.3301 5.00492,26.7573 4.70138,27.0861 C4.26262,27.5614 4.01347,27.8313 4.33716,27.967 C4.67478,28.1086 6.66968,28.1787 8.10952,27.3712 C9.23649,26.7392 9.91903,26.1087 10.3787,25.6842 C10.7588,25.3331 10.9864,25.1228 11.187,25.1688 C11.9059,25.3337 12.6478,25.4461 13.4075,25.5015 C13.4178,25.5022 13.4282,25.503 13.4386,25.5037 C13.7888,25.5284 14.1428,25.5411 14.5,25.5411 C21.9558,25.5411 28.0,20.0464 28.0,13.2683 C28.0,9.94336 26.5455,6.92722 24.1835,4.71703 ") + context.closePath() + if let path = context.path { + let strokePath = path.copy(strokingWithWidth: 1.0, lineCap: .round, lineJoin: .round, miterLimit: 0.0) + context.beginPath() + context.addPath(strokePath) + context.clip() + + let colorsArray = strokeColors.map { $0.cgColor } as NSArray + var locations: [CGFloat] = [0.0, 1.0] + let gradient = CGGradient(colorsSpace: deviceColorSpace, colors: colorsArray, locations: &locations)! + context.drawLinearGradient(gradient, start: CGPoint(), end: CGPoint(x: 0.0, y: size.height), options: CGGradientDrawingOptions()) + } + + context.restoreGState() + + let attributedString = NSAttributedString(string: title, attributes: [NSAttributedString.Key.font: Font.with(size: 19.0, design: .round, weight: .bold), NSAttributedString.Key.foregroundColor: UIColor.white]) + + let line = CTLineCreateWithAttributedString(attributedString) + let lineBounds = CTLineGetBoundsWithOptions(line, .useGlyphPathBounds) + + let lineOffset = CGPoint(x: title == "B" ? 1.0 : 0.0, y: 0.0) + let lineOrigin = CGPoint(x: floorToScreenPixels(-lineBounds.origin.x + (size.width - lineBounds.size.width) / 2.0) + lineOffset.x, y: floorToScreenPixels(-lineBounds.origin.y + (size.height - lineBounds.size.height) / 2.0) + 1.0) + + context.translateBy(x: size.width / 2.0, y: size.height / 2.0) + context.scaleBy(x: 1.0, y: -1.0) + context.translateBy(x: -size.width / 2.0, y: -size.height / 2.0) + + context.translateBy(x: lineOrigin.x, y: lineOrigin.y) + CTLineDraw(line, context) + context.translateBy(x: -lineOrigin.x, y: -lineOrigin.y) + }) +} diff --git a/submodules/TelegramUI/Components/ForumCreateTopicScreen/BUILD b/submodules/TelegramUI/Components/ForumCreateTopicScreen/BUILD new file mode 100644 index 0000000000..ae06114d1b --- /dev/null +++ b/submodules/TelegramUI/Components/ForumCreateTopicScreen/BUILD @@ -0,0 +1,37 @@ +load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library") + +swift_library( + name = "ForumCreateTopicScreen", + module_name = "ForumCreateTopicScreen", + srcs = glob([ + "Sources/**/*.swift", + ]), + copts = [ + "-warnings-as-errors", + ], + deps = [ + "//submodules/AsyncDisplayKit:AsyncDisplayKit", + "//submodules/Display:Display", + "//submodules/Postbox:Postbox", + "//submodules/TelegramCore:TelegramCore", + "//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit", + "//submodules/ComponentFlow:ComponentFlow", + "//submodules/Components/ViewControllerComponent:ViewControllerComponent", + "//submodules/TelegramUI/Components/AnimationCache:AnimationCache", + "//submodules/TelegramUI/Components/MultiAnimationRenderer:MultiAnimationRenderer", + "//submodules/Components/ComponentDisplayAdapters:ComponentDisplayAdapters", + "//submodules/Components/MultilineTextComponent:MultilineTextComponent", + "//submodules/TelegramPresentationData:TelegramPresentationData", + "//submodules/AccountContext:AccountContext", + "//submodules/AppBundle:AppBundle", + "//submodules/TelegramStringFormatting:TelegramStringFormatting", + "//submodules/PresentationDataUtils:PresentationDataUtils", + "//submodules/TelegramUI/Components/EmojiStatusComponent", + "//submodules/TelegramUI/Components/EntityKeyboard:EntityKeyboard", + "//submodules/TelegramUI/Components/EmojiTextAttachmentView:EmojiTextAttachmentView", + "//submodules/Components/PagerComponent:PagerComponent", + ], + visibility = [ + "//visibility:public", + ], +) diff --git a/submodules/TelegramUI/Components/ForumCreateTopicScreen/Sources/ForumCreateTopicScreen.swift b/submodules/TelegramUI/Components/ForumCreateTopicScreen/Sources/ForumCreateTopicScreen.swift new file mode 100644 index 0000000000..123fd603b8 --- /dev/null +++ b/submodules/TelegramUI/Components/ForumCreateTopicScreen/Sources/ForumCreateTopicScreen.swift @@ -0,0 +1,710 @@ +import Foundation +import UIKit +import Display +import AsyncDisplayKit +import ComponentFlow +import SwiftSignalKit +import ViewControllerComponent +import ComponentDisplayAdapters +import TelegramPresentationData +import AccountContext +import TelegramCore +import EntityKeyboard +import PagerComponent +import MultilineTextComponent +import EmojiStatusComponent +import Postbox + +private final class TitleFieldComponent: Component { + typealias EnvironmentType = Empty + + let context: AccountContext + let textColor: UIColor + let accentColor: UIColor + let placeholderColor: UIColor + let fileId: Int64 + let text: String + let textUpdated: (String) -> Void + + init( + context: AccountContext, + textColor: UIColor, + accentColor: UIColor, + placeholderColor: UIColor, + fileId: Int64, + text: String, + textUpdated: @escaping (String) -> Void + ) { + self.context = context + self.textColor = textColor + self.accentColor = accentColor + self.placeholderColor = placeholderColor + self.fileId = fileId + self.text = text + self.textUpdated = textUpdated + } + + static func ==(lhs: TitleFieldComponent, rhs: TitleFieldComponent) -> Bool { + if lhs.context !== rhs.context { + return false + } + if lhs.textColor != rhs.textColor { + return false + } + if lhs.accentColor != rhs.accentColor { + return false + } + if lhs.placeholderColor != rhs.placeholderColor { + return false + } + if lhs.fileId != rhs.fileId { + return false + } + if lhs.text != rhs.text { + return false + } + return true + } + + final class View: UIView { + private let iconView: ComponentView + private let textField: TextFieldNodeView + + private var component: TitleFieldComponent? + private weak var state: EmptyComponentState? + + override init(frame: CGRect) { + self.iconView = ComponentView() + self.textField = TextFieldNodeView(frame: .zero) + + super.init(frame: frame) + + self.textField.placeholder = "What do you want to discuss?" + self.textField.addTarget(self, action: #selector(self.textChanged(_:)), for: .editingChanged) + + self.addSubview(self.textField) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + deinit { + } + + @objc func textChanged(_ sender: Any) { + self.component?.textUpdated(self.textField.text ?? "") + } + + func update(component: TitleFieldComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment, transition: Transition) -> CGSize { + self.textField.textColor = component.textColor + self.textField.text = component.text + self.textField.font = Font.regular(17.0) + + self.component = component + self.state = state + + let titleCredibilityContent: EmojiStatusComponent.Content + if component.fileId == 0 { + titleCredibilityContent = .topic(title: String(component.text.prefix(1))) + } else { + titleCredibilityContent = .animation(content: .customEmoji(fileId: component.fileId), size: CGSize(width: 32.0, height: 32.0), placeholderColor: component.placeholderColor, themeColor: component.accentColor, loopMode: .count(2)) + } + + let iconSize = self.iconView.update( + transition: .easeInOut(duration: 0.2), + component: AnyComponent(EmojiStatusComponent( + context: component.context, + animationCache: component.context.animationCache, + animationRenderer: component.context.animationRenderer, + content: titleCredibilityContent, + isVisibleForAnimations: true, + action: nil + )), + environment: {}, + containerSize: CGSize(width: 32.0, height: 32.0) + ) + + if let iconComponentView = self.iconView.view { + if iconComponentView.superview == nil { + self.addSubview(iconComponentView) + } + + iconComponentView.frame = CGRect(origin: CGPoint(x: 15.0, y: floorToScreenPixels((availableSize.height - iconSize.height) / 2.0)), size: iconSize) + + self.textField.becomeFirstResponder() + } + + self.textField.frame = CGRect(x: 15.0 + iconSize.width + 15.0, y: 0.0, width: availableSize.width - 46.0 - iconSize.width, height: 44.0) + + return availableSize + } + } + + public func makeView() -> View { + return View(frame: CGRect()) + } + + public func update(view: View, availableSize: CGSize, state: EmptyComponentState, environment: Environment, transition: Transition) -> CGSize { + return view.update(component: self, availableSize: availableSize, state: state, environment: environment, transition: transition) + } +} + +private final class TopicIconSelectionComponent: Component { + public typealias EnvironmentType = Empty + + public let theme: PresentationTheme + public let strings: PresentationStrings + public let deviceMetrics: DeviceMetrics + public let emojiContent: EmojiPagerContentComponent + public let backgroundColor: UIColor + public let separatorColor: UIColor + + public init( + theme: PresentationTheme, + strings: PresentationStrings, + deviceMetrics: DeviceMetrics, + emojiContent: EmojiPagerContentComponent, + backgroundColor: UIColor, + separatorColor: UIColor + ) { + self.theme = theme + self.strings = strings + self.deviceMetrics = deviceMetrics + self.emojiContent = emojiContent + self.backgroundColor = backgroundColor + self.separatorColor = separatorColor + } + + public static func ==(lhs: TopicIconSelectionComponent, rhs: TopicIconSelectionComponent) -> Bool { + if lhs.theme !== rhs.theme { + return false + } + if lhs.strings != rhs.strings { + return false + } + if lhs.deviceMetrics != rhs.deviceMetrics { + return false + } + if lhs.emojiContent != rhs.emojiContent { + return false + } + if lhs.backgroundColor != rhs.backgroundColor { + return false + } + if lhs.separatorColor != rhs.separatorColor { + return false + } + return true + } + + public final class View: UIView { + private let keyboardView: ComponentView + private let keyboardClippingView: UIView + private let panelHostView: PagerExternalTopPanelContainer + private let panelBackgroundView: BlurredBackgroundView + private let panelSeparatorView: UIView + + private var component: TopicIconSelectionComponent? + private weak var state: EmptyComponentState? + + override init(frame: CGRect) { + self.keyboardView = ComponentView() + self.keyboardClippingView = UIView() + self.panelHostView = PagerExternalTopPanelContainer() + self.panelBackgroundView = BlurredBackgroundView(color: .clear, enableBlur: true) + self.panelSeparatorView = UIView() + + super.init(frame: frame) + + self.addSubview(self.keyboardClippingView) + self.addSubview(self.panelBackgroundView) + self.addSubview(self.panelSeparatorView) + self.addSubview(self.panelHostView) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + deinit { + } + + func update(component: TopicIconSelectionComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment, transition: Transition) -> CGSize { + self.backgroundColor = component.backgroundColor + let panelBackgroundColor = component.backgroundColor.withMultipliedAlpha(0.85) + self.panelBackgroundView.updateColor(color: panelBackgroundColor, transition: .immediate) + self.panelSeparatorView.backgroundColor = component.separatorColor + + self.component = component + self.state = state + + let topPanelHeight: CGFloat = 42.0 + + let keyboardSize = self.keyboardView.update( + transition: transition.withUserData(EmojiPagerContentComponent.SynchronousLoadBehavior(isDisabled: true)), + component: AnyComponent(EntityKeyboardComponent( + theme: component.theme, + strings: component.strings, + isContentInFocus: true, + containerInsets: UIEdgeInsets(top: topPanelHeight - 34.0, left: 0.0, bottom: 0.0, right: 0.0), + topPanelInsets: UIEdgeInsets(top: 0.0, left: 4.0, bottom: 0.0, right: 4.0), + emojiContent: component.emojiContent, + stickerContent: nil, + gifContent: nil, + hasRecentGifs: false, + availableGifSearchEmojies: [], + defaultToEmojiTab: true, + externalTopPanelContainer: self.panelHostView, + topPanelExtensionUpdated: { _, _ in }, + hideInputUpdated: { _, _, _ in }, + hideTopPanelUpdated: { _, _ in }, + switchToTextInput: {}, + switchToGifSubject: { _ in }, + reorderItems: { _, _ in }, + makeSearchContainerNode: { _ in return nil }, + deviceMetrics: component.deviceMetrics, + hiddenInputHeight: 0.0, + displayBottomPanel: false, + isExpanded: false + )), + environment: {}, + containerSize: availableSize + ) + if let keyboardComponentView = self.keyboardView.view { + if keyboardComponentView.superview == nil { + self.keyboardClippingView.addSubview(keyboardComponentView) + } + + if panelBackgroundColor.alpha < 0.01 { + self.keyboardClippingView.clipsToBounds = true + } else { + self.keyboardClippingView.clipsToBounds = false + } + + transition.setFrame(view: self.keyboardClippingView, frame: CGRect(origin: CGPoint(x: 0.0, y: topPanelHeight), size: CGSize(width: availableSize.width, height: availableSize.height - topPanelHeight))) + + transition.setFrame(view: keyboardComponentView, frame: CGRect(origin: CGPoint(x: 0.0, y: -topPanelHeight), size: keyboardSize)) + transition.setFrame(view: self.panelHostView, frame: CGRect(origin: CGPoint(x: 0.0, y: topPanelHeight - 34.0), size: CGSize(width: keyboardSize.width, height: 0.0))) + + transition.setFrame(view: self.panelBackgroundView, frame: CGRect(origin: CGPoint(), size: CGSize(width: keyboardSize.width, height: topPanelHeight))) + self.panelBackgroundView.update(size: self.panelBackgroundView.bounds.size, transition: transition.containedViewLayoutTransition) + + transition.setFrame(view: self.panelSeparatorView, frame: CGRect(origin: CGPoint(x: 0.0, y: topPanelHeight), size: CGSize(width: keyboardSize.width, height: UIScreenPixel))) + transition.setAlpha(view: self.panelSeparatorView, alpha: 1.0) + } + + return availableSize + } + } + + public func makeView() -> View { + return View(frame: CGRect()) + } + + public func update(view: View, availableSize: CGSize, state: EmptyComponentState, environment: Environment, transition: Transition) -> CGSize { + return view.update(component: self, availableSize: availableSize, state: state, environment: environment, transition: transition) + } +} + +private final class ForumCreateTopicScreenComponent: CombinedComponent { + typealias EnvironmentType = ViewControllerComponentContainer.Environment + + let context: AccountContext + let peerId: EnginePeer.Id + let mode: ForumCreateTopicScreen.Mode + let titleUpdated: (String) -> Void + + init(context: AccountContext, peerId: EnginePeer.Id, mode: ForumCreateTopicScreen.Mode, titleUpdated: @escaping (String) -> Void) { + self.context = context + self.peerId = peerId + self.mode = mode + self.titleUpdated = titleUpdated + } + + static func ==(lhs: ForumCreateTopicScreenComponent, rhs: ForumCreateTopicScreenComponent) -> Bool { + if lhs.context !== rhs.context { + return false + } + if lhs.peerId != rhs.peerId { + return false + } + if lhs.mode != rhs.mode { + return false + } + return true + } + + final class State: ComponentState { + private let context: AccountContext + private let titleUpdated: (String) -> Void + + var emojiContent: EmojiPagerContentComponent? + private let emojiContentDisposable = MetaDisposable() + + var title: String + var fileId: Int64 + + init(context: AccountContext, mode: ForumCreateTopicScreen.Mode, titleUpdated: @escaping (String) -> Void) { + self.context = context + self.titleUpdated = titleUpdated + + switch mode { + case .create: + self.title = "" + self.fileId = 0 + case let .edit(topic): + self.title = topic.info.title + self.fileId = topic.info.icon ?? 0 + } + + super.init() + + self.emojiContentDisposable.set(( + EmojiPagerContentComponent.emojiInputData( + context: self.context, + animationCache: self.context.animationCache, + animationRenderer: self.context.animationRenderer, + isStandalone: false, + isStatusSelection: false, + isReactionSelection: false, + isTopicIconSelection: true, + topReactionItems: [], + areUnicodeEmojiEnabled: false, + areCustomEmojiEnabled: true, + chatPeerId: self.context.account.peerId, + selectedItems: Set(), + topicTitle: self.title + ) + |> deliverOnMainQueue).start(next: { [weak self] content in + self?.emojiContent = content + self?.updated(transition: .immediate) + })) + } + + deinit { + self.emojiContentDisposable.dispose() + } + + func updateTitle(_ text: String) { + self.title = text + self.updated(transition: .immediate) + + self.titleUpdated(text) + + self.emojiContentDisposable.set(( + EmojiPagerContentComponent.emojiInputData( + context: self.context, + animationCache: self.context.animationCache, + animationRenderer: self.context.animationRenderer, + isStandalone: false, + isStatusSelection: false, + isReactionSelection: false, + isTopicIconSelection: true, + topReactionItems: [], + areUnicodeEmojiEnabled: false, + areCustomEmojiEnabled: true, + chatPeerId: self.context.account.peerId, + selectedItems: Set([MediaId(namespace: Namespaces.Media.CloudFile, id: self.fileId)]), + topicTitle: self.title + ) + |> deliverOnMainQueue).start(next: { [weak self] content in + self?.emojiContent = content + self?.updated(transition: .immediate) + })) + } + + func applyItem(groupId: AnyHashable, item: EmojiPagerContentComponent.Item?) { + guard let item = item else { + return + } + + self.fileId = item.itemFile?.fileId.id ?? 0 + self.updated(transition: .immediate) + + self.emojiContentDisposable.set(( + EmojiPagerContentComponent.emojiInputData( + context: self.context, + animationCache: self.context.animationCache, + animationRenderer: self.context.animationRenderer, + isStandalone: false, + isStatusSelection: false, + isReactionSelection: false, + isTopicIconSelection: true, + topReactionItems: [], + areUnicodeEmojiEnabled: false, + areCustomEmojiEnabled: true, + chatPeerId: self.context.account.peerId, + selectedItems: Set([MediaId(namespace: Namespaces.Media.CloudFile, id: self.fileId)]), + topicTitle: self.title + ) + |> deliverOnMainQueue).start(next: { [weak self] content in + self?.emojiContent = content + self?.updated(transition: .immediate) + })) + } + } + + func makeState() -> State { + return State( + context: self.context, + mode: self.mode, + titleUpdated: self.titleUpdated + ) + } + + static var body: Body { + let background = Child(Rectangle.self) + let titleHeader = Child(MultilineTextComponent.self) + let titleBackground = Child(RoundedRectangle.self) + let titleField = Child(TitleFieldComponent.self) + + let iconHeader = Child(MultilineTextComponent.self) + let iconBackground = Child(RoundedRectangle.self) + let iconSelector = Child(TopicIconSelectionComponent.self) + + return { context in + let environment = context.environment[EnvironmentType.self].value + let state = context.state + + let background = background.update( + component: Rectangle( + color: environment.theme.list.blocksBackgroundColor + ), + environment: {}, + availableSize: context.availableSize, + transition: context.transition + ) + + context.add(background + .position(CGPoint(x: context.availableSize.width / 2.0, y: context.availableSize.height / 2.0)) + ) + + let sideInset: CGFloat = 16.0 + let topInset: CGFloat = 16.0 + environment.navigationHeight + let headerSpacing: CGFloat = 6.0 + let sectionSpacing: CGFloat = 30.0 + + var contentHeight = topInset + + let titleHeader = titleHeader.update( + component: MultilineTextComponent( + text: .plain(NSAttributedString( + string: "ENTER TOPIC TITLE", + font: Font.regular(13.0), + textColor: environment.theme.list.freeTextColor, + paragraphAlignment: .natural) + ), + horizontalAlignment: .natural, + maximumNumberOfLines: 1 + ), + availableSize: CGSize(width: context.availableSize.width - sideInset * 2.0, height: CGFloat.greatestFiniteMagnitude), + transition: .immediate + ) + context.add(titleHeader + .position(CGPoint(x: sideInset * 2.0 + titleHeader.size.width / 2.0, y: contentHeight + titleHeader.size.height / 2.0)) + ) + contentHeight += titleHeader.size.height + headerSpacing + + let titleBackground = titleBackground.update( + component: RoundedRectangle( + color: environment.theme.list.itemBlocksBackgroundColor, + cornerRadius: 10.0 + ), + availableSize: CGSize(width: context.availableSize.width - sideInset * 2.0, height: 44.0), + transition: context.transition + ) + context.add(titleBackground + .position(CGPoint(x: context.availableSize.width / 2.0, y: contentHeight + titleBackground.size.height / 2.0)) + ) + + let titleField = titleField.update( + component: TitleFieldComponent( + context: context.component.context, + textColor: environment.theme.list.itemPrimaryTextColor, + accentColor: environment.theme.list.itemAccentColor, + placeholderColor: environment.theme.list.disclosureArrowColor, + fileId: state.fileId, + text: state.title, + textUpdated: { [weak state] text in + state?.updateTitle(text) + } + ), + availableSize: CGSize(width: context.availableSize.width - sideInset * 2.0, height: 44.0), + transition: context.transition + ) + context.add(titleField + .position(CGPoint(x: context.availableSize.width / 2.0, y: contentHeight + titleBackground.size.height / 2.0)) + ) + + contentHeight += titleBackground.size.height + sectionSpacing + + let iconHeader = iconHeader.update( + component: MultilineTextComponent( + text: .plain(NSAttributedString( + string: "SELECT TOPIC ICON", + font: Font.regular(13.0), + textColor: environment.theme.list.freeTextColor, + paragraphAlignment: .natural) + ), + horizontalAlignment: .natural, + maximumNumberOfLines: 1 + ), + availableSize: CGSize( + width: context.availableSize.width - sideInset * 2.0, + height: CGFloat.greatestFiniteMagnitude + ), + transition: .immediate + ) + context.add(iconHeader + .position(CGPoint(x: sideInset * 2.0 + iconHeader.size.width / 2.0, y: contentHeight + iconHeader.size.height / 2.0)) + ) + contentHeight += iconHeader.size.height + headerSpacing + + let iconBackground = iconBackground.update( + component: RoundedRectangle( + color: environment.theme.list.itemBlocksBackgroundColor, + cornerRadius: 10.0 + ), + availableSize: CGSize( + width: context.availableSize.width - sideInset * 2.0, + height: context.availableSize.height - topInset - titleHeader.size.height - titleBackground.size.height + ), + transition: context.transition + ) + context.add(iconBackground + .position(CGPoint(x: context.availableSize.width / 2.0, y: contentHeight + iconBackground.size.height / 2.0)) + ) + + if let emojiContent = state.emojiContent { + let availableHeight = context.availableSize.height - contentHeight - environment.inputHeight + + let iconSelector = iconSelector.update( + component: TopicIconSelectionComponent( + theme: environment.theme, + strings: environment.strings, + deviceMetrics: environment.deviceMetrics, + emojiContent: emojiContent, + backgroundColor: .clear, + separatorColor: environment.theme.list.blocksBackgroundColor + ), + environment: {}, + availableSize: CGSize(width: context.availableSize.width - sideInset * 2.0, height: availableHeight), + transition: context.transition + ) + context.add(iconSelector + .position(CGPoint(x: context.availableSize.width / 2.0, y: contentHeight + iconSelector.size.height / 2.0)) + ) + + let accountContext = context.component.context + emojiContent.inputInteractionHolder.inputInteraction = EmojiPagerContentComponent.InputInteraction( + performItemAction: { [weak state] groupId, item, _, _, _, _ in + state?.applyItem(groupId: groupId, item: item) + }, + deleteBackwards: { + }, + openStickerSettings: { + }, + openFeatured: { + }, + addGroupAction: { groupId, isPremiumLocked in + guard let collectionId = groupId.base as? ItemCollectionId else { + return + } + + let viewKey = PostboxViewKey.orderedItemList(id: Namespaces.OrderedItemList.CloudFeaturedEmojiPacks) + let _ = (accountContext.account.postbox.combinedView(keys: [viewKey]) + |> take(1) + |> deliverOnMainQueue).start(next: { views in + guard let view = views.views[viewKey] as? OrderedItemListView else { + return + } + for featuredEmojiPack in view.items.lazy.map({ $0.contents.get(FeaturedStickerPackItem.self)! }) { + if featuredEmojiPack.info.id == collectionId { +// if let strongSelf = self { +// strongSelf.scheduledEmojiContentAnimationHint = EmojiPagerContentComponent.ContentAnimation(type: .groupInstalled(id: collectionId)) +// } + let _ = accountContext.engine.stickers.addStickerPackInteractively(info: featuredEmojiPack.info, items: featuredEmojiPack.topItems).start() + + break + } + } + }) + }, + clearGroup: { _ in + }, + pushController: { c in + }, + presentController: { c in + }, + presentGlobalOverlayController: { c in + }, + navigationController: { + return nil + }, + requestUpdate: { _ in + }, + updateSearchQuery: { _, _ in + }, + chatPeerId: nil, + peekBehavior: nil, + customLayout: nil, + externalBackground: nil, + externalExpansionView: nil, + useOpaqueTheme: true + ) + } + + return context.availableSize + } + } +} + +public class ForumCreateTopicScreen: ViewControllerComponentContainer { + public enum Mode: Equatable { + case create + case edit(topic: ForumChannelTopics.Item) + } + + public init(context: AccountContext, peerId: EnginePeer.Id, mode: ForumCreateTopicScreen.Mode) { + var titleUpdatedImpl: ((String) -> Void)? + super.init(context: context, component: ForumCreateTopicScreenComponent(context: context, peerId: peerId, mode: mode, titleUpdated: { title in + titleUpdatedImpl?(title) + }), navigationBarAppearance: .transparent) + + let title: String + let doneTitle: String + switch mode { + case .create: + title = "New Topic" + doneTitle = "Create" + case .edit: + title = "Edit Topic" + doneTitle = "Done" + } + + self.title = title + + let presentationData = context.sharedContext.currentPresentationData.with { $0 } + self.navigationItem.leftBarButtonItem = UIBarButtonItem(title: presentationData.strings.Common_Cancel, style: .plain, target: self, action: #selector(self.cancelPressed)) + + self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: doneTitle, style: .done, target: self, action: #selector(self.createPressed)) + self.navigationItem.rightBarButtonItem?.isEnabled = false + + titleUpdatedImpl = { [weak self] title in + self?.navigationItem.rightBarButtonItem?.isEnabled = !title.isEmpty + } + } + + required public init(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + @objc private func cancelPressed() { + self.dismiss() + } + + @objc private func createPressed() { + self.dismiss() + } +} diff --git a/submodules/TelegramUI/Images.xcassets/Chat/Context Menu/PhoneCall.imageset/Contents.json b/submodules/TelegramUI/Images.xcassets/Chat/Context Menu/PhoneCall.imageset/Contents.json new file mode 100644 index 0000000000..248b5e5859 --- /dev/null +++ b/submodules/TelegramUI/Images.xcassets/Chat/Context Menu/PhoneCall.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "phonecall_24.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/submodules/TelegramUI/Images.xcassets/Chat/Context Menu/PhoneCall.imageset/phonecall_24.pdf b/submodules/TelegramUI/Images.xcassets/Chat/Context Menu/PhoneCall.imageset/phonecall_24.pdf new file mode 100644 index 0000000000..bb3744733a --- /dev/null +++ b/submodules/TelegramUI/Images.xcassets/Chat/Context Menu/PhoneCall.imageset/phonecall_24.pdf @@ -0,0 +1,424 @@ +%PDF-1.7 + +1 0 obj + << /Type /XObject + /Length 2 0 R + /Group << /Type /Group + /S /Transparency + >> + /Subtype /Form + /Resources << >> + /BBox [ 0.000000 0.000000 24.000000 24.000000 ] + >> +stream +/DeviceRGB CS +/DeviceRGB cs +1.000000 0.000000 -0.000000 1.000000 4.500000 1.839966 cm +2.336997 17.660034 m +2.662117 17.660034 2.919991 17.531717 3.113886 17.260115 c +4.585419 14.879068 l +4.920160 14.337935 4.887798 13.646688 4.503964 13.139196 c +3.449515 11.745041 l +3.304240 11.606829 3.209649 11.367731 3.209649 11.106469 c +3.209649 10.919914 3.258480 10.760313 3.345299 10.569205 c +3.613995 10.003538 4.318002 9.122787 5.191207 8.228218 c +5.368025 8.049210 l +6.244456 7.163609 7.244257 6.357477 7.850526 6.038754 c +8.070224 5.937879 8.234513 5.889532 8.432807 5.889532 c +8.701159 5.889532 8.948185 5.981611 9.144370 6.177905 c +10.453788 7.178677 l +10.962485 7.569689 11.660256 7.604506 12.205351 7.266076 c +14.664220 5.739452 l +14.893296 5.579560 15.000061 5.360890 15.000061 5.068824 c +15.000061 4.668618 14.761724 4.178541 14.364333 3.757545 c +13.671964 3.012113 12.839583 2.659973 11.811339 2.659973 c +9.637396 2.659973 6.759635 4.298767 4.190047 6.869761 c +1.619593 9.441620 0.000000 12.297401 0.000000 14.478063 c +0.000000 15.496849 0.341778 16.351761 1.049306 17.037554 c +1.462726 17.444048 1.928928 17.660034 2.336997 17.660034 c +h +0.000000 0.000000 0.000000 scn +f +n + +endstream +endobj + +2 0 obj + 1177 +endobj + +3 0 obj + << /Length 4 0 R + /FunctionType 4 + /Domain [ 0.000000 1.000000 ] + /Range [ 0.000000 1.000000 ] + >> +stream +{ 0 gt { 0 } { 1 } ifelse } +endstream +endobj + +4 0 obj + 27 +endobj + +5 0 obj + << /ExtGState << /E1 << /SMask << /Type /Mask + /G 1 0 R + /S /Alpha + /TR 3 0 R + >> + /Type /ExtGState + >> >> >> +endobj + +6 0 obj + << /Length 7 0 R >> +stream +/DeviceRGB CS +/DeviceRGB cs +q +/E1 gs +q +1.000000 0.000000 -0.000000 1.000000 4.500000 1.839966 cm +0.000000 0.000000 0.000000 scn +3.113886 17.260115 m +4.245259 17.959326 l +4.222027 17.996916 l +4.196352 18.032883 l +3.113886 17.260115 l +h +4.585419 14.879068 m +3.454046 14.179857 l +3.454337 14.179388 l +4.585419 14.879068 l +h +4.503964 13.139196 m +3.443199 13.941491 l +3.443199 13.941490 l +4.503964 13.139196 l +h +3.449515 11.745041 m +4.366253 10.781459 l +4.444844 10.856229 l +4.510280 10.942745 l +3.449515 11.745041 l +h +3.345299 10.569205 m +2.134399 10.019096 l +2.139083 10.008785 l +2.143943 9.998554 l +3.345299 10.569205 l +h +5.191207 8.228218 m +4.239443 7.299183 l +4.244984 7.293574 l +5.191207 8.228218 l +h +5.368025 8.049210 m +4.421801 7.114565 l +4.422691 7.113666 l +5.368025 8.049210 l +h +7.850526 6.038754 m +7.231641 4.861520 l +7.263175 4.844942 l +7.295551 4.830077 l +7.850526 6.038754 l +h +9.144370 6.177905 m +8.336740 7.234614 l +8.266318 7.180791 l +8.203662 7.118100 l +9.144370 6.177905 l +h +10.453788 7.178677 m +11.261421 6.121964 l +11.264320 6.124193 l +10.453788 7.178677 l +h +12.205351 7.266076 m +12.906886 8.396009 l +12.906886 8.396009 l +12.205351 7.266076 l +h +14.664220 5.739452 m +15.425447 6.830063 l +15.396130 6.850527 l +15.365755 6.869386 l +14.664220 5.739452 l +h +14.364333 3.757545 m +13.397125 4.670519 l +13.389837 4.662673 l +14.364333 3.757545 l +h +4.190047 6.869761 m +5.130756 7.809957 l +5.130756 7.809957 l +4.190047 6.869761 l +h +1.049306 17.037554 m +1.974998 16.082523 l +1.981782 16.089191 l +1.049306 17.037554 l +h +2.336997 16.330034 m +2.320346 16.330034 2.253638 16.334621 2.169936 16.377350 c +2.085590 16.420408 2.041937 16.472618 2.031421 16.487349 c +4.196352 18.032883 l +3.748895 18.659664 3.084965 18.990034 2.336997 18.990034 c +2.336997 16.330034 l +h +1.982513 16.560905 m +3.454046 14.179857 l +5.716792 15.578279 l +4.245259 17.959326 l +1.982513 16.560905 l +h +3.454337 14.179388 m +3.500106 14.105397 3.495682 14.010881 3.443199 13.941491 c +5.564729 12.336901 l +6.279915 13.282494 6.340214 14.570473 5.716501 15.578749 c +3.454337 14.179388 l +h +3.443199 13.941490 m +2.388749 12.547336 l +4.510280 10.942745 l +5.564729 12.336901 l +3.443199 13.941490 l +h +2.532776 12.708622 m +2.068971 12.267365 1.879649 11.648950 1.879649 11.106469 c +4.539649 11.106469 l +4.539649 11.079510 4.535252 11.043770 4.517922 10.998292 c +4.502114 10.956808 4.462042 10.872591 4.366253 10.781459 c +2.532776 12.708622 l +h +1.879649 11.106469 m +1.879649 10.656174 2.006887 10.299776 2.134399 10.019096 c +4.556200 11.119314 l +4.543678 11.146877 4.536608 11.164371 4.532750 11.174656 c +4.529046 11.184531 4.529113 11.185631 4.530626 11.179913 c +4.532265 11.173723 4.534810 11.162544 4.536798 11.147743 c +4.538805 11.132805 4.539649 11.118605 4.539649 11.106469 c +1.879649 11.106469 l +h +2.143943 9.998554 m +2.513995 9.219506 3.354690 8.205615 4.239460 7.299199 c +6.142955 9.157238 l +5.281314 10.039959 4.713994 10.787569 4.546656 11.139856 c +2.143943 9.998554 l +h +4.244984 7.293574 m +4.421802 7.114566 l +6.314249 8.983854 l +6.137431 9.162863 l +4.244984 7.293574 l +h +4.422691 7.113666 m +5.333439 6.193388 6.446281 5.274392 7.231641 4.861520 c +8.469412 7.215989 l +8.042233 7.440562 7.155473 8.133829 6.313359 8.984755 c +4.422691 7.113666 l +h +7.295551 4.830077 m +7.610502 4.685464 7.971885 4.559532 8.432807 4.559532 c +8.432807 7.219532 l +8.438139 7.219532 8.448376 7.219153 8.461496 7.217438 c +8.474616 7.215722 8.484693 7.213446 8.489946 7.212055 c +8.494530 7.210842 8.491272 7.211398 8.477601 7.216578 c +8.463371 7.221971 8.440556 7.231338 8.405501 7.247433 c +7.295551 4.830077 l +h +8.432807 4.559532 m +9.024679 4.559532 9.619445 4.771820 10.085079 5.237710 c +8.203662 7.118100 l +8.232141 7.146595 8.273987 7.176050 8.325019 7.196304 c +8.374480 7.215935 8.413715 7.219532 8.432807 7.219532 c +8.432807 4.559532 l +h +9.952001 5.121196 m +11.261418 6.121968 l +9.646158 8.235386 l +8.336740 7.234614 l +9.952001 5.121196 l +h +11.264320 6.124193 m +11.333877 6.177657 11.429284 6.182418 11.503816 6.136144 c +12.906886 8.396009 l +11.891228 9.026595 10.591094 8.961720 9.643255 8.233161 c +11.264320 6.124193 l +h +11.503816 6.136144 m +13.962685 4.609520 l +15.365755 6.869386 l +12.906886 8.396009 l +11.503816 6.136144 l +h +13.902991 4.648842 m +13.857372 4.680683 13.782755 4.749804 13.727364 4.861100 c +13.674102 4.968115 13.670061 5.050985 13.670061 5.068824 c +16.330061 5.068824 l +16.330061 5.757030 16.041370 6.400160 15.425447 6.830063 c +13.902991 4.648842 l +h +13.670061 5.068824 m +13.670061 5.122084 13.682167 5.099532 13.634643 5.001590 c +13.590631 4.910884 13.513090 4.793310 13.397157 4.670489 c +15.331510 2.844599 l +15.856868 3.401164 16.330061 4.202022 16.330061 5.068824 c +13.670061 5.068824 l +h +13.389837 4.662673 m +12.957663 4.197376 12.482564 3.989973 11.811339 3.989973 c +11.811339 1.329973 l +13.196602 1.329973 14.386265 1.826848 15.338829 2.852416 c +13.389837 4.662673 l +h +11.811339 3.989973 m +11.034931 3.989973 10.000110 4.292040 8.796299 4.962632 c +7.609632 5.623674 6.344436 6.595613 5.130756 7.809957 c +3.249338 5.929566 l +4.605247 4.572916 6.063725 3.439960 7.501822 2.638857 c +8.922773 1.847304 10.413804 1.329973 11.811339 1.329973 c +11.811339 3.989973 l +h +5.130756 7.809957 m +3.916355 9.025021 2.949746 10.284932 2.293909 11.466198 c +1.629269 12.663321 1.330000 13.695452 1.330000 14.478063 c +-1.330000 14.478063 l +-1.330000 13.080011 -0.819472 11.593922 -0.031702 10.175023 c +0.764871 8.740269 1.893285 7.286361 3.249338 5.929566 c +5.130756 7.809957 l +h +1.330000 14.478063 m +1.330000 15.163555 1.544419 15.665218 1.974975 16.082546 c +0.123637 17.992559 l +-0.860863 17.038303 -1.330000 15.830142 -1.330000 14.478063 c +1.330000 14.478063 l +h +1.981782 16.089191 m +2.096122 16.201618 2.197214 16.267076 2.268798 16.301296 c +2.342271 16.336422 2.365401 16.330034 2.336997 16.330034 c +2.336997 18.990034 l +1.477759 18.990034 0.695014 18.554413 0.116830 17.985914 c +1.981782 16.089191 l +h +f +n +Q +Q +q +1.000000 0.000000 -0.000000 1.000000 13.000000 13.000000 cm +0.000000 0.000000 0.000000 scn +1.000000 6.000000 m +1.552285 6.000000 2.000000 6.447715 2.000000 7.000000 c +2.000000 7.552285 1.552285 8.000000 1.000000 8.000000 c +0.447715 8.000000 0.000000 7.552285 0.000000 7.000000 c +0.000000 6.447715 0.447715 6.000000 1.000000 6.000000 c +h +5.000000 7.000000 m +5.000000 6.447715 4.552284 6.000000 4.000000 6.000000 c +3.447716 6.000000 3.000000 6.447715 3.000000 7.000000 c +3.000000 7.552285 3.447716 8.000000 4.000000 8.000000 c +4.552284 8.000000 5.000000 7.552285 5.000000 7.000000 c +h +8.000000 7.000000 m +8.000000 6.447715 7.552284 6.000000 7.000000 6.000000 c +6.447716 6.000000 6.000000 6.447715 6.000000 7.000000 c +6.000000 7.552285 6.447716 8.000000 7.000000 8.000000 c +7.552284 8.000000 8.000000 7.552285 8.000000 7.000000 c +h +8.000000 4.000000 m +8.000000 3.447715 7.552284 3.000000 7.000000 3.000000 c +6.447716 3.000000 6.000000 3.447715 6.000000 4.000000 c +6.000000 4.552285 6.447716 5.000000 7.000000 5.000000 c +7.552284 5.000000 8.000000 4.552285 8.000000 4.000000 c +h +4.000000 3.000000 m +4.552284 3.000000 5.000000 3.447715 5.000000 4.000000 c +5.000000 4.552285 4.552284 5.000000 4.000000 5.000000 c +3.447716 5.000000 3.000000 4.552285 3.000000 4.000000 c +3.000000 3.447715 3.447716 3.000000 4.000000 3.000000 c +h +2.000000 4.000000 m +2.000000 3.447715 1.552285 3.000000 1.000000 3.000000 c +0.447715 3.000000 0.000000 3.447715 0.000000 4.000000 c +0.000000 4.552285 0.447715 5.000000 1.000000 5.000000 c +1.552285 5.000000 2.000000 4.552285 2.000000 4.000000 c +h +7.000000 0.000000 m +7.552284 0.000000 8.000000 0.447715 8.000000 1.000000 c +8.000000 1.552285 7.552284 2.000000 7.000000 2.000000 c +6.447716 2.000000 6.000000 1.552285 6.000000 1.000000 c +6.000000 0.447715 6.447716 0.000000 7.000000 0.000000 c +h +5.000000 1.000000 m +5.000000 0.447715 4.552284 0.000000 4.000000 0.000000 c +3.447716 0.000000 3.000000 0.447715 3.000000 1.000000 c +3.000000 1.552285 3.447716 2.000000 4.000000 2.000000 c +4.552284 2.000000 5.000000 1.552285 5.000000 1.000000 c +h +1.000000 0.000000 m +1.552285 0.000000 2.000000 0.447715 2.000000 1.000000 c +2.000000 1.552285 1.552285 2.000000 1.000000 2.000000 c +0.447715 2.000000 0.000000 1.552285 0.000000 1.000000 c +0.000000 0.447715 0.447715 0.000000 1.000000 0.000000 c +h +f* +n +Q + +endstream +endobj + +7 0 obj + 8188 +endobj + +8 0 obj + << /Annots [] + /Type /Page + /MediaBox [ 0.000000 0.000000 24.000000 24.000000 ] + /Resources 5 0 R + /Contents 6 0 R + /Parent 9 0 R + >> +endobj + +9 0 obj + << /Kids [ 8 0 R ] + /Count 1 + /Type /Pages + >> +endobj + +10 0 obj + << /Pages 9 0 R + /Type /Catalog + >> +endobj + +xref +0 11 +0000000000 65535 f +0000000010 00000 n +0000001435 00000 n +0000001458 00000 n +0000001633 00000 n +0000001654 00000 n +0000001966 00000 n +0000010210 00000 n +0000010233 00000 n +0000010406 00000 n +0000010480 00000 n +trailer +<< /ID [ (some) (id) ] + /Root 10 0 R + /Size 11 +>> +startxref +10540 +%%EOF \ No newline at end of file diff --git a/submodules/TelegramUI/Sources/ChatBotInfoItem.swift b/submodules/TelegramUI/Sources/ChatBotInfoItem.swift index 393597ee46..52aad3bd1a 100644 --- a/submodules/TelegramUI/Sources/ChatBotInfoItem.swift +++ b/submodules/TelegramUI/Sources/ChatBotInfoItem.swift @@ -316,7 +316,7 @@ final class ChatBotInfoItemNode: ListViewItemNode { backgroundContent.clipsToBounds = true strongSelf.backgroundContent = backgroundContent - strongSelf.insertSubnode(backgroundContent, at: 0) + strongSelf.offsetContainer.insertSubnode(backgroundContent, at: 0) } } else { strongSelf.backgroundContent?.removeFromSupernode() diff --git a/submodules/TelegramUI/Sources/ChatControllerNode.swift b/submodules/TelegramUI/Sources/ChatControllerNode.swift index cd06e81307..52c9198f45 100644 --- a/submodules/TelegramUI/Sources/ChatControllerNode.swift +++ b/submodules/TelegramUI/Sources/ChatControllerNode.swift @@ -108,6 +108,10 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate { private let inputPanelOverlayNode: SparseNode private let inputPanelClippingNode: SparseNode private let inputPanelBackgroundNode: NavigationBackgroundNode + + private var navigationBarBackgroundContent: WallpaperBubbleBackgroundNode? + private var inputPanelBackgroundContent: WallpaperBubbleBackgroundNode? + private var intrinsicInputPanelBackgroundNodeSize: CGSize? private let inputPanelBackgroundSeparatorNode: ASDisplayNode private var inputPanelBottomBackgroundSeparatorBaseOffset: CGFloat = 0.0 @@ -1670,6 +1674,18 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate { transition.updatePosition(node: self.inputPanelOverlayNode, position: CGRect(origin: apparentInputBackgroundFrame.origin, size: layout.size).center, beginWithCurrentState: true) transition.updateBounds(node: self.inputPanelOverlayNode, bounds: CGRect(origin: CGPoint(x: 0.0, y: apparentInputBackgroundFrame.origin.y), size: layout.size), beginWithCurrentState: true) transition.updateFrame(node: self.inputPanelBackgroundNode, frame: apparentInputBackgroundFrame, beginWithCurrentState: true) + + if let navigationBarBackgroundContent = self.navigationBarBackgroundContent { + transition.updateFrame(node: navigationBarBackgroundContent, frame: CGRect(origin: .zero, size: CGSize(width: layout.size.width, height: navigationBarHeight + (titleAccessoryPanelBackgroundHeight ?? 0.0))), beginWithCurrentState: true) + navigationBarBackgroundContent.update(rect: CGRect(origin: .zero, size: CGSize(width: layout.size.width, height: navigationBarHeight + (titleAccessoryPanelBackgroundHeight ?? 0.0))), within: layout.size, transition: transition) + } + + if let inputPanelBackgroundContent = self.inputPanelBackgroundContent { + var apparentInputBackgroundFrame = apparentInputBackgroundFrame + apparentInputBackgroundFrame.size.height += 34.0 + transition.updateFrame(node: inputPanelBackgroundContent, frame: CGRect(origin: .zero, size: apparentInputBackgroundFrame.size), beginWithCurrentState: true) + inputPanelBackgroundContent.update(rect: apparentInputBackgroundFrame, within: layout.size, transition: transition) + } transition.updateFrame(node: self.contentDimNode, frame: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: layout.size.width, height: apparentInputBackgroundFrame.origin.y))) @@ -2069,6 +2085,14 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate { self.inputPanelBackgroundNode.update(size: CGSize(width: intrinsicInputPanelBackgroundNodeSize.width, height: intrinsicInputPanelBackgroundNodeSize.height + extensionValue), transition: transition) transition.updateFrame(node: self.inputPanelBottomBackgroundSeparatorNode, frame: CGRect(origin: CGPoint(x: 0.0, y: self.inputPanelBottomBackgroundSeparatorBaseOffset + extensionValue), size: CGSize(width: self.inputPanelBottomBackgroundSeparatorNode.bounds.width, height: UIScreenPixel)), beginWithCurrentState: true) + + if let inputPanelBackgroundContent = self.inputPanelBackgroundContent, let (layout, _) = self.validLayout { + var inputPanelBackgroundFrame = self.inputPanelBackgroundNode.frame + inputPanelBackgroundFrame.size.height = intrinsicInputPanelBackgroundNodeSize.height + extensionValue + + transition.updateFrame(node: inputPanelBackgroundContent, frame: CGRect(origin: .zero, size: inputPanelBackgroundFrame.size)) + inputPanelBackgroundContent.update(rect: inputPanelBackgroundFrame, within: layout.size, transition: transition) + } } private var storedHideInputExpanded: Bool? @@ -2171,11 +2195,37 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate { self.usePlainInputSeparator = false self.plainInputSeparatorAlpha = nil } + self.updatePlainInputSeparator(transition: .immediate) self.inputPanelBackgroundSeparatorNode.backgroundColor = self.chatPresentationInterfaceState.theme.chat.inputPanel.panelSeparatorColor self.inputPanelBottomBackgroundSeparatorNode.backgroundColor = self.chatPresentationInterfaceState.theme.chat.inputMediaPanel.panelSeparatorColor self.backgroundNode.updateBubbleTheme(bubbleTheme: chatPresentationInterfaceState.theme, bubbleCorners: chatPresentationInterfaceState.bubbleCorners) + + if self.backgroundNode.hasExtraBubbleBackground() { + if self.navigationBarBackgroundContent == nil { + if let navigationBarBackgroundContent = self.backgroundNode.makeBubbleBackground(for: .free), + let inputPanelBackgroundContent = self.backgroundNode.makeBubbleBackground(for: .free) { + self.navigationBarBackgroundContent = navigationBarBackgroundContent + self.inputPanelBackgroundContent = inputPanelBackgroundContent + + navigationBarBackgroundContent.allowsGroupOpacity = true + navigationBarBackgroundContent.implicitContentUpdate = false + navigationBarBackgroundContent.alpha = 0.2 + self.navigationBar?.insertSubnode(navigationBarBackgroundContent, at: 1) + + inputPanelBackgroundContent.allowsGroupOpacity = true + inputPanelBackgroundContent.implicitContentUpdate = false + inputPanelBackgroundContent.alpha = 0.2 + self.inputPanelBackgroundNode.addSubnode(inputPanelBackgroundContent) + } + } + } else { + self.navigationBarBackgroundContent?.removeFromSupernode() + self.navigationBarBackgroundContent = nil + self.inputPanelBackgroundContent?.removeFromSupernode() + self.inputPanelBackgroundContent = nil + } } let keepSendButtonEnabled = chatPresentationInterfaceState.interfaceState.forwardMessageIds != nil || chatPresentationInterfaceState.interfaceState.editMessage != nil diff --git a/submodules/TelegramUI/Sources/ChatMessageActionButtonsNode.swift b/submodules/TelegramUI/Sources/ChatMessageActionButtonsNode.swift index 6d0606d162..90b4f99192 100644 --- a/submodules/TelegramUI/Sources/ChatMessageActionButtonsNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageActionButtonsNode.swift @@ -223,16 +223,31 @@ private final class ChatMessageActionButtonNode: ASDisplayNode { node.backgroundBlurNode.isHidden = false } - if position == .bottomSingle { - let rect = node.backgroundBlurNode.bounds - let maskPath = UIBezierPath(roundRect: rect, topLeftRadius: bubbleCorners.auxiliaryRadius, topRightRadius: bubbleCorners.auxiliaryRadius, bottomLeftRadius: bubbleCorners.mainRadius, bottomRightRadius: bubbleCorners.mainRadius) - let shape = CAShapeLayer() - shape.path = maskPath.cgPath - node.layer.mask = shape - } else { - node.layer.mask = nil + + let rect = node.backgroundBlurNode.bounds + let maskPath: CGPath? + switch position { + case .bottomSingle: + maskPath = UIBezierPath(roundRect: rect, topLeftRadius: bubbleCorners.auxiliaryRadius, topRightRadius: bubbleCorners.auxiliaryRadius, bottomLeftRadius: bubbleCorners.mainRadius, bottomRightRadius: bubbleCorners.mainRadius).cgPath + case .bottomLeft: + maskPath = UIBezierPath(roundRect: rect, topLeftRadius: bubbleCorners.auxiliaryRadius, topRightRadius: bubbleCorners.auxiliaryRadius, bottomLeftRadius: bubbleCorners.mainRadius, bottomRightRadius: bubbleCorners.auxiliaryRadius).cgPath + case .bottomRight: + maskPath = UIBezierPath(roundRect: rect, topLeftRadius: bubbleCorners.auxiliaryRadius, topRightRadius: bubbleCorners.auxiliaryRadius, bottomLeftRadius: bubbleCorners.auxiliaryRadius, bottomRightRadius: bubbleCorners.mainRadius).cgPath + default: + maskPath = nil } + let currentMaskPath = (node.layer.mask as? CAShapeLayer)?.path + if currentMaskPath != maskPath { + if let maskPath = maskPath { + let shapeLayer = CAShapeLayer() + shapeLayer.path = maskPath + node.layer.mask = shapeLayer + } else { + node.layer.mask = nil + } + } + if iconImage != nil { if node.iconNode == nil { let iconNode = ASImageNode() diff --git a/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift index 7a9c9d3697..9b0c04b56a 100644 --- a/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift @@ -1133,7 +1133,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode ignoreForward = true effectiveAuthor = forwardInfo.author if effectiveAuthor == nil, let authorSignature = forwardInfo.authorSignature { - effectiveAuthor = TelegramUser(id: PeerId(namespace: Namespaces.Peer.Empty, id: PeerId.Id._internalFromInt64Value(Int64(authorSignature.persistentHashValue % 32))), accessHash: nil, firstName: authorSignature, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: nil) + effectiveAuthor = TelegramUser(id: PeerId(namespace: Namespaces.Peer.Empty, id: PeerId.Id._internalFromInt64Value(Int64(authorSignature.persistentHashValue % 32))), accessHash: nil, firstName: authorSignature, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: []) } } displayAuthorInfo = !mergedTop.merged && incoming && effectiveAuthor != nil @@ -1149,7 +1149,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode displayAuthorInfo = !mergedTop.merged && incoming } else if let forwardInfo = item.content.firstMessage.forwardInfo, forwardInfo.flags.contains(.isImported), let authorSignature = forwardInfo.authorSignature { ignoreForward = true - effectiveAuthor = TelegramUser(id: PeerId(namespace: Namespaces.Peer.Empty, id: PeerId.Id._internalFromInt64Value(Int64(authorSignature.persistentHashValue % 32))), accessHash: nil, firstName: authorSignature, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: nil) + effectiveAuthor = TelegramUser(id: PeerId(namespace: Namespaces.Peer.Empty, id: PeerId.Id._internalFromInt64Value(Int64(authorSignature.persistentHashValue % 32))), accessHash: nil, firstName: authorSignature, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: []) displayAuthorInfo = !mergedTop.merged && incoming } else if let _ = item.content.firstMessage.adAttribute, let author = item.content.firstMessage.author { ignoreForward = true diff --git a/submodules/TelegramUI/Sources/ChatMessageItem.swift b/submodules/TelegramUI/Sources/ChatMessageItem.swift index a1be6a4998..89436c8a97 100644 --- a/submodules/TelegramUI/Sources/ChatMessageItem.swift +++ b/submodules/TelegramUI/Sources/ChatMessageItem.swift @@ -305,7 +305,7 @@ public final class ChatMessageItem: ListViewItem, CustomStringConvertible { if let forwardInfo = content.firstMessage.forwardInfo { effectiveAuthor = forwardInfo.author if effectiveAuthor == nil, let authorSignature = forwardInfo.authorSignature { - effectiveAuthor = TelegramUser(id: PeerId(namespace: Namespaces.Peer.Empty, id: PeerId.Id._internalFromInt64Value(Int64(authorSignature.persistentHashValue % 32))), accessHash: nil, firstName: authorSignature, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: nil) + effectiveAuthor = TelegramUser(id: PeerId(namespace: Namespaces.Peer.Empty, id: PeerId.Id._internalFromInt64Value(Int64(authorSignature.persistentHashValue % 32))), accessHash: nil, firstName: authorSignature, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: []) } } displayAuthorInfo = incoming && effectiveAuthor != nil diff --git a/submodules/TelegramUI/Sources/ChatRecentActionsControllerNode.swift b/submodules/TelegramUI/Sources/ChatRecentActionsControllerNode.swift index 05c523dcbe..b8c99d6a02 100644 --- a/submodules/TelegramUI/Sources/ChatRecentActionsControllerNode.swift +++ b/submodules/TelegramUI/Sources/ChatRecentActionsControllerNode.swift @@ -659,6 +659,7 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode { let emptyFrame = CGRect(origin: CGPoint(x: 0.0, y: navigationBarHeight), size: CGSize(width: layout.size.width, height: layout.size.height - navigationBarHeight - panelHeight)) transition.updateFrame(node: self.emptyNode, frame: emptyFrame) + self.emptyNode.update(rect: emptyFrame, within: layout.size) self.emptyNode.updateLayout(backgroundNode: self.backgroundNode, size: emptyFrame.size, transition: transition) let contentBottomInset: CGFloat = panelHeight + 4.0 diff --git a/submodules/TelegramUI/Sources/ChatRestrictedNode.swift b/submodules/TelegramUI/Sources/ChatRestrictedNode.swift deleted file mode 100644 index 8b13789179..0000000000 --- a/submodules/TelegramUI/Sources/ChatRestrictedNode.swift +++ /dev/null @@ -1 +0,0 @@ - diff --git a/submodules/TelegramUI/Sources/PeerInfo/ListItems/PeerInfoScreenLabeledValueItem.swift b/submodules/TelegramUI/Sources/PeerInfo/ListItems/PeerInfoScreenLabeledValueItem.swift index 244eed07ea..9dfb49fd67 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/ListItems/PeerInfoScreenLabeledValueItem.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/ListItems/PeerInfoScreenLabeledValueItem.swift @@ -530,7 +530,7 @@ private final class PeerInfoScreenLabeledValueItemNode: PeerInfoScreenItemNode { self.containerNode.frame = CGRect(origin: CGPoint(), size: contentSize) self.contextSourceNode.frame = CGRect(origin: CGPoint(), size: contentSize) self.contextSourceNode.contentNode.frame = CGRect(origin: CGPoint(), size: contentSize) - self.containerNode.isGestureEnabled = false + self.containerNode.isGestureEnabled = item.contextAction != nil let nonExtractedRect = CGRect(origin: CGPoint(), size: CGSize(width: contentSize.width, height: contentSize.height)) let extractedRect = nonExtractedRect @@ -627,7 +627,7 @@ private final class PeerInfoScreenLabeledValueItemNode: PeerInfoScreenItemNode { } else { linkHighlightingNode = LinkHighlightingNode(color: theme.list.itemAccentColor.withAlphaComponent(0.5)) self.linkHighlightingNode = linkHighlightingNode - self.insertSubnode(linkHighlightingNode, belowSubnode: textNode) + self.contextSourceNode.contentNode.insertSubnode(linkHighlightingNode, belowSubnode: textNode) } linkHighlightingNode.frame = textNode.frame linkHighlightingNode.updateRects(rects) diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoPaneContainerNode.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoPaneContainerNode.swift index 1633da1ec1..3ad85bb14e 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoPaneContainerNode.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoPaneContainerNode.swift @@ -457,6 +457,7 @@ final class PeerInfoPaneContainerNode: ASDisplayNode, UIGestureRecognizerDelegat weak var parentController: ViewController? private let coveringBackgroundNode: NavigationBackgroundNode + private let additionalBackgroundNode: ASDisplayNode private let separatorNode: ASDisplayNode private let tabsContainerNode: PeerInfoPaneTabsContainerNode private let tabsSeparatorNode: ASDisplayNode @@ -514,6 +515,8 @@ final class PeerInfoPaneContainerNode: ASDisplayNode, UIGestureRecognizerDelegat self.peerId = peerId self.isMediaOnly = isMediaOnly + self.additionalBackgroundNode = ASDisplayNode() + self.separatorNode = ASDisplayNode() self.separatorNode.isLayerBacked = true @@ -528,6 +531,7 @@ final class PeerInfoPaneContainerNode: ASDisplayNode, UIGestureRecognizerDelegat super.init() // self.addSubnode(self.separatorNode) + self.addSubnode(self.additionalBackgroundNode) self.addSubnode(self.coveringBackgroundNode) self.addSubnode(self.tabsContainerNode) self.addSubnode(self.tabsSeparatorNode) @@ -745,9 +749,12 @@ final class PeerInfoPaneContainerNode: ASDisplayNode, UIGestureRecognizerDelegat transition.updateAlpha(node: self.coveringBackgroundNode, alpha: expansionFraction) +// transition.updateAlpha(node: self.additionalBackgroundNode, alpha: 1.0 - expansionFraction) + self.backgroundColor = presentationData.theme.list.plainBackgroundColor self.coveringBackgroundNode.updateColor(color: presentationData.theme.rootController.navigationBar.opaqueBackgroundColor, transition: .immediate) self.separatorNode.backgroundColor = presentationData.theme.list.itemBlocksSeparatorColor + self.additionalBackgroundNode.backgroundColor = presentationData.theme.list.itemBlocksBackgroundColor self.tabsSeparatorNode.backgroundColor = presentationData.theme.list.itemBlocksSeparatorColor let isScrollingLockedAtTop = expansionFraction < 1.0 - CGFloat.ulpOfOne @@ -955,6 +962,7 @@ final class PeerInfoPaneContainerNode: ASDisplayNode, UIGestureRecognizerDelegat transition.updateFrame(node: self.separatorNode, frame: CGRect(origin: CGPoint(x: 0.0, y: -UIScreenPixel - tabsOffset), size: CGSize(width: size.width, height: UIScreenPixel))) transition.updateFrame(node: self.coveringBackgroundNode, frame: CGRect(origin: CGPoint(x: 0.0, y: -UIScreenPixel - tabsOffset), size: CGSize(width: size.width, height: tabsHeight + UIScreenPixel))) + transition.updateFrame(node: self.additionalBackgroundNode, frame: CGRect(origin: CGPoint(x: 0.0, y: -UIScreenPixel - tabsOffset), size: CGSize(width: size.width, height: tabsHeight + UIScreenPixel))) self.coveringBackgroundNode.update(size: self.coveringBackgroundNode.bounds.size, transition: transition) transition.updateFrame(node: self.tabsSeparatorNode, frame: CGRect(origin: CGPoint(x: 0.0, y: tabsHeight - tabsOffset), size: CGSize(width: size.width, height: UIScreenPixel))) diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift index 8b4fcc8cb9..6d630dbb31 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift @@ -951,12 +951,18 @@ private func infoItems(data: PeerInfoScreenData?, context: AccountContext, prese })) } if let username = user.username { + var additionalUsernames: String? + let usernames = user.usernames.filter { !$0.flags.contains(.isEditable) && $0.flags.contains(.isActive) } + if !usernames.isEmpty { + additionalUsernames = presentationData.strings.Profile_AdditionalUsernames(String(usernames.map { "@\($0.username)" }.joined(separator: ", "))).string + } + items[.peerInfo]!.append( PeerInfoScreenLabeledValueItem( id: 1, label: presentationData.strings.Profile_Username, text: "@\(username)", - additionalText: nil, //presentationData.strings.Profile_AdditionalUsernames("@username1, @username2, @username3, @username4"), + additionalText: additionalUsernames, textColor: .accent, icon: .qrCode, action: { _ in @@ -1076,15 +1082,32 @@ private func infoItems(data: PeerInfoScreenData?, context: AccountContext, prese } if let username = channel.username { - items[.peerInfo]!.append(PeerInfoScreenLabeledValueItem(id: ItemUsername, label: presentationData.strings.Channel_LinkItem, text: "https://t.me/\(username)", textColor: .accent, icon: .qrCode, action: { _ in - interaction.openUsername(username) - }, longTapAction: { sourceNode in - interaction.openPeerInfoContextMenu(.link, sourceNode) - }, iconAction: { - interaction.openQrCode() - }, requestLayout: { - interaction.requestLayout(false) - })) + var additionalUsernames: String? + let usernames = channel.usernames.filter { !$0.flags.contains(.isEditable) && $0.flags.contains(.isActive) } + if !usernames.isEmpty { + additionalUsernames = presentationData.strings.Profile_AdditionalUsernames(String(usernames.map { "@\($0.username)" }.joined(separator: ", "))).string + } + + + items[.peerInfo]!.append( + PeerInfoScreenLabeledValueItem( + id: ItemUsername, + label: presentationData.strings.Channel_LinkItem, + text: "https://t.me/\(username)", + additionalText: additionalUsernames, + textColor: .accent, + icon: .qrCode, + action: { _ in + interaction.openUsername(username) + }, longTapAction: { sourceNode in + interaction.openPeerInfoContextMenu(.link, sourceNode) + }, iconAction: { + interaction.openQrCode() + }, requestLayout: { + interaction.requestLayout(false) + } + ) + ) } if let cachedData = data.cachedData as? CachedChannelData { let aboutText: String? @@ -4902,34 +4925,6 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate guard let strongSelf = self else { return } -// if case let .user(peer) = peer, let peerPhoneNumber = peer.phone, formatPhoneNumber(value) == formatPhoneNumber(peerPhoneNumber) { -// let actionSheet = ActionSheetController(presentationData: strongSelf.presentationData) -// let dismissAction: () -> Void = { [weak actionSheet] in -// actionSheet?.dismissAnimated() -// } -// actionSheet.setItemGroups([ -// ActionSheetItemGroup(items: [ -// ActionSheetButtonItem(title: strongSelf.presentationData.strings.UserInfo_TelegramCall, action: { -// dismissAction() -// self?.requestCall(isVideo: false) -// }), -// ActionSheetButtonItem(title: strongSelf.presentationData.strings.UserInfo_PhoneCall, action: { -// dismissAction() -// -// guard let strongSelf = self else { -// return -// } -// strongSelf.context.sharedContext.applicationBindings.openUrl("tel:\(formatPhoneNumber(value).replacingOccurrences(of: " ", with: ""))") -// }), -// ]), -// ActionSheetItemGroup(items: [ActionSheetButtonItem(title: strongSelf.presentationData.strings.Common_Cancel, action: { dismissAction() })]) -// ]) -// strongSelf.view.endEditing(true) -// strongSelf.controller?.present(actionSheet, in: .window(.root)) -// } else { -// strongSelf.context.sharedContext.applicationBindings.openUrl("tel:\(formatPhoneNumber(value).replacingOccurrences(of: " ", with: ""))") -// } -// let presentationData = strongSelf.presentationData let telegramCallAction: (Bool) -> Void = { [weak self] isVideo in @@ -4968,7 +4963,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate } }))) - items.append(.action(ContextMenuActionItem(text: presentationData.strings.UserInfo_PhoneCall, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: ""), color: theme.contextMenu.primaryColor) }, action: { c, _ in + items.append(.action(ContextMenuActionItem(text: presentationData.strings.UserInfo_PhoneCall, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/PhoneCall"), color: theme.contextMenu.primaryColor) }, action: { c, _ in c.dismiss { phoneCallAction() } @@ -4980,7 +4975,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate }))) } else { items = [ - .action(ContextMenuActionItem(text: presentationData.strings.UserInfo_PhoneCall, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: ""), color: theme.contextMenu.primaryColor) }, action: { c, _ in + .action(ContextMenuActionItem(text: presentationData.strings.UserInfo_PhoneCall, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/PhoneCall"), color: theme.contextMenu.primaryColor) }, action: { c, _ in c.dismiss { phoneCallAction() } diff --git a/submodules/TelegramUI/Sources/PollResultsController.swift b/submodules/TelegramUI/Sources/PollResultsController.swift index 83794a9ccc..8e486a83c7 100644 --- a/submodules/TelegramUI/Sources/PollResultsController.swift +++ b/submodules/TelegramUI/Sources/PollResultsController.swift @@ -251,7 +251,7 @@ private func pollResultsControllerEntries(presentationData: PresentationData, po displayCount = Int(voterCount) } for peerIndex in 0 ..< displayCount { - let fakeUser = TelegramUser(id: PeerId(namespace: .max, id: PeerId.Id._internalFromInt64Value(0)), accessHash: nil, firstName: "", lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: nil) + let fakeUser = TelegramUser(id: PeerId(namespace: .max, id: PeerId.Id._internalFromInt64Value(0)), accessHash: nil, firstName: "", lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: []) let peer = RenderedPeer(peer: fakeUser) entries.append(.optionPeer(optionId: i, index: peerIndex, peer: peer, optionText: optionTextHeader, optionAdditionalText: optionAdditionalTextHeader, optionCount: voterCount, optionExpanded: false, opaqueIdentifier: option.opaqueIdentifier, shimmeringAlternation: peerIndex % 2, isFirstInOption: peerIndex == 0)) } diff --git a/submodules/TranslateUI/Sources/TranslateScreen.swift b/submodules/TranslateUI/Sources/TranslateScreen.swift index 65a7dd83b9..d51fc4f99b 100644 --- a/submodules/TranslateUI/Sources/TranslateScreen.swift +++ b/submodules/TranslateUI/Sources/TranslateScreen.swift @@ -720,7 +720,9 @@ public class TranslateScreen: ViewController { statusBarHeight: 0.0, navigationHeight: navigationHeight, safeInsets: UIEdgeInsets(top: layout.intrinsicInsets.top + layout.safeInsets.top, left: layout.safeInsets.left, bottom: layout.intrinsicInsets.bottom + layout.safeInsets.bottom, right: layout.safeInsets.right), + inputHeight: layout.inputHeight ?? 0.0, metrics: layout.metrics, + deviceMetrics: layout.deviceMetrics, isVisible: self.currentIsVisible, theme: self.theme ?? self.presentationData.theme, strings: self.presentationData.strings, diff --git a/submodules/WallpaperBackgroundNode/Sources/WallpaperBackgroundNode.swift b/submodules/WallpaperBackgroundNode/Sources/WallpaperBackgroundNode.swift index 5f4b0af304..ed7626e528 100644 --- a/submodules/WallpaperBackgroundNode/Sources/WallpaperBackgroundNode.swift +++ b/submodules/WallpaperBackgroundNode/Sources/WallpaperBackgroundNode.swift @@ -41,7 +41,9 @@ public enum WallpaperBubbleType { public protocol WallpaperBubbleBackgroundNode: ASDisplayNode { var frame: CGRect { get set } - + + var implicitContentUpdate: Bool { get set } + func update(rect: CGRect, within containerSize: CGSize, transition: ContainedViewLayoutTransition) func update(rect: CGRect, within containerSize: CGSize, transition: CombinedTransition) func update(rect: CGRect, within containerSize: CGSize, animator: ControlledTransitionAnimator) @@ -292,6 +294,8 @@ private final class EffectImageLayer: SimpleLayer, GradientBackgroundPatternOver final class WallpaperBackgroundNodeImpl: ASDisplayNode, WallpaperBackgroundNode { final class BubbleBackgroundNodeImpl: ASDisplayNode, WallpaperBubbleBackgroundNode { + var implicitContentUpdate: Bool = true + private let bubbleType: WallpaperBubbleType private let contentNode: ASImageNode @@ -305,12 +309,14 @@ final class WallpaperBackgroundNodeImpl: ASDisplayNode, WallpaperBackgroundNode override var frame: CGRect { didSet { if oldValue.size != self.bounds.size { - self.contentNode.frame = self.bounds - if let cleanWallpaperNode = self.cleanWallpaperNode { - cleanWallpaperNode.frame = self.bounds - } - if let gradientWallpaperNode = self.gradientWallpaperNode { - gradientWallpaperNode.frame = self.bounds + if self.implicitContentUpdate { + self.contentNode.frame = self.bounds + if let cleanWallpaperNode = self.cleanWallpaperNode { + cleanWallpaperNode.frame = self.bounds + } + if let gradientWallpaperNode = self.gradientWallpaperNode { + gradientWallpaperNode.frame = self.bounds + } } } } @@ -1204,6 +1210,8 @@ final class WallpaperBackgroundNodeMergedImpl: ASDisplayNode, WallpaperBackgroun } final class BubbleBackgroundNodeImpl: ASDisplayNode, WallpaperBubbleBackgroundNode { + var implicitContentUpdate = true + private let bubbleType: WallpaperBubbleType private let contentNode: ASImageNode