Giveaway improvements

This commit is contained in:
Ilya Laktyushin 2023-10-22 16:48:19 +04:00
parent b167771b5f
commit e990abd718
6 changed files with 53 additions and 55 deletions

View File

@ -1062,17 +1062,19 @@ public protocol AccountContext: AnyObject {
public struct PremiumConfiguration { public struct PremiumConfiguration {
public static var defaultValue: 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 isPremiumDisabled: Bool
public let showPremiumGiftInAttachMenu: Bool public let showPremiumGiftInAttachMenu: Bool
public let showPremiumGiftInTextField: 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.isPremiumDisabled = isPremiumDisabled
self.showPremiumGiftInAttachMenu = showPremiumGiftInAttachMenu self.showPremiumGiftInAttachMenu = showPremiumGiftInAttachMenu
self.showPremiumGiftInTextField = showPremiumGiftInTextField self.showPremiumGiftInTextField = showPremiumGiftInTextField
self.giveawayGiftsPurchaseAvailable = giveawayGiftsPurchaseAvailable
} }
public static func with(appConfiguration: AppConfiguration) -> PremiumConfiguration { public static func with(appConfiguration: AppConfiguration) -> PremiumConfiguration {
@ -1080,7 +1082,8 @@ public struct PremiumConfiguration {
return PremiumConfiguration( return PremiumConfiguration(
isPremiumDisabled: data["premium_purchase_blocked"] as? Bool ?? false, isPremiumDisabled: data["premium_purchase_blocked"] as? Bool ?? false,
showPremiumGiftInAttachMenu: data["premium_gift_attach_menu_icon"] 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 { } else {
return .defaultValue return .defaultValue

View File

@ -1439,7 +1439,7 @@ private final class LimitSheetContent: CombinedComponent {
) )
var additionalContentHeight: CGFloat = 0.0 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( let orText = orText.update(
component: MultilineTextComponent(text: .plain(NSAttributedString(string: "or", font: Font.regular(15.0), textColor: textColor.withAlphaComponent(0.8), paragraphAlignment: .center))), 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), 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 { if let range = giftAttributedString.string.range(of: ">"), let chevronImage = state.cachedChevronImage?.0 {
giftAttributedString.addAttribute(.attachment, value: chevronImage, range: NSRange(range, in: giftAttributedString.string)) giftAttributedString.addAttribute(.attachment, value: chevronImage, range: NSRange(range, in: giftAttributedString.string))
} }
let openGift = component.openGift
let giftText = giftText.update( let giftText = giftText.update(
component: BalancedTextComponent( component: BalancedTextComponent(
text: .plain(giftAttributedString), text: .plain(giftAttributedString),
@ -1485,15 +1484,11 @@ private final class LimitSheetContent: CombinedComponent {
maximumNumberOfLines: 0, maximumNumberOfLines: 0,
lineSpacing: 0.1, lineSpacing: 0.1,
highlightColor: linkColor.withAlphaComponent(0.2), highlightColor: linkColor.withAlphaComponent(0.2),
highlightAction: { attributes in highlightAction: { _ in
if let _ = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.URL)] {
return NSAttributedString.Key(rawValue: TelegramTextAttributes.URL)
} else {
return nil return nil
}
}, },
tapAction: { _, _ in tapAction: { _, _ in
openGift?() openGift()
} }
), ),
availableSize: CGSize(width: context.availableSize.width - textSideInset * 2.0, height: context.availableSize.height), 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 { if link != nil {
height += 66.0 height += 66.0
if let _ = component.openGift {
height += 100.0 height += 100.0
}
} else { } else {
if isCurrent { if isCurrent {
height -= 53.0 height -= 53.0

View File

@ -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] = [] var entries: [StatsEntry] = []
switch state.section { switch state.section {
@ -822,10 +822,12 @@ private func channelStatsControllerEntries(state: ChannelStatsControllerState, p
entries.append(.boostLink(presentationData.theme, boostData.url)) entries.append(.boostLink(presentationData.theme, boostData.url))
entries.append(.boostLinkInfo(presentationData.theme, presentationData.strings.Stats_Boosts_LinkInfo)) entries.append(.boostLinkInfo(presentationData.theme, presentationData.strings.Stats_Boosts_LinkInfo))
if giveawayAvailable {
entries.append(.gifts(presentationData.theme, "Get Boosts via Gifts")) 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.")) entries.append(.giftsInfo(presentationData.theme, "Get more boosts for your channel by gifting Premium to your subscribers."))
} }
} }
}
return entries return entries
} }
@ -837,6 +839,8 @@ public func channelStatsController(context: AccountContext, updatedPresentationD
statePromise.set(stateValue.modify { f($0) }) statePromise.set(stateValue.modify { f($0) })
} }
let premiumConfiguration = PremiumConfiguration.with(appConfiguration: context.currentAppConfiguration.with { $0 })
var openMessageStatsImpl: ((MessageId) -> Void)? var openMessageStatsImpl: ((MessageId) -> Void)?
var contextActionImpl: ((MessageId, ASDisplayNode, ContextGesture?) -> Void)? var contextActionImpl: ((MessageId, ASDisplayNode, ContextGesture?) -> Void)?
@ -999,10 +1003,8 @@ public func channelStatsController(context: AccountContext, updatedPresentationD
return map 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 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)) return (controllerState, (listState, arguments))
} }

View File

@ -95,20 +95,8 @@ public enum UpdatePeerNameColorAndEmojiError {
} }
func _internal_updatePeerNameColorAndEmoji(account: Account, peerId: EnginePeer.Id, nameColor: PeerNameColor, backgroundEmojiId: Int64?) -> Signal<Void, UpdatePeerNameColorAndEmojiError> { func _internal_updatePeerNameColorAndEmoji(account: Account, peerId: EnginePeer.Id, nameColor: PeerNameColor, backgroundEmojiId: Int64?) -> Signal<Void, UpdatePeerNameColorAndEmojiError> {
let accountPeerId = account.peerId return account.postbox.transaction { transaction -> Signal<Void, UpdatePeerNameColorAndEmojiError> in
if let peer = transaction.getPeer(peerId) {
return account.postbox.transaction { transaction -> Signal<Peer, NoError> 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<Void, UpdatePeerNameColorAndEmojiError> in
if let peer = peer as? TelegramChannel, let inputChannel = apiInputChannel(peer) { if let peer = peer as? TelegramChannel, let inputChannel = apiInputChannel(peer) {
let flags: Int32 = (1 << 0) let flags: Int32 = (1 << 0)
return account.network.request(Api.functions.channels.updateColor(flags: flags, channel: inputChannel, color: nameColor.rawValue, backgroundEmojiId: backgroundEmojiId ?? 0)) return account.network.request(Api.functions.channels.updateColor(flags: flags, channel: inputChannel, color: nameColor.rawValue, backgroundEmojiId: backgroundEmojiId ?? 0))
@ -124,12 +112,18 @@ func _internal_updatePeerNameColorAndEmoji(account: Account, peerId: EnginePeer.
return account.postbox.transaction { transaction -> Void in return account.postbox.transaction { transaction -> Void in
if let apiChat = apiUpdatesGroups(result).first { if let apiChat = apiUpdatesGroups(result).first {
let parsedPeers = AccumulatedPeers(transaction: transaction, chats: [apiChat], users: []) let parsedPeers = AccumulatedPeers(transaction: transaction, chats: [apiChat], users: [])
updatePeers(transaction: transaction, accountPeerId: accountPeerId, peers: parsedPeers) updatePeers(transaction: transaction, accountPeerId: account.peerId, peers: parsedPeers)
} }
} |> mapError { _ -> UpdatePeerNameColorAndEmojiError in } }
|> mapError { _ -> UpdatePeerNameColorAndEmojiError in }
}
} else {
return .fail(.generic)
} }
} else { } else {
return .fail(.generic) return .fail(.generic)
} }
} }
|> castError(UpdatePeerNameColorAndEmojiError.self)
|> switchToLatest
} }

View File

@ -442,7 +442,7 @@ public func PeerNameColorScreen(
} }
updateState { state in updateState { state in
var updatedState = state var updatedState = state
updatedState.inProgress = true updatedState.inProgress = false
return updatedState return updatedState
} }
}, completed: { }, completed: {

View File

@ -8362,6 +8362,8 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
case .channelBoostRequired: case .channelBoostRequired:
self.postingAvailabilityDisposable?.dispose() self.postingAvailabilityDisposable?.dispose()
let premiumConfiguration = PremiumConfiguration.with(appConfiguration: self.context.currentAppConfiguration.with { $0 })
self.postingAvailabilityDisposable = combineLatest( self.postingAvailabilityDisposable = combineLatest(
queue: Queue.mainQueue(), queue: Queue.mainQueue(),
self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: self.peerId)), 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 { if let self {
self.openStats(boosts: true, boostStatus: status) self.openStats(boosts: true, boostStatus: status)
} }
}, openGift: { [weak self] in }, openGift: premiumConfiguration.giveawayGiftsPurchaseAvailable ? { [weak self] in
if let self { if let self {
let controller = createGiveawayController(context: self.context, peerId: self.peerId, subject: .generic) let controller = createGiveawayController(context: self.context, peerId: self.peerId, subject: .generic)
self.controller?.push(controller) self.controller?.push(controller)
} }
}) } : nil)
navigationController.pushViewController(controller) navigationController.pushViewController(controller)
} }