diff --git a/submodules/SettingsUI/Sources/Data and Storage/DataAndStorageSettingsController.swift b/submodules/SettingsUI/Sources/Data and Storage/DataAndStorageSettingsController.swift index 8ab3cdc71c..2caf610c6a 100644 --- a/submodules/SettingsUI/Sources/Data and Storage/DataAndStorageSettingsController.swift +++ b/submodules/SettingsUI/Sources/Data and Storage/DataAndStorageSettingsController.swift @@ -656,7 +656,7 @@ private func dataAndStorageControllerEntries(state: DataAndStorageControllerStat entries.append(.raiseToListen(presentationData.theme, presentationData.strings.Settings_RaiseToListen, data.mediaInputSettings.enableRaiseToSpeak)) entries.append(.raiseToListenInfo(presentationData.theme, presentationData.strings.Settings_RaiseToListenInfo)) - if let contentSettingsConfiguration = contentSettingsConfiguration, contentSettingsConfiguration.canAdjustSensitiveContent { + if !"".isEmpty, let contentSettingsConfiguration = contentSettingsConfiguration, contentSettingsConfiguration.canAdjustSensitiveContent { entries.append(.sensitiveContent(presentationData.strings.Settings_SensitiveContent, contentSettingsConfiguration.sensitiveContentEnabled)) entries.append(.sensitiveContentInfo(presentationData.strings.Settings_SensitiveContentInfo)) } diff --git a/submodules/TelegramUI/Components/Gifts/GiftOptionsScreen/Sources/GiftOptionsScreen.swift b/submodules/TelegramUI/Components/Gifts/GiftOptionsScreen/Sources/GiftOptionsScreen.swift index 0a91ed47cc..bbdccc2727 100644 --- a/submodules/TelegramUI/Components/Gifts/GiftOptionsScreen/Sources/GiftOptionsScreen.swift +++ b/submodules/TelegramUI/Components/Gifts/GiftOptionsScreen/Sources/GiftOptionsScreen.swift @@ -33,17 +33,20 @@ final class GiftOptionsScreenComponent: Component { let starsContext: StarsContext let peerId: EnginePeer.Id let premiumOptions: [CachedPremiumGiftOption] - + let completion: (() -> Void)? + init( context: AccountContext, starsContext: StarsContext, peerId: EnginePeer.Id, - premiumOptions: [CachedPremiumGiftOption] + premiumOptions: [CachedPremiumGiftOption], + completion: (() -> Void)? ) { self.context = context self.starsContext = starsContext self.peerId = peerId self.premiumOptions = premiumOptions + self.completion = completion } static func ==(lhs: GiftOptionsScreenComponent, rhs: GiftOptionsScreenComponent) -> Bool { @@ -293,7 +296,21 @@ final class GiftOptionsScreenComponent: Component { effectAlignment: .center, action: { [weak self] in if let self, let component = self.component { - controller()?.push(GiftSetupScreen(context: component.context, peerId: component.peerId, gift: gift)) + if let controller = controller() as? GiftOptionsScreen { + let mainController: ViewController + if let parentController = controller.parentController() { + mainController = parentController + } else { + mainController = controller + } + let giftController = GiftSetupScreen( + context: component.context, + peerId: component.peerId, + gift: gift, + completion: component.completion + ) + mainController.push(giftController) + } } }, animateAlpha: false @@ -357,6 +374,8 @@ final class GiftOptionsScreenComponent: Component { let purpose: AppStoreTransactionPurpose = .giftCode(peerIds: [component.peerId], boostPeer: nil, currency: currency, amount: amount) let quantity: Int32 = 1 + let completion = component.completion + let _ = (component.context.engine.payments.canPurchasePremium(purpose: purpose) |> deliverOnMainQueue).start(next: { [weak self] available in if let strongSelf = self { @@ -364,26 +383,30 @@ final class GiftOptionsScreenComponent: Component { if available { strongSelf.purchaseDisposable.set((inAppPurchaseManager.buyProduct(product.storeProduct, quantity: quantity, purpose: purpose) |> deliverOnMainQueue).start(next: { [weak self] status in - guard let self, case .purchased = status, let controller = self.environment?.controller(), let navigationController = controller.navigationController as? NavigationController else { - return - } - - var controllers = navigationController.viewControllers - controllers = controllers.filter { !($0 is GiftOptionsScreen) && !($0 is PeerInfoScreen) && !($0 is ContactSelectionController) } - var foundController = false - for controller in controllers.reversed() { - if let chatController = controller as? ChatController, case .peer(id: component.peerId) = chatController.chatLocation { - chatController.hintPlayNextOutgoingGift() - foundController = true - break + if let completion { + completion() + } else { + guard let self, case .purchased = status, let controller = self.environment?.controller(), let navigationController = controller.navigationController as? NavigationController else { + return } + + var controllers = navigationController.viewControllers + controllers = controllers.filter { !($0 is GiftOptionsScreen) && !($0 is PeerInfoScreen) && !($0 is ContactSelectionController) } + var foundController = false + for controller in controllers.reversed() { + if let chatController = controller as? ChatController, case .peer(id: component.peerId) = chatController.chatLocation { + chatController.hintPlayNextOutgoingGift() + foundController = true + break + } + } + if !foundController { + let chatController = component.context.sharedContext.makeChatController(context: component.context, chatLocation: .peer(id: component.peerId), subject: nil, botStart: nil, mode: .standard(.default), params: nil) + chatController.hintPlayNextOutgoingGift() + controllers.append(chatController) + } + navigationController.setViewControllers(controllers, animated: true) } - if !foundController { - let chatController = component.context.sharedContext.makeChatController(context: component.context, chatLocation: .peer(id: component.peerId), subject: nil, botStart: nil, mode: .standard(.default), params: nil) - chatController.hintPlayNextOutgoingGift() - controllers.append(chatController) - } - navigationController.setViewControllers(controllers, animated: true) }, error: { [weak self] error in guard let self, let controller = self.environment?.controller() else { return @@ -454,7 +477,6 @@ final class GiftOptionsScreenComponent: Component { self.backgroundColor = environment.theme.list.blocksBackgroundColor } -// let presentationData = component.context.sharedContext.currentPresentationData.with { $0 } let theme = environment.theme let strings = environment.strings @@ -651,7 +673,16 @@ final class GiftOptionsScreenComponent: Component { } let introController = component.context.sharedContext.makePremiumIntroController(context: component.context, source: .settings, forceDark: false, dismissed: nil) introController.navigationPresentation = .modal - environment.controller()?.push(introController) + + if let controller = environment.controller() as? GiftOptionsScreen { + let mainController: ViewController + if let parentController = controller.parentController() { + mainController = parentController + } else { + mainController = controller + } + mainController.push(introController) + } } )), environment: {}, @@ -814,7 +845,16 @@ final class GiftOptionsScreenComponent: Component { } let introController = component.context.sharedContext.makeStarsIntroScreen(context: component.context) introController.navigationPresentation = .modal - environment.controller()?.push(introController) + + if let controller = environment.controller() as? GiftOptionsScreen { + let mainController: ViewController + if let parentController = controller.parentController() { + mainController = parentController + } else { + mainController = controller + } + mainController.push(introController) + } } )), environment: {}, @@ -835,17 +875,25 @@ final class GiftOptionsScreenComponent: Component { id: AnyHashable(StarsFilter.all.rawValue), title: "All Gifts" )) - tabSelectorItems.append(TabSelectorComponent.Item( - id: AnyHashable(StarsFilter.limited.rawValue), - title: "Limited" - )) + var hasLimited = false var starsAmountsSet = Set() if let starGifts = self.state?.starGifts { for product in starGifts { starsAmountsSet.insert(product.price) + if product.availability != nil { + hasLimited = true + } } } + + if hasLimited { + tabSelectorItems.append(TabSelectorComponent.Item( + id: AnyHashable(StarsFilter.limited.rawValue), + title: "Limited" + )) + } + let starsAmounts = Array(starsAmountsSet).sorted() for amount in starsAmounts { tabSelectorItems.append(TabSelectorComponent.Item( @@ -1014,12 +1062,16 @@ final class GiftOptionsScreenComponent: Component { open class GiftOptionsScreen: ViewControllerComponentContainer, GiftOptionsScreenProtocol { private let context: AccountContext + public var parentController: () -> ViewController? = { + return nil + } + public init( context: AccountContext, starsContext: StarsContext, peerId: EnginePeer.Id, premiumOptions: [CachedPremiumGiftOption], - completion: @escaping () -> Void = {} + completion: (() -> Void)? = nil ) { self.context = context @@ -1027,7 +1079,8 @@ open class GiftOptionsScreen: ViewControllerComponentContainer, GiftOptionsScree context: context, starsContext: starsContext, peerId: peerId, - premiumOptions: premiumOptions + premiumOptions: premiumOptions, + completion: completion ), navigationBarAppearance: .none, theme: .default, updatedPresentationData: nil) self.navigationItem.backBarButtonItem = UIBarButtonItem(title: self.context.sharedContext.currentPresentationData.with { $0 }.strings.Common_Back, style: .plain, target: nil, action: nil) diff --git a/submodules/TelegramUI/Components/Gifts/GiftSetupScreen/Sources/GiftSetupScreen.swift b/submodules/TelegramUI/Components/Gifts/GiftSetupScreen/Sources/GiftSetupScreen.swift index ac85c06f65..f34017f111 100644 --- a/submodules/TelegramUI/Components/Gifts/GiftSetupScreen/Sources/GiftSetupScreen.swift +++ b/submodules/TelegramUI/Components/Gifts/GiftSetupScreen/Sources/GiftSetupScreen.swift @@ -34,15 +34,18 @@ final class GiftSetupScreenComponent: Component { let context: AccountContext let peerId: EnginePeer.Id let gift: StarGift - + let completion: (() -> Void)? + init( context: AccountContext, peerId: EnginePeer.Id, - gift: StarGift + gift: StarGift, + completion: (() -> Void)? = nil ) { self.context = context self.peerId = peerId self.gift = gift + self.completion = completion } static func ==(lhs: GiftSetupScreenComponent, rhs: GiftSetupScreenComponent) -> Bool { @@ -202,6 +205,8 @@ final class GiftSetupScreenComponent: Component { return .single(nil) } + let completion = component.completion + let _ = (inputData |> deliverOnMainQueue).startStandalone(next: { [weak self] inputData in guard let inputData else { @@ -209,26 +214,34 @@ final class GiftSetupScreenComponent: Component { } let _ = (component.context.engine.payments.sendStarsPaymentForm(formId: inputData.form.id, source: source) |> deliverOnMainQueue).start(next: { [weak self] result in - guard let self, let controller = self.environment?.controller(), let navigationController = controller.navigationController as? NavigationController else { - return - } - - var controllers = navigationController.viewControllers - controllers = controllers.filter { !($0 is GiftSetupScreen) && !($0 is GiftOptionsScreenProtocol) && !($0 is PeerInfoScreen) && !($0 is ContactSelectionController) } - var foundController = false - for controller in controllers.reversed() { - if let chatController = controller as? ChatController, case .peer(id: component.peerId) = chatController.chatLocation { - chatController.hintPlayNextOutgoingGift() - foundController = true - break + if let completion { + completion() + + if let self, let controller = self.environment?.controller() { + controller.dismiss() } + } else { + guard let self, let controller = self.environment?.controller(), let navigationController = controller.navigationController as? NavigationController else { + return + } + + var controllers = navigationController.viewControllers + controllers = controllers.filter { !($0 is GiftSetupScreen) && !($0 is GiftOptionsScreenProtocol) && !($0 is PeerInfoScreen) && !($0 is ContactSelectionController) } + var foundController = false + for controller in controllers.reversed() { + if let chatController = controller as? ChatController, case .peer(id: component.peerId) = chatController.chatLocation { + chatController.hintPlayNextOutgoingGift() + foundController = true + break + } + } + if !foundController { + let chatController = component.context.sharedContext.makeChatController(context: component.context, chatLocation: .peer(id: component.peerId), subject: nil, botStart: nil, mode: .standard(.default), params: nil) + chatController.hintPlayNextOutgoingGift() + controllers.append(chatController) + } + navigationController.setViewControllers(controllers, animated: true) } - if !foundController { - let chatController = component.context.sharedContext.makeChatController(context: component.context, chatLocation: .peer(id: component.peerId), subject: nil, botStart: nil, mode: .standard(.default), params: nil) - chatController.hintPlayNextOutgoingGift() - controllers.append(chatController) - } - navigationController.setViewControllers(controllers, animated: true) }) }) } @@ -1028,18 +1041,19 @@ public final class GiftSetupScreen: ViewControllerComponentContainer { public init( context: AccountContext, peerId: EnginePeer.Id, - gift: StarGift + gift: StarGift, + completion: (() -> Void)? = nil ) { self.context = context super.init(context: context, component: GiftSetupScreenComponent( context: context, peerId: peerId, - gift: gift + gift: gift, + completion: completion ), navigationBarAppearance: .default, theme: .default, updatedPresentationData: nil) self.title = "" - //self.navigationItem.backBarButtonItem = UIBarButtonItem(title: presentationData.strings.Common_Back, style: .plain, target: nil, action: nil) self.scrollToTop = { [weak self] in guard let self, let componentView = self.node.hostView.componentView as? GiftSetupScreenComponent.View else { diff --git a/submodules/TelegramUI/Components/PeerInfo/PeerInfoVisualMediaPaneNode/Sources/PeerInfoGiftsPaneNode.swift b/submodules/TelegramUI/Components/PeerInfo/PeerInfoVisualMediaPaneNode/Sources/PeerInfoGiftsPaneNode.swift index ff9d282d3e..3d1c8d7119 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PeerInfoVisualMediaPaneNode/Sources/PeerInfoGiftsPaneNode.swift +++ b/submodules/TelegramUI/Components/PeerInfo/PeerInfoVisualMediaPaneNode/Sources/PeerInfoGiftsPaneNode.swift @@ -38,11 +38,12 @@ public final class PeerInfoGiftsPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScr private let backgroundNode: ASDisplayNode private let scrollNode: ASScrollNode - private var unlockBackground: UIImageView? + private var unlockBackground: ASDisplayNode? + private var unlockSeparator: ASDisplayNode? private var unlockText: ComponentView? private var unlockButton: SolidRoundedButtonNode? - private var currentParams: (size: CGSize, sideInset: CGFloat, bottomInset: CGFloat, isScrollingLockedAtTop: Bool, presentationData: PresentationData)? + private var currentParams: (size: CGSize, sideInset: CGFloat, bottomInset: CGFloat, visibleHeight: CGFloat, isScrollingLockedAtTop: Bool, presentationData: PresentationData)? private var theme: PresentationTheme? private let presentationDataPromise = Promise() @@ -257,7 +258,8 @@ public final class PeerInfoGiftsPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScr self.theme = presentationData.theme let unlockText: ComponentView - let unlockBackground: UIImageView + let unlockBackground: ASDisplayNode + let unlockSeparator: ASDisplayNode let unlockButton: SolidRoundedButtonNode if let current = self.unlockText { unlockText = current @@ -269,11 +271,18 @@ public final class PeerInfoGiftsPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScr if let current = self.unlockBackground { unlockBackground = current } else { - unlockBackground = UIImageView() - unlockBackground.contentMode = .scaleToFill - self.view.addSubview(unlockBackground) + unlockBackground = ASDisplayNode() + self.addSubnode(unlockBackground) self.unlockBackground = unlockBackground } + + if let current = self.unlockSeparator { + unlockSeparator = current + } else { + unlockSeparator = ASDisplayNode() + self.addSubnode(unlockSeparator) + self.unlockSeparator = unlockSeparator + } if let current = self.unlockButton { unlockButton = current @@ -291,9 +300,8 @@ public final class PeerInfoGiftsPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScr } if themeUpdated { - let topColor = presentationData.theme.list.plainBackgroundColor.withAlphaComponent(0.0) - let bottomColor = presentationData.theme.list.plainBackgroundColor - unlockBackground.image = generateGradientImage(size: CGSize(width: 1.0, height: 170.0), colors: [topColor, bottomColor, bottomColor], locations: [0.0, 0.3, 1.0]) + unlockBackground.backgroundColor = presentationData.theme.rootController.tabBar.backgroundColor + unlockSeparator.backgroundColor = presentationData.theme.rootController.tabBar.separatorColor unlockButton.updateTheme(SolidRoundedButtonTheme(theme: presentationData.theme)) } @@ -305,15 +313,16 @@ public final class PeerInfoGiftsPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScr return nil }) - let scrollOffset: CGFloat = min(0.0, self.scrollNode.view.contentOffset.y + bottomInset + 80.0) - - transition.setFrame(view: unlockBackground, frame: CGRect(x: 0.0, y: size.height - bottomInset - 170.0 + scrollOffset, width: size.width, height: bottomInset + 170.0)) - + let scrollOffset: CGFloat = max(0.0, size.height - params.visibleHeight) + let buttonSideInset = sideInset + 16.0 let buttonSize = CGSize(width: size.width - buttonSideInset * 2.0, height: 50.0) - transition.setFrame(view: unlockButton.view, frame: CGRect(origin: CGPoint(x: buttonSideInset, y: size.height - bottomInset - buttonSize.height - 26.0), size: buttonSize)) + transition.setFrame(view: unlockButton.view, frame: CGRect(origin: CGPoint(x: buttonSideInset, y: size.height - bottomInset - buttonSize.height - scrollOffset), size: buttonSize)) let _ = unlockButton.updateLayout(width: buttonSize.width, transition: .immediate) + transition.setFrame(view: unlockBackground.view, frame: CGRect(x: 0.0, y: size.height - bottomInset - buttonSize.height - 8.0 - scrollOffset, width: size.width, height: bottomInset + buttonSize.height + 8.0)) + transition.setFrame(view: unlockSeparator.view, frame: CGRect(x: 0.0, y: size.height - bottomInset - buttonSize.height - 8.0 - scrollOffset, width: size.width, height: UIScreenPixel)) + let unlockSize = unlockText.update( transition: .immediate, component: AnyComponent( @@ -364,7 +373,7 @@ public final class PeerInfoGiftsPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScr } public func update(size: CGSize, topInset: CGFloat, sideInset: CGFloat, bottomInset: CGFloat, deviceMetrics: DeviceMetrics, visibleHeight: CGFloat, isScrollingLockedAtTop: Bool, expandProgress: CGFloat, navigationHeight: CGFloat, presentationData: PresentationData, synchronous: Bool, transition: ContainedViewLayoutTransition) { - self.currentParams = (size, sideInset, bottomInset, isScrollingLockedAtTop, presentationData) + self.currentParams = (size, sideInset, bottomInset, visibleHeight, isScrollingLockedAtTop, presentationData) self.presentationDataPromise.set(.single(presentationData)) self.backgroundNode.backgroundColor = presentationData.theme.list.blocksBackgroundColor diff --git a/submodules/TelegramUI/Components/PremiumGiftAttachmentScreen/Sources/PremiumGiftAttachmentScreen.swift b/submodules/TelegramUI/Components/PremiumGiftAttachmentScreen/Sources/PremiumGiftAttachmentScreen.swift index bada8afbba..f9ab8d7db7 100644 --- a/submodules/TelegramUI/Components/PremiumGiftAttachmentScreen/Sources/PremiumGiftAttachmentScreen.swift +++ b/submodules/TelegramUI/Components/PremiumGiftAttachmentScreen/Sources/PremiumGiftAttachmentScreen.swift @@ -11,9 +11,6 @@ import GiftOptionsScreen public class PremiumGiftAttachmentScreen: GiftOptionsScreen, AttachmentContainable { public var requestAttachmentMenuExpansion: () -> Void = {} public var updateNavigationStack: (@escaping ([AttachmentContainable]) -> ([AttachmentContainable], AttachmentMediaPickerContext?)) -> Void = { _ in } - public var parentController: () -> ViewController? = { - return nil - } public var updateTabBarAlpha: (CGFloat, ContainedViewLayoutTransition) -> Void = { _, _ in } public var updateTabBarVisibility: (Bool, ContainedViewLayoutTransition) -> Void = { _, _ in } public var cancelPanGesture: () -> Void = { }