mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-03 05:03:45 +00:00
Merge commit 'a91658373baee67ebcef073a68b21b87787ca6eb'
This commit is contained in:
commit
73b67e9a4e
@ -217,9 +217,9 @@ public enum DeviceMetrics: CaseIterable, Equatable {
|
||||
case .iPhone14Pro, .iPhone14ProMax:
|
||||
return 55.0
|
||||
case .iPhone16Pro, .iPhone16ProMax:
|
||||
return 55.0
|
||||
return 62.0
|
||||
case .iPhoneAir:
|
||||
return 55.0
|
||||
return 62.0
|
||||
case let .unknown(_, _, _, screenCornerRadius):
|
||||
return screenCornerRadius
|
||||
default:
|
||||
|
||||
@ -965,7 +965,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
||||
dict[1124938064] = { return Api.SponsoredMessageReportOption.parse_sponsoredMessageReportOption($0) }
|
||||
dict[-963180333] = { return Api.SponsoredPeer.parse_sponsoredPeer($0) }
|
||||
dict[-2136190013] = { return Api.StarGift.parse_starGift($0) }
|
||||
dict[973640632] = { return Api.StarGift.parse_starGiftUnique($0) }
|
||||
dict[-1329630181] = { return Api.StarGift.parse_starGiftUnique($0) }
|
||||
dict[-650279524] = { return Api.StarGiftAttribute.parse_starGiftAttributeBackdrop($0) }
|
||||
dict[970559507] = { return Api.StarGiftAttribute.parse_starGiftAttributeModel($0) }
|
||||
dict[-524291476] = { return Api.StarGiftAttribute.parse_starGiftAttributeOriginalDetails($0) }
|
||||
|
||||
@ -289,7 +289,7 @@ public extension Api {
|
||||
public extension Api {
|
||||
enum StarGift: TypeConstructorDescription {
|
||||
case starGift(flags: Int32, id: Int64, sticker: Api.Document, stars: Int64, availabilityRemains: Int32?, availabilityTotal: Int32?, availabilityResale: Int64?, convertStars: Int64, firstSaleDate: Int32?, lastSaleDate: Int32?, upgradeStars: Int64?, resellMinStars: Int64?, title: String?, releasedBy: Api.Peer?, perUserTotal: Int32?, perUserRemains: Int32?, lockedUntilDate: Int32?)
|
||||
case starGiftUnique(flags: Int32, id: Int64, giftId: Int64, title: String, slug: String, num: Int32, ownerId: Api.Peer?, ownerName: String?, ownerAddress: String?, attributes: [Api.StarGiftAttribute], availabilityIssued: Int32, availabilityTotal: Int32, giftAddress: String?, resellAmount: [Api.StarsAmount]?, releasedBy: Api.Peer?, valueAmount: Int64?, valueCurrency: String?, themePeer: Api.Peer?, peerColor: Api.PeerColor?)
|
||||
case starGiftUnique(flags: Int32, id: Int64, giftId: Int64, title: String, slug: String, num: Int32, ownerId: Api.Peer?, ownerName: String?, ownerAddress: String?, attributes: [Api.StarGiftAttribute], availabilityIssued: Int32, availabilityTotal: Int32, giftAddress: String?, resellAmount: [Api.StarsAmount]?, releasedBy: Api.Peer?, valueAmount: Int64?, valueCurrency: String?, themePeer: Api.Peer?, peerColor: Api.PeerColor?, hostId: Api.Peer?)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
@ -315,9 +315,9 @@ public extension Api {
|
||||
if Int(flags) & Int(1 << 8) != 0 {serializeInt32(perUserRemains!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 9) != 0 {serializeInt32(lockedUntilDate!, buffer: buffer, boxed: false)}
|
||||
break
|
||||
case .starGiftUnique(let flags, let id, let giftId, let title, let slug, let num, let ownerId, let ownerName, let ownerAddress, let attributes, let availabilityIssued, let availabilityTotal, let giftAddress, let resellAmount, let releasedBy, let valueAmount, let valueCurrency, let themePeer, let peerColor):
|
||||
case .starGiftUnique(let flags, let id, let giftId, let title, let slug, let num, let ownerId, let ownerName, let ownerAddress, let attributes, let availabilityIssued, let availabilityTotal, let giftAddress, let resellAmount, let releasedBy, let valueAmount, let valueCurrency, let themePeer, let peerColor, let hostId):
|
||||
if boxed {
|
||||
buffer.appendInt32(973640632)
|
||||
buffer.appendInt32(-1329630181)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt64(id, buffer: buffer, boxed: false)
|
||||
@ -346,6 +346,7 @@ public extension Api {
|
||||
if Int(flags) & Int(1 << 8) != 0 {serializeString(valueCurrency!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 10) != 0 {themePeer!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 11) != 0 {peerColor!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 12) != 0 {hostId!.serialize(buffer, true)}
|
||||
break
|
||||
}
|
||||
}
|
||||
@ -354,8 +355,8 @@ public extension Api {
|
||||
switch self {
|
||||
case .starGift(let flags, let id, let sticker, let stars, let availabilityRemains, let availabilityTotal, let availabilityResale, let convertStars, let firstSaleDate, let lastSaleDate, let upgradeStars, let resellMinStars, let title, let releasedBy, let perUserTotal, let perUserRemains, let lockedUntilDate):
|
||||
return ("starGift", [("flags", flags as Any), ("id", id as Any), ("sticker", sticker as Any), ("stars", stars as Any), ("availabilityRemains", availabilityRemains as Any), ("availabilityTotal", availabilityTotal as Any), ("availabilityResale", availabilityResale as Any), ("convertStars", convertStars as Any), ("firstSaleDate", firstSaleDate as Any), ("lastSaleDate", lastSaleDate as Any), ("upgradeStars", upgradeStars as Any), ("resellMinStars", resellMinStars as Any), ("title", title as Any), ("releasedBy", releasedBy as Any), ("perUserTotal", perUserTotal as Any), ("perUserRemains", perUserRemains as Any), ("lockedUntilDate", lockedUntilDate as Any)])
|
||||
case .starGiftUnique(let flags, let id, let giftId, let title, let slug, let num, let ownerId, let ownerName, let ownerAddress, let attributes, let availabilityIssued, let availabilityTotal, let giftAddress, let resellAmount, let releasedBy, let valueAmount, let valueCurrency, let themePeer, let peerColor):
|
||||
return ("starGiftUnique", [("flags", flags as Any), ("id", id as Any), ("giftId", giftId as Any), ("title", title as Any), ("slug", slug as Any), ("num", num as Any), ("ownerId", ownerId as Any), ("ownerName", ownerName as Any), ("ownerAddress", ownerAddress as Any), ("attributes", attributes as Any), ("availabilityIssued", availabilityIssued as Any), ("availabilityTotal", availabilityTotal as Any), ("giftAddress", giftAddress as Any), ("resellAmount", resellAmount as Any), ("releasedBy", releasedBy as Any), ("valueAmount", valueAmount as Any), ("valueCurrency", valueCurrency as Any), ("themePeer", themePeer as Any), ("peerColor", peerColor as Any)])
|
||||
case .starGiftUnique(let flags, let id, let giftId, let title, let slug, let num, let ownerId, let ownerName, let ownerAddress, let attributes, let availabilityIssued, let availabilityTotal, let giftAddress, let resellAmount, let releasedBy, let valueAmount, let valueCurrency, let themePeer, let peerColor, let hostId):
|
||||
return ("starGiftUnique", [("flags", flags as Any), ("id", id as Any), ("giftId", giftId as Any), ("title", title as Any), ("slug", slug as Any), ("num", num as Any), ("ownerId", ownerId as Any), ("ownerName", ownerName as Any), ("ownerAddress", ownerAddress as Any), ("attributes", attributes as Any), ("availabilityIssued", availabilityIssued as Any), ("availabilityTotal", availabilityTotal as Any), ("giftAddress", giftAddress as Any), ("resellAmount", resellAmount as Any), ("releasedBy", releasedBy as Any), ("valueAmount", valueAmount as Any), ("valueCurrency", valueCurrency as Any), ("themePeer", themePeer as Any), ("peerColor", peerColor as Any), ("hostId", hostId as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
@ -473,6 +474,10 @@ public extension Api {
|
||||
if Int(_1!) & Int(1 << 11) != 0 {if let signature = reader.readInt32() {
|
||||
_19 = Api.parse(reader, signature: signature) as? Api.PeerColor
|
||||
} }
|
||||
var _20: Api.Peer?
|
||||
if Int(_1!) & Int(1 << 12) != 0 {if let signature = reader.readInt32() {
|
||||
_20 = Api.parse(reader, signature: signature) as? Api.Peer
|
||||
} }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
@ -492,8 +497,9 @@ public extension Api {
|
||||
let _c17 = (Int(_1!) & Int(1 << 8) == 0) || _17 != nil
|
||||
let _c18 = (Int(_1!) & Int(1 << 10) == 0) || _18 != nil
|
||||
let _c19 = (Int(_1!) & Int(1 << 11) == 0) || _19 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 && _c16 && _c17 && _c18 && _c19 {
|
||||
return Api.StarGift.starGiftUnique(flags: _1!, id: _2!, giftId: _3!, title: _4!, slug: _5!, num: _6!, ownerId: _7, ownerName: _8, ownerAddress: _9, attributes: _10!, availabilityIssued: _11!, availabilityTotal: _12!, giftAddress: _13, resellAmount: _14, releasedBy: _15, valueAmount: _16, valueCurrency: _17, themePeer: _18, peerColor: _19)
|
||||
let _c20 = (Int(_1!) & Int(1 << 12) == 0) || _20 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 && _c16 && _c17 && _c18 && _c19 && _c20 {
|
||||
return Api.StarGift.starGiftUnique(flags: _1!, id: _2!, giftId: _3!, title: _4!, slug: _5!, num: _6!, ownerId: _7, ownerName: _8, ownerAddress: _9, attributes: _10!, availabilityIssued: _11!, availabilityTotal: _12!, giftAddress: _13, resellAmount: _14, releasedBy: _15, valueAmount: _16, valueCurrency: _17, themePeer: _18, peerColor: _19, hostId: _20)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
|
||||
@ -520,9 +520,10 @@ final class VideoChatMicButtonComponent: Component {
|
||||
var titleFrame = CGRect(origin: CGPoint(x: floor((size.width - titleSize.width) * 0.5), y: size.height + 16.0), size: titleSize)
|
||||
if component.isCompact {
|
||||
titleFrame.origin.y -= 11.0
|
||||
}
|
||||
if subtitleText != nil {
|
||||
titleFrame.origin.y -= 5.0
|
||||
} else {
|
||||
if subtitleText != nil {
|
||||
titleFrame.origin.y -= 5.0
|
||||
}
|
||||
}
|
||||
if let titleView = self.title.view {
|
||||
if titleView.superview == nil {
|
||||
|
||||
@ -2034,7 +2034,7 @@ final class VideoChatParticipantsComponent: Component {
|
||||
} else {
|
||||
let step: CGFloat = CGFloat(i - firstStep) / CGFloat(numSteps - firstStep - 1)
|
||||
let value: CGFloat = 1.0 - Display.bezierPoint(0.42, 0.0, 0.58, 1.0, step)
|
||||
return UIColor(white: 0.0, alpha: baseGradientAlpha * value).multipliedWith(.red)
|
||||
return UIColor(white: 0.0, alpha: baseGradientAlpha * value)
|
||||
}
|
||||
}
|
||||
let locations = (0 ..< numSteps).map { i -> CGFloat in
|
||||
|
||||
@ -2206,7 +2206,7 @@ final class VideoChatScreenComponent: Component {
|
||||
|
||||
let landscapeControlsWidth: CGFloat = 104.0
|
||||
var landscapeControlsOffsetX: CGFloat = 0.0
|
||||
let landscapeControlsSpacing: CGFloat = 30.0
|
||||
let landscapeControlsSpacing: CGFloat = 20.0
|
||||
|
||||
var leftInset: CGFloat = max(environment.safeInsets.left, 16.0)
|
||||
|
||||
@ -2554,11 +2554,58 @@ final class VideoChatScreenComponent: Component {
|
||||
self.encryptionKeyBackground = nil
|
||||
}
|
||||
|
||||
let videoButtonContent: VideoChatActionButtonComponent.Content?
|
||||
let videoControlButtonContent: VideoChatActionButtonComponent.Content
|
||||
|
||||
var buttonAudio: VideoChatActionButtonComponent.Content.Audio = .speaker
|
||||
var buttonIsEnabled = false
|
||||
if let (availableOutputs, maybeCurrentOutput) = self.audioOutputState, let currentOutput = maybeCurrentOutput {
|
||||
buttonIsEnabled = availableOutputs.count > 1
|
||||
switch currentOutput {
|
||||
case .builtin:
|
||||
buttonAudio = .builtin
|
||||
case .speaker:
|
||||
buttonAudio = .speaker
|
||||
case .headphones:
|
||||
buttonAudio = .headphones
|
||||
case let .port(port):
|
||||
var type: VideoChatActionButtonComponent.Content.BluetoothType = .generic
|
||||
let portName = port.name.lowercased()
|
||||
if portName.contains("airpods max") {
|
||||
type = .airpodsMax
|
||||
} else if portName.contains("airpods pro") {
|
||||
type = .airpodsPro
|
||||
} else if portName.contains("airpods") {
|
||||
type = .airpods
|
||||
}
|
||||
buttonAudio = .bluetooth(type)
|
||||
}
|
||||
if availableOutputs.count <= 1 {
|
||||
buttonAudio = .none
|
||||
}
|
||||
}
|
||||
|
||||
if let callState = self.callState, let muteState = callState.muteState, !muteState.canUnmute {
|
||||
videoButtonContent = nil
|
||||
videoControlButtonContent = .audio(audio: buttonAudio, isEnabled: buttonIsEnabled)
|
||||
} else {
|
||||
let isVideoActive = self.callState?.isMyVideoActive ?? false
|
||||
videoButtonContent = .video(isActive: isVideoActive)
|
||||
if isVideoActive {
|
||||
videoControlButtonContent = .rotateCamera
|
||||
} else {
|
||||
videoControlButtonContent = .audio(audio: buttonAudio, isEnabled: buttonIsEnabled)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let actionButtonDiameter: CGFloat = 56.0
|
||||
let expandedMicrophoneButtonDiameter: CGFloat = actionButtonDiameter
|
||||
let collapsedMicrophoneButtonDiameter: CGFloat = actionButtonDiameter // 116.0
|
||||
|
||||
let buttonsWidth: CGFloat = actionButtonDiameter * 5.0
|
||||
let buttonsCount = videoButtonContent == nil ? 4 : 5
|
||||
|
||||
let buttonsWidth: CGFloat = actionButtonDiameter * CGFloat(buttonsCount)
|
||||
let remainingButtonsSpace: CGFloat
|
||||
if isTwoColumnLayout {
|
||||
remainingButtonsSpace = mainColumnWidth - buttonsWidth
|
||||
@ -2566,7 +2613,7 @@ final class VideoChatScreenComponent: Component {
|
||||
remainingButtonsSpace = availableSize.width - 16.0 * 2.0 - buttonsWidth
|
||||
}
|
||||
|
||||
let actionMicrophoneButtonSpacing = min(25.0, floor(remainingButtonsSpace * 0.25))
|
||||
let actionMicrophoneButtonSpacing = min(33.0, floor(remainingButtonsSpace / CGFloat(buttonsCount - 1)))
|
||||
|
||||
var collapsedMicrophoneButtonFrame: CGRect = CGRect(origin: CGPoint(x: floor((availableSize.width - collapsedMicrophoneButtonDiameter) * 0.5), y: availableSize.height - 48.0 - environment.safeInsets.bottom - collapsedMicrophoneButtonDiameter), size: CGSize(width: collapsedMicrophoneButtonDiameter, height: collapsedMicrophoneButtonDiameter))
|
||||
if self.isAnimatedOutFromPrivateCall {
|
||||
@ -2607,7 +2654,7 @@ final class VideoChatScreenComponent: Component {
|
||||
}
|
||||
}
|
||||
|
||||
let microphoneButtonFrame: CGRect
|
||||
var microphoneButtonFrame: CGRect
|
||||
if areButtonsCollapsed {
|
||||
microphoneButtonFrame = expandedMicrophoneButtonFrame
|
||||
} else {
|
||||
@ -2631,25 +2678,40 @@ final class VideoChatScreenComponent: Component {
|
||||
} else {
|
||||
expandedParticipantsClippingY = expandedMicrophoneButtonFrame.minY - 24.0
|
||||
}
|
||||
|
||||
|
||||
let actionButtonSize = CGSize(width: actionButtonDiameter, height: actionButtonDiameter)
|
||||
var firstActionButtonFrame = CGRect(origin: CGPoint(x: microphoneButtonFrame.minX - (actionButtonDiameter + actionMicrophoneButtonSpacing) * 2.0, y: microphoneButtonFrame.minY + floor((microphoneButtonFrame.height - actionButtonDiameter) * 0.5)), size: actionButtonSize)
|
||||
var secondActionButtonFrame = CGRect(origin: CGPoint(x: firstActionButtonFrame.minX + actionMicrophoneButtonSpacing + actionButtonDiameter, y: microphoneButtonFrame.minY + floor((microphoneButtonFrame.height - actionButtonDiameter) * 0.5)), size: actionButtonSize)
|
||||
|
||||
var fourthActionButtonFrame = CGRect(origin: CGPoint(x: microphoneButtonFrame.maxX + 2.0 * actionMicrophoneButtonSpacing + actionButtonDiameter, y: microphoneButtonFrame.minY + floor((microphoneButtonFrame.height - actionButtonDiameter) * 0.5)), size: actionButtonSize)
|
||||
var thirdActionButtonFrame = CGRect(origin: CGPoint(x: microphoneButtonFrame.maxX + actionMicrophoneButtonSpacing, y: microphoneButtonFrame.minY + floor((microphoneButtonFrame.height - actionButtonDiameter) * 0.5)), size: actionButtonSize)
|
||||
|
||||
if buttonsOnTheSide {
|
||||
secondActionButtonFrame.origin.x = microphoneButtonFrame.minX
|
||||
secondActionButtonFrame.origin.y = microphoneButtonFrame.minY - landscapeControlsSpacing - actionButtonDiameter
|
||||
|
||||
if buttonsCount == 4 {
|
||||
if buttonsOnTheSide {
|
||||
firstActionButtonFrame.origin.x = microphoneButtonFrame.minX
|
||||
secondActionButtonFrame.origin.x = microphoneButtonFrame.minX
|
||||
thirdActionButtonFrame.origin.x = microphoneButtonFrame.minX
|
||||
fourthActionButtonFrame.origin.x = microphoneButtonFrame.minX
|
||||
|
||||
microphoneButtonFrame.origin.y = availableSize.height * 0.5 - landscapeControlsSpacing * 0.5 - actionButtonDiameter
|
||||
firstActionButtonFrame.origin.y = microphoneButtonFrame.minY - landscapeControlsSpacing - actionButtonDiameter
|
||||
thirdActionButtonFrame.origin.y = microphoneButtonFrame.maxY + landscapeControlsSpacing
|
||||
fourthActionButtonFrame.origin.y = microphoneButtonFrame.maxY + landscapeControlsSpacing + actionButtonDiameter + landscapeControlsSpacing
|
||||
} else {
|
||||
microphoneButtonFrame.origin.x = availableSize.width * 0.5 - actionMicrophoneButtonSpacing * 0.5 - actionButtonDiameter
|
||||
firstActionButtonFrame.origin.x = microphoneButtonFrame.minX - actionMicrophoneButtonSpacing - actionButtonDiameter
|
||||
thirdActionButtonFrame.origin.x = microphoneButtonFrame.maxX + actionMicrophoneButtonSpacing
|
||||
fourthActionButtonFrame.origin.x = microphoneButtonFrame.maxX + actionMicrophoneButtonSpacing + actionButtonDiameter + actionMicrophoneButtonSpacing
|
||||
}
|
||||
} else if buttonsOnTheSide {
|
||||
firstActionButtonFrame.origin.x = microphoneButtonFrame.minX
|
||||
firstActionButtonFrame.origin.y = secondActionButtonFrame.minY - landscapeControlsSpacing - actionButtonDiameter
|
||||
|
||||
secondActionButtonFrame.origin.x = microphoneButtonFrame.minX
|
||||
thirdActionButtonFrame.origin.x = microphoneButtonFrame.minX
|
||||
thirdActionButtonFrame.origin.y = microphoneButtonFrame.maxY + landscapeControlsSpacing
|
||||
|
||||
fourthActionButtonFrame.origin.x = microphoneButtonFrame.minX
|
||||
|
||||
secondActionButtonFrame.origin.y = microphoneButtonFrame.minY - landscapeControlsSpacing - actionButtonDiameter
|
||||
firstActionButtonFrame.origin.y = secondActionButtonFrame.minY - landscapeControlsSpacing - actionButtonDiameter
|
||||
thirdActionButtonFrame.origin.y = microphoneButtonFrame.maxY + landscapeControlsSpacing
|
||||
fourthActionButtonFrame.origin.y = thirdActionButtonFrame.maxY + landscapeControlsSpacing
|
||||
}
|
||||
|
||||
@ -3065,84 +3127,7 @@ final class VideoChatScreenComponent: Component {
|
||||
transition.setBounds(view: microphoneButtonView, bounds: CGRect(origin: CGPoint(), size: microphoneButtonFrame.size))
|
||||
}
|
||||
|
||||
let videoButtonContent: VideoChatActionButtonComponent.Content
|
||||
let videoControlButtonContent: VideoChatActionButtonComponent.Content
|
||||
|
||||
var buttonAudio: VideoChatActionButtonComponent.Content.Audio = .speaker
|
||||
var buttonIsEnabled = false
|
||||
if let (availableOutputs, maybeCurrentOutput) = self.audioOutputState, let currentOutput = maybeCurrentOutput {
|
||||
buttonIsEnabled = availableOutputs.count > 1
|
||||
switch currentOutput {
|
||||
case .builtin:
|
||||
buttonAudio = .builtin
|
||||
case .speaker:
|
||||
buttonAudio = .speaker
|
||||
case .headphones:
|
||||
buttonAudio = .headphones
|
||||
case let .port(port):
|
||||
var type: VideoChatActionButtonComponent.Content.BluetoothType = .generic
|
||||
let portName = port.name.lowercased()
|
||||
if portName.contains("airpods max") {
|
||||
type = .airpodsMax
|
||||
} else if portName.contains("airpods pro") {
|
||||
type = .airpodsPro
|
||||
} else if portName.contains("airpods") {
|
||||
type = .airpods
|
||||
}
|
||||
buttonAudio = .bluetooth(type)
|
||||
}
|
||||
if availableOutputs.count <= 1 {
|
||||
buttonAudio = .none
|
||||
}
|
||||
}
|
||||
|
||||
if let callState = self.callState, let muteState = callState.muteState, !muteState.canUnmute {
|
||||
videoButtonContent = .audio(audio: buttonAudio, isEnabled: buttonIsEnabled)
|
||||
videoControlButtonContent = .audio(audio: buttonAudio, isEnabled: buttonIsEnabled)
|
||||
} else {
|
||||
let isVideoActive = self.callState?.isMyVideoActive ?? false
|
||||
videoButtonContent = .video(isActive: isVideoActive)
|
||||
if isVideoActive {
|
||||
videoControlButtonContent = .rotateCamera
|
||||
} else {
|
||||
videoControlButtonContent = .audio(audio: buttonAudio, isEnabled: buttonIsEnabled)
|
||||
}
|
||||
}
|
||||
|
||||
let _ = self.videoButton.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(PlainButtonComponent(
|
||||
content: AnyComponent(VideoChatActionButtonComponent(
|
||||
strings: environment.strings,
|
||||
content: videoButtonContent,
|
||||
microphoneState: actionButtonMicrophoneState,
|
||||
isCollapsed: areButtonsActuallyCollapsed || buttonsOnTheSide
|
||||
)),
|
||||
effectAlignment: .center,
|
||||
action: { [weak self] in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
if let callState = self.callState, let muteState = callState.muteState, !muteState.canUnmute {
|
||||
self.onAudioRoutePressed()
|
||||
} else {
|
||||
self.onCameraPressed()
|
||||
}
|
||||
},
|
||||
animateAlpha: false
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: actionButtonDiameter, height: actionButtonDiameter)
|
||||
)
|
||||
|
||||
if let videoButtonView = self.videoButton.view {
|
||||
if videoButtonView.superview == nil {
|
||||
self.containerView.addSubview(videoButtonView)
|
||||
}
|
||||
transition.setPosition(view: videoButtonView, position: secondActionButtonFrame.center)
|
||||
transition.setBounds(view: videoButtonView, bounds: CGRect(origin: CGPoint(), size: secondActionButtonFrame.size))
|
||||
}
|
||||
|
||||
let _ = self.speakerButton.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(PlainButtonComponent(
|
||||
@ -3178,6 +3163,47 @@ final class VideoChatScreenComponent: Component {
|
||||
transition.setBounds(view: speakerButtonView, bounds: CGRect(origin: CGPoint(), size: firstActionButtonFrame.size))
|
||||
}
|
||||
|
||||
if let videoButtonContent {
|
||||
let _ = self.videoButton.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(PlainButtonComponent(
|
||||
content: AnyComponent(VideoChatActionButtonComponent(
|
||||
strings: environment.strings,
|
||||
content: videoButtonContent,
|
||||
microphoneState: actionButtonMicrophoneState,
|
||||
isCollapsed: areButtonsActuallyCollapsed || buttonsOnTheSide
|
||||
)),
|
||||
effectAlignment: .center,
|
||||
action: { [weak self] in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
if let callState = self.callState, let muteState = callState.muteState, !muteState.canUnmute {
|
||||
self.onAudioRoutePressed()
|
||||
} else {
|
||||
self.onCameraPressed()
|
||||
}
|
||||
},
|
||||
animateAlpha: false
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: actionButtonDiameter, height: actionButtonDiameter)
|
||||
)
|
||||
if let videoButtonView = self.videoButton.view {
|
||||
if videoButtonView.superview == nil {
|
||||
self.containerView.addSubview(videoButtonView)
|
||||
}
|
||||
transition.setPosition(view: videoButtonView, position: secondActionButtonFrame.center)
|
||||
transition.setBounds(view: videoButtonView, bounds: CGRect(origin: CGPoint(), size: secondActionButtonFrame.size))
|
||||
}
|
||||
} else if let videoButtonView = self.videoButton.view {
|
||||
let transition = ComponentTransition(animation: .curve(duration: 0.25, curve: .easeInOut))
|
||||
transition.animateScale(view: videoButtonView, from: 1.0, to: 0.01)
|
||||
transition.animateAlpha(view: videoButtonView, from: 1.0, to: 0.0, completion: { _ in
|
||||
videoButtonView.removeFromSuperview()
|
||||
})
|
||||
}
|
||||
|
||||
let _ = self.messageButton.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(PlainButtonComponent(
|
||||
@ -3239,7 +3265,7 @@ final class VideoChatScreenComponent: Component {
|
||||
var inputPanelBottomInset: CGFloat = 0.0
|
||||
var inputPanelSize: CGSize = .zero
|
||||
if self.inputPanelIsActive {
|
||||
let inputPanelAvailableWidth = availableSize.width
|
||||
let inputPanelAvailableWidth = availableSize.width - environment.safeInsets.left - environment.safeInsets.right
|
||||
var inputPanelAvailableHeight = 103.0
|
||||
|
||||
let keyboardWasHidden = self.inputPanelExternalState.isKeyboardHidden
|
||||
@ -3462,7 +3488,11 @@ final class VideoChatScreenComponent: Component {
|
||||
inputPanelBottomInset = inputHeight - environment.safeInsets.bottom
|
||||
} else {
|
||||
if self.inputPanelExternalState.isEditing {
|
||||
inputPanelBottomInset = availableSize.height - microphoneButtonFrame.minY
|
||||
if buttonsOnTheSide {
|
||||
inputPanelBottomInset = 16.0
|
||||
} else {
|
||||
inputPanelBottomInset = availableSize.height - microphoneButtonFrame.minY
|
||||
}
|
||||
} else {
|
||||
inputPanelBottomInset = -inputPanelSize.height - environment.safeInsets.bottom
|
||||
}
|
||||
@ -3758,7 +3788,8 @@ final class VideoChatScreenComponent: Component {
|
||||
}
|
||||
}
|
||||
|
||||
let messagesBottomInset: CGFloat = max(inputPanelBottomInset + inputPanelSize.height + 31.0, availableSize.height - microphoneButtonFrame.minY + 16.0) + reactionsInset
|
||||
let normalMessagesBottomInset: CGFloat = buttonsOnTheSide ? 16.0 : availableSize.height - microphoneButtonFrame.minY + 16.0
|
||||
let messagesBottomInset: CGFloat = max(inputPanelBottomInset + inputPanelSize.height + 31.0, normalMessagesBottomInset) + reactionsInset
|
||||
let messagesListSize = self.messagesList.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(MessageListComponent(
|
||||
@ -3768,9 +3799,9 @@ final class VideoChatScreenComponent: Component {
|
||||
sendActionTransition: sendActionTransition
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: availableSize.width, height: availableSize.height - messagesBottomInset)
|
||||
containerSize: CGSize(width: availableSize.width - environment.safeInsets.left - environment.safeInsets.right, height: availableSize.height - messagesBottomInset)
|
||||
)
|
||||
let messagesListFrame = CGRect(origin: CGPoint(x: 0.0, y: availableSize.height - messagesListSize.height - messagesBottomInset), size: messagesListSize)
|
||||
let messagesListFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((availableSize.width - messagesListSize.width) / 2.0), y: availableSize.height - messagesListSize.height - messagesBottomInset), size: messagesListSize)
|
||||
if let messagesListView = self.messagesList.view {
|
||||
if messagesListView.superview == nil {
|
||||
messagesListView.isUserInteractionEnabled = false
|
||||
|
||||
@ -362,7 +362,8 @@ func managedUniqueStarGifts(accountPeerId: PeerId, postbox: Postbox, network: Ne
|
||||
valueCurrency: nil,
|
||||
flags: [],
|
||||
themePeerId: nil,
|
||||
peerColor: nil
|
||||
peerColor: nil,
|
||||
hostPeerId: nil
|
||||
)
|
||||
if let entry = CodableEntry(RecentStarGiftItem(gift)) {
|
||||
items.append(OrderedItemListEntry(id: RecentStarGiftItemId(id).rawValue, contents: entry))
|
||||
|
||||
@ -322,6 +322,7 @@ public enum StarGift: Equatable, Codable, PostboxCoding {
|
||||
case flags
|
||||
case themePeerId
|
||||
case peerColor
|
||||
case hostPeerId
|
||||
}
|
||||
|
||||
public struct Flags: OptionSet {
|
||||
@ -610,8 +611,9 @@ public enum StarGift: Equatable, Codable, PostboxCoding {
|
||||
public let flags: Flags
|
||||
public let themePeerId: EnginePeer.Id?
|
||||
public let peerColor: PeerCollectibleColor?
|
||||
public let hostPeerId: EnginePeer.Id?
|
||||
|
||||
public init(id: Int64, giftId: Int64, title: String, number: Int32, slug: String, owner: Owner, attributes: [Attribute], availability: Availability, giftAddress: String?, resellAmounts: [CurrencyAmount]?, resellForTonOnly: Bool, releasedBy: EnginePeer.Id?, valueAmount: Int64?, valueCurrency: String?, flags: Flags, themePeerId: EnginePeer.Id?, peerColor: PeerCollectibleColor?) {
|
||||
public init(id: Int64, giftId: Int64, title: String, number: Int32, slug: String, owner: Owner, attributes: [Attribute], availability: Availability, giftAddress: String?, resellAmounts: [CurrencyAmount]?, resellForTonOnly: Bool, releasedBy: EnginePeer.Id?, valueAmount: Int64?, valueCurrency: String?, flags: Flags, themePeerId: EnginePeer.Id?, peerColor: PeerCollectibleColor?, hostPeerId: EnginePeer.Id?) {
|
||||
self.id = id
|
||||
self.giftId = giftId
|
||||
self.title = title
|
||||
@ -629,6 +631,7 @@ public enum StarGift: Equatable, Codable, PostboxCoding {
|
||||
self.flags = flags
|
||||
self.themePeerId = themePeerId
|
||||
self.peerColor = peerColor
|
||||
self.hostPeerId = hostPeerId
|
||||
}
|
||||
|
||||
public init(from decoder: Decoder) throws {
|
||||
@ -664,6 +667,7 @@ public enum StarGift: Equatable, Codable, PostboxCoding {
|
||||
self.flags = try container.decodeIfPresent(Int32.self, forKey: .flags).flatMap { Flags(rawValue: $0) } ?? []
|
||||
self.themePeerId = try container.decodeIfPresent(Int64.self, forKey: .themePeerId).flatMap { EnginePeer.Id($0) }
|
||||
self.peerColor = try container.decodeIfPresent(PeerCollectibleColor.self, forKey: .peerColor)
|
||||
self.hostPeerId = try container.decodeIfPresent(Int64.self, forKey: .hostPeerId).flatMap { EnginePeer.Id($0) }
|
||||
}
|
||||
|
||||
public init(decoder: PostboxDecoder) {
|
||||
@ -698,6 +702,7 @@ public enum StarGift: Equatable, Codable, PostboxCoding {
|
||||
self.flags = decoder.decodeOptionalInt32ForKey(CodingKeys.flags.rawValue).flatMap { Flags(rawValue: $0) } ?? []
|
||||
self.themePeerId = decoder.decodeOptionalInt64ForKey(CodingKeys.themePeerId.rawValue).flatMap { EnginePeer.Id($0) }
|
||||
self.peerColor = decoder.decodeCodable(PeerCollectibleColor.self, forKey: CodingKeys.peerColor.rawValue)
|
||||
self.hostPeerId = decoder.decodeOptionalInt64ForKey(CodingKeys.hostPeerId.rawValue).flatMap { EnginePeer.Id($0) }
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
@ -726,6 +731,7 @@ public enum StarGift: Equatable, Codable, PostboxCoding {
|
||||
try container.encode(self.flags.rawValue, forKey: .flags)
|
||||
try container.encodeIfPresent(self.themePeerId?.toInt64(), forKey: .themePeerId)
|
||||
try container.encodeIfPresent(self.peerColor, forKey: .peerColor)
|
||||
try container.encodeIfPresent(self.hostPeerId?.toInt64(), forKey: .hostPeerId)
|
||||
}
|
||||
|
||||
public func encode(_ encoder: PostboxEncoder) {
|
||||
@ -778,6 +784,11 @@ public enum StarGift: Equatable, Codable, PostboxCoding {
|
||||
} else {
|
||||
encoder.encodeNil(forKey: CodingKeys.peerColor.rawValue)
|
||||
}
|
||||
if let hostPeerId = self.hostPeerId {
|
||||
encoder.encodeInt64(hostPeerId.toInt64(), forKey: CodingKeys.hostPeerId.rawValue)
|
||||
} else {
|
||||
encoder.encodeNil(forKey: CodingKeys.hostPeerId.rawValue)
|
||||
}
|
||||
}
|
||||
|
||||
public func withResellAmounts(_ resellAmounts: [CurrencyAmount]?) -> UniqueGift {
|
||||
@ -798,7 +809,8 @@ public enum StarGift: Equatable, Codable, PostboxCoding {
|
||||
valueCurrency: self.valueCurrency,
|
||||
flags: self.flags,
|
||||
themePeerId: self.themePeerId,
|
||||
peerColor: self.peerColor
|
||||
peerColor: self.peerColor,
|
||||
hostPeerId: self.hostPeerId
|
||||
)
|
||||
}
|
||||
|
||||
@ -820,7 +832,8 @@ public enum StarGift: Equatable, Codable, PostboxCoding {
|
||||
valueCurrency: self.valueCurrency,
|
||||
flags: self.flags,
|
||||
themePeerId: self.themePeerId,
|
||||
peerColor: self.peerColor
|
||||
peerColor: self.peerColor,
|
||||
hostPeerId: self.hostPeerId
|
||||
)
|
||||
}
|
||||
|
||||
@ -842,7 +855,8 @@ public enum StarGift: Equatable, Codable, PostboxCoding {
|
||||
valueCurrency: self.valueCurrency,
|
||||
flags: self.flags,
|
||||
themePeerId: themePeerId,
|
||||
peerColor: self.peerColor
|
||||
peerColor: self.peerColor,
|
||||
hostPeerId: self.hostPeerId
|
||||
)
|
||||
}
|
||||
|
||||
@ -864,7 +878,8 @@ public enum StarGift: Equatable, Codable, PostboxCoding {
|
||||
valueCurrency: self.valueCurrency,
|
||||
flags: self.flags,
|
||||
themePeerId: self.themePeerId,
|
||||
peerColor: self.peerColor
|
||||
peerColor: self.peerColor,
|
||||
hostPeerId: self.hostPeerId
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -977,7 +992,7 @@ extension StarGift {
|
||||
return nil
|
||||
}
|
||||
self = .generic(StarGift.Gift(id: id, title: title, file: file, price: stars, convertStars: convertStars, availability: availability, soldOut: soldOut, flags: flags, upgradeStars: upgradeStars, releasedBy: releasedBy?.peerId, perUserLimit: perUserLimit, lockedUntilDate: lockedUntilDate))
|
||||
case let .starGiftUnique(apiFlags, id, giftId, title, slug, num, ownerPeerId, ownerName, ownerAddress, attributes, availabilityIssued, availabilityTotal, giftAddress, resellAmounts, releasedBy, valueAmount, valueCurrency, themePeer, peerColor):
|
||||
case let .starGiftUnique(apiFlags, id, giftId, title, slug, num, ownerPeerId, ownerName, ownerAddress, attributes, availabilityIssued, availabilityTotal, giftAddress, resellAmounts, releasedBy, valueAmount, valueCurrency, themePeer, peerColor, hostPeerId):
|
||||
let owner: StarGift.UniqueGift.Owner
|
||||
if let ownerAddress {
|
||||
owner = .address(ownerAddress)
|
||||
@ -1009,7 +1024,7 @@ extension StarGift {
|
||||
break
|
||||
}
|
||||
|
||||
self = .unique(StarGift.UniqueGift(id: id, giftId: giftId, title: title, number: num, slug: slug, owner: owner, attributes: attributes.compactMap { UniqueGift.Attribute(apiAttribute: $0) }, availability: UniqueGift.Availability(issued: availabilityIssued, total: availabilityTotal), giftAddress: giftAddress, resellAmounts: resellAmounts, resellForTonOnly: (apiFlags & (1 << 7)) != 0, releasedBy: releasedBy?.peerId, valueAmount: valueAmount, valueCurrency: valueCurrency, flags: flags, themePeerId: themePeer?.peerId, peerColor: peerCollectibleColor))
|
||||
self = .unique(StarGift.UniqueGift(id: id, giftId: giftId, title: title, number: num, slug: slug, owner: owner, attributes: attributes.compactMap { UniqueGift.Attribute(apiAttribute: $0) }, availability: UniqueGift.Availability(issued: availabilityIssued, total: availabilityTotal), giftAddress: giftAddress, resellAmounts: resellAmounts, resellForTonOnly: (apiFlags & (1 << 7)) != 0, releasedBy: releasedBy?.peerId, valueAmount: valueAmount, valueCurrency: valueCurrency, flags: flags, themePeerId: themePeer?.peerId, peerColor: peerCollectibleColor, hostPeerId: hostPeerId?.peerId))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -332,14 +332,6 @@ public extension Peer {
|
||||
}
|
||||
|
||||
var profileColor: PeerNameColor? {
|
||||
if let emojiStatus {
|
||||
switch emojiStatus.content {
|
||||
case let .starGift(_, _, _, _, _, _, outerColor, _, _):
|
||||
return PeerNameColor.other(outerColor)
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
switch self {
|
||||
case let user as TelegramUser:
|
||||
return user.profileColor
|
||||
@ -402,7 +394,7 @@ public extension Peer {
|
||||
|
||||
public extension TelegramPeerUsername {
|
||||
var isActive: Bool {
|
||||
return self.flags.contains(.isActive) || self.flags.contains(.isEditable)
|
||||
return self.flags.contains(.isActive)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1501,7 +1501,18 @@ private func infoItems(data: PeerInfoScreenData?, context: AccountContext, prese
|
||||
}
|
||||
|
||||
if let note = cachedData.note, !note.text.isEmpty {
|
||||
items[currentPeerInfoSection]!.append(PeerInfoScreenLabeledValueItem(id: 0, label: presentationData.strings.PeerInfo_Notes, rightLabel: presentationData.strings.PeerInfo_NotesInfo, text: note.text, entities: note.entities, textColor: .primary, textBehavior: .multiLine(maxLines: 100, enabledEntities: []), action: nil, linkItemAction: bioLinkAction, button: nil, contextAction: noteContextAction, requestLayout: { animated in
|
||||
var entities = note.entities
|
||||
if !context.isPremium {
|
||||
entities = entities.filter { entity in
|
||||
switch entity.type {
|
||||
case .Url, .TextUrl:
|
||||
return false
|
||||
default:
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
items[currentPeerInfoSection]!.append(PeerInfoScreenLabeledValueItem(id: 0, label: presentationData.strings.PeerInfo_Notes, rightLabel: presentationData.strings.PeerInfo_NotesInfo, text: note.text, entities: entities, textColor: .primary, textBehavior: .multiLine(maxLines: 100, enabledEntities: []), action: nil, linkItemAction: bioLinkAction, button: nil, contextAction: noteContextAction, requestLayout: { animated in
|
||||
interaction.requestLayout(animated)
|
||||
}))
|
||||
}
|
||||
@ -4577,7 +4588,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
||||
|
||||
let noteUpdateSignal: Signal<Never, ContactUpdateError>
|
||||
if noteUpdated, let note {
|
||||
let entities = generateChatInputTextEntities(note)
|
||||
let entities = generateTextEntities(note.string, enabledTypes: [.mention, .hashtag, .allUrl], currentEntities: generateChatInputTextEntities(note))
|
||||
noteUpdateSignal = context.engine.contacts.updateContactNote(peerId: peer.id, text: note.string, entities: entities)
|
||||
|> mapError { _ -> ContactUpdateError in
|
||||
return .generic
|
||||
|
||||
@ -768,7 +768,8 @@ final class UserAppearanceScreenComponent: Component {
|
||||
valueCurrency: nil,
|
||||
flags: [],
|
||||
themePeerId: nil,
|
||||
peerColor: nil
|
||||
peerColor: nil,
|
||||
hostPeerId: nil
|
||||
)
|
||||
signal = component.context.engine.accountData.setStarGiftStatus(starGift: gift, expirationDate: emojiStatus.expirationDate)
|
||||
} else {
|
||||
@ -1110,7 +1111,16 @@ final class UserAppearanceScreenComponent: Component {
|
||||
let updatedSection = Section(rawValue: intValue) ?? .profile
|
||||
if self.currentSection != updatedSection {
|
||||
if (updatedSection == .name && self.selectedProfileGift != nil) || (updatedSection == .profile && self.selectedNameGift != nil) {
|
||||
|
||||
switch updatedSection {
|
||||
case .profile:
|
||||
self.selectedNameGift = nil
|
||||
self.updatedPeerNameColor = nil
|
||||
self.updatedPeerNameEmoji = nil
|
||||
case .name:
|
||||
self.selectedProfileGift = nil
|
||||
self.updatedPeerProfileColor = nil
|
||||
self.updatedPeerProfileEmoji = nil
|
||||
}
|
||||
} else {
|
||||
self.currentSection = updatedSection
|
||||
self.state?.updated(transition: .easeInOut(duration: 0.3).withUserData(TransitionHint(animateTabChange: true)))
|
||||
@ -1871,6 +1881,8 @@ public class UserAppearanceScreen: ViewControllerComponentContainer {
|
||||
|
||||
self.automaticallyControlPresentationContextLayout = false
|
||||
|
||||
self.supportedOrientations = ViewControllerSupportedOrientations(regularSize: .all, compactSize: .portrait)
|
||||
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
self.title = ""
|
||||
self.navigationItem.backBarButtonItem = UIBarButtonItem(title: presentationData.strings.Common_Back, style: .plain, target: nil, action: nil)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user