From 81f179be9d915744dac9da8d9c5f59adb2fc2a97 Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Thu, 12 May 2022 06:35:14 +0400 Subject: [PATCH] Various improvements --- .../ChatListUI/Sources/ChatContextMenus.swift | 4 +- .../Sources/ChatListController.swift | 4 +- .../ChatListFilterPresetListController.swift | 4 +- .../Sources/Node/ChatListNode.swift | 4 +- .../Sources/ChannelVisibilityController.swift | 6 +- .../Sources/IncreaseLimitHeaderItem.swift | 2 +- .../Sources/OldChannelsController.swift | 12 +++- submodules/PremiumUI/Resources/star.scn | Bin 506803 -> 506829 bytes .../Sources/PremiumIntroScreen.swift | 65 +++++++++++++----- .../TelegramUI/Sources/ChatController.swift | 4 +- 10 files changed, 68 insertions(+), 37 deletions(-) diff --git a/submodules/ChatListUI/Sources/ChatContextMenus.swift b/submodules/ChatListUI/Sources/ChatContextMenus.swift index 672ec628ea..23bc17ed13 100644 --- a/submodules/ChatListUI/Sources/ChatContextMenus.swift +++ b/submodules/ChatListUI/Sources/ChatContextMenus.swift @@ -323,9 +323,7 @@ func chatContextMenuItems(context: AccountContext, peerId: PeerId, promoInfo: Ch var replaceImpl: ((ViewController) -> Void)? let controller = PremiumLimitScreen(context: context, subject: .pins, action: { - let premiumScreen = PremiumIntroScreen(context: context, action: { - - }) + let premiumScreen = PremiumIntroScreen(context: context) replaceImpl?(premiumScreen) }) chatListController?.push(controller) diff --git a/submodules/ChatListUI/Sources/ChatListController.swift b/submodules/ChatListUI/Sources/ChatListController.swift index ad293b8e21..c91b6a73df 100644 --- a/submodules/ChatListUI/Sources/ChatListController.swift +++ b/submodules/ChatListUI/Sources/ChatListController.swift @@ -1342,9 +1342,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController if filter.data.includePeers.peers.count >= limit { var replaceImpl: ((ViewController) -> Void)? let controller = PremiumLimitScreen(context: context, subject: .chatsInFolder, action: { - let controller = PremiumIntroScreen(context: context, action: { - - }) + let controller = PremiumIntroScreen(context: context) replaceImpl?(controller) }) replaceImpl = { [weak controller] c in diff --git a/submodules/ChatListUI/Sources/ChatListFilterPresetListController.swift b/submodules/ChatListUI/Sources/ChatListFilterPresetListController.swift index 0abd8a75e6..0ae2c4f341 100644 --- a/submodules/ChatListUI/Sources/ChatListFilterPresetListController.swift +++ b/submodules/ChatListUI/Sources/ChatListFilterPresetListController.swift @@ -292,9 +292,7 @@ public func chatListFilterPresetListController(context: AccountContext, mode: Ch if filters.count >= limit { var replaceImpl: ((ViewController) -> Void)? let controller = PremiumLimitScreen(context: context, subject: .folders, action: { - let controller = PremiumIntroScreen(context: context, action: { - - }) + let controller = PremiumIntroScreen(context: context) replaceImpl?(controller) }) replaceImpl = { [weak controller] c in diff --git a/submodules/ChatListUI/Sources/Node/ChatListNode.swift b/submodules/ChatListUI/Sources/Node/ChatListNode.swift index a89b0b66c4..e77cf7a025 100644 --- a/submodules/ChatListUI/Sources/Node/ChatListNode.swift +++ b/submodules/ChatListUI/Sources/Node/ChatListNode.swift @@ -845,9 +845,7 @@ public final class ChatListNode: ListView { case .limitExceeded: var replaceImpl: ((ViewController) -> Void)? let controller = PremiumLimitScreen(context: context, subject: .pins, action: { - let premiumScreen = PremiumIntroScreen(context: context, action: { - - }) + let premiumScreen = PremiumIntroScreen(context: context) replaceImpl?(premiumScreen) }) replaceImpl = { [weak controller] c in diff --git a/submodules/PeerInfoUI/Sources/ChannelVisibilityController.swift b/submodules/PeerInfoUI/Sources/ChannelVisibilityController.swift index eba1682f2d..6f2fbef360 100644 --- a/submodules/PeerInfoUI/Sources/ChannelVisibilityController.swift +++ b/submodules/PeerInfoUI/Sources/ChannelVisibilityController.swift @@ -22,6 +22,7 @@ import InviteLinksUI import ContextUI import UndoUI import QrCodeUI +import PremiumUI private final class ChannelVisibilityControllerArguments { let context: AccountContext @@ -1628,7 +1629,10 @@ public func channelVisibilityController(context: AccountContext, updatedPresenta } if hasNamesToRevoke && selectedType == .publicChannel { - footerItem = IncreaseLimitFooterItem(theme: presentationData.theme, title: presentationData.strings.Premium_IncreaseLimit, colorful: true, action: {}) + footerItem = IncreaseLimitFooterItem(theme: presentationData.theme, title: presentationData.strings.Premium_IncreaseLimit, colorful: true, action: { + let controller = PremiumIntroScreen(context: context) + pushControllerImpl?(controller) + }) } if let hadNamesToRevoke = hadNamesToRevoke { diff --git a/submodules/PeerInfoUI/Sources/IncreaseLimitHeaderItem.swift b/submodules/PeerInfoUI/Sources/IncreaseLimitHeaderItem.swift index dc25f7f8b6..0e7cf8b938 100644 --- a/submodules/PeerInfoUI/Sources/IncreaseLimitHeaderItem.swift +++ b/submodules/PeerInfoUI/Sources/IncreaseLimitHeaderItem.swift @@ -145,7 +145,7 @@ class IncreaseLimitHeaderItemNode: ListViewItemNode { let size = strongSelf.hostView.update( transition: .immediate, component: AnyComponent(PremiumLimitDisplayComponent( - inactiveColor: UIColor(rgb: 0xE9E9EA), + inactiveColor: UIColor(rgb: 0xe3e3e9), activeColors: [ UIColor(rgb: 0x0077ff), UIColor(rgb: 0x6b93ff), diff --git a/submodules/PeerInfoUI/Sources/OldChannelsController.swift b/submodules/PeerInfoUI/Sources/OldChannelsController.swift index e09d89e53b..32ae339284 100644 --- a/submodules/PeerInfoUI/Sources/OldChannelsController.swift +++ b/submodules/PeerInfoUI/Sources/OldChannelsController.swift @@ -12,6 +12,7 @@ import AccountContext import ContactsPeerItem import SearchUI import SolidRoundedButtonNode +import PremiumUI func localizedOldChannelDate(peer: InactiveChannel, strings: PresentationStrings) -> String { let timestamp = peer.lastActivityDate @@ -216,6 +217,7 @@ public func oldChannelsController(context: AccountContext, updatedPresentationDa } var dismissImpl: (() -> Void)? + var pushImpl: ((ViewController) -> Void)? var setDisplayNavigationBarImpl: ((Bool) -> Void)? var ensurePeerVisibleImpl: ((PeerId) -> Void)? @@ -321,7 +323,12 @@ public func oldChannelsController(context: AccountContext, updatedPresentationDa colorful = true } let footerItem = IncreaseLimitFooterItem(theme: presentationData.theme, title: buttonText, colorful: colorful, action: { - leaveActionImpl?() + if state.selectedPeers.count > 0 { + leaveActionImpl?() + } else { + let controller = PremiumIntroScreen(context: context) + pushImpl?(controller) + } }) let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: oldChannelsEntries(presentationData: presentationData, state: state, limit: limits.maxChannelsCount, premiumLimit: premiumLimits.maxChannelsCount, peers: peers, intent: intent), style: .blocks, emptyStateItem: emptyStateItem, searchItem: searchItem, footerItem: footerItem, initialScrollToItem: ListViewScrollToItem(index: 0, position: .top(-navigationBarSearchContentHeight), animated: false, curve: .Default(duration: 0.0), directionHint: .Up), crossfadeState: peersAreEmptyUpdated, animateChanges: false) @@ -364,6 +371,9 @@ public func oldChannelsController(context: AccountContext, updatedPresentationDa dismissImpl = { [weak controller] in controller?.dismiss() } + pushImpl = { [weak controller] c in + controller?.push(c) + } setDisplayNavigationBarImpl = { [weak controller] display in controller?.setDisplayNavigationBar(display, transition: .animated(duration: 0.5, curve: .spring)) } diff --git a/submodules/PremiumUI/Resources/star.scn b/submodules/PremiumUI/Resources/star.scn index 926ae318295445b217f24bc86cbb6c460f782b3c..3fcbdaa2552fe2ebc15a232a77da896ceaabe04a 100644 GIT binary patch delta 8969 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 Float { } private class StarComponent: Component { + let isVisible: Bool + + init(isVisible: Bool) { + self.isVisible = isVisible + } + static func ==(lhs: StarComponent, rhs: StarComponent) -> Bool { - return true + return lhs.isVisible == rhs.isVisible } final class View: UIView, SCNSceneRendererDelegate, ComponentTaggedView { @@ -149,7 +155,7 @@ private class StarComponent: Component { smallAngle = true } - self.playAppearanceAnimation(velocity: velocity.x, smallAngle: smallAngle, explode: !smallAngle && velocity.x > 600) + self.playAppearanceAnimation(velocity: velocity.x, smallAngle: smallAngle, explode: !smallAngle && abs(velocity.x) > 600) node.rotation = SCNVector4(x: 0.0, y: 1.0, z: 0.0, w: 0.0) default: break @@ -237,12 +243,14 @@ private class StarComponent: Component { particleSystem?.particleColorVariation = SCNVector4(0.15, 0.2, 0.35, 0.3) particleSystem?.particleVelocity = 2.2 particleSystem?.birthRate = 4.5 + particleSystem?.particleLifeSpan = 2.0 node.physicsField?.isActive = true Queue.mainQueue().after(1.0) { node.physicsField?.isActive = false particles.particleSystems?.first?.birthRate = 1.2 particleSystem?.particleVelocity = 1.65 + particleSystem?.particleLifeSpan = 4.0 } } @@ -459,15 +467,18 @@ private final class ScrollComponent: Component { public let content: AnyComponent<(ChildEnvironment, ScrollChildEnvironment)> public let contentInsets: UIEdgeInsets public let contentOffsetUpdated: (_ top: CGFloat, _ bottom: CGFloat) -> Void + public let contentOffsetWillCommit: (UnsafeMutablePointer) -> Void public init( content: AnyComponent<(ChildEnvironment, ScrollChildEnvironment)>, contentInsets: UIEdgeInsets, - contentOffsetUpdated: @escaping (_ top: CGFloat, _ bottom: CGFloat) -> Void + contentOffsetUpdated: @escaping (_ top: CGFloat, _ bottom: CGFloat) -> Void, + contentOffsetWillCommit: @escaping (UnsafeMutablePointer) -> Void ) { self.content = content self.contentInsets = contentInsets self.contentOffsetUpdated = contentOffsetUpdated + self.contentOffsetWillCommit = contentOffsetWillCommit } public static func ==(lhs: ScrollComponent, rhs: ScrollComponent) -> Bool { @@ -504,12 +515,18 @@ private final class ScrollComponent: Component { guard let component = self.component, !self.ignoreDidScroll else { return } - let topOffset = scrollView.contentOffset.y let bottomOffset = max(0.0, scrollView.contentSize.height - scrollView.contentOffset.y - scrollView.frame.height) component.contentOffsetUpdated(topOffset, bottomOffset) } + public func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer) { + guard let component = self.component, !self.ignoreDidScroll else { + return + } + component.contentOffsetWillCommit(targetContentOffset) + } + required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } @@ -1043,11 +1060,9 @@ private final class PremiumIntroScreenComponent: CombinedComponent { typealias EnvironmentType = ViewControllerComponentContainer.Environment let context: AccountContext - let action: () -> Void - init(context: AccountContext, action: @escaping () -> Void) { + init(context: AccountContext) { self.context = context - self.action = action } static func ==(lhs: PremiumIntroScreenComponent, rhs: PremiumIntroScreenComponent) -> Bool { @@ -1083,9 +1098,14 @@ private final class PremiumIntroScreenComponent: CombinedComponent { let background = background.update(component: Rectangle(color: environment.theme.list.blocksBackgroundColor), environment: {}, availableSize: context.availableSize, transition: context.transition) + var starIsVisible = true + if let topContentOffset = state.topContentOffset, topContentOffset >= 123.0 { + starIsVisible = false + } + let star = star.update( - component: StarComponent(), - availableSize: CGSize(width: min(390.0, context.availableSize.width), height: 180.0), + component: StarComponent(isVisible: starIsVisible), + availableSize: CGSize(width: min(390.0, context.availableSize.width), height: 220.0), transition: context.transition ) @@ -1132,7 +1152,7 @@ private final class PremiumIntroScreenComponent: CombinedComponent { height: 50.0, cornerRadius: 10.0, gloss: true, - action: context.component.action + action: {} ), availableSize: CGSize(width: context.availableSize.width - sideInset * 2.0 - environment.safeInsets.left - environment.safeInsets.right, height: 50.0), transition: context.transition) @@ -1165,6 +1185,13 @@ private final class PremiumIntroScreenComponent: CombinedComponent { state?.topContentOffset = topContentOffset state?.bottomContentOffset = bottomContentOffset state?.updated(transition: .immediate) + }, + contentOffsetWillCommit: { targetContentOffset in + if targetContentOffset.pointee.y < 100.0 { + targetContentOffset.pointee = CGPoint(x: 0.0, y: 0.0) + } else if targetContentOffset.pointee.y < 123.0 { + targetContentOffset.pointee = CGPoint(x: 0.0, y: 123.0) + } } ), environment: { environment }, @@ -1184,19 +1211,21 @@ private final class PremiumIntroScreenComponent: CombinedComponent { let titleOffset: CGFloat let titleScale: CGFloat let titleOffsetDelta = 160.0 - environment.navigationHeight / 2.0 - + if let topContentOffset = state.topContentOffset { - topPanelAlpha = min(30.0, max(0.0, topContentOffset - 80.0)) / 30.0 + topPanelAlpha = min(20.0, max(0.0, topContentOffset - 95.0)) / 20.0 + let topContentOffset = topContentOffset + max(0.0, min(1.0, topContentOffset / titleOffsetDelta)) * 10.0 titleOffset = topContentOffset - titleScale = 1.0 - max(0.0, min(1.0, titleOffset / titleOffsetDelta)) * 0.36 + let fraction = max(0.0, min(1.0, titleOffset / titleOffsetDelta)) + titleScale = 1.0 - fraction * 0.36 } else { topPanelAlpha = 0.0 - titleOffset = 0.0 titleScale = 1.0 + titleOffset = 0.0 } context.add(star - .position(CGPoint(x: context.availableSize.width / 2.0, y: star.size.height / 2.0 - 10.0 - titleOffset * titleScale)) + .position(CGPoint(x: context.availableSize.width / 2.0, y: star.size.height / 2.0 - 30.0 - titleOffset * titleScale)) .scale(titleScale) ) @@ -1240,7 +1269,6 @@ private final class PremiumIntroScreenComponent: CombinedComponent { public final class PremiumIntroScreen: ViewControllerComponentContainer { private let context: AccountContext - private let action: () -> Void private var didSetReady = false private let _ready = Promise() @@ -1248,11 +1276,10 @@ public final class PremiumIntroScreen: ViewControllerComponentContainer { return self._ready } - public init(context: AccountContext, action: @escaping () -> Void) { + public init(context: AccountContext) { self.context = context - self.action = action - super.init(context: context, component: PremiumIntroScreenComponent(context: context, action: action), navigationBarAppearance: .transparent) + super.init(context: context, component: PremiumIntroScreenComponent(context: context), navigationBarAppearance: .transparent) let presentationData = context.sharedContext.currentPresentationData.with { $0 } diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index a71513f605..995c3849d7 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -7949,9 +7949,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G strongSelf.presentInGlobalOverlay(UndoOverlayController(presentationData: strongSelf.presentationData, content: .sticker(context: strongSelf.context, file: stickerFile, title: strongSelf.presentationData.strings.Premium_MaxFavedStickersTitle("5").string, text: strongSelf.presentationData.strings.Premium_MaxFavedStickersText("10").string), elevatedLayout: true, action: { [weak self] action in if let strongSelf = self { if case .info = action { - let controller = PremiumIntroScreen(context: strongSelf.context, action: { - - }) + let controller = PremiumIntroScreen(context: strongSelf.context) strongSelf.push(controller) return true }