diff --git a/submodules/AccountContext/Sources/AccountContext.swift b/submodules/AccountContext/Sources/AccountContext.swift index 372ea55a43..0d2b212a0d 100644 --- a/submodules/AccountContext/Sources/AccountContext.swift +++ b/submodules/AccountContext/Sources/AccountContext.swift @@ -302,6 +302,7 @@ public enum ResolvedUrl { case story(peerId: PeerId, id: Int32) case boost(peerId: PeerId, status: ChannelBoostStatus?, myBoostStatus: MyBoostStatus?) case premiumGiftCode(slug: String) + case premiumMultiGift(reference: String?) } public enum ResolveUrlResult { @@ -941,7 +942,7 @@ public protocol SharedAccountContext: AnyObject { func makePremiumIntroController(context: AccountContext, source: PremiumIntroSource, forceDark: Bool, dismissed: (() -> Void)?) -> ViewController func makePremiumDemoController(context: AccountContext, subject: PremiumDemoSubject, action: @escaping () -> Void) -> ViewController func makePremiumLimitController(context: AccountContext, subject: PremiumLimitSubject, count: Int32, forceDark: Bool, cancel: @escaping () -> Void, action: @escaping () -> Bool) -> ViewController - func makePremiumGiftController(context: AccountContext) -> ViewController + func makePremiumGiftController(context: AccountContext, source: PremiumGiftSource) -> ViewController func makeStickerPackScreen(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal)?, mainStickerPack: StickerPackReference, stickerPacks: [StickerPackReference], loadedStickerPacks: [LoadedStickerPack], parentNavigationController: NavigationController?, sendSticker: ((FileMediaReference, UIView, CGRect) -> Bool)?) -> ViewController @@ -1008,6 +1009,15 @@ public enum PremiumIntroSource { case wallpapers } +public enum PremiumGiftSource: Equatable { + case profile + case attachMenu + case settings + case chatList + case channelBoost + case deeplink(String?) +} + public enum PremiumDemoSubject { case doubleLimits case moreUpload diff --git a/submodules/ChatListUI/Sources/Node/ChatListNode.swift b/submodules/ChatListUI/Sources/Node/ChatListNode.swift index 9f7a21fb85..44aa7d5a20 100644 --- a/submodules/ChatListUI/Sources/Node/ChatListNode.swift +++ b/submodules/ChatListUI/Sources/Node/ChatListNode.swift @@ -1612,7 +1612,7 @@ public final class ChatListNode: ListView { guard let self else { return } - let controller = self.context.sharedContext.makePremiumGiftController(context: self.context) + let controller = self.context.sharedContext.makePremiumGiftController(context: self.context, source: .chatList) self.push?(controller) }, openActiveSessions: { [weak self] in guard let self else { diff --git a/submodules/PremiumUI/Sources/PremiumBoostScreen.swift b/submodules/PremiumUI/Sources/PremiumBoostScreen.swift index 6a27077faf..6121857076 100644 --- a/submodules/PremiumUI/Sources/PremiumBoostScreen.swift +++ b/submodules/PremiumUI/Sources/PremiumBoostScreen.swift @@ -236,7 +236,7 @@ public func PremiumBoostScreen( actions: [ TextAlertAction(type: .defaultAction, title: presentationData.strings.ChannelBoost_MoreBoosts_Gift, action: { dismissImpl?() - let controller = context.sharedContext.makePremiumGiftController(context: context) + let controller = context.sharedContext.makePremiumGiftController(context: context, source: .channelBoost) pushController(controller) }), TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Close, action: {}) diff --git a/submodules/PremiumUI/Sources/PremiumGiftScreen.swift b/submodules/PremiumUI/Sources/PremiumGiftScreen.swift index b0f01da41f..979bfadb08 100644 --- a/submodules/PremiumUI/Sources/PremiumGiftScreen.swift +++ b/submodules/PremiumUI/Sources/PremiumGiftScreen.swift @@ -21,11 +21,7 @@ import TextFormat import UniversalMediaPlayer import InstantPageCache -public enum PremiumGiftSource: Equatable { - case profile - case attachMenu - case settings - +extension PremiumGiftSource { var identifier: String? { switch self { case .profile: @@ -34,6 +30,16 @@ public enum PremiumGiftSource: Equatable { return "attach" case .settings: return "settings" + case .chatList: + return "chats" + case .channelBoost: + return "channel_boost" + case let .deeplink(reference): + if let reference = reference { + return "deeplink_\(reference)" + } else { + return "deeplink" + } } } } diff --git a/submodules/PremiumUI/Sources/ReplaceBoostScreen.swift b/submodules/PremiumUI/Sources/ReplaceBoostScreen.swift index 048e0fe72a..453fdbc7ed 100644 --- a/submodules/PremiumUI/Sources/ReplaceBoostScreen.swift +++ b/submodules/PremiumUI/Sources/ReplaceBoostScreen.swift @@ -880,7 +880,7 @@ public class ReplaceBoostScreen: ViewController { } let navigationController = self.navigationController self.dismiss(animated: true, completion: { - let giftController = context.sharedContext.makePremiumGiftController(context: context) + let giftController = context.sharedContext.makePremiumGiftController(context: context, source: .channelBoost) navigationController?.pushViewController(giftController, animated: true) }) } diff --git a/submodules/TelegramUI/Components/Chat/ChatRecentActionsController/Sources/ChatRecentActionsControllerNode.swift b/submodules/TelegramUI/Components/Chat/ChatRecentActionsController/Sources/ChatRecentActionsControllerNode.swift index ed49c75dfb..7e6df9da57 100644 --- a/submodules/TelegramUI/Components/Chat/ChatRecentActionsController/Sources/ChatRecentActionsControllerNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatRecentActionsController/Sources/ChatRecentActionsControllerNode.swift @@ -1090,6 +1090,8 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode { break case .premiumGiftCode: break + case .premiumMultiGift: + break } } })) diff --git a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift index 7fe54cfbe3..794ec2aa17 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift @@ -8681,9 +8681,10 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro case .language: push(LocalizationListController(context: self.context)) case .premium: - self.controller?.push(PremiumIntroScreen(context: self.context, modal: false, source: .settings)) + let controller = self.context.sharedContext.makePremiumIntroController(context: self.context, source: .settings, forceDark: false, dismissed: nil) + self.controller?.push(controller) case .premiumGift: - let controller = self.context.sharedContext.makePremiumGiftController(context: self.context) + let controller = self.context.sharedContext.makePremiumGiftController(context: self.context, source: .settings) self.controller?.push(controller) case .stickers: if let settings = self.data?.globalSettings { diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetViewListComponent.swift b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetViewListComponent.swift index ddbb3b83ee..e0acaffd27 100644 --- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetViewListComponent.swift +++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetViewListComponent.swift @@ -584,6 +584,9 @@ final class StoryItemSetViewListComponent: Component { guard let self, let component = self.component else { return } + guard peer.id != component.context.account.peerId else { + return + } if let messageId { component.openMessage(peer, messageId) } else if let storyItem, let sourceView { @@ -592,9 +595,9 @@ final class StoryItemSetViewListComponent: Component { component.openPeer(peer) } }, - contextAction: { peer, view, gesture in + contextAction: item.peer.id != component.context.account.peerId ? { peer, view, gesture in component.peerContextAction(peer, view, gesture) - }, + } : nil, openStories: { [weak self] peer, avatarNode in guard let self, let component = self.component else { return diff --git a/submodules/TelegramUI/Components/Stories/StoryFooterPanelComponent/Sources/StoryFooterPanelComponent.swift b/submodules/TelegramUI/Components/Stories/StoryFooterPanelComponent/Sources/StoryFooterPanelComponent.swift index 1b1b481aa4..39d580dace 100644 --- a/submodules/TelegramUI/Components/Stories/StoryFooterPanelComponent/Sources/StoryFooterPanelComponent.swift +++ b/submodules/TelegramUI/Components/Stories/StoryFooterPanelComponent/Sources/StoryFooterPanelComponent.swift @@ -400,7 +400,7 @@ public final class StoryFooterPanelComponent: Component { var displayViewLists = false if case let .channel(channel) = component.peer, channel.flags.contains(.isCreator) || component.canViewChannelStats { - displayViewLists = reactionCount != 0 || forwardCount != 0 + displayViewLists = true } else { displayViewLists = viewCount != 0 && !component.isChannel } diff --git a/submodules/TelegramUI/Sources/OpenResolvedUrl.swift b/submodules/TelegramUI/Sources/OpenResolvedUrl.swift index d7ba72c945..d304b4a47d 100644 --- a/submodules/TelegramUI/Sources/OpenResolvedUrl.swift +++ b/submodules/TelegramUI/Sources/OpenResolvedUrl.swift @@ -581,7 +581,13 @@ func openResolvedUrlImpl( } case let .premiumOffer(reference): dismissInput() - let controller = PremiumIntroScreen(context: context, source: .deeplink(reference)) + let controller = context.sharedContext.makePremiumIntroController(context: context, source: .deeplink(reference), forceDark: false, dismissed: nil) + if let navigationController = navigationController { + navigationController.pushViewController(controller, animated: true) + } + case let .premiumMultiGift(reference): + dismissInput() + let controller = context.sharedContext.makePremiumGiftController(context: context, source: .deeplink(reference)) if let navigationController = navigationController { navigationController.pushViewController(controller, animated: true) } diff --git a/submodules/TelegramUI/Sources/OpenUrl.swift b/submodules/TelegramUI/Sources/OpenUrl.swift index 8c0fb3a87a..d298cc0397 100644 --- a/submodules/TelegramUI/Sources/OpenUrl.swift +++ b/submodules/TelegramUI/Sources/OpenUrl.swift @@ -842,6 +842,20 @@ func openExternalUrlImpl(context: AccountContext, urlContext: OpenURLContext, ur } } handleResolvedUrl(.premiumOffer(reference: reference)) + } else if parsedUrl.host == "premium_multigift" { + var reference: String? + if let components = URLComponents(string: "/?" + query) { + if let queryItems = components.queryItems { + for queryItem in queryItems { + if let value = queryItem.value { + if queryItem.name == "ref" { + reference = value + } + } + } + } + } + handleResolvedUrl(.premiumMultiGift(reference: reference)) } else if parsedUrl.host == "addlist" { if let components = URLComponents(string: "/?" + query) { var slug: String? diff --git a/submodules/TelegramUI/Sources/SharedAccountContext.swift b/submodules/TelegramUI/Sources/SharedAccountContext.swift index 1a52e57dc4..0afff5e7bc 100644 --- a/submodules/TelegramUI/Sources/SharedAccountContext.swift +++ b/submodules/TelegramUI/Sources/SharedAccountContext.swift @@ -1805,10 +1805,12 @@ public final class SharedAccountContextImpl: SharedAccountContext { } public func makePremiumIntroController(context: AccountContext, source: PremiumIntroSource, forceDark: Bool, dismissed: (() -> Void)?) -> ViewController { + var modal = true let mappedSource: PremiumSource switch source { case .settings: mappedSource = .settings + modal = false case .stickers: mappedSource = .stickers case .reactions: @@ -1872,7 +1874,7 @@ public final class SharedAccountContextImpl: SharedAccountContext { case .wallpapers: mappedSource = .wallpapers } - let controller = PremiumIntroScreen(context: context, source: mappedSource, forceDark: forceDark) + let controller = PremiumIntroScreen(context: context, modal: modal, source: mappedSource, forceDark: forceDark) controller.wasDismissed = dismissed return controller } @@ -1949,16 +1951,16 @@ public final class SharedAccountContextImpl: SharedAccountContext { return PremiumLimitScreen(context: context, subject: mappedSubject, count: count, forceDark: forceDark, cancel: cancel, action: action) } - public func makePremiumGiftController(context: AccountContext) -> ViewController { + public func makePremiumGiftController(context: AccountContext, source: PremiumGiftSource) -> ViewController { let options = Promise<[PremiumGiftCodeOption]>() options.set(context.engine.payments.premiumGiftCodeOptions(peerId: nil)) - + let presentationData = context.sharedContext.currentPresentationData.with { $0 } let limit: Int32 = 10 var reachedLimitImpl: ((Int32) -> Void)? let controller = context.sharedContext.makeContactMultiselectionController(ContactMultiselectionControllerParams(context: context, mode: .premiumGifting, options: [], isPeerEnabled: { peer in - if case let .user(user) = peer, user.botInfo == nil { + if case let .user(user) = peer, user.botInfo == nil && !peer.isService && !user.flags.contains(.isSupport) { return true } else { return false @@ -1990,11 +1992,14 @@ public final class SharedAccountContextImpl: SharedAccountContext { } }) } + guard !peerIds.isEmpty else { + return + } let mappedOptions = options.filter { $0.users == 1 }.map { CachedPremiumGiftOption(months: $0.months, currency: $0.currency, amount: $0.amount, botUrl: "", storeProductId: $0.storeProductId) } var pushImpl: ((ViewController) -> Void)? var filterImpl: (() -> Void)? - let giftController = PremiumGiftScreen(context: context, peerIds: peerIds, options: mappedOptions, source: .settings, pushController: { c in + let giftController = PremiumGiftScreen(context: context, peerIds: peerIds, options: mappedOptions, source: source, pushController: { c in pushImpl?(c) }, completion: { filterImpl?()