From 15fd6d7b37d0a2bbd522cf22ec0cdfdb595144e3 Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Sat, 1 Mar 2025 00:49:18 +0400 Subject: [PATCH] Various fixes --- .../Sources/LegacyPaintStickersContext.swift | 11 +++ .../Sources/MediaPickerScreen.swift | 7 +- .../Sources/MessageInputPanelComponent.swift | 2 +- .../Sources/PeerInfoGiftsCoverComponent.swift | 67 ++++++++++++++----- .../Chat/ChatControllerPaidMessage.swift | 2 +- .../TelegramUI/Sources/ChatController.swift | 12 ++-- .../ChatTextInputActionButtonsNode.swift | 2 +- .../Sources/ChatTextInputPanelNode.swift | 4 +- 8 files changed, 80 insertions(+), 27 deletions(-) diff --git a/submodules/LegacyMediaPickerUI/Sources/LegacyPaintStickersContext.swift b/submodules/LegacyMediaPickerUI/Sources/LegacyPaintStickersContext.swift index 9f30f07350..af525ff44f 100644 --- a/submodules/LegacyMediaPickerUI/Sources/LegacyPaintStickersContext.swift +++ b/submodules/LegacyMediaPickerUI/Sources/LegacyPaintStickersContext.swift @@ -629,6 +629,7 @@ private class SendStarsButtonView: HighlightTrackingButton, TGPhotoSendStarsButt override init(frame: CGRect) { self.backgroundView = UIView() + self.backgroundView.isUserInteractionEnabled = false self.textNode = ImmediateAnimatedCountLabelNode() self.textNode.isUserInteractionEnabled = false @@ -654,12 +655,22 @@ private class SendStarsButtonView: HighlightTrackingButton, TGPhotoSendStarsButt self.textNode.layer.animateAlpha(from: 0.4, to: 1.0, duration: 0.2) } } + + self.addTarget(self, action: #selector(self.buttonPressed), for: .touchUpInside) } required init?(coder: NSCoder) { preconditionFailure() } + deinit { + print() + } + + @objc private func buttonPressed() { + self.pressed?() + } + func updateFrame(_ frame: CGRect) { let transition: ContainedViewLayoutTransition if self.frame.width.isZero { diff --git a/submodules/MediaPickerUI/Sources/MediaPickerScreen.swift b/submodules/MediaPickerUI/Sources/MediaPickerScreen.swift index 86aca15324..4a6be111a9 100644 --- a/submodules/MediaPickerUI/Sources/MediaPickerScreen.swift +++ b/submodules/MediaPickerUI/Sources/MediaPickerScreen.swift @@ -1322,7 +1322,7 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att } } - let proceed: (Bool) -> Void = { convertToJpeg in + let proceed: (Bool) -> Void = { [weak self] convertToJpeg in let signals: [Any]! switch controller.subject { case .assets: @@ -1340,6 +1340,11 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att completion() self?.controller?.dismiss(animated: animated) }) + + Queue.mainQueue().after(1.5) { + controller.isDismissing = false + controller.completed = false + } } if asFile && hasHeic { diff --git a/submodules/TelegramUI/Components/MessageInputPanelComponent/Sources/MessageInputPanelComponent.swift b/submodules/TelegramUI/Components/MessageInputPanelComponent/Sources/MessageInputPanelComponent.swift index ad21bcfc7d..290e126b5e 100644 --- a/submodules/TelegramUI/Components/MessageInputPanelComponent/Sources/MessageInputPanelComponent.swift +++ b/submodules/TelegramUI/Components/MessageInputPanelComponent/Sources/MessageInputPanelComponent.swift @@ -1452,7 +1452,7 @@ public final class MessageInputPanelComponent: Component { inputActionButtonMode = .send } else { if self.textFieldExternalState.hasText { - if let sendPaidMessageStars = component.sendPaidMessageStars { + if let sendPaidMessageStars = component.sendPaidMessageStars, "".isEmpty { inputActionButtonMode = .stars(sendPaidMessageStars.value) } else { inputActionButtonMode = .send diff --git a/submodules/TelegramUI/Components/PeerInfo/PeerInfoCoverComponent/Sources/PeerInfoGiftsCoverComponent.swift b/submodules/TelegramUI/Components/PeerInfo/PeerInfoCoverComponent/Sources/PeerInfoGiftsCoverComponent.swift index ddb00e1961..267befaacd 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PeerInfoCoverComponent/Sources/PeerInfoGiftsCoverComponent.swift +++ b/submodules/TelegramUI/Components/PeerInfo/PeerInfoCoverComponent/Sources/PeerInfoGiftsCoverComponent.swift @@ -138,11 +138,11 @@ public final class PeerInfoGiftsCoverComponent: Component { private var giftsDisposable: Disposable? private var gifts: [ProfileGiftsContext.State.StarGift] = [] + private var appliedGiftIds: [Int64] = [] private var iconLayers: [AnyHashable: GiftIconLayer] = [:] private var iconPositions: [PositionGenerator.Position] = [] - private let seed = UInt(Date().timeIntervalSince1970) override public init(frame: CGRect) { self.avatarBackgroundGradientLayer = SimpleGradientLayer() @@ -185,6 +185,7 @@ public final class PeerInfoGiftsCoverComponent: Component { self.isUpdating = false } + let previousComponent = self.component self.component = component self.state = state @@ -193,7 +194,15 @@ public final class PeerInfoGiftsCoverComponent: Component { let iconSize = CGSize(width: 32.0, height: 32.0) - if previousCurrentSize?.width != availableSize.width { + let giftIds = self.gifts.map { gift in + if case let .unique(gift) = gift.gift { + return gift.id + } else { + return 0 + } + } + + if previousCurrentSize?.width != availableSize.width || (previousComponent != nil && previousComponent?.hasBackground != component.hasBackground) || self.appliedGiftIds != giftIds { var excludeRects: [CGRect] = [] excludeRects.append(CGRect(origin: .zero, size: CGSize(width: 50.0, height: 90.0))) excludeRects.append(CGRect(origin: CGPoint(x: availableSize.width - 105.0, y: 0.0), size: CGSize(width: 105.0, height: 90.0))) @@ -209,11 +218,12 @@ public final class PeerInfoGiftsCoverComponent: Component { minDistance: 75.0, maxDistance: availableSize.width / 2.0, padding: 12.0, - seed: self.seed, + seed: UInt(Date().timeIntervalSince1970), excludeRects: excludeRects ) self.iconPositions = positionGenerator.generatePositions(count: 9, viewSize: iconSize) } + self.appliedGiftIds = giftIds if self.giftsDisposable == nil { self.giftsDisposable = combineLatest( @@ -243,7 +253,7 @@ public final class PeerInfoGiftsCoverComponent: Component { self.gifts = pinnedGifts if !self.isUpdating { - self.state?.updated(transition: .immediate) + self.state?.updated(transition: .spring(duration: 0.4)) } }) } @@ -271,11 +281,13 @@ public final class PeerInfoGiftsCoverComponent: Component { } validIds.insert(id) + var iconTransition = transition let iconPosition = self.iconPositions[index] let iconLayer: GiftIconLayer if let current = self.iconLayers[id] { iconLayer = current } else { + iconTransition = .immediate iconLayer = GiftIconLayer(context: component.context, gift: gift, size: iconSize, glowing: component.hasBackground) iconLayer.startHovering() self.iconLayers[id] = iconLayer @@ -284,6 +296,7 @@ public final class PeerInfoGiftsCoverComponent: Component { iconLayer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2) iconLayer.animateScale(from: 0.01, to: 1.0, duration: 0.2) } + iconLayer.glowing = component.hasBackground let centerPosition = component.avatarCenter let finalPosition = iconPosition.center.offsetBy(dx: component.avatarCenter.x, dy: component.avatarCenter.y) @@ -303,10 +316,10 @@ public final class PeerInfoGiftsCoverComponent: Component { let effectivePosition = interpolateRect(from: finalPosition, to: centerPosition, t: itemScaleFraction) - transition.setBounds(layer: iconLayer, bounds: CGRect(origin: .zero, size: iconSize)) - transition.setPosition(layer: iconLayer, position: effectivePosition) - transition.setScale(layer: iconLayer, scale: iconPosition.scale * (1.0 - itemScaleFraction)) - transition.setAlpha(layer: iconLayer, alpha: 1.0 - itemScaleFraction) + iconTransition.setBounds(layer: iconLayer, bounds: CGRect(origin: .zero, size: iconSize)) + iconTransition.setPosition(layer: iconLayer, position: effectivePosition) + iconTransition.setScale(layer: iconLayer, scale: iconPosition.scale * (1.0 - itemScaleFraction)) + iconTransition.setAlpha(layer: iconLayer, alpha: 1.0 - itemScaleFraction) index += 1 } @@ -434,7 +447,7 @@ private class PositionGenerator { let distance = hypot(result.x - self.avatarFrame.center.x, result.y - self.avatarFrame.center.y) let baseScale = min(1.0, max(0.77, 1.0 - (distance - 75.0) / 75.0)) - let randomFactor = 0.05 + (1.0 - baseScale) * 0.1 + let randomFactor = 0.14 + (1.0 - baseScale) * 0.2 let randomValue = -randomFactor + CGFloat(self.rng.next()) * 2.0 * randomFactor let finalScale = min(1.2, max(baseScale * 0.65, baseScale + randomValue)) @@ -563,6 +576,8 @@ private final class StarsEffectLayer: SimpleLayer { } func setup(color: UIColor, size: CGSize) { + self.color = color + let emitter = CAEmitterCell() emitter.name = "emitter" emitter.contents = UIImage(bundleImageName: "Premium/Stars/Particle")?.cgImage @@ -586,8 +601,10 @@ private final class StarsEffectLayer: SimpleLayer { self.emitterLayer.emitterCells = [emitter] } + private var color: UIColor? + func update(color: UIColor, size: CGSize) { - if self.emitterLayer.emitterCells == nil { + if self.color != color { self.setup(color: color, size: size) } self.emitterLayer.seed = UInt32.random(in: .min ..< .max) @@ -604,7 +621,25 @@ private class GiftIconLayer: SimpleLayer { private let context: AccountContext private let gift: ProfileGiftsContext.State.StarGift private let size: CGSize - private let glowing: Bool + var glowing: Bool { + didSet { + self.shadowLayer.opacity = self.glowing ? 1.0 : 0.0 + + let color: UIColor + if self.glowing { + color = .white + } else if let layerTintColor = self.shadowLayer.layerTintColor { + color = UIColor(cgColor: layerTintColor) + } else { + color = .white + } + + let side = floor(self.size.width * 1.25) + let starsFrame = CGSize(width: side, height: side).centered(in: CGRect(origin: .zero, size: self.size)) + self.starsLayer.frame = starsFrame + self.starsLayer.update(color: color, size: starsFrame.size) + } + } let shadowLayer = SimpleLayer() let starsLayer = StarsEffectLayer() @@ -656,6 +691,7 @@ private class GiftIconLayer: SimpleLayer { self.shadowLayer.contents = shadowImage?.cgImage self.shadowLayer.layerTintColor = color.cgColor + self.shadowLayer.opacity = glowing ? 1.0 : 0.0 self.context = context self.gift = gift @@ -669,9 +705,7 @@ private class GiftIconLayer: SimpleLayer { self.starsLayer.frame = starsFrame self.starsLayer.update(color: glowing ? .white : color, size: starsFrame.size) - if glowing { - self.addSublayer(self.shadowLayer) - } + self.addSublayer(self.shadowLayer) self.addSublayer(self.starsLayer) self.addSublayer(self.animationLayer) } @@ -723,6 +757,7 @@ private class GiftIconLayer: SimpleLayer { self.shadowLayer.contents = shadowImage?.cgImage self.shadowLayer.layerTintColor = color.cgColor + self.shadowLayer.opacity = glowing ? 1.0 : 0.0 super.init() @@ -731,9 +766,7 @@ private class GiftIconLayer: SimpleLayer { self.starsLayer.frame = starsFrame self.starsLayer.update(color: glowing ? .white : color, size: starsFrame.size) - if glowing { - self.addSublayer(self.shadowLayer) - } + self.addSublayer(self.shadowLayer) self.addSublayer(self.starsLayer) self.addSublayer(self.animationLayer) } diff --git a/submodules/TelegramUI/Sources/Chat/ChatControllerPaidMessage.swift b/submodules/TelegramUI/Sources/Chat/ChatControllerPaidMessage.swift index 0833193f98..5aa4ed7a50 100644 --- a/submodules/TelegramUI/Sources/Chat/ChatControllerPaidMessage.swift +++ b/submodules/TelegramUI/Sources/Chat/ChatControllerPaidMessage.swift @@ -20,7 +20,7 @@ extension ChatControllerImpl { completion(false) return } - if let sendPaidMessageStars = self.presentationInterfaceState.sendPaidMessageStars { + if let sendPaidMessageStars = self.presentationInterfaceState.sendPaidMessageStars, self.presentationInterfaceState.interfaceState.editMessage == nil { let totalAmount = sendPaidMessageStars.value * Int64(count) let _ = (ApplicationSpecificNotice.dismissedPaidMessageWarningNamespace(accountManager: self.context.sharedContext.accountManager, peerId: peer.id) diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index ba2d94f03b..a86ba9fe77 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -2067,11 +2067,15 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G }) } }, sendCurrentMessage: { [weak self] silentPosting, messageEffect in - if let strongSelf = self { - if let _ = strongSelf.presentationInterfaceState.interfaceState.mediaDraftState { - strongSelf.sendMediaRecording(silentPosting: silentPosting, messageEffect: messageEffect) + if let self { + if let _ = self.presentationInterfaceState.interfaceState.mediaDraftState { + self.sendMediaRecording(silentPosting: silentPosting, messageEffect: messageEffect) } else { - strongSelf.chatDisplayNode.sendCurrentMessage(silentPosting: silentPosting, messageEffect: messageEffect) + self.presentPaidMessageAlertIfNeeded(count: 1, completion: { [weak self] postpone in + if let self { + self.chatDisplayNode.sendCurrentMessage(silentPosting: silentPosting, postpone: postpone, messageEffect: messageEffect) + } + }) } } }, sendMessage: { [weak self] text in diff --git a/submodules/TelegramUI/Sources/ChatTextInputActionButtonsNode.swift b/submodules/TelegramUI/Sources/ChatTextInputActionButtonsNode.swift index 5d83f3b04b..a831f1cab1 100644 --- a/submodules/TelegramUI/Sources/ChatTextInputActionButtonsNode.swift +++ b/submodules/TelegramUI/Sources/ChatTextInputActionButtonsNode.swift @@ -272,7 +272,7 @@ final class ChatTextInputActionButtonsNode: ASDisplayNode, ChatSendMessageAction self.validLayout = size var innerSize = size - if let sendPaidMessageStars = interfaceState.sendPaidMessageStars { + if let sendPaidMessageStars = interfaceState.sendPaidMessageStars, interfaceState.interfaceState.editMessage == nil { self.sendButton.imageNode.alpha = 0.0 self.textNode.isHidden = false diff --git a/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift b/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift index 129a29154f..18fcdf4e72 100644 --- a/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift +++ b/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift @@ -1915,7 +1915,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate, Ch placeholder = interfaceState.strings.Conversation_InputTextAnonymousPlaceholder } else if case let .replyThread(replyThreadMessage) = interfaceState.chatLocation, !replyThreadMessage.isForumPost, replyThreadMessage.peerId != self.context?.account.peerId { if replyThreadMessage.isChannelPost { - if let sendPaidMessageStars = interfaceState.sendPaidMessageStars { + if let sendPaidMessageStars = interfaceState.sendPaidMessageStars, interfaceState.interfaceState.editMessage == nil { placeholder = interfaceState.strings.Chat_InputTextPaidCommentPlaceholder(" # \(presentationStringsFormattedNumber(Int32(sendPaidMessageStars.value), interfaceState.dateTimeFormat.groupingSeparator))").string placeholderHasStar = true } else { @@ -1931,7 +1931,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate, Ch placeholder = interfaceState.strings.Chat_InputPlaceholderMessageInTopic(forumTopicData.title).string } } else { - if let sendPaidMessageStars = interfaceState.sendPaidMessageStars { + if let sendPaidMessageStars = interfaceState.sendPaidMessageStars, interfaceState.interfaceState.editMessage == nil { placeholder = interfaceState.strings.Chat_InputTextPaidMessagePlaceholder(" # \(presentationStringsFormattedNumber(Int32(sendPaidMessageStars.value), interfaceState.dateTimeFormat.groupingSeparator))").string placeholderHasStar = true } else {