From 2a9eb4346e2edab0545a4a944dd61109de5cc983 Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Thu, 16 Jun 2022 20:45:25 +0400 Subject: [PATCH 01/16] Various improvements --- .../Sources/SheetComponent.swift | 36 ++++++-- .../Sources/ViewControllerComponent.swift | 7 ++ .../Sources/CreatePollController.swift | 4 +- .../Sources/AddPaymentMethodSheetScreen.swift | 1 + .../PremiumUI/Sources/PremiumDemoScreen.swift | 1 + .../Sources/PremiumIntroScreen.swift | 18 ++-- .../Sources/PremiumLimitScreen.swift | 1 + .../Sources/PremiumLimitsListScreen.swift | 8 +- submodules/TabBarUI/Sources/TabBarNode.swift | 2 +- .../Sources/CallControllerNode.swift | 86 ++++++++++++++----- .../DefaultDarkPresentationTheme.swift | 2 + .../DefaultDarkTintedPresentationTheme.swift | 2 + .../Sources/DefaultDayPresentationTheme.swift | 2 + .../Sources/PresentationTheme.swift | 14 ++- .../Sources/PresentationThemeCodable.swift | 5 ++ .../Sources/AttachmentFileController.swift | 4 +- .../ChatMessageAnimatedStickerItemNode.swift | 8 +- .../TranslateUI/Sources/TranslateScreen.swift | 1 + .../WebUI/Sources/WebAppController.swift | 12 +-- 19 files changed, 157 insertions(+), 57 deletions(-) diff --git a/submodules/Components/SheetComponent/Sources/SheetComponent.swift b/submodules/Components/SheetComponent/Sources/SheetComponent.swift index 1841395688..8f1dd9b5fc 100644 --- a/submodules/Components/SheetComponent/Sources/SheetComponent.swift +++ b/submodules/Components/SheetComponent/Sources/SheetComponent.swift @@ -6,10 +6,12 @@ import ViewControllerComponent public final class SheetComponentEnvironment: Equatable { public let isDisplaying: Bool + public let isCentered: Bool public let dismiss: (Bool) -> Void - public init(isDisplaying: Bool, dismiss: @escaping (Bool) -> Void) { + public init(isDisplaying: Bool, isCentered: Bool, dismiss: @escaping (Bool) -> Void) { self.isDisplaying = isDisplaying + self.isCentered = isCentered self.dismiss = dismiss } @@ -17,6 +19,9 @@ public final class SheetComponentEnvironment: Equatable { if lhs.isDisplaying != rhs.isDisplaying { return false } + if lhs.isCentered != rhs.isCentered { + return false + } return true } } @@ -180,6 +185,7 @@ public final class SheetComponent: Component { private var currentAvailableSize: CGSize? func update(component: SheetComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment, transition: Transition) -> CGSize { + let sheetEnvironment = environment[SheetComponentEnvironment.self].value component.animateOut.connect { [weak self] completion in guard let strongSelf = self else { return @@ -195,19 +201,36 @@ public final class SheetComponent: Component { transition.setFrame(view: self.dimView, frame: CGRect(origin: CGPoint(), size: availableSize), completion: nil) + let containerSize: CGSize + if sheetEnvironment.isCentered { + let verticalInset: CGFloat = 44.0 + let maxSide = max(availableSize.width, availableSize.height) + let minSide = min(availableSize.width, availableSize.height) + containerSize = CGSize(width: min(availableSize.width - 20.0, floor(maxSide / 2.0)), height: min(availableSize.height, minSide) - verticalInset * 2.0) + } else { + containerSize = CGSize(width: availableSize.width, height: .greatestFiniteMagnitude) + } + let contentSize = self.contentView.update( transition: transition, component: component.content, environment: { environment[ChildEnvironmentType.self] }, - containerSize: CGSize(width: availableSize.width, height: .greatestFiniteMagnitude) + containerSize: containerSize ) self.ignoreScrolling = true - transition.setFrame(view: self.contentView, frame: CGRect(origin: .zero, size: contentSize), completion: nil) - transition.setFrame(view: self.backgroundView, frame: CGRect(origin: .zero, size: CGSize(width: contentSize.width, height: contentSize.height + 1000.0)), completion: nil) + + if sheetEnvironment.isCentered { + transition.setFrame(view: self.contentView, frame: CGRect(origin: CGPoint(x: floorToScreenPixels((availableSize.width - contentSize.width) / 2.0), y: 0.0), size: contentSize), completion: nil) + transition.setFrame(view: self.backgroundView, frame: CGRect(origin: CGPoint(x: floorToScreenPixels((availableSize.width - contentSize.width) / 2.0), y: floorToScreenPixels((availableSize.height - contentSize.height) / 2.0)), size: contentSize), completion: nil) + } else { + transition.setFrame(view: self.contentView, frame: CGRect(origin: .zero, size: contentSize), completion: nil) + transition.setFrame(view: self.backgroundView, frame: CGRect(origin: .zero, size: CGSize(width: contentSize.width, height: contentSize.height + 1000.0)), completion: nil) + } transition.setFrame(view: self.scrollView, frame: CGRect(origin: CGPoint(), size: availableSize), completion: nil) + self.scrollView.contentSize = contentSize self.scrollView.contentInset = UIEdgeInsets(top: max(0.0, availableSize.height - contentSize.height) + contentSize.height, left: 0.0, bottom: 0.0, right: 0.0) self.ignoreScrolling = false @@ -222,9 +245,8 @@ public final class SheetComponent: Component { } else if !environment[SheetComponentEnvironment.self].value.isDisplaying, self.previousIsDisplaying, let _ = transition.userData(ViewControllerComponentContainer.AnimateOutTransition.self) { self.animateOut(completion: {}) } - self.previousIsDisplaying = environment[SheetComponentEnvironment.self].value.isDisplaying - - self.dismiss = environment[SheetComponentEnvironment.self].value.dismiss + self.previousIsDisplaying = sheetEnvironment.isDisplaying + self.dismiss = sheetEnvironment.dismiss return availableSize } diff --git a/submodules/Components/ViewControllerComponent/Sources/ViewControllerComponent.swift b/submodules/Components/ViewControllerComponent/Sources/ViewControllerComponent.swift index ec7dc58860..fcf07de3f0 100644 --- a/submodules/Components/ViewControllerComponent/Sources/ViewControllerComponent.swift +++ b/submodules/Components/ViewControllerComponent/Sources/ViewControllerComponent.swift @@ -69,6 +69,7 @@ open class ViewControllerComponentContainer: ViewController { public let statusBarHeight: CGFloat public let navigationHeight: CGFloat public let safeInsets: UIEdgeInsets + public let metrics: LayoutMetrics public let isVisible: Bool public let theme: PresentationTheme public let strings: PresentationStrings @@ -79,6 +80,7 @@ open class ViewControllerComponentContainer: ViewController { statusBarHeight: CGFloat, navigationHeight: CGFloat, safeInsets: UIEdgeInsets, + metrics: LayoutMetrics, isVisible: Bool, theme: PresentationTheme, strings: PresentationStrings, @@ -88,6 +90,7 @@ open class ViewControllerComponentContainer: ViewController { self.statusBarHeight = statusBarHeight self.navigationHeight = navigationHeight self.safeInsets = safeInsets + self.metrics = metrics self.isVisible = isVisible self.theme = theme self.strings = strings @@ -109,6 +112,9 @@ open class ViewControllerComponentContainer: ViewController { if lhs.safeInsets != rhs.safeInsets { return false } + if lhs.metrics != rhs.metrics { + return false + } if lhs.isVisible != rhs.isVisible { return false } @@ -164,6 +170,7 @@ open class ViewControllerComponentContainer: ViewController { statusBarHeight: layout.statusBarHeight ?? 0.0, navigationHeight: navigationHeight, safeInsets: UIEdgeInsets(top: layout.intrinsicInsets.top + layout.safeInsets.top, left: layout.safeInsets.left, bottom: layout.intrinsicInsets.bottom + layout.safeInsets.bottom, right: layout.safeInsets.right), + metrics: layout.metrics, isVisible: self.currentIsVisible, theme: self.theme ?? self.presentationData.theme, strings: self.presentationData.strings, diff --git a/submodules/ComposePollUI/Sources/CreatePollController.swift b/submodules/ComposePollUI/Sources/CreatePollController.swift index f3fa5ebba8..b7d9c384e9 100644 --- a/submodules/ComposePollUI/Sources/CreatePollController.swift +++ b/submodules/ComposePollUI/Sources/CreatePollController.swift @@ -798,8 +798,8 @@ public func createPollController(context: AccountContext, updatedPresentationDat ) |> map { presentationData, state, limitsConfiguration -> (ItemListControllerState, (ItemListNodeState, Any)) in var presentationData = presentationData - if presentationData.theme.list.blocksBackgroundColor.rgb == 0x000000 { - let updatedTheme = presentationData.theme.withInvertedBlocksBackground() + if presentationData.theme.list.blocksBackgroundColor.rgb == presentationData.theme.list.plainBackgroundColor.rgb { + let updatedTheme = presentationData.theme.withModalBlocksBackground() presentationData = presentationData.withUpdated(theme: updatedTheme) } diff --git a/submodules/PaymentMethodUI/Sources/AddPaymentMethodSheetScreen.swift b/submodules/PaymentMethodUI/Sources/AddPaymentMethodSheetScreen.swift index 444c79c5c5..6b4004236a 100644 --- a/submodules/PaymentMethodUI/Sources/AddPaymentMethodSheetScreen.swift +++ b/submodules/PaymentMethodUI/Sources/AddPaymentMethodSheetScreen.swift @@ -207,6 +207,7 @@ private final class AddPaymentMethodSheetComponent: CombinedComponent { environment SheetComponentEnvironment( isDisplaying: environment.value.isVisible, + isCentered: false, dismiss: { animated in if animated { animateOut.invoke(Action { _ in diff --git a/submodules/PremiumUI/Sources/PremiumDemoScreen.swift b/submodules/PremiumUI/Sources/PremiumDemoScreen.swift index 327de73c3b..d5d47acc03 100644 --- a/submodules/PremiumUI/Sources/PremiumDemoScreen.swift +++ b/submodules/PremiumUI/Sources/PremiumDemoScreen.swift @@ -1102,6 +1102,7 @@ private final class DemoSheetComponent: CombinedComponent { environment SheetComponentEnvironment( isDisplaying: environment.value.isVisible, + isCentered: environment.metrics.widthClass == .regular, dismiss: { animated in if animated { animateOut.invoke(Action { _ in diff --git a/submodules/PremiumUI/Sources/PremiumIntroScreen.swift b/submodules/PremiumUI/Sources/PremiumIntroScreen.swift index 0de0d55b49..3f9a4bb8e7 100644 --- a/submodules/PremiumUI/Sources/PremiumIntroScreen.swift +++ b/submodules/PremiumUI/Sources/PremiumIntroScreen.swift @@ -654,7 +654,7 @@ private final class PerkComponent: CombinedComponent { static var body: Body { let iconBackground = Child(RoundedRectangle.self) let icon = Child(BundleIconComponent.self) - let title = Child(Text.self) + let title = Child(MultilineTextComponent.self) let subtitle = Child(MultilineTextComponent.self) let arrow = Child(BundleIconComponent.self) @@ -665,7 +665,7 @@ private final class PerkComponent: CombinedComponent { let iconTopInset: CGFloat = 15.0 let textTopInset: CGFloat = 9.0 let textBottomInset: CGFloat = 9.0 - let spacing: CGFloat = 3.0 + let spacing: CGFloat = 2.0 let iconSize = CGSize(width: 30.0, height: 30.0) let iconBackground = iconBackground.update( @@ -695,10 +695,16 @@ private final class PerkComponent: CombinedComponent { ) let title = title.update( - component: Text( - text: component.title, - font: Font.regular(17.0), - color: component.titleColor + component: MultilineTextComponent( + text: .plain( + NSAttributedString( + string: component.title, + font: Font.regular(17), + textColor: component.titleColor + ) + ), + maximumNumberOfLines: 0, + lineSpacing: 0.1 ), availableSize: CGSize(width: context.availableSize.width - iconBackground.size.width - sideInset * 2.83, height: context.availableSize.height), transition: context.transition diff --git a/submodules/PremiumUI/Sources/PremiumLimitScreen.swift b/submodules/PremiumUI/Sources/PremiumLimitScreen.swift index 89e3c65778..39abd2487e 100644 --- a/submodules/PremiumUI/Sources/PremiumLimitScreen.swift +++ b/submodules/PremiumUI/Sources/PremiumLimitScreen.swift @@ -1006,6 +1006,7 @@ private final class LimitSheetComponent: CombinedComponent { environment SheetComponentEnvironment( isDisplaying: environment.value.isVisible, + isCentered: environment.metrics.widthClass == .regular, dismiss: { animated in if animated { animateOut.invoke(Action { _ in diff --git a/submodules/PremiumUI/Sources/PremiumLimitsListScreen.swift b/submodules/PremiumUI/Sources/PremiumLimitsListScreen.swift index e4f47cf261..9c083cf901 100644 --- a/submodules/PremiumUI/Sources/PremiumLimitsListScreen.swift +++ b/submodules/PremiumUI/Sources/PremiumLimitsListScreen.swift @@ -617,16 +617,20 @@ public class PremimLimitsListScreen: ViewController { transition.setFrame(view: self.containerView, frame: clipFrame) transition.setFrame(view: self.scrollView, frame: CGRect(origin: CGPoint(), size: clipFrame.size), completion: nil) - let clipLayout = layout.withUpdatedSize(clipFrame.size) + var clipLayout = layout.withUpdatedSize(clipFrame.size) + if case .regular = layout.metrics.widthClass { + clipLayout = clipLayout.withUpdatedIntrinsicInsets(.zero) + } let footerHeight = self.footerNode.updateLayout(layout: clipLayout, transition: .immediate) - let convertedFooterFrame = self.view.convert(CGRect(origin: CGPoint(x: 0.0, y: layout.size.height - footerHeight), size: CGSize(width: clipFrame.width, height: footerHeight)), to: self.containerView) + let convertedFooterFrame = self.view.convert(CGRect(origin: CGPoint(x: clipFrame.minX, y: clipFrame.maxY - footerHeight), size: CGSize(width: clipFrame.width, height: footerHeight)), to: self.containerView) transition.setFrame(view: self.footerNode.view, frame: convertedFooterFrame) let environment = ViewControllerComponentContainer.Environment( statusBarHeight: 0.0, navigationHeight: navigationHeight, safeInsets: UIEdgeInsets(top: layout.intrinsicInsets.top + layout.safeInsets.top, left: layout.safeInsets.left, bottom: footerHeight, right: layout.safeInsets.right), + metrics: layout.metrics, isVisible: self.currentIsVisible, theme: self.theme ?? self.presentationData.theme, strings: self.presentationData.strings, diff --git a/submodules/TabBarUI/Sources/TabBarNode.swift b/submodules/TabBarUI/Sources/TabBarNode.swift index 2251a7ee7e..86ebf72173 100644 --- a/submodules/TabBarUI/Sources/TabBarNode.swift +++ b/submodules/TabBarUI/Sources/TabBarNode.swift @@ -576,7 +576,7 @@ class TabBarNode: ASDisplayNode { ContainedViewLayoutTransition.animated(duration: 0.2, curve: .easeInOut).updateTransformScale(node: node.ringImageNode, scale: 1.0, delay: 0.1) node.imageNode.layer.animateScale(from: 1.0, to: 0.87, duration: 0.1, removeOnCompletion: false, completion: { [weak node] _ in - node?.imageNode.layer.animateScale(from: 0.87, to: 1.0, duration: 0.2, removeOnCompletion: false, completion: { [weak node] _ in + node?.imageNode.layer.animateScale(from: 0.87, to: 1.0, duration: 0.14, removeOnCompletion: false, completion: { [weak node] _ in node?.imageNode.layer.removeAllAnimations() }) }) diff --git a/submodules/TelegramCallsUI/Sources/CallControllerNode.swift b/submodules/TelegramCallsUI/Sources/CallControllerNode.swift index f7baacd111..b612a9711e 100644 --- a/submodules/TelegramCallsUI/Sources/CallControllerNode.swift +++ b/submodules/TelegramCallsUI/Sources/CallControllerNode.swift @@ -16,6 +16,7 @@ import TooltipUI import AlertUI import PresentationDataUtils import DeviceAccess +import ContextUI private func interpolateFrame(from fromValue: CGRect, to toValue: CGRect, t: CGFloat) -> CGRect { return CGRect(x: floorToScreenPixels(toValue.origin.x * t + fromValue.origin.x * (1.0 - t)), y: floorToScreenPixels(toValue.origin.y * t + fromValue.origin.y * (1.0 - t)), width: floorToScreenPixels(toValue.size.width * t + fromValue.size.width * (1.0 - t)), height: floorToScreenPixels(toValue.size.height * t + fromValue.size.height * (1.0 - t))) @@ -200,17 +201,9 @@ private final class CallVideoNode: ASDisplayNode, PreviewVideoNode { case .rotation90: rotationAngle = CGFloat.pi / 2.0 case .rotation180: -// if isCompactLayout { - rotationAngle = CGFloat.pi -// } else { -// rotationAngle = 0.0 -// } + rotationAngle = CGFloat.pi case .rotation270: -// if isCompactLayout { - rotationAngle = -CGFloat.pi / 2.0 -// } else { -// rotationAngle = CGFloat.pi / 2.0 -// } + rotationAngle = -CGFloat.pi / 2.0 } var additionalAngle: CGFloat = 0.0 @@ -375,6 +368,7 @@ final class CallControllerNode: ViewControllerTracingNode, CallControllerNodePro private let containerTransformationNode: ASDisplayNode private let containerNode: ASDisplayNode + private let videoContainerNode: PinchSourceContainerNode private let imageNode: TransformImageNode private let dimNode: ASImageNode @@ -397,7 +391,7 @@ final class CallControllerNode: ViewControllerTracingNode, CallControllerNodePro private var displayedCameraConfirmation: Bool = false private var displayedCameraTooltip: Bool = false - + private var expandedVideoNode: CallVideoNode? private var minimizedVideoNode: CallVideoNode? private var disableAnimationForExpandedVideoOnce: Bool = false @@ -455,6 +449,7 @@ final class CallControllerNode: ViewControllerTracingNode, CallControllerNodePro private var isUIHidden: Bool = false private var isVideoPaused: Bool = false + private var isVideoPinched: Bool = false private enum PictureInPictureGestureState { case none @@ -486,6 +481,8 @@ final class CallControllerNode: ViewControllerTracingNode, CallControllerNodePro self.containerNode = ASDisplayNode() + self.videoContainerNode = PinchSourceContainerNode() + self.imageNode = TransformImageNode() self.imageNode.contentAnimations = [.subsequentUpdates] self.dimNode = ASImageNode() @@ -531,6 +528,7 @@ final class CallControllerNode: ViewControllerTracingNode, CallControllerNodePro } self.containerNode.addSubnode(self.imageNode) + self.containerNode.addSubnode(self.videoContainerNode) self.containerNode.addSubnode(self.dimNode) self.containerNode.addSubnode(self.statusNode) self.containerNode.addSubnode(self.buttonsNode) @@ -711,6 +709,40 @@ final class CallControllerNode: ViewControllerTracingNode, CallControllerNodePro } } }) + + self.videoContainerNode.activate = { [weak self] sourceNode in + guard let strongSelf = self else { + return + } + let pinchController = PinchController(sourceNode: sourceNode, getContentAreaInScreenSpace: { + return UIScreen.main.bounds + }) + strongSelf.sharedContext.mainWindow?.presentInGlobalOverlay(pinchController) + strongSelf.isVideoPinched = true + + strongSelf.videoContainerNode.contentNode.clipsToBounds = true + strongSelf.videoContainerNode.backgroundColor = .black + + if let (layout, navigationBarHeight) = strongSelf.validLayout { + strongSelf.videoContainerNode.contentNode.cornerRadius = layout.deviceMetrics.screenCornerRadius + + strongSelf.containerLayoutUpdated(layout, navigationBarHeight: navigationBarHeight, transition: .immediate) + } + } + + self.videoContainerNode.animatedOut = { [weak self] in + guard let strongSelf = self else { + return + } + strongSelf.isVideoPinched = false + + strongSelf.videoContainerNode.backgroundColor = .clear + strongSelf.videoContainerNode.contentNode.cornerRadius = 0.0 + + if let (layout, navigationBarHeight) = strongSelf.validLayout { + strongSelf.containerLayoutUpdated(layout, navigationBarHeight: navigationBarHeight, transition: .animated(duration: 0.3, curve: .easeInOut)) + } + } } deinit { @@ -830,9 +862,9 @@ final class CallControllerNode: ViewControllerTracingNode, CallControllerNodePro strongSelf.incomingVideoNodeValue = incomingVideoNode if let expandedVideoNode = strongSelf.expandedVideoNode { strongSelf.minimizedVideoNode = expandedVideoNode - strongSelf.containerNode.insertSubnode(incomingVideoNode, belowSubnode: expandedVideoNode) + strongSelf.videoContainerNode.contentNode.insertSubnode(incomingVideoNode, belowSubnode: expandedVideoNode) } else { - strongSelf.containerNode.insertSubnode(incomingVideoNode, belowSubnode: strongSelf.dimNode) + strongSelf.videoContainerNode.contentNode.addSubnode(incomingVideoNode) } strongSelf.expandedVideoNode = incomingVideoNode strongSelf.updateButtonsMode(transition: .animated(duration: 0.4, curve: .spring)) @@ -914,10 +946,10 @@ final class CallControllerNode: ViewControllerTracingNode, CallControllerNodePro strongSelf.outgoingVideoNodeValue = outgoingVideoNode if let expandedVideoNode = strongSelf.expandedVideoNode { strongSelf.minimizedVideoNode = outgoingVideoNode - strongSelf.containerNode.insertSubnode(outgoingVideoNode, aboveSubnode: expandedVideoNode) + strongSelf.videoContainerNode.contentNode.insertSubnode(outgoingVideoNode, aboveSubnode: expandedVideoNode) } else { strongSelf.expandedVideoNode = outgoingVideoNode - strongSelf.containerNode.insertSubnode(outgoingVideoNode, belowSubnode: strongSelf.dimNode) + strongSelf.videoContainerNode.contentNode.addSubnode(outgoingVideoNode) } strongSelf.updateButtonsMode(transition: .animated(duration: 0.4, curve: .spring)) @@ -1140,6 +1172,9 @@ final class CallControllerNode: ViewControllerTracingNode, CallControllerNodePro } self.callEnded?(presentRating) } + + let hasIncomingVideoNode = self.incomingVideoNodeValue != nil && self.expandedVideoNode === self.incomingVideoNodeValue + self.videoContainerNode.isPinchGestureEnabled = hasIncomingVideoNode } private func updateToastContent() { @@ -1481,6 +1516,8 @@ final class CallControllerNode: ViewControllerTracingNode, CallControllerNodePro let pipTransitionAlpha: CGFloat = 1.0 - self.pictureInPictureTransitionFraction uiDisplayTransition *= pipTransitionAlpha + let pinchTransitionAlpha: CGFloat = self.isVideoPinched ? 0.0 : 1.0 + let previousVideoButtonFrame = self.buttonsNode.videoButtonFrame().flatMap { frame -> CGRect in return self.buttonsNode.view.convert(frame, to: self.view) } @@ -1501,8 +1538,8 @@ final class CallControllerNode: ViewControllerTracingNode, CallControllerNodePro let toastCollapsedOriginY = self.pictureInPictureTransitionFraction > 0.0 ? layout.size.height : layout.size.height - max(layout.intrinsicInsets.bottom, 20.0) - toastHeight let toastOriginY = interpolate(from: toastCollapsedOriginY, to: defaultButtonsOriginY - toastSpacing - toastHeight, value: uiDisplayTransition) - var overlayAlpha: CGFloat = uiDisplayTransition - var toastAlpha: CGFloat = pipTransitionAlpha + var overlayAlpha: CGFloat = min(pinchTransitionAlpha, uiDisplayTransition) + var toastAlpha: CGFloat = min(pinchTransitionAlpha, pipTransitionAlpha) switch self.callState?.state { case .terminated, .terminating: @@ -1522,14 +1559,18 @@ final class CallControllerNode: ViewControllerTracingNode, CallControllerNodePro transition.updateCornerRadius(layer: self.containerTransformationNode.layer, cornerRadius: self.pictureInPictureTransitionFraction * 10.0) transition.updateFrame(node: self.containerNode, frame: CGRect(origin: CGPoint(x: (containerFrame.width - layout.size.width) / 2.0, y: floor(containerFrame.height - layout.size.height) / 2.0), size: layout.size)) - transition.updateFrame(node: self.dimNode, frame: CGRect(origin: CGPoint(), size: layout.size)) + transition.updateFrame(node: self.videoContainerNode, frame: containerFullScreenFrame) + self.videoContainerNode.update(size: containerFullScreenFrame.size, transition: transition) + + transition.updateAlpha(node: self.dimNode, alpha: pinchTransitionAlpha) + transition.updateFrame(node: self.dimNode, frame: containerFullScreenFrame) if let keyPreviewNode = self.keyPreviewNode { - transition.updateFrame(node: keyPreviewNode, frame: CGRect(origin: CGPoint(), size: layout.size)) + transition.updateFrame(node: keyPreviewNode, frame: containerFullScreenFrame) keyPreviewNode.updateLayout(size: layout.size, transition: .immediate) } - transition.updateFrame(node: self.imageNode, frame: CGRect(origin: CGPoint(), size: layout.size)) + transition.updateFrame(node: self.imageNode, frame: containerFullScreenFrame) let arguments = TransformImageArguments(corners: ImageCorners(), imageSize: CGSize(width: 640.0, height: 640.0).aspectFilled(layout.size), boundingSize: layout.size, intrinsicInsets: UIEdgeInsets()) let apply = self.imageNode.asyncLayout()(arguments) apply() @@ -1574,8 +1615,7 @@ final class CallControllerNode: ViewControllerTracingNode, CallControllerNodePro transition.updateFrame(node: self.buttonsNode, frame: CGRect(origin: CGPoint(x: 0.0, y: buttonsOriginY), size: CGSize(width: layout.size.width, height: buttonsHeight))) transition.updateAlpha(node: self.buttonsNode, alpha: overlayAlpha) - let fullscreenVideoFrame = CGRect(origin: CGPoint(), size: layout.size) - + let fullscreenVideoFrame = containerFullScreenFrame let previewVideoFrame = self.calculatePreviewVideoRect(layout: layout, navigationHeight: navigationBarHeight) if let removedMinimizedVideoNodeValue = self.removedMinimizedVideoNodeValue { @@ -1640,7 +1680,7 @@ final class CallControllerNode: ViewControllerTracingNode, CallControllerNodePro if let minimizedVideoNode = self.minimizedVideoNode { - transition.updateAlpha(node: minimizedVideoNode, alpha: pipTransitionAlpha) + transition.updateAlpha(node: minimizedVideoNode, alpha: min(pipTransitionAlpha, pinchTransitionAlpha)) var minimizedVideoTransition = transition var didAppear = false if minimizedVideoNode.frame.isEmpty { diff --git a/submodules/TelegramPresentationData/Sources/DefaultDarkPresentationTheme.swift b/submodules/TelegramPresentationData/Sources/DefaultDarkPresentationTheme.swift index 3b9353eac5..6d186f0120 100644 --- a/submodules/TelegramPresentationData/Sources/DefaultDarkPresentationTheme.swift +++ b/submodules/TelegramPresentationData/Sources/DefaultDarkPresentationTheme.swift @@ -376,6 +376,7 @@ public func makeDefaultDarkPresentationTheme(extendingThemeReference: Presentati let list = PresentationThemeList( blocksBackgroundColor: UIColor(rgb: 0x000000), + modalBlocksBackgroundColor: UIColor(rgb: 0x1c1c1d), plainBackgroundColor: UIColor(rgb: 0x000000), itemPrimaryTextColor: UIColor(rgb: 0xffffff), itemSecondaryTextColor: UIColor(rgb: 0x98989e), @@ -385,6 +386,7 @@ public func makeDefaultDarkPresentationTheme(extendingThemeReference: Presentati itemDestructiveColor: UIColor(rgb: 0xeb5545), itemPlaceholderTextColor: UIColor(rgb: 0x4d4d4d), itemBlocksBackgroundColor: UIColor(rgb: 0x1c1c1d), + itemModalBlocksBackgroundColor: UIColor(rgb: 0x2c2c2e), itemHighlightedBackgroundColor: UIColor(rgb: 0x313135), itemBlocksSeparatorColor: UIColor(rgb: 0x3d3d40), itemPlainSeparatorColor: UIColor(rgb: 0x3d3d40), diff --git a/submodules/TelegramPresentationData/Sources/DefaultDarkTintedPresentationTheme.swift b/submodules/TelegramPresentationData/Sources/DefaultDarkTintedPresentationTheme.swift index 72fed52de5..234bfd7798 100644 --- a/submodules/TelegramPresentationData/Sources/DefaultDarkTintedPresentationTheme.swift +++ b/submodules/TelegramPresentationData/Sources/DefaultDarkTintedPresentationTheme.swift @@ -604,6 +604,7 @@ public func makeDefaultDarkTintedPresentationTheme(extendingThemeReference: Pres let list = PresentationThemeList( blocksBackgroundColor: additionalBackgroundColor, + modalBlocksBackgroundColor: additionalBackgroundColor, plainBackgroundColor: additionalBackgroundColor, itemPrimaryTextColor: UIColor(rgb: 0xffffff), itemSecondaryTextColor: mainSecondaryTextColor.withAlphaComponent(0.5), @@ -613,6 +614,7 @@ public func makeDefaultDarkTintedPresentationTheme(extendingThemeReference: Pres itemDestructiveColor: UIColor(rgb: 0xff6767), itemPlaceholderTextColor: mainSecondaryTextColor.withAlphaComponent(0.5), itemBlocksBackgroundColor: mainBackgroundColor, + itemModalBlocksBackgroundColor: mainBackgroundColor, itemHighlightedBackgroundColor: mainSelectionColor, itemBlocksSeparatorColor: mainSeparatorColor, itemPlainSeparatorColor: mainSeparatorColor, diff --git a/submodules/TelegramPresentationData/Sources/DefaultDayPresentationTheme.swift b/submodules/TelegramPresentationData/Sources/DefaultDayPresentationTheme.swift index 29264c7f62..573f275c9f 100644 --- a/submodules/TelegramPresentationData/Sources/DefaultDayPresentationTheme.swift +++ b/submodules/TelegramPresentationData/Sources/DefaultDayPresentationTheme.swift @@ -447,6 +447,7 @@ public func makeDefaultDayPresentationTheme(extendingThemeReference: Presentatio let list = PresentationThemeList( blocksBackgroundColor: UIColor(rgb: 0xefeff4), + modalBlocksBackgroundColor: UIColor(rgb: 0xefeff4), plainBackgroundColor: UIColor(rgb: 0xffffff), itemPrimaryTextColor: UIColor(rgb: 0x000000), itemSecondaryTextColor: UIColor(rgb: 0x8e8e93), @@ -456,6 +457,7 @@ public func makeDefaultDayPresentationTheme(extendingThemeReference: Presentatio itemDestructiveColor: UIColor(rgb: 0xff3b30), itemPlaceholderTextColor: UIColor(rgb: 0xc8c8ce), itemBlocksBackgroundColor: UIColor(rgb: 0xffffff), + itemModalBlocksBackgroundColor: UIColor(rgb: 0xffffff), itemHighlightedBackgroundColor: UIColor(rgb: 0xe5e5ea), itemBlocksSeparatorColor: UIColor(rgb: 0xc8c7cc), itemPlainSeparatorColor: UIColor(rgb: 0xc8c7cc), diff --git a/submodules/TelegramPresentationData/Sources/PresentationTheme.swift b/submodules/TelegramPresentationData/Sources/PresentationTheme.swift index 23e60ea57f..85cbcefa86 100644 --- a/submodules/TelegramPresentationData/Sources/PresentationTheme.swift +++ b/submodules/TelegramPresentationData/Sources/PresentationTheme.swift @@ -428,6 +428,7 @@ public final class PresentationThemeList { public let blocksBackgroundColor: UIColor public let plainBackgroundColor: UIColor + public let modalBlocksBackgroundColor: UIColor public let itemPrimaryTextColor: UIColor public let itemSecondaryTextColor: UIColor public let itemDisabledTextColor: UIColor @@ -436,6 +437,7 @@ public final class PresentationThemeList { public let itemDestructiveColor: UIColor public let itemPlaceholderTextColor: UIColor public let itemBlocksBackgroundColor: UIColor + public let itemModalBlocksBackgroundColor: UIColor public let itemHighlightedBackgroundColor: UIColor public let itemBlocksSeparatorColor: UIColor public let itemPlainSeparatorColor: UIColor @@ -461,6 +463,7 @@ public final class PresentationThemeList { public init( blocksBackgroundColor: UIColor, + modalBlocksBackgroundColor: UIColor, plainBackgroundColor: UIColor, itemPrimaryTextColor: UIColor, itemSecondaryTextColor: UIColor, @@ -470,6 +473,7 @@ public final class PresentationThemeList { itemDestructiveColor: UIColor, itemPlaceholderTextColor: UIColor, itemBlocksBackgroundColor: UIColor, + itemModalBlocksBackgroundColor: UIColor, itemHighlightedBackgroundColor: UIColor, itemBlocksSeparatorColor: UIColor, itemPlainSeparatorColor: UIColor, @@ -494,6 +498,7 @@ public final class PresentationThemeList { paymentOption: PaymentOption ) { self.blocksBackgroundColor = blocksBackgroundColor + self.modalBlocksBackgroundColor = modalBlocksBackgroundColor self.plainBackgroundColor = plainBackgroundColor self.itemPrimaryTextColor = itemPrimaryTextColor self.itemSecondaryTextColor = itemSecondaryTextColor @@ -505,6 +510,7 @@ public final class PresentationThemeList { self.itemBlocksBackgroundColor = itemBlocksBackgroundColor self.itemHighlightedBackgroundColor = itemHighlightedBackgroundColor self.itemBlocksSeparatorColor = itemBlocksSeparatorColor + self.itemModalBlocksBackgroundColor = itemModalBlocksBackgroundColor self.itemPlainSeparatorColor = itemPlainSeparatorColor self.disclosureArrowColor = disclosureArrowColor self.sectionHeaderTextColor = sectionHeaderTextColor @@ -527,8 +533,8 @@ public final class PresentationThemeList { self.paymentOption = paymentOption } - public func withUpdated(blocksBackgroundColor: UIColor? = nil, plainBackgroundColor: UIColor? = nil, itemPrimaryTextColor: UIColor? = nil, itemSecondaryTextColor: UIColor? = nil, itemDisabledTextColor: UIColor? = nil, itemAccentColor: UIColor? = nil, itemHighlightedColor: UIColor? = nil, itemDestructiveColor: UIColor? = nil, itemPlaceholderTextColor: UIColor? = nil, itemBlocksBackgroundColor: UIColor? = nil, itemHighlightedBackgroundColor: UIColor? = nil, itemBlocksSeparatorColor: UIColor? = nil, itemPlainSeparatorColor: UIColor? = nil, disclosureArrowColor: UIColor? = nil, sectionHeaderTextColor: UIColor? = nil, freeTextColor: UIColor? = nil, freeTextErrorColor: UIColor? = nil, freeTextSuccessColor: UIColor? = nil, freeMonoIconColor: UIColor? = nil, itemSwitchColors: PresentationThemeSwitch? = nil, itemDisclosureActions: PresentationThemeItemDisclosureActions? = nil, itemCheckColors: PresentationThemeFillStrokeForeground? = nil, controlSecondaryColor: UIColor? = nil, freeInputField: PresentationInputFieldTheme? = nil, freePlainInputField: PresentationInputFieldTheme? = nil, mediaPlaceholderColor: UIColor? = nil, scrollIndicatorColor: UIColor? = nil, pageIndicatorInactiveColor: UIColor? = nil, inputClearButtonColor: UIColor? = nil, itemBarChart: PresentationThemeItemBarChart? = nil, itemInputField: PresentationInputFieldTheme? = nil, paymentOption: PaymentOption? = nil) -> PresentationThemeList { - return PresentationThemeList(blocksBackgroundColor: blocksBackgroundColor ?? self.blocksBackgroundColor, plainBackgroundColor: plainBackgroundColor ?? self.plainBackgroundColor, itemPrimaryTextColor: itemPrimaryTextColor ?? self.itemPrimaryTextColor, itemSecondaryTextColor: itemSecondaryTextColor ?? self.itemSecondaryTextColor, itemDisabledTextColor: itemDisabledTextColor ?? self.itemDisabledTextColor, itemAccentColor: itemAccentColor ?? self.itemAccentColor, itemHighlightedColor: itemHighlightedColor ?? self.itemHighlightedColor, itemDestructiveColor: itemDestructiveColor ?? self.itemDestructiveColor, itemPlaceholderTextColor: itemPlaceholderTextColor ?? self.itemPlaceholderTextColor, itemBlocksBackgroundColor: itemBlocksBackgroundColor ?? self.itemBlocksBackgroundColor, itemHighlightedBackgroundColor: itemHighlightedBackgroundColor ?? self.itemHighlightedBackgroundColor, itemBlocksSeparatorColor: itemBlocksSeparatorColor ?? self.itemBlocksSeparatorColor, itemPlainSeparatorColor: itemPlainSeparatorColor ?? self.itemPlainSeparatorColor, disclosureArrowColor: disclosureArrowColor ?? self.disclosureArrowColor, sectionHeaderTextColor: sectionHeaderTextColor ?? self.sectionHeaderTextColor, freeTextColor: freeTextColor ?? self.freeTextColor, freeTextErrorColor: freeTextErrorColor ?? self.freeTextErrorColor, freeTextSuccessColor: freeTextSuccessColor ?? self.freeTextSuccessColor, freeMonoIconColor: freeMonoIconColor ?? self.freeMonoIconColor, itemSwitchColors: itemSwitchColors ?? self.itemSwitchColors, itemDisclosureActions: itemDisclosureActions ?? self.itemDisclosureActions, itemCheckColors: itemCheckColors ?? self.itemCheckColors, controlSecondaryColor: controlSecondaryColor ?? self.controlSecondaryColor, freeInputField: freeInputField ?? self.freeInputField, freePlainInputField: freePlainInputField ?? self.freePlainInputField, mediaPlaceholderColor: mediaPlaceholderColor ?? self.mediaPlaceholderColor, scrollIndicatorColor: scrollIndicatorColor ?? self.scrollIndicatorColor, pageIndicatorInactiveColor: pageIndicatorInactiveColor ?? self.pageIndicatorInactiveColor, inputClearButtonColor: inputClearButtonColor ?? self.inputClearButtonColor, itemBarChart: itemBarChart ?? self.itemBarChart, itemInputField: itemInputField ?? self.itemInputField, paymentOption: paymentOption ?? self.paymentOption) + public func withUpdated(blocksBackgroundColor: UIColor? = nil, modalBlocksBackgroundColor: UIColor? = nil, plainBackgroundColor: UIColor? = nil, itemPrimaryTextColor: UIColor? = nil, itemSecondaryTextColor: UIColor? = nil, itemDisabledTextColor: UIColor? = nil, itemAccentColor: UIColor? = nil, itemHighlightedColor: UIColor? = nil, itemDestructiveColor: UIColor? = nil, itemPlaceholderTextColor: UIColor? = nil, itemBlocksBackgroundColor: UIColor? = nil, itemModalBlocksBackgroundColor: UIColor? = nil, itemHighlightedBackgroundColor: UIColor? = nil, itemBlocksSeparatorColor: UIColor? = nil, itemPlainSeparatorColor: UIColor? = nil, disclosureArrowColor: UIColor? = nil, sectionHeaderTextColor: UIColor? = nil, freeTextColor: UIColor? = nil, freeTextErrorColor: UIColor? = nil, freeTextSuccessColor: UIColor? = nil, freeMonoIconColor: UIColor? = nil, itemSwitchColors: PresentationThemeSwitch? = nil, itemDisclosureActions: PresentationThemeItemDisclosureActions? = nil, itemCheckColors: PresentationThemeFillStrokeForeground? = nil, controlSecondaryColor: UIColor? = nil, freeInputField: PresentationInputFieldTheme? = nil, freePlainInputField: PresentationInputFieldTheme? = nil, mediaPlaceholderColor: UIColor? = nil, scrollIndicatorColor: UIColor? = nil, pageIndicatorInactiveColor: UIColor? = nil, inputClearButtonColor: UIColor? = nil, itemBarChart: PresentationThemeItemBarChart? = nil, itemInputField: PresentationInputFieldTheme? = nil, paymentOption: PaymentOption? = nil) -> PresentationThemeList { + return PresentationThemeList(blocksBackgroundColor: blocksBackgroundColor ?? self.blocksBackgroundColor, modalBlocksBackgroundColor: modalBlocksBackgroundColor ?? self.modalBlocksBackgroundColor, plainBackgroundColor: plainBackgroundColor ?? self.plainBackgroundColor, itemPrimaryTextColor: itemPrimaryTextColor ?? self.itemPrimaryTextColor, itemSecondaryTextColor: itemSecondaryTextColor ?? self.itemSecondaryTextColor, itemDisabledTextColor: itemDisabledTextColor ?? self.itemDisabledTextColor, itemAccentColor: itemAccentColor ?? self.itemAccentColor, itemHighlightedColor: itemHighlightedColor ?? self.itemHighlightedColor, itemDestructiveColor: itemDestructiveColor ?? self.itemDestructiveColor, itemPlaceholderTextColor: itemPlaceholderTextColor ?? self.itemPlaceholderTextColor, itemBlocksBackgroundColor: itemBlocksBackgroundColor ?? self.itemBlocksBackgroundColor, itemModalBlocksBackgroundColor: itemModalBlocksBackgroundColor ?? self.itemModalBlocksBackgroundColor, itemHighlightedBackgroundColor: itemHighlightedBackgroundColor ?? self.itemHighlightedBackgroundColor, itemBlocksSeparatorColor: itemBlocksSeparatorColor ?? self.itemBlocksSeparatorColor, itemPlainSeparatorColor: itemPlainSeparatorColor ?? self.itemPlainSeparatorColor, disclosureArrowColor: disclosureArrowColor ?? self.disclosureArrowColor, sectionHeaderTextColor: sectionHeaderTextColor ?? self.sectionHeaderTextColor, freeTextColor: freeTextColor ?? self.freeTextColor, freeTextErrorColor: freeTextErrorColor ?? self.freeTextErrorColor, freeTextSuccessColor: freeTextSuccessColor ?? self.freeTextSuccessColor, freeMonoIconColor: freeMonoIconColor ?? self.freeMonoIconColor, itemSwitchColors: itemSwitchColors ?? self.itemSwitchColors, itemDisclosureActions: itemDisclosureActions ?? self.itemDisclosureActions, itemCheckColors: itemCheckColors ?? self.itemCheckColors, controlSecondaryColor: controlSecondaryColor ?? self.controlSecondaryColor, freeInputField: freeInputField ?? self.freeInputField, freePlainInputField: freePlainInputField ?? self.freePlainInputField, mediaPlaceholderColor: mediaPlaceholderColor ?? self.mediaPlaceholderColor, scrollIndicatorColor: scrollIndicatorColor ?? self.scrollIndicatorColor, pageIndicatorInactiveColor: pageIndicatorInactiveColor ?? self.pageIndicatorInactiveColor, inputClearButtonColor: inputClearButtonColor ?? self.inputClearButtonColor, itemBarChart: itemBarChart ?? self.itemBarChart, itemInputField: itemInputField ?? self.itemInputField, paymentOption: paymentOption ?? self.paymentOption) } } @@ -1479,8 +1485,8 @@ public final class PresentationTheme: Equatable { return PresentationTheme(name: self.name, index: self.index, referenceTheme: self.referenceTheme, overallDarkAppearance: self.overallDarkAppearance, intro: self.intro, passcode: self.passcode, rootController: self.rootController, list: self.list, chatList: self.chatList, chat: self.chat, actionSheet: self.actionSheet, contextMenu: self.contextMenu, inAppNotification: self.inAppNotification, chart: self.chart, preview: preview) } - public func withInvertedBlocksBackground() -> PresentationTheme { - let list = self.list.withUpdated(blocksBackgroundColor: self.list.itemBlocksBackgroundColor, itemBlocksBackgroundColor: self.list.blocksBackgroundColor) + public func withModalBlocksBackground() -> PresentationTheme { + let list = self.list.withUpdated(blocksBackgroundColor: self.list.modalBlocksBackgroundColor, itemBlocksBackgroundColor: self.list.itemModalBlocksBackgroundColor) return PresentationTheme(name: self.name, index: self.index, referenceTheme: self.referenceTheme, overallDarkAppearance: self.overallDarkAppearance, intro: self.intro, passcode: self.passcode, rootController: self.rootController, list: list, chatList: self.chatList, chat: self.chat, actionSheet: self.actionSheet, contextMenu: self.contextMenu, inAppNotification: self.inAppNotification, chart: self.chart, preview: self.preview) } } diff --git a/submodules/TelegramPresentationData/Sources/PresentationThemeCodable.swift b/submodules/TelegramPresentationData/Sources/PresentationThemeCodable.swift index f69eae26b8..fcd002deb2 100644 --- a/submodules/TelegramPresentationData/Sources/PresentationThemeCodable.swift +++ b/submodules/TelegramPresentationData/Sources/PresentationThemeCodable.swift @@ -813,6 +813,7 @@ extension PresentationThemeList.PaymentOption: Codable { extension PresentationThemeList: Codable { enum CodingKeys: String, CodingKey { case blocksBg + case modalBlocksBg case plainBg case primaryText case secondaryText @@ -822,6 +823,7 @@ extension PresentationThemeList: Codable { case destructive case placeholderText case itemBlocksBg + case itemModalBlocksBg case itemHighlightedBg case blocksSeparator case plainSeparator @@ -848,6 +850,7 @@ extension PresentationThemeList: Codable { public convenience init(from decoder: Decoder) throws { let values = try decoder.container(keyedBy: CodingKeys.self) + let codingPath = decoder.codingPath.map { $0.stringValue }.joined(separator: ".") let freePlainInputField: PresentationInputFieldTheme if let value = try? values.decode(PresentationInputFieldTheme.self, forKey: .freePlainInputField) { @@ -860,6 +863,7 @@ extension PresentationThemeList: Codable { self.init( blocksBackgroundColor: try decodeColor(values, .blocksBg), + modalBlocksBackgroundColor: try decodeColor(values, .modalBlocksBg, fallbackKey: "\(codingPath).blocksBg"), plainBackgroundColor: try decodeColor(values, .plainBg), itemPrimaryTextColor: try decodeColor(values, .primaryText), itemSecondaryTextColor: try decodeColor(values, .secondaryText), @@ -869,6 +873,7 @@ extension PresentationThemeList: Codable { itemDestructiveColor: try decodeColor(values, .destructive), itemPlaceholderTextColor: try decodeColor(values, .placeholderText), itemBlocksBackgroundColor: try decodeColor(values, .itemBlocksBg), + itemModalBlocksBackgroundColor: try decodeColor(values, .itemModalBlocksBg, fallbackKey: "\(codingPath).itemBlocksBg"), itemHighlightedBackgroundColor: try decodeColor(values, .itemHighlightedBg), itemBlocksSeparatorColor: try decodeColor(values, .blocksSeparator), itemPlainSeparatorColor: try decodeColor(values, .plainSeparator), diff --git a/submodules/TelegramUI/Sources/AttachmentFileController.swift b/submodules/TelegramUI/Sources/AttachmentFileController.swift index ef8dba066a..7860dbbf9f 100644 --- a/submodules/TelegramUI/Sources/AttachmentFileController.swift +++ b/submodules/TelegramUI/Sources/AttachmentFileController.swift @@ -239,8 +239,8 @@ public func attachmentFileController(context: AccountContext, updatedPresentatio ) |> map { presentationData, recentDocuments, state -> (ItemListControllerState, (ItemListNodeState, Any)) in var presentationData = presentationData - if presentationData.theme.list.blocksBackgroundColor.rgb == 0x000000 { - let updatedTheme = presentationData.theme.withInvertedBlocksBackground() + if presentationData.theme.list.blocksBackgroundColor.rgb == presentationData.theme.list.plainBackgroundColor.rgb { + let updatedTheme = presentationData.theme.withModalBlocksBackground() presentationData = presentationData.withUpdated(theme: updatedTheme) } diff --git a/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift index 5da4d930e0..f519798185 100644 --- a/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift @@ -1352,7 +1352,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { strongSelf.addSubnode(deliveryFailedNode) } let deliveryFailedSize = deliveryFailedNode.updateLayout(theme: item.presentationData.theme.theme) - let deliveryFailedFrame = CGRect(origin: CGPoint(x: imageFrame.maxX + deliveryFailedInset - deliveryFailedSize.width, y: imageFrame.maxY - deliveryFailedSize.height - imageInset), size: deliveryFailedSize) + let deliveryFailedFrame = CGRect(origin: CGPoint(x: imageFrame.maxX + deliveryFailedInset - deliveryFailedSize.width, y: imageFrame.maxY - deliveryFailedSize.height - imageInset + imageVerticalInset), size: deliveryFailedSize) if isAppearing { deliveryFailedNode.frame = deliveryFailedFrame transition.animatePositionAdditive(node: deliveryFailedNode, offset: CGPoint(x: deliveryFailedInset, y: 0.0)) @@ -1370,7 +1370,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { if let actionButtonsSizeAndApply = actionButtonsSizeAndApply { let actionButtonsNode = actionButtonsSizeAndApply.1(animation) let previousFrame = actionButtonsNode.frame - let actionButtonsFrame = CGRect(origin: CGPoint(x: imageFrame.minX, y: imageFrame.maxY), size: actionButtonsSizeAndApply.0) + let actionButtonsFrame = CGRect(origin: CGPoint(x: imageFrame.minX, y: imageFrame.maxY + imageVerticalInset), size: actionButtonsSizeAndApply.0) actionButtonsNode.frame = actionButtonsFrame if actionButtonsNode !== strongSelf.actionButtonsNode { strongSelf.actionButtonsNode = actionButtonsNode @@ -1397,7 +1397,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { if let reactionButtonsSizeAndApply = reactionButtonsSizeAndApply { let reactionButtonsNode = reactionButtonsSizeAndApply.1(animation) - var reactionButtonsFrame = CGRect(origin: CGPoint(x: imageFrame.minX, y: imageFrame.maxY), size: reactionButtonsSizeAndApply.0) + var reactionButtonsFrame = CGRect(origin: CGPoint(x: imageFrame.minX, y: imageFrame.maxY + imageVerticalInset), size: reactionButtonsSizeAndApply.0) if !incoming { reactionButtonsFrame.origin.x = imageFrame.maxX - reactionButtonsSizeAndApply.0.width } @@ -1689,7 +1689,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { var animationFrame: CGRect if isStickerEffect { let scale: CGFloat = 0.245 - animationFrame = animationNode.frame.offsetBy(dx: incomingMessage ? animationNode.frame.width * scale : -animationNode.frame.width * scale + 21.0, dy: -1.0).insetBy(dx: -animationNode.frame.width * scale, dy: -animationNode.frame.height * scale) + animationFrame = animationNode.frame.offsetBy(dx: incomingMessage ? animationNode.frame.width * scale - 21.0 : -animationNode.frame.width * scale + 21.0, dy: -1.0).insetBy(dx: -animationNode.frame.width * scale, dy: -animationNode.frame.height * scale) } else { animationFrame = animationNode.frame.insetBy(dx: -animationNode.frame.width, dy: -animationNode.frame.height) .offsetBy(dx: incomingMessage ? animationNode.frame.width - 10.0 : -animationNode.frame.width + 10.0, dy: 0.0) diff --git a/submodules/TranslateUI/Sources/TranslateScreen.swift b/submodules/TranslateUI/Sources/TranslateScreen.swift index 2cc5b5c46b..bf6098d0d0 100644 --- a/submodules/TranslateUI/Sources/TranslateScreen.swift +++ b/submodules/TranslateUI/Sources/TranslateScreen.swift @@ -720,6 +720,7 @@ public class TranslateScreen: ViewController { statusBarHeight: 0.0, navigationHeight: navigationHeight, safeInsets: UIEdgeInsets(top: layout.intrinsicInsets.top + layout.safeInsets.top, left: layout.safeInsets.left, bottom: layout.intrinsicInsets.bottom + layout.safeInsets.bottom, right: layout.safeInsets.right), + metrics: layout.metrics, isVisible: self.currentIsVisible, theme: self.theme ?? self.presentationData.theme, strings: self.presentationData.strings, diff --git a/submodules/WebUI/Sources/WebAppController.swift b/submodules/WebUI/Sources/WebAppController.swift index 71efdf5e6b..bd5958885d 100644 --- a/submodules/WebUI/Sources/WebAppController.swift +++ b/submodules/WebUI/Sources/WebAppController.swift @@ -161,9 +161,9 @@ public struct WebAppParameters { public func generateWebAppThemeParams(_ presentationTheme: PresentationTheme) -> [String: Any] { var backgroundColor = presentationTheme.list.plainBackgroundColor.rgb var secondaryBackgroundColor = presentationTheme.list.blocksBackgroundColor.rgb - if backgroundColor == 0x000000 { - backgroundColor = presentationTheme.list.itemBlocksBackgroundColor.rgb - secondaryBackgroundColor = presentationTheme.list.itemBlocksBackgroundColor.rgb + if presentationTheme.list.blocksBackgroundColor.rgb == presentationTheme.list.plainBackgroundColor.rgb { + backgroundColor = presentationTheme.list.modalBlocksBackgroundColor.rgb + secondaryBackgroundColor = presentationTheme.list.plainBackgroundColor.rgb } return [ "bg_color": Int32(bitPattern: backgroundColor), @@ -733,9 +733,9 @@ public final class WebAppController: ViewController, AttachmentContainable { let color: UIColor? var backgroundColor = self.presentationData.theme.list.plainBackgroundColor var secondaryBackgroundColor = self.presentationData.theme.list.blocksBackgroundColor - if backgroundColor.rgb == 0x000000 { - backgroundColor = self.presentationData.theme.list.itemBlocksBackgroundColor - secondaryBackgroundColor = self.presentationData.theme.list.itemBlocksBackgroundColor + if self.presentationData.theme.list.blocksBackgroundColor.rgb == self.presentationData.theme.list.plainBackgroundColor.rgb { + backgroundColor = self.presentationData.theme.list.modalBlocksBackgroundColor + secondaryBackgroundColor = self.presentationData.theme.list.plainBackgroundColor } if let headerColorKey = self.headerColorKey { switch headerColorKey { From ab721eed159285646c97121ece577926081a8006 Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Fri, 17 Jun 2022 00:39:22 +0400 Subject: [PATCH 02/16] Localize app icons --- Telegram/Telegram-iOS/en.lproj/Localizable.strings | 4 ++++ .../Sources/Themes/ThemeSettingsAppIconItem.swift | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/Telegram/Telegram-iOS/en.lproj/Localizable.strings b/Telegram/Telegram-iOS/en.lproj/Localizable.strings index 723ca92073..4f2eeb4d95 100644 --- a/Telegram/Telegram-iOS/en.lproj/Localizable.strings +++ b/Telegram/Telegram-iOS/en.lproj/Localizable.strings @@ -7731,3 +7731,7 @@ Sorry for the inconvenience."; "Settings.AddAnotherAccount.PremiumHelp" = "You can add up to four accounts with different phone numbers."; "Stickers.TrendingPremiumStickers" = "Trending Premium Stickers"; + +"Appearance.AppIconPremium" = "Premium"; +"Appearance.AppIconBlack" = "Black"; +"Appearance.AppIconTurbo" = "Turbo"; diff --git a/submodules/SettingsUI/Sources/Themes/ThemeSettingsAppIconItem.swift b/submodules/SettingsUI/Sources/Themes/ThemeSettingsAppIconItem.swift index ea6d3fa44d..c4096e6214 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeSettingsAppIconItem.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeSettingsAppIconItem.swift @@ -345,11 +345,11 @@ class ThemeSettingsAppIconItemNode: ListViewItemNode, ItemListItemNode { case "New2": name = item.strings.Appearance_AppIconNew2 case "Premium": - name = "Premium" + name = item.strings.Appearance_AppIconPremium case "PremiumBlack": - name = "Black" + name = item.strings.Appearance_AppIconBlack case "PremiumTurbo": - name = "Turbo" + name = item.strings.Appearance_AppIconTurbo default: name = icon.name } From 3892e07a910069885fe5c295301d8c8c4c6ecba7 Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Fri, 17 Jun 2022 20:57:23 +0400 Subject: [PATCH 03/16] Remove local check --- submodules/PremiumUI/Sources/PremiumIntroScreen.swift | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/submodules/PremiumUI/Sources/PremiumIntroScreen.swift b/submodules/PremiumUI/Sources/PremiumIntroScreen.swift index 3f9a4bb8e7..69301eaacd 100644 --- a/submodules/PremiumUI/Sources/PremiumIntroScreen.swift +++ b/submodules/PremiumUI/Sources/PremiumIntroScreen.swift @@ -1398,14 +1398,7 @@ private final class PremiumIntroScreenComponent: CombinedComponent { let premiumProduct = self.premiumProduct, !self.inProgress else { return } - - guard !self.context.account.testingEnvironment else { - let presentationData = self.context.sharedContext.currentPresentationData.with { $0 } - let alertController = textAlertController(context: self.context, title: nil, text: "Telegram Premium is not available in the test environment.", actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]) - self.present(alertController) - return - } - + addAppLogEvent(postbox: self.context.account.postbox, type: "premium.promo_screen_accept") self.inProgress = true From d9d9e9ef24fb699d232b8f890941a2b3b9f50ce2 Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Mon, 20 Jun 2022 15:33:34 +0500 Subject: [PATCH 04/16] Various fixes --- .../Sources/ChannelVisibilityController.swift | 85 +++++++------------ .../Sources/PhotoResources.swift | 6 +- 2 files changed, 30 insertions(+), 61 deletions(-) diff --git a/submodules/PeerInfoUI/Sources/ChannelVisibilityController.swift b/submodules/PeerInfoUI/Sources/ChannelVisibilityController.swift index 7734dc5774..3e60943bf1 100644 --- a/submodules/PeerInfoUI/Sources/ChannelVisibilityController.swift +++ b/submodules/PeerInfoUI/Sources/ChannelVisibilityController.swift @@ -847,7 +847,7 @@ private func channelVisibilityControllerEntries(presentationData: PresentationDa } var isDiscussion = false - if let cachedData = view.cachedData as? CachedChannelData, case .known = cachedData.linkedDiscussionPeerId { + if let cachedData = view.cachedData as? CachedChannelData, case let .known(peerId) = cachedData.linkedDiscussionPeerId, peerId != nil { isDiscussion = true } @@ -934,67 +934,40 @@ private func channelVisibilityControllerEntries(presentationData: PresentationDa switch selectedType { case .publicChannel: - let displayAvailability = publicChannelsToRevoke == nil || !(publicChannelsToRevoke!.isEmpty) - - if displayAvailability { - if let publicChannelsToRevoke = publicChannelsToRevoke { - // entries.append(.linksLimitInfo(presentationData.theme, presentationData.strings.Group_Username_RemoveExistingUsernamesOrExtendInfo("\(20)").string, limits.maxPublicLinksCount, premiumLimits.maxPublicLinksCount)) - - entries.append(.publicLinkAvailability(presentationData.theme, presentationData.strings.Group_Username_RemoveExistingUsernamesInfo, false)) - var index: Int32 = 0 - for peer in publicChannelsToRevoke.sorted(by: { lhs, rhs in - var lhsDate: Int32 = 0 - var rhsDate: Int32 = 0 - if let lhs = lhs as? TelegramChannel { - lhsDate = lhs.creationDate - } - if let rhs = rhs as? TelegramChannel { - rhsDate = rhs.creationDate - } - return lhsDate > rhsDate - }) { - entries.append(.existingLinkPeerItem(index, presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, presentationData.nameDisplayOrder, peer, ItemListPeerItemEditing(editable: true, editing: true, revealed: state.revealedRevokePeerId == peer.id), state.revokingPeerId == nil)) - index += 1 - } - } else { - entries.append(.publicLinkAvailability(presentationData.theme, presentationData.strings.Group_Username_CreatePublicLinkHelp, true)) - } - } else { - entries.append(.editablePublicLink(presentationData.theme, presentationData.strings, "", currentAddressName)) - if let status = state.addressNameValidationStatus { - let text: String - switch status { - case let .invalidFormat(error): - switch error { - case .startsWithDigit: - text = presentationData.strings.Group_Username_InvalidStartsWithNumber - case .startsWithUnderscore: - text = presentationData.strings.Channel_Username_InvalidStartsWithUnderscore - case .endsWithUnderscore: - text = presentationData.strings.Channel_Username_InvalidEndsWithUnderscore - case .tooShort: - text = presentationData.strings.Group_Username_InvalidTooShort - case .invalidCharacters: - text = presentationData.strings.Channel_Username_InvalidCharacters - } - case let .availability(availability): - switch availability { - case .available: - text = presentationData.strings.Channel_Username_UsernameIsAvailable(currentAddressName).string - case .invalid: + entries.append(.editablePublicLink(presentationData.theme, presentationData.strings, "", currentAddressName)) + if let status = state.addressNameValidationStatus { + let text: String + switch status { + case let .invalidFormat(error): + switch error { + case .startsWithDigit: + text = presentationData.strings.Group_Username_InvalidStartsWithNumber + case .startsWithUnderscore: + text = presentationData.strings.Channel_Username_InvalidStartsWithUnderscore + case .endsWithUnderscore: + text = presentationData.strings.Channel_Username_InvalidEndsWithUnderscore + case .tooShort: + text = presentationData.strings.Group_Username_InvalidTooShort + case .invalidCharacters: text = presentationData.strings.Channel_Username_InvalidCharacters - case .taken: - text = presentationData.strings.Channel_Username_InvalidTaken } - case .checking: - text = presentationData.strings.Channel_Username_CheckingUsername + case let .availability(availability): + switch availability { + case .available: + text = presentationData.strings.Channel_Username_UsernameIsAvailable(currentAddressName).string + case .invalid: + text = presentationData.strings.Channel_Username_InvalidCharacters + case .taken: + text = presentationData.strings.Channel_Username_InvalidTaken } - - entries.append(.publicLinkStatus(presentationData.theme, text, status)) + case .checking: + text = presentationData.strings.Channel_Username_CheckingUsername } - entries.append(.publicLinkInfo(presentationData.theme, presentationData.strings.Group_Username_CreatePublicLinkHelp)) + entries.append(.publicLinkStatus(presentationData.theme, text, status)) } + + entries.append(.publicLinkInfo(presentationData.theme, presentationData.strings.Group_Username_CreatePublicLinkHelp)) case .privateChannel: let invite = (view.cachedData as? CachedGroupData)?.exportedInvitation entries.append(.privateLinkHeader(presentationData.theme, presentationData.strings.InviteLink_InviteLink.uppercased())) diff --git a/submodules/PhotoResources/Sources/PhotoResources.swift b/submodules/PhotoResources/Sources/PhotoResources.swift index 6414f8a0c8..9335c9ee04 100644 --- a/submodules/PhotoResources/Sources/PhotoResources.swift +++ b/submodules/PhotoResources/Sources/PhotoResources.swift @@ -593,11 +593,7 @@ public func chatMessagePhotoInternal(photoData: Signal Date: Mon, 20 Jun 2022 16:11:47 +0500 Subject: [PATCH 05/16] Various fixes --- .../Sources/ChatMediaInputNode.swift | 61 ++++++++++++++----- 1 file changed, 45 insertions(+), 16 deletions(-) diff --git a/submodules/TelegramUI/Sources/ChatMediaInputNode.swift b/submodules/TelegramUI/Sources/ChatMediaInputNode.swift index bb3373b2b6..0feecd22f0 100644 --- a/submodules/TelegramUI/Sources/ChatMediaInputNode.swift +++ b/submodules/TelegramUI/Sources/ChatMediaInputNode.swift @@ -165,7 +165,7 @@ func preparedChatMediaInputGridEntryTransition(account: Account, view: ItemColle return ChatMediaInputGridTransition(deletions: deletions, insertions: insertions, updates: updates, updateFirstIndexInSectionOffset: firstIndexInSectionOffset, stationaryItems: stationaryItems, scrollToItem: scrollToItem, updateOpaqueState: opaqueState, animated: animated) } -func chatMediaInputPanelEntries(view: ItemCollectionsView, savedStickers: OrderedItemListView?, recentStickers: OrderedItemListView?, temporaryPackOrder: [ItemCollectionId]? = nil, trendingIsDismissed: Bool = false, peerSpecificPack: PeerSpecificPackData?, canInstallPeerSpecificPack: CanInstallPeerSpecificPack, theme: PresentationTheme, strings: PresentationStrings, premiumStickers: OrderedItemListView? = nil, hasGifs: Bool = true, hasSettings: Bool = true, expanded: Bool = false, reorderable: Bool = false) -> [ChatMediaInputPanelEntry] { +func chatMediaInputPanelEntries(view: ItemCollectionsView, savedStickers: OrderedItemListView?, recentStickers: OrderedItemListView?, temporaryPackOrder: [ItemCollectionId]? = nil, trendingIsDismissed: Bool = false, peerSpecificPack: PeerSpecificPackData?, canInstallPeerSpecificPack: CanInstallPeerSpecificPack, theme: PresentationTheme, strings: PresentationStrings, hasPremiumStickers: Bool = false, cloudPremiumStickers: OrderedItemListView? = nil, hasGifs: Bool = true, hasSettings: Bool = true, expanded: Bool = false, reorderable: Bool = false) -> [ChatMediaInputPanelEntry] { var entries: [ChatMediaInputPanelEntry] = [] if hasGifs { entries.append(.recentGifs(theme, strings, expanded)) @@ -204,7 +204,7 @@ func chatMediaInputPanelEntries(view: ItemCollectionsView, savedStickers: Ordere entries.append(.peerSpecific(theme: theme, peer: peer, expanded: expanded)) } - if let premiumStickers = premiumStickers, !premiumStickers.items.isEmpty { + if hasPremiumStickers { entries.append(.premium(theme, strings, expanded)) } @@ -261,7 +261,7 @@ func chatMediaInputPanelGifModeEntries(theme: PresentationTheme, strings: Presen return entries } -func chatMediaInputGridEntries(view: ItemCollectionsView, savedStickers: OrderedItemListView?, recentStickers: OrderedItemListView?, peerSpecificPack: PeerSpecificPackData?, canInstallPeerSpecificPack: CanInstallPeerSpecificPack, trendingPacks: [FeaturedStickerPackItem], installedPacks: Set, premiumStickers: OrderedItemListView? = nil, trendingIsDismissed: Bool = false, hasSearch: Bool = true, hasAccessories: Bool = true, strings: PresentationStrings, theme: PresentationTheme, hasPremium: Bool, isPremiumDisabled: Bool, trendingIsPremium: Bool) -> [ChatMediaInputGridEntry] { +func chatMediaInputGridEntries(view: ItemCollectionsView, savedStickers: OrderedItemListView?, recentStickers: OrderedItemListView?, peerSpecificPack: PeerSpecificPackData?, canInstallPeerSpecificPack: CanInstallPeerSpecificPack, trendingPacks: [FeaturedStickerPackItem], installedPacks: Set, premiumStickers: OrderedItemListView? = nil, cloudPremiumStickers: OrderedItemListView? = nil, trendingIsDismissed: Bool = false, hasSearch: Bool = true, hasAccessories: Bool = true, strings: PresentationStrings, theme: PresentationTheme, hasPremium: Bool, isPremiumDisabled: Bool, trendingIsPremium: Bool) -> [ChatMediaInputGridEntry] { var entries: [ChatMediaInputGridEntry] = [] if hasSearch && view.lower == nil { @@ -348,15 +348,35 @@ func chatMediaInputGridEntries(view: ItemCollectionsView, savedStickers: Ordered } } - if let premiumStickers = premiumStickers, !premiumStickers.items.isEmpty && hasPremium && !isPremiumDisabled { + if hasPremium && !isPremiumDisabled { + var existingStickerIds = Set() let packInfo = StickerPackCollectionInfo(id: ItemCollectionId(namespace: ChatMediaInputPanelAuxiliaryNamespace.premium.rawValue, id: 0), flags: [], accessHash: 0, title: strings.Stickers_PremiumStickers.uppercased(), shortName: "", thumbnail: nil, immediateThumbnailData: nil, hash: 0, count: 0) - for i in 0 ..< premiumStickers.items.count { - if let item = premiumStickers.items[i].contents.get(RecentMediaItem.self) { - let file = item.media - - let index = ItemCollectionItemIndex(index: Int32(i), id: file.fileId.id) - let stickerItem = StickerPackItem(index: index, file: file, indexKeys: []) - entries.append(.sticker(index: ItemCollectionViewEntryIndex(collectionIndex: -1, collectionId: packInfo.id, itemIndex: index), stickerItem: stickerItem, stickerPackInfo: packInfo, canManagePeerSpecificPack: nil, maybeManageable: hasAccessories, theme: theme, isLocked: stickerItem.file.isPremiumSticker && !hasPremium)) + + if let premiumStickers = premiumStickers { + for i in 0 ..< premiumStickers.items.count { + if let item = premiumStickers.items[i].contents.get(RecentMediaItem.self) { + let file = item.media + let index = ItemCollectionItemIndex(index: Int32(i), id: file.fileId.id) + let stickerItem = StickerPackItem(index: index, file: file, indexKeys: []) + entries.append(.sticker(index: ItemCollectionViewEntryIndex(collectionIndex: -1, collectionId: packInfo.id, itemIndex: index), stickerItem: stickerItem, stickerPackInfo: packInfo, canManagePeerSpecificPack: nil, maybeManageable: hasAccessories, theme: theme, isLocked: stickerItem.file.isPremiumSticker && !hasPremium)) + + existingStickerIds.insert(file.fileId.id) + } + } + } + + if let cloudPremiumStickers = cloudPremiumStickers { + for i in 0 ..< cloudPremiumStickers.items.count { + if let item = cloudPremiumStickers.items[i].contents.get(RecentMediaItem.self) { + let file = item.media + if !existingStickerIds.contains(file.fileId.id) { + let index = ItemCollectionItemIndex(index: Int32(i), id: file.fileId.id) + let stickerItem = StickerPackItem(index: index, file: file, indexKeys: []) + entries.append(.sticker(index: ItemCollectionViewEntryIndex(collectionIndex: -1, collectionId: packInfo.id, itemIndex: index), stickerItem: stickerItem, stickerPackInfo: packInfo, canManagePeerSpecificPack: nil, maybeManageable: hasAccessories, theme: theme, isLocked: stickerItem.file.isPremiumSticker && !hasPremium)) + + existingStickerIds.insert(file.fileId.id) + } + } } } } @@ -1157,10 +1177,9 @@ final class ChatMediaInputNode: ChatInputNode { savedStickers = orderedView } else if orderedView.collectionId == Namespaces.OrderedItemList.PremiumStickers { premiumStickers = orderedView + } else if orderedView.collectionId == Namespaces.OrderedItemList.CloudPremiumStickers { + cloudPremiumStickers = orderedView } -// else if orderedView.collectionId == Namespaces.OrderedItemList.CloudPremiumStickers { -// cloudPremiumStickers = orderedView -// } } var installedPacks = Set() @@ -1176,9 +1195,19 @@ final class ChatMediaInputNode: ChatInputNode { let hasPremium = accountPeer?.isPremium ?? false let featuredStickersConfiguration = featuredStickersConfiguration?.get(FeaturedStickersConfiguration.self) - let panelEntries = chatMediaInputPanelEntries(view: view, savedStickers: savedStickers, recentStickers: recentStickers, temporaryPackOrder: temporaryPackOrder, trendingIsDismissed: trendingIsDismissed, peerSpecificPack: peerSpecificPack.0, canInstallPeerSpecificPack: peerSpecificPack.1, theme: theme, strings: strings, premiumStickers: hasPremium ? premiumStickers : nil, expanded: panelExpanded, reorderable: true) + + var hasPremiumStickers = false + if hasPremium { + if let premiumStickers = premiumStickers, !premiumStickers.items.isEmpty { + hasPremiumStickers = true + } else if let cloudPremiumStickers = cloudPremiumStickers, !cloudPremiumStickers.items.isEmpty { + hasPremiumStickers = true + } + } + + let panelEntries = chatMediaInputPanelEntries(view: view, savedStickers: savedStickers, recentStickers: recentStickers, temporaryPackOrder: temporaryPackOrder, trendingIsDismissed: trendingIsDismissed, peerSpecificPack: peerSpecificPack.0, canInstallPeerSpecificPack: peerSpecificPack.1, theme: theme, strings: strings, hasPremiumStickers: hasPremiumStickers, cloudPremiumStickers: hasPremium ? cloudPremiumStickers : nil, expanded: panelExpanded, reorderable: true) let gifPaneEntries = chatMediaInputPanelGifModeEntries(theme: theme, strings: strings, reactions: reactions, animatedEmojiStickers: animatedEmojiStickers, expanded: panelExpanded) - var gridEntries = chatMediaInputGridEntries(view: view, savedStickers: savedStickers, recentStickers: recentStickers, peerSpecificPack: peerSpecificPack.0, canInstallPeerSpecificPack: peerSpecificPack.1, trendingPacks: trendingPacks, installedPacks: installedPacks, premiumStickers: premiumStickers, trendingIsDismissed: trendingIsDismissed, strings: strings, theme: theme, hasPremium: hasPremium, isPremiumDisabled: premiumConfiguration.isPremiumDisabled, trendingIsPremium: featuredStickersConfiguration?.isPremium ?? false) + var gridEntries = chatMediaInputGridEntries(view: view, savedStickers: savedStickers, recentStickers: recentStickers, peerSpecificPack: peerSpecificPack.0, canInstallPeerSpecificPack: peerSpecificPack.1, trendingPacks: trendingPacks, installedPacks: installedPacks, premiumStickers: premiumStickers, cloudPremiumStickers: cloudPremiumStickers, trendingIsDismissed: trendingIsDismissed, strings: strings, theme: theme, hasPremium: hasPremium, isPremiumDisabled: premiumConfiguration.isPremiumDisabled, trendingIsPremium: featuredStickersConfiguration?.isPremium ?? false) if view.higher == nil { var hasTopSeparator = true From ba599ffd3205f884cf05b908b7f3024bc198fbb2 Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Mon, 20 Jun 2022 16:15:28 +0500 Subject: [PATCH 06/16] Various fixes --- submodules/TelegramUI/Sources/ChatMediaInputNode.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/submodules/TelegramUI/Sources/ChatMediaInputNode.swift b/submodules/TelegramUI/Sources/ChatMediaInputNode.swift index 0feecd22f0..719b0ed586 100644 --- a/submodules/TelegramUI/Sources/ChatMediaInputNode.swift +++ b/submodules/TelegramUI/Sources/ChatMediaInputNode.swift @@ -1169,7 +1169,7 @@ final class ChatMediaInputNode: ChatInputNode { var savedStickers: OrderedItemListView? var recentStickers: OrderedItemListView? var premiumStickers: OrderedItemListView? -// var cloudPremiumStickers: OrderedItemListView? + var cloudPremiumStickers: OrderedItemListView? for orderedView in view.orderedItemListsViews { if orderedView.collectionId == Namespaces.OrderedItemList.CloudRecentStickers { recentStickers = orderedView From c8a981238e08d4259e8699ad1fe99dfa7d295c25 Mon Sep 17 00:00:00 2001 From: Ali <> Date: Mon, 20 Jun 2022 13:11:00 +0100 Subject: [PATCH 07/16] Support updateConfig --- .../Sources/Account/Account.swift | 12 +++++++++++- .../Account/AccountIntermediateState.swift | 19 +++++++++++++++---- .../State/AccountStateManagementUtils.swift | 9 +++++++-- .../Sources/State/AccountStateManager.swift | 6 ++++++ 4 files changed, 39 insertions(+), 7 deletions(-) diff --git a/submodules/TelegramCore/Sources/Account/Account.swift b/submodules/TelegramCore/Sources/Account/Account.swift index c53f093c55..aa05f25316 100644 --- a/submodules/TelegramCore/Sources/Account/Account.swift +++ b/submodules/TelegramCore/Sources/Account/Account.swift @@ -875,6 +875,7 @@ public class Account { private let serviceQueue = Queue() + private let accountManager: AccountManager public private(set) var stateManager: AccountStateManager! private(set) var contactSyncManager: ContactSyncManager! public private(set) var callSessionManager: CallSessionManager! @@ -935,6 +936,7 @@ public class Account { private let smallLogPostDisposable = MetaDisposable() public init(accountManager: AccountManager, id: AccountRecordId, basePath: String, testingEnvironment: Bool, postbox: Postbox, network: Network, networkArguments: NetworkInitializationArguments, peerId: PeerId, auxiliaryMethods: AccountAuxiliaryMethods, supplementary: Bool) { + self.accountManager = accountManager self.id = id self.basePath = basePath self.testingEnvironment = testingEnvironment @@ -1147,7 +1149,6 @@ public class Account { } } })) - self.managedOperationsDisposable.add(managedConfigurationUpdates(accountManager: accountManager, postbox: self.postbox, network: self.network).start()) self.managedOperationsDisposable.add(managedVoipConfigurationUpdates(postbox: self.postbox, network: self.network).start()) self.managedOperationsDisposable.add(managedAppConfigurationUpdates(postbox: self.postbox, network: self.network).start()) self.managedOperationsDisposable.add(managedPremiumPromoConfigurationUpdates(postbox: self.postbox, network: self.network).start()) @@ -1189,6 +1190,11 @@ public class Account { let _ = try? data.write(to: URL(fileURLWithPath: "\(basePath)/notificationsKey")) } }) + + self.stateManager.updateConfigRequested = { [weak self] in + self?.restartConfigurationUpdates() + } + self.restartConfigurationUpdates() } deinit { @@ -1201,6 +1207,10 @@ public class Account { self.networkTypeDisposable?.dispose() } + private func restartConfigurationUpdates() { + self.managedOperationsDisposable.add(managedConfigurationUpdates(accountManager: self.accountManager, postbox: self.postbox, network: self.network).start()) + } + private func postSmallLogIfNeeded() { let timestamp = CFAbsoluteTimeGetCurrent() if self.lastSmallLogPostTimestamp == nil || self.lastSmallLogPostTimestamp! < timestamp - 30.0 { diff --git a/submodules/TelegramCore/Sources/Account/AccountIntermediateState.swift b/submodules/TelegramCore/Sources/Account/AccountIntermediateState.swift index 859db18a16..ef32a9c1d6 100644 --- a/submodules/TelegramCore/Sources/Account/AccountIntermediateState.swift +++ b/submodules/TelegramCore/Sources/Account/AccountIntermediateState.swift @@ -114,6 +114,7 @@ enum AccountStateMutationOperation { case UpdateAutoremoveTimeout(peer: Api.Peer, value: CachedPeerAutoremoveTimeout.Value?) case UpdateAttachMenuBots case UpdateAudioTranscription(messageId: MessageId, id: Int64, isPending: Bool, text: String) + case UpdateConfig } struct HoleFromPreviousState { @@ -517,9 +518,13 @@ struct AccountMutableState { self.addOperation(.UpdateAttachMenuBots) } + mutating func reloadConfig() { + self.addOperation(.UpdateConfig) + } + mutating func addOperation(_ operation: AccountStateMutationOperation) { switch operation { - case .DeleteMessages, .DeleteMessagesWithGlobalIds, .EditMessage, .UpdateMessagePoll, .UpdateMessageReactions, .UpdateMedia, .ReadOutbox, .ReadGroupFeedInbox, .MergePeerPresences, .UpdateSecretChat, .AddSecretMessages, .ReadSecretOutbox, .AddPeerInputActivity, .UpdateCachedPeerData, .UpdatePinnedItemIds, .ReadMessageContents, .UpdateMessageImpressionCount, .UpdateMessageForwardsCount, .UpdateInstalledStickerPacks, .UpdateRecentGifs, .UpdateChatInputState, .UpdateCall, .AddCallSignalingData, .UpdateLangPack, .UpdateMinAvailableMessage, .UpdatePeerChatUnreadMark, .UpdateIsContact, .UpdatePeerChatInclusion, .UpdatePeersNearby, .UpdateTheme, .SyncChatListFilters, .UpdateChatListFilterOrder, .UpdateChatListFilter, .UpdateReadThread, .UpdateGroupCallParticipants, .UpdateGroupCall, .UpdateMessagesPinned, .UpdateAutoremoveTimeout, .UpdateAttachMenuBots, .UpdateAudioTranscription: + case .DeleteMessages, .DeleteMessagesWithGlobalIds, .EditMessage, .UpdateMessagePoll, .UpdateMessageReactions, .UpdateMedia, .ReadOutbox, .ReadGroupFeedInbox, .MergePeerPresences, .UpdateSecretChat, .AddSecretMessages, .ReadSecretOutbox, .AddPeerInputActivity, .UpdateCachedPeerData, .UpdatePinnedItemIds, .ReadMessageContents, .UpdateMessageImpressionCount, .UpdateMessageForwardsCount, .UpdateInstalledStickerPacks, .UpdateRecentGifs, .UpdateChatInputState, .UpdateCall, .AddCallSignalingData, .UpdateLangPack, .UpdateMinAvailableMessage, .UpdatePeerChatUnreadMark, .UpdateIsContact, .UpdatePeerChatInclusion, .UpdatePeersNearby, .UpdateTheme, .SyncChatListFilters, .UpdateChatListFilterOrder, .UpdateChatListFilter, .UpdateReadThread, .UpdateGroupCallParticipants, .UpdateGroupCall, .UpdateMessagesPinned, .UpdateAutoremoveTimeout, .UpdateAttachMenuBots, .UpdateAudioTranscription, .UpdateConfig: break case let .AddMessages(messages, location): for message in messages { @@ -645,6 +650,7 @@ struct AccountReplayedFinalState { let delayNotificatonsUntil: Int32? let updatedIncomingThreadReadStates: [MessageId: MessageId.Id] let updatedOutgoingThreadReadStates: [MessageId: MessageId.Id] + let updateConfig: Bool } struct AccountFinalStateEvents { @@ -668,12 +674,13 @@ struct AccountFinalStateEvents { let authorizationListUpdated: Bool let updatedIncomingThreadReadStates: [MessageId: MessageId.Id] let updatedOutgoingThreadReadStates: [MessageId: MessageId.Id] + let updateConfig: Bool var isEmpty: Bool { - return self.addedIncomingMessageIds.isEmpty && self.addedReactionEvents.isEmpty && self.wasScheduledMessageIds.isEmpty && self.deletedMessageIds.isEmpty && self.updatedTypingActivities.isEmpty && self.updatedWebpages.isEmpty && self.updatedCalls.isEmpty && self.addedCallSignalingData.isEmpty && self.updatedGroupCallParticipants.isEmpty && self.updatedPeersNearby?.isEmpty ?? true && self.isContactUpdates.isEmpty && self.displayAlerts.isEmpty && self.dismissBotWebViews.isEmpty && self.delayNotificatonsUntil == nil && self.updatedMaxMessageId == nil && self.updatedQts == nil && self.externallyUpdatedPeerId.isEmpty && !authorizationListUpdated && self.updatedIncomingThreadReadStates.isEmpty && self.updatedOutgoingThreadReadStates.isEmpty + return self.addedIncomingMessageIds.isEmpty && self.addedReactionEvents.isEmpty && self.wasScheduledMessageIds.isEmpty && self.deletedMessageIds.isEmpty && self.updatedTypingActivities.isEmpty && self.updatedWebpages.isEmpty && self.updatedCalls.isEmpty && self.addedCallSignalingData.isEmpty && self.updatedGroupCallParticipants.isEmpty && self.updatedPeersNearby?.isEmpty ?? true && self.isContactUpdates.isEmpty && self.displayAlerts.isEmpty && self.dismissBotWebViews.isEmpty && self.delayNotificatonsUntil == nil && self.updatedMaxMessageId == nil && self.updatedQts == nil && self.externallyUpdatedPeerId.isEmpty && !authorizationListUpdated && self.updatedIncomingThreadReadStates.isEmpty && self.updatedOutgoingThreadReadStates.isEmpty && !self.updateConfig } - init(addedIncomingMessageIds: [MessageId] = [], addedReactionEvents: [(reactionAuthor: Peer, reaction: String, message: Message, timestamp: Int32)] = [], wasScheduledMessageIds: [MessageId] = [], deletedMessageIds: [DeletedMessageId] = [], updatedTypingActivities: [PeerActivitySpace: [PeerId: PeerInputActivity?]] = [:], updatedWebpages: [MediaId: TelegramMediaWebpage] = [:], updatedCalls: [Api.PhoneCall] = [], addedCallSignalingData: [(Int64, Data)] = [], updatedGroupCallParticipants: [(Int64, GroupCallParticipantsContext.Update)] = [], updatedPeersNearby: [PeerNearby]? = nil, isContactUpdates: [(PeerId, Bool)] = [], displayAlerts: [(text: String, isDropAuth: Bool)] = [], dismissBotWebViews: [Int64] = [], delayNotificatonsUntil: Int32? = nil, updatedMaxMessageId: Int32? = nil, updatedQts: Int32? = nil, externallyUpdatedPeerId: Set = Set(), authorizationListUpdated: Bool = false, updatedIncomingThreadReadStates: [MessageId: MessageId.Id] = [:], updatedOutgoingThreadReadStates: [MessageId: MessageId.Id] = [:]) { + init(addedIncomingMessageIds: [MessageId] = [], addedReactionEvents: [(reactionAuthor: Peer, reaction: String, message: Message, timestamp: Int32)] = [], wasScheduledMessageIds: [MessageId] = [], deletedMessageIds: [DeletedMessageId] = [], updatedTypingActivities: [PeerActivitySpace: [PeerId: PeerInputActivity?]] = [:], updatedWebpages: [MediaId: TelegramMediaWebpage] = [:], updatedCalls: [Api.PhoneCall] = [], addedCallSignalingData: [(Int64, Data)] = [], updatedGroupCallParticipants: [(Int64, GroupCallParticipantsContext.Update)] = [], updatedPeersNearby: [PeerNearby]? = nil, isContactUpdates: [(PeerId, Bool)] = [], displayAlerts: [(text: String, isDropAuth: Bool)] = [], dismissBotWebViews: [Int64] = [], delayNotificatonsUntil: Int32? = nil, updatedMaxMessageId: Int32? = nil, updatedQts: Int32? = nil, externallyUpdatedPeerId: Set = Set(), authorizationListUpdated: Bool = false, updatedIncomingThreadReadStates: [MessageId: MessageId.Id] = [:], updatedOutgoingThreadReadStates: [MessageId: MessageId.Id] = [:], updateConfig: Bool = false) { self.addedIncomingMessageIds = addedIncomingMessageIds self.addedReactionEvents = addedReactionEvents self.wasScheduledMessageIds = wasScheduledMessageIds @@ -694,6 +701,7 @@ struct AccountFinalStateEvents { self.authorizationListUpdated = authorizationListUpdated self.updatedIncomingThreadReadStates = updatedIncomingThreadReadStates self.updatedOutgoingThreadReadStates = updatedOutgoingThreadReadStates + self.updateConfig = updateConfig } init(state: AccountReplayedFinalState) { @@ -717,6 +725,7 @@ struct AccountFinalStateEvents { self.authorizationListUpdated = state.state.state.authorizationListUpdated self.updatedIncomingThreadReadStates = state.updatedIncomingThreadReadStates self.updatedOutgoingThreadReadStates = state.updatedOutgoingThreadReadStates + self.updateConfig = state.updateConfig } func union(with other: AccountFinalStateEvents) -> AccountFinalStateEvents { @@ -742,6 +751,8 @@ struct AccountFinalStateEvents { let externallyUpdatedPeerId = self.externallyUpdatedPeerId.union(other.externallyUpdatedPeerId) let authorizationListUpdated = self.authorizationListUpdated || other.authorizationListUpdated - return AccountFinalStateEvents(addedIncomingMessageIds: self.addedIncomingMessageIds + other.addedIncomingMessageIds, addedReactionEvents: self.addedReactionEvents + other.addedReactionEvents, wasScheduledMessageIds: self.wasScheduledMessageIds + other.wasScheduledMessageIds, deletedMessageIds: self.deletedMessageIds + other.deletedMessageIds, updatedTypingActivities: self.updatedTypingActivities, updatedWebpages: self.updatedWebpages, updatedCalls: self.updatedCalls + other.updatedCalls, addedCallSignalingData: self.addedCallSignalingData + other.addedCallSignalingData, updatedGroupCallParticipants: self.updatedGroupCallParticipants + other.updatedGroupCallParticipants, isContactUpdates: self.isContactUpdates + other.isContactUpdates, displayAlerts: self.displayAlerts + other.displayAlerts, dismissBotWebViews: self.dismissBotWebViews + other.dismissBotWebViews, delayNotificatonsUntil: delayNotificatonsUntil, updatedMaxMessageId: updatedMaxMessageId, updatedQts: updatedQts, externallyUpdatedPeerId: externallyUpdatedPeerId, authorizationListUpdated: authorizationListUpdated, updatedIncomingThreadReadStates: self.updatedIncomingThreadReadStates.merging(other.updatedIncomingThreadReadStates, uniquingKeysWith: { lhs, _ in lhs })) + let updateConfig = self.updateConfig || other.updateConfig + + return AccountFinalStateEvents(addedIncomingMessageIds: self.addedIncomingMessageIds + other.addedIncomingMessageIds, addedReactionEvents: self.addedReactionEvents + other.addedReactionEvents, wasScheduledMessageIds: self.wasScheduledMessageIds + other.wasScheduledMessageIds, deletedMessageIds: self.deletedMessageIds + other.deletedMessageIds, updatedTypingActivities: self.updatedTypingActivities, updatedWebpages: self.updatedWebpages, updatedCalls: self.updatedCalls + other.updatedCalls, addedCallSignalingData: self.addedCallSignalingData + other.addedCallSignalingData, updatedGroupCallParticipants: self.updatedGroupCallParticipants + other.updatedGroupCallParticipants, isContactUpdates: self.isContactUpdates + other.isContactUpdates, displayAlerts: self.displayAlerts + other.displayAlerts, dismissBotWebViews: self.dismissBotWebViews + other.dismissBotWebViews, delayNotificatonsUntil: delayNotificatonsUntil, updatedMaxMessageId: updatedMaxMessageId, updatedQts: updatedQts, externallyUpdatedPeerId: externallyUpdatedPeerId, authorizationListUpdated: authorizationListUpdated, updatedIncomingThreadReadStates: self.updatedIncomingThreadReadStates.merging(other.updatedIncomingThreadReadStates, uniquingKeysWith: { lhs, _ in lhs }), updateConfig: updateConfig) } } diff --git a/submodules/TelegramCore/Sources/State/AccountStateManagementUtils.swift b/submodules/TelegramCore/Sources/State/AccountStateManagementUtils.swift index 24212dd5e2..d0c8e9ab1e 100644 --- a/submodules/TelegramCore/Sources/State/AccountStateManagementUtils.swift +++ b/submodules/TelegramCore/Sources/State/AccountStateManagementUtils.swift @@ -1530,6 +1530,8 @@ private func finalStateWithUpdatesAndServerTime(postbox: Postbox, network: Netwo updatedState.addUpdateAttachMenuBots() case let .updateWebViewResultSent(queryId): updatedState.addDismissWebView(queryId) + case .updateConfig: + updatedState.reloadConfig() default: break } @@ -2322,7 +2324,7 @@ private func optimizedOperations(_ operations: [AccountStateMutationOperation]) var currentAddScheduledMessages: OptimizeAddMessagesState? for operation in operations { switch operation { - case .DeleteMessages, .DeleteMessagesWithGlobalIds, .EditMessage, .UpdateMessagePoll, .UpdateMessageReactions, .UpdateMedia, .MergeApiChats, .MergeApiUsers, .MergePeerPresences, .UpdatePeer, .ReadInbox, .ReadOutbox, .ReadGroupFeedInbox, .ResetReadState, .ResetIncomingReadState, .UpdatePeerChatUnreadMark, .ResetMessageTagSummary, .UpdateNotificationSettings, .UpdateGlobalNotificationSettings, .UpdateSecretChat, .AddSecretMessages, .ReadSecretOutbox, .AddPeerInputActivity, .UpdateCachedPeerData, .UpdatePinnedItemIds, .ReadMessageContents, .UpdateMessageImpressionCount, .UpdateMessageForwardsCount, .UpdateInstalledStickerPacks, .UpdateRecentGifs, .UpdateChatInputState, .UpdateCall, .AddCallSignalingData, .UpdateLangPack, .UpdateMinAvailableMessage, .UpdateIsContact, .UpdatePeerChatInclusion, .UpdatePeersNearby, .UpdateTheme, .SyncChatListFilters, .UpdateChatListFilter, .UpdateChatListFilterOrder, .UpdateReadThread, .UpdateMessagesPinned, .UpdateGroupCallParticipants, .UpdateGroupCall, .UpdateAutoremoveTimeout, .UpdateAttachMenuBots, .UpdateAudioTranscription: + case .DeleteMessages, .DeleteMessagesWithGlobalIds, .EditMessage, .UpdateMessagePoll, .UpdateMessageReactions, .UpdateMedia, .MergeApiChats, .MergeApiUsers, .MergePeerPresences, .UpdatePeer, .ReadInbox, .ReadOutbox, .ReadGroupFeedInbox, .ResetReadState, .ResetIncomingReadState, .UpdatePeerChatUnreadMark, .ResetMessageTagSummary, .UpdateNotificationSettings, .UpdateGlobalNotificationSettings, .UpdateSecretChat, .AddSecretMessages, .ReadSecretOutbox, .AddPeerInputActivity, .UpdateCachedPeerData, .UpdatePinnedItemIds, .ReadMessageContents, .UpdateMessageImpressionCount, .UpdateMessageForwardsCount, .UpdateInstalledStickerPacks, .UpdateRecentGifs, .UpdateChatInputState, .UpdateCall, .AddCallSignalingData, .UpdateLangPack, .UpdateMinAvailableMessage, .UpdateIsContact, .UpdatePeerChatInclusion, .UpdatePeersNearby, .UpdateTheme, .SyncChatListFilters, .UpdateChatListFilter, .UpdateChatListFilterOrder, .UpdateReadThread, .UpdateMessagesPinned, .UpdateGroupCallParticipants, .UpdateGroupCall, .UpdateAutoremoveTimeout, .UpdateAttachMenuBots, .UpdateAudioTranscription, .UpdateConfig: if let currentAddMessages = currentAddMessages, !currentAddMessages.messages.isEmpty { result.append(.AddMessages(currentAddMessages.messages, currentAddMessages.location)) } @@ -2436,6 +2438,7 @@ func replayFinalState( var syncChatListFilters = false var deletedMessageIds: [DeletedMessageId] = [] var syncAttachMenuBots = false + var updateConfig = false var holesFromPreviousStateMessageIds: [MessageId] = [] var clearHolesFromPreviousStateForChannelMessagesWithPts: [PeerIdAndMessageNamespace: Int32] = [:] @@ -3379,6 +3382,8 @@ func replayFinalState( media: currentMessage.media )) }) + case .UpdateConfig: + updateConfig = true } } @@ -3754,5 +3759,5 @@ func replayFinalState( requestChatListFiltersSync(transaction: transaction) } - return AccountReplayedFinalState(state: finalState, addedIncomingMessageIds: addedIncomingMessageIds, addedReactionEvents: addedReactionEvents, wasScheduledMessageIds: wasScheduledMessageIds, addedSecretMessageIds: addedSecretMessageIds, deletedMessageIds: deletedMessageIds, updatedTypingActivities: updatedTypingActivities, updatedWebpages: updatedWebpages, updatedCalls: updatedCalls, addedCallSignalingData: addedCallSignalingData, updatedGroupCallParticipants: updatedGroupCallParticipants, updatedPeersNearby: updatedPeersNearby, isContactUpdates: isContactUpdates, delayNotificatonsUntil: delayNotificatonsUntil, updatedIncomingThreadReadStates: updatedIncomingThreadReadStates, updatedOutgoingThreadReadStates: updatedOutgoingThreadReadStates) + return AccountReplayedFinalState(state: finalState, addedIncomingMessageIds: addedIncomingMessageIds, addedReactionEvents: addedReactionEvents, wasScheduledMessageIds: wasScheduledMessageIds, addedSecretMessageIds: addedSecretMessageIds, deletedMessageIds: deletedMessageIds, updatedTypingActivities: updatedTypingActivities, updatedWebpages: updatedWebpages, updatedCalls: updatedCalls, addedCallSignalingData: addedCallSignalingData, updatedGroupCallParticipants: updatedGroupCallParticipants, updatedPeersNearby: updatedPeersNearby, isContactUpdates: isContactUpdates, delayNotificatonsUntil: delayNotificatonsUntil, updatedIncomingThreadReadStates: updatedIncomingThreadReadStates, updatedOutgoingThreadReadStates: updatedOutgoingThreadReadStates, updateConfig: updateConfig) } diff --git a/submodules/TelegramCore/Sources/State/AccountStateManager.swift b/submodules/TelegramCore/Sources/State/AccountStateManager.swift index f42199846e..a607d2b285 100644 --- a/submodules/TelegramCore/Sources/State/AccountStateManager.swift +++ b/submodules/TelegramCore/Sources/State/AccountStateManager.swift @@ -176,6 +176,8 @@ public final class AccountStateManager { private let appliedQtsPromise = Promise(nil) private let appliedQtsDisposable = MetaDisposable() + var updateConfigRequested: (() -> Void)? + init( accountPeerId: PeerId, accountManager: AccountManager, @@ -780,6 +782,10 @@ public final class AccountStateManager { if !events.deletedMessageIds.isEmpty { self.deletedMessagesPipe.putNext(events.deletedMessageIds) } + + if events.updateConfig { + self.updateConfigRequested?() + } case let .pollCompletion(pollId, preMessageIds, preSubscribers): if self.operations.count > 1 { self.operations.removeFirst() From fdab592a71a24c9dc096e698fd688b2638fa307c Mon Sep 17 00:00:00 2001 From: Ali <> Date: Sun, 19 Jun 2022 21:25:07 +0100 Subject: [PATCH 08/16] Create missing directory --- build-system/Make/BazelLocation.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build-system/Make/BazelLocation.py b/build-system/Make/BazelLocation.py index 73651ed182..92a866cdb0 100644 --- a/build-system/Make/BazelLocation.py +++ b/build-system/Make/BazelLocation.py @@ -5,6 +5,9 @@ import sys from BuildEnvironment import is_apple_silicon, resolve_executable, call_executable, BuildEnvironmentVersions def locate_bazel(base_path): + if not os.path.isdir('{}/base_path'.format(base_path)): + os.mkdir('{}/base_path'.format(base_path)) + versions = BuildEnvironmentVersions(base_path=os.getcwd()) if is_apple_silicon(): arch = 'darwin-arm64' From 79f27cf11695c325c18a72056ddc19ead56ca0c4 Mon Sep 17 00:00:00 2001 From: Ali <> Date: Mon, 20 Jun 2022 13:14:41 +0100 Subject: [PATCH 09/16] Gitlab workflow: allow import to fail [skip ci] --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4e9ce7601b..0b4f47e1a3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -61,10 +61,10 @@ jobs: # install fake certificates export CERTS_PATH="build-system/fake-codesigning/certs/distribution" for f in "$CERTS_PATH"/*.p12; do - security import "$f" -k "$MY_KEYCHAIN" -P "" -T /usr/bin/codesign -T /usr/bin/security + security import "$f" -k "$MY_KEYCHAIN" -P "" -T /usr/bin/codesign -T /usr/bin/security || true done for f in "$CERTS_PATH"/*.cer; do - security import "$f" -k "$MY_KEYCHAIN" -P "" -T /usr/bin/codesign -T /usr/bin/security + security import "$f" -k "$MY_KEYCHAIN" -P "" -T /usr/bin/codesign -T /usr/bin/security || true done security set-key-partition-list -S apple-tool:,apple: -k "$MY_KEYCHAIN_PASSWORD" "$MY_KEYCHAIN" From 4b51b8c1ad2f7e394418f798dd8accab9652744f Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Mon, 20 Jun 2022 18:48:59 +0500 Subject: [PATCH 10/16] Various fixes --- .../SheetComponent/Sources/SheetComponent.swift | 9 +++++---- .../Sources/ChannelVisibilityController.swift | 14 +++++++++++++- .../PremiumUI/Sources/PremiumDemoScreen.swift | 13 ++++++++----- .../TelegramCore/Sources/ApiUtils/BotInfo.swift | 5 +++-- .../State/AccountStateManagementUtils.swift | 8 ++++---- .../Sources/SyncCore/SyncCore_BotInfo.swift | 16 ++++++++++++++-- .../Sources/SyncCore/SyncCore_Namespaces.swift | 2 +- versions.json | 2 +- 8 files changed, 49 insertions(+), 20 deletions(-) diff --git a/submodules/Components/SheetComponent/Sources/SheetComponent.swift b/submodules/Components/SheetComponent/Sources/SheetComponent.swift index 8f1dd9b5fc..ad0576e9aa 100644 --- a/submodules/Components/SheetComponent/Sources/SheetComponent.swift +++ b/submodules/Components/SheetComponent/Sources/SheetComponent.swift @@ -170,14 +170,14 @@ public final class SheetComponent: Component { let transition = ContainedViewLayoutTransition.animated(duration: 0.35, curve: .customSpring(damping: 124.0, initialVelocity: initialVelocity)) let contentOffset = (self.scrollView.contentOffset.y + self.scrollView.contentInset.top - self.scrollView.contentSize.height) * -1.0 - let dismissalOffset = self.scrollView.contentSize.height + let dismissalOffset = self.scrollView.contentSize.height + abs(self.contentView.frame.minY) let delta = dismissalOffset - contentOffset transition.updatePosition(layer: self.scrollView.layer, position: CGPoint(x: self.scrollView.center.x, y: self.scrollView.center.y + delta), completion: { _ in completion() }) } else { - self.scrollView.layer.animatePosition(from: CGPoint(), to: CGPoint(x: 0.0, y: self.scrollView.contentSize.height), duration: 0.25, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, removeOnCompletion: false, additive: true, completion: { _ in + self.scrollView.layer.animatePosition(from: CGPoint(), to: CGPoint(x: 0.0, y: self.scrollView.contentSize.height + abs(self.contentView.frame.minY)), duration: 0.25, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, removeOnCompletion: false, additive: true, completion: { _ in completion() }) } @@ -223,8 +223,9 @@ public final class SheetComponent: Component { self.ignoreScrolling = true if sheetEnvironment.isCentered { - transition.setFrame(view: self.contentView, frame: CGRect(origin: CGPoint(x: floorToScreenPixels((availableSize.width - contentSize.width) / 2.0), y: 0.0), size: contentSize), completion: nil) - transition.setFrame(view: self.backgroundView, frame: CGRect(origin: CGPoint(x: floorToScreenPixels((availableSize.width - contentSize.width) / 2.0), y: floorToScreenPixels((availableSize.height - contentSize.height) / 2.0)), size: contentSize), completion: nil) + let y: CGFloat = floorToScreenPixels((availableSize.height - contentSize.height) / 2.0) + transition.setFrame(view: self.contentView, frame: CGRect(origin: CGPoint(x: floorToScreenPixels((availableSize.width - contentSize.width) / 2.0), y: -y), size: contentSize), completion: nil) + transition.setFrame(view: self.backgroundView, frame: CGRect(origin: CGPoint(x: floorToScreenPixels((availableSize.width - contentSize.width) / 2.0), y: -y), size: contentSize), completion: nil) } else { transition.setFrame(view: self.contentView, frame: CGRect(origin: .zero, size: contentSize), completion: nil) transition.setFrame(view: self.backgroundView, frame: CGRect(origin: .zero, size: CGSize(width: contentSize.width, height: contentSize.height + 1000.0)), completion: nil) diff --git a/submodules/PeerInfoUI/Sources/ChannelVisibilityController.swift b/submodules/PeerInfoUI/Sources/ChannelVisibilityController.swift index 3e60943bf1..5313ec7bbe 100644 --- a/submodules/PeerInfoUI/Sources/ChannelVisibilityController.swift +++ b/submodules/PeerInfoUI/Sources/ChannelVisibilityController.swift @@ -871,7 +871,19 @@ private func channelVisibilityControllerEntries(presentationData: PresentationDa } else if let peer = view.peers[view.peerId] as? TelegramGroup { if case .revokeNames = mode { let count = Int32(publicChannelsToRevoke?.count ?? 0) - entries.append(.linksLimitInfo(presentationData.theme, presentationData.strings.Group_Username_RemoveExistingUsernamesOrExtendInfo("\(premiumLimits.maxPublicLinksCount)").string, count, limits.maxPublicLinksCount, premiumLimits.maxPublicLinksCount, isPremiumDisabled)) + + let text: String + if count >= premiumLimits.maxPublicLinksCount { + text = presentationData.strings.Group_Username_RemoveExistingUsernamesFinalInfo + } else { + if isPremiumDisabled { + text = presentationData.strings.Group_Username_RemoveExistingUsernamesNoPremiumInfo + } else { + text = presentationData.strings.Group_Username_RemoveExistingUsernamesOrExtendInfo("\(premiumLimits.maxPublicLinksCount)").string + } + } + + entries.append(.linksLimitInfo(presentationData.theme, text, count, limits.maxPublicLinksCount, premiumLimits.maxPublicLinksCount, isPremiumDisabled)) if let publicChannelsToRevoke = publicChannelsToRevoke { var index: Int32 = 0 diff --git a/submodules/PremiumUI/Sources/PremiumDemoScreen.swift b/submodules/PremiumUI/Sources/PremiumDemoScreen.swift index d5d47acc03..f510ecf189 100644 --- a/submodules/PremiumUI/Sources/PremiumDemoScreen.swift +++ b/submodules/PremiumUI/Sources/PremiumDemoScreen.swift @@ -1027,10 +1027,13 @@ private final class DemoSheetContent: CombinedComponent { ) let bottomPanelPadding: CGFloat = 12.0 - let bottomInset: CGFloat = environment.safeInsets.bottom > 0.0 ? environment.safeInsets.bottom + 5.0 : bottomPanelPadding - let contentSize = CGSize(width: context.availableSize.width, height: buttonFrame.maxY + bottomInset) - - return contentSize + let bottomInset: CGFloat + if case .regular = environment.metrics.widthClass { + bottomInset = bottomPanelPadding + } else { + bottomInset = environment.safeInsets.bottom > 0.0 ? environment.safeInsets.bottom + 5.0 : bottomPanelPadding + } + return CGSize(width: context.availableSize.width, height: buttonFrame.maxY + bottomInset) } } } @@ -1071,7 +1074,7 @@ private final class DemoSheetComponent: CombinedComponent { } static var body: Body { - let sheet = Child(SheetComponent.self) + let sheet = Child(SheetComponent<(EnvironmentType)>.self) let animateOut = StoredActionSlot(Action.self) return { context in diff --git a/submodules/TelegramCore/Sources/ApiUtils/BotInfo.swift b/submodules/TelegramCore/Sources/ApiUtils/BotInfo.swift index 33a38190f7..e57e2dd6c4 100644 --- a/submodules/TelegramCore/Sources/ApiUtils/BotInfo.swift +++ b/submodules/TelegramCore/Sources/ApiUtils/BotInfo.swift @@ -16,8 +16,9 @@ extension BotMenuButton { extension BotInfo { convenience init(apiBotInfo: Api.BotInfo) { switch apiBotInfo { - case let .botInfo(_, _, description, descriptionPhoto, _, apiCommands, apiMenuButton): + case let .botInfo(_, _, description, descriptionPhoto, descriptionDocument, apiCommands, apiMenuButton): let photo: TelegramMediaImage? = descriptionPhoto.flatMap(telegramMediaImageFromApiPhoto) + let video: TelegramMediaFile? = descriptionDocument.flatMap { telegramMediaFileFromApiDocument($0, noPremium: false) } var commands: [BotCommand] = [] if let apiCommands = apiCommands { commands = apiCommands.map { command in @@ -31,7 +32,7 @@ extension BotInfo { if let apiMenuButton = apiMenuButton { menuButton = BotMenuButton(apiBotMenuButton: apiMenuButton) } - self.init(description: description ?? "", photo: photo, commands: commands, menuButton: menuButton) + self.init(description: description ?? "", photo: photo, video: video, commands: commands, menuButton: menuButton) } } } diff --git a/submodules/TelegramCore/Sources/State/AccountStateManagementUtils.swift b/submodules/TelegramCore/Sources/State/AccountStateManagementUtils.swift index 24212dd5e2..ce595b876b 100644 --- a/submodules/TelegramCore/Sources/State/AccountStateManagementUtils.swift +++ b/submodules/TelegramCore/Sources/State/AccountStateManagementUtils.swift @@ -1470,14 +1470,14 @@ private func finalStateWithUpdatesAndServerTime(postbox: Postbox, network: Netwo updatedState.updateCachedPeerData(peer.peerId, { current in if peer.peerId.namespace == Namespaces.Peer.CloudUser, let previous = current as? CachedUserData { if let botInfo = previous.botInfo { - return previous.withUpdatedBotInfo(BotInfo(description: botInfo.description, photo: botInfo.photo, commands: commands, menuButton: botInfo.menuButton)) + return previous.withUpdatedBotInfo(BotInfo(description: botInfo.description, photo: botInfo.photo, video: botInfo.video, commands: commands, menuButton: botInfo.menuButton)) } } else if peer.peerId.namespace == Namespaces.Peer.CloudGroup, let previous = current as? CachedGroupData { if let index = previous.botInfos.firstIndex(where: { $0.peerId == botPeerId }) { var updatedBotInfos = previous.botInfos let previousBotInfo = updatedBotInfos[index] updatedBotInfos.remove(at: index) - updatedBotInfos.insert(CachedPeerBotInfo(peerId: botPeerId, botInfo: BotInfo(description: previousBotInfo.botInfo.description, photo: previousBotInfo.botInfo.photo, commands: commands, menuButton: previousBotInfo.botInfo.menuButton)), at: index) + updatedBotInfos.insert(CachedPeerBotInfo(peerId: botPeerId, botInfo: BotInfo(description: previousBotInfo.botInfo.description, photo: previousBotInfo.botInfo.photo, video: previousBotInfo.botInfo.video, commands: commands, menuButton: previousBotInfo.botInfo.menuButton)), at: index) return previous.withUpdatedBotInfos(updatedBotInfos) } } else if peer.peerId.namespace == Namespaces.Peer.CloudChannel, let previous = current as? CachedChannelData { @@ -1485,7 +1485,7 @@ private func finalStateWithUpdatesAndServerTime(postbox: Postbox, network: Netwo var updatedBotInfos = previous.botInfos let previousBotInfo = updatedBotInfos[index] updatedBotInfos.remove(at: index) - updatedBotInfos.insert(CachedPeerBotInfo(peerId: botPeerId, botInfo: BotInfo(description: previousBotInfo.botInfo.description, photo: previousBotInfo.botInfo.photo, commands: commands, menuButton: previousBotInfo.botInfo.menuButton)), at: index) + updatedBotInfos.insert(CachedPeerBotInfo(peerId: botPeerId, botInfo: BotInfo(description: previousBotInfo.botInfo.description, photo: previousBotInfo.botInfo.photo, video: previousBotInfo.botInfo.video, commands: commands, menuButton: previousBotInfo.botInfo.menuButton)), at: index) return previous.withUpdatedBotInfos(updatedBotInfos) } } @@ -1497,7 +1497,7 @@ private func finalStateWithUpdatesAndServerTime(postbox: Postbox, network: Netwo updatedState.updateCachedPeerData(botPeerId, { current in if let previous = current as? CachedUserData { if let botInfo = previous.botInfo { - return previous.withUpdatedBotInfo(BotInfo(description: botInfo.description, photo: botInfo.photo, commands: botInfo.commands, menuButton: menuButton)) + return previous.withUpdatedBotInfo(BotInfo(description: botInfo.description, photo: botInfo.photo, video: botInfo.video, commands: botInfo.commands, menuButton: menuButton)) } } return current diff --git a/submodules/TelegramCore/Sources/SyncCore/SyncCore_BotInfo.swift b/submodules/TelegramCore/Sources/SyncCore/SyncCore_BotInfo.swift index 161992ff66..cb16fd9f6e 100644 --- a/submodules/TelegramCore/Sources/SyncCore/SyncCore_BotInfo.swift +++ b/submodules/TelegramCore/Sources/SyncCore/SyncCore_BotInfo.swift @@ -48,12 +48,14 @@ public enum BotMenuButton: PostboxCoding, Hashable { public final class BotInfo: PostboxCoding, Equatable { public let description: String public let photo: TelegramMediaImage? + public let video: TelegramMediaFile? public let commands: [BotCommand] public let menuButton: BotMenuButton - public init(description: String, photo: TelegramMediaImage?, commands: [BotCommand], menuButton: BotMenuButton) { + public init(description: String, photo: TelegramMediaImage?, video: TelegramMediaFile?, commands: [BotCommand], menuButton: BotMenuButton) { self.description = description self.photo = photo + self.video = video self.commands = commands self.menuButton = menuButton } @@ -65,6 +67,11 @@ public final class BotInfo: PostboxCoding, Equatable { } else { self.photo = nil } + if let video = decoder.decodeObjectForKey("vid", decoder: { TelegramMediaFile(decoder: $0) }) as? TelegramMediaFile { + self.video = video + } else { + self.video = nil + } self.commands = decoder.decodeObjectArrayWithDecoderForKey("c") self.menuButton = (decoder.decodeObjectForKey("b", decoder: { BotMenuButton(decoder: $0) }) as? BotMenuButton) ?? .commands } @@ -76,11 +83,16 @@ public final class BotInfo: PostboxCoding, Equatable { } else { encoder.encodeNil(forKey: "ph") } + if let video = self.video { + encoder.encodeObject(video, forKey: "vid") + } else { + encoder.encodeNil(forKey: "vid") + } encoder.encodeObjectArray(self.commands, forKey: "c") encoder.encodeObject(self.menuButton, forKey: "b") } public static func ==(lhs: BotInfo, rhs: BotInfo) -> Bool { - return lhs.description == rhs.description && lhs.commands == rhs.commands && lhs.menuButton == rhs.menuButton + return lhs.description == rhs.description && lhs.commands == rhs.commands && lhs.menuButton == rhs.menuButton && lhs.photo != rhs.photo } } diff --git a/submodules/TelegramCore/Sources/SyncCore/SyncCore_Namespaces.swift b/submodules/TelegramCore/Sources/SyncCore/SyncCore_Namespaces.swift index acd5448e77..db298b43d9 100644 --- a/submodules/TelegramCore/Sources/SyncCore/SyncCore_Namespaces.swift +++ b/submodules/TelegramCore/Sources/SyncCore/SyncCore_Namespaces.swift @@ -39,7 +39,7 @@ public struct Namespaces { } public struct ItemCollection { - public static let CloudStickerPacks: Int32 = 0 + public static let CloudStickerPacks: Int32 = 7 public static let CloudMaskPacks: Int32 = 1 public static let EmojiKeywords: Int32 = 2 public static let CloudAnimatedEmoji: Int32 = 3 diff --git a/versions.json b/versions.json index bc23f2426b..270d00c4a1 100644 --- a/versions.json +++ b/versions.json @@ -1,5 +1,5 @@ { - "app": "8.8", + "app": "8.8.1", "bazel": "5.1.0", "xcode": "13.4.1" } From 3f4308f366fa470be7097b33ff2568805b378232 Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Mon, 20 Jun 2022 22:43:28 +0500 Subject: [PATCH 11/16] Various fixes --- submodules/PremiumUI/BUILD | 1 + .../Sources/PremiumStarComponent.swift | 21 ++- ...agedPremiumPromoConfigurationUpdates.swift | 8 +- .../TelegramUI/Sources/ChatBotInfoItem.swift | 155 +++++++++++++++++- .../Sources/ChatHistoryEntriesForView.swift | 4 +- .../TelegramUI/Sources/ChatHistoryEntry.swift | 6 +- .../Sources/ChatHistoryListNode.swift | 8 +- 7 files changed, 184 insertions(+), 19 deletions(-) diff --git a/submodules/PremiumUI/BUILD b/submodules/PremiumUI/BUILD index 12c178b056..4728a45871 100644 --- a/submodules/PremiumUI/BUILD +++ b/submodules/PremiumUI/BUILD @@ -92,6 +92,7 @@ swift_library( "//submodules/TelegramUniversalVideoContent:TelegramUniversalVideoContent", "//submodules/RadialStatusNode:RadialStatusNode", "//submodules/ShimmerEffect:ShimmerEffect", + "//submodules/LegacyComponents:LegacyComponents", ], visibility = [ "//visibility:public", diff --git a/submodules/PremiumUI/Sources/PremiumStarComponent.swift b/submodules/PremiumUI/Sources/PremiumStarComponent.swift index b8a463b502..9ec5fe42b9 100644 --- a/submodules/PremiumUI/Sources/PremiumStarComponent.swift +++ b/submodules/PremiumUI/Sources/PremiumStarComponent.swift @@ -6,6 +6,7 @@ import SwiftSignalKit import SceneKit import GZip import AppBundle +import LegacyComponents private let sceneVersion: Int = 3 @@ -421,14 +422,22 @@ class PremiumStarComponent: Component { particles.particleSystems?.first?.birthRate = 1.2 particleSystem.particleVelocity = 1.0 particleSystem.particleLifeSpan = 4.0 - particleSystem.speedFactor = 1.0 - let animation = CABasicAnimation(keyPath: "speedFactor") - animation.fromValue = 2.0 - animation.toValue = 1.0 + let animation = POPBasicAnimation() + animation.property = (POPAnimatableProperty.property(withName: "speedFactor", initializer: { property in + property?.readBlock = { particleSystem, values in + values?.pointee = (particleSystem as! SCNParticleSystem).speedFactor + } + property?.writeBlock = { particleSystem, values in + (particleSystem as! SCNParticleSystem).speedFactor = values!.pointee + } + property?.threshold = 0.01 + }) as! POPAnimatableProperty) + animation.fromValue = 2.0 as NSNumber + animation.toValue = 1.0 as NSNumber + animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear) animation.duration = 0.5 - animation.timingFunction = CAMediaTimingFunction(name: .easeIn) - particleSystem.addAnimation(animation, forKey: "speedFactor") + particleSystem.pop_add(animation, forKey: "speedFactor") } } } diff --git a/submodules/TelegramCore/Sources/State/ManagedPremiumPromoConfigurationUpdates.swift b/submodules/TelegramCore/Sources/State/ManagedPremiumPromoConfigurationUpdates.swift index 764852ce33..5355396ad5 100644 --- a/submodules/TelegramCore/Sources/State/ManagedPremiumPromoConfigurationUpdates.swift +++ b/submodules/TelegramCore/Sources/State/ManagedPremiumPromoConfigurationUpdates.swift @@ -21,8 +21,12 @@ func updatePremiumPromoConfigurationOnce(postbox: Postbox, network: Network) -> return postbox.transaction { transaction -> Void in if case let .premiumPromo(_, _, _, _, _, _, apiUsers) = result { let users = apiUsers.map { TelegramUser(user: $0) } - updatePeers(transaction: transaction, peers: users, update: { _, updated -> Peer in - return updated + updatePeers(transaction: transaction, peers: users, update: { current, updated -> Peer in + if let updated = updated as? TelegramUser { + return TelegramUser.merge(lhs: current as? TelegramUser, rhs: updated) + } else { + return updated + } }) } diff --git a/submodules/TelegramUI/Sources/ChatBotInfoItem.swift b/submodules/TelegramUI/Sources/ChatBotInfoItem.swift index eaad36093e..3573575175 100644 --- a/submodules/TelegramUI/Sources/ChatBotInfoItem.swift +++ b/submodules/TelegramUI/Sources/ChatBotInfoItem.swift @@ -10,6 +10,8 @@ import TextFormat import UrlEscaping import PhotoResources import AccountContext +import UniversalMediaPlayer +import TelegramUniversalVideoContent private let messageFont = Font.regular(17.0) private let messageBoldFont = Font.semibold(17.0) @@ -21,14 +23,16 @@ final class ChatBotInfoItem: ListViewItem { fileprivate let title: String fileprivate let text: String fileprivate let photo: TelegramMediaImage? + fileprivate let video: TelegramMediaFile? fileprivate let controllerInteraction: ChatControllerInteraction fileprivate let presentationData: ChatPresentationData fileprivate let context: AccountContext - init(title: String, text: String, photo: TelegramMediaImage?, controllerInteraction: ChatControllerInteraction, presentationData: ChatPresentationData, context: AccountContext) { + init(title: String, text: String, photo: TelegramMediaImage?, video: TelegramMediaFile?, controllerInteraction: ChatControllerInteraction, presentationData: ChatPresentationData, context: AccountContext) { self.title = title self.text = text self.photo = photo + self.video = video self.controllerInteraction = controllerInteraction self.presentationData = presentationData self.context = context @@ -83,6 +87,7 @@ final class ChatBotInfoItemNode: ListViewItemNode { let offsetContainer: ASDisplayNode let backgroundNode: ASImageNode let imageNode: TransformImageNode + var videoNode: UniversalVideoNode? let titleNode: TextNode let textNode: TextNode private var linkHighlightingNode: LinkHighlightingNode? @@ -121,6 +126,30 @@ final class ChatBotInfoItemNode: ListViewItemNode { self.fetchDisposable.dispose() } + private func setup(context: AccountContext, videoFile: TelegramMediaFile?) { + guard self.videoNode == nil, let file = videoFile else { + return + } + + let videoContent = NativeVideoContent( + id: .message(1, MediaId(namespace: 0, id: Int64.random(in: 0.. Void)?) { + self.contentContainerNode.layer.animate(from: NSValue(cgRect: self.contentContainerNode.bounds), to: NSValue(cgRect: frame), keyPath: "bounds", timingFunction: kCAMediaTimingFunctionSpring, duration: 0.25, removeOnCompletion: false, completion: { _ in + }) + + if let maskLayer = self.contentContainerNode.layer.mask { + maskLayer.animate(from: NSValue(cgRect: self.contentContainerNode.bounds), to: NSValue(cgRect: frame), keyPath: "bounds", timingFunction: kCAMediaTimingFunctionSpring, duration: 0.25, removeOnCompletion: false, completion: { _ in + }) + + maskLayer.animate(from: NSValue(cgPoint: maskLayer.position), to: NSValue(cgPoint: CGPoint(x: frame.midX, y: frame.midY)), keyPath: "position", timingFunction: kCAMediaTimingFunctionSpring, duration: 0.25, removeOnCompletion: false, completion: { _ in + }) + } + + if let contentNode = self.contentNode { + contentNode.layer.animate(from: NSValue(cgPoint: contentNode.layer.position), to: NSValue(cgPoint: CGPoint(x: frame.midX, y: frame.midY)), keyPath: "position", timingFunction: kCAMediaTimingFunctionSpring, duration: 0.25, removeOnCompletion: false, completion: { _ in + completion?() + }) + } + } + + public func updateContentNodeSnapshot(_ snapshot: UIView?) { + } + + public func updateLayout(size: CGSize, transition: ContainedViewLayoutTransition) { + self.validLayoutSize = size + + let bounds = CGRect(origin: CGPoint(), size: size) + if let backgroundNode = self.backgroundNode { + transition.updateFrame(node: backgroundNode, frame: bounds) + } + if let foregroundNode = self.foregroundNode { + transition.updateFrame(node: foregroundNode, frame: bounds) + } + transition.updateFrame(node: self.contentContainerNode, frame: bounds) + if let maskLayer = self.contentContainerNode.layer.mask { + transition.updateFrame(layer: maskLayer, frame: bounds) + } + if let contentNode = self.contentNode { + transition.updateFrame(node: contentNode, frame: CGRect(origin: CGPoint(), size: size)) + contentNode.updateLayout(size: size, transition: transition) + } + } + + public func setStatus(_ status: Signal) { + } + + public func tap() { + } +} diff --git a/submodules/TelegramUI/Sources/ChatHistoryEntriesForView.swift b/submodules/TelegramUI/Sources/ChatHistoryEntriesForView.swift index 306f6b43d3..19bfb4cdf8 100644 --- a/submodules/TelegramUI/Sources/ChatHistoryEntriesForView.swift +++ b/submodules/TelegramUI/Sources/ChatHistoryEntriesForView.swift @@ -254,9 +254,9 @@ func chatHistoryEntriesForView( } } if case let .peer(peerId) = location, peerId.isReplies { - entries.insert(.ChatInfoEntry("", presentationData.strings.RepliesChat_DescriptionText, nil, presentationData), at: 0) + entries.insert(.ChatInfoEntry("", presentationData.strings.RepliesChat_DescriptionText, nil, nil, presentationData), at: 0) } else if let cachedPeerData = cachedPeerData as? CachedUserData, let botInfo = cachedPeerData.botInfo, !botInfo.description.isEmpty { - entries.insert(.ChatInfoEntry(presentationData.strings.Bot_DescriptionTitle, botInfo.description, botInfo.photo, presentationData), at: 0) + entries.insert(.ChatInfoEntry(presentationData.strings.Bot_DescriptionTitle, botInfo.description, botInfo.photo, botInfo.video, presentationData), at: 0) } else { var isEmpty = true if entries.count <= 3 { diff --git a/submodules/TelegramUI/Sources/ChatHistoryEntry.swift b/submodules/TelegramUI/Sources/ChatHistoryEntry.swift index 576b987534..dc2ea4241d 100644 --- a/submodules/TelegramUI/Sources/ChatHistoryEntry.swift +++ b/submodules/TelegramUI/Sources/ChatHistoryEntry.swift @@ -43,7 +43,7 @@ enum ChatHistoryEntry: Identifiable, Comparable { case MessageGroupEntry(MessageGroupInfo, [(Message, Bool, ChatHistoryMessageSelection, ChatMessageEntryAttributes, MessageHistoryEntryLocation?)], ChatPresentationData) case UnreadEntry(MessageIndex, ChatPresentationData) case ReplyCountEntry(MessageIndex, Bool, Int, ChatPresentationData) - case ChatInfoEntry(String, String, TelegramMediaImage?, ChatPresentationData) + case ChatInfoEntry(String, String, TelegramMediaImage?, TelegramMediaFile?, ChatPresentationData) case SearchEntry(PresentationTheme, PresentationStrings) var stableId: UInt64 { @@ -201,8 +201,8 @@ enum ChatHistoryEntry: Identifiable, Comparable { } else { return false } - case let .ChatInfoEntry(lhsTitle, lhsText, lhsPhoto, lhsPresentationData): - if case let .ChatInfoEntry(rhsTitle, rhsText, rhsPhoto, rhsPresentationData) = rhs, lhsTitle == rhsTitle, lhsText == rhsText, lhsPhoto == rhsPhoto, lhsPresentationData === rhsPresentationData { + case let .ChatInfoEntry(lhsTitle, lhsText, lhsPhoto, lhsVideo, lhsPresentationData): + if case let .ChatInfoEntry(rhsTitle, rhsText, rhsPhoto, rhsVideo, rhsPresentationData) = rhs, lhsTitle == rhsTitle, lhsText == rhsText, lhsPhoto == rhsPhoto, lhsVideo == rhsVideo, lhsPresentationData === rhsPresentationData { return true } else { return false diff --git a/submodules/TelegramUI/Sources/ChatHistoryListNode.swift b/submodules/TelegramUI/Sources/ChatHistoryListNode.swift index 9bbc76a83f..90c1257da4 100644 --- a/submodules/TelegramUI/Sources/ChatHistoryListNode.swift +++ b/submodules/TelegramUI/Sources/ChatHistoryListNode.swift @@ -247,8 +247,8 @@ private func mappedInsertEntries(context: AccountContext, chatLocation: ChatLoca return ListViewInsertItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatUnreadItem(index: entry.entry.index, presentationData: presentationData, context: context), directionHint: entry.directionHint) case let .ReplyCountEntry(_, isComments, count, presentationData): return ListViewInsertItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatReplyCountItem(index: entry.entry.index, isComments: isComments, count: count, presentationData: presentationData, context: context, controllerInteraction: controllerInteraction), directionHint: entry.directionHint) - case let .ChatInfoEntry(title, text, photo, presentationData): - return ListViewInsertItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatBotInfoItem(title: title, text: text, photo: photo, controllerInteraction: controllerInteraction, presentationData: presentationData, context: context), directionHint: entry.directionHint) + case let .ChatInfoEntry(title, text, photo, video, presentationData): + return ListViewInsertItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatBotInfoItem(title: title, text: text, photo: photo, video: video, controllerInteraction: controllerInteraction, presentationData: presentationData, context: context), directionHint: entry.directionHint) case let .SearchEntry(theme, strings): return ListViewInsertItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatListSearchItem(theme: theme, placeholder: strings.Common_Search, activate: { controllerInteraction.openSearch() @@ -292,8 +292,8 @@ private func mappedUpdateEntries(context: AccountContext, chatLocation: ChatLoca return ListViewUpdateItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatUnreadItem(index: entry.entry.index, presentationData: presentationData, context: context), directionHint: entry.directionHint) case let .ReplyCountEntry(_, isComments, count, presentationData): return ListViewUpdateItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatReplyCountItem(index: entry.entry.index, isComments: isComments, count: count, presentationData: presentationData, context: context, controllerInteraction: controllerInteraction), directionHint: entry.directionHint) - case let .ChatInfoEntry(title, text, photo, presentationData): - return ListViewUpdateItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatBotInfoItem(title: title, text: text, photo: photo, controllerInteraction: controllerInteraction, presentationData: presentationData, context: context), directionHint: entry.directionHint) + case let .ChatInfoEntry(title, text, photo, video, presentationData): + return ListViewUpdateItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatBotInfoItem(title: title, text: text, photo: photo, video: video, controllerInteraction: controllerInteraction, presentationData: presentationData, context: context), directionHint: entry.directionHint) case let .SearchEntry(theme, strings): return ListViewUpdateItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatListSearchItem(theme: theme, placeholder: strings.Common_Search, activate: { controllerInteraction.openSearch() From 009d2445d2f1033532fde6a1fcab2427fe5d64ee Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Tue, 21 Jun 2022 10:09:22 +0500 Subject: [PATCH 12/16] Various fixes --- submodules/TelegramUI/Sources/ChatBotInfoItem.swift | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/submodules/TelegramUI/Sources/ChatBotInfoItem.swift b/submodules/TelegramUI/Sources/ChatBotInfoItem.swift index 3573575175..fc5b3f0180 100644 --- a/submodules/TelegramUI/Sources/ChatBotInfoItem.swift +++ b/submodules/TelegramUI/Sources/ChatBotInfoItem.swift @@ -132,9 +132,9 @@ final class ChatBotInfoItemNode: ListViewItemNode { } let videoContent = NativeVideoContent( - id: .message(1, MediaId(namespace: 0, id: Int64.random(in: 0.. Date: Tue, 21 Jun 2022 09:48:48 +0100 Subject: [PATCH 13/16] Update tgcalls --- submodules/TgVoipWebrtc/tgcalls | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/submodules/TgVoipWebrtc/tgcalls b/submodules/TgVoipWebrtc/tgcalls index 7dd3cf86a3..c2620d42ee 160000 --- a/submodules/TgVoipWebrtc/tgcalls +++ b/submodules/TgVoipWebrtc/tgcalls @@ -1 +1 @@ -Subproject commit 7dd3cf86a3daa1ee8c1022930816cc8044d0ed5b +Subproject commit c2620d42ee6cff0c9fb078c1a6956c5c7fb6448e From 089eec1c09e72cd376f7e179a756577f3ca60ac4 Mon Sep 17 00:00:00 2001 From: Ali <> Date: Tue, 21 Jun 2022 09:49:02 +0100 Subject: [PATCH 14/16] Disable secret chat transcription --- .../TelegramUI/Sources/ChatMessageInteractiveFileNode.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/submodules/TelegramUI/Sources/ChatMessageInteractiveFileNode.swift b/submodules/TelegramUI/Sources/ChatMessageInteractiveFileNode.swift index 291367eac0..c7d82877f9 100644 --- a/submodules/TelegramUI/Sources/ChatMessageInteractiveFileNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageInteractiveFileNode.swift @@ -545,7 +545,7 @@ final class ChatMessageInteractiveFileNode: ASDisplayNode { var isVoice = false var audioDuration: Int32 = 0 - let canTranscribe = arguments.associatedData.isPremium + let canTranscribe = arguments.associatedData.isPremium && arguments.message.id.peerId.namespace != Namespaces.Peer.SecretChat let messageTheme = arguments.incoming ? arguments.presentationData.theme.theme.chat.message.incoming : arguments.presentationData.theme.theme.chat.message.outgoing From bd4d32d2937a6ba74609a25185a6c7b5a7f7177f Mon Sep 17 00:00:00 2001 From: Ali <> Date: Tue, 21 Jun 2022 09:49:27 +0100 Subject: [PATCH 15/16] Debugging --- submodules/TelegramCore/BUILD | 1 + .../Sources/Account/Account.swift | 6 ++ ...onizeInstalledStickerPacksOperations.swift | 57 ++++++++++++++++++- .../Sources/OngoingCallContext.swift | 2 +- 4 files changed, 64 insertions(+), 2 deletions(-) diff --git a/submodules/TelegramCore/BUILD b/submodules/TelegramCore/BUILD index 4a708502fb..28ab942151 100644 --- a/submodules/TelegramCore/BUILD +++ b/submodules/TelegramCore/BUILD @@ -21,6 +21,7 @@ swift_library( "//submodules/Reachability:Reachability", "//submodules/ManagedFile:ManagedFile", "//submodules/Utils/RangeSet:RangeSet", + "//submodules/GZip:GZip", ], visibility = [ "//visibility:public", diff --git a/submodules/TelegramCore/Sources/Account/Account.swift b/submodules/TelegramCore/Sources/Account/Account.swift index aa05f25316..39dc7502c4 100644 --- a/submodules/TelegramCore/Sources/Account/Account.swift +++ b/submodules/TelegramCore/Sources/Account/Account.swift @@ -1195,6 +1195,12 @@ public class Account { self?.restartConfigurationUpdates() } self.restartConfigurationUpdates() + + /*#if DEBUG + self.managedOperationsDisposable.add(debugFetchAllStickers(account: self).start(completed: { + print("debugFetchAllStickers done") + })) + #endif*/ } deinit { diff --git a/submodules/TelegramCore/Sources/State/ManagedSynchronizeInstalledStickerPacksOperations.swift b/submodules/TelegramCore/Sources/State/ManagedSynchronizeInstalledStickerPacksOperations.swift index efe4429c23..c046850633 100644 --- a/submodules/TelegramCore/Sources/State/ManagedSynchronizeInstalledStickerPacksOperations.swift +++ b/submodules/TelegramCore/Sources/State/ManagedSynchronizeInstalledStickerPacksOperations.swift @@ -3,7 +3,7 @@ import Postbox import SwiftSignalKit import TelegramApi import MtProtoKit - +import GZip private final class ManagedSynchronizeInstalledStickerPacksOperationsHelper { var operationDisposables: [Int32: Disposable] = [:] @@ -374,6 +374,61 @@ private func synchronizeInstalledStickerPacks(transaction: Transaction, postbox: } } +#if DEBUG + +func debugFetchAllStickers(account: Account) -> Signal { + let orderedItemListCollectionIds: [Int32] = [Namespaces.OrderedItemList.CloudSavedStickers] + let namespaces: [ItemCollectionId.Namespace] = [Namespaces.ItemCollection.CloudStickerPacks] + let stickerItems: Signal<[TelegramMediaFile], NoError> = account.postbox.itemCollectionsView(orderedItemListCollectionIds: orderedItemListCollectionIds, namespaces: namespaces, aroundIndex: nil, count: 10000000) + |> map { view -> [TelegramMediaFile] in + var files: [TelegramMediaFile] = [] + for entry in view.entries { + guard let item = entry.item as? StickerPackItem else { + continue + } + if !item.file.isAnimatedSticker { + continue + } + files.append(item.file) + } + return files + } + |> take(1) + + return stickerItems + |> mapToSignal { files -> Signal in + var loadFileSignals: [Signal] = [] + + let tempDir = TempBox.shared.tempDirectory() + print("debugFetchAllStickers into \(tempDir.path)") + + for file in files { + loadFileSignals.append(Signal { subscriber in + let fetch = fetchedMediaResource(mediaBox: account.postbox.mediaBox, reference: stickerPackFileReference(file).resourceReference(file.resource)).start() + let data = (account.postbox.mediaBox.resourceData(file.resource) + |> filter { $0.complete } + |> take(1)).start(next: { data in + if let dataValue = try? Data(contentsOf: URL(fileURLWithPath: data.path)), let unpackedData = TGGUnzipData(dataValue, 5 * 1024 * 1024) { + let filePath = tempDir.path + "/\(file.fileId.id).json" + let _ = try? unpackedData.write(to: URL(fileURLWithPath: filePath), options: .atomic) + subscriber.putCompletion() + } + }) + + return ActionDisposable { + fetch.dispose() + data.dispose() + } + }) + } + + return combineLatest(loadFileSignals) + |> ignoreValues + } +} + +#endif + private func continueSynchronizeInstalledStickerPacks(transaction: Transaction, postbox: Postbox, network: Network, stateManager: AccountStateManager, namespace: SynchronizeInstalledStickerPacksOperationNamespace, operation: SynchronizeInstalledStickerPacksOperation) -> Signal { let collectionNamespace: ItemCollectionId.Namespace switch namespace { diff --git a/submodules/TelegramVoip/Sources/OngoingCallContext.swift b/submodules/TelegramVoip/Sources/OngoingCallContext.swift index 39523582e1..8f24013ef5 100644 --- a/submodules/TelegramVoip/Sources/OngoingCallContext.swift +++ b/submodules/TelegramVoip/Sources/OngoingCallContext.swift @@ -738,7 +738,7 @@ public final class OngoingCallContext { private var signalingConnectionManager: QueueLocalObject? public static func versions(includeExperimental: Bool, includeReference: Bool) -> [(version: String, supportsVideo: Bool)] { - #if os(iOS) && DEBUG + #if os(iOS) && DEBUG && false if "".isEmpty { return [("5.0.0", true)] } From 75d3449e44d3711f19bc1b6a45099fb4603e3a55 Mon Sep 17 00:00:00 2001 From: Ali <> Date: Tue, 21 Jun 2022 09:49:42 +0100 Subject: [PATCH 16/16] Use custom currency formatting --- .../Sources/CurrencyFormat.swift | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/submodules/TelegramStringFormatting/Sources/CurrencyFormat.swift b/submodules/TelegramStringFormatting/Sources/CurrencyFormat.swift index b4aab4c33d..2986a87c58 100644 --- a/submodules/TelegramStringFormatting/Sources/CurrencyFormat.swift +++ b/submodules/TelegramStringFormatting/Sources/CurrencyFormat.swift @@ -19,6 +19,21 @@ private final class CurrencyFormatterEntry { } } +private func getCurrencyExp(currency: String) -> Int { + switch currency { + case "CLF": + return 4 + case "BHD", "IQD", "JOD", "KWD", "LYD", "OMR", "TND": + return 3 + case "BIF", "BYR", "CLP", "CVE", "DJF", "GNF", "ISK", "JPY", "KMF", "KRW", "MGA", "PYG", "RWF", "UGX", "UYI", "VND", "VUV", "XAF", "XOF", "XPF": + return 0 + case "MRO": + return 1 + default: + return 2 + } +} + private func loadCurrencyFormatterEntries() -> [String: CurrencyFormatterEntry] { guard let filePath = getAppBundle().path(forResource: "currencies", ofType: "json") else { return [:] @@ -35,7 +50,14 @@ private func loadCurrencyFormatterEntries() -> [String: CurrencyFormatterEntry] for (code, contents) in dict { if let contentsDict = contents as? [String: AnyObject] { - let entry = CurrencyFormatterEntry(symbol: contentsDict["symbol"] as! String, thousandsSeparator: contentsDict["thousandsSeparator"] as! String, decimalSeparator: contentsDict["decimalSeparator"] as! String, symbolOnLeft: (contentsDict["symbolOnLeft"] as! NSNumber).boolValue, spaceBetweenAmountAndSymbol: (contentsDict["spaceBetweenAmountAndSymbol"] as! NSNumber).boolValue, decimalDigits: (contentsDict["decimalDigits"] as! NSNumber).intValue) + let entry = CurrencyFormatterEntry( + symbol: contentsDict["symbol"] as! String, + thousandsSeparator: contentsDict["thousandsSeparator"] as! String, + decimalSeparator: contentsDict["decimalSeparator"] as! String, + symbolOnLeft: (contentsDict["symbolOnLeft"] as! NSNumber).boolValue, + spaceBetweenAmountAndSymbol: (contentsDict["spaceBetweenAmountAndSymbol"] as! NSNumber).boolValue, + decimalDigits: getCurrencyExp(currency: code.uppercased()) + ) result[code] = entry result[code.lowercased()] = entry }