diff --git a/submodules/TelegramUI/Components/ButtonComponent/Sources/ButtonComponent.swift b/submodules/TelegramUI/Components/ButtonComponent/Sources/ButtonComponent.swift index 0887af088a..6f983b088a 100644 --- a/submodules/TelegramUI/Components/ButtonComponent/Sources/ButtonComponent.swift +++ b/submodules/TelegramUI/Components/ButtonComponent/Sources/ButtonComponent.swift @@ -466,6 +466,9 @@ public final class ButtonComponent: Component { super.init(frame: frame) + self.button.isExclusiveTouch = true + self.layer.rasterizationScale = UIScreenScale + self.addSubview(self.containerView) self.addSubview(self.button) @@ -477,12 +480,24 @@ public final class ButtonComponent: Component { case .glass: let transition = ComponentTransition(animation: .curve(duration: highlighted ? 0.25 : 0.35, curve: .spring)) if highlighted { + self.layer.shouldRasterize = true + let highlightedColor = component.background.color.withMultiplied(hue: 1.0, saturation: 0.77, brightness: 1.01) transition.setBackgroundColor(view: self.containerView, color: highlightedColor) - transition.setScale(view: self.containerView, scale: 1.05) + transition.setScale(view: self.containerView, scale: 1.05, completion: { finished in + if finished { + self.layer.shouldRasterize = false + } + }) } else { + self.layer.shouldRasterize = true + transition.setBackgroundColor(view: self.containerView, color: component.background.color) - transition.setScale(view: self.containerView, scale: 1.0) + transition.setScale(view: self.containerView, scale: 1.0, completion: { finished in + if finished { + self.layer.shouldRasterize = false + } + }) } case .legacy: if highlighted { diff --git a/submodules/TelegramUI/Components/Gifts/GiftCraftScreen/BUILD b/submodules/TelegramUI/Components/Gifts/GiftCraftScreen/BUILD index e5a3568ad1..7262f33a94 100644 --- a/submodules/TelegramUI/Components/Gifts/GiftCraftScreen/BUILD +++ b/submodules/TelegramUI/Components/Gifts/GiftCraftScreen/BUILD @@ -49,6 +49,7 @@ swift_library( "//submodules/TelegramUI/Components/SpaceWarpView", "//submodules/ConfettiEffect", "//submodules/TelegramNotices", + "//submodules/TelegramUI/Components/Gifts/GiftLoadingShimmerView", ], visibility = [ "//visibility:public", diff --git a/submodules/TelegramUI/Components/Gifts/GiftCraftScreen/Sources/CraftTableComponent.swift b/submodules/TelegramUI/Components/Gifts/GiftCraftScreen/Sources/CraftTableComponent.swift index 51b83e7042..a6a3bff6eb 100644 --- a/submodules/TelegramUI/Components/Gifts/GiftCraftScreen/Sources/CraftTableComponent.swift +++ b/submodules/TelegramUI/Components/Gifts/GiftCraftScreen/Sources/CraftTableComponent.swift @@ -546,7 +546,7 @@ final class GiftSlotComponent: Component { self.state = state let backgroundFrame = CGRect(origin: .zero, size: availableSize).insetBy(dx: 1.0, dy: 1.0) - self.backgroundView.update(size: backgroundFrame.size, cornerRadius: 28.0, isDark: true, tintColor: .init(kind: .custom(style: .default, color: component.buttonColor)), transition: .immediate) + self.backgroundView.update(size: backgroundFrame.size, cornerRadius: 28.0, isDark: true, tintColor: .init(kind: .custom(style: .default, color: component.buttonColor)), isInteractive: true, transition: .immediate) transition.setFrame(view: self.backgroundView, frame: backgroundFrame) if component.gift == nil && component.isCrafting && previousComponent?.isCrafting == false { transition.setBlur(layer: self.backgroundView.layer, radius: 10.0) diff --git a/submodules/TelegramUI/Components/Gifts/GiftCraftScreen/Sources/DialIndicatorComponent.swift b/submodules/TelegramUI/Components/Gifts/GiftCraftScreen/Sources/DialIndicatorComponent.swift index a595eeb6db..468c44773f 100644 --- a/submodules/TelegramUI/Components/Gifts/GiftCraftScreen/Sources/DialIndicatorComponent.swift +++ b/submodules/TelegramUI/Components/Gifts/GiftCraftScreen/Sources/DialIndicatorComponent.swift @@ -106,7 +106,7 @@ final class DialIndicatorComponent: Component { self.backgroundLayer.lineCap = .round self.foregroundLayer.lineCap = .round - + self.addSubview(self.containerView) self.containerView.layer.addSublayer(self.backgroundLayer) diff --git a/submodules/TelegramUI/Components/Gifts/GiftCraftScreen/Sources/GiftCraftScreen.swift b/submodules/TelegramUI/Components/Gifts/GiftCraftScreen/Sources/GiftCraftScreen.swift index efaaf2a3dc..cef1be4731 100644 --- a/submodules/TelegramUI/Components/Gifts/GiftCraftScreen/Sources/GiftCraftScreen.swift +++ b/submodules/TelegramUI/Components/Gifts/GiftCraftScreen/Sources/GiftCraftScreen.swift @@ -166,9 +166,7 @@ private final class CraftGiftPageContent: Component { private let infoTitle = ComponentView() private let infoDescription = ComponentView() private var infoList = ComponentView() - - private var actionButton = ComponentView() - + private var craftState: CraftGiftsContext.State? private var craftStateDisposable: Disposable? @@ -338,6 +336,7 @@ private final class CraftGiftPageContent: Component { } self.starGiftsMap = starGiftsMap component.externalState.starGiftsMap = starGiftsMap + self.state?.updated() })) } @@ -1616,8 +1615,16 @@ private final class SheetContainerComponent: CombinedComponent { tintColor: .white ) )), - action: { _ in - dismiss(true) + action: { [weak state] _ in + guard let state else { + return + } + if state.displayInfo { + state.displayInfo = false + state.updated(transition: .spring(duration: 0.3)) + } else { + dismiss(true) + } } ) ), diff --git a/submodules/TelegramUI/Components/Gifts/GiftCraftScreen/Sources/SelectCraftGiftScreen.swift b/submodules/TelegramUI/Components/Gifts/GiftCraftScreen/Sources/SelectCraftGiftScreen.swift index ce7bf9fa8a..ed0b4dc0af 100644 --- a/submodules/TelegramUI/Components/Gifts/GiftCraftScreen/Sources/SelectCraftGiftScreen.swift +++ b/submodules/TelegramUI/Components/Gifts/GiftCraftScreen/Sources/SelectCraftGiftScreen.swift @@ -21,6 +21,7 @@ import ResizableSheetComponent import TooltipUI import GlassBarButtonComponent import ConfettiEffect +import GiftLoadingShimmerView final class SelectGiftPageContent: Component { typealias EnvironmentType = ViewControllerComponentContainer.Environment @@ -74,6 +75,7 @@ final class SelectGiftPageContent: Component { private let myGiftsTitle = ComponentView() private var gifts: [AnyHashable: ComponentView] = [:] private let myGiftsPlaceholder = ComponentView() + private let loadingView = GiftLoadingShimmerView() private let storeGiftsTitle = ComponentView() private let storeGifts = ComponentView() @@ -94,6 +96,8 @@ final class SelectGiftPageContent: Component { self.layer.cornerRadius = 40.0 self.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner] + + self.addSubview(self.loadingView) } required init?(coder: NSCoder) { @@ -204,10 +208,25 @@ final class SelectGiftPageContent: Component { } let itemWidth = (availableSize.width - itemSideInset * 2.0 - itemSpacing * CGFloat(itemsInRow - 1)) / CGFloat(itemsInRow) let itemSize = CGSize(width: itemWidth, height: itemWidth) - var itemFrame = CGRect(origin: CGPoint(x: itemSideInset, y: contentHeight), size: itemSize) + + var isLoading = false + if self.availableGifts.isEmpty, case .loading = (self.craftState?.dataState ?? .loading) { + isLoading = true + } + let loadingTransition: ComponentTransition = .easeInOut(duration: 0.25) + let loadingSize = CGSize(width: availableSize.width, height: 180.0) + if isLoading { + contentHeight += 120.0 + self.loadingView.update(size: loadingSize, theme: environment.theme, itemSize: itemSize, showFilters: false, isPlain: true, transition: .immediate) + loadingTransition.setAlpha(view: self.loadingView, alpha: 1.0) + } else { + loadingTransition.setAlpha(view: self.loadingView, alpha: 0.0) + } + transition.setFrame(view: self.loadingView, frame: CGRect(origin: CGPoint(x: 0.0, y: contentHeight - 170.0), size: loadingSize)) + + var itemFrame = CGRect(origin: CGPoint(x: itemSideInset, y: contentHeight), size: itemSize) var itemsHeight: CGFloat = 0.0 - var validIds: [AnyHashable] = [] for gift in self.availableGifts { let isVisible = "".isEmpty @@ -272,17 +291,15 @@ final class SelectGiftPageContent: Component { ) if let itemView = visibleItem.view { if itemView.superview == nil { - self.addSubview(itemView) - + if let _ = self.loadingView.superview { + self.insertSubview(itemView, belowSubview: self.loadingView) + } else { + self.addSubview(itemView) + } if !transition.animation.isImmediate { - let delay = ((itemFrame.minY - contentHeight) / itemSize.height) * 0.07 - itemView.layer.animateScale(from: 0.01, to: 1.0, duration: 0.25, delay: delay) - itemView.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.25, delay: delay) + itemView.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.25) } } - itemView.isUserInteractionEnabled = !component.selectedGiftIds.contains(gift.gift.id) - itemView.alpha = component.selectedGiftIds.contains(gift.gift.id) ? 0.4 : 1.0 - itemView.layer.allowsGroupOpacity = itemView.alpha < 1.0 itemTransition.setFrame(view: itemView, frame: itemFrame) } } @@ -315,7 +332,7 @@ final class SelectGiftPageContent: Component { for id in removeIds { self.gifts.removeValue(forKey: id) } - + if let state = self.craftState, case .ready = state.dataState, self.availableGifts.isEmpty { contentHeight += 10.0 let myGiftsPlaceholderSize = self.myGiftsPlaceholder.update( diff --git a/submodules/TelegramUI/Components/Gifts/GiftLoadingShimmerView/Sources/GiftLoadingShimmerView.swift b/submodules/TelegramUI/Components/Gifts/GiftLoadingShimmerView/Sources/GiftLoadingShimmerView.swift index a51f903f6e..2ba1af60ce 100644 --- a/submodules/TelegramUI/Components/Gifts/GiftLoadingShimmerView/Sources/GiftLoadingShimmerView.swift +++ b/submodules/TelegramUI/Components/Gifts/GiftLoadingShimmerView/Sources/GiftLoadingShimmerView.swift @@ -139,7 +139,7 @@ public final class GiftLoadingShimmerView: UIView { required init?(coder: NSCoder) { fatalError() } - public func update(size: CGSize, theme: PresentationTheme, showFilters: Bool = false, isPlain: Bool = false, transition: ContainedViewLayoutTransition) { + public func update(size: CGSize, theme: PresentationTheme, itemSize: CGSize? = nil, showFilters: Bool = false, isPlain: Bool = false, transition: ContainedViewLayoutTransition) { let backgroundColor = isPlain ? theme.list.itemBlocksBackgroundColor : theme.list.blocksBackgroundColor let color = theme.list.itemSecondaryTextColor.mixedWith(theme.list.blocksBackgroundColor, alpha: 0.85) @@ -169,7 +169,7 @@ public final class GiftLoadingShimmerView: UIView { let optionSpacing: CGFloat = 10.0 let optionWidth = (size.width - sideInset * 2.0 - optionSpacing * 2.0) / 3.0 - let itemSize = CGSize(width: optionWidth, height: 154.0) + let itemSize = itemSize ?? CGSize(width: optionWidth, height: 154.0) context.setBlendMode(.copy) context.setFillColor(UIColor.clear.cgColor) diff --git a/submodules/TelegramUI/Components/Gifts/GiftViewScreen/Sources/GiftUpgradeVariantsScreen.swift b/submodules/TelegramUI/Components/Gifts/GiftViewScreen/Sources/GiftUpgradeVariantsScreen.swift index 5e9fd677f8..833e8c3088 100644 --- a/submodules/TelegramUI/Components/Gifts/GiftViewScreen/Sources/GiftUpgradeVariantsScreen.swift +++ b/submodules/TelegramUI/Components/Gifts/GiftViewScreen/Sources/GiftUpgradeVariantsScreen.swift @@ -202,6 +202,8 @@ private final class GiftUpgradeVariantsScreenComponent: Component { self.containerView.addSubview(self.navigationBarContainer) self.dimView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.dimTapGesture(_:)))) + + self.alpha = 0.0 } required init?(coder: NSCoder) { @@ -271,6 +273,7 @@ private final class GiftUpgradeVariantsScreenComponent: Component { } func animateIn() { + self.alpha = 1.0 self.dimView.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.3) let animateOffset: CGFloat = self.bounds.height - self.backgroundLayer.frame.minY self.scrollContentClippingView.layer.animatePosition(from: CGPoint(x: 0.0, y: animateOffset), to: CGPoint(), duration: 0.5, timingFunction: kCAMediaTimingFunctionSpring, additive: true) @@ -1061,6 +1064,13 @@ private final class GiftUpgradeVariantsScreenComponent: Component { self.previewTimerTick() } self.state?.updated(transition: .easeInOut(duration: 0.25)) + + if let buttonView = self.playbackButton.view { + buttonView.isUserInteractionEnabled = false + Queue.mainQueue().after(0.3, { + buttonView.isUserInteractionEnabled = true + }) + } } )), environment: {}, @@ -1194,7 +1204,9 @@ public class GiftUpgradeVariantsScreen: ViewControllerComponentContainer { self.didPlayAppearAnimation = true if let componentView = self.node.hostView.componentView as? GiftUpgradeVariantsScreenComponent.View { - componentView.animateIn() + Queue.mainQueue().justDispatch { + componentView.animateIn() + } } } } diff --git a/submodules/TelegramUI/Components/Gifts/GiftViewScreen/Sources/GiftViewBuyGift.swift b/submodules/TelegramUI/Components/Gifts/GiftViewScreen/Sources/GiftViewBuyGift.swift index 48cbb81e84..ff996afa9c 100644 --- a/submodules/TelegramUI/Components/Gifts/GiftViewScreen/Sources/GiftViewBuyGift.swift +++ b/submodules/TelegramUI/Components/Gifts/GiftViewScreen/Sources/GiftViewBuyGift.swift @@ -37,6 +37,8 @@ public func buyStarGiftImpl( parseMarkdown: true ) controller.present(alertController, in: .window(.root)) + + beforeCompletion() return } @@ -207,6 +209,8 @@ public func buyStarGiftImpl( context.sharedContext.applicationBindings.openUrl(fragmentUrl) } )) + + beforeCompletion() } else { proceed() } diff --git a/submodules/TelegramUI/Components/PlainButtonComponent/Sources/PlainButtonComponent.swift b/submodules/TelegramUI/Components/PlainButtonComponent/Sources/PlainButtonComponent.swift index d36b09e40f..fadcc5c0d6 100644 --- a/submodules/TelegramUI/Components/PlainButtonComponent/Sources/PlainButtonComponent.swift +++ b/submodules/TelegramUI/Components/PlainButtonComponent/Sources/PlainButtonComponent.swift @@ -108,6 +108,7 @@ public final class PlainButtonComponent: Component { super.init(frame: frame) self.isExclusiveTouch = true + self.layer.rasterizationScale = UIScreenScale self.contentContainer.isUserInteractionEnabled = false self.addSubview(self.contentContainer) @@ -130,8 +131,13 @@ public final class PlainButtonComponent: Component { self.contentContainer.alpha = 0.7 } if animateScale { + self.layer.shouldRasterize = true let transition = ComponentTransition(animation: .curve(duration: 0.2, curve: .easeInOut)) - transition.setScale(layer: self.contentContainer.layer, scale: topScale) + transition.setScale(layer: self.contentContainer.layer, scale: topScale, completion: { finished in + if finished { + self.layer.shouldRasterize = false + } + }) } } else { if animateAlpha { @@ -140,15 +146,21 @@ public final class PlainButtonComponent: Component { } if animateScale { + self.layer.shouldRasterize = true + let transition = ComponentTransition(animation: .none) transition.setScale(layer: self.contentContainer.layer, scale: 1.0) - + self.contentContainer.layer.animateScale(from: topScale, to: maxScale, duration: 0.13, timingFunction: CAMediaTimingFunctionName.easeOut.rawValue, removeOnCompletion: false, completion: { [weak self] _ in guard let self else { return } - self.contentContainer.layer.animateScale(from: maxScale, to: 1.0, duration: 0.1, timingFunction: CAMediaTimingFunctionName.easeIn.rawValue) + self.contentContainer.layer.animateScale(from: maxScale, to: 1.0, duration: 0.1, timingFunction: CAMediaTimingFunctionName.easeIn.rawValue, completion: { finished in + if finished { + self.layer.shouldRasterize = false + } + }) }) } }