Various fixes

This commit is contained in:
Ilya Laktyushin 2025-03-01 00:49:18 +04:00
parent 86e7238bfa
commit 15fd6d7b37
8 changed files with 80 additions and 27 deletions

View File

@ -629,6 +629,7 @@ private class SendStarsButtonView: HighlightTrackingButton, TGPhotoSendStarsButt
override init(frame: CGRect) { override init(frame: CGRect) {
self.backgroundView = UIView() self.backgroundView = UIView()
self.backgroundView.isUserInteractionEnabled = false
self.textNode = ImmediateAnimatedCountLabelNode() self.textNode = ImmediateAnimatedCountLabelNode()
self.textNode.isUserInteractionEnabled = false 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.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) { required init?(coder: NSCoder) {
preconditionFailure() preconditionFailure()
} }
deinit {
print()
}
@objc private func buttonPressed() {
self.pressed?()
}
func updateFrame(_ frame: CGRect) { func updateFrame(_ frame: CGRect) {
let transition: ContainedViewLayoutTransition let transition: ContainedViewLayoutTransition
if self.frame.width.isZero { if self.frame.width.isZero {

View File

@ -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]! let signals: [Any]!
switch controller.subject { switch controller.subject {
case .assets: case .assets:
@ -1340,6 +1340,11 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att
completion() completion()
self?.controller?.dismiss(animated: animated) self?.controller?.dismiss(animated: animated)
}) })
Queue.mainQueue().after(1.5) {
controller.isDismissing = false
controller.completed = false
}
} }
if asFile && hasHeic { if asFile && hasHeic {

View File

@ -1452,7 +1452,7 @@ public final class MessageInputPanelComponent: Component {
inputActionButtonMode = .send inputActionButtonMode = .send
} else { } else {
if self.textFieldExternalState.hasText { if self.textFieldExternalState.hasText {
if let sendPaidMessageStars = component.sendPaidMessageStars { if let sendPaidMessageStars = component.sendPaidMessageStars, "".isEmpty {
inputActionButtonMode = .stars(sendPaidMessageStars.value) inputActionButtonMode = .stars(sendPaidMessageStars.value)
} else { } else {
inputActionButtonMode = .send inputActionButtonMode = .send

View File

@ -138,11 +138,11 @@ public final class PeerInfoGiftsCoverComponent: Component {
private var giftsDisposable: Disposable? private var giftsDisposable: Disposable?
private var gifts: [ProfileGiftsContext.State.StarGift] = [] private var gifts: [ProfileGiftsContext.State.StarGift] = []
private var appliedGiftIds: [Int64] = []
private var iconLayers: [AnyHashable: GiftIconLayer] = [:] private var iconLayers: [AnyHashable: GiftIconLayer] = [:]
private var iconPositions: [PositionGenerator.Position] = [] private var iconPositions: [PositionGenerator.Position] = []
private let seed = UInt(Date().timeIntervalSince1970)
override public init(frame: CGRect) { override public init(frame: CGRect) {
self.avatarBackgroundGradientLayer = SimpleGradientLayer() self.avatarBackgroundGradientLayer = SimpleGradientLayer()
@ -185,6 +185,7 @@ public final class PeerInfoGiftsCoverComponent: Component {
self.isUpdating = false self.isUpdating = false
} }
let previousComponent = self.component
self.component = component self.component = component
self.state = state self.state = state
@ -193,7 +194,15 @@ public final class PeerInfoGiftsCoverComponent: Component {
let iconSize = CGSize(width: 32.0, height: 32.0) 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] = [] var excludeRects: [CGRect] = []
excludeRects.append(CGRect(origin: .zero, size: CGSize(width: 50.0, height: 90.0))) 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))) 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, minDistance: 75.0,
maxDistance: availableSize.width / 2.0, maxDistance: availableSize.width / 2.0,
padding: 12.0, padding: 12.0,
seed: self.seed, seed: UInt(Date().timeIntervalSince1970),
excludeRects: excludeRects excludeRects: excludeRects
) )
self.iconPositions = positionGenerator.generatePositions(count: 9, viewSize: iconSize) self.iconPositions = positionGenerator.generatePositions(count: 9, viewSize: iconSize)
} }
self.appliedGiftIds = giftIds
if self.giftsDisposable == nil { if self.giftsDisposable == nil {
self.giftsDisposable = combineLatest( self.giftsDisposable = combineLatest(
@ -243,7 +253,7 @@ public final class PeerInfoGiftsCoverComponent: Component {
self.gifts = pinnedGifts self.gifts = pinnedGifts
if !self.isUpdating { 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) validIds.insert(id)
var iconTransition = transition
let iconPosition = self.iconPositions[index] let iconPosition = self.iconPositions[index]
let iconLayer: GiftIconLayer let iconLayer: GiftIconLayer
if let current = self.iconLayers[id] { if let current = self.iconLayers[id] {
iconLayer = current iconLayer = current
} else { } else {
iconTransition = .immediate
iconLayer = GiftIconLayer(context: component.context, gift: gift, size: iconSize, glowing: component.hasBackground) iconLayer = GiftIconLayer(context: component.context, gift: gift, size: iconSize, glowing: component.hasBackground)
iconLayer.startHovering() iconLayer.startHovering()
self.iconLayers[id] = iconLayer 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.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
iconLayer.animateScale(from: 0.01, 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 centerPosition = component.avatarCenter
let finalPosition = iconPosition.center.offsetBy(dx: component.avatarCenter.x, dy: component.avatarCenter.y) 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) let effectivePosition = interpolateRect(from: finalPosition, to: centerPosition, t: itemScaleFraction)
transition.setBounds(layer: iconLayer, bounds: CGRect(origin: .zero, size: iconSize)) iconTransition.setBounds(layer: iconLayer, bounds: CGRect(origin: .zero, size: iconSize))
transition.setPosition(layer: iconLayer, position: effectivePosition) iconTransition.setPosition(layer: iconLayer, position: effectivePosition)
transition.setScale(layer: iconLayer, scale: iconPosition.scale * (1.0 - itemScaleFraction)) iconTransition.setScale(layer: iconLayer, scale: iconPosition.scale * (1.0 - itemScaleFraction))
transition.setAlpha(layer: iconLayer, alpha: 1.0 - itemScaleFraction) iconTransition.setAlpha(layer: iconLayer, alpha: 1.0 - itemScaleFraction)
index += 1 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 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 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 randomValue = -randomFactor + CGFloat(self.rng.next()) * 2.0 * randomFactor
let finalScale = min(1.2, max(baseScale * 0.65, baseScale + randomValue)) 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) { func setup(color: UIColor, size: CGSize) {
self.color = color
let emitter = CAEmitterCell() let emitter = CAEmitterCell()
emitter.name = "emitter" emitter.name = "emitter"
emitter.contents = UIImage(bundleImageName: "Premium/Stars/Particle")?.cgImage emitter.contents = UIImage(bundleImageName: "Premium/Stars/Particle")?.cgImage
@ -586,8 +601,10 @@ private final class StarsEffectLayer: SimpleLayer {
self.emitterLayer.emitterCells = [emitter] self.emitterLayer.emitterCells = [emitter]
} }
private var color: UIColor?
func update(color: UIColor, size: CGSize) { func update(color: UIColor, size: CGSize) {
if self.emitterLayer.emitterCells == nil { if self.color != color {
self.setup(color: color, size: size) self.setup(color: color, size: size)
} }
self.emitterLayer.seed = UInt32.random(in: .min ..< .max) self.emitterLayer.seed = UInt32.random(in: .min ..< .max)
@ -604,7 +621,25 @@ private class GiftIconLayer: SimpleLayer {
private let context: AccountContext private let context: AccountContext
private let gift: ProfileGiftsContext.State.StarGift private let gift: ProfileGiftsContext.State.StarGift
private let size: CGSize 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 shadowLayer = SimpleLayer()
let starsLayer = StarsEffectLayer() let starsLayer = StarsEffectLayer()
@ -656,6 +691,7 @@ private class GiftIconLayer: SimpleLayer {
self.shadowLayer.contents = shadowImage?.cgImage self.shadowLayer.contents = shadowImage?.cgImage
self.shadowLayer.layerTintColor = color.cgColor self.shadowLayer.layerTintColor = color.cgColor
self.shadowLayer.opacity = glowing ? 1.0 : 0.0
self.context = context self.context = context
self.gift = gift self.gift = gift
@ -669,9 +705,7 @@ private class GiftIconLayer: SimpleLayer {
self.starsLayer.frame = starsFrame self.starsLayer.frame = starsFrame
self.starsLayer.update(color: glowing ? .white : color, size: starsFrame.size) 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.starsLayer)
self.addSublayer(self.animationLayer) self.addSublayer(self.animationLayer)
} }
@ -723,6 +757,7 @@ private class GiftIconLayer: SimpleLayer {
self.shadowLayer.contents = shadowImage?.cgImage self.shadowLayer.contents = shadowImage?.cgImage
self.shadowLayer.layerTintColor = color.cgColor self.shadowLayer.layerTintColor = color.cgColor
self.shadowLayer.opacity = glowing ? 1.0 : 0.0
super.init() super.init()
@ -731,9 +766,7 @@ private class GiftIconLayer: SimpleLayer {
self.starsLayer.frame = starsFrame self.starsLayer.frame = starsFrame
self.starsLayer.update(color: glowing ? .white : color, size: starsFrame.size) 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.starsLayer)
self.addSublayer(self.animationLayer) self.addSublayer(self.animationLayer)
} }

View File

@ -20,7 +20,7 @@ extension ChatControllerImpl {
completion(false) completion(false)
return 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 totalAmount = sendPaidMessageStars.value * Int64(count)
let _ = (ApplicationSpecificNotice.dismissedPaidMessageWarningNamespace(accountManager: self.context.sharedContext.accountManager, peerId: peer.id) let _ = (ApplicationSpecificNotice.dismissedPaidMessageWarningNamespace(accountManager: self.context.sharedContext.accountManager, peerId: peer.id)

View File

@ -2067,11 +2067,15 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}) })
} }
}, sendCurrentMessage: { [weak self] silentPosting, messageEffect in }, sendCurrentMessage: { [weak self] silentPosting, messageEffect in
if let strongSelf = self { if let self {
if let _ = strongSelf.presentationInterfaceState.interfaceState.mediaDraftState { if let _ = self.presentationInterfaceState.interfaceState.mediaDraftState {
strongSelf.sendMediaRecording(silentPosting: silentPosting, messageEffect: messageEffect) self.sendMediaRecording(silentPosting: silentPosting, messageEffect: messageEffect)
} else { } 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 }, sendMessage: { [weak self] text in

View File

@ -272,7 +272,7 @@ final class ChatTextInputActionButtonsNode: ASDisplayNode, ChatSendMessageAction
self.validLayout = size self.validLayout = size
var innerSize = 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.sendButton.imageNode.alpha = 0.0
self.textNode.isHidden = false self.textNode.isHidden = false

View File

@ -1915,7 +1915,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate, Ch
placeholder = interfaceState.strings.Conversation_InputTextAnonymousPlaceholder placeholder = interfaceState.strings.Conversation_InputTextAnonymousPlaceholder
} else if case let .replyThread(replyThreadMessage) = interfaceState.chatLocation, !replyThreadMessage.isForumPost, replyThreadMessage.peerId != self.context?.account.peerId { } else if case let .replyThread(replyThreadMessage) = interfaceState.chatLocation, !replyThreadMessage.isForumPost, replyThreadMessage.peerId != self.context?.account.peerId {
if replyThreadMessage.isChannelPost { 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 placeholder = interfaceState.strings.Chat_InputTextPaidCommentPlaceholder(" # \(presentationStringsFormattedNumber(Int32(sendPaidMessageStars.value), interfaceState.dateTimeFormat.groupingSeparator))").string
placeholderHasStar = true placeholderHasStar = true
} else { } else {
@ -1931,7 +1931,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate, Ch
placeholder = interfaceState.strings.Chat_InputPlaceholderMessageInTopic(forumTopicData.title).string placeholder = interfaceState.strings.Chat_InputPlaceholderMessageInTopic(forumTopicData.title).string
} }
} else { } 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 placeholder = interfaceState.strings.Chat_InputTextPaidMessagePlaceholder(" # \(presentationStringsFormattedNumber(Int32(sendPaidMessageStars.value), interfaceState.dateTimeFormat.groupingSeparator))").string
placeholderHasStar = true placeholderHasStar = true
} else { } else {