Various improvements

This commit is contained in:
Ilya Laktyushin 2025-08-27 21:51:58 +04:00
parent bd915704fa
commit 24e01cc8d4
3 changed files with 126 additions and 31 deletions

View File

@ -14973,3 +14973,24 @@ Sorry for the inconvenience.";
"Ton.WithdrawViaFragment.Info_URL" = "https://telegram.org/tos/bot-developers#6-2-2-tpa-balance"; "Ton.WithdrawViaFragment.Info_URL" = "https://telegram.org/tos/bot-developers#6-2-2-tpa-balance";
"MESSAGE_GIFT_THEME" = "%1$@ changed theme to %2$@"; "MESSAGE_GIFT_THEME" = "%1$@ changed theme to %2$@";
"Gift.Upgrade.Skip" = "Skip";
"Gift.Upgrade.UpgradeNext" = "Upgrade Next Gift";
"Gift.Value.DescriptionAveragePrice" = "This is the average sale price of **%@** on Telegram and Fragment over the past month.";
"Gift.Value.DescriptionLastPriceFragment" = "This is the last price at which **%@** was last sold on Fragment.";
"Gift.Value.DescriptionLastPriceTelegram" = "This is the last price at which **%@** was last sold on Telegram.";
"Gift.Value.LastPriceInfo" = "**%1$@** is the last price for %2$@ gifts listed on Telegram and Fragment.";
"Gift.Value.MinimumPriceInfo" = "**%1$@** is the floor price for %2$@ gifts listed on Telegram and Fragment.";
"Gift.Value.AveragePriceInfo" = "**%1$@** is the average sale price for %2$@ gifts listed on Telegram and Fragment over the past month.";
"Gift.Value.AveragePrice" = "Last Sale";
"Gift.Value.InitialSale" = "Initial Sale";
"Gift.Value.InitialPrice" = "Initial Price";
"Gift.Value.LastSale" = "Last Sale";
"Gift.Value.LastPrice" = "Last Price";
"Gift.Value.MinimumPrice" = "Minimum Price";
"Gift.Value.AveragePrice" = "Average Price";
"Gift.Value.ForSaleOnTelegram" = "for sale on Telegram";
"Gift.Value.ForSaleOnFragment" = "for sale on Fragment";

View File

