diff --git a/TelegramUI/BotCheckoutControllerNode.swift b/TelegramUI/BotCheckoutControllerNode.swift index 217715582e..d56ec06c33 100644 --- a/TelegramUI/BotCheckoutControllerNode.swift +++ b/TelegramUI/BotCheckoutControllerNode.swift @@ -312,6 +312,12 @@ private func botCheckoutControllerEntries(presentationData: PresentationData, st private let hasApplePaySupport: Bool = PKPaymentAuthorizationViewController.canMakePayments(usingNetworks: [.visa, .masterCard, .amex]) +private var applePayProviders = Set([ + "stripe", + "sberbank", + "yandex" +]) + private func availablePaymentMethods(current: BotCheckoutPaymentMethod?, supportsApplePay: Bool) -> [BotCheckoutPaymentMethod] { var methods: [BotCheckoutPaymentMethod] = [] if hasApplePaySupport { @@ -455,9 +461,34 @@ final class BotCheckoutControllerNode: ItemListControllerNode, strongSelf.present(controller, ViewControllerPresentationArguments(presentationAnimation: .modalSheet)) } else { var dismissImpl: (() -> Void)? - let controller = BotCheckoutWebInteractionController(account: account, url: paymentForm.url, intent: .addPaymentMethod({ method in - applyPaymentMethod(method) + let controller = BotCheckoutWebInteractionController(account: account, url: paymentForm.url, intent: .addPaymentMethod({ [weak self] token in dismissImpl?() + + guard let strongSelf = self else { + return + } + let canSave = paymentForm.canSaveCredentials || paymentForm.passwordMissing + let allowSaving = paymentForm.canSaveCredentials && !paymentForm.passwordMissing + if canSave { + present(standardTextAlertController(theme: AlertControllerTheme(presentationTheme: strongSelf.presentationData.theme), title: nil, text: strongSelf.presentationData.strings.Checkout_NewCard_SaveInfoHelp, actions: [TextAlertAction(type: .genericAction, title: strongSelf.presentationData.strings.Common_NotNow, action: { + var updatedToken = token + updatedToken.saveOnServer = false + applyPaymentMethod(.webToken(updatedToken)) + }), TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_Yes, action: { + var updatedToken = token + updatedToken.saveOnServer = true + applyPaymentMethod(.webToken(updatedToken)) + })]), nil) + } else { + var updatedToken = token + updatedToken.saveOnServer = false + applyPaymentMethod(.webToken(updatedToken)) + + if allowSaving { + present(standardTextAlertController(theme: AlertControllerTheme(presentationTheme: strongSelf.presentationData.theme), title: nil, text: strongSelf.presentationData.strings.Checkout_NewCard_SaveInfoEnableHelp.replacingOccurrences(of: "]", with: "").replacingOccurrences(of: "[", with: ""), actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: { + })]), nil) + } + } })) dismissImpl = { [weak controller] in controller?.dismiss() @@ -470,7 +501,7 @@ final class BotCheckoutControllerNode: ItemListControllerNode, openPaymentMethodImpl = { [weak self] in if let strongSelf = self, let paymentForm = strongSelf.paymentFormValue { let supportsApplePay: Bool - if let nativeProvider = paymentForm.nativeProvider, nativeProvider.name == "stripe" { + if let nativeProvider = paymentForm.nativeProvider, applePayProviders.contains(nativeProvider.name) { supportsApplePay = true } else { supportsApplePay = false @@ -661,8 +692,8 @@ final class BotCheckoutControllerNode: ItemListControllerNode, return } } - case let .webToken(_, data, saveOnServer): - credentials = .generic(data: data, saveOnServer: saveOnServer) + case let .webToken(token): + credentials = .generic(data: token.data, saveOnServer: token.saveOnServer) case .applePayStripe: let botPeerId = self.messageId.peerId let _ = (self.account.postbox.transaction({ transaction -> Peer? in @@ -856,7 +887,7 @@ final class BotCheckoutControllerNode: ItemListControllerNode, completion(.failure) return } - guard let nativeProvider = paymentForm.nativeProvider, nativeProvider.name == "stripe" else { + guard let nativeProvider = paymentForm.nativeProvider, applePayProviders.contains(nativeProvider.name) else { completion(.failure) return } diff --git a/TelegramUI/BotCheckoutNativeCardEntryControllerNode.swift b/TelegramUI/BotCheckoutNativeCardEntryControllerNode.swift index 9f7484ba15..b2f4764ef8 100644 --- a/TelegramUI/BotCheckoutNativeCardEntryControllerNode.swift +++ b/TelegramUI/BotCheckoutNativeCardEntryControllerNode.swift @@ -266,7 +266,7 @@ final class BotCheckoutNativeCardEntryControllerNode: ViewControllerTracingNode, if let strongSelf = self, let card = token.card { let last4 = card.last4() let brand = STPAPIClient.string(with: card.brand) - strongSelf.completion(.webToken(title: "\(brand)*\(last4)", data: "{\"type\": \"card\", \"id\": \"\(token.tokenId)\"}", saveOnServer: strongSelf.saveInfoItem.isOn)) + strongSelf.completion(.webToken(BotCheckoutPaymentWebToken(title: "\(brand)*\(last4)", data: "{\"type\": \"card\", \"id\": \"\(token.tokenId)\"}", saveOnServer: strongSelf.saveInfoItem.isOn))) } }, error: { [weak self] error in if let strongSelf = self { diff --git a/TelegramUI/BotCheckoutPaymentMethodSheet.swift b/TelegramUI/BotCheckoutPaymentMethodSheet.swift index a8586fcb50..a41e17873b 100644 --- a/TelegramUI/BotCheckoutPaymentMethodSheet.swift +++ b/TelegramUI/BotCheckoutPaymentMethodSheet.swift @@ -4,34 +4,17 @@ import AsyncDisplayKit import SwiftSignalKit import TelegramCore +struct BotCheckoutPaymentWebToken: Equatable { + let title: String + let data: String + var saveOnServer: Bool +} + enum BotCheckoutPaymentMethod: Equatable { case savedCredentials(BotPaymentSavedCredentials) - case webToken(title: String, data: String, saveOnServer: Bool) + case webToken(BotCheckoutPaymentWebToken) case applePayStripe - static func ==(lhs: BotCheckoutPaymentMethod, rhs: BotCheckoutPaymentMethod) -> Bool { - switch lhs { - case let .savedCredentials(credentials): - if case .savedCredentials(credentials) = rhs { - return true - } else { - return false - } - case let .webToken(title, data, saveOnServer): - if case .webToken(title, data, saveOnServer) = rhs { - return true - } else { - return false - } - case .applePayStripe: - if case .applePayStripe = rhs { - return true - } else { - return false - } - } - } - var title: String { switch self { case let .savedCredentials(credentials): @@ -39,8 +22,8 @@ enum BotCheckoutPaymentMethod: Equatable { case let .card(_, title): return title } - case let .webToken(title, _, _): - return title + case let .webToken(token): + return token.title case .applePayStripe: return "Apple Pay" } @@ -71,8 +54,8 @@ final class BotCheckoutPaymentMethodSheetController: ActionSheetController { title = cardTitle icon = nil } - case let .webToken(webTitle, _, _): - title = webTitle + case let .webToken(token): + title = token.title icon = nil case .applePayStripe: title = "Apple Pay" diff --git a/TelegramUI/BotCheckoutWebInteractionController.swift b/TelegramUI/BotCheckoutWebInteractionController.swift index 1bd2229bc4..7917de139e 100644 --- a/TelegramUI/BotCheckoutWebInteractionController.swift +++ b/TelegramUI/BotCheckoutWebInteractionController.swift @@ -6,7 +6,7 @@ import SwiftSignalKit import Postbox enum BotCheckoutWebInteractionControllerIntent { - case addPaymentMethod((BotCheckoutPaymentMethod) -> Void) + case addPaymentMethod((BotCheckoutPaymentWebToken) -> Void) case externalVerification((Bool) -> Void) } diff --git a/TelegramUI/BotCheckoutWebInteractionControllerNode.swift b/TelegramUI/BotCheckoutWebInteractionControllerNode.swift index 832b829438..7387993ee3 100644 --- a/TelegramUI/BotCheckoutWebInteractionControllerNode.swift +++ b/TelegramUI/BotCheckoutWebInteractionControllerNode.swift @@ -126,7 +126,7 @@ final class BotCheckoutWebInteractionControllerNode: ViewControllerTracingNode, } if case let .addPaymentMethod(completion) = self.intent { - completion(.webToken(title: title, data: credentialsString, saveOnServer: false)) + completion(BotCheckoutPaymentWebToken(title: title, data: credentialsString, saveOnServer: false)) } } } diff --git a/TelegramUI/ChatControllerNode.swift b/TelegramUI/ChatControllerNode.swift index ed445d6e7e..72e39ebe2a 100644 --- a/TelegramUI/ChatControllerNode.swift +++ b/TelegramUI/ChatControllerNode.swift @@ -1620,7 +1620,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate { let controller = ChatMessageActionSheetController(theme: self.chatPresentationInterfaceState.theme, actions: sheetActions ?? [], dismissed: { [weak self, weak contextMenuController] in self?.displayMessageActionSheet(stableId: nil, sheetActions: nil, displayContextMenuController: nil) contextMenuController?.dismiss() - }) + }, associatedController: contextMenuController) self.messageActionSheetController = (controller, stableId) if let sheetActions = sheetActions, !sheetActions.isEmpty { self.controllerInteraction.presentGlobalOverlayController(controller, nil) diff --git a/TelegramUI/ChatInterfaceStateContextMenus.swift b/TelegramUI/ChatInterfaceStateContextMenus.swift index 3ca0ebd966..3f02a444d4 100644 --- a/TelegramUI/ChatInterfaceStateContextMenus.swift +++ b/TelegramUI/ChatInterfaceStateContextMenus.swift @@ -550,9 +550,6 @@ func chatAvailableMessageActions(postbox: Postbox, accountPeerId: PeerId, messag if !isAction { optionsMap[id]!.insert(.forward) } - if message.flags.contains(.Incoming) { - optionsMap[id]!.insert(.report) - } } optionsMap[id]!.insert(.deleteLocally) if !message.flags.contains(.Incoming) { diff --git a/TelegramUI/ChatItemGalleryFooterContentNode.swift b/TelegramUI/ChatItemGalleryFooterContentNode.swift index 5633310210..b418002a0d 100644 --- a/TelegramUI/ChatItemGalleryFooterContentNode.swift +++ b/TelegramUI/ChatItemGalleryFooterContentNode.swift @@ -217,7 +217,7 @@ final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode { func setMessage(_ message: Message) { self.currentMessage = message - self.actionButton.isHidden = message.id.peerId.namespace == Namespaces.Peer.SecretChat || message.containsSecretMedia + self.actionButton.isHidden = message.containsSecretMedia let canDelete: Bool if let peer = message.peers[message.id.peerId] { diff --git a/TelegramUI/ChatListController.swift b/TelegramUI/ChatListController.swift index 10e6dae9b0..56726e2914 100644 --- a/TelegramUI/ChatListController.swift +++ b/TelegramUI/ChatListController.swift @@ -93,9 +93,26 @@ public class ChatListController: TelegramController, UIViewControllerPreviewingD self?.chatListDisplayNode.chatListNode.scrollToPosition(.top) } self.scrollToTopWithTabBar = { [weak self] in - self?.chatListDisplayNode.chatListNode.scrollToPosition(.top) + guard let strongSelf = self else { + return + } + if strongSelf.chatListDisplayNode.searchDisplayController != nil { + strongSelf.deactivateSearch(animated: true) + } else { + strongSelf.chatListDisplayNode.chatListNode.scrollToPosition(.top) + } //.auto for unread navigation } + self.longTapWithTabBar = { [weak self] in + guard let strongSelf = self else { + return + } + if strongSelf.chatListDisplayNode.searchDisplayController != nil { + strongSelf.deactivateSearch(animated: true) + } else { + strongSelf.chatListDisplayNode.chatListNode.scrollToPosition(.auto) + } + } let hasProxy = account.postbox.preferencesView(keys: [PreferencesKeys.proxySettings]) |> map { preferences -> (Bool, Bool) in diff --git a/TelegramUI/ChatMediaInputStickerGridItem.swift b/TelegramUI/ChatMediaInputStickerGridItem.swift index ca181e51e6..4e4b5f4289 100644 --- a/TelegramUI/ChatMediaInputStickerGridItem.swift +++ b/TelegramUI/ChatMediaInputStickerGridItem.swift @@ -194,8 +194,12 @@ final class ChatMediaInputStickerGridItemNode: GridItemNode { } @objc func imageNodeTap(_ recognizer: UITapGestureRecognizer) { + if self.imageNode.layer.animation(forKey: "opacity") != nil { + return + } if let interfaceInteraction = self.interfaceInteraction, let (_, item, _) = self.currentState, case .ended = recognizer.state { interfaceInteraction.sendSticker(.standalone(media: item.file)) + self.imageNode.layer.animateAlpha(from: 0.5, to: 1.0, duration: 1.0) } } diff --git a/TelegramUI/ChatMessageActionSheetController.swift b/TelegramUI/ChatMessageActionSheetController.swift index 83a44d0070..766776c708 100644 --- a/TelegramUI/ChatMessageActionSheetController.swift +++ b/TelegramUI/ChatMessageActionSheetController.swift @@ -10,11 +10,13 @@ final class ChatMessageActionSheetController: ViewController { private let theme: PresentationTheme private let actions: [ChatMessageContextMenuSheetAction] private let dismissed: () -> Void + private weak var associatedController: ViewController? - init(theme: PresentationTheme, actions: [ChatMessageContextMenuSheetAction], dismissed: @escaping () -> Void) { + init(theme: PresentationTheme, actions: [ChatMessageContextMenuSheetAction], dismissed: @escaping () -> Void, associatedController: ViewController?) { self.theme = theme self.actions = actions self.dismissed = dismissed + self.associatedController = associatedController super.init(navigationBarPresentationData: nil) } @@ -24,7 +26,7 @@ final class ChatMessageActionSheetController: ViewController { } override func loadDisplayNode() { - self.displayNode = ChatMessageActionSheetControllerNode(theme: self.theme, actions: self.actions, dismissed: self.dismissed) + self.displayNode = ChatMessageActionSheetControllerNode(theme: self.theme, actions: self.actions, dismissed: self.dismissed, associatedController: self.associatedController) self.displayNodeDidLoad() } diff --git a/TelegramUI/ChatMessageActionSheetControllerNode.swift b/TelegramUI/ChatMessageActionSheetControllerNode.swift index 85dd4ea36d..09933bcaa0 100644 --- a/TelegramUI/ChatMessageActionSheetControllerNode.swift +++ b/TelegramUI/ChatMessageActionSheetControllerNode.swift @@ -71,15 +71,17 @@ final class ChatMessageActionSheetControllerNode: ViewControllerTracingNode { private let actions: [ChatMessageContextMenuSheetAction] private let dismissed: () -> Void + private weak var associatedController: ViewController? private let actionNodes: [MessageActionButtonNode] private let feedback = HapticFeedback() private var validLayout: ContainerViewLayout? - init(theme: PresentationTheme, actions: [ChatMessageContextMenuSheetAction], dismissed: @escaping () -> Void) { + init(theme: PresentationTheme, actions: [ChatMessageContextMenuSheetAction], dismissed: @escaping () -> Void, associatedController: ViewController?) { self.theme = theme self.actions = actions self.dismissed = dismissed + self.associatedController = associatedController self.sideDimNode = ASDisplayNode() self.sideDimNode.backgroundColor = UIColor(white: 0.0, alpha: 0.5) @@ -202,7 +204,13 @@ final class ChatMessageActionSheetControllerNode: ViewControllerTracingNode { return self.inputDimNode.view } } - return nil + if let associatedController = self.associatedController { + let subpoint = self.view.convert(point, to: associatedController.view) + if let result = associatedController.view.hitTest(subpoint, with: event) { + return result + } + } + return self.inputDimNode.view } @objc func actionPressed(_ node: ASDisplayNode) { diff --git a/TelegramUI/GalleryController.swift b/TelegramUI/GalleryController.swift index 24e0c7d029..63dff18142 100644 --- a/TelegramUI/GalleryController.swift +++ b/TelegramUI/GalleryController.swift @@ -88,7 +88,10 @@ private let internalExtensions = Set([ "java", "jpg", "png", - "jpeg" + "jpeg", + "json", + "rs", + "cs" ]) private let internalMimeTypes = Set([ diff --git a/TelegramUI/OverlayPlayerControlsNode.swift b/TelegramUI/OverlayPlayerControlsNode.swift index 95edeed7ac..54f6f4f73b 100644 --- a/TelegramUI/OverlayPlayerControlsNode.swift +++ b/TelegramUI/OverlayPlayerControlsNode.swift @@ -194,11 +194,7 @@ final class OverlayPlayerControlsNode: ASDisplayNode { strongSelf.currentItemId = value?.item.id strongSelf.scrubberNode.ignoreSeekId = nil } - if let itemId = value?.item.id as? PeerMessagesMediaPlaylistItemId, itemId.messageId.peerId.namespace != Namespaces.Peer.SecretChat { - strongSelf.shareNode.isHidden = false - } else { - strongSelf.shareNode.isHidden = true - } + strongSelf.shareNode.isHidden = false var displayData: SharedMediaPlaybackDisplayData? if let value = value { let isPaused: Bool