Various fixes

This commit is contained in:
Ilya Laktyushin 2025-05-03 05:54:09 +04:00
parent 60aef02fa5
commit c04e8f3c11
5 changed files with 100 additions and 83 deletions

View File

@ -2438,6 +2438,7 @@ private final class ResaleGiftsContextImpl {
private var gifts: [StarGift] = []
private var attributes: [StarGift.UniqueGift.Attribute] = []
private var attributeCount: [ResaleGiftsContext.Attribute: Int32] = [:]
private var attributesHash: Int64?
private var count: Int32?
private var dataState: ResaleGiftsContext.State.DataState = .ready(canLoadMore: true, nextOffset: nil)
@ -2477,6 +2478,7 @@ private final class ResaleGiftsContextImpl {
let postbox = self.account.postbox
let sorting = self.sorting
let filterAttributes = self.filterAttributes
let currentAttributesHash = self.attributesHash
let dataState = self.dataState
@ -2511,46 +2513,45 @@ private final class ResaleGiftsContextImpl {
}
}
var attributesHash: Int64?
if "".isEmpty {
flags |= (1 << 0)
attributesHash = 0
}
let attributesHash = currentAttributesHash ?? 0
flags |= (1 << 0)
let signal = network.request(Api.functions.payments.getResaleStarGifts(flags: flags, attributesHash: attributesHash, giftId: giftId, attributes: apiAttributes, offset: initialNextOffset ?? "", limit: 36))
|> map(Optional.init)
|> `catch` { _ -> Signal<Api.payments.ResaleStarGifts?, NoError> in
return .single(nil)
}
|> mapToSignal { result -> Signal<([StarGift], [StarGift.UniqueGift.Attribute], [ResaleGiftsContext.Attribute: Int32], Int32, String?), NoError> in
|> mapToSignal { result -> Signal<([StarGift], [StarGift.UniqueGift.Attribute]?, [ResaleGiftsContext.Attribute: Int32]?, Int64?, Int32, String?), NoError> in
guard let result else {
return .single(([], [], [:], 0, nil))
return .single(([], nil, nil, nil, 0, nil))
}
return postbox.transaction { transaction -> ([StarGift], [StarGift.UniqueGift.Attribute], [ResaleGiftsContext.Attribute: Int32], Int32, String?) in
return postbox.transaction { transaction -> ([StarGift], [StarGift.UniqueGift.Attribute]?, [ResaleGiftsContext.Attribute: Int32]?, Int64?, Int32, String?) in
switch result {
case let .resaleStarGifts(_, count, gifts, nextOffset, attributes, attributesHash, chats, counters, users):
let _ = attributesHash
var resultAttributes: [StarGift.UniqueGift.Attribute] = []
var resultAttributes: [StarGift.UniqueGift.Attribute]?
if let attributes {
resultAttributes = attributes.compactMap { StarGift.UniqueGift.Attribute(apiAttribute: $0) }
}
var attributeCount: [ResaleGiftsContext.Attribute: Int32] = [:]
var attributeCount: [ResaleGiftsContext.Attribute: Int32]?
if let counters {
var attributeCountValue: [ResaleGiftsContext.Attribute: Int32] = [:]
for counter in counters {
switch counter {
case let .starGiftAttributeCounter(attribute, count):
switch attribute {
case let .starGiftAttributeIdModel(documentId):
attributeCount[.model(documentId)] = count
attributeCountValue[.model(documentId)] = count
case let .starGiftAttributeIdPattern(documentId):
attributeCount[.pattern(documentId)] = count
attributeCountValue[.pattern(documentId)] = count
case let .starGiftAttributeIdBackdrop(backdropId):
attributeCount[.backdrop(backdropId)] = count
attributeCountValue[.backdrop(backdropId)] = count
}
}
}
attributeCount = attributeCountValue
}
let parsedPeers = AccumulatedPeers(transaction: transaction, chats: chats, users: users)
@ -2563,13 +2564,13 @@ private final class ResaleGiftsContextImpl {
}
}
return (mappedGifts, resultAttributes, attributeCount, count, nextOffset)
return (mappedGifts, resultAttributes, attributeCount, attributesHash, count, nextOffset)
}
}
}
self.disposable.set((signal
|> deliverOn(self.queue)).start(next: { [weak self] (gifts, attributes, attributeCount, count, nextOffset) in
|> deliverOn(self.queue)).start(next: { [weak self] (gifts, attributes, attributeCount, attributesHash, count, nextOffset) in
guard let self else {
return
}
@ -2581,10 +2582,13 @@ private final class ResaleGiftsContextImpl {
let updatedCount = max(Int32(self.gifts.count), count)
self.count = updatedCount
self.attributes = attributes
if !attributeCount.isEmpty {
if let attributes, let attributeCount, let attributesHash {
self.attributes = attributes
self.attributeCount = attributeCount
self.attributesHash = attributesHash
}
self.dataState = .ready(canLoadMore: count != 0 && updatedCount > self.gifts.count && nextOffset != nil, nextOffset: nextOffset)
self.pushState()

View File

@ -458,9 +458,13 @@ final class GiftOptionsScreenComponent: Component {
mainController.push(giftController)
}
} else {
var forceUnique = false
if let disallowedGifts = self.state?.disallowedGifts, disallowedGifts.contains(.limited) && !disallowedGifts.contains(.unique) {
forceUnique = true
var forceUnique: Bool?
if let disallowedGifts = self.state?.disallowedGifts {
if disallowedGifts.contains(.limited) && !disallowedGifts.contains(.unique) {
forceUnique = true
} else if !disallowedGifts.contains(.limited) && disallowedGifts.contains(.unique) {
forceUnique = false
}
}
let giftController = GiftSetupScreen(

View File

@ -788,57 +788,60 @@ final class GiftSetupScreenComponent: Component {
contentHeight += sectionSpacing
}
if case let .starGift(starGift, _) = component.subject, let availability = starGift.availability, availability.resale > 0 {
let resaleSectionSize = self.resaleSection.update(
transition: transition,
component: AnyComponent(ListSectionComponent(
theme: environment.theme,
header: nil,
footer: nil,
items: [
AnyComponentWithIdentity(id: 0, component: AnyComponent(ListActionItemComponent(
theme: environment.theme,
title: AnyComponent(VStack([
AnyComponentWithIdentity(id: AnyHashable(0), component: AnyComponent(
MultilineTextComponent(
text: .plain(NSAttributedString(string: environment.strings.Gift_Send_AvailableForResale, font: Font.regular(presentationData.listsFontSize.baseDisplaySize), textColor: environment.theme.list.itemPrimaryTextColor))
if case let .starGift(starGift, forceUnique) = component.subject, let availability = starGift.availability, availability.resale > 0 {
if let forceUnique, !forceUnique {
} else {
let resaleSectionSize = self.resaleSection.update(
transition: transition,
component: AnyComponent(ListSectionComponent(
theme: environment.theme,
header: nil,
footer: nil,
items: [
AnyComponentWithIdentity(id: 0, component: AnyComponent(ListActionItemComponent(
theme: environment.theme,
title: AnyComponent(VStack([
AnyComponentWithIdentity(id: AnyHashable(0), component: AnyComponent(
MultilineTextComponent(
text: .plain(NSAttributedString(string: environment.strings.Gift_Send_AvailableForResale, font: Font.regular(presentationData.listsFontSize.baseDisplaySize), textColor: environment.theme.list.itemPrimaryTextColor))
)
)),
], alignment: .left, spacing: 2.0)),
accessory: .custom(ListActionItemComponent.CustomAccessory(component: AnyComponentWithIdentity(id: 0, component: AnyComponent(MultilineTextComponent(
text: .plain(NSAttributedString(
string: presentationStringsFormattedNumber(Int32(availability.resale), environment.dateTimeFormat.groupingSeparator),
font: Font.regular(presentationData.listsFontSize.baseDisplaySize),
textColor: environment.theme.list.itemSecondaryTextColor
)),
maximumNumberOfLines: 0
))), insets: UIEdgeInsets(top: 0.0, left: 0.0, bottom: 0.0, right: 16.0))),
action: { [weak self] _ in
guard let self, let component = self.component, let controller = environment.controller() else {
return
}
let storeController = component.context.sharedContext.makeGiftStoreController(
context: component.context,
peerId: component.peerId,
gift: starGift
)
)),
], alignment: .left, spacing: 2.0)),
accessory: .custom(ListActionItemComponent.CustomAccessory(component: AnyComponentWithIdentity(id: 0, component: AnyComponent(MultilineTextComponent(
text: .plain(NSAttributedString(
string: presentationStringsFormattedNumber(Int32(availability.resale), environment.dateTimeFormat.groupingSeparator),
font: Font.regular(presentationData.listsFontSize.baseDisplaySize),
textColor: environment.theme.list.itemSecondaryTextColor
)),
maximumNumberOfLines: 0
))), insets: UIEdgeInsets(top: 0.0, left: 0.0, bottom: 0.0, right: 16.0))),
action: { [weak self] _ in
guard let self, let component = self.component, let controller = environment.controller() else {
return
controller.push(storeController)
}
let storeController = component.context.sharedContext.makeGiftStoreController(
context: component.context,
peerId: component.peerId,
gift: starGift
)
controller.push(storeController)
}
)))
]
)),
environment: {},
containerSize: CGSize(width: availableSize.width - sideInset * 2.0, height: 10000.0)
)
let resaleSectionFrame = CGRect(origin: CGPoint(x: sideInset, y: contentHeight), size: resaleSectionSize)
if let resaleSectionView = self.resaleSection.view {
if resaleSectionView.superview == nil {
self.scrollView.addSubview(resaleSectionView)
)))
]
)),
environment: {},
containerSize: CGSize(width: availableSize.width - sideInset * 2.0, height: 10000.0)
)
let resaleSectionFrame = CGRect(origin: CGPoint(x: sideInset, y: contentHeight), size: resaleSectionSize)
if let resaleSectionView = self.resaleSection.view {
if resaleSectionView.superview == nil {
self.scrollView.addSubview(resaleSectionView)
}
transition.setFrame(view: resaleSectionView, frame: resaleSectionFrame)
}
transition.setFrame(view: resaleSectionView, frame: resaleSectionFrame)
contentHeight += resaleSectionSize.height
contentHeight += sectionSpacing
}
contentHeight += resaleSectionSize.height
contentHeight += sectionSpacing
}
let giftConfiguration = GiftConfiguration.with(appConfiguration: component.context.currentAppConfiguration.with { $0 })
@ -1128,7 +1131,7 @@ final class GiftSetupScreenComponent: Component {
if isChannelGift {
upgradeFooterRawString = environment.strings.Gift_SendChannel_Upgrade_Info(peerName).string
} else {
if forceUnique {
if forceUnique == true {
upgradeFooterRawString = environment.strings.Gift_Send_Upgrade_ForcedInfo(peerName).string
} else {
upgradeFooterRawString = environment.strings.Gift_Send_Upgrade_Info(peerName).string
@ -1201,8 +1204,8 @@ final class GiftSetupScreenComponent: Component {
)
)),
], alignment: .left, spacing: 2.0)),
accessory: .toggle(ListActionItemComponent.Toggle(style: .regular, isOn: self.includeUpgrade, isEnabled: !forceUnique, action: { [weak self] _ in
guard let self, !forceUnique else {
accessory: .toggle(ListActionItemComponent.Toggle(style: .regular, isOn: self.includeUpgrade, isEnabled: forceUnique != true, action: { [weak self] _ in
guard let self, forceUnique != true else {
return
}
self.includeUpgrade = !self.includeUpgrade
@ -1748,7 +1751,7 @@ final class GiftSetupScreenComponent: Component {
public final class GiftSetupScreen: ViewControllerComponentContainer {
public enum Subject: Equatable {
case premium(PremiumGiftProduct)
case starGift(StarGift.Gift, Bool)
case starGift(StarGift.Gift, Bool?)
}
private let context: AccountContext

View File

@ -789,6 +789,11 @@ final class GiftStoreScreenComponent: Component {
}
self.component = component
var isLoading = false
if self.state?.starGiftsState?.gifts == nil || self.state?.starGiftsState?.dataState == .loading {
isLoading = true
}
let theme = environment.theme
let strings = environment.strings
@ -887,6 +892,10 @@ final class GiftStoreScreenComponent: Component {
balanceIconView.bounds = CGRect(origin: .zero, size: balanceIconSize)
}
var topInset: CGFloat = 0.0
if environment.statusBarHeight > 0.0 {
topInset = environment.statusBarHeight - 6.0
}
let titleSize = self.title.update(
transition: transition,
component: AnyComponent(MultilineTextComponent(
@ -900,7 +909,7 @@ final class GiftStoreScreenComponent: Component {
if titleView.superview == nil {
self.addSubview(titleView)
}
transition.setFrame(view: titleView, frame: CGRect(origin: CGPoint(x: floor((availableSize.width - titleSize.width) / 2.0), y: 10.0), size: titleSize))
transition.setFrame(view: titleView, frame: CGRect(origin: CGPoint(x: floor((availableSize.width - titleSize.width) / 2.0), y: topInset + 10.0), size: titleSize))
}
let effectiveCount: Int32
@ -922,7 +931,7 @@ final class GiftStoreScreenComponent: Component {
environment: {},
containerSize: CGSize(width: availableSize.width - headerSideInset * 2.0, height: 100.0)
)
let subtitleFrame = CGRect(origin: CGPoint(x: floor((availableSize.width - subtitleSize.width) / 2.0), y: 31.0), size: subtitleSize)
let subtitleFrame = CGRect(origin: CGPoint(x: floor((availableSize.width - subtitleSize.width) / 2.0), y: topInset + 31.0), size: subtitleSize)
if let subtitleView = self.subtitle.view {
if subtitleView.superview == nil {
self.addSubview(subtitleView)
@ -984,10 +993,10 @@ final class GiftStoreScreenComponent: Component {
modelTitle = environment.strings.Gift_Store_Filter_Selected_Model(modelCount)
}
if backdropCount > 0 {
backdropTitle = environment.strings.Gift_Store_Filter_Selected_Backdrop(modelCount)
backdropTitle = environment.strings.Gift_Store_Filter_Selected_Backdrop(backdropCount)
}
if symbolCount > 0 {
symbolTitle = environment.strings.Gift_Store_Filter_Selected_Symbol(modelCount)
symbolTitle = environment.strings.Gift_Store_Filter_Selected_Symbol(symbolCount)
}
}
@ -1036,7 +1045,7 @@ final class GiftStoreScreenComponent: Component {
if filterSelectorView.superview == nil {
self.addSubview(filterSelectorView)
}
transition.setFrame(view: filterSelectorView, frame: CGRect(origin: CGPoint(x: floor((availableSize.width - filterSize.width) / 2.0), y: 56.0), size: filterSize))
transition.setFrame(view: filterSelectorView, frame: CGRect(origin: CGPoint(x: floor((availableSize.width - filterSize.width) / 2.0), y: topInset + 56.0), size: filterSize))
}
if let starGifts = self.state?.starGiftsState?.gifts {
@ -1078,12 +1087,7 @@ final class GiftStoreScreenComponent: Component {
self.topOverscrollLayer.frame = CGRect(origin: CGPoint(x: 0.0, y: -3000.0), size: CGSize(width: availableSize.width, height: 3000.0))
self.updateScrolling(transition: transition)
var isLoading = false
if self.state?.starGiftsState?.gifts == nil || self.state?.starGiftsState?.dataState == .loading {
isLoading = true
}
let loadingTransition: ComponentTransition = .easeInOut(duration: 0.25)
if isLoading {
self.loadingNode.update(size: availableSize, theme: environment.theme, transition: .immediate)

View File

@ -805,6 +805,7 @@ private final class GiftViewSheetContent: CombinedComponent {
default:
break
}
self.updated(transition: .easeInOut(duration: 0.2))
let text = presentationData.strings.Gift_View_Resale_Unlist_Success(giftTitle).string
let tooltipController = UndoOverlayController(
@ -880,7 +881,8 @@ private final class GiftViewSheetContent: CombinedComponent {
default:
break
}
self.updated(transition: .easeInOut(duration: 0.2))
var text = presentationData.strings.Gift_View_Resale_List_Success(giftTitle).string
if update {
let starsString = presentationData.strings.Gift_View_Resale_Relist_Success_Stars(Int32(price))