@ -205,8 +205,6 @@ private final class GiftValueSheetContent: CombinedComponent {
let theme = environment.theme let theme = environment.theme
let strings = environment.strings let strings = environment.strings
let dateTimeFormat = environment.dateTimeFormat let dateTimeFormat = environment.dateTimeFormat
//let nameDisplayOrder = component.context.sharedContext.currentPresentationData.with { $0 }.nameDisplayOrder
//let controller = environment.controller
let state = context.state let state = context.state
@ -319,12 +317,12 @@ private final class GiftValueSheetContent: CombinedComponent {
var descriptionText: String var descriptionText: String
if component.valueInfo.valueIsAverage { if component.valueInfo.valueIsAverage {
descriptionText = "This is the average sale price of **\(giftCollectionTitle)** on Telegram and Fragment over the past month." descriptionText = strings.Gift_Value_DescriptionAveragePrice(giftCollectionTitle).string
} else { } else {
if component.valueInfo.isLastSaleOnFragment { if component.valueInfo.isLastSaleOnFragment {
descriptionText = "This is the last price at which **\(giftTitle)** was last sold on Fragment." descriptionText = strings.Gift_Value_DescriptionLastPriceFragment(giftTitle).string
} else { } else {
descriptionText = "This is the last price at which **\(giftTitle)** was last sold on Telegram." descriptionText = strings.Gift_Value_DescriptionLastPriceTelegram(giftTitle).string
} }
} }
if !descriptionText.isEmpty { if !descriptionText.isEmpty {
@ -394,7 +392,7 @@ private final class GiftValueSheetContent: CombinedComponent {
tableItems.append(.init( tableItems.append(.init(
id: "initialDate", id: "initialDate",
title: "Initial Sale", title: strings.Gift_Value_InitialSale,
component: AnyComponent( component: AnyComponent(
MultilineTextComponent(text: .plain(NSAttributedString(string: stringForMediumDate(timestamp: component.valueInfo.initialSaleDate, strings: strings, dateTimeFormat: dateTimeFormat), font: tableFont, textColor: tableTextColor))) MultilineTextComponent(text: .plain(NSAttributedString(string: stringForMediumDate(timestamp: component.valueInfo.initialSaleDate, strings: strings, dateTimeFormat: dateTimeFormat), font: tableFont, textColor: tableTextColor)))
) )
@ -410,7 +408,7 @@ private final class GiftValueSheetContent: CombinedComponent {
tableItems.append(.init( tableItems.append(.init(
id: "initialPrice", id: "initialPrice",
title: "Initial Price", title: strings.Gift_Value_InitialPrice,
component: AnyComponent(MultilineTextWithEntitiesComponent( component: AnyComponent(MultilineTextWithEntitiesComponent(
context: component.context, context: component.context,
animationCache: component.context.animationCache, animationCache: component.context.animationCache,
@ -425,7 +423,7 @@ private final class GiftValueSheetContent: CombinedComponent {
if let lastSaleDate = component.valueInfo.lastSaleDate { if let lastSaleDate = component.valueInfo.lastSaleDate {
tableItems.append(.init( tableItems.append(.init(
id: "lastDate", id: "lastDate",
title: "Last Sale", title: strings.Gift_Value_LastSale,
component: AnyComponent( component: AnyComponent(
MultilineTextComponent(text: .plain(NSAttributedString(string: stringForMediumDate(timestamp: lastSaleDate, strings: strings, dateTimeFormat: dateTimeFormat), font: tableFont, textColor: tableTextColor))) MultilineTextComponent(text: .plain(NSAttributedString(string: stringForMediumDate(timestamp: lastSaleDate, strings: strings, dateTimeFormat: dateTimeFormat), font: tableFont, textColor: tableTextColor)))
) )
@ -457,7 +455,7 @@ private final class GiftValueSheetContent: CombinedComponent {
color: theme.list.itemAccentColor color: theme.list.itemAccentColor
)), )),
action: { [weak state] in action: { [weak state] in
state?.showAttributeInfo(tag: tag, text: "**\(lastSalePriceString)** is the last price for \(giftCollectionTitle) gifts listed on Telegram and Fragment.") state?.showAttributeInfo(tag: tag, text: strings.Gift_Value_LastPriceInfo(lastSalePriceString, giftCollectionTitle).string)
} }
).tagged(tag)) ).tagged(tag))
@ -467,7 +465,7 @@ private final class GiftValueSheetContent: CombinedComponent {
) )
tableItems.append(.init( tableItems.append(.init(
id: "lastPrice", id: "lastPrice",
title: "Last Price", title: strings.Gift_Value_LastPrice,
hasBackground: false, hasBackground: false,
component: itemComponent component: itemComponent
)) ))
@ -494,8 +492,7 @@ private final class GiftValueSheetContent: CombinedComponent {
color: theme.list.itemAccentColor color: theme.list.itemAccentColor
)), )),
action: { [weak state] in action: { [weak state] in
state?.showAttributeInfo(tag: tag, text: "**\(floorPriceString)** is the floor price for \(giftCollectionTitle) gifts listed on Telegram and Fragment.") state?.showAttributeInfo(tag: tag, text: strings.Gift_Value_MinimumPriceInfo(floorPriceString, giftCollectionTitle).string)
} }
).tagged(tag)) ).tagged(tag))
)) ))
@ -504,7 +501,7 @@ private final class GiftValueSheetContent: CombinedComponent {
) )
tableItems.append(.init( tableItems.append(.init(
id: "floorPrice", id: "floorPrice",
title: "Minumum Price", title: strings.Gift_Value_MinimumPrice,
hasBackground: false, hasBackground: false,
component: itemComponent component: itemComponent
)) ))
@ -531,7 +528,7 @@ private final class GiftValueSheetContent: CombinedComponent {
color: theme.list.itemAccentColor color: theme.list.itemAccentColor
)), )),
action: { [weak state] in action: { [weak state] in
state?.showAttributeInfo(tag: tag, text: "**\(averagePriceString)** is the average sale price of \(giftCollectionTitle) on Telegram and Fragment over the past month.") state?.showAttributeInfo(tag: tag, text: strings.Gift_Value_AveragePriceInfo(averagePriceString, giftCollectionTitle).string)
} }
).tagged(tag)) ).tagged(tag))
)) ))
@ -540,7 +537,7 @@ private final class GiftValueSheetContent: CombinedComponent {
) )
tableItems.append(.init( tableItems.append(.init(
id: "averagePrice", id: "averagePrice",
title: "Average Price", title: strings.Gift_Value_AveragePrice,
hasBackground: false, hasBackground: false,
component: itemComponent component: itemComponent
)) ))
@ -587,7 +584,7 @@ private final class GiftValueSheetContent: CombinedComponent {
) )
)), )),
AnyComponentWithIdentity(id: "label", component: AnyComponent( AnyComponentWithIdentity(id: "label", component: AnyComponent(
MultilineTextComponent(text: .plain(NSAttributedString(string: " for sale on Telegram", font: Font.regular(17.0), textColor: theme.actionSheet.controlAccentColor))) MultilineTextComponent(text: .plain(NSAttributedString(string: " \(strings.Gift_Value_ForSaleOnTelegram)", font: Font.regular(17.0), textColor: theme.actionSheet.controlAccentColor)))
)), )),
AnyComponentWithIdentity(id: "arrow", component: AnyComponent( AnyComponentWithIdentity(id: "arrow", component: AnyComponent(
BundleIconComponent(name: "Chat/Context Menu/Arrow", tintColor: theme.actionSheet.controlAccentColor) BundleIconComponent(name: "Chat/Context Menu/Arrow", tintColor: theme.actionSheet.controlAccentColor)
@ -639,7 +636,7 @@ private final class GiftValueSheetContent: CombinedComponent {
) )
)), )),
AnyComponentWithIdentity(id: "label", component: AnyComponent( AnyComponentWithIdentity(id: "label", component: AnyComponent(
MultilineTextComponent(text: .plain(NSAttributedString(string: " for sale on Fragment", font: Font.regular(17.0), textColor: theme.actionSheet.controlAccentColor))) MultilineTextComponent(text: .plain(NSAttributedString(string: " \(strings.Gift_Value_ForSaleOnFragment)", font: Font.regular(17.0), textColor: theme.actionSheet.controlAccentColor)))
)), )),
AnyComponentWithIdentity(id: "arrow", component: AnyComponent( AnyComponentWithIdentity(id: "arrow", component: AnyComponent(
BundleIconComponent(name: "Chat/Context Menu/Arrow", tintColor: theme.actionSheet.controlAccentColor) BundleIconComponent(name: "Chat/Context Menu/Arrow", tintColor: theme.actionSheet.controlAccentColor)

View File

@ -104,6 +104,7 @@ private final class GiftViewSheetContent: CombinedComponent {
var cachedHiddenImage: (UIImage, PresentationTheme)? var cachedHiddenImage: (UIImage, PresentationTheme)?
var inProgress = false var inProgress = false
var canSkip = false
var testUpgradeAnimation = !"".isEmpty var testUpgradeAnimation = !"".isEmpty
@ -668,14 +669,32 @@ private final class GiftViewSheetContent: CombinedComponent {
return return
} }
self.isOpeningValue = true self.isOpeningValue = true
let presentationData = self.context.sharedContext.currentPresentationData.with { $0 }
let _ = (self.context.engine.payments.getUniqueStarGiftValueInfo(slug: uniqueGift.slug) let _ = (self.context.engine.payments.getUniqueStarGiftValueInfo(slug: uniqueGift.slug)
|> deliverOnMainQueue).start(next: { [weak self] valueInfo in |> deliverOnMainQueue).start(next: { [weak self] valueInfo in
guard let self, let valueInfo else { guard let self else {
return return
} }
self.isOpeningValue = false self.isOpeningValue = false
let valueController = GiftValueScreen(context: self.context, gift: gift, valueInfo: valueInfo) if let valueInfo {
controller.push(valueController) let valueController = GiftValueScreen(context: self.context, gift: gift, valueInfo: valueInfo)
controller.push(valueController)
} else {
guard let controller = self.getController() as? GiftViewScreen else {
return
}
let alertController = textAlertController(
context: self.context,
title: nil,
text: presentationData.strings.Login_UnknownError,
actions: [
TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})
],
parseMarkdown: true
)
controller.present(alertController, in: .window(.root))
}
}) })
} }
@ -1528,7 +1547,28 @@ private final class GiftViewSheetContent: CombinedComponent {
} }
} }
func skipAnimation() {
guard let arguments = self.subject.arguments, case let .unique(uniqueGift) = arguments.gift else {
return
}
self.canSkip = false
self.revealedNumberDigits = "\(uniqueGift.number)".count
self.revealedAttributes.insert(.backdrop)
self.revealedAttributes.insert(.pattern)
self.revealedAttributes.insert(.model)
self.updated(transition: .easeInOut(duration: 0.2))
}
func commitUpgrade() { func commitUpgrade() {
let duration = Double.random(in: 0.85 ..< 2.25)
let firstFraction = Double.random(in: 0.2 ..< 0.4)
let secondFraction = Double.random(in: 0.2 ..< 0.4)
let thirdFraction = 1.0 - firstFraction - secondFraction
let firstDuration = duration * firstFraction
let secondDuration = duration * secondFraction
let thirdDuration = duration * thirdFraction
if self.testUpgradeAnimation, let arguments = self.subject.arguments, case let .unique(uniqueGift) = arguments.gift { if self.testUpgradeAnimation, let arguments = self.subject.arguments, case let .unique(uniqueGift) = arguments.gift {
self.inProgress = true self.inProgress = true
self.updated() self.updated()
@ -1538,10 +1578,14 @@ private final class GiftViewSheetContent: CombinedComponent {
} }
Queue.mainQueue().after(0.5, { Queue.mainQueue().after(0.5, {
self.canSkip = true
self.updated(transition: .immediate)
self.inUpgradePreview = false self.inUpgradePreview = false
self.inProgress = false self.inProgress = false
self.justUpgraded = true self.justUpgraded = true
self.revealedNumberDigits = -1 self.revealedNumberDigits = -1
for i in 0 ..< "\(uniqueGift.number)".count { for i in 0 ..< "\(uniqueGift.number)".count {
@ -1552,17 +1596,22 @@ private final class GiftViewSheetContent: CombinedComponent {
} }
self.updated(transition: .spring(duration: 0.4)) self.updated(transition: .spring(duration: 0.4))
Queue.mainQueue().after(1.2) { Queue.mainQueue().after(firstDuration) {
self.revealedAttributes.insert(.backdrop) self.revealedAttributes.insert(.backdrop)
self.updated(transition: .immediate) self.updated(transition: .immediate)
Queue.mainQueue().after(0.7) { Queue.mainQueue().after(secondDuration) {
self.revealedAttributes.insert(.pattern) self.revealedAttributes.insert(.pattern)
self.updated(transition: .immediate) self.updated(transition: .immediate)
Queue.mainQueue().after(0.7) { Queue.mainQueue().after(thirdDuration) {
self.revealedAttributes.insert(.model) self.revealedAttributes.insert(.model)
self.updated(transition: .immediate) self.updated(transition: .immediate)
Queue.mainQueue().after(0.55) {
self.canSkip = false
self.updated(transition: .easeInOut(duration: 0.2))
}
Queue.mainQueue().after(0.6) { Queue.mainQueue().after(0.6) {
if let controller = self.getController() as? GiftViewScreen { if let controller = self.getController() as? GiftViewScreen {
@ -1619,6 +1668,9 @@ private final class GiftViewSheetContent: CombinedComponent {
guard let self, let controller = self.getController() as? GiftViewScreen else { guard let self, let controller = self.getController() as? GiftViewScreen else {
return return
} }
self.canSkip = true
self.updated(transition: .immediate)
self.inProgress = false self.inProgress = false
self.inUpgradePreview = false self.inUpgradePreview = false
@ -1638,18 +1690,23 @@ private final class GiftViewSheetContent: CombinedComponent {
} }
} }
} }
Queue.mainQueue().after(1.2) { Queue.mainQueue().after(firstDuration) {
self.revealedAttributes.insert(.backdrop) self.revealedAttributes.insert(.backdrop)
self.updated(transition: .immediate) self.updated(transition: .immediate)
Queue.mainQueue().after(0.7) { Queue.mainQueue().after(secondDuration) {
self.revealedAttributes.insert(.pattern) self.revealedAttributes.insert(.pattern)
self.updated(transition: .immediate) self.updated(transition: .immediate)
Queue.mainQueue().after(0.7) { Queue.mainQueue().after(thirdDuration) {
self.revealedAttributes.insert(.model) self.revealedAttributes.insert(.model)
self.updated(transition: .immediate) self.updated(transition: .immediate)
Queue.mainQueue().after(0.55) {
self.canSkip = false
self.updated(transition: .easeInOut(duration: 0.2))
}
Queue.mainQueue().after(0.6) { Queue.mainQueue().after(0.6) {
if let controller = self.getController() as? GiftViewScreen { if let controller = self.getController() as? GiftViewScreen {
@ -3771,7 +3828,25 @@ private final class GiftViewSheetContent: CombinedComponent {
pressedColor: theme.list.itemCheckColors.fillColor.withMultipliedAlpha(0.9) pressedColor: theme.list.itemCheckColors.fillColor.withMultipliedAlpha(0.9)
) )
let buttonChild: _UpdatedChildComponent let buttonChild: _UpdatedChildComponent
if showWearPreview, let uniqueGift { if state.canSkip {
buttonChild = button.update(
component: ButtonComponent(
background: buttonBackground,
content: AnyComponentWithIdentity(
id: AnyHashable("skip"),
component: AnyComponent(MultilineTextComponent(text: .plain(NSAttributedString(string: strings.Gift_Upgrade_Skip, font: Font.semibold(17.0), textColor: theme.list.itemCheckColors.foregroundColor, paragraphAlignment: .center))))
),
isEnabled: true,
displaysProgress: state.inProgress,
action: { [weak state] in
if let state {
state.skipAnimation()
}
}),
availableSize: buttonSize,
transition: context.transition
)
} else if showWearPreview, let uniqueGift {
let buttonContent: AnyComponentWithIdentity<Empty> let buttonContent: AnyComponentWithIdentity<Empty>
let premiumConfiguration = PremiumConfiguration.with(appConfiguration: component.context.currentAppConfiguration.with { $0 }) let premiumConfiguration = PremiumConfiguration.with(appConfiguration: component.context.currentAppConfiguration.with { $0 })
@ -4091,7 +4166,9 @@ private final class GiftViewSheetContent: CombinedComponent {
isEnabled: true, isEnabled: true,
displaysProgress: state.inProgress, displaysProgress: state.inProgress,
action: { [weak state] in action: { [weak state] in
state?.dismiss(animated: true) if let state {
state.dismiss(animated: true)
}
}), }),
availableSize: buttonSize, availableSize: buttonSize,
transition: context.transition transition: context.transition
@ -4100,7 +4177,7 @@ private final class GiftViewSheetContent: CombinedComponent {
let buttonFrame = CGRect(origin: CGPoint(x: sideInset, y: originY), size: buttonChild.size) let buttonFrame = CGRect(origin: CGPoint(x: sideInset, y: originY), size: buttonChild.size)
var buttonAlpha: CGFloat = 1.0 var buttonAlpha: CGFloat = 1.0
if let nextGiftToUpgrade = state.nextGiftToUpgrade, case let .generic(gift) = nextGiftToUpgrade.gift { if let nextGiftToUpgrade = state.nextGiftToUpgrade, case let .generic(gift) = nextGiftToUpgrade.gift, !state.canSkip {
buttonAlpha = 0.0 buttonAlpha = 0.0
let upgradeNextButton = upgradeNextButton.update( let upgradeNextButton = upgradeNextButton.update(
@ -4108,7 +4185,7 @@ private final class GiftViewSheetContent: CombinedComponent {
content: AnyComponent( content: AnyComponent(
HStack([ HStack([
AnyComponentWithIdentity(id: "label", component: AnyComponent( AnyComponentWithIdentity(id: "label", component: AnyComponent(
MultilineTextComponent(text: .plain(NSAttributedString(string: "Upgrade Next Gift", font: Font.regular(17.0), textColor: theme.actionSheet.controlAccentColor))) MultilineTextComponent(text: .plain(NSAttributedString(string: strings.Gift_Upgrade_UpgradeNext, font: Font.regular(17.0), textColor: theme.actionSheet.controlAccentColor)))
)), )),
AnyComponentWithIdentity(id: "icon", component: AnyComponent( AnyComponentWithIdentity(id: "icon", component: AnyComponent(
GiftItemComponent( GiftItemComponent(