mirror of
https://github.com/TelegramMessenger/Telegram-iOS.git
synced 2026-07-06 03:33:41 +02:00
Merge commit '10a429b944' into experimental-3
This commit is contained in:
commit
3982aa3f9e
24 changed files with 337 additions and 181 deletions
|
|
@ -15614,7 +15614,7 @@ Error: %8$@";
|
|||
"Notification.StarGiftOffer.Expiration.Hours_any" = "%@ h";
|
||||
"Notification.StarGiftOffer.Expiration.Minutes_1" = "%@ m";
|
||||
"Notification.StarGiftOffer.Expiration.Minutes_any" = "%@ m";
|
||||
"Notification.StarGiftOffer.Expiration.Delimiter" = "";
|
||||
"Notification.StarGiftOffer.Expiration.Delimiter" = " ";
|
||||
|
||||
"Chat.GiftPurchaseOffer.AcceptConfirmation.Title" = "Confirm Sale";
|
||||
"Chat.GiftPurchaseOffer.AcceptConfirmation.Text" = "Do you want to sell **%1$@** to %2$@ for **%3$@**? You'll receive **%4$@** after fees.";
|
||||
|
|
|
|||
|
|
@ -305,7 +305,11 @@ public final class SheetComponent<ChildEnvironmentType: Sendable & Equatable>: C
|
|||
|
||||
let transition = ContainedViewLayoutTransition.animated(duration: 0.4, curve: .spring)
|
||||
let targetPosition = self.scrollView.center
|
||||
self.scrollView.center = targetPosition.offsetBy(dx: 0.0, dy: self.scrollView.contentSize.height)
|
||||
var offset: CGFloat = self.scrollView.contentSize.height
|
||||
if self.isCentered {
|
||||
offset = self.frame.height + self.scrollView.frame.height * 0.5
|
||||
}
|
||||
self.scrollView.center = targetPosition.offsetBy(dx: 0.0, dy: offset)
|
||||
transition.animateView(allowUserInteraction: true, {
|
||||
self.scrollView.center = targetPosition
|
||||
})
|
||||
|
|
@ -338,18 +342,27 @@ public final class SheetComponent<ChildEnvironmentType: Sendable & Equatable>: C
|
|||
let contentOffset = (self.scrollView.contentOffset.y + self.scrollView.contentInset.top - self.scrollView.contentSize.height) * -1.0
|
||||
let dismissalOffset = self.scrollView.contentSize.height + abs(contentView.frame.minY)
|
||||
let delta = dismissalOffset - contentOffset
|
||||
var targetPosition = self.scrollView.center.y + delta
|
||||
if self.isCentered {
|
||||
targetPosition = self.frame.height + self.scrollView.frame.height * 0.5
|
||||
}
|
||||
|
||||
transition.updatePosition(layer: self.scrollView.layer, position: CGPoint(x: self.scrollView.center.x, y: self.scrollView.center.y + delta), completion: { _ in
|
||||
transition.updatePosition(layer: self.scrollView.layer, position: CGPoint(x: self.scrollView.center.x, y: targetPosition), completion: { _ in
|
||||
completion()
|
||||
})
|
||||
} else {
|
||||
self.scrollView.layer.animatePosition(from: CGPoint(), to: CGPoint(x: 0.0, y: self.scrollView.contentSize.height + abs(contentView.frame.minY)), duration: 0.25, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, removeOnCompletion: false, additive: true, completion: { _ in
|
||||
var targetOffset: CGFloat = self.scrollView.contentSize.height + abs(contentView.frame.minY)
|
||||
if self.isCentered {
|
||||
targetOffset = self.frame.height + self.scrollView.frame.height * 0.5
|
||||
}
|
||||
self.scrollView.layer.animatePosition(from: CGPoint(), to: CGPoint(x: 0.0, y: targetOffset), duration: 0.25, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, removeOnCompletion: false, additive: true, completion: { _ in
|
||||
completion()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private var currentHasInputHeight = false
|
||||
private var isCentered = false
|
||||
private var currentAvailableSize: CGSize?
|
||||
func update(component: SheetComponent<ChildEnvironmentType>, availableSize: CGSize, state: EmptyComponentState, environment: Environment<EnvironmentType>, transition: ComponentTransition) -> CGSize {
|
||||
let previousHasInputHeight = self.currentHasInputHeight
|
||||
|
|
@ -364,6 +377,7 @@ public final class SheetComponent<ChildEnvironmentType: Sendable & Equatable>: C
|
|||
}
|
||||
|
||||
self.component = component
|
||||
self.isCentered = sheetEnvironment.isCentered
|
||||
self.currentHasInputHeight = sheetEnvironment.hasInputHeight
|
||||
|
||||
if self.isAnimatingOut {
|
||||
|
|
@ -454,7 +468,7 @@ public final class SheetComponent<ChildEnvironmentType: Sendable & Equatable>: C
|
|||
switch component.style {
|
||||
case .glass:
|
||||
let clipFrame = CGRect(origin: CGPoint(x: glassInset, y: -glassInset), size: CGSize(width: contentSize.width, height: contentSize.height))
|
||||
self.clipView.update(size: clipFrame.size, color: .clear, topCornerRadius: topCornerRadius, bottomCornerRadius: bottomCornerRadius, transition: transition)
|
||||
self.clipView.update(size: clipFrame.size, color: .clear, topCornerRadius: topCornerRadius - 1.5, bottomCornerRadius: bottomCornerRadius, transition: transition)
|
||||
transition.setFrame(view: self.clipView, frame: clipFrame)
|
||||
transition.setFrame(view: contentView, frame: CGRect(origin: .zero, size: CGSize(width: contentSize.width, height: contentSize.height)), completion: nil)
|
||||
transition.setFrame(view: self.backgroundView, frame: CGRect(origin: CGPoint(x: glassInset, y: -glassInset), size: CGSize(width: contentSize.width, height: contentSize.height)), completion: nil)
|
||||
|
|
@ -468,7 +482,7 @@ public final class SheetComponent<ChildEnvironmentType: Sendable & Equatable>: C
|
|||
transition.setFrame(view: effectView, frame: CGRect(origin: .zero, size: CGSize(width: contentSize.width, height: contentSize.height + 1000.0)), completion: nil)
|
||||
}
|
||||
}
|
||||
self.backgroundView.update(size: contentSize, color: backgroundColor, topCornerRadius: topCornerRadius, bottomCornerRadius: bottomCornerRadius, transition: transition)
|
||||
self.backgroundView.update(size: contentSize, color: backgroundColor, topCornerRadius: topCornerRadius + 1.5, bottomCornerRadius: bottomCornerRadius, transition: transition)
|
||||
}
|
||||
}
|
||||
transition.setFrame(view: self.scrollView, frame: CGRect(origin: CGPoint(), size: availableSize), completion: nil)
|
||||
|
|
|
|||
|
|
@ -1135,7 +1135,11 @@ static id<LegacyComponentsContext> _defaultContext = nil;
|
|||
return UIEdgeInsetsMake(0.0f, 44.0f, 21.0f, 44.0f);
|
||||
|
||||
default:
|
||||
return UIEdgeInsetsMake(44.0f, 0.0f, 34.0f, 0.0f);
|
||||
if (iosMajorVersion() >= 26) {
|
||||
return UIEdgeInsetsMake(44.0f, 0.0f, 20.0f, 0.0f);
|
||||
} else {
|
||||
return UIEdgeInsetsMake(44.0f, 0.0f, 34.0f, 0.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -716,6 +716,22 @@ NSString *suffix = @"";
|
|||
[platform isEqualToString:@"iPad14,11"])
|
||||
return @"iPad Air (7th gen)";
|
||||
|
||||
if ([platform isEqualToString:@"iPad15,3"] ||
|
||||
[platform isEqualToString:@"iPad15,4"])
|
||||
return @"iPad Air 11 inch (7th gen)";
|
||||
|
||||
if ([platform isEqualToString:@"iPad15,5"] ||
|
||||
[platform isEqualToString:@"iPad15,6"])
|
||||
return @"iPad Air 13 inch (7th gen)";
|
||||
|
||||
if ([platform isEqualToString:@"iPad15,7"] ||
|
||||
[platform isEqualToString:@"iPad15,8"])
|
||||
return @"iPad (11th gen)";
|
||||
|
||||
if ([platform isEqualToString:@"iPad16,1"] ||
|
||||
[platform isEqualToString:@"iPad16,2"])
|
||||
return @"iPad mini (7th gen)";
|
||||
|
||||
if ([platform isEqualToString:@"iPad16,3"] ||
|
||||
[platform isEqualToString:@"iPad16,4"])
|
||||
return @"iPad Pro 11 inch (5th gen)";
|
||||
|
|
|
|||
|
|
@ -1664,6 +1664,12 @@ public func selectivePrivacySettingsController(
|
|||
} else {
|
||||
updatedDisallowedGifts.remove(.premium)
|
||||
}
|
||||
case .channel:
|
||||
if value {
|
||||
updatedDisallowedGifts.insert(.channel)
|
||||
} else {
|
||||
updatedDisallowedGifts.remove(.channel)
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3822,32 +3822,34 @@ final class CachedStartGiftUpgradeAttributes: Codable {
|
|||
|
||||
func _internal_getStarGiftUpgradeAttributes(account: Account, giftId: Int64) -> Signal<[StarGift.UniqueGift.Attribute]?, NoError> {
|
||||
return account.postbox.transaction { transaction in
|
||||
if let cachedGifts = transaction.retrieveItemCacheEntry(id: giftUpgradesId(giftId: giftId))?.get(CachedStartGiftUpgradeAttributes.self) {
|
||||
return .single(cachedGifts.attributes)
|
||||
} else {
|
||||
return account.network.request(Api.functions.payments.getStarGiftUpgradeAttributes(giftId: giftId))
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<Api.payments.StarGiftUpgradeAttributes?, NoError> in
|
||||
let remote = account.network.request(Api.functions.payments.getStarGiftUpgradeAttributes(giftId: giftId))
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<Api.payments.StarGiftUpgradeAttributes?, NoError> in
|
||||
return .single(nil)
|
||||
}
|
||||
|> mapToSignal { result -> Signal<[StarGift.UniqueGift.Attribute]?, NoError> in
|
||||
guard let result else {
|
||||
return .single(nil)
|
||||
}
|
||||
|> mapToSignal { result -> Signal<[StarGift.UniqueGift.Attribute]?, NoError> in
|
||||
guard let result else {
|
||||
return .single(nil)
|
||||
}
|
||||
switch result {
|
||||
case let .starGiftUpgradeAttributes(apiAttributes):
|
||||
let attributes = apiAttributes.compactMap { StarGift.UniqueGift.Attribute(apiAttribute: $0) }
|
||||
return account.postbox.transaction { transaction in
|
||||
if !attributes.isEmpty {
|
||||
if let entry = CodableEntry(CachedStartGiftUpgradeAttributes(attributes: attributes)) {
|
||||
transaction.putItemCacheEntry(id: giftUpgradesId(giftId: giftId), entry: entry)
|
||||
}
|
||||
switch result {
|
||||
case let .starGiftUpgradeAttributes(apiAttributes):
|
||||
let attributes = apiAttributes.compactMap { StarGift.UniqueGift.Attribute(apiAttribute: $0) }
|
||||
return account.postbox.transaction { transaction in
|
||||
if !attributes.isEmpty {
|
||||
if let entry = CodableEntry(CachedStartGiftUpgradeAttributes(attributes: attributes)) {
|
||||
transaction.putItemCacheEntry(id: giftUpgradesId(giftId: giftId), entry: entry)
|
||||
}
|
||||
return attributes
|
||||
}
|
||||
return attributes
|
||||
}
|
||||
}
|
||||
}
|
||||
if let cachedGifts = transaction.retrieveItemCacheEntry(id: giftUpgradesId(giftId: giftId))?.get(CachedStartGiftUpgradeAttributes.self) {
|
||||
return .single(cachedGifts.attributes)
|
||||
|> then(remote)
|
||||
} else {
|
||||
return remote
|
||||
}
|
||||
}
|
||||
|> switchToLatest
|
||||
}
|
||||
|
|
|
|||
|
|
@ -580,7 +580,7 @@ public class GiftAuctionsManager {
|
|||
}
|
||||
|
||||
public extension GiftAuctionContext.State {
|
||||
func getPlace(myBid: Int64?, myBidDate: Int32?) -> Int32? {
|
||||
func getPlace(myBid: Int64?, myBidDate: Int32?) -> (place: Int32, isApproximate: Bool)? {
|
||||
guard case let .ongoing(_, _, _, _, bidLevels, _, _, _, _, _, _, _) = self.auctionState else {
|
||||
return nil
|
||||
}
|
||||
|
|
@ -592,7 +592,7 @@ public extension GiftAuctionContext.State {
|
|||
|
||||
let levels = bidLevels
|
||||
guard !levels.isEmpty else {
|
||||
return 1
|
||||
return (1, false)
|
||||
}
|
||||
|
||||
func isWorse(than level: GiftAuctionContext.State.BidLevel) -> Bool {
|
||||
|
|
@ -614,7 +614,7 @@ public extension GiftAuctionContext.State {
|
|||
}
|
||||
}
|
||||
if lowerIndex == -1 {
|
||||
return 1
|
||||
return (1, false)
|
||||
}
|
||||
|
||||
let lowerPosition = levels[lowerIndex].position
|
||||
|
|
@ -626,14 +626,14 @@ public extension GiftAuctionContext.State {
|
|||
nextPosition = lowerPosition
|
||||
}
|
||||
if nextPosition == lowerPosition + 1 {
|
||||
return lowerPosition + 1
|
||||
return (lowerPosition + 1, false)
|
||||
} else {
|
||||
return nextPosition
|
||||
return (lowerPosition, true)
|
||||
}
|
||||
}
|
||||
|
||||
var place: Int32? {
|
||||
return self.getPlace(myBid: nil, myBidDate: nil)
|
||||
return self.getPlace(myBid: nil, myBidDate: nil)?.place
|
||||
}
|
||||
|
||||
var startDate: Int32 {
|
||||
|
|
|
|||
|
|
@ -348,8 +348,8 @@ public func makeDefaultDarkPresentationTheme(extendingThemeReference: Presentati
|
|||
badgeBackgroundColor: UIColor(rgb: 0xffffff),
|
||||
badgeStrokeColor: UIColor(rgb: 0x1c1c1d),
|
||||
badgeTextColor: UIColor(rgb: 0x000000),
|
||||
segmentedBackgroundColor: UIColor(rgb: 0x3a3b3d),
|
||||
segmentedForegroundColor: UIColor(rgb: 0x6f7075),
|
||||
segmentedBackgroundColor: UIColor(rgb: 0xffffff, alpha: 0.11),
|
||||
segmentedForegroundColor: UIColor(rgb: 0xffffff, alpha: 0.36),
|
||||
segmentedTextColor: UIColor(rgb: 0xffffff),
|
||||
segmentedDividerColor: UIColor(rgb: 0x505155),
|
||||
clearButtonBackgroundColor: UIColor(rgb: 0xffffff, alpha: 0.1),
|
||||
|
|
|
|||
|
|
@ -139,7 +139,7 @@ public func customizeDefaultDarkTintedPresentationTheme(theme: PresentationTheme
|
|||
opaqueBackgroundColor: mainBackgroundColor,
|
||||
separatorColor: mainSeparatorColor,
|
||||
segmentedBackgroundColor: mainInputColor,
|
||||
segmentedForegroundColor: mainBackgroundColor,
|
||||
segmentedForegroundColor: mainSecondaryTextColor?.withAlphaComponent(0.4),
|
||||
segmentedDividerColor: mainSecondaryTextColor?.withAlphaComponent(0.5)
|
||||
),
|
||||
navigationSearchBar: rootController.navigationSearchBar.withUpdated(
|
||||
|
|
@ -571,7 +571,7 @@ public func makeDefaultDarkTintedPresentationTheme(extendingThemeReference: Pres
|
|||
badgeStrokeColor: UIColor(rgb: 0xef5b5b),
|
||||
badgeTextColor: UIColor(rgb: 0xffffff),
|
||||
segmentedBackgroundColor: mainInputColor,
|
||||
segmentedForegroundColor: mainBackgroundColor,
|
||||
segmentedForegroundColor: mainSecondaryTextColor.withAlphaComponent(0.4),
|
||||
segmentedTextColor: UIColor(rgb: 0xffffff),
|
||||
segmentedDividerColor: mainSecondaryTextColor.withAlphaComponent(0.5),
|
||||
clearButtonBackgroundColor: UIColor(rgb: 0xffffff, alpha: 0.1),
|
||||
|
|
|
|||
|
|
@ -293,7 +293,7 @@ private final class DemoSheetContent: CombinedComponent {
|
|||
let bottomEdgeEffectHeight = 108.0
|
||||
let bottomEdgeEffect = bottomEdgeEffect.update(
|
||||
component: EdgeEffectComponent(
|
||||
color: .clear,
|
||||
color: environment.theme.actionSheet.opaqueItemBackgroundColor,
|
||||
blur: true,
|
||||
alpha: 1.0,
|
||||
size: CGSize(width: context.availableSize.width, height: bottomEdgeEffectHeight),
|
||||
|
|
|
|||
|
|
@ -1141,6 +1141,8 @@ public final class GiftItemComponent: Component {
|
|||
} else {
|
||||
if [.buttonIcon, .tableIcon].contains(component.mode) {
|
||||
|
||||
} else if case .upgradePreview = component.mode {
|
||||
self.backgroundLayer.backgroundColor = component.theme.list.itemModalBlocksBackgroundColor.cgColor
|
||||
} else {
|
||||
self.backgroundLayer.backgroundColor = component.theme.list.itemBlocksBackgroundColor.cgColor
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1084,6 +1084,9 @@ final class GiftOptionsScreenComponent: Component {
|
|||
guard let self, let component = self.component, let controller = controller(), let navigationController = controller.navigationController as? NavigationController else {
|
||||
return
|
||||
}
|
||||
guard component.peerId != component.context.account.peerId else {
|
||||
return
|
||||
}
|
||||
let _ = (component.context.engine.data.get(
|
||||
TelegramEngine.EngineData.Item.Peer.Peer(id: component.peerId)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ import AnimatedTextComponent
|
|||
import GlassBarButtonComponent
|
||||
import MessageInputPanelComponent
|
||||
import GiftRemainingCountComponent
|
||||
import GlassBackgroundComponent
|
||||
|
||||
private final class GiftSetupScreenComponent: Component {
|
||||
typealias EnvironmentType = ViewControllerComponentContainer.Environment
|
||||
|
|
@ -113,6 +114,7 @@ private final class GiftSetupScreenComponent: Component {
|
|||
private let upgradeSection = ComponentView<Empty>()
|
||||
private let hideSection = ComponentView<Empty>()
|
||||
|
||||
private let glassContainerView = GlassBackgroundContainerView()
|
||||
private let inputPanel = ComponentView<Empty>()
|
||||
private let inputPanelExternalState = MessageInputPanelComponent.ExternalState()
|
||||
|
||||
|
|
@ -1365,11 +1367,16 @@ private final class GiftSetupScreenComponent: Component {
|
|||
transition.setFrame(view: introContentView, frame: CGRect(origin: CGPoint(x: rawSideInset, y: 0.0), size: introContentSize))
|
||||
}
|
||||
|
||||
let inputPanelFrame = CGRect(origin: CGPoint(x: rawSideInset + inputPanelInset, y: contentHeight + introContentSize.height - inputPanelInset - inputPanelSize.height + 6.0), size: inputPanelSize)
|
||||
let glassContainerFrame = CGRect(origin: CGPoint(x: rawSideInset + inputPanelInset, y: contentHeight + introContentSize.height - inputPanelInset - inputPanelSize.height + 6.0 - 20.0), size: CGSize(width: inputPanelSize.width, height: inputPanelSize.height + 40.0))
|
||||
self.glassContainerView.update(size: glassContainerFrame.size, isDark: theme.overallDarkAppearance, transition: transition)
|
||||
|
||||
let inputPanelFrame = CGRect(origin: CGPoint(x: 0.0, y: 20.0), size: inputPanelSize)
|
||||
if let inputPanelView = self.inputPanel.view {
|
||||
if inputPanelView.superview == nil {
|
||||
self.scrollContentView.addSubview(inputPanelView)
|
||||
self.scrollContentView.addSubview(self.glassContainerView)
|
||||
self.glassContainerView.contentView.addSubview(inputPanelView)
|
||||
}
|
||||
transition.setFrame(view: self.glassContainerView, frame: glassContainerFrame)
|
||||
transition.setFrame(view: inputPanelView, frame: inputPanelFrame)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -369,17 +369,20 @@ private final class PeerPlaceComponent: Component {
|
|||
let theme: PresentationTheme
|
||||
let color: UIColor
|
||||
let place: Int32?
|
||||
let placeIsApproximate: Bool
|
||||
let groupingSeparator: String
|
||||
|
||||
init(
|
||||
theme: PresentationTheme,
|
||||
color: UIColor,
|
||||
place: Int32?,
|
||||
placeIsApproximate: Bool,
|
||||
groupingSeparator: String
|
||||
) {
|
||||
self.theme = theme
|
||||
self.color = color
|
||||
self.place = place
|
||||
self.placeIsApproximate = placeIsApproximate
|
||||
self.groupingSeparator = groupingSeparator
|
||||
}
|
||||
|
||||
|
|
@ -393,6 +396,9 @@ private final class PeerPlaceComponent: Component {
|
|||
if lhs.place != rhs.place {
|
||||
return false
|
||||
}
|
||||
if lhs.placeIsApproximate != rhs.placeIsApproximate {
|
||||
return false
|
||||
}
|
||||
if lhs.groupingSeparator != rhs.groupingSeparator {
|
||||
return false
|
||||
}
|
||||
|
|
@ -455,7 +461,7 @@ private final class PeerPlaceComponent: Component {
|
|||
var placeString: String
|
||||
if let place = component.place {
|
||||
placeString = presentationStringsFormattedNumber(place, component.groupingSeparator)
|
||||
if place >= 100 {
|
||||
if component.placeIsApproximate {
|
||||
placeString = "\(compactNumericCountString(Int(place), decimalSeparator: ".", showDecimalPart: false))+"
|
||||
}
|
||||
} else {
|
||||
|
|
@ -501,6 +507,7 @@ private final class PeerComponent: Component {
|
|||
let groupingSeparator: String
|
||||
let peer: EnginePeer
|
||||
let place: Int32
|
||||
let placeIsApproximate: Bool
|
||||
let amount: Int64
|
||||
let status: Status?
|
||||
let isLast: Bool
|
||||
|
|
@ -512,6 +519,7 @@ private final class PeerComponent: Component {
|
|||
groupingSeparator: String,
|
||||
peer: EnginePeer,
|
||||
place: Int32,
|
||||
placeIsApproximate: Bool,
|
||||
amount: Int64,
|
||||
status: Status? = nil,
|
||||
isLast: Bool,
|
||||
|
|
@ -522,6 +530,7 @@ private final class PeerComponent: Component {
|
|||
self.groupingSeparator = groupingSeparator
|
||||
self.peer = peer
|
||||
self.place = place
|
||||
self.placeIsApproximate = placeIsApproximate
|
||||
self.amount = amount
|
||||
self.status = status
|
||||
self.isLast = isLast
|
||||
|
|
@ -541,6 +550,9 @@ private final class PeerComponent: Component {
|
|||
if lhs.place != rhs.place {
|
||||
return false
|
||||
}
|
||||
if lhs.placeIsApproximate != rhs.placeIsApproximate {
|
||||
return false
|
||||
}
|
||||
if lhs.amount != rhs.amount {
|
||||
return false
|
||||
}
|
||||
|
|
@ -623,8 +635,17 @@ private final class PeerComponent: Component {
|
|||
let presentationData = component.context.sharedContext.currentPresentationData.with { $0 }
|
||||
let placeSize = self.place.update(
|
||||
transition: .immediate,
|
||||
component: AnyComponent(PeerPlaceComponent(theme: component.theme, color: color, place: component.status == .returned ? nil : component.place, groupingSeparator: presentationData.dateTimeFormat.groupingSeparator)),
|
||||
environment: {},
|
||||
component: AnyComponent(
|
||||
PeerPlaceComponent(
|
||||
theme: component.theme,
|
||||
color: color,
|
||||
place: component.status == .returned ? nil : component.place,
|
||||
placeIsApproximate: component.placeIsApproximate,
|
||||
groupingSeparator: presentationData.dateTimeFormat.groupingSeparator
|
||||
)
|
||||
),
|
||||
environment: {
|
||||
},
|
||||
containerSize: CGSize(width: 40.0, height: 40.0)
|
||||
)
|
||||
let placeFrame = CGRect(origin: CGPoint(x: 0.0, y: floorToScreenPixels((size.height - placeSize.height) / 2.0)), size: placeSize)
|
||||
|
|
@ -2213,8 +2234,9 @@ private final class GiftAuctionBidScreenComponent: Component {
|
|||
isBiddingUp = false
|
||||
}
|
||||
|
||||
place = giftAuctionState.getPlace(myBid: myBidAmount, myBidDate: myBidDate) ?? 1
|
||||
|
||||
let placeAndIsApproximate = giftAuctionState.getPlace(myBid: myBidAmount, myBidDate: myBidDate) ?? (1, false)
|
||||
place = placeAndIsApproximate.place
|
||||
|
||||
var bidTitle: String
|
||||
var bidTitleColor: UIColor
|
||||
var bidStatus: PeerComponent.Status?
|
||||
|
|
@ -2247,7 +2269,18 @@ private final class GiftAuctionBidScreenComponent: Component {
|
|||
|
||||
if let peer = self.peersMap[component.context.account.peerId] {
|
||||
myBidTitleComponent = AnyComponent(PeerHeaderComponent(color: bidTitleColor, dateTimeFormat: environment.dateTimeFormat, title: bidTitle, giftTitle: giftTitle, giftNumber: giftNumber))
|
||||
myBidComponent = AnyComponent(PeerComponent(context: component.context, theme: environment.theme, groupingSeparator: environment.dateTimeFormat.groupingSeparator, peer: peer, place: place, amount: myBidAmount, status: bidStatus, isLast: true, action: nil))
|
||||
myBidComponent = AnyComponent(PeerComponent(
|
||||
context: component.context,
|
||||
theme: environment.theme,
|
||||
groupingSeparator: environment.dateTimeFormat.groupingSeparator,
|
||||
peer: peer,
|
||||
place: place,
|
||||
placeIsApproximate: placeAndIsApproximate.isApproximate,
|
||||
amount: myBidAmount,
|
||||
status: bidStatus,
|
||||
isLast: true,
|
||||
action: nil
|
||||
))
|
||||
}
|
||||
|
||||
var i: Int32 = 1
|
||||
|
|
@ -2259,7 +2292,17 @@ private final class GiftAuctionBidScreenComponent: Component {
|
|||
break
|
||||
}
|
||||
}
|
||||
topBidsComponents.append((peer.id, AnyComponent(PeerComponent(context: component.context, theme: environment.theme, groupingSeparator: environment.dateTimeFormat.groupingSeparator, peer: peer, place: i, amount: bid, isLast: i == topBidders.count, action: nil))))
|
||||
topBidsComponents.append((peer.id, AnyComponent(PeerComponent(
|
||||
context: component.context,
|
||||
theme: environment.theme,
|
||||
groupingSeparator: environment.dateTimeFormat.groupingSeparator,
|
||||
peer: peer,
|
||||
place: i,
|
||||
placeIsApproximate: false,
|
||||
amount: bid,
|
||||
isLast: i == topBidders.count,
|
||||
action: nil
|
||||
))))
|
||||
i += 1
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -129,41 +129,43 @@ private final class GiftAuctionViewSheetContent: CombinedComponent {
|
|||
}
|
||||
self.giftUpgradeAttributes = attributes
|
||||
|
||||
let randomModels = Array(attributes.filter({ attribute in
|
||||
if case .model = attribute {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
if self.previewModels.isEmpty {
|
||||
let randomModels = Array(attributes.filter({ attribute in
|
||||
if case .model = attribute {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}).shuffled().prefix(5))
|
||||
self.previewModels = randomModels
|
||||
|
||||
let randomBackdrops = Array(attributes.filter({ attribute in
|
||||
if case .backdrop = attribute {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}).shuffled())
|
||||
self.previewBackdrops = randomBackdrops
|
||||
|
||||
let randomSymbols = Array(attributes.filter({ attribute in
|
||||
if case .pattern = attribute {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}).shuffled().prefix(5))
|
||||
self.previewSymbols = randomSymbols
|
||||
|
||||
for case let .model(_, file, _) in self.previewModels where !self.fetchedFiles.contains(file.fileId.id) {
|
||||
self.disposables.add(freeMediaFileResourceInteractiveFetched(account: context.account, userLocation: .other, fileReference: .standalone(media: file), resource: file.resource).start())
|
||||
self.fetchedFiles.insert(file.fileId.id)
|
||||
}
|
||||
}).shuffled().prefix(5))
|
||||
self.previewModels = randomModels
|
||||
|
||||
let randomBackdrops = Array(attributes.filter({ attribute in
|
||||
if case .backdrop = attribute {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
|
||||
for case let .pattern(_, file, _) in self.previewSymbols where !self.fetchedFiles.contains(file.fileId.id) {
|
||||
self.disposables.add(freeMediaFileResourceInteractiveFetched(account: context.account, userLocation: .other, fileReference: .standalone(media: file), resource: file.resource).start())
|
||||
self.fetchedFiles.insert(file.fileId.id)
|
||||
}
|
||||
}).shuffled())
|
||||
self.previewBackdrops = randomBackdrops
|
||||
|
||||
let randomSymbols = Array(attributes.filter({ attribute in
|
||||
if case .pattern = attribute {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}).shuffled().prefix(5))
|
||||
self.previewSymbols = randomSymbols
|
||||
|
||||
for case let .model(_, file, _) in self.previewModels where !self.fetchedFiles.contains(file.fileId.id) {
|
||||
self.disposables.add(freeMediaFileResourceInteractiveFetched(account: context.account, userLocation: .other, fileReference: .standalone(media: file), resource: file.resource).start())
|
||||
self.fetchedFiles.insert(file.fileId.id)
|
||||
}
|
||||
|
||||
for case let .pattern(_, file, _) in self.previewSymbols where !self.fetchedFiles.contains(file.fileId.id) {
|
||||
self.disposables.add(freeMediaFileResourceInteractiveFetched(account: context.account, userLocation: .other, fileReference: .standalone(media: file), resource: file.resource).start())
|
||||
self.fetchedFiles.insert(file.fileId.id)
|
||||
}
|
||||
|
||||
self.updated()
|
||||
|
|
@ -736,12 +738,9 @@ private final class GiftAuctionViewSheetContent: CombinedComponent {
|
|||
} else {
|
||||
return false
|
||||
}
|
||||
}), case let .backdrop(_, _, innerColor, outerColor, _, _, _) = backdropAttribute {
|
||||
let topColor = UIColor(rgb: UInt32(bitPattern: innerColor)).withMultiplied(hue: 1.01, saturation: 1.22, brightness: 1.04)
|
||||
let bottomColor = UIColor(rgb: UInt32(bitPattern: outerColor)).withMultiplied(hue: 0.97, saturation: 1.45, brightness: 0.89)
|
||||
buttonColor = topColor.mixedWith(bottomColor, alpha: 0.8).withMultipliedBrightnessBy(1.25)
|
||||
|
||||
secondaryTextColor = topColor.withMultiplied(hue: 1.0, saturation: 1.02, brightness: 1.25).mixedWith(UIColor.white, alpha: 0.5)
|
||||
}), case let .backdrop(_, _, innerColor, _, _, _, _) = backdropAttribute {
|
||||
buttonColor = UIColor(rgb: UInt32(bitPattern: innerColor)).withMultipliedBrightnessBy(1.05)
|
||||
secondaryTextColor = UIColor(rgb: UInt32(bitPattern: innerColor)).withMultiplied(hue: 1.0, saturation: 1.02, brightness: 1.25).mixedWith(UIColor.white, alpha: 0.3)
|
||||
}
|
||||
|
||||
let headerHeight: CGFloat = 264.0
|
||||
|
|
|
|||
|
|
@ -199,7 +199,7 @@ private final class GiftAuctionWearPreviewSheetContent: CombinedComponent {
|
|||
return { context in
|
||||
let environment = context.environment[ViewControllerComponentContainer.Environment.self].value
|
||||
let component = context.component
|
||||
let theme = environment.theme
|
||||
let theme = environment.theme.withModalBlocksBackground()
|
||||
let strings = environment.strings
|
||||
let nameDisplayOrder = component.context.sharedContext.currentPresentationData.with { $0 }.nameDisplayOrder
|
||||
let controller = environment.controller
|
||||
|
|
@ -293,19 +293,16 @@ private final class GiftAuctionWearPreviewSheetContent: CombinedComponent {
|
|||
} else {
|
||||
return false
|
||||
}
|
||||
}), case let .backdrop(_, _, innerColor, outerColor, _, _, _) = backdropAttribute {
|
||||
let topColor = UIColor(rgb: UInt32(bitPattern: innerColor)).withMultiplied(hue: 1.01, saturation: 1.22, brightness: 1.04)
|
||||
let bottomColor = UIColor(rgb: UInt32(bitPattern: outerColor)).withMultiplied(hue: 0.97, saturation: 1.45, brightness: 0.89)
|
||||
buttonColor = topColor.mixedWith(bottomColor, alpha: 0.8)
|
||||
|
||||
secondaryTextColor = topColor.withMultiplied(hue: 1.0, saturation: 1.02, brightness: 1.25).mixedWith(UIColor.white, alpha: 0.5)
|
||||
}), case let .backdrop(_, _, innerColor, _, _, _, _) = backdropAttribute {
|
||||
buttonColor = UIColor(rgb: UInt32(bitPattern: innerColor)).withMultipliedBrightnessBy(1.05)
|
||||
secondaryTextColor = UIColor(rgb: UInt32(bitPattern: innerColor)).withMultiplied(hue: 1.0, saturation: 1.02, brightness: 1.25).mixedWith(UIColor.white, alpha: 0.3)
|
||||
}
|
||||
|
||||
let closeButton = closeButton.update(
|
||||
component: GlassBarButtonComponent(
|
||||
size: CGSize(width: 40.0, height: 40.0),
|
||||
backgroundColor: buttonColor.withMultipliedBrightnessBy(1.2),
|
||||
isDark: theme.overallDarkAppearance,
|
||||
backgroundColor: buttonColor,
|
||||
isDark: false,
|
||||
state: .tintedGlass,
|
||||
component: AnyComponentWithIdentity(id: "close", component: AnyComponent(
|
||||
BundleIconComponent(
|
||||
|
|
|
|||
|
|
@ -78,7 +78,8 @@ private final class GiftUpgradePreviewScreenComponent: Component {
|
|||
private let containerView: UIView
|
||||
private let backgroundLayer: SimpleLayer
|
||||
private let navigationBarContainer: SparseContainerView
|
||||
private let glassContainerView: GlassBackgroundContainerView
|
||||
private let closeGlassContainerView: GlassBackgroundContainerView
|
||||
private let playbackGlassContainerView: GlassBackgroundContainerView
|
||||
private let scrollView: ScrollView
|
||||
private let scrollContentClippingView: SparseContainerView
|
||||
private let scrollContentView: UIView
|
||||
|
|
@ -151,7 +152,8 @@ private final class GiftUpgradePreviewScreenComponent: Component {
|
|||
self.topEdgeEffectView = EdgeEffectView()
|
||||
self.topEdgeEffectView.alpha = 0.0
|
||||
|
||||
self.glassContainerView = GlassBackgroundContainerView()
|
||||
self.closeGlassContainerView = GlassBackgroundContainerView()
|
||||
self.playbackGlassContainerView = GlassBackgroundContainerView()
|
||||
|
||||
self.scrollView = ScrollView()
|
||||
|
||||
|
|
@ -372,10 +374,18 @@ private final class GiftUpgradePreviewScreenComponent: Component {
|
|||
|
||||
let visibleBounds = self.scrollView.bounds.insetBy(dx: 0.0, dy: -10.0)
|
||||
|
||||
let sideInset: CGFloat = 16.0 + environment.safeInsets.left
|
||||
let fillingSize: CGFloat
|
||||
if case .regular = environment.metrics.widthClass {
|
||||
fillingSize = min(itemLayout.containerSize.width, 414.0) - environment.safeInsets.left * 2.0
|
||||
} else {
|
||||
fillingSize = min(itemLayout.containerSize.width, environment.deviceMetrics.screenSize.width) - environment.safeInsets.left * 2.0
|
||||
}
|
||||
|
||||
let rawSideInset: CGFloat = floor((itemLayout.containerSize.width - fillingSize) * 0.5)
|
||||
let sideInset: CGFloat = rawSideInset + 16.0
|
||||
|
||||
let optionSpacing: CGFloat = 10.0
|
||||
let optionWidth = (itemLayout.containerSize.width - sideInset * 2.0 - optionSpacing * 2.0) / 3.0
|
||||
let optionWidth = (fillingSize - 16.0 * 2.0 - optionSpacing * 2.0) / 3.0
|
||||
let optionSize = CGSize(width: optionWidth, height: 126.0)
|
||||
|
||||
let topInset: CGFloat = 393.0
|
||||
|
|
@ -409,8 +419,8 @@ private final class GiftUpgradePreviewScreenComponent: Component {
|
|||
var isSelected = false
|
||||
for attribute in attributeList {
|
||||
switch attribute {
|
||||
case let .model(name, _, rarityValue):
|
||||
itemId += name
|
||||
case let .model(name, file, rarityValue):
|
||||
itemId += "\(file.fileId.id)"
|
||||
if self.selectedSection == .models {
|
||||
title = name
|
||||
rarity = rarityValue
|
||||
|
|
@ -418,8 +428,8 @@ private final class GiftUpgradePreviewScreenComponent: Component {
|
|||
|
||||
isSelected = self.selectedModel == attribute
|
||||
}
|
||||
case let .backdrop(name, _, _, _, _, _, rarityValue):
|
||||
itemId += name
|
||||
case let .backdrop(name, id, _, _, _, _, rarityValue):
|
||||
itemId += "\(id)"
|
||||
if self.selectedSection == .backdrops {
|
||||
title = name
|
||||
rarity = rarityValue
|
||||
|
|
@ -427,8 +437,8 @@ private final class GiftUpgradePreviewScreenComponent: Component {
|
|||
|
||||
isSelected = self.selectedBackdrop == attribute
|
||||
}
|
||||
case let .pattern(name, _, rarityValue):
|
||||
itemId += name
|
||||
case let .pattern(name, file, rarityValue):
|
||||
itemId += "\(file.fileId.id)"
|
||||
if self.selectedSection == .symbols {
|
||||
title = name
|
||||
rarity = rarityValue
|
||||
|
|
@ -520,7 +530,7 @@ private final class GiftUpgradePreviewScreenComponent: Component {
|
|||
}
|
||||
}
|
||||
itemFrame.origin.x += itemFrame.width + optionSpacing
|
||||
if itemFrame.maxX > itemLayout.containerSize.width {
|
||||
if itemFrame.maxX > rawSideInset + fillingSize {
|
||||
itemFrame.origin.x = sideInset
|
||||
itemFrame.origin.y += optionSize.height + optionSpacing
|
||||
}
|
||||
|
|
@ -634,6 +644,7 @@ private final class GiftUpgradePreviewScreenComponent: Component {
|
|||
|
||||
var buttonColor: UIColor = .white.withAlphaComponent(0.1)
|
||||
var secondaryTextColor: UIColor = .white.withAlphaComponent(0.4)
|
||||
var badgeColor: UIColor = .white.withAlphaComponent(0.4)
|
||||
|
||||
var attributes: [StarGift.UniqueGift.Attribute] = []
|
||||
if !self.previewModels.isEmpty {
|
||||
|
|
@ -670,11 +681,16 @@ private final class GiftUpgradePreviewScreenComponent: Component {
|
|||
return false
|
||||
}
|
||||
}), case let .backdrop(_, _, innerColor, outerColor, _, _, _) = backdropAttribute {
|
||||
let topColor = UIColor(rgb: UInt32(bitPattern: innerColor)).withMultiplied(hue: 1.01, saturation: 1.22, brightness: 1.04)
|
||||
let bottomColor = UIColor(rgb: UInt32(bitPattern: outerColor)).withMultiplied(hue: 0.97, saturation: 1.45, brightness: 0.89)
|
||||
buttonColor = topColor.mixedWith(bottomColor, alpha: 0.8).withMultipliedBrightnessBy(1.25)
|
||||
buttonColor = UIColor(rgb: UInt32(bitPattern: innerColor)).withMultipliedBrightnessBy(1.05)
|
||||
|
||||
secondaryTextColor = topColor.withMultiplied(hue: 1.0, saturation: 1.02, brightness: 1.25).mixedWith(UIColor.white, alpha: 0.3)
|
||||
badgeColor = UIColor(rgb: UInt32(bitPattern: innerColor)).withMultipliedBrightnessBy(1.05)
|
||||
let outer = UIColor(rgb: UInt32(bitPattern: outerColor))
|
||||
if outer.lightness < 0.06 {
|
||||
badgeColor = UIColor(rgb: UInt32(bitPattern: innerColor)).withMultipliedBrightnessBy(1.45)
|
||||
} else if outer.lightness < 0.295 {
|
||||
badgeColor = UIColor(rgb: UInt32(bitPattern: innerColor)).withMultipliedBrightnessBy(1.19)
|
||||
}
|
||||
secondaryTextColor = UIColor(rgb: UInt32(bitPattern: innerColor)).withMultiplied(hue: 1.0, saturation: 1.02, brightness: 1.25).mixedWith(UIColor.white, alpha: 0.3)
|
||||
}
|
||||
|
||||
var contentHeight: CGFloat = 0.0
|
||||
|
|
@ -695,9 +711,9 @@ private final class GiftUpgradePreviewScreenComponent: Component {
|
|||
}
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: availableSize.width, height: 300.0),
|
||||
containerSize: CGSize(width: fillingSize, height: 300.0),
|
||||
)
|
||||
let headerFrame = CGRect(origin: CGPoint(x: floor((fillingSize - headerSize.width) * 0.5), y: 0.0), size: headerSize)
|
||||
let headerFrame = CGRect(origin: CGPoint(x: floor((availableSize.width - headerSize.width) * 0.5), y: 0.0), size: headerSize)
|
||||
if let headerView = self.header.view {
|
||||
if headerView.superview == nil {
|
||||
headerView.isUserInteractionEnabled = false
|
||||
|
|
@ -724,7 +740,7 @@ private final class GiftUpgradePreviewScreenComponent: Component {
|
|||
environment: {},
|
||||
containerSize: CGSize(width: availableSize.width - sideInset * 2.0, height: 100.0)
|
||||
)
|
||||
let titleFrame = CGRect(origin: CGPoint(x: floor((fillingSize - titleSize.width) * 0.5), y: contentHeight - 124.0), size: titleSize)
|
||||
let titleFrame = CGRect(origin: CGPoint(x: floor((availableSize.width - titleSize.width) * 0.5), y: contentHeight - 124.0), size: titleSize)
|
||||
if let titleView = self.title.view {
|
||||
if titleView.superview == nil {
|
||||
self.navigationBarContainer.addSubview(titleView)
|
||||
|
|
@ -732,22 +748,30 @@ private final class GiftUpgradePreviewScreenComponent: Component {
|
|||
transition.setFrame(view: titleView, frame: titleFrame)
|
||||
}
|
||||
|
||||
var subtitleItems: [AnimatedTextComponent.Item] = []
|
||||
let subtitleString = self.isPlaying ? environment.strings.Gift_Variants_RandomTraits : environment.strings.Gift_Variants_SelectedTraits
|
||||
let words = subtitleString.components(separatedBy: " ")
|
||||
for i in 0 ..< words.count {
|
||||
var text = words[i]
|
||||
if i > 0 {
|
||||
text = " \(text)"
|
||||
}
|
||||
subtitleItems.append(AnimatedTextComponent.Item(id: text.lowercased(), content: .text(text)))
|
||||
}
|
||||
|
||||
let subtitleSize = self.subtitle.update(
|
||||
transition: .spring(duration: 0.2),
|
||||
component: AnyComponent(AnimatedTextComponent(
|
||||
font: Font.regular(14.0),
|
||||
color: secondaryTextColor,
|
||||
items: [
|
||||
AnimatedTextComponent.Item(id: self.isPlaying ? "random" : "selected", content: .text(self.isPlaying ? "Random" : "Selected")),
|
||||
AnimatedTextComponent.Item(id: "traits", content: .text(" Traits"))
|
||||
],
|
||||
items: subtitleItems,
|
||||
noDelay: true,
|
||||
blur: true
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: availableSize.width - sideInset * 2.0, height: 100.0)
|
||||
)
|
||||
let subtitleFrame = CGRect(origin: CGPoint(x: floor((fillingSize - subtitleSize.width) * 0.5), y: contentHeight - 97.0), size: subtitleSize)
|
||||
let subtitleFrame = CGRect(origin: CGPoint(x: floor((availableSize.width - subtitleSize.width) * 0.5), y: contentHeight - 97.0), size: subtitleSize)
|
||||
if let subtitleView = self.subtitle.view {
|
||||
if subtitleView.superview == nil {
|
||||
self.navigationBarContainer.addSubview(subtitleView)
|
||||
|
|
@ -755,9 +779,8 @@ private final class GiftUpgradePreviewScreenComponent: Component {
|
|||
transition.setFrame(view: subtitleView, frame: subtitleFrame)
|
||||
}
|
||||
|
||||
|
||||
let attributeSpacing: CGFloat = 10.0
|
||||
let attributeWidth: CGFloat = floor((fillingSize - sideInset * 2.0 - attributeSpacing * CGFloat(attributes.count - 1)) / CGFloat(attributes.count))
|
||||
let attributeWidth: CGFloat = floor((fillingSize - attributeSpacing * CGFloat(attributes.count - 1)) / CGFloat(attributes.count))
|
||||
let attributeHeight: CGFloat = 45.0
|
||||
|
||||
for i in 0 ..< attributes.count {
|
||||
|
|
@ -777,8 +800,9 @@ private final class GiftUpgradePreviewScreenComponent: Component {
|
|||
transition: transition,
|
||||
component: AnyComponent(AttributeInfoComponent(
|
||||
strings: environment.strings,
|
||||
backgroundColor: buttonColor,
|
||||
secondaryTextColor: secondaryTextColor,
|
||||
backgroundColor: UIColor.white.withAlphaComponent(0.16),
|
||||
secondaryTextColor: secondaryTextColor.mixedWith(.white, alpha: 0.3),
|
||||
badgeColor: badgeColor,
|
||||
attribute: attribute
|
||||
)),
|
||||
environment: {},
|
||||
|
|
@ -793,8 +817,8 @@ private final class GiftUpgradePreviewScreenComponent: Component {
|
|||
}
|
||||
|
||||
let edgeEffectHeight: CGFloat = 44.0
|
||||
let edgeEffectFrame = CGRect(origin: CGPoint(x: 0.0, y: contentHeight + 44.0), size: CGSize(width: availableSize.width, height: edgeEffectHeight))
|
||||
let edgeSolidFrame = CGRect(origin: CGPoint(x: 0.0, y: contentHeight), size: CGSize(width: availableSize.width, height: 44.0))
|
||||
let edgeEffectFrame = CGRect(origin: CGPoint(x: rawSideInset, y: contentHeight + 44.0), size: CGSize(width: fillingSize, height: edgeEffectHeight))
|
||||
let edgeSolidFrame = CGRect(origin: CGPoint(x: rawSideInset, y: contentHeight), size: CGSize(width: fillingSize, height: 44.0))
|
||||
transition.setFrame(view: self.topEdgeSolidView, frame: edgeSolidFrame)
|
||||
transition.setFrame(view: self.topEdgeEffectView, frame: edgeEffectFrame)
|
||||
self.topEdgeSolidView.backgroundColor = theme.list.blocksBackgroundColor
|
||||
|
|
@ -825,7 +849,7 @@ private final class GiftUpgradePreviewScreenComponent: Component {
|
|||
environment: {},
|
||||
containerSize: CGSize(width: fillingSize - 8.0 * 2.0, height: 100.0)
|
||||
)
|
||||
let segmentedControlFrame = CGRect(origin: CGPoint(x: floor((fillingSize - segmentedSize.width) * 0.5), y: contentHeight), size: segmentedSize)
|
||||
let segmentedControlFrame = CGRect(origin: CGPoint(x: floor((availableSize.width - segmentedSize.width) * 0.5), y: contentHeight), size: segmentedSize)
|
||||
if let segmentedControlComponentView = self.segmentControl.view {
|
||||
if segmentedControlComponentView.superview == nil {
|
||||
self.navigationBarContainer.addSubview(self.topEdgeSolidView)
|
||||
|
|
@ -869,7 +893,7 @@ private final class GiftUpgradePreviewScreenComponent: Component {
|
|||
environment: {},
|
||||
containerSize: CGSize(width: availableSize.width - sideInset * 2.0, height: 100.0)
|
||||
)
|
||||
let descriptionFrame = CGRect(origin: CGPoint(x: floor((fillingSize - descriptionSize.width) * 0.5), y: contentHeight), size: descriptionSize)
|
||||
let descriptionFrame = CGRect(origin: CGPoint(x: floor((availableSize.width - descriptionSize.width) * 0.5), y: contentHeight), size: descriptionSize)
|
||||
if let descriptionView = self.descriptionText.view {
|
||||
if descriptionView.superview == nil {
|
||||
self.scrollContentView.addSubview(descriptionView)
|
||||
|
|
@ -891,9 +915,12 @@ private final class GiftUpgradePreviewScreenComponent: Component {
|
|||
}
|
||||
transition.setFrame(view: self.backgroundHandleView, frame: backgroundHandleFrame)
|
||||
|
||||
self.glassContainerView.update(size: CGSize(width: fillingSize, height: 64.0), isDark: false, transition: .immediate)
|
||||
self.glassContainerView.frame = CGRect(origin: CGPoint(x: rawSideInset, y: 0.0), size: CGSize(width: fillingSize, height: 64.0))
|
||||
|
||||
self.playbackGlassContainerView.update(size: CGSize(width: fillingSize, height: 64.0), isDark: false, transition: .immediate)
|
||||
self.playbackGlassContainerView.frame = CGRect(origin: CGPoint(x: rawSideInset, y: 0.0), size: CGSize(width: fillingSize, height: 64.0))
|
||||
|
||||
self.closeGlassContainerView.update(size: CGSize(width: 64.0, height: 64.0), isDark: false, transition: .immediate)
|
||||
self.closeGlassContainerView.frame = CGRect(origin: CGPoint(x: rawSideInset, y: 0.0), size: CGSize(width: 64.0, height: 64.0))
|
||||
|
||||
let closeButtonSize = self.closeButton.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(GlassBarButtonComponent(
|
||||
|
|
@ -920,8 +947,9 @@ private final class GiftUpgradePreviewScreenComponent: Component {
|
|||
let closeButtonFrame = CGRect(origin: CGPoint(x: 16.0, y: 16.0), size: closeButtonSize)
|
||||
if let closeButtonView = self.closeButton.view {
|
||||
if closeButtonView.superview == nil {
|
||||
self.navigationBarContainer.addSubview(self.glassContainerView)
|
||||
self.navigationBarContainer.addSubview(closeButtonView)
|
||||
self.navigationBarContainer.addSubview(self.playbackGlassContainerView)
|
||||
self.navigationBarContainer.addSubview(self.closeGlassContainerView)
|
||||
self.closeGlassContainerView.contentView.addSubview(closeButtonView)
|
||||
}
|
||||
transition.setFrame(view: closeButtonView, frame: closeButtonFrame)
|
||||
}
|
||||
|
|
@ -968,7 +996,7 @@ private final class GiftUpgradePreviewScreenComponent: Component {
|
|||
let playbackButtonFrame = CGRect(origin: CGPoint(x: fillingSize - 16.0 - playbackButtonSize.width, y: 16.0), size: playbackButtonSize)
|
||||
if let playbackButtonView = self.playbackButton.view {
|
||||
if playbackButtonView.superview == nil {
|
||||
self.glassContainerView.contentView.addSubview(playbackButtonView)
|
||||
self.playbackGlassContainerView.contentView.addSubview(playbackButtonView)
|
||||
}
|
||||
transition.setFrame(view: playbackButtonView, frame: playbackButtonFrame)
|
||||
}
|
||||
|
|
@ -1112,17 +1140,20 @@ private final class AttributeInfoComponent: Component {
|
|||
let strings: PresentationStrings
|
||||
let backgroundColor: UIColor
|
||||
let secondaryTextColor: UIColor
|
||||
let badgeColor: UIColor
|
||||
let attribute: StarGift.UniqueGift.Attribute
|
||||
|
||||
init(
|
||||
strings: PresentationStrings,
|
||||
backgroundColor: UIColor,
|
||||
secondaryTextColor: UIColor,
|
||||
badgeColor: UIColor,
|
||||
attribute: StarGift.UniqueGift.Attribute
|
||||
) {
|
||||
self.strings = strings
|
||||
self.backgroundColor = backgroundColor
|
||||
self.secondaryTextColor = secondaryTextColor
|
||||
self.badgeColor = badgeColor
|
||||
self.attribute = attribute
|
||||
}
|
||||
|
||||
|
|
@ -1136,6 +1167,9 @@ private final class AttributeInfoComponent: Component {
|
|||
if lhs.secondaryTextColor != rhs.secondaryTextColor {
|
||||
return false
|
||||
}
|
||||
if lhs.badgeColor != rhs.badgeColor {
|
||||
return false
|
||||
}
|
||||
if lhs.attribute != rhs.attribute {
|
||||
return false
|
||||
}
|
||||
|
|
@ -1193,9 +1227,7 @@ private final class AttributeInfoComponent: Component {
|
|||
subtitle = ""
|
||||
rarity = 0
|
||||
}
|
||||
|
||||
let _ = rarity
|
||||
|
||||
|
||||
let titleSize = self.title.update(
|
||||
transition: .spring(duration: 0.2),
|
||||
component: AnyComponent(AnimatedTextComponent(
|
||||
|
|
@ -1266,7 +1298,7 @@ private final class AttributeInfoComponent: Component {
|
|||
|
||||
let badgeBackgroundFrame = badgeFrame.insetBy(dx: -5.5, dy: -2.0)
|
||||
transition.setFrame(layer: self.badgeBackground, frame: badgeBackgroundFrame)
|
||||
transition.setBackgroundColor(layer: self.badgeBackground, color: component.backgroundColor.mixedWith(component.secondaryTextColor, alpha: 0.5))
|
||||
transition.setBackgroundColor(layer: self.badgeBackground, color: component.badgeColor)
|
||||
|
||||
|
||||
return availableSize
|
||||
|
|
|
|||
|
|
@ -5164,42 +5164,50 @@ final class GiftViewSheetComponent: CombinedComponent {
|
|||
|
||||
var headerContent: AnyComponent<Empty>?
|
||||
if let arguments = context.component.subject.arguments, case .unique = arguments.gift, let fromPeerId = arguments.fromPeerId, var fromPeerName = arguments.fromPeerName, arguments.fromPeerId != context.component.context.account.peerId && !(arguments.fromPeerId?.isTelegramNotifications ?? false) {
|
||||
let dateString = stringForMediumDate(timestamp: arguments.date, strings: environment.strings, dateTimeFormat: environment.dateTimeFormat, withTime: false)
|
||||
|
||||
if fromPeerName.count > 25 {
|
||||
fromPeerName = "\(fromPeerName.prefix(25))…"
|
||||
var showSenderInfo = false
|
||||
if arguments.incoming {
|
||||
showSenderInfo = true
|
||||
} else if arguments.peerId == context.component.context.account.peerId {
|
||||
showSenderInfo = true
|
||||
}
|
||||
if showSenderInfo {
|
||||
let dateString = stringForMediumDate(timestamp: arguments.date, strings: environment.strings, dateTimeFormat: environment.dateTimeFormat, withTime: false)
|
||||
|
||||
if fromPeerName.count > 25 {
|
||||
fromPeerName = "\(fromPeerName.prefix(25))…"
|
||||
}
|
||||
let rawString = environment.strings.Gift_View_SenderInfo(fromPeerName, dateString).string
|
||||
let attributedString = parseMarkdownIntoAttributedString(rawString, attributes: MarkdownAttributes(body: MarkdownAttributeSet(font: Font.regular(13.0), textColor: .white), bold: MarkdownAttributeSet(font: Font.semibold(13.0), textColor: .white), link: MarkdownAttributeSet(font: Font.regular(13.0), textColor: .white), linkAttribute: { _ in return nil }))
|
||||
|
||||
let context = context.component.context
|
||||
headerContent = AnyComponent(
|
||||
PlainButtonComponent(content: AnyComponent(HeaderContentComponent(attributedText: attributedString)), action: {
|
||||
if let controller = controller(), let navigationController = controller.navigationController as? NavigationController {
|
||||
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: fromPeerId))
|
||||
|> deliverOnMainQueue).start(next: { [weak navigationController] peer in
|
||||
guard let peer, let navigationController else {
|
||||
return
|
||||
}
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(
|
||||
navigationController: navigationController,
|
||||
chatController: nil,
|
||||
context: context,
|
||||
chatLocation: .peer(peer),
|
||||
subject: nil,
|
||||
botStart: nil,
|
||||
updateTextInputState: nil,
|
||||
keepStack: .always,
|
||||
useExisting: true,
|
||||
purposefulAction: nil,
|
||||
scrollToEndIfExists: false,
|
||||
activateMessageSearch: nil,
|
||||
animated: true
|
||||
))
|
||||
})
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
let rawString = environment.strings.Gift_View_SenderInfo(fromPeerName, dateString).string
|
||||
let attributedString = parseMarkdownIntoAttributedString(rawString, attributes: MarkdownAttributes(body: MarkdownAttributeSet(font: Font.regular(13.0), textColor: .white), bold: MarkdownAttributeSet(font: Font.semibold(13.0), textColor: .white), link: MarkdownAttributeSet(font: Font.regular(13.0), textColor: .white), linkAttribute: { _ in return nil }))
|
||||
|
||||
let context = context.component.context
|
||||
headerContent = AnyComponent(
|
||||
PlainButtonComponent(content: AnyComponent(HeaderContentComponent(attributedText: attributedString)), action: {
|
||||
if let controller = controller(), let navigationController = controller.navigationController as? NavigationController {
|
||||
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: fromPeerId))
|
||||
|> deliverOnMainQueue).start(next: { [weak navigationController] peer in
|
||||
guard let peer, let navigationController else {
|
||||
return
|
||||
}
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(
|
||||
navigationController: navigationController,
|
||||
chatController: nil,
|
||||
context: context,
|
||||
chatLocation: .peer(peer),
|
||||
subject: nil,
|
||||
botStart: nil,
|
||||
updateTextInputState: nil,
|
||||
keepStack: .always,
|
||||
useExisting: true,
|
||||
purposefulAction: nil,
|
||||
scrollToEndIfExists: false,
|
||||
activateMessageSearch: nil,
|
||||
animated: true
|
||||
))
|
||||
})
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
let sheet = sheet.update(
|
||||
|
|
|
|||
|
|
@ -142,6 +142,7 @@ final class TableComponent: CombinedComponent {
|
|||
var innerTotalOffset: CGFloat = 0.0
|
||||
var hasRowBackground = false
|
||||
var rowBackgroundIsLast = false
|
||||
var hasStraightSide = false
|
||||
|
||||
for item in context.component.items {
|
||||
let insets: UIEdgeInsets
|
||||
|
|
@ -194,6 +195,12 @@ final class TableComponent: CombinedComponent {
|
|||
}
|
||||
hasRowBackground = true
|
||||
}
|
||||
if item.title == nil {
|
||||
if i != 0 {
|
||||
rowBackgroundIsLast = true
|
||||
}
|
||||
hasStraightSide = true
|
||||
}
|
||||
|
||||
i += 1
|
||||
}
|
||||
|
|
@ -247,8 +254,8 @@ final class TableComponent: CombinedComponent {
|
|||
context.clear(bounds)
|
||||
|
||||
var offset: CGFloat = 0.0
|
||||
if hasRowBackground {
|
||||
offset = rowBackgroundIsLast ? borderRadius : -borderRadius
|
||||
if hasStraightSide {
|
||||
offset = rowBackgroundIsLast ? 0.0 : -borderRadius
|
||||
|
||||
bounds.origin.y += offset
|
||||
bounds.size.height += borderRadius
|
||||
|
|
|
|||
|
|
@ -418,6 +418,7 @@ public class GlassBackgroundView: UIView {
|
|||
let nativeFrame = CGRect(origin: CGPoint(), size: size)
|
||||
transition.setFrame(view: nativeView, frame: nativeFrame)
|
||||
}
|
||||
nativeView.overrideUserInterfaceStyle = isDark ? .dark : .light
|
||||
}
|
||||
if let backgroundNode = self.backgroundNode {
|
||||
backgroundNode.updateColor(color: .clear, forceKeepBlur: tintColor.color.alpha != 1.0, transition: transition.containedViewLayoutTransition)
|
||||
|
|
|
|||
|
|
@ -74,13 +74,15 @@ private final class PeerInfoScreenCallListItemNode: PeerInfoScreenItemNode {
|
|||
|
||||
let params = ListViewItemLayoutParams(width: width, leftInset: safeInsets.left, rightInset: safeInsets.right, availableHeight: 1000.0)
|
||||
|
||||
let verticalInset: CGFloat = 8.0
|
||||
|
||||
let itemNode: ItemListCallListItemNode
|
||||
if let current = self.itemNode {
|
||||
itemNode = current
|
||||
addressItem.updateNode(async: { $0() }, node: {
|
||||
return itemNode
|
||||
}, params: params, previousItem: nil, nextItem: nil, animation: .None, completion: { (layout, apply) in
|
||||
let nodeFrame = CGRect(origin: CGPoint(), size: CGSize(width: width, height: layout.size.height))
|
||||
let nodeFrame = CGRect(origin: CGPoint(x: 0.0, y: verticalInset), size: CGSize(width: width, height: layout.size.height))
|
||||
|
||||
itemNode.contentSize = layout.contentSize
|
||||
itemNode.insets = layout.insets
|
||||
|
|
@ -100,9 +102,8 @@ private final class PeerInfoScreenCallListItemNode: PeerInfoScreenItemNode {
|
|||
self.addSubnode(itemNode)
|
||||
}
|
||||
|
||||
let verticalInset: CGFloat = 8.0
|
||||
let height = itemNode.contentSize.height + verticalInset * 2.0
|
||||
|
||||
let height = itemNode.contentSize.height + verticalInset * 2.0
|
||||
transition.updateFrame(node: itemNode, frame: CGRect(origin: CGPoint(x: 0.0, y: verticalInset), size: itemNode.bounds.size))
|
||||
|
||||
let highlightNodeOffset: CGFloat = topItem == nil ? 0.0 : UIScreenPixel
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@ public final class SegmentControlComponent: Component {
|
|||
}
|
||||
|
||||
if themeUpdated {
|
||||
let backgroundColor = component.theme.overallDarkAppearance ? component.theme.list.itemBlocksBackgroundColor : component.theme.rootController.navigationBar.segmentedBackgroundColor
|
||||
let backgroundColor = component.theme.rootController.navigationBar.segmentedBackgroundColor
|
||||
segmentedView.setTitleTextAttributes([
|
||||
.font: Font.semibold(14.0),
|
||||
.foregroundColor: component.theme.rootController.navigationBar.segmentedTextColor
|
||||
|
|
|
|||
|
|
@ -213,11 +213,13 @@ private final class SheetContent: CombinedComponent {
|
|||
case .stars:
|
||||
amountTitle = environment.strings.Gift_Offer_PriceSectionStars
|
||||
minAmount = StarsAmount(value: gift.minOfferStars ?? resaleConfiguration.starGiftResaleMinStarsAmount, nanos: 0)
|
||||
maxAmount = StarsAmount(value: resaleConfiguration.starGiftResaleMaxStarsAmount, nanos: 0)
|
||||
case .ton:
|
||||
amountTitle = environment.strings.Gift_Offer_PriceSectionTon
|
||||
minAmount = StarsAmount(value: resaleConfiguration.starGiftResaleMinTonAmount, nanos: 0)
|
||||
maxAmount = StarsAmount(value: resaleConfiguration.starGiftResaleMaxTonAmount, nanos: 0)
|
||||
}
|
||||
maxAmount = nil
|
||||
|
||||
amountPlaceholder = environment.strings.Gift_Offer_PricePlaceholder
|
||||
|
||||
if let usdWithdrawRate = withdrawConfiguration.usdWithdrawRate, let tonUsdRate = withdrawConfiguration.tonUsdRate, let amount = state.amount, amount > StarsAmount.zero {
|
||||
|
|
@ -1767,8 +1769,15 @@ public final class AmountFieldComponent: Component {
|
|||
guard let component = self.component, let value = component.value else {
|
||||
return
|
||||
}
|
||||
self.textField.text = "\(value)"
|
||||
self.placeholderView.view?.isHidden = self.textField.text?.isEmpty ?? false
|
||||
var text = ""
|
||||
switch component.currency {
|
||||
case .stars:
|
||||
text = "\(value)"
|
||||
case .ton:
|
||||
text = "\(formatTonAmountText(value, dateTimeFormat: PresentationDateTimeFormat(timeFormat: component.dateTimeFormat.timeFormat, dateFormat: component.dateTimeFormat.dateFormat, dateSeparator: "", dateSuffix: "", requiresFullYear: false, decimalSeparator: ".", groupingSeparator: ""), maxDecimalPositions: nil))"
|
||||
}
|
||||
self.textField.text = text
|
||||
self.placeholderView.view?.isHidden = !(self.textField.text ?? "").isEmpty
|
||||
}
|
||||
|
||||
func update(component: AmountFieldComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment<EnvironmentType>, transition: ComponentTransition) -> CGSize {
|
||||
|
|
@ -1788,7 +1797,7 @@ public final class AmountFieldComponent: Component {
|
|||
text = "\(formatTonAmountText(value, dateTimeFormat: PresentationDateTimeFormat(timeFormat: component.dateTimeFormat.timeFormat, dateFormat: component.dateTimeFormat.dateFormat, dateSeparator: "", dateSuffix: "", requiresFullYear: false, decimalSeparator: ".", groupingSeparator: ""), maxDecimalPositions: nil))"
|
||||
}
|
||||
self.textField.text = text
|
||||
self.placeholderView.view?.isHidden = text.isEmpty
|
||||
self.placeholderView.view?.isHidden = !text.isEmpty
|
||||
} else {
|
||||
self.textField.text = ""
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,7 +52,12 @@ public enum DeviceModel: CaseIterable, Equatable {
|
|||
.iPhone16,
|
||||
.iPhone16Plus,
|
||||
.iPhone16Pro,
|
||||
.iPhone16ProMax
|
||||
.iPhone16ProMax,
|
||||
.iPhone16e,
|
||||
.iPhone17,
|
||||
.iPhone17Pro,
|
||||
.iPhone17ProMax,
|
||||
.iPhoneAir
|
||||
]
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue