mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Various improvements
This commit is contained in:
parent
4f255424e5
commit
cc6f7882f1
@ -569,7 +569,7 @@ final class StarsStatisticsScreenComponent: Component {
|
|||||||
theme: environment.theme,
|
theme: environment.theme,
|
||||||
strings: strings,
|
strings: strings,
|
||||||
dateTimeFormat: environment.dateTimeFormat,
|
dateTimeFormat: environment.dateTimeFormat,
|
||||||
containerInsets: UIEdgeInsets(top: 0.0, left: environment.safeInsets.left, bottom: 0.0, right: environment.safeInsets.right),
|
containerInsets: .zero,
|
||||||
isScrollable: false,
|
isScrollable: false,
|
||||||
isCurrent: true,
|
isCurrent: true,
|
||||||
externalScrollBounds: self.lastScrollBounds ?? .zero,
|
externalScrollBounds: self.lastScrollBounds ?? .zero,
|
||||||
|
@ -102,6 +102,12 @@ final class StarsTransactionsListPanelComponent: Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private final class ScrollViewImpl: UIScrollView {
|
private final class ScrollViewImpl: UIScrollView {
|
||||||
|
var forceDecelerating = false
|
||||||
|
|
||||||
|
override var isDecelerating: Bool {
|
||||||
|
return self.forceDecelerating || super.isDecelerating
|
||||||
|
}
|
||||||
|
|
||||||
override func touchesShouldCancel(in view: UIView) -> Bool {
|
override func touchesShouldCancel(in view: UIView) -> Bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -111,8 +117,9 @@ final class StarsTransactionsListPanelComponent: Component {
|
|||||||
private let scrollView: ScrollViewImpl
|
private let scrollView: ScrollViewImpl
|
||||||
|
|
||||||
private let measureItem = ComponentView<Empty>()
|
private let measureItem = ComponentView<Empty>()
|
||||||
private var visibleItems: [String: ComponentView<Empty>] = [:]
|
private var visibleItems: [AnyHashable: ComponentView<Empty>] = [:]
|
||||||
private var separatorViews: [String: UIView] = [:]
|
private var separatorLayers: [AnyHashable: SimpleLayer] = [:]
|
||||||
|
private var highlightLayer = SimpleLayer()
|
||||||
|
|
||||||
private var ignoreScrolling: Bool = false
|
private var ignoreScrolling: Bool = false
|
||||||
|
|
||||||
@ -145,6 +152,8 @@ final class StarsTransactionsListPanelComponent: Component {
|
|||||||
self.scrollView.delegate = self
|
self.scrollView.delegate = self
|
||||||
self.scrollView.clipsToBounds = true
|
self.scrollView.clipsToBounds = true
|
||||||
self.addSubview(self.scrollView)
|
self.addSubview(self.scrollView)
|
||||||
|
|
||||||
|
self.scrollView.layer.addSublayer(self.highlightLayer)
|
||||||
}
|
}
|
||||||
|
|
||||||
required init?(coder: NSCoder) {
|
required init?(coder: NSCoder) {
|
||||||
@ -163,6 +172,79 @@ final class StarsTransactionsListPanelComponent: Component {
|
|||||||
|
|
||||||
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
|
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
|
||||||
cancelContextGestures(view: scrollView)
|
cancelContextGestures(view: scrollView)
|
||||||
|
if let decelerationAnimator = self.decelerationAnimator {
|
||||||
|
self.scrollView.forceDecelerating = false
|
||||||
|
self.decelerationAnimator = nil
|
||||||
|
decelerationAnimator.invalidate()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var decelerationAnimator: ConstantDisplayLinkAnimator?
|
||||||
|
func transferVelocity(_ velocity: CGFloat) {
|
||||||
|
if velocity <= 0.0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.decelerationAnimator?.isPaused = true
|
||||||
|
let startTime = CACurrentMediaTime()
|
||||||
|
var currentOffset = self.scrollView.contentOffset
|
||||||
|
let decelerationRate: CGFloat = 0.998
|
||||||
|
self.scrollView.forceDecelerating = true
|
||||||
|
//self.scrollViewDidEndDragging(self.scrollView, willDecelerate: true)
|
||||||
|
self.decelerationAnimator = ConstantDisplayLinkAnimator(update: { [weak self] in
|
||||||
|
guard let strongSelf = self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let t = CACurrentMediaTime() - startTime
|
||||||
|
var currentVelocity = velocity * 15.0 * CGFloat(pow(Double(decelerationRate), 1000.0 * t))
|
||||||
|
currentOffset.y += currentVelocity
|
||||||
|
let maxOffset = strongSelf.scrollView.contentSize.height - strongSelf.scrollView.bounds.height
|
||||||
|
if currentOffset.y >= maxOffset {
|
||||||
|
currentOffset.y = maxOffset
|
||||||
|
currentVelocity = 0.0
|
||||||
|
}
|
||||||
|
if currentOffset.y < 0.0 {
|
||||||
|
currentOffset.y = 0.0
|
||||||
|
currentVelocity = 0.0
|
||||||
|
}
|
||||||
|
|
||||||
|
var didEnd = false
|
||||||
|
if abs(currentVelocity) < 0.1 {
|
||||||
|
strongSelf.decelerationAnimator?.isPaused = true
|
||||||
|
strongSelf.decelerationAnimator = nil
|
||||||
|
didEnd = true
|
||||||
|
}
|
||||||
|
var contentOffset = strongSelf.scrollView.contentOffset
|
||||||
|
contentOffset.y = floorToScreenPixels(currentOffset.y)
|
||||||
|
strongSelf.scrollView.setContentOffset(contentOffset, animated: false)
|
||||||
|
strongSelf.scrollViewDidScroll(strongSelf.scrollView)
|
||||||
|
if didEnd {
|
||||||
|
//strongSelf.scrollViewDidEndDecelerating(strongSelf.scrollView)
|
||||||
|
strongSelf.scrollView.forceDecelerating = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
self.decelerationAnimator?.isPaused = false
|
||||||
|
}
|
||||||
|
|
||||||
|
private var highlightedItemId: AnyHashable?
|
||||||
|
private func updateHighlightedItem(itemId: AnyHashable?) {
|
||||||
|
guard let environment = self.environment else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if self.highlightedItemId == itemId {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let previousHighlightedItemId = self.highlightedItemId
|
||||||
|
self.highlightedItemId = itemId
|
||||||
|
|
||||||
|
if let _ = previousHighlightedItemId, itemId == nil {
|
||||||
|
ComponentTransition.easeInOut(duration: 0.2).setBackgroundColor(layer: self.highlightLayer, color: .clear)
|
||||||
|
}
|
||||||
|
if let itemId, let itemView = self.visibleItems[itemId]?.view {
|
||||||
|
var highlightFrame = itemView.frame
|
||||||
|
highlightFrame.size.height += UIScreenPixel
|
||||||
|
self.highlightLayer.frame = highlightFrame
|
||||||
|
ComponentTransition.immediate.setBackgroundColor(layer: self.highlightLayer, color: environment.theme.list.itemHighlightedBackgroundColor)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func updateScrolling(transition: ComponentTransition) {
|
private func updateScrolling(transition: ComponentTransition) {
|
||||||
@ -173,34 +255,34 @@ final class StarsTransactionsListPanelComponent: Component {
|
|||||||
var visibleBounds = environment.externalScrollBounds ?? self.scrollView.bounds
|
var visibleBounds = environment.externalScrollBounds ?? self.scrollView.bounds
|
||||||
visibleBounds = visibleBounds.insetBy(dx: 0.0, dy: -100.0)
|
visibleBounds = visibleBounds.insetBy(dx: 0.0, dy: -100.0)
|
||||||
|
|
||||||
var validIds = Set<String>()
|
var validIds = Set<AnyHashable>()
|
||||||
if let visibleItems = itemLayout.visibleItems(for: visibleBounds) {
|
if let visibleItems = itemLayout.visibleItems(for: visibleBounds) {
|
||||||
for index in visibleItems.lowerBound ..< visibleItems.upperBound {
|
for index in visibleItems.lowerBound ..< visibleItems.upperBound {
|
||||||
if index >= self.items.count {
|
if index >= self.items.count {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
let item = self.items[index]
|
let item = self.items[index]
|
||||||
let id = item.extendedId
|
let id = AnyHashable(item.extendedId)
|
||||||
validIds.insert(id)
|
validIds.insert(id)
|
||||||
|
|
||||||
var itemTransition = transition
|
var itemTransition = transition
|
||||||
let itemView: ComponentView<Empty>
|
let itemView: ComponentView<Empty>
|
||||||
let separatorView: UIView
|
let separatorLayer: SimpleLayer
|
||||||
if let current = self.visibleItems[id], let currentSeparator = self.separatorViews[id] {
|
if let current = self.visibleItems[id], let currentSeparator = self.separatorLayers[id] {
|
||||||
itemView = current
|
itemView = current
|
||||||
separatorView = currentSeparator
|
separatorLayer = currentSeparator
|
||||||
} else {
|
} else {
|
||||||
itemTransition = .immediate
|
itemTransition = .immediate
|
||||||
itemView = ComponentView()
|
itemView = ComponentView()
|
||||||
self.visibleItems[id] = itemView
|
self.visibleItems[id] = itemView
|
||||||
|
|
||||||
separatorView = UIView()
|
separatorLayer = SimpleLayer()
|
||||||
self.separatorViews[id] = separatorView
|
self.separatorLayers[id] = separatorLayer
|
||||||
self.scrollView.addSubview(separatorView)
|
self.scrollView.layer.addSublayer(separatorLayer)
|
||||||
}
|
}
|
||||||
|
|
||||||
separatorView.backgroundColor = environment.theme.list.itemBlocksSeparatorColor
|
separatorLayer.backgroundColor = environment.theme.list.itemBlocksSeparatorColor.cgColor
|
||||||
separatorView.isHidden = index == self.items.count - 1
|
separatorLayer.isHidden = index == self.items.count - 1
|
||||||
|
|
||||||
let fontBaseDisplaySize = 17.0
|
let fontBaseDisplaySize = 17.0
|
||||||
|
|
||||||
@ -367,12 +449,18 @@ final class StarsTransactionsListPanelComponent: Component {
|
|||||||
if !item.flags.contains(.isLocal) {
|
if !item.flags.contains(.isLocal) {
|
||||||
component.action(item)
|
component.action(item)
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
updateIsHighlighted: { [weak self] _, highlighted in
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.updateHighlightedItem(itemId: highlighted ? id : nil)
|
||||||
}
|
}
|
||||||
)),
|
)),
|
||||||
environment: {},
|
environment: {},
|
||||||
containerSize: CGSize(width: itemLayout.containerWidth, height: itemLayout.itemHeight)
|
containerSize: CGSize(width: itemLayout.containerWidth - itemLayout.containerInsets.left - itemLayout.containerInsets.right, height: itemLayout.itemHeight)
|
||||||
)
|
)
|
||||||
let itemFrame = itemLayout.itemFrame(for: index)
|
let itemFrame = itemLayout.itemFrame(for: index).offsetBy(dx: itemLayout.containerInsets.left, dy: 0.0)
|
||||||
if let itemComponentView = itemView.view {
|
if let itemComponentView = itemView.view {
|
||||||
if itemComponentView.superview == nil {
|
if itemComponentView.superview == nil {
|
||||||
if !transition.animation.isImmediate {
|
if !transition.animation.isImmediate {
|
||||||
@ -383,11 +471,11 @@ final class StarsTransactionsListPanelComponent: Component {
|
|||||||
itemTransition.setFrame(view: itemComponentView, frame: itemFrame)
|
itemTransition.setFrame(view: itemComponentView, frame: itemFrame)
|
||||||
}
|
}
|
||||||
let sideInset: CGFloat = 60.0 + environment.containerInsets.left
|
let sideInset: CGFloat = 60.0 + environment.containerInsets.left
|
||||||
itemTransition.setFrame(view: separatorView, frame: CGRect(x: sideInset, y: itemFrame.maxY, width: itemFrame.width - sideInset, height: UIScreenPixel))
|
itemTransition.setFrame(layer: separatorLayer, frame: CGRect(x: sideInset, y: itemFrame.maxY, width: itemFrame.width - sideInset - environment.containerInsets.right, height: UIScreenPixel))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var removeIds: [String] = []
|
var removeIds: [AnyHashable] = []
|
||||||
for (id, itemView) in self.visibleItems {
|
for (id, itemView) in self.visibleItems {
|
||||||
if !validIds.contains(id) {
|
if !validIds.contains(id) {
|
||||||
removeIds.append(id)
|
removeIds.append(id)
|
||||||
@ -398,10 +486,10 @@ final class StarsTransactionsListPanelComponent: Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (id, separatorView) in self.separatorViews {
|
for (id, separatorLayer) in self.separatorLayers {
|
||||||
if !validIds.contains(id) {
|
if !validIds.contains(id) {
|
||||||
transition.setAlpha(view: separatorView, alpha: 0.0, completion: { [weak separatorView] _ in
|
transition.setAlpha(layer: separatorLayer, alpha: 0.0, completion: { [weak separatorLayer] _ in
|
||||||
separatorView?.removeFromSuperview()
|
separatorLayer?.removeFromSuperlayer()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -427,6 +427,7 @@ final class StarsTransactionsPanelContainerComponent: Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class View: UIView, UIGestureRecognizerDelegate {
|
class View: UIView, UIGestureRecognizerDelegate {
|
||||||
|
private let topPanelClippingView: UIView
|
||||||
private let topPanelBackgroundView: UIView
|
private let topPanelBackgroundView: UIView
|
||||||
private let topPanelMergedBackgroundView: UIView
|
private let topPanelMergedBackgroundView: UIView
|
||||||
private let topPanelSeparatorLayer: SimpleLayer
|
private let topPanelSeparatorLayer: SimpleLayer
|
||||||
@ -436,6 +437,7 @@ final class StarsTransactionsPanelContainerComponent: Component {
|
|||||||
private weak var state: EmptyComponentState?
|
private weak var state: EmptyComponentState?
|
||||||
|
|
||||||
private let panelsBackgroundLayer: SimpleLayer
|
private let panelsBackgroundLayer: SimpleLayer
|
||||||
|
private let clippingView: UIView
|
||||||
private var visiblePanels: [AnyHashable: ComponentView<StarsTransactionsPanelEnvironment>] = [:]
|
private var visiblePanels: [AnyHashable: ComponentView<StarsTransactionsPanelEnvironment>] = [:]
|
||||||
private var actualVisibleIds = Set<AnyHashable>()
|
private var actualVisibleIds = Set<AnyHashable>()
|
||||||
private var currentId: AnyHashable?
|
private var currentId: AnyHashable?
|
||||||
@ -443,6 +445,10 @@ final class StarsTransactionsPanelContainerComponent: Component {
|
|||||||
private var animatingTransition: Bool = false
|
private var animatingTransition: Bool = false
|
||||||
|
|
||||||
override init(frame: CGRect) {
|
override init(frame: CGRect) {
|
||||||
|
self.topPanelClippingView = UIView()
|
||||||
|
self.topPanelClippingView.clipsToBounds = true
|
||||||
|
self.topPanelClippingView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
|
||||||
|
|
||||||
self.topPanelBackgroundView = UIView()
|
self.topPanelBackgroundView = UIView()
|
||||||
|
|
||||||
self.topPanelMergedBackgroundView = UIView()
|
self.topPanelMergedBackgroundView = UIView()
|
||||||
@ -452,11 +458,16 @@ final class StarsTransactionsPanelContainerComponent: Component {
|
|||||||
|
|
||||||
self.panelsBackgroundLayer = SimpleLayer()
|
self.panelsBackgroundLayer = SimpleLayer()
|
||||||
|
|
||||||
|
self.clippingView = UIView()
|
||||||
|
self.clippingView.clipsToBounds = true
|
||||||
|
|
||||||
super.init(frame: frame)
|
super.init(frame: frame)
|
||||||
|
|
||||||
self.layer.addSublayer(self.panelsBackgroundLayer)
|
self.layer.addSublayer(self.panelsBackgroundLayer)
|
||||||
self.addSubview(self.topPanelBackgroundView)
|
self.addSubview(self.clippingView)
|
||||||
self.addSubview(self.topPanelMergedBackgroundView)
|
self.addSubview(self.topPanelClippingView)
|
||||||
|
self.topPanelClippingView.addSubview(self.topPanelBackgroundView)
|
||||||
|
self.topPanelClippingView.addSubview(self.topPanelMergedBackgroundView)
|
||||||
self.layer.addSublayer(self.topPanelSeparatorLayer)
|
self.layer.addSublayer(self.topPanelSeparatorLayer)
|
||||||
|
|
||||||
let panRecognizer = InteractiveTransitionGestureRecognizer(target: self, action: #selector(self.panGesture(_:)), allowedDirections: { [weak self] point in
|
let panRecognizer = InteractiveTransitionGestureRecognizer(target: self, action: #selector(self.panGesture(_:)), allowedDirections: { [weak self] point in
|
||||||
@ -593,6 +604,12 @@ final class StarsTransactionsPanelContainerComponent: Component {
|
|||||||
transition.setAlpha(view: self.topPanelBackgroundView, alpha: 1.0 - value)
|
transition.setAlpha(view: self.topPanelBackgroundView, alpha: 1.0 - value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func transferVelocity(_ velocity: CGFloat) {
|
||||||
|
if let currentPanelView = self.currentPanelView as? StarsTransactionsListPanelComponent.View {
|
||||||
|
currentPanelView.transferVelocity(velocity)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func update(component: StarsTransactionsPanelContainerComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment<StarsTransactionsPanelContainerEnvironment>, transition: ComponentTransition) -> CGSize {
|
func update(component: StarsTransactionsPanelContainerComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment<StarsTransactionsPanelContainerEnvironment>, transition: ComponentTransition) -> CGSize {
|
||||||
let environment = environment[StarsTransactionsPanelContainerEnvironment.self].value
|
let environment = environment[StarsTransactionsPanelContainerEnvironment.self].value
|
||||||
|
|
||||||
@ -610,13 +627,17 @@ final class StarsTransactionsPanelContainerComponent: Component {
|
|||||||
|
|
||||||
let topPanelCoverHeight: CGFloat = 10.0
|
let topPanelCoverHeight: CGFloat = 10.0
|
||||||
|
|
||||||
let topPanelFrame = CGRect(origin: CGPoint(x: 0.0, y: -topPanelCoverHeight), size: CGSize(width: availableSize.width, height: 44.0))
|
let containerWidth = availableSize.width - component.insets.left - component.insets.right
|
||||||
transition.setFrame(view: self.topPanelBackgroundView, frame: topPanelFrame)
|
let topPanelFrame = CGRect(origin: CGPoint(x: component.insets.left, y: -topPanelCoverHeight), size: CGSize(width: containerWidth, height: 44.0))
|
||||||
transition.setFrame(view: self.topPanelMergedBackgroundView, frame: topPanelFrame)
|
transition.setFrame(view: self.topPanelClippingView, frame: topPanelFrame)
|
||||||
|
transition.setFrame(view: self.topPanelBackgroundView, frame: CGRect(origin: .zero, size: topPanelFrame.size))
|
||||||
|
transition.setFrame(view: self.topPanelMergedBackgroundView, frame: CGRect(origin: .zero, size: topPanelFrame.size))
|
||||||
|
|
||||||
transition.setFrame(layer: self.panelsBackgroundLayer, frame: CGRect(origin: CGPoint(x: 0.0, y: topPanelFrame.maxY), size: CGSize(width: availableSize.width, height: availableSize.height - topPanelFrame.maxY)))
|
transition.setCornerRadius(layer: self.topPanelClippingView.layer, cornerRadius: component.insets.left > 0.0 ? 11.0 : 0.0)
|
||||||
|
|
||||||
transition.setFrame(layer: self.topPanelSeparatorLayer, frame: CGRect(origin: CGPoint(x: 0.0, y: topPanelFrame.maxY), size: CGSize(width: availableSize.width, height: UIScreenPixel)))
|
transition.setFrame(layer: self.panelsBackgroundLayer, frame: CGRect(origin: CGPoint(x: component.insets.left, y: topPanelFrame.maxY), size: CGSize(width: containerWidth, height: availableSize.height - topPanelFrame.maxY)))
|
||||||
|
|
||||||
|
transition.setFrame(layer: self.topPanelSeparatorLayer, frame: CGRect(origin: CGPoint(x: component.insets.left, y: topPanelFrame.maxY), size: CGSize(width: containerWidth, height: UIScreenPixel)))
|
||||||
|
|
||||||
if let currentIdValue = self.currentId, !component.items.contains(where: { $0.id == currentIdValue }) {
|
if let currentIdValue = self.currentId, !component.items.contains(where: { $0.id == currentIdValue }) {
|
||||||
self.currentId = nil
|
self.currentId = nil
|
||||||
@ -641,7 +662,7 @@ final class StarsTransactionsPanelContainerComponent: Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let sideInset: CGFloat = 16.0
|
let sideInset: CGFloat = 16.0 + component.insets.left
|
||||||
let condensedPanelWidth: CGFloat = availableSize.width - sideInset * 2.0
|
let condensedPanelWidth: CGFloat = availableSize.width - sideInset * 2.0
|
||||||
let headerSize = self.header.update(
|
let headerSize = self.header.update(
|
||||||
transition: transition,
|
transition: transition,
|
||||||
@ -674,7 +695,7 @@ final class StarsTransactionsPanelContainerComponent: Component {
|
|||||||
if headerView.superview == nil {
|
if headerView.superview == nil {
|
||||||
self.addSubview(headerView)
|
self.addSubview(headerView)
|
||||||
}
|
}
|
||||||
transition.setFrame(view: headerView, frame: CGRect(origin: topPanelFrame.origin.offsetBy(dx: sideInset, dy: 0.0), size: headerSize))
|
transition.setFrame(view: headerView, frame: CGRect(origin: topPanelFrame.origin.offsetBy(dx: 16.0, dy: 0.0), size: headerSize))
|
||||||
}
|
}
|
||||||
|
|
||||||
let centralPanelFrame = CGRect(origin: CGPoint(x: 0.0, y: topPanelFrame.maxY), size: CGSize(width: availableSize.width, height: availableSize.height - topPanelFrame.maxY))
|
let centralPanelFrame = CGRect(origin: CGPoint(x: 0.0, y: topPanelFrame.maxY), size: CGSize(width: availableSize.width, height: availableSize.height - topPanelFrame.maxY))
|
||||||
@ -769,7 +790,7 @@ final class StarsTransactionsPanelContainerComponent: Component {
|
|||||||
)
|
)
|
||||||
if let panelView = panel.view {
|
if let panelView = panel.view {
|
||||||
if panelView.superview == nil {
|
if panelView.superview == nil {
|
||||||
self.insertSubview(panelView, belowSubview: self.topPanelBackgroundView)
|
self.clippingView.addSubview(panelView)
|
||||||
}
|
}
|
||||||
|
|
||||||
panelTransition.setFrame(view: panelView, frame: itemFrame, completion: { [weak self] _ in
|
panelTransition.setFrame(view: panelView, frame: itemFrame, completion: { [weak self] _ in
|
||||||
@ -790,6 +811,11 @@ final class StarsTransactionsPanelContainerComponent: Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let clippingFrame = CGRect(origin: CGPoint(x: component.insets.left, y: 0.0), size: CGSize(width: availableSize.width - component.insets.left - component.insets.right, height: availableSize.height))
|
||||||
|
|
||||||
|
transition.setPosition(view: self.clippingView, position: clippingFrame.center)
|
||||||
|
transition.setBounds(view: self.clippingView, bounds: CGRect(origin: CGPoint(x: component.insets.left, y: 0.0), size: clippingFrame.size))
|
||||||
|
|
||||||
var removeIds: [AnyHashable] = []
|
var removeIds: [AnyHashable] = []
|
||||||
for (id, panel) in self.visiblePanels {
|
for (id, panel) in self.visiblePanels {
|
||||||
if !validIds.contains(id) {
|
if !validIds.contains(id) {
|
||||||
|
@ -120,6 +120,8 @@ final class StarsTransactionsScreenComponent: Component {
|
|||||||
private var previousVelocityM1: CGFloat = 0.0
|
private var previousVelocityM1: CGFloat = 0.0
|
||||||
private var previousVelocity: CGFloat = 0.0
|
private var previousVelocity: CGFloat = 0.0
|
||||||
|
|
||||||
|
private var listIsExpanded = false
|
||||||
|
|
||||||
private var ignoreScrolling: Bool = false
|
private var ignoreScrolling: Bool = false
|
||||||
|
|
||||||
private var stateDisposable: Disposable?
|
private var stateDisposable: Disposable?
|
||||||
@ -200,6 +202,19 @@ final class StarsTransactionsScreenComponent: Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
|
||||||
|
guard let navigationMetrics = self.navigationMetrics else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if let panelContainerView = self.panelContainer.view as? StarsTransactionsPanelContainerComponent.View {
|
||||||
|
let paneAreaExpansionFinalPoint: CGFloat = panelContainerView.frame.minY - navigationMetrics.navigationHeight
|
||||||
|
if abs(scrollView.contentOffset.y - paneAreaExpansionFinalPoint) < .ulpOfOne {
|
||||||
|
panelContainerView.transferVelocity(self.previousVelocityM1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
|
func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
|
||||||
guard let _ = self.navigationMetrics else {
|
guard let _ = self.navigationMetrics else {
|
||||||
return
|
return
|
||||||
@ -273,6 +288,14 @@ final class StarsTransactionsScreenComponent: Component {
|
|||||||
if let view = self.topBalanceIconView.view {
|
if let view = self.topBalanceIconView.view {
|
||||||
view.alpha = topBalanceAlpha
|
view.alpha = topBalanceAlpha
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let listIsExpanded = expansionDistanceFactor == 0.0
|
||||||
|
if listIsExpanded != self.listIsExpanded {
|
||||||
|
self.listIsExpanded = listIsExpanded
|
||||||
|
if !self.isUpdating {
|
||||||
|
self.state?.updated(transition: .init(animation: .curve(duration: 0.25, curve: .slide)))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let _ = self.panelContainer.updateEnvironment(
|
let _ = self.panelContainer.updateEnvironment(
|
||||||
@ -362,7 +385,7 @@ final class StarsTransactionsScreenComponent: Component {
|
|||||||
|
|
||||||
var contentHeight: CGFloat = 0.0
|
var contentHeight: CGFloat = 0.0
|
||||||
|
|
||||||
let sideInsets: CGFloat = environment.safeInsets.left + environment.safeInsets.right + 16 * 2.0
|
let sideInsets: CGFloat = environment.safeInsets.left + environment.safeInsets.right + 16.0 * 2.0
|
||||||
let bottomInset: CGFloat = environment.safeInsets.bottom
|
let bottomInset: CGFloat = environment.safeInsets.bottom
|
||||||
|
|
||||||
contentHeight += environment.statusBarHeight
|
contentHeight += environment.statusBarHeight
|
||||||
@ -834,13 +857,16 @@ final class StarsTransactionsScreenComponent: Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !panelItems.isEmpty {
|
if !panelItems.isEmpty {
|
||||||
|
let panelContainerInset: CGFloat = self.listIsExpanded ? 0.0 : 16.0
|
||||||
|
let panelContainerCornerRadius: CGFloat = self.listIsExpanded ? 0.0 : 11.0
|
||||||
|
|
||||||
let panelContainerSize = self.panelContainer.update(
|
let panelContainerSize = self.panelContainer.update(
|
||||||
transition: panelTransition,
|
transition: panelTransition,
|
||||||
component: AnyComponent(StarsTransactionsPanelContainerComponent(
|
component: AnyComponent(StarsTransactionsPanelContainerComponent(
|
||||||
theme: environment.theme,
|
theme: environment.theme,
|
||||||
strings: environment.strings,
|
strings: environment.strings,
|
||||||
dateTimeFormat: environment.dateTimeFormat,
|
dateTimeFormat: environment.dateTimeFormat,
|
||||||
insets: UIEdgeInsets(top: 0.0, left: environment.safeInsets.left, bottom: bottomInset, right: environment.safeInsets.right),
|
insets: UIEdgeInsets(top: 0.0, left: environment.safeInsets.left + panelContainerInset, bottom: bottomInset, right: environment.safeInsets.right + panelContainerInset),
|
||||||
items: panelItems,
|
items: panelItems,
|
||||||
currentPanelUpdated: { [weak self] id, transition in
|
currentPanelUpdated: { [weak self] id, transition in
|
||||||
guard let self else {
|
guard let self else {
|
||||||
@ -859,7 +885,8 @@ final class StarsTransactionsScreenComponent: Component {
|
|||||||
if panelContainerView.superview == nil {
|
if panelContainerView.superview == nil {
|
||||||
self.scrollContainerView.addSubview(panelContainerView)
|
self.scrollContainerView.addSubview(panelContainerView)
|
||||||
}
|
}
|
||||||
transition.setFrame(view: panelContainerView, frame: CGRect(origin: CGPoint(x: 0.0, y: contentHeight), size: panelContainerSize))
|
transition.setFrame(view: panelContainerView, frame: CGRect(origin: CGPoint(x: floor((availableSize.width - panelContainerSize.width) / 2.0), y: contentHeight), size: panelContainerSize))
|
||||||
|
transition.setCornerRadius(layer: panelContainerView.layer, cornerRadius: panelContainerCornerRadius)
|
||||||
}
|
}
|
||||||
contentHeight += panelContainerSize.height
|
contentHeight += panelContainerSize.height
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user