Various fixes

This commit is contained in:
Ilya Laktyushin 2025-11-14 02:08:00 +04:00
parent 1d351a0547
commit cbf23d0df5
8 changed files with 66 additions and 18 deletions

View File

@ -4,6 +4,7 @@ import UIKit
public final class Button: Component { public final class Button: Component {
public let content: AnyComponent<Empty> public let content: AnyComponent<Empty>
public let minSize: CGSize? public let minSize: CGSize?
public let hitTestEdgeInsets: UIEdgeInsets?
public let tag: AnyObject? public let tag: AnyObject?
public let automaticHighlight: Bool public let automaticHighlight: Bool
public let isEnabled: Bool public let isEnabled: Bool
@ -22,6 +23,7 @@ public final class Button: Component {
self.init( self.init(
content: content, content: content,
minSize: nil, minSize: nil,
hitTestEdgeInsets: nil,
tag: nil, tag: nil,
automaticHighlight: automaticHighlight, automaticHighlight: automaticHighlight,
isEnabled: isEnabled, isEnabled: isEnabled,
@ -34,6 +36,7 @@ public final class Button: Component {
private init( private init(
content: AnyComponent<Empty>, content: AnyComponent<Empty>,
minSize: CGSize? = nil, minSize: CGSize? = nil,
hitTestEdgeInsets: UIEdgeInsets? = nil,
tag: AnyObject? = nil, tag: AnyObject? = nil,
automaticHighlight: Bool = true, automaticHighlight: Bool = true,
isEnabled: Bool = true, isEnabled: Bool = true,
@ -44,6 +47,7 @@ public final class Button: Component {
) { ) {
self.content = content self.content = content
self.minSize = minSize self.minSize = minSize
self.hitTestEdgeInsets = hitTestEdgeInsets
self.tag = tag self.tag = tag
self.automaticHighlight = automaticHighlight self.automaticHighlight = automaticHighlight
self.isEnabled = isEnabled self.isEnabled = isEnabled
@ -57,6 +61,22 @@ public final class Button: Component {
return Button( return Button(
content: self.content, content: self.content,
minSize: minSize, minSize: minSize,
hitTestEdgeInsets: self.hitTestEdgeInsets,
tag: self.tag,
automaticHighlight: self.automaticHighlight,
isEnabled: self.isEnabled,
isExclusive: self.isExclusive,
action: self.action,
holdAction: self.holdAction,
highlightedAction: self.highlightedAction
)
}
public func withHitTestEdgeInsets(_ hitTestEdgeInsets: UIEdgeInsets?) -> Button {
return Button(
content: self.content,
minSize: self.minSize,
hitTestEdgeInsets: hitTestEdgeInsets,
tag: self.tag, tag: self.tag,
automaticHighlight: self.automaticHighlight, automaticHighlight: self.automaticHighlight,
isEnabled: self.isEnabled, isEnabled: self.isEnabled,
@ -71,6 +91,7 @@ public final class Button: Component {
return Button( return Button(
content: self.content, content: self.content,
minSize: self.minSize, minSize: self.minSize,
hitTestEdgeInsets: self.hitTestEdgeInsets,
tag: self.tag, tag: self.tag,
automaticHighlight: self.automaticHighlight, automaticHighlight: self.automaticHighlight,
isEnabled: self.isEnabled, isEnabled: self.isEnabled,
@ -86,6 +107,7 @@ public final class Button: Component {
return Button( return Button(
content: self.content, content: self.content,
minSize: self.minSize, minSize: self.minSize,
hitTestEdgeInsets: self.hitTestEdgeInsets,
tag: self.tag, tag: self.tag,
automaticHighlight: self.automaticHighlight, automaticHighlight: self.automaticHighlight,
isEnabled: self.isEnabled, isEnabled: self.isEnabled,
@ -100,6 +122,7 @@ public final class Button: Component {
return Button( return Button(
content: self.content, content: self.content,
minSize: self.minSize, minSize: self.minSize,
hitTestEdgeInsets: self.hitTestEdgeInsets,
tag: tag, tag: tag,
automaticHighlight: self.automaticHighlight, automaticHighlight: self.automaticHighlight,
isEnabled: self.isEnabled, isEnabled: self.isEnabled,
@ -117,6 +140,9 @@ public final class Button: Component {
if lhs.minSize != rhs.minSize { if lhs.minSize != rhs.minSize {
return false return false
} }
if lhs.hitTestEdgeInsets != rhs.hitTestEdgeInsets {
return false
}
if lhs.tag !== rhs.tag { if lhs.tag !== rhs.tag {
return false return false
} }
@ -174,6 +200,14 @@ public final class Button: Component {
private var holdActionTriggerred: Bool = false private var holdActionTriggerred: Bool = false
private var holdActionTimer: Timer? private var holdActionTimer: Timer?
public override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
var bounds = self.bounds
if let hitTestEdgeInsets = self.component?.hitTestEdgeInsets {
bounds = bounds.insetBy(dx: hitTestEdgeInsets.left, dy: hitTestEdgeInsets.top)
}
return bounds.contains(point)
}
override init(frame: CGRect) { override init(frame: CGRect) {
self.contentView = ComponentHostView<Empty>() self.contentView = ComponentHostView<Empty>()
self.contentView.isUserInteractionEnabled = false self.contentView.isUserInteractionEnabled = false

View File

@ -347,7 +347,7 @@ final class StarsTransactionItemNode: ListViewItemNode, ItemListItemNode {
theme: item.presentationData.theme, theme: item.presentationData.theme,
title: AnyComponent(VStack(titleComponents, alignment: .left, spacing: 2.0)), title: AnyComponent(VStack(titleComponents, alignment: .left, spacing: 2.0)),
contentInsets: UIEdgeInsets(top: 9.0, left: 0.0, bottom: 8.0, right: 0.0), contentInsets: UIEdgeInsets(top: 9.0, left: 0.0, bottom: 8.0, right: 0.0),
leftIcon: .custom(AnyComponentWithIdentity(id: "avatar", component: AnyComponent(StarsAvatarComponent(context: item.context, theme: item.presentationData.theme, peer: .transactionPeer(item.transaction.peer), photo: nil, media: [], uniqueGift: nil, backgroundColor: item.presentationData.theme.list.itemBlocksBackgroundColor))), false), leftIcon: .custom(AnyComponentWithIdentity(id: "avatar", component: AnyComponent(StarsAvatarComponent(context: item.context, theme: item.presentationData.theme, peer: .transactionPeer(item.transaction.peer), photo: nil, media: [], gift: nil, backgroundColor: item.presentationData.theme.list.itemBlocksBackgroundColor))), false),
icon: nil, icon: nil,
accessory: .custom(ListActionItemComponent.CustomAccessory(component: AnyComponentWithIdentity(id: "label", component: AnyComponent(StarsLabelComponent(text: itemLabel, iconName: itemIconName, iconColor: itemIconColor))), insets: UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 16.0))), accessory: .custom(ListActionItemComponent.CustomAccessory(component: AnyComponentWithIdentity(id: "label", component: AnyComponent(StarsLabelComponent(text: itemLabel, iconName: itemIconName, iconColor: itemIconColor))), insets: UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 16.0))),
action: { [weak self] _ in action: { [weak self] _ in

View File

@ -1411,6 +1411,7 @@ final class CaptureControlsComponent: Component {
transition.setAlpha(view: bottomSettingsButtonView, alpha: !isLiveStream || isLiveActive || isRecording || isTransitioning || hideControls ? 0.0 : 1.0) transition.setAlpha(view: bottomSettingsButtonView, alpha: !isLiveStream || isLiveActive || isRecording || isTransitioning || hideControls ? 0.0 : 1.0)
} }
var hitTestEdgeInsets: UIEdgeInsets?
var blobState: ShutterBlobView.BlobState var blobState: ShutterBlobView.BlobState
switch component.shutterState { switch component.shutterState {
case .generic, .disabled: case .generic, .disabled:
@ -1423,6 +1424,7 @@ final class CaptureControlsComponent: Component {
blobState = self.panBlobState ?? .video blobState = self.panBlobState ?? .video
case .live: case .live:
blobState = .live blobState = .live
hitTestEdgeInsets = UIEdgeInsets(top: 0.0, left: -130.0, bottom: 0.0, right: -130.0)
} }
let shutterButtonSize = self.shutterButtonView.update( let shutterButtonSize = self.shutterButtonView.update(
@ -1451,7 +1453,7 @@ final class CaptureControlsComponent: Component {
component.shutterTapped() component.shutterTapped()
}, },
highlightedAction: self.shutterHightlightedAction highlightedAction: self.shutterHightlightedAction
).minSize(maximumShutterSize) ).minSize(maximumShutterSize).withHitTestEdgeInsets(hitTestEdgeInsets)
), ),
environment: {}, environment: {},
containerSize: availableSize containerSize: availableSize

View File

@ -177,7 +177,7 @@ private final class GiftWithdrawAlertContentNode: AlertContentNode {
peer: .transactionPeer(.fragment), peer: .transactionPeer(.fragment),
photo: nil, photo: nil,
media: [], media: [],
uniqueGift: nil, gift: nil,
backgroundColor: .clear, backgroundColor: .clear,
size: avatarSize size: avatarSize
) )

View File

@ -24,7 +24,7 @@ public final class StarsAvatarComponent: Component {
let peer: StarsAvatarComponent.Peer? let peer: StarsAvatarComponent.Peer?
let photo: TelegramMediaWebFile? let photo: TelegramMediaWebFile?
let media: [Media] let media: [Media]
let uniqueGift: StarGift.UniqueGift? let gift: StarGift?
let backgroundColor: UIColor let backgroundColor: UIColor
let size: CGSize? let size: CGSize?
@ -34,7 +34,7 @@ public final class StarsAvatarComponent: Component {
peer: StarsAvatarComponent.Peer?, peer: StarsAvatarComponent.Peer?,
photo: TelegramMediaWebFile?, photo: TelegramMediaWebFile?,
media: [Media], media: [Media],
uniqueGift: StarGift.UniqueGift?, gift: StarGift?,
backgroundColor: UIColor, backgroundColor: UIColor,
size: CGSize? = nil size: CGSize? = nil
) { ) {
@ -43,7 +43,7 @@ public final class StarsAvatarComponent: Component {
self.peer = peer self.peer = peer
self.photo = photo self.photo = photo
self.media = media self.media = media
self.uniqueGift = uniqueGift self.gift = gift
self.backgroundColor = backgroundColor self.backgroundColor = backgroundColor
self.size = size self.size = size
} }
@ -64,7 +64,7 @@ public final class StarsAvatarComponent: Component {
if !areMediaArraysEqual(lhs.media, rhs.media) { if !areMediaArraysEqual(lhs.media, rhs.media) {
return false return false
} }
if lhs.uniqueGift != rhs.uniqueGift { if lhs.gift != rhs.gift {
return false return false
} }
if lhs.backgroundColor != rhs.backgroundColor { if lhs.backgroundColor != rhs.backgroundColor {
@ -121,8 +121,17 @@ public final class StarsAvatarComponent: Component {
var dimensions = size var dimensions = size
var didSetup = false var didSetup = false
if let gift = component.uniqueGift { if let gift = component.gift {
let giftFrame = CGRect(origin: .zero, size: size) let giftFrame = CGRect(origin: .zero, size: size)
var subject: GiftItemComponent.Subject
switch gift {
case let .generic(gift):
subject = .starGift(gift: gift, price: "")
case let .unique(gift):
subject = .uniqueGift(gift: gift, price: nil)
}
let _ = self.giftView.update( let _ = self.giftView.update(
transition: .immediate, transition: .immediate,
component: AnyComponent( component: AnyComponent(
@ -131,7 +140,7 @@ public final class StarsAvatarComponent: Component {
theme: component.theme, theme: component.theme,
strings: component.context.sharedContext.currentPresentationData.with { $0 }.strings, strings: component.context.sharedContext.currentPresentationData.with { $0 }.strings,
peer: nil, peer: nil,
subject: .uniqueGift(gift: gift, price: nil), subject: subject,
mode: .thumbnail mode: .thumbnail
) )
), ),

View File

@ -214,6 +214,7 @@ private final class StarsTransactionSheetContent: CombinedComponent {
var photo: TelegramMediaWebFile? var photo: TelegramMediaWebFile?
var transactionStatus: (String, UIColor)? = nil var transactionStatus: (String, UIColor)? = nil
var isGift = false var isGift = false
var isGiftAuctionBid = false
var isSubscription = false var isSubscription = false
var isSubscriber = false var isSubscriber = false
var isSubscriptionFee = false var isSubscriptionFee = false
@ -356,6 +357,7 @@ private final class StarsTransactionSheetContent: CombinedComponent {
case .generic: case .generic:
if transaction.flags.contains(.isStarGiftAuctionBid) { if transaction.flags.contains(.isStarGiftAuctionBid) {
titleText = strings.Stars_Transaction_GiftAuctionBid titleText = strings.Stars_Transaction_GiftAuctionBid
isGiftAuctionBid = true
} else { } else {
titleText = strings.Stars_Transaction_Gift_Title titleText = strings.Stars_Transaction_Gift_Title
} }
@ -927,7 +929,7 @@ private final class StarsTransactionSheetContent: CombinedComponent {
)) ))
} }
if isGift, toPeer == nil { if isGift && !isGiftAuctionBid, toPeer == nil {
tableItems.append(.init( tableItems.append(.init(
id: "from", id: "from",
title: strings.Stars_Transaction_From, title: strings.Stars_Transaction_From,
@ -950,7 +952,7 @@ private final class StarsTransactionSheetContent: CombinedComponent {
) )
) )
)) ))
} else if let toPeer, !isRefProgram { } else if let toPeer, !isRefProgram && !isGiftAuctionBid {
let title: String let title: String
if isGiftUpgrade { if isGiftUpgrade {
title = strings.Stars_Transaction_GiftFrom title = strings.Stars_Transaction_GiftFrom
@ -2438,7 +2440,7 @@ private final class PeerCellComponent: Component {
let avatarNaturalSize = self.avatar.update( let avatarNaturalSize = self.avatar.update(
transition: .immediate, transition: .immediate,
component: AnyComponent( component: AnyComponent(
StarsAvatarComponent(context: component.context, theme: component.theme, peer: .transactionPeer(peer), photo: nil, media: [], uniqueGift: nil, backgroundColor: .clear) StarsAvatarComponent(context: component.context, theme: component.theme, peer: .transactionPeer(peer), photo: nil, media: [], gift: nil, backgroundColor: .clear)
), ),
environment: {}, environment: {},
containerSize: CGSize(width: 40.0, height: 40.0) containerSize: CGSize(width: 40.0, height: 40.0)

View File

@ -301,7 +301,7 @@ final class StarsTransactionsListPanelComponent: Component {
var itemDate: String var itemDate: String
var itemPeer: StarsAvatarComponent.Peer = .transactionPeer(item.peer) var itemPeer: StarsAvatarComponent.Peer = .transactionPeer(item.peer)
var itemFile: TelegramMediaFile? var itemFile: TelegramMediaFile?
var uniqueGift: StarGift.UniqueGift? var itemGift: StarGift?
switch item.peer { switch item.peer {
case let .peer(peer): case let .peer(peer):
if let months = item.premiumGiftMonths { if let months = item.premiumGiftMonths {
@ -325,17 +325,18 @@ final class StarsTransactionsListPanelComponent: Component {
if item.flags.contains(.isStarGiftAuctionBid), case let .generic(gift) = starGift { if item.flags.contains(.isStarGiftAuctionBid), case let .generic(gift) = starGift {
itemTitle = gift.title ?? "Gift" itemTitle = gift.title ?? "Gift"
itemSubtitle = environment.strings.Stars_Intro_Transaction_GiftAuctionBid itemSubtitle = environment.strings.Stars_Intro_Transaction_GiftAuctionBid
itemGift = starGift
} else if item.flags.contains(.isStarGiftPrepaidUpgrade) { } else if item.flags.contains(.isStarGiftPrepaidUpgrade) {
itemTitle = peer.displayTitle(strings: environment.strings, displayOrder: .firstLast) itemTitle = peer.displayTitle(strings: environment.strings, displayOrder: .firstLast)
itemSubtitle = environment.strings.Stars_Intro_Transaction_PrepaidGiftUpgrade itemSubtitle = environment.strings.Stars_Intro_Transaction_PrepaidGiftUpgrade
} else if item.flags.contains(.isStarGiftDropOriginalDetails), case let .unique(gift) = starGift { } else if item.flags.contains(.isStarGiftDropOriginalDetails), case let .unique(gift) = starGift {
itemTitle = "\(gift.title) #\(presentationStringsFormattedNumber(gift.number, environment.dateTimeFormat.groupingSeparator))" itemTitle = "\(gift.title) #\(presentationStringsFormattedNumber(gift.number, environment.dateTimeFormat.groupingSeparator))"
itemSubtitle = environment.strings.Stars_Intro_Transaction_GiftDropOriginalDetails itemSubtitle = environment.strings.Stars_Intro_Transaction_GiftDropOriginalDetails
uniqueGift = gift itemGift = starGift
} else if item.flags.contains(.isStarGiftUpgrade), case let .unique(gift) = starGift { } else if item.flags.contains(.isStarGiftUpgrade), case let .unique(gift) = starGift {
itemTitle = "\(gift.title) #\(presentationStringsFormattedNumber(gift.number, environment.dateTimeFormat.groupingSeparator))" itemTitle = "\(gift.title) #\(presentationStringsFormattedNumber(gift.number, environment.dateTimeFormat.groupingSeparator))"
itemSubtitle = environment.strings.Stars_Intro_Transaction_GiftUpgrade itemSubtitle = environment.strings.Stars_Intro_Transaction_GiftUpgrade
uniqueGift = gift itemGift = starGift
} else { } else {
itemTitle = peer.displayTitle(strings: environment.strings, displayOrder: .firstLast) itemTitle = peer.displayTitle(strings: environment.strings, displayOrder: .firstLast)
switch starGift { switch starGift {
@ -526,7 +527,7 @@ final class StarsTransactionsListPanelComponent: Component {
theme: environment.theme, theme: environment.theme,
title: AnyComponent(VStack(titleComponents, alignment: .left, spacing: 2.0)), title: AnyComponent(VStack(titleComponents, alignment: .left, spacing: 2.0)),
contentInsets: UIEdgeInsets(top: 9.0, left: environment.containerInsets.left, bottom: 8.0, right: environment.containerInsets.right), contentInsets: UIEdgeInsets(top: 9.0, left: environment.containerInsets.left, bottom: 8.0, right: environment.containerInsets.right),
leftIcon: .custom(AnyComponentWithIdentity(id: "avatar", component: AnyComponent(StarsAvatarComponent(context: component.context, theme: environment.theme, peer: itemPeer, photo: item.photo, media: item.media, uniqueGift: uniqueGift, backgroundColor: environment.theme.list.plainBackgroundColor))), false), leftIcon: .custom(AnyComponentWithIdentity(id: "avatar", component: AnyComponent(StarsAvatarComponent(context: component.context, theme: environment.theme, peer: itemPeer, photo: item.photo, media: item.media, gift: itemGift, backgroundColor: environment.theme.list.plainBackgroundColor))), false),
icon: nil, icon: nil,
accessory: .custom(ListActionItemComponent.CustomAccessory(component: AnyComponentWithIdentity(id: "label", component: AnyComponent(StarsLabelComponent(text: itemLabel, iconName: itemIconName, iconColor: itemIconColor))), insets: UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 16.0))), accessory: .custom(ListActionItemComponent.CustomAccessory(component: AnyComponentWithIdentity(id: "label", component: AnyComponent(StarsLabelComponent(text: itemLabel, iconName: itemIconName, iconColor: itemIconColor))), insets: UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 16.0))),
action: { [weak self] _ in action: { [weak self] _ in

View File

@ -929,7 +929,7 @@ final class StarsTransactionsScreenComponent: Component {
if let photo = subscription.photo { if let photo = subscription.photo {
nameGroupComponent = AnyComponent( nameGroupComponent = AnyComponent(
HStack([ HStack([
AnyComponentWithIdentity(id: AnyHashable(0), component: AnyComponent(StarsAvatarComponent(context: component.context, theme: environment.theme, peer: nil, photo: photo, media: [], uniqueGift: nil, backgroundColor: .clear, size: CGSize(width: 19.0, height: 19.0)))), AnyComponentWithIdentity(id: AnyHashable(0), component: AnyComponent(StarsAvatarComponent(context: component.context, theme: environment.theme, peer: nil, photo: photo, media: [], gift: nil, backgroundColor: .clear, size: CGSize(width: 19.0, height: 19.0)))),
AnyComponentWithIdentity(id: AnyHashable(1), component: nameComponent) AnyComponentWithIdentity(id: AnyHashable(1), component: nameComponent)
], spacing: 6.0) ], spacing: 6.0)
) )
@ -972,7 +972,7 @@ final class StarsTransactionsScreenComponent: Component {
style: .glass, style: .glass,
title: AnyComponent(VStack(titleComponents, alignment: .left, spacing: 2.0)), title: AnyComponent(VStack(titleComponents, alignment: .left, spacing: 2.0)),
contentInsets: UIEdgeInsets(top: 9.0, left: 0.0, bottom: 8.0, right: 0.0), contentInsets: UIEdgeInsets(top: 9.0, left: 0.0, bottom: 8.0, right: 0.0),
leftIcon: .custom(AnyComponentWithIdentity(id: "avatar", component: AnyComponent(StarsAvatarComponent(context: component.context, theme: environment.theme, peer: .transactionPeer(.peer(subscription.peer)), photo: nil, media: [], uniqueGift: nil, backgroundColor: environment.theme.list.plainBackgroundColor))), false), leftIcon: .custom(AnyComponentWithIdentity(id: "avatar", component: AnyComponent(StarsAvatarComponent(context: component.context, theme: environment.theme, peer: .transactionPeer(.peer(subscription.peer)), photo: nil, media: [], gift: nil, backgroundColor: environment.theme.list.plainBackgroundColor))), false),
icon: nil, icon: nil,
accessory: .custom(ListActionItemComponent.CustomAccessory(component: labelComponent, insets: UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 16.0))), accessory: .custom(ListActionItemComponent.CustomAccessory(component: labelComponent, insets: UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 16.0))),
action: { [weak self] _ in action: { [weak self] _ in