Boost improvements

This commit is contained in:
Ilya Laktyushin
2023-10-25 02:14:16 +04:00
parent 488504793d
commit 3d22de75fc
10 changed files with 400 additions and 166 deletions

View File

@@ -22,7 +22,7 @@ import ShareController
import ItemListPeerActionItem
import PremiumUI
private let maxUsersDisplayedLimit: Int32 = 50
private let maxUsersDisplayedLimit: Int32 = 5
private final class ChannelStatsControllerArguments {
let context: AccountContext
@@ -31,20 +31,20 @@ private final class ChannelStatsControllerArguments {
let contextAction: (MessageId, ASDisplayNode, ContextGesture?) -> Void
let copyBoostLink: (String) -> Void
let shareBoostLink: (String) -> Void
let openPeer: (EnginePeer) -> Void
let openBoost: (ChannelBoostersContext.State.Boost) -> Void
let expandBoosters: () -> Void
let openGifts: () -> Void
let createPrepaidGiveaway: (PrepaidGiveaway) -> Void
let updateGiftsSelected: (Bool) -> Void
init(context: AccountContext, loadDetailedGraph: @escaping (StatsGraph, Int64) -> Signal<StatsGraph?, NoError>, openMessage: @escaping (MessageId) -> Void, contextAction: @escaping (MessageId, ASDisplayNode, ContextGesture?) -> Void, copyBoostLink: @escaping (String) -> Void, shareBoostLink: @escaping (String) -> Void, openPeer: @escaping (EnginePeer) -> Void, expandBoosters: @escaping () -> Void, openGifts: @escaping () -> Void, createPrepaidGiveaway: @escaping (PrepaidGiveaway) -> Void, updateGiftsSelected: @escaping (Bool) -> Void) {
init(context: AccountContext, loadDetailedGraph: @escaping (StatsGraph, Int64) -> Signal<StatsGraph?, NoError>, openMessage: @escaping (MessageId) -> Void, contextAction: @escaping (MessageId, ASDisplayNode, ContextGesture?) -> Void, copyBoostLink: @escaping (String) -> Void, shareBoostLink: @escaping (String) -> Void, openBoost: @escaping (ChannelBoostersContext.State.Boost) -> Void, expandBoosters: @escaping () -> Void, openGifts: @escaping () -> Void, createPrepaidGiveaway: @escaping (PrepaidGiveaway) -> Void, updateGiftsSelected: @escaping (Bool) -> Void) {
self.context = context
self.loadDetailedGraph = loadDetailedGraph
self.openMessageStats = openMessage
self.contextAction = contextAction
self.copyBoostLink = copyBoostLink
self.shareBoostLink = shareBoostLink
self.openPeer = openPeer
self.openBoost = openBoost
self.expandBoosters = expandBoosters
self.openGifts = openGifts
self.createPrepaidGiveaway = createPrepaidGiveaway
@@ -118,7 +118,7 @@ private enum StatsEntry: ItemListNodeEntry {
case boostersTitle(PresentationTheme, String)
case boostersPlaceholder(PresentationTheme, String)
case boosterTabs(PresentationTheme, String, String, Bool)
case booster(Int32, PresentationTheme, PresentationDateTimeFormat, EnginePeer?, Int32, ChannelBoostersContext.State.Boost.Flags, Int32, Int32)
case booster(Int32, PresentationTheme, PresentationDateTimeFormat, ChannelBoostersContext.State.Boost)
case boostersExpand(PresentationTheme, String)
case boostersInfo(PresentationTheme, String)
@@ -232,7 +232,7 @@ private enum StatsEntry: ItemListNodeEntry {
return 2102
case .boosterTabs:
return 2103
case let .booster(index, _, _, _, _, _, _, _):
case let .booster(index, _, _, _):
return 2104 + index
case .boostersExpand:
return 10000
@@ -439,8 +439,8 @@ private enum StatsEntry: ItemListNodeEntry {
} else {
return false
}
case let .booster(lhsIndex, lhsTheme, lhsDateTimeFormat, lhsPeer, lhsCount, lhsFlags, lhsDate, lhsExpires):
if case let .booster(rhsIndex, rhsTheme, rhsDateTimeFormat, rhsPeer, rhsCount, rhsFlags, rhsDate, rhsExpires) = rhs, lhsIndex == rhsIndex, lhsTheme === rhsTheme, lhsDateTimeFormat == rhsDateTimeFormat, lhsPeer == rhsPeer, lhsCount == rhsCount, lhsFlags == rhsFlags, lhsDate == rhsDate, lhsExpires == rhsExpires {
case let .booster(lhsIndex, lhsTheme, lhsDateTimeFormat, lhsBoost):
if case let .booster(rhsIndex, rhsTheme, rhsDateTimeFormat, rhsBoost) = rhs, lhsIndex == rhsIndex, lhsTheme === rhsTheme, lhsDateTimeFormat == rhsDateTimeFormat, lhsBoost == rhsBoost {
return true
} else {
return false
@@ -548,38 +548,49 @@ private enum StatsEntry: ItemListNodeEntry {
return BoostsTabsItem(theme: presentationData.theme, boostsText: boostText, giftsText: giftText, selectedTab: giftSelected ? .gifts : .boosts, sectionId: self.section, selectionUpdated: { tab in
arguments.updateGiftsSelected(tab == .gifts)
})
case let .booster(_, _, _, peer, count, flags, date, expires):
let expiresValue = stringForDate(timestamp: expires, strings: presentationData.strings)
case let .booster(_, _, _, boost):
let count = boost.multiplier
let expiresValue = stringForDate(timestamp: boost.expires, strings: presentationData.strings)
let expiresString: String
let durationMonths = Int32(round(Float(expires - date) / (86400.0 * 30.0)))
let durationMonths = Int32(round(Float(boost.expires - boost.date) / (86400.0 * 30.0)))
let durationString = "\(durationMonths)m"
let title: String
let icon: GiftOptionItem.Icon
var label: String?
if flags.contains(.isGiveaway) {
if boost.flags.contains(.isGiveaway) {
label = "🏆 Giveaway"
} else if flags.contains(.isGift) {
} else if boost.flags.contains(.isGift) {
label = "🎁 Gift"
}
if let peer {
let color: GiftOptionItem.Icon.Color
if durationMonths > 11 {
color = .red
} else if durationMonths > 5 {
color = .blue
} else {
color = .green
}
if boost.flags.contains(.isUnclaimed) {
title = "Unclaimed"
icon = .image(color: color, name: "Premium/Unclaimed")
expiresString = "\(durationString)\(expiresValue)"
} else if let peer = boost.peer {
title = peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
icon = .peer(peer)
expiresString = presentationData.strings.Stats_Boosts_ExpiresOn(expiresValue).string
} else {
let color: GiftOptionItem.Icon.Color
if durationMonths > 11 {
color = .red
} else if durationMonths > 5 {
color = .blue
if let _ = label {
expiresString = expiresValue
} else {
color = .green
expiresString = presentationData.strings.Stats_Boosts_ExpiresOn(expiresValue).string
}
if flags.contains(.isUnclaimed) {
} else {
if boost.flags.contains(.isUnclaimed) {
title = "Unclaimed"
icon = .image(color: color, name: "Premium/Unclaimed")
} else if flags.contains(.isGiveaway) {
} else if boost.flags.contains(.isGiveaway) {
title = "To be distributed"
icon = .image(color: color, name: "Premium/ToBeDistributed")
} else {
@@ -588,9 +599,9 @@ private enum StatsEntry: ItemListNodeEntry {
}
expiresString = "\(durationString)\(expiresValue)"
}
return GiftOptionItem(presentationData: presentationData, context: arguments.context, icon: icon, title: title, titleFont: .bold, titleBadge: count > 1 ? "\(count)" : nil, subtitle: expiresString, label: label.flatMap { .semitransparent($0) }, sectionId: self.section, action: peer != nil && peer?.id != arguments.context.account.peerId ? {
arguments.openPeer(peer!)
} : nil)
return GiftOptionItem(presentationData: presentationData, context: arguments.context, icon: icon, title: title, titleFont: .bold, titleBadge: count > 1 ? "\(count)" : nil, subtitle: expiresString, label: label.flatMap { .semitransparent($0) }, sectionId: self.section, action: {
arguments.openBoost(boost)
})
case let .boostersExpand(theme, title):
return ItemListPeerActionItem(presentationData: presentationData, icon: PresentationResourcesItemList.downArrowImage(theme), title: title, sectionId: self.section, editing: false, action: {
arguments.expandBoosters()
@@ -626,7 +637,7 @@ private enum StatsEntry: ItemListNodeEntry {
default:
color = .blue
}
return GiftOptionItem(presentationData: presentationData, context: arguments.context, icon: .image(color: color, name: "Premium/Giveaway"), title: title, titleFont: .bold, titleBadge: "\(prepaidGiveaway.quantity)", subtitle: subtitle, label: nil, sectionId: self.section, action: {
return GiftOptionItem(presentationData: presentationData, context: arguments.context, icon: .image(color: color, name: "Premium/Giveaway"), title: title, titleFont: .bold, titleBadge: "\(prepaidGiveaway.quantity * 4)", subtitle: subtitle, label: nil, sectionId: self.section, action: {
arguments.createPrepaidGiveaway(prepaidGiveaway)
})
}
@@ -824,12 +835,12 @@ private func channelStatsControllerEntries(state: ChannelStatsControllerState, p
}
for booster in boosters {
entries.append(.booster(boosterIndex, presentationData.theme, presentationData.dateTimeFormat, booster.peer, booster.multiplier, booster.flags, booster.date, booster.expires))
entries.append(.booster(boosterIndex, presentationData.theme, presentationData.dateTimeFormat, booster))
boosterIndex += 1
}
if !effectiveExpanded {
entries.append(.boostersExpand(presentationData.theme, presentationData.strings.PeopleNearby_ShowMorePeople(Int32(selectedState.count) - maxUsersDisplayedLimit)))
entries.append(.boostersExpand(presentationData.theme, presentationData.strings.Stats_Boosts_ShowMoreBoosts(Int32(selectedState.count) - maxUsersDisplayedLimit)))
}
}
@@ -899,7 +910,6 @@ public func channelStatsController(context: AccountContext, updatedPresentationD
var presentImpl: ((ViewController) -> Void)?
var pushImpl: ((ViewController) -> Void)?
var navigateToProfileImpl: ((EnginePeer) -> Void)?
let arguments = ChannelStatsControllerArguments(context: context, loadDetailedGraph: { graph, x -> Signal<StatsGraph?, NoError> in
return statsContext.loadDetailedGraph(graph, x: x)
@@ -954,8 +964,9 @@ public func channelStatsController(context: AccountContext, updatedPresentationD
}
presentImpl?(shareController)
},
openPeer: { peer in
navigateToProfileImpl?(peer)
openBoost: { boost in
let controller = PremiumGiftCodeScreen(context: context, subject: .boost(peerId, boost), action: {})
pushImpl?(controller)
},
expandBoosters: {
updateState { $0.withUpdatedBoostersExpanded(true) }
@@ -1087,11 +1098,6 @@ public func channelStatsController(context: AccountContext, updatedPresentationD
pushImpl = { [weak controller] c in
controller?.push(c)
}
navigateToProfileImpl = { [weak controller] peer in
if let navigationController = controller?.navigationController as? NavigationController, let controller = context.sharedContext.makePeerInfoController(context: context, updatedPresentationData: nil, peer: peer._asPeer(), mode: .generic, avatarInitiallyExpanded: peer.largeProfileImage != nil, fromChat: false, requestsContext: nil) {
navigationController.pushViewController(controller)
}
}
return controller
}