Various fixes

This commit is contained in:
Ilya Laktyushin 2025-03-12 18:57:22 +04:00
parent a67c0b41af
commit 369116767a
8 changed files with 82 additions and 49 deletions

View File

@ -4098,7 +4098,7 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
strongSelf.secretIconNode = iconNode
}
iconNode.image = currentSecretIconImage
transition.updateFrame(node: iconNode, frame: CGRect(origin: CGPoint(x: contentRect.origin.x, y: contentRect.origin.y + floor((titleLayout.size.height - currentSecretIconImage.size.height) / 2.0)), size: currentSecretIconImage.size))
transition.updateFrame(node: iconNode, frame: CGRect(origin: CGPoint(x: contentRect.origin.x + titleLeftOffset, y: contentRect.origin.y + floor((titleLayout.size.height - currentSecretIconImage.size.height) / 2.0)), size: currentSecretIconImage.size))
titleOffset += currentSecretIconImage.size.width + 3.0
} else if let secretIconNode = strongSelf.secretIconNode {
strongSelf.secretIconNode = nil

View File

@ -111,6 +111,7 @@ public final class PeerInfoCoverComponent: Component {
public let files: [Int64: TelegramMediaFile]
public let isDark: Bool
public let avatarCenter: CGPoint
public let avatarSize: CGSize
public let avatarScale: CGFloat
public let defaultHeight: CGFloat
public let gradientOnTop: Bool
@ -124,6 +125,7 @@ public final class PeerInfoCoverComponent: Component {
files: [Int64: TelegramMediaFile],
isDark: Bool,
avatarCenter: CGPoint,
avatarSize: CGSize = CGSize(width: 100.0, height: 100.0),
avatarScale: CGFloat,
defaultHeight: CGFloat,
gradientOnTop: Bool = false,
@ -136,6 +138,7 @@ public final class PeerInfoCoverComponent: Component {
self.files = files
self.isDark = isDark
self.avatarCenter = avatarCenter
self.avatarSize = avatarSize
self.avatarScale = avatarScale
self.defaultHeight = defaultHeight
self.gradientOnTop = gradientOnTop
@ -160,6 +163,9 @@ public final class PeerInfoCoverComponent: Component {
if lhs.avatarCenter != rhs.avatarCenter {
return false
}
if lhs.avatarSize != rhs.avatarSize {
return false
}
if lhs.avatarScale != rhs.avatarScale {
return false
}
@ -492,7 +498,7 @@ public final class PeerInfoCoverComponent: Component {
transition.containedViewLayoutTransition.updateFrameAdditive(view: self.backgroundPatternContainer, frame: backgroundPatternContainerFrame)
transition.setAlpha(view: self.backgroundPatternContainer, alpha: component.patternTransitionFraction)
var baseDistance: CGFloat = 72.0
var baseDistance: CGFloat = component.avatarSize.width / 2.0 + 22.0
var baseRowDistance: CGFloat = 28.0
var baseItemSize: CGFloat = 26.0
if availableSize.width <= 60.0 {
@ -516,7 +522,7 @@ public final class PeerInfoCoverComponent: Component {
let baseItemDistance: CGFloat = baseDistance + CGFloat(row) * baseRowDistance
let itemDistanceFraction = max(0.0, min(1.0, baseItemDistance / (baseDistance * 2.0)))
let itemScaleFraction = patternScaleValueAt(fraction: component.avatarTransitionFraction, t: itemDistanceFraction, reverse: false)
let itemScaleFraction = patternScaleValueAt(fraction: component.avatarTransitionFraction * 1.6, t: itemDistanceFraction, reverse: false)
let itemDistance = baseItemDistance * (1.0 - itemScaleFraction) + 20.0 * itemScaleFraction
var itemAngle: CGFloat

View File

@ -304,26 +304,28 @@ public final class PeerInfoGiftsCoverComponent: Component {
}
iconLayer.glowing = component.hasBackground
let centerPosition = component.avatarCenter
let finalPosition = iconPosition.center.offsetBy(dx: component.avatarCenter.x, dy: component.avatarCenter.y)
let itemScaleFraction = patternScaleValueAt(fraction: component.avatarTransitionFraction, t: 0.0, reverse: false)
let itemDistanceFraction = max(0.0, min(0.5, (iconPosition.distance - component.avatarSize.width / 2.0) / 144.0))
let itemScaleFraction = patternScaleValueAt(fraction: min(1.0, component.avatarTransitionFraction * 1.33), t: itemDistanceFraction, reverse: false)
func interpolateRect(from: CGPoint, to: CGPoint, t: CGFloat) -> CGPoint {
func interpolatePosition(from: PositionGenerator.Position, to: PositionGenerator.Position, t: CGFloat) -> PositionGenerator.Position {
let clampedT = max(0, min(1, t))
let interpolatedX = from.x + (to.x - from.x) * clampedT
let interpolatedY = from.y + (to.y - from.y) * clampedT
let interpolatedDistance = from.distance + (to.distance - from.distance) * clampedT
let interpolatedAngle = from.angle + (to.angle - from.angle) * clampedT
return CGPoint(
x: interpolatedX,
y: interpolatedY
)
return PositionGenerator.Position(distance: interpolatedDistance, angle: interpolatedAngle, scale: from.scale)
}
let effectivePosition = interpolateRect(from: finalPosition, to: centerPosition, t: itemScaleFraction)
let toAngle: CGFloat = .pi * 0.18
let centerPosition = PositionGenerator.Position(distance: 0.0, angle: iconPosition.angle + toAngle, scale: iconPosition.scale)
let effectivePosition = interpolatePosition(from: iconPosition, to: centerPosition, t: itemScaleFraction)
let effectiveAngle = toAngle * itemScaleFraction
let absolutePosition = getAbsolutePosition(position: effectivePosition, centerPoint: component.avatarCenter)
iconTransition.setBounds(layer: iconLayer, bounds: CGRect(origin: .zero, size: iconSize))
iconTransition.setPosition(layer: iconLayer, position: effectivePosition)
iconTransition.setPosition(layer: iconLayer, position: absolutePosition)
iconLayer.updateRotation(effectiveAngle, transition: iconTransition)
iconTransition.setScale(layer: iconLayer, scale: iconPosition.scale * (1.0 - itemScaleFraction))
iconTransition.setAlpha(layer: iconLayer, alpha: 1.0 - itemScaleFraction)
@ -586,7 +588,12 @@ private class GiftIconLayer: SimpleLayer {
override func layoutSublayers() {
self.shadowLayer.frame = CGRect(origin: .zero, size: self.bounds.size).insetBy(dx: -8.0, dy: -8.0)
self.animationLayer.frame = CGRect(origin: .zero, size: self.bounds.size)
self.animationLayer.bounds = CGRect(origin: .zero, size: self.bounds.size)
self.animationLayer.position = CGPoint(x: self.bounds.width / 2.0, y: self.bounds.height / 2.0)
}
func updateRotation(_ angle: CGFloat, transition: ComponentTransition) {
self.animationLayer.transform = CATransform3DMakeRotation(angle, 0.0, 0.0, 1.0)
}
func startAnimations(index: Int) {
@ -644,8 +651,16 @@ private class GiftIconLayer: SimpleLayer {
private struct PositionGenerator {
struct Position {
let center: CGPoint
let distance: CGFloat
let angle: CGFloat
let scale: CGFloat
var relativeCartesian: CGPoint {
return CGPoint(
x: self.distance * cos(self.angle),
y: self.distance * sin(self.angle)
)
}
}
let containerSize: CGSize
@ -706,15 +721,13 @@ private struct PositionGenerator {
let orbitRangeSize = self.innerOrbitRange.max - self.innerOrbitRange.min
let orbitDistanceFactor = self.innerOrbitRange.min + orbitRangeSize * CGFloat(self.lokiRng.next())
let orbitDistance = orbitDistanceFactor * centerRadius
let distance = orbitDistanceFactor * centerRadius
let angleRange: CGFloat = placeOnLeftSide ? .pi : .pi
let angleOffset: CGFloat = placeOnLeftSide ? .pi/2 : -(.pi/2)
let angle = angleOffset + angleRange * CGFloat(self.lokiRng.next())
let absoluteX = centerPoint.x + orbitDistance * cos(angle)
let absoluteY = centerPoint.y + orbitDistance * sin(angle)
let absolutePosition = CGPoint(x: absoluteX, y: absoluteY)
let absolutePosition = getAbsolutePosition(distance: distance, angle: angle, centerPoint: centerPoint)
if absolutePosition.x - itemSize.width/2 < self.edgePadding ||
absolutePosition.x + itemSize.width/2 > self.containerSize.width - self.edgePadding ||
@ -723,11 +736,6 @@ private struct PositionGenerator {
continue
}
let relativePosition = CGPoint(
x: absolutePosition.x - centerPoint.x,
y: absolutePosition.y - centerPoint.y
)
let itemRect = CGRect(
x: absolutePosition.x - itemSize.width/2,
y: absolutePosition.y - itemSize.height/2,
@ -735,10 +743,12 @@ private struct PositionGenerator {
height: itemSize.height
)
if self.isValidPosition(itemRect, existingPositions: positions.map { self.posToAbsolute($0.center, centerPoint: centerPoint) }, itemSize: itemSize) {
if self.isValidPosition(itemRect, existingPositions: positions.map {
getAbsolutePosition(distance: $0.distance, angle: $0.angle, centerPoint: centerPoint)
}, itemSize: itemSize) {
let scaleRangeSize = max(self.scaleRange.min + 0.1, 0.75) - self.scaleRange.max
let scale = self.scaleRange.max + scaleRangeSize * CGFloat(self.lokiRng.next())
positions.append(Position(center: relativePosition, scale: scale))
positions.append(Position(distance: distance, angle: angle, scale: scale))
if absolutePosition.x < centerPoint.x {
leftPositions += 1
@ -757,16 +767,13 @@ private struct PositionGenerator {
let orbitRangeSize = self.outerOrbitRange.max - self.outerOrbitRange.min
let orbitDistanceFactor = self.outerOrbitRange.min + orbitRangeSize * CGFloat(self.lokiRng.next())
let orbitDistance = orbitDistanceFactor * centerRadius
let distance = orbitDistanceFactor * centerRadius
let angleRange: CGFloat = placeOnLeftSide ? .pi : .pi
let angleOffset: CGFloat = placeOnLeftSide ? .pi/2 : -(.pi/2)
let angle = angleOffset + angleRange * CGFloat(self.lokiRng.next())
let absoluteX = centerPoint.x + orbitDistance * cos(angle)
let absoluteY = centerPoint.y + orbitDistance * sin(angle)
let absolutePosition = CGPoint(x: absoluteX, y: absoluteY)
let absolutePosition = getAbsolutePosition(distance: distance, angle: angle, centerPoint: centerPoint)
if absolutePosition.x - itemSize.width/2 < self.edgePadding ||
absolutePosition.x + itemSize.width/2 > self.containerSize.width - self.edgePadding ||
absolutePosition.y - itemSize.height/2 < self.edgePadding ||
@ -774,11 +781,6 @@ private struct PositionGenerator {
continue
}
let relativePosition = CGPoint(
x: absolutePosition.x - centerPoint.x,
y: absolutePosition.y - centerPoint.y
)
let itemRect = CGRect(
x: absolutePosition.x - itemSize.width/2,
y: absolutePosition.y - itemSize.height/2,
@ -786,12 +788,12 @@ private struct PositionGenerator {
height: itemSize.height
)
if self.isValidPosition(itemRect, existingPositions: positions.map { self.posToAbsolute($0.center, centerPoint: centerPoint) }, itemSize: itemSize) {
let distance = hypot(absolutePosition.x - centerPoint.x, absolutePosition.y - centerPoint.y)
if self.isValidPosition(itemRect, existingPositions: positions.map {
getAbsolutePosition(distance: $0.distance, angle: $0.angle, centerPoint: centerPoint)
}, itemSize: itemSize) {
let normalizedDistance = min(distance / maxPossibleDistance, 1.0)
let scale = self.scaleRange.max - normalizedDistance * (self.scaleRange.max - self.scaleRange.min)
positions.append(Position(center: relativePosition, scale: scale))
positions.append(Position(distance: distance, angle: angle, scale: scale))
if absolutePosition.x < centerPoint.x {
leftPositions += 1
@ -804,8 +806,11 @@ private struct PositionGenerator {
return positions
}
private func posToAbsolute(_ relativePos: CGPoint, centerPoint: CGPoint) -> CGPoint {
return CGPoint(x: relativePos.x + centerPoint.x, y: relativePos.y + centerPoint.y)
func getAbsolutePosition(distance: CGFloat, angle: CGFloat, centerPoint: CGPoint) -> CGPoint {
return CGPoint(
x: centerPoint.x + distance * cos(angle),
y: centerPoint.y + distance * sin(angle)
)
}
private func isValidPosition(_ rect: CGRect, existingPositions: [CGPoint], itemSize: CGSize) -> Bool {
@ -833,6 +838,20 @@ private struct PositionGenerator {
}
}
private func getAbsolutePosition(position: PositionGenerator.Position, centerPoint: CGPoint) -> CGPoint {
return CGPoint(
x: centerPoint.x + position.distance * cos(position.angle),
y: centerPoint.y + position.distance * sin(position.angle)
)
}
private func getAbsolutePosition(distance: CGFloat, angle: CGFloat, centerPoint: CGPoint) -> CGPoint {
return CGPoint(
x: centerPoint.x + distance * cos(angle),
y: centerPoint.y + distance * sin(angle)
)
}
private func windowFunction(t: CGFloat) -> CGFloat {
return bezierPoint(0.6, 0.0, 0.4, 1.0, t)
}

View File

@ -74,6 +74,7 @@ final class PeerInfoHeaderNavigationButtonContainerNode: SparseNode {
func update(size: CGSize, presentationData: PresentationData, leftButtons: [PeerInfoHeaderNavigationButtonSpec], rightButtons: [PeerInfoHeaderNavigationButtonSpec], expandFraction: CGFloat, shouldAnimateIn: Bool, transition: ContainedViewLayoutTransition) {
let sideInset: CGFloat = 24.0
let expandedSideInset: CGFloat = 16.0
let maximumExpandOffset: CGFloat = 14.0
let expandOffset: CGFloat = -expandFraction * maximumExpandOffset
@ -188,7 +189,7 @@ final class PeerInfoHeaderNavigationButtonContainerNode: SparseNode {
self.currentRightButtons = rightButtons
var nextRegularButtonOrigin = size.width - sideInset - 8.0
var nextExpandedButtonOrigin = size.width - sideInset - 8.0
var nextExpandedButtonOrigin = size.width - expandedSideInset
for spec in rightButtons.reversed() {
let buttonNode: PeerInfoHeaderNavigationButton
var wasAdded = false
@ -268,7 +269,7 @@ final class PeerInfoHeaderNavigationButtonContainerNode: SparseNode {
}
} else {
var nextRegularButtonOrigin = size.width - sideInset - 8.0
var nextExpandedButtonOrigin = size.width - sideInset - 8.0
var nextExpandedButtonOrigin = size.width - expandedSideInset
for spec in rightButtons.reversed() {
var key = spec.key

View File

@ -2311,6 +2311,7 @@ final class PeerInfoHeaderNode: ASDisplayNode {
files: [:],
isDark: presentationData.theme.overallDarkAppearance,
avatarCenter: apparentAvatarFrame.center.offsetBy(dx: bannerInset, dy: 0.0),
avatarSize: apparentAvatarFrame.size,
avatarScale: avatarScale,
defaultHeight: backgroundDefaultHeight,
gradientCenter: CGPoint(x: 0.5, y: buttonKeys.isEmpty ? 0.5 : 0.45),

View File

@ -379,7 +379,7 @@ public final class PeerInfoGiftsPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScr
let optionSpacing: CGFloat = 10.0
let itemsSideInset = params.sideInset + 16.0
let defaultItemsInRow = params.size.width > params.size.height ? 5 : 3
let defaultItemsInRow = params.size.width > params.size.height || params.size.width > 414.0 ? 5 : 3
let itemsInRow = max(1, min(starsProducts.count, defaultItemsInRow))
let defaultOptionWidth = (params.size.width - itemsSideInset * 2.0 - optionSpacing * CGFloat(defaultItemsInRow - 1)) / CGFloat(defaultItemsInRow)
let optionWidth = (params.size.width - itemsSideInset * 2.0 - optionSpacing * CGFloat(itemsInRow - 1)) / CGFloat(itemsInRow)
@ -613,7 +613,7 @@ public final class PeerInfoGiftsPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScr
}
var bottomScrollInset: CGFloat = 0.0
var contentHeight = ceil(CGFloat(starsProducts.count) / 3.0) * (starsOptionSize.height + optionSpacing) - optionSpacing + topInset + 16.0
var contentHeight = ceil(CGFloat(starsProducts.count) / CGFloat(defaultItemsInRow)) * (starsOptionSize.height + optionSpacing) - optionSpacing + topInset + 16.0
let size = params.size
let sideInset = params.sideInset

View File

@ -5786,7 +5786,10 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
if case let .known(value) = cachedData.businessIntro {
businessIntro = value
}
sendPaidMessageStars = cachedData.sendPaidMessageStars
if case let .peer(peerId) = chatLocation, peerId.namespace == Namespaces.Peer.SecretChat {
} else {
sendPaidMessageStars = cachedData.sendPaidMessageStars
}
} else if let cachedData = peerView.cachedData as? CachedGroupData {
var invitedBy: Peer?
if let invitedByPeerId = cachedData.invitedBy {

View File

@ -2232,6 +2232,9 @@ public final class WebAppController: ViewController, AttachmentContainable {
self.webView?.sendEvent(name: "fullscreen_changed", data: paramsString)
controller.isFullscreen = isFullscreen
if isFullscreen {
controller.requestAttachmentMenuExpansion()
}
if let (layout, _) = self.validLayout, case .regular = layout.metrics.widthClass {
if let snapshotView = self.webView?.snapshotView(afterScreenUpdates: false) {