diff --git a/submodules/AccountContext/Sources/AccountContext.swift b/submodules/AccountContext/Sources/AccountContext.swift index f6faf2f539..550c56c2f0 100644 --- a/submodules/AccountContext/Sources/AccountContext.swift +++ b/submodules/AccountContext/Sources/AccountContext.swift @@ -1062,17 +1062,19 @@ public protocol AccountContext: AnyObject { public struct PremiumConfiguration { public static var defaultValue: PremiumConfiguration { - return PremiumConfiguration(isPremiumDisabled: false, showPremiumGiftInAttachMenu: false, showPremiumGiftInTextField: false) + return PremiumConfiguration(isPremiumDisabled: false, showPremiumGiftInAttachMenu: false, showPremiumGiftInTextField: false, giveawayGiftsPurchaseAvailable: false) } public let isPremiumDisabled: Bool public let showPremiumGiftInAttachMenu: Bool public let showPremiumGiftInTextField: Bool + public let giveawayGiftsPurchaseAvailable: Bool - fileprivate init(isPremiumDisabled: Bool, showPremiumGiftInAttachMenu: Bool, showPremiumGiftInTextField: Bool) { + fileprivate init(isPremiumDisabled: Bool, showPremiumGiftInAttachMenu: Bool, showPremiumGiftInTextField: Bool, giveawayGiftsPurchaseAvailable: Bool) { self.isPremiumDisabled = isPremiumDisabled self.showPremiumGiftInAttachMenu = showPremiumGiftInAttachMenu self.showPremiumGiftInTextField = showPremiumGiftInTextField + self.giveawayGiftsPurchaseAvailable = giveawayGiftsPurchaseAvailable } public static func with(appConfiguration: AppConfiguration) -> PremiumConfiguration { @@ -1080,7 +1082,8 @@ public struct PremiumConfiguration { return PremiumConfiguration( isPremiumDisabled: data["premium_purchase_blocked"] as? Bool ?? false, showPremiumGiftInAttachMenu: data["premium_gift_attach_menu_icon"] as? Bool ?? false, - showPremiumGiftInTextField: data["premium_gift_text_field_icon"] as? Bool ?? false + showPremiumGiftInTextField: data["premium_gift_text_field_icon"] as? Bool ?? false, + giveawayGiftsPurchaseAvailable: data["giveaway_gifts_purchase_available"] as? Bool ?? false ) } else { return .defaultValue diff --git a/submodules/PremiumUI/Sources/PremiumLimitScreen.swift b/submodules/PremiumUI/Sources/PremiumLimitScreen.swift index eaf1617170..6e5a18f43c 100644 --- a/submodules/PremiumUI/Sources/PremiumLimitScreen.swift +++ b/submodules/PremiumUI/Sources/PremiumLimitScreen.swift @@ -1439,7 +1439,7 @@ private final class LimitSheetContent: CombinedComponent { ) var additionalContentHeight: CGFloat = 0.0 - if case let .storiesChannelBoost(_, _, _, _, _, link, _) = component.subject, link != nil { + if case let .storiesChannelBoost(_, _, _, _, _, link, _) = component.subject, link != nil, let openGift = component.openGift { let orText = orText.update( component: MultilineTextComponent(text: .plain(NSAttributedString(string: "or", font: Font.regular(15.0), textColor: textColor.withAlphaComponent(0.8), paragraphAlignment: .center))), availableSize: CGSize(width: context.availableSize.width - sideInset * 2.0, height: context.availableSize.height), @@ -1477,7 +1477,6 @@ private final class LimitSheetContent: CombinedComponent { if let range = giftAttributedString.string.range(of: ">"), let chevronImage = state.cachedChevronImage?.0 { giftAttributedString.addAttribute(.attachment, value: chevronImage, range: NSRange(range, in: giftAttributedString.string)) } - let openGift = component.openGift let giftText = giftText.update( component: BalancedTextComponent( text: .plain(giftAttributedString), @@ -1485,15 +1484,11 @@ private final class LimitSheetContent: CombinedComponent { maximumNumberOfLines: 0, lineSpacing: 0.1, highlightColor: linkColor.withAlphaComponent(0.2), - highlightAction: { attributes in - if let _ = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.URL)] { - return NSAttributedString.Key(rawValue: TelegramTextAttributes.URL) - } else { - return nil - } + highlightAction: { _ in + return nil }, tapAction: { _, _ in - openGift?() + openGift() } ), availableSize: CGSize(width: context.availableSize.width - textSideInset * 2.0, height: context.availableSize.height), @@ -1517,7 +1512,9 @@ private final class LimitSheetContent: CombinedComponent { if link != nil { height += 66.0 - height += 100.0 + if let _ = component.openGift { + height += 100.0 + } } else { if isCurrent { height -= 53.0 diff --git a/submodules/StatisticsUI/Sources/ChannelStatsController.swift b/submodules/StatisticsUI/Sources/ChannelStatsController.swift index d155a4a864..a9782d1b48 100644 --- a/submodules/StatisticsUI/Sources/ChannelStatsController.swift +++ b/submodules/StatisticsUI/Sources/ChannelStatsController.swift @@ -663,7 +663,7 @@ private struct ChannelStatsControllerState: Equatable { } -private func channelStatsControllerEntries(state: ChannelStatsControllerState, peer: EnginePeer?, data: ChannelStats?, messages: [Message]?, interactions: [MessageId: ChannelStatsMessageInteractions]?, boostData: ChannelBoostStatus?, boostersState: ChannelBoostersContext.State?, giftsState: ChannelBoostersContext.State?, presentationData: PresentationData) -> [StatsEntry] { +private func channelStatsControllerEntries(state: ChannelStatsControllerState, peer: EnginePeer?, data: ChannelStats?, messages: [Message]?, interactions: [MessageId: ChannelStatsMessageInteractions]?, boostData: ChannelBoostStatus?, boostersState: ChannelBoostersContext.State?, giftsState: ChannelBoostersContext.State?, presentationData: PresentationData, giveawayAvailable: Bool) -> [StatsEntry] { var entries: [StatsEntry] = [] switch state.section { @@ -822,8 +822,10 @@ private func channelStatsControllerEntries(state: ChannelStatsControllerState, p entries.append(.boostLink(presentationData.theme, boostData.url)) entries.append(.boostLinkInfo(presentationData.theme, presentationData.strings.Stats_Boosts_LinkInfo)) - entries.append(.gifts(presentationData.theme, "Get Boosts via Gifts")) - entries.append(.giftsInfo(presentationData.theme, "Get more boosts for your channel by gifting Premium to your subscribers.")) + if giveawayAvailable { + entries.append(.gifts(presentationData.theme, "Get Boosts via Gifts")) + entries.append(.giftsInfo(presentationData.theme, "Get more boosts for your channel by gifting Premium to your subscribers.")) + } } } @@ -837,6 +839,8 @@ public func channelStatsController(context: AccountContext, updatedPresentationD statePromise.set(stateValue.modify { f($0) }) } + let premiumConfiguration = PremiumConfiguration.with(appConfiguration: context.currentAppConfiguration.with { $0 }) + var openMessageStatsImpl: ((MessageId) -> Void)? var contextActionImpl: ((MessageId, ASDisplayNode, ContextGesture?) -> Void)? @@ -998,11 +1002,9 @@ public func channelStatsController(context: AccountContext, updatedPresentationD map[interactions.messageId] = interactions return map } - - - + let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: .sectionControl([presentationData.strings.Stats_Statistics, presentationData.strings.Stats_Boosts], state.section == .boosts ? 1 : 0), leftNavigationButton: nil, rightNavigationButton: nil, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back), animateChanges: true) - let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: channelStatsControllerEntries(state: state, peer: peer, data: data, messages: messages, interactions: interactions, boostData: boostData, boostersState: boostersState, giftsState: giftsState, presentationData: presentationData), style: .blocks, emptyStateItem: emptyStateItem, crossfadeState: previous == nil, animateChanges: false) + let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: channelStatsControllerEntries(state: state, peer: peer, data: data, messages: messages, interactions: interactions, boostData: boostData, boostersState: boostersState, giftsState: giftsState, presentationData: presentationData, giveawayAvailable: premiumConfiguration.giveawayGiftsPurchaseAvailable), style: .blocks, emptyStateItem: emptyStateItem, crossfadeState: previous == nil, animateChanges: false) return (controllerState, (listState, arguments)) } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Peers/UpdatePeerInfo.swift b/submodules/TelegramCore/Sources/TelegramEngine/Peers/UpdatePeerInfo.swift index d5426b3767..f91d9d3fce 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Peers/UpdatePeerInfo.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Peers/UpdatePeerInfo.swift @@ -95,41 +95,35 @@ public enum UpdatePeerNameColorAndEmojiError { } func _internal_updatePeerNameColorAndEmoji(account: Account, peerId: EnginePeer.Id, nameColor: PeerNameColor, backgroundEmojiId: Int64?) -> Signal { - let accountPeerId = account.peerId - - return account.postbox.transaction { transaction -> Signal in - guard let peer = transaction.getPeer(peerId) as? TelegramChannel else { - return .complete() - } - updatePeersCustom(transaction: transaction, peers: [peer.withUpdatedNameColor(nameColor).withUpdatedBackgroundEmojiId(backgroundEmojiId)], update: { _, updated in - return updated - }) - return .single(peer) - } - |> switchToLatest - |> castError(UpdatePeerNameColorAndEmojiError.self) - |> mapToSignal { peer -> Signal in - if let peer = peer as? TelegramChannel, let inputChannel = apiInputChannel(peer) { - let flags: Int32 = (1 << 0) - return account.network.request(Api.functions.channels.updateColor(flags: flags, channel: inputChannel, color: nameColor.rawValue, backgroundEmojiId: backgroundEmojiId ?? 0)) - |> mapError { error -> UpdatePeerNameColorAndEmojiError in - if error.errorDescription.hasPrefix("BOOSTS_REQUIRED") { - return .channelBoostRequired - } - return .generic - } - |> mapToSignal { result -> Signal in - account.stateManager.addUpdates(result) - - return account.postbox.transaction { transaction -> Void in - if let apiChat = apiUpdatesGroups(result).first { - let parsedPeers = AccumulatedPeers(transaction: transaction, chats: [apiChat], users: []) - updatePeers(transaction: transaction, accountPeerId: accountPeerId, peers: parsedPeers) + return account.postbox.transaction { transaction -> Signal in + if let peer = transaction.getPeer(peerId) { + if let peer = peer as? TelegramChannel, let inputChannel = apiInputChannel(peer) { + let flags: Int32 = (1 << 0) + return account.network.request(Api.functions.channels.updateColor(flags: flags, channel: inputChannel, color: nameColor.rawValue, backgroundEmojiId: backgroundEmojiId ?? 0)) + |> mapError { error -> UpdatePeerNameColorAndEmojiError in + if error.errorDescription.hasPrefix("BOOSTS_REQUIRED") { + return .channelBoostRequired + } + return .generic } - } |> mapError { _ -> UpdatePeerNameColorAndEmojiError in } + |> mapToSignal { result -> Signal in + account.stateManager.addUpdates(result) + + return account.postbox.transaction { transaction -> Void in + if let apiChat = apiUpdatesGroups(result).first { + let parsedPeers = AccumulatedPeers(transaction: transaction, chats: [apiChat], users: []) + updatePeers(transaction: transaction, accountPeerId: account.peerId, peers: parsedPeers) + } + } + |> mapError { _ -> UpdatePeerNameColorAndEmojiError in } + } + } else { + return .fail(.generic) } } else { return .fail(.generic) } - } + } + |> castError(UpdatePeerNameColorAndEmojiError.self) + |> switchToLatest } diff --git a/submodules/TelegramUI/Components/Settings/PeerNameColorScreen/Sources/PeerNameColorScreen.swift b/submodules/TelegramUI/Components/Settings/PeerNameColorScreen/Sources/PeerNameColorScreen.swift index 375a200043..60b31d61f6 100644 --- a/submodules/TelegramUI/Components/Settings/PeerNameColorScreen/Sources/PeerNameColorScreen.swift +++ b/submodules/TelegramUI/Components/Settings/PeerNameColorScreen/Sources/PeerNameColorScreen.swift @@ -442,7 +442,7 @@ public func PeerNameColorScreen( } updateState { state in var updatedState = state - updatedState.inProgress = true + updatedState.inProgress = false return updatedState } }, completed: { diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift index 7112dcbb90..d9c9c6e5c5 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift @@ -8362,6 +8362,8 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro case .channelBoostRequired: self.postingAvailabilityDisposable?.dispose() + let premiumConfiguration = PremiumConfiguration.with(appConfiguration: self.context.currentAppConfiguration.with { $0 }) + self.postingAvailabilityDisposable = combineLatest( queue: Queue.mainQueue(), self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: self.peerId)), @@ -8387,12 +8389,12 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro if let self { self.openStats(boosts: true, boostStatus: status) } - }, openGift: { [weak self] in + }, openGift: premiumConfiguration.giveawayGiftsPurchaseAvailable ? { [weak self] in if let self { let controller = createGiveawayController(context: self.context, peerId: self.peerId, subject: .generic) self.controller?.push(controller) } - }) + } : nil) navigationController.pushViewController(controller) }