Various improvements

This commit is contained in:
Ilya Laktyushin 2022-05-12 06:35:14 +04:00
parent d67875a3f6
commit 81f179be9d
10 changed files with 68 additions and 37 deletions

View File

@ -323,9 +323,7 @@ func chatContextMenuItems(context: AccountContext, peerId: PeerId, promoInfo: Ch
var replaceImpl: ((ViewController) -> Void)? var replaceImpl: ((ViewController) -> Void)?
let controller = PremiumLimitScreen(context: context, subject: .pins, action: { let controller = PremiumLimitScreen(context: context, subject: .pins, action: {
let premiumScreen = PremiumIntroScreen(context: context, action: { let premiumScreen = PremiumIntroScreen(context: context)
})
replaceImpl?(premiumScreen) replaceImpl?(premiumScreen)
}) })
chatListController?.push(controller) chatListController?.push(controller)

View File

@ -1342,9 +1342,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
if filter.data.includePeers.peers.count >= limit { if filter.data.includePeers.peers.count >= limit {
var replaceImpl: ((ViewController) -> Void)? var replaceImpl: ((ViewController) -> Void)?
let controller = PremiumLimitScreen(context: context, subject: .chatsInFolder, action: { let controller = PremiumLimitScreen(context: context, subject: .chatsInFolder, action: {
let controller = PremiumIntroScreen(context: context, action: { let controller = PremiumIntroScreen(context: context)
})
replaceImpl?(controller) replaceImpl?(controller)
}) })
replaceImpl = { [weak controller] c in replaceImpl = { [weak controller] c in

View File

@ -292,9 +292,7 @@ public func chatListFilterPresetListController(context: AccountContext, mode: Ch
if filters.count >= limit { if filters.count >= limit {
var replaceImpl: ((ViewController) -> Void)? var replaceImpl: ((ViewController) -> Void)?
let controller = PremiumLimitScreen(context: context, subject: .folders, action: { let controller = PremiumLimitScreen(context: context, subject: .folders, action: {
let controller = PremiumIntroScreen(context: context, action: { let controller = PremiumIntroScreen(context: context)
})
replaceImpl?(controller) replaceImpl?(controller)
}) })
replaceImpl = { [weak controller] c in replaceImpl = { [weak controller] c in

View File

@ -845,9 +845,7 @@ public final class ChatListNode: ListView {
case .limitExceeded: case .limitExceeded:
var replaceImpl: ((ViewController) -> Void)? var replaceImpl: ((ViewController) -> Void)?
let controller = PremiumLimitScreen(context: context, subject: .pins, action: { let controller = PremiumLimitScreen(context: context, subject: .pins, action: {
let premiumScreen = PremiumIntroScreen(context: context, action: { let premiumScreen = PremiumIntroScreen(context: context)
})
replaceImpl?(premiumScreen) replaceImpl?(premiumScreen)
}) })
replaceImpl = { [weak controller] c in replaceImpl = { [weak controller] c in

View File

@ -22,6 +22,7 @@ import InviteLinksUI
import ContextUI import ContextUI
import UndoUI import UndoUI
import QrCodeUI import QrCodeUI
import PremiumUI
private final class ChannelVisibilityControllerArguments { private final class ChannelVisibilityControllerArguments {
let context: AccountContext let context: AccountContext
@ -1628,7 +1629,10 @@ public func channelVisibilityController(context: AccountContext, updatedPresenta
} }
if hasNamesToRevoke && selectedType == .publicChannel { 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 { if let hadNamesToRevoke = hadNamesToRevoke {

View File

@ -145,7 +145,7 @@ class IncreaseLimitHeaderItemNode: ListViewItemNode {
let size = strongSelf.hostView.update( let size = strongSelf.hostView.update(
transition: .immediate, transition: .immediate,
component: AnyComponent(PremiumLimitDisplayComponent( component: AnyComponent(PremiumLimitDisplayComponent(
inactiveColor: UIColor(rgb: 0xE9E9EA), inactiveColor: UIColor(rgb: 0xe3e3e9),
activeColors: [ activeColors: [
UIColor(rgb: 0x0077ff), UIColor(rgb: 0x0077ff),
UIColor(rgb: 0x6b93ff), UIColor(rgb: 0x6b93ff),

View File

@ -12,6 +12,7 @@ import AccountContext
import ContactsPeerItem import ContactsPeerItem
import SearchUI import SearchUI
import SolidRoundedButtonNode import SolidRoundedButtonNode
import PremiumUI
func localizedOldChannelDate(peer: InactiveChannel, strings: PresentationStrings) -> String { func localizedOldChannelDate(peer: InactiveChannel, strings: PresentationStrings) -> String {
let timestamp = peer.lastActivityDate let timestamp = peer.lastActivityDate
@ -216,6 +217,7 @@ public func oldChannelsController(context: AccountContext, updatedPresentationDa
} }
var dismissImpl: (() -> Void)? var dismissImpl: (() -> Void)?
var pushImpl: ((ViewController) -> Void)?
var setDisplayNavigationBarImpl: ((Bool) -> Void)? var setDisplayNavigationBarImpl: ((Bool) -> Void)?
var ensurePeerVisibleImpl: ((PeerId) -> Void)? var ensurePeerVisibleImpl: ((PeerId) -> Void)?
@ -321,7 +323,12 @@ public func oldChannelsController(context: AccountContext, updatedPresentationDa
colorful = true colorful = true
} }
let footerItem = IncreaseLimitFooterItem(theme: presentationData.theme, title: buttonText, colorful: colorful, action: { 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) 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 dismissImpl = { [weak controller] in
controller?.dismiss() controller?.dismiss()
} }
pushImpl = { [weak controller] c in
controller?.push(c)
}
setDisplayNavigationBarImpl = { [weak controller] display in setDisplayNavigationBarImpl = { [weak controller] display in
controller?.setDisplayNavigationBar(display, transition: .animated(duration: 0.5, curve: .spring)) controller?.setDisplayNavigationBar(display, transition: .animated(duration: 0.5, curve: .spring))
} }

View File

@ -23,8 +23,14 @@ private func rad2deg(_ number: Float) -> Float {
} }
private class StarComponent: Component { private class StarComponent: Component {
let isVisible: Bool
init(isVisible: Bool) {
self.isVisible = isVisible
}
static func ==(lhs: StarComponent, rhs: StarComponent) -> Bool { static func ==(lhs: StarComponent, rhs: StarComponent) -> Bool {
return true return lhs.isVisible == rhs.isVisible
} }
final class View: UIView, SCNSceneRendererDelegate, ComponentTaggedView { final class View: UIView, SCNSceneRendererDelegate, ComponentTaggedView {
@ -149,7 +155,7 @@ private class StarComponent: Component {
smallAngle = true 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) node.rotation = SCNVector4(x: 0.0, y: 1.0, z: 0.0, w: 0.0)
default: default:
break break
@ -237,12 +243,14 @@ private class StarComponent: Component {
particleSystem?.particleColorVariation = SCNVector4(0.15, 0.2, 0.35, 0.3) particleSystem?.particleColorVariation = SCNVector4(0.15, 0.2, 0.35, 0.3)
particleSystem?.particleVelocity = 2.2 particleSystem?.particleVelocity = 2.2
particleSystem?.birthRate = 4.5 particleSystem?.birthRate = 4.5
particleSystem?.particleLifeSpan = 2.0
node.physicsField?.isActive = true node.physicsField?.isActive = true
Queue.mainQueue().after(1.0) { Queue.mainQueue().after(1.0) {
node.physicsField?.isActive = false node.physicsField?.isActive = false
particles.particleSystems?.first?.birthRate = 1.2 particles.particleSystems?.first?.birthRate = 1.2
particleSystem?.particleVelocity = 1.65 particleSystem?.particleVelocity = 1.65
particleSystem?.particleLifeSpan = 4.0
} }
} }
@ -459,15 +467,18 @@ private final class ScrollComponent<ChildEnvironment: Equatable>: Component {
public let content: AnyComponent<(ChildEnvironment, ScrollChildEnvironment)> public let content: AnyComponent<(ChildEnvironment, ScrollChildEnvironment)>
public let contentInsets: UIEdgeInsets public let contentInsets: UIEdgeInsets
public let contentOffsetUpdated: (_ top: CGFloat, _ bottom: CGFloat) -> Void public let contentOffsetUpdated: (_ top: CGFloat, _ bottom: CGFloat) -> Void
public let contentOffsetWillCommit: (UnsafeMutablePointer<CGPoint>) -> Void
public init( public init(
content: AnyComponent<(ChildEnvironment, ScrollChildEnvironment)>, content: AnyComponent<(ChildEnvironment, ScrollChildEnvironment)>,
contentInsets: UIEdgeInsets, contentInsets: UIEdgeInsets,
contentOffsetUpdated: @escaping (_ top: CGFloat, _ bottom: CGFloat) -> Void contentOffsetUpdated: @escaping (_ top: CGFloat, _ bottom: CGFloat) -> Void,
contentOffsetWillCommit: @escaping (UnsafeMutablePointer<CGPoint>) -> Void
) { ) {
self.content = content self.content = content
self.contentInsets = contentInsets self.contentInsets = contentInsets
self.contentOffsetUpdated = contentOffsetUpdated self.contentOffsetUpdated = contentOffsetUpdated
self.contentOffsetWillCommit = contentOffsetWillCommit
} }
public static func ==(lhs: ScrollComponent, rhs: ScrollComponent) -> Bool { public static func ==(lhs: ScrollComponent, rhs: ScrollComponent) -> Bool {
@ -504,12 +515,18 @@ private final class ScrollComponent<ChildEnvironment: Equatable>: Component {
guard let component = self.component, !self.ignoreDidScroll else { guard let component = self.component, !self.ignoreDidScroll else {
return return
} }
let topOffset = scrollView.contentOffset.y let topOffset = scrollView.contentOffset.y
let bottomOffset = max(0.0, scrollView.contentSize.height - scrollView.contentOffset.y - scrollView.frame.height) let bottomOffset = max(0.0, scrollView.contentSize.height - scrollView.contentOffset.y - scrollView.frame.height)
component.contentOffsetUpdated(topOffset, bottomOffset) component.contentOffsetUpdated(topOffset, bottomOffset)
} }
public func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
guard let component = self.component, !self.ignoreDidScroll else {
return
}
component.contentOffsetWillCommit(targetContentOffset)
}
required init?(coder: NSCoder) { required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented") fatalError("init(coder:) has not been implemented")
} }
@ -1043,11 +1060,9 @@ private final class PremiumIntroScreenComponent: CombinedComponent {
typealias EnvironmentType = ViewControllerComponentContainer.Environment typealias EnvironmentType = ViewControllerComponentContainer.Environment
let context: AccountContext let context: AccountContext
let action: () -> Void
init(context: AccountContext, action: @escaping () -> Void) { init(context: AccountContext) {
self.context = context self.context = context
self.action = action
} }
static func ==(lhs: PremiumIntroScreenComponent, rhs: PremiumIntroScreenComponent) -> Bool { 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) 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( let star = star.update(
component: StarComponent(), component: StarComponent(isVisible: starIsVisible),
availableSize: CGSize(width: min(390.0, context.availableSize.width), height: 180.0), availableSize: CGSize(width: min(390.0, context.availableSize.width), height: 220.0),
transition: context.transition transition: context.transition
) )
@ -1132,7 +1152,7 @@ private final class PremiumIntroScreenComponent: CombinedComponent {
height: 50.0, height: 50.0,
cornerRadius: 10.0, cornerRadius: 10.0,
gloss: true, 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), availableSize: CGSize(width: context.availableSize.width - sideInset * 2.0 - environment.safeInsets.left - environment.safeInsets.right, height: 50.0),
transition: context.transition) transition: context.transition)
@ -1165,6 +1185,13 @@ private final class PremiumIntroScreenComponent: CombinedComponent {
state?.topContentOffset = topContentOffset state?.topContentOffset = topContentOffset
state?.bottomContentOffset = bottomContentOffset state?.bottomContentOffset = bottomContentOffset
state?.updated(transition: .immediate) 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 }, environment: { environment },
@ -1184,19 +1211,21 @@ private final class PremiumIntroScreenComponent: CombinedComponent {
let titleOffset: CGFloat let titleOffset: CGFloat
let titleScale: CGFloat let titleScale: CGFloat
let titleOffsetDelta = 160.0 - environment.navigationHeight / 2.0 let titleOffsetDelta = 160.0 - environment.navigationHeight / 2.0
if let topContentOffset = state.topContentOffset { 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 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 { } else {
topPanelAlpha = 0.0 topPanelAlpha = 0.0
titleOffset = 0.0
titleScale = 1.0 titleScale = 1.0
titleOffset = 0.0
} }
context.add(star 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) .scale(titleScale)
) )
@ -1240,7 +1269,6 @@ private final class PremiumIntroScreenComponent: CombinedComponent {
public final class PremiumIntroScreen: ViewControllerComponentContainer { public final class PremiumIntroScreen: ViewControllerComponentContainer {
private let context: AccountContext private let context: AccountContext
private let action: () -> Void
private var didSetReady = false private var didSetReady = false
private let _ready = Promise<Bool>() private let _ready = Promise<Bool>()
@ -1248,11 +1276,10 @@ public final class PremiumIntroScreen: ViewControllerComponentContainer {
return self._ready return self._ready
} }
public init(context: AccountContext, action: @escaping () -> Void) { public init(context: AccountContext) {
self.context = context 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 } let presentationData = context.sharedContext.currentPresentationData.with { $0 }

View File

@ -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 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 let strongSelf = self {
if case .info = action { if case .info = action {
let controller = PremiumIntroScreen(context: strongSelf.context, action: { let controller = PremiumIntroScreen(context: strongSelf.context)
})
strongSelf.push(controller) strongSelf.push(controller)
return true return true
} }