From 91d94884e8eff21ec7fc2039e264d338b6f00bd3 Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Wed, 23 Mar 2022 00:54:05 +0400 Subject: [PATCH] Various Improvements --- .../Resources/ChangePhoneNumber.tgs | Bin 0 -> 12761 bytes .../Telegram-iOS/en.lproj/Localizable.strings | 7 + .../Sources/AccountContext.swift | 62 +++- submodules/AttachmentUI/BUILD | 2 + .../Sources/AttachmentPanel.swift | 2 +- .../Sources/MoreButtonNode.swift} | 20 +- .../Sources/MediaPickerScreen.swift | 4 +- .../Sources/ChannelAdminController.swift | 42 ++- .../Sources/ChangePhoneNumberController.swift | 10 +- .../Sources/LogoutOptionsController.swift | 5 +- .../PrivacyIntroController.swift | 38 ++- .../Search/SettingsSearchableItems.swift | 4 +- ...SyncCore_ReplyMarkupMessageAttribute.swift | 5 - .../PresentationThemeEssentialGraphics.swift | 4 + .../BotLogo.imageset}/Contents.json | 2 +- .../Bot Payments/BotLogo.imageset/Tmp.png | Bin 0 -> 4854 bytes .../Bot Payments/Contents.json | 6 +- .../Chat List/Tabs/Contents.json | 6 +- .../Chat List/Tabs/Holiday/Contents.json | 9 - .../Holiday/IconCalls.imageset/Calls@2x.png | Bin 1887 -> 0 bytes .../Holiday/IconCalls.imageset/Calls@3x.png | Bin 2875 -> 0 bytes .../Holiday/IconCalls.imageset/Contents.json | 22 -- .../Holiday/IconChats.imageset/Contents.json | 22 -- .../IconChats.imageset/Messages@2x.png | Bin 2661 -> 0 bytes .../IconChats.imageset/Messages@3x.png | Bin 4107 -> 0 bytes .../IconContacts.imageset/Contacts@2x.png | Bin 2073 -> 0 bytes .../IconContacts.imageset/Contacts@3x.png | Bin 3350 -> 0 bytes .../IconContacts.imageset/Contents.json | 22 -- .../IconSettings.imageset/Contents.json | 22 -- .../IconSettings.imageset/Settings@2x.png | Bin 2231 -> 0 bytes .../IconSettings.imageset/Settings@3x.png | Bin 3452 -> 0 bytes .../UndoInfoIcon.imageset/Contents.json | 22 -- .../UndoInfoIcon.imageset/tip@2x.png | Bin 878 -> 0 bytes .../UndoInfoIcon.imageset/tip@3x.png | Bin 1523 -> 0 bytes .../Message/BotWebApp.imageset/Contents.json | 12 + .../BotWebApp.imageset/Size=10px-2.pdf | 85 +++++ .../Snowflake.imageset/Snowflake.png | Bin 5794 -> 0 bytes .../Sources/ChatButtonKeyboardInputNode.swift | 2 - .../TelegramUI/Sources/ChatController.swift | 23 +- .../Sources/ChatControllerInteraction.swift | 4 - .../ChatMessageActionButtonsNode.swift | 12 +- .../Sources/ChatMessageItemView.swift | 2 - .../ChatRecentActionsControllerNode.swift | 1 - .../Sources/DrawingStickersScreen.swift | 1 - .../TelegramUI/Sources/OpenResolvedUrl.swift | 6 +- submodules/TelegramUI/Sources/OpenUrl.swift | 6 + .../OverlayAudioPlayerControllerNode.swift | 1 - .../Sources/PeerInfo/PeerInfoScreen.swift | 10 +- .../Sources/SharedAccountContext.swift | 1 - .../UrlHandling/Sources/UrlHandling.swift | 59 +++- .../UrlWhitelist/Sources/UrlWhitelist.swift | 2 +- submodules/WebUI/BUILD | 6 + .../Sources/WebAppAlertContentNode.swift | 225 ++++++++++++++ .../WebUI/Sources/WebAppController.swift | 293 ++++++++++++++++++ submodules/WebUI/Sources/WebController.swift | 35 --- .../WebUI/Sources/WebControllerNode.swift | 35 --- 56 files changed, 856 insertions(+), 303 deletions(-) create mode 100644 Telegram/Telegram-iOS/Resources/ChangePhoneNumber.tgs rename submodules/{MediaPickerUI/Sources/MediaPickerMoreButton.swift => AttachmentUI/Sources/MoreButtonNode.swift} (90%) rename submodules/TelegramUI/Images.xcassets/{Components/Snowflake.imageset => Bot Payments/BotLogo.imageset}/Contents.json (88%) create mode 100644 submodules/TelegramUI/Images.xcassets/Bot Payments/BotLogo.imageset/Tmp.png delete mode 100644 submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/Contents.json delete mode 100644 submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconCalls.imageset/Calls@2x.png delete mode 100644 submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconCalls.imageset/Calls@3x.png delete mode 100644 submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconCalls.imageset/Contents.json delete mode 100644 submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconChats.imageset/Contents.json delete mode 100644 submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconChats.imageset/Messages@2x.png delete mode 100644 submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconChats.imageset/Messages@3x.png delete mode 100644 submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconContacts.imageset/Contacts@2x.png delete mode 100644 submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconContacts.imageset/Contacts@3x.png delete mode 100644 submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconContacts.imageset/Contents.json delete mode 100644 submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconSettings.imageset/Contents.json delete mode 100644 submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconSettings.imageset/Settings@2x.png delete mode 100644 submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconSettings.imageset/Settings@3x.png delete mode 100644 submodules/TelegramUI/Images.xcassets/Chat List/UndoInfoIcon.imageset/Contents.json delete mode 100644 submodules/TelegramUI/Images.xcassets/Chat List/UndoInfoIcon.imageset/tip@2x.png delete mode 100644 submodules/TelegramUI/Images.xcassets/Chat List/UndoInfoIcon.imageset/tip@3x.png create mode 100644 submodules/TelegramUI/Images.xcassets/Chat/Message/BotWebApp.imageset/Contents.json create mode 100644 submodules/TelegramUI/Images.xcassets/Chat/Message/BotWebApp.imageset/Size=10px-2.pdf delete mode 100644 submodules/TelegramUI/Images.xcassets/Components/Snowflake.imageset/Snowflake.png create mode 100644 submodules/WebUI/Sources/WebAppAlertContentNode.swift create mode 100644 submodules/WebUI/Sources/WebAppController.swift delete mode 100644 submodules/WebUI/Sources/WebController.swift delete mode 100644 submodules/WebUI/Sources/WebControllerNode.swift diff --git a/Telegram/Telegram-iOS/Resources/ChangePhoneNumber.tgs b/Telegram/Telegram-iOS/Resources/ChangePhoneNumber.tgs new file mode 100644 index 0000000000000000000000000000000000000000..fc113e1da591cd95237e68870d6fd10d33e62c72 GIT binary patch literal 12761 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 Void)? + public var action: ((ASDisplayNode, ContextGesture?) -> Void)? private let containerNode: ContextControllerSourceNode - let contextSourceNode: ContextReferenceContentNode + public let contextSourceNode: ContextReferenceContentNode private let buttonNode: HighlightableButtonNode - let iconNode: MoreIconNode + public let iconNode: MoreIconNode - var theme: PresentationTheme { + public var theme: PresentationTheme { didSet { self.iconNode.customColor = self.theme.rootController.navigationBar.buttonColor } } - init(theme: PresentationTheme) { + public init(theme: PresentationTheme) { self.theme = theme self.contextSourceNode = ContextReferenceContentNode() diff --git a/submodules/MediaPickerUI/Sources/MediaPickerScreen.swift b/submodules/MediaPickerUI/Sources/MediaPickerScreen.swift index 850a623d0c..eca2079bda 100644 --- a/submodules/MediaPickerUI/Sources/MediaPickerScreen.swift +++ b/submodules/MediaPickerUI/Sources/MediaPickerScreen.swift @@ -115,7 +115,7 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable { private let collection: PHAssetCollection? private let titleView: MediaPickerTitleView - private let moreButtonNode: MediaPickerMoreButtonNode + private let moreButtonNode: MoreButtonNode public weak var webSearchController: WebSearchController? @@ -1078,7 +1078,7 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable { self.titleView = MediaPickerTitleView(theme: self.presentationData.theme, segments: [self.presentationData.strings.Attachment_AllMedia, self.presentationData.strings.Attachment_SelectedMedia(1)], selectedIndex: 0) self.titleView.title = collection?.localizedTitle ?? presentationData.strings.Attachment_Gallery - self.moreButtonNode = MediaPickerMoreButtonNode(theme: self.presentationData.theme) + self.moreButtonNode = MoreButtonNode(theme: self.presentationData.theme) super.init(navigationBarPresentationData: NavigationBarPresentationData(presentationData: presentationData)) diff --git a/submodules/PeerInfoUI/Sources/ChannelAdminController.swift b/submodules/PeerInfoUI/Sources/ChannelAdminController.swift index a9a07c0095..c8ef27cb87 100644 --- a/submodules/PeerInfoUI/Sources/ChannelAdminController.swift +++ b/submodules/PeerInfoUI/Sources/ChannelAdminController.swift @@ -585,12 +585,6 @@ private func channelAdminControllerEntries(presentationData: PresentationData, s ] } - if invite { - maskRightsFlags.remove(.canManageCalls) - maskRightsFlags.remove(.canBeAnonymous) - maskRightsFlags.remove(.canAddAdmins) - } - if isCreator { if isGroup { entries.append(.rightsTitle(presentationData.theme, presentationData.strings.Channel_EditAdmin_PermissionsHeader)) @@ -747,24 +741,18 @@ private func channelAdminControllerEntries(presentationData: PresentationData, s let isGroup = true let isChannel = false - var maskRightsFlags: TelegramChatAdminRightsFlags = .groupSpecific + let maskRightsFlags: TelegramChatAdminRightsFlags = .groupSpecific let rightsOrder: [TelegramChatAdminRightsFlags] = [ - .canChangeInfo, - .canDeleteMessages, - .canBanUsers, - .canInviteUsers, - .canPinMessages, - .canManageCalls, - .canBeAnonymous, - .canAddAdmins - ] - - if invite { - maskRightsFlags.remove(.canManageCalls) - maskRightsFlags.remove(.canBeAnonymous) - maskRightsFlags.remove(.canAddAdmins) - } - + .canChangeInfo, + .canDeleteMessages, + .canBanUsers, + .canInviteUsers, + .canPinMessages, + .canManageCalls, + .canBeAnonymous, + .canAddAdmins + ] + let accountUserRightsFlags: TelegramChatAdminRightsFlags = maskRightsFlags let currentRightsFlags: TelegramChatAdminRightsFlags @@ -812,13 +800,19 @@ private func channelAdminControllerEntries(presentationData: PresentationData, s return entries } -public func channelAdminController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal)? = nil, peerId: PeerId, adminId: PeerId, initialParticipant: ChannelParticipant?, invite: Bool = false, updated: @escaping (TelegramChatAdminRights?) -> Void, upgradedToSupergroup: @escaping (PeerId, @escaping () -> Void) -> Void, transferedOwnership: @escaping (PeerId) -> Void) -> ViewController { +public func channelAdminController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal)? = nil, peerId: PeerId, adminId: PeerId, initialParticipant: ChannelParticipant?, invite: Bool = false, initialAdminRights: TelegramChatAdminRightsFlags? = nil, updated: @escaping (TelegramChatAdminRights?) -> Void, upgradedToSupergroup: @escaping (PeerId, @escaping () -> Void) -> Void, transferedOwnership: @escaping (PeerId) -> Void) -> ViewController { let statePromise = ValuePromise(ChannelAdminControllerState(), ignoreRepeated: true) let stateValue = Atomic(value: ChannelAdminControllerState()) let updateState: ((ChannelAdminControllerState) -> ChannelAdminControllerState) -> Void = { f in statePromise.set(stateValue.modify { f($0) }) } + if let initialAdminRights = initialAdminRights { + updateState { + return $0.withUpdatedUpdatedFlags(initialAdminRights) + } + } + let actionsDisposable = DisposableSet() let updateRightsDisposable = MetaDisposable() diff --git a/submodules/SettingsUI/Sources/ChangePhoneNumberController.swift b/submodules/SettingsUI/Sources/ChangePhoneNumberController.swift index 8acb504124..1c20235e74 100644 --- a/submodules/SettingsUI/Sources/ChangePhoneNumberController.swift +++ b/submodules/SettingsUI/Sources/ChangePhoneNumberController.swift @@ -14,7 +14,7 @@ import PhoneNumberFormat import CoreTelephony import MessageUI -final class ChangePhoneNumberController: ViewController, MFMailComposeViewControllerDelegate { +public final class ChangePhoneNumberController: ViewController, MFMailComposeViewControllerDelegate { private var controllerNode: ChangePhoneNumberControllerNode { return self.displayNode as! ChangePhoneNumberControllerNode } @@ -41,7 +41,7 @@ final class ChangePhoneNumberController: ViewController, MFMailComposeViewContro private var presentationData: PresentationData - init(context: AccountContext) { + public init(context: AccountContext) { self.context = context self.presentationData = context.sharedContext.currentPresentationData.with { $0 } @@ -98,19 +98,19 @@ final class ChangePhoneNumberController: ViewController, MFMailComposeViewContro self.navigationBar?.updateBackgroundAlpha(0.0, transition: .immediate) } - override func viewWillAppear(_ animated: Bool) { + override public func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) self.controllerNode.activateInput() } - override func viewDidAppear(_ animated: Bool) { + override public func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) self.controllerNode.activateInput() } - override func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) { + override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) { super.containerLayoutUpdated(layout, transition: transition) self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: 0.0, transition: transition) diff --git a/submodules/SettingsUI/Sources/LogoutOptionsController.swift b/submodules/SettingsUI/Sources/LogoutOptionsController.swift index 13c9e68b1e..54f275b104 100644 --- a/submodules/SettingsUI/Sources/LogoutOptionsController.swift +++ b/submodules/SettingsUI/Sources/LogoutOptionsController.swift @@ -152,7 +152,10 @@ public func logoutOptionsController(context: AccountContext, navigationControlle pushControllerImpl?(storageUsageController(context: context)) dismissImpl?() }, changePhoneNumber: { - pushControllerImpl?(ChangePhoneNumberIntroController(context: context, phoneNumber: phoneNumber)) + let introController = PrivacyIntroController(context: context, mode: .changePhoneNumber(phoneNumber), proceedAction: { + replaceTopControllerImpl?(ChangePhoneNumberController(context: context)) + }) + pushControllerImpl?(introController) dismissImpl?() }, contactSupport: { [weak navigationController] in let supportPeer = Promise() diff --git a/submodules/SettingsUI/Sources/Privacy and Security/PrivacyIntroController.swift b/submodules/SettingsUI/Sources/Privacy and Security/PrivacyIntroController.swift index 0449e6daa1..4fafef3f8e 100644 --- a/submodules/SettingsUI/Sources/Privacy and Security/PrivacyIntroController.swift +++ b/submodules/SettingsUI/Sources/Privacy and Security/PrivacyIntroController.swift @@ -8,15 +8,19 @@ import TelegramCore import TelegramPresentationData import AccountContext import AppBundle +import PhoneNumberFormat -enum PrivacyIntroControllerMode { +public enum PrivacyIntroControllerMode { case passcode case twoStepVerification + case changePhoneNumber(String) var animationName: String? { switch self { case .passcode: return "Passcode" + case .changePhoneNumber: + return "ChangePhoneNumber" case .twoStepVerification: return nil } @@ -24,10 +28,8 @@ enum PrivacyIntroControllerMode { func icon(theme: PresentationTheme) -> UIImage? { switch self { - case .passcode: + case .passcode, .changePhoneNumber, .twoStepVerification: return generateTintedImage(image: UIImage(bundleImageName: "Settings/PasscodeIntroIcon"), color: theme.list.freeTextColor) - case .twoStepVerification: - return generateTintedImage(image: UIImage(bundleImageName: "Settings/PasswordIntroIcon"), color: theme.list.freeTextColor) } } @@ -37,6 +39,8 @@ enum PrivacyIntroControllerMode { return strings.PasscodeSettings_Title case .twoStepVerification: return strings.PrivacySettings_TwoStepAuth + case .changePhoneNumber: + return strings.ChangePhoneNumberNumber_Title } } @@ -46,6 +50,8 @@ enum PrivacyIntroControllerMode { return strings.PasscodeSettings_Title case .twoStepVerification: return strings.TwoStepAuth_AdditionalPassword + case let .changePhoneNumber(phoneNumber): + return formatPhoneNumber(phoneNumber) } } @@ -55,15 +61,19 @@ enum PrivacyIntroControllerMode { return strings.PasscodeSettings_HelpTop case .twoStepVerification: return strings.TwoStepAuth_SetPasswordHelp + case .changePhoneNumber: + return strings.PhoneNumberHelp_Help } } func buttonTitle(strings: PresentationStrings) -> String { switch self { - case .passcode: - return strings.PasscodeSettings_TurnPasscodeOn - case .twoStepVerification: - return strings.TwoStepAuth_SetPassword + case .passcode: + return strings.PasscodeSettings_TurnPasscodeOn + case .twoStepVerification: + return strings.TwoStepAuth_SetPassword + case .changePhoneNumber: + return strings.PhoneNumberHelp_ChangeNumber } } @@ -71,7 +81,7 @@ enum PrivacyIntroControllerMode { switch self { case .passcode: return strings.PasscodeSettings_HelpBottom - case .twoStepVerification: + case .twoStepVerification, .changePhoneNumber: return "" } } @@ -87,7 +97,7 @@ public final class PrivacyIntroControllerPresentationArguments { } } -final class PrivacyIntroController: ViewController { +public final class PrivacyIntroController: ViewController { private let context: AccountContext private let mode: PrivacyIntroControllerMode private let arguments: PrivacyIntroControllerPresentationArguments @@ -102,7 +112,7 @@ final class PrivacyIntroController: ViewController { private var isDismissed: Bool = false - init(context: AccountContext, mode: PrivacyIntroControllerMode, arguments: PrivacyIntroControllerPresentationArguments = PrivacyIntroControllerPresentationArguments(), proceedAction: @escaping () -> Void) { + public init(context: AccountContext, mode: PrivacyIntroControllerMode, arguments: PrivacyIntroControllerPresentationArguments = PrivacyIntroControllerPresentationArguments(), proceedAction: @escaping () -> Void) { self.context = context self.mode = mode self.arguments = arguments @@ -116,6 +126,8 @@ final class PrivacyIntroController: ViewController { self.title = self.mode.controllerTitle(strings: self.presentationData.strings) + self.navigationItem.backBarButtonItem = UIBarButtonItem(title: self.presentationData.strings.Common_Back, style: .plain, target: nil, action: nil) + if arguments.animateIn { self.navigationItem.setLeftBarButton(UIBarButtonItem(title: self.presentationData.strings.Common_Cancel, style: .plain, target: self, action: #selector(self.cancelPressed)), animated: false) } @@ -161,7 +173,7 @@ final class PrivacyIntroController: ViewController { self.navigationBar?.updateBackgroundAlpha(0.0, transition: .immediate) } - override func viewDidAppear(_ animated: Bool) { + override public func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) if self.arguments.animateIn { self.controllerNode.animateIn(slide: true) @@ -170,7 +182,7 @@ final class PrivacyIntroController: ViewController { } } - override func dismiss(completion: (() -> Void)? = nil) { + override public func dismiss(completion: (() -> Void)? = nil) { if !self.isDismissed { self.isDismissed = true if self.arguments.animateIn { diff --git a/submodules/SettingsUI/Sources/Search/SettingsSearchableItems.swift b/submodules/SettingsUI/Sources/Search/SettingsSearchableItems.swift index 1027d7354d..f401eca9f2 100644 --- a/submodules/SettingsUI/Sources/Search/SettingsSearchableItems.swift +++ b/submodules/SettingsUI/Sources/Search/SettingsSearchableItems.swift @@ -193,7 +193,9 @@ private func profileSearchableItems(context: AccountContext, canAddAccount: Bool return (transaction.getPeer(context.account.peerId) as? TelegramUser)?.phone ?? "" } |> deliverOnMainQueue).start(next: { phoneNumber in - present(.push, ChangePhoneNumberIntroController(context: context, phoneNumber: formatPhoneNumber(phoneNumber))) + present(.push, PrivacyIntroController(context: context, mode: .changePhoneNumber(phoneNumber), proceedAction: { + present(.push, ChangePhoneNumberController(context: context)) + })) }) })) items.append(SettingsSearchableItem(id: .profile(3), title: strings.Settings_Username, alternate: synonyms(strings.SettingsSearch_Synonyms_EditProfile_Username), icon: icon, breadcrumbs: [strings.EditProfile_Title], present: { context, _, present in diff --git a/submodules/TelegramCore/Sources/SyncCore/SyncCore_ReplyMarkupMessageAttribute.swift b/submodules/TelegramCore/Sources/SyncCore/SyncCore_ReplyMarkupMessageAttribute.swift index 7e558a81cf..815f8139cc 100644 --- a/submodules/TelegramCore/Sources/SyncCore/SyncCore_ReplyMarkupMessageAttribute.swift +++ b/submodules/TelegramCore/Sources/SyncCore/SyncCore_ReplyMarkupMessageAttribute.swift @@ -12,7 +12,6 @@ public enum ReplyMarkupButtonAction: PostboxCoding, Equatable { case urlAuth(url: String, buttonId: Int32) case setupPoll(isQuiz: Bool?) case openUserProfile(peerId: PeerId) - case addToChat public init(decoder: PostboxDecoder) { switch decoder.decodeInt32ForKey("v", orElse: 0) { @@ -38,8 +37,6 @@ public enum ReplyMarkupButtonAction: PostboxCoding, Equatable { self = .setupPoll(isQuiz: decoder.decodeOptionalInt32ForKey("isq").flatMap { $0 != 0 }) case 10: self = .openUserProfile(peerId: PeerId(decoder.decodeInt64ForKey("peerId", orElse: 0))) - case 11: - self = .addToChat default: self = .text } @@ -82,8 +79,6 @@ public enum ReplyMarkupButtonAction: PostboxCoding, Equatable { case let .openUserProfile(peerId): encoder.encodeInt32(10, forKey: "v") encoder.encodeInt64(peerId.toInt64(), forKey: "peerId") - case .addToChat: - encoder.encodeInt32(11, forKey: "v") } } } diff --git a/submodules/TelegramPresentationData/Sources/PresentationThemeEssentialGraphics.swift b/submodules/TelegramPresentationData/Sources/PresentationThemeEssentialGraphics.swift index 651e2f8c55..e101ca8a67 100644 --- a/submodules/TelegramPresentationData/Sources/PresentationThemeEssentialGraphics.swift +++ b/submodules/TelegramPresentationData/Sources/PresentationThemeEssentialGraphics.swift @@ -541,6 +541,7 @@ public final class PrincipalThemeAdditionalGraphics { public let chatBubbleActionButtonIncomingPaymentIconImage: UIImage public let chatBubbleActionButtonIncomingProfileIconImage: UIImage public let chatBubbleActionButtonIncomingAddToChatIconImage: UIImage + public let chatBubbleActionButtonIncomingWebAppIconImage: UIImage public let chatBubbleActionButtonOutgoingMessageIconImage: UIImage public let chatBubbleActionButtonOutgoingLinkIconImage: UIImage @@ -550,6 +551,7 @@ public final class PrincipalThemeAdditionalGraphics { public let chatBubbleActionButtonOutgoingPaymentIconImage: UIImage public let chatBubbleActionButtonOutgoingProfileIconImage: UIImage public let chatBubbleActionButtonOutgoingAddToChatIconImage: UIImage + public let chatBubbleActionButtonOutgoingWebAppIconImage: UIImage public let chatEmptyItemLockIcon: UIImage public let emptyChatListCheckIcon: UIImage @@ -594,6 +596,7 @@ public final class PrincipalThemeAdditionalGraphics { self.chatBubbleActionButtonIncomingPaymentIconImage = generateTintedImage(image: UIImage(bundleImageName: "Chat/Message/BotPayment"), color: bubbleVariableColor(variableColor: theme.message.incoming.actionButtonsTextColor, wallpaper: wallpaper))! self.chatBubbleActionButtonIncomingProfileIconImage = generateTintedImage(image: UIImage(bundleImageName: "Chat/Message/BotProfile"), color: bubbleVariableColor(variableColor: theme.message.incoming.actionButtonsTextColor, wallpaper: wallpaper))! self.chatBubbleActionButtonIncomingAddToChatIconImage = generateTintedImage(image: UIImage(bundleImageName: "Chat/Message/BotAddToChat"), color: bubbleVariableColor(variableColor: theme.message.incoming.actionButtonsTextColor, wallpaper: wallpaper))! + self.chatBubbleActionButtonIncomingWebAppIconImage = generateTintedImage(image: UIImage(bundleImageName: "Chat/Message/BotWebApp"), color: bubbleVariableColor(variableColor: theme.message.incoming.actionButtonsTextColor, wallpaper: wallpaper))! self.chatBubbleActionButtonOutgoingMessageIconImage = generateTintedImage(image: UIImage(bundleImageName: "Chat/Message/BotMessage"), color: bubbleVariableColor(variableColor: theme.message.outgoing.actionButtonsTextColor, wallpaper: wallpaper))! self.chatBubbleActionButtonOutgoingLinkIconImage = generateTintedImage(image: UIImage(bundleImageName: "Chat/Message/BotLink"), color: bubbleVariableColor(variableColor: theme.message.outgoing.actionButtonsTextColor, wallpaper: wallpaper))! self.chatBubbleActionButtonOutgoingShareIconImage = generateTintedImage(image: UIImage(bundleImageName: "Chat/Message/BotShare"), color: bubbleVariableColor(variableColor: theme.message.outgoing.actionButtonsTextColor, wallpaper: wallpaper))! @@ -602,6 +605,7 @@ public final class PrincipalThemeAdditionalGraphics { self.chatBubbleActionButtonOutgoingPaymentIconImage = generateTintedImage(image: UIImage(bundleImageName: "Chat/Message/BotPayment"), color: bubbleVariableColor(variableColor: theme.message.outgoing.actionButtonsTextColor, wallpaper: wallpaper))! self.chatBubbleActionButtonOutgoingProfileIconImage = generateTintedImage(image: UIImage(bundleImageName: "Chat/Message/BotProfile"), color: bubbleVariableColor(variableColor: theme.message.outgoing.actionButtonsTextColor, wallpaper: wallpaper))! self.chatBubbleActionButtonOutgoingAddToChatIconImage = generateTintedImage(image: UIImage(bundleImageName: "Chat/Message/BotAddToChat"), color: bubbleVariableColor(variableColor: theme.message.outgoing.actionButtonsTextColor, wallpaper: wallpaper))! + self.chatBubbleActionButtonOutgoingWebAppIconImage = generateTintedImage(image: UIImage(bundleImageName: "Chat/Message/BotWebApp"), color: bubbleVariableColor(variableColor: theme.message.outgoing.actionButtonsTextColor, wallpaper: wallpaper))! self.chatEmptyItemLockIcon = generateImage(CGSize(width: 9.0, height: 13.0), rotatedContext: { size, context in context.clear(CGRect(origin: CGPoint(), size: size)) diff --git a/submodules/TelegramUI/Images.xcassets/Components/Snowflake.imageset/Contents.json b/submodules/TelegramUI/Images.xcassets/Bot Payments/BotLogo.imageset/Contents.json similarity index 88% rename from submodules/TelegramUI/Images.xcassets/Components/Snowflake.imageset/Contents.json rename to submodules/TelegramUI/Images.xcassets/Bot Payments/BotLogo.imageset/Contents.json index 204c66f291..96acb63cc3 100644 --- a/submodules/TelegramUI/Images.xcassets/Components/Snowflake.imageset/Contents.json +++ b/submodules/TelegramUI/Images.xcassets/Bot Payments/BotLogo.imageset/Contents.json @@ -9,7 +9,7 @@ "scale" : "2x" }, { - "filename" : "Snowflake.png", + "filename" : "Tmp.png", "idiom" : "universal", "scale" : "3x" } diff --git a/submodules/TelegramUI/Images.xcassets/Bot Payments/BotLogo.imageset/Tmp.png b/submodules/TelegramUI/Images.xcassets/Bot Payments/BotLogo.imageset/Tmp.png new file mode 100644 index 0000000000000000000000000000000000000000..a74a40092b09c3d65f3e70e5cd31b0fd4d5c4e01 GIT binary patch literal 4854 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 literal 0 HcmV?d00001 diff --git a/submodules/TelegramUI/Images.xcassets/Bot Payments/Contents.json b/submodules/TelegramUI/Images.xcassets/Bot Payments/Contents.json index 38f0c81fc2..6e965652df 100644 --- a/submodules/TelegramUI/Images.xcassets/Bot Payments/Contents.json +++ b/submodules/TelegramUI/Images.xcassets/Bot Payments/Contents.json @@ -1,9 +1,9 @@ { "info" : { - "version" : 1, - "author" : "xcode" + "author" : "xcode", + "version" : 1 }, "properties" : { "provides-namespace" : true } -} \ No newline at end of file +} diff --git a/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Contents.json b/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Contents.json index 38f0c81fc2..6e965652df 100644 --- a/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Contents.json +++ b/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Contents.json @@ -1,9 +1,9 @@ { "info" : { - "version" : 1, - "author" : "xcode" + "author" : "xcode", + "version" : 1 }, "properties" : { "provides-namespace" : true } -} \ No newline at end of file +} diff --git a/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/Contents.json b/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/Contents.json deleted file mode 100644 index 38f0c81fc2..0000000000 --- a/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/Contents.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "info" : { - "version" : 1, - "author" : "xcode" - }, - "properties" : { - "provides-namespace" : true - } -} \ No newline at end of file diff --git a/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconCalls.imageset/Calls@2x.png b/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconCalls.imageset/Calls@2x.png deleted file mode 100644 index 3d12d7e27b695169eec983a3ab5104d07bfcc012..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1887 zcmV-l2cYPx+8A(JzRCodHnr~>8RT#i`x4FAURNFokD^!w(76?hA5P_7i5yc>s{Z-8Tun7E8 z_Cak;Kjfz($q(kB_LoEu3O2A1B5^2+h?y2OqDJ*)t%j^^?%wr#Ztodq@4tJ_d*8b| z>ArCGob&vDp7WeP?|WBLQhbUTC}yCTfno;!zZpp6EA-*v;pD``M13NW*no{E)9LgR zz-q=10v}jdSja%f{uKDX=}&KO_B?}a5HnX!N;|x{taZ5|f*V&kbo;3me{r&6Nz)r!t#YEu>;u&Ql z-P_jICe;!6gs$1%-rl#E@oPxmYr#vvTf}#XAuxIfffc~acQW%Ig$ds)G%DeBD&d5m zzrG0|`0ZqGn3mHq#(G4>!Wf3H(7#ImHqOZLHA#Q6uC8uUoEje=m-|6A-D;9vL%$yS z(~LLKUrXQDPmwiw(2=4wl7w?^{&F`$#uz+CiyS=0J}1x{mxjL zdcIJdvuDpfG(A1NnZ$JB(@P3(1D#loA>&DaC$oKheJ>#3VYD#V-Otg87!QfS1t|o8JPo+W^R3S*5fMhskap=79LUMEGy1=!Ga2loA9^CST2n}Hg_ z3D;Qv`c9tV#^HzEV!7ZP8*({|@_1tNB!DdSMA6K#C)edA&%nUI+9e2Wz+IzG4fVdl zDd?xe&z9m3gMP7j642V(dJ4w#VTycc7iwy1Jc;A%-sZ!bK~V)KC2(od590IF;n=zm zB;$vdm?Sng&65BaWru0ANWv%|C|-7dv0>)c5!icfgK7+|f#80XCVho>L(w6+biCLS zo8U%ud{EzsMPl;oo}P=4Qi9JB0LOd16ZdpT}0u&(9AK_|{lF3s6ELE|!;+&G&mWa0{U8U!@M2qh5MRRh!f25yfX_?^ak>i!B5!mOI5Rgc&dFUs zj>9lV!)W-D!j~>y!;gmX`O!QtLw-yOC%Zg9e#oU|4+a&w;Lw?fBTUR1?g#s9P6?|7 z%+1ZcDZ$4PF;2@(aG&UsejGZ{v4>;$2cUfYF?x)bfE;so@7}$Q)})bUm?+I}DD~Z| zR;`+*ay|gH(@^#^W^zCFs#qGIkf3J`<%De(d-bNrr12)m(X$)n#=(mxJa2Fd8>1xu zAQ3X#=?pgfPg;0IMr1`tIJ<|MbbR#?{1CusD$%eZhnfq7*A38k70QuFX z%*F{oVU4L$#fKxZcE<=rp%gsKi;ccf9pfw)ntFTOiA-j{K!=jCfwiX0HcP-%rwN~$ zd7ak}r_=M&FH{2Z5=<1Og-U>|dH3UobMwSLw%G%$jmtfNHM|Qr1AHF^>K@STta(-T znN3hLkhurQCW!2(&R(LCk-J{kot4jNa0ibg6S=vQOKvz(BijeZ4QPM?aliWw+opqPPT28tOdX5ik) Zz`yZdD#Qg+uzUKSMN{52vEsXC7^;?< z)-pNLqBznxTXveep?W&EaiY4Nx4N1~RNgo}`SXk5ITDm5&2OLx{@~$)?#+TFh#JLzwNnmc z?u-gfFnB%p$*9|`NU$D|@E2odVL87!sS?_G%Ky?qJDfheIP>r+6gs$MpTaX!E!F4r%bL z=t*jQ&9HS;PJhKcZ-W$0JD9?zF`mrCg}Ah|Bu~$!Q<*Mt1n#0#qyHECA_sYZpLuw3)m|Y z#e=qSZEQ`YD3q`t-bC(g;C1c+$j#pN@%U}%v0-4YTA*5!P>HG7Vs-zYXnk}urOi_n z=?k2Vg)8Eu1oyS>`|!niex7IB6eb^&w)D9B3x`#x$Pigbxb3EC0)wr7RjNc}bwr`i zB4WrPGOK2q!W!96G0l_H1ss-oaJMjvXg-8PfRzmm#T0JU&%u8#aD2Q2)-m;K@DSal zn-5liOvGWc?@F%xSVs|&D#SdPN-93V~C1&o<+n(}AU)w-s*$xW+zGo?=g1*6jwE39PiG{vmq zCh8FSH34QH$kI{bPB|0hhm58omLR{+ZFA2=t%SNuqmF7;D}5()KQ`t8e|k!%iicxL zWdREs9hF<=aQGodovHC#s|{&{85RXo8k~@qk=gd0zTHBLH5I7_*_e!Snia+;3U4#+ zx<|Pl>(wQ%bG*92lr}(BoQ595K%-n!<81>~W&YdB{q*Gi=9F%BbF5$YH#1-rU`*6QXd%VnRF=fLx@T10l=Sw>S%TgY3!I!2qK<{+V=nM-kebN4D<)>DQFtgv3WWLIrJnK{l1fnjfY$Td)Xw7X;S5p!t=6J?R*cy*nMm;smwyUW;-y*@-x;vkALQ=IoIjPPwQI?fDS;yZoo zdGE(5clEBt#l^NCWd^t*|2Y7M4m>|hL^n5E3ihwgm!z%LTOGC5tHr+gvQB8@xl+%! zTAYAI>tW7cs14e{NRZWlaFcB6 zw;;)VYQS>;gvH0j7YnWQK_If)2VlllF*vqO*X?qHggR^NXp zp`_spH_7)I7{BozO@NPPWC0Sn_sgr7xddhs*5@|TI$!Y?3z#aEpdMweX{4_M>V=e2 z&%a&>*bDkI$t=W6t0YZptA@1^`wh4VFhQu$`4EUkmnAtVR~fX)H7!UhaZGDCu9M=D zEdLbt@rf;?aN})cd5vmsdt!hN_l_M)<>4^6&@>?{3nD~TC0`Q6ELs9bKWb)0x)yHQ z>Q_^6ZF3YzWK+uguA9WO-ylj)c-zF+^aul0+P%*#^@xVzt@tz1F@MNhw!2f%cSec> zm4lEwhI1_kl107#Sc&~?$fui$lL~(G>qNUnMgZ+g#Hy5gfd1}=ydy9vu%uV=NOIwv zH$fm23+5ufD5PXaCdKZzKR$%F6P0#20Mh4k`M77N!PKD#|9&|5B}_37O7b~zu)7-V z9=w>gO}P9UUH5m>i4t5Kq~D-Z>GEsPTX~uIhc`ilm^PcvoAm#o3cjMewVV=Inqb%c Q_YDKO4`Et08aAQ-0m&MHKmY&$ diff --git a/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconCalls.imageset/Contents.json b/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconCalls.imageset/Contents.json deleted file mode 100644 index 802b6afe81..0000000000 --- a/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconCalls.imageset/Contents.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x" - }, - { - "filename" : "Calls@2x.png", - "idiom" : "universal", - "scale" : "2x" - }, - { - "filename" : "Calls@3x.png", - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconChats.imageset/Contents.json b/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconChats.imageset/Contents.json deleted file mode 100644 index b0d2ce266b..0000000000 --- a/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconChats.imageset/Contents.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x" - }, - { - "filename" : "Messages@2x.png", - "idiom" : "universal", - "scale" : "2x" - }, - { - "filename" : "Messages@3x.png", - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconChats.imageset/Messages@2x.png b/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconChats.imageset/Messages@2x.png deleted file mode 100644 index ffa49c3ae1b516b7dccb3fa84cc3d1ebd26001c9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2661 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 JPDHLkV1gD7-!uRK diff --git a/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconContacts.imageset/Contacts@2x.png b/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconContacts.imageset/Contacts@2x.png deleted file mode 100644 index 115d8526c5045d8b7c76cc0fe88d318236aa06b4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2073 zcmV+!2RP)Px+(@8`@RCodHT5V`nRUF^57uR4IQj5w3$&w;_6-Hv2Sx(TjjACwWIxJZc1Xk9k zz8Lkv?1esMBPsW0PQ$lSN^>}~1f^mn7!?avR?HHj*yi5){VwNR?sIou?!C`>_7FZ7 zF6W&8`~P=d?|Ghrg8Y+5Adf&Efjj~iF9NBlOnuw7ZMUaVsg)BG6AMtzgzu|`|FfX| z3feK0dzzY>zMiVMrUZcY_V!1{$H!kra@R*m3_yHeSXlUCV`Jm4DDs)eWEFtc*49}_ zx)TA;OBmz{fbr;>HEa43>RZ*a1^|*@2=5;PfXl2=7z6;opI|=>5RMwe60@=b0Fy`J zhY(ds;>gk!M*u`kHb8I=0EazdKbdLIr{`Z#AVxy9>*-J!c9dxwiFdkAo-xrTZD$%^ zSl=lCT4F!IP1T+!e5iPdXifp(R%eLfU{O)gHGCm+P$6gIdny(m3bSUCvo(N+ z9Ju;Q=Z=YEU;l-C^kU`M*jRs1*2WLYqCVHvVaeGDz#_FW6lB(#E`1fdiV_Rd0+TKD zcnf;InKG=0Wo`VRyvd~00D5I60yFtr8Xoo`VH@8Ur!T*eVa3@LKpgVJCc}^- zsXO!K5`dyep}P@s=F1rX82*1*avR6cfaHEmH=W)B ze*=!ObFtms2F~epuGczE9=11br_U?+KFQ|G7mQGG1^{~HgvFn?LgFm&ZCP1aHIi71 zcZ+z}l13hFfM#4xA@ZfgS7f&JAcVwHZEbDqVDWLhbI>lwWyO=LSFe7DUclRc)7fU$ zO%IY91b-Dq!G4n*KBiWHzXN{COmgJG<^$3m^xlNddeHs>iz93+Vtm&Irf~!yxvTIV zhT#^xci=6jW0cETipMzgr4V$O&|aJv+i)JZS<+?M+1Ysud6W^dlBF$+i;I7dOz7Ot zI?8gqjJ1WaGY2W7Dz)bT7+}x0qr6w8C~4sTE$gm{#{F_Hip^}Ppi zd?xF`k~uJ!AT3ze0stY-dF4}DTDn6rF#l_0JqP7t=@S6>F-cmW)aGIWU{1h*UxlOd zwY9aslhEDWeF@stK68pI=v{vVpi@*^tBgpQ3z;SWq;j^(NZ8G=MMG$xR2jC>aOi2~{QzIqZSpEUMqiJlqkf~TD@tW9lrsUaRbj{@ z4G#~ml02LVc>9~H$6t)m5q?aHV6?et0T73XBMM{Os{F+V^#W^5p(m}nP0T2u#mv!SVkj=ov zIY9e6K{kB{ZRZRC1QGdnfMCF`>&~XYfddChT?ePL=hBxG0B`_FojZ5#eOGVaP zF6VPkm)vNl2ca%e2F&U zxZawHy^N;-zUOx#kjHQq=e2jN2Ra|{jim%(=byday0i3DR8%aX{=mS%rzrgEEz(R60DlTS|F%gcDlZWL+qZAO_QHh=J#g~*v}w~e z)YsRar9*)58UT1Mg7Y)D)1Tka&~Toz9UUDr@MZS}syEnl0s0~Q7~%nko2hbK&TPaK zT!A>2Ada7H`eA;eDS+$f4jAH9c0GaMdSn zuXtBfNaQ=bHR!R2AUjNXB=s~dGJ-crVKZKvGL#K4U%)TNw}S2gig{mz5w`_Cs{=B! zIw>~E(3MF5P~O8KpoRFrIfYxHRj7M*(PMi60!PfIIIA{g0m7@$dkcwg#t$*xh`^cS z9?biru+Qr`)uW6}B`9erS&3R=p6x>b{0Uq8Ao!D5)avW%>VDD+Ss3t<+PQOQA(Kb1 zUy2_-c>J~f6>lE^d(dJ!jU9E*4l42YeIoz}v>Lm^dytE~w+9`t4iI_9@OmD}zY-yN z>R6{(*iY;!fZ@3njy?$+3bzq(g{!YN*t#=pKipn0fxQpNaa8P zbl0+F%e)0pB@>gz-}glz+9RU!O{bH2F4kl!Ee~##b&lc=BvA-w6_VevL0(k^3P6Yk~8GSLQRI53q00000NkvXXu0mjf DusYCd diff --git a/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconContacts.imageset/Contacts@3x.png b/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconContacts.imageset/Contacts@3x.png deleted file mode 100644 index aaddd096eb73ef94220a1a89d73bbf3cbc5e4ae2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3350 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 diff --git a/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconContacts.imageset/Contents.json b/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconContacts.imageset/Contents.json deleted file mode 100644 index 1cc3b663ca..0000000000 --- a/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconContacts.imageset/Contents.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x" - }, - { - "filename" : "Contacts@2x.png", - "idiom" : "universal", - "scale" : "2x" - }, - { - "filename" : "Contacts@3x.png", - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconSettings.imageset/Contents.json b/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconSettings.imageset/Contents.json deleted file mode 100644 index 2ea1fc8abd..0000000000 --- a/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconSettings.imageset/Contents.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x" - }, - { - "filename" : "Settings@2x.png", - "idiom" : "universal", - "scale" : "2x" - }, - { - "filename" : "Settings@3x.png", - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconSettings.imageset/Settings@2x.png b/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconSettings.imageset/Settings@2x.png deleted file mode 100644 index c00ec0876d1bede15588dd5763b5dfd0314870e5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2231 zcmV;o2uSydP)Px-aY;l$RCodHn|p{=MI6W7m%Aiwk3R}+CDaUr9++EE8EV=eQMgGYuDdHq8B|nc z5*3wg3PF@be-v0`=<1pgw$kGtOQRynwX_G)L#5h`3QBh|*GId3zLz_fv&S=YX3o8v zMfbq$%>3TJ-@JZv&fO6s%1=20CR}KJDND5dC%pKjIROG2eoJyrH3C z&5Ri{j=5;la9g%)sqX3NX@l+ooS&FN{}{7yX$s8{bWi}+tXXpB4uRN1 zS=!RlvX*+#LY4?dPsQ4`Yg?$>DdQ7~jt35)XL?&(+xy3(k|99>VDxt)=7MBVPH1;^ zb@g5I=g`!pV6?XeR+^ri{*)X2FCLjcCQAcE-os){p?4nb8=r zy=HjxBY(Q-N9xn_I0Gv17(hVnZEHvX&Im9dPWoL0Fg?0>HPn<5T?`>;H0MeBH zC-ETx__YWRqib@jLrxSI<#DhiqP%Sl3BWIjs{DXA7&7hlw0}4KNd0>rXFvrW0|=BPk_U5Qg2(mGeI)6o6wRw%HrC5 z`Z#)kbarHe>USBi=0e-Sg_Gqr&)1OAZOwg*E_$O{nyww%#_Saz|OOlCQKsy6m4BA_p- z9e=C=AaXlci@AF>0=C!I)?Utgw<8h&POqk(qj^?TAaozne-a~x?Ufkvm!SKKs9xGX zq5F26+$1#pK2HovVPK}Nedbq8;=^;`t|E4 z5#@`)9j0vK&5!qVH8Qf)yeS%wb9yOS%k11XZ{ECJMoxEkcg?O{yHI>2|18Z~PBoH=v$i$1S>2F+fk+Xlf({h)U)GV2+HEoKllZrph4!Gi~< zU|Tb`wSupW>y+2iAQuz~_I+W*56qH?Ogbzb~ z5WTOUOL_;8-;WI^rReFCFE$$MG028@fL+xm^OFGuIq-aGQ&ucICR;kwoYzc#Nxs;0 z7Yt7#;JDkI1b4ye>+64W;fuj#kBi=IQVASaMl38WKEK6!XohYuCA_l0u@1rHS@CC!?=b}*9_@JI@SP?Ki<%`uoUMwty(V9V}Ie_7_xwSoAOc2CN{{M_*rRlTb z<%4{&;%x}QabODPx-LcITy!oR25cgOYi(+33i{%!X`dhYVw~Sg`g|kT^zAkqD{Ke@ z=M7Lj0eFtmVqno42j8aLDi|~?Dc3~tYJ=ZLwUkTAs26f0WNv^k)sT3cM@el z5`afb?Yzt==_nb$7=2x1-=#mzz>2Kj!}+TSg1!co^eOoakaaS&uCA_y+O{_JarHsY z>}e`$QxZS8N(S%t=MRVT=p3FIAi;Wg8#{)twaYMG-wW%Q8Tyx+7m|KIpjpG6Lccp$ z1kF_F`)R*{^AGdmjNGkJGRsdn0_6ylBT$Y&IRd4Nz~8SPz8(O6!%+YL002ovPDHLk FV1i%gIR*d# diff --git a/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconSettings.imageset/Settings@3x.png b/submodules/TelegramUI/Images.xcassets/Chat List/Tabs/Holiday/IconSettings.imageset/Settings@3x.png deleted file mode 100644 index 27cad3a239863c18e13d5399156cab53152e15e9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3452 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 eK#oAU5%?dUvSAC4p_6L>0000 diff --git a/submodules/TelegramUI/Images.xcassets/Chat List/UndoInfoIcon.imageset/Contents.json b/submodules/TelegramUI/Images.xcassets/Chat List/UndoInfoIcon.imageset/Contents.json deleted file mode 100644 index 95fe8c9b15..0000000000 --- a/submodules/TelegramUI/Images.xcassets/Chat List/UndoInfoIcon.imageset/Contents.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "tip@2x.png", - "scale" : "2x" - }, - { - "idiom" : "universal", - "filename" : "tip@3x.png", - "scale" : "3x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/submodules/TelegramUI/Images.xcassets/Chat List/UndoInfoIcon.imageset/tip@2x.png b/submodules/TelegramUI/Images.xcassets/Chat List/UndoInfoIcon.imageset/tip@2x.png deleted file mode 100644 index 401374b9f5aaa5ae920d0ded7b1627489cceaef2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 878 zcmV-!1CjiRP)ljA7=~k1v9(L5B7p=d?a(1x5Mze2(WUBCsehvtzW}8E z1U9zjA25(^2nM7M2nwP|VP;7eD3!wVx@Y&2IEbX*IrhEMn>*h*-}k-t*`M$1q+y7` zVDJ!gZPX+eRu{>;R);}N%EDl8bCx79>N}+75cAi=s?T|IB&r&v_=<$ zt1LmTkhyp(u;6~o4j zL}6eP_C2HXt}2$ze~C&ab@E3Yjkhq%A(M73yIr~LF}dqwk>f%^h|zd`50x0J2qoqg zqJEABcWbl(F}kC4U{%E^WX0BTv1&WVm>_zdLp{D&-~uBD@Q$PEYO{c1RIHPMVkJ$> zJhMOQ4g34h3W{}d@}<-I31Fo_(2A8BXXnWGkq}XbB7lIs z0-Hr`1-nhvG#on$H3bNP-x$?3qhThhuC@@ko_b(i4}f*Yq0VWVSW(iWes`*qT)mxt zkZA8Eh|#q9OZDQLDWWyq6s(fyOc5CWsVza*7n8AdXYK=~4w|TXNHq1_rq!8{*kx>g zmIH?OF2$#S&enAe>B;qeC?|+XeB1aN_}j+y?;3JiH;V;J5>&Mb+)WPdq69?+3DT4{ z7Mx3v)|z8MUxIX(iv?#Aq_+UE;8cS2N+TAW1b;X!IkB##S)AnE;}iv%K9ndZojz#D z2}27FS53A1O*LeKUezxA@qkkesUU`hZVboc`_!i8*lD<$f-7vUBQ0aSvzAcOHS`ES zT8nRFL$2W(w5Dwe4%F?;pkL4049ZR>Mz(T6&hRtJKdx?7JoOB1d3B4bVpYtO!BMnc z()xwXmyW7iB3-)j)eOxh)qyun%U{E`wkwP-u{~k9UHUPO2~sDb;(6gEL8#W7F^%^s z&Xp9?mWz?}jmbo* z&37XSbN07*qoM6N<$ Eg3_>_lmGw# diff --git a/submodules/TelegramUI/Images.xcassets/Chat List/UndoInfoIcon.imageset/tip@3x.png b/submodules/TelegramUI/Images.xcassets/Chat List/UndoInfoIcon.imageset/tip@3x.png deleted file mode 100644 index c8962f67d00870b12495b8c1e48f787449ee2e58..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1523 zcmVcLz4oWXjH|4 zMI87R)wH5dvW2tnG6MhF)ae6FcLbXHjr(ZdpsC67`6tr`ZP%7Y;4t_xmTsXh)V3JT z4)Xn$X-m6aVPu3}L#IvDrdr)r<-(@o>l~W3b`OuY+HYX_0{z~86%XoMs#mFStxBam zEu*%njg_PlIL@|pYP(#i#(o#NY}#7diqcD!iZps^Aebe2hfDT$QG*M?0d0|;HRb5@ z=vmbMyu2r5ya~KVc?EL80Zp^(?@=G~w4bqi&p7=S;V~2MGSDRXH1PhbWfX9_HR)QO zVDSBMN0o*uuWPw7?n~h|-sy(j$Gv9;nspR^1g~omgX#|kDD2}Y$Bu=R7vk4W*W|FL zC(9YhOh+iFQFJ9!vi$_xrxjVMQl@DCCV6igCaHZh;K=fee!rILNM2$k+3F zjhdYWobOAP}+AI|Oyef1;BvfSDDlTGaERM%7aR zLX&g9ppw_nkPfPRIi*WgYtup!jqWEIx!#Z}jw&rAIT|9kO8|RdDVg{syB$avBskY& zoXtRhSvMkZuh^{+Le8*%#{D2|Z#>QO_JS_e=RG^oNAvRnH{VCkJ^MU>Yj^-6a1HmJ z?cH>#hSu@+;fU-F;F=w#0bDa~a}hXw<}*k=0*`g6>f5M6>JfN2fU5`0mL9-a5;eo! z;2vahU+P?XruTF;8`oCx=t1TI{M7fJ+ih8y!g{yGOnsb0-+K;HjX=c8f^$6st5(hI zm5Nve_d+`GJ}&)28fVqv-JHFXr*?~P8dmWOY1Qy`?P_LkhnSJ=nUpX7t*3GfbXy`E$-e#R;9 zi)4YW;{eKlbES3cSB6Oj9At0fl+OwA5eF1knxj}NNt=dAs`3mtllviIy-#sc)lRhG zT5Ib{o5)DToyFiIS6MB($q0mZxjZ(=_%xH*e!_Wdzl0e(^lORj+4jvkEo_K|D<{*R z*g`n(^CLLxhR<*d=(LI2R2f?1#&hmT=n9SD)8u`L`ntDuxt5nEALXm=2sB6aFPwd$|LRdcXjt-3 zD#ru$8|d(J(HuUd$-oD(KF}@ zdIDA2B%=4hTK94n)f@KCe%aj_I2x4_K> +endobj + +2 0 obj + << /Length 3 0 R >> +stream +/DeviceRGB CS +/DeviceRGB cs +q +1.000000 0.000000 -0.000000 1.000000 1.000000 1.000000 cm +0.000000 0.000000 0.000000 scn +2.000000 8.000000 m +0.895431 8.000000 0.000000 7.104569 0.000000 6.000000 c +0.000000 2.000000 l +0.000000 0.895431 0.895431 0.000000 2.000000 0.000000 c +6.000000 0.000000 l +7.104569 0.000000 8.000000 0.895431 8.000000 2.000000 c +8.000000 6.000000 l +8.000000 7.104569 7.104569 8.000000 6.000000 8.000000 c +2.000000 8.000000 l +h +2.000002 5.669998 m +1.629971 5.669998 1.330002 5.370029 1.330002 4.999998 c +1.330002 2.009998 l +1.330002 1.639967 1.629971 1.339998 2.000001 1.339998 c +5.990002 1.339998 l +6.360033 1.339998 6.660002 1.639967 6.660002 2.009998 c +6.660002 4.999998 l +6.660002 5.370029 6.360033 5.669998 5.990002 5.669998 c +2.000002 5.669998 l +h +f* +n +Q + +endstream +endobj + +3 0 obj + 778 +endobj + +4 0 obj + << /Annots [] + /Type /Page + /MediaBox [ 0.000000 0.000000 10.000000 10.000000 ] + /Resources 1 0 R + /Contents 2 0 R + /Parent 5 0 R + >> +endobj + +5 0 obj + << /Kids [ 4 0 R ] + /Count 1 + /Type /Pages + >> +endobj + +6 0 obj + << /Pages 5 0 R + /Type /Catalog + >> +endobj + +xref +0 7 +0000000000 65535 f +0000000010 00000 n +0000000034 00000 n +0000000868 00000 n +0000000890 00000 n +0000001063 00000 n +0000001137 00000 n +trailer +<< /ID [ (some) (id) ] + /Root 6 0 R + /Size 7 +>> +startxref +1196 +%%EOF \ No newline at end of file diff --git a/submodules/TelegramUI/Images.xcassets/Components/Snowflake.imageset/Snowflake.png b/submodules/TelegramUI/Images.xcassets/Components/Snowflake.imageset/Snowflake.png deleted file mode 100644 index f781e571612bfa9fdef756e6f9526bc4461cd55b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5794 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 diff --git a/submodules/TelegramUI/Sources/ChatButtonKeyboardInputNode.swift b/submodules/TelegramUI/Sources/ChatButtonKeyboardInputNode.swift index 54b4aa55dd..ee3274981a 100644 --- a/submodules/TelegramUI/Sources/ChatButtonKeyboardInputNode.swift +++ b/submodules/TelegramUI/Sources/ChatButtonKeyboardInputNode.swift @@ -215,8 +215,6 @@ final class ChatButtonKeyboardInputNode: ChatInputNode { self.controllerInteraction.openPollCreation(isQuiz) case let .openUserProfile(peerId): self.controllerInteraction.openPeer(peerId, .info, nil, nil) - case .addToChat: - self.controllerInteraction.openAddToChat() } if dismissIfOnce { if let message = self.message { diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index bb5e623c08..08e352840f 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -75,6 +75,7 @@ import ChatPresentationInterfaceState import Pasteboard import ChatSendMessageActionUI import ChatTextLinkEditUI +import WebUI #if DEBUG import os.signpost @@ -3298,23 +3299,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G return } strongSelf.openResolved(result: .join(joinHash), sourceMessageId: nil) - }, openAddToChat: { [weak self] in - guard let strongSelf = self else { - return - } - guard let peerId = strongSelf.presentationInterfaceState.chatLocation.peerId else { - return - } - strongSelf.context.sharedContext.openResolvedUrl(.groupBotStart(peerId: peerId, payload: ""), context: strongSelf.context, urlContext: .generic, navigationController: strongSelf.effectiveNavigationController, openPeer: { id, navigation in - }, sendFile: nil, - sendSticker: nil, - requestMessageActionUrlAuth: nil, - joinVoiceChat: nil, - present: { [weak self] c, a in - self?.present(c, in: .window(.root), with: a) - }, dismissInput: { [weak self] in - self?.view.endEditing(true) - }, contentContext: nil) }, requestMessageUpdate: { [weak self] id in if let strongSelf = self { strongSelf.chatDisplayNode.historyNode.requestMessageUpdate(id) @@ -10435,6 +10419,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G if canSendPolls { availableTabs.insert(.poll, at: availableTabs.count - 1) } +// availableTabs.insert(.app("Web App"), at: 1) let inputText = self.presentationInterfaceState.interfaceState.effectiveInputState.inputText @@ -10700,7 +10685,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G completion(controller, nil) strongSelf.controllerNavigationDisposable.set(nil) case .app: - return + let controller = WebAppController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, url: "", message: nil) + completion(controller, nil) + strongSelf.controllerNavigationDisposable.set(nil) } } let present = { diff --git a/submodules/TelegramUI/Sources/ChatControllerInteraction.swift b/submodules/TelegramUI/Sources/ChatControllerInteraction.swift index fc16e56473..acff7b34b1 100644 --- a/submodules/TelegramUI/Sources/ChatControllerInteraction.swift +++ b/submodules/TelegramUI/Sources/ChatControllerInteraction.swift @@ -131,7 +131,6 @@ public final class ChatControllerInteraction { let commitEmojiInteraction: (MessageId, String, EmojiInteraction, TelegramMediaFile) -> Void let openLargeEmojiInfo: (String, String?, TelegramMediaFile) -> Void let openJoinLink: (String) -> Void - let openAddToChat: () -> Void let requestMessageUpdate: (MessageId) -> Void let cancelInteractiveKeyboardGestures: () -> Void @@ -231,7 +230,6 @@ public final class ChatControllerInteraction { commitEmojiInteraction: @escaping (MessageId, String, EmojiInteraction, TelegramMediaFile) -> Void, openLargeEmojiInfo: @escaping (String, String?, TelegramMediaFile) -> Void, openJoinLink: @escaping (String) -> Void, - openAddToChat: @escaping () -> Void, requestMessageUpdate: @escaping (MessageId) -> Void, cancelInteractiveKeyboardGestures: @escaping () -> Void, automaticMediaDownloadSettings: MediaAutoDownloadSettings, @@ -317,7 +315,6 @@ public final class ChatControllerInteraction { self.commitEmojiInteraction = commitEmojiInteraction self.openLargeEmojiInfo = openLargeEmojiInfo self.openJoinLink = openJoinLink - self.openAddToChat = openAddToChat self.requestMessageUpdate = requestMessageUpdate self.cancelInteractiveKeyboardGestures = cancelInteractiveKeyboardGestures @@ -377,7 +374,6 @@ public final class ChatControllerInteraction { }, commitEmojiInteraction: { _, _, _, _ in }, openLargeEmojiInfo: { _, _, _ in }, openJoinLink: { _ in - }, openAddToChat: { }, requestMessageUpdate: { _ in }, cancelInteractiveKeyboardGestures: { }, automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings, diff --git a/submodules/TelegramUI/Sources/ChatMessageActionButtonsNode.swift b/submodules/TelegramUI/Sources/ChatMessageActionButtonsNode.swift index fb16be1edb..57ec1c7151 100644 --- a/submodules/TelegramUI/Sources/ChatMessageActionButtonsNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageActionButtonsNode.swift @@ -94,7 +94,13 @@ private final class ChatMessageActionButtonNode: ASDisplayNode { switch button.action { case .text: iconImage = incoming ? graphics.chatBubbleActionButtonIncomingMessageIconImage : graphics.chatBubbleActionButtonOutgoingMessageIconImage - case .url, .urlAuth: + case let .url(value): + if value.lowercased().contains("?startgroup=") { + iconImage = incoming ? graphics.chatBubbleActionButtonIncomingAddToChatIconImage : graphics.chatBubbleActionButtonOutgoingAddToChatIconImage + } else { + iconImage = incoming ? graphics.chatBubbleActionButtonIncomingLinkIconImage : graphics.chatBubbleActionButtonOutgoingLinkIconImage + } + case .urlAuth: iconImage = incoming ? graphics.chatBubbleActionButtonIncomingLinkIconImage : graphics.chatBubbleActionButtonOutgoingLinkIconImage case .requestPhone: iconImage = incoming ? graphics.chatBubbleActionButtonIncomingPhoneIconImage : graphics.chatBubbleActionButtonOutgoingPhoneIconImage @@ -106,8 +112,8 @@ private final class ChatMessageActionButtonNode: ASDisplayNode { iconImage = incoming ? graphics.chatBubbleActionButtonIncomingPaymentIconImage : graphics.chatBubbleActionButtonOutgoingPaymentIconImage case .openUserProfile: iconImage = incoming ? graphics.chatBubbleActionButtonIncomingProfileIconImage : graphics.chatBubbleActionButtonOutgoingProfileIconImage - case .addToChat: - iconImage = incoming ? graphics.chatBubbleActionButtonIncomingAddToChatIconImage : graphics.chatBubbleActionButtonOutgoingAddToChatIconImage + case .openWebApp: + iconImage = incoming ? graphics.chatBubbleActionButtonIncomingWebAppIconImage : graphics.chatBubbleActionButtonOutgoingWebAppIconImage default: iconImage = nil } diff --git a/submodules/TelegramUI/Sources/ChatMessageItemView.swift b/submodules/TelegramUI/Sources/ChatMessageItemView.swift index b67c735cb4..c111678fb1 100644 --- a/submodules/TelegramUI/Sources/ChatMessageItemView.swift +++ b/submodules/TelegramUI/Sources/ChatMessageItemView.swift @@ -854,8 +854,6 @@ public class ChatMessageItemView: ListViewItemNode, ChatMessageItemNodeProtocol break case let .openUserProfile(peerId): item.controllerInteraction.openPeer(peerId, .info, nil, nil) - case .addToChat: - item.controllerInteraction.openAddToChat() } } } diff --git a/submodules/TelegramUI/Sources/ChatRecentActionsControllerNode.swift b/submodules/TelegramUI/Sources/ChatRecentActionsControllerNode.swift index 41fd0f9401..105475eb41 100644 --- a/submodules/TelegramUI/Sources/ChatRecentActionsControllerNode.swift +++ b/submodules/TelegramUI/Sources/ChatRecentActionsControllerNode.swift @@ -532,7 +532,6 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode { }, commitEmojiInteraction: { _, _, _, _ in }, openLargeEmojiInfo: { _, _, _ in }, openJoinLink: { _ in - }, openAddToChat: { }, requestMessageUpdate: { _ in }, cancelInteractiveKeyboardGestures: { }, automaticMediaDownloadSettings: self.automaticMediaDownloadSettings, diff --git a/submodules/TelegramUI/Sources/DrawingStickersScreen.swift b/submodules/TelegramUI/Sources/DrawingStickersScreen.swift index 9bea55cb0d..66cc0c9175 100644 --- a/submodules/TelegramUI/Sources/DrawingStickersScreen.swift +++ b/submodules/TelegramUI/Sources/DrawingStickersScreen.swift @@ -159,7 +159,6 @@ private final class DrawingStickersScreenNode: ViewControllerTracingNode { }, commitEmojiInteraction: { _, _, _, _ in }, openLargeEmojiInfo: { _, _, _ in }, openJoinLink: { _ in - }, openAddToChat: { }, requestMessageUpdate: { _ in }, cancelInteractiveKeyboardGestures: { }, automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings, diff --git a/submodules/TelegramUI/Sources/OpenResolvedUrl.swift b/submodules/TelegramUI/Sources/OpenResolvedUrl.swift index 138305c63b..c605239805 100644 --- a/submodules/TelegramUI/Sources/OpenResolvedUrl.swift +++ b/submodules/TelegramUI/Sources/OpenResolvedUrl.swift @@ -67,7 +67,7 @@ func openResolvedUrlImpl(_ resolvedUrl: ResolvedUrl, context: AccountContext, ur present(standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: presentationData.strings.Conversation_ErrorInaccessibleMessage, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil) case let .botStart(peerId, payload): openPeer(peerId, .withBotStartPayload(ChatControllerInitialBotStart(payload: payload, behavior: .interactive))) - case let .groupBotStart(botPeerId, payload): + case let .groupBotStart(botPeerId, payload, adminRights): let controller = context.sharedContext.makePeerSelectionController(PeerSelectionControllerParams(context: context, filter: [.onlyGroupsAndChannels, .onlyManageable, .excludeDisabled], hasContactSelector: false, title: presentationData.strings.Bot_AddToChat_Title)) controller.peerSelected = { [weak controller] peer in let peerId = peer.id @@ -132,7 +132,7 @@ func openResolvedUrlImpl(_ resolvedUrl: ResolvedUrl, context: AccountContext, ur if let peer = peer as? TelegramChannel { if peer.flags.contains(.isCreator) || peer.adminRights != nil { - let controller = channelAdminController(context: context, peerId: peerId, adminId: botPeerId, initialParticipant: nil, invite: true, updated: { _ in + let controller = channelAdminController(context: context, peerId: peerId, adminId: botPeerId, initialParticipant: nil, invite: true, initialAdminRights: adminRights?.chatAdminRights, updated: { _ in controller?.dismiss() }, upgradedToSupergroup: { _, _ in }, transferedOwnership: { _ in }) navigationController?.pushViewController(controller) @@ -143,7 +143,7 @@ func openResolvedUrlImpl(_ resolvedUrl: ResolvedUrl, context: AccountContext, ur if case .member = peer.role { addMemberImpl() } else { - let controller = channelAdminController(context: context, peerId: peerId, adminId: botPeerId, initialParticipant: nil, invite: true, updated: { _ in + let controller = channelAdminController(context: context, peerId: peerId, adminId: botPeerId, initialParticipant: nil, invite: true, initialAdminRights: adminRights?.chatAdminRights, updated: { _ in controller?.dismiss() }, upgradedToSupergroup: { _, _ in }, transferedOwnership: { _ in }) navigationController?.pushViewController(controller) diff --git a/submodules/TelegramUI/Sources/OpenUrl.swift b/submodules/TelegramUI/Sources/OpenUrl.swift index 31096d46e3..c75f110003 100644 --- a/submodules/TelegramUI/Sources/OpenUrl.swift +++ b/submodules/TelegramUI/Sources/OpenUrl.swift @@ -610,6 +610,7 @@ func openExternalUrlImpl(context: AccountContext, urlContext: OpenURLContext, ur var domain: String? var start: String? var startGroup: String? + var admin: String? var game: String? var post: String? var voiceChat: String? @@ -624,6 +625,8 @@ func openExternalUrlImpl(context: AccountContext, urlContext: OpenURLContext, ur start = value } else if queryItem.name == "startgroup" { startGroup = value + } else if queryItem.name == "admin" { + admin = value } else if queryItem.name == "game" { game = value } else if queryItem.name == "post" { @@ -648,6 +651,9 @@ func openExternalUrlImpl(context: AccountContext, urlContext: OpenURLContext, ur result += "?start=\(start)" } else if let startGroup = startGroup { result += "?startgroup=\(startGroup)" + if let admin = admin { + result += "&admin=\(admin)" + } } else if let game = game { result += "?game=\(game)" } else if let voiceChat = voiceChat { diff --git a/submodules/TelegramUI/Sources/OverlayAudioPlayerControllerNode.swift b/submodules/TelegramUI/Sources/OverlayAudioPlayerControllerNode.swift index 31739fd2ae..9026c3295d 100644 --- a/submodules/TelegramUI/Sources/OverlayAudioPlayerControllerNode.swift +++ b/submodules/TelegramUI/Sources/OverlayAudioPlayerControllerNode.swift @@ -151,7 +151,6 @@ final class OverlayAudioPlayerControllerNode: ViewControllerTracingNode, UIGestu }, commitEmojiInteraction: { _, _, _, _ in }, openLargeEmojiInfo: { _, _, _ in }, openJoinLink: { _ in - }, openAddToChat: { }, requestMessageUpdate: { _ in }, cancelInteractiveKeyboardGestures: { }, automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings, pollActionState: ChatInterfacePollActionState(), stickerSettings: ChatInterfaceStickerSettings(loopAnimatedStickers: false), presentationContext: ChatPresentationContext(backgroundNode: nil)) diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift index d4c22dd610..768b7d40e0 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift @@ -2265,7 +2265,6 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate }, commitEmojiInteraction: { _, _, _, _ in }, openLargeEmojiInfo: { _, _, _ in }, openJoinLink: { _ in - }, openAddToChat: { }, requestMessageUpdate: { _ in }, cancelInteractiveKeyboardGestures: { }, automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings, @@ -4787,7 +4786,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate guard let controller = self.controller else { return } - self.context.sharedContext.openResolvedUrl(.groupBotStart(peerId: peerId, payload: ""), context: self.context, urlContext: .generic, navigationController: controller.navigationController as? NavigationController, openPeer: { id, navigation in + self.context.sharedContext.openResolvedUrl(.groupBotStart(peerId: peerId, payload: "", adminRights: nil), context: self.context, urlContext: .generic, navigationController: controller.navigationController as? NavigationController, openPeer: { id, navigation in }, sendFile: nil, sendSticker: nil, requestMessageActionUrlAuth: nil, @@ -5648,7 +5647,12 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate self.openTips() case .phoneNumber: if let user = self.data?.peer as? TelegramUser, let phoneNumber = user.phone { - self.controller?.push(ChangePhoneNumberIntroController(context: self.context, phoneNumber: phoneNumber)) + let introController = PrivacyIntroController(context: self.context, mode: .changePhoneNumber(phoneNumber), proceedAction: { [weak self] in + if let strongSelf = self, let navigationController = strongSelf.controller?.navigationController as? NavigationController { + navigationController.replaceTopController(ChangePhoneNumberController(context: strongSelf.context), animated: true) + } + }) + self.controller?.push(introController) } case .username: self.controller?.push(usernameSetupController(context: self.context)) diff --git a/submodules/TelegramUI/Sources/SharedAccountContext.swift b/submodules/TelegramUI/Sources/SharedAccountContext.swift index cc74cf4f79..8c00a2f4b8 100644 --- a/submodules/TelegramUI/Sources/SharedAccountContext.swift +++ b/submodules/TelegramUI/Sources/SharedAccountContext.swift @@ -1325,7 +1325,6 @@ public final class SharedAccountContextImpl: SharedAccountContext { }, commitEmojiInteraction: { _, _, _, _ in }, openLargeEmojiInfo: { _, _, _ in }, openJoinLink: { _ in - }, openAddToChat: { }, requestMessageUpdate: { _ in }, cancelInteractiveKeyboardGestures: { }, automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings, diff --git a/submodules/UrlHandling/Sources/UrlHandling.swift b/submodules/UrlHandling/Sources/UrlHandling.swift index a423819fa0..26328af18c 100644 --- a/submodules/UrlHandling/Sources/UrlHandling.swift +++ b/submodules/UrlHandling/Sources/UrlHandling.swift @@ -19,9 +19,53 @@ private let baseTelegraPhPaths = [ "telegram.org/tour/" ] +extension ResolvedBotAdminRights { + init?(_ string: String) { + var rawValue: UInt32 = 0 + + let components = string.lowercased().components(separatedBy: "+") + if components.contains("change_info") { + rawValue |= ResolvedBotAdminRights.changeInfo.rawValue + } + if components.contains("post_messages") { + rawValue |= ResolvedBotAdminRights.postMessages.rawValue + } + if components.contains("delete_messages") { + rawValue |= ResolvedBotAdminRights.deleteMessages.rawValue + } + if components.contains("restrict_members") { + rawValue |= ResolvedBotAdminRights.restrictMembers.rawValue + } + if components.contains("invite_users") { + rawValue |= ResolvedBotAdminRights.inviteUsers.rawValue + } + if components.contains("pin_messages") { + rawValue |= ResolvedBotAdminRights.pinMessages.rawValue + } + if components.contains("promote_members") { + rawValue |= ResolvedBotAdminRights.promoteMembers.rawValue + } + if components.contains("manage_video_chats") { + rawValue |= ResolvedBotAdminRights.manageVideoChats.rawValue + } + if components.contains("manage_chat") { + rawValue |= ResolvedBotAdminRights.manageChat.rawValue + } + if components.contains("anonymous") { + rawValue |= ResolvedBotAdminRights.canBeAnonymous.rawValue + } + + if rawValue != 0 { + self.init(rawValue: rawValue) + } else { + return nil + } + } +} + public enum ParsedInternalPeerUrlParameter { case botStart(String) - case groupBotStart(String) + case groupBotStart(String, ResolvedBotAdminRights?) case channelMessage(Int32, Double?) case replyThread(Int32, Int32) case voiceChat(String?) @@ -141,7 +185,14 @@ public func parseInternalUrl(query: String) -> ParsedInternalUrl? { if queryItem.name == "start" { return .peerName(peerName, .botStart(value)) } else if queryItem.name == "startgroup" { - return .peerName(peerName, .groupBotStart(value)) + var botAdminRights: ResolvedBotAdminRights? + for queryItem in queryItems { + if queryItem.name == "admin", let value = queryItem.value { + botAdminRights = ResolvedBotAdminRights(value) + break + } + } + return .peerName(peerName, .groupBotStart(value, botAdminRights)) } else if queryItem.name == "game" { return nil } else if ["voicechat", "videochat", "livestream"].contains(queryItem.name) { @@ -378,8 +429,8 @@ private func resolveInternalUrl(context: AccountContext, url: ParsedInternalUrl) switch parameter { case let .botStart(payload): return .single(.botStart(peerId: peer.id, payload: payload)) - case let .groupBotStart(payload): - return .single(.groupBotStart(peerId: peer.id, payload: payload)) + case let .groupBotStart(payload, adminRights): + return .single(.groupBotStart(peerId: peer.id, payload: payload, adminRights: adminRights)) case let .channelMessage(id, timecode): return .single(.channelMessage(peerId: peer.id, messageId: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: id), timecode: timecode)) case let .replyThread(id, replyId): diff --git a/submodules/UrlWhitelist/Sources/UrlWhitelist.swift b/submodules/UrlWhitelist/Sources/UrlWhitelist.swift index 30e1c542f4..4321d495b8 100644 --- a/submodules/UrlWhitelist/Sources/UrlWhitelist.swift +++ b/submodules/UrlWhitelist/Sources/UrlWhitelist.swift @@ -36,7 +36,7 @@ public func parseUrl(url: String, wasConcealed: Bool) -> (string: String, concea var parsedUrlValue: URL? if url.hasPrefix("tel:") { return (url, false) - } else if let parsed = URL(string: url) { + } else if url.lowercased().hasPrefix("http://") || url.lowercased().hasPrefix("https://"), let parsed = URL(string: url) { parsedUrlValue = parsed } else if let parsed = URL(string: "https://" + url) { parsedUrlValue = parsed diff --git a/submodules/WebUI/BUILD b/submodules/WebUI/BUILD index bbd1827908..33468d677f 100644 --- a/submodules/WebUI/BUILD +++ b/submodules/WebUI/BUILD @@ -10,8 +10,14 @@ swift_library( "-warnings-as-errors", ], deps = [ + "//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit", "//submodules/AsyncDisplayKit:AsyncDisplayKit", "//submodules/Display:Display", + "//submodules/TelegramCore:TelegramCore", + "//submodules/TelegramPresentationData:TelegramPresentationData", + "//submodules/AccountContext:AccountContext", + "//submodules/AttachmentUI:AttachmentUI", + "//submodules/CounterContollerTitleView:CounterContollerTitleView", ], visibility = [ "//visibility:public", diff --git a/submodules/WebUI/Sources/WebAppAlertContentNode.swift b/submodules/WebUI/Sources/WebAppAlertContentNode.swift new file mode 100644 index 0000000000..35752610e4 --- /dev/null +++ b/submodules/WebUI/Sources/WebAppAlertContentNode.swift @@ -0,0 +1,225 @@ +import Foundation +import UIKit +import SwiftSignalKit +import AsyncDisplayKit +import Display +import Postbox +import TelegramCore +import TelegramPresentationData +import TelegramUIPreferences +import AccountContext +import AppBundle + +private final class WebAppAlertContentNode: AlertContentNode { + private let strings: PresentationStrings + + private let textNode: ASTextNode + private let iconNode: ASImageNode + + private let actionNodesSeparator: ASDisplayNode + private let actionNodes: [TextAlertContentActionNode] + private let actionVerticalSeparators: [ASDisplayNode] + + private var validLayout: CGSize? + + override var dismissOnOutsideTap: Bool { + return self.isUserInteractionEnabled + } + + init(theme: AlertControllerTheme, ptheme: PresentationTheme, strings: PresentationStrings, actions: [TextAlertAction]) { + self.strings = strings + + self.textNode = ASTextNode() + self.textNode.maximumNumberOfLines = 0 + + self.iconNode = ASImageNode() + self.iconNode.displaysAsynchronously = false + self.iconNode.displayWithoutProcessing = true + + self.actionNodesSeparator = ASDisplayNode() + self.actionNodesSeparator.isLayerBacked = true + + self.actionNodes = actions.map { action -> TextAlertContentActionNode in + return TextAlertContentActionNode(theme: theme, action: action) + } + + var actionVerticalSeparators: [ASDisplayNode] = [] + if actions.count > 1 { + for _ in 0 ..< actions.count - 1 { + let separatorNode = ASDisplayNode() + separatorNode.isLayerBacked = true + actionVerticalSeparators.append(separatorNode) + } + } + self.actionVerticalSeparators = actionVerticalSeparators + + super.init() + + self.addSubnode(self.textNode) + self.addSubnode(self.iconNode) + + self.addSubnode(self.actionNodesSeparator) + + for actionNode in self.actionNodes { + self.addSubnode(actionNode) + } + + for separatorNode in self.actionVerticalSeparators { + self.addSubnode(separatorNode) + } + + self.updateTheme(theme) + } + + override func updateTheme(_ theme: AlertControllerTheme) { + self.textNode.attributedText = NSAttributedString(string: strings.WebApp_AddToAttachmentText("Web App").string, font: Font.bold(17.0), textColor: theme.primaryColor, paragraphAlignment: .center) + self.iconNode.image = generateTintedImage(image: UIImage(bundleImageName: "Bot Payments/BotLogo"), color: theme.accentColor) + + self.actionNodesSeparator.backgroundColor = theme.separatorColor + for actionNode in self.actionNodes { + actionNode.updateTheme(theme) + } + for separatorNode in self.actionVerticalSeparators { + separatorNode.backgroundColor = theme.separatorColor + } + + if let size = self.validLayout { + _ = self.updateLayout(size: size, transition: .immediate) + } + } + + override func updateLayout(size: CGSize, transition: ContainedViewLayoutTransition) -> CGSize { + var size = size + size.width = min(size.width , 270.0) + + self.validLayout = size + + var origin: CGPoint = CGPoint(x: 0.0, y: 20.0) + + var iconSize = CGSize() + var iconFrame = CGRect() + if let icon = self.iconNode.image { + iconSize = icon.size + iconFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - iconSize.width) / 2.0), y: origin.y), size: iconSize) + origin.y += iconSize.height + 16.0 + } + + let textSize = self.textNode.measure(size) + var textFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - textSize.width) / 2.0), y: origin.y), size: textSize) + + let actionButtonHeight: CGFloat = 44.0 + var minActionsWidth: CGFloat = 0.0 + let maxActionWidth: CGFloat = floor(size.width / CGFloat(self.actionNodes.count)) + let actionTitleInsets: CGFloat = 8.0 + + var effectiveActionLayout = TextAlertContentActionLayout.horizontal + for actionNode in self.actionNodes { + let actionTitleSize = actionNode.titleNode.updateLayout(CGSize(width: maxActionWidth, height: actionButtonHeight)) + if case .horizontal = effectiveActionLayout, actionTitleSize.height > actionButtonHeight * 0.6667 { + effectiveActionLayout = .vertical + } + switch effectiveActionLayout { + case .horizontal: + minActionsWidth += actionTitleSize.width + actionTitleInsets + case .vertical: + minActionsWidth = max(minActionsWidth, actionTitleSize.width + actionTitleInsets) + } + } + + let insets = UIEdgeInsets(top: 18.0, left: 18.0, bottom: 18.0, right: 18.0) + + var contentWidth = max(textSize.width, minActionsWidth) + contentWidth = max(contentWidth, 234.0) + + var actionsHeight: CGFloat = 0.0 + switch effectiveActionLayout { + case .horizontal: + actionsHeight = actionButtonHeight + case .vertical: + actionsHeight = actionButtonHeight * CGFloat(self.actionNodes.count) + } + + let resultWidth = contentWidth + insets.left + insets.right + let resultSize = CGSize(width: resultWidth, height: iconSize.height + textSize.height + actionsHeight + 17.0 + insets.top + insets.bottom) + + transition.updateFrame(node: self.actionNodesSeparator, frame: CGRect(origin: CGPoint(x: 0.0, y: resultSize.height - actionsHeight - UIScreenPixel), size: CGSize(width: resultSize.width, height: UIScreenPixel))) + + var actionOffset: CGFloat = 0.0 + let actionWidth: CGFloat = floor(resultSize.width / CGFloat(self.actionNodes.count)) + var separatorIndex = -1 + var nodeIndex = 0 + for actionNode in self.actionNodes { + if separatorIndex >= 0 { + let separatorNode = self.actionVerticalSeparators[separatorIndex] + switch effectiveActionLayout { + case .horizontal: + transition.updateFrame(node: separatorNode, frame: CGRect(origin: CGPoint(x: actionOffset - UIScreenPixel, y: resultSize.height - actionsHeight), size: CGSize(width: UIScreenPixel, height: actionsHeight - UIScreenPixel))) + case .vertical: + transition.updateFrame(node: separatorNode, frame: CGRect(origin: CGPoint(x: 0.0, y: resultSize.height - actionsHeight + actionOffset - UIScreenPixel), size: CGSize(width: resultSize.width, height: UIScreenPixel))) + } + } + separatorIndex += 1 + + let currentActionWidth: CGFloat + switch effectiveActionLayout { + case .horizontal: + if nodeIndex == self.actionNodes.count - 1 { + currentActionWidth = resultSize.width - actionOffset + } else { + currentActionWidth = actionWidth + } + case .vertical: + currentActionWidth = resultSize.width + } + + let actionNodeFrame: CGRect + switch effectiveActionLayout { + case .horizontal: + actionNodeFrame = CGRect(origin: CGPoint(x: actionOffset, y: resultSize.height - actionsHeight), size: CGSize(width: currentActionWidth, height: actionButtonHeight)) + actionOffset += currentActionWidth + case .vertical: + actionNodeFrame = CGRect(origin: CGPoint(x: 0.0, y: resultSize.height - actionsHeight + actionOffset), size: CGSize(width: currentActionWidth, height: actionButtonHeight)) + actionOffset += actionButtonHeight + } + + transition.updateFrame(node: actionNode, frame: actionNodeFrame) + + nodeIndex += 1 + } + + iconFrame.origin.x = floorToScreenPixels((resultSize.width - iconFrame.width) / 2.0) + transition.updateFrame(node: self.iconNode, frame: iconFrame) + + textFrame.origin.x = floorToScreenPixels((resultSize.width - textFrame.width) / 2.0) + transition.updateFrame(node: self.textNode, frame: textFrame) + + return resultSize + } +} + +func addWebAppToAttachmentController(sharedContext: SharedAccountContext) -> AlertController { + let presentationData = sharedContext.currentPresentationData.with { $0 } + let theme = presentationData.theme + let strings = presentationData.strings + + var dismissImpl: ((Bool) -> Void)? + var contentNode: WebAppAlertContentNode? + let actions: [TextAlertAction] = [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: { + dismissImpl?(true) + }), TextAlertAction(type: .defaultAction, title: presentationData.strings.WebApp_AddToAttachmentAdd, action: { + dismissImpl?(true) + + })] + + contentNode = WebAppAlertContentNode(theme: AlertControllerTheme(presentationData: presentationData), ptheme: theme, strings: strings, actions: actions) + + let controller = AlertController(theme: AlertControllerTheme(presentationData: presentationData), contentNode: contentNode!) + dismissImpl = { [weak controller] animated in + if animated { + controller?.dismissAnimated() + } else { + controller?.dismiss() + } + } + return controller +} diff --git a/submodules/WebUI/Sources/WebAppController.swift b/submodules/WebUI/Sources/WebAppController.swift new file mode 100644 index 0000000000..961a506ba1 --- /dev/null +++ b/submodules/WebUI/Sources/WebAppController.swift @@ -0,0 +1,293 @@ +import Foundation +import UIKit +import WebKit +import Display +import AsyncDisplayKit +import TelegramCore +import SwiftSignalKit +import TelegramPresentationData +import AccountContext +import AttachmentUI +import CounterContollerTitleView +import ContextUI + +private class WeakGameScriptMessageHandler: NSObject, WKScriptMessageHandler { + private let f: (WKScriptMessage) -> () + + init(_ f: @escaping (WKScriptMessage) -> ()) { + self.f = f + + super.init() + } + + func userContentController(_ controller: WKUserContentController, didReceive scriptMessage: WKScriptMessage) { + self.f(scriptMessage) + } +} + +public final class WebAppController: ViewController, AttachmentContainable { + public var requestAttachmentMenuExpansion: () -> Void = { } + public var updateNavigationStack: (@escaping ([AttachmentContainable]) -> ([AttachmentContainable], AttachmentMediaPickerContext?)) -> Void = { _ in } + public var updateTabBarAlpha: (CGFloat, ContainedViewLayoutTransition) -> Void = { _, _ in } + public var cancelPanGesture: () -> Void = { } + + private class Node: ViewControllerTracingNode { + private var webView: WKWebView? + + private let context: AccountContext + var presentationData: PresentationData + private let present: (ViewController, Any?) -> Void + private let message: EngineMessage? + + init(context: AccountContext, presentationData: PresentationData, url: String, present: @escaping (ViewController, Any?) -> Void, message: EngineMessage?) { + self.context = context + self.presentationData = presentationData + self.present = present + self.message = message + + super.init() + + self.backgroundColor = .white + + let js = "var TelegramWebviewProxyProto = function() {}; " + + "TelegramWebviewProxyProto.prototype.postEvent = function(eventName, eventData) { " + + "window.webkit.messageHandlers.performAction.postMessage({'eventName': eventName, 'eventData': eventData}); " + + "}; " + + "var TelegramWebviewProxy = new TelegramWebviewProxyProto();" + + let configuration = WKWebViewConfiguration() + let userController = WKUserContentController() + + let userScript = WKUserScript(source: js, injectionTime: .atDocumentStart, forMainFrameOnly: false) + userController.addUserScript(userScript) + + userController.add(WeakGameScriptMessageHandler { [weak self] message in + if let strongSelf = self { + strongSelf.handleScriptMessage(message) + } + }, name: "performAction") + + configuration.userContentController = userController + + configuration.allowsInlineMediaPlayback = true + if #available(iOSApplicationExtension 10.0, iOS 10.0, *) { + configuration.mediaTypesRequiringUserActionForPlayback = [] + } else if #available(iOSApplicationExtension 9.0, iOS 9.0, *) { + configuration.requiresUserActionForMediaPlayback = false + } else { + configuration.mediaPlaybackRequiresUserAction = false + } + + let webView = WKWebView(frame: CGRect(), configuration: configuration) + if #available(iOSApplicationExtension 9.0, iOS 9.0, *) { + webView.allowsLinkPreview = false + } + if #available(iOSApplicationExtension 11.0, iOS 11.0, *) { + webView.scrollView.contentInsetAdjustmentBehavior = .never + } + webView.interactiveTransitionGestureRecognizerTest = { point -> Bool in + return point.x > 30.0 + } + + self.view.addSubview(webView) + self.webView = webView + + if let parsedUrl = URL(string: url) { + webView.load(URLRequest(url: parsedUrl)) + } + } + + func containerLayoutUpdated(_ layout: ContainerViewLayout, navigationBarHeight: CGFloat, transition: ContainedViewLayoutTransition) { + if let webView = self.webView { + webView.frame = CGRect(origin: CGPoint(x: 0.0, y: navigationBarHeight), size: CGSize(width: layout.size.width, height: max(1.0, layout.size.height - navigationBarHeight))) + } + } + + func animateIn() { + self.layer.animatePosition(from: CGPoint(x: self.layer.position.x, y: self.layer.position.y + self.layer.bounds.size.height), to: self.layer.position, duration: 0.5, timingFunction: kCAMediaTimingFunctionSpring) + } + + func animateOut(completion: (() -> Void)? = nil) { + self.layer.animatePosition(from: self.layer.position, to: CGPoint(x: self.layer.position.x, y: self.layer.position.y + self.layer.bounds.size.height), duration: 0.2, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, removeOnCompletion: false, completion: { _ in + completion?() + }) + } + + private func shareData() -> (EnginePeer, String)? { + guard let message = self.message else { + return nil + } + var botPeer: EnginePeer? + var gameName: String? + for media in message.media { + if let game = media as? TelegramMediaGame { + inner: for attribute in message.attributes { + if let attribute = attribute as? InlineBotMessageAttribute, let peerId = attribute.peerId { + botPeer = message.peers[peerId].flatMap(EnginePeer.init) + break inner + } + } + if botPeer == nil { + botPeer = message.author + } + + gameName = game.name + } + } + if let botPeer = botPeer, let gameName = gameName { + return (botPeer, gameName) + } + + return nil + } + + private func handleScriptMessage(_ message: WKScriptMessage) { + guard let body = message.body as? [String: Any] else { + return + } + + guard let eventName = body["eventName"] as? String else { + return + } + + if eventName == "share_game" || eventName == "share_score" { + if let (botPeer, gameName) = self.shareData(), let addressName = botPeer.addressName, !addressName.isEmpty, !gameName.isEmpty { + if eventName == "share_score" { + + } else { + + } + } + } + } + } + + + private var controllerNode: Node { + return self.displayNode as! Node + } + + private let moreButtonNode: MoreButtonNode + + private let context: AccountContext + private let url: String + private let message: EngineMessage? + + private var presentationData: PresentationData + + public init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal)? = nil, url: String, message: EngineMessage?) { + self.context = context + self.url = url + self.message = message + + self.presentationData = updatedPresentationData?.initial ?? context.sharedContext.currentPresentationData.with { $0 } + + var theme = NavigationBarTheme(rootControllerTheme: self.presentationData.theme) + theme = theme.withUpdatedBackgroundColor(self.presentationData.theme.list.plainBackgroundColor) + let navigationBarPresentationData = NavigationBarPresentationData(theme: theme, strings: NavigationBarStrings(back: "", close: "")) + + self.moreButtonNode = MoreButtonNode(theme: self.presentationData.theme) + self.moreButtonNode.iconNode.enqueueState(.more, animated: false) + + super.init(navigationBarPresentationData: navigationBarPresentationData) + + self.statusBar.statusBarStyle = self.presentationData.theme.rootController.statusBarStyle.style + + self.navigationItem.leftBarButtonItem = UIBarButtonItem(title: self.presentationData.strings.Common_Cancel, style: .plain, target: self, action: #selector(self.cancelPressed)) + self.navigationItem.rightBarButtonItem = UIBarButtonItem(customDisplayNode: self.moreButtonNode) + self.navigationItem.rightBarButtonItem?.action = #selector(self.moreButtonPressed) + self.navigationItem.rightBarButtonItem?.target = self + + let titleView = CounterContollerTitleView(theme: self.presentationData.theme) + titleView.title = CounterContollerTitle(title: "Web App", counter: self.presentationData.strings.Bot_GenericBotStatus) + self.navigationItem.titleView = titleView + + self.moreButtonNode.action = { [weak self] _, gesture in + if let strongSelf = self { + strongSelf.morePressed(node: strongSelf.moreButtonNode.contextSourceNode, gesture: gesture) + } + } + } + + required public init(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + deinit { + assert(true) + } + + @objc private func cancelPressed() { + self.dismiss() + } + + @objc private func moreButtonPressed() { + self.moreButtonNode.action?(self.moreButtonNode.contextSourceNode, nil) + } + + @objc private func morePressed(node: ContextReferenceContentNode, gesture: ContextGesture?) { + var items: [ContextMenuItem] = [] + items.append(.action(ContextMenuActionItem(text: "Open Bot", icon: { theme in + return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Bots"), color: theme.contextMenu.primaryColor) + }, action: { [weak self] _, f in + f(.default) + + guard let strongSelf = self else { + return + } + let controller = addWebAppToAttachmentController(sharedContext: strongSelf.context.sharedContext) + strongSelf.present(controller, in: .window(.root)) + }))) + + items.append(.action(ContextMenuActionItem(text: "Reload Page", icon: { theme in + return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Share"), color: theme.contextMenu.primaryColor) + }, action: { _, f in + f(.default) + + + }))) + + items.append(.action(ContextMenuActionItem(text: "Remove Bot", textColor: .destructive, icon: { theme in + return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Delete"), color: theme.contextMenu.destructiveColor) + }, action: { _, f in + f(.default) + + }))) + + let contextController = ContextController(account: self.context.account, presentationData: self.presentationData, source: .reference(WebAppContextReferenceContentSource(controller: self, sourceNode: node)), items: .single(ContextController.Items(content: .list(items))), gesture: gesture) + self.presentInGlobalOverlay(contextController) + } + + override public func loadDisplayNode() { + self.displayNode = Node(context: self.context, presentationData: self.presentationData, url: self.url, present: { [weak self] c, a in + self?.present(c, in: .window(.root), with: a) + }, message: self.message) + } + + override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) { + super.containerLayoutUpdated(layout, transition: transition) + + self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition) + } + + override public var presentationController: UIPresentationController? { + get { + return nil + } set(value) { + } + } +} + +private final class WebAppContextReferenceContentSource: ContextReferenceContentSource { + private let controller: ViewController + private let sourceNode: ContextReferenceContentNode + + init(controller: ViewController, sourceNode: ContextReferenceContentNode) { + self.controller = controller + self.sourceNode = sourceNode + } + + func transitionInfo() -> ContextControllerReferenceViewInfo? { + return ContextControllerReferenceViewInfo(referenceView: self.sourceNode.view, contentAreaInScreenSpace: UIScreen.main.bounds) + } +} diff --git a/submodules/WebUI/Sources/WebController.swift b/submodules/WebUI/Sources/WebController.swift deleted file mode 100644 index 12f9d4516f..0000000000 --- a/submodules/WebUI/Sources/WebController.swift +++ /dev/null @@ -1,35 +0,0 @@ -import Foundation -import UIKit -import Display -import SafariServices - -public final class WebController: ViewController { - private let url: URL - - private var controllerNode: WebControllerNode { - return self.displayNode as! WebControllerNode - } - - public init(url: URL) { - self.url = url - - super.init(navigationBarPresentationData: nil) - - self.edgesForExtendedLayout = [] - } - - required public init(coder aDecoder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - override public func loadDisplayNode() { - self.displayNode = WebControllerNode(url: self.url) - - self.displayNodeDidLoad() - } - - override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) { - super.containerLayoutUpdated(layout, transition: transition) - self.controllerNode.containerLayoutUpdated(layout, transition: transition) - } -} diff --git a/submodules/WebUI/Sources/WebControllerNode.swift b/submodules/WebUI/Sources/WebControllerNode.swift deleted file mode 100644 index 3daf4b7369..0000000000 --- a/submodules/WebUI/Sources/WebControllerNode.swift +++ /dev/null @@ -1,35 +0,0 @@ -import Foundation -import UIKit -import AsyncDisplayKit -import Display -import WebKit - -final class WebControllerNode: ViewControllerTracingNode { - private let webView: WKWebView - - init(url: URL) { - let configuration = WKWebViewConfiguration() - self.webView = WKWebView(frame: CGRect(), configuration: configuration) - if #available(iOSApplicationExtension 9.0, iOS 9.0, *) { - self.webView.allowsLinkPreview = false - } - self.webView.allowsBackForwardNavigationGestures = true - //webView.navigationDelegate = self - - super.init() - - self.view.addSubview(self.webView) - if #available(iOSApplicationExtension 11.0, iOS 11.0, *) { - self.webView.scrollView.contentInsetAdjustmentBehavior = .never - } - self.webView.scrollView.contentInset = UIEdgeInsets(top: 0.0, left: 10.0, bottom: 0.0, right: 10.0) - - self.webView.load(URLRequest(url: url)) - } - - func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) { - transition.animateView { - self.webView.frame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: layout.size.width, height: max(1.0, layout.size.height))) - } - } -}