Merge branch 'beta'

This commit is contained in:
Isaac 2025-04-17 23:57:25 +04:00
commit b484d03de6
7 changed files with 134 additions and 58 deletions

View File

@ -412,8 +412,8 @@ class CallListCallItemNode: ItemListRevealOptionsItemNode {
} else if case let .conferenceCall(conferenceCall) = action.action { } else if case let .conferenceCall(conferenceCall) = action.action {
isConference = true isConference = true
if let peer = message.author, !conferenceAvatars.contains(where: { $0.id == peer.id }) { if let peer = message.peers[message.id.peerId], !conferenceAvatars.contains(where: { $0.id == peer.id }) {
conferenceAvatars.append(peer) conferenceAvatars.append(EnginePeer(peer))
} }
for id in conferenceCall.otherParticipants { for id in conferenceCall.otherParticipants {

View File

@ -13,6 +13,7 @@ swift_library(
"//submodules/AsyncDisplayKit:AsyncDisplayKit", "//submodules/AsyncDisplayKit:AsyncDisplayKit",
"//submodules/Display:Display", "//submodules/Display:Display",
"//submodules/TelegramPresentationData:TelegramPresentationData", "//submodules/TelegramPresentationData:TelegramPresentationData",
"//submodules/ComponentFlow",
], ],
visibility = [ visibility = [
"//visibility:public", "//visibility:public",

View File

@ -3,6 +3,7 @@ import UIKit
import Display import Display
import AsyncDisplayKit import AsyncDisplayKit
import TelegramPresentationData import TelegramPresentationData
import ComponentFlow
public struct CounterControllerTitle: Equatable { public struct CounterControllerTitle: Equatable {
public var title: String public var title: String
@ -16,24 +17,28 @@ public struct CounterControllerTitle: Equatable {
public final class CounterControllerTitleView: UIView { public final class CounterControllerTitleView: UIView {
private let titleNode: ImmediateTextNode private let titleNode: ImmediateTextNode
private let subtitleNode: ImmediateTextNode
private var subtitleNode: ImmediateTextNode
private var disappearingSubtitleNode: ImmediateTextNode?
public var title: CounterControllerTitle = CounterControllerTitle(title: "", counter: nil) { public var title: CounterControllerTitle = CounterControllerTitle(title: "", counter: nil) {
didSet { didSet {
if self.title != oldValue { if self.title != oldValue {
self.update() self.update(animated: oldValue.title.isEmpty == self.title.title.isEmpty)
} }
} }
} }
public var theme: PresentationTheme { public var theme: PresentationTheme {
didSet { didSet {
self.update() self.update(animated: false)
} }
} }
private var primaryTextColor: UIColor? private var primaryTextColor: UIColor?
private var secondaryTextColor: UIColor? private var secondaryTextColor: UIColor?
private var nextLayoutTransition: ContainedViewLayoutTransition?
public func updateTextColors(primary: UIColor?, secondary: UIColor?, transition: ContainedViewLayoutTransition) { public func updateTextColors(primary: UIColor?, secondary: UIColor?, transition: ContainedViewLayoutTransition) {
self.primaryTextColor = primary self.primaryTextColor = primary
@ -52,18 +57,40 @@ public final class CounterControllerTitleView: UIView {
} }
} }
self.update() self.update(animated: false)
} }
private func update() { private func update(animated: Bool) {
let primaryTextColor = self.primaryTextColor ?? self.theme.rootController.navigationBar.primaryTextColor let primaryTextColor = self.primaryTextColor ?? self.theme.rootController.navigationBar.primaryTextColor
let secondaryTextColor = self.secondaryTextColor ?? self.theme.rootController.navigationBar.secondaryTextColor let secondaryTextColor = self.secondaryTextColor ?? self.theme.rootController.navigationBar.secondaryTextColor
self.titleNode.attributedText = NSAttributedString(string: self.title.title, font: Font.semibold(17.0), textColor: primaryTextColor) self.titleNode.attributedText = NSAttributedString(string: self.title.title, font: Font.semibold(17.0), textColor: primaryTextColor)
self.subtitleNode.attributedText = NSAttributedString(string: self.title.counter ?? "", font: Font.with(size: 13.0, traits: .monospacedNumbers), textColor: secondaryTextColor)
let subtitleText = NSAttributedString(string: self.title.counter ?? "", font: Font.with(size: 13.0, traits: .monospacedNumbers), textColor: secondaryTextColor)
if let previousSubtitleText = self.subtitleNode.attributedText, previousSubtitleText.string.isEmpty != subtitleText.string.isEmpty && subtitleText.string.isEmpty {
if let disappearingSubtitleNode = self.disappearingSubtitleNode {
self.disappearingSubtitleNode = nil
disappearingSubtitleNode.removeFromSupernode()
}
self.disappearingSubtitleNode = self.subtitleNode
self.subtitleNode = ImmediateTextNode()
self.subtitleNode.displaysAsynchronously = false
self.subtitleNode.maximumNumberOfLines = 1
self.subtitleNode.truncationType = .end
self.subtitleNode.isOpaque = false
self.subtitleNode.attributedText = subtitleText
self.addSubnode(self.subtitleNode)
} else {
self.subtitleNode.attributedText = subtitleText
}
self.accessibilityLabel = self.title.title self.accessibilityLabel = self.title.title
self.accessibilityValue = self.title.counter self.accessibilityValue = self.title.counter
if animated {
self.nextLayoutTransition = .animated(duration: 0.4, curve: .spring)
}
self.setNeedsLayout() self.setNeedsLayout()
} }
@ -110,11 +137,31 @@ public final class CounterControllerTitleView: UIView {
} else { } else {
combinedHeight = titleSize.height combinedHeight = titleSize.height
} }
var transition: ContainedViewLayoutTransition = .immediate
if let nextLayoutTransition = self.nextLayoutTransition {
if !self.titleNode.bounds.isEmpty {
transition = nextLayoutTransition
}
self.nextLayoutTransition = nil
}
let titleFrame = CGRect(origin: CGPoint(x: floor((size.width - titleSize.width) / 2.0), y: floor((size.height - combinedHeight) / 2.0)), size: titleSize) let titleFrame = CGRect(origin: CGPoint(x: floor((size.width - titleSize.width) / 2.0), y: floor((size.height - combinedHeight) / 2.0)), size: titleSize)
self.titleNode.frame = titleFrame self.titleNode.bounds = CGRect(origin: CGPoint(), size: titleFrame.size)
transition.updatePosition(node: self.titleNode, position: titleFrame.center)
let subtitleFrame = CGRect(origin: CGPoint(x: floor((size.width - subtitleSize.width) / 2.0), y: floor((size.height - combinedHeight) / 2.0) + titleSize.height + spacing), size: subtitleSize) let subtitleFrame = CGRect(origin: CGPoint(x: floor((size.width - subtitleSize.width) / 2.0), y: floor((size.height - combinedHeight) / 2.0) + titleSize.height + spacing), size: subtitleSize)
self.subtitleNode.frame = subtitleFrame self.subtitleNode.bounds = CGRect(origin: CGPoint(), size: subtitleFrame.size)
transition.updatePosition(node: self.subtitleNode, position: subtitleFrame.center)
transition.updateTransformScale(node: self.subtitleNode, scale: self.title.counter != nil ? 1.0 : 0.001)
transition.updateAlpha(node: self.subtitleNode, alpha: self.title.counter != nil ? 1.0 : 0.0)
if let disappearingSubtitleNode = self.disappearingSubtitleNode {
transition.updatePosition(node: disappearingSubtitleNode, position: subtitleFrame.center)
transition.updateTransformScale(node: disappearingSubtitleNode, scale: self.title.counter != nil ? 1.0 : 0.001)
transition.updateAlpha(node: disappearingSubtitleNode, alpha: self.title.counter != nil ? 1.0 : 0.0, completion: { [weak disappearingSubtitleNode] _ in
disappearingSubtitleNode?.removeFromSupernode()
})
}
} }
} }

View File

@ -65,58 +65,75 @@ private func stringForCallType(message: Message, strings: PresentationStrings) -
var string = "" var string = ""
for media in message.media { for media in message.media {
switch media { switch media {
case let action as TelegramMediaAction: case let action as TelegramMediaAction:
switch action.action { switch action.action {
case let .phoneCall(_, discardReason, _, isVideo): case let .phoneCall(_, discardReason, _, isVideo):
let incoming = message.flags.contains(.Incoming) let incoming = message.flags.contains(.Incoming)
if let discardReason = discardReason { if let discardReason = discardReason {
switch discardReason { switch discardReason {
case .disconnect: case .disconnect:
if isVideo { if isVideo {
string = strings.Notification_VideoCallCanceled string = strings.Notification_VideoCallCanceled
} else { } else {
string = strings.Notification_CallCanceled string = strings.Notification_CallCanceled
}
case .missed, .busy:
if incoming {
if isVideo {
string = strings.Notification_VideoCallMissed
} else {
string = strings.Notification_CallMissed
}
} else {
if isVideo {
string = strings.Notification_VideoCallCanceled
} else {
string = strings.Notification_CallCanceled
}
}
case .hangup:
break
}
} }
case .missed, .busy:
if string.isEmpty { if incoming {
if incoming { if isVideo {
if isVideo { string = strings.Notification_VideoCallMissed
string = strings.Notification_VideoCallIncoming
} else {
string = strings.Notification_CallIncoming
}
} else { } else {
if isVideo { string = strings.Notification_CallMissed
string = strings.Notification_VideoCallOutgoing }
} else { } else {
string = strings.Notification_CallOutgoing if isVideo {
} string = strings.Notification_VideoCallCanceled
} else {
string = strings.Notification_CallCanceled
} }
} }
default: case .hangup:
break break
}
}
if string.isEmpty {
if incoming {
if isVideo {
string = strings.Notification_VideoCallIncoming
} else {
string = strings.Notification_CallIncoming
}
} else {
if isVideo {
string = strings.Notification_VideoCallOutgoing
} else {
string = strings.Notification_CallOutgoing
}
}
}
case let .conferenceCall(conferenceCall):
let incoming = message.flags.contains(.Incoming)
let missedTimeout: Int32 = 30
let currentTime = Int32(Date().timeIntervalSince1970)
if conferenceCall.flags.contains(.isMissed) {
string = strings.Chat_CallMessage_DeclinedGroupCall
} else if conferenceCall.duration == nil && message.timestamp < currentTime - missedTimeout {
string = strings.Chat_CallMessage_MissedGroupCall
} else {
if incoming {
string = strings.Chat_CallMessage_IncomingGroupCall
} else {
string = strings.Chat_CallMessage_OutgoingGroupCall
}
} }
default: default:
break break
}
default:
break
} }
} }
return string return string

View File

@ -2373,9 +2373,6 @@ public final class AccountViewTracker {
}() }()
let groupingPredicate: (Message, Message) -> Bool = { lhs, rhs in let groupingPredicate: (Message, Message) -> Bool = { lhs, rhs in
if lhs.id.peerId != rhs.id.peerId {
return false
}
let lhsTimestamp = ((lhs.timestamp + timezoneOffset) / (granularity)) * (granularity) let lhsTimestamp = ((lhs.timestamp + timezoneOffset) / (granularity)) * (granularity)
let rhsTimestamp = ((rhs.timestamp + timezoneOffset) / (granularity)) * (granularity) let rhsTimestamp = ((rhs.timestamp + timezoneOffset) / (granularity)) * (granularity)
if lhsTimestamp != rhsTimestamp { if lhsTimestamp != rhsTimestamp {
@ -2400,6 +2397,7 @@ public final class AccountViewTracker {
} }
} }
} }
var rhsVideo = false var rhsVideo = false
var rhsMissed = false var rhsMissed = false
var rhsOther = false var rhsOther = false
@ -2422,6 +2420,14 @@ public final class AccountViewTracker {
if lhsMissed != rhsMissed || lhsOther != rhsOther || lhsVideo != rhsVideo || lhsConferenceId != rhsConferenceId { if lhsMissed != rhsMissed || lhsOther != rhsOther || lhsVideo != rhsVideo || lhsConferenceId != rhsConferenceId {
return false return false
} }
if lhsConferenceId != nil && rhsConferenceId != nil {
} else {
if lhs.id.peerId != rhs.id.peerId {
return false
}
}
return true return true
} }

View File

@ -37,6 +37,11 @@ func _internal_createGroup(account: Account, title: String, peerIds: [PeerId], t
} }
} }
var ttlPeriod = ttlPeriod
if ttlPeriod == nil {
ttlPeriod = 0
}
var flags: Int32 = 0 var flags: Int32 = 0
if let _ = ttlPeriod { if let _ = ttlPeriod {
flags |= 1 << 0 flags |= 1 << 0

@ -1 +1 @@
Subproject commit ea93dec2c8910197681ae785fd05a864e27d3db9 Subproject commit 79d6b6612bdf06d5b1744937846aa2a4286886a7