Merge commit 'ba24da05932f634d5d19e647fb3de0d9105dbd7c'

This commit is contained in:
Isaac 2024-02-16 22:52:05 +04:00
commit 31260e710b
18 changed files with 113 additions and 39 deletions

View File

@ -11307,3 +11307,11 @@ Sorry for the inconvenience.";
"Story.GroupCommentingRestrictedPlaceholder" = "Comments restricted. Boost the group to unlock."; "Story.GroupCommentingRestrictedPlaceholder" = "Comments restricted. Boost the group to unlock.";
"Story.GroupCommentingRestrictedPlaceholderAction" = "Learn More..."; "Story.GroupCommentingRestrictedPlaceholderAction" = "Learn More...";
"GroupBoost.Table.Group.VoiceToText" = "Voice-to-Text Conversion";
"GroupBoost.Table.Group.EmojiPack" = "Custom Emojipack";
"ChannelBoost.Header.Boost" = "boost";
"ChannelBoost.Header.Giveaway" = "giveaway";
"ChannelBoost.Header.Features" = "features";

View File

@ -983,6 +983,7 @@ final class AttachmentPanel: ASDisplayNode, UIScrollViewDelegate {
}, openPremiumGift: { }, openPremiumGift: {
}, openPremiumRequiredForMessaging: { }, openPremiumRequiredForMessaging: {
}, openBoostToUnrestrict: { }, openBoostToUnrestrict: {
}, updateVideoTrimRange: { _, _, _, _ in
}, updateHistoryFilter: { _ in }, updateHistoryFilter: { _ in
}, updateDisplayHistoryFilterAsList: { _ in }, updateDisplayHistoryFilterAsList: { _ in
}, requestLayout: { _ in }, requestLayout: { _ in

View File

@ -277,13 +277,16 @@ public final class AvatarNode: ASDisplayNode {
private struct Params: Equatable { private struct Params: Equatable {
let peerId: EnginePeer.Id? let peerId: EnginePeer.Id?
let resourceId: String? let resourceId: String?
let clipStyle: AvatarNodeClipStyle
init( init(
peerId: EnginePeer.Id?, peerId: EnginePeer.Id?,
resourceId: String? resourceId: String?,
clipStyle: AvatarNodeClipStyle
) { ) {
self.peerId = peerId self.peerId = peerId
self.resourceId = resourceId self.resourceId = resourceId
self.clipStyle = clipStyle
} }
} }
@ -315,6 +318,15 @@ public final class AvatarNode: ASDisplayNode {
private var params: Params? private var params: Params?
private var loadDisposable: Disposable? private var loadDisposable: Disposable?
var clipStyle: AvatarNodeClipStyle {
if let params = self.params {
return params.clipStyle
} else if case let .peerAvatar(_, _, _, _, clipStyle) = self.state {
return clipStyle
}
return .none
}
public var badgeView: AvatarBadgeView? { public var badgeView: AvatarBadgeView? {
didSet { didSet {
if self.badgeView !== oldValue { if self.badgeView !== oldValue {
@ -516,6 +528,7 @@ public final class AvatarNode: ASDisplayNode {
} else if peer?.restrictionText(platform: "ios", contentSettings: contentSettings) == nil { } else if peer?.restrictionText(platform: "ios", contentSettings: contentSettings) == nil {
representation = peer?.smallProfileImage representation = peer?.smallProfileImage
} }
let updatedState: AvatarNodeState = .peerAvatar(peer?.id ?? EnginePeer.Id(0), peer?.nameColor, peer?.displayLetters ?? [], representation, clipStyle) let updatedState: AvatarNodeState = .peerAvatar(peer?.id ?? EnginePeer.Id(0), peer?.nameColor, peer?.displayLetters ?? [], representation, clipStyle)
if updatedState != self.state || overrideImage != self.overrideImage || theme !== self.theme { if updatedState != self.state || overrideImage != self.overrideImage || theme !== self.theme {
self.state = updatedState self.state = updatedState
@ -599,7 +612,8 @@ public final class AvatarNode: ASDisplayNode {
let smallProfileImage = peer?.smallProfileImage let smallProfileImage = peer?.smallProfileImage
let params = Params( let params = Params(
peerId: peer?.id, peerId: peer?.id,
resourceId: smallProfileImage?.resource.id.stringRepresentation resourceId: smallProfileImage?.resource.id.stringRepresentation,
clipStyle: clipStyle
) )
if self.params == params { if self.params == params {
return return
@ -689,6 +703,7 @@ public final class AvatarNode: ASDisplayNode {
} else if peer?.restrictionText(platform: "ios", contentSettings: genericContext.currentContentSettings.with { $0 }) == nil { } else if peer?.restrictionText(platform: "ios", contentSettings: genericContext.currentContentSettings.with { $0 }) == nil {
representation = peer?.smallProfileImage representation = peer?.smallProfileImage
} }
let updatedState: AvatarNodeState = .peerAvatar(peer?.id ?? EnginePeer.Id(0), peer?.nameColor, peer?.displayLetters ?? [], representation, clipStyle) let updatedState: AvatarNodeState = .peerAvatar(peer?.id ?? EnginePeer.Id(0), peer?.nameColor, peer?.displayLetters ?? [], representation, clipStyle)
if updatedState != self.state || overrideImage != self.overrideImage || theme !== self.theme { if updatedState != self.state || overrideImage != self.overrideImage || theme !== self.theme {
self.state = updatedState self.state = updatedState
@ -1212,15 +1227,18 @@ public final class AvatarNode: ASDisplayNode {
public var colors: Colors public var colors: Colors
public var lineWidth: CGFloat public var lineWidth: CGFloat
public var inactiveLineWidth: CGFloat public var inactiveLineWidth: CGFloat
public var forceRoundedRect: Bool
public init( public init(
colors: Colors, colors: Colors,
lineWidth: CGFloat, lineWidth: CGFloat,
inactiveLineWidth: CGFloat inactiveLineWidth: CGFloat,
forceRoundedRect: Bool = false
) { ) {
self.colors = colors self.colors = colors
self.lineWidth = lineWidth self.lineWidth = lineWidth
self.inactiveLineWidth = inactiveLineWidth self.inactiveLineWidth = inactiveLineWidth
self.forceRoundedRect = forceRoundedRect
} }
} }
@ -1274,7 +1292,8 @@ public final class AvatarNode: ASDisplayNode {
totalCount: storyStats.totalCount, totalCount: storyStats.totalCount,
unseenCount: storyStats.unseenCount unseenCount: storyStats.unseenCount
), ),
progress: mappedProgress progress: mappedProgress,
isRoundedRect: self.contentNode.clipStyle == .roundedRect || storyPresentationParams.forceRoundedRect
)), )),
environment: {}, environment: {},
containerSize: indicatorSize containerSize: indicatorSize

View File

@ -2905,14 +2905,17 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
}))) })))
} else if case let .channel(channel) = peer { } else if case let .channel(channel) = peer {
let openTitle: String let openTitle: String
let openIcon: String
switch channel.info { switch channel.info {
case .broadcast: case .broadcast:
openTitle = self.presentationData.strings.ChatList_ContextOpenChannel openTitle = self.presentationData.strings.ChatList_ContextOpenChannel
openIcon = "Chat/Context Menu/Channels"
case .group: case .group:
openTitle = self.presentationData.strings.ChatList_ContextOpenGroup openTitle = self.presentationData.strings.ChatList_ContextOpenGroup
openIcon = "Chat/Context Menu/Groups"
} }
items.append(.action(ContextMenuActionItem(text: openTitle, icon: { theme in items.append(.action(ContextMenuActionItem(text: openTitle, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Channels"), color: theme.contextMenu.primaryColor) return generateTintedImage(image: UIImage(bundleImageName: openIcon), color: theme.contextMenu.primaryColor)
}, action: { [weak self] c, _ in }, action: { [weak self] c, _ in
c.dismiss(completion: { c.dismiss(completion: {
guard let self else { guard let self else {

View File

@ -176,6 +176,7 @@ public final class ChatPanelInterfaceInteraction {
public let updateHistoryFilter: ((ChatPresentationInterfaceState.HistoryFilter?) -> ChatPresentationInterfaceState.HistoryFilter?) -> Void public let updateHistoryFilter: ((ChatPresentationInterfaceState.HistoryFilter?) -> ChatPresentationInterfaceState.HistoryFilter?) -> Void
public let updateDisplayHistoryFilterAsList: (Bool) -> Void public let updateDisplayHistoryFilterAsList: (Bool) -> Void
public let openBoostToUnrestrict: () -> Void public let openBoostToUnrestrict: () -> Void
public let updateVideoTrimRange: (Double, Double, Bool, Bool) -> Void
public let requestLayout: (ContainedViewLayoutTransition) -> Void public let requestLayout: (ContainedViewLayoutTransition) -> Void
public let chatController: () -> ViewController? public let chatController: () -> ViewController?
public let statuses: ChatPanelInterfaceInteractionStatuses? public let statuses: ChatPanelInterfaceInteractionStatuses?
@ -286,6 +287,7 @@ public final class ChatPanelInterfaceInteraction {
openPremiumGift: @escaping () -> Void, openPremiumGift: @escaping () -> Void,
openPremiumRequiredForMessaging: @escaping () -> Void, openPremiumRequiredForMessaging: @escaping () -> Void,
openBoostToUnrestrict: @escaping () -> Void, openBoostToUnrestrict: @escaping () -> Void,
updateVideoTrimRange: @escaping (Double, Double, Bool, Bool) -> Void,
updateHistoryFilter: @escaping ((ChatPresentationInterfaceState.HistoryFilter?) -> ChatPresentationInterfaceState.HistoryFilter?) -> Void, updateHistoryFilter: @escaping ((ChatPresentationInterfaceState.HistoryFilter?) -> ChatPresentationInterfaceState.HistoryFilter?) -> Void,
updateDisplayHistoryFilterAsList: @escaping (Bool) -> Void, updateDisplayHistoryFilterAsList: @escaping (Bool) -> Void,
requestLayout: @escaping (ContainedViewLayoutTransition) -> Void, requestLayout: @escaping (ContainedViewLayoutTransition) -> Void,
@ -397,6 +399,7 @@ public final class ChatPanelInterfaceInteraction {
self.openPremiumGift = openPremiumGift self.openPremiumGift = openPremiumGift
self.openPremiumRequiredForMessaging = openPremiumRequiredForMessaging self.openPremiumRequiredForMessaging = openPremiumRequiredForMessaging
self.openBoostToUnrestrict = openBoostToUnrestrict self.openBoostToUnrestrict = openBoostToUnrestrict
self.updateVideoTrimRange = updateVideoTrimRange
self.updateHistoryFilter = updateHistoryFilter self.updateHistoryFilter = updateHistoryFilter
self.updateDisplayHistoryFilterAsList = updateDisplayHistoryFilterAsList self.updateDisplayHistoryFilterAsList = updateDisplayHistoryFilterAsList
self.requestLayout = requestLayout self.requestLayout = requestLayout
@ -516,6 +519,7 @@ public final class ChatPanelInterfaceInteraction {
}, openPremiumGift: { }, openPremiumGift: {
}, openPremiumRequiredForMessaging: { }, openPremiumRequiredForMessaging: {
}, openBoostToUnrestrict: { }, openBoostToUnrestrict: {
}, updateVideoTrimRange: { _, _, _, _ in
}, updateHistoryFilter: { _ in }, updateHistoryFilter: { _ in
}, updateDisplayHistoryFilterAsList: { _ in }, updateDisplayHistoryFilterAsList: { _ in
}, requestLayout: { _ in }, requestLayout: { _ in

View File

@ -271,9 +271,9 @@ private final class LevelSectionComponent: CombinedComponent {
case .customWallpaper: case .customWallpaper:
return isGroup ? strings.ChannelBoost_Table_Group_CustomWallpaper : strings.ChannelBoost_Table_CustomWallpaper return isGroup ? strings.ChannelBoost_Table_Group_CustomWallpaper : strings.ChannelBoost_Table_CustomWallpaper
case .audioTranscription: case .audioTranscription:
return "Voice-to-Text Conversion" return strings.GroupBoost_Table_Group_VoiceToText
case .emojiPack: case .emojiPack:
return "Custom Emojipack" return strings.GroupBoost_Table_Group_EmojiPack
} }
} }
@ -2234,12 +2234,12 @@ public class PremiumBoostLevelsScreen: ViewController {
self.myBoostCount += 1 self.myBoostCount += 1
let _ = (context.engine.peers.applyChannelBoost(peerId: peerId, slots: [availableBoost.slot]) let _ = (context.engine.peers.applyChannelBoost(peerId: peerId, slots: [availableBoost.slot])
|> deliverOnMainQueue).startStandalone(completed: { [weak self] in |> deliverOnMainQueue).startStandalone(next: { [weak self] myBoostStatus in
self?.updatedState.set(context.engine.peers.getChannelBoostStatus(peerId: peerId) self?.updatedState.set(context.engine.peers.getChannelBoostStatus(peerId: peerId)
|> beforeNext { [weak self] status in |> beforeNext { [weak self] boostStatus in
if let self, let status { if let self, let boostStatus, let myBoostStatus {
Queue.mainQueue().async { Queue.mainQueue().async {
self.controller?.boostStatusUpdated(status) self.controller?.boostStatusUpdated(boostStatus, myBoostStatus)
} }
} }
} }
@ -2293,8 +2293,8 @@ public class PremiumBoostLevelsScreen: ViewController {
).startStandalone(next: { boostStatus, myBoostStatus in ).startStandalone(next: { boostStatus, myBoostStatus in
dismissReplaceImpl?() dismissReplaceImpl?()
if let boostStatus { if let boostStatus, let myBoostStatus {
boostStatusUpdated(boostStatus) boostStatusUpdated(boostStatus, myBoostStatus)
} }
let levelsController = PremiumBoostLevelsScreen( let levelsController = PremiumBoostLevelsScreen(
@ -2466,7 +2466,7 @@ public class PremiumBoostLevelsScreen: ViewController {
private var currentLayout: ContainerViewLayout? private var currentLayout: ContainerViewLayout?
public var boostStatusUpdated: (ChannelBoostStatus) -> Void = { _ in } public var boostStatusUpdated: (ChannelBoostStatus, MyBoostStatus) -> Void = { _, _ in }
public var disposed: () -> Void = {} public var disposed: () -> Void = {}
public init( public init(

View File

@ -399,7 +399,7 @@ private final class BoostHeaderComponent: CombinedComponent {
content: AnyComponent( content: AnyComponent(
BoostButtonComponent( BoostButtonComponent(
iconName: "Premium/Boosts/Boost", iconName: "Premium/Boosts/Boost",
title: "boost" title: component.strings.ChannelBoost_Header_Boost
) )
), ),
effectAlignment: .center, effectAlignment: .center,
@ -419,7 +419,7 @@ private final class BoostHeaderComponent: CombinedComponent {
content: AnyComponent( content: AnyComponent(
BoostButtonComponent( BoostButtonComponent(
iconName: "Premium/Boosts/Giveaway", iconName: "Premium/Boosts/Giveaway",
title: "giveaway" title: component.strings.ChannelBoost_Header_Giveaway
) )
), ),
effectAlignment: .center, effectAlignment: .center,
@ -439,7 +439,7 @@ private final class BoostHeaderComponent: CombinedComponent {
content: AnyComponent( content: AnyComponent(
BoostButtonComponent( BoostButtonComponent(
iconName: "Premium/Boosts/Features", iconName: "Premium/Boosts/Features",
title: "features" title: component.strings.ChannelBoost_Header_Features
) )
), ),
effectAlignment: .center, effectAlignment: .center,

View File

@ -1525,7 +1525,7 @@ public func channelStatsController(context: AccountContext, updatedPresentationD
controller?.push(giveawayController) controller?.push(giveawayController)
} }
) )
boostController.boostStatusUpdated = { boostStatus in boostController.boostStatusUpdated = { boostStatus, _ in
boostDataPromise.set(.single(boostStatus)) boostDataPromise.set(.single(boostStatus))
} }
controller?.push(boostController) controller?.push(boostController)

View File

@ -169,6 +169,7 @@ public final class ChatRecentActionsController: TelegramBaseController {
}, openPremiumGift: { }, openPremiumGift: {
}, openPremiumRequiredForMessaging: { }, openPremiumRequiredForMessaging: {
}, openBoostToUnrestrict: { }, openBoostToUnrestrict: {
}, updateVideoTrimRange: { _, _, _, _ in
}, updateHistoryFilter: { _ in }, updateHistoryFilter: { _ in
}, updateDisplayHistoryFilterAsList: { _ in }, updateDisplayHistoryFilterAsList: { _ in
}, requestLayout: { _ in }, requestLayout: { _ in

View File

@ -126,10 +126,17 @@ final class PeerInfoAvatarTransformContainerNode: ASDisplayNode {
progress: storyProgress progress: storyProgress
) )
} }
var isForum = false
if let peer, let channel = peer as? TelegramChannel, channel.isForum {
isForum = true
}
self.avatarNode.setStoryStats(storyStats: storyStats, presentationParams: AvatarNode.StoryPresentationParams( self.avatarNode.setStoryStats(storyStats: storyStats, presentationParams: AvatarNode.StoryPresentationParams(
colors: colors, colors: colors,
lineWidth: 3.0, lineWidth: 3.0,
inactiveLineWidth: 1.5 inactiveLineWidth: 1.5,
forceRoundedRect: isForum
), transition: Transition(transition)) ), transition: Transition(transition))
} }

View File

@ -419,6 +419,7 @@ final class PeerInfoSelectionPanelNode: ASDisplayNode {
}, openPremiumGift: { }, openPremiumGift: {
}, openPremiumRequiredForMessaging: { }, openPremiumRequiredForMessaging: {
}, openBoostToUnrestrict: { }, openBoostToUnrestrict: {
}, updateVideoTrimRange: { _, _, _, _ in
}, updateHistoryFilter: { _ in }, updateHistoryFilter: { _ in
}, updateDisplayHistoryFilterAsList: { _ in }, updateDisplayHistoryFilterAsList: { _ in
}, requestLayout: { _ in }, requestLayout: { _ in
@ -1727,7 +1728,7 @@ private func editingItems(data: PeerInfoScreenData?, state: PeerInfoState, chatL
} }
} }
if let cachedData = data.cachedData as? CachedChannelData, cachedData.flags.contains(.canViewStats) { if let cachedData = data.cachedData as? CachedChannelData, isCreator || cachedData.flags.contains(.canViewStats) {
items[.peerAdditionalSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemStats, label: .none, text: presentationData.strings.Channel_Info_Stats, icon: UIImage(bundleImageName: "Chat/Info/StatsIcon"), action: { items[.peerAdditionalSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemStats, label: .none, text: presentationData.strings.Channel_Info_Stats, icon: UIImage(bundleImageName: "Chat/Info/StatsIcon"), action: {
interaction.openStats(false) interaction.openStats(false)
})) }))

View File

@ -733,6 +733,7 @@ final class PeerSelectionControllerNode: ASDisplayNode {
}, openPremiumGift: { }, openPremiumGift: {
}, openPremiumRequiredForMessaging: { }, openPremiumRequiredForMessaging: {
}, openBoostToUnrestrict: { }, openBoostToUnrestrict: {
}, updateVideoTrimRange: { _, _, _, _ in
}, updateHistoryFilter: { _ in }, updateHistoryFilter: { _ in
}, updateDisplayHistoryFilterAsList: { _ in }, updateDisplayHistoryFilterAsList: { _ in
}, requestLayout: { _ in }, requestLayout: { _ in

View File

@ -304,6 +304,7 @@ final class ChannelAppearanceScreenComponent: Component {
private var premiumConfiguration: PremiumConfiguration? private var premiumConfiguration: PremiumConfiguration?
private var boostLevel: Int? private var boostLevel: Int?
private var boostStatus: ChannelBoostStatus? private var boostStatus: ChannelBoostStatus?
private var myBoostStatus: MyBoostStatus?
private var boostStatusDisposable: Disposable? private var boostStatusDisposable: Disposable?
private var isApplyingSettings: Bool = false private var isApplyingSettings: Bool = false
@ -656,6 +657,7 @@ final class ChannelAppearanceScreenComponent: Component {
peerId: component.peerId, peerId: component.peerId,
mode: .owner(subject: subject), mode: .owner(subject: subject),
status: status, status: status,
myBoostStatus: myBoostStatus,
openStats: { [weak self] in openStats: { [weak self] in
guard let self else { guard let self else {
return return
@ -670,6 +672,14 @@ final class ChannelAppearanceScreenComponent: Component {
self.environment?.controller()?.push(controller) self.environment?.controller()?.push(controller)
} }
) )
controller.boostStatusUpdated = { [weak self] boostStatus, myBoostStatus in
if let self {
self.boostStatus = boostStatus
self.boostLevel = boostStatus.level
self.myBoostStatus = myBoostStatus
self.state?.updated(transition: .immediate)
}
}
self.environment?.controller()?.push(controller) self.environment?.controller()?.push(controller)
HapticFeedback().impact(.light) HapticFeedback().impact(.light)
@ -924,13 +934,16 @@ final class ChannelAppearanceScreenComponent: Component {
}) })
} }
if self.boostStatusDisposable == nil { if self.boostStatusDisposable == nil {
self.boostStatusDisposable = (component.context.engine.peers.getChannelBoostStatus(peerId: component.peerId) self.boostStatusDisposable = combineLatest(queue: Queue.mainQueue(),
|> deliverOnMainQueue).start(next: { [weak self] boostStatus in component.context.engine.peers.getChannelBoostStatus(peerId: component.peerId),
component.context.engine.peers.getMyBoostStatus()
).start(next: { [weak self] boostStatus, myBoostStatus in
guard let self else { guard let self else {
return return
} }
self.boostLevel = boostStatus?.level self.boostLevel = boostStatus?.level
self.boostStatus = boostStatus self.boostStatus = boostStatus
self.myBoostStatus = myBoostStatus
if !self.isUpdating { if !self.isUpdating {
self.state?.updated(transition: .immediate) self.state?.updated(transition: .immediate)

View File

@ -50,6 +50,7 @@ public final class AvatarStoryIndicatorComponent: Component {
public let inactiveLineWidth: CGFloat public let inactiveLineWidth: CGFloat
public let counters: Counters? public let counters: Counters?
public let progress: Progress? public let progress: Progress?
public let isRoundedRect: Bool
public init( public init(
hasUnseen: Bool, hasUnseen: Bool,
@ -58,7 +59,8 @@ public final class AvatarStoryIndicatorComponent: Component {
activeLineWidth: CGFloat, activeLineWidth: CGFloat,
inactiveLineWidth: CGFloat, inactiveLineWidth: CGFloat,
counters: Counters?, counters: Counters?,
progress: Progress? = nil progress: Progress? = nil,
isRoundedRect: Bool = false
) { ) {
self.hasUnseen = hasUnseen self.hasUnseen = hasUnseen
self.hasUnseenCloseFriendsItems = hasUnseenCloseFriendsItems self.hasUnseenCloseFriendsItems = hasUnseenCloseFriendsItems
@ -67,6 +69,7 @@ public final class AvatarStoryIndicatorComponent: Component {
self.inactiveLineWidth = inactiveLineWidth self.inactiveLineWidth = inactiveLineWidth
self.counters = counters self.counters = counters
self.progress = progress self.progress = progress
self.isRoundedRect = isRoundedRect
} }
public static func ==(lhs: AvatarStoryIndicatorComponent, rhs: AvatarStoryIndicatorComponent) -> Bool { public static func ==(lhs: AvatarStoryIndicatorComponent, rhs: AvatarStoryIndicatorComponent) -> Bool {
@ -91,6 +94,9 @@ public final class AvatarStoryIndicatorComponent: Component {
if lhs.progress != rhs.progress { if lhs.progress != rhs.progress {
return false return false
} }
if lhs.isRoundedRect != rhs.isRoundedRect {
return false
}
return true return true
} }
@ -211,7 +217,7 @@ public final class AvatarStoryIndicatorComponent: Component {
} }
} }
func update(size: CGSize, radius: CGFloat, lineWidth: CGFloat, value: Value, transition: Transition) { func update(size: CGSize, radius: CGFloat, isRoundedRect: Bool, lineWidth: CGFloat, value: Value, transition: Transition) {
let params = Params( let params = Params(
size: size, size: size,
lineWidth: lineWidth, lineWidth: lineWidth,
@ -295,7 +301,7 @@ public final class AvatarStoryIndicatorComponent: Component {
var locations: [CGFloat] = [0.0, 1.0] var locations: [CGFloat] = [0.0, 1.0]
if let counters = component.counters, counters.totalCount > 1 { if let counters = component.counters, counters.totalCount > 1, !component.isRoundedRect {
let center = CGPoint(x: size.width * 0.5, y: size.height * 0.5) let center = CGPoint(x: size.width * 0.5, y: size.height * 0.5)
let spacing: CGFloat = component.activeLineWidth * 2.0 let spacing: CGFloat = component.activeLineWidth * 2.0
let angularSpacing: CGFloat = spacing / radius let angularSpacing: CGFloat = spacing / radius
@ -347,7 +353,11 @@ public final class AvatarStoryIndicatorComponent: Component {
} else { } else {
let lineWidth: CGFloat = component.hasUnseen ? component.activeLineWidth : component.inactiveLineWidth let lineWidth: CGFloat = component.hasUnseen ? component.activeLineWidth : component.inactiveLineWidth
context.setLineWidth(lineWidth) context.setLineWidth(lineWidth)
if component.isRoundedRect {
context.addPath(UIBezierPath(roundedRect: CGRect(origin: CGPoint(x: size.width * 0.5 - diameter * 0.5, y: size.height * 0.5 - diameter * 0.5), size: size).insetBy(dx: lineWidth * 0.5, dy: lineWidth * 0.5), cornerRadius: floor(diameter * 0.25)).cgPath)
} else {
context.addEllipse(in: CGRect(origin: CGPoint(x: size.width * 0.5 - diameter * 0.5, y: size.height * 0.5 - diameter * 0.5), size: size).insetBy(dx: lineWidth * 0.5, dy: lineWidth * 0.5)) context.addEllipse(in: CGRect(origin: CGPoint(x: size.width * 0.5 - diameter * 0.5, y: size.height * 0.5 - diameter * 0.5), size: size).insetBy(dx: lineWidth * 0.5, dy: lineWidth * 0.5))
}
context.replacePathWithStrokedPath() context.replacePathWithStrokedPath()
context.clip() context.clip()
@ -369,7 +379,7 @@ public final class AvatarStoryIndicatorComponent: Component {
transition.setFrame(view: self.indicatorView, frame: indicatorFrame) transition.setFrame(view: self.indicatorView, frame: indicatorFrame)
let progressTransition = Transition(animation: .curve(duration: 0.3, curve: .easeInOut)) let progressTransition = Transition(animation: .curve(duration: 0.3, curve: .easeInOut))
if let progress = component.progress { if let progress = component.progress, !component.isRoundedRect {
let colorLayer: SimpleGradientLayer let colorLayer: SimpleGradientLayer
if let current = self.colorLayer { if let current = self.colorLayer {
colorLayer = current colorLayer = current
@ -415,7 +425,7 @@ public final class AvatarStoryIndicatorComponent: Component {
mappedProgress = .progress(value) mappedProgress = .progress(value)
} }
progressLayer.update(size: indicatorFrame.size, radius: radius, lineWidth: lineWidth, value: mappedProgress, transition: .immediate) progressLayer.update(size: indicatorFrame.size, radius: radius, isRoundedRect: component.isRoundedRect, lineWidth: lineWidth, value: mappedProgress, transition: .immediate)
} else { } else {
progressTransition.setAlpha(view: self.indicatorView, alpha: 1.0) progressTransition.setAlpha(view: self.indicatorView, alpha: 1.0)

View File

@ -966,7 +966,7 @@ public class VideoMessageCameraScreen: ViewController {
if let controller = self.controller, let layout = self.validLayout { if let controller = self.controller, let layout = self.validLayout {
let insets = layout.insets(options: .input) let insets = layout.insets(options: .input)
if point.y > layout.size.height - insets.bottom - controller.inputPanelFrame.height { if point.y > layout.size.height - insets.bottom - controller.inputPanelFrame.0.height {
if layout.metrics.isTablet { if layout.metrics.isTablet {
if point.x < layout.size.width * 0.33 { if point.x < layout.size.width * 0.33 {
return result return result
@ -1111,9 +1111,9 @@ public class VideoMessageCameraScreen: ViewController {
self.didAppear() self.didAppear()
} }
var backgroundFrame = CGRect(origin: .zero, size: CGSize(width: layout.size.width, height: controller.inputPanelFrame.minY)) var backgroundFrame = CGRect(origin: .zero, size: CGSize(width: layout.size.width, height: controller.inputPanelFrame.0.minY))
if backgroundFrame.maxY < layout.size.height - 100.0 && (layout.inputHeight ?? 0.0).isZero { if backgroundFrame.maxY < layout.size.height - 100.0 && (layout.inputHeight ?? 0.0).isZero && !controller.inputPanelFrame.1 {
backgroundFrame = CGRect(origin: .zero, size: CGSize(width: layout.size.width, height: layout.size.height - layout.intrinsicInsets.bottom - controller.inputPanelFrame.height)) backgroundFrame = CGRect(origin: .zero, size: CGSize(width: layout.size.width, height: layout.size.height - layout.intrinsicInsets.bottom - controller.inputPanelFrame.0.height))
} }
transition.setPosition(view: self.backgroundView, position: backgroundFrame.center) transition.setPosition(view: self.backgroundView, position: backgroundFrame.center)
@ -1266,7 +1266,7 @@ public class VideoMessageCameraScreen: ViewController {
private let context: AccountContext private let context: AccountContext
private let updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? private let updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?
private let inputPanelFrame: CGRect private let inputPanelFrame: (CGRect, Bool)
fileprivate var allowLiveUpload: Bool fileprivate var allowLiveUpload: Bool
fileprivate var viewOnceAvailable: Bool fileprivate var viewOnceAvailable: Bool
@ -1417,7 +1417,7 @@ public class VideoMessageCameraScreen: ViewController {
updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?,
allowLiveUpload: Bool, allowLiveUpload: Bool,
viewOnceAvailable: Bool, viewOnceAvailable: Bool,
inputPanelFrame: CGRect, inputPanelFrame: (CGRect, Bool),
chatNode: ASDisplayNode?, chatNode: ASDisplayNode?,
completion: @escaping (EnqueueMessage?, Bool?, Int32?) -> Void completion: @escaping (EnqueueMessage?, Bool?, Int32?) -> Void
) { ) {

View File

@ -11136,6 +11136,10 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
) )
self.push(boostController) self.push(boostController)
}) })
}, updateVideoTrimRange: { [weak self] start, end, updatedEnd, apply in
if let videoRecorder = self?.videoRecorderValue {
videoRecorder.updateTrimRange(start: start, end: end, updatedEnd: updatedEnd, apply: apply)
}
}, updateHistoryFilter: { [weak self] update in }, updateHistoryFilter: { [weak self] update in
guard let self else { guard let self else {
return return
@ -14128,7 +14132,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
updatedPresentationData: self.updatedPresentationData, updatedPresentationData: self.updatedPresentationData,
allowLiveUpload: peerId.namespace != Namespaces.Peer.SecretChat, allowLiveUpload: peerId.namespace != Namespaces.Peer.SecretChat,
viewOnceAvailable: !isScheduledMessages && peerId.namespace == Namespaces.Peer.CloudUser && peerId != self.context.account.peerId && !isBot, viewOnceAvailable: !isScheduledMessages && peerId.namespace == Namespaces.Peer.CloudUser && peerId != self.context.account.peerId && !isBot,
inputPanelFrame: currentInputPanelFrame, inputPanelFrame: (currentInputPanelFrame, self.chatDisplayNode.inputNode != nil),
chatNode: self.chatDisplayNode.historyNode, chatNode: self.chatDisplayNode.historyNode,
completion: { [weak self] message, silentPosting, scheduleTime in completion: { [weak self] message, silentPosting, scheduleTime in
guard let self, let videoController = self.videoRecorderValue else { guard let self, let videoController = self.videoRecorderValue else {

View File

@ -188,7 +188,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
private let inputContextOverTextPanelContainer: ChatControllerTitlePanelNodeContainer private let inputContextOverTextPanelContainer: ChatControllerTitlePanelNodeContainer
private var overlayContextPanelNode: ChatInputContextPanelNode? private var overlayContextPanelNode: ChatInputContextPanelNode?
private var inputNode: ChatInputNode? private(set) var inputNode: ChatInputNode?
private var disappearingNode: ChatInputNode? private var disappearingNode: ChatInputNode?
private(set) var textInputPanelNode: ChatTextInputPanelNode? private(set) var textInputPanelNode: ChatTextInputPanelNode?

View File

@ -328,8 +328,10 @@ final class ChatRecordingPreviewInputPanelNode: ChatInputPanelNode {
) )
], ],
positionUpdated: { _, _ in }, positionUpdated: { _, _ in },
trackTrimUpdated: { _, start, end, updatedEnd, apply in trackTrimUpdated: { [weak self] _, start, end, updatedEnd, apply in
// video.control.updateTrimRange(start, end, updatedEnd, apply) if let self {
self.interfaceInteraction?.updateVideoTrimRange(start, end, updatedEnd, apply)
}
}, },
trackOffsetUpdated: { _, _, _ in }, trackOffsetUpdated: { _, _, _ in },
trackLongPressed: { _, _ in } trackLongPressed: { _, _ in }